From 2e6545f6127abd2a775e0e4cbd103cd8a67f34ac Mon Sep 17 00:00:00 2001 From: Arif Ali Date: Sun, 6 Nov 2011 23:26:22 +0000 Subject: [PATCH] 1.1: Initial commit --- bin/NBMerge.exe | Bin 0 -> 77824 bytes bin/osnbtool.exe | Bin 0 -> 110592 bytes bin/template_os.nb.payload | Bin 0 -> 524288 bytes bin/yang.exe | Bin 0 -> 16384 bytes compile | 55 + lk/AndroidBoot.mk | 66 + lk/app/aboot/aboot.c | 735 + lk/app/aboot/bootimg.h | 97 + lk/app/aboot/fastboot.c | 372 + lk/app/aboot/fastboot.h | 50 + lk/app/aboot/recovery.c | 277 + lk/app/aboot/recovery.h | 77 + lk/app/aboot/rules.mk | 7 + lk/app/app.c | 66 + lk/app/nandwrite/bootimg.h | 99 + lk/app/nandwrite/nandwrite.c | 220 + lk/app/nandwrite/rules.mk | 6 + lk/app/rules.mk | 5 + lk/app/shell/rules.mk | 7 + lk/app/shell/shell.c | 41 + lk/app/stringtests/mymemcpy.S | 169 + lk/app/stringtests/mymemset.S | 109 + lk/app/stringtests/rules.mk | 6 + lk/app/stringtests/string_tests.c | 249 + lk/app/tests/include/app/tests.h | 30 + lk/app/tests/printf_tests.c | 90 + lk/app/tests/rules.mk | 8 + lk/app/tests/tests.c | 46 + lk/app/tests/thread_tests.c | 322 + lk/arch/arm/arch.c | 72 + lk/arch/arm/asm.S | 103 + lk/arch/arm/cache-ops.S | 366 + lk/arch/arm/cache.c | 22 + lk/arch/arm/compile.mk | 33 + lk/arch/arm/crt0.S | 175 + lk/arch/arm/dcc.S | 41 + lk/arch/arm/exceptions.S | 132 + lk/arch/arm/faults.c | 91 + lk/arch/arm/include/arch/arch_thread.h | 31 + lk/arch/arm/include/arch/arm.h | 94 + lk/arch/arm/include/arch/arm/cores.h | 122 + lk/arch/arm/include/arch/arm/dcc.h | 33 + lk/arch/arm/include/arch/arm/mmu.h | 44 + lk/arch/arm/include/arch/arm/ops.h | 48 + lk/arch/arm/include/arch/defines.h | 43 + lk/arch/arm/mmu.c | 100 + lk/arch/arm/ops.S | 213 + lk/arch/arm/rules.mk | 142 + lk/arch/arm/system-onesegment.ld | 82 + lk/arch/arm/system-twosegment.ld | 85 + lk/arch/arm/thread.c | 88 + lk/dev/dev.c | 28 + lk/dev/fbcon/fbcon.c | 245 + lk/dev/fbcon/font5x12.h | 126 + lk/dev/fbcon/rules.mk | 5 + lk/dev/keys/gpio_keypad.c | 618 + lk/dev/keys/keys.c | 67 + lk/dev/keys/rules.mk | 10 + .../net/smc91c96/include/dev/net/smc91c96.h | 29 + lk/dev/net/smc91c96/rules.mk | 8 + lk/dev/net/smc91c96/smc91c96.c | 70 + lk/dev/net/smc91c96/smc91c96_p.h | 80 + lk/dev/pmic/twl4030/include/dev/twl4030.h | 36 + lk/dev/pmic/twl4030/rules.mk | 7 + lk/dev/pmic/twl4030/twl4030.c | 169 + lk/dev/pmic/twl4030/twl4030_hw.h | 369 + lk/dev/rules.mk | 5 + lk/dev/usb/rules.mk | 5 + lk/dev/usb/usb.c | 307 + lk/include/app.h | 49 + lk/include/arch.h | 37 + lk/include/arch/ops.h | 71 + lk/include/arch/thread.h | 34 + lk/include/asm.h | 30 + lk/include/assert.h | 40 + lk/include/bits.h | 59 + lk/include/compiler.h | 109 + lk/include/ctype.h | 43 + lk/include/debug.h | 95 + lk/include/dev/ethernet.h | 38 + lk/include/dev/fbcon.h | 54 + lk/include/dev/flash.h | 67 + lk/include/dev/gpio.h | 51 + lk/include/dev/gpio_keypad.h | 248 + lk/include/dev/i2c.h | 39 + lk/include/dev/keys.h | 91 + lk/include/dev/uart.h | 38 + lk/include/dev/udc.h | 120 + lk/include/dev/usb.h | 65 + lk/include/dev/usbc.h | 98 + lk/include/endian.h | 95 + lk/include/err.h | 41 + lk/include/hw/mii.h | 75 + lk/include/hw/usb.h | 106 + lk/include/inttypes.h | 29 + lk/include/kernel/dpc.h | 38 + lk/include/kernel/event.h | 63 + lk/include/kernel/mutex.h | 49 + lk/include/kernel/thread.h | 227 + lk/include/kernel/timer.h | 59 + lk/include/lib/console.h | 62 + lk/include/lib/heap.h | 35 + lk/include/lib/ptable.h | 70 + lk/include/limits.h | 121 + lk/include/list.h | 269 + lk/include/malloc.h | 43 + lk/include/new.h | 35 + lk/include/platform.h | 38 + lk/include/platform/debug.h | 51 + lk/include/platform/interrupts.h | 35 + lk/include/platform/timer.h | 31 + lk/include/printf.h | 44 + lk/include/rand.h | 29 + lk/include/reg.h | 44 + lk/include/stdint.h | 60 + lk/include/stdio.h | 12 + lk/include/stdlib.h | 49 + lk/include/string.h | 80 + lk/include/sys/types.h | 68 + lk/include/target.h | 38 + lk/kernel/debug.c | 126 + lk/kernel/dpc.c | 88 + lk/kernel/event.c | 138 + lk/kernel/main.c | 158 + lk/kernel/mutex.c | 169 + lk/kernel/rules.mk | 16 + lk/kernel/thread.c | 666 + lk/kernel/timer.c | 142 + lk/lib/console/console.c | 340 + lk/lib/console/rules.mk | 6 + lk/lib/debug/debug.c | 360 + lk/lib/debug/rules.mk | 4 + lk/lib/heap/heap.c | 380 + lk/lib/heap/rules.mk | 4 + lk/lib/libc/atexit.c | 29 + lk/lib/libc/atoi.c | 105 + lk/lib/libc/ctype.c | 86 + lk/lib/libc/eabi.c | 51 + lk/lib/libc/malloc.c | 55 + lk/lib/libc/new.cpp | 51 + lk/lib/libc/printf.c | 341 + lk/lib/libc/pure_virtual.cpp | 29 + lk/lib/libc/rand.c | 30 + lk/lib/libc/rules.mk | 20 + lk/lib/libc/string/arch/arm/memcpy.S | 177 + lk/lib/libc/string/arch/arm/memset.S | 113 + lk/lib/libc/string/arch/arm/rules.mk | 11 + lk/lib/libc/string/bcopy.c | 35 + lk/lib/libc/string/bzero.c | 35 + lk/lib/libc/string/memchr.c | 45 + lk/lib/libc/string/memcmp.c | 40 + lk/lib/libc/string/memcpy.c | 69 + lk/lib/libc/string/memmove.c | 93 + lk/lib/libc/string/memscan.c | 41 + lk/lib/libc/string/memset.c | 61 + lk/lib/libc/string/rules.mk | 42 + lk/lib/libc/string/strcat.c | 42 + lk/lib/libc/string/strchr.c | 37 + lk/lib/libc/string/strcmp.c | 41 + lk/lib/libc/string/strcoll.c | 34 + lk/lib/libc/string/strcpy.c | 39 + lk/lib/libc/string/strdup.c | 43 + lk/lib/libc/string/strerror.c | 36 + lk/lib/libc/string/strlcat.c | 50 + lk/lib/libc/string/strlcpy.c | 47 + lk/lib/libc/string/strlen.c | 41 + lk/lib/libc/string/strncat.c | 48 + lk/lib/libc/string/strncmp.c | 42 + lk/lib/libc/string/strncpy.c | 40 + lk/lib/libc/string/strnicmp.c | 55 + lk/lib/libc/string/strnlen.c | 38 + lk/lib/libc/string/strpbrk.c | 44 + lk/lib/libc/string/strrchr.c | 45 + lk/lib/libc/string/strspn.c | 48 + lk/lib/libc/string/strstr.c | 46 + lk/lib/libc/string/strtok.c | 51 + lk/lib/libc/string/strxfrm.c | 42 + lk/lib/ptable/ptable.c | 99 + lk/lib/ptable/rules.mk | 4 + lk/make/build.mk | 30 + lk/make/macros.mk | 5 + lk/make/module.mk | 21 + lk/makefile | 188 + lk/platform/armemu/debug.c | 93 + lk/platform/armemu/include/platform/armemu.h | 29 + .../armemu/include/platform/armemu/memmap.h | 148 + lk/platform/armemu/interrupts.c | 117 + lk/platform/armemu/net.c | 398 + lk/platform/armemu/platform.c | 44 + lk/platform/armemu/platform_p.h | 30 + lk/platform/armemu/rules.mk | 28 + lk/platform/armemu/timer.c | 75 + lk/platform/at91sam7/README | 15 + lk/platform/at91sam7/at91sam7s.pins | 32 + lk/platform/at91sam7/at91sam7x.pins | 31 + lk/platform/at91sam7/debug.c | 81 + lk/platform/at91sam7/emac_dev.c | 250 + .../at91sam7/include/platform/at91sam7.h | 794 + lk/platform/at91sam7/init_clock.S | 101 + lk/platform/at91sam7/init_clock_48mhz.S | 58 + lk/platform/at91sam7/interrupts.c | 100 + lk/platform/at91sam7/mkboard.py | 178 + lk/platform/at91sam7/mux.c | 39 + lk/platform/at91sam7/platform.c | 31 + lk/platform/at91sam7/platform_early.S | 56 + lk/platform/at91sam7/rules.mk | 70 + lk/platform/at91sam7/timer.c | 103 + lk/platform/debug.c | 24 + lk/platform/init.c | 54 + lk/platform/integrator/debug.c | 146 + .../integrator/include/platform/integrator.h | 59 + lk/platform/integrator/interrupts.c | 238 + lk/platform/integrator/platform.c | 55 + lk/platform/integrator/platform_p.h | 30 + lk/platform/integrator/rules.mk | 26 + lk/platform/integrator/timer.c | 101 + lk/platform/msm7k/acpuclock.c | 153 + lk/platform/msm7k/gpio.c | 228 + lk/platform/msm7k/include/platform/iomap.h | 51 + lk/platform/msm7k/include/platform/irqs.h | 95 + lk/platform/msm7k/interrupts.c | 140 + lk/platform/msm7k/panel.c | 471 + lk/platform/msm7k/platform.c | 80 + lk/platform/msm7k/rules.mk | 24 + lk/platform/msm7x30/acpuclock.c | 175 + lk/platform/msm7x30/arch_init.S | 699 + lk/platform/msm7x30/gpio.c | 241 + lk/platform/msm7x30/gpio_hw.h | 181 + lk/platform/msm7x30/include/platform/iomap.h | 64 + lk/platform/msm7x30/include/platform/irqs.h | 170 + lk/platform/msm7x30/interrupts.c | 159 + lk/platform/msm7x30/panel.c | 674 + lk/platform/msm7x30/platform.c | 141 + lk/platform/msm7x30/rules.mk | 29 + lk/platform/msm8x60/acpuclock.c | 273 + lk/platform/msm8x60/gpio.c | 48 + lk/platform/msm8x60/include/platform/clock.h | 105 + .../msm8x60/include/platform/gpio_hw.h | 60 + lk/platform/msm8x60/include/platform/iomap.h | 138 + lk/platform/msm8x60/include/platform/irqs.h | 75 + lk/platform/msm8x60/include/platform/pmic.h | 85 + lk/platform/msm8x60/interrupts.c | 187 + lk/platform/msm8x60/mmc_init.c | 104 + lk/platform/msm8x60/panel.c | 363 + lk/platform/msm8x60/platform.c | 151 + lk/platform/msm8x60/pmic.c | 101 + lk/platform/msm8x60/rules.mk | 30 + lk/platform/msm_shared/debug.c | 81 + lk/platform/msm_shared/dmov.h | 173 + lk/platform/msm_shared/hsusb.c | 935 ++ lk/platform/msm_shared/hsusb.h | 189 + lk/platform/msm_shared/i2c_qup.c | 840 + lk/platform/msm_shared/include/i2c_qup.h | 254 + lk/platform/msm_shared/include/jtag.h | 40 + lk/platform/msm_shared/include/mddi.h | 84 + lk/platform/msm_shared/include/mipi_dsi.h | 449 + lk/platform/msm_shared/include/mmc.h | 623 + lk/platform/msm_shared/include/nand.h | 203 + lk/platform/msm_shared/include/splash.h | 12930 ++++++++++++++++ lk/platform/msm_shared/include/uart_dm.h | 273 + lk/platform/msm_shared/jtag.c | 115 + lk/platform/msm_shared/jtag_hook.S | 33 + lk/platform/msm_shared/lcdc.c | 161 + lk/platform/msm_shared/mddi.c | 344 + lk/platform/msm_shared/mddi_hw.h | 249 + lk/platform/msm_shared/mipi_dsi.c | 652 + lk/platform/msm_shared/mmc.c | 2796 ++++ lk/platform/msm_shared/nand.c | 3475 +++++ lk/platform/msm_shared/proc_comm.c | 368 + lk/platform/msm_shared/rules.mk | 31 + lk/platform/msm_shared/smem.c | 91 + lk/platform/msm_shared/smem.h | 201 + lk/platform/msm_shared/smem_ptable.c | 156 + lk/platform/msm_shared/timer.c | 203 + lk/platform/msm_shared/uart.c | 207 + lk/platform/msm_shared/uart_dm.c | 526 + lk/platform/omap3/cpu_early_init.S | 30 + lk/platform/omap3/debug.c | 86 + lk/platform/omap3/i2c.c | 315 + lk/platform/omap3/include/platform/omap3.h | 257 + lk/platform/omap3/interrupts.c | 161 + lk/platform/omap3/platform.c | 65 + lk/platform/omap3/platform_p.h | 30 + lk/platform/omap3/rules.mk | 37 + lk/platform/omap3/timer.c | 133 + lk/platform/omap3/uart.c | 163 + lk/platform/omap3/usbc.c | 882 ++ lk/platform/omap5912/debug.c | 143 + .../omap5912/include/platform/omap5912.h | 139 + lk/platform/omap5912/interrupts.c | 193 + lk/platform/omap5912/platform.c | 52 + lk/platform/omap5912/platform_p.h | 30 + lk/platform/omap5912/rules.mk | 24 + lk/platform/omap5912/timer.c | 110 + lk/platform/qsd8650a/acpuclock.c | 68 + lk/platform/qsd8650a/arch_init.S | 631 + lk/platform/qsd8650a/gpio.c | 212 + lk/platform/qsd8650a/gpio_hw.h | 118 + lk/platform/qsd8650a/include/platform/iomap.h | 44 + lk/platform/qsd8650a/include/platform/irqs.h | 131 + lk/platform/qsd8650a/interrupts.c | 159 + lk/platform/qsd8650a/platform.c | 69 + lk/platform/qsd8650a/rules.mk | 25 + lk/platform/qsd8k/acpuclock.c | 95 + lk/platform/qsd8k/arch_init.S | 648 + lk/platform/qsd8k/gpio.c | 212 + lk/platform/qsd8k/gpio_hw.h | 118 + lk/platform/qsd8k/include/platform/iomap.h | 48 + lk/platform/qsd8k/include/platform/irqs.h | 131 + lk/platform/qsd8k/interrupts.c | 159 + lk/platform/qsd8k/panel.c | 657 + lk/platform/qsd8k/platform.c | 84 + lk/platform/qsd8k/rules.mk | 26 + lk/platform/rules.mk | 7 + lk/project/aboot-surf7k.mk | 11 + lk/project/aboot-surf8k.mk | 11 + lk/project/armemu-test.mk | 16 + lk/project/beagle-test.mk | 11 + lk/project/htcleo.mk | 11 + lk/project/msm7625_ffa.mk | 11 + lk/project/msm7625_ffa_nandwrite.mk | 14 + lk/project/msm7625_surf.mk | 11 + lk/project/msm7625_surf_nandwrite.mk | 14 + lk/project/msm7627_7x_ffa.mk | 11 + lk/project/msm7627_7x_ffa_nandwrite.mk | 14 + lk/project/msm7627_7x_surf.mk | 11 + lk/project/msm7627_7x_surf_nandwrite.mk | 14 + lk/project/msm7627_ffa.mk | 11 + lk/project/msm7627_ffa_nandwrite.mk | 14 + lk/project/msm7627_surf.mk | 11 + lk/project/msm7627_surf_nandwrite.mk | 14 + lk/project/msm7630_1x.mk | 11 + lk/project/msm7630_1x_nandwrite.mk | 14 + lk/project/msm7630_fusion.mk | 5 + lk/project/msm7630_fusion_nandwrite.mk | 5 + lk/project/msm7630_surf.mk | 11 + lk/project/msm7630_surf_nandwrite.mk | 14 + lk/project/msm8655_surf.mk | 11 + lk/project/msm8655_surf_nandwrite.mk | 14 + lk/project/msm8660_csfb.mk | 11 + lk/project/msm8660_surf.mk | 11 + lk/project/osk5912-test.mk | 10 + lk/project/qemu-arm-test.mk | 9 + lk/project/qsd8250_ffa.mk | 11 + lk/project/qsd8250_ffa_nandwrite.mk | 14 + lk/project/qsd8250_surf.mk | 11 + lk/project/qsd8250_surf_nandwrite.mk | 14 + lk/project/qsd8650a_st1x.mk | 11 + lk/project/qsd8650a_st1x_nandwrite.mk | 14 + lk/project/sam7ex256-test.mk | 9 + lk/project/surf-test.mk | 14 + lk/scripts/attach.cmm | 10 + lk/scripts/buildall | 7 + lk/scripts/config_a11.cmm | 16 + lk/scripts/config_scorpion.cmm | 14 + lk/scripts/do-armemu-test | 7 + lk/scripts/do-beagle-test | 6 + lk/scripts/do-osk5912-test | 6 + lk/scripts/do-sam7ex256-test | 6 + lk/scripts/lk.cmm | 49 + lk/scripts/tagit | 7 + lk/target/armemu/rules.mk | 6 + lk/target/beagle/include/target/debugconfig.h | 28 + lk/target/beagle/rules.mk | 15 + lk/target/htcleo/atags.c | 17 + lk/target/htcleo/include/target/display.h | 46 + lk/target/htcleo/init.c | 205 + lk/target/htcleo/keypad.c | 79 + lk/target/htcleo/nand.c | 1091 ++ lk/target/htcleo/nand.h | 95 + lk/target/htcleo/rules.mk | 55 + lk/target/htcleo/tools/makefile | 30 + lk/target/htcleo/tools/mkheader.c | 55 + lk/target/init.c | 72 + lk/target/msm7625_ffa/atags.c | 32 + .../msm7625_ffa/include/target/display.h | 47 + lk/target/msm7625_ffa/init.c | 192 + lk/target/msm7625_ffa/keypad.c | 112 + lk/target/msm7625_ffa/rules.mk | 39 + lk/target/msm7625_ffa/tools/makefile | 38 + lk/target/msm7625_ffa/tools/mkheader.c | 87 + lk/target/msm7625_surf/atags.c | 32 + .../msm7625_surf/include/target/display.h | 47 + lk/target/msm7625_surf/init.c | 192 + lk/target/msm7625_surf/keypad.c | 112 + lk/target/msm7625_surf/rules.mk | 39 + lk/target/msm7625_surf/tools/makefile | 37 + lk/target/msm7625_surf/tools/mkheader.c | 87 + lk/target/msm7627_ffa/atags.c | 67 + .../msm7627_ffa/include/target/display.h | 47 + lk/target/msm7627_ffa/init.c | 219 + lk/target/msm7627_ffa/keypad.c | 112 + lk/target/msm7627_ffa/rules.mk | 41 + lk/target/msm7627_ffa/tools/makefile | 39 + lk/target/msm7627_ffa/tools/mkheader.c | 87 + lk/target/msm7627_surf/atags.c | 72 + .../msm7627_surf/include/target/display.h | 47 + lk/target/msm7627_surf/init.c | 227 + lk/target/msm7627_surf/keypad.c | 112 + lk/target/msm7627_surf/rules.mk | 40 + lk/target/msm7627_surf/tools/makefile | 38 + lk/target/msm7627_surf/tools/mkheader.c | 87 + lk/target/msm7630_1x/atags.c | 119 + lk/target/msm7630_1x/include/target/display.h | 47 + lk/target/msm7630_1x/init.c | 271 + lk/target/msm7630_1x/keypad.c | 66 + lk/target/msm7630_1x/panel.c | 471 + lk/target/msm7630_1x/rules.mk | 40 + lk/target/msm7630_1x/tools/makefile | 41 + lk/target/msm7630_1x/tools/mkheader.c | 91 + lk/target/msm7630_surf/atags.c | 130 + .../msm7630_surf/include/target/display.h | 47 + lk/target/msm7630_surf/init.c | 378 + lk/target/msm7630_surf/keypad.c | 66 + lk/target/msm7630_surf/rules.mk | 42 + lk/target/msm7630_surf/tools/makefile | 45 + lk/target/msm7630_surf/tools/mkheader.c | 316 + lk/target/msm8660_surf/atags.c | 87 + .../msm8660_surf/include/target/display.h | 63 + lk/target/msm8660_surf/init.c | 233 + lk/target/msm8660_surf/keypad.c | 60 + lk/target/msm8660_surf/rules.mk | 41 + lk/target/msm8660_surf/tools/makefile | 44 + lk/target/msm8660_surf/tools/mkheader.c | 316 + lk/target/osk5912/init.c | 33 + lk/target/osk5912/rules.mk | 17 + lk/target/qemu-arm/rules.mk | 7 + lk/target/qsd8250_ffa/atags.c | 82 + .../qsd8250_ffa/include/target/display.h | 47 + lk/target/qsd8250_ffa/init.c | 200 + lk/target/qsd8250_ffa/keypad.c | 112 + lk/target/qsd8250_ffa/rules.mk | 38 + lk/target/qsd8250_ffa/tools/makefile | 30 + lk/target/qsd8250_ffa/tools/mkheader.c | 55 + lk/target/qsd8250_surf/atags.c | 82 + .../qsd8250_surf/include/target/display.h | 47 + lk/target/qsd8250_surf/init.c | 200 + lk/target/qsd8250_surf/keypad.c | 112 + lk/target/qsd8250_surf/rules.mk | 39 + lk/target/qsd8250_surf/tools/makefile | 30 + lk/target/qsd8250_surf/tools/mkheader.c | 55 + lk/target/qsd8650a_st1x/atags.c | 56 + .../qsd8650a_st1x/include/target/display.h | 47 + lk/target/qsd8650a_st1x/init.c | 200 + lk/target/qsd8650a_st1x/keypad.c | 38 + lk/target/qsd8650a_st1x/rules.mk | 38 + lk/target/qsd8650a_st1x/tools/makefile | 30 + lk/target/qsd8650a_st1x/tools/mkheader.c | 55 + lk/target/rules.mk | 6 + lk/target/sam7ex256/README | 6 + lk/target/sam7ex256/include/platform/mux.def | 9 + lk/target/sam7ex256/include/platform/mux.h | 42 + lk/target/sam7ex256/mkmux.sh | 1 + lk/target/sam7ex256/rules.mk | 10 + lk/target/surf-msm7k/atags.c | 43 + lk/target/surf-msm7k/init.c | 120 + lk/target/surf-msm7k/keypad.c | 111 + lk/target/surf-msm7k/panel.c | 471 + lk/target/surf-msm7k/rules.mk | 39 + lk/target/surf-qsd8k/atags.c | 43 + lk/target/surf-qsd8k/init.c | 120 + lk/target/surf-qsd8k/keypad.c | 111 + lk/target/surf-qsd8k/rules.mk | 34 + nbfix.c | 39 + readme_boot.img.txt | 2 + tinboot/tinboot.S | 49 + 466 files changed, 69344 insertions(+) create mode 100644 bin/NBMerge.exe create mode 100644 bin/osnbtool.exe create mode 100644 bin/template_os.nb.payload create mode 100644 bin/yang.exe create mode 100644 compile create mode 100644 lk/AndroidBoot.mk create mode 100644 lk/app/aboot/aboot.c create mode 100644 lk/app/aboot/bootimg.h create mode 100644 lk/app/aboot/fastboot.c create mode 100644 lk/app/aboot/fastboot.h create mode 100644 lk/app/aboot/recovery.c create mode 100644 lk/app/aboot/recovery.h create mode 100644 lk/app/aboot/rules.mk create mode 100644 lk/app/app.c create mode 100644 lk/app/nandwrite/bootimg.h create mode 100644 lk/app/nandwrite/nandwrite.c create mode 100644 lk/app/nandwrite/rules.mk create mode 100644 lk/app/rules.mk create mode 100644 lk/app/shell/rules.mk create mode 100644 lk/app/shell/shell.c create mode 100644 lk/app/stringtests/mymemcpy.S create mode 100644 lk/app/stringtests/mymemset.S create mode 100644 lk/app/stringtests/rules.mk create mode 100644 lk/app/stringtests/string_tests.c create mode 100644 lk/app/tests/include/app/tests.h create mode 100644 lk/app/tests/printf_tests.c create mode 100644 lk/app/tests/rules.mk create mode 100644 lk/app/tests/tests.c create mode 100644 lk/app/tests/thread_tests.c create mode 100644 lk/arch/arm/arch.c create mode 100644 lk/arch/arm/asm.S create mode 100644 lk/arch/arm/cache-ops.S create mode 100644 lk/arch/arm/cache.c create mode 100644 lk/arch/arm/compile.mk create mode 100644 lk/arch/arm/crt0.S create mode 100644 lk/arch/arm/dcc.S create mode 100644 lk/arch/arm/exceptions.S create mode 100644 lk/arch/arm/faults.c create mode 100644 lk/arch/arm/include/arch/arch_thread.h create mode 100644 lk/arch/arm/include/arch/arm.h create mode 100644 lk/arch/arm/include/arch/arm/cores.h create mode 100644 lk/arch/arm/include/arch/arm/dcc.h create mode 100644 lk/arch/arm/include/arch/arm/mmu.h create mode 100644 lk/arch/arm/include/arch/arm/ops.h create mode 100644 lk/arch/arm/include/arch/defines.h create mode 100644 lk/arch/arm/mmu.c create mode 100644 lk/arch/arm/ops.S create mode 100644 lk/arch/arm/rules.mk create mode 100644 lk/arch/arm/system-onesegment.ld create mode 100644 lk/arch/arm/system-twosegment.ld create mode 100644 lk/arch/arm/thread.c create mode 100644 lk/dev/dev.c create mode 100644 lk/dev/fbcon/fbcon.c create mode 100644 lk/dev/fbcon/font5x12.h create mode 100644 lk/dev/fbcon/rules.mk create mode 100644 lk/dev/keys/gpio_keypad.c create mode 100644 lk/dev/keys/keys.c create mode 100644 lk/dev/keys/rules.mk create mode 100644 lk/dev/net/smc91c96/include/dev/net/smc91c96.h create mode 100644 lk/dev/net/smc91c96/rules.mk create mode 100644 lk/dev/net/smc91c96/smc91c96.c create mode 100644 lk/dev/net/smc91c96/smc91c96_p.h create mode 100644 lk/dev/pmic/twl4030/include/dev/twl4030.h create mode 100644 lk/dev/pmic/twl4030/rules.mk create mode 100644 lk/dev/pmic/twl4030/twl4030.c create mode 100644 lk/dev/pmic/twl4030/twl4030_hw.h create mode 100644 lk/dev/rules.mk create mode 100644 lk/dev/usb/rules.mk create mode 100644 lk/dev/usb/usb.c create mode 100644 lk/include/app.h create mode 100644 lk/include/arch.h create mode 100644 lk/include/arch/ops.h create mode 100644 lk/include/arch/thread.h create mode 100644 lk/include/asm.h create mode 100644 lk/include/assert.h create mode 100644 lk/include/bits.h create mode 100644 lk/include/compiler.h create mode 100644 lk/include/ctype.h create mode 100644 lk/include/debug.h create mode 100644 lk/include/dev/ethernet.h create mode 100644 lk/include/dev/fbcon.h create mode 100644 lk/include/dev/flash.h create mode 100644 lk/include/dev/gpio.h create mode 100644 lk/include/dev/gpio_keypad.h create mode 100644 lk/include/dev/i2c.h create mode 100644 lk/include/dev/keys.h create mode 100644 lk/include/dev/uart.h create mode 100644 lk/include/dev/udc.h create mode 100644 lk/include/dev/usb.h create mode 100644 lk/include/dev/usbc.h create mode 100644 lk/include/endian.h create mode 100644 lk/include/err.h create mode 100644 lk/include/hw/mii.h create mode 100644 lk/include/hw/usb.h create mode 100644 lk/include/inttypes.h create mode 100644 lk/include/kernel/dpc.h create mode 100644 lk/include/kernel/event.h create mode 100644 lk/include/kernel/mutex.h create mode 100644 lk/include/kernel/thread.h create mode 100644 lk/include/kernel/timer.h create mode 100644 lk/include/lib/console.h create mode 100644 lk/include/lib/heap.h create mode 100644 lk/include/lib/ptable.h create mode 100644 lk/include/limits.h create mode 100644 lk/include/list.h create mode 100644 lk/include/malloc.h create mode 100644 lk/include/new.h create mode 100644 lk/include/platform.h create mode 100644 lk/include/platform/debug.h create mode 100644 lk/include/platform/interrupts.h create mode 100644 lk/include/platform/timer.h create mode 100644 lk/include/printf.h create mode 100644 lk/include/rand.h create mode 100644 lk/include/reg.h create mode 100644 lk/include/stdint.h create mode 100644 lk/include/stdio.h create mode 100644 lk/include/stdlib.h create mode 100644 lk/include/string.h create mode 100644 lk/include/sys/types.h create mode 100644 lk/include/target.h create mode 100644 lk/kernel/debug.c create mode 100644 lk/kernel/dpc.c create mode 100644 lk/kernel/event.c create mode 100644 lk/kernel/main.c create mode 100644 lk/kernel/mutex.c create mode 100644 lk/kernel/rules.mk create mode 100644 lk/kernel/thread.c create mode 100644 lk/kernel/timer.c create mode 100644 lk/lib/console/console.c create mode 100644 lk/lib/console/rules.mk create mode 100644 lk/lib/debug/debug.c create mode 100644 lk/lib/debug/rules.mk create mode 100644 lk/lib/heap/heap.c create mode 100644 lk/lib/heap/rules.mk create mode 100644 lk/lib/libc/atexit.c create mode 100644 lk/lib/libc/atoi.c create mode 100644 lk/lib/libc/ctype.c create mode 100644 lk/lib/libc/eabi.c create mode 100644 lk/lib/libc/malloc.c create mode 100644 lk/lib/libc/new.cpp create mode 100644 lk/lib/libc/printf.c create mode 100644 lk/lib/libc/pure_virtual.cpp create mode 100644 lk/lib/libc/rand.c create mode 100644 lk/lib/libc/rules.mk create mode 100644 lk/lib/libc/string/arch/arm/memcpy.S create mode 100644 lk/lib/libc/string/arch/arm/memset.S create mode 100644 lk/lib/libc/string/arch/arm/rules.mk create mode 100644 lk/lib/libc/string/bcopy.c create mode 100644 lk/lib/libc/string/bzero.c create mode 100644 lk/lib/libc/string/memchr.c create mode 100644 lk/lib/libc/string/memcmp.c create mode 100644 lk/lib/libc/string/memcpy.c create mode 100644 lk/lib/libc/string/memmove.c create mode 100644 lk/lib/libc/string/memscan.c create mode 100644 lk/lib/libc/string/memset.c create mode 100644 lk/lib/libc/string/rules.mk create mode 100644 lk/lib/libc/string/strcat.c create mode 100644 lk/lib/libc/string/strchr.c create mode 100644 lk/lib/libc/string/strcmp.c create mode 100644 lk/lib/libc/string/strcoll.c create mode 100644 lk/lib/libc/string/strcpy.c create mode 100644 lk/lib/libc/string/strdup.c create mode 100644 lk/lib/libc/string/strerror.c create mode 100644 lk/lib/libc/string/strlcat.c create mode 100644 lk/lib/libc/string/strlcpy.c create mode 100644 lk/lib/libc/string/strlen.c create mode 100644 lk/lib/libc/string/strncat.c create mode 100644 lk/lib/libc/string/strncmp.c create mode 100644 lk/lib/libc/string/strncpy.c create mode 100644 lk/lib/libc/string/strnicmp.c create mode 100644 lk/lib/libc/string/strnlen.c create mode 100644 lk/lib/libc/string/strpbrk.c create mode 100644 lk/lib/libc/string/strrchr.c create mode 100644 lk/lib/libc/string/strspn.c create mode 100644 lk/lib/libc/string/strstr.c create mode 100644 lk/lib/libc/string/strtok.c create mode 100644 lk/lib/libc/string/strxfrm.c create mode 100644 lk/lib/ptable/ptable.c create mode 100644 lk/lib/ptable/rules.mk create mode 100644 lk/make/build.mk create mode 100644 lk/make/macros.mk create mode 100644 lk/make/module.mk create mode 100644 lk/makefile create mode 100644 lk/platform/armemu/debug.c create mode 100644 lk/platform/armemu/include/platform/armemu.h create mode 100644 lk/platform/armemu/include/platform/armemu/memmap.h create mode 100644 lk/platform/armemu/interrupts.c create mode 100644 lk/platform/armemu/net.c create mode 100644 lk/platform/armemu/platform.c create mode 100644 lk/platform/armemu/platform_p.h create mode 100644 lk/platform/armemu/rules.mk create mode 100644 lk/platform/armemu/timer.c create mode 100644 lk/platform/at91sam7/README create mode 100644 lk/platform/at91sam7/at91sam7s.pins create mode 100644 lk/platform/at91sam7/at91sam7x.pins create mode 100644 lk/platform/at91sam7/debug.c create mode 100644 lk/platform/at91sam7/emac_dev.c create mode 100644 lk/platform/at91sam7/include/platform/at91sam7.h create mode 100644 lk/platform/at91sam7/init_clock.S create mode 100644 lk/platform/at91sam7/init_clock_48mhz.S create mode 100644 lk/platform/at91sam7/interrupts.c create mode 100644 lk/platform/at91sam7/mkboard.py create mode 100644 lk/platform/at91sam7/mux.c create mode 100644 lk/platform/at91sam7/platform.c create mode 100644 lk/platform/at91sam7/platform_early.S create mode 100644 lk/platform/at91sam7/rules.mk create mode 100644 lk/platform/at91sam7/timer.c create mode 100644 lk/platform/debug.c create mode 100644 lk/platform/init.c create mode 100644 lk/platform/integrator/debug.c create mode 100644 lk/platform/integrator/include/platform/integrator.h create mode 100644 lk/platform/integrator/interrupts.c create mode 100644 lk/platform/integrator/platform.c create mode 100644 lk/platform/integrator/platform_p.h create mode 100644 lk/platform/integrator/rules.mk create mode 100644 lk/platform/integrator/timer.c create mode 100644 lk/platform/msm7k/acpuclock.c create mode 100644 lk/platform/msm7k/gpio.c create mode 100644 lk/platform/msm7k/include/platform/iomap.h create mode 100644 lk/platform/msm7k/include/platform/irqs.h create mode 100644 lk/platform/msm7k/interrupts.c create mode 100644 lk/platform/msm7k/panel.c create mode 100644 lk/platform/msm7k/platform.c create mode 100644 lk/platform/msm7k/rules.mk create mode 100644 lk/platform/msm7x30/acpuclock.c create mode 100644 lk/platform/msm7x30/arch_init.S create mode 100644 lk/platform/msm7x30/gpio.c create mode 100644 lk/platform/msm7x30/gpio_hw.h create mode 100644 lk/platform/msm7x30/include/platform/iomap.h create mode 100644 lk/platform/msm7x30/include/platform/irqs.h create mode 100644 lk/platform/msm7x30/interrupts.c create mode 100644 lk/platform/msm7x30/panel.c create mode 100644 lk/platform/msm7x30/platform.c create mode 100644 lk/platform/msm7x30/rules.mk create mode 100644 lk/platform/msm8x60/acpuclock.c create mode 100644 lk/platform/msm8x60/gpio.c create mode 100644 lk/platform/msm8x60/include/platform/clock.h create mode 100644 lk/platform/msm8x60/include/platform/gpio_hw.h create mode 100644 lk/platform/msm8x60/include/platform/iomap.h create mode 100644 lk/platform/msm8x60/include/platform/irqs.h create mode 100644 lk/platform/msm8x60/include/platform/pmic.h create mode 100644 lk/platform/msm8x60/interrupts.c create mode 100644 lk/platform/msm8x60/mmc_init.c create mode 100644 lk/platform/msm8x60/panel.c create mode 100644 lk/platform/msm8x60/platform.c create mode 100644 lk/platform/msm8x60/pmic.c create mode 100644 lk/platform/msm8x60/rules.mk create mode 100644 lk/platform/msm_shared/debug.c create mode 100644 lk/platform/msm_shared/dmov.h create mode 100644 lk/platform/msm_shared/hsusb.c create mode 100644 lk/platform/msm_shared/hsusb.h create mode 100644 lk/platform/msm_shared/i2c_qup.c create mode 100644 lk/platform/msm_shared/include/i2c_qup.h create mode 100644 lk/platform/msm_shared/include/jtag.h create mode 100644 lk/platform/msm_shared/include/mddi.h create mode 100644 lk/platform/msm_shared/include/mipi_dsi.h create mode 100644 lk/platform/msm_shared/include/mmc.h create mode 100644 lk/platform/msm_shared/include/nand.h create mode 100644 lk/platform/msm_shared/include/splash.h create mode 100644 lk/platform/msm_shared/include/uart_dm.h create mode 100644 lk/platform/msm_shared/jtag.c create mode 100644 lk/platform/msm_shared/jtag_hook.S create mode 100644 lk/platform/msm_shared/lcdc.c create mode 100644 lk/platform/msm_shared/mddi.c create mode 100644 lk/platform/msm_shared/mddi_hw.h create mode 100644 lk/platform/msm_shared/mipi_dsi.c create mode 100644 lk/platform/msm_shared/mmc.c create mode 100644 lk/platform/msm_shared/nand.c create mode 100644 lk/platform/msm_shared/proc_comm.c create mode 100644 lk/platform/msm_shared/rules.mk create mode 100644 lk/platform/msm_shared/smem.c create mode 100644 lk/platform/msm_shared/smem.h create mode 100644 lk/platform/msm_shared/smem_ptable.c create mode 100644 lk/platform/msm_shared/timer.c create mode 100644 lk/platform/msm_shared/uart.c create mode 100644 lk/platform/msm_shared/uart_dm.c create mode 100644 lk/platform/omap3/cpu_early_init.S create mode 100644 lk/platform/omap3/debug.c create mode 100644 lk/platform/omap3/i2c.c create mode 100644 lk/platform/omap3/include/platform/omap3.h create mode 100644 lk/platform/omap3/interrupts.c create mode 100644 lk/platform/omap3/platform.c create mode 100644 lk/platform/omap3/platform_p.h create mode 100644 lk/platform/omap3/rules.mk create mode 100644 lk/platform/omap3/timer.c create mode 100644 lk/platform/omap3/uart.c create mode 100644 lk/platform/omap3/usbc.c create mode 100644 lk/platform/omap5912/debug.c create mode 100644 lk/platform/omap5912/include/platform/omap5912.h create mode 100644 lk/platform/omap5912/interrupts.c create mode 100644 lk/platform/omap5912/platform.c create mode 100644 lk/platform/omap5912/platform_p.h create mode 100644 lk/platform/omap5912/rules.mk create mode 100644 lk/platform/omap5912/timer.c create mode 100644 lk/platform/qsd8650a/acpuclock.c create mode 100644 lk/platform/qsd8650a/arch_init.S create mode 100644 lk/platform/qsd8650a/gpio.c create mode 100644 lk/platform/qsd8650a/gpio_hw.h create mode 100644 lk/platform/qsd8650a/include/platform/iomap.h create mode 100644 lk/platform/qsd8650a/include/platform/irqs.h create mode 100644 lk/platform/qsd8650a/interrupts.c create mode 100644 lk/platform/qsd8650a/platform.c create mode 100644 lk/platform/qsd8650a/rules.mk create mode 100644 lk/platform/qsd8k/acpuclock.c create mode 100644 lk/platform/qsd8k/arch_init.S create mode 100644 lk/platform/qsd8k/gpio.c create mode 100644 lk/platform/qsd8k/gpio_hw.h create mode 100644 lk/platform/qsd8k/include/platform/iomap.h create mode 100644 lk/platform/qsd8k/include/platform/irqs.h create mode 100644 lk/platform/qsd8k/interrupts.c create mode 100644 lk/platform/qsd8k/panel.c create mode 100644 lk/platform/qsd8k/platform.c create mode 100644 lk/platform/qsd8k/rules.mk create mode 100644 lk/platform/rules.mk create mode 100644 lk/project/aboot-surf7k.mk create mode 100644 lk/project/aboot-surf8k.mk create mode 100644 lk/project/armemu-test.mk create mode 100644 lk/project/beagle-test.mk create mode 100644 lk/project/htcleo.mk create mode 100644 lk/project/msm7625_ffa.mk create mode 100644 lk/project/msm7625_ffa_nandwrite.mk create mode 100644 lk/project/msm7625_surf.mk create mode 100644 lk/project/msm7625_surf_nandwrite.mk create mode 100644 lk/project/msm7627_7x_ffa.mk create mode 100644 lk/project/msm7627_7x_ffa_nandwrite.mk create mode 100644 lk/project/msm7627_7x_surf.mk create mode 100644 lk/project/msm7627_7x_surf_nandwrite.mk create mode 100644 lk/project/msm7627_ffa.mk create mode 100644 lk/project/msm7627_ffa_nandwrite.mk create mode 100644 lk/project/msm7627_surf.mk create mode 100644 lk/project/msm7627_surf_nandwrite.mk create mode 100644 lk/project/msm7630_1x.mk create mode 100644 lk/project/msm7630_1x_nandwrite.mk create mode 100644 lk/project/msm7630_fusion.mk create mode 100644 lk/project/msm7630_fusion_nandwrite.mk create mode 100644 lk/project/msm7630_surf.mk create mode 100644 lk/project/msm7630_surf_nandwrite.mk create mode 100644 lk/project/msm8655_surf.mk create mode 100644 lk/project/msm8655_surf_nandwrite.mk create mode 100644 lk/project/msm8660_csfb.mk create mode 100644 lk/project/msm8660_surf.mk create mode 100644 lk/project/osk5912-test.mk create mode 100644 lk/project/qemu-arm-test.mk create mode 100644 lk/project/qsd8250_ffa.mk create mode 100644 lk/project/qsd8250_ffa_nandwrite.mk create mode 100644 lk/project/qsd8250_surf.mk create mode 100644 lk/project/qsd8250_surf_nandwrite.mk create mode 100644 lk/project/qsd8650a_st1x.mk create mode 100644 lk/project/qsd8650a_st1x_nandwrite.mk create mode 100644 lk/project/sam7ex256-test.mk create mode 100644 lk/project/surf-test.mk create mode 100644 lk/scripts/attach.cmm create mode 100644 lk/scripts/buildall create mode 100644 lk/scripts/config_a11.cmm create mode 100644 lk/scripts/config_scorpion.cmm create mode 100644 lk/scripts/do-armemu-test create mode 100644 lk/scripts/do-beagle-test create mode 100644 lk/scripts/do-osk5912-test create mode 100644 lk/scripts/do-sam7ex256-test create mode 100644 lk/scripts/lk.cmm create mode 100644 lk/scripts/tagit create mode 100644 lk/target/armemu/rules.mk create mode 100644 lk/target/beagle/include/target/debugconfig.h create mode 100644 lk/target/beagle/rules.mk create mode 100644 lk/target/htcleo/atags.c create mode 100644 lk/target/htcleo/include/target/display.h create mode 100644 lk/target/htcleo/init.c create mode 100644 lk/target/htcleo/keypad.c create mode 100644 lk/target/htcleo/nand.c create mode 100644 lk/target/htcleo/nand.h create mode 100644 lk/target/htcleo/rules.mk create mode 100644 lk/target/htcleo/tools/makefile create mode 100644 lk/target/htcleo/tools/mkheader.c create mode 100644 lk/target/init.c create mode 100644 lk/target/msm7625_ffa/atags.c create mode 100644 lk/target/msm7625_ffa/include/target/display.h create mode 100644 lk/target/msm7625_ffa/init.c create mode 100644 lk/target/msm7625_ffa/keypad.c create mode 100644 lk/target/msm7625_ffa/rules.mk create mode 100644 lk/target/msm7625_ffa/tools/makefile create mode 100644 lk/target/msm7625_ffa/tools/mkheader.c create mode 100644 lk/target/msm7625_surf/atags.c create mode 100644 lk/target/msm7625_surf/include/target/display.h create mode 100644 lk/target/msm7625_surf/init.c create mode 100644 lk/target/msm7625_surf/keypad.c create mode 100644 lk/target/msm7625_surf/rules.mk create mode 100644 lk/target/msm7625_surf/tools/makefile create mode 100644 lk/target/msm7625_surf/tools/mkheader.c create mode 100644 lk/target/msm7627_ffa/atags.c create mode 100644 lk/target/msm7627_ffa/include/target/display.h create mode 100644 lk/target/msm7627_ffa/init.c create mode 100644 lk/target/msm7627_ffa/keypad.c create mode 100644 lk/target/msm7627_ffa/rules.mk create mode 100644 lk/target/msm7627_ffa/tools/makefile create mode 100644 lk/target/msm7627_ffa/tools/mkheader.c create mode 100644 lk/target/msm7627_surf/atags.c create mode 100644 lk/target/msm7627_surf/include/target/display.h create mode 100644 lk/target/msm7627_surf/init.c create mode 100644 lk/target/msm7627_surf/keypad.c create mode 100644 lk/target/msm7627_surf/rules.mk create mode 100644 lk/target/msm7627_surf/tools/makefile create mode 100644 lk/target/msm7627_surf/tools/mkheader.c create mode 100644 lk/target/msm7630_1x/atags.c create mode 100644 lk/target/msm7630_1x/include/target/display.h create mode 100644 lk/target/msm7630_1x/init.c create mode 100644 lk/target/msm7630_1x/keypad.c create mode 100644 lk/target/msm7630_1x/panel.c create mode 100644 lk/target/msm7630_1x/rules.mk create mode 100644 lk/target/msm7630_1x/tools/makefile create mode 100644 lk/target/msm7630_1x/tools/mkheader.c create mode 100644 lk/target/msm7630_surf/atags.c create mode 100644 lk/target/msm7630_surf/include/target/display.h create mode 100644 lk/target/msm7630_surf/init.c create mode 100644 lk/target/msm7630_surf/keypad.c create mode 100644 lk/target/msm7630_surf/rules.mk create mode 100644 lk/target/msm7630_surf/tools/makefile create mode 100644 lk/target/msm7630_surf/tools/mkheader.c create mode 100644 lk/target/msm8660_surf/atags.c create mode 100644 lk/target/msm8660_surf/include/target/display.h create mode 100644 lk/target/msm8660_surf/init.c create mode 100644 lk/target/msm8660_surf/keypad.c create mode 100644 lk/target/msm8660_surf/rules.mk create mode 100644 lk/target/msm8660_surf/tools/makefile create mode 100644 lk/target/msm8660_surf/tools/mkheader.c create mode 100644 lk/target/osk5912/init.c create mode 100644 lk/target/osk5912/rules.mk create mode 100644 lk/target/qemu-arm/rules.mk create mode 100644 lk/target/qsd8250_ffa/atags.c create mode 100644 lk/target/qsd8250_ffa/include/target/display.h create mode 100644 lk/target/qsd8250_ffa/init.c create mode 100644 lk/target/qsd8250_ffa/keypad.c create mode 100644 lk/target/qsd8250_ffa/rules.mk create mode 100644 lk/target/qsd8250_ffa/tools/makefile create mode 100644 lk/target/qsd8250_ffa/tools/mkheader.c create mode 100644 lk/target/qsd8250_surf/atags.c create mode 100644 lk/target/qsd8250_surf/include/target/display.h create mode 100644 lk/target/qsd8250_surf/init.c create mode 100644 lk/target/qsd8250_surf/keypad.c create mode 100644 lk/target/qsd8250_surf/rules.mk create mode 100644 lk/target/qsd8250_surf/tools/makefile create mode 100644 lk/target/qsd8250_surf/tools/mkheader.c create mode 100644 lk/target/qsd8650a_st1x/atags.c create mode 100644 lk/target/qsd8650a_st1x/include/target/display.h create mode 100644 lk/target/qsd8650a_st1x/init.c create mode 100644 lk/target/qsd8650a_st1x/keypad.c create mode 100644 lk/target/qsd8650a_st1x/rules.mk create mode 100644 lk/target/qsd8650a_st1x/tools/makefile create mode 100644 lk/target/qsd8650a_st1x/tools/mkheader.c create mode 100644 lk/target/rules.mk create mode 100644 lk/target/sam7ex256/README create mode 100644 lk/target/sam7ex256/include/platform/mux.def create mode 100644 lk/target/sam7ex256/include/platform/mux.h create mode 100644 lk/target/sam7ex256/mkmux.sh create mode 100644 lk/target/sam7ex256/rules.mk create mode 100644 lk/target/surf-msm7k/atags.c create mode 100644 lk/target/surf-msm7k/init.c create mode 100644 lk/target/surf-msm7k/keypad.c create mode 100644 lk/target/surf-msm7k/panel.c create mode 100644 lk/target/surf-msm7k/rules.mk create mode 100644 lk/target/surf-qsd8k/atags.c create mode 100644 lk/target/surf-qsd8k/init.c create mode 100644 lk/target/surf-qsd8k/keypad.c create mode 100644 lk/target/surf-qsd8k/rules.mk create mode 100644 nbfix.c create mode 100644 readme_boot.img.txt create mode 100644 tinboot/tinboot.S diff --git a/bin/NBMerge.exe b/bin/NBMerge.exe new file mode 100644 index 0000000000000000000000000000000000000000..c68108e5ff340830f2b2596e4e8f05bfb136e099 GIT binary patch literal 77824 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 O=vxo^)`Qcn2mcp&omkrd literal 0 HcmV?d00001 diff --git a/bin/osnbtool.exe b/bin/osnbtool.exe new file mode 100644 index 0000000000000000000000000000000000000000..39227d27ad59936554d2aa0b2dc2fb7809ebc44c GIT binary patch literal 110592 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Ƌ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 Cgf=Mv literal 0 HcmV?d00001 diff --git a/bin/template_os.nb.payload b/bin/template_os.nb.payload new file mode 100644 index 0000000000000000000000000000000000000000..43363b0b532bde571abd6d0a05e8f1007d71f150 GIT binary patch literal 524288 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 z1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la5CI}U z1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la5CI}U z1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la5CI}U z1c<+-2_gbSfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la z5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z}}y HOyK_jFJYc6 literal 0 HcmV?d00001 diff --git a/bin/yang.exe b/bin/yang.exe new file mode 100644 index 0000000000000000000000000000000000000000..66844e537583d34a287162a577ba0cde04a5d475 GIT binary patch literal 16384 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "recovery.h" +#include "bootimg.h" +#include "fastboot.h" + +#define EXPAND(NAME) #NAME +#define TARGET(NAME) EXPAND(NAME) +#define DEFAULT_CMDLINE "console=null"; + +#ifdef MEMBASE +#define EMMC_BOOT_IMG_HEADER_ADDR (0xFF000+(MEMBASE)) +#else +#define EMMC_BOOT_IMG_HEADER_ADDR 0xFF000 +#endif + +#define RECOVERY_MODE 0x77665502 +#define FASTBOOT_MODE 0x77665500 + +static const char *emmc_cmdline = " androidboot.emmc=true"; +static const char *battchg_pause = " androidboot.battchg_pause=true"; + +static struct udc_device surf_udc_device = { + .vendor_id = 0x18d1, + .product_id = 0x0D02, + .version_id = 0x0001, + .manufacturer = "Google", + .product = "Android", +}; + +struct atag_ptbl_entry +{ + char name[16]; + unsigned offset; + unsigned size; + unsigned flags; +}; + +void platform_uninit_timer(void); +unsigned* target_atag_mem(unsigned* ptr); +unsigned board_machtype(void); +unsigned check_reboot_mode(void); +void *target_get_scratch_address(void); +int target_is_emmc_boot(void); +void reboot_device(unsigned); +void target_battery_charging_enable(unsigned enable, unsigned disconnect); +unsigned int mmc_write (unsigned long long data_addr, + unsigned int data_len, unsigned int* in); +unsigned long long mmc_ptn_offset (unsigned char * name); +unsigned long long mmc_ptn_size (unsigned char * name); +void display_shutdown(void); + +static void ptentry_to_tag(unsigned **ptr, struct ptentry *ptn) +{ + struct atag_ptbl_entry atag_ptn; + + if (ptn->type == TYPE_MODEM_PARTITION) + return; + memcpy(atag_ptn.name, ptn->name, 16); + atag_ptn.name[15] = '\0'; + atag_ptn.offset = ptn->start; + atag_ptn.size = ptn->length; + atag_ptn.flags = ptn->flags; + memcpy(*ptr, &atag_ptn, sizeof(struct atag_ptbl_entry)); + *ptr += sizeof(struct atag_ptbl_entry) / sizeof(unsigned); +} + +void boot_linux(void *kernel, unsigned *tags, + const char *cmdline, unsigned machtype, + void *ramdisk, unsigned ramdisk_size) +{ + unsigned *ptr = tags; + unsigned pcount = 0; + void (*entry)(unsigned,unsigned,unsigned*) = kernel; + struct ptable *ptable; + int cmdline_len = 0; + int have_cmdline = 0; + int pause_at_bootup = 0; + + /* CORE */ + *ptr++ = 2; + *ptr++ = 0x54410001; + + if (ramdisk_size) { + *ptr++ = 4; + *ptr++ = 0x54420005; + *ptr++ = (unsigned)ramdisk; + *ptr++ = ramdisk_size; + } + + ptr = target_atag_mem(ptr); + + if (!target_is_emmc_boot()) { + /* Skip NAND partition ATAGS for eMMC boot */ + if ((ptable = flash_get_ptable()) && (ptable->count != 0)) { + int i; + for(i=0; i < ptable->count; i++) { + struct ptentry *ptn; + ptn = ptable_get(ptable, i); + if (ptn->type == TYPE_APPS_PARTITION) + pcount++; + } + *ptr++ = 2 + (pcount * (sizeof(struct atag_ptbl_entry) / + sizeof(unsigned))); + *ptr++ = 0x4d534d70; + for (i = 0; i < ptable->count; ++i) + ptentry_to_tag(&ptr, ptable_get(ptable, i)); + } + } + + if (cmdline && cmdline[0]) { + cmdline_len = strlen(cmdline); + have_cmdline = 1; + } + if (target_is_emmc_boot()) { + cmdline_len += strlen(emmc_cmdline); + } + if (target_pause_for_battery_charge()) { + pause_at_bootup = 1; + cmdline_len += strlen(battchg_pause); + } + if (cmdline_len > 0) { + const char *src; + char *dst; + unsigned n; + /* include terminating 0 and round up to a word multiple */ + n = (cmdline_len + 4) & (~3); + *ptr++ = (n / 4) + 2; + *ptr++ = 0x54410009; + dst = (char *)ptr; + if (have_cmdline) { + src = cmdline; + while ((*dst++ = *src++)); + } + if (target_is_emmc_boot()) { + src = emmc_cmdline; + if (have_cmdline) --dst; + have_cmdline = 1; + while ((*dst++ = *src++)); + } + if (pause_at_bootup) { + src = battchg_pause; + if (have_cmdline) --dst; + while ((*dst++ = *src++)); + } + ptr += (n / 4); + } + + /* END */ + *ptr++ = 0; + *ptr++ = 0; + + dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d)\n", + kernel, ramdisk, ramdisk_size); + if (cmdline) + dprintf(INFO, "cmdline: %s\n", cmdline); + + enter_critical_section(); + //cedesmith: this will hang + //platform_uninit_timer(); + arch_disable_cache(UCACHE); + arch_disable_mmu(); +#if DISPLAY_SPLASH_SCREEN + display_shutdown(); +#endif + + __asm__ volatile ( + "dsb \n" + "isb \n" + ); + + //cedesmith: cotulla's code so kernel will not crash. aux control register + __asm__ volatile ( + "MRC p15, 0, r0, c1, c0, 1 \n" + "BIC r0, r0, #0x40 \n" // (1<<6) Instruction cache reload on a parity error disabled + "BIC r0, r0, #0x200000 \n" // (1<<21) undocumented bit ? + "MCR p15, 0, r0, c1, c0, 1 \n" + ); + + /* + // flash on to see we get here + __asm__ volatile ( + "ldr r4, =0xa9000864 @ bank6_in (phys) \n" + "ldr r5, =0xa9000814 @ bank6_out (phys) \n" + "orr r6, r4, #0x200000 @ 22nd bit for flash \n" + "str r6, [r5, #0] @ store in out (enables bright for 500ms, limited by hardware) \n" + ); + */ + entry(0, machtype, tags); +} + +unsigned page_size = 0; +unsigned page_mask = 0; + +#define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y))) + +static unsigned char buf[4096]; //Equal to max-supported pagesize + +int boot_linux_from_mmc(void) +{ + struct boot_img_hdr *hdr = (void*) buf; + struct boot_img_hdr *uhdr; + unsigned offset = 0; + unsigned long long ptn = 0; + unsigned n = 0; + const char *cmdline; + + uhdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR; + if (!memcmp(uhdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { + dprintf(INFO, "Unified boot method!\n"); + hdr = uhdr; + goto unified_boot; + } + if(!boot_into_recovery) + { + ptn = mmc_ptn_offset("boot"); + if(ptn == 0) { + dprintf(CRITICAL, "ERROR: No boot partition found\n"); + return -1; + } + } + else + { + ptn = mmc_ptn_offset("recovery"); + if(ptn == 0) { + dprintf(CRITICAL, "ERROR: No recovery partition found\n"); + return -1; + } + } + + if (mmc_read(ptn + offset, (unsigned int *)buf, page_size)) { + dprintf(CRITICAL, "ERROR: Cannot read boot image header\n"); + return -1; + } + + if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { + dprintf(CRITICAL, "ERROR: Invaled boot image header\n"); + return -1; + } + + if (hdr->page_size && (hdr->page_size != page_size)) { + page_size = hdr->page_size; + page_mask = page_size - 1; + } + offset += page_size; + + n = ROUND_TO_PAGE(hdr->kernel_size, page_mask); + if (mmc_read(ptn + offset, (void *)hdr->kernel_addr, n)) { + dprintf(CRITICAL, "ERROR: Cannot read kernel image\n"); + return -1; + } + offset += n; + + n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask); + if (mmc_read(ptn + offset, (void *)hdr->ramdisk_addr, n)) { + dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n"); + return -1; + } + offset += n; + +unified_boot: + dprintf(INFO, "\nkernel @ %x (%d bytes)\n", hdr->kernel_addr, + hdr->kernel_size); + dprintf(INFO, "ramdisk @ %x (%d bytes)\n", hdr->ramdisk_addr, + hdr->ramdisk_size); + + if(hdr->cmdline[0]) { + cmdline = (char*) hdr->cmdline; + } else { + cmdline = DEFAULT_CMDLINE; + } + dprintf(INFO, "cmdline = '%s'\n", cmdline); + + dprintf(INFO, "\nBooting Linux\n"); + boot_linux((void *)hdr->kernel_addr, (void *)TAGS_ADDR, + (const char *)cmdline, board_machtype(), + (void *)hdr->ramdisk_addr, hdr->ramdisk_size); + + return 0; +} + +int boot_linux_from_flash(void) +{ + struct boot_img_hdr *hdr = (void*) buf; + unsigned n; + struct ptentry *ptn; + struct ptable *ptable; + unsigned offset = 0; + const char *cmdline; + + if (target_is_emmc_boot()) { + hdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR; + if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { + dprintf(CRITICAL, "ERROR: Invalid boot image header\n"); + return -1; + } + goto continue_boot; + } + + ptable = flash_get_ptable(); + if (ptable == NULL) { + dprintf(CRITICAL, "ERROR: Partition table not found\n"); + return -1; + } + + if(!boot_into_recovery) + { + ptn = ptable_find(ptable, "boot"); + if (ptn == NULL) { + dprintf(CRITICAL, "ERROR: No boot partition found\n"); + return -1; + } + } + else + { + ptn = ptable_find(ptable, "recovery"); + if (ptn == NULL) { + dprintf(CRITICAL, "ERROR: No recovery partition found\n"); + return -1; + } + } + + if (flash_read(ptn, offset, buf, page_size)) { + dprintf(CRITICAL, "ERROR: Cannot read boot image header\n"); + return -1; + } + offset += page_size; + + if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { + dprintf(CRITICAL, "ERROR: Invaled boot image heador\n"); + return -1; + } + + if (hdr->page_size != page_size) { + dprintf(CRITICAL, "ERROR: Invaled boot image pagesize. Device pagesize: %d, Image pagesize: %d\n",page_size,hdr->page_size); + return -1; + } + + n = ROUND_TO_PAGE(hdr->kernel_size, page_mask); + if (flash_read(ptn, offset, (void *)hdr->kernel_addr, n)) { + dprintf(CRITICAL, "ERROR: Cannot read kernel image\n"); + return -1; + } + offset += n; + + n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask); + if (flash_read(ptn, offset, (void *)hdr->ramdisk_addr, n)) { + dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n"); + return -1; + } + offset += n; + +continue_boot: + dprintf(INFO, "\nkernel @ %x (%d bytes)\n", hdr->kernel_addr, + hdr->kernel_size); + dprintf(INFO, "ramdisk @ %x (%d bytes)\n", hdr->ramdisk_addr, + hdr->ramdisk_size); + + if(hdr->cmdline[0]) { + cmdline = (char*) hdr->cmdline; + } else { + cmdline = DEFAULT_CMDLINE; + } + dprintf(INFO, "cmdline = '%s'\n", cmdline); + + /* TODO: create/pass atags to kernel */ + + dprintf(INFO, "\nBooting Linux\n"); + boot_linux((void *)hdr->kernel_addr, (void *)TAGS_ADDR, + (const char *)cmdline, board_machtype(), + (void *)hdr->ramdisk_addr, hdr->ramdisk_size); + + return 0; +} + +void cmd_boot(const char *arg, void *data, unsigned sz) +{ + unsigned kernel_actual; + unsigned ramdisk_actual; + static struct boot_img_hdr hdr; + char *ptr = ((char*) data); + + if (sz < sizeof(hdr)) { + fastboot_fail("invalid bootimage header"); + return; + } + + memcpy(&hdr, data, sizeof(hdr)); + + /* ensure commandline is terminated */ + hdr.cmdline[BOOT_ARGS_SIZE-1] = 0; + + if(target_is_emmc_boot() && hdr.page_size) { + page_size = hdr.page_size; + page_mask = page_size - 1; + } + + kernel_actual = ROUND_TO_PAGE(hdr.kernel_size, page_mask); + ramdisk_actual = ROUND_TO_PAGE(hdr.ramdisk_size, page_mask); + + //cedesmith: this will prevent lk booting lk.bin + //if (page_size + kernel_actual + ramdisk_actual < sz) { + // fastboot_fail("incomplete bootimage"); + // return; + //} + + memmove((void*) KERNEL_ADDR, ptr + page_size, hdr.kernel_size); + memmove((void*) RAMDISK_ADDR, ptr + page_size + kernel_actual, hdr.ramdisk_size); + + fastboot_okay(""); + target_battery_charging_enable(0, 1); + udc_stop(); + + boot_linux((void*) KERNEL_ADDR, (void*) TAGS_ADDR, + (const char*) hdr.cmdline, board_machtype(), + (void*) RAMDISK_ADDR, hdr.ramdisk_size); +} + +void cmd_erase(const char *arg, void *data, unsigned sz) +{ + struct ptentry *ptn; + struct ptable *ptable; + + ptable = flash_get_ptable(); + if (ptable == NULL) { + fastboot_fail("partition table doesn't exist"); + return; + } + + ptn = ptable_find(ptable, arg); + if (ptn == NULL) { + fastboot_fail("unknown partition name"); + return; + } + + if (flash_erase(ptn)) { + fastboot_fail("failed to erase partition"); + return; + } + fastboot_okay(""); +} + + +void cmd_erase_mmc(const char *arg, void *data, unsigned sz) +{ + unsigned long long ptn = 0; + unsigned int out[512] = {0}; + + ptn = mmc_ptn_offset(arg); + if(ptn == 0) { + fastboot_fail("partition table doesn't exist"); + return; + } + + + /* Simple inefficient version of erase. Just writing + 0 in first block */ + if (mmc_write(ptn , 512, (unsigned int *)out)) { + fastboot_fail("failed to erase partition"); + return; + } + fastboot_okay(""); +} + + +void cmd_flash_mmc(const char *arg, void *data, unsigned sz) +{ + unsigned long long ptn = 0; + unsigned long long size = 0; + + ptn = mmc_ptn_offset(arg); + if(ptn == 0) { + fastboot_fail("partition table doesn't exist"); + return; + } + + if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) { + if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { + fastboot_fail("image is not a boot image"); + return; + } + } + + size = mmc_ptn_size(arg); + if (ROUND_TO_PAGE(sz,511) > size) { + fastboot_fail("size too large"); + return; + } + + if (mmc_write(ptn , sz, (unsigned int *)data)) { + fastboot_fail("flash write failure"); + return; + } + fastboot_okay(""); + return; +} + +void cmd_flash(const char *arg, void *data, unsigned sz) +{ + struct ptentry *ptn; + struct ptable *ptable; + unsigned extra = 0; + + ptable = flash_get_ptable(); + if (ptable == NULL) { + fastboot_fail("partition table doesn't exist"); + return; + } + + ptn = ptable_find(ptable, arg); + if (ptn == NULL) { + fastboot_fail("unknown partition name"); + return; + } + + if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) { + if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { + fastboot_fail("image is not a boot image"); + return; + } + } + + if (!strcmp(ptn->name, "system") || !strcmp(ptn->name, "userdata") + || !strcmp(ptn->name, "persist")) + extra = ((page_size >> 9) * 16); + else + sz = ROUND_TO_PAGE(sz, page_mask); + + dprintf(INFO, "writing %d bytes to '%s'\n", sz, ptn->name); + if (flash_write(ptn, extra, data, sz)) { + fastboot_fail("flash write failure"); + return; + } + dprintf(INFO, "partition '%s' updated\n", ptn->name); + fastboot_okay(""); +} + +void cmd_continue(const char *arg, void *data, unsigned sz) +{ + fastboot_okay(""); + target_battery_charging_enable(0, 1); + udc_stop(); + if (target_is_emmc_boot()) + { + boot_linux_from_mmc(); + } + else + { + boot_linux_from_flash(); + } +} + +void cmd_reboot(const char *arg, void *data, unsigned sz) +{ + dprintf(INFO, "rebooting the device\n"); + fastboot_okay(""); + reboot_device(0); +} + +void cmd_reboot_bootloader(const char *arg, void *data, unsigned sz) +{ + dprintf(INFO, "rebooting the device\n"); + fastboot_okay(""); + reboot_device(FASTBOOT_MODE); +} + +void splash_screen () +{ + struct ptentry *ptn; + struct ptable *ptable; + struct fbcon_config *fb_display = NULL; + + if (!target_is_emmc_boot()) + { + ptable = flash_get_ptable(); + if (ptable == NULL) { + dprintf(CRITICAL, "ERROR: Partition table not found\n"); + return -1; + } + + ptn = ptable_find(ptable, "splash"); + if (ptn == NULL) { + dprintf(CRITICAL, "ERROR: No splash partition found\n"); + } else { + fb_display = fbcon_display(); + if (fb_display) { + if (flash_read(ptn, 0, fb_display->base, + (fb_display->width * fb_display->height * fb_display->bpp/8))) { + fbcon_clear(); + dprintf(CRITICAL, "ERROR: Cannot read splash image\n"); + } + } + } + } +} + +void aboot_init(const struct app_descriptor *app) +{ + unsigned reboot_mode = 0; + unsigned disp_init = 0; + unsigned usb_init = 0; + + /* Setup page size information for nand/emmc reads */ + if (target_is_emmc_boot()) + { + page_size = 2048; + page_mask = page_size - 1; + } + else + { + page_size = flash_page_size(); + page_mask = page_size - 1; + } + + /* Display splash screen if enabled */ + #if DISPLAY_SPLASH_SCREEN + display_init(); + dprintf(INFO, "Diplay initialized\n"); + disp_init = 1; + diplay_image_on_screen(); + #endif + + /* Check if we should do something other than booting up */ + if (keys_get_state(KEY_HOME) != 0) + boot_into_recovery = 1; + if (keys_get_state(KEY_BACK) != 0) + goto fastboot; + if (keys_get_state(KEY_CLEAR) != 0) + goto fastboot; + + #if NO_KEYPAD_DRIVER + /* With no keypad implementation, check the status of USB connection. */ + /* If USB is connected then go into fastboot mode. */ + usb_init = 1; + udc_init(&surf_udc_device); + if (usb_cable_status()) + goto fastboot; + #endif + + reboot_mode = check_reboot_mode(); + if (reboot_mode == RECOVERY_MODE) { + boot_into_recovery = 1; + } else if(reboot_mode == FASTBOOT_MODE) { + goto fastboot; + } + + if (target_is_emmc_boot()) + { + boot_linux_from_mmc(); + } + else + { + recovery_init(); + boot_linux_from_flash(); + } + dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting " + "to fastboot mode.\n"); + +fastboot: + + if(!usb_init) + udc_init(&surf_udc_device); + + fastboot_register("boot", cmd_boot); + + if (target_is_emmc_boot()) + { + fastboot_register("flash:", cmd_flash_mmc); + fastboot_register("erase:", cmd_erase_mmc); + } + else + { + fastboot_register("flash:", cmd_flash); + fastboot_register("erase:", cmd_erase); + } + + fastboot_register("continue", cmd_continue); + fastboot_register("reboot", cmd_reboot); + fastboot_register("reboot-bootloader", cmd_reboot_bootloader); + fastboot_publish("product", TARGET(BOARD)); + fastboot_publish("kernel", "lk"); + + //fastboot_init(target_get_scratch_address(), 120 * 1024 * 1024); + fastboot_init(target_get_scratch_address(), MEMBASE - SCRATCH_ADDR - 0x00100000); + udc_start(); + target_battery_charging_enable(1, 0); +} + +APP_START(aboot) + .init = aboot_init, +APP_END + diff --git a/lk/app/aboot/bootimg.h b/lk/app/aboot/bootimg.h new file mode 100644 index 0000000..44fde92 --- /dev/null +++ b/lk/app/aboot/bootimg.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2008 The Android Open Source 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: + * * 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. + * + * 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 _BOOT_IMAGE_H_ +#define _BOOT_IMAGE_H_ + +typedef struct boot_img_hdr boot_img_hdr; + +#define BOOT_MAGIC "ANDROID!" +#define BOOT_MAGIC_SIZE 8 +#define BOOT_NAME_SIZE 16 +#define BOOT_ARGS_SIZE 512 + +struct boot_img_hdr +{ + unsigned char magic[BOOT_MAGIC_SIZE]; + + unsigned kernel_size; /* size in bytes */ + unsigned kernel_addr; /* physical load addr */ + + unsigned ramdisk_size; /* size in bytes */ + unsigned ramdisk_addr; /* physical load addr */ + + unsigned second_size; /* size in bytes */ + unsigned second_addr; /* physical load addr */ + + unsigned tags_addr; /* physical addr for kernel tags */ + unsigned page_size; /* flash page size we assume */ + unsigned unused[2]; /* future expansion: should be 0 */ + + unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */ + + unsigned char cmdline[BOOT_ARGS_SIZE]; + + unsigned id[8]; /* timestamp / checksum / sha1 / etc */ +}; + +/* +** +-----------------+ +** | boot header | 1 page +** +-----------------+ +** | kernel | n pages +** +-----------------+ +** | ramdisk | m pages +** +-----------------+ +** | second stage | o pages +** +-----------------+ +** +** n = (kernel_size + page_size - 1) / page_size +** m = (ramdisk_size + page_size - 1) / page_size +** o = (second_size + page_size - 1) / page_size +** +** 0. all entities are page_size aligned in flash +** 1. kernel and ramdisk are required (size != 0) +** 2. second is optional (second_size == 0 -> no second) +** 3. load each element (kernel, ramdisk, second) at +** the specified physical address (kernel_addr, etc) +** 4. prepare tags at tag_addr. kernel_args[] is +** appended to the kernel commandline in the tags. +** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr +** 6. if second_size != 0: jump to second_addr +** else: jump to kernel_addr +*/ + +boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, + void *ramdisk, unsigned ramdisk_size, + void *second, unsigned second_size, + unsigned page_size, + unsigned *bootimg_size); + +void bootimg_set_cmdline(boot_img_hdr *hdr, const char *cmdline); +#endif diff --git a/lk/app/aboot/fastboot.c b/lk/app/aboot/fastboot.c new file mode 100644 index 0000000..6752dde --- /dev/null +++ b/lk/app/aboot/fastboot.c @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2009, Google 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +void boot_linux(void *bootimg, unsigned sz); + +/* todo: give lk strtoul and nuke this */ +static unsigned hex2unsigned(const char *x) +{ + unsigned n = 0; + + while(*x) { + switch(*x) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = (n << 4) | (*x - '0'); + break; + case 'a': case 'b': case 'c': + case 'd': case 'e': case 'f': + n = (n << 4) | (*x - 'a' + 10); + break; + case 'A': case 'B': case 'C': + case 'D': case 'E': case 'F': + n = (n << 4) | (*x - 'A' + 10); + break; + default: + return n; + } + x++; + } + + return n; +} + +struct fastboot_cmd { + struct fastboot_cmd *next; + const char *prefix; + unsigned prefix_len; + void (*handle)(const char *arg, void *data, unsigned sz); +}; + +struct fastboot_var { + struct fastboot_var *next; + const char *name; + const char *value; +}; + +static struct fastboot_cmd *cmdlist; + +void fastboot_register(const char *prefix, + void (*handle)(const char *arg, void *data, unsigned sz)) +{ + struct fastboot_cmd *cmd; + cmd = malloc(sizeof(*cmd)); + if (cmd) { + cmd->prefix = prefix; + cmd->prefix_len = strlen(prefix); + cmd->handle = handle; + cmd->next = cmdlist; + cmdlist = cmd; + } +} + +static struct fastboot_var *varlist; + +void fastboot_publish(const char *name, const char *value) +{ + struct fastboot_var *var; + var = malloc(sizeof(*var)); + if (var) { + var->name = name; + var->value = value; + var->next = varlist; + varlist = var; + } +} + + +static event_t usb_online; +static event_t txn_done; +static unsigned char buffer[4096]; +static struct udc_endpoint *in, *out; +static struct udc_request *req; +int txn_status; + +static void *download_base; +static unsigned download_max; +static unsigned download_size; + +#define STATE_OFFLINE 0 +#define STATE_COMMAND 1 +#define STATE_COMPLETE 2 +#define STATE_ERROR 3 + +static unsigned fastboot_state = STATE_OFFLINE; + +static void req_complete(struct udc_request *req, unsigned actual, int status) +{ + txn_status = status; + req->length = actual; + event_signal(&txn_done, 0); +} + +static int usb_read(void *_buf, unsigned len) +{ + int r; + unsigned xfer; + unsigned char *buf = _buf; + int count = 0; + + if (fastboot_state == STATE_ERROR) + goto oops; + + while (len > 0) { + xfer = (len > 4096) ? 4096 : len; + req->buf = buf; + req->length = xfer; + req->complete = req_complete; + r = udc_request_queue(out, req); + if (r < 0) { + dprintf(INFO, "usb_read() queue failed\n"); + goto oops; + } + event_wait(&txn_done); + + if (txn_status < 0) { + dprintf(INFO, "usb_read() transaction failed\n"); + goto oops; + } + + count += req->length; + buf += req->length; + len -= req->length; + + /* short transfer? */ + if (req->length != xfer) break; + } + + return count; + +oops: + fastboot_state = STATE_ERROR; + return -1; +} + +static int usb_write(void *buf, unsigned len) +{ + int r; + + if (fastboot_state == STATE_ERROR) + goto oops; + + req->buf = buf; + req->length = len; + req->complete = req_complete; + r = udc_request_queue(in, req); + if (r < 0) { + dprintf(INFO, "usb_write() queue failed\n"); + goto oops; + } + event_wait(&txn_done); + if (txn_status < 0) { + dprintf(INFO, "usb_write() transaction failed\n"); + goto oops; + } + return req->length; + +oops: + fastboot_state = STATE_ERROR; + return -1; +} + +void fastboot_ack(const char *code, const char *reason) +{ + char response[64]; + + if (fastboot_state != STATE_COMMAND) + return; + + if (reason == 0) + reason = ""; + + snprintf(response, 64, "%s%s", code, reason); + fastboot_state = STATE_COMPLETE; + + usb_write(response, strlen(response)); + +} + +void fastboot_fail(const char *reason) +{ + fastboot_ack("FAIL", reason); +} + +void fastboot_okay(const char *info) +{ + fastboot_ack("OKAY", info); +} + +static void cmd_getvar(const char *arg, void *data, unsigned sz) +{ + struct fastboot_var *var; + + for (var = varlist; var; var = var->next) { + if (!strcmp(var->name, arg)) { + fastboot_okay(var->value); + return; + } + } + fastboot_okay(""); +} + +static void cmd_download(const char *arg, void *data, unsigned sz) +{ + char response[64]; + unsigned len = hex2unsigned(arg); + int r; + + download_size = 0; + if (len > download_max) { + fastboot_fail("data too large"); + return; + } + + sprintf(response,"DATA%08x", len); + if (usb_write(response, strlen(response)) < 0) + return; + + r = usb_read(download_base, len); + if ((r < 0) || (r != len)) { + fastboot_state = STATE_ERROR; + return; + } + download_size = len; + fastboot_okay(""); +} + +static void fastboot_command_loop(void) +{ + struct fastboot_cmd *cmd; + int r; + dprintf(INFO,"fastboot: processing commands\n"); + +again: + while (fastboot_state != STATE_ERROR) { + r = usb_read(buffer, 64); + if (r < 0) break; + buffer[r] = 0; + dprintf(INFO,"fastboot: %s\n", buffer); + + for (cmd = cmdlist; cmd; cmd = cmd->next) { + if (memcmp(buffer, cmd->prefix, cmd->prefix_len)) + continue; + fastboot_state = STATE_COMMAND; + cmd->handle((const char*) buffer + cmd->prefix_len, + (void*) download_base, download_size); + if (fastboot_state == STATE_COMMAND) + fastboot_fail("unknown reason"); + goto again; + } + + fastboot_fail("unknown command"); + + } + fastboot_state = STATE_OFFLINE; + dprintf(INFO,"fastboot: oops!\n"); +} + +static int fastboot_handler(void *arg) +{ + for (;;) { + event_wait(&usb_online); + fastboot_command_loop(); + } + return 0; +} + +static void fastboot_notify(struct udc_gadget *gadget, unsigned event) +{ + if (event == UDC_EVENT_ONLINE) { + event_signal(&usb_online, 0); + } +} + +static struct udc_endpoint *fastboot_endpoints[2]; + +static struct udc_gadget fastboot_gadget = { + .notify = fastboot_notify, + .ifc_class = 0xff, + .ifc_subclass = 0x42, + .ifc_protocol = 0x03, + .ifc_endpoints = 2, + .ifc_string = "fastboot", + .ept = fastboot_endpoints, +}; + +int fastboot_init(void *base, unsigned size) +{ + thread_t *thr; + dprintf(INFO, "fastboot_init()\n"); + + download_base = base; + download_max = size; + + event_init(&usb_online, 0, EVENT_FLAG_AUTOUNSIGNAL); + event_init(&txn_done, 0, EVENT_FLAG_AUTOUNSIGNAL); + + in = udc_endpoint_alloc(UDC_TYPE_BULK_IN, 512); + if (!in) + goto fail_alloc_in; + out = udc_endpoint_alloc(UDC_TYPE_BULK_OUT, 512); + if (!out) + goto fail_alloc_out; + + fastboot_endpoints[0] = in; + fastboot_endpoints[1] = out; + + req = udc_request_alloc(); + if (!req) + goto fail_alloc_req; + + if (udc_register_gadget(&fastboot_gadget)) + goto fail_udc_register; + + fastboot_register("getvar:", cmd_getvar); + fastboot_register("download:", cmd_download); + fastboot_publish("version", "0.5"); + + thr = thread_create("fastboot", fastboot_handler, 0, DEFAULT_PRIORITY, 4096); + thread_resume(thr); + return 0; + +fail_udc_register: + udc_request_free(req); +fail_alloc_req: + udc_endpoint_free(out); +fail_alloc_out: + udc_endpoint_free(in); +fail_alloc_in: + return -1; +} diff --git a/lk/app/aboot/fastboot.h b/lk/app/aboot/fastboot.h new file mode 100644 index 0000000..42d8f8a --- /dev/null +++ b/lk/app/aboot/fastboot.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2009, Google 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. + * + * 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 __APP_FASTBOOT_H +#define __APP_FASTBOOT_H + +int fastboot_init(void *xfer_buffer, unsigned max); + +/* register a command handler + * - command handlers will be called if their prefix matches + * - they are expected to call fastboot_okay() or fastboot_fail() + * to indicate success/failure before returning + */ +void fastboot_register(const char *prefix, + void (*handle)(const char *arg, void *data, unsigned size)); + +/* publish a variable readable by the built-in getvar command */ +void fastboot_publish(const char *name, const char *value); + +/* only callable from within a command handler */ +void fastboot_okay(const char *result); +void fastboot_fail(const char *reason); + + +#endif diff --git a/lk/app/aboot/recovery.c b/lk/app/aboot/recovery.c new file mode 100644 index 0000000..228fa86 --- /dev/null +++ b/lk/app/aboot/recovery.c @@ -0,0 +1,277 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "recovery.h" +#include "bootimg.h" + +static const int MISC_PAGES = 3; // number of pages to save +static const int MISC_COMMAND_PAGE = 1; // bootloader command is this page +static char buf[4096]; +unsigned boot_into_recovery = 0; + +void reboot_device(unsigned); + +int get_recovery_message(struct recovery_message *out) +{ + struct ptentry *ptn; + struct ptable *ptable; + unsigned offset = 0; + unsigned pagesize = flash_page_size(); + + ptable = flash_get_ptable(); + + if (ptable == NULL) { + dprintf(CRITICAL, "ERROR: Partition table not found\n"); + return -1; + } + ptn = ptable_find(ptable, "misc"); + + if (ptn == NULL) { + dprintf(CRITICAL, "ERROR: No misc partition found\n"); + return -1; + } + + offset += (pagesize * MISC_COMMAND_PAGE); + dprintf(CRITICAL, "flash_read misc partition \n"); + if (flash_read(ptn, offset, buf, pagesize)) { + dprintf(CRITICAL, "ERROR: Cannot read recovery_header\n"); + return -1; + } + dprintf(CRITICAL, "flash_read misc partition done\n"); + memcpy(out, buf, sizeof(*out)); + return 0; +} + +int set_recovery_message(const struct recovery_message *in) +{ + struct ptentry *ptn; + struct ptable *ptable; + unsigned offset = 0; + unsigned pagesize = flash_page_size(); + unsigned n = 0; + + ptable = flash_get_ptable(); + + if (ptable == NULL) { + dprintf(CRITICAL, "ERROR: Partition table not found\n"); + return -1; + } + ptn = ptable_find(ptable, "misc"); + + if (ptn == NULL) { + dprintf(CRITICAL, "ERROR: No misc partition found\n"); + return -1; + } + + n = pagesize * (MISC_COMMAND_PAGE + 1); + + if (flash_read(ptn, offset, SCRATCH_ADDR, n)) { + dprintf(CRITICAL, "ERROR: Cannot read recovery_header\n"); + return -1; + } + + offset += (pagesize * MISC_COMMAND_PAGE); + offset += SCRATCH_ADDR; + memcpy(offset, in, sizeof(*in)); + if (flash_write(ptn, 0, (void *)SCRATCH_ADDR, n)) { + dprintf(CRITICAL, "ERROR: flash write fail!\n"); + return -1; + } +} + +int read_update_header_for_bootloader(struct update_header *header) +{ + struct ptentry *ptn; + struct ptable *ptable; + unsigned offset = 0; + unsigned pagesize = flash_page_size(); + + ptable = flash_get_ptable(); + if (ptable == NULL) { + dprintf(CRITICAL, "ERROR: Partition table not found\n"); + return -1; + } + ptn = ptable_find(ptable, "cache"); + + if (ptn == NULL) { + dprintf(CRITICAL, "ERROR: No cache partition found\n"); + return -1; + } + if (flash_read(ptn, offset, buf, pagesize)) { + dprintf(CRITICAL, "ERROR: Cannot read recovery_header\n"); + return -1; + } + memcpy(header, buf, sizeof(*header)); + + if(strncmp(header->MAGIC, UPDATE_MAGIC, UPDATE_MAGIC_SIZE)) + { + return -1; + } + return 0; +} + +int update_firmware_image (struct update_header *header, char *name) +{ + struct ptentry *ptn; + struct ptable *ptable; + unsigned offset = 0; + unsigned pagesize = flash_page_size(); + unsigned pagemask = pagesize -1; + unsigned n = 0; + + ptable = flash_get_ptable(); + if (ptable == NULL) { + dprintf(CRITICAL, "ERROR: Partition table not found\n"); + return -1; + } + + ptn = ptable_find(ptable, "cache"); + if (ptn == NULL) { + dprintf(CRITICAL, "ERROR: No cache partition found\n"); + return -1; + } + + offset += header->image_offset; + n = (header->image_length + pagemask) & (~pagemask); + + if (flash_read(ptn, offset, SCRATCH_ADDR, n)) { + dprintf(CRITICAL, "ERROR: Cannot read radio image\n"); + return -1; + } + + ptn = ptable_find(ptable, name); + if (ptn == NULL) { + dprintf(CRITICAL, "ERROR: No %s partition found\n", name); + return -1; + } + + if (flash_write(ptn, 0, SCRATCH_ADDR, n)) { + dprintf(CRITICAL, "ERROR: flash write fail!\n"); + return -1; + } + + dprintf(INFO, "Partition writen successfully!"); + return 0; +} + +/* Bootloader / Recovery Flow + * + * On every boot, the bootloader will read the recovery_message + * from flash and check the command field. The bootloader should + * deal with the command field not having a 0 terminator correctly + * (so as to not crash if the block is invalid or corrupt). + * + * The bootloader will have to publish the partition that contains + * the recovery_message to the linux kernel so it can update it. + * + * if command == "boot-recovery" -> boot recovery.img + * else if command == "update-radio" -> update radio image (below) + * else -> boot boot.img (normal boot) + * + * Radio Update Flow + * 1. the bootloader will attempt to load and validate the header + * 2. if the header is invalid, status="invalid-update", goto #8 + * 3. display the busy image on-screen + * 4. if the update image is invalid, status="invalid-radio-image", goto #8 + * 5. attempt to update the firmware (depending on the command) + * 6. if successful, status="okay", goto #8 + * 7. if failed, and the old image can still boot, status="failed-update" + * 8. write the recovery_message, leaving the recovery field + * unchanged, updating status, and setting command to + * "boot-recovery" + * 9. reboot + * + * The bootloader will not modify or erase the cache partition. + * It is recovery's responsibility to clean up the mess afterwards. + */ + +int recovery_init (void) +{ + struct recovery_message msg; + struct update_header header; + char partition_name[32]; + unsigned valid_command = 0; + + // get recovery message + if(get_recovery_message(&msg)) + return -1; + if (msg.command[0] != 0 && msg.command[0] != 255) { + dprintf("Recovery command: %.*s\n", sizeof(msg.command), msg.command); + } + msg.command[sizeof(msg.command)-1] = '\0'; //Ensure termination + + if (!strcmp("boot-recovery",msg.command)) { + valid_command = 1; + strcpy(msg.command, ""); // to safe against multiple reboot into recovery + strcpy(msg.status, "OKAY"); + set_recovery_message(&msg); // send recovery message + boot_into_recovery = 1; // Boot in recovery mode + return 0; + } + + if (!strcmp("update-radio",msg.command)) { + valid_command = 1; + strcpy(partition_name, "FOTA"); + } + + //Todo: Add support for bootloader update too. + + if(!valid_command) { + //We need not to do anything + return 0; // Boot in normal mode + } + + if (read_update_header_for_bootloader(&header)) { + strcpy(msg.status, "invalid-update"); + goto SEND_RECOVERY_MSG; + } + + if (update_firmware_image (&header, partition_name)) { + strcpy(msg.status, "failed-update"); + goto SEND_RECOVERY_MSG; + } + strcpy(msg.status, "OKAY"); + +SEND_RECOVERY_MSG: + strcpy(msg.command, "boot-recovery"); + set_recovery_message(&msg); // send recovery message + boot_into_recovery = 1; // Boot in recovery mode + reboot_device(0); + return 0; +} diff --git a/lk/app/aboot/recovery.h b/lk/app/aboot/recovery.h new file mode 100644 index 0000000..f76358f --- /dev/null +++ b/lk/app/aboot/recovery.h @@ -0,0 +1,77 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _BOOTLOADER_RECOVERY_H +#define _BOOTLOADER_RECOVERY_H + +#define UPDATE_MAGIC "MSM-RADIO-UPDATE" +#define UPDATE_MAGIC_SIZE 16 +#define UPDATE_VERSION 0x00010000 + + +/* Recovery Message */ +struct recovery_message { + char command[32]; + char status[32]; + char recovery[1024]; +}; + + +struct update_header { + unsigned char MAGIC[UPDATE_MAGIC_SIZE]; + + unsigned version; + unsigned size; + + unsigned image_offset; + unsigned image_length; + + unsigned bitmap_width; + unsigned bitmap_height; + unsigned bitmap_bpp; + + unsigned busy_bitmap_offset; + unsigned busy_bitmap_length; + + unsigned fail_bitmap_offset; + unsigned fail_bitmap_length; +}; + + + +int get_recovery_message(struct recovery_message *out); +int set_recovery_message(const struct recovery_message *in); + +int read_update_header_for_bootloader(struct update_header *header); +int update_firmware_image (struct update_header *header, char *name); + +int recovery_init (void); + +extern unsigned boot_into_recovery; + +#endif diff --git a/lk/app/aboot/rules.mk b/lk/app/aboot/rules.mk new file mode 100644 index 0000000..c23784e --- /dev/null +++ b/lk/app/aboot/rules.mk @@ -0,0 +1,7 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/aboot.o \ + $(LOCAL_DIR)/fastboot.o \ + $(LOCAL_DIR)/recovery.o + diff --git a/lk/app/app.c b/lk/app/app.c new file mode 100644 index 0000000..2aad5f4 --- /dev/null +++ b/lk/app/app.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009 Travis Geiselbrecht + * + * 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 + +extern const struct app_descriptor __apps_start; +extern const struct app_descriptor __apps_end; + +static void start_app(const struct app_descriptor *app); + +/* one time setup */ +void apps_init(void) +{ + const struct app_descriptor *app; + + /* call all the init routines */ + for (app = &__apps_start; app != &__apps_end; app++) { + if (app->init) + app->init(app); + } + + /* start any that want to start on boot */ + for (app = &__apps_start; app != &__apps_end; app++) { + if (app->entry && (app->flags & APP_FLAG_DONT_START_ON_BOOT) == 0) { + start_app(app); + } + } +} + +static int app_thread_entry(void *arg) +{ + const struct app_descriptor *app = (const struct app_descriptor *)arg; + + app->entry(app, NULL); + + return 0; +} + +static void start_app(const struct app_descriptor *app) +{ + printf("starting app %s\n", app->name); + + thread_resume(thread_create(app->name, &app_thread_entry, (void *)app, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); +} + diff --git a/lk/app/nandwrite/bootimg.h b/lk/app/nandwrite/bootimg.h new file mode 100644 index 0000000..87a0b3a --- /dev/null +++ b/lk/app/nandwrite/bootimg.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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. + * + * 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 _BOOT_IMAGE_H_ +#define _BOOT_IMAGE_H_ + +typedef struct boot_img_hdr boot_img_hdr; + +#define BOOT_MAGIC "ANDROID!" +#define BOOT_MAGIC_SIZE 8 +#define BOOT_NAME_SIZE 16 +#define BOOT_ARGS_SIZE 512 + +struct boot_img_hdr +{ + unsigned char magic[BOOT_MAGIC_SIZE]; + + unsigned kernel_size; /* size in bytes */ + unsigned kernel_addr; /* physical load addr */ + + unsigned ramdisk_size; /* size in bytes */ + unsigned ramdisk_addr; /* physical load addr */ + + unsigned second_size; /* size in bytes */ + unsigned second_addr; /* physical load addr */ + + unsigned tags_addr; /* physical addr for kernel tags */ + unsigned page_size; /* flash page size we assume */ + unsigned unused[2]; /* future expansion: should be 0 */ + + unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */ + + unsigned char cmdline[BOOT_ARGS_SIZE]; + + unsigned id[8]; /* timestamp / checksum / sha1 / etc */ +}; + +/* +** +-----------------+ +** | boot header | 1 page +** +-----------------+ +** | kernel | n pages +** +-----------------+ +** | ramdisk | m pages +** +-----------------+ +** | second stage | o pages +** +-----------------+ +** +** n = (kernel_size + page_size - 1) / page_size +** m = (ramdisk_size + page_size - 1) / page_size +** o = (second_size + page_size - 1) / page_size +** +** 0. all entities are page_size aligned in flash +** 1. kernel and ramdisk are required (size != 0) +** 2. second is optional (second_size == 0 -> no second) +** 3. load each element (kernel, ramdisk, second) at +** the specified physical address (kernel_addr, etc) +** 4. prepare tags at tag_addr. kernel_args[] is +** appended to the kernel commandline in the tags. +** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr +** 6. if second_size != 0: jump to second_addr +** else: jump to kernel_addr +*/ + +boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, + void *ramdisk, unsigned ramdisk_size, + void *second, unsigned second_size, + unsigned page_size, + unsigned *bootimg_size); + +void bootimg_set_cmdline(boot_img_hdr *hdr, const char *cmdline); +#endif + diff --git a/lk/app/nandwrite/nandwrite.c b/lk/app/nandwrite/nandwrite.c new file mode 100644 index 0000000..e262470 --- /dev/null +++ b/lk/app/nandwrite/nandwrite.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bootimg.h" + +#define FLASH_PAGE_SIZE 2048 +#define FLASH_PAGE_BITS 11 + +unsigned page_size = 0; +unsigned page_mask = 0; + +static unsigned load_addr = 0xffffffff; + +#define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y))) + +void acpu_clock_init(void); +void platform_uninit_timer(void); + +int startswith(const char *str, const char *prefix) +{ + while(*prefix){ + if(*prefix++ != *str++) return 0; + } + return 1; +} + +/* XXX */ +void verify_flash(struct ptentry *p, void *addr, unsigned len, int extra) +{ + uint32_t offset = 0; + void *buf = malloc(FLASH_PAGE_SIZE + extra); + int verify_extra = extra; + if(verify_extra > 4) + verify_extra = 16; + while(len > 0) { + flash_read_ext(p, extra, offset, buf, FLASH_PAGE_SIZE); + if(memcmp(addr, buf, FLASH_PAGE_SIZE + verify_extra)) { + dprintf(CRITICAL, "verify failed at 0x%08x\n", offset); + jtag_fail("verify failed"); + return; + } + offset += FLASH_PAGE_SIZE; + addr += FLASH_PAGE_SIZE; + len -= FLASH_PAGE_SIZE; + if(extra) { + addr += extra; + len -= extra; + } + } + dprintf(INFO, "verify done %d extra bytes\n", verify_extra); + jtag_okay("verify done"); +} + +void handle_flash(const char *name, unsigned addr, unsigned sz) +{ + struct ptentry *ptn; + struct ptable *ptable; + void *data = (void *) addr; + unsigned extra = 0; + + ptable = flash_get_ptable(); + if (ptable == NULL) { + jtag_fail("partition table doesn't exist"); + return; + } + + ptn = ptable_find(ptable, name); + if (ptn == NULL) { + jtag_fail("unknown partition name"); + return; + } + + if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) { + if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { + jtag_fail("image is not a boot image"); + return; + } + } + + if (!strcmp(ptn->name, "system") || !strcmp(ptn->name, "userdata") || !strcmp(ptn->name, "persist")) + extra = ((page_size >> 9) * 16); + else + sz = ROUND_TO_PAGE(sz, page_mask); + + data = (void *)target_get_scratch_address(); + + dprintf(INFO, "writing %d bytes to '%s'\n", sz, ptn->name); + if (flash_write(ptn, extra, data, sz)) { + jtag_fail("flash write failure"); + return; + } + dprintf(INFO, "partition '%s' updated\n", ptn->name); + jtag_okay("Done"); + enter_critical_section(); + platform_uninit_timer(); + arch_disable_cache(UCACHE); + arch_disable_mmu(); +} + +static unsigned char *tmpbuf = 0; + + +/*XXX*/ +void handle_dump(const char *name, unsigned offset) +{ + struct ptentry *p; + struct ptable *ptable; + + if(tmpbuf == 0) { + tmpbuf = malloc(4096); + } + + dprintf(INFO, "dump '%s' partition\n", name); + + ptable = flash_get_ptable(); + + if (ptable == NULL) { + jtag_fail("partition table doesn't exist"); + return; + } + + p = ptable_find(ptable, name); + + if(p == 0) { + jtag_fail("partition not found"); + return; + } else { + +#if 0 + /* XXX reimpl */ + if(flash_read_page(p->start * 64, tmpbuf, tmpbuf + 2048)){ + jtag_fail("flash_read() failed"); + return; + } +#endif + dprintf(INFO, "page %d data:\n", p->start * 64); + hexdump(tmpbuf, 256); + dprintf(INFO, "page %d extra:\n", p->start * 64); + hexdump(tmpbuf, 16); + jtag_okay("done"); + enter_critical_section(); + platform_uninit_timer(); + arch_disable_cache(UCACHE); + arch_disable_mmu(); + } +} + +void handle_query_load_address(unsigned addr) +{ + unsigned *return_addr = (unsigned *)addr; + + if (return_addr) + *return_addr = target_get_scratch_address(); + + jtag_okay("done"); +} + +void handle_command(const char *cmd, unsigned a0, unsigned a1, unsigned a2) +{ + if(startswith(cmd,"flash:")){ + handle_flash(cmd + 6, a0, a1); + return; + } + + if(startswith(cmd,"dump:")){ + handle_dump(cmd + 5, a0); + return; + } + + if(startswith(cmd,"loadaddr:")){ + handle_query_load_address(a0); + return; + } + + jtag_fail("unknown command"); +} + +void nandwrite_init(void) +{ + page_size = flash_page_size(); + page_mask = page_size - 1; + jtag_cmd_loop(handle_command); +} + + diff --git a/lk/app/nandwrite/rules.mk b/lk/app/nandwrite/rules.mk new file mode 100644 index 0000000..40d84ab --- /dev/null +++ b/lk/app/nandwrite/rules.mk @@ -0,0 +1,6 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/nandwrite.o \ + + diff --git a/lk/app/rules.mk b/lk/app/rules.mk new file mode 100644 index 0000000..74abd56 --- /dev/null +++ b/lk/app/rules.mk @@ -0,0 +1,5 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/app.o + diff --git a/lk/app/shell/rules.mk b/lk/app/shell/rules.mk new file mode 100644 index 0000000..5b7c919 --- /dev/null +++ b/lk/app/shell/rules.mk @@ -0,0 +1,7 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +MODULES += \ + lib/console + +OBJS += \ + $(LOCAL_DIR)/shell.o diff --git a/lk/app/shell/shell.c b/lk/app/shell/shell.c new file mode 100644 index 0000000..bdf67c5 --- /dev/null +++ b/lk/app/shell/shell.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2009 Travis Geiselbrecht + * + * 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 + +static void shell_init(const struct app_descriptor *app) +{ + console_init(); +} + +static void shell_entry(const struct app_descriptor *app, void *args) +{ + console_start(); +} + +APP_START(shell) + .init = shell_init, + .entry = shell_entry, +APP_END + diff --git a/lk/app/stringtests/mymemcpy.S b/lk/app/stringtests/mymemcpy.S new file mode 100644 index 0000000..975500a --- /dev/null +++ b/lk/app/stringtests/mymemcpy.S @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +.text +.align 2 + + .global mymemcpy +mymemcpy: + // check for zero length copy or the same pointer + cmp r2, #0 + cmpne r1, r0 + bxeq lr + + // save a few registers for use and the return code (input dst) + stmfd sp!, {r0, r4, r5, lr} + + // check for forwards overlap (src > dst, distance < len) + subs r3, r0, r1 + cmpgt r2, r3 + bgt .L_forwardoverlap + + // check for a short copy len. + // 20 bytes is enough so that if a 16 byte alignment needs to happen there is at least a + // wordwise copy worth of work to be done. + cmp r2, #(16+4) + blt .L_bytewise + + // see if they are similarly aligned on 4 byte boundaries + eor r3, r0, r1 + tst r3, #3 + bne .L_bytewise // dissimilarly aligned, nothing we can do (for now) + + // check for 16 byte alignment on dst. + // this will also catch src being not 4 byte aligned, since it is similarly 4 byte + // aligned with dst at this point. + tst r0, #15 + bne .L_not16bytealigned + + // check to see if we have at least 32 bytes of data to copy. + // if not, just revert to wordwise copy + cmp r2, #32 + blt .L_wordwise + +.L_bigcopy: + // copy 32 bytes at a time. src & dst need to be at least 4 byte aligned, + // and we need at least 32 bytes remaining to copy + + // save r6-r7 for use in the big copy + stmfd sp!, {r6-r7} + + sub r2, r2, #32 // subtract an extra 32 to the len so we can avoid an extra compare + +.L_bigcopy_loop: + ldmia r1!, {r4, r5, r6, r7} + stmia r0!, {r4, r5, r6, r7} + ldmia r1!, {r4, r5, r6, r7} + subs r2, r2, #32 + stmia r0!, {r4, r5, r6, r7} + bge .L_bigcopy_loop + + // restore r6-r7 + ldmfd sp!, {r6-r7} + + // see if we are done + adds r2, r2, #32 + beq .L_done + + // less then 4 bytes left? + cmp r2, #4 + blt .L_bytewise + +.L_wordwise: + // copy 4 bytes at a time. + // src & dst are guaranteed to be word aligned, and at least 4 bytes are left to copy. + subs r2, r2, #4 + +.L_wordwise_loop: + ldr r3, [r1], #4 + subs r2, r2, #4 + str r3, [r0], #4 + bge .L_wordwise_loop + + // correct the remaining len and test for completion + adds r2, r2, #4 + beq .L_done + +.L_bytewise: + // simple bytewise copy + ldrb r3, [r1], #1 + subs r2, r2, #1 + strb r3, [r0], #1 + bgt .L_bytewise + +.L_done: + // load dst for return and restore r4,r5 +#if ARM_ARCH_LEVEL >= 5 + ldmfd sp!, {r0, r4, r5, pc} +#else + ldmfd sp!, {r0, r4, r5, lr} + bx lr +#endif + +.L_not16bytealigned: + // dst is not 16 byte aligned, so we will copy up to 15 bytes to get it aligned. + // src is guaranteed to be similarly word aligned with dst. + + // set the condition flags based on the alignment. + lsl r12, r0, #28 + rsb r12, r12, #0 + msr CPSR_f, r12 // move into NZCV fields in CPSR + + // move as many bytes as necessary to get the dst aligned + ldrvsb r3, [r1], #1 // V set + ldrcsh r4, [r1], #2 // C set + ldreq r5, [r1], #4 // Z set + + strvsb r3, [r0], #1 + strcsh r4, [r0], #2 + streq r5, [r0], #4 + + ldmmiia r1!, {r3-r4} // N set + stmmiia r0!, {r3-r4} + + // fix the remaining len + sub r2, r2, r12, lsr #28 + + // test to see what we should do now + cmp r2, #32 + bge .L_bigcopy + b .L_wordwise + + // src and dest overlap 'forwards' or dst > src +.L_forwardoverlap: + + // do a bytewise reverse copy for now + add r1, r1, r2 + add r0, r0, r2 + +.L_bytewisereverse: + // simple bytewise reverse copy + ldrb r3, [r1], #-1 + subs r2, r2, #1 + strb r3, [r0], #-1 + bgt .L_bytewisereverse + + b .L_done + diff --git a/lk/app/stringtests/mymemset.S b/lk/app/stringtests/mymemset.S new file mode 100644 index 0000000..2d35d4f --- /dev/null +++ b/lk/app/stringtests/mymemset.S @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +.text +.align 2 + +/* void *memset(void *s, int c, size_t n); */ + .global mymemset +mymemset: + // check for zero length + cmp r2, #0 + bxeq lr + + // save the original pointer + mov r12, r0 + + // short memsets aren't worth optimizing + cmp r2, #(32 + 16) + blt .L_bytewise + + // fill a 32 bit register with the 8 bit value + and r1, r1, #0xff + orr r1, r1, r1, lsl #8 + orr r1, r1, r1, lsl #16 + + // check for 16 byte alignment + tst r0, #15 + bne .L_not16bytealigned + +.L_bigset: + // dump some registers to make space for our values + stmfd sp!, { r4-r5 } + + // fill a bunch of registers with the set value + mov r3, r1 + mov r4, r1 + mov r5, r1 + + // prepare the count register so we can avoid an extra compare + sub r2, r2, #32 + + // 32 bytes at a time +.L_bigset_loop: + stmia r0!, { r1, r3, r4, r5 } + subs r2, r2, #32 + stmia r0!, { r1, r3, r4, r5 } + bge .L_bigset_loop + + // restore our dumped registers + ldmfd sp!, { r4-r5 } + + // see if we're done + adds r2, r2, #32 + beq .L_done + +.L_bytewise: + // bytewise memset + subs r2, r2, #1 + strb r1, [r0], #1 + bgt .L_bytewise + +.L_done: + // restore the base pointer as return value + mov r0, r12 + bx lr + +.L_not16bytealigned: + // dst is not 16 byte aligned, so we will set up to 15 bytes to get it aligned. + + // set the condition flags based on the alignment. + lsl r3, r0, #28 + rsb r3, r3, #0 + msr CPSR_f, r3 // move into NZCV fields in CPSR + + // move as many bytes as necessary to get the dst aligned + strvsb r1, [r0], #1 // V set + strcsh r1, [r0], #2 // C set + streq r1, [r0], #4 // Z set + strmi r1, [r0], #4 // N set + strmi r1, [r0], #4 // N set + + // fix the remaining len + sub r2, r2, r3, lsr #28 + + // do the large memset + b .L_bigset + diff --git a/lk/app/stringtests/rules.mk b/lk/app/stringtests/rules.mk new file mode 100644 index 0000000..853a4fa --- /dev/null +++ b/lk/app/stringtests/rules.mk @@ -0,0 +1,6 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/string_tests.o \ + $(LOCAL_DIR)/mymemcpy.o \ + $(LOCAL_DIR)/mymemset.o diff --git a/lk/app/stringtests/string_tests.c b/lk/app/stringtests/string_tests.c new file mode 100644 index 0000000..6664346 --- /dev/null +++ b/lk/app/stringtests/string_tests.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include + +static uint8_t *src; +static uint8_t *dst; + +static uint8_t *src2; +static uint8_t *dst2; + +#define BUFFER_SIZE (1024*1024) +#define ITERATIONS 16 + +extern void *mymemcpy(void *dst, const void *src, size_t len); +extern void *mymemset(void *dst, int c, size_t len); + +static void *null_memcpy(void *dst, const void *src, size_t len) +{ + return dst; +} + +static time_t bench_memcpy_routine(void *memcpy_routine(void *, const void *, size_t), size_t srcalign, size_t dstalign) +{ + int i; + time_t t0; + + t0 = current_time(); + for (i=0; i < ITERATIONS; i++) { + memcpy_routine(dst + dstalign, src + srcalign, BUFFER_SIZE); + } + return current_time() - t0; +} + +static void bench_memcpy(void) +{ + time_t null, libc, mine; + size_t srcalign, dstalign; + + printf("memcpy speed test\n"); + thread_sleep(200); // let the debug string clear the serial port + + for (srcalign = 0; srcalign < 64; ) { + for (dstalign = 0; dstalign < 64; ) { + + null = bench_memcpy_routine(&null_memcpy, srcalign, dstalign); + libc = bench_memcpy_routine(&memcpy, srcalign, dstalign); + mine = bench_memcpy_routine(&mymemcpy, srcalign, dstalign); + + printf("srcalign %lu, dstalign %lu\n", srcalign, dstalign); + printf(" null memcpy %u msecs\n", null); + printf(" libc memcpy %u msecs, %llu bytes/sec\n", libc, BUFFER_SIZE * ITERATIONS * 1000ULL / libc); + printf(" my memcpy %u msecs, %llu bytes/sec\n", mine, BUFFER_SIZE * ITERATIONS * 1000ULL / mine); + + if (dstalign == 0) + dstalign = 1; + else + dstalign <<= 1; + } + if (srcalign == 0) + srcalign = 1; + else + srcalign <<= 1; + } +} + +static void fillbuf(void *ptr, size_t len, uint32_t seed) +{ + size_t i; + + for (i = 0; i < len; i++) { + ((char *)ptr)[i] = seed; + seed *= 0x1234567; + } +} + +static void validate_memcpy(void) +{ + size_t srcalign, dstalign, size; + const size_t maxsize = 256; + + printf("testing memcpy for correctness\n"); + + /* + * do the simple tests to make sure that memcpy doesn't color outside + * the lines for all alignment cases + */ + for (srcalign = 0; srcalign < 64; srcalign++) { + for (dstalign = 0; dstalign < 64; dstalign++) { +// printf("srcalign %zu, dstalign %zu\n", srcalign, dstalign); + for (size = 0; size < maxsize; size++) { + +// printf("srcalign %zu, dstalign %zu, size %zu\n", srcalign, dstalign, size); + + fillbuf(src, maxsize * 2, 567); + fillbuf(src2, maxsize * 2, 567); + fillbuf(dst, maxsize * 2, 123514); + fillbuf(dst2, maxsize * 2, 123514); + + memcpy(dst + dstalign, src + srcalign, size); + mymemcpy(dst2 + dstalign, src2 + srcalign, size); + + int comp = memcmp(dst, dst2, maxsize * 2); + if (comp != 0) { + printf("error! srcalign %zu, dstalign %zu, size %zu\n", srcalign, dstalign, size); + } + } + } + } +} + +static time_t bench_memset_routine(void *memset_routine(void *, int, size_t), size_t dstalign) +{ + int i; + time_t t0; + + t0 = current_time(); + for (i=0; i < ITERATIONS; i++) { + memset_routine(dst + dstalign, 0, BUFFER_SIZE); + } + return current_time() - t0; +} + +static void bench_memset(void) +{ + time_t libc, mine; + size_t dstalign; + + printf("memset speed test\n"); + thread_sleep(200); // let the debug string clear the serial port + + for (dstalign = 0; dstalign < 64; dstalign++) { + + libc = bench_memset_routine(&memset, dstalign); + mine = bench_memset_routine(&mymemset, dstalign); + + printf("dstalign %lu\n", dstalign); + printf(" libc memset %u msecs, %llu bytes/sec\n", libc, BUFFER_SIZE * ITERATIONS * 1000ULL / libc); + printf(" my memset %u msecs, %llu bytes/sec\n", mine, BUFFER_SIZE * ITERATIONS * 1000ULL / mine); + } +} + +static void validate_memset(void) +{ + size_t dstalign, size; + int c; + const size_t maxsize = 256; + + printf("testing memset for correctness\n"); + + for (dstalign = 0; dstalign < 64; dstalign++) { + printf("align %zd\n", dstalign); + for (size = 0; size < maxsize; size++) { + for (c = 0; c < 256; c++) { + + fillbuf(dst, maxsize * 2, 123514); + fillbuf(dst2, maxsize * 2, 123514); + + memset(dst + dstalign, c, size); + mymemset(dst2 + dstalign, c, size); + + int comp = memcmp(dst, dst2, maxsize * 2); + if (comp != 0) { + printf("error! align %zu, c %d, size %zu\n", dstalign, c, size); + } + } + } + } +} + +#if defined(WITH_LIB_CONSOLE) +#include + +static int string_tests(int argc, cmd_args *argv) +{ + src = memalign(64, BUFFER_SIZE + 256); + dst = memalign(64, BUFFER_SIZE + 256); + src2 = memalign(64, BUFFER_SIZE + 256); + dst2 = memalign(64, BUFFER_SIZE + 256); + + printf("src %p, dst %p\n", src, dst); + printf("src2 %p, dst2 %p\n", src2, dst2); + + if (argc < 3) { + printf("not enough arguments:\n"); +usage: + printf("%s validate \n", argv[0].str); + printf("%s bench \n", argv[0].str); + goto out; + } + + if (!strcmp(argv[1].str, "validate")) { + if (!strcmp(argv[2].str, "memcpy")) { + validate_memcpy(); + } else if (!strcmp(argv[2].str, "memset")) { + validate_memset(); + } + } else if (!strcmp(argv[1].str, "bench")) { + if (!strcmp(argv[2].str, "memcpy")) { + bench_memcpy(); + } else if (!strcmp(argv[2].str, "memset")) { + bench_memset(); + } + } else { + goto usage; + } + +out: + free(src); + free(dst); + free(src2); + free(dst2); + + return 0; +} + +STATIC_COMMAND_START +{ "string", NULL, &string_tests }, +STATIC_COMMAND_END(stringtests); + +#endif + +APP_START(stringtests) +APP_END + diff --git a/lk/app/tests/include/app/tests.h b/lk/app/tests/include/app/tests.h new file mode 100644 index 0000000..9144809 --- /dev/null +++ b/lk/app/tests/include/app/tests.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __APP_TESTS_H +#define __APP_TESTS_H + +int thread_tests(void); +void printf_tests(void); + +#endif + diff --git a/lk/app/tests/printf_tests.c b/lk/app/tests/printf_tests.c new file mode 100644 index 0000000..2c3ebc0 --- /dev/null +++ b/lk/app/tests/printf_tests.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +void printf_tests(void) +{ + printf("printf tests\n"); + + printf("numbers:\n"); + printf("int8: %hhd %hhd %hhd\n", -12, 0, 254); + printf("uint8: %hhu %hhu %hhu\n", -12, 0, 254); + printf("int16: %hd %hd %hd\n", -1234, 0, 1234); + printf("uint16:%hu %hu %hu\n", -1234, 0, 1234); + printf("int: %d %d %d\n", -12345678, 0, 12345678); + printf("uint: %u %u %u\n", -12345678, 0, 12345678); + printf("long: %ld %ld %ld\n", -12345678, 0, 12345678); + printf("ulong: %lu %lu %lu\n", -12345678, 0, 12345678); + printf("long: %D %D %D\n", -12345678, 0, 12345678); + printf("ulong: %U %U %U\n", -12345678, 0, 12345678); + printf("longlong: %lli %lli %lli\n", -12345678LL, 0LL, 12345678LL); + printf("ulonglong: %llu %llu %llu\n", -12345678LL, 0LL, 12345678LL); + printf("size_t: %zd %zd %zd\n", -12345678, 0, 12345678); + printf("usize_t: %zu %zu %zu\n", -12345678, 0, 12345678); + + printf("hex:\n"); + printf("uint8: %hhx %hhx %hhx\n", -12, 0, 254); + printf("uint16:%hx %hx %hx\n", -1234, 0, 1234); + printf("uint: %x %x %x\n", -12345678, 0, 12345678); + printf("ulong: %lx %lx %lx\n", -12345678, 0, 12345678); + printf("ulong: %X %X %X\n", -12345678, 0, 12345678); + printf("ulonglong: %llx %llx %llx\n", -12345678LL, 0LL, 12345678LL); + printf("usize_t: %zx %zx %zx\n", -12345678, 0, 12345678); + + printf("alt/sign:\n"); + printf("uint: %#x %#X\n", 0xabcdef, 0xabcdef); + printf("int: %+d %+d\n", 12345678, -12345678); + + printf("formatting\n"); + printf("int: a%8da\n", 12345678); + printf("int: a%9da\n", 12345678); + printf("int: a%-9da\n", 12345678); + printf("int: a%10da\n", 12345678); + printf("int: a%-10da\n", 12345678); + printf("int: a%09da\n", 12345678); + printf("int: a%010da\n", 12345678); + printf("int: a%6da\n", 12345678); + + printf("a%1sa\n", "b"); + printf("a%9sa\n", "b"); + printf("a%-9sa\n", "b"); + printf("a%5sa\n", "thisisatest"); + + int err; + + err = printf("a"); + printf(" returned %d\n", err); + err = printf("ab"); + printf(" returned %d\n", err); + err = printf("abc"); + printf(" returned %d\n", err); + err = printf("abcd"); + printf(" returned %d\n", err); + err = printf("abcde"); + printf(" returned %d\n", err); + err = printf("abcdef"); + printf(" returned %d\n", err); +} + + diff --git a/lk/app/tests/rules.mk b/lk/app/tests/rules.mk new file mode 100644 index 0000000..8f78eed --- /dev/null +++ b/lk/app/tests/rules.mk @@ -0,0 +1,8 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include + +OBJS += \ + $(LOCAL_DIR)/tests.o \ + $(LOCAL_DIR)/thread_tests.o \ + $(LOCAL_DIR)/printf_tests.o diff --git a/lk/app/tests/tests.c b/lk/app/tests/tests.c new file mode 100644 index 0000000..1a8130b --- /dev/null +++ b/lk/app/tests/tests.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +#if defined(WITH_LIB_CONSOLE) +#include + +STATIC_COMMAND_START + { "printf_tests", NULL, (console_cmd)&printf_tests }, + { "thread_tests", NULL, (console_cmd)&thread_tests }, +STATIC_COMMAND_END(tests); + +#endif + +static void tests_init(const struct app_descriptor *app) +{ +} + +APP_START(tests) + .init = tests_init, + .flags = 0, +APP_END + diff --git a/lk/app/tests/thread_tests.c b/lk/app/tests/thread_tests.c new file mode 100644 index 0000000..acbdfbd --- /dev/null +++ b/lk/app/tests/thread_tests.c @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include + +static int sleep_thread(void *arg) +{ + for(;;) { + printf("sleeper %p\n", current_thread); + thread_sleep(rand() % 500); + } + return 0; +} + +int sleep_test(void) +{ + int i; + for(i=0; i < 16; i++) + thread_resume(thread_create("sleeper", &sleep_thread, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + return 0; +} + +static volatile int shared = 0; +static mutex_t m; +static volatile int mutex_thread_count = 0; + +static int mutex_thread(void *arg) +{ + int i; + const int iterations = 10000; + + atomic_add(&mutex_thread_count, 1); + + printf("mutex tester thread %p starting up, will go for %d iterations\n", current_thread, iterations); + + for (i = 0; i < iterations; i++) { + mutex_acquire(&m); + + if (shared != 0) + panic("someone else has messed with the shared data\n"); + + shared = (int)current_thread; + thread_yield(); + shared = 0; + + mutex_release(&m); + thread_yield(); + } + atomic_add(&mutex_thread_count, -1); + + return 0; +} + +static int mutex_timeout_thread(void *arg) +{ + mutex_t *timeout_mutex = (mutex_t *)arg; + status_t err; + + printf("mutex_timeout_thread acquiring mutex %p with 1 second timeout\n", timeout_mutex); + err = mutex_acquire_timeout(timeout_mutex, 1000); + printf("mutex_acquire_timeout returns %d\n", err); + + return err; +} + +static int mutex_zerotimeout_thread(void *arg) +{ + mutex_t *timeout_mutex = (mutex_t *)arg; + status_t err; + + printf("mutex_zerotimeout_thread acquiring mutex %p with zero second timeout\n", timeout_mutex); + err = mutex_acquire_timeout(timeout_mutex, 0); + printf("mutex_acquire_timeout returns %d\n", err); + + return err; +} + +int mutex_test(void) +{ + mutex_init(&m); + + int i; + for(i=0; i < 5; i++) + thread_resume(thread_create("mutex tester", &mutex_thread, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + + thread_sleep(1000); + + while (mutex_thread_count > 0) + thread_yield(); + + printf("done with simple mutex tests\n"); + + printf("testing mutex timeout\n"); + + mutex_t timeout_mutex; + + mutex_init(&timeout_mutex); + mutex_acquire(&timeout_mutex); + + for (i=0; i < 2; i++) + thread_resume(thread_create("mutex timeout tester", &mutex_timeout_thread, (void *)&timeout_mutex, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + for (i=0; i < 2; i++) + thread_resume(thread_create("mutex timeout tester", &mutex_zerotimeout_thread, (void *)&timeout_mutex, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + + thread_sleep(5000); + mutex_release(&timeout_mutex); + + printf("done with mutex tests\n"); + + mutex_destroy(&timeout_mutex); + + return 0; +} + +static event_t e; + +static int event_signaller(void *arg) +{ + printf("event signaller pausing\n"); + thread_sleep(1000); + +// for (;;) { + printf("signalling event\n"); + event_signal(&e, true); + printf("done signalling event\n"); + thread_yield(); +// } + + return 0; +} + +static int event_waiter(void *arg) +{ + printf("event waiter starting\n"); + + for (;;) { + printf("%p: waiting on event...\n", current_thread); + if (event_wait(&e) < 0) { + printf("%p: event_wait() returned error\n", current_thread); + return -1; + } + printf("%p: done waiting on event...\n", current_thread); + thread_yield(); + } + + return 0; +} + +void event_test(void) +{ + /* make sure signalling the event wakes up all the threads */ + event_init(&e, false, 0); + thread_resume(thread_create("event signaller", &event_signaller, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("event waiter 0", &event_waiter, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("event waiter 1", &event_waiter, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("event waiter 2", &event_waiter, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("event waiter 3", &event_waiter, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_sleep(2000); + event_destroy(&e); + + /* make sure signalling the event wakes up precisely one thread */ + event_init(&e, false, EVENT_FLAG_AUTOUNSIGNAL); + thread_resume(thread_create("event signaller", &event_signaller, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("event waiter 0", &event_waiter, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("event waiter 1", &event_waiter, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("event waiter 2", &event_waiter, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("event waiter 3", &event_waiter, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_sleep(2000); + event_destroy(&e); +} + +static int quantum_tester(void *arg) +{ + for (;;) { + printf("%p: in this thread. rq %d\n", current_thread, current_thread->remaining_quantum); + } + return 0; +} + +void quantum_test(void) +{ + thread_resume(thread_create("quantum tester 0", &quantum_tester, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("quantum tester 1", &quantum_tester, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("quantum tester 2", &quantum_tester, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("quantum tester 3", &quantum_tester, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); +} + +static event_t context_switch_event; +static event_t context_switch_done_event; + +static int context_switch_tester(void *arg) +{ + int i; + uint total_count = 0; + const int iter = 100000; + int thread_count = (int)arg; + + event_wait(&context_switch_event); + + uint count = debug_cycle_count(); + for (i = 0; i < iter; i++) { + thread_yield(); + } + total_count += debug_cycle_count() - count; + thread_sleep(1000); + printf("took %u cycles to yield %d times, %u per yield, %u per yield per thread\n", + total_count, iter, total_count / iter, total_count / iter / thread_count); + + event_signal(&context_switch_done_event, true); + + return 0; +} + +void context_switch_test(void) +{ + event_init(&context_switch_event, false, 0); + event_init(&context_switch_done_event, false, 0); + + thread_resume(thread_create("context switch idle", &context_switch_tester, (void *)1, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_sleep(100); + event_signal(&context_switch_event, true); + event_wait(&context_switch_done_event); + thread_sleep(100); + + event_unsignal(&context_switch_event); + event_unsignal(&context_switch_done_event); + thread_resume(thread_create("context switch 2a", &context_switch_tester, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("context switch 2b", &context_switch_tester, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_sleep(100); + event_signal(&context_switch_event, true); + event_wait(&context_switch_done_event); + thread_sleep(100); + + event_unsignal(&context_switch_event); + event_unsignal(&context_switch_done_event); + thread_resume(thread_create("context switch 4a", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("context switch 4b", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("context switch 4c", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("context switch 4d", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + thread_sleep(100); + event_signal(&context_switch_event, true); + event_wait(&context_switch_done_event); + thread_sleep(100); +} + +static volatile int atomic; +static volatile int atomic_count; + +static int atomic_tester(void *arg) +{ + int add = (int)arg; + int i; + + TRACEF("add %d\n", add); + + for (i=0; i < 1000000; i++) { + atomic_add(&atomic, add); + } + + int old = atomic_add(&atomic_count, -1); + TRACEF("exiting, old count %d\n", old); + + return 0; +} + +static void atomic_test(void) +{ + atomic = 0; + atomic_count = 8; + + thread_resume(thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE)); + thread_resume(thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE)); + + while (atomic_count > 0) { + thread_sleep(1); + } + + printf("atomic count == %d (should be zero)\n", atomic); +} + +int thread_tests(void) +{ + mutex_test(); + event_test(); + + thread_sleep(200); + context_switch_test(); + + atomic_test(); + + return 0; +} diff --git a/lk/arch/arm/arch.c b/lk/arch/arm/arch.c new file mode 100644 index 0000000..37b557c --- /dev/null +++ b/lk/arch/arm/arch.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include + +#if ARM_CPU_CORTEX_A8 +static void set_vector_base(addr_t addr) +{ + __asm__ volatile("mcr p15, 0, %0, c12, c0, 0" :: "r" (addr)); +} +#endif + +void arch_early_init(void) +{ + /* turn off the cache */ + arch_disable_cache(UCACHE); + + /* set the vector base to our exception vectors so we dont need to double map at 0 */ +#if ARM_CPU_CORTEX_A8 + set_vector_base(MEMBASE); +#endif + +#if ARM_WITH_MMU + arm_mmu_init(); + + platform_init_mmu_mappings(); +#endif + + /* turn the cache back on */ + arch_enable_cache(UCACHE); + +#if ARM_WITH_NEON + /* enable cp10 and cp11 */ + uint32_t val; + __asm__ volatile("mrc p15, 0, %0, c1, c0, 2" : "=r" (val)); + val |= (3<<22)|(3<<20); + __asm__ volatile("mcr p15, 0, %0, c1, c0, 2" :: "r" (val)); + + /* set enable bit in fpexc */ + val = (1<<30); + __asm__ volatile("mcr p10, 7, %0, c8, c0, 0" :: "r" (val)); +#endif +} + +void arch_init(void) +{ +} + diff --git a/lk/arch/arm/asm.S b/lk/arch/arm/asm.S new file mode 100644 index 0000000..1b0ea1e --- /dev/null +++ b/lk/arch/arm/asm.S @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + + + /* context switch frame is as follows: + * ulr + * usp + * lr + * r11 + * r10 + * r9 + * r8 + * r7 + * r6 + * r5 + * r4 + */ +/* arm_context_switch(addr_t *old_sp, addr_t new_sp) */ +FUNCTION(arm_context_switch) + /* save all the usual registers + user regs */ + /* the spsr is saved and restored in the iframe by exceptions.S */ + sub r3, sp, #(11*4) /* can't use sp in user mode stm */ + mov r12, lr + stmia r3, { r4-r11, r12, r13, r14 }^ + + /* save old sp */ + str r3, [r0] + + /* clear any exlusive locks that the old thread holds */ +#if ARM_ISA_ARMV7 + /* can clear it directly */ + .word 0xf57ff01f // clrex +#elif ARM_ISA_ARMV6 + /* have to do a fake strex to clear it */ + ldr r0, =strex_spot + strex r3, r2, [r0] +#endif + + /* load new regs */ + ldmia r1, { r4-r11, r12, r13, r14 }^ + mov lr, r12 /* restore lr */ + add sp, r1, #(11*4) /* restore sp */ + bx lr + +.ltorg + +FUNCTION(arm_save_mode_regs) + mrs r1, cpsr + +#if ARM_ISA_ARMv6 + cps #0x11 /* fiq */ + str r13, [r0], #4 + str r14, [r0], #4 + cps #0x12 /* irq */ + str r13, [r0], #4 + str r14, [r0], #4 + cps #0x13 /* svc */ + str r13, [r0], #4 + str r14, [r0], #4 + cps #0x17 /* abt */ + str r13, [r0], #4 + str r14, [r0], #4 + cps #0x1b /* und */ + str r13, [r0], #4 + str r14, [r0], #4 + cps #0x1f /* sys */ + str r13, [r0], #4 + str r14, [r0], #4 +#else + // XXX implement + b . +#endif + + msr cpsr_c, r1 + + bx lr + +.data +strex_spot: + .word 0 + + diff --git a/lk/arch/arm/cache-ops.S b/lk/arch/arm/cache-ops.S new file mode 100644 index 0000000..8a545dc --- /dev/null +++ b/lk/arch/arm/cache-ops.S @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +.text + +#if ARM_WITH_CACHE + +/* low level cache routines for various cpu families */ + +#if ARM_CPU_ARM1136 || ARM_CPU_ARM926 + +/* void arch_disable_cache(uint flags) */ +FUNCTION(arch_disable_cache) + mov r12, #0 // zero register + mrs r3, cpsr // save the old interrupt state +#if ARM_ISA_ARMv6 + .word 0xf10c01c0 /* cpsid iaf */ // interrupts disabled +#else + orr r3, r3, #(1<<7) + msr cpsr, r3 +#endif + +.Ldcache_disable: + tst r0, #DCACHE + beq .Licache_disable + mrc p15, 0, r1, c1, c0, 0 // cr1 + tst r1, #(1<<2) // is the dcache already disabled? + beq .Licache_disable + + bic r1, #(1<<2) + mcr p15, 0, r1, c1, c0, 0 // disable dcache + +#if ARM_CPU_ARM1136 + mcr p15, 0, r12, c7, c14, 0 // clean & invalidate dcache +#elif ARM_CPU_ARM926 +0: + mrc p15, 0, r15, c7, c14, 3 // clean & invalidate dcache + bne 0b +#else +#error whut? +#endif + mcr p15, 0, r0, c7, c10, 4 // data sync barrier (formerly drain write buffer) + +.Licache_disable: + tst r0, #ICACHE + beq .Ldone_disable + + mrc p15, 0, r1, c1, c0, 0 // cr1 + bic r1, #(1<<12) + mcr p15, 0, r1, c1, c0, 0 // disable icache + + mcr p15, 0, r12, c7, c5, 0 // invalidate icache + +.Ldone_disable: + msr cpsr, r3 + bx lr + +/* void arch_enable_cache(uint flags) */ +FUNCTION(arch_enable_cache) + mov r12, #0 // zero register + mrs r3, cpsr // save the old interrupt state +#if ARM_ISA_ARMv6 + .word 0xf10c01c0 /* cpsid iaf */ // interrupts disabled +#else + orr r3, r3, #(1<<7) + msr cpsr, r3 +#endif + +.Ldcache_enable: + tst r0, #DCACHE + beq .Licache_enable + mrc p15, 0, r1, c1, c0, 0 // cr1 + tst r1, #(1<<2) // is the dcache already enabled? + bne .Licache_enable + + mcr p15, 0, r12, c7, c6, 0 // invalidate dcache + + orr r1, #(1<<2) + mcr p15, 0, r1, c1, c0, 0 // enable dcache + +.Licache_enable: + tst r0, #ICACHE + beq .Ldone_enable + + mcr p15, 0, r12, c7, c5, 0 // invalidate icache + + mrc p15, 0, r1, c1, c0, 0 // cr1 + orr r1, #(1<<12) + mcr p15, 0, r1, c1, c0, 0 // enable icache + +.Ldone_enable: + msr cpsr, r3 + bx lr + +#elif ARM_CPU_CORTEX_A8 + +/* void arch_disable_cache(uint flags) */ +FUNCTION(arch_disable_cache) + stmfd sp!, {r4-r11, lr} + + mov r7, r0 // save flags + + mrs r12, cpsr // save the old interrupt state + .word 0xf10c01c0 /* cpsid iaf */ // interrupts disabled + +.Ldcache_disable: + tst r7, #DCACHE + beq .Licache_disable + mrc p15, 0, r0, c1, c0, 0 // cr1 + tst r0, #(1<<2) // is the dcache already disabled? + beq .Ldcache_already_disabled + + bic r0, #(1<<2) + mcr p15, 0, r0, c1, c0, 0 // disable dcache + + // flush and invalidate the dcache + // NOTE: trashes a bunch of registers, can't be spilling stuff to the stack + bl flush_invalidate_cache_v7 + + b .Ldcache_disable_L2 + +.Ldcache_already_disabled: + // make sure all of the caches are invalidated + // NOTE: trashes a bunch of registers, can't be spilling stuff to the stack + bl invalidate_cache_v7 + +.Ldcache_disable_L2: + +#if ARM_WITH_L2 + // disable the L2, if present + mrc p15, 0, r0, c1, c0, 1 // aux cr1 + bic r0, #(1<<1) + mcr p15, 0, r0, c1, c0, 1 // disable L2 dcache +#endif + +.Licache_disable: + tst r7, #ICACHE + beq .Ldone_disable + + mrc p15, 0, r0, c1, c0, 0 // cr1 + bic r0, #(1<<12) + mcr p15, 0, r0, c1, c0, 0 // disable icache + +.Ldone_disable: + // make sure the icache is always invalidated + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 // invalidate icache to PoU + + msr cpsr, r12 + ldmfd sp!, {r4-r11, pc} + +/* void arch_enable_cache(uint flags) */ +FUNCTION(arch_enable_cache) + stmfd sp!, {r4-r11, lr} + + mov r7, r0 // save flags + + mrs r12, cpsr // save the old interrupt state + .word 0xf10c01c0 /* cpsid iaf */ // interrupts disabled + +.Ldcache_enable: + tst r7, #DCACHE + beq .Licache_enable + mrc p15, 0, r0, c1, c0, 0 // cr1 + tst r0, #(1<<2) // is the dcache already enabled? + bne .Licache_enable + + // invalidate L1 and L2 + // NOTE: trashes a bunch of registers, can't be spilling stuff to the stack + bl invalidate_cache_v7 + +#if ARM_WITH_L2 + // enable the L2, if present + mrc p15, 0, r0, c1, c0, 1 // aux cr1 + orr r0, #(1<<1) + mcr p15, 0, r0, c1, c0, 1 // enable L2 dcache +#endif + + mrc p15, 0, r0, c1, c0, 0 // cr1 + orr r0, #(1<<2) + mcr p15, 0, r0, c1, c0, 0 // enable dcache + +.Licache_enable: + tst r7, #ICACHE + beq .Ldone_enable + + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 // invalidate icache to PoU + + mrc p15, 0, r0, c1, c0, 0 // cr1 + orr r0, #(1<<12) + mcr p15, 0, r0, c1, c0, 0 // enable icache + +.Ldone_enable: + msr cpsr, r12 + ldmfd sp!, {r4-r11, pc} + +// flush & invalidate cache routine, trashes r0-r6, r9-r11 +flush_invalidate_cache_v7: + /* from ARMv7 manual, B2-17 */ + MRC p15, 1, R0, c0, c0, 1 // Read CLIDR + ANDS R3, R0, #0x7000000 + MOV R3, R3, LSR #23 // Cache level value (naturally aligned) + BEQ .Lfinished + MOV R10, #0 +.Loop1: + ADD R2, R10, R10, LSR #1 // Work out 3xcachelevel + MOV R1, R0, LSR R2 // bottom 3 bits are the Cache type for this level + AND R1, R1, #7 // get those 3 bits alone + CMP R1, #2 + BLT .Lskip // no cache or only instruction cache at this level + MCR p15, 2, R10, c0, c0, 0 // write the Cache Size selection register + .word 0xf57ff06f // ISB // ISB to sync the change to the CacheSizeID reg + MRC p15, 1, R1, c0, c0, 0 // reads current Cache Size ID register + AND R2, R1, #0x7 // extract the line length field + ADD R2, R2, #4 // add 4 for the line length offset (log2 16 bytes) + LDR R4, =0x3FF + ANDS R4, R4, R1, LSR #3 // R4 is the max number on the way size (right aligned) + CLZ R5, R4 // R5 is the bit position of the way size increment + LDR R6, =0x00007FFF + ANDS R6, R6, R1, LSR #13 // R6 is the max number of the index size (right aligned) +.Loop2: + MOV R9, R4 // R9 working copy of the max way size (right aligned) +.Loop3: + ORR R11, R10, R9, LSL R5 // factor in the way number and cache number into R11 + ORR R11, R11, R6, LSL R2 // factor in the index number + MCR p15, 0, R11, c7, c14, 2 // clean & invalidate by set/way + SUBS R9, R9, #1 // decrement the way number + BGE .Loop3 + SUBS R6, R6, #1 // decrement the index + BGE .Loop2 +.Lskip: + ADD R10, R10, #2 // increment the cache number + CMP R3, R10 + BGT .Loop1 + +.Lfinished: + mov r10, #0 + mcr p15, 2, r10, c0, c0, 0 // select cache level 0 + .word 0xf57ff06f // isb + + bx lr + +// invalidate cache routine, trashes r0-r6, r9-r11 +invalidate_cache_v7: + /* from ARMv7 manual, B2-17 */ + MRC p15, 1, R0, c0, c0, 1 // Read CLIDR + ANDS R3, R0, #0x7000000 + MOV R3, R3, LSR #23 // Cache level value (naturally aligned) + BEQ .Lfinished_invalidate + MOV R10, #0 +.Loop1_invalidate: + ADD R2, R10, R10, LSR #1 // Work out 3xcachelevel + MOV R1, R0, LSR R2 // bottom 3 bits are the Cache type for this level + AND R1, R1, #7 // get those 3 bits alone + CMP R1, #2 + BLT .Lskip_invalidate // no cache or only instruction cache at this level + MCR p15, 2, R10, c0, c0, 0 // write the Cache Size selection register + .word 0xf57ff06f // ISB // ISB to sync the change to the CacheSizeID reg + MRC p15, 1, R1, c0, c0, 0 // reads current Cache Size ID register + AND R2, R1, #0x7 // extract the line length field + ADD R2, R2, #4 // add 4 for the line length offset (log2 16 bytes) + LDR R4, =0x3FF + ANDS R4, R4, R1, LSR #3 // R4 is the max number on the way size (right aligned) + CLZ R5, R4 // R5 is the bit position of the way size increment + LDR R6, =0x00007FFF + ANDS R6, R6, R1, LSR #13 // R6 is the max number of the index size (right aligned) +.Loop2_invalidate: + MOV R9, R4 // R9 working copy of the max way size (right aligned) +.Loop3_invalidate: + ORR R11, R10, R9, LSL R5 // factor in the way number and cache number into R11 + ORR R11, R11, R6, LSL R2 // factor in the index number + MCR p15, 0, R11, c7, c6, 2 // invalidate by set/way + SUBS R9, R9, #1 // decrement the way number + BGE .Loop3_invalidate + SUBS R6, R6, #1 // decrement the index + BGE .Loop2_invalidate +.Lskip_invalidate: + ADD R10, R10, #2 // increment the cache number + CMP R3, R10 + BGT .Loop1_invalidate + +.Lfinished_invalidate: + mov r10, #0 + mcr p15, 2, r10, c0, c0, 0 // select cache level 0 + .word 0xf57ff06f // isb + + bx lr + +#else +#error unhandled cpu +#endif + +#if ARM_CPU_ARM926 || ARM_CPU_ARM1136 || ARM_CPU_CORTEX_A8 +/* shared cache flush routines */ + + /* void arch_flush_cache_range(addr_t start, size_t len); */ +FUNCTION(arch_clean_cache_range) +0: + mcr p15, 0, r0, c7, c10, 1 // clean cache to PoC by MVA + add r0, r0, #CACHE_LINE + subs r1, r1, #CACHE_LINE + bhs 0b + + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 // data sync barrier (formerly drain write buffer) + + bx lr + + /* void arch_flush_invalidate_cache_range(addr_t start, size_t len); */ +FUNCTION(arch_clean_invalidate_cache_range) +0: + mcr p15, 0, r0, c7, c14, 1 // clean & invalidate cache to PoC by MVA + add r0, r0, #CACHE_LINE + subs r1, r1, #CACHE_LINE + bhs 0b + + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 // data sync barrier (formerly drain write buffer) + + bx lr +#else +#error unhandled cpu +#endif + +#else + +/* no cache */ + +FUNCTION(arch_disable_cache) + bx lr + +FUNCTION(arch_enable_cache) + bx lr + +FUNCTION(arch_clean_cache_range) + bx lr + +FUNCTION(arch_clean_invalidate_cache_range) + bx lr + +#endif // ARM_WITH_CACHE + diff --git a/lk/arch/arm/cache.c b/lk/arch/arm/cache.c new file mode 100644 index 0000000..0a403b5 --- /dev/null +++ b/lk/arch/arm/cache.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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. + */ diff --git a/lk/arch/arm/compile.mk b/lk/arch/arm/compile.mk new file mode 100644 index 0000000..b509e16 --- /dev/null +++ b/lk/arch/arm/compile.mk @@ -0,0 +1,33 @@ + +$(BUILDDIR)/%.o: %.c $(SRCDEPS) + @$(MKDIR) + @echo compiling $< + $(NOECHO)$(CC) $(CFLAGS) $(THUMBCFLAGS) --std=c99 $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ + +$(BUILDDIR)/%.o: %.cpp $(SRCDEPS) + @$(MKDIR) + @echo compiling $< + $(NOECHO)$(CC) $(CFLAGS) $(CPPFLAGS) $(THUMBCFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ + +# to override thumb setting, mark the .o file as .Ao +$(BUILDDIR)/%.Ao: %.c $(SRCDEPS) + @$(MKDIR) + @echo compiling $< + $(NOECHO)$(CC) $(CFLAGS) --std=c99 $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ + +$(BUILDDIR)/%.Ao: %.cpp $(SRCDEPS) + @$(MKDIR) + @echo compiling $< + $(NOECHO)$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ + +# assembly is always compiled in ARM mode at the moment +$(BUILDDIR)/%.Ao: %.S $(SRCDEPS) + @$(MKDIR) + @echo compiling $< + $(NOECHO)$(CC) $(CFLAGS) $(ASMFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ + +$(BUILDDIR)/%.o: %.S $(SRCDEPS) + @$(MKDIR) + @echo compiling $< + $(NOECHO)$(CC) $(CFLAGS) $(ASMFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@ + diff --git a/lk/arch/arm/crt0.S b/lk/arch/arm/crt0.S new file mode 100644 index 0000000..a1777f0 --- /dev/null +++ b/lk/arch/arm/crt0.S @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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. + */ + +#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5 +#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5 + +.text +.globl _start +_start: + b reset + b arm_undefined + b arm_syscall + b arm_prefetch_abort + b arm_data_abort + b arm_reserved + b arm_irq + b arm_fiq + +reset: + /* do some cpu setup */ +#if ARM_WITH_CP15 + mrc p15, 0, r0, c1, c0, 0 + /* XXX this is currently for arm926, revist with armv6 cores */ + /* new thumb behavior, low exception vectors, i/d cache disable, mmu disabled */ + bic r0, r0, #(1<<15| 1<<13 | 1<<12) + bic r0, r0, #(1<<2 | 1<<0) + /* enable alignment faults */ + orr r0, r0, #(1<<1) + mcr p15, 0, r0, c1, c0, 0 +#endif + +#if WITH_CPU_EARLY_INIT + /* call platform/arch/etc specific init code */ + bl __cpu_early_init + + /* declare return address as global to avoid using stack */ +.globl _cpu_early_init_complete + _cpu_early_init_complete: + +#endif + +#if (!ENABLE_NANDWRITE) +#if WITH_CPU_WARM_BOOT + ldr r0, warm_boot_tag + cmp r0, #1 + + /* if set, warm boot */ + ldreq pc, =BASE_ADDR + + mov r0, #1 + str r0, warm_boot_tag +#endif +#endif + + /* see if we need to relocate */ + mov r0, pc + sub r0, r0, #(.Laddr - _start) +.Laddr: + ldr r1, =_start + cmp r0, r1 + beq .Lstack_setup + + /* we need to relocate ourselves to the proper spot */ + ldr r2, =__data_end + +.Lrelocate_loop: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + bne .Lrelocate_loop + + /* we're relocated, jump to the right address */ + ldr r0, =.Lstack_setup + bx r0 + +.ltorg +#if WITH_CPU_WARM_BOOT +warm_boot_tag: + .word 0 +#endif + +.Lstack_setup: + /* set up the stack for irq, fiq, abort, undefined, system/user, and lastly supervisor mode */ + mrs r0, cpsr + bic r0, r0, #0x1f + + ldr r2, =abort_stack_top + orr r1, r0, #0x12 // irq + msr cpsr_c, r1 + ldr r13, =irq_save_spot /* save a pointer to a temporary dumping spot used during irq delivery */ + + orr r1, r0, #0x11 // fiq + msr cpsr_c, r1 + mov sp, r2 + + orr r1, r0, #0x17 // abort + msr cpsr_c, r1 + mov sp, r2 + + orr r1, r0, #0x1b // undefined + msr cpsr_c, r1 + mov sp, r2 + + orr r1, r0, #0x1f // system + msr cpsr_c, r1 + mov sp, r2 + + orr r1, r0, #0x13 // supervisor + msr cpsr_c, r1 + mov sp, r2 + + /* copy the initialized data segment out of rom if necessary */ + ldr r0, =__data_start_rom + ldr r1, =__data_start + ldr r2, =__data_end + + cmp r0, r1 + beq .L__do_bss + +.L__copy_loop: + cmp r1, r2 + ldrlt r3, [r0], #4 + strlt r3, [r1], #4 + blt .L__copy_loop + +.L__do_bss: + /* clear out the bss */ + ldr r0, =__bss_start + ldr r1, =_end + mov r2, #0 +.L__bss_loop: + cmp r0, r1 + strlt r2, [r0], #4 + blt .L__bss_loop + +#ifdef ARM_CPU_CORTEX_A8 + DSB + ISB +#endif + + bl kmain + b . + +.ltorg + +.bss +.align 2 + /* the abort stack is for unrecoverable errors. + * also note the initial working stack is set to here. + * when the threading system starts up it'll switch to a new + * dynamically allocated stack, so we don't need it for very long + */ +abort_stack: + .skip 1024 +abort_stack_top: diff --git a/lk/arch/arm/dcc.S b/lk/arch/arm/dcc.S new file mode 100644 index 0000000..69a6585 --- /dev/null +++ b/lk/arch/arm/dcc.S @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2008 Brian Swetland + * + * 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. + */ + +.global dcc_putc +.global dcc_getc + +#if defined(ARM_ISA_ARMV6) || defined(ARM_ISA_ARMV7) +dcc_getc: + mrc 14, 0, r0, c0, c1, 0 + tst r0, #(1 << 30) + moveq r0, #-1 + mrcne 14, 0, r0, c0, c5, 0 + bx lr + +dcc_putc: + mrc 14, 0, r15, c0, c1, 0 + mcrcc 14, 0, r0, c0, c5, 0 + movcc r0, #0 + movcs r0, #-1 + bx lr +#endif diff --git a/lk/arch/arm/exceptions.S b/lk/arch/arm/exceptions.S new file mode 100644 index 0000000..0c881b9 --- /dev/null +++ b/lk/arch/arm/exceptions.S @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +FUNCTION(arm_undefined) + stmfd sp!, { r0-r12, r14 } + sub sp, sp, #12 + mov r0, sp + mrs r1, spsr + stmia r0, { r1, r13-r14 }^ + b arm_undefined_handler + b . + +FUNCTION(arm_syscall) + stmfd sp!, { r0-r12, r14 } + sub sp, sp, #12 + mov r0, sp + mrs r1, spsr + stmia r0, { r1, r13-r14 }^ + b arm_syscall_handler + b . + +FUNCTION(arm_prefetch_abort) + stmfd sp!, { r0-r12, r14 } + sub sp, sp, #12 + mov r0, sp + mrs r1, spsr + stmia r0, { r1, r13-r14 }^ + b arm_prefetch_abort_handler + b . + +FUNCTION(arm_data_abort) + stmfd sp!, { r0-r12, r14 } + sub sp, sp, #12 + mov r0, sp + mrs r1, spsr + stmia r0, { r1, r13-r14 }^ + b arm_data_abort_handler + b . + +FUNCTION(arm_reserved) + b . + +FUNCTION(arm_irq) + /* XXX only deals with interrupting supervisor mode */ + + /* save r4-r6 and use as a temporary place to save while we switch into supervisor mode */ + stmia r13, { r4-r6 } + mov r4, r13 + sub r5, lr, #4 + mrs r6, spsr + + /* move into supervisor mode. irq/fiq disabled */ + msr cpsr_c, #(3<<6 | 0x13) + + /* save the return address */ + stmfd sp!, { r5 } + + /* save C trashed regs, supervisor lr */ + stmfd sp!, { r0-r3, r12, lr } + + /* save spsr */ + stmfd sp!, { r6 } + + /* restore r4-r6 */ + ldmia r4, { r4-r6 } + + /* increment the global critical section count */ + ldr r1, =critical_section_count + ldr r0, [r1] + add r0, r0, #1 + str r0, [r1] + + /* call into higher level code */ + mov r0, sp /* iframe */ + bl platform_irq + + /* reschedule if the handler returns nonzero */ + cmp r0, #0 + blne thread_preempt + + /* decrement the global critical section count */ + ldr r1, =critical_section_count + ldr r0, [r1] + sub r0, r0, #1 + str r0, [r1] + + /* restore spsr */ + ldmfd sp!, { r0 } + msr spsr_cxsf, r0 + + /* restore back to where we came from */ + ldmfd sp!, { r0-r3, r12, lr, pc }^ + +.bss +.align 2 + .global irq_save_spot +irq_save_spot: + .word 0 /* r4 */ + .word 0 /* r5 */ + .word 0 /* r6 */ + +.text +FUNCTION(arm_fiq) + sub lr, lr, #4 + stmfd sp!, { r0-r3, r12, lr } + + bl platform_fiq + + ldmfd sp!, { r0-r3, r12, pc }^ + +.ltorg diff --git a/lk/arch/arm/faults.c b/lk/arch/arm/faults.c new file mode 100644 index 0000000..020266a --- /dev/null +++ b/lk/arch/arm/faults.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +static void dump_fault_frame(struct arm_fault_frame *frame) +{ + dprintf(CRITICAL, "r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n", frame->r[0], frame->r[1], frame->r[2], frame->r[3]); + dprintf(CRITICAL, "r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", frame->r[4], frame->r[5], frame->r[6], frame->r[7]); + dprintf(CRITICAL, "r8 0x%08x r9 0x%08x r10 0x%08x r11 0x%08x\n", frame->r[8], frame->r[9], frame->r[10], frame->r[11]); + dprintf(CRITICAL, "r12 0x%08x usp 0x%08x ulr 0x%08x pc 0x%08x\n", frame->r[12], frame->usp, frame->ulr, frame->pc); + dprintf(CRITICAL, "spsr 0x%08x\n", frame->spsr); + + struct arm_mode_regs regs; + arm_save_mode_regs(®s); + + dprintf(CRITICAL, "%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_FIQ) ? '*' : ' ', "fiq", regs.fiq_r13, regs.fiq_r14); + dprintf(CRITICAL, "%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_IRQ) ? '*' : ' ', "irq", regs.irq_r13, regs.irq_r14); + dprintf(CRITICAL, "%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_SVC) ? '*' : ' ', "svc", regs.svc_r13, regs.svc_r14); + dprintf(CRITICAL, "%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_UND) ? '*' : ' ', "und", regs.und_r13, regs.und_r14); + dprintf(CRITICAL, "%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_SYS) ? '*' : ' ', "sys", regs.sys_r13, regs.sys_r14); + + // dump the bottom of the current stack + addr_t stack; + switch (frame->spsr & MODE_MASK) { + case MODE_FIQ: stack = regs.fiq_r13; break; + case MODE_IRQ: stack = regs.irq_r13; break; + case MODE_SVC: stack = regs.svc_r13; break; + case MODE_UND: stack = regs.und_r13; break; + case MODE_SYS: stack = regs.sys_r13; break; + default: + stack = 0; + } + + if (stack != 0) { + dprintf(CRITICAL, "bottom of stack at 0x%08x:\n", (unsigned int)stack); + hexdump((void *)stack, 128); + } +} + +static void exception_die(struct arm_fault_frame *frame, int pc_off, const char *msg) +{ + inc_critical_section(); + frame->pc += pc_off; + dprintf(CRITICAL, msg); + dump_fault_frame(frame); + + halt(); + for(;;); +} + +void arm_syscall_handler(struct arm_fault_frame *frame) +{ + exception_die(frame, -4, "unhandled syscall, halting\n"); +} + +void arm_undefined_handler(struct arm_fault_frame *frame) +{ + exception_die(frame, -4, "undefined abort, halting\n"); +} + +void arm_data_abort_handler(struct arm_fault_frame *frame) +{ + exception_die(frame, -8, "data abort, halting\n"); +} + +void arm_prefetch_abort_handler(struct arm_fault_frame *frame) +{ + exception_die(frame, -4, "prefetch abort, halting\n"); +} diff --git a/lk/arch/arm/include/arch/arch_thread.h b/lk/arch/arm/include/arch/arch_thread.h new file mode 100644 index 0000000..2f4facf --- /dev/null +++ b/lk/arch/arm/include/arch/arch_thread.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ARM_ARCH_THREAD_H +#define __ARM_ARCH_THREAD_H + +struct arch_thread { + vaddr_t sp; +}; + +#endif + diff --git a/lk/arch/arm/include/arch/arm.h b/lk/arch/arm/include/arch/arm.h new file mode 100644 index 0000000..a14bf9c --- /dev/null +++ b/lk/arch/arm/include/arch/arm.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ARCH_ARM_H +#define __ARCH_ARM_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +void arm_context_switch(vaddr_t *old_sp, vaddr_t new_sp); + +static inline uint32_t read_cpsr() { + uint32_t cpsr; + + __asm__ volatile("mrs %0, cpsr" : "=r" (cpsr)); + return cpsr; +} + +struct arm_iframe { + uint32_t spsr; + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; +}; + +struct arm_fault_frame { + uint32_t spsr; + uint32_t usp; + uint32_t ulr; + uint32_t r[13]; + uint32_t pc; +}; + +#define MODE_MASK 0x1f +#define MODE_USR 0x10 +#define MODE_FIQ 0x11 +#define MODE_IRQ 0x12 +#define MODE_SVC 0x13 +#define MODE_MON 0x16 +#define MODE_ABT 0x17 +#define MODE_UND 0x1b +#define MODE_SYS 0x1f + +struct arm_mode_regs { + uint32_t fiq_r13, fiq_r14; + uint32_t irq_r13, irq_r14; + uint32_t svc_r13, svc_r14; + uint32_t abt_r13, abt_r14; + uint32_t und_r13, und_r14; + uint32_t sys_r13, sys_r14; +}; + +void arm_save_mode_regs(struct arm_mode_regs *regs); + +uint32_t arm_read_cr1(void); +void arm_write_cr1(uint32_t val); +uint32_t arm_read_cr1_aux(void); +void arm_write_cr1_aux(uint32_t val); +void arm_write_ttbr(uint32_t val); +void arm_write_dacr(uint32_t val); +void arm_invalidate_tlb(void); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/lk/arch/arm/include/arch/arm/cores.h b/lk/arch/arm/include/arch/arm/cores.h new file mode 100644 index 0000000..e5ddd66 --- /dev/null +++ b/lk/arch/arm/include/arch/arm/cores.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ARM_CORES_H +#define __ARM_CORES_H + +/* + * make the gcc built in define a little easier to deal with + * to decide what core it is generating code for + * + * ARM_ARCH_LEVEL gets assigned a numeric value of the general family + * + * ARM_ARCH_* gets defined for each feature recursively + */ + +#if defined(__ARM_ARCH_7M__) +#define ARM_ARCH_7M 1 +#endif +#if defined(__ARM_ARCH_7R__) +#define ARM_ARCH_7R 1 +#endif +#if defined(__ARM_ARCH_7A__) || defined(ARM_ARCH_7R) +#define ARM_ARCH_7A 1 +#endif +#if defined(__ARM_ARCH_7__) || defined(ARM_ARCH_7A) || defined(ARM_ARCH_7M) +#define ARM_ARCH_7 1 +#ifndef ARM_ARCH_LEVEL +#define ARM_ARCH_LEVEL 7 +#endif +#endif + +#if defined(__ARM_ARCH_6M__) +#define ARM_ARCH_6M 1 +#endif +#if defined(__ARM_ARCH_6T2__) || defined(ARM_ARCH_7) +#define ARM_ARCH_6T2 1 +#endif +#if defined(__ARM_ARCH_6ZK__) +#define ARM_ARCH_6ZK 1 +#endif +#if defined(__ARM_ARCH_6Z__) || defined(ARM_ARCH_6ZK) +#define ARM_ARCH_6Z 1 +#endif +#if defined(__ARM_ARCH_6K__) || defined(ARM_ARCH_6ZK) || defined(ARM_ARCH_7) +#define ARM_ARCH_6K 1 +#endif +#if defined(__ARM_ARCH_6J__) +#define ARM_ARCH_6J 1 +#endif +#if defined(__ARM_ARCH_6__) || defined(ARM_ARCH_6J) || defined(ARM_ARCH_6K) || defined(ARM_ARCH_6Z) || defined(ARM_ARCH_6T2) || defined(ARM_ARCH_6M) +#define ARM_ARCH_6 1 +#ifndef ARM_ARCH_LEVEL +#define ARM_ARCH_LEVEL 6 +#endif +#endif + +#if defined(__ARM_ARCH_5TEJ__) +#define ARM_ARCH_5TEJ 1 +#endif +#if defined(__ARM_ARCH_5TE__) || defined(ARM_ARCH_5TEJ) || defined(ARM_ARCH_6) +#define ARM_ARCH_5TE 1 +#endif +#if defined(__ARM_ARCH_5E__) || defined(ARM_ARCH_5TE) +#define ARM_ARCH_5E 1 +#endif +#if defined(__ARM_ARCH_5T__) || defined(ARM_ARCH_5TE) +#define ARM_ARCH_5T 1 +#endif +#if defined(__ARM_ARCH_5__) || defined(ARM_ARCH_5E) || defined(ARM_ARCH_5T) +#define ARM_ARCH_5 1 +#ifndef ARM_ARCH_LEVEL +#define ARM_ARCH_LEVEL 5 +#endif +#endif + +#if defined(__ARM_ARCH_4T__) || defined(ARM_ARCH_5T) +#define ARM_ARCH_4T 1 +#endif +#if defined(__ARM_ARCH_4__) || defined(ARM_ARCH_4T) || defined(ARM_ARCH_5) +#define ARM_ARCH_4 1 +#ifndef ARM_ARCH_LEVEL +#define ARM_ARCH_LEVEL 4 +#endif +#endif + +#if 0 +/* test */ +#if ARM_ARCH_LEVEL >= 7 +#warning ARM_ARCH_LEVEL >= 7 +#endif +#if ARM_ARCH_LEVEL >= 6 +#warning ARM_ARCH_LEVEL >= 6 +#endif +#if ARM_ARCH_LEVEL >= 5 +#warning ARM_ARCH_LEVEL >= 5 +#endif +#if ARM_ARCH_LEVEL >= 4 +#warning ARM_ARCH_LEVEL >= 4 +#endif +#endif + +#endif + diff --git a/lk/arch/arm/include/arch/arm/dcc.h b/lk/arch/arm/include/arch/arm/dcc.h new file mode 100644 index 0000000..ba1aba0 --- /dev/null +++ b/lk/arch/arm/include/arch/arm/dcc.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008 Brian Swetland + * + * 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 __ARCH_ARM_DCC_H +#define __ARCH_ARM_DCC_H + +/* returns < 0 if no data available */ +int dcc_getc(void); + +/* returns < 0 if output register was already full */ +int dcc_putc(unsigned c); + +#endif diff --git a/lk/arch/arm/include/arch/arm/mmu.h b/lk/arch/arm/include/arch/arm/mmu.h new file mode 100644 index 0000000..719710c --- /dev/null +++ b/lk/arch/arm/include/arch/arm/mmu.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ARCH_ARM_MMU_H +#define __ARCH_ARM_MMU_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +void arm_mmu_init(void); + +#define MMU_FLAG_CACHED 0x1 +#define MMU_FLAG_BUFFERED 0x2 +#define MMU_FLAG_READWRITE 0x4 +void arm_mmu_map_section(addr_t paddr, addr_t vaddr, uint flags); + + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/lk/arch/arm/include/arch/arm/ops.h b/lk/arch/arm/include/arch/arm/ops.h new file mode 100644 index 0000000..6e763c9 --- /dev/null +++ b/lk/arch/arm/include/arch/arm/ops.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ARCH_ARM_OPS_H +#define __ARHC_ARM_OPS_H + +#if 0 +#include + +#ifndef ASSEMBLY + +#if ARM_ISA_ARMV7 || ARM_ISA_ARMV6 +// override of some routines +__GNU_INLINE __ALWAYS_INLINE extern inline void arch_enable_ints(void) +{ + __asm__("cpsie i"); +} + +__GNU_INLINE __ALWAYS_INLINE extern inline void arch_disable_ints(void) +{ + __asm__("cpsid i"); +} +#endif + +#endif +#endif + +#endif + diff --git a/lk/arch/arm/include/arch/defines.h b/lk/arch/arm/include/arch/defines.h new file mode 100644 index 0000000..1d62a68 --- /dev/null +++ b/lk/arch/arm/include/arch/defines.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ARCH_CPU_H +#define __ARCH_CPU_H + +/* arm specific stuff */ +#define PAGE_SIZE 4096 + +#if ARM_CPU_ARM7 +/* irrelevant, no consistent cache */ +#define CACHE_LINE 32 +#elif ARM_CPU_ARM926 +#define CACHE_LINE 32 +#elif ARM_CPU_ARM1136 +#define CACHE_LINE 32 +#elif ARM_CPU_CORTEX_A8 +#define CACHE_LINE 64 +#else +#error unknown cpu +#endif + +#endif + diff --git a/lk/arch/arm/mmu.c b/lk/arch/arm/mmu.c new file mode 100644 index 0000000..74e9ecd --- /dev/null +++ b/lk/arch/arm/mmu.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include + +#if ARM_WITH_MMU + +#define MB (1024*1024) + +/* the location of the table may be brought in from outside */ +#if WITH_EXTERNAL_TRANSLATION_TABLE +#if !defined(MMU_TRANSLATION_TABLE_ADDR) +#error must set MMU_TRANSLATION_TABLE_ADDR in the make configuration +#endif +static uint32_t *tt = (void *)MMU_TRANSLATION_TABLE_ADDR; +#else +/* the main translation table */ +static uint32_t tt[4096] __ALIGNED(16384); +#endif + +void arm_mmu_map_section(addr_t paddr, addr_t vaddr, uint flags) +{ + int index; + uint AP; + uint CB; + uint TEX = 0; + +#if defined(PLATFORM_MSM7K) + if ((paddr >= 0x88000000) && (paddr < 0xD0000000)) { + /* peripherals in the 0x88000000 - 0xD0000000 range must + * be mapped as DEVICE NON-SHARED: TEX=2, C=0, B=0 + */ + TEX = 2; + flags &= (~(MMU_FLAG_CACHED | MMU_FLAG_BUFFERED)); + } +#endif + + AP = (flags & MMU_FLAG_READWRITE) ? 0x3 : 0x2; + CB = ((flags & MMU_FLAG_CACHED) ? 0x2 : 0) | ((flags & MMU_FLAG_BUFFERED) ? 0x1 : 0); + + index = vaddr / MB; + // section mapping + tt[index] = (paddr & ~(MB-1)) | (TEX << 12) | (AP << 10) | (0<<5) | (CB << 2) | (2<<0); + + arm_invalidate_tlb(); +} + +void arm_mmu_init(void) +{ + int i; + + /* set some mmu specific control bits */ + arm_write_cr1(arm_read_cr1() & ~((1<<29)|(1<<28)|(1<<0))); // access flag disabled, TEX remap disabled, mmu disabled + + /* set up an identity-mapped translation table with cache disabled */ + for (i=0; i < 4096; i++) { + arm_mmu_map_section(i * MB, i * MB, MMU_FLAG_READWRITE); // map everything uncached + } + + /* set up the translation table base */ + arm_write_ttbr((uint32_t)tt); + + /* set up the domain access register */ + arm_write_dacr(0x00000001); + + /* turn on the mmu */ + arm_write_cr1(arm_read_cr1() | 0x1); +} + +void arch_disable_mmu(void) +{ + arm_write_cr1(arm_read_cr1() & ~(1<<0)); // access flag disabled, TEX remap disabled, mmu disabled +} + +#endif // ARM_WITH_MMU + diff --git a/lk/arch/arm/ops.S b/lk/arch/arm/ops.S new file mode 100644 index 0000000..a858fa3 --- /dev/null +++ b/lk/arch/arm/ops.S @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +.text + +/* void arch_enable_ints(void); */ +FUNCTION(arch_enable_ints) + mrs r0, cpsr + bic r0, r0, #(1<<7) /* clear the I bit */ + msr cpsr_c, r0 + bx lr + +/* void arch_disable_ints(void); */ +FUNCTION(arch_disable_ints) + mrs r0, cpsr + orr r0, r0, #(1<<7) + msr cpsr_c, r0 + bx lr + +/* int atomic_swap(int *ptr, int val); */ +FUNCTION(atomic_swap) + swp r0, r2, [r1] + bx lr + +/* int atomic_add(int *ptr, int val); */ +FUNCTION(atomic_add) +#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7 + /* use load/store exclusive */ +.L_loop_add: + ldrex r12, [r0] + add r2, r12, r1 + strex r3, r2, [r0] + cmp r3, #0 + bne .L_loop_add + + /* save old value */ + mov r0, r12 + bx lr +#else + /* disable interrupts, do the add, and reenable */ + mrs r2, cpsr + mov r12, r2 + orr r2, r2, #(3<<6) + msr cpsr_c, r2 + + /* ints disabled, old cpsr state in r12 */ + + /* do the add, leave the previous value in r0 */ + mov r3, r0 + ldr r0, [r3] + add r2, r0, r1 + str r2, [r3] + + /* restore interrupts and exit */ + msr cpsr_c, r12 + bx lr +#endif + +/* int atomic_and(int *ptr, int val); */ +FUNCTION(atomic_and) +#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7 + /* use load/store exclusive */ +.L_loop_and: + ldrex r12, [r0] + and r2, r12, r1 + strex r3, r2, [r0] + cmp r3, #0 + bne .L_loop_and + + /* save old value */ + mov r0, r12 + bx lr +#else + /* disable interrupts, do the and, and reenable */ + mrs r2, cpsr + mov r12, r2 + orr r2, r2, #(3<<6) + msr cpsr_c, r2 + + /* ints disabled, old cpsr state in r12 */ + + /* do the and, leave the previous value in r0 */ + mov r3, r0 + ldr r0, [r3] + and r2, r0, r1 + str r2, [r3] + + /* restore interrupts and exit */ + msr cpsr_c, r12 + bx lr +#endif + +/* int atomic_or(int *ptr, int val); */ +FUNCTION(atomic_or) +#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7 + /* use load/store exclusive */ +.L_loop_or: + ldrex r12, [r0] + orr r2, r12, r1 + strex r3, r2, [r0] + cmp r3, #0 + bne .L_loop_or + + /* save old value */ + mov r0, r12 + bx lr +#else + /* disable interrupts, do the or, and reenable */ + mrs r2, cpsr + mov r12, r2 + orr r2, r2, #(3<<6) + msr cpsr_c, r2 + + /* ints disabled, old cpsr state in r12 */ + + /* do the or, leave the previous value in r0 */ + mov r3, r0 + ldr r0, [r3] + orr r2, r0, r1 + str r2, [r3] + + /* restore interrupts and exit */ + msr cpsr_c, r12 + bx lr +#endif + +/* void arch_idle(); */ +FUNCTION(arch_idle) +#if ARM_CPU_CORTEX_A8 + .word 0xe320f003 /* wfi */ +#elif PLATFORM_MSM7K + /* TODO: safely handle wfi */ +#elif ARM_CPU_ARM1136 || ARM_CPU_ARM926 + mov r0, #0 + mcr p15, 0, r0, c7, c0, #4 +#elif ARM_CPU_ARM7 + /* nothing to do here */ +#else +#error unknown cpu +#endif + bx lr + +/* uint32_t arm_read_cr1(void) */ +FUNCTION(arm_read_cr1) + mrc p15, 0, r0, c1, c0, 0 + bx lr + +/* void arm_write_cr1(uint32_t val) */ +FUNCTION(arm_write_cr1) + mcr p15, 0, r0, c1, c0, 0 + bx lr + +/* uint32_t arm_read_cr1_aux(void) */ +FUNCTION(arm_read_cr1_aux) + mrc p15, 0, r0, c1, c0, 1 + bx lr + +/* void arm_write_cr1_aux(uint32_t val) */ +FUNCTION(arm_write_cr1_aux) + mcr p15, 0, r0, c1, c0, 1 + bx lr + +/* void arm_write_ttbr(uint32_t val) */ +FUNCTION(arm_write_ttbr) + mcr p15, 0, r0, c2, c0, 0 + bx lr + +/* void arm_write_dacr(uint32_t val) */ +FUNCTION(arm_write_dacr) + mcr p15, 0, r0, c3, c0, 0 + bx lr + +/* void arm_invalidate_tlb(void) */ +FUNCTION(arm_invalidate_tlb) + mov r0, #0 + mcr p15, 0, r0, c8, c7, 0 + bx lr + +/* void arch_switch_stacks_and_call(addr_t call, addr_t stack) */ +FUNCTION(arch_switch_stacks_and_call) + mov sp, r1 + bx r0 + +/*void dmb(void) */ +FUNCTION(dmb) +#if ARM_CPU_CORTEX_A8 + dmb sy +#elif ARM_CPU_ARM1136 + mov r0, #0 + mcr p15, 0, r0, c7, c10, 5 +#endif + bx lr diff --git a/lk/arch/arm/rules.mk b/lk/arch/arm/rules.mk new file mode 100644 index 0000000..6f56edd --- /dev/null +++ b/lk/arch/arm/rules.mk @@ -0,0 +1,142 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +# can override this in local.mk +ENABLE_THUMB?=true + +DEFINES += \ + ARM_CPU_$(ARM_CPU)=1 + +# do set some options based on the cpu core +HANDLED_CORE := false +ifeq ($(ARM_CPU),cortex-a8) +DEFINES += \ + ARM_WITH_CP15=1 \ + ARM_WITH_MMU=1 \ + ARM_ISA_ARMv7=1 \ + ARM_WITH_VFP=1 \ + ARM_WITH_NEON=1 \ + ARM_WITH_THUMB=1 \ + ARM_WITH_THUMB2=1 \ + ARM_WITH_CACHE=1 \ + ARM_WITH_L2=1 +CFLAGS += -mcpu=$(ARM_CPU) +#CFLAGS += -mcpu=arm1136jf-s # compiler doesn't understand cortex yet +HANDLED_CORE := true +#CFLAGS += -mfpu=vfp -mfloat-abi=softfp +endif +ifeq ($(ARM_CPU),arm1136j-s) +DEFINES += \ + ARM_WITH_CP15=1 \ + ARM_WITH_MMU=1 \ + ARM_ISA_ARMv6=1 \ + ARM_WITH_THUMB=1 \ + ARM_WITH_CACHE=1 \ + ARM_CPU_ARM1136=1 +CFLAGS += -mcpu=$(ARM_CPU) +HANDLED_CORE := true +endif +ifeq ($(ARM_CPU),arm1176jzf-s) +DEFINES += \ + ARM_WITH_CP15=1 \ + ARM_WITH_MMU=1 \ + ARM_ISA_ARMv6=1 \ + ARM_WITH_VFP=1 \ + ARM_WITH_THUMB=1 \ + ARM_WITH_CACHE=1 \ + ARM_CPU_ARM1136=1 +CFLAGS += -mcpu=$(ARM_CPU) +HANDLED_CORE := true +endif +ifeq ($(ARM_CPU),arm926ej-s) +DEFINES += \ + ARM_WITH_CP15=1 \ + ARM_WITH_MMU=1 \ + ARM_ISA_ARMv5E=1 \ + ARM_WITH_THUMB=1 \ + ARM_WITH_CACHE=1 \ + ARM_CPU_ARM9=1 \ + ARM_CPU_ARM926=1 +CFLAGS += -mcpu=$(ARM_CPU) +HANDLED_CORE := true +endif +ifeq ($(ARM_CPU),arm7tdmi) +DEFINES += \ + ARM_ISA_ARMv4=1 \ + ARM_WITH_THUMB=1 \ + ARM_CPU_ARM7=1 +CFLAGS += -mcpu=$(ARM_CPU) +HANDLED_CORE := true +endif + +ifneq ($(HANDLED_CORE),true) +$(warning $(LOCAL_DIR)/rules.mk doesnt have logic for arm core $(ARM_CPU)) +$(warning this is likely to be broken) +endif + +THUMBCFLAGS := +THUMBINTERWORK := +ifeq ($(ENABLE_THUMB),true) +THUMBCFLAGS := -mthumb -D__thumb__ +THUMBINTERWORK := -mthumb-interwork +endif + +INCLUDES += \ + -I$(LOCAL_DIR)/include + +BOOTOBJS += \ + $(LOCAL_DIR)/crt0.o + +OBJS += \ + $(LOCAL_DIR)/arch.Ao \ + $(LOCAL_DIR)/asm.o \ + $(LOCAL_DIR)/cache.o \ + $(LOCAL_DIR)/cache-ops.o \ + $(LOCAL_DIR)/ops.o \ + $(LOCAL_DIR)/exceptions.o \ + $(LOCAL_DIR)/faults.o \ + $(LOCAL_DIR)/mmu.o \ + $(LOCAL_DIR)/thread.o \ + $(LOCAL_DIR)/dcc.o + +# set the default toolchain to arm eabi and set a #define +TOOLCHAIN_PREFIX ?= arm-eabi- +ifeq ($(TOOLCHAIN_PREFIX),arm-none-linux-gnueabi-) +# XXX test for EABI better than this +# eabi compilers dont need this +THUMBINTERWORK:= +endif + +CFLAGS += $(THUMBINTERWORK) + +# make sure some bits were set up +MEMVARS_SET := 0 +ifneq ($(MEMBASE),) +MEMVARS_SET := 1 +endif +ifneq ($(MEMSIZE),) +MEMVARS_SET := 1 +endif +ifeq ($(MEMVARS_SET),0) +$(error missing MEMBASE or MEMSIZE variable, please set in target rules.mk) +endif + +LIBGCC := $(shell $(TOOLCHAIN_PREFIX)gcc $(CFLAGS) $(THUMBCFLAGS) -print-libgcc-file-name) +#$(info LIBGCC = $(LIBGCC)) + +# potentially generated files that should be cleaned out with clean make rule +GENERATED += \ + $(BUILDDIR)/system-onesegment.ld \ + $(BUILDDIR)/system-twosegment.ld + +# rules for generating the linker scripts + +$(BUILDDIR)/system-onesegment.ld: $(LOCAL_DIR)/system-onesegment.ld + @echo generating $@ + @$(MKDIR) + $(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@ + +$(BUILDDIR)/system-twosegment.ld: $(LOCAL_DIR)/system-twosegment.ld + @echo generating $@ + @$(MKDIR) + $(NOECHO)sed "s/%ROMBASE%/$(ROMBASE)/;s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@ + diff --git a/lk/arch/arm/system-onesegment.ld b/lk/arch/arm/system-onesegment.ld new file mode 100644 index 0000000..9f0e7fc --- /dev/null +++ b/lk/arch/arm/system-onesegment.ld @@ -0,0 +1,82 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +ENTRY(_start) +SECTIONS +{ + . = %MEMBASE%; + + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) } + .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) } + .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } + .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x9090 + .plt : { *(.plt) } + + /* text/read-only data */ + .text : { *(.text .text.* .glue_7* .gnu.linkonce.t.*) } =0x9090 + + .rodata : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + . = ALIGN(4); + __commands_start = .; + KEEP (*(.commands)) + __commands_end = .; + . = ALIGN(4); + __apps_start = .; + KEEP (*(.apps)) + __apps_end = .; + . = ALIGN(4); + __rodata_end = . ; + } + + /* writable data */ + __data_start_rom = .; /* in one segment binaries, the rom data address is on top of the ram data address */ + __data_start = .; + .data : SUBALIGN(4) { *(.data .data.* .gnu.linkonce.d.*) } + + __ctor_list = .; + .ctors : { *(.ctors) } + __ctor_end = .; + __dtor_list = .; + .dtors : { *(.dtors) } + __dtor_end = .; + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + + __data_end = .; + + /* unintialized data (in same segment as writable data) */ + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss .bss.*) } + + . = ALIGN(4); + _end = .; + + . = %MEMBASE% + %MEMSIZE%; + _end_of_ram = .; + + /* Strip unnecessary stuff */ + /DISCARD/ : { *(.comment .note .eh_frame) } +} diff --git a/lk/arch/arm/system-twosegment.ld b/lk/arch/arm/system-twosegment.ld new file mode 100644 index 0000000..3a1c04c --- /dev/null +++ b/lk/arch/arm/system-twosegment.ld @@ -0,0 +1,85 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +ENTRY(_start) +SECTIONS +{ + . = %ROMBASE%; + + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) } + .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) } + .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } + .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x9090 + .plt : { *(.plt) } + + /* text/read-only data */ + .text : { *(.text .text.* .glue_7* .gnu.linkonce.t.*) } =0x9090 + + .rodata : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + . = ALIGN(4); + __commands_start = .; + KEEP (*(.commands)) + __commands_end = .; + . = ALIGN(4); + __apps_start = .; + KEEP (*(.apps)) + __apps_end = .; + . = ALIGN(4); + __rodata_end = . ; + } + + /* writable data */ + __data_start_rom = .; + . = %MEMBASE%; + __data_start = .; + .data : + AT ( ADDR (.rodata) + SIZEOF (.rodata) ) + { *(.data .data.* .gnu.linkonce.d.*) } + + __ctor_list = .; + .ctors : { *(.ctors) } + __ctor_end = .; + __dtor_list = .; + .dtors : { *(.dtors) } + __dtor_end = .; + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + + __data_end = .; + + /* unintialized data (in same segment as writable data) */ + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss .bss.*) } + + . = ALIGN(4); + _end = . ; + + . = %MEMBASE% + %MEMSIZE%; + _end_of_ram = . ; + + /* Strip unnecessary stuff */ + /DISCARD/ : { *(.comment .note .eh_frame) } +} diff --git a/lk/arch/arm/thread.c b/lk/arch/arm/thread.c new file mode 100644 index 0000000..c16a432 --- /dev/null +++ b/lk/arch/arm/thread.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include + +struct context_switch_frame { + vaddr_t r4; + vaddr_t r5; + vaddr_t r6; + vaddr_t r7; + vaddr_t r8; + vaddr_t r9; + vaddr_t r10; + vaddr_t r11; + vaddr_t lr; + vaddr_t usp; + vaddr_t ulr; +}; + +extern void arm_context_switch(addr_t *old_sp, addr_t new_sp); + +static void initial_thread_func(void) __NO_RETURN; +static void initial_thread_func(void) +{ + int ret; + +// dprintf("initial_thread_func: thread %p calling %p with arg %p\n", current_thread, current_thread->entry, current_thread->arg); +// dump_thread(current_thread); + + /* exit the implicit critical section we're within */ + exit_critical_section(); + + ret = current_thread->entry(current_thread->arg); + +// dprintf("initial_thread_func: thread %p exiting with %d\n", current_thread, ret); + + thread_exit(ret); +} + +void arch_thread_initialize(thread_t *t) +{ + // create a default stack frame on the stack + vaddr_t stack_top = (vaddr_t)t->stack + t->stack_size; + + // make sure the top of the stack is 8 byte aligned for EABI compliance + stack_top = ROUNDDOWN(stack_top, 8); + + struct context_switch_frame *frame = (struct context_switch_frame *)(stack_top); + frame--; + + // fill it in + memset(frame, 0, sizeof(*frame)); + frame->lr = (vaddr_t)&initial_thread_func; + + // set the stack pointer + t->arch.sp = (vaddr_t)frame; +} + +void arch_context_switch(thread_t *oldthread, thread_t *newthread) +{ +// dprintf("arch_context_switch: old %p (%s), new %p (%s)\n", oldthread, oldthread->name, newthread, newthread->name); + arm_context_switch(&oldthread->arch.sp, newthread->arch.sp); +} + diff --git a/lk/dev/dev.c b/lk/dev/dev.c new file mode 100644 index 0000000..5288b51 --- /dev/null +++ b/lk/dev/dev.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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. + */ + +void dev_init(void) +{ + +} + diff --git a/lk/dev/fbcon/fbcon.c b/lk/dev/fbcon/fbcon.c new file mode 100644 index 0000000..61e7cb4 --- /dev/null +++ b/lk/dev/fbcon/fbcon.c @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "font5x12.h" + +struct pos { + int x; + int y; +}; + +static struct fbcon_config *config = NULL; + +#define RGB565_BLACK 0x0000 +#define RGB565_WHITE 0xffff + +#define RGB888_BLACK 0x000000 +#define RGB888_WHITE 0xffffff + +#define FONT_WIDTH 5 +#define FONT_HEIGHT 12 + +static uint16_t BGCOLOR; +static uint16_t FGCOLOR; + +static struct pos cur_pos; +static struct pos max_pos; + +static void fbcon_drawglyph(uint16_t *pixels, uint16_t paint, unsigned stride, + unsigned *glyph) +{ + unsigned x, y, data; + stride -= FONT_WIDTH; + + data = glyph[0]; + for (y = 0; y < (FONT_HEIGHT / 2); ++y) { + for (x = 0; x < FONT_WIDTH; ++x) { + if (data & 1) + *pixels = paint; + data >>= 1; + pixels++; + } + pixels += stride; + } + + data = glyph[1]; + for (y = 0; y < (FONT_HEIGHT / 2); y++) { + for (x = 0; x < FONT_WIDTH; x++) { + if (data & 1) + *pixels = paint; + data >>= 1; + pixels++; + } + pixels += stride; + } +} + +static void fbcon_flush(void) +{ + if (config->update_start) + config->update_start(); + if (config->update_done) + while (!config->update_done()); +} + +/* TODO: Take stride into account */ +static void fbcon_scroll_up(void) +{ + unsigned short *dst = config->base; + unsigned short *src = dst + (config->width * FONT_HEIGHT); + unsigned count = config->width * (config->height - FONT_HEIGHT); + + while(count--) { + *dst++ = *src++; + } + + count = config->width * FONT_HEIGHT; + while(count--) { + *dst++ = BGCOLOR; + } + + fbcon_flush(); +} + +/* TODO: take stride into account */ +void fbcon_clear(void) +{ + unsigned count = config->width * config->height; + memset(config->base, BGCOLOR, count * ((config->bpp) / 8)); +} + + +static void fbcon_set_colors(unsigned bg, unsigned fg) +{ + BGCOLOR = bg; + FGCOLOR = fg; +} + +void fbcon_putc(char c) +{ + uint16_t *pixels; + + /* ignore anything that happens before fbcon is initialized */ + if (!config) + return; + + if((unsigned char)c > 127) + return; + if((unsigned char)c < 32) { + if(c == '\n') + goto newline; + else if (c == '\r') + cur_pos.x = 0; + return; + } + + pixels = config->base; + pixels += cur_pos.y * FONT_HEIGHT * config->width; + pixels += cur_pos.x * (FONT_WIDTH + 1); + fbcon_drawglyph(pixels, FGCOLOR, config->stride, + font5x12 + (c - 32) * 2); + + cur_pos.x++; + if (cur_pos.x < max_pos.x) + return; + +newline: + cur_pos.y++; + cur_pos.x = 0; + if(cur_pos.y >= max_pos.y) { + cur_pos.y = max_pos.y - 1; + fbcon_scroll_up(); + } else + fbcon_flush(); +} + +void fbcon_setup(struct fbcon_config *_config) +{ + uint32_t bg; + uint32_t fg; + + ASSERT(_config); + + config = _config; + + switch (config->format) { + case FB_FORMAT_RGB565: + fg = RGB565_WHITE; + bg = RGB565_BLACK; + break; + case FB_FORMAT_RGB888: + fg = RGB888_WHITE; + bg = RGB888_BLACK; + break; + default: + dprintf(CRITICAL, "unknown framebuffer pixel format\n"); + ASSERT(0); + break; + } + + fbcon_set_colors(bg, fg); + + cur_pos.x = 0; + cur_pos.y = 0; + max_pos.x = config->width / (FONT_WIDTH+1); + max_pos.y = (config->height - 1) / FONT_HEIGHT; +#if !DISPLAY_SPLASH_SCREEN + fbcon_clear(); +#endif +} + +struct fbcon_config* fbcon_display(void) +{ + return config; +} + +void diplay_image_on_screen(void) +{ + unsigned i = 0; + unsigned total_x = config->width; + unsigned total_y = config->height; + unsigned bytes_per_bpp = ((config->bpp) / 8); + unsigned image_base = ((((total_y/2) - (SPLASH_IMAGE_WIDTH / 2) - 1) * + (config->width)) + (total_x/2 - (SPLASH_IMAGE_HEIGHT / 2))); + fbcon_clear(); + +#if DISPLAY_TYPE_MIPI + if (bytes_per_bpp == 3) + { + for (i = 0; i < SPLASH_IMAGE_WIDTH; i++) + { + memcpy (config->base + ((image_base + (i * (config->width))) * bytes_per_bpp), + imageBuffer_rgb888 + (i * SPLASH_IMAGE_HEIGHT * bytes_per_bpp), + SPLASH_IMAGE_HEIGHT * bytes_per_bpp); + } + } + fbcon_flush(); + if(is_cmd_mode_enabled()) + mipi_dsi_cmd_mode_trigger(); + +#else + if (bytes_per_bpp == 2) + { + for (i = 0; i < SPLASH_IMAGE_WIDTH; i++) + { + memcpy (config->base + ((image_base + (i * (config->width))) * bytes_per_bpp), + imageBuffer + (i * SPLASH_IMAGE_HEIGHT * bytes_per_bpp), + SPLASH_IMAGE_HEIGHT * bytes_per_bpp); + } + } + fbcon_flush(); +#endif +} diff --git a/lk/dev/fbcon/font5x12.h b/lk/dev/fbcon/font5x12.h new file mode 100644 index 0000000..e033bf6 --- /dev/null +++ b/lk/dev/fbcon/font5x12.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008 The Android Open Source 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: + * * 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. + * + * 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. + */ + +unsigned font5x12[] = { + 0x00000000, 0x00000000, + 0x08421080, 0x00020084, + 0x00052940, 0x00000000, + 0x15f52800, 0x0000295f, + 0x1c52f880, 0x00023e94, + 0x08855640, 0x0004d542, + 0x04528800, 0x000b2725, + 0x00021080, 0x00000000, + 0x04211088, 0x00821042, + 0x10841082, 0x00221108, + 0x09575480, 0x00000000, + 0x3e420000, 0x00000084, + 0x00000000, 0x00223000, + 0x3e000000, 0x00000000, + 0x00000000, 0x00471000, + 0x08844200, 0x00008442, + 0x2318a880, 0x00022a31, + 0x08429880, 0x000f9084, + 0x1108c5c0, 0x000f8444, + 0x1c4443e0, 0x00074610, + 0x14a62100, 0x000423e9, + 0x26d087e0, 0x00074610, + 0x1e10c5c0, 0x00074631, + 0x088443e0, 0x00010844, + 0x1d18c5c0, 0x00074631, + 0x3d18c5c0, 0x00074610, + 0x08e20000, 0x00471000, + 0x08e20000, 0x00223000, + 0x02222200, 0x00082082, + 0x01f00000, 0x000003e0, + 0x20820820, 0x00008888, + 0x1108c5c0, 0x00020084, + 0x2b98c5c0, 0x000f05b5, + 0x2318a880, 0x0008c63f, + 0x1d2949e0, 0x0007ca52, + 0x0210c5c0, 0x00074421, + 0x252949e0, 0x0007ca52, + 0x1e1087e0, 0x000f8421, + 0x1e1087e0, 0x00008421, + 0x0210c5c0, 0x00074639, + 0x3f18c620, 0x0008c631, + 0x084211c0, 0x00071084, + 0x10842380, 0x00032508, + 0x0654c620, 0x0008c525, + 0x02108420, 0x000f8421, + 0x2b5dc620, 0x0008c631, + 0x2b59ce20, 0x0008c739, + 0x2318c5c0, 0x00074631, + 0x1f18c5e0, 0x00008421, + 0x2318c5c0, 0x01075631, + 0x1f18c5e0, 0x0008c525, + 0x1c10c5c0, 0x00074610, + 0x084213e0, 0x00021084, + 0x2318c620, 0x00074631, + 0x1518c620, 0x0002114a, + 0x2b18c620, 0x000556b5, + 0x08a54620, 0x0008c54a, + 0x08a54620, 0x00021084, + 0x088443e0, 0x000f8442, + 0x0421084e, 0x00e10842, + 0x08210420, 0x00084108, + 0x1084210e, 0x00e42108, + 0x0008a880, 0x00000000, + 0x00000000, 0x01f00000, + 0x00000104, 0x00000000, + 0x20e00000, 0x000b663e, + 0x22f08420, 0x0007c631, + 0x22e00000, 0x00074421, + 0x23e84200, 0x000f4631, + 0x22e00000, 0x0007443f, + 0x1e214980, 0x00010842, + 0x22e00000, 0x1d187a31, + 0x26d08420, 0x0008c631, + 0x08601000, 0x00071084, + 0x10c02000, 0x0c94a108, + 0x0a908420, 0x0008a4a3, + 0x084210c0, 0x00071084, + 0x2ab00000, 0x0008d6b5, + 0x26d00000, 0x0008c631, + 0x22e00000, 0x00074631, + 0x22f00000, 0x0210be31, + 0x23e00000, 0x21087a31, + 0x26d00000, 0x00008421, + 0x22e00000, 0x00074506, + 0x04f10800, 0x00064842, + 0x23100000, 0x000b6631, + 0x23100000, 0x00022951, + 0x23100000, 0x000556b5, + 0x15100000, 0x0008a884, + 0x23100000, 0x1d185b31, + 0x11f00000, 0x000f8444, + 0x06421098, 0x01821084, + 0x08421080, 0x00021084, + 0x30421083, 0x00321084, + 0x0004d640, 0x00000000, + 0x00000000, 0x00000000, +}; diff --git a/lk/dev/fbcon/rules.mk b/lk/dev/fbcon/rules.mk new file mode 100644 index 0000000..85c678c --- /dev/null +++ b/lk/dev/fbcon/rules.mk @@ -0,0 +1,5 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/fbcon.o + diff --git a/lk/dev/keys/gpio_keypad.c b/lk/dev/keys/gpio_keypad.c new file mode 100644 index 0000000..86a31c7 --- /dev/null +++ b/lk/dev/keys/gpio_keypad.c @@ -0,0 +1,618 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct gpio_kp { + struct gpio_keypad_info *keypad_info; + struct timer timer; + event_t full_scan; + int current_output; + unsigned int some_keys_pressed:2; + unsigned long keys_pressed[0]; +}; + +struct gpio_qwerty_kp { + struct qwerty_keypad_info *keypad_info; + struct timer timer; + event_t full_scan; + int num_of_scans; + unsigned int some_keys_pressed:2; + unsigned long keys_pressed[0]; +}; + +static struct gpio_qwerty_kp *qwerty_keypad; +/* TODO: Support multiple keypads? */ +static struct gpio_kp *keypad; + +static void check_output(struct gpio_kp *kp, int out, int polarity) +{ + struct gpio_keypad_info *kpinfo = kp->keypad_info; + int key_index; + int in; + int gpio; + int changed = 0; + + key_index = out * kpinfo->ninputs; + for (in = 0; in < kpinfo->ninputs; in++, key_index++) { + gpio = kpinfo->input_gpios[in]; + changed = 0; + if (gpio_get(gpio) ^ !polarity) { + if (kp->some_keys_pressed < 3) + kp->some_keys_pressed++; + changed = !bitmap_set(kp->keys_pressed, key_index); + } else { + changed = bitmap_clear(kp->keys_pressed, key_index); + } + if (changed) { + int state = bitmap_test(kp->keys_pressed, key_index); + keys_post_event(kpinfo->keymap[key_index], state); + } + } + + /* sets up the right state for the next poll cycle */ + gpio = kpinfo->output_gpios[out]; + if (kpinfo->flags & GPIOKPF_DRIVE_INACTIVE) + gpio_set(gpio, !polarity); + else + gpio_config(gpio, GPIO_INPUT); +} + +static enum handler_return +gpio_keypad_timer_func(struct timer *timer, time_t now, void *arg) +{ + struct gpio_kp *kp = keypad; + struct gpio_keypad_info *kpinfo = kp->keypad_info; + int polarity = !!(kpinfo->flags & GPIOKPF_ACTIVE_HIGH); + int out; + int gpio; + + out = kp->current_output; + if (out == kpinfo->noutputs) { + out = 0; + kp->some_keys_pressed = 0; + } else { + check_output(kp, out, polarity); + out++; + } + + kp->current_output = out; + if (out < kpinfo->noutputs) { + gpio = kpinfo->output_gpios[out]; + if (kpinfo->flags & GPIOKPF_DRIVE_INACTIVE) + gpio_set(gpio, polarity); + else + gpio_config(gpio, polarity ? GPIO_OUTPUT : 0); + timer_set_oneshot(timer, kpinfo->settle_time, + gpio_keypad_timer_func, NULL); + goto done; + } + + if (/*!kp->use_irq*/ 1 || kp->some_keys_pressed) { + event_signal(&kp->full_scan, false); + timer_set_oneshot(timer, kpinfo->poll_time, + gpio_keypad_timer_func, NULL); + goto done; + } + +#if 0 + /* No keys are pressed, reenable interrupt */ + for (out = 0; out < kpinfo->noutputs; out++) { + if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) + gpio_set(kpinfo->output_gpios[out], polarity); + else + gpio_config(kpinfo->output_gpios[out], polarity ? GPIO_OUTPUT : 0); + } + for (in = 0; in < kpinfo->ninputs; in++) + enable_irq(gpio_to_irq(kpinfo->input_gpios[in])); + return INT_RESCHEDULE; +#endif + +done: + return INT_RESCHEDULE; +} + +void gpio_keypad_init(struct gpio_keypad_info *kpinfo) +{ + int key_count; + int output_val; + int output_cfg; + int i; + int len; + + ASSERT(kpinfo->keymap && kpinfo->input_gpios && kpinfo->output_gpios); + key_count = kpinfo->ninputs * kpinfo->noutputs; + + len = sizeof(struct gpio_kp) + (sizeof(unsigned long) * + BITMAP_NUM_WORDS(key_count)); + keypad = malloc(len); + ASSERT(keypad); + + memset(keypad, 0, len); + keypad->keypad_info = kpinfo; + + output_val = (!!(kpinfo->flags & GPIOKPF_ACTIVE_HIGH)) ^ + (!!(kpinfo->flags & GPIOKPF_DRIVE_INACTIVE)); + output_cfg = kpinfo->flags & GPIOKPF_DRIVE_INACTIVE ? GPIO_OUTPUT : 0; + for (i = 0; i < kpinfo->noutputs; i++) { + gpio_set(kpinfo->output_gpios[i], output_val); + gpio_config(kpinfo->output_gpios[i], output_cfg); + } + for (i = 0; i < kpinfo->ninputs; i++) + gpio_config(kpinfo->input_gpios[i], GPIO_INPUT); + + keypad->current_output = kpinfo->noutputs; + + event_init(&keypad->full_scan, false, EVENT_FLAG_AUTOUNSIGNAL); + timer_initialize(&keypad->timer); + timer_set_oneshot(&keypad->timer, 0, gpio_keypad_timer_func, NULL); + + /* wait for the keypad to complete one full scan */ + event_wait(&keypad->full_scan); +} + +int i2c_ssbi_poll_for_device_ready(void) +{ + unsigned long timeout = SSBI_TIMEOUT_US; + + while (!(readl(MSM_SSBI_BASE + SSBI2_STATUS) & SSBI_STATUS_READY)) { + if (--timeout == 0) { + dprintf(INFO, "In Device ready function:Timeout, status %x\n", readl(MSM_SSBI_BASE + SSBI2_STATUS)); + return 1; + } + } + + return 0; +} + +int i2c_ssbi_poll_for_read_completed(void) +{ + unsigned long timeout = SSBI_TIMEOUT_US; + + while (!(readl(MSM_SSBI_BASE + SSBI2_STATUS) & SSBI_STATUS_RD_READY)) { + if (--timeout == 0) { + dprintf(INFO, "In read completed function:Timeout, status %x\n", readl(MSM_SSBI_BASE + SSBI2_STATUS)); + return 1; + } + } + + return 0; +} + +int i2c_ssbi_read_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr) +{ + int ret = 0; + unsigned char *buf = buffer; + unsigned short len = length; + unsigned short addr = slave_addr; + unsigned long read_cmd = SSBI_CMD_READ(addr); + unsigned long mode2 = readl(MSM_SSBI_BASE + SSBI2_MODE2); + + //buf = alloc(len * sizeof(8)); + if (mode2 & SSBI_MODE2_SSBI2_MODE) + writel(SSBI_MODE2_REG_ADDR_15_8(mode2, addr), + MSM_SSBI_BASE + SSBI2_MODE2); + + while (len) { + ret = i2c_ssbi_poll_for_device_ready(); + if (ret) { + dprintf (CRITICAL, "Error: device not ready\n"); + return ret; + } + + writel(read_cmd, MSM_SSBI_BASE + SSBI2_CMD); + + ret = i2c_ssbi_poll_for_read_completed(); + if (ret) { + dprintf (CRITICAL, "Error: read not completed\n"); + return ret; + } + + *buf++ = readl(MSM_SSBI_BASE + SSBI2_RD) & SSBI_RD_REG_DATA_MASK; + len--; + } + return 0; +} + +int i2c_ssbi_write_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr) +{ + int ret = 0; + unsigned long timeout = SSBI_TIMEOUT_US; + unsigned char *buf = buffer; + unsigned short len = length; + unsigned short addr = slave_addr; + unsigned long mode2 = readl(MSM_SSBI_BASE + SSBI2_MODE2); + + if (mode2 & SSBI_MODE2_SSBI2_MODE) + writel(SSBI_MODE2_REG_ADDR_15_8(mode2, addr), + MSM_SSBI_BASE + SSBI2_MODE2); + + while (len) { + ret = i2c_ssbi_poll_for_device_ready(); + if (ret) { + dprintf (CRITICAL, "Error: device not ready\n"); + return ret; + } + + writel(SSBI_CMD_WRITE(addr, *buf++), MSM_SSBI_BASE + SSBI2_CMD); + + while (readl(MSM_SSBI_BASE + SSBI2_STATUS) & SSBI_STATUS_MCHN_BUSY) { + if (--timeout == 0) { + dprintf(INFO, "In Device ready function:Timeout, status %x\n", readl(MSM_SSBI_BASE + SSBI2_STATUS)); + return 1; + } + } + len--; + } + return 0; +} + +int pa1_ssbi2_read_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr) +{ + unsigned val = 0x0; + unsigned temp = 0x0000; + unsigned char *buf = buffer; + unsigned short len = length; + unsigned short addr = slave_addr; + unsigned long timeout = SSBI_TIMEOUT_US; + + while(len) + { + val |= ((addr << PA1_SSBI2_REG_ADDR_SHIFT) | + (PA1_SSBI2_CMD_READ << PA1_SSBI2_CMD_RDWRN_SHIFT)); + writel(val, PA1_SSBI2_CMD); + while(!((temp = readl(PA1_SSBI2_RD_STATUS)) & (1 << PA1_SSBI2_TRANS_DONE_SHIFT))) { + if (--timeout == 0) { + dprintf(INFO, "In Device ready function:Timeout\n"); + return 1; + } + } + len--; + *buf++ = (temp & (PA1_SSBI2_REG_DATA_MASK << PA1_SSBI2_REG_DATA_SHIFT)); + } + return 0; +} + +int pa1_ssbi2_write_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr) +{ + unsigned val; + unsigned char *buf = buffer; + unsigned short len = length; + unsigned short addr = slave_addr; + unsigned temp = 0x00; + unsigned char written_data1 = 0x00; + unsigned long timeout = SSBI_TIMEOUT_US; + //unsigned char written_data2 = 0x00; + + while(len) + { + temp = 0x00; + written_data1 = 0x00; + val = (addr << PA1_SSBI2_REG_ADDR_SHIFT) | + (PA1_SSBI2_CMD_WRITE << PA1_SSBI2_CMD_RDWRN_SHIFT) | + (*buf & 0xFF); + writel(val, PA1_SSBI2_CMD); + while(!((temp = readl(PA1_SSBI2_RD_STATUS)) & (1 << PA1_SSBI2_TRANS_DONE_SHIFT))) { + if (--timeout == 0) { + dprintf(INFO, "In Device write function:Timeout\n"); + return 1; + } + } + len--; + buf++; + } + return 0; +} + +int pa2_ssbi2_read_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr) +{ + unsigned val = 0x0; + unsigned temp = 0x0000; + unsigned char *buf = buffer; + unsigned short len = length; + unsigned short addr = slave_addr; + unsigned long timeout = SSBI_TIMEOUT_US; + + while(len) + { + val |= ((addr << PA2_SSBI2_REG_ADDR_SHIFT) | + (PA2_SSBI2_CMD_READ << PA2_SSBI2_CMD_RDWRN_SHIFT)); + writel(val, PA2_SSBI2_CMD); + while(!((temp = readl(PA2_SSBI2_RD_STATUS)) & (1 << PA2_SSBI2_TRANS_DONE_SHIFT))) { + if (--timeout == 0) { + dprintf(INFO, "In Device ready function:Timeout\n"); + return 1; + } + } + len--; + *buf++ = (temp & (PA2_SSBI2_REG_DATA_MASK << PA2_SSBI2_REG_DATA_SHIFT)); + } + return 0; +} + +int pa2_ssbi2_write_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr) +{ + unsigned val; + unsigned char *buf = buffer; + unsigned short len = length; + unsigned short addr = slave_addr; + unsigned temp = 0x00; + unsigned char written_data1 = 0x00; + unsigned long timeout = SSBI_TIMEOUT_US; + + while(len) + { + temp = 0x00; + written_data1 = 0x00; + val = (addr << PA2_SSBI2_REG_ADDR_SHIFT) | + (PA2_SSBI2_CMD_WRITE << PA2_SSBI2_CMD_RDWRN_SHIFT) | + (*buf & 0xFF); + writel(val, PA2_SSBI2_CMD); + while(!((temp = readl(PA2_SSBI2_RD_STATUS)) & (1 << PA2_SSBI2_TRANS_DONE_SHIFT))) { + if (--timeout == 0) { + dprintf(INFO, "In Device write function:Timeout\n"); + return 1; + } + } + len--; + buf++; + } + return 0; +} + +int pm8058_gpio_config(int gpio, struct pm8058_gpio *param) +{ + int rc; + write_func wr_function = (qwerty_keypad->keypad_info)->wr_func; + unsigned char bank[8]; + static int dir_map[] = { + PM8058_GPIO_MODE_OFF, + PM8058_GPIO_MODE_OUTPUT, + PM8058_GPIO_MODE_INPUT, + PM8058_GPIO_MODE_BOTH, + }; + + if (param == 0) { + dprintf (INFO, "pm8058_gpio struct not defined\n"); + return -1; + } + + /* Select banks and configure the gpio */ + bank[0] = PM8058_GPIO_WRITE | + ((param->vin_sel << PM8058_GPIO_VIN_SHIFT) & + PM8058_GPIO_VIN_MASK) | + PM8058_GPIO_MODE_ENABLE; + bank[1] = PM8058_GPIO_WRITE | + ((1 << PM8058_GPIO_BANK_SHIFT) & PM8058_GPIO_BANK_MASK) | + ((dir_map[param->direction] << PM8058_GPIO_MODE_SHIFT) & + PM8058_GPIO_MODE_MASK) | + ((param->direction & PM_GPIO_DIR_OUT) ? + PM8058_GPIO_OUT_BUFFER : 0); + bank[2] = PM8058_GPIO_WRITE | + ((2 << PM8058_GPIO_BANK_SHIFT) & PM8058_GPIO_BANK_MASK) | + ((param->pull << PM8058_GPIO_PULL_SHIFT) & + PM8058_GPIO_PULL_MASK); + bank[3] = PM8058_GPIO_WRITE | + ((3 << PM8058_GPIO_BANK_SHIFT) & PM8058_GPIO_BANK_MASK) | + ((param->out_strength << PM8058_GPIO_OUT_STRENGTH_SHIFT) & + PM8058_GPIO_OUT_STRENGTH_MASK); + bank[4] = PM8058_GPIO_WRITE | + ((4 << PM8058_GPIO_BANK_SHIFT) & PM8058_GPIO_BANK_MASK) | + ((param->function << PM8058_GPIO_FUNC_SHIFT) & + PM8058_GPIO_FUNC_MASK); + + rc = (*wr_function)(bank, 5, SSBI_REG_ADDR_GPIO(gpio)); + if (rc) { + dprintf(INFO, "Failed on 1st ssbi_write(): rc=%d.\n", rc); + return 1; + } + return 0; +} + +int pm8058_gpio_config_kypd_drv(int gpio_start, int num_gpios) +{ + int rc; + struct pm8058_gpio kypd_drv = { + .direction = PM_GPIO_DIR_OUT, + .pull = PM_GPIO_PULL_NO, + .vin_sel = 2, + .out_strength = PM_GPIO_STRENGTH_LOW, + .function = PM_GPIO_FUNC_1, + .inv_int_pol = 1, + }; + + while (num_gpios--) { + rc = pm8058_gpio_config(gpio_start++, &kypd_drv); + if (rc) { + dprintf(INFO, "FAIL pm8058_gpio_config(): rc=%d.\n", rc); + return rc; + } + } + + return 0; +} + +int pm8058_gpio_config_kypd_sns(int gpio_start, int num_gpios) +{ + int rc; + struct pm8058_gpio kypd_sns = { + .direction = PM_GPIO_DIR_IN, + .pull = PM_GPIO_PULL_UP1, + .vin_sel = 2, + .out_strength = PM_GPIO_STRENGTH_NO, + .function = PM_GPIO_FUNC_NORMAL, + .inv_int_pol = 1, + }; + + while (num_gpios--) { + rc = pm8058_gpio_config(gpio_start++, &kypd_sns); + if (rc) { + dprintf(INFO, "FAIL pm8058_gpio_config(): rc=%d.\n", rc); + return rc; + } + } + + return 0; +} + +void ssbi_gpio_init(void) +{ + unsigned char kypd_cntl_init = 0x84; + unsigned char kypd_scan_init = 0x20; + int rows = (qwerty_keypad->keypad_info)->rows; + int columns = (qwerty_keypad->keypad_info)->columns; + write_func wr_function = (qwerty_keypad->keypad_info)->wr_func; + + if ((*wr_function)(&kypd_cntl_init, 1, SSBI_REG_KYPD_CNTL_ADDR)) + dprintf (CRITICAL, "Error in initializing SSBI_REG_KYPD_CNTL register\n"); + + if ((*wr_function)(&kypd_scan_init, 1, SSBI_REG_KYPD_SCAN_ADDR)) + dprintf (CRITICAL, "Error in initializing SSBI_REG_KYPD_SCAN register\n"); + + pm8058_gpio_config_kypd_sns(SSBI_OFFSET_ADDR_GPIO_KYPD_SNS, columns); + pm8058_gpio_config_kypd_drv(SSBI_OFFSET_ADDR_GPIO_KYPD_DRV, rows); +} + +static enum handler_return +scan_qwerty_keypad(struct timer *timer, time_t now, void *arg) +{ + unsigned int rows = (qwerty_keypad->keypad_info)->rows; + unsigned int columns = (qwerty_keypad->keypad_info)->columns; + unsigned int num_of_ssbi_reads = (qwerty_keypad->keypad_info)->num_of_reads; + read_func rd_function = (qwerty_keypad->keypad_info)->rd_func; + unsigned char column_new_keys = 0x00; + unsigned char column_old_keys = 0x00; + int shift = 0; + static int key_detected = 0; + + if ((*rd_function)((qwerty_keypad->keypad_info)->rec_keys, num_of_ssbi_reads, + SSBI_REG_KYPD_REC_DATA_ADDR)) + dprintf (CRITICAL, "Error in initializing SSBI_REG_KYPD_CNTL register\n"); + + if ((*rd_function)((qwerty_keypad->keypad_info)->old_keys, num_of_ssbi_reads, + SSBI_REG_KYPD_OLD_DATA_ADDR)) + dprintf (CRITICAL, "Error in initializing SSBI_REG_KYPD_CNTL register\n"); + + while (rows--) { + if (((qwerty_keypad->keypad_info)->rec_keys[rows] + != (qwerty_keypad->keypad_info)->old_keys[rows]) + && ((qwerty_keypad->keypad_info)->rec_keys[rows] != 0x00) + && ((qwerty_keypad->keypad_info)->old_keys[rows] != 0x00)) { + while (columns--) { + column_new_keys = ((qwerty_keypad->keypad_info)->rec_keys[rows]); + column_old_keys = ((qwerty_keypad->keypad_info)->old_keys[rows]); + if (((0x01 << columns) & (~column_new_keys)) + && !((0x01 << columns) & (~column_old_keys))) { + shift = (rows * 8) + columns; + if ((qwerty_keypad->keypad_info)->keymap[shift]) { + if (shift != key_detected) { + key_detected = shift; + keys_post_event((qwerty_keypad->keypad_info)->keymap[shift], 1); + event_signal(&qwerty_keypad->full_scan, false); + timer_set_oneshot(timer, (qwerty_keypad->keypad_info)->poll_time, + scan_qwerty_keypad, NULL); + return INT_RESCHEDULE; + + } + } + } + } + } + } + if (qwerty_keypad->num_of_scans < 10) + { + (qwerty_keypad->num_of_scans)++; + timer_set_oneshot(timer, (qwerty_keypad->keypad_info)->settle_time, + scan_qwerty_keypad, NULL); + return INT_RESCHEDULE; + } + + event_signal(&qwerty_keypad->full_scan, false); + return INT_RESCHEDULE; + +} + +void ssbi_keypad_init(struct qwerty_keypad_info *qwerty_kp) +{ + int len; + + len = sizeof(struct gpio_qwerty_kp); + qwerty_keypad = malloc(len); + ASSERT(qwerty_keypad); + + memset(qwerty_keypad, 0, len); + qwerty_keypad->keypad_info = qwerty_kp; + ssbi_gpio_init(); + + qwerty_keypad->num_of_scans = 0; + + event_init(&qwerty_keypad->full_scan, false, EVENT_FLAG_AUTOUNSIGNAL); + timer_initialize(&qwerty_keypad->timer); + timer_set_oneshot(&qwerty_keypad->timer, 0, scan_qwerty_keypad, NULL); + + /* wait for the keypad to complete one full scan */ + event_wait(&qwerty_keypad->full_scan); +} + +void pmic_write(unsigned address, unsigned data) +{ + write_func wr_function = &i2c_ssbi_write_bytes; + if(wr_function == NULL) + return; + if ((*wr_function)(&data, 1, address)) + dprintf (CRITICAL, "Error in initializing register\n"); + +} +void toshiba_pmic_gpio_init(unsigned gpio) +{ + pmic_write(gpio,0x85); + pmic_write(gpio,0x98); + pmic_write(gpio,0xB8); + pmic_write(gpio,0xC6); +} diff --git a/lk/dev/keys/keys.c b/lk/dev/keys/keys.c new file mode 100644 index 0000000..3e7c452 --- /dev/null +++ b/lk/dev/keys/keys.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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. + */ + +#include +#include +#include +#include + +static unsigned long key_bitmap[BITMAP_NUM_WORDS(MAX_KEYS)]; + +void keys_init(void) +{ + memset(key_bitmap, 0, sizeof(key_bitmap)); +} + +void keys_post_event(uint16_t code, int16_t value) +{ + if (code >= MAX_KEYS) { + dprintf(INFO, "Invalid keycode posted: %d\n", code); + return; + } + + /* TODO: Implement an actual event queue if it becomes necessary */ + if (value) + bitmap_set(key_bitmap, code); + else + bitmap_clear(key_bitmap, code); + +// dprintf(INFO, "key state change: %d %d\n", code, value); +} + +int keys_get_state(uint16_t code) +{ + if (code >= MAX_KEYS) { + dprintf(INFO, "Invalid keycode requested: %d\n", code); + return -1; + } + return bitmap_test(key_bitmap, code); +} diff --git a/lk/dev/keys/rules.mk b/lk/dev/keys/rules.mk new file mode 100644 index 0000000..1e27527 --- /dev/null +++ b/lk/dev/keys/rules.mk @@ -0,0 +1,10 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/keys.o + +ifeq ($(KEYS_USE_GPIO_KEYPAD),1) +OBJS += \ + $(LOCAL_DIR)/gpio_keypad.o +endif + diff --git a/lk/dev/net/smc91c96/include/dev/net/smc91c96.h b/lk/dev/net/smc91c96/include/dev/net/smc91c96.h new file mode 100644 index 0000000..acd543e --- /dev/null +++ b/lk/dev/net/smc91c96/include/dev/net/smc91c96.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 _DEV_NET_SMC91C96_H +#define _DEV_NET_SMC91C96_H + +void smc91c96_init(void); + +#endif + diff --git a/lk/dev/net/smc91c96/rules.mk b/lk/dev/net/smc91c96/rules.mk new file mode 100644 index 0000000..d675117 --- /dev/null +++ b/lk/dev/net/smc91c96/rules.mk @@ -0,0 +1,8 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += \ + -I$(LOCAL_DIR)/include + +OBJS += \ + $(LOCAL_DIR)/smc91c96.o + diff --git a/lk/dev/net/smc91c96/smc91c96.c b/lk/dev/net/smc91c96/smc91c96.c new file mode 100644 index 0000000..0bab5d7 --- /dev/null +++ b/lk/dev/net/smc91c96/smc91c96.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 "smc91c96_p.h" + +#if !defined(SMC91C96_BASE_ADDR) || !defined(SMC91C96_IRQ) +#error need to define SMC91C96_BASE_ADDR and SMC91C96_IRQ in project +#endif + +static addr_t smc91c96_base = SMC91C96_BASE_ADDR; +static uint8_t mac_addr[6]; + +#define SMC_REG16(reg) ((volatile uint16_t *)(smc91c96_base + (reg))) +#define SMC_REG8(reg) ((volatile uint8_t *)(smc91c96_base + (reg))) + +static inline void smc_bank(int bank) +{ + *SMC_REG16(SMC_BSR) = bank; +} + +void smc91c96_init(void) +{ + int i; + + TRACE; + + // try to detect it + if ((*SMC_REG16(SMC_BSR) & 0xff00) != 0x3300) { + TRACEF("didn't see smc91c96 chip at 0x%x\n", (unsigned int)smc91c96_base); + } + + // read revision + smc_bank(3); + TRACEF("detected, revision 0x%x\n", *SMC_REG16(SMC_REV)); + + // read in the mac address + smc_bank(1); + for (i=0; i < 6; i++) { + mac_addr[i] = *SMC_REG8(SMC_IAR0 + i); + } + TRACEF("mac address %02x:%02x:%02x:%02x:%02x:%02x\n", + mac_addr[0], mac_addr[1], mac_addr[2], + mac_addr[3], mac_addr[4], mac_addr[5]); + + smc_bank(0); +} + diff --git a/lk/dev/net/smc91c96/smc91c96_p.h b/lk/dev/net/smc91c96/smc91c96_p.h new file mode 100644 index 0000000..0baf210 --- /dev/null +++ b/lk/dev/net/smc91c96/smc91c96_p.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __SMC91C96_P_H +#define __SMC91C96_P_H + +// LAN91C96 stuffs + +/* registers */ + +#define SMC_BSR 14 + +/* bank 0 */ +#define SMC_TCR 0 +#define SMC_EPHSR 2 +#define SMC_RCR 4 +#define SMC_ECR 6 +#define SMC_MIR 8 +#define SMC_MCR 10 + +/* bank 1 */ +#define SMC_CR 0 +#define SMC_BAR 2 +#define SMC_IAR0 4 +#define SMC_IAR1 5 +#define SMC_IAR2 6 +#define SMC_IAR3 7 +#define SMC_IAR4 8 +#define SMC_IAR5 9 +#define SMC_GPR 10 +#define SMC_CTR 12 + +/* bank 2 */ +#define SMC_MMUCR 0 +#define SMC_AUTOTX 1 +#define SMC_PNR 2 +#define SMC_ARR 3 +#define SMC_FIFO 4 +#define SMC_PTR 6 +#define SMC_DATA0 8 +#define SMC_DATA1 10 +#define SMC_IST 12 +#define SMC_ACK 12 +#define SMC_MSK 13 + +/* bank 3 */ +#define SMC_MT0 0 +#define SMC_MT1 1 +#define SMC_MT2 2 +#define SMC_MT3 3 +#define SMC_MT4 4 +#define SMC_MT5 5 +#define SMC_MT6 6 +#define SMC_MT7 7 +#define SMC_MGMT 8 +#define SMC_REV 10 +#define SMC_ERCV 12 + + +#endif + diff --git a/lk/dev/pmic/twl4030/include/dev/twl4030.h b/lk/dev/pmic/twl4030/include/dev/twl4030.h new file mode 100644 index 0000000..f863221 --- /dev/null +++ b/lk/dev/pmic/twl4030/include/dev/twl4030.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __DEV_TWL4030_H +#define __DEV_TWL4030_H + +#include + +void twl4030_init(void); + +/* USB parts of the pmic */ +int twl4030_usb_reset(void); +int twl4030_set_usb_pullup(bool pullup); +int twl4030_init_hs(void); + +#endif + diff --git a/lk/dev/pmic/twl4030/rules.mk b/lk/dev/pmic/twl4030/rules.mk new file mode 100644 index 0000000..e75e8ff --- /dev/null +++ b/lk/dev/pmic/twl4030/rules.mk @@ -0,0 +1,7 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include + +OBJS += \ + $(LOCAL_DIR)/twl4030.o + diff --git a/lk/dev/pmic/twl4030/twl4030.c b/lk/dev/pmic/twl4030/twl4030.c new file mode 100644 index 0000000..66058b8 --- /dev/null +++ b/lk/dev/pmic/twl4030/twl4030.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 "twl4030_hw.h" + +// XXX move to target specific setup +#define TWL_I2C_BUS 0 + +void twl4030_init(void) +{ +} + +static int twl4030_usb_write(uint8_t address, uint8_t data) +{ + return i2c_write_reg(TWL_I2C_BUS, TWL_USB_ADDR, address, data); +} + +static int twl4030_usb_read(uint8_t address) +{ + uint8_t data; + + int err = i2c_read_reg(TWL_I2C_BUS, TWL_USB_ADDR, address, &data); + if (err < 0) + return err; + + return data; +} + +static int twl4030_usb_set_bits(uint8_t reg, uint8_t bits) +{ + return twl4030_usb_write(reg + 1, bits); +} + +static int twl4030_usb_clear_bits(uint8_t reg, uint8_t bits) +{ + return twl4030_usb_write(reg + 2, bits); +} + +static void twl4030_i2c_access(bool on) +{ + int val; + + if ((val = twl4030_usb_read(PHY_CLK_CTRL)) >= 0) { + if (on) { + /* enable DPLL to access PHY registers over I2C */ + val |= REQ_PHY_DPLL_CLK; + twl4030_usb_write(PHY_CLK_CTRL, (uint8_t)val); + + while (!(twl4030_usb_read(PHY_CLK_CTRL_STS) & PHY_DPLL_CLK)) { + spin(10); + } + if (!(twl4030_usb_read(PHY_CLK_CTRL_STS) & PHY_DPLL_CLK)) + printf("Timeout setting T2 HSUSB " "PHY DPLL clock\n"); + } else { + /* let ULPI control the DPLL clock */ + val &= ~REQ_PHY_DPLL_CLK; + twl4030_usb_write(PHY_CLK_CTRL, (uint8_t)val); + } + } + return; +} + +int twl4030_usb_reset(void) +{ + TRACE_ENTRY; +#if 0 + twl4030_usb_clear_bits(OTG_CTRL, DMPULLDOWN | DPPULLDOWN); + twl4030_usb_clear_bits(USB_INT_EN_RISE, ~0); + twl4030_usb_clear_bits(USB_INT_EN_FALL, ~0); + twl4030_usb_clear_bits(MCPC_IO_CTRL, ~TXDTYP); + twl4030_usb_set_bits(MCPC_IO_CTRL, TXDTYP); + twl4030_usb_clear_bits(OTHER_FUNC_CTRL, (BDIS_ACON_EN | FIVEWIRE_MODE)); + twl4030_usb_clear_bits(OTHER_IFC_CTRL, ~0); + twl4030_usb_clear_bits(OTHER_INT_EN_RISE, ~0); + twl4030_usb_clear_bits(OTHER_INT_EN_FALL, ~0); + twl4030_usb_clear_bits(OTHER_IFC_CTRL2, ~0); + twl4030_usb_clear_bits(REG_CTRL_EN, ULPI_I2C_CONFLICT_INTEN); + twl4030_usb_clear_bits(OTHER_FUNC_CTRL2, VBAT_TIMER_EN); +#endif + + /* Enable writing to power configuration registers */ + i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, PROTECT_KEY, 0xC0); + i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, PROTECT_KEY, 0x0C); + + /* put VUSB3V1 LDO in active state */ + i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB_DEDICATED2, 0); + + /* input to VUSB3V1 LDO is from VBAT, not VBUS */ + i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB_DEDICATED1, 0x14); + + /* turn on 3.1V regulator */ + i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB3V1_DEV_GRP, 0x20); + i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB3V1_TYPE, 0); + + /* turn on 1.5V regulator */ + i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB1V5_DEV_GRP, 0x20); + i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB1V5_TYPE, 0); + + /* turn on 1.8V regulator */ + i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB1V8_DEV_GRP, 0x20); + i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB1V8_TYPE, 0); + + /* disable access to power configuration registers */ + i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, PROTECT_KEY, 0); + + /* turn on the phy */ + uint8_t pwr = twl4030_usb_read(PHY_PWR_CTRL); + pwr &= ~PHYPWD; + twl4030_usb_write(PHY_PWR_CTRL, pwr); + twl4030_usb_write(PHY_CLK_CTRL, + twl4030_usb_read(PHY_CLK_CTRL) | + (CLOCKGATING_EN | CLK32K_EN)); + + /* set DPLL i2c access mode */ + twl4030_i2c_access(true); + /* set ulpi mode */ + twl4030_usb_clear_bits(IFC_CTRL, CARKITMODE); + twl4030_usb_set_bits(POWER_CTRL, OTG_ENAB); + twl4030_usb_write(FUNC_CTRL, XCVRSELECT_HS); // set high speed mode +// twl4030_usb_write(FUNC_CTRL, XCVRSELECT_FS); // set full speed mode + twl4030_i2c_access(false); + + return 0; +} + +int twl4030_init_hs(void) +{ + return 0; +} + +int twl4030_set_usb_pullup(bool pullup) +{ + TRACE_ENTRY; + + if (pullup) { + twl4030_usb_clear_bits(OTG_CTRL, DPPULLDOWN); + twl4030_usb_set_bits(FUNC_CTRL, TERMSELECT); + } else { + twl4030_usb_clear_bits(FUNC_CTRL, TERMSELECT); + twl4030_usb_set_bits(OTG_CTRL, DPPULLDOWN); + } + + return 0; +} + + diff --git a/lk/dev/pmic/twl4030/twl4030_hw.h b/lk/dev/pmic/twl4030/twl4030_hw.h new file mode 100644 index 0000000..d7ea926 --- /dev/null +++ b/lk/dev/pmic/twl4030/twl4030_hw.h @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __TWL4030_HW_H +#define __TWL4030_HW_H + +/* TWL i2c addresses */ +#define TWL_I2C_ADDR0 0x48 +#define TWL_I2C_ADDR1 0x49 +#define TWL_I2C_ADDR2 0x4a +#define TWL_I2C_ADDR3 0x4b + +#define TWL_USB_ADDR TWL_I2C_ADDR0 +#define TWL_INTBR_ADDR TWL_I2C_ADDR1 +#define TWL_PM_RECEIVER_ADDR TWL_I2C_ADDR3 + +/* TWL registers */ +#define PROTECT_KEY 0x44 +#define VAUX1_DEV_GRP 0x72 +#define VAUX1_TYPE 0x73 +#define VAUX1_REMAP 0x74 +#define VAUX1_DEDICATED 0x75 +#define VAUX2_DEV_GRP 0x76 +#define VAUX2_TYPE 0x77 +#define VAUX2_REMAP 0x78 +#define VAUX2_DEDICATED 0x79 +#define VAUX3_DEV_GRP 0x7a +#define VAUX3_TYPE 0x7b +#define VAUX3_REMAP 0x7c +#define VAUX3_DEDICATED 0x7d +#define VAUX4_DEV_GRP 0x7e +#define VAUX4_TYPE 0x7f +#define VAUX4_REMAP 0x80 +#define VAUX4_DEDICATED 0x81 +#define VMMC1_DEV_GRP 0x82 +#define VMMC1_TYPE 0x83 +#define VMMC1_REMAP 0x84 +#define VMMC1_DEDICATED 0x85 +#define VMMC2_DEV_GRP 0x86 +#define VMMC2_TYPE 0x87 +#define VMMC2_REMAP 0x88 +#define VMMC2_DEDICATED 0x89 +#define VPLL1_DEV_GRP 0x8a +#define VPLL1_TYPE 0x8b +#define VPLL1_REMAP 0x8c +#define VPLL1_DEDICATED 0x8d +#define VPLL2_DEV_GRP 0x8e +#define VPLL2_TYPE 0x8f +#define VPLL2_REMAP 0x90 +#define VPLL2_DEDICATED 0x91 +#define VDAC_DEV_GRP 0x96 +#define VDAC_DEDICATED 0x99 +#define VDD2_DEV_GRP 0xBE +#define VDD2_TYPE 0xBF +#define VDD2_REMAP 0xC0 +#define VDD2_CFG 0xC1 +#define VSIM_DEV_GRP 0x92 +#define VSIM_TYPE 0x93 +#define VSIM_REMAP 0x94 +#define VSIM_DEDICATED 0x95 +#define PMBR1 0x92 + +#define SECONDS_REG 0x1C +#define MINUTES_REG 0x1D +#define ALARM_SECONDS_REG 0x23 +#define ALARM_MINUTES_REG 0x24 +#define ALARM_HOURS_REG 0x25 + +#define RTC_STATUS_REG 0x2A +#define RTC_INTERRUPTS_REG 0x2B + +#define PWR_ISR1 0x2E +#define PWR_IMR1 0x2F +#define PWR_ISR2 0x30 +#define PWR_IMR2 0x31 +#define PWR_EDR1 0x33 + +#define CFG_PWRANA2 0x3F +#define RTC_INTERRUPTS_REG 0x2B +#define STS_HW_CONDITIONS 0x45 + +#define P1_SW_EVENTS 0x46 +#define P2_SW_EVENTS 0x47 +#define P3_SW_EVENTS 0x48 + +#define VDD1_TRIM1 0x62 +#define VDD1_TRIM2 0x63 +#define VDD1_VFLOOR 0xBB +#define VDD1_VROOF 0xBC +#define PB_CFG 0x4A +#define PB_WORD_MSB 0x4B +#define PB_WORD_LSB 0x4C + +#define VSIM_REMAP 0x94 +#define VDAC_REMAP 0x98 +#define VINTANA1_DEV_GRP 0x9A +#define VINTANA1_REMAP 0x9C +#define VINTANA2_REMAP 0xA0 +#define VINTANA2_DEV_GRP 0x9E +#define VINTDIG_DEV_GRP 0xA2 +#define VINTDIG_REMAP 0xA4 +#define VIO_DEV_GRP 0xA6 +#define VIO_REMAP 0xA8 +#define VDD1_REMAP 0xB2 +#define VDD2_REMAP 0xC0 +#define REGEN_REMAP 0xDC +#define NRESPWRON_REMAP 0xDF +#define CLKEN_REMAP 0xE2 +#define SYSEN_REMAP 0xE5 +#define HFCLKOUT_REMAP 0xE8 +#define HFCLKOUT_DEV_GRP 0xE6 +#define T32KCLKOUT_REMAP 0xEB +#define TRITON_RESET_REMAP 0xEE +#define MAINREF_REMAP 0xF1 +#define VIBRA_CTL 0x45 + + +#define VUSB1V5_DEV_GRP 0xCC +#define VUSB1V5_TYPE 0xCD +#define VUSB1V5_REMAP 0xCE +#define VUSB1V8_DEV_GRP 0xCF +#define VUSB1V8_TYPE 0xD0 +#define VUSB1V8_REMAP 0xD1 +#define VUSB3V1_DEV_GRP 0xD2 +#define VUSB3V1_TYPE 0xD3 +#define VUSB3V1_REMAP 0xD4 +#define VUSBCP_DEV_GRP 0xD5 +#define VUSBCP_TYPE 0xD6 +#define VUSBCP_REMAP 0xD7 +#define VUSB_DEDICATED1 0xD8 +#define VUSB_DEDICATED2 0xD9 + +/* USB registers */ +#define VENDOR_ID_LO 0x0 +#define VENDOR_ID_HI 0x1 +#define PRODUCT_ID_LO 0x2 +#define PRODUCT_ID_HI 0x3 +#define FUNC_CTRL 0x4 +#define FUNC_CTRL_SET 0x5 +#define FUNC_CTRL_CLR 0x6 +# define SUSPENDM (1 << 6) +# define RESET (1 << 5) +# define OPMODE_MASK (3 << 3) /* bits 3 and 4 */ +# define OPMODE_NORMAL (0 << 3) +# define OPMODE_NONDRIVING (1 << 3) +# define OPMODE_DISABLE_BIT_NRZI (2 << 3) +# define TERMSELECT (1 << 2) +# define XCVRSELECT_MASK (3 << 0) /* bits 0 and 1 */ +# define XCVRSELECT_HS (0 << 0) +# define XCVRSELECT_FS (1 << 0) +# define XCVRSELECT_LS (2 << 0) +# define XCVRSELECT_FS4LS (3 << 0) +#define IFC_CTRL 0x7 +#define IFC_CTRL_SET 0x8 +#define IFC_CTRL_CLR 0x9 +# define INTERFACE_PROTECT_DISABLE (1 << 7) +# define AUTORESUME (1 << 4) +# define CLOCKSUSPENDM (1 << 3) +# define CARKITMODE (1 << 2) +# define FSLSSERIALMODE_3PIN (1 << 1) +#define OTG_CTRL 0xa +#define OTG_CTRL_SET 0xb +#define OTG_CTRL_CLR 0xc +#define DRVVBUS (1 << 5) +#define CHRGVBUS (1 << 4) +#define DISCHRGVBUS (1 << 3) +#define DMPULLDOWN (1 << 2) +#define DPPULLDOWN (1 << 1) +#define IDPULLUP (1 << 0) +#define USB_INT_EN_RISE 0xd +#define USB_INT_EN_RISE_SET 0xe +#define USB_INT_EN_RISE_CLR 0xf +#define USB_INT_EN_FALL 0x10 +#define USB_INT_EN_FALL_SET 0x11 +#define USB_INT_EN_FALL_CLR 0x12 +# define HOSTDISCONNECT (1 << 0) +#define USB_INT_STS 0x13 +#define USB_INT_LATCH 0x14 +#define USB_DEBUG 0x15 +#define SCRATCH_REG 0x16 +#define SCRATCH_REG_SET 0x17 +#define SCRATCH_REG_CLR 0x18 +#define CARKIT_CTRL 0x19 +#define CARKIT_CTRL_SET 0x1a +#define CARKIT_CTRL_CLR 0x1b +#define MICEN (1 << 6) +#define SPKRIGHTEN (1 << 5) +#define SPKLEFTEN (1 << 4) +#define RXDEN (1 << 3) +#define TXDEN (1 << 2) +#define IDGNDDRV (1 << 1) +#define CARKITPWR (1 << 0) +#define CARKIT_INT_DELAY 0x1c +#define CARKIT_INT_EN 0x1d +#define CARKIT_INT_EN_SET 0x1e +#define CARKIT_INT_EN_CLR 0x1f +#define CARKIT_INT_STS 0x20 +#define CARKIT_INT_LATCH 0x21 +#define CARKIT_PLS_CTRL 0x22 +#define CARKIT_PLS_CTRL_SET 0x23 +#define CARKIT_PLS_CTRL_CLR 0x24 +# define SPKRRIGHT_BIASEN (1 << 3) +# define SPKRLEFT_BIASEN (1 << 2) +# define RXPLSEN (1 << 1) +# define TXPLSEN (1 << 0) +#define TRANS_POS_WIDTH 0x25 +#define TRANS_NEG_WIDTH 0x26 +#define RCV_PLTY_RECOVERY 0x27 +#define MCPC_CTRL 0x30 +#define MCPC_CTRL_SET 0x31 +#define MCPC_CTRL_CLR 0x32 +#define RTSOL (1 << 7) +#define EXTSWR (1 << 6) +#define EXTSWC (1 << 5) +#define VOICESW (1 << 4) +#define OUT64K (1 << 3) +#define RTSCTSSW (1 << 2) +#define HS_UART (1 << 0) +#define MCPC_IO_CTRL 0x033 +#define MCPC_IO_CTRL_SET 0x034 +#define MCPC_IO_CTRL_CLR 0x035 +#define MICBIASEN (1<< 5) +#define CTS_NPU (1 << 4) +#define RXD_PU (1 << 3) +#define TXDTYP (1 << 2) +#define CTSTYP (1 << 1) +#define RTSTYP (1 << 0) +#define MCPC_CTRL2 0x036 +#define MCPC_CTRL2_SET 0x037 +#define MCPC_CTRL2_CLR 0x038 +# define MCPC_CK_EN (1 << 0) +#define OTHER_FUNC_CTRL 0x080 +#define OTHER_FUNC_CTRL_SET 0x081 +#define OTHER_FUNC_CTRL_CLR 0x082 +#define BDIS_ACON_EN (1<< 4) +#define FIVEWIRE_MODE (1 << 2) +#define OTHER_IFC_CTRL 0x083 +#define OTHER_IFC_CTRL_SET 0x084 +#define OTHER_IFC_CTRL_CLR 0x085 +# define OE_INT_EN (1 << 6) +# define CEA2011_MODE (1 << 5) +# define FSLSSERIALMODE_4PIN (1 << 4) +# define HIZ_ULPI_60MHZ_OUT (1 << 3) +# define HIZ_ULPI (1 << 2) +# define ALT_INT_REROUTE (1 << 0) +#define OTHER_INT_EN_RISE 0x086 +#define OTHER_INT_EN_RISE_SET 0x087 +#define OTHER_INT_EN_RISE_CLR 0x088 +#define OTHER_INT_EN_FALL 0x089 +#define OTHER_INT_EN_FALL_SET 0x08A +#define OTHER_INT_EN_FALL_CLR 0x08B +#define OTHER_INT_STS 0x8C +#define OTHER_INT_LATCH 0x8D +#define ID_INT_EN_RISE 0x08E +#define ID_INT_EN_RISE_SET 0x08F +#define ID_INT_EN_RISE_CLR 0x090 +#define ID_INT_EN_FALL 0x091 +#define ID_INT_EN_FALL_SET 0x092 +#define ID_INT_EN_FALL_CLR 0x093 +#define ID_INT_STS 0x094 +#define ID_INT_LATCH 0x95 +#define ID_STATUS 0x96 +#define CARKIT_SM_1_INT_EN 0x097 +#define CARKIT_SM_1_INT_EN_SET 0x098 +#define CARKIT_SM_1_INT_EN_CLR 0x099 +#define CARKIT_SM_1_INT_STS 0x09A +#define CARKIT_SM_1_INT_LATCH 0x9B +#define CARKIT_SM_2_INT_EN 0x09C +#define CARKIT_SM_2_INT_EN_SET 0x09D +#define CARKIT_SM_2_INT_EN_CLR 0x09E +#define CARKIT_SM_2_INT_STS 0x09F +#define CARKIT_SM_2_INT_LATCH 0xA0 +#define CARKIT_SM_CTRL 0x0A1 +#define CARKIT_SM_CTRL_SET 0x0A2 +#define CARKIT_SM_CTRL_CLR 0x0A3 +#define CARKIT_SM_CMD 0x0A4 +#define CARKIT_SM_CMD_SET 0x0A5 +#define CARKIT_SM_CMD_CLR 0x0A6 +#define CARKIT_SM_CMD_STS 0xA7 +#define CARKIT_SM_STATUS 0xA8 +#define CARKIT_SM_NEXT_STATUS 0xA9 +#define CARKIT_SM_ERR_STATUS 0xAA +#define CARKIT_SM_CTRL_STATE 0xAB +#define POWER_CTRL 0xAC +#define POWER_CTRL_SET 0xAD +#define POWER_CTRL_CLR 0xAE +# define OTG_ENAB (1 << 5) +#define OTHER_IFC_CTRL2 0xAF +#define OTHER_IFC_CTRL2_SET 0xB0 +#define OTHER_IFC_CTRL2_CLR 0xB1 +# define ULPI_TXEN_POL (1 << 3) +# define ULPI_4PIN_2430 (1 << 2) +#define REG_CTRL_EN 0xB2 +#define REG_CTRL_EN_SET 0xB3 +#define REG_CTRL_EN_CLR 0xB4 +#define REG_CTRL_ERROR 0xB5 +#define ULPI_I2C_CONFLICT_INTEN (1 << 0) +#define OTHER_FUNC_CTRL2 0xB8 +#define OTHER_FUNC_CTRL2_SET 0xB9 +#define OTHER_FUNC_CTRL2_CLR 0xBA +#define VBAT_TIMER_EN (1 << 0) +#define CARKIT_ANA_CTRL 0xBB +#define CARKIT_ANA_CTRL_SET 0xBC +#define CARKIT_ANA_CTRL_CLR 0xBD +#define VBUS_DEBOUNCE 0xC0 +#define ID_DEBOUNCE 0xC1 +#define TPH_DP_CON_MIN 0xC2 +#define TPH_DP_CON_MAX 0xC3 +#define TCR_DP_CON_MIN 0xC4 +#define TCR_DP_CON_MAX 0xC5 +#define TPH_DP_PD_SHORT 0xC6 +#define TPH_CMD_DLY 0xC7 +#define TPH_DET_RST 0xC8 +#define TPH_AUD_BIAS 0xC9 +#define TCR_UART_DET_MIN 0xCA +#define TCR_UART_DET_MAX 0xCB +#define TPH_ID_INT_PW 0xCD +#define TACC_ID_INT_WAIT 0xCE +#define TACC_ID_INT_PW 0xCF +#define TPH_CMD_WAIT 0xD0 +#define TPH_ACK_WAIT 0xD1 +#define TPH_DP_DISC_DET 0xD2 +#define VBAT_TIMER 0xD3 +#define CARKIT_4W_DEBUG 0xE0 +#define CARKIT_5W_DEBUG 0xE1 +#define CARKIT_5W_DEBUG 0xE1 +#define TEST_CTRL_CLR 0xEB +#define TEST_CARKIT_SET 0xEC +#define TEST_CARKIT_CLR 0xED +#define TEST_POWER_SET 0xEE +#define TEST_POWER_CLR 0xEF +#define TEST_ULPI 0xF0 +#define TXVR_EN_TEST_SET 0xF2 +#define TXVR_EN_TEST_CLR 0xF3 +#define VBUS_EN_TEST 0xF4 +#define ID_EN_TEST 0xF5 +#define PSM_EN_TEST_SET 0xF6 +#define PSM_EN_TEST_CLR 0xF7 +#define PHY_TRIM_CTRL 0xFC +#define PHY_PWR_CTRL 0xFD +# define PHYPWD (1 << 0) +#define PHY_CLK_CTRL 0xFE +# define CLOCKGATING_EN (1 << 2) +# define CLK32K_EN (1 << 1) +# define REQ_PHY_DPLL_CLK (1 << 0) +#define PHY_CLK_CTRL_STS 0xFF +# define PHY_DPLL_CLK (1 << 0) + +#endif + diff --git a/lk/dev/rules.mk b/lk/dev/rules.mk new file mode 100644 index 0000000..cbc5ba7 --- /dev/null +++ b/lk/dev/rules.mk @@ -0,0 +1,5 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/dev.o + diff --git a/lk/dev/usb/rules.mk b/lk/dev/usb/rules.mk new file mode 100644 index 0000000..649f0c4 --- /dev/null +++ b/lk/dev/usb/rules.mk @@ -0,0 +1,5 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/usb.o + diff --git a/lk/dev/usb/usb.c b/lk/dev/usb/usb.c new file mode 100644 index 0000000..1b1661d --- /dev/null +++ b/lk/dev/usb/usb.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include + +#define LOCAL_TRACE 0 + +#define MAX_STRINGS 8 +static usb_string strings[MAX_STRINGS]; + +static usb_config *config; + +static uint8_t active_config; +static bool usb_active = false; + +static void append_desc_data(usb_descriptor *desc, const void *dat, size_t len) +{ + uint8_t *ptr = malloc(desc->len + len); + + memcpy(ptr, desc->desc, desc->len); + memcpy(ptr + desc->len, dat, len); + free(desc->desc); + desc->desc = ptr; + desc->len += len; +} + +/* returns the interface number assigned */ +static int usb_append_interface(usb_descriptor *desc, const uint8_t *int_descr, size_t len) +{ + uint8_t *ptr = malloc(len); + int interface_num; + + // create a temporary copy of the interface + memcpy(ptr, int_descr, len); + + // find the last interface used + interface_num = ((uint8_t *)desc->desc)[4]; // current interface + + // patch our interface descriptor with the new id + ptr[2] = interface_num; + + // append it to our config desriptor + append_desc_data(desc, ptr, len); + free(ptr); + + // patch the total length of the config descriptor and set the number of interfaces + ((uint16_t *)desc->desc)[1] += len; + interface_num++; + ((uint8_t *)desc->desc)[4] = interface_num; + + return interface_num - 1; +} + +int usb_append_interface_highspeed(const uint8_t *int_descr, size_t len) +{ + return usb_append_interface(&config->highspeed.config, int_descr, len); +} + +int usb_append_interface_lowspeed(const uint8_t *int_descr, size_t len) +{ + return usb_append_interface(&config->lowspeed.config, int_descr, len); +} + +void usb_set_string_descriptor(usb_descriptor *desc, const char *string) +{ + int len = strlen(string); + ushort *data; + int datalen = len * 2 + 2; + + data = malloc(datalen); + + /* write length field */ + data[0] = 0x0300 + datalen; + + /* copy the string into the uint16_t based usb string */ + int i; + for (i = 0; i < len; i++) { + data[i + 1] = string[i]; + } + + desc->desc = (void *)data; + desc->len = datalen; +} + +static void set_usb_id(uint16_t vendor, uint16_t product) +{ + // patch the current configuration to with the vendor/product id + ((uint16_t *)config->lowspeed.device.desc)[4] = vendor; + ((uint16_t *)config->lowspeed.device.desc)[5] = product; + + ((uint16_t *)config->highspeed.device.desc)[4] = vendor; + ((uint16_t *)config->highspeed.device.desc)[5] = product; +} + +void usb_add_string(const char *string, uint8_t id) +{ + uint i; + size_t len = strlen(string); + uint16_t *strbuf = malloc(len * 2 + 2); + + /* build the usb string descriptor */ + strbuf[0] = 0x300 | (len * 2 + 2); + for (i = 0; i < len; i++) { + strbuf[i + 1] = (uint16_t)string[i]; + } + + /* find a slot to put it */ + for (i = 0; i < MAX_STRINGS; i++) { + if (strings[i].id == 0) { + strings[i].string.desc = strbuf; + strings[i].string.len = len * 2 + 2; + strings[i].id = id; + break; + } + } +} + +static int default_usb_callback(usbc_callback_op_t op, const union usb_callback_args *args) +{ + LTRACEF("op %d, args %p\n", op, args); + + /* start looking for specific things to handle */ + if (op == CB_SETUP_MSG) { + const struct usb_setup *setup = args->setup; + DEBUG_ASSERT(setup); + LTRACEF("SETUP: req_type=%#x req=%#x value=%#x index=%#x len=%#x\n", setup->request_type, setup->request, setup->value, setup->index, setup->length); + + if ((setup->request_type & TYPE_MASK) == TYPE_STANDARD) { + switch (setup->request) { + case SET_ADDRESS: + LTRACEF("SET_ADDRESS 0x%x\n", setup->value); + usbc_ep0_ack(); + break; + case SET_FEATURE: + case CLEAR_FEATURE: + // OTAY + LTRACEF("SET/CLEAR_FEATURE, feature 0x%x\n", setup->value); + usbc_ep0_ack(); + break; + case SET_DESCRIPTOR: + LTRACEF("SET_DESCRIPTOR\n"); + usbc_ep0_stall(); + break; + case GET_DESCRIPTOR: { + /* Get the right descriptors based on current speed */ + const struct usb_descriptor_speed *speed; + if (usbc_is_highspeed()) { + speed = &config->highspeed; + } else { + speed = &config->lowspeed; + } + + if ((setup->request_type & RECIP_MASK) == RECIP_DEVICE) { + switch (setup->value) { + case 0x100: /* device */ + LTRACEF("got GET_DESCRIPTOR, device descriptor\n"); + usbc_ep0_send(speed->device.desc, speed->device.len, + setup->length); + break; + case 0x200: /* CONFIGURATION */ + LTRACEF("got GET_DESCRIPTOR, config descriptor\n"); + usbc_ep0_send(speed->config.desc, speed->config.len, + setup->length); + break; + case 0x300: /* Language ID */ + LTRACEF("got GET_DESCRIPTOR, language id\n"); + usbc_ep0_send(config->langid.desc, + config->langid.len, setup->length); + break; + case (0x301)...(0x3ff): { + /* string descriptor, search our list for a match */ + uint i; + bool found = false; + uint8_t id = setup->value & 0xff; + for (i = 0; i < MAX_STRINGS; i++) { + if (strings[i].id == id) { + usbc_ep0_send(strings[i].string.desc, + strings[i].string.len, + setup->length); + found = true; + break; + } + } + if (!found) { + /* couldn't find one, stall */ + usbc_ep0_stall(); + } + break; + } + case 0x600: /* DEVICE QUALIFIER */ + LTRACEF("got GET_DESCRIPTOR, device qualifier\n"); + usbc_ep0_send(speed->device_qual.desc, + speed->device_qual.len, setup->length); + break; + case 0xa00: + /* we aint got one of these */ + LTRACEF("got GET_DESCRIPTOR, debug descriptor\n"); + usbc_ep0_stall(); + break; + default: + LTRACEF("unhandled descriptor %#x\n", setup->value); + // stall + break; + } + } else { + // interface/endpoint descriptors? let someone else handle it + // STALL + } + break; + } + + case SET_CONFIGURATION: + LTRACEF("SET_CONFIGURATION %d\n", setup->value); + active_config = setup->value; + usbc_ep0_ack(); + break; + + case GET_CONFIGURATION: + LTRACEF("GET_CONFIGURATION\n"); + usbc_ep0_send(&active_config, 1, setup->length); + break; + + case SET_INTERFACE: + LTRACEF("SET_INTERFACE %d\n", setup->value); + usbc_ep0_ack(); + break; + + case GET_INTERFACE: { + static uint8_t i = 1; + LTRACEF("GET_INTERFACE\n"); + usbc_ep0_send(&i, 1, setup->length); + break; + } + + case GET_STATUS: { + static uint16_t i = 1; // self powered + LTRACEF("GET_STATUS\n"); + usbc_ep0_send(&i, 2, setup->length); + break; + } + default: + LTRACEF("unhandled standard request 0x%x\n", setup->request); + } + } + } + + return 0; +} + +void usb_setup(usb_config *_config) +{ + ASSERT(_config); + + config = _config; + + ASSERT(usb_active == false); + + // set the default usb control callback handler + usbc_set_callback(&default_usb_callback); +} + +void usb_start(void) +{ + ASSERT(config); + ASSERT(usb_active == false); + + // go online + usbc_set_active(true); + usb_active = true; +} + +void usb_stop(void) +{ + ASSERT(usb_active == true); + + usb_active = false; + usbc_set_active(false); +} + +void usb_init(void) +{ +} + diff --git a/lk/include/app.h b/lk/include/app.h new file mode 100644 index 0000000..f06bf27 --- /dev/null +++ b/lk/include/app.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2009 Travis Geiselbrecht + * + * 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 __APP_H +#define __APP_H + +/* app support api */ +void apps_init(void); /* one time setup */ + +/* app entry point */ +struct app_descriptor; +typedef void (*app_init)(const struct app_descriptor *); +typedef void (*app_entry)(const struct app_descriptor *, void *args); + +/* app startup flags */ +#define APP_FLAG_DONT_START_ON_BOOT 0x1 + +/* each app needs to define one of these to define its startup conditions */ +struct app_descriptor { + const char *name; + app_init init; + app_entry entry; + unsigned int flags; +}; + +#define APP_START(appname) struct app_descriptor _app_##appname __SECTION(".apps") = { .name = #appname, +#define APP_END }; + +#endif + diff --git a/lk/include/arch.h b/lk/include/arch.h new file mode 100644 index 0000000..b9f93b6 --- /dev/null +++ b/lk/include/arch.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ARCH_H +#define __ARCH_H + +#if defined(__cplusplus) +extern "C" { +#endif + +void arch_early_init(void); +void arch_init(void); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/lk/include/arch/ops.h b/lk/include/arch/ops.h new file mode 100644 index 0000000..d5bafd0 --- /dev/null +++ b/lk/include/arch/ops.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ARCH_OPS_H +#define __ARCH_OPS_H + +#ifndef ASSEMBLY + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +void arch_enable_ints(void); +void arch_disable_ints(void); + +int atomic_swap(volatile int *ptr, int val); +int atomic_add(volatile int *ptr, int val); +int atomic_and(volatile int *ptr, int val); +int atomic_or(volatile int *ptr, int val); + +#endif // !ASSEMBLY +#define ICACHE 1 +#define DCACHE 2 +#define UCACHE (ICACHE|DCACHE) +#ifndef ASSEMBLY + +void arch_disable_cache(uint flags); +void arch_enable_cache(uint flags); + +void arch_clean_cache_range(addr_t start, size_t len); +void arch_clean_invalidate_cache_range(addr_t start, size_t len); + +void arch_idle(void); + +void arch_disable_mmu(void); + +void arch_switch_stacks_and_call(addr_t call, addr_t stack) __NO_RETURN; + +#if defined(__cplusplus) +} +#endif + +#endif // !ASSEMBLY + +#if ARCH_ARM +#include +#endif + +#endif diff --git a/lk/include/arch/thread.h b/lk/include/arch/thread.h new file mode 100644 index 0000000..06de51d --- /dev/null +++ b/lk/include/arch/thread.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ARCH_THREAD_H +#define __ARCH_THREAD_H + +// give the arch code a chance to declare the arch_thread struct +#include + +struct thread; + +void arch_thread_initialize(struct thread *); +void arch_context_switch(struct thread *oldthread, struct thread *newthread); + +#endif diff --git a/lk/include/asm.h b/lk/include/asm.h new file mode 100644 index 0000000..dadf2c4 --- /dev/null +++ b/lk/include/asm.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ASM_H +#define __ASM_H + +//#define FUNCTION(x) .global x; .type x,@function; x: +#define FUNCTION(x) .global x; x: + +#endif + diff --git a/lk/include/assert.h b/lk/include/assert.h new file mode 100644 index 0000000..332dfdb --- /dev/null +++ b/lk/include/assert.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ASSERT_H +#define __ASSERT_H + +#include +#include + +#define ASSERT(x) \ + do { if (unlikely(!(x))) { panic("ASSERT FAILED at (%s:%d): %s\n", __FILE__, __LINE__, #x); } } while (0) + +#if DEBUGLEVEL > 1 +#define DEBUG_ASSERT(x) \ + do { if (unlikely(!(x))) { panic("DEBUG ASSERT FAILED at (%s:%d): %s\n", __FILE__, __LINE__, #x); } } while (0) +#else +#define DEBUG_ASSERT(x) \ + do { } while(0) +#endif + +#endif diff --git a/lk/include/bits.h b/lk/include/bits.h new file mode 100644 index 0000000..d60e76f --- /dev/null +++ b/lk/include/bits.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __BITS_H +#define __BITS_H + +#include + +#define clz(x) __builtin_clz(x) + +#define BIT(x, bit) ((x) & (1 << (bit))) +#define BIT_SHIFT(x, bit) (((x) >> (bit)) & 1) +#define BITS(x, high, low) ((x) & (((1<<((high)+1))-1) & ~((1<<(low))-1))) +#define BITS_SHIFT(x, high, low) (((x) >> (low)) & ((1<<((high)-(low)+1))-1)) +#define BIT_SET(x, bit) (((x) & (1 << (bit))) ? 1 : 0) + +#define BITMAP_BITS_PER_WORD (sizeof(unsigned long) * 8) +#define BITMAP_NUM_WORDS(x) (((x) / BITMAP_BITS_PER_WORD) + 1) +#define BITMAP_WORD(x) ((x) / BITMAP_BITS_PER_WORD) +#define BITMAP_BIT_IN_WORD(x) ((x) & (BITMAP_BITS_PER_WORD - 1)) + +static inline int bitmap_set(unsigned long *bitmap, int bit) +{ + unsigned long mask = 1 << BITMAP_BIT_IN_WORD(bit); + return atomic_or((int*)&bitmap[BITMAP_WORD(bit)], mask) & mask ? 1 : 0; +} + +static inline int bitmap_clear(unsigned long *bitmap, int bit) +{ + unsigned long mask = 1 << BITMAP_BIT_IN_WORD(bit); + + return atomic_and((int*)&bitmap[BITMAP_WORD(bit)], ~mask) & mask ? 1:0; +} + +static inline int bitmap_test(unsigned long *bitmap, int bit) +{ + return BIT_SET(bitmap[BITMAP_WORD(bit)], BITMAP_BIT_IN_WORD(bit)); +} + +#endif diff --git a/lk/include/compiler.h b/lk/include/compiler.h new file mode 100644 index 0000000..cd4b243 --- /dev/null +++ b/lk/include/compiler.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __COMPILER_H +#define __COMPILER_H + +#ifndef __ASSEMBLY__ + +#if __GNUC__ +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#define __UNUSED __attribute__((__unused__)) +#define __PACKED __attribute__((packed)) +#define __ALIGNED(x) __attribute__((aligned(x))) +#define __PRINTFLIKE(__fmt,__varargs) __attribute__((__format__ (__printf__, __fmt, __varargs))) +#define __SCANFLIKE(__fmt,__varargs) __attribute__((__format__ (__scanf__, __fmt, __varargs))) +#define __SECTION(x) __attribute((section(x))) +#define __PURE __attribute((pure)) +#define __CONST __attribute((const)) +#define __NO_RETURN __attribute__((noreturn)) +#define __MALLOC __attribute__((malloc)) +#define __WEAK __attribute__((weak)) +#define __GNU_INLINE __attribute__((gnu_inline)) +#define __GET_CALLER(x) __builtin_return_address(0) + +/* look for gcc 3.0 and above */ +#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 0) +#define __ALWAYS_INLINE __attribute__((always_inline)) +#else +#define __ALWAYS_INLINE +#endif + +/* look for gcc 3.1 and above */ +#if !defined(__DEPRECATED) // seems to be built in in some versions of the compiler +#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define __DEPRECATED __attribute((deprecated)) +#else +#define __DEPRECATED +#endif +#endif + +/* look for gcc 3.3 and above */ +#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) +/* the may_alias attribute was introduced in gcc 3.3; before that, there + * was no way to specify aliasiang rules on a type-by-type basis */ +#define __MAY_ALIAS __attribute__((may_alias)) + +/* nonnull was added in gcc 3.3 as well */ +#define __NONNULL(x) __attribute((nonnull x)) +#else +#define __MAY_ALIAS +#define __NONNULL(x) +#endif + +/* look for gcc 3.4 and above */ +#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define __WARN_UNUSED_RESULT __attribute((warn_unused_result)) +#else +#define __WARN_UNUSED_RESULT +#endif + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) +#define __EXTERNALLY_VISIBLE __attribute__((externally_visible)) +#else +#define __EXTERNALLY_VISIBLE +#endif + +#else + +#define likely(x) (x) +#define unlikely(x) (x) +#define __UNUSED +#define __PACKED +#define __ALIGNED(x) +#define __PRINTFLIKE(__fmt,__varargs) +#define __SCANFLIKE(__fmt,__varargs) +#define __SECTION(x) +#define __PURE +#define __CONST +#define __NONNULL(x) +#define __DEPRECATED +#define __WARN_UNUSED_RESULT +#define __ALWAYS_INLINE +#define __MAY_ALIAS +#define __NO_RETURN +#endif + +#endif + +#endif diff --git a/lk/include/ctype.h b/lk/include/ctype.h new file mode 100644 index 0000000..7f9982e --- /dev/null +++ b/lk/include/ctype.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __CTYPE_H +#define __CTYPE_H + +int isalnum(int c); +int isalpha(int c); +int isblank(int c); +int iscntrl(int c); +int isdigit(int c); +int isgraph(int c); +int islower(int c); +int isprint(int c); +int ispunct(int c); +int isspace(int c); +int isupper(int c); +int isxdigit(int c); + +int tolower(int c); +int toupper(int c); + +#endif + diff --git a/lk/include/debug.h b/lk/include/debug.h new file mode 100644 index 0000000..e5ebc19 --- /dev/null +++ b/lk/include/debug.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __DEBUG_H +#define __DEBUG_H + +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(DEBUG) +#define DEBUGLEVEL DEBUG +#else +#define DEBUGLEVEL 2 +#endif + +/* debug levels */ +#define CRITICAL 0 +#define ALWAYS 0 +#define INFO 1 +#define SPEW 2 + +/* output */ +void _dputc(char c); // XXX for now, platform implements +int _dputs(const char *str); +int _dprintf(const char *fmt, ...) __PRINTFLIKE(1, 2); +int _dvprintf(const char *fmt, va_list ap); + +#define dputc(level, str) do { if ((level) <= DEBUGLEVEL) { _dputc(str); } } while (0) +#define dputs(level, str) do { if ((level) <= DEBUGLEVEL) { _dputs(str); } } while (0) +#define dprintf(level, x...) do { if ((level) <= DEBUGLEVEL) { _dprintf(x); } } while (0) +#define dvprintf(level, x...) do { if ((level) <= DEBUGLEVEL) { _dvprintf(x); } } while (0) + +/* input */ +int dgetc(char *c); + +/* systemwide halts */ +void halt(void) __NO_RETURN; + +void _panic(void *caller, const char *fmt, ...) __PRINTFLIKE(2, 3) __NO_RETURN; +#define panic(x...) _panic(__GET_CALLER(), x) + +#define PANIC_UNIMPLEMENTED panic("%s unimplemented\n", __PRETTY_FUNCTION__) + +/* spin the cpu for a period of (short) time */ +void spin(uint32_t usecs); + +/* dump memory */ +void hexdump(const void *ptr, size_t len); +void hexdump8(const void *ptr, size_t len); + +/* trace routines */ +#define TRACE_ENTRY printf("%s: entry\n", __PRETTY_FUNCTION__) +#define TRACE_EXIT printf("%s: exit\n", __PRETTY_FUNCTION__) +#define TRACE_ENTRY_OBJ printf("%s: entry obj %p\n", __PRETTY_FUNCTION__, this) +#define TRACE_EXIT_OBJ printf("%s: exit obj %p\n", __PRETTY_FUNCTION__, this) +#define TRACE printf("%s:%d\n", __PRETTY_FUNCTION__, __LINE__) +#define TRACEF(x...) do { printf("%s:%d: ", __PRETTY_FUNCTION__, __LINE__); printf(x); } while (0) + +/* trace routines that work if LOCAL_TRACE is set */ +#define LTRACE_ENTRY do { if (LOCAL_TRACE) { TRACE_ENTRY; } } while (0) +#define LTRACE_EXIT do { if (LOCAL_TRACE) { TRACE_EXIT; } } while (0) +#define LTRACE do { if (LOCAL_TRACE) { TRACE; } } while (0) +#define LTRACEF(x...) do { if (LOCAL_TRACE) { TRACEF(x); } } while (0) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/lk/include/dev/ethernet.h b/lk/include/dev/ethernet.h new file mode 100644 index 0000000..afb103e --- /dev/null +++ b/lk/include/dev/ethernet.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __DEV_ETHERNET_H +#define __DEV_ETHERNET_H + +/* Queue an ethernet frame for send. +** +** CRC and minimum length padding are handled by the driver. +** +** Data is malloc()'d and ownership is transfered to the ethernet +** device which will free() it once the packet is transmitted. +** +*/ +int ethernet_send(void *data, unsigned length); + +status_t ethernet_init(void); /* initialize the ethernet device */ + +#endif diff --git a/lk/include/dev/fbcon.h b/lk/include/dev/fbcon.h new file mode 100644 index 0000000..ebcf9d7 --- /dev/null +++ b/lk/include/dev/fbcon.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * 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 __DEV_FBCON_H +#define __DEV_FBCON_H + +#define FB_FORMAT_RGB565 0 +#define FB_FORMAT_RGB888 1 + +struct fbcon_config { + void *base; + unsigned width; + unsigned height; + unsigned stride; + unsigned bpp; + unsigned format; + + void (*update_start)(void); + int (*update_done)(void); +}; + +void fbcon_setup(struct fbcon_config *cfg); +void fbcon_putc(char c); +void fbcon_clear(void); +struct fbcon_config* fbcon_display(void); + +#endif /* __DEV_FBCON_H */ diff --git a/lk/include/dev/flash.h b/lk/include/dev/flash.h new file mode 100644 index 0000000..4fa931c --- /dev/null +++ b/lk/include/dev/flash.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2008, Google 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. + * + * 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 __DEV_FLASH_H +#define __DEV_FLASH_H + +#include + + +struct flash_info { + unsigned id; + unsigned type; + unsigned vendor; + unsigned device; + unsigned page_size; + unsigned block_size; + unsigned spare_size; + unsigned num_blocks; +}; + +void flash_init(void); +struct ptable *flash_get_ptable(void); +void flash_set_ptable(struct ptable *ptable); +struct flash_info *flash_get_info(void); + +/* flash operations */ +int flash_erase(struct ptentry *ptn); +int flash_read_ext(struct ptentry *ptn, unsigned extra_per_page, + unsigned offset, void *data, unsigned bytes); +int flash_write(struct ptentry *ptn, unsigned extra_per_page, const void *data, + unsigned bytes); + +static inline int flash_read(struct ptentry *ptn, unsigned offset, void *data, + unsigned bytes) +{ + return flash_read_ext(ptn, 0, offset, data, bytes); +} +unsigned flash_page_size(void); + + +#endif /* __DEV_FLASH_H */ diff --git a/lk/include/dev/gpio.h b/lk/include/dev/gpio.h new file mode 100644 index 0000000..22ca9e4 --- /dev/null +++ b/lk/include/dev/gpio.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2008, Google 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. + * + * 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 __DEV_GPIO_H +#define __DEV_GPIO_H + +#define GPIO_INPUT 0x0000 +#define GPIO_OUTPUT 0x0001 + +#define GPIO_LEVEL 0x0000 +#define GPIO_EDGE 0x0010 + +#define GPIO_RISING 0x0020 +#define GPIO_FALLING 0x0040 + +#define GPIO_HIGH 0x0020 +#define GPIO_LOW 0x0040 + +#define GPIO_PULLUP 0x0100 +#define GPIO_PULLDOWN 0x0200 + +int gpio_config(unsigned nr, unsigned flags); +void gpio_set(unsigned nr, unsigned on); +int gpio_get(unsigned nr); + +#endif diff --git a/lk/include/dev/gpio_keypad.h b/lk/include/dev/gpio_keypad.h new file mode 100644 index 0000000..f467729 --- /dev/null +++ b/lk/include/dev/gpio_keypad.h @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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 __DEV_GPIO_KEYPAD_H +#define __DEV_GPIO_KEYPAD_H + +#include + +/* unset: drive active output low, set: drive active output high */ +#define GPIOKPF_ACTIVE_HIGH (1U << 0) +#define GPIOKPF_DRIVE_INACTIVE (1U << 1) + +struct gpio_keypad_info { + /* size must be ninputs * noutputs */ + const uint16_t *keymap; + unsigned *input_gpios; + unsigned *output_gpios; + int ninputs; + int noutputs; + /* time to wait before reading inputs after driving each output */ + time_t settle_time; + time_t poll_time; + unsigned flags; +}; + +void gpio_keypad_init(struct gpio_keypad_info *kpinfo); + +//Macros for SSBI Qwerty keypad for 7x30 + +/* SSBI 2.0 controller registers */ +#define MSM_SSBI_BASE 0xAD900000 + +#define SSBI_TIMEOUT_US 100 + +#define SSBI2_CTL 0x0000 +#define SSBI2_RESET 0x0004 +#define SSBI2_CMD 0x0008 +#define SSBI2_RD 0x0010 +#define SSBI2_STATUS 0x0014 +#define SSBI2_PRIORITIES 0x0018 +#define SSBI2_MODE2 0x001C + +/* SSBI_CMD fields */ +#define SSBI_CMD_SEND_TERM_SYM (0x01 << 27) +#define SSBI_CMD_WAKEUP_SLAVE (0x01 << 26) +#define SSBI_CMD_USE_ENABLE (0x01 << 25) +#define SSBI_CMD_RDWRN (0x01 << 24) +#define SSBI_CMD_REG_ADDR_SHFT (0x10) +#define SSBI_CMD_REG_ADDR_MASK (0xFF << SSBI_CMD_REG_ADDR_SHFT) +#define SSBI_CMD_REG_DATA_SHFT (0x00) +#define SSBI_CMD_REG_DATA_MASK (0xFF << SSBI_CMD_REG_DATA_SHFT) + +/* SSBI_STATUS fields */ +#define SSBI_STATUS_DATA_IN 0x10 +#define SSBI_STATUS_RD_CLOBBERED 0x08 +#define SSBI_STATUS_RD_READY 0x04 +#define SSBI_STATUS_READY 0x02 +#define SSBI_STATUS_MCHN_BUSY 0x01 + +/* SSBI_RD fields */ +#define SSBI_RD_USE_ENABLE 0x02000000 +#define SSBI_RD_RDWRN 0x01000000 +#define SSBI_RD_REG_ADDR_SHFT 0x10 +#define SSBI_RD_REG_ADDR_MASK (0xFF << SSBI_RD_REG_ADDR_SHFT) +#define SSBI_RD_REG_DATA_SHFT (0x00) +#define SSBI_RD_REG_DATA_MASK (0xFF << SSBI_RD_REG_DATA_SHFT) + +/* SSBI_MODE2 fields */ +#define SSBI_MODE2_REG_ADDR_15_8_SHFT 0x04 +#define SSBI_MODE2_REG_ADDR_15_8_MASK (0x7F << SSBI_MODE2_REG_ADDR_15_8_SHFT) +#define SSBI_MODE2_ADDR_WIDTH_SHFT 0x01 +#define SSBI_MODE2_ADDR_WIDTH_MASK (0x07 << SSBI_MODE2_ADDR_WIDTH_SHFT) +#define SSBI_MODE2_SSBI2_MODE 0x00000001 + +//Keypad controller configurations +#define SSBI_REG_KYPD_CNTL_ADDR 0x148 +#define SSBI_REG_KYPD_SCAN_ADDR 0x149 +#define SSBI_REG_KYPD_TEST_ADDR 0x14A +#define SSBI_REG_KYPD_REC_DATA_ADDR 0x14B +#define SSBI_REG_KYPD_OLD_DATA_ADDR 0x14C + +// GPIO configurations + +#define SSBI_REG_ADDR_GPIO_BASE 0x150 +#define SSBI_OFFSET_ADDR_GPIO_KYPD_SNS 0x000 +#define SSBI_OFFSET_ADDR_GPIO_KYPD_DRV 0x008 +#define SSBI_REG_ADDR_GPIO(n) (SSBI_REG_ADDR_GPIO_BASE + n) + +#define PM_GPIO_DIR_OUT 0x01 +#define PM_GPIO_DIR_IN 0x02 +#define PM_GPIO_DIR_BOTH (PM_GPIO_DIR_OUT | PM_GPIO_DIR_IN) + +#define PM_GPIO_PULL_UP1 2 +#define PM_GPIO_PULL_UP2 3 +#define PM_GPIO_PULL_DN 4 +#define PM_GPIO_PULL_NO 5 + +#define PM_GPIO_STRENGTH_NO 0 +#define PM_GPIO_STRENGTH_HIGH 1 +#define PM_GPIO_STRENGTH_MED 2 +#define PM_GPIO_STRENGTH_LOW 3 + +#define PM_GPIO_FUNC_NORMAL 0 +#define PM_GPIO_FUNC_PAIRED 1 +#define PM_GPIO_FUNC_1 2 +#define PM_GPIO_FUNC_2 3 + +#define PM8058_GPIO_BANK_MASK 0x70 +#define PM8058_GPIO_BANK_SHIFT 4 +#define PM8058_GPIO_WRITE 0x80 + +/* Bank 0 */ +#define PM8058_GPIO_VIN_MASK 0x0E +#define PM8058_GPIO_VIN_SHIFT 1 +#define PM8058_GPIO_MODE_ENABLE 0x01 + +/* Bank 1 */ +#define PM8058_GPIO_MODE_MASK 0x0C +#define PM8058_GPIO_MODE_SHIFT 2 +#define PM8058_GPIO_OUT_BUFFER 0x02 +#define PM8058_GPIO_OUT_INVERT 0x01 + +#define PM8058_GPIO_MODE_OFF 3 +#define PM8058_GPIO_MODE_OUTPUT 2 +#define PM8058_GPIO_MODE_INPUT 0 +#define PM8058_GPIO_MODE_BOTH 1 + +/* Bank 2 */ +#define PM8058_GPIO_PULL_MASK 0x0E +#define PM8058_GPIO_PULL_SHIFT 1 + +/* Bank 3 */ +#define PM8058_GPIO_OUT_STRENGTH_MASK 0x0C +#define PM8058_GPIO_OUT_STRENGTH_SHIFT 2 + +/* Bank 4 */ +#define PM8058_GPIO_FUNC_MASK 0x0E +#define PM8058_GPIO_FUNC_SHIFT 1 + + +/* PMIC Arbiter 1: SSBI2 Configuration Micro ARM registers */ +#define PA1_SSBI2_CMD 0x00500000 +#define PA1_SSBI2_RD_STATUS 0x00500004 + +#define PA1_SSBI2_REG_ADDR_SHIFT 8 +#define PA1_SSBI2_CMD_RDWRN_SHIFT 24 +#define PA1_SSBI2_TRANS_DONE_SHIFT 27 + +#define PA1_SSBI2_REG_DATA_MASK 0xFF +#define PA1_SSBI2_REG_DATA_SHIFT 0 + +#define PA1_SSBI2_CMD_READ 1 +#define PA1_SSBI2_CMD_WRITE 0 + +/* PMIC Arbiter 2: SSBI2 Configuration Micro ARM registers */ +#define PA2_SSBI2_CMD 0x00C00000 +#define PA2_SSBI2_RD_STATUS 0x00C00004 + +#define PA2_SSBI2_REG_ADDR_SHIFT 8 +#define PA2_SSBI2_CMD_RDWRN_SHIFT 24 +#define PA2_SSBI2_TRANS_DONE_SHIFT 27 + +#define PA2_SSBI2_REG_DATA_MASK 0xFF +#define PA2_SSBI2_REG_DATA_SHIFT 0 + +#define PA2_SSBI2_CMD_READ 1 +#define PA2_SSBI2_CMD_WRITE 0 + +struct pm8058_gpio { + int direction; + int pull; + int vin_sel; /* 0..7 */ + int out_strength; + int function; + int inv_int_pol; /* invert interrupt polarity */ +}; + +typedef int (*read_func)(unsigned char *, unsigned short, unsigned short); +typedef int (*write_func)(unsigned char *, unsigned short, unsigned short); + +struct qwerty_keypad_info { + /* size must be ninputs * noutputs */ + unsigned int *keymap; + unsigned char *old_keys; + unsigned char *rec_keys; + unsigned int rows; + unsigned int columns; + unsigned int num_of_reads; + read_func rd_func; + write_func wr_func; + /* time to wait before reading inputs after driving each output */ + time_t settle_time; + time_t poll_time; + unsigned flags; +}; + +#define SSBI_CMD_READ(AD) \ + (SSBI_CMD_RDWRN | (((AD) & 0xFF) << SSBI_CMD_REG_ADDR_SHFT)) + +#define SSBI_CMD_WRITE(AD, DT) \ + ((((AD) & 0xFF) << SSBI_CMD_REG_ADDR_SHFT) | \ + (((DT) & 0xFF) << SSBI_CMD_REG_DATA_SHFT)) + +#define SSBI_MODE2_REG_ADDR_15_8(MD, AD) \ + (((MD) & 0x0F) | ((((AD) >> 8) << SSBI_MODE2_REG_ADDR_15_8_SHFT) & \ + SSBI_MODE2_REG_ADDR_15_8_MASK)) + +void ssbi_keypad_init (struct qwerty_keypad_info *); +int i2c_ssbi_read_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr); +int i2c_ssbi_write_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr); +int pa1_ssbi2_read_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr); +int pa1_ssbi2_write_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr); + +#endif /* __DEV_GPIO_KEYPAD_H */ diff --git a/lk/include/dev/i2c.h b/lk/include/dev/i2c.h new file mode 100644 index 0000000..fef1303 --- /dev/null +++ b/lk/include/dev/i2c.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __DEV_I2C_H +#define __DEV_I2C_H + +void i2c_init(void); +void i2c_init_early(void); + +/* send and receive blocks of data */ +int i2c_transmit(int bus, uint8_t address, const void *buf, size_t count); +int i2c_receive(int bus, uint8_t address, void *buf, size_t count); + +/* a few convenience routines based on the usual way of accessing 8 byte registers on i2c slave devices */ +int i2c_write_reg(int bus, uint8_t address, uint8_t reg, uint8_t val); +int i2c_read_reg(int bus, uint8_t address, uint8_t reg, uint8_t *val); + + +#endif + diff --git a/lk/include/dev/keys.h b/lk/include/dev/keys.h new file mode 100644 index 0000000..6159875 --- /dev/null +++ b/lk/include/dev/keys.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009, Google 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 Google, Inc. 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 __DEV_KEYS_H +#define __DEV_KEYS_H + +#include + +/* these are just the ascii values for the chars */ +#define KEY_0 0x30 +#define KEY_1 0x31 +#define KEY_2 0x32 +#define KEY_3 0x33 +#define KEY_4 0x34 +#define KEY_5 0x35 +#define KEY_6 0x36 +#define KEY_7 0x37 +#define KEY_8 0x38 +#define KEY_9 0x39 + +#define KEY_A 0x61 + +#define KEY_ESC 0x100 +#define KEY_F1 0x101 +#define KEY_F2 0x102 +#define KEY_F3 0x103 +#define KEY_F4 0x104 +#define KEY_F5 0x105 +#define KEY_F6 0x106 +#define KEY_F7 0x107 +#define KEY_F8 0x108 +#define KEY_F9 0x109 + +#define KEY_LEFT 0x110 +#define KEY_RIGHT 0x111 +#define KEY_UP 0x112 +#define KEY_DOWN 0x113 +#define KEY_CENTER 0x114 + +#define KEY_VOLUMEUP 0x115 +#define KEY_VOLUMEDOWN 0x116 +#define KEY_MUTE 0x117 +#define KEY_SOUND 0x118 + +#define KEY_SOFT1 0x11a +#define KEY_SOFT2 0x11b +#define KEY_STAR 0x11c +#define KEY_SHARP 0x11d +#define KEY_MAIL 0x11e + +#define KEY_SEND 0x120 +#define KEY_CLEAR 0x121 +#define KEY_HOME 0x122 +#define KEY_BACK 0x123 +#define KEY_MENU 0x124 + +#define MAX_KEYS 0x1ff + +void keys_init(void); +void keys_post_event(uint16_t code, int16_t value); +int keys_get_state(uint16_t code); + +#endif /* __DEV_KEYS_H */ diff --git a/lk/include/dev/uart.h b/lk/include/dev/uart.h new file mode 100644 index 0000000..e3439dd --- /dev/null +++ b/lk/include/dev/uart.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __DEV_UART_H +#define __DEV_UART_H + +#include + +void uart_init(void); +void uart_init_early(void); + +int uart_putc(int port, char c); +int uart_getc(int port, bool wait); +void uart_flush_tx(int port); +void uart_flush_rx(int port); +void uart_init_port(int port, uint baud); + +#endif + diff --git a/lk/include/dev/udc.h b/lk/include/dev/udc.h new file mode 100644 index 0000000..0d8cff1 --- /dev/null +++ b/lk/include/dev/udc.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2009, Google 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. + * + * 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 __DEV_UDC_H +#define __DEV_UDC_H + +/* USB Device Controller Transfer Request */ +struct udc_request { + void *buf; + unsigned length; + void (*complete)(struct udc_request *req, unsigned actual, int status); + void *context; +}; + +/* endpoints are opaque handles specific to the particular device controller */ +struct udc_endpoint; + +struct udc_request *udc_request_alloc(void); +void udc_request_free(struct udc_request *req); +int udc_request_queue(struct udc_endpoint *ept, struct udc_request *req); +int udc_request_cancel(struct udc_endpoint *ept, struct udc_request *req); + +#define UDC_TYPE_BULK_IN 1 +#define UDC_TYPE_BULK_OUT 2 + +struct udc_endpoint *udc_endpoint_alloc(unsigned type, unsigned maxpkt); +void udc_endpoint_free(struct udc_endpoint *ept); + +#define UDC_EVENT_ONLINE 1 +#define UDC_EVENT_OFFLINE 2 + +struct udc_gadget { + void (*notify)(struct udc_gadget *gadget, unsigned event); + void *context; + + unsigned char ifc_class; + unsigned char ifc_subclass; + unsigned char ifc_protocol; + unsigned char ifc_endpoints; + const char *ifc_string; + unsigned flags; + + struct udc_endpoint **ept; +}; + +struct udc_device { + unsigned short vendor_id; + unsigned short product_id; + unsigned short version_id; + + const char *manufacturer; + const char *product; + const char *serialno; +}; + +int udc_init(struct udc_device *devinfo); +int udc_register_gadget(struct udc_gadget *gadget); +int udc_start(void); +int udc_stop(void); + +/* these should probably go elsewhere */ +#define GET_STATUS 0 +#define CLEAR_FEATURE 1 +#define SET_FEATURE 3 +#define SET_ADDRESS 5 +#define GET_DESCRIPTOR 6 +#define SET_DESCRIPTOR 7 +#define GET_CONFIGURATION 8 +#define SET_CONFIGURATION 9 +#define GET_INTERFACE 10 +#define SET_INTERFACE 11 +#define SYNCH_FRAME 12 + +#define TYPE_DEVICE 1 +#define TYPE_CONFIGURATION 2 +#define TYPE_STRING 3 +#define TYPE_INTERFACE 4 +#define TYPE_ENDPOINT 5 + +#define DEVICE_READ 0x80 +#define DEVICE_WRITE 0x00 +#define INTERFACE_READ 0x81 +#define INTERFACE_WRITE 0x01 +#define ENDPOINT_READ 0x82 +#define ENDPOINT_WRITE 0x02 + +struct setup_packet { + unsigned char type; + unsigned char request; + unsigned short value; + unsigned short index; + unsigned short length; +} __attribute__ ((packed)); + +#endif diff --git a/lk/include/dev/usb.h b/lk/include/dev/usb.h new file mode 100644 index 0000000..e33bea4 --- /dev/null +++ b/lk/include/dev/usb.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __DEV_USB_H +#define __DEV_USB_H + +#include +#include + +/* top level initialization for usb client, abstracts away the interfaces */ +typedef struct { + void *desc; + size_t len; +} usb_descriptor __ALIGNED(2); + +typedef struct { + usb_descriptor string; + uint8_t id; +} usb_string; + +/* complete usb config struct, passed in to usb_setup() */ +typedef struct { + struct usb_descriptor_speed { + usb_descriptor device; + usb_descriptor device_qual; + usb_descriptor config; + } lowspeed, highspeed; + usb_descriptor langid; +} usb_config; + +void usb_init(void); + +/* external code needs to set up the usb stack via the following calls */ +void usb_setup(usb_config *config); + +/* apped new interface descriptors to the existing config if desired */ +int usb_append_interface_highspeed(const uint8_t *int_descr, size_t len); +int usb_append_interface_lowspeed(const uint8_t *int_descr, size_t len); + +void usb_add_string(const char *string, uint8_t id); + +void usb_start(void); +void usb_stop(void); + +#endif + diff --git a/lk/include/dev/usbc.h b/lk/include/dev/usbc.h new file mode 100644 index 0000000..f566190 --- /dev/null +++ b/lk/include/dev/usbc.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __DEV_USBC_H +#define __DEV_USBC_H + +#include +#include +#include + +void usbc_init(void); + +typedef uint ep_t; + +typedef enum { + IN = 0, + OUT +} ep_dir_t; + +typedef enum { + CB_RESET, + CB_SUSPEND, + CB_RESUME, + CB_DISCONNECT, + CB_ONLINE, + CB_OFFLINE, + CB_SETUP_MSG, + + /* endpoint transfer stuff */ + CB_EP_RXCOMPLETE, + CB_EP_TXCOMPLETE, + CB_EP_TRANSFER_CANCELLED, +} usbc_callback_op_t; + +typedef struct { + void *buf; + size_t buflen; + uint bufpos; + int result; + void *extra; // extra pointer to store whatever you want +} usbc_transfer; + +enum { + USB_TRANSFER_RESULT_OK = 0, + USB_TRANSFER_RESULT_ERR = -1, + USB_TRANSFER_RESULT_CANCELLED = -2, +}; + +typedef int (*ep_callback)(ep_t endpoint, usbc_callback_op_t op, usbc_transfer *transfer); + +void usbc_setup_endpoint(ep_t ep, ep_dir_t dir, bool active, ep_callback callback, uint width, uint blocksize); +int usbc_queue_rx(ep_t ep, usbc_transfer *transfer); +int usbc_queue_tx(ep_t ep, usbc_transfer *transfer); + +/* setup arg is valid during CB_SETUP_MSG */ +union usb_callback_args { + const struct usb_setup *setup; +}; + +typedef int (*usb_callback)(usbc_callback_op_t op, const union usb_callback_args *args); + +int usbc_set_callback(usb_callback); +int usbc_set_active(bool active); + +/* called back from within a callback to handle setup responses */ +void usbc_ep0_ack(void); +void usbc_ep0_stall(void); +void usbc_ep0_send(const void *buf, size_t len, size_t maxlen); +void usbc_ep0_recv(void *buf, size_t len, ep_callback); + +bool usbc_is_highspeed(void); + +static inline void usbc_dump_transfer(const usbc_transfer *t) +{ + printf("usb transfer %p: buf %p, buflen %zd, bufpos %u, result %d\n", t, t->buf, t->buflen, t->bufpos, t->result); +} + +#endif + diff --git a/lk/include/endian.h b/lk/include/endian.h new file mode 100644 index 0000000..30623b2 --- /dev/null +++ b/lk/include/endian.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ENDIAN_H +#define __ENDIAN_H + +#include + +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif + +#if __POWERPC__ +#include +#endif + +#if defined(ARCH_ARM) +#define BYTE_ORDER LITTLE_ENDIAN +#endif + +#ifndef BYTE_ORDER +#error "need to get the BYTE_ORDER define from somewhere" +#endif + +// define a macro that unconditionally swaps +#define SWAP_32(x) \ + (((uint32_t)(x) << 24) | (((uint32_t)(x) & 0xff00) << 8) |(((uint32_t)(x) & 0x00ff0000) >> 8) | ((uint32_t)(x) >> 24)) +#define SWAP_16(x) \ + ((((uint16_t)(x) & 0xff) << 8) | ((uint16_t)(x) >> 8)) + +// standard swap macros +#if BYTE_ORDER == BIG_ENDIAN +#define LE32(val) SWAP_32(val) +#define LE16(val) SWAP_16(val) +#define BE32(val) (val) +#define BE16(val) (val) +#else +#define LE32(val) (val) +#define LE16(val) (val) +#define BE32(val) SWAP_32(val) +#define BE16(val) SWAP_16(val) +#endif + +#define LE32SWAP(var) (var) = LE32(var); +#define LE16SWAP(var) (var) = LE16(var); +#define BE32SWAP(var) (var) = BE32(var); +#define BE16SWAP(var) (var) = BE16(var); + +/* classic network byte swap stuff */ +#define ntohs(n) BE16(n) +#define htons(h) BE16(h) +#define ntohl(n) BE32(n) +#define htonl(h) BE32(h) + +// some memory access macros +#if __POWERPC__ +#define READ_MEM_WORD(ptr) __lwbrx((word *)(ptr), 0) +#define READ_MEM_HALFWORD(ptr) __lhbrx((halfword *)(ptr), 0) +#define READ_MEM_BYTE(ptr) (*(byte *)(ptr)) +#define WRITE_MEM_WORD(ptr, data) __stwbrx(data, (word *)(ptr), 0) +#define WRITE_MEM_HALFWORD(ptr, data) __sthbrx(data, (halfword *)(ptr), 0) +#define WRITE_MEM_BYTE(ptr, data) (*(byte *)(ptr) = (data)) +#else +#define READ_MEM_WORD(ptr) SWAPIT_32(*(word *)(ptr)) +#define READ_MEM_HALFWORD(ptr) SWAPIT_16(*(halfword *)(ptr)) +#define READ_MEM_BYTE(ptr) (*(byte *)(ptr)) +#define WRITE_MEM_WORD(ptr, data) (*(word *)(ptr) = SWAPIT_32(data)) +#define WRITE_MEM_HALFWORD(ptr, data) (*(halfword *)(ptr) = SWAPIT_16(data)) +#define WRITE_MEM_BYTE(ptr, data) (*(byte *)(ptr) = (data)) +#endif + + +#endif diff --git a/lk/include/err.h b/lk/include/err.h new file mode 100644 index 0000000..3b8b401 --- /dev/null +++ b/lk/include/err.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __ERR_H +#define __ERR_H + +#define NO_ERROR 0 +#define ERROR -1 +#define ERR_NOT_FOUND -2 +#define ERR_NOT_READY -3 +#define ERR_NO_MSG -4 +#define ERR_NO_MEMORY -5 +#define ERR_ALREADY_STARTED -6 +#define ERR_NOT_VALID -7 +#define ERR_INVALID_ARGS -8 +#define ERR_NOT_ENOUGH_BUFFER -9 +#define ERR_NOT_SUSPENDED -10 +#define ERR_OBJECT_DESTROYED -11 +#define ERR_NOT_BLOCKED -12 +#define ERR_TIMED_OUT -13 + +#endif diff --git a/lk/include/hw/mii.h b/lk/include/hw/mii.h new file mode 100644 index 0000000..0ff8979 --- /dev/null +++ b/lk/include/hw/mii.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2006 Brian Swetland + * + * 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 __HW_MII_H +#define __HW_MII_H + +#define MII_REG_BCR 0x00 +#define MII_REG_BSR 0x01 +#define MII_REG_PHY_ID1 0x02 +#define MII_REG_PHY_ID2 0x03 +#define MII_REG_AUTO_ADV 0x04 +#define MII_REG_AUTO_LINK 0x05 +#define MII_REG_AUTO_EXPN 0x06 +#define MII_REG_AUTO_NEXT 0x07 +#define MII_REG_LINK_NEXT 0x08 +#define MII_REG_RXER_CNT 0x15 +#define MII_REG_ICSR 0x1b +#define MII_REG_100TX_PHY 0x1f + +#define MII_BCR_RESET 0x8000 +#define MII_BCR_LOOPBACK 0x4000 +#define MII_BCR_100MBPS 0x2000 +#define MII_BCR_AUTO_ENABLE 0x1000 +#define MII_BCR_PWR_DOWN 0x0800 +#define MII_BCR_ISOLATE 0x0400 +#define MII_BCR_AUTO_RESTART 0x0200 +#define MII_BCR_FULL_DUPLEX 0x0100 +#define MII_BCR_COL_TEST 0x0080 +#define MII_BCR_TX_DISABLE 0x0001 + +#define MII_BSR_T4 0x8000 +#define MII_BSR_100TX_FULL 0x4000 +#define MII_BSR_100TX_HALF 0x2000 +#define MII_BSR_10T_FULL 0x1000 +#define MII_BSR_10T_HALF 0x0800 +#define MII_BSR_NO_PREAMBLE 0x0040 +#define MII_BSR_AUTO_COMPLETE 0x0020 +#define MII_BSR_REMOTE_FAULT 0x0010 +#define MII_BSR_AUTO_ABLE 0x0008 +#define MII_BSR_LINK_UP 0x0004 +#define MII_BSR_JABBER 0x0002 +#define MII_BSR_EXTEND 0x0001 + +#define MII_100TX_PHY_ISOLATE 0x0040 +#define MII_100TX_MODE_MASK 0x001C +#define MII_100TX_MODE_AUTO 0x0000 +#define MII_100TX_MODE_10T_H 0x0004 +#define MII_100TX_MODE_100TX_H 0x0008 +#define MII_100TX_MODE_10T_F 0x0014 +#define MII_100TX_MODE_100TX_F 0x0018 +#define MII_100TX_MODE_ISOLATE 0x001C +#define MII_100TX_SQE_TEST 0x0002 +#define MII_100TX_NO_SCRAMBLE 0x0001 + +#endif diff --git a/lk/include/hw/usb.h b/lk/include/hw/usb.h new file mode 100644 index 0000000..a533b7b --- /dev/null +++ b/lk/include/hw/usb.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __HW_USB_H +#define __HW_USB_H + +#include +#include + +/* GLOBAL STATUS VALUES */ +#define STD_COMMAND 0x00 +#define SETUP_COMMAND_PHASE 0x40 +#define FUNCTION_ERROR 0x7F /* Used when we are stalling the function EP0 */ +#define HUB_ERROR 0xFF /* Used when we are stalling the HUB EP0 */ + +/* Request Types */ +#define DIR_OUT (0 << 7) +#define DIR_IN (1 << 7) +#define DIR_MASK (1 << 7) +#define TYPE_STANDARD (0 << 5) +#define TYPE_CLASS (1 << 5) +#define TYPE_VENDOR (2 << 5) +#define TYPE_MASK (3 << 5) +#define RECIP_DEVICE (0 << 0) +#define RECIP_INTERFACE (1 << 0) +#define RECIP_ENDPOINT (2 << 0) +#define RECIP_OTHER (3 << 0) +#define RECIP_MASK (0x1f << 0) + +/* 1.0 Request Values */ +#define GET_STATUS 0x00 +#define CLEAR_FEATURE 0x01 +#define SET_FEATURE 0x03 +#define SET_ADDRESS 0x05 +#define GET_DESCRIPTOR 0x06 +#define SET_DESCRIPTOR 0x07 +#define GET_CONFIGURATION 0x08 +#define SET_CONFIGURATION 0x09 +#define GET_INTERFACE 0x0A +#define SET_INTERFACE 0x0B +#define SYNCH_FRAME 0x0C + +/* Mass storage requests */ +#define MASS_STORAGE_GET_MAX_LUN 0xfe +#define MASS_STORAGE_RESET 0xff + +/* DFU requests */ +#define DFU_DETACH 0x00 +#define DFU_DNLOAD 0x01 +#define DFU_UPLOAD 0x02 +#define DFU_GETSTATUS 0x03 +#define DFU_CLRSTATUS 0x04 +#define DFU_GETSTATE 0x05 +#define DFU_ABORT 0x06 + +/* HID Request Values */ +#define GET_REPORT 0x01 +#define GET_IDLE 0x02 +#define GET_PROTOCOL 0x03 +#define SET_REPORT 0x09 +#define SET_IDLE 0x0A +#define SET_PROTOCOL 0x0B + +/* Descriptor Types */ +#define DEVICE 0x01 +#define CONFIGURATION 0x02 +#define STRING 0x03 +#define INTERFACE 0x04 +#define ENDPOINT 0x05 +#define DEVICE_QUALIFIER 0x06 +#define OTHER_SPEED_CONFIGURATION 0x07 +#define INTERFACE_POWER 0x08 +#define HID 0x21 +#define HIDREPORT 0x22 +#define HIDPHYSICAL 0x23 + +/* general USB defines */ +struct usb_setup { + uint8_t request_type; + uint8_t request; + uint16_t value; + uint16_t index; + uint16_t length; +} __PACKED; + +#endif + diff --git a/lk/include/inttypes.h b/lk/include/inttypes.h new file mode 100644 index 0000000..f6681e3 --- /dev/null +++ b/lk/include/inttypes.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __INTTYPES_H +#define __INTTYPES_H + +#include + +#endif + diff --git a/lk/include/kernel/dpc.h b/lk/include/kernel/dpc.h new file mode 100644 index 0000000..9059e25 --- /dev/null +++ b/lk/include/kernel/dpc.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __KERNEL_DPC_H +#define __KERNEL_DPC_H + +#include +#include + +void dpc_init(void); + +typedef void (*dpc_callback)(void *arg); + +#define DPC_FLAG_NORESCHED 0x1 + +status_t dpc_queue(dpc_callback, void *arg, uint flags); + +#endif + diff --git a/lk/include/kernel/event.h b/lk/include/kernel/event.h new file mode 100644 index 0000000..8666737 --- /dev/null +++ b/lk/include/kernel/event.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __KERNEL_EVENT_H +#define __KERNEL_EVENT_H + +#include + +#define EVENT_MAGIC 'evnt' + +typedef struct event { + int magic; + bool signalled; + uint flags; + wait_queue_t wait; +} event_t; + +#define EVENT_FLAG_AUTOUNSIGNAL 1 + +/* Rules for Events: + * - Events may be signaled from interrupt context *but* the reschedule + * parameter must be false in that case. + * - Events may not be waited upon from interrupt context. + * - Events without FLAG_AUTOUNSIGNAL: + * - Wake up any waiting threads when signaled. + * - Continue to do so (no threads will wait) until unsignaled. + * - Events with FLAG_AUTOUNSIGNAL: + * - If one or more threads are waiting when signaled, one thread will + * be woken up and return. The signaled state will not be set. + * - If no threads are waiting when signaled, the Event will remain + * in the signaled state until a thread attempts to wait (at which + * time it will unsignal atomicly and return immediately) or + * event_unsignal() is called. +*/ + +void event_init(event_t *, bool initial, uint flags); +void event_destroy(event_t *); +status_t event_wait(event_t *); +status_t event_wait_timeout(event_t *, time_t); /* wait on the event with a timeout */ +status_t event_signal(event_t *, bool reschedule); +status_t event_unsignal(event_t *); + +#endif + diff --git a/lk/include/kernel/mutex.h b/lk/include/kernel/mutex.h new file mode 100644 index 0000000..40fe72f --- /dev/null +++ b/lk/include/kernel/mutex.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __KERNEL_MUTEX_H +#define __KERNEL_MUTEX_H + +#include + +#define MUTEX_MAGIC 'mutx' + +typedef struct mutex { + int magic; + int count; + thread_t *holder; + wait_queue_t wait; +} mutex_t; + +/* Rules for Mutexes: + * - Mutexes are only safe to use from thread context. + * - Mutexes are non-recursive. +*/ + +void mutex_init(mutex_t *); +void mutex_destroy(mutex_t *); +status_t mutex_acquire(mutex_t *); +status_t mutex_acquire_timeout(mutex_t *, time_t); /* try to acquire the mutex with a timeout value */ +status_t mutex_release(mutex_t *); + +#endif + diff --git a/lk/include/kernel/thread.h b/lk/include/kernel/thread.h new file mode 100644 index 0000000..8f76291 --- /dev/null +++ b/lk/include/kernel/thread.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __KERNEL_THREAD_H +#define __KERNEL_THREAD_H + +#include +#include +#include +#include +#include + +enum thread_state { + THREAD_SUSPENDED = 0, + THREAD_READY, + THREAD_RUNNING, + THREAD_BLOCKED, + THREAD_SLEEPING, + THREAD_DEATH, +}; + +typedef int (*thread_start_routine)(void *arg); + +/* thread local storage */ +enum thread_tls_list { + MAX_TLS_ENTRY +}; + +#define THREAD_MAGIC 'thrd' + +typedef struct thread { + int magic; + struct list_node thread_list_node; + + /* active bits */ + struct list_node queue_node; + int priority; + enum thread_state state; + int saved_critical_section_count; + int remaining_quantum; + + /* if blocked, a pointer to the wait queue */ + struct wait_queue *blocking_wait_queue; + status_t wait_queue_block_ret; + + /* architecture stuff */ + struct arch_thread arch; + + /* stack stuff */ + void *stack; + size_t stack_size; + + /* entry point */ + thread_start_routine entry; + void *arg; + + /* return code */ + int retcode; + + /* thread local storage */ + uint32_t tls[MAX_TLS_ENTRY]; + + char name[32]; +} thread_t; + +/* thread priority */ +#define NUM_PRIORITIES 32 +#define LOWEST_PRIORITY 0 +#define HIGHEST_PRIORITY (NUM_PRIORITIES - 1) +#define DPC_PRIORITY (NUM_PRIORITIES - 2) +#define IDLE_PRIORITY LOWEST_PRIORITY +#define LOW_PRIORITY (NUM_PRIORITIES / 4) +#define DEFAULT_PRIORITY (NUM_PRIORITIES / 2) +#define HIGH_PRIORITY ((NUM_PRIORITIES / 4) * 3) + +/* stack size */ +#define DEFAULT_STACK_SIZE 8192 + +/* functions */ +void thread_init_early(void); +void thread_init(void); +void thread_become_idle(void) __NO_RETURN; +void thread_set_name(const char *name); +void thread_set_priority(int priority); +thread_t *thread_create(const char *name, thread_start_routine entry, void *arg, int priority, size_t stack_size); +status_t thread_resume(thread_t *); +void thread_exit(int retcode) __NO_RETURN; +void thread_sleep(time_t delay); + +void dump_thread(thread_t *t); +void dump_all_threads(void); + +/* scheduler routines */ +void thread_yield(void); /* give up the cpu voluntarily */ +void thread_preempt(void); /* get preempted (inserted into head of run queue) */ +void thread_block(void); /* block on something and reschedule */ + +/* called on every timer tick for the scheduler to do quantum expiration */ +enum handler_return thread_timer_tick(void); + +/* the current thread */ +extern thread_t *current_thread; + +/* the idle thread */ +extern thread_t *idle_thread; + +/* critical sections */ +extern int critical_section_count; + +static inline __ALWAYS_INLINE void enter_critical_section(void) +{ + critical_section_count++; + if (critical_section_count == 1) + arch_disable_ints(); +} + +static inline __ALWAYS_INLINE void exit_critical_section(void) +{ + critical_section_count--; + if (critical_section_count == 0) + arch_enable_ints(); +} + +static inline __ALWAYS_INLINE bool in_critical_section(void) +{ + return critical_section_count > 0; +} + +/* only used by interrupt glue */ +static inline void inc_critical_section(void) { critical_section_count++; } +static inline void dec_critical_section(void) { critical_section_count--; } + +/* thread local storage */ +static inline __ALWAYS_INLINE uint32_t tls_get(uint entry) +{ + return current_thread->tls[entry]; +} + +static inline __ALWAYS_INLINE uint32_t tls_set(uint entry, uint32_t val) +{ + uint32_t oldval = current_thread->tls[entry]; + current_thread->tls[entry] = val; + return oldval; +} + +/* wait queue stuff */ +#define WAIT_QUEUE_MAGIC 'wait' + +typedef struct wait_queue { + int magic; + struct list_node list; + int count; +} wait_queue_t; + +/* wait queue primitive */ +/* NOTE: must be inside critical section when using these */ +void wait_queue_init(wait_queue_t *); + +/* + * release all the threads on this wait queue with a return code of ERR_OBJECT_DESTROYED. + * the caller must assure that no other threads are operating on the wait queue during or + * after the call. + */ +void wait_queue_destroy(wait_queue_t *, bool reschedule); + +/* + * block on a wait queue. + * return status is whatever the caller of wait_queue_wake_*() specifies. + * a timeout other than INFINITE_TIME will set abort after the specified time + * and return ERR_TIMED_OUT. a timeout of 0 will immediately return. + */ +status_t wait_queue_block(wait_queue_t *, time_t timeout); + +/* + * release one or more threads from the wait queue. + * reschedule = should the system reschedule if any is released. + * wait_queue_error = what wait_queue_block() should return for the blocking thread. + */ +int wait_queue_wake_one(wait_queue_t *, bool reschedule, status_t wait_queue_error); +int wait_queue_wake_all(wait_queue_t *, bool reschedule, status_t wait_queue_error); + +/* + * remove the thread from whatever wait queue it's in. + * return an error if the thread is not currently blocked (or is the current thread) + */ +status_t thread_unblock_from_wait_queue(thread_t *t, bool reschedule, status_t wait_queue_error); + +/* thread level statistics */ +#define THREAD_STATS 0 +#if THREAD_STATS +struct thread_stats { + bigtime_t idle_time; + bigtime_t last_idle_timestamp; + int reschedules; + int context_switches; + int preempts; + int yields; + int interrupts; /* platform code increment this */ + int timer_ints; /* timer code increment this */ + int timers; /* timer code increment this */ +}; + +extern struct thread_stats thread_stats; + +#endif + +#endif + diff --git a/lk/include/kernel/timer.h b/lk/include/kernel/timer.h new file mode 100644 index 0000000..98332fd --- /dev/null +++ b/lk/include/kernel/timer.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __KERNEL_TIMER_H +#define __KERNEL_TIMER_H + +#include +#include + +void timer_init(void); + +struct timer; +typedef enum handler_return (*timer_callback)(struct timer *, time_t now, void *arg); + +#define TIMER_MAGIC 'timr' + +typedef struct timer { + int magic; + struct list_node node; + + time_t scheduled_time; + time_t periodic_time; + + timer_callback callback; + void *arg; +} timer_t; + +/* Rules for Timers: + * - Timer callbacks occur from interrupt context + * - Timers may be programmed or canceled from interrupt or thread context + * - Timers may be canceled or reprogrammed from within their callback + * - Timers currently are dispatched from a 10ms periodic tick +*/ +void timer_initialize(timer_t *); +void timer_set_oneshot(timer_t *, time_t delay, timer_callback, void *arg); +void timer_set_periodic(timer_t *, time_t period, timer_callback, void *arg); +void timer_cancel(timer_t *); + +#endif + diff --git a/lk/include/lib/console.h b/lk/include/lib/console.h new file mode 100644 index 0000000..6641542 --- /dev/null +++ b/lk/include/lib/console.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __LIB_CONSOLE_H +#define __LIB_CONSOLE_H + +#include +#include + +/* command args */ +typedef struct { + const char *str; + unsigned int u; + int i; +} cmd_args; + +typedef int (*console_cmd)(int argc, const cmd_args *argv); + +/* a block of commands to register */ +typedef struct { + const char *cmd_str; + const char *help_str; + const console_cmd cmd_callback; +} cmd; + +typedef struct _cmd_block { + struct _cmd_block *next; + size_t count; + const cmd *list; +} cmd_block; + +/* register a static block of commands at init time */ +#define STATIC_COMMAND_START static const cmd _cmd_list[] = { +#define STATIC_COMMAND_END(name) }; const cmd_block _cmd_block_##name __SECTION(".commands")= { NULL, sizeof(_cmd_list) / sizeof(_cmd_list[0]), _cmd_list } + +/* external api */ +int console_init(void); +void console_start(void); +void console_register_commands(cmd_block *block); +int console_run_command(const char *string); + +#endif + diff --git a/lk/include/lib/heap.h b/lk/include/lib/heap.h new file mode 100644 index 0000000..54ea73b --- /dev/null +++ b/lk/include/lib/heap.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __LIB_HEAP_H +#define __LIB_HEAP_H + +#include + +void *heap_alloc(size_t, unsigned int alignment); +void heap_free(void *); + +void heap_init(void); + + + +#endif diff --git a/lk/include/lib/ptable.h b/lk/include/lib/ptable.h new file mode 100644 index 0000000..07fbf80 --- /dev/null +++ b/lk/include/lib/ptable.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * 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 __LIB_PTABLE_H +#define __LIB_PTABLE_H + +/* flash partitions are defined in terms of blocks + * (flash erase units) + */ +#define MAX_PTENTRY_NAME 16 +#define MAX_PTABLE_PARTS 32 + +#define TYPE_MODEM_PARTITION 1 +#define TYPE_APPS_PARTITION 0 +#define PERM_NON_WRITEABLE 0 +#define PERM_WRITEABLE 1 +struct ptentry +{ + char name[MAX_PTENTRY_NAME]; + unsigned start; + unsigned length; + unsigned flags; + char type; + char perm; +}; + +struct ptable +{ + struct ptentry parts[MAX_PTABLE_PARTS]; + int count; +}; + +/* tools to populate and query the partition table */ +void ptable_init(struct ptable *ptable); +void ptable_add(struct ptable *ptable, char *name, unsigned start, + unsigned length, unsigned flags, char type, char perm); +struct ptentry *ptable_find(struct ptable *ptable, const char *name); +struct ptentry *ptable_get(struct ptable *ptable, int n); +int ptable_size(struct ptable *ptable); +void ptable_dump(struct ptable *ptable); + +#endif /* __LIB_PTABLE_H */ diff --git a/lk/include/limits.h b/lk/include/limits.h new file mode 100644 index 0000000..ec83068 --- /dev/null +++ b/lk/include/limits.h @@ -0,0 +1,121 @@ +/* This administrivia gets added to the beginning of limits.h + if the system has its own version of limits.h. */ + +/* We use _GCC_LIMITS_H_ because we want this not to match + any macros that the system's limits.h uses for its own purposes. */ +#ifndef _GCC_LIMITS_H_ /* Terminated in limity.h. */ +#define _GCC_LIMITS_H_ + +#ifndef _LIMITS_H___ +#define _LIMITS_H___ + +/* Number of bits in a `char'. */ +#undef CHAR_BIT +#define CHAR_BIT __CHAR_BIT__ + +/* Maximum length of a multibyte character. */ +#ifndef MB_LEN_MAX +#define MB_LEN_MAX 1 +#endif + +/* Minimum and maximum values a `signed char' can hold. */ +#undef SCHAR_MIN +#define SCHAR_MIN (-SCHAR_MAX - 1) +#undef SCHAR_MAX +#define SCHAR_MAX __SCHAR_MAX__ + +/* Maximum value an `unsigned char' can hold. (Minimum is 0). */ +#undef UCHAR_MAX +#if __SCHAR_MAX__ == __INT_MAX__ +# define UCHAR_MAX (SCHAR_MAX * 2U + 1U) +#else +# define UCHAR_MAX (SCHAR_MAX * 2 + 1) +#endif + +/* Minimum and maximum values a `char' can hold. */ +#ifdef __CHAR_UNSIGNED__ +# undef CHAR_MIN +# if __SCHAR_MAX__ == __INT_MAX__ +# define CHAR_MIN 0U +# else +# define CHAR_MIN 0 +# endif +# undef CHAR_MAX +# define CHAR_MAX UCHAR_MAX +#else +# undef CHAR_MIN +# define CHAR_MIN SCHAR_MIN +# undef CHAR_MAX +# define CHAR_MAX SCHAR_MAX +#endif + +/* Minimum and maximum values a `signed short int' can hold. */ +#undef SHRT_MIN +#define SHRT_MIN (-SHRT_MAX - 1) +#undef SHRT_MAX +#define SHRT_MAX __SHRT_MAX__ + +/* Maximum value an `unsigned short int' can hold. (Minimum is 0). */ +#undef USHRT_MAX +#if __SHRT_MAX__ == __INT_MAX__ +# define USHRT_MAX (SHRT_MAX * 2U + 1U) +#else +# define USHRT_MAX (SHRT_MAX * 2 + 1) +#endif + +/* Minimum and maximum values a `signed int' can hold. */ +#undef INT_MIN +#define INT_MIN (-INT_MAX - 1) +#undef INT_MAX +#define INT_MAX __INT_MAX__ + +/* Maximum value an `unsigned int' can hold. (Minimum is 0). */ +#undef UINT_MAX +#define UINT_MAX (INT_MAX * 2U + 1U) + +/* Minimum and maximum values a `signed long int' can hold. + (Same as `int'). */ +#undef LONG_MIN +#define LONG_MIN (-LONG_MAX - 1L) +#undef LONG_MAX +#define LONG_MAX __LONG_MAX__ + +/* Maximum value an `unsigned long int' can hold. (Minimum is 0). */ +#undef ULONG_MAX +#define ULONG_MAX (LONG_MAX * 2UL + 1UL) + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +/* Minimum and maximum values a `signed long long int' can hold. */ +# undef LLONG_MIN +# define LLONG_MIN (-LLONG_MAX - 1LL) +# undef LLONG_MAX +# define LLONG_MAX __LONG_LONG_MAX__ + +/* Maximum value an `unsigned long long int' can hold. (Minimum is 0). */ +# undef ULLONG_MAX +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +#endif + +#if defined (__GNU_LIBRARY__) ? defined (__USE_GNU) : !defined (__STRICT_ANSI__) +/* Minimum and maximum values a `signed long long int' can hold. */ +# undef LONG_LONG_MIN +# define LONG_LONG_MIN (-LONG_LONG_MAX - 1LL) +# undef LONG_LONG_MAX +# define LONG_LONG_MAX __LONG_LONG_MAX__ + +/* Maximum value an `unsigned long long int' can hold. (Minimum is 0). */ +# undef ULONG_LONG_MAX +# define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1ULL) +#endif + +#endif /* _LIMITS_H___ */ +/* This administrivia gets added to the end of limits.h + if the system has its own version of limits.h. */ + +#else /* not _GCC_LIMITS_H_ */ + +#ifdef _GCC_NEXT_LIMITS_H +#include_next /* recurse down to the real one */ +#endif + +#endif /* not _GCC_LIMITS_H_ */ diff --git a/lk/include/list.h b/lk/include/list.h new file mode 100644 index 0000000..96cd0d4 --- /dev/null +++ b/lk/include/list.h @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __LIST_H +#define __LIST_H + +#include + +#define containerof(ptr, type, member) \ + ((type *)((addr_t)(ptr) - offsetof(type, member))) + +struct list_node { + struct list_node *prev; + struct list_node *next; +}; + +#define LIST_INITIAL_VALUE(list) { &(list), &(list) } + +static inline void list_initialize(struct list_node *list) +{ + list->prev = list->next = list; +} + +static inline void list_clear_node(struct list_node *item) +{ + item->prev = item->next = 0; +} + +static inline bool list_in_list(struct list_node *item) +{ + if (item->prev == 0 && item->next == 0) + return false; + else + return true; +} + +static inline void list_add_head(struct list_node *list, struct list_node *item) +{ + item->next = list->next; + item->prev = list; + list->next->prev = item; + list->next = item; +} + +#define list_add_after(entry, new_entry) list_add_head(entry, new_entry) + +static inline void list_add_tail(struct list_node *list, struct list_node *item) +{ + item->prev = list->prev; + item->next = list; + list->prev->next = item; + list->prev = item; +} + +#define list_add_before(entry, new_entry) list_add_tail(entry, new_entry) + +static inline void list_delete(struct list_node *item) +{ + item->next->prev = item->prev; + item->prev->next = item->next; + item->prev = item->next = 0; +} + +static inline struct list_node* list_remove_head(struct list_node *list) +{ + if(list->next != list) { + struct list_node *item = list->next; + list_delete(item); + return item; + } else { + return NULL; + } +} + +#define list_remove_head_type(list, type, element) ({\ + struct list_node *__nod = list_remove_head(list);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_remove_tail(struct list_node *list) +{ + if(list->prev != list) { + struct list_node *item = list->prev; + list_delete(item); + return item; + } else { + return NULL; + } +} + +#define list_remove_tail_type(list, type, element) ({\ + struct list_node *__nod = list_remove_tail(list);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_peek_head(struct list_node *list) +{ + if(list->next != list) { + return list->next; + } else { + return NULL; + } +} + +#define list_peek_head_type(list, type, element) ({\ + struct list_node *__nod = list_peek_head(list);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_peek_tail(struct list_node *list) +{ + if(list->prev != list) { + return list->prev; + } else { + return NULL; + } +} + +#define list_peek_tail_type(list, type, element) ({\ + struct list_node *__nod = list_peek_tail(list);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_prev(struct list_node *list, struct list_node *item) +{ + if(item->prev != list) + return item->prev; + else + return NULL; +} + +#define list_prev_type(list, item, type, element) ({\ + struct list_node *__nod = list_prev(list, item);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_prev_wrap(struct list_node *list, struct list_node *item) +{ + if(item->prev != list) + return item->prev; + else if(item->prev->prev != list) + return item->prev->prev; + else + return NULL; +} + +#define list_prev_wrap_type(list, item, type, element) ({\ + struct list_node *__nod = list_prev_wrap(list, item);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_next(struct list_node *list, struct list_node *item) +{ + if(item->next != list) + return item->next; + else + return NULL; +} + +#define list_next_type(list, item, type, element) ({\ + struct list_node *__nod = list_next(list, item);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +static inline struct list_node* list_next_wrap(struct list_node *list, struct list_node *item) +{ + if(item->next != list) + return item->next; + else if(item->next->next != list) + return item->next->next; + else + return NULL; +} + +#define list_next_wrap_type(list, item, type, element) ({\ + struct list_node *__nod = list_next_wrap(list, item);\ + type *__t;\ + if(__nod)\ + __t = containerof(__nod, type, element);\ + else\ + __t = (type *)0;\ + __t;\ +}) + +// iterates over the list, node should be struct list_node* +#define list_for_every(list, node) \ + for(node = (list)->next; node != (list); node = node->next) + +// iterates over the list in a safe way for deletion of current node +// node and temp_node should be struct list_node* +#define list_for_every_safe(list, node, temp_node) \ + for(node = (list)->next, temp_node = (node)->next;\ + node != (list);\ + node = temp_node, temp_node = (node)->next) + +// iterates over the list, entry should be the container structure type * +#define list_for_every_entry(list, entry, type, member) \ + for((entry) = containerof((list)->next, type, member);\ + &(entry)->member != (list);\ + (entry) = containerof((entry)->member.next, type, member)) + +// iterates over the list in a safe way for deletion of current node +// entry and temp_entry should be the container structure type * +#define list_for_every_entry_safe(list, entry, temp_entry, type, member) \ + for(entry = containerof((list)->next, type, member),\ + temp_entry = containerof((entry)->member.next, type, member);\ + &(entry)->member != (list);\ + entry = temp_entry, temp_entry = containerof((temp_entry)->member.next, type, member)) + +static inline bool list_is_empty(struct list_node *list) +{ + return (list->next == list) ? true : false; +} + +#endif diff --git a/lk/include/malloc.h b/lk/include/malloc.h new file mode 100644 index 0000000..d48f6d2 --- /dev/null +++ b/lk/include/malloc.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __MALLOC_H +#define __MALLOC_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +void *malloc(size_t size) __MALLOC; +void *memalign(size_t boundary, size_t size) __MALLOC; +void *calloc(size_t count, size_t size) __MALLOC; +void free(void *ptr); + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/lk/include/new.h b/lk/include/new.h new file mode 100644 index 0000000..d150c18 --- /dev/null +++ b/lk/include/new.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __NEW_H +#define __NEW_H + +#include + +void *operator new(size_t); +void *operator new(size_t, void *ptr); +void *operator new[](size_t); +void *operator new[](size_t, void *ptr); +void operator delete(void *p); +void operator delete[](void *p); + +#endif diff --git a/lk/include/platform.h b/lk/include/platform.h new file mode 100644 index 0000000..5f7e303 --- /dev/null +++ b/lk/include/platform.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __PLATFORM_H +#define __PLATFORM_H + +time_t current_time(void); +bigtime_t current_time_hires(void); + +/* super early platform initialization, before almost everything */ +void platform_early_init(void); + +/* later init, after the kernel has come up */ +void platform_init(void); + +/* called by the arch init code to get the platform to set up any mmu mappings it may need */ +void platform_init_mmu_mappings(void); + +#endif diff --git a/lk/include/platform/debug.h b/lk/include/platform/debug.h new file mode 100644 index 0000000..4ab460a --- /dev/null +++ b/lk/include/platform/debug.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __PLATFORM_DEBUG_H +#define __PLATFORM_DEBUG_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +void debug_dump_regs(void); +uint32_t debug_cycle_count(void); + +void debug_dump_memory_bytes(void *mem, int len); +void debug_dump_memory_halfwords(void *mem, int len); +void debug_dump_memory_words(void *mem, int len); + +void debug_set_trace_level(int trace_type, int level); + +void platform_halt(void) __NO_RETURN; + +#if defined(__cplusplus) +} +#endif + + +#endif + diff --git a/lk/include/platform/interrupts.h b/lk/include/platform/interrupts.h new file mode 100644 index 0000000..7ee25bc --- /dev/null +++ b/lk/include/platform/interrupts.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __PLATFORM_INTERRUPTS_H +#define __PLATFORM_INTERRUPTS_H + +#include + +status_t mask_interrupt(unsigned int vector); +status_t unmask_interrupt(unsigned int vector); + +typedef enum handler_return (*int_handler)(void *arg); + +void register_int_handler(unsigned int vector, int_handler handler, void *arg); + +#endif diff --git a/lk/include/platform/timer.h b/lk/include/platform/timer.h new file mode 100644 index 0000000..2a6e617 --- /dev/null +++ b/lk/include/platform/timer.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __PLATFORM_TIMER_H +#define __PLATFORM_TIMER_H + +typedef enum handler_return (*platform_timer_callback)(void *arg, time_t now); + +status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, time_t interval); + +#endif + diff --git a/lk/include/printf.h b/lk/include/printf.h new file mode 100644 index 0000000..2d09120 --- /dev/null +++ b/lk/include/printf.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __LIB_PRINTF_H +#define __LIB_PRINTF_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +int printf(const char *fmt, ...); +int sprintf(char *str, const char *fmt, ...) __PRINTFLIKE(2, 3); +int snprintf(char *str, size_t len, const char *fmt, ...) __PRINTFLIKE(3, 4); +int vsprintf(char *str, const char *fmt, va_list ap); +int vsnprintf(char *str, size_t len, const char *fmt, va_list ap); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/lk/include/rand.h b/lk/include/rand.h new file mode 100644 index 0000000..907cf20 --- /dev/null +++ b/lk/include/rand.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __RAND_H +#define __RAND_H + +int rand(void); + +#endif + diff --git a/lk/include/reg.h b/lk/include/reg.h new file mode 100644 index 0000000..b5dd528 --- /dev/null +++ b/lk/include/reg.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __REG_H +#define __REG_H + +#include + +/* low level macros for accessing memory mapped hardware registers */ +#define REG64(addr) ((volatile uint64_t *)(addr)) +#define REG32(addr) ((volatile uint32_t *)(addr)) +#define REG16(addr) ((volatile uint16_t *)(addr)) +#define REG8(addr) ((volatile uint8_t *)(addr)) + +#define RMWREG64(addr, startbit, width, val) *REG64(addr) = (*REG64(addr) & ~(((1<<(width)) - 1) << (startbit))) | ((val) << (startbit)) +#define RMWREG32(addr, startbit, width, val) *REG32(addr) = (*REG32(addr) & ~(((1<<(width)) - 1) << (startbit))) | ((val) << (startbit)) +#define RMWREG16(addr, startbit, width, val) *REG16(addr) = (*REG16(addr) & ~(((1<<(width)) - 1) << (startbit))) | ((val) << (startbit)) +#define RMWREG8(addr, startbit, width, val) *REG8(addr) = (*REG8(addr) & ~(((1<<(width)) - 1) << (startbit))) | ((val) << (startbit)) + +#define writel(v, a) (*REG32(a) = (v)) +#define readl(a) (*REG32(a)) + +#define writeb(v, a) (*REG8(a) = (v)) +#define readb(a) (*REG8(a)) +#endif diff --git a/lk/include/stdint.h b/lk/include/stdint.h new file mode 100644 index 0000000..0ea9e8a --- /dev/null +++ b/lk/include/stdint.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __STDINT_H +#define __STDINT_H + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +typedef signed char int8_t; +typedef short int16_t; +typedef int int32_t; +typedef long long int64_t; + +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +typedef long intptr_t; +typedef unsigned long uintptr_t; + +typedef long long intmax_t; +typedef unsigned long long uintmax_t; + +#endif + diff --git a/lk/include/stdio.h b/lk/include/stdio.h new file mode 100644 index 0000000..ebabfca --- /dev/null +++ b/lk/include/stdio.h @@ -0,0 +1,12 @@ +#ifndef __STDIO_H +#define __STDIO_H + +#include +#include + +void putc(char c); +int puts(const char *str); +int getc(char *c); // XXX not really getc + +#endif + diff --git a/lk/include/stdlib.h b/lk/include/stdlib.h new file mode 100644 index 0000000..fb1e1de --- /dev/null +++ b/lk/include/stdlib.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __STDLIB_H +#define __STDLIB_H + +#include +#include +#include +#include +#include +#include + +int atoi(const char *num); +unsigned int atoui(const char *num); +long atol(const char *num); +unsigned long atoul(const char *num); + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1)) +#define ROUNDDOWN(a, b) ((a) & ~((b)-1)) + +/* allocate a buffer on the stack aligned and padded to the cpu's cache line size */ +#define STACKBUF_DMA_ALIGN(var, size) \ + uint8_t __##var[(size) + CACHE_LINE]; uint8_t *var = (uint8_t *)(ROUNDUP((addr_t)__##var, CACHE_LINE)) + +#endif + diff --git a/lk/include/string.h b/lk/include/string.h new file mode 100644 index 0000000..3dccd92 --- /dev/null +++ b/lk/include/string.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __LIB_STRING_H +#define __LIB_STRING_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void *memchr (void const *, int, size_t) __PURE; +int memcmp (void const *, const void *, size_t) __PURE; +void *memcpy (void *, void const *, size_t); +void *memmove(void *, void const *, size_t); +void *memset (void *, int, size_t); + +char *strcat(char *, char const *); +char *strchr(char const *, int) __PURE; +int strcmp(char const *, char const *) __PURE; +char *strcpy(char *, char const *); +char const *strerror(int) __CONST; +size_t strlen(char const *) __PURE; +char *strncat(char *, char const *, size_t); +int strncmp(char const *, char const *, size_t) __PURE; +char *strncpy(char *, char const *, size_t); +char *strpbrk(char const *, char const *) __PURE; +char *strrchr(char const *, int) __PURE; +size_t strspn(char const *, char const *) __PURE; +size_t strcspn(const char *s, const char *) __PURE; +char *strstr(char const *, char const *) __PURE; +char *strtok(char *, char const *); +int strcoll(const char *s1, const char *s2) __PURE; +size_t strxfrm(char *dest, const char *src, size_t n) __PURE; +char *strdup(const char *str) __MALLOC; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* non standard */ +void *bcopy(void const *, void *, size_t); +void bzero(void *, size_t); +size_t strlcat(char *, char const *, size_t); +size_t strlcpy(char *, char const *, size_t); +int strncasecmp(char const *, char const *, size_t) __PURE; +int strnicmp(char const *, char const *, size_t) __PURE; +size_t strnlen(char const *s, size_t count) __PURE; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lk/include/sys/types.h b/lk/include/sys/types.h new file mode 100644 index 0000000..510ab05 --- /dev/null +++ b/lk/include/sys/types.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __SYS_TYPES_H +#define __SYS_TYPES_H + +#ifndef __cplusplus +#define false 0 +#define true 1 +typedef int bool; +#endif + +#include +#include +#include + +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; + +#ifndef _SIZE_T_DEFINED_ +typedef unsigned long size_t; +#endif +typedef long ssize_t; +typedef long long off_t; + +typedef int status_t; + +typedef uintptr_t addr_t; +typedef uintptr_t vaddr_t; +typedef uintptr_t paddr_t; + +typedef int kobj_id; + +typedef unsigned long time_t; +typedef unsigned long long bigtime_t; +#define INFINITE_TIME ULONG_MAX + +enum handler_return { + INT_NO_RESCHEDULE = 0, + INT_RESCHEDULE, +}; + +#endif diff --git a/lk/include/target.h b/lk/include/target.h new file mode 100644 index 0000000..ace8834 --- /dev/null +++ b/lk/include/target.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __TARGET_H +#define __TARGET_H + +/* super early platform initialization, before almost everything */ +void target_early_init(void); + +/* later init, after the kernel has come up */ +void target_init(void); + +/* get memory address for fastboot image loading */ +void *target_get_scratch_address(void); + +/* if target is using eMMC bootup */ +int target_is_emmc_boot(void); + +#endif diff --git a/lk/kernel/debug.c b/lk/kernel/debug.c new file mode 100644 index 0000000..c3d7220 --- /dev/null +++ b/lk/kernel/debug.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +#if defined(WITH_LIB_CONSOLE) +#include + +static int cmd_threads(int argc, const cmd_args *argv); +static int cmd_threadstats(int argc, const cmd_args *argv); +static int cmd_threadload(int argc, const cmd_args *argv); + +STATIC_COMMAND_START +#if DEBUGLEVEL > 1 + { "threads", "list kernel threads", &cmd_threads }, +#endif +#if THREAD_STATS + { "threadstats", "thread level statistics", &cmd_threadstats }, + { "threadload", "toggle thread load display", &cmd_threadload }, +#endif +STATIC_COMMAND_END(kernel); + +#if DEBUGLEVEL > 1 +static int cmd_threads(int argc, const cmd_args *argv) +{ + printf("thread list:\n"); + dump_all_threads(); + + return 0; +} +#endif + +#if THREAD_STATS +static int cmd_threadstats(int argc, const cmd_args *argv) +{ + printf("thread stats:\n"); + printf("\ttotal idle time: %lld\n", thread_stats.idle_time); + printf("\ttotal busy time: %lld\n", current_time_hires() - thread_stats.idle_time); + printf("\treschedules: %d\n", thread_stats.reschedules); + printf("\tcontext_switches: %d\n", thread_stats.context_switches); + printf("\tpreempts: %d\n", thread_stats.preempts); + printf("\tyields: %d\n", thread_stats.yields); + printf("\tinterrupts: %d\n", thread_stats.interrupts); + printf("\ttimer interrupts: %d\n", thread_stats.timer_ints); + printf("\ttimers: %d\n", thread_stats.timers); + + return 0; +} + +static enum handler_return threadload(struct timer *t, time_t now, void *arg) +{ + static struct thread_stats old_stats; + static bigtime_t last_idle_time; + + timer_set_oneshot(t, 1000, &threadload, NULL); + + bigtime_t idle_time = thread_stats.idle_time; + if (current_thread == idle_thread) { + idle_time += current_time_hires() - thread_stats.last_idle_timestamp; + } + bigtime_t busy_time = 1000000ULL - (idle_time - last_idle_time); + + uint busypercent = (busy_time * 10000) / (1000000); + +// printf("idle_time %lld, busytime %lld\n", idle_time - last_idle_time, busy_time); + printf("LOAD: %d.%02d%%, cs %d, ints %d, timer ints %d, timers %d\n", busypercent / 100, busypercent % 100, + thread_stats.context_switches - old_stats.context_switches, + thread_stats.interrupts - old_stats.interrupts, + thread_stats.timer_ints - old_stats.timer_ints, + thread_stats.timers - old_stats.timers); + + old_stats = thread_stats; + last_idle_time = idle_time; + + return INT_NO_RESCHEDULE; +} + +static int cmd_threadload(int argc, const cmd_args *argv) +{ + static bool showthreadload = false; + static timer_t tltimer; + + enter_critical_section(); + + if (showthreadload == false) { + // start the display + timer_initialize(&tltimer); + timer_set_oneshot(&tltimer, 1000, &threadload, NULL); + showthreadload = true; + } else { + timer_cancel(&tltimer); + showthreadload = false; + } + + exit_critical_section(); + + return 0; +} + +#endif + +#endif + diff --git a/lk/kernel/dpc.c b/lk/kernel/dpc.c new file mode 100644 index 0000000..184ac31 --- /dev/null +++ b/lk/kernel/dpc.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include + +struct dpc { + struct list_node node; + + dpc_callback cb; + void *arg; +}; + +static struct list_node dpc_list = LIST_INITIAL_VALUE(dpc_list); +static event_t dpc_event; + +static int dpc_thread_routine(void *arg); + +void dpc_init(void) +{ + event_init(&dpc_event, false, 0); + + thread_resume(thread_create("dpc", &dpc_thread_routine, NULL, DPC_PRIORITY, DEFAULT_STACK_SIZE)); +} + +status_t dpc_queue(dpc_callback cb, void *arg, uint flags) +{ + struct dpc *dpc; + + dpc = malloc(sizeof(struct dpc)); + + dpc->cb = cb; + dpc->arg = arg; + enter_critical_section(); + list_add_tail(&dpc_list, &dpc->node); + event_signal(&dpc_event, (flags & DPC_FLAG_NORESCHED) ? false : true); + exit_critical_section(); + + return NO_ERROR; +} + +static int dpc_thread_routine(void *arg) +{ + for (;;) { + event_wait(&dpc_event); + + enter_critical_section(); + struct dpc *dpc = list_remove_head_type(&dpc_list, struct dpc, node); + if (!dpc) + event_unsignal(&dpc_event); + exit_critical_section(); + + if (dpc) { +// dprintf("dpc calling %p, arg %p\n", dpc->cb, dpc->arg); + dpc->cb(dpc->arg); + + free(dpc); + } + } + + return 0; +} + + diff --git a/lk/kernel/event.c b/lk/kernel/event.c new file mode 100644 index 0000000..09e485a --- /dev/null +++ b/lk/kernel/event.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +#if DEBUGLEVEL > 1 +#define EVENT_CHECK 1 +#endif + +void event_init(event_t *e, bool initial, uint flags) +{ +#if EVENT_CHECK +// ASSERT(e->magic != EVENT_MAGIC); +#endif + + e->magic = EVENT_MAGIC; + e->signalled = initial; + e->flags = flags; + wait_queue_init(&e->wait); +} + +void event_destroy(event_t *e) +{ + enter_critical_section(); + +#if EVENT_CHECK + ASSERT(e->magic == EVENT_MAGIC); +#endif + + e->magic = 0; + e->signalled = false; + e->flags = 0; + wait_queue_destroy(&e->wait, true); + + exit_critical_section(); +} + +status_t event_wait_timeout(event_t *e, time_t timeout) +{ + status_t ret = NO_ERROR; + + enter_critical_section(); + +#if EVENT_CHECK + ASSERT(e->magic == EVENT_MAGIC); +#endif + + if (e->signalled) { + /* signalled, we're going to fall through */ + if (e->flags & EVENT_FLAG_AUTOUNSIGNAL) { + /* autounsignal flag lets one thread fall through before unsignalling */ + e->signalled = false; + } + } else { + /* unsignalled, block here */ + ret = wait_queue_block(&e->wait, timeout); + if (ret < 0) + goto err; + } + +err: + exit_critical_section(); + + return ret; +} + +status_t event_wait(event_t *e) +{ + return event_wait_timeout(e, INFINITE_TIME); +} + +status_t event_signal(event_t *e, bool reschedule) +{ + enter_critical_section(); + +#if EVENT_CHECK + ASSERT(e->magic == EVENT_MAGIC); +#endif + + if (!e->signalled) { + if (e->flags & EVENT_FLAG_AUTOUNSIGNAL) { + /* try to release one thread and leave unsignalled if successful */ + if (wait_queue_wake_one(&e->wait, reschedule, NO_ERROR) <= 0) { + /* + * if we didn't actually find a thread to wake up, go to + * signalled state and let the next call to event_wait + * unsignal the event. + */ + e->signalled = true; + } + } else { + /* release all threads and remain signalled */ + e->signalled = true; + wait_queue_wake_all(&e->wait, reschedule, NO_ERROR); + } + } + + exit_critical_section(); + + return NO_ERROR; +} + +status_t event_unsignal(event_t *e) +{ + enter_critical_section(); + +#if EVENT_CHECK + ASSERT(e->magic == EVENT_MAGIC); +#endif + + e->signalled = false; + + exit_critical_section(); + + return NO_ERROR; +} + diff --git a/lk/kernel/main.c b/lk/kernel/main.c new file mode 100644 index 0000000..f48ea55 --- /dev/null +++ b/lk/kernel/main.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include +#include + +extern void *__ctor_list; +extern void *__ctor_end; +extern int __bss_start; +extern int _end; + +static int bootstrap2(void *arg); + +#if (ENABLE_NANDWRITE) +void bootstrap_nandwrite(void); +#endif + +static void call_constructors(void) +{ + void **ctor; + + ctor = &__ctor_list; + while(ctor != &__ctor_end) { + void (*func)(void); + + func = (void (*)())*ctor; + + func(); + ctor++; + } +} + +/* called from crt0.S */ +void kmain(void) __NO_RETURN __EXTERNALLY_VISIBLE; +void kmain(void) +{ + // get us into some sort of thread context + thread_init_early(); + + // early arch stuff + arch_early_init(); + + // do any super early platform initialization + platform_early_init(); + + // do any super early target initialization + target_early_init(); + + dprintf(INFO, "welcome to lk\n\n"); + + // deal with any static constructors + dprintf(SPEW, "calling constructors\n"); + call_constructors(); + + // bring up the kernel heap + dprintf(SPEW, "initializing heap\n"); + heap_init(); + + // initialize the threading system + dprintf(SPEW, "initializing threads\n"); + thread_init(); + + // initialize the dpc system + dprintf(SPEW, "initializing dpc\n"); + dpc_init(); + + // initialize kernel timers + dprintf(SPEW, "initializing timers\n"); + timer_init(); + +#if (!ENABLE_NANDWRITE) + // create a thread to complete system initialization + dprintf(SPEW, "creating bootstrap completion thread\n"); + thread_resume(thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); + + // enable interrupts + exit_critical_section(); + + // become the idle thread + thread_become_idle(); +#else + bootstrap_nandwrite(); +#endif +} + +int main(void); + +static int bootstrap2(void *arg) +{ + dprintf(SPEW, "top of bootstrap2()\n"); + + arch_init(); + + // initialize the rest of the platform + dprintf(SPEW, "initializing platform\n"); + platform_init(); + + // initialize the target + dprintf(SPEW, "initializing target\n"); + target_init(); + + dprintf(SPEW, "calling apps_init()\n"); + apps_init(); + + return 0; +} + +#if (ENABLE_NANDWRITE) +void bootstrap_nandwrite(void) +{ + dprintf(SPEW, "top of bootstrap2()\n"); + + arch_init(); + + // initialize the rest of the platform + dprintf(SPEW, "initializing platform\n"); + platform_init(); + + // initialize the target + dprintf(SPEW, "initializing target\n"); + target_init(); + + dprintf(SPEW, "calling nandwrite_init()\n"); + nandwrite_init(); + + return 0; +} +#endif diff --git a/lk/kernel/mutex.c b/lk/kernel/mutex.c new file mode 100644 index 0000000..4998b6a --- /dev/null +++ b/lk/kernel/mutex.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +#if DEBUGLEVEL > 1 +#define MUTEX_CHECK 1 +#endif + +void mutex_init(mutex_t *m) +{ +#if MUTEX_CHECK +// ASSERT(m->magic != MUTEX_MAGIC); +#endif + + m->magic = MUTEX_MAGIC; + m->count = 0; + m->holder = 0; + wait_queue_init(&m->wait); +} + +void mutex_destroy(mutex_t *m) +{ + enter_critical_section(); + +#if MUTEX_CHECK + ASSERT(m->magic == MUTEX_MAGIC); +#endif + + if (m->holder != 0 && current_thread != m->holder) + panic("mutex_destroy: thread %p (%s) tried to release mutex %p it doesn't own. owned by %p (%s)\n", + current_thread, current_thread->name, m, m->holder, m->holder ? m->holder->name : "none"); + + m->magic = 0; + m->count = 0; + wait_queue_destroy(&m->wait, true); + exit_critical_section(); +} + +status_t mutex_acquire(mutex_t *m) +{ + status_t ret = NO_ERROR; + + if (current_thread == m->holder) + panic("mutex_acquire: thread %p (%s) tried to acquire mutex %p it already owns.\n", + current_thread, current_thread->name, m); + + enter_critical_section(); + +#if MUTEX_CHECK + ASSERT(m->magic == MUTEX_MAGIC); +#endif + +// dprintf("mutex_acquire: m %p, count %d, curr %p\n", m, m->count, current_thread); + + m->count++; + if (unlikely(m->count > 1)) { + /* + * block on the wait queue. If it returns an error, it was likely destroyed + * out from underneath us, so make sure we dont scribble thread ownership + * on the mutex. + */ + ret = wait_queue_block(&m->wait, INFINITE_TIME); + if (ret < 0) + goto err; + } + m->holder = current_thread; + +err: + exit_critical_section(); + + return ret; +} + +status_t mutex_acquire_timeout(mutex_t *m, time_t timeout) +{ + status_t ret = NO_ERROR; + + if (current_thread == m->holder) + panic("mutex_acquire_timeout: thread %p (%s) tried to acquire mutex %p it already owns.\n", + current_thread, current_thread->name, m); + + if (timeout == INFINITE_TIME) + return mutex_acquire(m); + + enter_critical_section(); + +#if MUTEX_CHECK + ASSERT(m->magic == MUTEX_MAGIC); +#endif + +// dprintf("mutex_acquire_timeout: m %p, count %d, curr %p, timeout %d\n", m, m->count, current_thread, timeout); + + m->count++; + if (unlikely(m->count > 1)) { + ret = wait_queue_block(&m->wait, timeout); + if (ret < NO_ERROR) { + /* if the acquisition timed out, back out the acquire and exit */ + if (ret == ERR_TIMED_OUT) { + /* + * XXX race: the mutex may have been destroyed after the timeout, + * but before we got scheduled again which makes messing with the + * count variable dangerous. + */ + m->count--; + goto err; + } + /* if there was a general error, it may have been destroyed out from + * underneath us, so just exit (which is really an invalid state anyway) + */ + } + } + m->holder = current_thread; + +err: + exit_critical_section(); + + return ret; +} + +status_t mutex_release(mutex_t *m) +{ + if (current_thread != m->holder) + panic("mutex_release: thread %p (%s) tried to release mutex %p it doesn't own. owned by %p (%s)\n", + current_thread, current_thread->name, m, m->holder, m->holder ? m->holder->name : "none"); + + enter_critical_section(); + +#if MUTEX_CHECK + ASSERT(m->magic == MUTEX_MAGIC); +#endif + +// dprintf("mutex_release: m %p, count %d, holder %p, curr %p\n", m, m->count, m->holder, current_thread); + + m->holder = 0; + m->count--; + if (unlikely(m->count >= 1)) { + /* release a thread */ +// dprintf("releasing thread\n"); + wait_queue_wake_one(&m->wait, true, NO_ERROR); + } + + exit_critical_section(); + + return NO_ERROR; +} + diff --git a/lk/kernel/rules.mk b/lk/kernel/rules.mk new file mode 100644 index 0000000..45cf94d --- /dev/null +++ b/lk/kernel/rules.mk @@ -0,0 +1,16 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +MODULES += \ + lib/libc \ + lib/debug \ + lib/heap + +OBJS += \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/dpc.o \ + $(LOCAL_DIR)/event.o \ + $(LOCAL_DIR)/main.o \ + $(LOCAL_DIR)/mutex.o \ + $(LOCAL_DIR)/thread.o \ + $(LOCAL_DIR)/timer.o + diff --git a/lk/kernel/thread.c b/lk/kernel/thread.c new file mode 100644 index 0000000..eeccdd6 --- /dev/null +++ b/lk/kernel/thread.c @@ -0,0 +1,666 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include +#include + +#if DEBUGLEVEL > 1 +#define THREAD_CHECKS 1 +#endif + +#if THREAD_STATS +struct thread_stats thread_stats; +#endif + +/* global thread list */ +static struct list_node thread_list; + +/* the current thread */ +thread_t *current_thread; + +/* the global critical section count */ +int critical_section_count = 1; + +/* the run queue */ +static struct list_node run_queue[NUM_PRIORITIES]; +static uint32_t run_queue_bitmap; + +/* the bootstrap thread (statically allocated) */ +static thread_t bootstrap_thread; + +/* the idle thread */ +thread_t *idle_thread; + +/* local routines */ +static void thread_resched(void); +static void idle_thread_routine(void) __NO_RETURN; + +/* run queue manipulation */ +static void insert_in_run_queue_head(thread_t *t) +{ +#if THREAD_CHECKS + ASSERT(t->magic == THREAD_MAGIC); + ASSERT(t->state == THREAD_READY); + ASSERT(!list_in_list(&t->queue_node)); + ASSERT(in_critical_section()); +#endif + + list_add_head(&run_queue[t->priority], &t->queue_node); + run_queue_bitmap |= (1<priority); +} + +static void insert_in_run_queue_tail(thread_t *t) +{ +#if THREAD_CHECKS + ASSERT(t->magic == THREAD_MAGIC); + ASSERT(t->state == THREAD_READY); + ASSERT(!list_in_list(&t->queue_node)); + ASSERT(in_critical_section()); +#endif + + list_add_tail(&run_queue[t->priority], &t->queue_node); + run_queue_bitmap |= (1<priority); +} + +static void init_thread_struct(thread_t *t, const char *name) +{ + memset(t, 0, sizeof(thread_t)); + t->magic = THREAD_MAGIC; + strlcpy(t->name, name, sizeof(t->name)); +} + +thread_t *thread_create(const char *name, thread_start_routine entry, void *arg, int priority, size_t stack_size) +{ + thread_t *t; + + t = malloc(sizeof(thread_t)); + if (!t) + return NULL; + + init_thread_struct(t, name); + + t->entry = entry; + t->arg = arg; + t->priority = priority; + t->saved_critical_section_count = 1; /* we always start inside a critical section */ + t->state = THREAD_SUSPENDED; + t->blocking_wait_queue = NULL; + t->wait_queue_block_ret = NO_ERROR; + + /* create the stack */ + t->stack = malloc(stack_size); + if (!t->stack) { + free(t); + return NULL; + } + + t->stack_size = stack_size; + + /* inheirit thread local storage from the parent */ + int i; + for (i=0; i < MAX_TLS_ENTRY; i++) + t->tls[i] = current_thread->tls[i]; + + /* set up the initial stack frame */ + arch_thread_initialize(t); + + /* add it to the global thread list */ + enter_critical_section(); + list_add_head(&thread_list, &t->thread_list_node); + exit_critical_section(); + + return t; +} + +status_t thread_resume(thread_t *t) +{ +#if THREAD_CHECKS + ASSERT(t->magic == THREAD_MAGIC); + ASSERT(t->state != THREAD_DEATH); +#endif + + if (t->state == THREAD_READY || t->state == THREAD_RUNNING) + return ERR_NOT_SUSPENDED; + + enter_critical_section(); + t->state = THREAD_READY; + insert_in_run_queue_head(t); + thread_yield(); + exit_critical_section(); + + return NO_ERROR; +} + +static void thread_cleanup_dpc(void *thread) +{ + thread_t *t = (thread_t *)thread; + +// dprintf(SPEW, "thread_cleanup_dpc: thread %p (%s)\n", t, t->name); + +#if THREAD_CHECKS + ASSERT(t->state == THREAD_DEATH); + ASSERT(t->blocking_wait_queue == NULL); + ASSERT(!list_in_list(&t->queue_node)); +#endif + + /* remove it from the master thread list */ + enter_critical_section(); + list_delete(&t->thread_list_node); + exit_critical_section(); + + /* free its stack and the thread structure itself */ + if (t->stack) + free(t->stack); + + free(t); +} + +void thread_exit(int retcode) +{ +#if THREAD_CHECKS + ASSERT(current_thread->magic == THREAD_MAGIC); + ASSERT(current_thread->state == THREAD_RUNNING); +#endif + +// dprintf("thread_exit: current %p\n", current_thread); + + enter_critical_section(); + + /* enter the dead state */ + current_thread->state = THREAD_DEATH; + current_thread->retcode = retcode; + + /* schedule a dpc to clean ourselves up */ + dpc_queue(thread_cleanup_dpc, (void *)current_thread, DPC_FLAG_NORESCHED); + + /* reschedule */ + thread_resched(); + + panic("somehow fell through thread_exit()\n"); +} + +static void idle_thread_routine(void) +{ + for(;;) + arch_idle(); +} + +/* + * Internal reschedule routine. The current thread needs to already be in whatever + * state and queues it needs to be in. This routine simply picks the next thread and + * switches to it. + */ +void thread_resched(void) +{ + thread_t *oldthread; + thread_t *newthread; + +// dprintf("thread_resched: current %p: ", current_thread); +// dump_thread(current_thread); + +#if THREAD_CHECKS + ASSERT(in_critical_section()); +#endif + +#if THREAD_STATS + thread_stats.reschedules++; +#endif + + oldthread = current_thread; + + // at the moment, can't deal with more than 32 priority levels + ASSERT(NUM_PRIORITIES <= 32); + + // should at least find the idle thread +#if THREAD_CHECKS + ASSERT(run_queue_bitmap != 0); +#endif + + int next_queue = HIGHEST_PRIORITY - __builtin_clz(run_queue_bitmap) - (32 - NUM_PRIORITIES); + //dprintf(SPEW, "bitmap 0x%x, next %d\n", run_queue_bitmap, next_queue); + + newthread = list_remove_head_type(&run_queue[next_queue], thread_t, queue_node); + +#if THREAD_CHECKS + ASSERT(newthread); +#endif + + if (list_is_empty(&run_queue[next_queue])) + run_queue_bitmap &= ~(1<= LOWEST_PRIORITY; i--) { + newthread = list_remove_head_type(&run_queue[i], thread_t, queue_node); + if (newthread) + break; + } +#endif + +// dprintf("newthread: "); +// dump_thread(newthread); + + newthread->state = THREAD_RUNNING; + + if (newthread == oldthread) + return; + + /* set up quantum for the new thread if it was consumed */ + if (newthread->remaining_quantum <= 0) { + newthread->remaining_quantum = 5; // XXX make this smarter + } + +#if THREAD_STATS + thread_stats.context_switches++; + + if (oldthread == idle_thread) { + bigtime_t now = current_time_hires(); + thread_stats.idle_time += now - thread_stats.last_idle_timestamp; + } + if (newthread == idle_thread) { + thread_stats.last_idle_timestamp = current_time_hires(); + } +#endif + +#if THREAD_CHECKS + ASSERT(critical_section_count > 0); + ASSERT(newthread->saved_critical_section_count > 0); +#endif + + /* do the switch */ + oldthread->saved_critical_section_count = critical_section_count; + current_thread = newthread; + critical_section_count = newthread->saved_critical_section_count; + arch_context_switch(oldthread, newthread); +} + +void thread_yield(void) +{ +#if THREAD_CHECKS + ASSERT(current_thread->magic == THREAD_MAGIC); + ASSERT(current_thread->state == THREAD_RUNNING); +#endif + + enter_critical_section(); + +#if THREAD_STATS + thread_stats.yields++; +#endif + + /* we are yielding the cpu, so stick ourselves into the tail of the run queue and reschedule */ + current_thread->state = THREAD_READY; + current_thread->remaining_quantum = 0; + insert_in_run_queue_tail(current_thread); + thread_resched(); + + exit_critical_section(); +} + +void thread_preempt(void) +{ +#if THREAD_CHECKS + ASSERT(current_thread->magic == THREAD_MAGIC); + ASSERT(current_thread->state == THREAD_RUNNING); +#endif + + enter_critical_section(); + +#if THREAD_STATS + if (current_thread != idle_thread) + thread_stats.preempts++; /* only track when a meaningful preempt happens */ +#endif + + /* we are being preempted, so we get to go back into the front of the run queue if we have quantum left */ + current_thread->state = THREAD_READY; + if (current_thread->remaining_quantum > 0) + insert_in_run_queue_head(current_thread); + else + insert_in_run_queue_tail(current_thread); /* if we're out of quantum, go to the tail of the queue */ + thread_resched(); + + exit_critical_section(); +} + +void thread_block(void) +{ +#if THREAD_CHECKS + ASSERT(current_thread->magic == THREAD_MAGIC); + ASSERT(current_thread->state == THREAD_BLOCKED); +#endif + + enter_critical_section(); + + /* we are blocking on something. the blocking code should have already stuck us on a queue */ + thread_resched(); + + exit_critical_section(); +} + +enum handler_return thread_timer_tick(void) +{ + if (current_thread == idle_thread) + return INT_NO_RESCHEDULE; + + current_thread->remaining_quantum--; + if (current_thread->remaining_quantum <= 0) + return INT_RESCHEDULE; + else + return INT_NO_RESCHEDULE; +} + +/* timer callback to wake up a sleeping thread */ +static enum handler_return thread_sleep_handler(timer_t *timer, time_t now, void *arg) +{ + thread_t *t = (thread_t *)arg; + +#if THREAD_CHECKS + ASSERT(t->magic == THREAD_MAGIC); + ASSERT(t->state == THREAD_SLEEPING); +#endif + + t->state = THREAD_READY; + insert_in_run_queue_head(t); + + return INT_RESCHEDULE; +} + +void thread_sleep(time_t delay) +{ + timer_t timer; + +#if THREAD_CHECKS + ASSERT(current_thread->magic == THREAD_MAGIC); + ASSERT(current_thread->state == THREAD_RUNNING); +#endif + + timer_initialize(&timer); + + enter_critical_section(); + timer_set_oneshot(&timer, delay, thread_sleep_handler, (void *)current_thread); + current_thread->state = THREAD_SLEEPING; + thread_resched(); + exit_critical_section(); +} + +void thread_init_early(void) +{ + int i; + + /* initialize the run queues */ + for (i=0; i < NUM_PRIORITIES; i++) + list_initialize(&run_queue[i]); + + /* initialize the thread list */ + list_initialize(&thread_list); + + /* create a thread to cover the current running state */ + thread_t *t = &bootstrap_thread; + init_thread_struct(t, "bootstrap"); + + /* half construct this thread, since we're already running */ + t->priority = HIGHEST_PRIORITY; + t->state = THREAD_RUNNING; + t->saved_critical_section_count = 1; + list_add_head(&thread_list, &t->thread_list_node); + current_thread = t; +} + +void thread_init(void) +{ +} + +void thread_set_name(const char *name) +{ + strlcpy(current_thread->name, name, sizeof(current_thread->name)); +} + +void thread_set_priority(int priority) +{ + if (priority < LOWEST_PRIORITY) + priority = LOWEST_PRIORITY; + if (priority > HIGHEST_PRIORITY) + priority = HIGHEST_PRIORITY; + current_thread->priority = priority; +} + +void thread_become_idle(void) +{ + thread_set_name("idle"); + thread_set_priority(IDLE_PRIORITY); + idle_thread = current_thread; + idle_thread_routine(); +} + +void dump_thread(thread_t *t) +{ + dprintf(INFO, "dump_thread: t %p (%s)\n", t, t->name); + dprintf(INFO, "\tstate %d, priority %d, remaining quantum %d, critical section %d\n", t->state, t->priority, t->remaining_quantum, t->saved_critical_section_count); + dprintf(INFO, "\tstack %p, stack_size %zd\n", t->stack, t->stack_size); + dprintf(INFO, "\tentry %p, arg %p\n", t->entry, t->arg); + dprintf(INFO, "\twait queue %p, wait queue ret %d\n", t->blocking_wait_queue, t->wait_queue_block_ret); + dprintf(INFO, "\ttls:"); + int i; + for (i=0; i < MAX_TLS_ENTRY; i++) { + dprintf(INFO, " 0x%x", t->tls[i]); + } + dprintf(INFO, "\n"); +} + +void dump_all_threads(void) +{ + thread_t *t; + + enter_critical_section(); + list_for_every_entry(&thread_list, t, thread_t, thread_list_node) { + dump_thread(t); + } + exit_critical_section(); +} + +/* wait queue */ +void wait_queue_init(wait_queue_t *wait) +{ + wait->magic = WAIT_QUEUE_MAGIC; + list_initialize(&wait->list); + wait->count = 0; +} + +static enum handler_return wait_queue_timeout_handler(timer_t *timer, time_t now, void *arg) +{ + thread_t *thread = (thread_t *)arg; + +#if THREAD_CHECKS + ASSERT(thread->magic == THREAD_MAGIC); +#endif + + if (thread_unblock_from_wait_queue(thread, false, ERR_TIMED_OUT) >= NO_ERROR) + return INT_RESCHEDULE; + + return INT_NO_RESCHEDULE; +} + +status_t wait_queue_block(wait_queue_t *wait, time_t timeout) +{ + timer_t timer; + +#if THREAD_CHECKS + ASSERT(wait->magic == WAIT_QUEUE_MAGIC); + ASSERT(current_thread->state == THREAD_RUNNING); + ASSERT(in_critical_section()); +#endif + + if (timeout == 0) + return ERR_TIMED_OUT; + + list_add_tail(&wait->list, ¤t_thread->queue_node); + wait->count++; + current_thread->state = THREAD_BLOCKED; + current_thread->blocking_wait_queue = wait; + current_thread->wait_queue_block_ret = NO_ERROR; + + /* if the timeout is nonzero or noninfinite, set a callback to yank us out of the queue */ + if (timeout != INFINITE_TIME) { + timer_initialize(&timer); + timer_set_oneshot(&timer, timeout, wait_queue_timeout_handler, (void *)current_thread); + } + + thread_block(); + + /* we don't really know if the timer fired or not, so it's better safe to try to cancel it */ + if (timeout != INFINITE_TIME) { + timer_cancel(&timer); + } + + return current_thread->wait_queue_block_ret; +} + +int wait_queue_wake_one(wait_queue_t *wait, bool reschedule, status_t wait_queue_error) +{ + thread_t *t; + int ret = 0; + +#if THREAD_CHECKS + ASSERT(wait->magic == WAIT_QUEUE_MAGIC); + ASSERT(in_critical_section()); +#endif + + t = list_remove_head_type(&wait->list, thread_t, queue_node); + if (t) { + wait->count--; +#if THREAD_CHECKS + ASSERT(t->state == THREAD_BLOCKED); +#endif + t->state = THREAD_READY; + t->wait_queue_block_ret = wait_queue_error; + t->blocking_wait_queue = NULL; + + /* if we're instructed to reschedule, stick the current thread on the head + * of the run queue first, so that the newly awakened thread gets a chance to run + * before the current one, but the current one doesn't get unnecessarilly punished. + */ + if (reschedule) { + current_thread->state = THREAD_READY; + insert_in_run_queue_head(current_thread); + } + insert_in_run_queue_head(t); + if (reschedule) + thread_resched(); + ret = 1; + } + + return ret; +} + +int wait_queue_wake_all(wait_queue_t *wait, bool reschedule, status_t wait_queue_error) +{ + thread_t *t; + int ret = 0; + +#if THREAD_CHECKS + ASSERT(wait->magic == WAIT_QUEUE_MAGIC); + ASSERT(in_critical_section()); +#endif + + if (reschedule && wait->count > 0) { + /* if we're instructed to reschedule, stick the current thread on the head + * of the run queue first, so that the newly awakened threads get a chance to run + * before the current one, but the current one doesn't get unnecessarilly punished. + */ + current_thread->state = THREAD_READY; + insert_in_run_queue_head(current_thread); + } + + /* pop all the threads off the wait queue into the run queue */ + while ((t = list_remove_head_type(&wait->list, thread_t, queue_node))) { + wait->count--; +#if THREAD_CHECKS + ASSERT(t->state == THREAD_BLOCKED); +#endif + t->state = THREAD_READY; + t->wait_queue_block_ret = wait_queue_error; + t->blocking_wait_queue = NULL; + + insert_in_run_queue_head(t); + ret++; + } + +#if THREAD_CHECKS + ASSERT(wait->count == 0); +#endif + + if (reschedule && ret > 0) + thread_resched(); + + return ret; +} + +void wait_queue_destroy(wait_queue_t *wait, bool reschedule) +{ +#if THREAD_CHECKS + ASSERT(wait->magic == WAIT_QUEUE_MAGIC); + ASSERT(in_critical_section()); +#endif + wait_queue_wake_all(wait, reschedule, ERR_OBJECT_DESTROYED); + wait->magic = 0; +} + +status_t thread_unblock_from_wait_queue(thread_t *t, bool reschedule, status_t wait_queue_error) +{ + enter_critical_section(); + +#if THREAD_CHECKS + ASSERT(t->magic == THREAD_MAGIC); +#endif + + if (t->state != THREAD_BLOCKED) + return ERR_NOT_BLOCKED; + +#if THREAD_CHECKS + ASSERT(t->blocking_wait_queue != NULL); + ASSERT(t->blocking_wait_queue->magic == WAIT_QUEUE_MAGIC); + ASSERT(list_in_list(&t->queue_node)); +#endif + + list_delete(&t->queue_node); + t->blocking_wait_queue->count--; + t->blocking_wait_queue = NULL; + t->state = THREAD_READY; + t->wait_queue_block_ret = wait_queue_error; + insert_in_run_queue_head(t); + + if (reschedule) + thread_resched(); + + exit_critical_section(); + + return NO_ERROR; +} + + diff --git a/lk/kernel/timer.c b/lk/kernel/timer.c new file mode 100644 index 0000000..71bc4fb --- /dev/null +++ b/lk/kernel/timer.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include + +static struct list_node timer_queue; + +void timer_initialize(timer_t *timer) +{ + timer->magic = TIMER_MAGIC; + list_clear_node(&timer->node); + timer->scheduled_time = 0; + timer->periodic_time = 0; + timer->callback = 0; + timer->arg = 0; +} + +static void insert_timer_in_queue(timer_t *timer) +{ + timer_t *entry; + + list_for_every_entry(&timer_queue, entry, timer_t, node) { + if (entry->scheduled_time > timer->scheduled_time) { + list_add_before(&entry->node, &timer->node); + return; + } + } + + /* walked off the end of the list */ + list_add_tail(&timer_queue, &timer->node); +} + +void timer_set_oneshot(timer_t *timer, time_t delay, timer_callback callback, void *arg) +{ + time_t now; + +// TRACEF("delay %d, callback %p, arg %p\n", delay, callback, arg); + + DEBUG_ASSERT(timer->magic == TIMER_MAGIC); + + if (list_in_list(&timer->node)) { + panic("timer %p already in list\n", timer); + } + + now = current_time(); + timer->scheduled_time = now + delay; + timer->periodic_time = 0; + timer->callback = callback; + timer->arg = arg; + +// TRACEF("scheduled time %u\n", timer->scheduled_time); + + enter_critical_section(); + + insert_timer_in_queue(timer); + + exit_critical_section(); +} + +void timer_cancel(timer_t *timer) +{ + DEBUG_ASSERT(timer->magic == TIMER_MAGIC); + + enter_critical_section(); + + if (list_in_list(&timer->node)) + list_delete(&timer->node); + + exit_critical_section(); +} + +/* called at interrupt time to process any pending timers */ +static enum handler_return timer_tick(void *arg, time_t now) +{ + timer_t *timer; + enum handler_return ret = INT_NO_RESCHEDULE; + +#if THREAD_STATS + thread_stats.timer_ints++; +#endif + + for (;;) { + /* see if there's an event to process */ + timer = list_peek_head_type(&timer_queue, timer_t, node); + if (likely(!timer || now < timer->scheduled_time)) + break; + + /* process it */ + DEBUG_ASSERT(timer->magic == TIMER_MAGIC); + list_delete(&timer->node); +// timer = list_remove_head_type(&timer_queue, timer_t, node); +// ASSERT(timer); + +#if THREAD_STATS + thread_stats.timers++; +#endif + +// TRACEF("firing callback %p, arg %p\n", timer->callback, timer->arg); + if (timer->callback(timer, now, timer->arg) == INT_RESCHEDULE) + ret = INT_RESCHEDULE; + } + + /* let the scheduler have a shot to do quantum expiration, etc */ + if (thread_timer_tick() == INT_RESCHEDULE) + ret = INT_RESCHEDULE; + + return INT_RESCHEDULE; +} + +void timer_init(void) +{ + list_initialize(&timer_queue); + + /* register for a periodic timer tick */ + platform_set_periodic_timer(timer_tick, NULL, 10); /* 10ms */ +} + + diff --git a/lk/lib/console/console.c b/lk/lib/console/console.c new file mode 100644 index 0000000..5782530 --- /dev/null +++ b/lk/lib/console/console.c @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include + +static cmd_block *command_list = NULL; + +/* a linear array of statically defined command blocks, + defined in the linker script. + */ +extern cmd_block __commands_start; +extern cmd_block __commands_end; + +static int cmd_help(int argc, const cmd_args *argv); +static int cmd_test(int argc, const cmd_args *argv); + +STATIC_COMMAND_START + { "help", "this list", &cmd_help }, + { "test", "test the command processor", &cmd_test }, +STATIC_COMMAND_END(help); + +int console_init(void) +{ + printf("console_init: entry\n"); + + /* add all the statically defined commands to the list */ + cmd_block *block; + for (block = &__commands_start; block != &__commands_end; block++) { + console_register_commands(block); + } + + return 0; +} + +static const cmd *match_command(const char *command) +{ + cmd_block *block; + size_t i; + + for (block = command_list; block != NULL; block = block->next) { + const cmd *curr_cmd = block->list; + for (i = 0; i < block->count; i++) { + if (strcmp(command, curr_cmd[i].cmd_str) == 0) { + return &curr_cmd[i]; + } + } + } + + return NULL; +} + +static int read_line(char *buffer, int len) +{ + int pos = 0; + int escape_level = 0; + + for (;;) { + char c; + + /* loop until we get a char */ + if (getc(&c) < 0) + continue; + +// printf("c = 0x%hhx\n", c); + + if (escape_level == 0) { + switch (c) { + case '\r': + case '\n': + putc(c); + goto done; + + case 0x7f: // backspace or delete + case 0x8: + if (pos > 0) { + pos--; + puts("\x1b[1D"); // move to the left one + putc(' '); + puts("\x1b[1D"); // move to the left one + } + break; + + case 0x1b: // escape + escape_level++; + break; + + default: + buffer[pos++] = c; + putc(c); + } + } else if (escape_level == 1) { + // inside an escape, look for '[' + if (c == '[') { + escape_level++; + } else { + // we didn't get it, abort + escape_level = 0; + } + } else { // escape_level > 1 + switch (c) { + case 67: // right arrow + buffer[pos++] = ' '; + putc(' '); + break; + case 68: // left arrow + if (pos > 0) { + pos--; + puts("\x1b[1D"); // move to the left one + putc(' '); + puts("\x1b[1D"); // move to the left one + } + break; + case 65: // up arrow + case 66: // down arrow + // XXX do history here + break; + default: + break; + } + escape_level = 0; + } + + /* end of line. */ + if (pos == (len - 1)) { + puts("\nerror: line too long\n"); + pos = 0; + goto done; + } + } + +done: +// printf("returning pos %d\n", pos); + + buffer[pos] = 0; + return pos; +} + +static int tokenize_command(char *buffer, cmd_args *args, int arg_count) +{ + int pos; + int arg; + bool finished; + enum { + INITIAL = 0, + IN_SPACE, + IN_TOKEN + } state; + + pos = 0; + arg = 0; + state = INITIAL; + finished = false; + + for (;;) { + char c = buffer[pos]; + + if (c == '\0') + finished = true; + +// printf("c 0x%hhx state %d arg %d pos %d\n", c, state, arg, pos); + + switch (state) { + case INITIAL: + if (isspace(c)) { + state = IN_SPACE; + } else { + state = IN_TOKEN; + args[arg].str = &buffer[pos]; + } + break; + case IN_TOKEN: + if (finished) { + arg++; + goto done; + } + if (isspace(c)) { + arg++; + buffer[pos] = 0; + /* are we out of tokens? */ + if (arg == arg_count) + goto done; + state = IN_SPACE; + } + pos++; + break; + case IN_SPACE: + if (finished) + goto done; + if (!isspace(c)) { + state = IN_TOKEN; + args[arg].str = &buffer[pos]; + } + pos++; + break; + } + } + +done: + return arg; +} + +static void convert_args(int argc, cmd_args *argv) +{ + int i; + + for (i = 0; i < argc; i++) { + argv[i].u = atoui(argv[i].str); + argv[i].i = atoi(argv[i].str); + } +} + +static void console_loop(void) +{ + cmd_args args[16]; + char buffer[256]; + + printf("entering main console loop\n"); + + for (;;) { + puts("] "); + + int len = read_line(buffer, sizeof(buffer)); + if (len == 0) + continue; + +// printf("line = '%s'\n", buffer); + + /* tokenize the line */ + int argc = tokenize_command(buffer, args, 16); + if (argc < 0) { + printf("syntax error\n"); + continue; + } else if (argc == 0) { + continue; + } + +// printf("after tokenize: argc %d\n", argc); +// for (int i = 0; i < argc; i++) +// printf("%d: '%s'\n", i, args[i].str); + + /* convert the args */ + convert_args(argc, args); + + /* try to match the command */ + const cmd *command = match_command(args[0].str); + if (!command) { + printf("command not found\n"); + continue; + } + + int result = command->cmd_callback(argc, args); + + // XXX do something with the result + } +} + + +void console_start(void) +{ + + console_loop(); +} + +int console_run_command(const char *string) +{ + const cmd *command; + + ASSERT(string != NULL); + + command = match_command(string); + if (!command) + return -1; + + int result = command->cmd_callback(0, NULL); + + return result; +} + +void console_register_commands(cmd_block *block) +{ + ASSERT(block); + ASSERT(block->next == NULL); + + block->next = command_list; + command_list = block; +} + +static int cmd_help(int argc, const cmd_args *argv) +{ + + printf("command list:\n"); + + cmd_block *block; + size_t i; + + for (block = command_list; block != NULL; block = block->next) { + const cmd *curr_cmd = block->list; + for (i = 0; i < block->count; i++) { + printf("\t%-16s: %s\n", curr_cmd[i].cmd_str, curr_cmd[i].help_str ? curr_cmd[i].help_str : ""); + } + } + + return 0; +} + +static int cmd_test(int argc, const cmd_args *argv) +{ + int i; + + printf("argc %d, argv %p\n", argc, argv); + for (i = 0; i < argc; i++) + printf("\t%d: str '%s', i %d, u %#x\n", i, argv[i].str, argv[i].i, argv[i].u); + + return 0; +} + diff --git a/lk/lib/console/rules.mk b/lk/lib/console/rules.mk new file mode 100644 index 0000000..ac3487d --- /dev/null +++ b/lk/lib/console/rules.mk @@ -0,0 +1,6 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include + +OBJS += \ + $(LOCAL_DIR)/console.o diff --git a/lk/lib/debug/debug.c b/lk/lib/debug/debug.c new file mode 100644 index 0000000..bdc2d02 --- /dev/null +++ b/lk/lib/debug/debug.c @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include +#include +#include +#include + +void spin(uint32_t usecs) +{ + bigtime_t start = current_time_hires(); + + while ((current_time_hires() - start) < usecs) + ; +} + +void halt(void) +{ + enter_critical_section(); // disable ints + platform_halt(); +} + +void _panic(void *caller, const char *fmt, ...) +{ + dprintf(ALWAYS, "panic (caller %p): ", caller); + + va_list ap; + va_start(ap, fmt); + _dvprintf(fmt, ap); + va_end(ap); + + halt(); +} + +int _dputs(const char *str) +{ + while(*str != 0) { + _dputc(*str++); + } + + return 0; +} + +int _dprintf(const char *fmt, ...) +{ + char buf[256]; + char ts_buf[13]; + int err; + + snprintf(ts_buf, sizeof(ts_buf), "[%u] ", current_time()); + dputs(ALWAYS, ts_buf); + + va_list ap; + va_start(ap, fmt); + err = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + dputs(ALWAYS, buf); + + return err; +} + +int _dvprintf(const char *fmt, va_list ap) +{ + char buf[256]; + int err; + + err = vsnprintf(buf, sizeof(buf), fmt, ap); + + dputs(ALWAYS, buf); + + return err; +} + +void hexdump(const void *ptr, size_t len) +{ + addr_t address = (addr_t)ptr; + size_t count; + int i; + + for (count = 0 ; count < len; count += 16) { + printf("0x%08lx: ", address); + printf("%08x %08x %08x %08x |", *(const uint32_t *)address, *(const uint32_t *)(address + 4), *(const uint32_t *)(address + 8), *(const uint32_t *)(address + 12)); + for (i=0; i < 16; i++) { + char c = *(const char *)(address + i); + if (isalpha(c)) { + printf("%c", c); + } else { + printf("."); + } + } + printf("|\n"); + address += 16; + } +} + +void hexdump8(const void *ptr, size_t len) +{ + addr_t address = (addr_t)ptr; + size_t count; + int i; + + for (count = 0 ; count < len; count += 16) { + printf("0x%08lx: ", address); + for (i=0; i < 16; i++) { + printf("0x%02hhx ", *(const uint8_t *)(address + i)); + } + printf("\n"); + address += 16; + } +} + +#ifdef WITH_LIB_CONSOLE +#include + +static int cmd_display_mem(int argc, const cmd_args *argv); +static int cmd_modify_mem(int argc, const cmd_args *argv); +static int cmd_fill_mem(int argc, const cmd_args *argv); +static int cmd_reset(int argc, const cmd_args *argv); +static int cmd_memtest(int argc, const cmd_args *argv); +static int cmd_copy_mem(int argc, const cmd_args *argv); + +STATIC_COMMAND_START +#if DEBUGLEVEL > 0 + { "dw", "display memory in words", &cmd_display_mem }, + { "dh", "display memory in halfwords", &cmd_display_mem }, + { "db", "display memory in bytes", &cmd_display_mem }, + { "mw", "modify word of memory", &cmd_modify_mem }, + { "mh", "modify halfword of memory", &cmd_modify_mem }, + { "mb", "modify byte of memory", &cmd_modify_mem }, + { "fw", "fill range of memory by word", &cmd_fill_mem }, + { "fh", "fill range of memory by halfword", &cmd_fill_mem }, + { "fb", "fill range of memory by byte", &cmd_fill_mem }, + { "mc", "copy a range of memory", &cmd_copy_mem }, +#endif +#if DEBUGLEVEL > 1 + { "mtest", "simple memory test", &cmd_memtest }, +#endif +STATIC_COMMAND_END(mem); + +static int cmd_display_mem(int argc, const cmd_args *argv) +{ + int size; + + if (argc < 3) { + printf("not enough arguments\n"); + printf("%s
\n", argv[0].str); + return -1; + } + + if (strcmp(argv[0].str, "dw") == 0) { + size = 4; + } else if (strcmp(argv[0].str, "dh") == 0) { + size = 2; + } else { + size = 1; + } + + unsigned long address = argv[1].u; + size_t len = argv[2].u; + unsigned long stop = address + len; + int count = 0; + + if ((address & (size - 1)) != 0) { + printf("unaligned address, cannot display\n"); + return -1; + } + + for ( ; address < stop; address += size) { + if (count == 0) + printf("0x%08lx: ", address); + switch (size) { + case 4: + printf("%08x ", *(uint32_t *)address); + break; + case 2: + printf("%04hx ", *(uint16_t *)address); + break; + case 1: + printf("%02hhx ", *(uint8_t *)address); + break; + } + count += size; + if (count == 16) { + printf("\n"); + count = 0; + } + } + + if (count != 0) + printf("\n"); + + return 0; +} + +static int cmd_modify_mem(int argc, const cmd_args *argv) +{ + int size; + + if (argc < 3) { + printf("not enough arguments\n"); + printf("%s
\n", argv[0].str); + return -1; + } + + if (strcmp(argv[0].str, "mw") == 0) { + size = 4; + } else if (strcmp(argv[0].str, "mh") == 0) { + size = 2; + } else { + size = 1; + } + + unsigned long address = argv[1].u; + unsigned int val = argv[2].u; + + if ((address & (size - 1)) != 0) { + printf("unaligned address, cannot modify\n"); + return -1; + } + + switch (size) { + case 4: + *(uint32_t *)address = (uint32_t)val; + break; + case 2: + *(uint16_t *)address = (uint16_t)val; + break; + case 1: + *(uint8_t *)address = (uint8_t)val; + break; + } + + return 0; +} + +static int cmd_fill_mem(int argc, const cmd_args *argv) +{ + int size; + + if (argc < 4) { + printf("not enough arguments\n"); + printf("%s
\n", argv[0].str); + return -1; + } + + if (strcmp(argv[0].str, "fw") == 0) { + size = 4; + } else if (strcmp(argv[0].str, "fh") == 0) { + size = 2; + } else { + size = 1; + } + + unsigned long address = argv[1].u; + unsigned long len = argv[2].u; + unsigned long stop = address + len; + unsigned int val = argv[3].u; + + if ((address & (size - 1)) != 0) { + printf("unaligned address, cannot modify\n"); + return -1; + } + + for ( ; address < stop; address += size) { + switch (size) { + case 4: + *(uint32_t *)address = (uint32_t)val; + break; + case 2: + *(uint16_t *)address = (uint16_t)val; + break; + case 1: + *(uint8_t *)address = (uint8_t)val; + break; + } + } + + return 0; +} + +static int cmd_copy_mem(int argc, const cmd_args *argv) +{ + if (argc < 4) { + printf("not enough arguments\n"); + printf("%s \n", argv[0].str); + return -1; + } + + addr_t source = argv[1].u; + addr_t target = argv[2].u; + size_t len = argv[3].u; + + memcpy((void *)target, (const void *)source, len); + + return 0; +} + +static int cmd_memtest(int argc, const cmd_args *argv) +{ + if (argc < 3) { + printf("not enough arguments\n"); + printf("%s \n", argv[0].str); + return -1; + } + + uint32_t *ptr; + size_t len; + + ptr = (uint32_t *)argv[1].u; + len = (size_t)argv[2].u; + + size_t i; + // write out + printf("writing first pass..."); + for (i = 0; i < len / 4; i++) { + ptr[i] = i; + } + printf("done\n"); + + // verify + printf("verifying..."); + for (i = 0; i < len / 4; i++) { + if (ptr[i] != i) + printf("error at %p\n", &ptr[i]); + } + printf("done\n"); + + return 0; +} + +#endif + diff --git a/lk/lib/debug/rules.mk b/lk/lib/debug/rules.mk new file mode 100644 index 0000000..5cc8926 --- /dev/null +++ b/lk/lib/debug/rules.mk @@ -0,0 +1,4 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/debug.o diff --git a/lk/lib/heap/heap.c b/lk/lib/heap/heap.c new file mode 100644 index 0000000..c67bc25 --- /dev/null +++ b/lk/lib/heap/heap.c @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include + +#define LOCAL_TRACE 0 + +#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1)) + +#define HEAP_MAGIC 'HEAP' + +#if WITH_STATIC_HEAP + +#if !defined(HEAP_START) || !defined(HEAP_LEN) +#error WITH_STATIC_HEAP set but no HEAP_START or HEAP_LEN defined +#endif + +#else +// end of the binary +extern int _end; + +// end of memory +extern int _end_of_ram; + +#define HEAP_START ((unsigned long)&_end) +#define HEAP_LEN ((size_t)&_end_of_ram - (size_t)&_end) +#endif + +struct free_heap_chunk { + struct list_node node; + size_t len; +}; + +struct heap { + void *base; + size_t len; + struct list_node free_list; +}; + +// heap static vars +static struct heap theheap; + +// structure placed at the beginning every allocation +struct alloc_struct_begin { + unsigned int magic; + void *ptr; + size_t size; +}; + +static void dump_free_chunk(struct free_heap_chunk *chunk) +{ + dprintf(INFO, "\t\tbase %p, end 0x%lx, len 0x%zx\n", chunk, (vaddr_t)chunk + chunk->len, chunk->len); +} + +static void heap_dump(void) +{ + dprintf(INFO, "Heap dump:\n"); + dprintf(INFO, "\tbase %p, len 0x%zx\n", theheap.base, theheap.len); + dprintf(INFO, "\tfree list:\n"); + + struct free_heap_chunk *chunk; + list_for_every_entry(&theheap.free_list, chunk, struct free_heap_chunk, node) { + dump_free_chunk(chunk); + } +} + +static void heap_test(void) +{ + void *ptr[16]; + + ptr[0] = heap_alloc(8, 0); + ptr[1] = heap_alloc(32, 0); + ptr[2] = heap_alloc(7, 0); + ptr[3] = heap_alloc(0, 0); + ptr[4] = heap_alloc(98713, 0); + ptr[5] = heap_alloc(16, 0); + + heap_free(ptr[5]); + heap_free(ptr[1]); + heap_free(ptr[3]); + heap_free(ptr[0]); + heap_free(ptr[4]); + heap_free(ptr[2]); + + heap_dump(); + + int i; + for (i=0; i < 16; i++) + ptr[i] = 0; + + for (i=0; i < 32768; i++) { + unsigned int index = (unsigned int)rand() % 16; + + if ((i % (16*1024)) == 0) + printf("pass %d\n", i); + +// printf("index 0x%x\n", index); + if (ptr[index]) { +// printf("freeing ptr[0x%x] = %p\n", index, ptr[index]); + heap_free(ptr[index]); + ptr[index] = 0; + } + unsigned int align = 1 << ((unsigned int)rand() % 8); + ptr[index] = heap_alloc((unsigned int)rand() % 32768, align); +// printf("ptr[0x%x] = %p, align 0x%x\n", index, ptr[index], align); + + DEBUG_ASSERT(((addr_t)ptr[index] % align) == 0); +// heap_dump(); + } + + for (i=0; i < 16; i++) { + if (ptr[i]) + heap_free(ptr[i]); + } + + heap_dump(); +} + +// try to insert this free chunk into the free list, consuming the chunk by merging it with +// nearby ones if possible. Returns base of whatever chunk it became in the list. +static struct free_heap_chunk *heap_insert_free_chunk(struct free_heap_chunk *chunk) +{ +#if DEBUGLEVEL > INFO + vaddr_t chunk_end = (vaddr_t)chunk + chunk->len; +#endif + +// dprintf("%s: chunk ptr %p, size 0x%lx, chunk_end 0x%x\n", __FUNCTION__, chunk, chunk->len, chunk_end); + + struct free_heap_chunk *next_chunk; + struct free_heap_chunk *last_chunk; + + // walk through the list, finding the node to insert before + list_for_every_entry(&theheap.free_list, next_chunk, struct free_heap_chunk, node) { + if (chunk < next_chunk) { + DEBUG_ASSERT(chunk_end <= (vaddr_t)next_chunk); + + list_add_before(&next_chunk->node, &chunk->node); + + goto try_merge; + } + } + + // walked off the end of the list, add it at the tail + list_add_tail(&theheap.free_list, &chunk->node); + + // try to merge with the previous chunk +try_merge: + last_chunk = list_prev_type(&theheap.free_list, &chunk->node, struct free_heap_chunk, node); + if (last_chunk) { + if ((vaddr_t)last_chunk + last_chunk->len == (vaddr_t)chunk) { + // easy, just extend the previous chunk + last_chunk->len += chunk->len; + + // remove ourself from the list + list_delete(&chunk->node); + + // set the chunk pointer to the newly extended chunk, in case + // it needs to merge with the next chunk below + chunk = last_chunk; + } + } + + // try to merge with the next chunk + if (next_chunk) { + if ((vaddr_t)chunk + chunk->len == (vaddr_t)next_chunk) { + // extend our chunk + chunk->len += next_chunk->len; + + // remove them from the list + list_delete(&next_chunk->node); + } + } + + return chunk; +} + +struct free_heap_chunk *heap_create_free_chunk(void *ptr, size_t len) +{ + DEBUG_ASSERT((len % sizeof(void *)) == 0); // size must be aligned on pointer boundary + + struct free_heap_chunk *chunk = (struct free_heap_chunk *)ptr; + chunk->len = len; + + return chunk; +} + +void *heap_alloc(size_t size, unsigned int alignment) +{ + void *ptr; + + LTRACEF("size %zd, align %d\n", size, alignment); + + // alignment must be power of 2 + if (alignment & (alignment - 1)) + return NULL; + + // we always put a size field + base pointer + magic in front of the allocation + size += sizeof(struct alloc_struct_begin); + + // make sure we allocate at least the size of a struct free_heap_chunk so that + // when we free it, we can create a struct free_heap_chunk struct and stick it + // in the spot + if (size < sizeof(struct free_heap_chunk)) + size = sizeof(struct free_heap_chunk); + + // round up size to a multiple of native pointer size + size = ROUNDUP(size, sizeof(void *)); + + // deal with nonzero alignments + if (alignment > 0) { + if (alignment < 16) + alignment = 16; + + // add alignment for worst case fit + size += alignment; + } + + // critical section + enter_critical_section(); + + // walk through the list + ptr = NULL; + struct free_heap_chunk *chunk; + list_for_every_entry(&theheap.free_list, chunk, struct free_heap_chunk, node) { + DEBUG_ASSERT((chunk->len % sizeof(void *)) == 0); // len should always be a multiple of pointer size + + // is it big enough to service our allocation? + if (chunk->len >= size) { + ptr = chunk; + + // remove it from the list + struct list_node *next_node = list_next(&theheap.free_list, &chunk->node); + list_delete(&chunk->node); + + if (chunk->len > size + sizeof(struct free_heap_chunk)) { + // there's enough space in this chunk to create a new one after the allocation + struct free_heap_chunk *newchunk = heap_create_free_chunk((uint8_t *)ptr + size, chunk->len - size); + + // truncate this chunk + chunk->len -= chunk->len - size; + + // add the new one where chunk used to be + if (next_node) + list_add_before(next_node, &newchunk->node); + else + list_add_tail(&theheap.free_list, &newchunk->node); + } + + // the allocated size is actually the length of this chunk, not the size requested + DEBUG_ASSERT(chunk->len >= size); + size = chunk->len; + + ptr = (void *)((addr_t)ptr + sizeof(struct alloc_struct_begin)); + + // align the output if requested + if (alignment > 0) { + ptr = (void *)ROUNDUP((addr_t)ptr, alignment); + } + + struct alloc_struct_begin *as = (struct alloc_struct_begin *)ptr; + as--; + as->magic = HEAP_MAGIC; + as->ptr = (void *)chunk; + as->size = size; + + break; + } + } + + LTRACEF("returning ptr %p\n", ptr); + +// heap_dump(); + + exit_critical_section(); + + return ptr; +} + +void heap_free(void *ptr) +{ + if (ptr == 0) + return; + + LTRACEF("ptr %p\n", ptr); + + // check for the old allocation structure + struct alloc_struct_begin *as = (struct alloc_struct_begin *)ptr; + as--; + + DEBUG_ASSERT(as->magic == HEAP_MAGIC); + + LTRACEF("allocation was %zd bytes long at ptr %p\n", as->size, as->ptr); + + // looks good, create a free chunk and add it to the pool + enter_critical_section(); + heap_insert_free_chunk(heap_create_free_chunk(as->ptr, as->size)); + exit_critical_section(); + +// heap_dump(); +} + +void heap_init(void) +{ + LTRACE_ENTRY; + + // set the heap range + theheap.base = (void *)HEAP_START; + theheap.len = HEAP_LEN; + + LTRACEF("base %p size %zd bytes\n", theheap.base, theheap.len); + + // initialize the free list + list_initialize(&theheap.free_list); + + // create an initial free chunk + heap_insert_free_chunk(heap_create_free_chunk(theheap.base, theheap.len)); + + // dump heap info +// heap_dump(); + +// dprintf(INFO, "running heap tests\n"); +// heap_test(); +} + +#if DEBUGLEVEL > 1 +#if WITH_LIB_CONSOLE + +#include + +static int cmd_heap(int argc, const cmd_args *argv); + +STATIC_COMMAND_START + { "heap", "heap debug commands", &cmd_heap }, +STATIC_COMMAND_END(heap); + +static int cmd_heap(int argc, const cmd_args *argv) +{ + if (argc < 2) { + printf("not enough arguments\n"); + return -1; + } + + if (strcmp(argv[1].str, "info") == 0) { + heap_dump(); + } else { + printf("unrecognized command\n"); + return -1; + } + + return 0; +} + +#endif +#endif + diff --git a/lk/lib/heap/rules.mk b/lk/lib/heap/rules.mk new file mode 100644 index 0000000..c9307ab --- /dev/null +++ b/lk/lib/heap/rules.mk @@ -0,0 +1,4 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/heap.o diff --git a/lk/lib/libc/atexit.c b/lk/lib/libc/atexit.c new file mode 100644 index 0000000..85d7bdf --- /dev/null +++ b/lk/lib/libc/atexit.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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. + */ + +/* nulled out atexit. static object constructors call this */ +int atexit(void (*func)(void)) +{ + return 0; +} + diff --git a/lk/lib/libc/atoi.c b/lk/lib/libc/atoi.c new file mode 100644 index 0000000..e3dd320 --- /dev/null +++ b/lk/lib/libc/atoi.c @@ -0,0 +1,105 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +#define LONG_IS_INT 1 + +static int hexval(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + + return 0; +} + +int atoi(const char *num) +{ +#if !LONG_IS_INT + // XXX fail +#else + return atol(num); +#endif +} + +unsigned int atoui(const char *num) +{ +#if !LONG_IS_INT + // XXX fail +#else + return atoul(num); +#endif +} + +long atol(const char *num) +{ + long value = 0; + int neg = 0; + + if (num[0] == '0' && num[1] == 'x') { + // hex + num += 2; + while (*num && isxdigit(*num)) + value = value * 16 + hexval(*num++); + } else { + // decimal + if (num[0] == '-') { + neg = 1; + num++; + } + while (*num && isdigit(*num)) + value = value * 10 + *num++ - '0'; + } + + if (neg) + value = -value; + + return value; +} + +unsigned long atoul(const char *num) +{ + unsigned long value = 0; + if (num[0] == '0' && num[1] == 'x') { + // hex + num += 2; + while (*num && isxdigit(*num)) + value = value * 16 + hexval(*num++); + } else { + // decimal + while (*num && isdigit(*num)) + value = value * 10 + *num++ - '0'; + } + + return value; +} + diff --git a/lk/lib/libc/ctype.c b/lk/lib/libc/ctype.c new file mode 100644 index 0000000..1509822 --- /dev/null +++ b/lk/lib/libc/ctype.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +#if 0 +/* XXX unimplemented for now */ +int iscntrl(int c); +int isgraph(int c); +int isprint(int c); +int ispunct(int c); +#endif + +int isblank(int c) +{ + return (c == ' ' || c == '\t'); +} + +int isspace(int c) +{ + return (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'); +} + +int islower(int c) +{ + return ((c >= 'a') && (c <= 'z')); +} + +int isupper(int c) +{ + return ((c >= 'A') && (c <= 'Z')); +} + +int isdigit(int c) +{ + return ((c >= '0') && (c <= '9')); +} + +int isalpha(int c) +{ + return isupper(c) || islower(c); +} + +int isalnum(int c) +{ + return isalpha(c) || isdigit(c); +} + +int isxdigit(int c) +{ + return isdigit(c) || ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F')); +} + +int tolower(int c) +{ + if ((c >= 'A') && (c <= 'Z')) + return c + ('a' - 'A'); + return c; +} + +int toupper(int c) +{ + if ((c >= 'a') && (c <= 'z')) + return c + ('A' - 'a'); + return c; +} + diff --git a/lk/lib/libc/eabi.c b/lk/lib/libc/eabi.c new file mode 100644 index 0000000..9d607f1 --- /dev/null +++ b/lk/lib/libc/eabi.c @@ -0,0 +1,51 @@ +/* Copyright (c) 2008 Travis Geiselbrecht + * + * 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. + */ + +/* some cruft we have to define when using the linux toolchain */ +#include + +#if defined(__ARM_EABI_UNWINDER__) && __ARM_EABI_UNWINDER__ + +/* Our toolchain has eabi functionality built in, but they're not really used. + * so we stub them out here. */ +_Unwind_Reason_Code __aeabi_unwind_cpp_pr0(_Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context) +{ + return _URC_FAILURE; +} + +_Unwind_Reason_Code __aeabi_unwind_cpp_pr1(_Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context) +{ + return _URC_FAILURE; +} + +_Unwind_Reason_Code __aeabi_unwind_cpp_pr2(_Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context) +{ + return _URC_FAILURE; +} + +#endif + +/* needed by some piece of EABI */ +void raise(void) +{ +} + diff --git a/lk/lib/libc/malloc.c b/lk/lib/libc/malloc.c new file mode 100644 index 0000000..fd5fe8a --- /dev/null +++ b/lk/lib/libc/malloc.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +void *malloc(size_t size) +{ + return heap_alloc(size, 0); +} + +void *memalign(size_t boundary, size_t size) +{ + return heap_alloc(size, boundary); +} + +void *calloc(size_t count, size_t size) +{ + void *ptr; + size_t realsize = count * size; + + ptr = heap_alloc(realsize, 0); + if (!ptr) + return NULL; + + memset(ptr, 0, realsize); + return ptr; +} + +void free(void *ptr) +{ + return heap_free(ptr); +} + diff --git a/lk/lib/libc/new.cpp b/lk/lib/libc/new.cpp new file mode 100644 index 0000000..3a5f431 --- /dev/null +++ b/lk/lib/libc/new.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006 Travis Geiselbrecht + * + * 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 + +void *operator new(size_t s) +{ + return heap_alloc(s, 0); +} + +void *operator new[](size_t s) +{ + return heap_alloc(s, 0); +} + +void *operator new(size_t , void *p) +{ + return p; +} + +void operator delete(void *p) +{ + return heap_free(p); +} + +void operator delete[](void *p) +{ + return heap_free(p); +} + diff --git a/lk/lib/libc/printf.c b/lk/lib/libc/printf.c new file mode 100644 index 0000000..b7bf2bb --- /dev/null +++ b/lk/lib/libc/printf.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include + +void putc(char c) +{ + return _dputc(c); +} + +int puts(const char *str) +{ + return _dputs(str); +} + +int getc(char *c) +{ + return dgetc(c); +} + +int printf(const char *fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = _dvprintf(fmt, ap); + va_end(ap); + + return err; +} + +int sprintf(char *str, const char *fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = vsprintf(str, fmt, ap); + va_end(ap); + + return err; +} + +int snprintf(char *str, size_t len, const char *fmt, ...) +{ + int err; + + va_list ap; + va_start(ap, fmt); + err = vsnprintf(str, len, fmt, ap); + va_end(ap); + + return err; +} + + +#define LONGFLAG 0x00000001 +#define LONGLONGFLAG 0x00000002 +#define HALFFLAG 0x00000004 +#define HALFHALFFLAG 0x00000008 +#define SIZETFLAG 0x00000010 +#define ALTFLAG 0x00000020 +#define CAPSFLAG 0x00000040 +#define SHOWSIGNFLAG 0x00000080 +#define SIGNEDFLAG 0x00000100 +#define LEFTFORMATFLAG 0x00000200 +#define LEADZEROFLAG 0x00000400 + +static char *longlong_to_string(char *buf, unsigned long long n, int len, uint flag) +{ + int pos = len; + int negative = 0; + + if((flag & SIGNEDFLAG) && (long long)n < 0) { + negative = 1; + n = -n; + } + + buf[--pos] = 0; + + /* only do the math if the number is >= 10 */ + while(n >= 10) { + int digit = n % 10; + + n /= 10; + + buf[--pos] = digit + '0'; + } + buf[--pos] = n + '0'; + + if(negative) + buf[--pos] = '-'; + else if((flag & SHOWSIGNFLAG)) + buf[--pos] = '+'; + + return &buf[pos]; +} + +static char *longlong_to_hexstring(char *buf, unsigned long long u, int len, uint flag) +{ + int pos = len; + static const char hextable[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + static const char hextable_caps[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + const char *table; + + if((flag & CAPSFLAG)) + table = hextable_caps; + else + table = hextable; + + buf[--pos] = 0; + do { + unsigned int digit = u % 16; + u /= 16; + + buf[--pos] = table[digit]; + } while(u != 0); + + return &buf[pos]; +} + +int vsprintf(char *str, const char *fmt, va_list ap) +{ + return vsnprintf(str, INT_MAX, fmt, ap); +} + +int vsnprintf(char *str, size_t len, const char *fmt, va_list ap) +{ + char c; + unsigned char uc; + const char *s; + unsigned long long n; + void *ptr; + int flags; + unsigned int format_num; + size_t chars_written = 0; + char num_buffer[32]; + +#define OUTPUT_CHAR(c) do { (*str++ = c); chars_written++; if (chars_written + 1 == len) goto done; } while(0) +#define OUTPUT_CHAR_NOLENCHECK(c) do { (*str++ = c); chars_written++; } while(0) + + for(;;) { + /* handle regular chars that aren't format related */ + while((c = *fmt++) != 0) { + if(c == '%') + break; /* we saw a '%', break and start parsing format */ + OUTPUT_CHAR(c); + } + + /* make sure we haven't just hit the end of the string */ + if(c == 0) + break; + + /* reset the format state */ + flags = 0; + format_num = 0; + +next_format: + /* grab the next format character */ + c = *fmt++; + if(c == 0) + break; + + switch(c) { + case '0'...'9': + if (c == '0' && format_num == 0) + flags |= LEADZEROFLAG; + format_num *= 10; + format_num += c - '0'; + goto next_format; + case '.': + /* XXX for now eat numeric formatting */ + goto next_format; + case '%': + OUTPUT_CHAR('%'); + break; + case 'c': + uc = va_arg(ap, unsigned int); + OUTPUT_CHAR(uc); + break; + case 's': + s = va_arg(ap, const char *); + if(s == 0) + s = ""; + goto _output_string; + case '-': + flags |= LEFTFORMATFLAG; + goto next_format; + case '+': + flags |= SHOWSIGNFLAG; + goto next_format; + case '#': + flags |= ALTFLAG; + goto next_format; + case 'l': + if(flags & LONGFLAG) + flags |= LONGLONGFLAG; + flags |= LONGFLAG; + goto next_format; + case 'h': + if(flags & HALFFLAG) + flags |= HALFHALFFLAG; + flags |= HALFFLAG; + goto next_format; + case 'z': + flags |= SIZETFLAG; + goto next_format; + case 'D': + flags |= LONGFLAG; + /* fallthrough */ + case 'i': + case 'd': + n = (flags & LONGLONGFLAG) ? va_arg(ap, long long) : + (flags & LONGFLAG) ? va_arg(ap, long) : + (flags & HALFHALFFLAG) ? (signed char)va_arg(ap, int) : + (flags & HALFFLAG) ? (short)va_arg(ap, int) : + (flags & SIZETFLAG) ? va_arg(ap, ssize_t) : + va_arg(ap, int); + flags |= SIGNEDFLAG; + s = longlong_to_string(num_buffer, n, sizeof(num_buffer), flags); + goto _output_string; + case 'U': + flags |= LONGFLAG; + /* fallthrough */ + case 'u': + n = (flags & LONGLONGFLAG) ? va_arg(ap, unsigned long long) : + (flags & LONGFLAG) ? va_arg(ap, unsigned long) : + (flags & HALFHALFFLAG) ? (unsigned char)va_arg(ap, unsigned int) : + (flags & HALFFLAG) ? (unsigned short)va_arg(ap, unsigned int) : + (flags & SIZETFLAG) ? va_arg(ap, size_t) : + va_arg(ap, unsigned int); + s = longlong_to_string(num_buffer, n, sizeof(num_buffer), flags); + goto _output_string; + case 'p': + flags |= LONGFLAG | ALTFLAG; + goto hex; + case 'X': + flags |= CAPSFLAG; + /* fallthrough */ +hex: + case 'x': + n = (flags & LONGLONGFLAG) ? va_arg(ap, unsigned long long) : + (flags & LONGFLAG) ? va_arg(ap, unsigned long) : + (flags & HALFHALFFLAG) ? (unsigned char)va_arg(ap, unsigned int) : + (flags & HALFFLAG) ? (unsigned short)va_arg(ap, unsigned int) : + (flags & SIZETFLAG) ? va_arg(ap, size_t) : + va_arg(ap, unsigned int); + s = longlong_to_hexstring(num_buffer, n, sizeof(num_buffer), flags); + if(flags & ALTFLAG) { + OUTPUT_CHAR('0'); + OUTPUT_CHAR((flags & CAPSFLAG) ? 'X': 'x'); + } + goto _output_string; + case 'n': + ptr = va_arg(ap, void *); + if(flags & LONGLONGFLAG) + *(long long *)ptr = chars_written; + else if(flags & LONGFLAG) + *(long *)ptr = chars_written; + else if(flags & HALFHALFFLAG) + *(signed char *)ptr = chars_written; + else if(flags & HALFFLAG) + *(short *)ptr = chars_written; + else if(flags & SIZETFLAG) + *(size_t *)ptr = chars_written; + else + *(int *)ptr = chars_written; + break; + default: + OUTPUT_CHAR('%'); + OUTPUT_CHAR(c); + break; + } + + /* move on to the next field */ + continue; + + /* shared output code */ +_output_string: + if (flags & LEFTFORMATFLAG) { + /* left justify the text */ + uint count = 0; + while(*s != 0) { + OUTPUT_CHAR(*s++); + count++; + } + + /* pad to the right (if necessary) */ + for (; format_num > count; format_num--) + OUTPUT_CHAR(' '); + } else { + /* right justify the text (digits) */ + size_t string_len = strlen(s); + char outchar = (flags & LEADZEROFLAG) ? '0' : ' '; + for (; format_num > string_len; format_num--) + OUTPUT_CHAR(outchar); + + /* output the string */ + while(*s != 0) + OUTPUT_CHAR(*s++); + } + continue; + } + +done: + /* null terminate */ + OUTPUT_CHAR_NOLENCHECK('\0'); + chars_written--; /* don't count the null */ + +#undef OUTPUT_CHAR +#undef OUTPUT_CHAR_NOLENCHECK + + return chars_written; +} + + diff --git a/lk/lib/libc/pure_virtual.cpp b/lk/lib/libc/pure_virtual.cpp new file mode 100644 index 0000000..68cfe3b --- /dev/null +++ b/lk/lib/libc/pure_virtual.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2006 Travis Geiselbrecht + * + * 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 + +extern "C" void __cxa_pure_virtual(void) +{ + panic("pure virtual called\n"); +} + diff --git a/lk/lib/libc/rand.c b/lk/lib/libc/rand.c new file mode 100644 index 0000000..fe4f392 --- /dev/null +++ b/lk/lib/libc/rand.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +static int randseed = 12345; + +int rand(void) +{ + return (randseed = randseed * 12345 + 17); +} diff --git a/lk/lib/libc/rules.mk b/lk/lib/libc/rules.mk new file mode 100644 index 0000000..e250cfe --- /dev/null +++ b/lk/lib/libc/rules.mk @@ -0,0 +1,20 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/atoi.o \ + $(LOCAL_DIR)/ctype.o \ + $(LOCAL_DIR)/printf.o \ + $(LOCAL_DIR)/malloc.o \ + $(LOCAL_DIR)/rand.o \ + $(LOCAL_DIR)/eabi.o + + +include $(LOCAL_DIR)/string/rules.mk + +ifeq ($(WITH_CPP_SUPPORT),true) +OBJS += \ + $(LOCAL_DIR)/new.o \ + $(LOCAL_DIR)/atexit.o \ + $(LOCAL_DIR)/pure_virtual.o +endif + diff --git a/lk/lib/libc/string/arch/arm/memcpy.S b/lk/lib/libc/string/arch/arm/memcpy.S new file mode 100644 index 0000000..3b7816d --- /dev/null +++ b/lk/lib/libc/string/arch/arm/memcpy.S @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +.text +.align 2 + +/* void bcopy(const void *src, void *dest, size_t n); */ +FUNCTION(bcopy) + // swap args for bcopy + mov r12, r0 + mov r0, r1 + mov r1, r12 + +/* void *memcpy(void *dest, const void *src, size_t n); */ +FUNCTION(memmove) +FUNCTION(memcpy) + // check for zero length copy or the same pointer + cmp r2, #0 + cmpne r1, r0 + bxeq lr + + // save a few registers for use and the return code (input dst) + stmfd sp!, {r0, r4, r5, lr} + + // check for forwards overlap (src > dst, distance < len) + subs r3, r0, r1 + cmpgt r2, r3 + bgt .L_forwardoverlap + + // check for a short copy len. + // 20 bytes is enough so that if a 16 byte alignment needs to happen there is at least a + // wordwise copy worth of work to be done. + cmp r2, #(16+4) + blt .L_bytewise + + // see if they are similarly aligned on 4 byte boundaries + eor r3, r0, r1 + tst r3, #3 + bne .L_bytewise // dissimilarly aligned, nothing we can do (for now) + + // check for 16 byte alignment on dst. + // this will also catch src being not 4 byte aligned, since it is similarly 4 byte + // aligned with dst at this point. + tst r0, #15 + bne .L_not16bytealigned + + // check to see if we have at least 32 bytes of data to copy. + // if not, just revert to wordwise copy + cmp r2, #32 + blt .L_wordwise + +.L_bigcopy: + // copy 32 bytes at a time. src & dst need to be at least 4 byte aligned, + // and we need at least 32 bytes remaining to copy + + // save r6-r7 for use in the big copy + stmfd sp!, {r6-r7} + + sub r2, r2, #32 // subtract an extra 32 to the len so we can avoid an extra compare + +.L_bigcopy_loop: + ldmia r1!, {r4, r5, r6, r7} + stmia r0!, {r4, r5, r6, r7} + ldmia r1!, {r4, r5, r6, r7} + subs r2, r2, #32 + stmia r0!, {r4, r5, r6, r7} + bge .L_bigcopy_loop + + // restore r6-r7 + ldmfd sp!, {r6-r7} + + // see if we are done + adds r2, r2, #32 + beq .L_done + + // less then 4 bytes left? + cmp r2, #4 + blt .L_bytewise + +.L_wordwise: + // copy 4 bytes at a time. + // src & dst are guaranteed to be word aligned, and at least 4 bytes are left to copy. + subs r2, r2, #4 + +.L_wordwise_loop: + ldr r3, [r1], #4 + subs r2, r2, #4 + str r3, [r0], #4 + bge .L_wordwise_loop + + // correct the remaining len and test for completion + adds r2, r2, #4 + beq .L_done + +.L_bytewise: + // simple bytewise copy + ldrb r3, [r1], #1 + subs r2, r2, #1 + strb r3, [r0], #1 + bgt .L_bytewise + +.L_done: + // load dst for return and restore r4,r5 +#if ARM_ARCH_LEVEL >= 5 + ldmfd sp!, {r0, r4, r5, pc} +#else + ldmfd sp!, {r0, r4, r5, lr} + bx lr +#endif + +.L_not16bytealigned: + // dst is not 16 byte aligned, so we will copy up to 15 bytes to get it aligned. + // src is guaranteed to be similarly word aligned with dst. + + // set the condition flags based on the alignment. + lsl r12, r0, #28 + rsb r12, r12, #0 + msr CPSR_f, r12 // move into NZCV fields in CPSR + + // move as many bytes as necessary to get the dst aligned + ldrvsb r3, [r1], #1 // V set + ldrcsh r4, [r1], #2 // C set + ldreq r5, [r1], #4 // Z set + + strvsb r3, [r0], #1 + strcsh r4, [r0], #2 + streq r5, [r0], #4 + + ldmmiia r1!, {r3-r4} // N set + stmmiia r0!, {r3-r4} + + // fix the remaining len + sub r2, r2, r12, lsr #28 + + // test to see what we should do now + cmp r2, #32 + bge .L_bigcopy + b .L_wordwise + + // src and dest overlap 'forwards' or dst > src +.L_forwardoverlap: + + // do a bytewise reverse copy for now + add r1, r1, r2 + add r0, r0, r2 + +.L_bytewisereverse: + // simple bytewise reverse copy + ldrb r3, [r1], #-1 + subs r2, r2, #1 + strb r3, [r0], #-1 + bgt .L_bytewisereverse + + b .L_done + diff --git a/lk/lib/libc/string/arch/arm/memset.S b/lk/lib/libc/string/arch/arm/memset.S new file mode 100644 index 0000000..b31d053 --- /dev/null +++ b/lk/lib/libc/string/arch/arm/memset.S @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +.text +.align 2 + +/* void bzero(void *s, size_t n); */ +FUNCTION(bzero) + mov r2, r1 + mov r1, #0 + +/* void *memset(void *s, int c, size_t n); */ +FUNCTION(memset) + // check for zero length + cmp r2, #0 + bxeq lr + + // save the original pointer + mov r12, r0 + + // short memsets aren't worth optimizing + cmp r2, #(32 + 16) + blt .L_bytewise + + // fill a 32 bit register with the 8 bit value + and r1, r1, #0xff + orr r1, r1, r1, lsl #8 + orr r1, r1, r1, lsl #16 + + // check for 16 byte alignment + tst r0, #15 + bne .L_not16bytealigned + +.L_bigset: + // dump some registers to make space for our values + stmfd sp!, { r4-r5 } + + // fill a bunch of registers with the set value + mov r3, r1 + mov r4, r1 + mov r5, r1 + + // prepare the count register so we can avoid an extra compare + sub r2, r2, #32 + + // 32 bytes at a time +.L_bigset_loop: + stmia r0!, { r1, r3, r4, r5 } + subs r2, r2, #32 + stmia r0!, { r1, r3, r4, r5 } + bge .L_bigset_loop + + // restore our dumped registers + ldmfd sp!, { r4-r5 } + + // see if we're done + adds r2, r2, #32 + beq .L_done + +.L_bytewise: + // bytewise memset + subs r2, r2, #1 + strb r1, [r0], #1 + bgt .L_bytewise + +.L_done: + // restore the base pointer as return value + mov r0, r12 + bx lr + +.L_not16bytealigned: + // dst is not 16 byte aligned, so we will set up to 15 bytes to get it aligned. + + // set the condition flags based on the alignment. + lsl r3, r0, #28 + rsb r3, r3, #0 + msr CPSR_f, r3 // move into NZCV fields in CPSR + + // move as many bytes as necessary to get the dst aligned + strvsb r1, [r0], #1 // V set + strcsh r1, [r0], #2 // C set + streq r1, [r0], #4 // Z set + strmi r1, [r0], #4 // N set + strmi r1, [r0], #4 // N set + + // fix the remaining len + sub r2, r2, r3, lsr #28 + + // do the large memset + b .L_bigset + diff --git a/lk/lib/libc/string/arch/arm/rules.mk b/lk/lib/libc/string/arch/arm/rules.mk new file mode 100644 index 0000000..89a68f4 --- /dev/null +++ b/lk/lib/libc/string/arch/arm/rules.mk @@ -0,0 +1,11 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +ASM_STRING_OPS := bcopy bzero memcpy memmove memset + +OBJS += \ + $(LOCAL_DIR)/memcpy.o \ + $(LOCAL_DIR)/memset.o + +# filter out the C implementation +C_STRING_OPS := $(filter-out $(ASM_STRING_OPS),$(C_STRING_OPS)) + diff --git a/lk/lib/libc/string/bcopy.c b/lk/lib/libc/string/bcopy.c new file mode 100644 index 0000000..873e6f6 --- /dev/null +++ b/lk/lib/libc/string/bcopy.c @@ -0,0 +1,35 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +void * +bcopy(void const *src, void *dest, size_t count) +{ + return memcpy(dest, src, count); +} + diff --git a/lk/lib/libc/string/bzero.c b/lk/lib/libc/string/bzero.c new file mode 100644 index 0000000..32b43bb --- /dev/null +++ b/lk/lib/libc/string/bzero.c @@ -0,0 +1,35 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +void +bzero(void *dst, size_t count) +{ + memset(dst, 0, count); +} + diff --git a/lk/lib/libc/string/memchr.c b/lk/lib/libc/string/memchr.c new file mode 100644 index 0000000..094c2a1 --- /dev/null +++ b/lk/lib/libc/string/memchr.c @@ -0,0 +1,45 @@ +/* +** Copyright 2001, Manuel J. Petit. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +void * +memchr(void const *buf, int c, size_t len) +{ + size_t i; + unsigned char const *b= buf; + unsigned char x= (c&0xff); + + for(i= 0; i< len; i++) { + if(b[i]== x) { + return (void*)(b+i); + } + } + + return NULL; +} + diff --git a/lk/lib/libc/string/memcmp.c b/lk/lib/libc/string/memcmp.c new file mode 100644 index 0000000..a050bc7 --- /dev/null +++ b/lk/lib/libc/string/memcmp.c @@ -0,0 +1,40 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +int +memcmp(const void *cs, const void *ct, size_t count) +{ + const unsigned char *su1, *su2; + signed char res = 0; + + for(su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) + if((res = *su1 - *su2) != 0) + break; + return res; +} diff --git a/lk/lib/libc/string/memcpy.c b/lk/lib/libc/string/memcpy.c new file mode 100644 index 0000000..00e547e --- /dev/null +++ b/lk/lib/libc/string/memcpy.c @@ -0,0 +1,69 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + + +#if !_ASM_MEMCPY + +typedef long word; + +#define lsize sizeof(word) +#define lmask (lsize - 1) + +void *memcpy(void *dest, const void *src, size_t count) +{ + char *d = (char *)dest; + const char *s = (const char *)src; + int len; + + if(count == 0 || dest == src) + return dest; + + if(((long)d | (long)s) & lmask) { + // src and/or dest do not align on word boundary + if((((long)d ^ (long)s) & lmask) || (count < lsize)) + len = count; // copy the rest of the buffer with the byte mover + else + len = lsize - ((long)d & lmask); // move the ptrs up to a word boundary + + count -= len; + for(; len > 0; len--) + *d++ = *s++; + } + for(len = count / lsize; len > 0; len--) { + *(word *)d = *(word *)s; + d += lsize; + s += lsize; + } + for(len = count & lmask; len > 0; len--) + *d++ = *s++; + + return dest; +} + +#endif diff --git a/lk/lib/libc/string/memmove.c b/lk/lib/libc/string/memmove.c new file mode 100644 index 0000000..cb08a6c --- /dev/null +++ b/lk/lib/libc/string/memmove.c @@ -0,0 +1,93 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +#if !_ASM_MEMMOVE + +typedef long word; + +#define lsize sizeof(word) +#define lmask (lsize - 1) + +void * +memmove(void *dest, void const *src, size_t count) +{ + char *d = (char *)dest; + const char *s = (const char *)src; + int len; + + if(count == 0 || dest == src) + return dest; + + if((long)d < (long)s) { + if(((long)d | (long)s) & lmask) { + // src and/or dest do not align on word boundary + if((((long)d ^ (long)s) & lmask) || (count < lsize)) + len = count; // copy the rest of the buffer with the byte mover + else + len = lsize - ((long)d & lmask); // move the ptrs up to a word boundary + + count -= len; + for(; len > 0; len--) + *d++ = *s++; + } + for(len = count / lsize; len > 0; len--) { + *(word *)d = *(word *)s; + d += lsize; + s += lsize; + } + for(len = count & lmask; len > 0; len--) + *d++ = *s++; + } else { + d += count; + s += count; + if(((long)d | (long)s) & lmask) { + // src and/or dest do not align on word boundary + if((((long)d ^ (long)s) & lmask) || (count <= lsize)) + len = count; + else + len = ((long)d & lmask); + + count -= len; + for(; len > 0; len--) + *--d = *--s; + } + for(len = count / lsize; len > 0; len--) { + d -= lsize; + s -= lsize; + *(word *)d = *(word *)s; + } + for(len = count & lmask; len > 0; len--) + *--d = *--s; + } + + return dest; +} + +#endif + diff --git a/lk/lib/libc/string/memscan.c b/lk/lib/libc/string/memscan.c new file mode 100644 index 0000000..7d58cf2 --- /dev/null +++ b/lk/lib/libc/string/memscan.c @@ -0,0 +1,41 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +void *memscan(void *addr, int c, size_t size) +{ + unsigned char *p = (unsigned char *)addr; + + while(size) { + if(*p == c) + return (void *)p; + p++; + size--; + } + return (void *)p; +} diff --git a/lk/lib/libc/string/memset.c b/lk/lib/libc/string/memset.c new file mode 100644 index 0000000..1abee39 --- /dev/null +++ b/lk/lib/libc/string/memset.c @@ -0,0 +1,61 @@ +/* +** Copyright 2005, Michael Noisternig. All rights reserved. +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +void * +memset(void *s, int c, size_t count) +{ + char *xs = (char *) s; + size_t len = (-(size_t)s) & (sizeof(size_t)-1); + int cc = c & 0xff; + + if ( count > len ) { + count -= len; + cc |= cc << 8; + cc |= cc << 16; + + // write to non-aligned memory byte-wise + for ( ; len > 0; len-- ) + *xs++ = c; + + // write to aligned memory dword-wise + for ( len = count/sizeof(size_t); len > 0; len-- ) { + *((size_t *)xs) = cc; + xs += sizeof(size_t); + } + + count &= sizeof(size_t)-1; + } + + // write remaining bytes + for ( ; count > 0; count-- ) + *xs++ = c; + + return s; +} diff --git a/lk/lib/libc/string/rules.mk b/lk/lib/libc/string/rules.mk new file mode 100644 index 0000000..1d038e6 --- /dev/null +++ b/lk/lib/libc/string/rules.mk @@ -0,0 +1,42 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +C_STRING_OPS := \ + bcopy \ + bzero \ + memchr \ + memcmp \ + memcpy \ + memmove \ + memset \ + strcat \ + strchr \ + strcmp \ + strcoll \ + strcpy \ + strdup \ + strerror \ + strlcat \ + strlcpy \ + strlen \ + strncat \ + strncpy \ + strncmp \ + strnicmp \ + strnlen \ + strpbrk \ + strrchr \ + strspn \ + strstr \ + strtok \ + strxfrm + +LIBC_STRING_C_DIR := $(LOCAL_DIR) + +# include the arch specific string routines +# +# the makefile may filter out implemented versions from the C_STRING_OPS variable +include $(LOCAL_DIR)/arch/$(ARCH)/rules.mk + +OBJS += \ + $(addprefix $(LIBC_STRING_C_DIR)/,$(addsuffix .o,$(C_STRING_OPS))) + diff --git a/lk/lib/libc/string/strcat.c b/lk/lib/libc/string/strcat.c new file mode 100644 index 0000000..445b95a --- /dev/null +++ b/lk/lib/libc/string/strcat.c @@ -0,0 +1,42 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +char * +strcat(char *dest, char const*src) +{ + char *tmp = dest; + + while(*dest) + dest++; + while((*dest++ = *src++) != '\0') + ; + + return tmp; +} + diff --git a/lk/lib/libc/string/strchr.c b/lk/lib/libc/string/strchr.c new file mode 100644 index 0000000..4c6bb16 --- /dev/null +++ b/lk/lib/libc/string/strchr.c @@ -0,0 +1,37 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +char * +strchr(const char *s, int c) +{ + for(; *s != (char) c; ++s) + if (*s == '\0') + return NULL; + return (char *) s; +} diff --git a/lk/lib/libc/string/strcmp.c b/lk/lib/libc/string/strcmp.c new file mode 100644 index 0000000..5402718 --- /dev/null +++ b/lk/lib/libc/string/strcmp.c @@ -0,0 +1,41 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +int +strcmp(char const *cs, char const *ct) +{ + signed char __res; + + while(1) { + if((__res = *cs - *ct++) != 0 || !*cs++) + break; + } + + return __res; +} diff --git a/lk/lib/libc/string/strcoll.c b/lk/lib/libc/string/strcoll.c new file mode 100644 index 0000000..021946a --- /dev/null +++ b/lk/lib/libc/string/strcoll.c @@ -0,0 +1,34 @@ +/* +** Copyright 2004, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +int +strcoll(const char *s1, const char *s2) +{ + return strcmp(s1, s2); +} + diff --git a/lk/lib/libc/string/strcpy.c b/lk/lib/libc/string/strcpy.c new file mode 100644 index 0000000..e6cc78e --- /dev/null +++ b/lk/lib/libc/string/strcpy.c @@ -0,0 +1,39 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +char * +strcpy(char *dest, char const *src) +{ + char *tmp = dest; + + while((*dest++ = *src++) != '\0') + ; + return tmp; +} + diff --git a/lk/lib/libc/string/strdup.c b/lk/lib/libc/string/strdup.c new file mode 100644 index 0000000..bbfc6a3 --- /dev/null +++ b/lk/lib/libc/string/strdup.c @@ -0,0 +1,43 @@ +/* +** Copyright 2004, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +char * +strdup(const char *str) +{ + size_t len; + char *copy; + + len = strlen(str) + 1; + copy = malloc(len); + if (copy == NULL) + return NULL; + memcpy(copy, str, len); + return copy; +} + diff --git a/lk/lib/libc/string/strerror.c b/lk/lib/libc/string/strerror.c new file mode 100644 index 0000000..7319659 --- /dev/null +++ b/lk/lib/libc/string/strerror.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +char const * +strerror(int errnum) +{ + if (errnum < 0) { + return "General Error"; + } else { + return "No Error"; + } +} + diff --git a/lk/lib/libc/string/strlcat.c b/lk/lib/libc/string/strlcat.c new file mode 100644 index 0000000..5e3488d --- /dev/null +++ b/lk/lib/libc/string/strlcat.c @@ -0,0 +1,50 @@ +/* +** Copyright 2002, Manuel J. Petit. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +size_t +strlcat(char *dst, char const *src, size_t s) +{ + size_t i; + size_t j= strnlen(dst, s); + + if(!s) { + return j+strlen(src); + } + + dst+= j; + + for(i= 0; ((i< s-1) && src[i]); i++) { + dst[i]= src[i]; + } + + dst[i]= 0; + + return j + i + strlen(src+i); +} diff --git a/lk/lib/libc/string/strlcpy.c b/lk/lib/libc/string/strlcpy.c new file mode 100644 index 0000000..a0995a0 --- /dev/null +++ b/lk/lib/libc/string/strlcpy.c @@ -0,0 +1,47 @@ +/* +** Copyright 2002, Manuel J. Petit. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +size_t +strlcpy(char *dst, char const *src, size_t s) +{ + size_t i= 0; + + if(!s) { + return strlen(src); + } + + for(i= 0; ((i< s-1) && src[i]); i++) { + dst[i]= src[i]; + } + + dst[i]= 0; + + return i + strlen(src+i); +} diff --git a/lk/lib/libc/string/strlen.c b/lk/lib/libc/string/strlen.c new file mode 100644 index 0000000..9f87fc0 --- /dev/null +++ b/lk/lib/libc/string/strlen.c @@ -0,0 +1,41 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +size_t +strlen(char const *s) +{ + size_t i; + + i= 0; + while(s[i]) { + i+= 1; + } + + return i; +} diff --git a/lk/lib/libc/string/strncat.c b/lk/lib/libc/string/strncat.c new file mode 100644 index 0000000..fe0393d --- /dev/null +++ b/lk/lib/libc/string/strncat.c @@ -0,0 +1,48 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +char * +strncat(char *dest, char const *src, size_t count) +{ + char *tmp = dest; + + if(count > 0) { + while(*dest) + dest++; + while((*dest++ = *src++)) { + if (--count == 0) { + *dest = '\0'; + break; + } + } + } + + return tmp; +} + diff --git a/lk/lib/libc/string/strncmp.c b/lk/lib/libc/string/strncmp.c new file mode 100644 index 0000000..2f4d877 --- /dev/null +++ b/lk/lib/libc/string/strncmp.c @@ -0,0 +1,42 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +int +strncmp(char const *cs, char const *ct, size_t count) +{ + signed char __res = 0; + + while(count > 0) { + if ((__res = *cs - *ct++) != 0 || !*cs++) + break; + count--; + } + + return __res; +} diff --git a/lk/lib/libc/string/strncpy.c b/lk/lib/libc/string/strncpy.c new file mode 100644 index 0000000..b0bf174 --- /dev/null +++ b/lk/lib/libc/string/strncpy.c @@ -0,0 +1,40 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +char * +strncpy(char *dest, char const *src, size_t count) +{ + char *tmp = dest; + + while(count-- && (*dest++ = *src++) != '\0') + ; + + return tmp; +} + diff --git a/lk/lib/libc/string/strnicmp.c b/lk/lib/libc/string/strnicmp.c new file mode 100644 index 0000000..0ca82b3 --- /dev/null +++ b/lk/lib/libc/string/strnicmp.c @@ -0,0 +1,55 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +int +strnicmp(char const *s1, char const *s2, size_t len) +{ + unsigned char c1 = '\0'; + unsigned char c2 = '\0'; + + if(len > 0) { + do { + c1 = *s1; c2 = *s2; + s1++; s2++; + if(!c1) + break; + if(!c2) + break; + if(c1 == c2) + continue; + c1 = tolower(c1); + c2 = tolower(c2); + if (c1 != c2) + break; + } while(--len); + } + return (int)c1 - (int)c2; +} +#pragma weak strncasecmp=strnicmp diff --git a/lk/lib/libc/string/strnlen.c b/lk/lib/libc/string/strnlen.c new file mode 100644 index 0000000..afd19a7 --- /dev/null +++ b/lk/lib/libc/string/strnlen.c @@ -0,0 +1,38 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +size_t +strnlen(char const *s, size_t count) +{ + const char *sc; + + for(sc = s; count-- && *sc != '\0'; ++sc) + ; + return sc - s; +} diff --git a/lk/lib/libc/string/strpbrk.c b/lk/lib/libc/string/strpbrk.c new file mode 100644 index 0000000..a97bcb6 --- /dev/null +++ b/lk/lib/libc/string/strpbrk.c @@ -0,0 +1,44 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +char * +strpbrk(char const *cs, char const *ct) +{ + const char *sc1; + const char *sc2; + + for(sc1 = cs; *sc1 != '\0'; ++sc1) { + for(sc2 = ct; *sc2 != '\0'; ++sc2) { + if(*sc1 == *sc2) + return (char *)sc1; + } + } + + return NULL; +} diff --git a/lk/lib/libc/string/strrchr.c b/lk/lib/libc/string/strrchr.c new file mode 100644 index 0000000..5327659 --- /dev/null +++ b/lk/lib/libc/string/strrchr.c @@ -0,0 +1,45 @@ +/* +** Copyright 2001, Manuel J. Petit. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +char * +strrchr(char const *s, int c) +{ + char const *last= c?0:s; + + + while(*s) { + if(*s== c) { + last= s; + } + + s+= 1; + } + + return (char *)last; +} diff --git a/lk/lib/libc/string/strspn.c b/lk/lib/libc/string/strspn.c new file mode 100644 index 0000000..354c1d6 --- /dev/null +++ b/lk/lib/libc/string/strspn.c @@ -0,0 +1,48 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +size_t +strspn(char const *s, char const *accept) +{ + const char *p; + const char *a; + size_t count = 0; + + for(p = s; *p != '\0'; ++p) { + for(a = accept; *a != '\0'; ++a) { + if(*p == *a) + break; + } + if(*a == '\0') + return count; + ++count; + } + + return count; +} diff --git a/lk/lib/libc/string/strstr.c b/lk/lib/libc/string/strstr.c new file mode 100644 index 0000000..a36b3f9 --- /dev/null +++ b/lk/lib/libc/string/strstr.c @@ -0,0 +1,46 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +char * +strstr(char const *s1, char const *s2) +{ + int l1, l2; + + l2 = strlen(s2); + if (!l2) + return (char *)s1; + l1 = strlen(s1); + while(l1 >= l2) { + l1--; + if (!memcmp(s1,s2,l2)) + return (char *)s1; + s1++; + } + return NULL; +} diff --git a/lk/lib/libc/string/strtok.c b/lk/lib/libc/string/strtok.c new file mode 100644 index 0000000..b7c4585 --- /dev/null +++ b/lk/lib/libc/string/strtok.c @@ -0,0 +1,51 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +static char *___strtok = NULL; + +char * +strtok(char *s, char const *ct) +{ + char *sbegin, *send; + + sbegin = s ? s : ___strtok; + if (!sbegin) { + return NULL; + } + sbegin += strspn(sbegin,ct); + if (*sbegin == '\0') { + ___strtok = NULL; + return( NULL ); + } + send = strpbrk( sbegin, ct); + if (send && *send != '\0') + *send++ = '\0'; + ___strtok = send; + return (sbegin); +} diff --git a/lk/lib/libc/string/strxfrm.c b/lk/lib/libc/string/strxfrm.c new file mode 100644 index 0000000..df005ec --- /dev/null +++ b/lk/lib/libc/string/strxfrm.c @@ -0,0 +1,42 @@ +/* +** Copyright 2004, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +size_t +strxfrm(char *dest, const char *src, size_t n) +{ + size_t len = strlen(src); + + if(n) { + size_t copy_len = len < n ? len : n - 1; + memcpy(dest, src, copy_len); + dest[copy_len] = 0; + } + return len; +} + diff --git a/lk/lib/ptable/ptable.c b/lk/lib/ptable/ptable.c new file mode 100644 index 0000000..3ddf5fa --- /dev/null +++ b/lk/lib/ptable/ptable.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + *Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +void ptable_init(struct ptable *ptable) +{ + ASSERT(ptable); + + memset(ptable, 0, sizeof(struct ptable)); +} + +char* ptype[] = {"Apps", "Modem"}; +char* pperm[] = {"No", "Yes"}; + +void ptable_add(struct ptable *ptable, char *name, unsigned start, + unsigned length, unsigned flags, char type, char perm) +{ + struct ptentry *ptn; + + ASSERT(ptable && ptable->count < MAX_PTABLE_PARTS); + + ptn = &ptable->parts[ptable->count++]; + strncpy(ptn->name, name, MAX_PTENTRY_NAME); + ptn->start = start; + ptn->length = length; + ptn->flags = flags; + ptn->type = type; + ptn->perm = perm; +} + +void ptable_dump(struct ptable *ptable) +{ + struct ptentry *ptn; + int i; + + for (i = 0; i < ptable->count; ++i) { + ptn = &ptable->parts[i]; + dprintf(INFO, "ptn %d name='%s' start=%08x len=%08x " + "flags=%08x type=%s Writable=%s\n", i, ptn->name, ptn->start, ptn->length, + ptn->flags, ptype[ptn->type], pperm[ptn->perm]); + } +} + +struct ptentry *ptable_find(struct ptable *ptable, const char *name) +{ + struct ptentry *ptn; + int i; + + for (i = 0; i < ptable->count; ++i) { + ptn = &ptable->parts[i]; + if (!strcmp(ptn->name, name)) + return ptn; + } + + return NULL; +} + +struct ptentry *ptable_get(struct ptable *ptable, int n) +{ + if (n >= ptable->count) + return NULL; + return &ptable->parts[n]; +} + +int ptable_size(struct ptable *ptable) +{ + return ptable->count; +} diff --git a/lk/lib/ptable/rules.mk b/lk/lib/ptable/rules.mk new file mode 100644 index 0000000..d3ff349 --- /dev/null +++ b/lk/lib/ptable/rules.mk @@ -0,0 +1,4 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/ptable.o diff --git a/lk/make/build.mk b/lk/make/build.mk new file mode 100644 index 0000000..028dc2c --- /dev/null +++ b/lk/make/build.mk @@ -0,0 +1,30 @@ +# comment out or override if you want to see the full output of each command +NOECHO ?= @ + +$(OUTBIN): $(OUTELF) + @echo generating image: $@ + $(NOECHO)$(SIZE) $< + $(NOCOPY)$(OBJCOPY) -O binary $< $@ + +$(OUTELF): $(ALLOBJS) $(LINKER_SCRIPT) + @echo linking $@ + $(NOECHO)$(LD) $(LDFLAGS) -T $(LINKER_SCRIPT) $(ALLOBJS) $(LIBGCC) -o $@ + +$(OUTELF).sym: $(OUTELF) + @echo generating symbols: $@ + $(NOECHO)$(OBJDUMP) -t $< | $(CPPFILT) > $@ + +$(OUTELF).lst: $(OUTELF) + @echo generating listing: $@ + $(NOECHO)$(OBJDUMP) -Mreg-names-raw -d $< | $(CPPFILT) > $@ + +$(OUTELF).debug.lst: $(OUTELF) + @echo generating listing: $@ + $(NOECHO)$(OBJDUMP) -Mreg-names-raw -S $< | $(CPPFILT) > $@ + +$(OUTELF).size: $(OUTELF) + @echo generating size map: $@ + $(NOECHO)$(NM) -S --size-sort $< > $@ + +include arch/$(ARCH)/compile.mk + diff --git a/lk/make/macros.mk b/lk/make/macros.mk new file mode 100644 index 0000000..13c1d9b --- /dev/null +++ b/lk/make/macros.mk @@ -0,0 +1,5 @@ +# Find the local dir of the make file +GET_LOCAL_DIR = $(patsubst %/,%,$(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))) + +# makes sure the target dir exists +MKDIR = if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi diff --git a/lk/make/module.mk b/lk/make/module.mk new file mode 100644 index 0000000..9e82ef3 --- /dev/null +++ b/lk/make/module.mk @@ -0,0 +1,21 @@ +# included from the main makefile to include a set of rules.mk to satisfy +# the current MODULE list. If as a byproduct of including the rules.mk +# more stuff shows up on the MODULE list, recurse + +# sort and filter out any modules that have already been included +MODULES := $(sort $(MODULES)) +MODULES := $(filter-out $(ALLMODULES),$(MODULES)) + +ifneq ($(MODULES),) + +ALLMODULES += $(MODULES) +ALLMODULES := $(sort $(ALLMODULES)) +INCMODULES := $(MODULES) +MODULES := +$(info including $(INCMODULES)) +include $(addsuffix /rules.mk,$(INCMODULES)) + +include make/module.mk + +endif + diff --git a/lk/makefile b/lk/makefile new file mode 100644 index 0000000..d6687da --- /dev/null +++ b/lk/makefile @@ -0,0 +1,188 @@ +-include local.mk +include make/macros.mk + +# If one of our goals (from the commandline) happens to have a +# matching project/goal.mk, then we should re-invoke make with +# that project name specified... + +project-name := $(firstword $(MAKECMDGOALS)) + +ifneq ($(project-name),) +ifneq ($(wildcard project/$(project-name).mk),) +do-nothing := 1 +$(MAKECMDGOALS) _all: make-make +make-make: + @PROJECT=$(project-name) $(MAKE) $(filter-out $(project-name), $(MAKECMDGOALS)) +endif +endif + +ifeq ($(do-nothing),) + +ifeq ($(PROJECT),) +$(error No project specified. Use "make projectname" or put "PROJECT := projectname" in local.mk) +endif + +DEBUG ?= 0 + +ifndef $(BOOTLOADER_OUT) +BOOTLOADER_OUT := . +endif + +LK_TOP_DIR:= . +BUILDDIR := $(BOOTLOADER_OUT)/build-$(PROJECT) +OUTBIN := $(BUILDDIR)/lk.bin +OUTELF := $(BUILDDIR)/lk +CONFIGHEADER := $(BUILDDIR)/config.h + +INCLUDES := -I$(BUILDDIR) -Iinclude +CFLAGS := -O2 -g -fno-builtin -finline -W -Wall -Wno-multichar -Wno-unused-parameter -Wno-unused-function -include $(CONFIGHEADER) +#CFLAGS += -Werror +ifeq ($(EMMC_BOOT),1) + CFLAGS += -D_EMMC_BOOT=1 +endif +# When the host arch is ARM, ensure stack protection code is not emitted since +# it's not supported by the bootloader's libc +ifneq ($(shell uname -m | grep "arm.*"),) + CFLAGS += -fno-stack-protector +endif +CPPFLAGS := -fno-exceptions -fno-rtti -fno-threadsafe-statics +#CPPFLAGS += -Weffc++ +ASMFLAGS := -DASSEMBLY +LDFLAGS := + +CFLAGS += -ffunction-sections -fdata-sections +LDFLAGS += -gc-sections + +# top level rule +all:: $(OUTBIN) $(OUTELF).lst $(OUTELF).debug.lst $(OUTELF).sym $(OUTELF).size APPSBOOTHEADER + +# the following three object lists are identical except for the ordering +# which is bootobjs, kobjs, objs +BOOTOBJS := +OBJS := + +# a linker script needs to be declared in one of the project/target/platform files +LINKER_SCRIPT := + +# anything you add here will be deleted in make clean +GENERATED := $(CONFIGHEADER) + +# anything added to DEFINES will be put into $(BUILDDIR)/config.h +DEFINES := LK=1 + +# Anything added to SRCDEPS will become a dependency of every source file in the system. +# Useful for header files that may be included by one or more source files. +SRCDEPS := $(CONFIGHEADER) + +# these need to be filled out by the project/target/platform rules.mk files +TARGET := +PLATFORM := +ARCH := +ALLMODULES := +MODULES := + +# any rules you put here will also be built by the system before considered being complete +EXTRA_BUILDDEPS := + +# any rules you put here will be depended on in clean builds +EXTRA_CLEANDEPS := + +include project/$(PROJECT).mk +include target/$(TARGET)/rules.mk +include target/$(TARGET)/tools/makefile +include platform/$(PLATFORM)/rules.mk +include arch/$(ARCH)/rules.mk +include platform/rules.mk +include target/rules.mk +include kernel/rules.mk +include dev/rules.mk +include app/rules.mk + +# recursively include any modules in the MODULE variable, leaving a trail of included +# modules in the ALLMODULES list +include make/module.mk + +# any extra top level build dependencies that someone declared +all:: $(EXTRA_BUILDDEPS) + +ALLOBJS := \ + $(BOOTOBJS) \ + $(OBJS) + +# add some automatic configuration defines +DEFINES += \ + BOARD=$(PROJECT) \ + PROJECT_$(PROJECT)=1 \ + TARGET_$(TARGET)=1 \ + PLATFORM_$(PLATFORM)=1 \ + ARCH_$(ARCH)=1 \ + $(addsuffix =1,$(addprefix WITH_,$(ALLMODULES))) + +# debug build? +ifneq ($(DEBUG),) +DEFINES += \ + DEBUG=$(DEBUG) +endif + +ALLOBJS := $(addprefix $(BUILDDIR)/,$(ALLOBJS)) + +DEPS := $(ALLOBJS:%o=%d) + +# default to no ccache +CCACHE ?= +CC := $(CCACHE) $(TOOLCHAIN_PREFIX)gcc +LD := $(TOOLCHAIN_PREFIX)ld +OBJDUMP := $(TOOLCHAIN_PREFIX)objdump +OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy +CPPFILT := $(TOOLCHAIN_PREFIX)c++filt +SIZE := $(TOOLCHAIN_PREFIX)size +NM := $(TOOLCHAIN_PREFIX)nm + +# comment out or override if you want to see the full output of each command +NOECHO ?= @ + +# the logic to compile and link stuff is in here +include make/build.mk + +clean: $(EXTRA_CLEANDEPS) + rm -f $(ALLOBJS) $(DEPS) $(GENERATED) $(OUTBIN) $(OUTELF) $(OUTELF).lst + +spotless: + rm -rf build-* + +install: all + scp $(OUTBIN) 192.168.0.4:/tftproot + +# generate a config.h file with all of the DEFINES laid out in #define format +configheader: + +$(CONFIGHEADER): configheader + @$(MKDIR) + @echo generating $@ + @rm -f $(CONFIGHEADER).tmp; \ + echo \#ifndef __CONFIG_H > $(CONFIGHEADER).tmp; \ + echo \#define __CONFIG_H >> $(CONFIGHEADER).tmp; \ + for d in `echo $(DEFINES) | tr [:lower:] [:upper:]`; do \ + echo "#define $$d" | sed "s/=/\ /g;s/-/_/g;s/\//_/g" >> $(CONFIGHEADER).tmp; \ + done; \ + echo \#endif >> $(CONFIGHEADER).tmp; \ + if [ -f "$(CONFIGHEADER)" ]; then \ + if cmp "$(CONFIGHEADER).tmp" "$(CONFIGHEADER)"; then \ + rm -f $(CONFIGHEADER).tmp; \ + else \ + mv $(CONFIGHEADER).tmp $(CONFIGHEADER); \ + fi \ + else \ + mv $(CONFIGHEADER).tmp $(CONFIGHEADER); \ + fi + +# Empty rule for the .d files. The above rules will build .d files as a side +# effect. Only works on gcc 3.x and above, however. +%.d: + +ifeq ($(filter $(MAKECMDGOALS), clean), ) +-include $(DEPS) +endif + +.PHONY: configheader +endif diff --git a/lk/platform/armemu/debug.c b/lk/platform/armemu/debug.c new file mode 100644 index 0000000..09aabd5 --- /dev/null +++ b/lk/platform/armemu/debug.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include + +void _dputc(char c) +{ + *REG8(DEBUG_STDOUT) = c; +} + +int dgetc(char *c) +{ + int8_t result = (int8_t)*REG8(DEBUG_STDIN); + + if (result == -1) + return -1; + + *c = (char)result; + return 0; +} + +void debug_dump_regs(void) +{ + *REG32(DEBUG_REGDUMP) = 1; +} + +void platform_halt(void) +{ + *REG32(DEBUG_HALT) = 1; + for(;;); +} + +void debug_dump_memory_bytes(void *mem, int len) +{ + *REG32(DEBUG_MEMDUMPADDR) = (unsigned int)mem; + *REG32(DEBUG_MEMDUMPLEN) = len; + *REG32(DEBUG_MEMDUMP_BYTE) = 1; +} + +void debug_dump_memory_halfwords(void *mem, int len) +{ + len /= 2; + + *REG32(DEBUG_MEMDUMPADDR) = (unsigned int)mem; + *REG32(DEBUG_MEMDUMPLEN) = len; + *REG32(DEBUG_MEMDUMP_HALFWORD) = 1; +} + +void debug_dump_memory_words(void *mem, int len) +{ + len /= 4; + + *REG32(DEBUG_MEMDUMPADDR) = (unsigned int)mem; + *REG32(DEBUG_MEMDUMPLEN) = len; + *REG32(DEBUG_MEMDUMP_WORD) = 1; +} + +void debug_set_trace_level(int trace_type, int level) +{ + if(trace_type < 0 || trace_type >= 4) + return; + + *REG32(DEBUG_SET_TRACELEVEL_CPU + trace_type * 4) = level; +} + +uint32_t debug_cycle_count() +{ + return *REG32(DEBUG_CYCLE_COUNT); +} diff --git a/lk/platform/armemu/include/platform/armemu.h b/lk/platform/armemu/include/platform/armemu.h new file mode 100644 index 0000000..10b0d60 --- /dev/null +++ b/lk/platform/armemu/include/platform/armemu.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __PLATFORM_ARMEMU_H +#define __PLATFORM_ARMEMU_H + +#include + +#endif + diff --git a/lk/platform/armemu/include/platform/armemu/memmap.h b/lk/platform/armemu/include/platform/armemu/memmap.h new file mode 100644 index 0000000..9df4e0b --- /dev/null +++ b/lk/platform/armemu/include/platform/armemu/memmap.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2005-2006 Travis Geiselbrecht + * + * 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 __MEMMAP_H +#define __MEMMAP_H + +#define MEMBANK_SIZE (4*1024*1024) + +/* some helpful macros */ +#define REG(x) ((volatile unsigned int *)(x)) +#define REG_H(x) ((volatile unsigned short *)(x)) +#define REG_B(x) ((volatile unsigned char *)(x)) + +/* memory map of our generic arm system */ +// XXX make more dynamic +#define MAINMEM_BASE 0x0 +#define MAINMEM_SIZE (MEMBANK_SIZE) + +/* peripherals are all mapped here */ +#define PERIPHERAL_BASE (0xf0000000) + +/* system info */ +#define SYSINFO_REGS_BASE (PERIPHERAL_BASE) +#define SYSINFO_REGS_SIZE MEMBANK_SIZE +#define SYSINFO_FEATURES (SYSINFO_REGS_BASE + 0) +#define SYSINFO_FEATURE_DISPLAY 0x00000001 +#define SYSINFO_FEATURE_CONSOLE 0x00000002 +#define SYSINFO_FEATURE_NETWORK 0x00000004 + + /* a write to this register latches the current emulator system time, so the next two regs can be read atomically */ +#define SYSINFO_TIME_LATCH (SYSINFO_REGS_BASE + 4) + /* gettimeofday() style time values */ +#define SYSINFO_TIME_SECS (SYSINFO_REGS_BASE + 8) +#define SYSINFO_TIME_USECS (SYSINFO_REGS_BASE + 12) + +/* display */ +#define DISPLAY_BASE (SYSINFO_REGS_BASE + SYSINFO_REGS_SIZE) +#define DISPLAY_SIZE MEMBANK_SIZE +#define DISPLAY_FRAMEBUFFER DISPLAY_BASE +#define DISPLAY_REGS_BASE (DISPLAY_BASE + DISPLAY_SIZE) +#define DISPLAY_REGS_SIZE MEMBANK_SIZE + /* no display regs for now */ + +/* console (keyboard controller */ +#define CONSOLE_REGS_BASE (DISPLAY_REGS_BASE + DISPLAY_REGS_SIZE) +#define CONSOLE_REGS_SIZE MEMBANK_SIZE +#define KYBD_STAT (CONSOLE_REGS_BASE + 0) +#define KYBD_DATA (CONSOLE_REGS_BASE + 4) + +/* programmable timer */ +#define PIT_REGS_BASE (CONSOLE_REGS_BASE + CONSOLE_REGS_SIZE) +#define PIT_REGS_SIZE MEMBANK_SIZE +#define PIT_STATUS (PIT_REGS_BASE + 0) // status bit +#define PIT_CLEAR (PIT_REGS_BASE + 4) // a nonzero write clears any pending timer +#define PIT_CLEAR_INT (PIT_REGS_BASE + 8) // a nonzero write clears the pending interrupt +#define PIT_INTERVAL (PIT_REGS_BASE + 12) // set the countdown interval, and what the interval is reset to if periodic +#define PIT_START_ONESHOT (PIT_REGS_BASE + 16) // a nonzero write starts a oneshot countdown +#define PIT_START_PERIODIC (PIT_REGS_BASE + 20) // a nonzero write starts a periodic countdown + +#define PIT_STATUS_ACTIVE 0x1 +#define PIT_STATUS_INT_PEND 0x2 + +/* interrupt controller */ +#define PIC_REGS_BASE (PIT_REGS_BASE + PIT_REGS_SIZE) +#define PIC_REGS_SIZE MEMBANK_SIZE + + /* Current vector mask, read-only */ +#define PIC_MASK (PIC_REGS_BASE + 0) + /* Mask any of the 32 interrupt vectors by writing a 1 in the appropriate bit */ +#define PIC_MASK_LATCH (PIC_REGS_BASE + 4) + /* Unmask any of the 32 interrupt vectors by writing a 1 in the appropriate bit */ +#define PIC_UNMASK_LATCH (PIC_REGS_BASE + 8) + /* each bit corresponds to the current status of the interrupt line */ +#define PIC_STAT (PIC_REGS_BASE + 12) + /* one bit set for the highest priority non-masked active interrupt */ +#define PIC_CURRENT_BIT (PIC_REGS_BASE + 16) + /* holds the current interrupt number of the highest priority non-masked active interrupt, + * or 0xffffffff if no interrupt is active + */ +#define PIC_CURRENT_NUM (PIC_REGS_BASE + 20) + + /* interrupt map */ +#define INT_PIT 0 +#define INT_KEYBOARD 1 +#define INT_NET 2 +#define PIC_MAX_INT 32 + +/* debug interface */ +#define DEBUG_REGS_BASE (PIC_REGS_BASE + PIC_REGS_SIZE) +#define DEBUG_REGS_SIZE MEMBANK_SIZE +#define DEBUG_STDOUT (DEBUG_REGS_BASE + 0) /* writes to this register are sent through to stdout */ +#define DEBUG_STDIN (DEBUG_REGS_BASE + 0) /* reads from this register return the contents of stdin + * or -1 if no data is pending */ +#define DEBUG_REGDUMP (DEBUG_REGS_BASE + 4) /* writes to this register cause the emulator to dump registers */ +#define DEBUG_HALT (DEBUG_REGS_BASE + 8) /* writes to this register will halt the emulator */ + +#define DEBUG_MEMDUMPADDR (DEBUG_REGS_BASE + 12) /* set the base address of memory to dump */ +#define DEBUG_MEMDUMPLEN (DEBUG_REGS_BASE + 16) /* set the length of memory to dump */ +#define DEBUG_MEMDUMP_BYTE (DEBUG_REGS_BASE + 20) /* trigger a memory dump in byte format */ +#define DEBUG_MEMDUMP_HALFWORD (DEBUG_REGS_BASE + 24) /* trigger a memory dump in halfword format */ +#define DEBUG_MEMDUMP_WORD (DEBUG_REGS_BASE + 28) /* trigger a memory dump in word format */ + +/* lets you set the trace level of the various subsystems from within the emulator */ +/* only works on emulator builds that support dynamic trace levels */ +#define DEBUG_SET_TRACELEVEL_CPU (DEBUG_REGS_BASE + 32) +#define DEBUG_SET_TRACELEVEL_UOP (DEBUG_REGS_BASE + 36) +#define DEBUG_SET_TRACELEVEL_SYS (DEBUG_REGS_BASE + 40) +#define DEBUG_SET_TRACELEVEL_MMU (DEBUG_REGS_BASE + 44) + +#define DEBUG_CYCLE_COUNT (DEBUG_REGS_BASE + 48) +#define DEBUG_INS_COUNT (DEBUG_REGS_BASE + 52) + +/* network interface */ +#define NET_REGS_BASE (DEBUG_REGS_BASE + DEBUG_REGS_SIZE) +#define NET_REGS_SIZE MEMBANK_SIZE + +#define NET_BUF_LEN 2048 +#define NET_IN_BUF_COUNT 32 + +#define NET_HEAD (NET_REGS_BASE + 0) /* current next buffer the hardware will write to */ +#define NET_TAIL (NET_REGS_BASE + 4) /* currently selected input buffer */ +#define NET_SEND (NET_REGS_BASE + 8) /* writes to this register sends whatever is in the out buf */ +#define NET_SEND_LEN (NET_REGS_BASE + 12) /* length of packet to send */ +#define NET_OUT_BUF (NET_REGS_BASE + NET_BUF_LEN) + +#define NET_IN_BUF_LEN (NET_REGS_BASE + 16) /* length of the currently selected in buffer, via tail register */ +#define NET_IN_BUF (NET_REGS_BASE + NET_BUF_LEN*2) + +#endif diff --git a/lk/platform/armemu/interrupts.c b/lk/platform/armemu/interrupts.c new file mode 100644 index 0000000..9b149a3 --- /dev/null +++ b/lk/platform/armemu/interrupts.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include +#include +#include "platform_p.h" + +struct int_handler_struct { + int_handler handler; + void *arg; +}; + +static struct int_handler_struct int_handler_table[PIC_MAX_INT]; + +void platform_init_interrupts(void) +{ + // mask all the interrupts + *REG32(PIC_MASK_LATCH) = 0xffffffff; +} + +status_t mask_interrupt(unsigned int vector) +{ + if (vector >= PIC_MAX_INT) + return ERR_INVALID_ARGS; + +// dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector); + + enter_critical_section(); + + *REG32(PIC_MASK_LATCH) = 1 << vector; + + exit_critical_section(); + + return NO_ERROR; +} + +status_t unmask_interrupt(unsigned int vector) +{ + if (vector >= PIC_MAX_INT) + return ERR_INVALID_ARGS; + +// dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector); + + enter_critical_section(); + + *REG32(PIC_UNMASK_LATCH) = 1 << vector; + + exit_critical_section(); + + return NO_ERROR; +} + +enum handler_return platform_irq(struct arm_iframe *frame) +{ + // get the current vector + unsigned int vector = *REG32(PIC_CURRENT_NUM); + if (vector == 0xffffffff) + return INT_NO_RESCHEDULE; + +// dprintf("platform_irq: spsr 0x%x, pc 0x%x, currthread %p, vector %d\n", frame->spsr, frame->pc, current_thread, vector); + + // deliver the interrupt + enum handler_return ret; + + ret = INT_NO_RESCHEDULE; + if (int_handler_table[vector].handler) + ret = int_handler_table[vector].handler(int_handler_table[vector].arg); + +// dprintf("platform_irq: exit %d\n", ret); + + return ret; +} + +void platform_fiq(struct arm_iframe *frame) +{ + panic("FIQ: unimplemented\n"); +} + +void register_int_handler(unsigned int vector, int_handler handler, void *arg) +{ + if (vector >= PIC_MAX_INT) + panic("register_int_handler: vector out of range %d\n", vector); + + enter_critical_section(); + + int_handler_table[vector].handler = handler; + int_handler_table[vector].arg = arg; + + exit_critical_section(); +} + diff --git a/lk/platform/armemu/net.c b/lk/platform/armemu/net.c new file mode 100644 index 0000000..e27d321 --- /dev/null +++ b/lk/platform/armemu/net.c @@ -0,0 +1,398 @@ +#if WITH_LWIP +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * This file is a skeleton for developing Ethernet network interface + * drivers for lwIP. Add code to the low_level functions and do a + * search-and-replace for the word "ethernetif" to replace it with + * something that better describes your network interface. + */ +/* + * ARMEMU bits + * Copyright (c) 2006 Travis Geiselbrecht + * + * 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 +#include +#include + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include + +#include "netif/etharp.h" + +/* Define those to better describe your network interface. */ +#define IFNAME0 'e' +#define IFNAME1 'n' + +struct ethernetif { + struct eth_addr *ethaddr; + /* Add whatever per-interface state that is needed here. */ +}; + +static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; + +/* Forward declarations. */ +static void ethernetif_input(struct netif *netif); +static err_t ethernetif_output(struct netif *netif, struct pbuf *p, + struct ip_addr *ipaddr); + +static void +low_level_init(struct netif *netif) +{ + struct ethernetif *ethernetif = netif->state; + + /* set MAC hardware address length */ + netif->hwaddr_len = 6; + + /* set MAC hardware address */ + netif->hwaddr[0] = 0; + netif->hwaddr[1] = 0x01; + netif->hwaddr[2] = 0x02; + netif->hwaddr[3] = 0x03; + netif->hwaddr[4] = 0x04; + netif->hwaddr[5] = 0x05; + + /* maximum transfer unit */ + netif->mtu = 1500; + + /* broadcast capability */ + netif->flags = NETIF_FLAG_BROADCAST; + + /* Do whatever else is needed to initialize interface. */ +} + +/* + * low_level_output(): + * + * Should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + */ + +static err_t +low_level_output(struct netif *netif, struct pbuf *p) +{ + struct ethernetif *ethernetif = netif->state; + struct pbuf *q; + int i; + int j; + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + /* XXX maybe just a mutex? */ + enter_critical_section(); + + i = 0; + for(q = p; q != NULL; q = q->next) { + /* Send the data from the pbuf to the interface, one pbuf at a + time. The size of the data in each pbuf is kept in the ->len + variable. */ +// debug_dump_memory_bytes(q->payload, q->len); + for (j = 0; j < q->len; j++) + *REG8(NET_OUT_BUF + i + j) = ((unsigned char *)q->payload)[j]; + i += q->len; + } + + *REG(NET_SEND_LEN) = i; + *REG(NET_SEND) = 1; + + exit_critical_section(); + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + +#if LINK_STATS + lwip_stats.link.xmit++; +#endif /* LINK_STATS */ + + return ERR_OK; +} + +/* + * low_level_input(): + * + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + */ + +static struct pbuf * +low_level_input(struct netif *netif) +{ + struct ethernetif *ethernetif = netif->state; + struct pbuf *p, *q; + u16_t len; + int i; + int head, tail; + + /* get the head and tail pointers from the ethernet interface */ + head = *REG(NET_HEAD); + tail = *REG(NET_TAIL); + + if (tail == head) + return NULL; // false alarm + + /* Obtain the size of the packet and put it into the "len" + variable. */ + len = *REG(NET_IN_BUF_LEN); + +#if ETH_PAD_SIZE + len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ +#endif + + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + if (p != NULL) { + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + /* We iterate over the pbuf chain until we have read the entire + * packet into the pbuf. */ + int pos = 0; + for(q = p; q != NULL; q = q->next) { + /* Read enough bytes to fill this pbuf in the chain. The + * available data in the pbuf is given by the q->len + * variable. */ + for (i=0; i < q->len; i++) { + ((unsigned char *)q->payload)[i] = *REG8(NET_IN_BUF + pos); + pos++; + } + } + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + +#if LINK_STATS + lwip_stats.link.recv++; +#endif /* LINK_STATS */ + } else { +#if LINK_STATS + lwip_stats.link.memerr++; + lwip_stats.link.drop++; +#endif /* LINK_STATS */ + } + + /* push the tail pointer up by one, giving the buffer back to the hardware */ + *REG(NET_TAIL) = (tail + 1) % NET_IN_BUF_COUNT; + + return p; +} + +/* + * ethernetif_output(): + * + * This function is called by the TCP/IP stack when an IP packet + * should be sent. It calls the function called low_level_output() to + * do the actual transmission of the packet. + * + */ + +static err_t +ethernetif_output(struct netif *netif, struct pbuf *p, + struct ip_addr *ipaddr) +{ +// dprintf("ethernetif_output: netif %p, pbuf %p, ipaddr %p\n", netif, p, ipaddr); + + /* resolve hardware address, then send (or queue) packet */ + return etharp_output(netif, ipaddr, p); + +} + +/* + * ethernetif_input(): + * + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. + * + */ + +static void +ethernetif_input(struct netif *netif) +{ + struct ethernetif *ethernetif; + struct eth_hdr *ethhdr; + struct pbuf *p; + + ethernetif = netif->state; + + /* move received packet into a new pbuf */ + p = low_level_input(netif); + /* no packet could be read, silently ignore this */ + if (p == NULL) return; + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = p->payload; + +#if LINK_STATS + lwip_stats.link.recv++; +#endif /* LINK_STATS */ + + ethhdr = p->payload; + +// dprintf("ethernetif_input: type 0x%x\n", htons(ethhdr->type)); + + switch (htons(ethhdr->type)) { + /* IP packet? */ + case ETHTYPE_IP: + /* update ARP table */ + etharp_ip_input(netif, p); + /* skip Ethernet header */ + pbuf_header(p, -sizeof(struct eth_hdr)); + /* pass to network layer */ + netif->input(p, netif); + break; + + case ETHTYPE_ARP: + /* pass p to ARP module */ + etharp_arp_input(netif, ethernetif->ethaddr, p); + break; + default: + pbuf_free(p); + p = NULL; + break; + } +} + +static enum handler_return ethernet_int(void *arg) +{ + struct netif *netif = (struct netif *)arg; + + ethernetif_input(netif); + + return INT_RESCHEDULE; +} + + + +/* + * ethernetif_init(): + * + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + */ + +static err_t +ethernetif_init(struct netif *netif) +{ + struct ethernetif *ethernetif; + + ethernetif = mem_malloc(sizeof(struct ethernetif)); + + if (ethernetif == NULL) + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n")); + return ERR_MEM; + } + + netif->state = ethernetif; + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + netif->output = ethernetif_output; + netif->linkoutput = low_level_output; + + ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); + + low_level_init(netif); + + return ERR_OK; +} + +status_t ethernet_init(void) +{ + /* check to see if the ethernet feature is turned on */ + if ((*REG(SYSINFO_FEATURES) & SYSINFO_FEATURE_NETWORK) == 0) + return ERR_NOT_FOUND; + + struct netif *netif = calloc(sizeof(struct netif), 1); + struct ip_addr *ipaddr = calloc(sizeof(struct ip_addr), 1); + struct ip_addr *netmask = calloc(sizeof(struct ip_addr), 1); + struct ip_addr *gw = calloc(sizeof(struct ip_addr), 1); + + struct netif *netifret = netif_add(netif, ipaddr, netmask, gw, NULL, ðernetif_init, &ip_input); + if (netifret == NULL) { + free(netif); + free(ipaddr); + free(netmask); + free(gw); + return ERR_NOT_FOUND; + } + + /* register for interrupt handlers */ + register_int_handler(INT_NET, ethernet_int, netif); + + netif_set_default(netif); + + unmask_interrupt(INT_NET, NULL); + + return NO_ERROR; +} + +#endif // WITH_LWIP diff --git a/lk/platform/armemu/platform.c b/lk/platform/armemu/platform.c new file mode 100644 index 0000000..1425674 --- /dev/null +++ b/lk/platform/armemu/platform.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 "platform_p.h" + +void platform_init_mmu_mappings(void) +{ +} + +void platform_early_init(void) +{ + /* initialize the interrupt controller */ + platform_init_interrupts(); + + /* initialize the timer block */ + platform_init_timer(); +} + +void platform_init(void) +{ +} + diff --git a/lk/platform/armemu/platform_p.h b/lk/platform/armemu/platform_p.h new file mode 100644 index 0000000..872ea2b --- /dev/null +++ b/lk/platform/armemu/platform_p.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __PLATFORM_P_H +#define __PLATFORM_P_H + +void platform_init_interrupts(void); +void platform_init_timer(void); + +#endif + diff --git a/lk/platform/armemu/rules.mk b/lk/platform/armemu/rules.mk new file mode 100644 index 0000000..13543f4 --- /dev/null +++ b/lk/platform/armemu/rules.mk @@ -0,0 +1,28 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +ARCH := arm +ARM_CPU := arm926ej-s +CPU := generic + +# emulater doesn't support thumb properly +ENABLE_THUMB := false + +INCLUDES += \ + -I$(LOCAL_DIR)/include + +OBJS += \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/interrupts.o \ + $(LOCAL_DIR)/platform.o \ + $(LOCAL_DIR)/timer.o \ + + +# $(LOCAL_DIR)/console.o \ + $(LOCAL_DIR)/net.o \ + +MEMBASE := 0x0 +MEMSIZE := 0x400000 # 4MB + +LINKER_SCRIPT += \ + $(BUILDDIR)/system-onesegment.ld + diff --git a/lk/platform/armemu/timer.c b/lk/platform/armemu/timer.c new file mode 100644 index 0000000..4d209a4 --- /dev/null +++ b/lk/platform/armemu/timer.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include "platform_p.h" + +static platform_timer_callback t_callback; + +status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, time_t interval) +{ + enter_critical_section(); + + t_callback = callback; + + *REG(PIT_CLEAR) = 1; + *REG(PIT_INTERVAL) = interval; + *REG(PIT_START_PERIODIC) = 1; + + unmask_interrupt(INT_PIT); + + exit_critical_section(); + + return NO_ERROR; +} + +time_t current_time(void) +{ + time_t time; + *REG(SYSINFO_TIME_LATCH) = 1; + time = *REG(SYSINFO_TIME_SECS) * 1000; + time += *REG(SYSINFO_TIME_USECS) / 1000; + + return time; +} + +static enum handler_return platform_tick(void *arg) +{ + *REG(PIT_CLEAR_INT) = 1; + if (t_callback) { + return t_callback(arg, current_time()); + } else { + return INT_NO_RESCHEDULE; + } +} + +void platform_init_timer(void) +{ + register_int_handler(INT_PIT, &platform_tick, NULL); +} + diff --git a/lk/platform/at91sam7/README b/lk/platform/at91sam7/README new file mode 100644 index 0000000..41ce561 --- /dev/null +++ b/lk/platform/at91sam7/README @@ -0,0 +1,15 @@ + +Platform support for the ATMEL AT91SAM7[XS] ARM7 microcontrollers. + +This is a base platform -- it needs to be specialized for a particular +board (see sam7ex256 as an example of this) to be useful. In particular +it does not provide the platform/board.h (which must include the +correct at91sam7*h file and mux config). + +TODO: +- support clock rates other than (and above) 18MHz +- compute uart divisor, PIT interval, etc from MCK +- timer hook should honor the requested interval +- current_time() should return a meaningful value +- actually pass argument to interrupt handlers? + diff --git a/lk/platform/at91sam7/at91sam7s.pins b/lk/platform/at91sam7/at91sam7s.pins new file mode 100644 index 0000000..e9c4474 --- /dev/null +++ b/lk/platform/at91sam7/at91sam7s.pins @@ -0,0 +1,32 @@ +PA0 PWM0 TIOA0 +PA1 PWM1 TIOB0 +PA2 PWM2 SCK0 +PA3 TWD NPCS3 +PA4 TWCK TCLK0 +PA5 RXD0 NPCS3 +PA6 TXD0 PCK0 +PA7 RTS0 PWM3 +PA8 CTS0 ADTRG +PA9 DRXD NPCS1 +PA10 DTXD NPCS2 +PA11 NPCS0 PWM0 +PA12 MISO PWM1 +PA13 MOSI PWM2 +PA14 SPCK PWM3 +PA15 TF TIOA1 +PA16 TK TIOB1 +PA17 TD PCK1 +PA18 RD PCK2 +PA19 RK FIQ +PA20 RF IRQ0 +PA21 RXD1 PCK1 +PA22 TXD1 NPCS3 +PA23 SCK1 PWM0 +PA24 RTS1 PWM1 +PA25 CTS1 PWM2 +PA26 DCD1 TIOA2 +PA27 DTR1 TIOB2 +PA28 DSR1 TCLK1 +PA29 RI1 TCLK2 +PA30 IRQ1 NPCS2 +PA31 NPCS1 PCK2 \ No newline at end of file diff --git a/lk/platform/at91sam7/at91sam7x.pins b/lk/platform/at91sam7/at91sam7x.pins new file mode 100644 index 0000000..f026fb6 --- /dev/null +++ b/lk/platform/at91sam7/at91sam7x.pins @@ -0,0 +1,31 @@ +PA0 RXD0 NC +PA1 TXD0 NC +PA2 SCK0 SPI1_NPCS1 +PA3 RTS0 SPI1_NPCS2 +PA4 CTS0 SPI1_NPCS3 +PA5 RXD1 NC +PA6 TXD1 NC +PA7 SCK1 SPI0_NPCS1 +PA8 RTS1 SPI0_NPCS2 +PA9 CTS1 SPI0_NPCS3 +PA10 TWD NC +PA11 TWCK NC +PA12 SPI0_NPCS0 NC +PA13 SPI0_NPCS1 PCK1 +PA14 SPI0_NPCS2 IRQ1 +PA15 SPI0_NPCS3 TCLK2 +PA16 SPI0_MISO NC +PA17 SPI0_MOSI NC +PA18 SPI0_SPCK NC +PA19 CANRX NC +PA20 CANTX NC +PA21 TF SPI1_NPCS0 +PA22 TK SPI1_SPCK +PA23 TD SPI1_MOSI +PA24 RD SPI1_MISO +PA25 RK SPI1_NPCS1 +PA26 RF SPI1_NPCS2 +PA27 DRXD PCK3 +PA28 DTXD NC +PA29 FIQ SPI1_NPCS3 +PA30 IRQ0 PCK2 diff --git a/lk/platform/at91sam7/debug.c b/lk/platform/at91sam7/debug.c new file mode 100644 index 0000000..ad8f262 --- /dev/null +++ b/lk/platform/at91sam7/debug.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +void ser_init(void) +{ + AT91DBGU *dbgu = AT91DBGU_ADDR; + +// AT91PIO *pio = AT91PIO_ADDR; +// pio->select_a = PIN_DRXD | PIN_DTXD; +// pio->pio_disable = PIN_DRXD | PIN_DTXD; + + dbgu->MR = DBGU_PAR_NONE | DBGU_MODE_NORMAL; + // dbgu->BRGR = 10; //MCK_IN_MHZ / 115200 / 16; + dbgu->BRGR = AT91_MCK_MHZ / 115200 / 16; + dbgu->CR = DBGU_RXEN | DBGU_TXEN; +} + +void ser_putc(unsigned c) +{ + AT91DBGU *dbgu = AT91DBGU_ADDR; + if(c == 10) { + while(!(dbgu->SR & DBGU_TXRDY)); + dbgu->THR = 13; + } + while(!(dbgu->SR & DBGU_TXRDY)); + dbgu->THR = c; +} + +void ser_puts(const char *s) +{ + AT91DBGU *dbgu = AT91DBGU_ADDR; + while(*s) { + if(*s == 10) { + while(!(dbgu->SR & DBGU_TXRDY)); + dbgu->THR = 13; + } + while(!(dbgu->SR & DBGU_TXRDY)); + dbgu->THR = *s++; + } +} + +void _dputc(char c) +{ + ser_putc(c); +} + +void platform_halt() +{ + arch_disable_ints(); + for(;;); +} + +uint32_t debug_cycle_count() +{ + PANIC_UNIMPLEMENTED; +} diff --git a/lk/platform/at91sam7/emac_dev.c b/lk/platform/at91sam7/emac_dev.c new file mode 100644 index 0000000..03a3237 --- /dev/null +++ b/lk/platform/at91sam7/emac_dev.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +#include + +#include +#include + +#include + +void emac_init_send(void); + +#define PHYA 31 + +static unsigned mi_rd(AT91EMAC *emac, unsigned addr) +{ + addr &= 0x1f; + + thread_sleep(20); + + emac->MAN = + (1 << 30) | /* sof: 01 */ + (2 << 28) | /* rw: 10 = read */ + (PHYA << 23) | /* phya: PHYA */ + (addr << 18) | /* rega: addr */ + (2 << 16); /* code: 10 */ + + while(!(emac->NSR & NSR_IDLE)) ; + + thread_sleep(20); + return emac->MAN & 0xffff; +} + +static void mi_wr(AT91EMAC *emac, unsigned addr, unsigned val) +{ + addr &= 0x1f; + val &= 0xffff; + + emac->MAN = + (1 << 30) | /* sof: 01 */ + (1 << 28) | /* rw: 01 = read */ + (PHYA << 23) | /* phya: PHYA */ + (addr << 18) | /* rega: addr */ + (2 << 16) | /* code: 10 */ + val; /* data: val */ + + while(!(emac->NSR & NSR_IDLE)) ; +} + +#define PIN_EMAC_ALL 0x3ffff +#define PIN_PHY_PD (1 << 18) +#define PIN_PHY_IRQ (1 << 26) + +#define PIN_PHYAD0 (1 << 26) +#define PIN_PHYAD1 (1 << 14) +#define PIN_PHYAD2 (1 << 13) +#define PIN_PHYAD3 (1 << 6) +#define PIN_PHYAD4 (1 << 5) +#define PIN_LPBK (1 << 15) +#define PIN_ISOLATE (1 << 7) +#define PIN_RMII_MODE (1 << 16) +#define PIN_RMII_BTB (1 << 4) + +/* select RMII w/ BTB, 100mbps duplex autonegotiate +** disable ISOLATE and LPBK +** phya=00001b +*/ +#define PIN_RESET_LOW (PIN_LPBK) + +int emac_init(void) +{ + AT91EMAC *emac = AT91EMAC_ADDR; + AT91PIO *piob = AT91PIOB_ADDR; + AT91PMC *pmc = AT91PMC_ADDR; + AT91RSTC *rstc = AT91RSTC_ADDR; + + dprintf(INFO, "emac_init()\n"); + + /* enable clock to EMAC */ + pmc->PCER = (1 << PID_EMAC); + + thread_sleep(10); + + /* for reset, all lines are gpio inputs and pullups are + enabled or disabled per strapping mode defined above */ + piob->pio_enable = PIN_EMAC_ALL | PIN_PHY_PD | PIN_PHY_IRQ; + piob->select_a = PIN_EMAC_ALL; + piob->pullup_enable = PIN_EMAC_ALL | PIN_PHY_IRQ; + piob->pullup_disable = PIN_LPBK | PIN_ISOLATE | PIN_RMII_MODE; + piob->output_disable = PIN_EMAC_ALL; + + /* PHY PD becomes output and high (no powerdown mode */ + piob->data_set = PIN_PHY_PD; + piob->output_enable = PIN_PHY_PD; + + thread_sleep(30); + + dprintf(INFO, "emac_init() - reset phy\n"); + + /* assert the RST line and wait until the it deasserts */ + rstc->CR = RSTC_KEY | RSTC_EXTRST; + while(rstc->SR & RSTC_NRSTL) ; + + thread_sleep(30); + + /* after reset all the gpios are assigned to the EMAC, + except for PHY_PD (which remains output and high) */ + piob->pio_disable = PIN_EMAC_ALL; + + emac->USRIO = USRIO_CLKEN; + + thread_sleep(1000); + + dprintf(INFO, "emac_init() - read state\n"); + + emac->NCR = NCR_MPE; + emac->NCFG = NCFG_CLK_d64; + + dprintf(INFO, "bcr = %x\n", mi_rd(emac, MII_REG_BCR)); + dprintf(INFO, "id1 = %x\n", mi_rd(emac, MII_REG_PHY_ID1)); + dprintf(INFO, "id2 = %x\n", mi_rd(emac, MII_REG_PHY_ID2)); + +#if 0 + unsigned state, last; + last = 0xff; + + for(;;) { + state = mi_rd(emac, MII_REG_100TX_PHY) & MII_100TX_MODE_MASK; + if(last != state) { + last = state; + char *name; + switch(state) { + case MII_100TX_MODE_AUTO: + name = "auto negotiate"; + break; + case MII_100TX_MODE_10T_H: + name = "10-T half duplex"; + break; + case MII_100TX_MODE_10T_F: + name = "10-T full duplex"; + break; + case MII_100TX_MODE_100TX_H: + name = "100-TX half duplex"; + break; + case MII_100TX_MODE_100TX_F: + name = "100-TX full duplex"; + break; + case MII_100TX_MODE_ISOLATE: + name = "isolate"; + break; + default: + name = "unknown"; + } + dprintf(INFO, "link state: %s\n", name); + } + thread_sleep(100); + } +#endif + + emac_init_send(); + + return 0; +} + +#define XMIT_ENTRY_COUNT 32 +static emac_xmit_entry xmit_list[XMIT_ENTRY_COUNT]; +static unsigned xmit_next = 0; +static mutex_t xmit_lock; + +void emac_init_send(void) +{ + AT91EMAC *emac = AT91EMAC_ADDR; + int i; + + for(i = 0; i < XMIT_ENTRY_COUNT; i++) { + xmit_list[i].info = XMIT_USED; + xmit_list[i].addr = 0; + } + xmit_list[i-1].info |= XMIT_LAST; + + emac->NCFG = NCFG_CLK_d64 | NCFG_SPD | NCFG_FD; + emac->NCR = NCR_TE | NCR_MPE; + emac->TBQP = (unsigned) xmit_list; + + mutex_init(&xmit_lock); +} + +int ethernet_send(void *data, unsigned len) +{ + AT91EMAC *emac = AT91EMAC_ADDR; + + emac_xmit_entry *xe; + int waited = 0; + + mutex_acquire(&xmit_lock); + + xe = xmit_list + xmit_next; + + while(!(xe->info & XMIT_USED)) { + thread_yield(); + waited++; + } + + if(waited) dprintf(INFO, "W%d\n",waited); + + if(xe->addr != 0) { + free((void*) xe->addr); + } + + xe->addr = (unsigned) data; + if(xmit_next == (XMIT_ENTRY_COUNT - 1)) { + xe->info = XMIT_LENGTH(len) | XMIT_LAST | XMIT_WRAP; + xmit_next = 0; + } else { + xe->info = XMIT_LENGTH(len) | XMIT_LAST; + xmit_next++; + } + + emac->NCR |= NCR_TSTART; + + mutex_release(&xmit_lock); + + return 0; +} + diff --git a/lk/platform/at91sam7/include/platform/at91sam7.h b/lk/platform/at91sam7/include/platform/at91sam7.h new file mode 100644 index 0000000..cd5a50f --- /dev/null +++ b/lk/platform/at91sam7/include/platform/at91sam7.h @@ -0,0 +1,794 @@ +/* at91sam7s.h -- AT91SAM7S hardware definitions +** +** Copyright 2006, Brian Swetland. All rights reserved. +** See provided LICENSE file or http://frotz.net/LICENSE for details. +*/ + +#ifndef __PLATFORM_AT91SAM7_H__ +#define __PLATFORM_AT91SAM7_H__ + +#if !defined(AT91_SAM7X) && !defined(AT91_SAM7S) +#error Unspecified Architecture - AT91SAM7S or AT91SAM7X must be defined +#endif + +/* peripheral ids */ +#define PID_AIC_FIQ 0 +#define PID_SYSIRQ 1 +#define PID_PIOA 2 +#define PID_USART0 6 +#define PID_USART1 7 +#define PID_SSC 8 +#define PID_TWI 9 +#define PID_PWMC 10 +#define PID_UDP 11 +#define PID_TC0 12 +#define PID_TC1 13 +#define PID_TC2 14 +#if AT91_SAM7X +#define PID_PIOB 3 +#define PID_SPI0 4 +#define PID_SPI1 5 +#define PID_CAN 15 +#define PID_EMAC 16 +#define PID_ADC 17 +#define PID_AIC_IRQ0 30 +#define PID_AIC_IRQ1 31 +#else +#define PID_ADC 4 +#define PID_SPI0 5 +#define PID_AIC_IRQ 30 +#endif + +#define BASE_FLASH 0x00100000 +#define BASE_SRAM 0x00200000 +#define BASE_TC 0xFFFA0000 +#define BASE_UDP 0xFFFB0000 +#define BASE_TWI 0xFFFB8000 +#define BASE_USART0 0xFFFC0000 +#define BASE_USART1 0xFFFC4000 +#define BASE_PWMC 0xFFFCC000 +#define BASE_SSC 0xFFFD4000 +#define BASE_ADC 0xFFFD8000 +#define BASE_SPI0 0xFFFE0000 + +#define BASE_AIC 0xFFFFF000 +#define BASE_DBGU 0xFFFFF200 +#define BASE_PIOA 0xFFFFF400 +#define BASE_PMC 0xFFFFFC00 +#define BASE_RSTC 0xFFFFFD00 +#define BASE_RTT 0xFFFFFD20 +#define BASE_PIT 0xFFFFFD30 +#define BASE_WDT 0xFFFFFD40 +#define BASE_VREG 0xFFFFFD60 +#define BASE_MC 0xFFFFFF00 + +#if AT91_SAM7X +#define BASE_CAN 0xFFFD0000 +#define BASE_EMAC 0xFFFDC000 +#define BASE_SPI1 0xFFFE4000 +#define BASE_PIOB 0xFFFFF600 +#endif + + +typedef volatile unsigned int vu4; + +typedef struct +{ + vu4 MR; + vu4 SR; + vu4 PIVR; + vu4 PIIR; +} AT91PIT; + +/* MR */ +#define PIT_PITEN (1 << 24) +#define PIT_PITIEN (1 << 25) + +/* SR */ +#define PIT_PITS (1) + +/* PIxR */ +#define PIT_PICNT(x) (x >> 20) +#define PIT_CPIV(x) (x & 0x000fffff) + +#define AT91PIT_ADDR ((AT91PIT*) BASE_PIT) + +typedef struct +{ + vu4 CR; + vu4 MR; + vu4 IER; + vu4 IDR; + vu4 IMR; + vu4 SR; + vu4 RHR; + vu4 THR; + vu4 BRGR; + vu4 __0[7]; + vu4 CIDR; + vu4 EXID; + vu4 FNR; +} AT91DBGU; + +/* CR bits */ +#define DBGU_RSTRX 0x00000004 +#define DBGU_RSTTX 0x00000008 +#define DBGU_RXEN 0x00000010 +#define DBGU_RXDIS 0x00000020 +#define DBGU_TXEN 0x00000040 +#define DBGU_TXDIS 0x00000080 +#define DBGU_RSTSTA 0x00000100 + +/* MR bits */ +#define DBGU_PAR_EVEN 0x00000000 +#define DBGU_PAR_ODD 0x00000200 +#define DBGU_PAR_SPACE 0x00000400 +#define DBGU_PAR_MARK 0x00000600 +#define DBGU_PAR_NONE 0x00000800 + +#define DBGU_MODE_NORMAL 0x00000000 +#define DBGU_MODE_ECHO 0x0000C000 +#define DBGU_MODE_LLOOP 0x00008000 +#define DBGU_MODE_RLOOP 0x00004000 + +/* IER, IDR, IMR, and SR bits */ +#define DBGU_RXRDY 0x00000001 +#define DBGU_TXRDY 0x00000002 +#define DBGU_ENDRX 0x00000008 +#define DBGU_ENDTX 0x00000010 +#define DBGU_OVRE 0x00000020 +#define DBGU_FRAME 0x00000040 +#define DBGU_PARE 0x00000080 +#define DBGU_TXEMPTY 0x00000200 +#define DBGU_TXBUFE 0x00000800 +#define DBGU_RXBUFF 0x00001000 +#define DBGU_COMMTX 0x40000000 +#define DBGU_COMMRX 0x80000000 + +#define AT91DBGU_ADDR ((AT91DBGU*) BASE_DBGU) + +typedef struct +{ + vu4 pio_enable; + vu4 pio_disable; + vu4 pio_status; + vu4 __0; + vu4 output_enable; + vu4 output_disable; + vu4 output_status; + vu4 __1; + vu4 filter_enable; + vu4 filter_disable; + vu4 filter_status; + vu4 __2; + vu4 data_set; + vu4 data_clear; + vu4 data_status; + vu4 pin_status; + vu4 irq_enable; + vu4 irq_disable; + vu4 irq_mask; + vu4 irq_status; + vu4 multidriver_enable; + vu4 multidriver_disable; + vu4 multidriver_status; + vu4 __3; + vu4 pullup_disable; + vu4 pullup_enable; + vu4 pullup_status; + vu4 __4; + vu4 select_a; + vu4 select_b; + vu4 select_status; + vu4 __5[9]; + vu4 write_enable; + vu4 write_disable; + vu4 write_status; +} AT91PIO; + +#define AT91PIOA_ADDR ((AT91PIO*) BASE_PIOA) +#if AT91_SAM7X +#define AT91PIOB_ADDR ((AT91PIO*) BASE_PIOB) +#endif + +typedef struct +{ + vu4 SCER; + vu4 SCDR; + vu4 SCSR; + vu4 __0; + vu4 PCER; + vu4 PCDR; + vu4 PCSR; + vu4 __1; + vu4 MOR; + vu4 MCFR; + vu4 __2; + vu4 PLLR; + vu4 MCKR; + vu4 __3[2]; + vu4 PCK0; + vu4 PCK1; + vu4 PCK2; +} AT91PMC; + +#define AT91PMC_ADDR ((AT91PMC*) BASE_PMC) + +/* PMC_SCER/SCDR */ +#define PMC_PCK 0x00000001 +#define PMC_UDP 0x00000080 +#define PMC_PCK0 0x00000100 +#define PMC_PCK1 0x00000200 +#define PMC_PCK2 0x00000400 + +typedef struct +{ + vu4 CR; + vu4 MR; + vu4 RDR; + vu4 TDR; + vu4 SR; + vu4 IER; + vu4 IDR; + vu4 IMR; + vu4 __0[4]; + vu4 CSR0; + vu4 CSR1; + vu4 CSR2; + vu4 CSR3; +} AT91SPI; + +#define AT91SPI0_ADDR ((AT91SPI*) BASE_SPI0) +#if AT91_SAM7X +#define AT91SPI1_ADDR ((AT91SPI*) BASE_SPI0) +#endif + +/* CR bits */ +#define SPI_SPIEN 0x00000001 +#define SPI_SPIDIS 0x00000002 +#define SPI_SWRST 0x00000080 +#define SPI_LASTXFER 0x01000000 + +/* MR bits */ +#define SPI_MSTR 0x00000001 +#define SPI_PS 0x00000002 +#define SPI_PCSDEC 0x00000004 +#define SPI_MODFDIS 0x00000010 +#define SPI_LLB 0x00000080 +#define SPI_DLYBCS(n) (((n) & 0xff) << 24) +#define SPI_PCS0 0x000e0000 +#define SPI_PCS1 0x000d0000 +#define SPI_PCS2 0x000b0000 +#define SPI_PCS3 0x00070000 + +/* SR bits */ +#define SPI_RDRF 0x00000001 /* recv data reg full */ +#define SPI_TDRE 0x00000002 /* xmit data reg empty */ +#define SPI_MODF 0x00000004 /* mode fault error */ +#define SPI_OVRES 0x00000008 /* overrun error */ +#define SPI_ENDRX 0x00000010 /* end of rx buffer */ +#define SPI_ENDTX 0x00000020 /* end of tx buffer */ +#define SPI_RXBUFF 0x00000040 /* rx buffer full */ +#define SPI_TXBUFE 0x00000080 /* tx buffer empty */ +#define SPI_NSSR 0x00000100 /* rising edge on NSS */ +#define SPI_TXEMPTY 0x00000200 /* transmission regs empty */ +#define SPI_SPIENS 0x00010000 + +typedef struct +{ + vu4 FRM_NUM; + vu4 GLB_STAT; + vu4 FADDR; + vu4 __0; + vu4 IER; + vu4 IDR; + vu4 IMR; + vu4 ISR; + vu4 ICR; + vu4 __1; + vu4 RST_EP; + vu4 __2; + vu4 CSR0; + vu4 CSR1; + vu4 CSR2; + vu4 CSR3; + vu4 __3[4]; + vu4 FDR0; + vu4 FDR1; + vu4 FDR2; + vu4 FDR3; + vu4 __4[5]; + vu4 TXVC; +} AT91UDP; + +#define AT91UDP_ADDR ((AT91UDP*) BASE_UDP) + +// GLB_STAT bits +#define UDP_FADDEN 0x00000001 +#define UDP_CONFG 0x00000002 +#define UDP_ESR 0x00000004 +#define UDP_RSMINPR 0x00000008 +#define UDP_RMWUPE 0x00000010 + +// FADDR bits +#define UDP_FEN 0x00000100 + +// interrupt bits +#define UDP_EP0INT 0x00000001 +#define UDP_EP1INT 0x00000002 +#define UDP_EP2INT 0x00000004 +#define UDP_EP3INT 0x00000008 +#define UDP_RXSUSP 0x00000100 +#define UDP_RXRSM 0x00000200 +#define UDP_EXTRSM 0x00000400 +#define UDP_SOFINT 0x00000800 +#define UDP_ENDBUSRES 0x00001000 +#define UDP_WAKEUP 0x00002000 + +// RST_EP bits +#define UDP_EP0 0x00000001 +#define UDP_EP1 0x00000002 +#define UDP_EP2 0x00000004 +#define UDP_EP3 0x00000008 + +// CSR bits +#define UDP_TXCOMP 0x00000001 +#define UDP_RX_DATA_BK0 0x00000002 +#define UDP_RXSETUP 0x00000004 +#define UDP_STALLSENT 0x00000008 +#define UDP_ISOERROR 0x00000008 +#define UDP_TXPKTRDY 0x00000010 +#define UDP_FORCESTALL 0x00000020 +#define UDP_RX_DATA_BK1 0x00000040 +#define UDP_DIR 0x00000080 + +#define UDP_DTGL 0x00000800 +#define UDP_EPEDS 0x00008000 + +#define UDP_TYPE_CONTROL 0x00000000 +#define UDP_TYPE_ISOCH_OUT 0x00000100 +#define UDP_TYPE_BULK_OUT 0x00000200 +#define UDP_TYPE_INT_OUT 0x00000300 +#define UDP_TYPE_ISOCH_IN 0x00000500 +#define UDP_TYPE_BULK_IN 0x00000600 +#define UDP_TYPE_INT_IN 0x00000700 + +typedef struct +{ + vu4 SMR[32]; + vu4 SVR[32]; + vu4 IVR; + vu4 FVR; + vu4 ISR; + vu4 IPR; + vu4 IMR; + vu4 CISR; + vu4 __0[2]; + vu4 IECR; + vu4 IDCR; + vu4 ICCR; + vu4 ISCR; + vu4 EOICR; + vu4 SPU; + vu4 DCR; + vu4 __1; + vu4 FFER; + vu4 FFDR; + vu4 FFSR; +} AT91AIC; + +#define AT91AIC_ADDR ((AT91AIC*) BASE_AIC) + + +typedef struct +{ + vu4 CR; + vu4 MR; + vu4 IER; + vu4 IDR; + vu4 IMD; + vu4 CSR; + vu4 RHR; + vu4 THR; + vu4 BRGR; + vu4 RTOR; + vu4 TTGR; + vu4 __0[5]; + vu4 FIDI; + vu4 NER; + vu4 __1; + vu4 IF; + vu4 MAN; +} AT91USART; + +#define AT91USART0_ADDR ((AT91USART*) 0xFFFC0000) +#define AT91USART1_ADDR ((AT91USART*) 0xFFFC4000) + +/* CR */ +#define USART_RSTRX 0x00000004 +#define USART_RSTTX 0x00000008 +#define USART_RXEN 0x00000010 +#define USART_RXDIS 0x00000020 +#define USART_TXEN 0x00000040 +#define USART_TXDIS 0x00000080 +#define USART_RSTSTA 0x00000100 +#define USART_STTBRK 0x00000200 +#define USART_STPBRK 0x00000400 +#define USART_STTTO 0x00000800 +#define USART_SENDA 0x00001000 +#define USART_RSTIT 0x00002000 +#define USART_RSTNACK 0x00004000 +#define USART_RETTO 0x00008000 +#define USART_DTREN 0x00010000 +#define USART_DTRDIS 0x00020000 +#define USART_RTSEN 0x00040000 +#define USART_RTSDIS 0x00080000 + +/* MR */ +#define USART_MODE_NORMAL 0x00000000 +#define USART_MODE_RS485 0x00000001 +#define USART_MODE_HWHS 0x00000002 +#define USART_MODE_MODEM 0x00000003 +#define USART_MODE_ISO7816T0 0x00000004 +#define USART_MODE_ISO7816T1 0x00000006 +#define USART_MODE_IRDA 0x00000008 + +#define USART_CLK_MCK 0x00000000 +#define USART_CLK_MCK_DIV 0x00000010 +#define USART_CLK_SCK 0x00000030 + +#define USART_CHRL_5BITS 0x00000000 +#define USART_CHRL_6BITS 0x00000040 +#define USART_CHRL_7BITS 0x00000080 +#define USART_CHRL_8BITS 0x000000C0 + +#define USART_SYNCHRONOUS 0x00000100 + +#define USART_PARITY_EVEN 0x00000000 +#define USART_PARITY_ODD 0x00000200 +#define USART_PARITY_SPACE 0x00000400 +#define USART_PARITY_MARK 0x00000600 +#define USART_PARITY_NONE 0x00000800 +#define USART_PARITY_MULTIDROP 0x00000C00 + +#define USART_1STOP 0x00000000 +#define USART_1X5STOP 0x00001000 +#define USART_2STOP 0x00002000 + +#define USART_CHMODE_NORMAL 0x00000000 +#define USART_CHMODE_ECHO 0x00004000 +#define USART_CHMODE_LLOOP 0x00008000 +#define USART_CHMODE_RLOOP 0x0000C000 + +#define USART_MSBF 0x00010000 +#define USART_MODE9 0x00020000 +#define USART_CLKO 0x00040000 +#define USART_OVER 0x00080000 +#define USART_INACK 0x00100000 +#define USART_DSNACK 0x00200000 +#define USART_VAR_SYNC 0x00400000 + +#define USART_FILTER 0x10000000 +#define USART_MAN 0x20000000 +#define USART_ONEBIT 0x80000000 + +/* CSR */ +#define USART_RXRDY 0x00000001 +#define USART_TXRDY 0x00000002 +#define USART_RXBRK 0x00000004 +#define USART_ENDRX 0x00000008 +#define USART_ENDTX 0x00000010 +#define USART_OVRE 0x00000020 +#define USART_FRAME 0x00000040 +#define USART_PARE 0x00000080 +#define USART_TIMEOUT 0x00000100 +#define USART_TXEMPTY 0x00000200 +#define USART_ITERATION 0x00000400 +#define USART_TXBUFE 0x00000800 +#define USART_RXBUFF 0x00001000 +#define USART_NACK 0x00002000 + + +typedef struct +{ + vu4 CR; + vu4 SR; + vu4 MR; +} AT91RSTC; + +#define RSTC_KEY 0xA5000000 + +/* cr */ +#define RSTC_PROCRST 0x00000001 +#define RSTC_PERRST 0x00000004 +#define RSTC_EXTRST 0x00000008 + +/* sr */ +#define RSTC_URSTS 0x00000001 +#define RSTC_BODSTS 0x00000002 +#define RSTC_RSTTYP_MASK 0x00000070 +#define RSTC_RSTTYP_COLD 0x00000000 +#define RSTC_RSTTYP_WATCHDOG 0x00000020 +#define RSTC_RSTTYP_SOFTWARE 0x00000030 +#define RSTC_RSTTYP_NRST_PIN 0x00000040 +#define RSTC_RSTTYP_BROWNOUT 0x00000060 +#define RSTC_NRSTL 0x00010000 +#define RSTC_SRCMP 0x00020000 + +/* mr */ +#define RSTC_URSTEN 0x00000001 +#define RSTC_URSTIEN 0x00000010 +#define RSTC_ERSTL(n) (((n) & 0xf) << 8) +#define RSTC_BODIEN 0x00010000 + +#define AT91RSTC_ADDR ((AT91RSTC*) BASE_RSTC) + +#if AT91_SAM7X + +typedef struct +{ + vu4 NCR; + vu4 NCFG; + vu4 NSR; + vu4 __0; + + vu4 __1; + vu4 TSR; + vu4 RBQP; + vu4 TBQP; + + vu4 RSR; + vu4 ISR; + vu4 IER; + vu4 IDR; + + vu4 IMR; + vu4 MAN; + vu4 PTR; + vu4 PFR; + + vu4 FTO; + vu4 SCF; + vu4 MCF; + vu4 FRO; + + vu4 FCSE; + vu4 ALE; + vu4 DTF; + vu4 LCOL; + + vu4 ECOL; + vu4 TUND; + vu4 CSE; + vu4 RRE; + + vu4 ROV; + vu4 RSE; + vu4 ELE; + vu4 RJA; + + vu4 USF; + vu4 STE; + vu4 RLE; + vu4 __2; + + vu4 HRB; + vu4 HRT; + vu4 SA1B; + vu4 SA1T; + + vu4 SA2B; + vu4 SA2T; + vu4 SA3B; + vu4 SA3T; + + vu4 SA4B; + vu4 SA5T; + vu4 TID; + vu4 __3; + + vu4 USRIO; +} AT91EMAC; + + +#define NCR_LB 0x00000001 +#define NCR_LLB 0x00000002 +#define NCR_RE 0x00000004 +#define NCR_TE 0x00000008 +#define NCR_MPE 0x00000010 +#define NCR_CLRSTAT 0x00000020 +#define NCR_INCSTAT 0x00000040 +#define NCR_WESTAT 0x00000080 +#define NCR_BP 0x00000100 +#define NCR_TSTART 0x00000200 +#define NCR_THALT 0x00000400 + +#define NCFG_SPD 0x00000001 +#define NCFG_FD 0x00000002 +#define NCFG_JFRAME 0x00000008 +#define NCFG_CAF 0x00000010 +#define NCFG_NBC 0x00000020 +#define NCFG_MTI 0x00000040 +#define NCFG_UNI 0x00000080 +#define NCFG_BIG 0x00000100 +#define NCFG_CLK_d8 0x00000000 +#define NCFG_CLK_d16 0x00000400 +#define NCFG_CLK_d32 0x00000800 +#define NCFG_CLK_d64 0x00000C00 +#define NCFG_RTY 0x00001000 +#define NCFG_PAE 0x00002000 +#define NCFG_RBOF_0 0x00000000 +#define NCFG_RBOF_1 0x00004000 +#define NCFG_RBOF_2 0x00008000 +#define NCFG_RBOF_3 0x0000C000 +#define NCFG_RLCE 0x00010000 +#define NCFG_DRFCS 0x00020000 +#define NCFG_EFRHD 0x00040000 +#define NCFG_IRXFCS 0x00080000 + +#define NSR_MDIO 0x00000002 +#define NSR_IDLE 0x00000004 + +#define TSR_UBR 0x00000001 +#define TSR_COL 0x00000002 +#define TSR_RLE 0x00000004 +#define TSR_TGO 0x00000008 +#define TSR_BEX 0x00000010 +#define TSR_COMP 0x00000020 +#define TSR_UND 0x00000040 + +#define RSR_BNA 0x00000001 +#define RSR_REC 0x00000002 +#define RSR_OVR 0x00000004 + +#define ISR_MFD 0x00000001 +#define ISR_RCOMP 0x00000002 +#define ISR_RXUBR 0x00000004 +#define ISR_TXUBR 0x00000008 +#define ISR_TUND 0x00000010 +#define ISR_RLE 0x00000020 +#define ISR_TXERR 0x00000040 +#define ISR_TCOMP 0x00000080 +#define ISR_ROVR 0x00000400 +#define ISR_HRESP 0x00000800 +#define ISR_PFR 0x00001000 +#define ISR_PTZ 0x00002000 + +#define USRIO_RMII 0x00000001 +#define USRIO_CLKEN 0x00000002 + +#define AT91EMAC_ADDR ((AT91EMAC*) BASE_EMAC) + + +typedef struct +{ + vu4 addr; + vu4 info; +} emac_xmit_entry; + +#define XMIT_USED 0x80000000 +#define XMIT_WRAP 0x40000000 +#define XMIT_ERR_RETRY 0x20000000 +#define XMIT_ERR_UNDERRUN 0x10000000 +#define XMIT_ERR_EXHAUSTED 0x08000000 +#define XMIT_NO_CRC 0x00010000 +#define XMIT_LAST 0x00008000 +#define XMIT_LENGTH(n) ((n) & 0x3FF) + + +/* CAN Registers */ + + +typedef struct +{ + vu4 MMR; /* Mailbox Mode Register */ + vu4 MAM; /* Mailbox Acceptance Mask Register */ + vu4 MID; /* Mailbox ID Register */ + vu4 MFID; /* Mailbox Family ID Register */ + vu4 MSR; /* Mailbox Status Register */ + vu4 MDL; /* Mailbox Data Low Register */ + vu4 MDH; /* Mailbox Data High Register */ + vu4 MCR; /* Mailbox Control Register */ +} AT91CAN_MAILBOX; + +typedef struct +{ + vu4 MR; /* Mode Register */ + vu4 IER; /* Interrupt Enable Register */ + vu4 IDR; /* Interrupt Disable Register */ + vu4 IMR; /* Interrupt Mask Register */ + vu4 SR; /* Status Register */ + vu4 BR; /* Baudrate Register */ + vu4 TIM; /* Timer Register */ + vu4 TIMESTP; /* Timestamp Register */ + vu4 ECR; /* Error Counter Register */ + vu4 TCR; /* Transfer Command Register */ + vu4 ACR; /* Abort Command Register */ + + vu4 __0[53]; /* 0x002c - 0x0100 is undefined */ + vu4 __1[63]; /* 0x0200 - 0x01fc is reserved */ + AT91CAN_MAILBOX Mailbox[8]; +} AT91CAN; + +#define CAN_CANEN 0x00000001 /* CAN Controller Enable */ +#define CAN_LPM 0x00000002 /* Enable Low Power Mode */ +#define CAN_ABM 0x00000004 /* Enable Autoband/Listen Mode */ +#define CAN_OVL 0x00000008 /* Enable Overload Frame */ +#define CAN_TEOF 0x00000010 /* Timestamp Messages at each Frame */ +#define CAN_TTM 0x00000020 /* Enable Time Trigger Mode */ +#define CAN_TIMFRZ 0x00000040 /* Enable Timer Freeze */ +#define CAN_DRPT 0x00000080 /* Disable Repeat */ + +#define CAN_MB(x) (0x00000001 << x) /* Enable Interrupt Enable */ +#define CAN_ERRA 0x00010000 /* Enable Error Active Mode Interrupt */ +#define CAN_WARN 0x00020000 /* Enable Warning Limit Interrupt */ +#define CAN_ERRP 0x00040000 /* Enable Passive mode interrupt */ +#define CAN_BOFF 0x00080000 /* Enable Bus-off mode interrupt */ +#define CAN_SLEEP 0x00100000 /* Enable Sleep Interrupt */ +#define CAN_WAKEUP 0x00200000 /* Enable Wakeup Interrupt */ +#define CAN_TOVF 0x00400000 /* Enable Timer Overflow Interrupt */ +#define CAN_TSTP 0x00800000 /* Enable TimeStamp Interrupt */ +#define CAN_CERR 0x01000000 /* Enable CRC Error Interrupt */ +#define CAN_SERR 0x02000000 /* Enable Stuffing Error Interrupt */ +#define CAN_AERR 0x04000000 /* Enable Acknowledgement Error Int */ +#define CAN_FERR 0x08000000 /* Enable Form Error Interrupt */ +#define CAN_BERR 0x10000000 /* Enable Bit Error Interrupt */ + +#define CAN_RBSY 0x20000000 /* Receiver Busy */ +#define CAN_TBSY 0x40000000 /* Transmitter Busy */ +#define CAN_OVLSY 0x80000000 /* Overload Busy */ + +/* Can Baudrate Regiister */ + +#define CAN_PHASE2(x) (x) +#define CAN_PHASE2_MASK 0x07 +#define CAN_PHASE1(x) (x<<4) +#define CAN_PHASE1_MASK (0x07 << 4) +#define CAN_PROPAG(x) (x<<8) +#define CAN_PROPAG_MASK (0x07 << 8) +#define CAN_SJW(x) (x<<12) +#define CAN_SJW_MASK(x) (0x03 << 12) +#define CAN_BRP(x) (x<<16) +#define CAN_BRP_MASK (0x7f << 16) +#define CAN_SMP 0x01000000 /* Sampling Mode */ + +/* CAN Transfer Command Register */ + +#define TCR_TIMRST 0x80000000 /* Timer Reset */ + +/* CAN Message Mode Register */ + +#define CAN_MTIMEMARK(x) (0x0000001 << x) +#define CAN_PRIOR(x) (x << 16) +#define CAN_MOT(x) (x << 24) + +#define CAN_MIDVB(x) (x) +#define CAN_MIDVA(x) (x << 18) +#define CAN_MIDE 0x20000000 + + +/* CAN MSRx */ + +/* These are receive, so pass in the value of the register... */ + +#define CAN_MTIMESTAMP(x) (x & 0x0000ffff) +#define CAN_MDLC(x) ( (x >> 16) & 0x0f) /* Mailbox code length */ +#define CAN_MRTR 0x00100000 /* Mailbox Remote Trx Request*/ +#define CAN_MABT 0x00400000 /* Mailbox Message Abort */ +#define CAN_MRDY 0x00800000 /* Mailbox Ready */ +#define CAN_MMI 0x01000000 /* Mailbox Message Ignored */ + +/* Message Control Register */ + +//#define CAN_MDLC(x) (x<<16) /* Mailbox Data Length Code */ +#define CAN_MACR (0x01 << 22) /* Abort Request */ +#define CAN_MTCR (0x01 << 23) /* Mailbox Transfer Command */ + + +#define AT91CAN_ADDR ((AT91CAN*) BASE_CAN) + + + +#endif + +#endif diff --git a/lk/platform/at91sam7/init_clock.S b/lk/platform/at91sam7/init_clock.S new file mode 100644 index 0000000..2de137f --- /dev/null +++ b/lk/platform/at91sam7/init_clock.S @@ -0,0 +1,101 @@ +/* init_clock.S -- AT91SAM7 clock coldstart code +** +** Copyright 2006, Brian Swetland. All rights reserved. +** See provided LICENSE file or http://frotz.net/LICENSE for details. +*/ + +.globl init_clock + +init_clock: +/* init flash controller timing for 18.432MHz */ + mov r1, #0xffffff00 + ldr r0, =0x00340100 + str r0, [r1, #0x60] + +#define PMC_MOR 0x20 +#define PMC_MCFR 0x24 +#define PMC_PLLR 0x2c +#define PMC_MCKR 0x30 +#define PMC_SR 0x68 + +/* PMC_MOR */ +#define PMC_MOSCEN 0x01 +#define PMC_OSCBYPASS 0x02 + +/* PMC_MCFR */ +#define PMC_MAINRDY 0x00010000 + +/* PMC_SR */ +#define PMC_MOSCS 0x01 +#define PMC_LOCK 0x04 +#define PMC_MCKRDY 0x08 + +/* PMC_MCKR */ +#define PMC_CSS_SLOW 0x00 +#define PMC_CSS_MAIN 0x01 +#define PMC_CSS_PLL 0x03 +#define PMC_PRES_NONE 0x00 +#define PMC_PRES_DIV2 0x04 +#define PMC_PRES_DIV4 0x08 + +/* Oscillator Init Sequence based on the Atmel sample code +** in cstartup_boot_SAM7S32_64.s +** +** I cleaned it up a bit -- why they use a temporary register, +** AND and then CMP instead of just TSTing against an immediate +** boggles my mind. I think this could be a bit simpler yet, +** but debugging it is a pain, so Good Enough wins for now. +*/ + ldr r1, =0xfffffc00 + +/* bypass main oscillator */ + mov r0, #PMC_OSCBYPASS + str r0, [r1, #PMC_MOR] + +/* compensate MAINRDY rising flag (45 SCLK) */ + mov r0, #45 +1: subs r0, r0, #1 + bhi 1b + +/* if MAINRDY is set, we have an external oscillator */ + ldr r0, [r1, #PMC_MCFR] + tst r0, #PMC_MAINRDY + bne ext_osc_found + +/* reset MOSCS flag */ + mov r0, #0 + str r0, [r1, #PMC_MOR] + +/* enable main oscillator */ + ldr r0, =((0x40 << 8) | PMC_MOSCEN) + str r0, [r1, #PMC_MOR] + +/* wait for main oscillator to come online */ +1: ldr r0, [r1, #PMC_SR] + tst r0, #PMC_MOSCS + beq 1b + +ext_osc_found: +/* select main oscillator, no prescaler for MCK */ + mov r0, #(PMC_CSS_MAIN | PMC_PRES_NONE) + str r0, [r1, #PMC_MCKR] + +/* wait until MCK settles to continue */ +1: ldr r0, [r1, #PMC_SR] + tst r0, #PMC_MCKRDY + beq 1b + +/* this is a bit of voodoo for selecting a 96.109MHz PLL +** freq (MUL=72, DIV=14, OUT=0, USBDIV=/1) from the 18.432MHz +** main clock. +*/ + ldr r0, =0x10483f0e + str r0, [r1, #PMC_PLLR] + +/* let the PLL lock before we continue */ +1: ldr r0, [r1, #PMC_SR] + tst r0, #PMC_LOCK + beq 1b + + mov pc, lr + diff --git a/lk/platform/at91sam7/init_clock_48mhz.S b/lk/platform/at91sam7/init_clock_48mhz.S new file mode 100644 index 0000000..a5bf961 --- /dev/null +++ b/lk/platform/at91sam7/init_clock_48mhz.S @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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. + */ +.globl init_48mhz_clock + +#define PMC_MCKR 0x30 +#define PMC_SR 0x68 + +#define PMC_MCKRDY 0x08 +#define PMC_PRES_DIV2 0x04 +#define PMC_CSS_PLL 0x03 + +/* BUG? +** +** If I try to exit by bx lr, lr is corrupted somewhere in here. +** No clue why. FIQ USB wedge not playing nice? Am I cheating +** with my CPSR calls? +*/ +init_48mhz_clock: + ldr r1, =0xfffffc00 + mov r2, lr + + // turn on /2 prescaler + mov r0, #PMC_PRES_DIV2 + str r0, [r1, #PMC_MCKR] +wait_for_clock1: + ldr r0, [r1, #PMC_SR] + tst r0, #PMC_MCKRDY + beq wait_for_clock1 + + // switch to pll clock + mov r0, #(PMC_PRES_DIV2 | PMC_CSS_PLL) + str r0, [r1, #PMC_MCKR] +wait_for_clock2: + ldr r0, [r1, #PMC_SR] + tst r0, #PMC_MCKRDY + beq wait_for_clock2 + + bx r2 diff --git a/lk/platform/at91sam7/interrupts.c b/lk/platform/at91sam7/interrupts.c new file mode 100644 index 0000000..1bfd277 --- /dev/null +++ b/lk/platform/at91sam7/interrupts.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include + +static int do_nothing() +{ + return INT_NO_RESCHEDULE; +} + +void platform_init_interrupts(void) +{ + AT91AIC *aic = AT91AIC_ADDR; + int n; + + for(n = 0; n < 31; n++) { + aic->SVR[n] = (unsigned) do_nothing; + } + aic->SPU = (unsigned) do_nothing; +} + + +status_t mask_interrupt(unsigned int vector) +{ + AT91AIC *aic = AT91AIC_ADDR; + + if(vector > 31) return ERR_INVALID_ARGS; + + aic->IDCR = (1 << vector); + + return NO_ERROR; +} + +status_t unmask_interrupt(unsigned int vector) +{ + AT91AIC *aic = AT91AIC_ADDR; + if(vector > 31) return ERR_INVALID_ARGS; + + aic->IECR = (1 << vector); + + return NO_ERROR; +} + +void platform_irq(struct arm_iframe *frame) +{ + AT91AIC *aic = AT91AIC_ADDR; + int_handler func; + enum handler_return ret; + + inc_critical_section(); + + func = (int_handler) aic->IVR; +// dprintf("platform_irq() -> %p\n", func); + + ret = func(0); + + aic->EOICR = (unsigned) aic; + + if(ret == INT_RESCHEDULE) { + thread_preempt(); + } + + dec_critical_section(); +} + +void platform_fiq(struct arm_iframe *frame) +{ +} + +void register_int_handler(unsigned int vector, int_handler handler, void *arg) +{ + AT91AIC *aic = AT91AIC_ADDR; + if(vector > 31) return; + aic->SVR[vector] = (unsigned) handler; +} diff --git a/lk/platform/at91sam7/mkboard.py b/lk/platform/at91sam7/mkboard.py new file mode 100644 index 0000000..62ce696 --- /dev/null +++ b/lk/platform/at91sam7/mkboard.py @@ -0,0 +1,178 @@ +#!/usr/bin/python + +## mkboard.py -- atmel pio mux utility +## +## Copyright 2006, Brian Swetland. All rights reserved. +## See provided LICENSE file or http://frotz.net/LICENSE for details. +## + +import os, sys, string + +# pindef -> num, out, pull, pio, sela, selb + +reg_output_disable = 0 +reg_output_enable = 0 +reg_pullup_disable = 0 +reg_pullup_enable = 0 +reg_pio_disable = 0 +reg_pio_enable = 0 +reg_select_a = 0 +reg_select_b = 0 + +def setup_registers(pindef): + global reg_output_disable + global reg_output_enable + global reg_pullup_disable + global reg_pullup_enable + global reg_pio_disable + global reg_pio_enable + global reg_select_a + global reg_select_b + + (num, out, pull, pio, sela, selb) = pindef + + bit = 1 << num + + if out: + reg_output_enable |= bit + reg_output_disable &= (~bit) + else: + reg_output_enable &= (~bit) + reg_output_disable |= bit + + if pull: + reg_pullup_enable |= bit + reg_pullup_disable &= (~bit) + else: + reg_pullup_enable &= (~bit) + reg_pullup_disable |= bit + + if pio: + reg_pio_enable |= bit + reg_pio_disable &= (~bit) + else: + reg_pio_enable &= (~bit) + reg_pio_disable |= bit + + if sela: + reg_select_a |= bit + if selb: + reg_select_b |= bit + +def import_pindef(fn): + pass + +def read_pins_def(fn, table): + output = "" + fd = open(fn,'r') + for line in fd.xreadlines(): + line = line.split('#')[0].strip() + if not line: continue + + (gpio,pa,pb) = line.split() + num = int(gpio[2:]) + + table[gpio+"_IN"] = (num, 0, 0, 1, 0, 0) + table[gpio+"_IN_PULLUP"] = (num, 0, 1, 1, 0, 0) + table[gpio+"_OUT"] = (num, 1, 0, 1, 0, 0) + table[gpio+"_"+pa] = (num, 0, 0, 0, 1, 0) + table[gpio+"_"+pb] = (num, 0, 0, 0, 0, 1) + + return output + +def read_board_def(fn, table): + pins = {} + output = "" + for n in range(0,32): + pins[n] = '' + + fd = open(fn,'r') + for line in fd.xreadlines(): + line = line.split('#')[0].strip() + if not line: continue + + if len(line.split('=')) == 2: + (line,func) = line.split('=') + line = line.strip() + func = func.strip() + else: + func = '' + + parts = line.split() + if len(parts) < 2: + print "ERROR: invalid definition '%s'" % line + sys.exit(1) + + if not func: + if (parts[1] == 'IN') or (parts[1] == 'OUT'): + func = parts[0] + else: + func = parts[1] + + pin = string.join(parts,"_") + + if not table.has_key(pin): + print "ERROR: pin '%s' does not exist" % pin + sys.exit(1) + + pindef = table[pin] + num = pindef[0] + if pins[num]: + print "ERROR: pin '%s' conflicts with pin '%s'" % (pin, pins[num]) + sys.exit(1) + pins[num] = pin + + setup_registers(pindef) + output += "#define PIN_%-12s (1 << %d)\n" % (func, num) + + return output + +table = {} +output = "" + +for fn in sys.argv[1:]: + if fn.endswith('.pins'): + if table: + print "ERROR: only one pin definition file allowed" + sys.exit(1) + output = read_pins_def(fn, table) + continue + + if fn.endswith('.def'): + if not table: + print "ERROR: must specify a pin definition file first" + sys.exit(1) + + reg_output_disable = 0xffffffffL + reg_output_enable = 0L + reg_pullup_disable = 0L + reg_pullup_enable = 0xffffffffL + reg_pio_disable = 0L + reg_pio_enable = 0xffffffffL + reg_select_a = 0L + reg_select_b = 0L + + output = read_board_def(fn, table) + fd = open(fn[:-4] + ".h", 'w') + fd.write("/* DO NOT EDIT -- AUTOGENERATED FROM '%s' */\n\n" % fn) + fd.write("#ifndef __BOARD_DEFINITION_FILE__\n") + fd.write("#define __BOARD_DEFINITION_FILE__\n\n") + fd.write(output) + fd.write("\n") + fd.write("#define BOARD_OUTPUT_DISABLE 0x%08x\n" % reg_output_disable) + fd.write("#define BOARD_OUTPUT_ENABLE 0x%08x\n" % reg_output_enable) + fd.write("#define BOARD_PULLUP_DISABLE 0x%08x\n" % reg_pullup_disable) + fd.write("#define BOARD_PULLUP_ENABLE 0x%08x\n" % reg_pullup_enable) + fd.write("#define BOARD_PIO_DISABLE 0x%08x\n" % reg_pio_disable) + fd.write("#define BOARD_PIO_ENABLE 0x%08x\n" % reg_pio_enable) + fd.write("#define BOARD_SELECT_A 0x%08x\n" % reg_select_a) + fd.write("#define BOARD_SELECT_B 0x%08x\n" % reg_select_b) + fd.write("\n#endif\n") + fd.close() + continue + + print "ERROR: what is '%s'?" % fn + sys.exit(1) + + + diff --git a/lk/platform/at91sam7/mux.c b/lk/platform/at91sam7/mux.c new file mode 100644 index 0000000..7c9d9a6 --- /dev/null +++ b/lk/platform/at91sam7/mux.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +void mux_init(void) +{ + AT91PIO *pio = AT91PIOA_ADDR; + + pio->output_disable = BOARD_OUTPUT_DISABLE; + pio->output_enable = BOARD_OUTPUT_ENABLE; + pio->pullup_disable = BOARD_PULLUP_DISABLE; + pio->pullup_enable = BOARD_PULLUP_ENABLE; + pio->pio_disable = BOARD_PIO_DISABLE; + pio->pio_enable = BOARD_PIO_ENABLE; + pio->select_a = BOARD_SELECT_A; + pio->select_b = BOARD_SELECT_B; +} + diff --git a/lk/platform/at91sam7/platform.c b/lk/platform/at91sam7/platform.c new file mode 100644 index 0000000..378c06d --- /dev/null +++ b/lk/platform/at91sam7/platform.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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. + */ + +void emac_init(); + +void platform_init(void) +{ +#if AT91_SAM7X + emac_init(); +#endif +} diff --git a/lk/platform/at91sam7/platform_early.S b/lk/platform/at91sam7/platform_early.S new file mode 100644 index 0000000..e78e271 --- /dev/null +++ b/lk/platform/at91sam7/platform_early.S @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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. + */ + +.globl platform_early_init +platform_early_init: + stmdb sp!, {lr} + +/* enable the NRST reset pin */ + ldr r1, =0xfffffd08 + ldr r0, =0xa5000401 + str r0, [r1] + +/* disable watchdog */ + ldr r1, =0xfffffd44 + ldr r0, =0x3fff8fff + str r0, [r1] + + bl init_clock + bl init_48mhz_clock + +/* copy the .data section from ROM to RAM */ + ldr r0, =__rodata_end + ldr r1, =__data_start + ldr r2, =__bss_start +__data_loop: + cmp r1, r2 + ldrlt r3, [r0], #4 + strlt r3, [r1], #4 + blt __data_loop + + bl mux_init + bl ser_init + bl platform_init_interrupts + + ldmia sp!, {lr} + bx lr diff --git a/lk/platform/at91sam7/rules.mk b/lk/platform/at91sam7/rules.mk new file mode 100644 index 0000000..9186ef8 --- /dev/null +++ b/lk/platform/at91sam7/rules.mk @@ -0,0 +1,70 @@ +# +# The TARGET is expected to indicate which *specific* AT91SAM7 chip +# is being used, since features and memory vary from chip to chip +# +# chip ram rom EMAC CAN +# AT91CHIP := sam7s64 16k 64k N N +# AT91CHIP := sam7s256 64k 256k N N +# AT91CHIP := sam7x256 64k 256k Y Y +# + +# ROMBASE, MEMBASE, and MEMSIZE are required for the linker script +ROMBASE := 0x0 +MEMBASE := 0x200000 + +TMP_CFG := bad +ifeq ($(AT91CHIP), sam7x256) +DEFINES += AT91_SAM7X=1 +DEFINES += AT91_RAMSIZE=65536 +DEFINES += AT91_ROMSIZE=262144 +MEMSIZE := 65536 +TMP_CFG := ok +endif +ifeq ($(AT91CHIP), sam7s256) +DEFINES += AT91_SAM7S=1 +DEFINES += AT91_RAMSIZE=65536 +DEFINES += AT91_ROMSIZE=262144 +MEMSIZE := 65536 +TMP_CFG := ok +endif +ifeq ($(AT91CHIP), sam7s64) +DEFINES += AT91_SAM7S=1 +DEFINES += AT91_RAMSIZE=16384 +DEFINES += AT91_ROMSIZE=65536 +MEMSIZE := 16384 +TMP_CFG := ok +endif + +ifeq ($(TMP_CFG), bad) +$(error The AT91SAM7 platform requires AT91CHIP be set by the target) +endif + +LOCAL_DIR := $(GET_LOCAL_DIR) + +ARCH := arm +ARM_CPU := arm7tdmi + +DEFINES += AT91_MCK_MHZ=48000000 + +INCLUDES += \ + -I$(LOCAL_DIR)/include + +OBJS += \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/interrupts.o \ + $(LOCAL_DIR)/platform_early.o \ + $(LOCAL_DIR)/platform.o \ + $(LOCAL_DIR)/timer.o \ + $(LOCAL_DIR)/init_clock.o \ + $(LOCAL_DIR)/init_clock_48mhz.o \ + $(LOCAL_DIR)/mux.o \ + $(LOCAL_DIR)/emac_dev.o + +# use a two segment memory layout, where all of the read-only sections +# of the binary reside in rom, and the read/write are in memory. The +# ROMBASE, MEMBASE, and MEMSIZE make variables are required to be set +# for the linker script to be generated properly. +# +LINKER_SCRIPT += \ + $(BUILDDIR)/system-twosegment.ld + diff --git a/lk/platform/at91sam7/timer.c b/lk/platform/at91sam7/timer.c new file mode 100644 index 0000000..be65e9c --- /dev/null +++ b/lk/platform/at91sam7/timer.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include + +#define FIXED_1KHZ_TIMER 0 + +static platform_timer_callback timer_func; + +static volatile time_t ticks = 0; + +#if FIXED_1KHZ_TIMER +static volatile int timer_interval; +static volatile int timer_downcount; +#else +static int timer_ms_per_tick; +#endif + +time_t current_time(void) +{ + return ticks; +} + +static enum handler_return pit_irq_handler(void *arg) +{ + AT91PIT *pit = AT91PIT_ADDR; + unsigned n = PIT_PICNT(pit->PIVR); + +#if FIXED_1KHZ_TIMER + ticks += n; + timer_downcount -= n; + + if(timer_downcount <= 0) { + timer_downcount = timer_interval; + return timer_func(0, ticks); + } else { + return INT_NO_RESCHEDULE; + } +#else + ticks += (n * timer_ms_per_tick); + return timer_func(0, ticks); +#endif +} + +status_t platform_set_periodic_timer(platform_timer_callback callback, + void *arg, time_t interval) +{ + unsigned n; + + AT91PIT *pit = AT91PIT_ADDR; + + n = AT91_MCK_MHZ / 16 / 1000; + dprintf(INFO, "timer: MCK=%dKHz, n=%d\n", AT91_MCK_MHZ / 1000, n); + + enter_critical_section(); + + timer_func = callback; + +#if FIXED_1KHZ_TIMER + timer_interval = interval; + timer_downcount = interval; +#else + timer_ms_per_tick = interval; + n *= interval; +#endif + + pit->MR = PIT_PITEN | PIT_PITIEN | (n & 0xfffff); + + register_int_handler(PID_SYSIRQ, pit_irq_handler, 0); + unmask_interrupt(PID_SYSIRQ); + + exit_critical_section(); + + return NO_ERROR; +} + diff --git a/lk/platform/debug.c b/lk/platform/debug.c new file mode 100644 index 0000000..a38ccbc --- /dev/null +++ b/lk/platform/debug.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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. + */ + + diff --git a/lk/platform/init.c b/lk/platform/init.c new file mode 100644 index 0000000..113cd41 --- /dev/null +++ b/lk/platform/init.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +/* + * default implementations of these routines, if the platform code + * chooses not to implement. + */ + +__WEAK void platform_init_mmu_mappings(void) +{ +} + +__WEAK void platform_early_init(void) +{ +} + +__WEAK void platform_init(void) +{ +} + +__WEAK void display_init(void) +{ +} + +__WEAK void display_shutdown(void) +{ +} + +__WEAK void platform_config_interleaved_mode_gpios(void) +{ +} diff --git a/lk/platform/integrator/debug.c b/lk/platform/integrator/debug.c new file mode 100644 index 0000000..0a2e058 --- /dev/null +++ b/lk/platform/integrator/debug.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include + +static void write_uart_reg(int uart, int reg, unsigned char data) +{ + unsigned long base; + int mul = 4; + + switch(uart) { + case 0: base = INTEGRATOR_UART0_REG_BASE; break; + case 1: base = INTEGRATOR_UART1_REG_BASE; break; + default: return; + } + + *(volatile unsigned char *)(base + reg * mul) = data; +} + +static unsigned char read_uart_reg(int uart, int reg) +{ + unsigned long base; + int mul = 4; + + switch(uart) { + case 0: base = INTEGRATOR_UART0_REG_BASE; break; + case 1: base = INTEGRATOR_UART1_REG_BASE; break; + default: return 0; + } + + return *(volatile unsigned char *)(base + reg * mul); +} + +static int uart_init(void) +{ +#if 0 + /* clear the tx & rx fifo and disable */ + write_uart_reg(0, UART_FCR, 0x6); +#endif + + return 0; +} + +static int uart_putc(int port, char c ) +{ + write_uart_reg(0, PL011_UARTDR, c); +#if 0 + while (!(read_uart_reg(port, UART_LSR) & (1<<6))) // wait for the shift register to empty + ; + write_uart_reg(port, UART_THR, c); +#endif + return 0; +} + +static int uart_getc(int port, bool wait) /* returns -1 if no data available */ +{ +#if 0 + if (wait) { + while (!(read_uart_reg(port, UART_LSR) & (1<<0))) // wait for data to show up in the rx fifo + ; + } else { + if (!(read_uart_reg(port, UART_LSR) & (1<<0))) + return -1; + } + return read_uart_reg(port, UART_RHR); +#endif + return -1; +} + +void _dputc(char c) +{ + uart_putc(0, c); +} + +int dgetc(char *c) +{ + int result = uart_getc(0, false); + + if (result < 0) + return -1; + + *c = result; + return 0; +} + +void debug_dump_regs(void) +{ + PANIC_UNIMPLEMENTED; +} + +void platform_halt(void) +{ + dprintf(ALWAYS, "HALT: spinning forever...\n"); + for(;;); +} + +void debug_dump_memory_bytes(void *mem, int len) +{ + PANIC_UNIMPLEMENTED; +} + +void debug_dump_memory_halfwords(void *mem, int len) +{ + PANIC_UNIMPLEMENTED; +} + +void debug_dump_memory_words(void *mem, int len) +{ + PANIC_UNIMPLEMENTED; +} + +void debug_set_trace_level(int trace_type, int level) +{ + PANIC_UNIMPLEMENTED; +} + +uint32_t debug_cycle_count() +{ + PANIC_UNIMPLEMENTED; +} diff --git a/lk/platform/integrator/include/platform/integrator.h b/lk/platform/integrator/include/platform/integrator.h new file mode 100644 index 0000000..47eaacb --- /dev/null +++ b/lk/platform/integrator/include/platform/integrator.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __INTEGRATOR_H +#define __INTEGRATOR_H + +/* memory map */ +#define SDRAM_BASE 0x00000000 + +#define INTEGRATOR_CORE_REG_BASE 0x10000000 +#define INTEGRATOR_SYS_REG_BASE 0x11000000 +#define INTEGRATOR_EBI_REG_BASE 0x12000000 +#define INTEGRATOR_TIMER_REG_BASE 0x13000000 +#define INTEGRATOR_INT_REG_BASE 0x14000000 +#define INTEGRATOR_UART0_REG_BASE 0x16000000 +#define INTEGRATOR_UART1_REG_BASE 0x17000000 +#define INTEGRATOR_LEDS_REG_BASE 0x1a000000 +#define INTEGRATOR_GPIO_REG_BASE 0x1b000000 + +/* uart stuff */ +#define PL011_UARTDR (0) +#define PL011_UARTRSR (1) +#define PL011_UARTECR (1) +#define PL011_UARTFR (6) +#define PL011_UARTILPR (8) +#define PL011_UARTIBRD (9) +#define PL011_UARTFBRD (10) +#define PL011_UARTLCR_H (11) +#define PL011_UARTCR (12) +#define PL011_UARTIFLS (13) +#define PL011_UARTIMSC (14) +#define PL011_UARTTRIS (15) +#define PL011_UARTTMIS (16) +#define PL011_UARTICR (17) +#define PL011_UARTMACR (18) + +#define INT_VECTORS 32 // XXX just made this up + +#endif + diff --git a/lk/platform/integrator/interrupts.c b/lk/platform/integrator/interrupts.c new file mode 100644 index 0000000..7391eda --- /dev/null +++ b/lk/platform/integrator/interrupts.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include +#include "platform_p.h" +#include + +struct int_handler_struct { + int_handler handler; + void *arg; +}; + +static struct int_handler_struct int_handler_table[INT_VECTORS]; + +#if 0 +static const uint32_t icBase[5] = { + INTCON0_BASE, INTCON1_BASE, INTCON2_BASE, INTCON3_BASE, INTCON4_BASE }; + +/* a bitmap of the level triggered interrupt vectors */ +static uint32_t level_trigger[5] = { + 0xb3fefe8f, // level 1 0-31 + 0xfdb3c1fd, // level 2 0-31 + 0xfffff7ff, // level 2 32-63 + 0xbfffffff, // level 2 64-95 + 0xffffffff // level 2 96-128 +}; + +inline volatile uint32_t *ICReg(uint controller, uint reg) +{ + return (volatile uint32_t *)(icBase[controller] + reg); +} + +inline uint32_t readICReg(uint controller, uint reg) +{ + return *ICReg(controller, reg); +} +inline void writeICReg(uint controller, uint reg, uint val) +{ + *ICReg(controller, reg) = val; +} + +inline uint vectorToController(uint vector) +{ + return vector / 32; +} +#endif + +void platform_init_interrupts(void) +{ +#if 0 + unsigned int i; + + // mask all interrupts + *ICReg(0, INTCON_MIR) = 0xfffffffa; + *ICReg(1, INTCON_MIR) = 0xffffffff; + *ICReg(2, INTCON_MIR) = 0xffffffff; + *ICReg(3, INTCON_MIR) = 0xffffffff; + *ICReg(4, INTCON_MIR) = 0xffffffff; + + // set up each of the interrupts + for (i = 0; i < INT_VECTORS; i++) { + // set each vector up as high priority, IRQ, and default edge/level sensitivity + *ICReg(i / 32, INTCON_ILR_BASE + 4*(i%32)) = ((level_trigger[i/32] & (1<<(i%32))) ? (1<<1) : (0<<1)) | 0; + } + + // clear any pending interrupts + *ICReg(0, INTCON_ITR) = 0; + *ICReg(1, INTCON_ITR) = 0; + *ICReg(2, INTCON_ITR) = 0; + *ICReg(3, INTCON_ITR) = 0; + *ICReg(4, INTCON_ITR) = 0; + + // globally unmask interrupts + *ICReg(1, INTCON_CONTROL) = 3; + *ICReg(0, INTCON_CONTROL) = 3; + *ICReg(0, INTCON_GMR) = 0; + + dprintf("end of platform_init_interrupts\n"); + +#if 0 + arch_enable_ints(); + + dprintf("&ITR0 0x%x\n", (uint32_t)ICReg(0, INTCON_ITR)); + + dprintf("ITR0 0x%x\n", *ICReg(0, INTCON_ITR)); + dprintf("MIR0 0x%x\n", *ICReg(0, INTCON_MIR)); + dprintf("SIR_IRQ0 0x%x\n", *ICReg(0, INTCON_SIR_IRQ)); + + *ICReg(0, INTCON_ILR_BASE + 4*7) = 0; + *ICReg(0, INTCON_MIR) &= ~0x80; + + dprintf("triggering int\n"); + + *ICReg(0, INTCON_SISR) = 0x80; + + dprintf("ITR0 0x%x\n", *ICReg(0, INTCON_ITR)); + dprintf("MIR0 0x%x\n", *ICReg(0, INTCON_MIR)); + dprintf("SIR_IRQ0 0x%x\n", *ICReg(0, INTCON_SIR_IRQ)); + + for(;;); +#endif +#endif +} + +status_t mask_interrupt(unsigned int vector) +{ +#if 0 + if (vector >= INT_VECTORS) + return ERR_INVALID_ARGS; + +// dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector); + + enter_critical_section(); + + if (oldstate) + *oldstate = false; + + volatile uint32_t *mir = ICReg(vectorToController(vector), INTCON_MIR); + *mir = *mir | (1<<(vector % 32)); + + exit_critical_section(); +#endif + + return NO_ERROR; +} + +status_t unmask_interrupt(unsigned int vector) +{ +#if 0 + if (vector >= INT_VECTORS) + return ERR_INVALID_ARGS; + +// dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector); + + enter_critical_section(); + + if (oldstate) + *oldstate = false; + + volatile uint32_t *mir = ICReg(vectorToController(vector), INTCON_MIR); + *mir = *mir & ~(1<<(vector % 32)); + + exit_critical_section(); +#endif + + return NO_ERROR; +} + +void platform_irq(struct arm_iframe *frame) +{ + PANIC_UNIMPLEMENTED; +#if 0 + // get the current vector + unsigned int vector; + + inc_critical_section(); + + // read from the first level int handler + vector = *ICReg(0, INTCON_SIR_IRQ); + + // see if it's coming from the second level handler + if (vector == 0) { + vector = *ICReg(1, INTCON_SIR_IRQ) + 32; + } + +// dprintf("platform_irq: spsr 0x%x, pc 0x%x, currthread %p, vector %d\n", frame->spsr, frame->pc, current_thread, vector); + + // deliver the interrupt + enum handler_return ret; + + ret = INT_NO_RESCHEDULE; + if (int_handler_table[vector].handler) + ret = int_handler_table[vector].handler(int_handler_table[vector].arg); + + // ack the interrupt + if (vector >= 32) { + // interrupt is chained, so ack the second level first, and then the first + *ICReg(vector / 32, INTCON_ITR) = ~(1 << (vector % 32)); + *ICReg(1, INTCON_CONTROL) |= 1; + vector = 0; // force the following code to ack the chained first level vector + } + + *ICReg(0, INTCON_ITR) = ~(1 << vector); + *ICReg(0, INTCON_CONTROL) = 1; + + if (ret == INT_RESCHEDULE) + thread_preempt(); + + dec_critical_section(); + +// dprintf("platform_irq: exit\n"); +#endif +} + +void platform_fiq(struct arm_iframe *frame) +{ + PANIC_UNIMPLEMENTED; +} + +void register_int_handler(unsigned int vector, int_handler handler, void *arg) +{ + if (vector >= INT_VECTORS) + panic("register_int_handler: vector out of range %d\n", vector); + + enter_critical_section(); + + int_handler_table[vector].handler = handler; + int_handler_table[vector].arg = arg; + + exit_critical_section(); +} + diff --git a/lk/platform/integrator/platform.c b/lk/platform/integrator/platform.c new file mode 100644 index 0000000..5b31242 --- /dev/null +++ b/lk/platform/integrator/platform.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 "platform_p.h" +#include +#include + +void platform_init_mmu_mappings(void) +{ +} + +void platform_early_init(void) +{ +#if 0 + /* do some memory map initialization */ + addr_t addr; + arm_mmu_map_section(SDRAM_BASE, 0, MMU_FLAG_CACHED|MMU_FLAG_BUFFERED); + for (addr = SDRAM_BASE; addr < SDRAM_BASE + SDRAM_SIZE; addr += (1024*1024)) { + arm_mmu_map_section(addr, addr, MMU_FLAG_CACHED|MMU_FLAG_BUFFERED|MMU_FLAG_READWRITE); + } + + /* initialize the interrupt controller */ + platform_init_interrupts(); + + /* initialize the timer block */ + platform_init_timer(); +#endif +} + +void platform_init(void) +{ +} + diff --git a/lk/platform/integrator/platform_p.h b/lk/platform/integrator/platform_p.h new file mode 100644 index 0000000..872ea2b --- /dev/null +++ b/lk/platform/integrator/platform_p.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __PLATFORM_P_H +#define __PLATFORM_P_H + +void platform_init_interrupts(void); +void platform_init_timer(void); + +#endif + diff --git a/lk/platform/integrator/rules.mk b/lk/platform/integrator/rules.mk new file mode 100644 index 0000000..a189153 --- /dev/null +++ b/lk/platform/integrator/rules.mk @@ -0,0 +1,26 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +ARCH := arm +ARM_CPU := arm926ej-s +CPU := generic + +INCLUDES += \ + -I$(LOCAL_DIR)/include + +OBJS += \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/platform.o \ + $(LOCAL_DIR)/interrupts.o \ + $(LOCAL_DIR)/timer.o \ + +# $(LOCAL_DIR)/net.o \ + + +# $(LOCAL_DIR)/console.o \ + +MEMBASE ?= 0x0 +MEMSIZE ?= 0x08000000 # 128MB + +LINKER_SCRIPT += \ + $(BUILDDIR)/system-onesegment.ld + diff --git a/lk/platform/integrator/timer.c b/lk/platform/integrator/timer.c new file mode 100644 index 0000000..55d14de --- /dev/null +++ b/lk/platform/integrator/timer.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include +#include "platform_p.h" + +static time_t system_time = 0; + +static time_t tick_interval; +static uint32_t ticks_per_interval; +static platform_timer_callback t_callback; +static void *callback_arg; + +status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, time_t interval) +{ +#if 0 + enter_critical_section(); + + t_callback = callback; + callback_arg = arg; + tick_interval = interval; + ticks_per_interval = interval * 32768 / 1000; // interval is in ms + + OS_TIMER_CTRL_REG = 0; // stop it + OS_TIMER_TICK_VALUE_REG = ticks_per_interval; + OS_TIMER_CTRL_REG = (1<<3) | (1<<2) | (1<<1) | (1<<0); + + exit_critical_section(); +#endif + + return NO_ERROR; +} + +time_t current_time(void) +{ +#if 0 + time_t t; + uint32_t delta_ticks; + uint32_t delta_ticks2; + +retry: + delta_ticks = OS_TIMER_TICK_COUNTER_REG; + t = system_time; + delta_ticks2 = OS_TIMER_TICK_COUNTER_REG; + if (delta_ticks2 > delta_ticks) + goto retry; + + t += ((ticks_per_interval - delta_ticks2) * tick_interval) / ticks_per_interval; + + return t; +#else + static time_t time = 0; + return time++; +#endif + +} + +static enum handler_return os_timer_tick(void *arg) +{ + system_time += tick_interval; +// dprintf("os_timer_tick %d\n", system_time); + + return t_callback(callback_arg, system_time); +} + +void platform_init_timer(void) +{ +#if 0 + OS_TIMER_CTRL_REG = 0; // stop the timer if it's already running + + register_int_handler(IRQ_OS_TIMER, &os_timer_tick, NULL); + unmask_interrupt(IRQ_OS_TIMER, NULL); +#endif +} + diff --git a/lk/platform/msm7k/acpuclock.c b/lk/platform/msm7k/acpuclock.c new file mode 100644 index 0000000..25c7ceb --- /dev/null +++ b/lk/platform/msm7k/acpuclock.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +#define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100) +#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) +#define VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) +#define PLL2_L_VAL_ADDR (MSM_CLK_CTL_BASE + 0x33C) + +#define SRC_SEL_PLL1 1 /* PLL1. */ +#define SRC_SEL_PLL2 2 /* PLL2. */ +#define SRC_SEL_PLL3 3 /* PLL3. Used for 7x25. */ +#define DIV_4 3 +#define DIV_2 1 +#define WAIT_CNT 100 +#define VDD_LEVEL 7 +#define MIN_AXI_HZ 120000000 +#define ACPU_800MHZ 41 + +void pll_request(unsigned pll, unsigned enable); +void axi_clock_init(unsigned rate); + +/* The stepping frequencies have been choosen to make sure the step + * is <= 256 MHz for both turbo mode and normal mode targets. The + * table also assumes the ACPU is running at TCXO freq and AHB div is + * set to DIV_1. + * + * To use the tables: + * - Start at location 0/1 depending on clock source sel bit. + * - Set values till end of table skipping every other entry. + * - When you reach the end of the table, you are done scaling. + * + * TODO: Need to fix SRC_SEL_PLL1 for 7x25. + */ + +uint32_t const clk_cntl_reg_val_7625[] = { + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_4, + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_4 << 8), + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_2 << 8), + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_2, + (WAIT_CNT << 16) | (SRC_SEL_PLL3 << 4) | DIV_2, + (WAIT_CNT << 16) | (SRC_SEL_PLL3 << 12) | (DIV_2 << 8), +}; + +uint32_t const clk_cntl_reg_val_7627[] = { + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_4, + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_4 << 8), + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_2 << 8), + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_2, + (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 4) | DIV_2, + (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 12) | (DIV_2 << 8), +}; + +uint32_t const clk_cntl_reg_val_7627T[] = { + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_4, + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_4 << 8), + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 12) | (DIV_2 << 8), + (WAIT_CNT << 16) | (SRC_SEL_PLL1 << 4) | DIV_2, + (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 4), + (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 12), +}; + +/* Using DIV_4 for all cases to avoid worrying about turbo vs. normal + * mode. Able to use DIV_4 for all steps because it's the largest AND + * the final value. */ +uint32_t const clk_sel_reg_val[] = { + DIV_4 << 1 | 1, + DIV_4 << 1 | 0, + DIV_4 << 1 | 0, + DIV_4 << 1 | 1, + DIV_4 << 1 | 1, + DIV_4 << 1 | 0, +}; + +void mdelay(unsigned msecs); + + +void acpu_clock_init(void) +{ + unsigned i,clk; + +#if (!ENABLE_NANDWRITE) + int *modem_stat_check = (MSM_SHARED_BASE + 0x14); + + /* Wait for modem to be ready before clock init */ + while (readl(modem_stat_check) != 1); +#endif + + /* Increase VDD level to the final value. */ + writel((1 << 7) | (VDD_LEVEL << 3), VDD_SVS_PLEVEL_ADDR); +#if (!ENABLE_NANDWRITE) + thread_sleep(1); +#else + mdelay(1); +#endif + + /* Read clock source select bit. */ + i = readl(A11S_CLK_SEL_ADDR) & 1; + clk = readl(PLL2_L_VAL_ADDR) & 0x3F; + + /* Jump into table and set every other entry. */ + for(; i < ARRAY_SIZE(clk_cntl_reg_val_7627); i += 2) { +#ifdef ENABLE_PLL3 + writel(clk_cntl_reg_val_7625[i], A11S_CLK_CNTL_ADDR); +#else + if(clk == ACPU_800MHZ) + writel(clk_cntl_reg_val_7627T[i], A11S_CLK_CNTL_ADDR); + else + writel(clk_cntl_reg_val_7627[i], A11S_CLK_CNTL_ADDR); +#endif + /* Would need a dmb() here but the whole address space is + * strongly ordered, so it should be fine. + */ + writel(clk_sel_reg_val[i], A11S_CLK_SEL_ADDR); +#if (!ENABLE_NANDWRITE) + thread_sleep(1); +#else + mdelay(1); +#endif + } +} diff --git a/lk/platform/msm7k/gpio.c b/lk/platform/msm7k/gpio.c new file mode 100644 index 0000000..8968921 --- /dev/null +++ b/lk/platform/msm7k/gpio.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2008, Google 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off)) +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off)) + +/* output value */ +#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */ +#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 42-16 */ +#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-43 */ +#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */ +#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 106-95 */ + +/* same pin map as above, output enable */ +#define GPIO_OE_0 GPIO1_REG(0x10) +#define GPIO_OE_1 GPIO2_REG(0x08) +#define GPIO_OE_2 GPIO1_REG(0x14) +#define GPIO_OE_3 GPIO1_REG(0x18) +#define GPIO_OE_4 GPIO1_REG(0x1C) + +/* same pin map as above, input read */ +#define GPIO_IN_0 GPIO1_REG(0x34) +#define GPIO_IN_1 GPIO2_REG(0x20) +#define GPIO_IN_2 GPIO1_REG(0x38) +#define GPIO_IN_3 GPIO1_REG(0x3C) +#define GPIO_IN_4 GPIO1_REG(0x40) + +/* same pin map as above, 1=edge 0=level interrup */ +#define GPIO_INT_EDGE_0 GPIO1_REG(0x60) +#define GPIO_INT_EDGE_1 GPIO2_REG(0x50) +#define GPIO_INT_EDGE_2 GPIO1_REG(0x64) +#define GPIO_INT_EDGE_3 GPIO1_REG(0x68) +#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C) + +/* same pin map as above, 1=positive 0=negative */ +#define GPIO_INT_POS_0 GPIO1_REG(0x70) +#define GPIO_INT_POS_1 GPIO2_REG(0x58) +#define GPIO_INT_POS_2 GPIO1_REG(0x74) +#define GPIO_INT_POS_3 GPIO1_REG(0x78) +#define GPIO_INT_POS_4 GPIO1_REG(0x7C) + +/* same pin map as above, interrupt enable */ +#define GPIO_INT_EN_0 GPIO1_REG(0x80) +#define GPIO_INT_EN_1 GPIO2_REG(0x60) +#define GPIO_INT_EN_2 GPIO1_REG(0x84) +#define GPIO_INT_EN_3 GPIO1_REG(0x88) +#define GPIO_INT_EN_4 GPIO1_REG(0x8C) + +/* same pin map as above, write 1 to clear interrupt */ +#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90) +#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68) +#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94) +#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98) +#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C) + +/* same pin map as above, 1=interrupt pending */ +#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0) +#define GPIO_INT_STATUS_1 GPIO2_REG(0x70) +#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4) +#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8) +#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC) + +typedef struct gpioregs gpioregs; + +struct gpioregs +{ + unsigned out; + unsigned in; + unsigned int_status; + unsigned int_clear; + unsigned int_en; + unsigned int_edge; + unsigned int_pos; + unsigned oe; +}; + +static gpioregs GPIO_REGS[] = { + { + .out = GPIO_OUT_0, + .in = GPIO_IN_0, + .int_status = GPIO_INT_STATUS_0, + .int_clear = GPIO_INT_CLEAR_0, + .int_en = GPIO_INT_EN_0, + .int_edge = GPIO_INT_EDGE_0, + .int_pos = GPIO_INT_POS_0, + .oe = GPIO_OE_0, + }, + { + .out = GPIO_OUT_1, + .in = GPIO_IN_1, + .int_status = GPIO_INT_STATUS_1, + .int_clear = GPIO_INT_CLEAR_1, + .int_en = GPIO_INT_EN_1, + .int_edge = GPIO_INT_EDGE_1, + .int_pos = GPIO_INT_POS_1, + .oe = GPIO_OE_1, + }, + { + .out = GPIO_OUT_2, + .in = GPIO_IN_2, + .int_status = GPIO_INT_STATUS_2, + .int_clear = GPIO_INT_CLEAR_2, + .int_en = GPIO_INT_EN_2, + .int_edge = GPIO_INT_EDGE_2, + .int_pos = GPIO_INT_POS_2, + .oe = GPIO_OE_2, + }, + { + .out = GPIO_OUT_3, + .in = GPIO_IN_3, + .int_status = GPIO_INT_STATUS_3, + .int_clear = GPIO_INT_CLEAR_3, + .int_en = GPIO_INT_EN_3, + .int_edge = GPIO_INT_EDGE_3, + .int_pos = GPIO_INT_POS_3, + .oe = GPIO_OE_3, + }, + { + .out = GPIO_OUT_4, + .in = GPIO_IN_4, + .int_status = GPIO_INT_STATUS_4, + .int_clear = GPIO_INT_CLEAR_4, + .int_en = GPIO_INT_EN_4, + .int_edge = GPIO_INT_EDGE_4, + .int_pos = GPIO_INT_POS_4, + .oe = GPIO_OE_4, + }, +}; + +static gpioregs *find_gpio(unsigned n, unsigned *bit) +{ + if(n > 106) + return 0; + if(n > 94) { + *bit = 1 << (n - 95); + return GPIO_REGS + 4; + } + if(n > 67) { + *bit = 1 << (n - 68); + return GPIO_REGS + 3; + } + if(n > 42) { + *bit = 1 << (n - 43); + return GPIO_REGS + 2; + } + if(n > 15) { + *bit = 1 << (n - 16); + return GPIO_REGS + 1; + } + *bit = 1 << n; + return GPIO_REGS + 0; +} + +int gpio_config(unsigned n, unsigned flags) +{ + gpioregs *r; + unsigned b; + unsigned v; + + if ((r = find_gpio(n, &b)) == 0) + return -1; + + v = readl(r->oe); + if (flags & GPIO_OUTPUT) { + writel(v | b, r->oe); + } else { + writel(v & (~b), r->oe); + } + return 0; +} + +void gpio_set(unsigned n, unsigned on) +{ + gpioregs *r; + unsigned b; + unsigned v; + + if((r = find_gpio(n, &b)) == 0) + return; + + v = readl(r->out); + if(on) { + writel(v | b, r->out); + } else { + writel(v & (~b), r->out); + } +} + +int gpio_get(unsigned n) +{ + gpioregs *r; + unsigned b; + + if((r = find_gpio(n, &b)) == 0) return 0; + + return (readl(r->in) & b) ? 1 : 0; +} + diff --git a/lk/platform/msm7k/include/platform/iomap.h b/lk/platform/msm7k/include/platform/iomap.h new file mode 100644 index 0000000..9d58c30 --- /dev/null +++ b/lk/platform/msm7k/include/platform/iomap.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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 _PLATFORM_MSM7K_IOMAP_H_ +#define _PLATFORM_MSM7K_IOMAP_H_ + +#define MSM_GPIO1_BASE 0xA9200000 +#define MSM_GPIO2_BASE 0xA9300000 + +#define MSM_UART1_BASE 0xA9A00000 +#define MSM_UART2_BASE 0xA9B00000 +#define MSM_UART3_BASE 0xA9C00000 + +#define MSM_VIC_BASE 0xC0000000 +#define MSM_GPT_BASE 0xC0100000 +#define MSM_CSR_BASE 0xC0100000 +#define MSM_CLK_CTL_BASE 0xA8600000 + +#define MSM_SHARED_BASE 0x00100000 + +#define MSM_SDC1_BASE 0xA0400000 + +#endif diff --git a/lk/platform/msm7k/include/platform/irqs.h b/lk/platform/msm7k/include/platform/irqs.h new file mode 100644 index 0000000..073af16 --- /dev/null +++ b/lk/platform/msm7k/include/platform/irqs.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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 _PLATFORM_MSM7K_IRQS_H_ +#define _PLATFORM_MSM7K_IRQS_H_ + +#define INT_A9_M2A_0 0 +#define INT_A9_M2A_1 1 +#define INT_A9_M2A_2 2 +#define INT_A9_M2A_3 3 +#define INT_A9_M2A_4 4 +#define INT_A9_M2A_5 5 +#define INT_A9_M2A_6 6 +#define INT_GP_TIMER_EXP 7 +#define INT_DEBUG_TIMER_EXP 8 +#define INT_UART1 9 +#define INT_UART2 10 +#define INT_UART3 11 +#define INT_UART1_RX 12 +#define INT_UART2_RX 13 +#define INT_UART3_RX 14 +#define INT_USB_OTG 15 +#define INT_MDDI_PRI 16 +#define INT_MDDI_EXT 17 +#define INT_MDDI_CLIENT 18 +#define INT_MDP 19 +#define INT_GRAPHICS 20 +#define INT_ADM_AARM 21 +#define INT_ADSP_A11 22 +#define INT_ADSP_A9_A11 23 +#define INT_SDC1_0 24 +#define INT_SDC1_1 25 +#define INT_SDC2_0 26 +#define INT_SDC2_1 27 +#define INT_KEYSENSE 28 +#define INT_TCHSCRN_SSBI 29 +#define INT_TCHSCRN1 30 +#define INT_TCHSCRN2 31 + +#define INT_GPIO_GROUP1 (32 + 0) +#define INT_GPIO_GROUP2 (32 + 1) +#define INT_PWB_I2C (32 + 2) +#define INT_NAND_WR_ER_DONE (32 + 3) +#define INT_NAND_OP_DONE (32 + 4) +#define INT_SOFTRESET (32 + 5) +#define INT_PBUS_ARM11 (32 + 6) +#define INT_AXI_MPU_SMI (32 + 7) +#define INT_AXI_MPU_EBI1 (32 + 8) +#define INT_AD_HSSD (32 + 9) +#define INT_ARM11_PM (32 + 10) +#define INT_ARM11_DMA (32 + 11) +#define INT_TSIF_IRQ (32 + 12) +#define INT_UART1DM_IRQ (32 + 13) +#define INT_UART1DM_RX (32 + 14) +#define INT_USB_HS (32 + 15) +#define INT_SDC3_0 (32 + 16) +#define INT_SDC3_1 (32 + 17) +#define INT_SDC4_0 (32 + 18) +#define INT_SDC4_1 (32 + 19) +#define INT_UART2DM_RX (32 + 20) +#define INT_UART2DM_IRQ (32 + 21) + +#define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) + +#define NR_IRQS 54 + +#endif diff --git a/lk/platform/msm7k/interrupts.c b/lk/platform/msm7k/interrupts.c new file mode 100644 index 0000000..3e2ea2f --- /dev/null +++ b/lk/platform/msm7k/interrupts.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define VIC_REG(off) (MSM_VIC_BASE + (off)) + +#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_EN0 VIC_REG(0x0010) +#define VIC_INT_EN1 VIC_REG(0x0014) +#define VIC_INT_ENCLEAR0 VIC_REG(0x0020) +#define VIC_INT_ENCLEAR1 VIC_REG(0x0024) +#define VIC_INT_ENSET0 VIC_REG(0x0030) +#define VIC_INT_ENSET1 VIC_REG(0x0034) +#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */ +#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */ +#define VIC_NO_PEND_VAL VIC_REG(0x0060) +#define VIC_INT_MASTEREN VIC_REG(0x0064) /* 1: IRQ, 2: FIQ */ +#define VIC_PROTECTION VIC_REG(0x006C) /* 1: ENABLE */ +#define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */ +#define VIC_IRQ_STATUS0 VIC_REG(0x0080) +#define VIC_IRQ_STATUS1 VIC_REG(0x0084) +#define VIC_FIQ_STATUS0 VIC_REG(0x0090) +#define VIC_FIQ_STATUS1 VIC_REG(0x0094) +#define VIC_RAW_STATUS0 VIC_REG(0x00A0) +#define VIC_RAW_STATUS1 VIC_REG(0x00A4) +#define VIC_INT_CLEAR0 VIC_REG(0x00B0) +#define VIC_INT_CLEAR1 VIC_REG(0x00B4) +#define VIC_SOFTINT0 VIC_REG(0x00C0) +#define VIC_SOFTINT1 VIC_REG(0x00C4) +#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */ +#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */ +#define VIC_IRQ_VEC_WR VIC_REG(0x00D8) +#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E0) +#define VIC_IRQ_IN_STACK VIC_REG(0x00E4) +#define VIC_TEST_BUS_SEL VIC_REG(0x00E8) + +struct ihandler { + int_handler func; + void *arg; +}; + +static struct ihandler handler[NR_IRQS]; + +void platform_init_interrupts(void) +{ + writel(0xffffffff, VIC_INT_CLEAR0); + writel(0xffffffff, VIC_INT_CLEAR1); + writel(0, VIC_INT_SELECT0); + writel(0, VIC_INT_SELECT1); + writel(0xffffffff, VIC_INT_TYPE0); + writel(0xffffffff, VIC_INT_TYPE1); + writel(0, VIC_CONFIG); + writel(1, VIC_INT_MASTEREN); +} + +enum handler_return platform_irq(struct arm_iframe *frame) +{ + unsigned num; + enum handler_return ret; + num = readl(VIC_IRQ_VEC_RD); + num = readl(VIC_IRQ_VEC_PEND_RD); + if (num > NR_IRQS) + return 0; + writel(1 << (num & 31), (num > 31) ? VIC_INT_CLEAR1 : VIC_INT_CLEAR0); + ret = handler[num].func(handler[num].arg); + writel(0, VIC_IRQ_VEC_WR); + return ret; +} + +void platform_fiq(struct arm_iframe *frame) +{ + PANIC_UNIMPLEMENTED; +} + +status_t mask_interrupt(unsigned int vector) +{ + unsigned reg = (vector > 31) ? VIC_INT_ENCLEAR1 : VIC_INT_ENCLEAR0; + unsigned bit = 1 << (vector & 31); + writel(bit, reg); + return 0; +} + +status_t unmask_interrupt(unsigned int vector) +{ + unsigned reg = (vector > 31) ? VIC_INT_ENSET1 : VIC_INT_ENSET0; + unsigned bit = 1 << (vector & 31); + writel(bit, reg); + return 0; +} + +void register_int_handler(unsigned int vector, int_handler func, void *arg) +{ + if (vector >= NR_IRQS) + return; + + enter_critical_section(); + handler[vector].func = func; + handler[vector].arg = arg; + exit_critical_section(); +} + diff --git a/lk/platform/msm7k/panel.c b/lk/platform/msm7k/panel.c new file mode 100644 index 0000000..7c93c8c --- /dev/null +++ b/lk/platform/msm7k/panel.c @@ -0,0 +1,471 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#define MDDI_CLIENT_CORE_BASE 0x108000 +#define LCD_CONTROL_BLOCK_BASE 0x110000 +#define SPI_BLOCK_BASE 0x120000 +#define I2C_BLOCK_BASE 0x130000 +#define PWM_BLOCK_BASE 0x140000 +#define GPIO_BLOCK_BASE 0x150000 +#define SYSTEM_BLOCK1_BASE 0x160000 +#define SYSTEM_BLOCK2_BASE 0x170000 + + +#define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00) +#define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04) +#define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08) +#define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C) +#define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10) +#define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14) +#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18) +#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C) +#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20) +#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24) +#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28) +#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C) +#define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30) +#define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34) +#define INTMONI (MDDI_CLIENT_CORE_BASE|0x38) +#define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C) +#define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40) +#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44) +#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48) +#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C) +#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50) +#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54) + + +#define SRST (LCD_CONTROL_BLOCK_BASE|0x00) +#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04) +#define START (LCD_CONTROL_BLOCK_BASE|0x08) +#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C) +#define CMN (LCD_CONTROL_BLOCK_BASE|0x10) +#define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14) +#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18) +#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C) +#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20) +#define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24) +#define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28) + +#define PXL (LCD_CONTROL_BLOCK_BASE|0x30) +#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34) +#define HSW (LCD_CONTROL_BLOCK_BASE|0x38) +#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C) +#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40) +#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44) +#define VSW (LCD_CONTROL_BLOCK_BASE|0x48) +#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C) +#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50) +#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54) +#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58) +#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C) +#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60) +#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64) +#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68) +#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C) +#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70) +#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74) +#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78) +#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C) +#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80) +#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84) +#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88) +#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C) + +#define MONI (LCD_CONTROL_BLOCK_BASE|0xB0) + +#define Current (LCD_CONTROL_BLOCK_BASE|0xC0) +#define LCD (LCD_CONTROL_BLOCK_BASE|0xC4) +#define COMMAND (LCD_CONTROL_BLOCK_BASE|0xC8) + + +#define SSICTL (SPI_BLOCK_BASE|0x00) +#define SSITIME (SPI_BLOCK_BASE|0x04) +#define SSITX (SPI_BLOCK_BASE|0x08) +#define SSIRX (SPI_BLOCK_BASE|0x0C) +#define SSIINTC (SPI_BLOCK_BASE|0x10) +#define SSIINTS (SPI_BLOCK_BASE|0x14) +#define SSIDBG1 (SPI_BLOCK_BASE|0x18) +#define SSIDBG2 (SPI_BLOCK_BASE|0x1C) +#define SSIID (SPI_BLOCK_BASE|0x20) + + +#define I2CSETUP (I2C_BLOCK_BASE|0x00) +#define I2CCTRL (I2C_BLOCK_BASE|0x04) + + +#define TIMER0LOAD (PWM_BLOCK_BASE|0x00) +#define TIMER0VALUE (PWM_BLOCK_BASE|0x04) +#define TIMER0CONTROL (PWM_BLOCK_BASE|0x08) +#define TIMER0INTCLR (PWM_BLOCK_BASE|0x0C) +#define TIMER0RIS (PWM_BLOCK_BASE|0x10) +#define TIMER0MIS (PWM_BLOCK_BASE|0x14) +#define TIMER0BGLOAD (PWM_BLOCK_BASE|0x18) +#define PWM0OFF (PWM_BLOCK_BASE|0x1C) +#define TIMER1LOAD (PWM_BLOCK_BASE|0x20) +#define TIMER1VALUE (PWM_BLOCK_BASE|0x24) +#define TIMER1CONTROL (PWM_BLOCK_BASE|0x28) +#define TIMER1INTCLR (PWM_BLOCK_BASE|0x2C) +#define TIMER1RIS (PWM_BLOCK_BASE|0x30) +#define TIMER1MIS (PWM_BLOCK_BASE|0x34) +#define TIMER1BGLOAD (PWM_BLOCK_BASE|0x38) +#define PWM1OFF (PWM_BLOCK_BASE|0x3C) +#define TIMERITCR (PWM_BLOCK_BASE|0x60) +#define TIMERITOP (PWM_BLOCK_BASE|0x64) +#define PWMCR (PWM_BLOCK_BASE|0x68) +#define PWMID (PWM_BLOCK_BASE|0x6C) +#define PWMMON (PWM_BLOCK_BASE|0x70) + + +#define GPIODATA (GPIO_BLOCK_BASE|0x00) +#define GPIODIR (GPIO_BLOCK_BASE|0x04) +#define GPIOIS (GPIO_BLOCK_BASE|0x08) +#define GPIOIBE (GPIO_BLOCK_BASE|0x0C) +#define GPIOIEV (GPIO_BLOCK_BASE|0x10) +#define GPIOIE (GPIO_BLOCK_BASE|0x14) +#define GPIORIS (GPIO_BLOCK_BASE|0x18) +#define GPIOMIS (GPIO_BLOCK_BASE|0x1C) +#define GPIOIC (GPIO_BLOCK_BASE|0x20) +#define GPIOOMS (GPIO_BLOCK_BASE|0x24) +#define GPIOPC (GPIO_BLOCK_BASE|0x28) + +#define GPIOID (GPIO_BLOCK_BASE|0x30) + + +#define WKREQ (SYSTEM_BLOCK1_BASE|0x00) +#define CLKENB (SYSTEM_BLOCK1_BASE|0x04) +#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08) +#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C) +#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00) + +struct init_table { + unsigned int reg; + unsigned int val; +}; + +static struct init_table toshiba_480x640_init_table[] = { + { DPSET0, 0x4BEC0066 }, // # MDC.DPSET0 # Setup DPLL parameters + { DPSET1, 0x00000113 }, // # MDC.DPSET1 + { DPSUS, 0x00000000 }, // # MDC.DPSUS # Set DPLL oscillation enable + { DPRUN, 0x00000001 }, // # MDC.DPRUN # Release reset signal for DPLL + { 0, 14 }, // wait_ms(14); + { SYSCKENA, 0x00000001 }, // # MDC.SYSCKENA # Enable system clock output + { CLKENB, 0x000000EF }, // # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) + { GPIO_BLOCK_BASE, 0x03FF0000 }, // # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 + { GPIODIR, 0x0000024D }, // # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) + { SYSTEM_BLOCK2_BASE, 0x00000173 }, // # SYS.GPIOSEL # GPIO port multiplexing control + { GPIOPC, 0x03C300C0 }, // # GPI .GPIOPC # GPIO2,3 PD cut + { SYSTEM_BLOCK1_BASE, 0x00000000 }, // # SYS.WKREQ # Wake-up request event is VSYNC alignment + { GPIOIS, 0x00000000 }, // # GPI .GPIOIS # Set interrupt sense of GPIO + { GPIOIEV, 0x00000001 }, // # GPI .GPIOIEV # Set interrupt event of GPIO + { GPIOIC, 0x000003FF }, // # GPI .GPIOIC # GPIO interrupt clear + { GPIO_BLOCK_BASE, 0x00060006 }, // # GPI .GPIODATA # Release LCDD reset + { GPIO_BLOCK_BASE, 0x00080008 }, // # GPI .GPIODATA # eDRAM VD supply + { GPIO_BLOCK_BASE, 0x02000200 }, // # GPI .GPIODATA # TEST LED ON + { DRAMPWR, 0x00000001 }, // # SYS.DRAMPWR # eDRAM power up + { TIMER0CONTROL, 0x00000060 }, // # PWM.Timer0Control # PWM0 output stop + { PWM_BLOCK_BASE, 0x00001388 }, // # PWM.Timer0Load # PWM0 10kHz , Duty 99 (BackLight OFF) + //{PWM0OFF, 0x00000001 }, // # PWM.PWM0OFF +#if 0 + { PWM0OFF, 0x00001387 }, // SURF 100% backlight + { PWM0OFF, 0x00000000 }, // FFA 100% backlight +#endif + { PWM0OFF, 0x000009C3 }, // 50% BL + { TIMER1CONTROL, 0x00000060 }, // # PWM.Timer1Control # PWM1 output stop + { TIMER1LOAD, 0x00001388 }, // # PWM.Timer1Load # PWM1 10kHz , Duty 99 (BackLight OFF) + //{PWM1OFF, 0x00000001 }, // # PWM.PWM1OFF + { PWM1OFF, 0x00001387 }, + { TIMER0CONTROL, 0x000000E0 }, // # PWM.Timer0Control # PWM0 output start + { TIMER1CONTROL, 0x000000E0 }, // # PWM.Timer1Control # PWM1 output start + { PWMCR, 0x00000003 }, // # PWM.PWMCR # PWM output enable + { 0, 1 }, // wait_ms(1); + { SPI_BLOCK_BASE, 0x00000799 }, // # SPI .SSICTL # SPI operation mode setting + { SSITIME, 0x00000100 }, // # SPI .SSITIME # SPI serial interface timing setting + { SPI_BLOCK_BASE, 0x0000079b }, // # SPI .SSICTL # Set SPI active mode + + { SSITX, 0x00000000 }, // # SPI.SSITX # Release from Deep Stanby mode + { 0, 1 }, // wait_ms(1); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 1 }, // wait_ms(1); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 1 }, // wait_ms(1); + { SSITX, 0x000800BA }, // # SPI.SSITX *NOTE 1 # Command setting of SPI block + { SSITX, 0x00000111 }, // # Display mode setup(1) : Normaly Black + { SSITX, 0x00080036 }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Memory access control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BB }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Display mode setup(2) + { SSITX, 0x0008003A }, // # Command setting of SPI block + { SSITX, 0x00000160 }, // # RGB Interface data format + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BF }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Drivnig method + { SSITX, 0x000800B1 }, // # Command setting of SPI block + { SSITX, 0x0000015D }, // # Booster operation setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B2 }, // # Command setting of SPI block + { SSITX, 0x00000133 }, // # Booster mode setup + { SSITX, 0x000800B3 }, // # Command setting of SPI block + { SSITX, 0x00000122 }, // # Booster frequencies setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B4 }, // # Command setting of SPI block + { SSITX, 0x00000102 }, // # OP-amp capability/System clock freq. division setup + { SSITX, 0x000800B5 }, // # Command setting of SPI block + { SSITX, 0x0000011F }, // # VCS Voltage adjustment (1C->1F for Rev 2) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B6 }, // # Command setting of SPI block + { SSITX, 0x00000128 }, // # VCOM Voltage adjustment + { SSITX, 0x000800B7 }, // # Command setting of SPI block + { SSITX, 0x00000103 }, // # Configure an external display signal + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B9 }, // # Command setting of SPI block + { SSITX, 0x00000120 }, // # DCCK/DCEV timing setup + { SSITX, 0x000800BD }, // # Command setting of SPI block + { SSITX, 0x00000102 }, // # ASW signal control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BE }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Dummy display (white/black) count setup for QUAD Data operation + { SSITX, 0x000800C0 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (A) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C1 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (B) + { SSITX, 0x000800C2 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (C) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C3 }, // # Command setting of SPI block + { SSITX, 0x0008010A }, // # wait_ms(-in line clock count setup (D) + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C4 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # Seep-in line clock count setup (E) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C5 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # wait_ms(-in line clock count setup (F) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C6 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # wait_ms(-in line clock setup (G) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C7 }, // # Command setting of SPI block + { SSITX, 0x00080133 }, // # Gamma 1 fine tuning (1) + { SSITX, 0x00000143 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C8 }, // # Command setting of SPI block + { SSITX, 0x00000144 }, // # Gamma 1 fine tuning (2) + { SSITX, 0x000800C9 }, // # Command setting of SPI block + { SSITX, 0x00000133 }, // # Gamma 1 inclination adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CA }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Gamma 1 blue offset adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800EC }, // # Command setting of SPI block + { SSITX, 0x00080102 }, // # Total number of horizontal clock cycles (1) [PCLK Sync. VGA setting] + { SSITX, 0x00000118 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CF }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Blanking period control (1) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D0 }, // # Command setting of SPI block + { SSITX, 0x00080110 }, // # Blanking period control (2) [PCLK Sync. Table1 for VGA] + { SSITX, 0x00000104 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D1 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # CKV timing control on/off [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D2 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV1,2 timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000013A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D3 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # OEV timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000013A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D4 }, // # Command setting of SPI block + { SSITX, 0x00080124 }, // # ASW timing control (1) [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000016E }, // + { 0, 1 }, // wait_ms(1); // # Wait SPI fifo empty + { SSITX, 0x000800D5 }, // # Command setting of SPI block + { SSITX, 0x00000124 }, // # ASW timing control (2) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800ED }, // # Command setting of SPI block + { SSITX, 0x00080101 }, // # Total number of horizontal clock cycles (2) [PCLK Sync. Table1 for QVGA ] + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D6 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Blanking period control (1) [PCLK Sync. Table2 for QVGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D7 }, // # Command setting of SPI block + { SSITX, 0x00080110 }, // # Blanking period control (2) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D8 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # CKV timing control on/off [PCLK Sync. Table2 for QVGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D9 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV1,2 timing control [PCLK Sync. Table2 for QVGA] + { SSITX, 0x00000114 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800DE }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # OEV timing control [PCLK Sync. Table2 for QVGA] + { SSITX, 0x00000114 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800DF }, // # Command setting of SPI block + { SSITX, 0x00080112 }, // # ASW timing control (1) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x0000013F }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E0 }, // # Command setting of SPI block + { SSITX, 0x0000010B }, // # ASW timing control (2) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x000800E2 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Built-in oscillator frequency division setup [Frequency division ratio : 2 (60Hq) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E3 }, // # Command setting of SPI block + { SSITX, 0x00000136 }, // # Built-in oscillator clock count setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E4 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV timing control for using build-in osc + { SSITX, 0x00000103 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E5 }, // # Command setting of SPI block + { SSITX, 0x00080102 }, // # OEV timing control for using build-in osc + { SSITX, 0x00000104 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E6 }, // # Command setting of SPI block + { SSITX, 0x00000103 }, // # DCEV timing control for using build-in osc + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E7 }, // # Command setting of SPI block + { SSITX, 0x00080104 }, // # ASW timing setup for using build-in osc(1) + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E8 }, // # Command setting of SPI block + { SSITX, 0x00000104 }, // # ASW timing setup for using build-in osc(2) + + + { CLKENB, 0x000001EF }, // # SYS.CLKENB # DCLK enable + { START, 0x00000000 }, // # LCD.START # LCDC wait_ms( mode + { WRSTB, 0x0000003F }, // # LCD.WRSTB # write_client_reg( strobe + { RDSTB, 0x00000432 }, // # LCD.RDSTB # Read strobe + { PORT_ENB, 0x00000002 }, // # LCD.PORT_ENB # Asynchronous port enable + { VSYNIF, 0x00000000 }, // # LCD.VSYNCIF # VSYNC I/F mode set + { ASY_DATA, 0x80000000 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00000001 }, // # Oscillator start + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + { 0, 10 }, // wait_ms(10); + { ASY_DATA, 0x80000000 }, // # LCD.ASY_DATx # DUMMY write_client_reg(@*NOTE2 + { ASY_DATB, 0x80000000 }, // + { ASY_DATC, 0x80000000 }, // + { ASY_DATD, 0x80000000 }, // + { ASY_CMDSET, 0x00000009 }, // # LCD.ASY_CMDSET + { ASY_CMDSET, 0x00000008 }, // # LCD.ASY_CMDSET + { ASY_DATA, 0x80000007 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00004005 }, // # LCD driver control + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + { 0, 20 }, // wait_ms(20); + { ASY_DATA, 0x80000059 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00000000 }, // # LTPS I/F control + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + + { VSYNIF, 0x00000001 }, // # LCD.VSYNCIF # VSYNC I/F mode OFF + { PORT_ENB, 0x00000001 }, // # LCD.PORT_ENB # SYNC I/F output select + + /******************************/ + + { VSYNIF, 0x00000001 }, // VSYNC I/F mode OFF + { PORT_ENB, 0x00000001 }, // SYNC I/F mode ON + + { BITMAP1, 0x01E000F0 }, // MDC.BITMAP2 ); // Setup of PITCH size to Frame buffer1 + { BITMAP2, 0x01E000F0 }, // MDC.BITMAP3 ); // Setup of PITCH size to Frame buffer2 + { BITMAP3, 0x01E000F0 }, // MDC.BITMAP4 ); // Setup of PITCH size to Frame buffer3 + { BITMAP4, 0x00DC00B0 }, // MDC.BITMAP5 ); // Setup of PITCH size to Frame buffer4 + { CLKENB, 0x000001EF }, // SYS.CLKENB ); // DCLK supply + { PORT_ENB, 0x00000001 }, // LCD.PORT_ENB ); // Synchronous port enable + { PORT, 0x00000004 }, // LCD.PORT ); // Polarity of DE is set to high active + { PXL, 0x00000002 }, // LCD.PXL ); // ACTMODE 2 set (1st frame black data output) + { MPLFBUF, 0x00000000 }, // LCD.MPLFBUF ); // Select the reading buffer + { HCYCLE, 0x0000010b }, // LCD.HCYCLE ); // Setup to VGA size + { HSW, 0x00000003 }, // LCD.HSW + { HDE_START, 0x00000007 }, // LCD.HDE_START + { HDE_SIZE, 0x000000EF }, // LCD.HDE_SIZE + { VCYCLE, 0x00000285 }, // LCD.VCYCLE + { VSW, 0x00000001 }, // LCD.VSW + { VDE_START, 0x00000003 }, // LCD.VDE_START + { VDE_SIZE, 0x0000027F }, // LCD.VDE_SIZE + + { START, 0x00000001 }, // LCD.START ); // LCDC - Pixel data transfer start + + { 0, 10 }, // wait_ms( 10 ); + { SSITX, 0x000800BC }, // SPI.SSITX ); // Command setting of SPI block + { SSITX, 0x00000180 }, // Display data setup + { SSITX, 0x0008003B }, // Command setting of SPI block + { SSITX, 0x00000100 }, // Quad Data configuration - VGA + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B0 }, // Command setting of SPI block + { SSITX, 0x00000116 }, // Power supply ON/OFF control + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B8 }, // Command setting of SPI block + { SSITX, 0x000801FF }, // Output control + { SSITX, 0x000001F5 }, + { 0, 1 }, // wait_ms( 1); // Wait SPI fifo empty + { SSITX, 0x00000011 }, // wait_ms(-out (Command only) + { SSITX, 0x00000029 }, // Display on (Command only) + + { SYSTEM_BLOCK1_BASE, 0x00000002 }, // # wakeREQ -> GPIO + + { 0, 0 } +}; + +static void _panel_init(struct init_table *init_table) +{ + unsigned n; + + dprintf(INFO, "panel_init()\n"); + + n = 0; + while (init_table[n].reg != 0 || init_table[n].val != 0) { + if (init_table[n].reg != 0) + mddi_remote_write(init_table[n].val, init_table[n].reg); + else + mdelay(init_table[n].val); + n++; + } + + dprintf(INFO, "panel_init() done\n"); +} + +void panel_init(struct mddi_client_caps *client_caps) +{ + switch(client_caps->manufacturer_name) { + case 0xd263: // Toshiba + dprintf(INFO, "Found Toshiba panel\n"); + _panel_init(toshiba_480x640_init_table); + break; + case 0x4474: //?? + if (client_caps->product_code == 0xc065) + dprintf(INFO, "Found WVGA panel\n"); + break; + } +} + +void panel_poweron(void) +{ + gpio_set(88, 0); + gpio_config(88, GPIO_OUTPUT); + udelay(10); + gpio_set(88, 1); + mdelay(10); + + //mdelay(1000); // uncomment for second stage boot +} + +void panel_backlight(int on) +{} diff --git a/lk/platform/msm7k/platform.c b/lk/platform/msm7k/platform.c new file mode 100644 index 0000000..6ce150c --- /dev/null +++ b/lk/platform/msm7k/platform.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include + +static struct fbcon_config *fb_config; + +void platform_init_interrupts(void); +void platform_init_timer(); + +void uart3_clock_init(void); +void uart_init(void); + +void acpu_clock_init(void); + +void mddi_clock_init(unsigned num, unsigned rate); + +void platform_early_init(void) +{ + //uart3_clock_init(); + //uart_init(); + + platform_init_interrupts(); + platform_init_timer(); +} + +void platform_init(void) +{ + dprintf(INFO, "platform_init()\n"); + + acpu_clock_init(); +} + +void display_init(void) +{ +#if DISPLAY_TYPE_MDDI + fb_config = mddi_init(); + ASSERT(fb_config); + fbcon_setup(fb_config); +#endif +#if DISPLAY_TYPE_LCDC + fb_config = lcdc_init(); + ASSERT(fb_config); + fbcon_setup(fb_config); +#endif +} diff --git a/lk/platform/msm7k/rules.mk b/lk/platform/msm7k/rules.mk new file mode 100644 index 0000000..b5507a3 --- /dev/null +++ b/lk/platform/msm7k/rules.mk @@ -0,0 +1,24 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +ARCH := arm +ARM_CPU := arm1136j-s +CPU := generic + +MMC_SLOT := 1 +DEFINES += MMC_SLOT=$(MMC_SLOT) + +INCLUDES += -I$(LOCAL_DIR)/include + +MODULES += dev/fbcon + +OBJS += \ + $(LOCAL_DIR)/platform.o \ + $(LOCAL_DIR)/interrupts.o \ + $(LOCAL_DIR)/gpio.o \ + $(LOCAL_DIR)/panel.o \ + $(LOCAL_DIR)/acpuclock.o + +LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld + +include platform/msm_shared/rules.mk + diff --git a/lk/platform/msm7x30/acpuclock.c b/lk/platform/msm7x30/acpuclock.c new file mode 100644 index 0000000..2fe7604 --- /dev/null +++ b/lk/platform/msm7x30/acpuclock.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2009, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#define REG_BASE(off) (MSM_CLK_CTL_BASE + (off)) +#define REG(off) (MSM_CLK_CTL_SH2_BASE + (off)) + +#define PLL_ENA_REG REG(0x0264) +#define PLL2_STATUS_BASE_REG REG_BASE(0x0350) + +#define SH2_OWN_ROW2_BASE_REG REG_BASE(0x0424) + +/* Macros to select PLL2 with divide by 1 */ +#define ACPU_SRC_SEL 3 +#define ACPU_SRC_DIV 0 + +#define BIT(n) (1 << (n)) +#define VREG_CONFIG (BIT(7) | BIT(6)) /* Enable VREG, pull-down if disabled. */ +#define VREG_DATA (VREG_CONFIG | (VREF_SEL << 5)) +#define VREF_SEL 1 /* 0: 0.625V (50mV step), 1: 0.3125V (25mV step). */ +#define V_STEP (25 * (2 - VREF_SEL)) /* Minimum voltage step size. */ +#define MV(mv) ((mv) / (!((mv) % V_STEP))) +/* mv = (750mV + (raw * 25mV)) * (2 - VREF_SEL) */ +#define VDD_RAW(mv) (((MV(mv) / V_STEP) - 30) | VREG_DATA) + +void spm_init(void) +{ + writel(0x05, MSM_SAW_BASE + 0x10); /* MSM_SPM_REG_SAW_CFG */ + writel(0x18, MSM_SAW_BASE + 0x14); /* MSM_SPM_REG_SAW_SPM_CTL */ + writel(0x00006666, MSM_SAW_BASE + 0x18); /* MSM_SPM_REG_SAW_SPM_SLP_TMR_DLY */ + writel(0xFF000666, MSM_SAW_BASE + 0x1C); /* MSM_SPM_REG_SAW_SPM_WAKE_TMR_DLY */ + + writel(0x01, MSM_SAW_BASE + 0x24); /* MSM_SPM_REG_SAW_SLP_CLK_EN */ + writel(0x03, MSM_SAW_BASE + 0x28); /* MSM_SPM_REG_SAW_SLP_HSFS_PRECLMP_EN */ + writel(0x00, MSM_SAW_BASE + 0x2C); /* MSM_SPM_REG_SAW_SLP_HSFS_POSTCLMP_EN */ + + writel(0x01, MSM_SAW_BASE + 0x30); /* MSM_SPM_REG_SAW_SLP_CLMP_EN */ + writel(0x00, MSM_SAW_BASE + 0x34); /* MSM_SPM_REG_SAW_SLP_RST_EN */ + writel(0x00, MSM_SAW_BASE + 0x38); /* MSM_SPM_REG_SAW_SPM_MPM_CFG */ +} + +/* Configures msmc2 voltage. vlevel is in mV */ +void msmc2_config(unsigned vlevel) +{ + unsigned val; + val = readl(MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */ + val &= ~0xFF; + val |= VDD_RAW(vlevel); + writel(val, MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */ + + /* Wait for PMIC state to return to idle and for VDD to stabilize */ + while(((readl(MSM_SAW_BASE + 0x0C) >> 0x20) & 0x3) != 0); + udelay(160); +} + +void enable_pll(unsigned num) +{ + unsigned reg_val; + reg_val = readl(PLL_ENA_REG); + reg_val |= (1 << num); + writel(reg_val, PLL_ENA_REG); + /* Wait until PLL is enabled */ + while ((readl(PLL2_STATUS_BASE_REG) & (1 << 16)) == 0); +} + +void acpu_clock_init(void) +{ + unsigned reg_clksel, reg_clkctl, src_sel; + /* Fixing msmc2 voltage */ + spm_init(); + msmc2_config(1200); /* Setting msmc2 1.2V */ + + /* Enable pll 2 */ + enable_pll(2); + + reg_clksel = readl(SCSS_CLK_SEL); + + /* CLK_SEL_SRC1NO */ + src_sel = reg_clksel & 1; + + /* Program clock source and divider. */ + reg_clkctl = readl(SCSS_CLK_CTL); + reg_clkctl &= ~(0xFF << (8 * src_sel)); + reg_clkctl |= ACPU_SRC_SEL<< (4 + 8 * src_sel); + reg_clkctl |= ACPU_SRC_DIV<< (0 + 8 * src_sel); + writel(reg_clkctl, SCSS_CLK_CTL); + + /* Toggle clock source. */ + reg_clksel ^= 1; + + /* Program clock source selection. */ + writel(reg_clksel, SCSS_CLK_SEL); +} + +void hsusb_clock_init(void) +{ + int val = 0; + unsigned sh2_own_row2; + unsigned sh2_own_row2_hsusb_mask = (1 << 11); + + sh2_own_row2 = readl(SH2_OWN_ROW2_BASE_REG); + if(sh2_own_row2 & sh2_own_row2_hsusb_mask) + { + /* USB local clock control enabled */ + /* Set value in MD register */ + val = 0x5DF; + writel(val, SH2_USBH_MD_REG); + + /* Set value in NS register */ + val = 1 << 8; + val = val | readl(SH2_USBH_NS_REG); + writel(val, SH2_USBH_NS_REG); + + val = 1 << 11; + val = val | readl(SH2_USBH_NS_REG); + writel(val, SH2_USBH_NS_REG); + + val = 1 << 9; + val = val | readl(SH2_USBH_NS_REG); + writel(val, SH2_USBH_NS_REG); + + val = 1 << 13; + val = val | readl(SH2_USBH_NS_REG); + writel(val, SH2_USBH_NS_REG); + + /* Enable USBH_P_CLK */ + val = 1 << 25; + val = val | readl(SH2_GLBL_CLK_ENA_SC); + writel(val, SH2_GLBL_CLK_ENA_SC); + } + else + { + /* USB local clock control not enabled; use proc comm */ + usb_clock_init(); + } +} + +void adm_enable_clock(void) +{ + unsigned int val=0; + + /* Enable ADM_CLK */ + val = 1 << 5; + val = val | readl(SH2_GLBL_CLK_ENA_SC); + writel(val, SH2_GLBL_CLK_ENA_SC); +} diff --git a/lk/platform/msm7x30/arch_init.S b/lk/platform/msm7x30/arch_init.S new file mode 100644 index 0000000..8093152 --- /dev/null +++ b/lk/platform/msm7x30/arch_init.S @@ -0,0 +1,699 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + + +/* TODO: + * - style cleanup + * - do we need to do *all* of this at boot? + */ + +.text +.code 32 + +#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5 +#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5 + +/* + ; LVT Ring Osc counter + ; used to determine sense amp settings + ; Clobbers registers r0, r4, r5, r6, r7, r9, r10, r11 +*/ +.equ CLK_CTL_BASE, 0xA8600000 +.equ A_GLBL_CLK_ENA, 0x0000 +.equ A_PRPH_WEB_NS_REG,0x0080 +.equ A_MSM_CLK_RINGOSC,0x00D0 +.equ A_TCXO_CNT, 0x00D4 +.equ A_TCXO_CNT_DONE, 0x00D8 +.equ A_RINGOSC_CNT, 0x00DC +.equ A_MISC_CLK_CTL, 0x0108 +.equ CLK_TEST, 0xA8600114 +.equ SPSS_CSR_BASE, 0xAC100000 +.equ A_SCRINGOSC, 0x0510 + +//;; Number of TCXO cycles to count ring oscillations +.equ TCXO_CNT_VAL, 0x100 + +//; Halcyon addresses +.equ TCSR_CONF_FUSE_1, 0xAB600060 //; TCSR_CONF_FUSE_1 register +.equ TCSR_CONF_FUSE_4, 0xAB60006C //; TCSR_CONF_FUSE_4 register + +//; SCORPION_L1_ACC (1:0) Fuses bit location +.equ L1_ACC_BIT_0, 12 //;12th bit of TCSR_CONF_FUSE_4 +.equ L1_ACC_BIT_1, 13 //;13th bit of TCSR_CONF_FUSE_4 +//; SCORPION_L2_ACC (2:0) Fuses bit location +.equ L2_ACC_BIT_0, 25 //;25th bit of TCSR_CONF_FUSE_1 +.equ L2_ACC_BIT_1, 10 //;10th bit of TCSR_CONF_FUSE_4 +.equ L2_ACC_BIT_2, 11 //;11th bit of TCSR_CONF_FUSE_4 + +//; CP15: PVR2F0 values according to SCORPION_L1_ACC (1:0) +.equ PVR2F0_00, 0x00000000 +.equ PVR2F0_01, 0x04000000 +.equ PVR2F0_10, 0x08000000 +.equ PVR2F0_11, 0x0C000000 + +//; CP15: PVR2F1 values according to SCORPION_L1_ACC (1:0) +.equ PVR2F1_00, 0x00000008 +.equ PVR2F1_01, 0x00000008 +.equ PVR2F1_10, 0x00000208 +.equ PVR2F1_11, 0x00000208 + +//; CP15: PVR0F2 values according to SCORPION_L1_ACC (1:0) +.equ PVR0F2_00, 0x00000000 +.equ PVR0F2_01, 0x00000000 +.equ PVR0F2_10, 0x00000200 +.equ PVR0F2_11, 0x00000200 + +//; CP15: PVR0F0 values according to SCORPION_L1_ACC (1:0) +.equ PVR0F0_00, 0x7F000000 +.equ PVR0F0_01, 0x7F000400 +.equ PVR0F0_10, 0x7F000000 +.equ PVR0F0_11, 0x7F000400 + +//; CP15: L2VR3F1 values according to SCORPION_L2_ACC (2:0) +.equ L2VR3F1_000, 0x00FFFF60 +.equ L2VR3F1_001, 0x00FFFF40 +.equ L2VR3F1_010, 0x00FFFC60 +.equ L2VR3F1_011, 0x00FFFC40 +.equ L2VR3F1_100, 0x00FCFF60 +.equ L2VR3F1_101, 0x00FCFF40 +.equ L2VR3F1_110, 0x00FCFC60 +.equ L2VR3F1_111, 0x00FCFC40 + +.globl SET_SA +SET_SA: + + //;-------------------------------------------------------------------- + //; Fuse bits used to determine sense amp settings + //;-------------------------------------------------------------------- + + //; Reading L1_ACC + LDR r4, = 0x0 + + //; Read L1_ACC_BIT_0 + LDR r1, =TCSR_CONF_FUSE_4 + LDR r2, =L1_ACC_BIT_0 + LDR r3, [r1] + MOV r3, r3, LSR r2 + AND r3, r3, #1 + ORR r4, r3, r4 + + //; Read L1_ACC_BIT_1 + LDR r1, =TCSR_CONF_FUSE_4 + LDR r2, =L1_ACC_BIT_1 + LDR r3, [r1] + MOV r3, r3, LSR r2 + AND r3, r3, #1 + MOV r3, r3, LSL #1 + ORR r4, r3, r4 + +l1_ck_0: + //; if L1_[1:0] == 00 + LDR r5, = 0x0 + CMP r4, r5 + BNE l1_ck_1 + LDR r0, =PVR0F0_00 + LDR r1, =PVR0F2_00 + LDR r2, =PVR2F0_00 + LDR r3, =PVR2F1_00 + B WRITE_L1_SA_SETTINGS + +l1_ck_1: + //; if L1_[1:0] == 01 + LDR r1, = 0x01 + CMP r4, r1 + BNE l1_ck_2 + LDR r0, =PVR0F0_01 + LDR r1, =PVR0F2_01 + LDR r2, =PVR2F0_01 + LDR r3, =PVR2F1_01 + B WRITE_L1_SA_SETTINGS + +l1_ck_2: + //; if L1_[2:0] == 10 + LDR r1, = 0x02 + CMP r4, r1 + BNE l1_ck_3 + LDR r0, =PVR0F0_10 + LDR r1, =PVR0F2_10 + LDR r2, =PVR2F0_10 + LDR r3, =PVR2F1_10 + B WRITE_L1_SA_SETTINGS + +l1_ck_3: + //; if L1_[2:0] == 11 + LDR r1, = 0x03 + CMP r4, r1 + LDR r0, =PVR0F0_11 + LDR r1, =PVR0F2_11 + LDR r2, =PVR2F0_11 + LDR r3, =PVR2F1_11 + B WRITE_L1_SA_SETTINGS + + +WRITE_L1_SA_SETTINGS: + + //;WCP15_PVR0F0 r0 + MCR p15, 0x0, r0, c15, c15, 0x0 //; write R0 to PVR0F0 + + //;WCP15_PVR0F2 r1 + MCR p15, 0x0, r1, c15, c15, 0x2 //; write R1 to PVR0F2 + + //;WCP15_PVR2F0 r2 + MCR p15, 0x2, r2, c15, c15, 0x0 //; write R2 to PVR2F0 + + // Disable predecode repair cache on certain Scorpion revisions + // (Raptor V2 and earlier, or Halcyon V1) + MRC p15, 0, r1, c0, c0, 0 //; MIDR + BIC r2, r1, #0xf0 //; check for Halcyon V1 + LDR r4, =0x511f0000 + CMP r2, r4 + BNE PVR2F1 + +DPRC: + MRC p15, 0, r1, c15, c15, 2 //; PVR0F2 + ORR r1, r1, #0x10 //; enable bit 4 + MCR p15, 0, r1, c15, c15, 2 //; disable predecode repair cache + +PVR2F1: + //;WCP15_PVR2F1 r3 + MCR p15, 0x2, r3, c15, c15, 0x1 //; write R3 to PVR2F1 + + //; Reading L2_ACC + LDR r4, = 0x0 + + //; Read L2_ACC_BIT_0 + LDR r1, =TCSR_CONF_FUSE_1 + LDR r2, =L2_ACC_BIT_0 + LDR r3, [r1] + MOV r3, r3, LSR r2 + AND r3, r3, #1 + ORR r4, r3, r4 + + //; Read L2_ACC_BIT_1 + LDR r1, =TCSR_CONF_FUSE_4 + LDR r2, =L2_ACC_BIT_1 + LDR r3, [r1] + MOV r3, r3, LSR r2 + AND r3, r3, #1 + MOV r3, r3, LSL #1 + ORR r4, r3, r4 + + //; Read L2_ACC_BIT_2 + LDR r1, =TCSR_CONF_FUSE_4 + LDR r2, =L2_ACC_BIT_2 + LDR r3, [r1] + MOV r3, r3, LSR r2 + AND r3, r3, #1 + MOV r3, r3, LSL #2 + ORR r4, r3, r4 + +l2_ck_0: + //; if L2_[2:0] == 000 + LDR r5, = 0x0 + CMP r4, r5 + BNE l2_ck_1 + LDR r0, =L2VR3F1_000 + B WRITE_L2_SA_SETTINGS + +l2_ck_1: + //; if L2_[2:0] == 001 + LDR r5, = 0x1 + CMP r4, r5 + BNE l2_ck_2 + LDR r0, =L2VR3F1_001 + B WRITE_L2_SA_SETTINGS + +l2_ck_2: + //; if L2_[2:0] == 010 + LDR r5, = 0x2 + CMP r4, r5 + BNE l2_ck_3 + LDR r0, =L2VR3F1_010 + B WRITE_L2_SA_SETTINGS + +l2_ck_3: + //; if L2_[2:0] == 011 + LDR r5, = 0x3 + CMP r4, r5 + BNE l2_ck_4 + LDR r0, =L2VR3F1_011 + B WRITE_L2_SA_SETTINGS + +l2_ck_4: + //; if L2_[2:0] == 100 + LDR r5, = 0x4 + CMP r4, r5 + BNE l2_ck_5 + LDR r0, =L2VR3F1_100 + B WRITE_L2_SA_SETTINGS + +l2_ck_5: + //; if L2_[2:0] == 101 + LDR r5, = 0x5 + CMP r4, r5 + BNE l2_ck_6 + LDR r0, =L2VR3F1_101 + B WRITE_L2_SA_SETTINGS + +l2_ck_6: + //; if L2_[2:0] == 110 + LDR r5, = 0x6 + CMP r4, r5 + BNE l2_ck_7 + LDR r0, =L2VR3F1_110 + B WRITE_L2_SA_SETTINGS + +l2_ck_7: + //; if L2_[2:0] == 111 + LDR r5, = 0x7 + CMP r4, r5 + LDR r0, =L2VR3F1_111 + B WRITE_L2_SA_SETTINGS + +WRITE_L2_SA_SETTINGS: + //;WCP15_L2VR3F1 r0 + MCR p15, 0x3, r0, c15, c15, 0x1 //;write r0 to L2VR3F1 + DSB + ISB + + LDR r0, =0 //;make sure the registers we touched + LDR r1, =0 //;are cleared when we return + LDR r2, =0 + LDR r3, =0 + LDR r4, =0 + LDR r5, =0 + + //; routine complete + B _cpu_early_init_complete + +.ltorg + + +.globl __cpu_early_init +__cpu_early_init: + //; Zero out r0 for use throughout this code. All other GPRs + //; (r1-r3) are set throughout this code to help establish + //; a consistent startup state for any code that follows. + //; Users should add code at the end of this routine to establish + //; their own stack address (r13), add translation page tables, enable + //; the caches, etc. + MOV r0, #0x0 + + + //; Remove hardcoded cache settings. appsbl_handler.s calls Set_SA + //; API to dynamically configure cache for slow/nominal/fast parts + + //; DCIALL to invalidate L2 cache bank (needs to be run 4 times, once per bank) + //; This must be done early in code (prior to enabling the caches) + MOV r1, #0x2 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank D ([15:14] == 2'b00) + ORR r1, r1, #0x00004000 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank C ([15:14] == 2'b01) + ADD r1, r1, #0x00004000 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank B ([15:14] == 2'b10) + ADD r1, r1, #0x00004000 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank A ([15:14] == 2'b11) + + //; Initialize the BPCR - setup Global History Mask (GHRM) to all 1's + //; and have all address bits (AM) participate. + //; Different settings can be used to improve performance + // MOVW r1, #0x01FF +.word 0xe30011ff // hardcoded MOVW instruction due to lack of compiler support + // MOVT r1, #0x01FF +.word 0xe34011ff // hardcoded MOVT instruction due to lack of compiler support + MCR p15, 7, r1, c15, c0, 2 //; WCP15_BPCR + + + //; Initialize all I$ Victim Registers to 0 for startup + MCR p15, 0, r0, c9, c1, 0 //; WCP15_ICVIC0 r0 + MCR p15, 0, r0, c9, c1, 1 //; WCP15_ICVIC1 r0 + MCR p15, 0, r0, c9, c1, 2 //; WCP15_ICVIC2 r0 + MCR p15, 0, r0, c9, c1, 3 //; WCP15_ICVIC3 r0 + MCR p15, 0, r0, c9, c1, 4 //; WCP15_ICVIC4 r0 + MCR p15, 0, r0, c9, c1, 5 //; WCP15_ICVIC5 r0 + MCR p15, 0, r0, c9, c1, 6 //; WCP15_ICVIC5 r0 + MCR p15, 0, r0, c9, c1, 7 //; WCP15_ICVIC7 r0 + + //; Initialize all I$ Locked Victim Registers (Unlocked Floors) to 0 + MCR p15, 1, r0, c9, c1, 0 //; WCP15_ICFLOOR0 r0 + MCR p15, 1, r0, c9, c1, 1 //; WCP15_ICFLOOR1 r0 + MCR p15, 1, r0, c9, c1, 2 //; WCP15_ICFLOOR2 r0 + MCR p15, 1, r0, c9, c1, 3 //; WCP15_ICFLOOR3 r0 + MCR p15, 1, r0, c9, c1, 4 //; WCP15_ICFLOOR4 r0 + MCR p15, 1, r0, c9, c1, 5 //; WCP15_ICFLOOR5 r0 + MCR p15, 1, r0, c9, c1, 6 //; WCP15_ICFLOOR6 r0 + MCR p15, 1, r0, c9, c1, 7 //; WCP15_ICFLOOR7 r0 + + //; Initialize all D$ Victim Registers to 0 + MCR p15, 2, r0, c9, c1, 0 //; WP15_DCVIC0 r0 + MCR p15, 2, r0, c9, c1, 1 //; WP15_DCVIC1 r0 + MCR p15, 2, r0, c9, c1, 2 //; WP15_DCVIC2 r0 + MCR p15, 2, r0, c9, c1, 3 //; WP15_DCVIC3 r0 + MCR p15, 2, r0, c9, c1, 4 //; WP15_DCVIC4 r0 + MCR p15, 2, r0, c9, c1, 5 //; WP15_DCVIC5 r0 + MCR p15, 2, r0, c9, c1, 6 //; WP15_DCVIC6 r0 + MCR p15, 2, r0, c9, c1, 7 //; WP15_DCVIC7 r0 + + //; Initialize all D$ Locked VDCtim Registers (Unlocked Floors) to 0 + MCR p15, 3, r0, c9, c1, 0 //; WCP15_DCFLOOR0 r0 + MCR p15, 3, r0, c9, c1, 1 //; WCP15_DCFLOOR1 r0 + MCR p15, 3, r0, c9, c1, 2 //; WCP15_DCFLOOR2 r0 + MCR p15, 3, r0, c9, c1, 3 //; WCP15_DCFLOOR3 r0 + MCR p15, 3, r0, c9, c1, 4 //; WCP15_DCFLOOR4 r0 + MCR p15, 3, r0, c9, c1, 5 //; WCP15_DCFLOOR5 r0 + MCR p15, 3, r0, c9, c1, 6 //; WCP15_DCFLOOR6 r0 + MCR p15, 3, r0, c9, c1, 7 //; WCP15_DCFLOOR7 r0 + + //; Initialize ASID to zero + MCR p15, 0, r0, c13, c0, 1 //; WCP15_CONTEXTIDR r0 + + //; ICIALL to invalidate entire I-Cache + MCR p15, 0, r0, c7, c5, 0 //; ICIALLU + + //; DCIALL to invalidate entire D-Cache + MCR p15, 0, r0, c9, c0, 6 //; DCIALL r0 + + //; Initialize ADFSR to zero + MCR p15, 0, r0, c5, c1, 0 //; ADFSR r0 + + //; Initialize EFSR to zero + MCR p15, 7, r0, c15, c0, 1 //; EFSR r0 + + //; The VBAR (Vector Base Address Register) should be initialized + //; early in your code. We are setting it to zero + MCR p15, 0, r0, c12, c0, 0 //; WCP15_VBAR r0 + + //; Ensure the MCR's above have completed their operation before continuing + DSB + ISB + + //; Setup CCPR - Cache Coherency Policy Register + //; setup CCPR[L1ISHP, L2ISHP] both to 0b00 (no forcing) + //; setup CCPR[L1OSHP, L2OSHP] both to 0b10 (force non-cacheable) + MOVW r2, #0x88 + MCR p15, 0, r2, c10, c4, 2 + + //;------------------------------------------------------------------- + //; There are a number of registers that must be set prior to enabling + //; the MMU. The DCAR is one of these registers. We are setting + //; it to zero (no access) to easily detect improper setup in subsequent + //; code sequences + //;------------------------------------------------------------------- + //; Setup DACR (Domain Access Control Register) to zero + MCR p15, 0, r0, c3, c0, 0 //; WCP15_DACR r0 + + //; Setup DCLKCR to allow normal D-Cache line fills + MCR p15, 1, r0, c9, c0, 7 //; WCP15_DCLKCR r0 + + //; Setup the TLBLKCR + //; Victim = 6'b000000; Floor = 6'b000000; + //; IASIDCFG = 2'b00 (State-Machine); IALLCFG = 2'b01 (Flash); BNA = 1'b0; + MOV r1, #0x02 + MCR p15, 0, r1, c10, c1, 3 //; WCP15_TLBLKCR r1 + + //;Make sure TLBLKCR is complete before continuing + ISB + + //; Invalidate the UTLB + MCR p15, 0, r0, c8, c7, 0 //; UTLBIALL + + //; Make sure UTLB request has been presented to macro before continuing + ISB + +SYSI2: + //; setup L2CR1 to some default Instruction and data prefetching values + //; Users may want specific settings for various performance enhancements + //; In Halcyon we do not have broadcasting barriers. So we need to turn + // ; on bit 8 of L2CR1; which DBB:( Disable barrier broadcast ) + LDR r2, =0x133 + MCR p15, 3, r2, c15, c0, 3 //; WCP15_L2CR1 r0 + + + //; Enable Z bit to enable branch prediction (default is off) + MRC p15, 0, r2, c1, c0, 0 //; RCP15_SCTLR r2 + ORR r2, r2, #0x00000800 + MCR p15, 0, r2, c1, c0, 0 //; WCP15_SCTLR r2 + + //; Make sure Link stack is initialized with branch and links to sequential addresses + //; This aids in creating a predictable startup environment + BL SEQ1 +SEQ1: BL SEQ2 +SEQ2: BL SEQ3 +SEQ3: BL SEQ4 +SEQ4: BL SEQ5 +SEQ5: BL SEQ6 +SEQ6: BL SEQ7 +SEQ7: BL SEQ8 +SEQ8: + + //; REMOVE FOLLOWING THREE INSTRUCTIONS WHEN POWER COLLAPSE IS ENA + //;Make sure the DBGOSLSR[LOCK] bit is cleared to allow access to the debug registers + //; Writing anything but the "secret code" to the DBGOSLAR clears the DBGOSLSR[LOCK] bit + MCR p14, 0, r0, c1, c0, 4 //; WCP14_DBGOSLAR r0 + + + //; Read the DBGPRSR to clear the DBGPRSR[STICKYPD] + //; Any read to DBGPRSR clear the STICKYPD bit + //; ISB guarantees the read completes before attempting to + //; execute a CP14 instruction. + MRC p14, 0, r3, c1, c5, 4 //; RCP14_DBGPRSR r3 + ISB + + //; Initialize the Watchpoint Control Registers to zero (optional) + //;;; MCR p14, 0, r0, c0, c0, 7 ; WCP14_DBGWCR0 r0 + //;;; MCR p14, 0, r0, c0, c1, 7 ; WCP14_DBGWCR1 r0 + + + //;---------------------------------------------------------------------- + //; The saved Program Status Registers (SPSRs) should be setup + //; prior to any automatic mode switches. The following + //; code sets these registers up to a known state. Users will need to + //; customize these settings to meet their needs. + //;---------------------------------------------------------------------- + MOV r2, #0x1f + MOV r1, #0xd7 //;ABT mode + msr cpsr_c, r1 //;ABT mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xdb //;UND mode + msr cpsr_c, r1 //;UND mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd1 //;FIQ mode + msr cpsr_c, r1 //;FIQ mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd2 //;IRQ mode + msr cpsr_c, r1 //;IRQ mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd6 //;Monitor mode + msr cpsr_c, r1 //;Monitor mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd3 //;SVC mode + msr cpsr_c, r1 //;SVC mode + msr spsr_cxfs, r2 //;clear the spsr + + + //;---------------------------------------------------------------------- + //; Enabling Error reporting is something users may want to do at + //; some other point in time. We have chosen some default settings + //; that should be reviewed. Most of these registers come up in an + //; unpredictable state after reset. + //;---------------------------------------------------------------------- +//;Start of error and control setting + + //; setup L2CR0 with various L2/TCM control settings + //; enable out of order bus attributes and error reporting + //; this register comes up unpredictable after reset + // MOVW r1, #0x0F0F +.word 0xe3001f0f // hardcoded MOVW instruction due to lack of compiler support + // MOVT r1, #0xC005 +.word 0xe34c1005 // hardcoded MOVW instruction due to lack of compiler support + MCR p15, 3, r1, c15, c0, 1 //; WCP15_L2CR0 r1 + + //; setup L2CPUCR + //; MOV r2, #0xFF + //; Enable I and D cache parity + //;L2CPUCR[7:5] = 3~Rh7 ~V enable parity error reporting for modified, + //;tag, and data parity errors + MOV r2, #0xe0 + MCR p15, 3, r2, c15, c0, 2 //; WCP15_L2CPUCR r2 + + //; setup SPCR + //; enable all error reporting (reset value is unpredicatble for most bits) + MOV r3, #0x0F + MCR p15, 0, r3, c9, c7, 0 //; WCP15_SPCR r3 + + //; setup DMACHCRs (reset value unpredictable) + //; control setting and enable all error reporting + MOV r1, #0x0F + + //; DMACHCR0 = 0000000F + MOV r2, #0x00 //; channel 0 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; DMACHCR1 = 0000000F + MOV r2, #0x01 //; channel 1 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; DMACHCR2 = 0000000F + MOV r2, #0x02 //; channel 2 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; DMACHCR3 = 0000000F + MOV r2, #0x03 //; channel 3 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; Set ACTLR (reset unpredictable) + //; Set AVIVT control, error reporting, etc. + //; MOV r3, #0x07 + //; Enable I and D cache parity + //;ACTLR[2:0] = 3'h7 - enable parity error reporting from L2/I$/D$) + //;ACTLR[5:4] = 2'h3 - enable parity + //;ACTLR[19:18] =2'h3 - always generate and check parity(when MMU disabled). + //;Value to be written #0xC0037 + // MOVW r3, #0x0037 +.word 0xe3003037 // hardcoded MOVW instruction due to lack of compiler support + // MOVT r3, #0x000C +.word 0xe340300c // hardcoded MOVW instruction due to lack of compiler support + MCR p15, 0, r3, c1, c0, 1 //; WCP15_ACTLR r3 + +//;End of error and control setting + + //;---------------------------------------------------------------------- + //; Unlock ETM and read StickyPD to halt the ETM clocks from running. + //; This is required for power saving whether the ETM is used or not. + //;---------------------------------------------------------------------- + + //;Clear ETMOSLSR[LOCK] bit + MOV r1, #0x00000000 + MCR p14, 1, r1, c1, c0, 4 //; WCP14_ETMOSLAR r1 + + //;Clear ETMPDSR[STICKYPD] bit + MRC p14, 1, r2, c1, c5, 4 //; RCP14_ETMPDSR r2 + +/* +#ifdef APPSBL_ETM_ENABLE + ;---------------------------------------------------------------------- + ; Optionally Enable the ETM (Embedded Trace Macro) which is used for debug + ;---------------------------------------------------------------------- + + ; enable ETM clock if disabled + MRC p15, 7, r1, c15, c0, 5 ; RCP15_CPMR r1 + ORR r1, r1, #0x00000008 + MCR p15, 7, r1, c15, c0, 5 ; WCP15_CPMR r1 + ISB + + ; set trigger event to counter1 being zero + MOV r3, #0x00000040 + MCR p14, 1, r3, c0, c2, 0 ; WCP14_ETMTRIGGER r3 + + ; clear ETMSR + MOV r2, #0x00000000 + MCR p14, 1, r2, c0, c4, 0 ; WCP14_ETMSR r2 + + ; clear trace enable single address comparator usage + MCR p14, 1, r2, c0, c7, 0 ; WCP14_ETMTECR2 r2 + + ; set trace enable to always + MOV r2, #0x0000006F + MCR p14, 1, r2, c0, c8, 0 ; WCP14_ETMTEEVR r2 + + ; clear trace enable address range comparator usage and exclude nothing + MOV r2, #0x01000000 + MCR p14, 1, r2, c0, c9, 0 ; WCP14_ETMTECR1 r2 + + ; set view data to always + MOV r2, #0x0000006F + MCR p14, 1, r2, c0, c12, 0 ; WCP14_ETMVDEVR r2 + + ; clear view data single address comparator usage + MOV r2, #0x00000000 + MCR p14, 1, r2, c0, c13, 0 ; WCP14_ETMVDCR1 r2 + + ; clear view data address range comparator usage and exclude nothing + MOV r2, #0x00010000 + MCR p14, 1, r2, c0, c15, 0 ; WCP14_ETMVDCR3 r2 + + ; set counter1 to 194 + MOV r2, #0x000000C2 + MCR p14, 1, r2, c0, c0, 5 ; WCP14_ETMCNTRLDVR1 r2 + + ; set counter1 to never reload + MOV r2, #0x0000406F + MCR p14, 1, r2, c0, c8, 5 ; WCP14_ETMCNTRLDEVR1 r2 + + ; set counter1 to decrement every cycle + MOV r2, #0x0000006F + MCR p14, 1, r2, c0, c4, 5 ; WCP14_ETMCNTENR1 r2 + + ; Set trace synchronization frequency 1024 bytes + MOV r2, #0x00000400 + MCR p14, 1, r2, c0, c8, 7 ; WCP14_ETMSYNCFR r2 + + ; Program etm control register + ; - Set the CPU to ETM clock ratio to 1:1 + ; - Set the ETM to perform data address tracing + MOV r2, #0x00002008 + MCR p14, 1, r2, c0, c0, 0 ; WCP14_ETMCR r2 + ISB +#endif *//* APPSBL_ETM_ENABLE */ + +/* +#ifdef APPSBL_VFP_ENABLE + ;---------------------------------------------------------------------- + ; Perform the following operations if you intend to make use of + ; the VFP/Neon unit. Note that the FMXR instruction requires a CPU ID + ; indicating the VFP unit is present (i.e.Cortex-A8). . + ; Some tools will require full double precision floating point support + ; which will become available in Scorpion pass 2 + ;---------------------------------------------------------------------- + ; allow full access to CP 10 and 11 space for VFP/NEON use + MRC p15, 0, r1, c1, c0, 2 ; Read CP Access Control Register + ORR r1, r1, #0x00F00000 ; enable full access for p10,11 + MCR p15, 0, r1, c1, c0, 2 ; Write CPACR + + ;make sure the CPACR is complete before continuing + ISB + + ; Enable VFP itself (certain OSes may want to dynamically set/clear + ; the enable bit based on the application being executed + MOV r1, #0x40000000 + FMXR FPEXC, r1 +#endif *//* APPSBL_VFP_ENABLE */ + + /* we have no stack, so just tail-call into the SET_SA routine... */ + b SET_SA + + +.ltorg diff --git a/lk/platform/msm7x30/gpio.c b/lk/platform/msm7x30/gpio.c new file mode 100644 index 0000000..1204944 --- /dev/null +++ b/lk/platform/msm7x30/gpio.c @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "gpio_hw.h" + +typedef struct gpioregs gpioregs; + +struct gpioregs +{ + unsigned out; + unsigned in; + unsigned int_status; + unsigned int_clear; + unsigned int_en; + unsigned int_edge; + unsigned int_pos; + unsigned oe; +}; + +static gpioregs GPIO_REGS[] = { + { + .out = GPIO_OUT_0, + .in = GPIO_IN_0, + .int_status = GPIO_INT_STATUS_0, + .int_clear = GPIO_INT_CLEAR_0, + .int_en = GPIO_INT_EN_0, + .int_edge = GPIO_INT_EDGE_0, + .int_pos = GPIO_INT_POS_0, + .oe = GPIO_OE_0, + }, + { + .out = GPIO_OUT_1, + .in = GPIO_IN_1, + .int_status = GPIO_INT_STATUS_1, + .int_clear = GPIO_INT_CLEAR_1, + .int_en = GPIO_INT_EN_1, + .int_edge = GPIO_INT_EDGE_1, + .int_pos = GPIO_INT_POS_1, + .oe = GPIO_OE_1, + }, + { + .out = GPIO_OUT_2, + .in = GPIO_IN_2, + .int_status = GPIO_INT_STATUS_2, + .int_clear = GPIO_INT_CLEAR_2, + .int_en = GPIO_INT_EN_2, + .int_edge = GPIO_INT_EDGE_2, + .int_pos = GPIO_INT_POS_2, + .oe = GPIO_OE_2, + }, + { + .out = GPIO_OUT_3, + .in = GPIO_IN_3, + .int_status = GPIO_INT_STATUS_3, + .int_clear = GPIO_INT_CLEAR_3, + .int_en = GPIO_INT_EN_3, + .int_edge = GPIO_INT_EDGE_3, + .int_pos = GPIO_INT_POS_3, + .oe = GPIO_OE_3, + }, + { + .out = GPIO_OUT_4, + .in = GPIO_IN_4, + .int_status = GPIO_INT_STATUS_4, + .int_clear = GPIO_INT_CLEAR_4, + .int_en = GPIO_INT_EN_4, + .int_edge = GPIO_INT_EDGE_4, + .int_pos = GPIO_INT_POS_4, + .oe = GPIO_OE_4, + }, + { + .out = GPIO_OUT_5, + .in = GPIO_IN_5, + .int_status = GPIO_INT_STATUS_5, + .int_clear = GPIO_INT_CLEAR_5, + .int_en = GPIO_INT_EN_5, + .int_edge = GPIO_INT_EDGE_5, + .int_pos = GPIO_INT_POS_5, + .oe = GPIO_OE_5, + }, + { + .out = GPIO_OUT_6, + .in = GPIO_IN_6, + .int_status = GPIO_INT_STATUS_6, + .int_clear = GPIO_INT_CLEAR_6, + .int_en = GPIO_INT_EN_6, + .int_edge = GPIO_INT_EDGE_6, + .int_pos = GPIO_INT_POS_6, + .oe = GPIO_OE_6, + }, + { + .out = GPIO_OUT_7, + .in = GPIO_IN_7, + .int_status = GPIO_INT_STATUS_7, + .int_clear = GPIO_INT_CLEAR_7, + .int_en = GPIO_INT_EN_7, + .int_edge = GPIO_INT_EDGE_7, + .int_pos = GPIO_INT_POS_7, + .oe = GPIO_OE_7, + }, +}; + +static gpioregs *find_gpio(unsigned n, unsigned *bit) +{ + if(n > 150) { + *bit = 1 << (n - 151); + return GPIO_REGS + 7; + } + if(n > 133) { + *bit = 1 << (n - 134); + return GPIO_REGS + 6; + } + if(n > 106) { + *bit = 1 << (n - 107); + return GPIO_REGS + 5; + } + if(n > 94) { + *bit = 1 << (n - 95); + return GPIO_REGS + 4; + } + if(n > 67) { + *bit = 1 << (n - 68); + return GPIO_REGS + 3; + } + if(n > 43) { + *bit = 1 << (n - 44); + return GPIO_REGS + 2; + } + if(n > 15) { + *bit = 1 << (n - 16); + return GPIO_REGS + 1; + } + *bit = 1 << n; + return GPIO_REGS + 0; +} + +int gpio_config(unsigned n, unsigned flags) +{ + gpioregs *r; + unsigned b; + unsigned v; + + if ((r = find_gpio(n, &b)) == 0) + return -1; + + v = readl(r->oe); + if (flags & GPIO_OUTPUT) { + writel(v | b, r->oe); + } else { + writel(v & (~b), r->oe); + } + return 0; +} + +void gpio_set(unsigned n, unsigned on) +{ + gpioregs *r; + unsigned b; + unsigned v; + + if((r = find_gpio(n, &b)) == 0) return; + + v = readl(r->out); + if(on) { + writel(v | b, r->out); + } else { + writel(v & (~b), r->out); + } +} + +int gpio_get(unsigned n) +{ + gpioregs *r; + unsigned b; + + if((r = find_gpio(n, &b)) == 0) return 0; + + return (readl(r->in) & b) ? 1 : 0; +} + +void platform_config_interleaved_mode_gpios(void) +{ + /* configure EB2_CS1 through GPIO86 */ + writel (GPIO_ALT_FUNC_PAGE_REG, 0x56); + writel (GPIO_ALT_FUNC_CFG_REG, 0x04); + /* configure the EBI2_BUSY1_N through GPIO115 */ + writel (GPIO_ALT_FUNC_PAGE_REG, 0x73); + writel (GPIO_ALT_FUNC_CFG_REG, 0x08); +} + +/* Enables all gpios passed in table*/ +int platform_gpios_enable(const struct msm_gpio *table, int size) +{ + int rc; + int i; + const struct msm_gpio *g; + for (i = 0; i < size; i++) { + g = table + i; + /* Enable gpio */ + rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE); + if (rc) { + goto err; + } + } + return 0; +err: + return rc; +} + diff --git a/lk/platform/msm7x30/gpio_hw.h b/lk/platform/msm7x30/gpio_hw.h new file mode 100644 index 0000000..7d7e722 --- /dev/null +++ b/lk/platform/msm7x30/gpio_hw.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * 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 __PLATFORM_MSM7X30_GPIO_HW_H +#define __PLATFORM_MSM7X30_GPIO_HW_H + +#define MSM_GPIO1_BASE 0xAC001000 +#define MSM_GPIO2_BASE 0xAC101000 + +#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off)) +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off)) + +/* output value */ +#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */ +#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 43-16 */ +#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-44 */ +#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */ +#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 106-95 */ +#define GPIO_OUT_5 GPIO1_REG(0x50) /* gpio 133-107 */ +#define GPIO_OUT_6 GPIO1_REG(0xC4) /* gpio 150-134 */ +#define GPIO_OUT_7 GPIO1_REG(0x214) /* gpio 181-151 */ + +/* same pin map as above, output enable */ +#define GPIO_OE_0 GPIO1_REG(0x10) +#define GPIO_OE_1 GPIO2_REG(0x08) +#define GPIO_OE_2 GPIO1_REG(0x14) +#define GPIO_OE_3 GPIO1_REG(0x18) +#define GPIO_OE_4 GPIO1_REG(0x1C) +#define GPIO_OE_5 GPIO1_REG(0x54) +#define GPIO_OE_6 GPIO1_REG(0xC8) +#define GPIO_OE_7 GPIO1_REG(0x218) + +/* same pin map as above, input read */ +#define GPIO_IN_0 GPIO1_REG(0x34) +#define GPIO_IN_1 GPIO2_REG(0x20) +#define GPIO_IN_2 GPIO1_REG(0x38) +#define GPIO_IN_3 GPIO1_REG(0x3C) +#define GPIO_IN_4 GPIO1_REG(0x40) +#define GPIO_IN_5 GPIO1_REG(0x44) +#define GPIO_IN_6 GPIO1_REG(0xCC) +#define GPIO_IN_7 GPIO1_REG(0x21C) + +/* same pin map as above, 1=edge 0=level interrup */ +#define GPIO_INT_EDGE_0 GPIO1_REG(0x60) +#define GPIO_INT_EDGE_1 GPIO2_REG(0x50) +#define GPIO_INT_EDGE_2 GPIO1_REG(0x64) +#define GPIO_INT_EDGE_3 GPIO1_REG(0x68) +#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C) +#define GPIO_INT_EDGE_5 GPIO1_REG(0xC0) +#define GPIO_INT_EDGE_6 GPIO1_REG(0xD0) +#define GPIO_INT_EDGE_7 GPIO1_REG(0x240) + +/* same pin map as above, 1=positive 0=negative */ +#define GPIO_INT_POS_0 GPIO1_REG(0x70) +#define GPIO_INT_POS_1 GPIO2_REG(0x58) +#define GPIO_INT_POS_2 GPIO1_REG(0x74) +#define GPIO_INT_POS_3 GPIO1_REG(0x78) +#define GPIO_INT_POS_4 GPIO1_REG(0x7C) +#define GPIO_INT_POS_5 GPIO1_REG(0xBC) +#define GPIO_INT_POS_6 GPIO1_REG(0xD4) +#define GPIO_INT_POS_7 GPIO1_REG(0x228) + +/* same pin map as above, interrupt enable */ +#define GPIO_INT_EN_0 GPIO1_REG(0x80) +#define GPIO_INT_EN_1 GPIO2_REG(0x60) +#define GPIO_INT_EN_2 GPIO1_REG(0x84) +#define GPIO_INT_EN_3 GPIO1_REG(0x88) +#define GPIO_INT_EN_4 GPIO1_REG(0x8C) +#define GPIO_INT_EN_5 GPIO1_REG(0xB8) +#define GPIO_INT_EN_6 GPIO1_REG(0xD8) +#define GPIO_INT_EN_7 GPIO1_REG(0x22C) + +/* same pin map as above, write 1 to clear interrupt */ +#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90) +#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68) +#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94) +#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98) +#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C) +#define GPIO_INT_CLEAR_5 GPIO1_REG(0xB4) +#define GPIO_INT_CLEAR_6 GPIO1_REG(0xDC) +#define GPIO_INT_CLEAR_7 GPIO1_REG(0x230) + +/* same pin map as above, 1=interrupt pending */ +#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0) +#define GPIO_INT_STATUS_1 GPIO2_REG(0x70) +#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4) +#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8) +#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC) +#define GPIO_INT_STATUS_5 GPIO1_REG(0xB0) +#define GPIO_INT_STATUS_6 GPIO1_REG(0xE0) +#define GPIO_INT_STATUS_7 GPIO1_REG(0x234) + + +#define GPIO_OUT_VAL_REG_BASE 0xABC00000 +#define GPIO_ALT_FUNC_PAGE_REG (GPIO_OUT_VAL_REG_BASE + 0x20) +#define GPIO_ALT_FUNC_CFG_REG (GPIO_OUT_VAL_REG_BASE + 0x24) + +/* GPIO TLMM: Direction */ +#define GPIO_INPUT 0 +#define GPIO_OUTPUT 1 + +/* GPIO TLMM: Pullup/Pulldown */ +#define GPIO_NO_PULL 0 +#define GPIO_PULL_DOWN 1 +#define GPIO_KEEPER 2 +#define GPIO_PULL_UP 3 + +/* GPIO TLMM: Drive Strength */ +#define GPIO_2MA 0 +#define GPIO_4MA 1 +#define GPIO_6MA 2 +#define GPIO_8MA 3 +#define GPIO_10MA 4 +#define GPIO_12MA 5 +#define GPIO_14MA 6 +#define GPIO_16MA 7 + +#define GPIO38_GPIO_CNTRL 0x175 + +/* GPIO TLMM: Status */ +#define GPIO_ENABLE 0 +#define GPIO_DISABLE 1 + +#define GPIO_CFG(gpio, func, dir, pull, drvstr) \ + ((((gpio) & 0x3FF) << 4) | \ + ((func) & 0xf) | \ + (((dir) & 0x1) << 14) | \ + (((pull) & 0x3) << 15) | \ + (((drvstr) & 0xF) << 17)) + +/** + * struct msm_gpio - GPIO pin description + * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config() + * @label - textual label + * + * Usually, GPIO's are operated by sets. + * This struct accumulate all GPIO information in single source + * and facilitete group operations provided by msm_gpios_xxx() + */ +struct msm_gpio { + unsigned gpio_cfg; + const char *label; +}; + +/** + * extract GPIO pin from bit-field used for gpio_tlmm_config + */ +#define GPIO_PIN(gpio_cfg) (((gpio_cfg) >> 4) & 0x3ff) +#define GPIO_FUNC(gpio_cfg) (((gpio_cfg) >> 0) & 0xf) +#define GPIO_DIR(gpio_cfg) (((gpio_cfg) >> 14) & 0x1) +#define GPIO_PULL(gpio_cfg) (((gpio_cfg) >> 15) & 0x3) +#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf) + +#endif diff --git a/lk/platform/msm7x30/include/platform/iomap.h b/lk/platform/msm7x30/include/platform/iomap.h new file mode 100644 index 0000000..f012f5b --- /dev/null +++ b/lk/platform/msm7x30/include/platform/iomap.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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 Google, Inc. 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 _PLATFORM_MSM7X30_IOMAP_H_ +#define _PLATFORM_MSM7X30_IOMAP_H_ + +#define MSM_UART1_BASE 0xACA00000 +#define MSM_UART2_BASE 0xACB00000 +#define MSM_UART3_BASE 0xACC00000 + +#define MSM_VIC_BASE 0xC0080000 +#define MSM_TMR_BASE 0xC0100000 +#define MSM_GPT_BASE (MSM_TMR_BASE + 0x04) +#define MSM_CSR_BASE 0xC0100000 +#define MSM_GCC_BASE 0xC0182000 + +#define MSM_SDC1_BASE 0xA0400000 +#define MSM_SDC2_BASE 0xA0500000 +#define MSM_SDC3_BASE 0xA3000000 +#define MSM_SDC4_BASE 0xA3100000 + +#define MSM_SHARED_BASE 0x00100000 + +#define MSM_CLK_CTL_BASE 0xAB800000 +#define MSM_CLK_CTL_SH2_BASE 0xABA01000 +#define SCSS_CLK_CTL 0xC0101004 +#define SCSS_CLK_SEL 0xC0101008 + +#define MSM_USB_BASE 0xA3600000 +#define SH2_USBH_MD_REG 0xABA012BC +#define SH2_USBH_NS_REG 0xABA012C0 +#define SH2_GLBL_CLK_ENA_SC 0xABA013BC + +#define MSM_SAW_BASE 0xC0102000 +#endif diff --git a/lk/platform/msm7x30/include/platform/irqs.h b/lk/platform/msm7x30/include/platform/irqs.h new file mode 100644 index 0000000..ad58b59 --- /dev/null +++ b/lk/platform/msm7x30/include/platform/irqs.h @@ -0,0 +1,170 @@ +/* Copyright (c) 2009, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT 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 __ASM_ARCH_MSM_IRQS_7X30_H +#define __ASM_ARCH_MSM_IRQS_7X30_H + +/* MSM ACPU Interrupt Numbers */ + +#define INT_DEBUG_TIMER_EXP 0 +#define INT_GPT0_TIMER_EXP 1 +#define INT_GPT1_TIMER_EXP 2 +#define INT_WDT0_ACCSCSSBARK 3 +#define INT_WDT1_ACCSCSSBARK 4 +#define INT_AVS_SVIC 5 +#define INT_AVS_SVIC_SW_DONE 6 +#define INT_SC_DBG_RX_FULL 7 +#define INT_SC_DBG_TX_EMPTY 8 +#define INT_SC_PERF_MON 9 +#define INT_AVS_REQ_DOWN 10 +#define INT_AVS_REQ_UP 11 +#define INT_SC_ACG 12 +/* SCSS_VICFIQSTS1[13:15] are RESERVED */ +#define INT_L2_SVICCPUIRPTREQ 16 +#define INT_L2_SVICDMANSIRPTREQ 17 +#define INT_L2_SVICDMASIRPTREQ 18 +#define INT_L2_SVICSLVIRPTREQ 19 +#define INT_AD5A_MPROC_APPS_0 20 +#define INT_AD5A_MPROC_APPS_1 21 +#define INT_A9_M2A_0 22 +#define INT_A9_M2A_1 23 +#define INT_A9_M2A_2 24 +#define INT_A9_M2A_3 25 +#define INT_A9_M2A_4 26 +#define INT_A9_M2A_5 27 +#define INT_A9_M2A_6 28 +#define INT_A9_M2A_7 29 +#define INT_A9_M2A_8 30 +#define INT_A9_M2A_9 31 + +#define INT_AXI_EBI1_SC (32 + 0) +#define INT_IMEM_ERR (32 + 1) +#define INT_AXI_EBI0_SC (32 + 2) +#define INT_PBUS_SC_IRQC (32 + 3) +#define INT_PERPH_BUS_BPM (32 + 4) +#define INT_CC_TEMP_SENSE (32 + 5) +#define INT_UXMC_EBI0 (32 + 6) +#define INT_UXMC_EBI1 (32 + 7) +#define INT_EBI2_OP_DONE (32 + 8) +#define INT_EBI2_WR_ER_DONE (32 + 9) +#define INT_TCSR_SPSS_CE (32 + 10) +#define INT_EMDH (32 + 11) +#define INT_PMDH (32 + 12) +#define INT_MDC (32 + 13) +#define INT_MIDI_TO_SUPSS (32 + 14) +#define INT_LPA_2 (32 + 15) +#define INT_GPIO_GROUP1_SECURE (32 + 16) +#define INT_GPIO_GROUP2_SECURE (32 + 17) +#define INT_GPIO_GROUP1 (32 + 18) +#define INT_GPIO_GROUP2 (32 + 19) +#define INT_MPRPH_SOFTRESET (32 + 20) +#define INT_PWB_I2C (32 + 21) +#define INT_PWB_I2C_2 (32 + 22) +#define INT_TSSC_SAMPLE (32 + 23) +#define INT_TSSC_PENUP (32 + 24) +#define INT_TCHSCRN_SSBI (32 + 25) +#define INT_FM_RDS (32 + 26) +#define INT_KEYSENSE (32 + 27) +#define INT_USB_OTG_HS (32 + 28) +#define INT_USB_OTG_HS2 (32 + 29) +#define INT_USB_OTG_HS3 (32 + 30) +#define INT_RESERVED_BIT31 (32 + 31) + +#define INT_SPI_OUTPUT (64 + 0) +#define INT_SPI_INPUT (64 + 1) +#define INT_SPI_ERROR (64 + 2) +#define INT_UART1 (64 + 3) +#define INT_UART1_RX (64 + 4) +#define INT_UART2 (64 + 5) +#define INT_UART2_RX (64 + 6) +#define INT_UART3 (64 + 7) +#define INT_UART3_RX (64 + 8) +#define INT_UART1DM_IRQ (64 + 9) +#define INT_UART1DM_RX (64 + 10) +#define INT_UART2DM_IRQ (64 + 11) +#define INT_UART2DM_RX (64 + 12) +#define INT_TSIF (64 + 13) +#define INT_ADM_SC1 (64 + 14) +#define INT_ADM_SC2 (64 + 15) +#define INT_MDP (64 + 16) +#define INT_VPE (64 + 17) +#define INT_GRP_2D (64 + 18) +#define INT_GRP_3D (64 + 19) +#define INT_ROTATOR (64 + 20) +#define INT_MFC720 (64 + 21) +#define INT_JPEG (64 + 22) +#define INT_VFE (64 + 23) +#define INT_TV_ENC (64 + 24) +#define INT_PMIC_SSBI (64 + 25) +#define INT_MPM_1 (64 + 26) +#define INT_TCSR_SPSS_SAMPLE (64 + 27) +#define INT_TCSR_SPSS_PENUP (64 + 28) +#define INT_MPM_2 (64 + 29) +#define INT_SDC1_0 (64 + 30) +#define INT_SDC1_1 (64 + 31) + +#define INT_SDC3_0 (96 + 0) +#define INT_SDC3_1 (96 + 1) +#define INT_SDC2_0 (96 + 2) +#define INT_SDC2_1 (96 + 3) +#define INT_SDC4_0 (96 + 4) +#define INT_SDC4_1 (96 + 5) +#define INT_PWB_QUP_IN (96 + 6) +#define INT_PWB_QUP_OUT (96 + 7) +#define INT_PWB_QUP_ERR (96 + 8) +/* SCSS_VICFIQSTS3[6:31] are RESERVED */ + +/* Retrofit universal macro names */ +#define INT_ADM_AARM INT_ADM_SC2 +#define INT_USB_HS INT_USB_OTG_HS +#define INT_USB_OTG INT_USB_OTG_HS +#define INT_TCHSCRN1 INT_TSSC_SAMPLE +#define INT_TCHSCRN2 INT_TSSC_PENUP +#define INT_GP_TIMER_EXP INT_GPT0_TIMER_EXP +#define INT_ADSP_A11 INT_AD5A_MPROC_APPS_0 +#define INT_ADSP_A9_A11 INT_AD5A_MPROC_APPS_1 +#define INT_MDDI_EXT INT_EMDH +#define INT_MDDI_PRI INT_PMDH +#define INT_MDDI_CLIENT INT_MDC +#define INT_NAND_WR_ER_DONE INT_EBI2_WR_ER_DONE +#define INT_NAND_OP_DONE INT_EBI2_OP_DONE + +#define NR_MSM_IRQS 128 +#define NR_GPIO_IRQS 182 +#define PMIC8058_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS) +#define NR_PMIC8058_GPIO_IRQS 40 +#define NR_PMIC8058_MPP_IRQS 12 +#define NR_PMIC8058_MISC_IRQS 8 +#define NR_PMIC8058_IRQS (NR_PMIC8058_GPIO_IRQS +\ + NR_PMIC8058_MPP_IRQS +\ + NR_PMIC8058_MISC_IRQS) +#define NR_BOARD_IRQS NR_PMIC8058_IRQS + +#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS) + +#endif /* __ASM_ARCH_MSM_IRQS_7X30_H */ diff --git a/lk/platform/msm7x30/interrupts.c b/lk/platform/msm7x30/interrupts.c new file mode 100644 index 0000000..9071677 --- /dev/null +++ b/lk/platform/msm7x30/interrupts.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define VIC_REG(off) (MSM_VIC_BASE + (off)) + +#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_EN0 VIC_REG(0x0010) +#define VIC_INT_EN1 VIC_REG(0x0014) +#define VIC_INT_ENCLEAR0 VIC_REG(0x0020) +#define VIC_INT_ENCLEAR1 VIC_REG(0x0024) +#define VIC_INT_ENSET0 VIC_REG(0x0030) +#define VIC_INT_ENSET1 VIC_REG(0x0034) +#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */ +#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */ +#define VIC_NO_PEND_VAL VIC_REG(0x0060) +#define VIC_INT_MASTEREN VIC_REG(0x0068) /* 1: IRQ, 2: FIQ */ +#define VIC_CONFIG VIC_REG(0x006C) /* 1: USE ARM1136 VIC */ +#define VIC_SECURITY0 VIC_REG(0x0070) +#define VIC_SECURITY1 VIC_REG(0x0074) +#define VIC_IRQ_STATUS0 VIC_REG(0x0080) +#define VIC_IRQ_STATUS1 VIC_REG(0x0084) +#define VIC_FIQ_STATUS0 VIC_REG(0x0090) +#define VIC_FIQ_STATUS1 VIC_REG(0x0094) +#define VIC_RAW_STATUS0 VIC_REG(0x00A0) +#define VIC_RAW_STATUS1 VIC_REG(0x00A4) +#define VIC_INT_CLEAR0 VIC_REG(0x00B0) +#define VIC_INT_CLEAR1 VIC_REG(0x00B4) +#define VIC_SOFTINT0 VIC_REG(0x00C0) +#define VIC_SOFTINT1 VIC_REG(0x00C4) +#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */ +#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */ +#define VIC_IRQ_VEC_WR VIC_REG(0x00D8) +#define VIC_FIQ_VEC_RD VIC_REG(0x00DC) /* pending int # */ +#define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0) /* pending vector addr */ +#define VIC_FIQ_VEC_WR VIC_REG(0x00E4) +#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E8) +#define VIC_IRQ_IN_STACK VIC_REG(0x00EC) +#define VIC_FIQ_IN_SERVICE VIC_REG(0x00F0) +#define VIC_FIQ_IN_STACK VIC_REG(0x00F4) +#define VIC_TEST_BUS_SEL VIC_REG(0x00F8) + +#define SIRC_REG(off) (MSM_SIRC_BASE + (off)) + +#define SIRC_INT_SELECT SIRC_REG(0x0000) /* 0: IRQ0 1: IRQ1 */ +#define SIRC_INT_ENABLE SIRC_REG(0x0004) +#define SIRC_INT_ENCLEAR SIRC_REG(0x0008) +#define SIRC_INT_ENSET SIRC_REG(0x000C) +#define SIRC_INT_TYPE SIRC_REG(0x0010) /* 1: EDGE, 0: LEVEL */ +#define SIRC_INT_POLARITY SIRC_REG(0x0014) /* 1: NEG, 0: POS */ +#define SIRC_SECURITY SIRC_REG(0x0018) /* 0: SEC, 1: NSEC */ +#define SIRC_IRQ0_STATUS SIRC_REG(0x001C) +#define SIRC_IRQ1_STATUS SIRC_REG(0x0020) +#define SIRC_RAW_STATUS SIRC_REG(0x0024) + +struct ihandler { + int_handler func; + void *arg; +}; + +static struct ihandler handler[NR_IRQS]; + +void platform_init_interrupts(void) +{ + writel(0xffffffff, VIC_INT_CLEAR0); + writel(0xffffffff, VIC_INT_CLEAR1); + writel(0, VIC_INT_SELECT0); + writel(0, VIC_INT_SELECT1); + writel(0xffffffff, VIC_INT_TYPE0); + writel(0xffffffff, VIC_INT_TYPE1); + writel(0, VIC_CONFIG); + writel(1, VIC_INT_MASTEREN); +} + +enum handler_return platform_irq(struct arm_iframe *frame) +{ + unsigned num; + enum handler_return ret; + num = readl(VIC_IRQ_VEC_RD); + num = readl(VIC_IRQ_VEC_PEND_RD); + if (num > NR_IRQS) + return 0; + writel(1 << (num & 31), (num > 31) ? VIC_INT_CLEAR1 : VIC_INT_CLEAR0); + ret = handler[num].func(handler[num].arg); + writel(0, VIC_IRQ_VEC_WR); + return ret; +} + +void platform_fiq(struct arm_iframe *frame) +{ + PANIC_UNIMPLEMENTED; +} + +status_t mask_interrupt(unsigned int vector) +{ + unsigned reg = (vector > 31) ? VIC_INT_ENCLEAR1 : VIC_INT_ENCLEAR0; + unsigned bit = 1 << (vector & 31); + writel(bit, reg); + return 0; +} + +status_t unmask_interrupt(unsigned int vector) +{ + unsigned reg = (vector > 31) ? VIC_INT_ENSET1 : VIC_INT_ENSET0; + unsigned bit = 1 << (vector & 31); + writel(bit, reg); + return 0; +} + +void register_int_handler(unsigned int vector, int_handler func, void *arg) +{ + if (vector >= NR_IRQS) + return; + + enter_critical_section(); + handler[vector].func = func; + handler[vector].arg = arg; + exit_critical_section(); +} + diff --git a/lk/platform/msm7x30/panel.c b/lk/platform/msm7x30/panel.c new file mode 100644 index 0000000..f7239c1 --- /dev/null +++ b/lk/platform/msm7x30/panel.c @@ -0,0 +1,674 @@ +/* + * Copyright (c) 2007, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Code Aurora 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. + */ + +#include +#include +#include +#include "gpio_hw.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +static int display_common_power(int); + +#if DISPLAY_TYPE_MDDI +#include + +#define MDDI_CLIENT_CORE_BASE 0x108000 +#define LCD_CONTROL_BLOCK_BASE 0x110000 +#define SPI_BLOCK_BASE 0x120000 +#define I2C_BLOCK_BASE 0x130000 +#define PWM_BLOCK_BASE 0x140000 +#define GPIO_BLOCK_BASE 0x150000 +#define SYSTEM_BLOCK1_BASE 0x160000 +#define SYSTEM_BLOCK2_BASE 0x170000 + + +#define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00) +#define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04) +#define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08) +#define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C) +#define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10) +#define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14) +#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18) +#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C) +#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20) +#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24) +#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28) +#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C) +#define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30) +#define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34) +#define INTMONI (MDDI_CLIENT_CORE_BASE|0x38) +#define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C) +#define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40) +#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44) +#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48) +#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C) +#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50) +#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54) + + +#define SRST (LCD_CONTROL_BLOCK_BASE|0x00) +#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04) +#define START (LCD_CONTROL_BLOCK_BASE|0x08) +#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C) +#define CMN (LCD_CONTROL_BLOCK_BASE|0x10) +#define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14) +#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18) +#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C) +#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20) +#define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24) +#define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28) + +#define PXL (LCD_CONTROL_BLOCK_BASE|0x30) +#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34) +#define HSW (LCD_CONTROL_BLOCK_BASE|0x38) +#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C) +#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40) +#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44) +#define VSW (LCD_CONTROL_BLOCK_BASE|0x48) +#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C) +#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50) +#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54) +#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58) +#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C) +#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60) +#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64) +#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68) +#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C) +#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70) +#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74) +#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78) +#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C) +#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80) +#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84) +#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88) +#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C) + +#define MONI (LCD_CONTROL_BLOCK_BASE|0xB0) + +#define Current (LCD_CONTROL_BLOCK_BASE|0xC0) +#define LCD (LCD_CONTROL_BLOCK_BASE|0xC4) +#define COMMAND (LCD_CONTROL_BLOCK_BASE|0xC8) + + +#define SSICTL (SPI_BLOCK_BASE|0x00) +#define SSITIME (SPI_BLOCK_BASE|0x04) +#define SSITX (SPI_BLOCK_BASE|0x08) +#define SSIRX (SPI_BLOCK_BASE|0x0C) +#define SSIINTC (SPI_BLOCK_BASE|0x10) +#define SSIINTS (SPI_BLOCK_BASE|0x14) +#define SSIDBG1 (SPI_BLOCK_BASE|0x18) +#define SSIDBG2 (SPI_BLOCK_BASE|0x1C) +#define SSIID (SPI_BLOCK_BASE|0x20) + + +#define I2CSETUP (I2C_BLOCK_BASE|0x00) +#define I2CCTRL (I2C_BLOCK_BASE|0x04) + + +#define TIMER0LOAD (PWM_BLOCK_BASE|0x00) +#define TIMER0VALUE (PWM_BLOCK_BASE|0x04) +#define TIMER0CONTROL (PWM_BLOCK_BASE|0x08) +#define TIMER0INTCLR (PWM_BLOCK_BASE|0x0C) +#define TIMER0RIS (PWM_BLOCK_BASE|0x10) +#define TIMER0MIS (PWM_BLOCK_BASE|0x14) +#define TIMER0BGLOAD (PWM_BLOCK_BASE|0x18) +#define PWM0OFF (PWM_BLOCK_BASE|0x1C) +#define TIMER1LOAD (PWM_BLOCK_BASE|0x20) +#define TIMER1VALUE (PWM_BLOCK_BASE|0x24) +#define TIMER1CONTROL (PWM_BLOCK_BASE|0x28) +#define TIMER1INTCLR (PWM_BLOCK_BASE|0x2C) +#define TIMER1RIS (PWM_BLOCK_BASE|0x30) +#define TIMER1MIS (PWM_BLOCK_BASE|0x34) +#define TIMER1BGLOAD (PWM_BLOCK_BASE|0x38) +#define PWM1OFF (PWM_BLOCK_BASE|0x3C) +#define TIMERITCR (PWM_BLOCK_BASE|0x60) +#define TIMERITOP (PWM_BLOCK_BASE|0x64) +#define PWMCR (PWM_BLOCK_BASE|0x68) +#define PWMID (PWM_BLOCK_BASE|0x6C) +#define PWMMON (PWM_BLOCK_BASE|0x70) + + +#define GPIODATA (GPIO_BLOCK_BASE|0x00) +#define GPIODIR (GPIO_BLOCK_BASE|0x04) +#define GPIOIS (GPIO_BLOCK_BASE|0x08) +#define GPIOIBE (GPIO_BLOCK_BASE|0x0C) +#define GPIOIEV (GPIO_BLOCK_BASE|0x10) +#define GPIOIE (GPIO_BLOCK_BASE|0x14) +#define GPIORIS (GPIO_BLOCK_BASE|0x18) +#define GPIOMIS (GPIO_BLOCK_BASE|0x1C) +#define GPIOIC (GPIO_BLOCK_BASE|0x20) +#define GPIOOMS (GPIO_BLOCK_BASE|0x24) +#define GPIOPC (GPIO_BLOCK_BASE|0x28) + +#define GPIOID (GPIO_BLOCK_BASE|0x30) + + +#define WKREQ (SYSTEM_BLOCK1_BASE|0x00) +#define CLKENB (SYSTEM_BLOCK1_BASE|0x04) +#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08) +#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C) +#define CNT_DIS (SYSTEM_BLOCK1_BASE|0x10) +#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00) + +struct init_table { + unsigned int reg; + unsigned int val; +}; + +static struct init_table toshiba_480x800_init_table[] = { + { DPSET0, 0x4BEC0066 }, // # MDC.DPSET0 # Setup DPLL parameters + { DPSET1, 0x00000113 }, // # MDC.DPSET1 + { DPSUS, 0x00000000 }, // # MDC.DPSUS # Set DPLL oscillation enable + { DPRUN, 0x00000001 }, // # MDC.DPRUN # Release reset signal for DPLL + { 0, 15 }, // wait_ms(15); + { SYSCKENA, 0x00000001 }, // # MDC.SYSCKENA # Enable system clock output + { CLKENB, 0x000000E9 }, // # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) + + { GPIO_BLOCK_BASE, 0x03FF0000 }, // # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 + { GPIODIR, 0x0000024D }, // # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) + { SYSTEM_BLOCK2_BASE, 0x00000173 }, // # SYS.GPIOSEL # GPIO port multiplexing control + { GPIOPC, 0x03C300C0 }, // # GPI .GPIOPC # GPIO2,3 PD cut + { SYSTEM_BLOCK1_BASE, 0x00000000 }, // # SYS.WKREQ # Wake-up request event is VSYNC alignment + { GPIOIS, 0x00000000 }, // # GPI .GPIOIS # Set interrupt sense of GPIO + { GPIOIEV, 0x00000001 }, // # GPI .GPIOIEV # Set interrupt event of GPIO + { GPIOIC, 0x000003FF }, // # GPI .GPIOIC # GPIO interrupt clear + { GPIO_BLOCK_BASE, 0x00040004 }, // # GPI .GPIODATA # Release LCDD reset + + { GPIO_BLOCK_BASE, 0x00080008 }, // # GPI .GPIODATA # eDRAM VD supply + { DRAMPWR, 0x00000001 }, // # SYS.DRAMPWR # eDRAM power up + { CLKENB, 0x000000EB }, // # enable eDRAM clock + + { PWMCR, 0x00000000 }, // # PWM.PWMCR # PWM output enable + { 0, 1 }, // wait_ms(1); + { SPI_BLOCK_BASE, 0x00060399}, // # SPI .SSICTL # SPI operation mode setting + { SSITIME, 0x00000100 }, // # SPI .SSITIME # SPI serial interface timing setting + { CNT_DIS, 0x00000002 }, // # SPI .SSITIME # SPI serial interface timing setting + { SPI_BLOCK_BASE, 0x0006039B }, // # SPI .SSICTL # Set SPI active mode + + { SSITX, 0x00000000 }, // # SPI.SSITX # Release from Deep Stanby mode + { 0, 7 }, // wait_ms(2); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 7 }, // wait_ms(2); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 7 }, // wait_ms(2); + + { SSITX, 0x000800BA }, // # SPI.SSITX *NOTE 1 # Command setting of SPI block + { SSITX, 0x00000111 }, // # Display mode setup(1) : Normaly Black + { SSITX, 0x00080036 }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Memory access control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x0008003A }, // # Command setting of SPI block + { SSITX, 0x00000160 }, // # Display mode setup(2) + { SSITX, 0x000800B1 }, // # Command setting of SPI block + { SSITX, 0x0000015D }, // # RGB Interface data format + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B2 }, // # Command setting of SPI block + { SSITX, 0x00000133 }, // # Drivnig method + { SSITX, 0x000800B3 }, // # Command setting of SPI block + { SSITX, 0x00000122 }, // # Booster operation setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B4 }, // # Command setting of SPI block + { SSITX, 0x00000102 }, // # OP-amp capability/System clock freq. division setup + { SSITX, 0x000800B5 }, // # Command setting of SPI block + { SSITX, 0x0000011E }, // # VCS Voltage adjustment (1C->1F for Rev 2) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B6 }, // # Command setting of SPI block + { SSITX, 0x00000127 }, // # VCOM Voltage adjustment + { SSITX, 0x000800B7 }, // # Command setting of SPI block + { SSITX, 0x00000103 }, // # Configure an external display signal + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B9 }, // # Command setting of SPI block + { SSITX, 0x00000124 }, // # DCCK/DCEV timing setup + { SSITX, 0x000800BD }, // # Command setting of SPI block + { SSITX, 0x000001A1 }, // # ASW signal control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BB }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Dummy display (white/black) count setup for QUAD Data operation + { SSITX, 0x000800BF }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Dummy display (white/black) count setup for QUAD Data operation + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BE }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # wait_ms(-out FR count setup (A) + { SSITX, 0x000800C0 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (A) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C1 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (B) + { SSITX, 0x000800C2 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (C) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C3 }, // # Command setting of SPI block + { SSITX, 0x00080132 }, // # wait_ms(-in line clock count setup (D) + { SSITX, 0x00000132 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C4 }, // # Command setting of SPI block + { SSITX, 0x00080132 }, // # Seep-in line clock count setup (E) + { SSITX, 0x00000132 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C5 }, // # Command setting of SPI block + { SSITX, 0x00080132 }, // # wait_ms(-in line clock count setup (F) + { SSITX, 0x00000132 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C6 }, // # Command setting of SPI block + { SSITX, 0x00080132 }, // # wait_ms(-in line clock setup (G) + { SSITX, 0x00000132 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C7 }, // # Command setting of SPI block + { SSITX, 0x00080164 }, // # Gamma 1 fine tuning (1) + { SSITX, 0x00000145 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C8 }, // # Command setting of SPI block + { SSITX, 0x00000144 }, // # Gamma 1 fine tuning (2) + { SSITX, 0x000800C9 }, // # Command setting of SPI block + { SSITX, 0x00000152 }, // # Gamma 1 inclination adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CA }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Gamma 1 blue offset adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800EC }, // # Command setting of SPI block + { SSITX, 0x00080102 }, // # Total number of horizontal clock cycles (1) [PCLK Sync. VGA setting] + { SSITX, 0x00000118 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CF }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Blanking period control (1) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D0 }, // # Command setting of SPI block + { SSITX, 0x00080110 }, // # Blanking period control (2) [PCLK Sync. Table1 for VGA] + { SSITX, 0x00000104 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D1 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # CKV timing control on/off [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D2 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV1,2 timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x00000128 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D3 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # OEV timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x00000128 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D4 }, // # Command setting of SPI block + { SSITX, 0x00080126 }, // # ASW timing control (1) [PCLK Sync. Table1 for VGA] + { SSITX, 0x000001A4 }, // + { 0, 1 }, // wait_ms(1); // # Wait SPI fifo empty + { SSITX, 0x000800D5 }, // # Command setting of SPI block + { SSITX, 0x00000120 }, // # ASW timing control (2) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800EF }, // # Command setting of SPI block + { SSITX, 0x00080132 }, // # Total number of horizontal clock cycles (2) [PCLK Sync. Table1 for QVGA ] + { SSITX, 0x00000100 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + + { BITMAP0, 0x032001E0 }, // MDC.BITMAP0 ); // Setup of PITCH size to Frame buffer1 + { BITMAP1, 0x032001E0 }, // MDC.BITMAP1 ); // Setup of PITCH size to Frame buffer1 + { BITMAP2, 0x014000F0 }, // MDC.BITMAP3 ); // Setup of PITCH size to Frame buffer2 + { BITMAP3, 0x014000F0 }, // MDC.BITMAP4 ); // Setup of PITCH size to Frame buffer3 + { BITMAP4, 0x014000F0 }, // MDC.BITMAP5 ); // Setup of PITCH size to Frame buffer4 + { CLKENB, 0x000001EB }, // SYS.CLKENB ); // DCLK supply + { PORT_ENB, 0x00000001 }, // LCD.PORT_ENB ); // Synchronous port enable + { PORT, 0x00000004 }, // LCD.PORT ); // Polarity of DE is set to high active + { PXL, 0x00000002 }, // LCD.PXL ); // ACTMODE 2 set (1st frame black data output) + { MPLFBUF, 0x00000000 }, // LCD.MPLFBUF ); // Select the reading buffer + { HCYCLE, 0x0000010B }, // LCD.HCYCLE ); // Setup to VGA size + { HSW, 0x00000003 }, // LCD.HSW + { HDE_START, 0x00000007 }, // LCD.HDE_START + { HDE_SIZE, 0x000000EF }, // LCD.HDE_SIZE + { VCYCLE, 0x00000325 }, // LCD.VCYCLE + { VSW, 0x00000001 }, // LCD.VSW + { VDE_START, 0x00000003 }, // LCD.VDE_START + { VDE_SIZE, 0x0000031F }, // LCD.VDE_SIZE + + { START, 0x00000001 }, // LCD.START ); // LCDC - Pixel data transfer start + + { 0, 10 }, // wait_ms( 10 ); + { SSITX, 0x000800BC }, // SPI.SSITX ); // Command setting of SPI block + { SSITX, 0x00000180 }, // Display data setup + { SSITX, 0x0008003B }, // Command setting of SPI block + { SSITX, 0x00000100 }, // Quad Data configuration - VGA + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B0 }, // Command setting of SPI block + { SSITX, 0x00000116 }, // Power supply ON/OFF control + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B8 }, // Command setting of SPI block + { SSITX, 0x000801FF }, // Output control + { SSITX, 0x000001F5 }, + { 0, 1 }, // wait_ms( 1); // Wait SPI fifo empty + { SSITX, 0x00000011 }, // wait_ms(-out (Command only) + { 0, 5 }, // wait_ms( 1); // Wait SPI fifo empty + { SSITX, 0x00000029 }, // Display on (Command only) + + //{ SYSTEM_BLOCK1_BASE, 0x00000002 }, // # wakeREQ -> GPIO + + { 0, 0 } +}; + +void mddi_panel_poweron(void) +{ + display_common_power(1); +} + +static void _panel_init(struct init_table *init_table) +{ + unsigned n; + + dprintf(INFO, "panel_init()\n"); + + n = 0; + while (init_table[n].reg != 0 || init_table[n].val != 0) { + if (init_table[n].reg != 0) + mddi_remote_write(init_table[n].val, init_table[n].reg); + else + mdelay(init_table[n].val); + n++; + } + + dprintf(INFO, "panel_init() done\n"); +} + +void panel_init(struct mddi_client_caps *client_caps) +{ + switch(client_caps->manufacturer_name) { + case 0xd263: // Toshiba + dprintf(INFO, "Found Toshiba panel\n"); + _panel_init(toshiba_480x800_init_table); + break; + case 0x4474: //?? + if (client_caps->product_code == 0xc065) + dprintf(INFO, "Found WVGA panel\n"); + break; + } +} +#endif //mddi + +void panel_poweron(void) +{ +#if DISPLAY_TYPE_LCDC + panel_backlight(1); + lcdc_on(); +#endif +} + +void panel_backlight(int on) +{ + unsigned char reg_data = 0xA0; + if(on) + pmic_write(0x132, reg_data); + else + pmic_write(0x132, 0); +} + +static unsigned wega_reset_gpio = +GPIO_CFG(180, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA); + +#define LDO12_CNTRL 0x015 +#define LDO15_CNTRL 0x089 +#define LDO16_CNTRL 0x08A +#define LDO20_CNTRL 0x11F // PM8058 only +#define LDO_LOCAL_EN_BMSK 0x80 + +static int display_common_power(int on) +{ + int rc = 0, flag_on = !!on; + static int display_common_power_save_on; + unsigned int vreg_ldo12, vreg_ldo15, vreg_ldo20, vreg_ldo16, vreg_ldo8; + if (display_common_power_save_on == flag_on) + return 0; + + display_common_power_save_on = flag_on; + + if (on) { + /* reset Toshiba WeGA chip -- toggle reset pin -- gpio_180 */ + rc = gpio_tlmm_config(wega_reset_gpio, GPIO_ENABLE); + if (rc) { + return rc; + } + + gpio_set(180, 0); /* bring reset line low to hold reset*/ + } + + // Set power for WEGA chip. + // Set LD020 to 1.5V + pmic_write(LDO20_CNTRL, 0x00 | LDO_LOCAL_EN_BMSK); + mdelay(5); + + // Set LD012 to 1.8V + pmic_write(LDO12_CNTRL, 0x06 | LDO_LOCAL_EN_BMSK); + mdelay(5); + + // Set LD016 to 2.6V + pmic_write(LDO16_CNTRL, 0x16 | LDO_LOCAL_EN_BMSK); + mdelay(5); + + // Set LD015 to 3.0V + pmic_write(LDO15_CNTRL, 0x1E | LDO_LOCAL_EN_BMSK); + mdelay(5); + + gpio_set(180, 1); /* bring reset line high */ + mdelay(10); /* 10 msec before IO can be accessed */ + if (rc) { + return rc; + } + + return rc; +} + +#if DISPLAY_TYPE_LCDC +static struct msm_gpio lcd_panel_gpios[] = { + { GPIO_CFG(45, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_clk" }, + { GPIO_CFG(46, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_cs0" }, + { GPIO_CFG(47, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_mosi" }, + { GPIO_CFG(48, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA), "spi_miso" } +}; + +int lcdc_toshiba_panel_power(int on) +{ + int rc, i; + struct msm_gpio *gp; + + rc = display_common_power(on); + if (rc < 0) { + return rc; + } + + if (on) { + rc = platform_gpios_enable(lcd_panel_gpios, + ARRAY_SIZE(lcd_panel_gpios)); + if(rc) + { + return rc; + } + } else { /* off */ + gp = lcd_panel_gpios; + for (i = 0; i < ARRAY_SIZE(lcd_panel_gpios); i++) { + /* ouput low */ + gpio_set(GPIO_PIN(gp->gpio_cfg), 0); + gp++; + } + } + + return rc; +} + +#define SPI_SCLK 45 +#define SPI_CS 46 +#define SPI_MOSI 47 +#define SPI_MISO 48 + +static void toshiba_spi_write_byte(char dc, unsigned char data) +{ + unsigned bit; + int bnum; + + gpio_set(SPI_SCLK, 0); /* clk low */ + /* dc: 0 for command, 1 for parameter */ + gpio_set(SPI_MOSI, dc); + mdelay(1); /* at least 20 ns */ + gpio_set(SPI_SCLK, 1); /* clk high */ + mdelay(1); /* at least 20 ns */ + bnum = 8; /* 8 data bits */ + bit = 0x80; + while (bnum) { + gpio_set(SPI_SCLK, 0); /* clk low */ + if (data & bit) + gpio_set(SPI_MOSI, 1); + else + gpio_set(SPI_MOSI, 0); + mdelay(1); + gpio_set(SPI_SCLK, 1); /* clk high */ + mdelay(1); + bit >>= 1; + bnum--; + } +} + +static int toshiba_spi_write (char cmd, unsigned data, int num) +{ + char *bp; + gpio_set(SPI_CS, 1); /* cs high */ + + /* command byte first */ + toshiba_spi_write_byte(0, cmd); + + /* followed by parameter bytes */ + if (num) { + bp = (char *)&data;; + bp += (num - 1); + while (num) { + toshiba_spi_write_byte(1, *bp); + num--; + bp--; + } + } + gpio_set(SPI_CS, 0); /* cs low */ + mdelay(1); + return 0; +} + + +void lcdc_disp_on (void) +{ + gpio_set(SPI_CS, 0); /* low */ + gpio_set(SPI_SCLK, 1); /* high */ + gpio_set(SPI_MOSI, 0); + gpio_set(SPI_MISO, 0); + + if (1) { + toshiba_spi_write(0, 0, 0); + mdelay(7); + toshiba_spi_write(0, 0, 0); + mdelay(7); + toshiba_spi_write(0, 0, 0); + mdelay(7); + toshiba_spi_write(0xba, 0x11, 1); + toshiba_spi_write(0x36, 0x00, 1); + mdelay(1); + toshiba_spi_write(0x3a, 0x60, 1); + toshiba_spi_write(0xb1, 0x5d, 1); + mdelay(1); + toshiba_spi_write(0xb2, 0x33, 1); + toshiba_spi_write(0xb3, 0x22, 1); + mdelay(1); + toshiba_spi_write(0xb4, 0x02, 1); + toshiba_spi_write(0xb5, 0x1e, 1); /* vcs -- adjust brightness */ + mdelay(1); + toshiba_spi_write(0xb6, 0x27, 1); + toshiba_spi_write(0xb7, 0x03, 1); + mdelay(1); + toshiba_spi_write(0xb9, 0x24, 1); + toshiba_spi_write(0xbd, 0xa1, 1); + mdelay(1); + toshiba_spi_write(0xbb, 0x00, 1); + toshiba_spi_write(0xbf, 0x01, 1); + mdelay(1); + toshiba_spi_write(0xbe, 0x00, 1); + toshiba_spi_write(0xc0, 0x11, 1); + mdelay(1); + toshiba_spi_write(0xc1, 0x11, 1); + toshiba_spi_write(0xc2, 0x11, 1); + mdelay(1); + toshiba_spi_write(0xc3, 0x3232, 2); + mdelay(1); + toshiba_spi_write(0xc4, 0x3232, 2); + mdelay(1); + toshiba_spi_write(0xc5, 0x3232, 2); + mdelay(1); + toshiba_spi_write(0xc6, 0x3232, 2); + mdelay(1); + toshiba_spi_write(0xc7, 0x6445, 2); + mdelay(1); + toshiba_spi_write(0xc8, 0x44, 1); + toshiba_spi_write(0xc9, 0x52, 1); + mdelay(1); + toshiba_spi_write(0xca, 0x00, 1); + mdelay(1); + toshiba_spi_write(0xec, 0x02a4, 2); /* 0x02a4 */ + mdelay(1); + toshiba_spi_write(0xcf, 0x01, 1); + mdelay(1); + toshiba_spi_write(0xd0, 0xc003, 2); /* c003 */ + mdelay(1); + toshiba_spi_write(0xd1, 0x01, 1); + mdelay(1); + toshiba_spi_write(0xd2, 0x0028, 2); + mdelay(1); + toshiba_spi_write(0xd3, 0x0028, 2); + mdelay(1); + toshiba_spi_write(0xd4, 0x26a4, 2); + mdelay(1); + toshiba_spi_write(0xd5, 0x20, 1); + mdelay(1); + toshiba_spi_write(0xef, 0x3200, 2); + mdelay(32); + toshiba_spi_write(0xbc, 0x80, 1); /* wvga pass through */ + toshiba_spi_write(0x3b, 0x00, 1); + mdelay(1); + toshiba_spi_write(0xb0, 0x16, 1); + mdelay(1); + toshiba_spi_write(0xb8, 0xfff5, 2); + mdelay(1); + toshiba_spi_write(0x11, 0, 0); + mdelay(5); + toshiba_spi_write(0x29, 0, 0); + mdelay(5); + } +} + +void lcdc_on(void) +{ + lcdc_clock_init(27648000); + lcdc_toshiba_panel_power(1); + lcdc_disp_on(); +} + +#endif diff --git a/lk/platform/msm7x30/platform.c b/lk/platform/msm7x30/platform.c new file mode 100644 index 0000000..5480e24 --- /dev/null +++ b/lk/platform/msm7x30/platform.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include + +#include +#include +#include +#include +#include +#include "gpio_hw.h" + +void platform_init_interrupts(void); +void platform_init_timer(); + +void uart2_clock_init(void); +void uart_init(void); + +struct fbcon_config *lcdc_init(void); + +#define ARRAY_SIZE(a) (sizeof(a)/(sizeof((a)[0]))) + +static unsigned uart2_gpio_table[] = { + GPIO_CFG(49, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), + GPIO_CFG(50, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), + GPIO_CFG(51, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), + GPIO_CFG(52, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), +}; + +void uart2_mux_init(void) +{ + platform_gpios_enable(uart2_gpio_table, ARRAY_SIZE(uart2_gpio_table)); +} + +void platform_early_init(void) +{ +#if WITH_DEBUG_UART + uart2_mux_init(); + uart2_clock_init(); + uart_init(); +#endif + platform_init_interrupts(); + platform_init_timer(); +} + +void platform_init(void) +{ + struct fbcon_config *fb_cfg; + + dprintf(INFO, "platform_init()\n"); + acpu_clock_init(); + adm_enable_clock(); +} + +void mdp4_display_intf_sel(int output, int intf) +{ + unsigned bits, mask; + unsigned dma2_cfg_reg; + bits = readl(MSM_MDP_BASE1 + 0x0038); + mask = 0x03; /* 2 bits */ + intf &= 0x03; /* 2 bits */ + + switch (output) { + case EXTERNAL_INTF_SEL: + intf <<= 4; + mask <<= 4; + break; + case SECONDARY_INTF_SEL: + intf &= 0x02; /* only MDDI and EBI2 support */ + intf <<= 2; + mask <<= 2; + break; + default: + break; + } + + bits &= ~mask; + bits |= intf; + writel(bits, MSM_MDP_BASE1 + 0x0038); /* MDP_DISP_INTF_SEL */ +} + + + +void display_init(void) +{ + struct fbcon_config *fb_cfg; + +#if DISPLAY_TYPE_MDDI + mddi_clock_init(0, 480000000); + mddi_panel_poweron(); + /* We need to config GPIO 38 for Sleep clock with Spl Fun 2 */ + toshiba_pmic_gpio_init(GPIO38_GPIO_CNTRL); + fb_cfg = mddi_init(); + fbcon_setup(fb_cfg); +#endif + +#if DISPLAY_TYPE_LCDC + mdp_clock_init(122880000); + fb_cfg = lcdc_init(); + panel_poweron(); + fbcon_setup(fb_cfg); +#endif +} + +void display_shutdown(void) +{ +#if DISPLAY_TYPE_LCDC + /* Turning off LCDC */ + lcdc_shutdown(); +#endif +} + diff --git a/lk/platform/msm7x30/rules.mk b/lk/platform/msm7x30/rules.mk new file mode 100644 index 0000000..8bb591a --- /dev/null +++ b/lk/platform/msm7x30/rules.mk @@ -0,0 +1,29 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +ARCH := arm +ARM_CPU := cortex-a8 +#arm1136j-s +CPU := generic + +MMC_SLOT := 2 + +DEFINES += WITH_CPU_EARLY_INIT=1 WITH_CPU_WARM_BOOT=1 \ + MMC_SLOT=$(MMC_SLOT) MDP4=1 + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/target/$(TARGET)/include + +DEVS += fbcon +MODULES += dev/fbcon + +OBJS += \ + $(LOCAL_DIR)/arch_init.o \ + $(LOCAL_DIR)/platform.o \ + $(LOCAL_DIR)/interrupts.o \ + $(LOCAL_DIR)/gpio.o \ + $(LOCAL_DIR)/panel.o \ + $(LOCAL_DIR)/acpuclock.o + +LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld + +include platform/msm_shared/rules.mk + diff --git a/lk/platform/msm8x60/acpuclock.c b/lk/platform/msm8x60/acpuclock.c new file mode 100644 index 0000000..37d49b0 --- /dev/null +++ b/lk/platform/msm8x60/acpuclock.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +/* Read, modify, then write-back a register. */ +static void rmwreg(uint32_t val, uint32_t reg, uint32_t mask) +{ + uint32_t regval = readl(reg); + regval &= ~mask; + regval |= val; + writel(regval, reg); +} + + +/* Enable/disable for non-shared NT PLLs. */ +int nt_pll_enable(uint8_t src, uint8_t enable) +{ + static const struct { + uint32_t const mode_reg; + uint32_t const status_reg; + } pll_reg[] = { + [PLL_1] = { MM_PLL0_MODE_REG, MM_PLL0_STATUS_REG }, + [PLL_2] = { MM_PLL1_MODE_REG, MM_PLL1_STATUS_REG }, + [PLL_3] = { MM_PLL2_MODE_REG, MM_PLL2_STATUS_REG }, + }; + uint32_t pll_mode; + + pll_mode = readl(pll_reg[src].mode_reg); + if (enable) { + /* Disable PLL bypass mode. */ + pll_mode |= (1<<1); + writel( pll_mode, pll_reg[src].mode_reg); + + /* H/W requires a 5us delay between disabling the bypass and + * de-asserting the reset. Delay 10us just to be safe. */ + udelay(10); + + /* De-assert active-low PLL reset. */ + pll_mode |= (1<<2); + writel( pll_mode, pll_reg[src].mode_reg); + + /* Enable PLL output. */ + pll_mode |= (1<<0); + writel( pll_mode, pll_reg[src].mode_reg); + + /* Wait until PLL is enabled. */ + while (!readl(pll_reg[src].status_reg)); + } else { + /* Disable the PLL output, disable test mode, enable + * the bypass mode, and assert the reset. */ + pll_mode &= 0xFFFFFFF0; + writel( pll_mode, pll_reg[src].mode_reg); + } + + return 0; +} + + +/* Write the M,N,D values and enable the MDP Core Clock */ +void config_mdp_clk( uint32_t ns, + uint32_t md, + uint32_t cc, + uint32_t ns_addr, + uint32_t md_addr, + uint32_t cc_addr) +{ + int val = 0; + + /* MN counter reset */ + val = 1 << 31; + writel(val, ns_addr); + + /* Write the MD and CC register values */ + writel(md, md_addr); + writel(cc, cc_addr); + + /* Reset the clk control, and Write ns val */ + val = 1 << 31; + val |= ns; + writel(val, ns_addr); + + /* Clear MN counter reset */ + val = 1 << 31; + val = ~val; + val = val & readl(ns_addr); + writel(val, ns_addr); + + /* Enable MND counter */ + val = 1 << 8; + val = val | readl(cc_addr); + writel(val, cc_addr); + + /* Enable the root of the clock tree */ + val = 1 << 2; + val = val | readl(cc_addr); + writel(val, cc_addr); + + /* Enable the MDP Clock */ + val = 1 << 0; + val = val | readl(cc_addr); + writel(val, cc_addr); +} + +/* Write the M,N,D values and enable the Pixel Core Clock */ +void config_pixel_clk( uint32_t ns, + uint32_t md, + uint32_t cc, + uint32_t ns_addr, + uint32_t md_addr, + uint32_t cc_addr){ + unsigned int val = 0; + + /* Activate the reset for the M/N Counter */ + val = 1 << 7; + writel(val, ns_addr); + + /* Write the MD and CC register values */ + writel(md, md_addr); + writel(cc, cc_addr); + + /* Write the ns value, and active reset for M/N Counter, again */ + val = 1 << 7; + val |= ns; + writel(val, ns_addr); + + /* De-activate the reset for M/N Counter */ + val = 1 << 7; + val = ~val; + val = val & readl(ns_addr); + writel(val, ns_addr); + + /* Enable MND counter */ + val = 1 << 5; + val = val | readl(cc_addr); + writel(val, cc_addr); + + /* Enable the root of the clock tree */ + val = 1 << 2; + val = val | readl(cc_addr); + writel(val, cc_addr); + + /* Enable the MDP Clock */ + val = 1 << 0; + val = val | readl(cc_addr); + writel(val, cc_addr); + + /* Enable the LCDC Clock */ + val = 1 << 8; + val = val | readl(cc_addr); + writel(val, cc_addr); +} + +/* Set rate and enable the clock */ +void clock_config(uint32_t ns, + uint32_t md, + uint32_t ns_addr, + uint32_t md_addr) +{ + unsigned int val = 0; + + /* Activate the reset for the M/N Counter */ + val = 1 << 7; + writel(val, ns_addr); + + /* Write the MD value into the MD register */ + writel(md, md_addr); + + /* Write the ns value, and active reset for M/N Counter, again */ + val = 1 << 7; + val |= ns; + writel(val, ns_addr); + + /* De-activate the reset for M/N Counter */ + val = 1 << 7; + val = ~val; + val = val & readl(ns_addr); + writel(val, ns_addr); + + /* Enable the M/N Counter */ + val = 1 << 8; + val = val | readl(ns_addr); + writel(val, ns_addr); + + /* Enable the Clock Root */ + val = 1 << 11; + val = val | readl(ns_addr); + writel(val, ns_addr); + + /* Enable the Clock Branch */ + val = 1 << 9; + val = val | readl(ns_addr); + writel(val, ns_addr); +} + +void acpu_clock_init (void) +{ +} + +void hsusb_clock_init(void) +{ + int val; + /* Vote for PLL8 */ + val = readl(0x009034C0); + val |= (1<<8); + writel(val, 0x009034C0); + /* Wait until PLL is enabled. */ + while (!(readl(0x00903158) & (1<<16))); + + //Set 7th bit in NS Register + val = 1 << 7; + writel(val, USB_HS1_XVCR_FS_CLK_NS); + + //Set rate specific value in MD + writel(0x000500DF, USB_HS1_XVCR_FS_CLK_MD); + + //Set value in NS register + val = 1 << 7; + val |= 0x00E400C3; + writel(val, USB_HS1_XVCR_FS_CLK_NS); + + // Clear 7th bit + val = 1 << 7; + val = ~val; + val = val & readl(USB_HS1_XVCR_FS_CLK_NS); + writel(val, USB_HS1_XVCR_FS_CLK_NS); + + //set 11th bit + val = 1 << 11; + val |= readl(USB_HS1_XVCR_FS_CLK_NS); + writel(val, USB_HS1_XVCR_FS_CLK_NS); + + //set 9th bit + val = 1 << 9; + val |= readl(USB_HS1_XVCR_FS_CLK_NS); + writel(val, USB_HS1_XVCR_FS_CLK_NS); + + //set 8th bit + val = 1 << 8; + val |= readl(USB_HS1_XVCR_FS_CLK_NS); + writel(val, USB_HS1_XVCR_FS_CLK_NS); +} + diff --git a/lk/platform/msm8x60/gpio.c b/lk/platform/msm8x60/gpio.c new file mode 100644 index 0000000..021678e --- /dev/null +++ b/lk/platform/msm8x60/gpio.c @@ -0,0 +1,48 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include + +void gpio_tlmm_config(uint32_t gpio, uint8_t func, + uint8_t dir, uint8_t pull, + uint8_t drvstr, uint32_t enable) +{ + unsigned int val = 0; + val |= pull; + val |= func << 2; + val |= drvstr << 6; + val |= enable << 9; + unsigned int *addr = (unsigned int *)GPIO_BASE_ADDR(gpio); + writel(val, addr); + return; +} diff --git a/lk/platform/msm8x60/include/platform/clock.h b/lk/platform/msm8x60/include/platform/clock.h new file mode 100644 index 0000000..fc6ff46 --- /dev/null +++ b/lk/platform/msm8x60/include/platform/clock.h @@ -0,0 +1,105 @@ +/* + * * Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 __PLATFORM_MSM8X60_CLOCK_H +#define __PLATFORM_MSM8X60_CLOCK_H + +/* MMSS CLK CTR base address */ +#define MSM_MMSS_CLK_CTL 0x04000000 +#define REG_MM(off) (MSM_MMSS_CLK_CTL + (off)) + +#define AHB_NS_REG REG_MM(0x0004) +#define AXI_NS_REG REG_MM(0x0014) +#define MM_PLL0_CONFIG_REG REG_MM(0x0310) +#define MM_PLL0_L_VAL_REG REG_MM(0x0304) +#define MM_PLL0_M_VAL_REG REG_MM(0x0308) +#define MM_PLL0_MODE_REG REG_MM(0x0300) +#define MM_PLL0_N_VAL_REG REG_MM(0x030C) +#define MM_PLL0_STATUS_REG REG_MM(0x0318) +#define MM_PLL1_CONFIG_REG REG_MM(0x032C) +#define MM_PLL1_L_VAL_REG REG_MM(0x0320) +#define MM_PLL1_M_VAL_REG REG_MM(0x0324) +#define MM_PLL1_MODE_REG REG_MM(0x031C) +#define MM_PLL1_N_VAL_REG REG_MM(0x0328) +#define MM_PLL1_STATUS_REG REG_MM(0x0334) +#define MM_PLL2_CONFIG_REG REG_MM(0x0348) +#define MM_PLL2_L_VAL_REG REG_MM(0x033C) +#define MM_PLL2_M_VAL_REG REG_MM(0x0340) +#define MM_PLL2_MODE_REG REG_MM(0x0338) +#define MM_PLL2_N_VAL_REG REG_MM(0x0344) +#define MM_PLL2_STATUS_REG REG_MM(0x0350) + +/* LCD related clock defines */ +#define MMSS_AHB_NS_REG (MSM_MMSS_CLK_CTL + 0x04) +#define MMSS_AHB_EN_REG (MSM_MMSS_CLK_CTL + 0x08) +#define MMSS_AXI_NS_REG (MSM_MMSS_CLK_CTL + 0x14) +#define MMSS_MAXI_EN_REG (MSM_MMSS_CLK_CTL + 0x18) +#define MMSS_MAXI_EN2_REG (MSM_MMSS_CLK_CTL + 0x20) +#define MMSS_SAXI_EN_REG (MSM_MMSS_CLK_CTL + 0x30) + +#define MDP_CC_REG (MSM_MMSS_CLK_CTL + 0xC0) +#define MDP_MD_REG (MSM_MMSS_CLK_CTL + 0xC4) +#define MDP_NS_REG (MSM_MMSS_CLK_CTL + 0xD0) +#define LCD_PIXEL_CC_REG (MSM_MMSS_CLK_CTL + 0xD4) +#define LCD_PIXEL_NS_REG (MSM_MMSS_CLK_CTL + 0xDC) +#define LCD_PIXEL_MD_REG (MSM_MMSS_CLK_CTL + 0xD8) + +/* Configured at 200 MHz */ +#define MDP_NS_VAL 0x3F000008 +#define MDP_MD_VAL 0x000001FB +#define MDP_CC_VAL 0x00000400 + +/* Configured at 53.99 MHz */ +#define PIXEL_NS_VAL 0xFE4F4002 +#define PIXEL_MD_VAL 0x00A9FDA6 +#define PIXEL_CC_VAL 0x00000080 + +#define MSM_CLK_CTL_BASE 0x00900000 +#define BB_PLL8_L_VAL_REG (MSM_CLK_CTL_BASE + 0x3144) +#define BB_PLL8_M_VAL_REG (MSM_CLK_CTL_BASE + 0x3148) +#define BB_PLL8_MODE_REG (MSM_CLK_CTL_BASE + 0x3140) +#define BB_PLL8_N_VAL_REG (MSM_CLK_CTL_BASE + 0x314C) + + +enum clk_sources { + PLL_0 = 0, + PLL_1, + PLL_2, + PLL_3, + PLL_4, + PLL_5, + PLL_6, + PLL_7, + PLL_8, + MXO, + PXO, + CXO, + NUM_SRC +}; + +#endif diff --git a/lk/platform/msm8x60/include/platform/gpio_hw.h b/lk/platform/msm8x60/include/platform/gpio_hw.h new file mode 100644 index 0000000..14f0762 --- /dev/null +++ b/lk/platform/msm8x60/include/platform/gpio_hw.h @@ -0,0 +1,60 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 __PLATFORM_MSM8X60_GPIO_HW_H +#define __PLATFORM_MSM8X60_GPIO_HW_H + +#define TLMM_BASE_ADDR (0x800000) +#define GPIO_BASE (0x1000) +#define GPIO_BASE_ADDR(x) (TLMM_BASE_ADDR + GPIO_BASE + (x)*0x10) + +/* GPIO TLMM: Direction */ +#define GPIO_INPUT 0 +#define GPIO_OUTPUT 1 + +/* GPIO TLMM: Pullup/Pulldown */ +#define GPIO_NO_PULL 0 +#define GPIO_PULL_DOWN 1 +#define GPIO_KEEPER 2 +#define GPIO_PULL_UP 3 + +/* GPIO TLMM: Drive Strength */ +#define GPIO_2MA 0 +#define GPIO_4MA 1 +#define GPIO_6MA 2 +#define GPIO_8MA 3 +#define GPIO_10MA 4 +#define GPIO_12MA 5 +#define GPIO_14MA 6 +#define GPIO_16MA 7 + +/* GPIO TLMM: Status */ +#define GPIO_ENABLE 0 +#define GPIO_DISABLE 1 + +#endif diff --git a/lk/platform/msm8x60/include/platform/iomap.h b/lk/platform/msm8x60/include/platform/iomap.h new file mode 100644 index 0000000..e7d23db --- /dev/null +++ b/lk/platform/msm8x60/include/platform/iomap.h @@ -0,0 +1,138 @@ +/* Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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 _PLATFORM_MSM8X60_IOMAP_H_ +#define _PLATFORM_MSM8X60_IOMAP_H_ + +#define MSM_UART3_BASE 0xA9C00000 + +#define MSM_VIC_BASE 0x02080000 +#define MSM_TMR_BASE 0x02000000 +#define MSM_GPT_BASE (MSM_TMR_BASE + 0x04) +#define MSM_CSR_BASE 0x02081000 +#define MSM_GCC_BASE 0x02082000 +#define MSM_ACC0_BASE 0x02041000 +#define MSM_ACC1_BASE 0x02051000 + +#define MSM_TCSR_BASE 0x16B00000 +#define TCSR_WDOG_CFG 0x30 +#define MSM_WDT0_RST (MSM_TMR_BASE + 0x38) +#define MSM_WDT0_EN (MSM_TMR_BASE + 0x40) +#define MSM_WDT0_BT (MSM_TMR_BASE + 0x4C) + +#define MSM_GIC_CPU_BASE 0x02081000 +#define MSM_GIC_DIST_BASE 0x02080000 + +#define MSM_SDC1_BASE 0x12400000 + +#define MSM_SHARED_BASE 0x40000000 + +#define SURF_DEBUG_LED_ADDR 0x1D000202 + +#define GPIO_CFG133_ADDR 0x00801850 +#define GPIO_CFG135_ADDR 0x00801870 +#define GPIO_CFG136_ADDR 0x00801880 +#define GPIO_CFG137_ADDR 0x00801890 +#define GPIO_CFG138_ADDR 0x008018A0 +#define GPIO_CFG139_ADDR 0x008018B0 +#define GPIO_CFG140_ADDR 0x008018C0 +#define GPIO_CFG141_ADDR 0x008018D0 +#define GPIO_CFG142_ADDR 0x008018E0 +#define GPIO_CFG143_ADDR 0x008018F0 +#define GPIO_CFG144_ADDR 0x00801900 +#define GPIO_CFG145_ADDR 0x00801910 +#define GPIO_CFG146_ADDR 0x00801920 +#define GPIO_CFG147_ADDR 0x00801930 +#define GPIO_CFG148_ADDR 0x00801940 +#define GPIO_CFG149_ADDR 0x00801950 +#define GPIO_CFG150_ADDR 0x00801960 +#define GPIO_CFG151_ADDR 0x00801970 +#define GPIO_CFG152_ADDR 0x00801980 +#define GPIO_CFG153_ADDR 0x00801990 +#define GPIO_CFG154_ADDR 0x008019A0 +#define GPIO_CFG155_ADDR 0x008019B0 +#define GPIO_CFG156_ADDR 0x008019C0 +#define GPIO_CFG157_ADDR 0x008019D0 +#define GPIO_CFG158_ADDR 0x008019E0 + +#define GSBI1_BASE (0x16000000) +#define GSBI2_BASE (0x16100000) +#define GSBI3_BASE (0x16200000) +#define GSBI4_BASE (0x16300000) +#define GSBI5_BASE (0x16400000) +#define GSBI6_BASE (0x16500000) +#define GSBI7_BASE (0x16600000) +#define GSBI8_BASE (0x19800000) +#define GSBI9_BASE (0x19900000) +#define GSBI10_BASE (0x19A00000) +#define GSBI11_BASE (0x19B00000) +#define GSBI12_BASE (0x19C00000) + +#define GSBI1_QUP_BASE (GSBI1_BASE + 0x80000) +#define GSBI2_QUP_BASE (GSBI2_BASE + 0x80000) +#define GSBI3_QUP_BASE (GSBI3_BASE + 0x80000) +#define GSBI4_QUP_BASE (GSBI4_BASE + 0x80000) +#define GSBI5_QUP_BASE (GSBI5_BASE + 0x80000) +#define GSBI6_QUP_BASE (GSBI6_BASE + 0x80000) +#define GSBI7_QUP_BASE (GSBI7_BASE + 0x80000) +#define GSBI8_QUP_BASE (GSBI8_BASE + 0x80000) +#define GSBI9_QUP_BASE (GSBI9_BASE + 0x80000) +#define GSBI10_QUP_BASE (GSBI10_BASE + 0x80000) +#define GSBI11_QUP_BASE (GSBI11_BASE + 0x80000) +#define GSBI12_QUP_BASE (GSBI12_BASE + 0x80000) + +#define GSBI_CTL_PROTOCOL_CODE_I2C (0x20) + +#define CLK_CTL_BASE 0x00900000 + +#define GSBIn_HCLK_CTL(n) ((CLK_CTL_BASE) + 0x29C0 + (32 * ((n) - 1))) +#define GSBIn_HCLK_FS(n) ((CLK_CTL_BASE) + 0x29C4 + (32 * ((n) - 1))) +#define GSBIn_QUP_APPS_MD(n) ((CLK_CTL_BASE) + 0x29C8 + (32 * ((n) - 1))) +#define GSBIn_QUP_APPS_NS(n) ((CLK_CTL_BASE) + 0x29CC + (32 * ((n) - 1))) + +/* Defines for the GPIO EXPANDER chip, SX1509QIULTRT */ +#define GPIO_EXPANDER_REG_OPEN_DRAIN_A (0x0B) +#define GPIO_EXPANDER_REG_DIR_B (0x0E) +#define GPIO_EXPANDER_REG_DIR_A (0x0F) +#define GPIO_EXPANDER_REG_DATA_B (0x10) +#define GPIO_EXPANDER_REG_DATA_A (0x11) +#define CORE_GPIO_EXPANDER_I2C_ADDRESS (0x3E) +#define EEPROM_I2C_ADDRESS (0x52) + +#define EBI2_CHIP_SELECT_CFG0 0x1A100000 +#define EBI2_XMEM_CS3_CFG1 0x1A110034 + +#define MSM_USB_BASE 0x12500000 +#define USB_HS1_XVCR_FS_CLK_MD 0x00902908 +#define USB_HS1_XVCR_FS_CLK_NS 0x0090290C + +#endif diff --git a/lk/platform/msm8x60/include/platform/irqs.h b/lk/platform/msm8x60/include/platform/irqs.h new file mode 100644 index 0000000..7fbf37e --- /dev/null +++ b/lk/platform/msm8x60/include/platform/irqs.h @@ -0,0 +1,75 @@ +/* Copyright (c) 2009-2010, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT 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 __ASM_ARCH_MSM_IRQS_8x60_H +#define __ASM_ARCH_MSM_IRQS_8x60_H + +/* MSM ACPU Interrupt Numbers */ + +#define GIC_PPI_START 16 +#define GIC_SPI_START 32 +#define INT_DEBUG_TIMER_EXP (GIC_PPI_START + 0) + +#define USB1_HS_IRQ (GIC_SPI_START + 100) +#define USB1_HS_BAM_IRQ (GIC_SPI_START + 94) +#define USB2_IRQ (GIC_SPI_START + 141) +#define USB1_IRQ (GIC_SPI_START + 142) +#define GSBI1_QUP_IRQ (GIC_SPI_START + 147) +#define GSBI2_UART_IRQ (GIC_SPI_START + 148) +#define GSBI2_QUP_IRQ (GIC_SPI_START + 149) +#define GSBI3_UART_IRQ (GIC_SPI_START + 150) +#define GSBI3_QUP_IRQ (GIC_SPI_START + 151) +#define GSBI4_UART_IRQ (GIC_SPI_START + 152) +#define GSBI4_QUP_IRQ (GIC_SPI_START + 153) +#define GSBI5_UART_IRQ (GIC_SPI_START + 154) +#define GSBI5_QUP_IRQ (GIC_SPI_START + 155) +#define GSBI6_UART_IRQ (GIC_SPI_START + 156) +#define GSBI6_QUP_IRQ (GIC_SPI_START + 157) +#define GSBI7_UART_IRQ (GIC_SPI_START + 158) +#define GSBI7_QUP_IRQ (GIC_SPI_START + 159) +#define GSBI8_UART_IRQ (GIC_SPI_START + 160) +#define GSBI8_QUP_IRQ (GIC_SPI_START + 161) +#define GSBI9_UART_IRQ (GIC_SPI_START + 189) +#define GSBI9_QUP_IRQ (GIC_SPI_START + 190) +#define GSBI10_UART_IRQ (GIC_SPI_START + 191) +#define GSBI10_QUP_IRQ (GIC_SPI_START + 192) +#define GSBI11_UART_IRQ (GIC_SPI_START + 193) +#define GSBI11_QUP_IRQ (GIC_SPI_START + 194) +#define GSBI12_UART_IRQ (GIC_SPI_START + 195) +#define GSBI12_QUP_IRQ (GIC_SPI_START + 196) + +/* Retrofit universal macro names */ +#define INT_USB_HS USB1_HS_IRQ + +#define NR_MSM_IRQS 256 +#define NR_GPIO_IRQS 173 +#define NR_BOARD_IRQS 0 + +#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS) + +#endif /* __ASM_ARCH_MSM_IRQS_8x60_H */ diff --git a/lk/platform/msm8x60/include/platform/pmic.h b/lk/platform/msm8x60/include/platform/pmic.h new file mode 100644 index 0000000..d761d9c --- /dev/null +++ b/lk/platform/msm8x60/include/platform/pmic.h @@ -0,0 +1,85 @@ +/* + * * Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 __PLATFORM_MSM8X60_PMIC_H +#define __PLATFORM_MSM8X60_PMIC_H + +/* PMIC 8901 LDO Module defines */ +#define PM8901_LDO_BASE (0x2F) + +#define PM8901_LDO_L0 (PM8901_LDO_BASE + 0x00) +#define PM8901_LDO_L0_TEST_BANK (PM8901_LDO_BASE + 0x01) +#define PM8901_LDO_L1 (PM8901_LDO_BASE + 0x02) +#define PM8901_LDO_L1_TEST_BANK (PM8901_LDO_BASE + 0x03) +#define PM8901_LDO_L2 (PM8901_LDO_BASE + 0x04) +#define PM8901_LDO_L2_TEST_BANK (PM8901_LDO_BASE + 0x05) +#define PM8901_LDO_L3 (PM8901_LDO_BASE + 0x06) +#define PM8901_LDO_L3_TEST_BANK (PM8901_LDO_BASE + 0x07) +#define PM8901_LDO_L4 (PM8901_LDO_BASE + 0x08) +#define PM8901_LDO_L4_TEST_BANK (PM8901_LDO_BASE + 0x09) +#define PM8901_LDO_L5 (PM8901_LDO_BASE + 0x0A) +#define PM8901_LDO_L5_TEST_BANK (PM8901_LDO_BASE + 0x0B) +#define PM8901_LDO_L6 (PM8901_LDO_BASE + 0x0C) +#define PM8901_LDO_L6_TEST_BANK (PM8901_LDO_BASE + 0x0D) +#define PM8901_LDO_L7 (PM8901_LDO_BASE + 0x0E) +#define PM8901_LDO_L7_TEST_BANK (PM8901_LDO_BASE + 0x0F) + +#define PM8901_LDO_TEST_BANK(n) ((n)<<4) + +#define PM8901_LDO_CTL_ENABLE__S (7) +#define PM8901_LDO_CTL_PULL_DOWN__S (6) +#define PM8901_LDO_CTL_MODE__S (5) +/* LDO CTL */ +#define LDO_CTL_ENABLE_MASK (0x80) +#define LDO_CTL_PULL_DOWN_MASK (0x40) +#define LDO_CTL_NORMAL_POWER_MODE_MASK (0x20) +#define LDO_CTL_VOLTAGE_SET_MASK (0x1F) + +/* LDO TEST BANK 2 */ +#define LDO_TEST_RANGE_SELECT_MASK (0x01) + +/* LDO TEST BANK 4 */ +#define LDO_TEST_OUTPUT_RANGE_MASK (0x01) + +/* LDO TEST BANK 5 */ +#define LDO_TEST_XO_EN_ALL_MASK (0x1F) + +/* PMIC 8058 defines */ +#define LPG_CTL_0 (0x13C) +#define LPG_CTL_1 (0x13D) +#define LPG_CTL_2 (0x13E) +#define LPG_CTL_3 (0x13F) +#define LPG_CTL_4 (0x140) +#define LPG_CTL_5 (0x141) +#define LPG_CTL_6 (0x142) +#define LPG_BANK_SEL (0x143) +#define LPG_BANK_ENABLE (0x144) +#define GPIO24_GPIO_CNTRL (0x167) +#define GPIO25_GPIO_CNTRL (0x168) + +#endif diff --git a/lk/platform/msm8x60/interrupts.c b/lk/platform/msm8x60/interrupts.c new file mode 100644 index 0000000..8118981 --- /dev/null +++ b/lk/platform/msm8x60/interrupts.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define GIC_CPU_REG(off) (MSM_GIC_CPU_BASE + (off)) +#define GIC_DIST_REG(off) (MSM_GIC_DIST_BASE + (off)) + +#define GIC_CPU_CTRL GIC_CPU_REG(0x00) +#define GIC_CPU_PRIMASK GIC_CPU_REG(0x04) +#define GIC_CPU_BINPOINT GIC_CPU_REG(0x08) +#define GIC_CPU_INTACK GIC_CPU_REG(0x0c) +#define GIC_CPU_EOI GIC_CPU_REG(0x10) +#define GIC_CPU_RUNNINGPRI GIC_CPU_REG(0x14) +#define GIC_CPU_HIGHPRI GIC_CPU_REG(0x18) + +#define GIC_DIST_CTRL GIC_DIST_REG(0x000) +#define GIC_DIST_CTR GIC_DIST_REG(0x004) +#define GIC_DIST_ENABLE_SET GIC_DIST_REG(0x100) +#define GIC_DIST_ENABLE_CLEAR GIC_DIST_REG(0x180) +#define GIC_DIST_PENDING_SET GIC_DIST_REG(0x200) +#define GIC_DIST_PENDING_CLEAR GIC_DIST_REG(0x280) +#define GIC_DIST_ACTIVE_BIT GIC_DIST_REG(0x300) +#define GIC_DIST_PRI GIC_DIST_REG(0x400) +#define GIC_DIST_TARGET GIC_DIST_REG(0x800) +#define GIC_DIST_CONFIG GIC_DIST_REG(0xc00) +#define GIC_DIST_SOFTINT GIC_DIST_REG(0xf00) + +struct ihandler { + int_handler func; + void *arg; +}; + +static struct ihandler handler[NR_IRQS]; + +void platform_init_interrupts(void) +{ + platform_gic_dist_init(); + platform_gic_cpu_init(); +} + +void platform_gic_dist_init(void) +{ + unsigned int i; + unsigned num_irq = 0; + unsigned cpumask = 1; + + cpumask |= cpumask << 8; + cpumask |= cpumask << 16; + + /* Disabling GIC */ + writel(0, GIC_DIST_CTRL); + + /* + * Find out how many interrupts are supported. + */ + num_irq = readl(GIC_DIST_CTR) & 0x1f; + num_irq = (num_irq + 1) * 32; + + /* Set each interrupt line to use N-N software model + and edge sensitive, active high */ + for (i=32; i < num_irq; i += 16) + writel(0xffffffff, GIC_DIST_CONFIG + i * 4/16 ); + + writel(0xffffffff, GIC_DIST_CONFIG + 4); + + /* Set up interrupts for this CPU */ + for (i = 32; i < num_irq; i += 4) + writel(cpumask, GIC_DIST_TARGET + i * 4 / 4); + + /* Set priority of all interrupts*/ + + /* + * In bootloader we dont care about priority so + * setting up equal priorities for all + */ + for (i=0; i < num_irq; i += 4) + writel(0xa0a0a0a0, GIC_DIST_PRI + i * 4/4); + + /*Disabling interrupts*/ + for (i=0; i < num_irq; i += 32) + writel(0xffffffff, GIC_DIST_ENABLE_CLEAR + i * 4/32); + + writel(0x0000ffff, GIC_DIST_ENABLE_SET); + + /*Enabling GIC*/ + writel(1, GIC_DIST_CTRL); +} + +void platform_gic_cpu_init(void) +{ + writel(0xf0, GIC_CPU_PRIMASK); + writel(1, GIC_CPU_CTRL); +} + +enum handler_return platform_irq(struct arm_iframe *frame) +{ + unsigned num; + enum handler_return ret; + num = readl(GIC_CPU_INTACK); + if (num > NR_IRQS) + return 0; + ret = handler[num].func(handler[num].arg); + writel(num, GIC_CPU_EOI); + return ret; +} + +void platform_fiq(struct arm_iframe *frame) +{ + PANIC_UNIMPLEMENTED; +} + +status_t mask_interrupt(unsigned int vector) +{ + unsigned reg = GIC_DIST_ENABLE_CLEAR + (vector/32)*4; + unsigned bit = 1 << (vector & 31); + writel(bit, reg); + return 0; +} + +status_t unmask_interrupt(unsigned int vector) +{ + + unsigned reg = GIC_DIST_ENABLE_SET + (vector/32)*4; + unsigned bit = 1 << (vector & 31); + writel(bit, reg); + return 0; +} + +void register_int_handler(unsigned int vector, int_handler func, void *arg) +{ + if (vector >= NR_IRQS) + return; + + enter_critical_section(); + handler[vector].func = func; + handler[vector].arg = arg; + exit_critical_section(); +} + +void clear_pending_int(void) +{ + unsigned num_irq = 0; + + num_irq = readl(GIC_DIST_CTR) & 0x1f; + num_irq = (num_irq + 1) * 32; + unsigned i; + for (i = 0; i < num_irq; i += 32) + writel(0xffffffff, GIC_DIST_PENDING_CLEAR + i * 4 / 32); +} diff --git a/lk/platform/msm8x60/mmc_init.c b/lk/platform/msm8x60/mmc_init.c new file mode 100644 index 0000000..d0a89ec --- /dev/null +++ b/lk/platform/msm8x60/mmc_init.c @@ -0,0 +1,104 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include "mmc.h" + +#define CLK_CTL_BASE 0x00900000 + +#define SDC_NS(n) (CLK_CTL_BASE + 0x282C + 32*((n) - 1)) +#define SDC1_NS SDC_NS(1) +#define SDC2_NS SDC_NS(2) +#define SDC3_NS SDC_NS(3) +#define SDC4_NS SDC_NS(4) +#define SDC5_NS SDC_NS(5) + +#define SDC_MD(n) (CLK_CTL_BASE + 0x2828 + 32*((n) - 1)) +#define SDC1_MD SDC_MD(1) +#define SDC2_MD SDC_MD(2) +#define SDC3_MD SDC_MD(3) +#define SDC4_MD SDC_MD(4) +#define SDC5_MD SDC_MD(5) + +static void mmc_set_clk(unsigned ns, unsigned md) +{ + unsigned int val; + /*Clock Init*/ + // 1. Set bit 7 in the NS registers + val = 1 << 7; + writel(val, SDC1_NS); + + //2. Program MD registers + writel(md, SDC1_MD); + + //3. Program NS resgister OR'd with Bit 7 + val = 1 << 7; + val |= ns; + writel(val, SDC1_NS); + + //4. Clear bit 7 of NS register + val = 1 << 7; + val = ~val; + val = val & readl(SDC1_NS); + writel(val, SDC1_NS); + + //5. For MD != NA set bit 8 of NS register + val = 1 << 8; + val = val | readl(SDC1_NS); + writel(val, SDC1_NS); + + //6. Set bit 11 in NS register + val = 1 << 11; + val = val | readl(SDC1_NS); + writel(val, SDC1_NS); + + //7. Set bit 9 in NS register + val = 1 << 9; + val = val | readl(SDC1_NS); + writel(val, SDC1_NS); +} + + +void clock_set_enable (unsigned int mclk) +{ + if (mclk == MMC_CLK_400KHZ) + { + mmc_set_clk(0x0010005B, 0x0001000F); + } + else if (mclk == MMC_CLK_20MHZ) + { + mmc_set_clk(0x00ED0043, 0x000100EC); + } + else if (mclk == MMC_CLK_48MHZ) + { + mmc_set_clk(0x00FE005B, 0x000100FD); + } +} diff --git a/lk/platform/msm8x60/panel.c b/lk/platform/msm8x60/panel.c new file mode 100644 index 0000000..ee94eb8 --- /dev/null +++ b/lk/platform/msm8x60/panel.c @@ -0,0 +1,363 @@ +/* + * * Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +static struct qup_i2c_dev *dev = NULL; + +uint8_t expander_read(uint8_t addr) +{ + uint8_t ret = 0; + /* Create a i2c_msg buffer, that is used to put the controller into read + mode and then to read some data. */ + struct i2c_msg msg_buf[] = { + {CORE_GPIO_EXPANDER_I2C_ADDRESS, I2C_M_WR, 1, &addr}, + {CORE_GPIO_EXPANDER_I2C_ADDRESS, I2C_M_RD, 1, &ret} + }; + + qup_i2c_xfer(dev, msg_buf, 2); + + return ret; +} + +uint8_t expander_write(uint8_t addr, uint8_t val) +{ + uint8_t data_buf[] = { addr, val }; + + /* Create a i2c_msg buffer, that is used to put the controller into write + mode and then to write some data. */ + struct i2c_msg msg_buf[] = { {CORE_GPIO_EXPANDER_I2C_ADDRESS, + I2C_M_WR, 2, data_buf} + }; + + qup_i2c_xfer(dev, msg_buf, 1); + + /* Double check that the write worked. */ + if (val != expander_read(addr)) { + return -1; + } + + return 0; +} + +void panel_poweron(void) +{ + panel_backlight(1); + lcdc_on(); +} + +void panel_backlight(int on) +{ +} + +static int display_common_power(int on) +{ +} + +static int lcd_power_on() +{ + uint8_t buffer = 0x0, mask = 0x0, prev_val = 0x0; + int ret = 0; + + /* Configure LDO L2 TEST Bank 2, to Range Select 0 */ + buffer = (0x80); /* Write mode */ + buffer |= (PM8901_LDO_TEST_BANK(2)); /* Test Bank 2 */ + mask = buffer | LDO_TEST_RANGE_SELECT_MASK; + + if ((ret = pm8901_test_bank_read(&prev_val, + PM8901_LDO_TEST_BANK(2), + PM8901_LDO_L2_TEST_BANK))) { + return ret; + } + if ((ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2_TEST_BANK, + prev_val))) { + return ret; + } + + /* Configure LDO L2 TEST Bank 4, for High Range Mode */ + buffer = (0x80); /* Write mode */ + buffer |= (PM8901_LDO_TEST_BANK(4)); /* Test Bank 4 */ + buffer |= (0x01); /* Put into High Range Mode */ + mask = buffer | LDO_TEST_OUTPUT_RANGE_MASK; + + if ((ret = pm8901_test_bank_read(&prev_val, + PM8901_LDO_TEST_BANK(4), + PM8901_LDO_L2_TEST_BANK))) { + return ret; + } + if ((ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2_TEST_BANK, + prev_val))) { + return ret; + } + + /* Configure LDO L2 TEST Bank 5, for XO_EN<3-0> to 1 */ + buffer = (0x80); /* Write mode */ + buffer |= (PM8901_LDO_TEST_BANK(5)); /* Test Bank 5 */ + buffer |= (0x0F); /* Enable XO_EN */ + mask = buffer | LDO_TEST_XO_EN_ALL_MASK; + + if ((ret = pm8901_test_bank_read(&prev_val, + PM8901_LDO_TEST_BANK(5), + PM8901_LDO_L2_TEST_BANK))) { + return ret; + } + if ((ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2_TEST_BANK, + prev_val))) { + return ret; + } + + /* Enable LDO L2 at Max Voltage (should be around 3.3v) */ + buffer = (0x1 << PM8901_LDO_CTL_ENABLE__S); + /* Disable Pull Down */ + buffer |= (0x0 << PM8901_LDO_CTL_PULL_DOWN__S); + /* Put LDO into normal mode instead of low power mode */ + buffer |= (0x0 << PM8901_LDO_CTL_MODE__S); + /* Write a 31 into the Voltage Programming value to obtain 3.3v VREG = + 1.75V + X * 100mV */ + buffer |= (0x1F); + mask = buffer | LDO_CTL_ENABLE_MASK | + LDO_CTL_PULL_DOWN_MASK | + LDO_CTL_NORMAL_POWER_MODE_MASK | LDO_CTL_VOLTAGE_SET_MASK; + + /* Do a normal read here, as to not destroy the value in LDO control */ + if ((ret = pm8901_read(&prev_val, 1, PM8901_LDO_L2))) { + return ret; + } + /* Configure the LDO2 for 3.3v */ + ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2, prev_val); + return ret; +} + +/* Configures the GPIO that are needed to enable LCD. + * This function also configures the PMIC for PWM control of the LCD backlight. + */ +static void lcd_gpio_cfg(uint8_t on) +{ + uint32_t func; + uint32_t pull; + uint32_t dir; + uint32_t enable = 0; /* not used in gpio_tlmm_config */ + uint32_t drv; + if (on) { + func = 1; /* Configure GPIO for LCDC function */ + pull = GPIO_NO_PULL; + dir = 1; /* doesn't matter since it is not configured as + GPIO */ + drv = GPIO_16MA; + } else { + /* As discussed in the MSM8660 FFA HW SW Control Doc configure these + GPIO as input and pull down. */ + func = 0; /* GPIO */ + pull = GPIO_PULL_DOWN; + dir = 0; /* Input */ + drv = 0; /* does not matter configured as input */ + } + + gpio_tlmm_config(0, func, dir, pull, drv, enable); /* lcdc_pclk */ + gpio_tlmm_config(1, func, dir, pull, drv, enable); /* lcdc_hsync */ + gpio_tlmm_config(2, func, dir, pull, drv, enable); /* lcdc_vsync */ + gpio_tlmm_config(3, func, dir, pull, drv, enable); /* lcdc_den */ + gpio_tlmm_config(4, func, dir, pull, drv, enable); /* lcdc_red7 */ + gpio_tlmm_config(5, func, dir, pull, drv, enable); /* lcdc_red6 */ + gpio_tlmm_config(6, func, dir, pull, drv, enable); /* lcdc_red5 */ + gpio_tlmm_config(7, func, dir, pull, drv, enable); /* lcdc_red4 */ + gpio_tlmm_config(8, func, dir, pull, drv, enable); /* lcdc_red3 */ + gpio_tlmm_config(9, func, dir, pull, drv, enable); /* lcdc_red2 */ + gpio_tlmm_config(10, func, dir, pull, drv, enable); /* lcdc_red1 */ + gpio_tlmm_config(11, func, dir, pull, drv, enable); /* lcdc_red0 */ + gpio_tlmm_config(12, func, dir, pull, drv, enable); /* lcdc_rgn7 */ + gpio_tlmm_config(13, func, dir, pull, drv, enable); /* lcdc_rgn6 */ + gpio_tlmm_config(14, func, dir, pull, drv, enable); /* lcdc_rgn5 */ + gpio_tlmm_config(15, func, dir, pull, drv, enable); /* lcdc_rgn4 */ + gpio_tlmm_config(16, func, dir, pull, drv, enable); /* lcdc_rgn3 */ + gpio_tlmm_config(17, func, dir, pull, drv, enable); /* lcdc_rgn2 */ + gpio_tlmm_config(18, func, dir, pull, drv, enable); /* lcdc_rgn1 */ + gpio_tlmm_config(19, func, dir, pull, drv, enable); /* lcdc_rgn0 */ + gpio_tlmm_config(20, func, dir, pull, drv, enable); /* lcdc_blu7 */ + gpio_tlmm_config(21, func, dir, pull, drv, enable); /* lcdc_blu6 */ + gpio_tlmm_config(22, func, dir, pull, drv, enable); /* lcdc_blu5 */ + gpio_tlmm_config(23, func, dir, pull, drv, enable); /* lcdc_blu4 */ + gpio_tlmm_config(24, func, dir, pull, drv, enable); /* lcdc_blu3 */ + gpio_tlmm_config(25, func, dir, pull, drv, enable); /* lcdc_blu2 */ + gpio_tlmm_config(26, func, dir, pull, drv, enable); /* lcdc_blu1 */ + gpio_tlmm_config(27, func, dir, pull, drv, enable); /* lcdc_blu0 */ +} + +/* Backlight duty cycle init is used to configure the PMIC8058 for + * PWM output and drive those pins. + */ +static void bl_duty_cycle_init(void) +{ + /* Disable backlight LPG channels before configuring them and dedicated + PMIC GPIOs */ + pm8058_write_one(0x00, LPG_BANK_ENABLE); + + /* Configure PM8058 GPIO24 as a PWM driver (LPG ch0) for chain 1 of 6 LEDs */ + pm8058_write_one(0x81, GPIO24_GPIO_CNTRL); /* Write, Bank0, VIN0, Mode + selection enabled */ + pm8058_write_one(0x98, GPIO24_GPIO_CNTRL); /* Write, Bank1, OutOn/InOff, + CMOS, Don't Invert Output */ + pm8058_write_one(0xAA, GPIO24_GPIO_CNTRL); /* Write, Bank2, GPIO no pull */ + pm8058_write_one(0xB4, GPIO24_GPIO_CNTRL); /* Write, Bank3, high drv + strength */ + pm8058_write_one(0xC6, GPIO24_GPIO_CNTRL); /* Write, Bank4, Src: LPG_DRV1 + (Spec. Fnc 2) */ + pm8058_write_one(0xD8, GPIO24_GPIO_CNTRL); /* Write, Bank5, Interrupt + polarity noninversion */ + + /* Configure PM8058 GPIO25 as a PWM driver (LPG ch1) for chain 2 of 5 LEDs */ + pm8058_write_one(0x81, GPIO25_GPIO_CNTRL); /* Write, Bank0, VIN0, Mode + selection enabled */ + pm8058_write_one(0x98, GPIO25_GPIO_CNTRL); /* Write, Bank1, OutOn/InOff, + CMOS, Don't Invert Output */ + pm8058_write_one(0xAA, GPIO25_GPIO_CNTRL); /* Write, Bank2, GPIO no pull */ + pm8058_write_one(0xB4, GPIO25_GPIO_CNTRL); /* Write, Bank3, high drv + strength */ + pm8058_write_one(0xC6, GPIO25_GPIO_CNTRL); /* Write, Bank4, Src: LPG_DRV2 + (Spec. Fnc 2) */ + pm8058_write_one(0xD8, GPIO25_GPIO_CNTRL); /* Write, Bank5, Interrupt + polarity noninversion */ + + /* Configure PM8058 LPG channel 0 as non-LUT PWM for PM8058 GPIO24 */ + pm8058_write_one(0x0, LPG_BANK_SEL); /* Select LPG ch0 slice of control + regs */ + pm8058_write_one(0x00, LPG_CTL_0); /* Disable PWM, PWM output, and LPG + ramp generator */ + pm8058_write_one(0x40, LPG_CTL_1); /* Dont Toggle, Enable user PWM value, + no LUT high value idx */ + pm8058_write_one(0x00, LPG_CTL_2); /* Dont Loop, no LUT low value index */ + pm8058_write_one(0xDE, LPG_CTL_3); /* LS 8 bits of 9-bit PWM user value */ + pm8058_write_one(0x7F, LPG_CTL_4); /* MSbit of 9-bit PWM user value, + 19.2MHz, Dev 6, Expo M = 7 */ + pm8058_write_one(0x01, LPG_CTL_5); /* PWM = 9bit, disable pause at high + value LUT index */ + pm8058_write_one(0x00, LPG_CTL_6); /* Disable pause at low value LUT index + */ + pm8058_write_one(0x0C, LPG_CTL_0); /* Enable PWM and PWM output, LPG ramp + generator remains disabled */ + + /* Configure PM8058 LPG chan 1 as PWM for PM8058 GPIO25 */ + pm8058_write_one(0x1, LPG_BANK_SEL); /* Select LPG ch1 slice of control + regs */ + pm8058_write_one(0x00, LPG_CTL_0); /* Disable PWM, PWM output, and LPG + ramp generator */ + pm8058_write_one(0x40, LPG_CTL_1); /* Dont Toggle, Enable user PWM value, + no LUT high value idx */ + pm8058_write_one(0x00, LPG_CTL_2); /* Dont Loop, no LUT low value index */ + pm8058_write_one(0x00, LPG_CTL_3); /* LS 8 bits of 9-bit PWM user value */ + pm8058_write_one(0x7F, LPG_CTL_4); /* MSbit of 9-bit PWM user value, + 19.2MHz, Dev 6, Expo M = 7 */ + pm8058_write_one(0x01, LPG_CTL_5); /* PWM = 9bit, disable pause at high + value LUT index */ + pm8058_write_one(0x00, LPG_CTL_6); /* Disable pause at low value LUT index + */ + pm8058_write_one(0x0C, LPG_CTL_0); /* Enable PWM and PWM output, LPG ramp + generator remains disabled */ + + /* Enable both LPG channels to enable backlight driver */ + pm8058_write_one(0x03, LPG_BANK_ENABLE); /* Enable LPG ch0 (GPIO24) & + ch1 (GPIO25) */ +} + +void board_lcd_enable(void) +{ + dev = qup_i2c_init(GSBI8_BASE, 100000, 24000000); + + /* Make sure dev is created and initialized properly */ + if (!dev) { + while (1) ; + return; + } + + /* Store current value of these registers as to not destroy their previous + state. */ + uint8_t open_drain_a = expander_read(GPIO_EXPANDER_REG_OPEN_DRAIN_A); + uint8_t dir_b = expander_read(GPIO_EXPANDER_REG_DIR_B); + uint8_t dir_a = expander_read(GPIO_EXPANDER_REG_DIR_A); + uint8_t data_b = expander_read(GPIO_EXPANDER_REG_DATA_B); + uint8_t data_a = expander_read(GPIO_EXPANDER_REG_DATA_A); + + /* Set the LVDS_SHUTDOWN_N to open drain and output low. */ + dprintf(INFO, "Enable lvds_shutdown_n line for Open Drain.\n"); + expander_write(GPIO_EXPANDER_REG_OPEN_DRAIN_A, 0x04 | open_drain_a); + + dprintf(INFO, "Enable lvds_shutdown_n line for output.\n"); + expander_write(GPIO_EXPANDER_REG_DIR_A, ~0x04 & dir_a); + + dprintf(INFO, "Drive the LVDS_SHUTDOWN_N pin high here.\n"); + expander_write(GPIO_EXPANDER_REG_DATA_A, 0x04 | data_a); + + /* Turn on the VREG_L2B to 3.3V. */ + + /* Power on the appropiate PMIC LDO power rails */ + if (lcd_power_on()) + return; + + /* Enable the GPIO as LCDC mode LCD. */ + lcd_gpio_cfg(1); + + /* Arbitrary delay */ + udelay(20000); + + /* Set the backlight duty cycle via the PM8058 LPG_DRV1 and LPG_DRV2 */ + bl_duty_cycle_init(); + + dprintf(INFO, "Enable BACKLIGHT_EN line for output.\n"); + expander_write(GPIO_EXPANDER_REG_DIR_B, ~0x10 & dir_b); + + dprintf(INFO, "Drive BACKLIGHT_EN to high\n"); + expander_write(GPIO_EXPANDER_REG_DATA_B, 0x10 | data_b); + +} + +void mdp_clock_init(void) +{ + /* Turn on the PLL2, to ramp up the MDP clock to max (200MHz) */ + nt_pll_enable(PLL_2, 1); + + config_mdp_clk(MDP_NS_VAL, MDP_MD_VAL, + MDP_CC_VAL, MDP_NS_REG, MDP_MD_REG, MDP_CC_REG); + + config_pixel_clk(PIXEL_NS_VAL, PIXEL_MD_VAL, + PIXEL_CC_VAL, LCD_PIXEL_NS_REG, + LCD_PIXEL_MD_REG, LCD_PIXEL_CC_REG); +} + +void lcdc_on(void) +{ + board_lcd_enable(); +} diff --git a/lk/platform/msm8x60/platform.c b/lk/platform/msm8x60/platform.c new file mode 100644 index 0000000..f071dcf --- /dev/null +++ b/lk/platform/msm8x60/platform.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#define CONVERT_ENDIAN_U32(val) \ + ((((uint32_t)(val) & 0x000000FF) << 24) | \ + (((uint32_t)(val) & 0x0000FF00) << 8) | \ + (((uint32_t)(val) & 0x00FF0000) >> 8) | \ + (((uint32_t)(val) & 0xFF000000) >> 24)) + +#define CONVERT_ENDIAN_U16(val) \ + ((((uint16_t)(val) & 0x00FF) << 8) | \ + (((uint16_t)(val) & 0xFF00) >> 8)) + +/* Configuration Data Table */ +#define CDT_MAGIC_NUMBER 0x43445400 +struct cdt_header +{ + uint32_t magic; /* Magic number */ + uint16_t version; /* Version number */ + uint32_t reserved1; + uint32_t reserved2; +}__attribute__((packed)); + +void platform_init_interrupts(void); +void platform_init_timer(); + +void uart3_clock_init(void); +void uart_init(void); + +struct fbcon_config *lcdc_init(void); + +void platform_early_init(void) +{ + uart_init(); + platform_init_interrupts(); + platform_init_timer(); +} + +void platform_init(void) +{ + dprintf(INFO, "platform_init()\n"); +} + +void display_init(void) +{ + struct fbcon_config *fb_cfg; +#if DISPLAY_TYPE_LCDC + mdp_clock_init(); + fb_cfg = lcdc_init(); + panel_poweron(); + fbcon_setup(fb_cfg); +#endif +#if DISPLAY_TYPE_MIPI + mdp_clock_init(); + fb_cfg = mipi_init(); + fbcon_setup(fb_cfg); +#endif + +} + +void display_shutdown(void) +{ +#if DISPLAY_TYPE_LCDC + /* Turning off LCDC */ + lcdc_shutdown(); +#endif +#if DISPLAY_TYPE_MIPI + mipi_dsi_shutdown(); +#endif +} + +static struct qup_i2c_dev* dev = NULL; + +uint32_t eprom_read (uint16_t addr, uint8_t count) { + uint32_t ret = 0; + if(!dev){ + return ret; + } + /* Create a i2c_msg buffer, that is used to put the controller into + * read mode and then to read some data. + */ + struct i2c_msg msg_buf[] = { + {EEPROM_I2C_ADDRESS, I2C_M_WR, 2, &addr}, + {EEPROM_I2C_ADDRESS, I2C_M_RD, count, &ret} + }; + + qup_i2c_xfer(dev, msg_buf, 2); + return ret; +} + +/* Read EEPROM to find out product id. Return 0 in case of failure */ +uint32_t platform_id_read (void) +{ + uint32_t id = 0; + uint16_t offset = 0; + dev = qup_i2c_init(GSBI8_BASE, 100000, 24000000); + if(!dev){ + return id; + } + /* Check if EPROM is valid */ + if (CONVERT_ENDIAN_U32(eprom_read(0, 4)) == CDT_MAGIC_NUMBER) + { + /* Get offset for platform ID info from Meta Data block 0 */ + offset = eprom_read(CONVERT_ENDIAN_U16(0 + + sizeof(struct cdt_header)), 2); + /* Read platform ID */ + id = eprom_read(CONVERT_ENDIAN_U16(offset), 4); + id = CONVERT_ENDIAN_U32(id); + id = (id & 0x00FF0000) >> 16; + } + return id; +} + diff --git a/lk/platform/msm8x60/pmic.c b/lk/platform/msm8x60/pmic.c new file mode 100644 index 0000000..24c044e --- /dev/null +++ b/lk/platform/msm8x60/pmic.c @@ -0,0 +1,101 @@ +/* + * * Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +typedef int (*pm8058_write_func) (unsigned char *, unsigned short, + unsigned short); +extern int pa1_ssbi2_write_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr); + +/*PM8058*/ +void pm8058_write_one(unsigned data, unsigned address) +{ + pm8058_write_func wr_function = &pa1_ssbi2_write_bytes; + if (wr_function == NULL) + return; + if ((*wr_function) (&data, 1, address)) + dprintf(CRITICAL, "Error in initializing register\n"); + +} + +/*PM8901*/ +extern int pa2_ssbi2_write_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr); +extern int pa2_ssbi2_read_bytes(unsigned char *buffer, unsigned short length, + unsigned short slave_addr); +/* + * Write to the control registers on PMIC via the SSBI2 interface. + * Returns : (0) on success and (-1) on error. + */ +int pm8901_write(uint8_t * buffer, uint32_t length, uint32_t slave_addr) +{ + return pa2_ssbi2_write_bytes(buffer, length, slave_addr); +} + +/* + * Read from the control registers on PMIC via the SSBI2 interface. + * Returns : (0) on success and (-1) on error. + */ +int pm8901_read(uint8_t * buffer, uint32_t length, uint32_t slave_addr) +{ + return pa2_ssbi2_read_bytes(buffer, length, slave_addr); +} + +/* + * PMIC 8901 LDO vreg read. + */ +int pm8901_test_bank_read(uint8_t * buffer, uint8_t bank, uint16_t addr) +{ + int ret = pm8901_write(&bank, 1, addr); + /* if the write does not work we can't read. */ + if (ret) { + return ret; + } + + return pm8901_read(buffer, 1, addr); +} + +/* + * PMIC 8901 LDO vreg write. + */ +int pm8901_vreg_write(uint8_t * buffer, uint8_t mask, uint16_t addr, + uint8_t prev_val) +{ + uint8_t reg; + + /* Clear the bits we want to try and set. */ + reg = (prev_val & ~mask); + /* Set the bits we want to set, before writing them to addr */ + reg |= (*buffer & mask); + return pm8901_write(®, 1, addr); +} diff --git a/lk/platform/msm8x60/rules.mk b/lk/platform/msm8x60/rules.mk new file mode 100644 index 0000000..e69b266 --- /dev/null +++ b/lk/platform/msm8x60/rules.mk @@ -0,0 +1,30 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +ARCH := arm +ARM_CPU := cortex-a8 +#arm1136j-s +CPU := generic + +MMC_SLOT := 1 + +DEFINES += WITH_CPU_EARLY_INIT=0 WITH_CPU_WARM_BOOT=0 \ + MMC_SLOT=$(MMC_SLOT) MDP4=1 + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared/include + +DEVS += fbcon +MODULES += dev/fbcon + +OBJS += \ + $(LOCAL_DIR)/platform.o \ + $(LOCAL_DIR)/interrupts.o \ + $(LOCAL_DIR)/acpuclock.o \ + $(LOCAL_DIR)/mmc_init.o \ + $(LOCAL_DIR)/gpio.o \ + $(LOCAL_DIR)/panel.o \ + $(LOCAL_DIR)/pmic.o + +LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld + +include platform/msm_shared/rules.mk + diff --git a/lk/platform/msm_shared/debug.c b/lk/platform/msm_shared/debug.c new file mode 100644 index 0000000..935d886 --- /dev/null +++ b/lk/platform/msm_shared/debug.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include + +void _dputc(char c) +{ +#if WITH_DEBUG_DCC + if (c == '\n') { + while (dcc_putc('\r') < 0); + } + while (dcc_putc(c) < 0); +#endif +#if WITH_DEBUG_UART + uart_putc(0, c); +#endif +#if WITH_DEBUG_FBCON && WITH_DEV_FBCON + fbcon_putc(c); +#endif +#if WITH_DEBUG_JTAG + jtag_dputc(c); +#endif +} + +int dgetc(char *c) +{ + int n; +#if WITH_DEBUG_DCC + n = dcc_getc(); +#elif WITH_DEBUG_UART + n = uart_getc(0, 0); +#else + n = -1; +#endif + if (n < 0) { + return -1; + } else { + *c = n; + return 0; + } +} + +void platform_halt(void) +{ + dprintf(INFO, "HALT: spinning forever...\n"); + for(;;); +} + diff --git a/lk/platform/msm_shared/dmov.h b/lk/platform/msm_shared/dmov.h new file mode 100644 index 0000000..76ebf56 --- /dev/null +++ b/lk/platform/msm_shared/dmov.h @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2008, Google 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. + * + * 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 __PLATFORM_MSM_SHARED_DMOV_H +#define __PLATFORM_MSM_SHARED_DMOV_H + +#ifdef PLATFORM_MSM7X30 +#define MSM_DMOV_BASE 0xAC400000 +#else +#define MSM_DMOV_BASE 0xA9700000 +#endif + +/* see 80-VA736-2 C pp 415-439 */ + +#define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2)) +#define DMOV_SD1(off, ch) (MSM_DMOV_BASE + 0x0400 + (off) + ((ch) << 2)) +#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2)) +#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2)) + +#ifdef PLATFORM_MSM7X30 +#define DMOV_SDn DMOV_SD2 +#else +#define DMOV_SDn DMOV_SD3 +#endif + + + +/* only security domain 3 is available to the ARM11 +** +** SD0 -> mARM trusted, SD1 -> mARM nontrusted, SD2 -> aDSP, SD3 -> aARM +** +*/ + +#define DMOV_CMD_PTR(ch) DMOV_SDn(0x000, ch) +#define DMOV_CMD_LIST (0 << 29) /* does not work */ +#define DMOV_CMD_PTR_LIST (1 << 29) /* works */ +#define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */ +#define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */ +#define DMOV_CMD_ADDR(addr) ((addr) >> 3) + +#define DMOV_RSLT(ch) DMOV_SDn(0x040, ch) +#define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */ +#define DMOV_RSLT_ERROR (1 << 3) +#define DMOV_RSLT_FLUSH (1 << 2) +#define DMOV_RSLT_DONE (1 << 1) /* top pointer done */ +#define DMOV_RSLT_USER (1 << 0) /* command with FR force result */ + +#define DMOV_FLUSH0(ch) DMOV_SDn(0x080, ch) +#define DMOV_FLUSH1(ch) DMOV_SDn(0x0C0, ch) +#define DMOV_FLUSH2(ch) DMOV_SDn(0x100, ch) +#define DMOV_FLUSH3(ch) DMOV_SDn(0x140, ch) +#define DMOV_FLUSH4(ch) DMOV_SDn(0x180, ch) +#define DMOV_FLUSH5(ch) DMOV_SDn(0x1C0, ch) + +#define DMOV_STATUS(ch) DMOV_SDn(0x200, ch) +#define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29)) +#define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3) +#define DMOV_STATUS_RSLT_VALID (1 << 1) +#define DMOV_STATUS_CMD_PTR_RDY (1 << 0) + +#define DMOV_ISR DMOV_SDn(0x380, 0) + +#define DMOV_CONFIG(ch) DMOV_SDn(0x300, ch) +#define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2) +#define DMOV_CONFIG_FOREC_FLUSH_RSLT (1 << 1) +#define DMOV_CONFIG_IRQ_EN (1 << 0) + +/* channel assignments - from qc/dmov_7500.h */ + +#define DMOV_NAND_CHAN 7 +#define DMOV_NAND_CRCI_CMD 5 +#define DMOV_NAND_CRCI_DATA 4 + +#define DMOV_SDC1_CHAN 8 +#define DMOV_SDC1_CRCI 6 + +#define DMOV_SDC2_CHAN 8 +#define DMOV_SDC2_CRCI 7 + +#define DMOV_TSIF_CHAN 10 +#define DMOV_TSIF_CRCI 10 + +#define DMOV_USB_CHAN 11 + +/* no client rate control ifc (eg, ram) */ +#define DMOV_NONE_CRCI 0 + + +/* If the CMD_PTR register has CMD_PTR_LIST selected, the data mover +** is going to walk a list of 32bit pointers as described below. Each +** pointer points to a *array* of dmov_s, etc structs. The last pointer +** in the list is marked with CMD_PTR_LP. The last struct in each array +** is marked with CMD_LC (see below). +*/ +#define CMD_PTR_ADDR(addr) ((addr) >> 3) +#define CMD_PTR_LP (1 << 31) /* last pointer */ +#define CMD_PTR_PT (3 << 29) /* ? */ + + +/* Single Item Mode -- seems to work as expected */ +typedef struct { + unsigned cmd; + unsigned src; + unsigned dst; + unsigned len; +} dmov_s; + +/* Scatter/Gather Mode -- does this work?*/ +typedef struct { + unsigned cmd; + unsigned src_dscr; + unsigned dst_dscr; + unsigned _reserved; +} dmov_sg; + +/* bits for the cmd field of the above structures */ + +#define CMD_LC (1 << 31) /* last command */ +#define CMD_FR (1 << 22) /* force result -- does not work? */ +#define CMD_OCU (1 << 21) /* other channel unblock */ +#define CMD_OCB (1 << 20) /* other channel block */ +#define CMD_TCB (1 << 19) /* ? */ +#define CMD_DAH (1 << 18) /* destination address hold -- does not work?*/ +#define CMD_SAH (1 << 17) /* source address hold -- does not work? */ + +#define CMD_MODE_SINGLE (0 << 0) /* dmov_s structure used */ +#define CMD_MODE_SG (1 << 0) /* untested */ +#define CMD_MODE_IND_SG (2 << 0) /* untested */ +#define CMD_MODE_BOX (3 << 0) /* untested */ + +#define CMD_DST_SWAP_BYTES (1 << 14) /* exchange each byte n with byte n+1 */ +#define CMD_DST_SWAP_SHORTS (1 << 15) /* exchange each short n with short n+1 */ +#define CMD_DST_SWAP_WORDS (1 << 16) /* exchange each word n with word n+1 */ + +#define CMD_SRC_SWAP_BYTES (1 << 11) /* exchange each byte n with byte n+1 */ +#define CMD_SRC_SWAP_SHORTS (1 << 12) /* exchange each short n with short n+1 */ +#define CMD_SRC_SWAP_WORDS (1 << 13) /* exchange each word n with word n+1 */ + +#define CMD_DST_CRCI(n) (((n) & 15) << 7) +#define CMD_SRC_CRCI(n) (((n) & 15) << 3) + + +/* NOTES: +** +** Looks like Channels 4, 5, 6, 7, 8, 10, 11 are available to the ARM11 +** +*/ +#endif /* __PLATFORM_MSM_SHARED_DMOV_H */ diff --git a/lk/platform/msm_shared/hsusb.c b/lk/platform/msm_shared/hsusb.c new file mode 100644 index 0000000..bdd8e2e --- /dev/null +++ b/lk/platform/msm_shared/hsusb.c @@ -0,0 +1,935 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "hsusb.h" + +int charger_usb_disconnected(void); +int charger_usb_i(unsigned current); +int charger_usb_is_pc_connected(void); +int charger_usb_is_charger_connected(void); + +/* common code - factor out into a shared file */ + +struct udc_descriptor { + struct udc_descriptor *next; + unsigned short tag; /* ((TYPE << 8) | NUM) */ + unsigned short len; /* total length */ + unsigned char data[0]; +}; + +struct udc_descriptor *udc_descriptor_alloc(unsigned type, unsigned num, unsigned len) +{ + struct udc_descriptor *desc; + if ((len > 255) || (len < 2) || (num > 255) || (type > 255)) + return 0; + + if(!(desc = malloc(sizeof(struct udc_descriptor) + len))) + return 0; + + desc->next = 0; + desc->tag = (type << 8) | num; + desc->len = len; + desc->data[0] = len; + desc->data[1] = type; + + return desc; +} + +static struct udc_descriptor *desc_list = 0; +static unsigned next_string_id = 1; + +void udc_descriptor_register(struct udc_descriptor *desc) +{ + desc->next = desc_list; + desc_list = desc; +} + +unsigned udc_string_desc_alloc(const char *str) +{ + unsigned len; + struct udc_descriptor *desc; + unsigned char *data; + + if (next_string_id > 255) + return 0; + + if (!str) + return 0; + + len = strlen(str); + desc = udc_descriptor_alloc(TYPE_STRING, next_string_id, len * 2 + 2); + if (!desc) + return 0; + next_string_id++; + + /* expand ascii string to utf16 */ + data = desc->data + 2; + while (len-- > 0) { + *data++ = *str++; + *data++ = 0; + } + + udc_descriptor_register(desc); + return desc->tag & 0xff; +} + +/* end of common code */ + +__WEAK void hsusb_clock_init(void) +{ + return 0; +} + +#if 1 +#define DBG(x...) do {} while(0) +#else +#define DBG(x...) dprintf(INFO, x) +#endif + +#define DBG1(x...) dprintf(INFO, x) + +#define usb_status(a,b) + +struct usb_request { + struct udc_request req; + struct ept_queue_item *item; +}; + +struct udc_endpoint +{ + struct udc_endpoint *next; + unsigned bit; + struct ept_queue_head *head; + struct usb_request *req; + unsigned char num; + unsigned char in; + unsigned short maxpkt; +}; + +struct udc_endpoint *ept_list = 0; +struct ept_queue_head *epts = 0; + +static int usb_online = 0; +static int usb_highspeed = 0; + +static struct udc_device *the_device; +static struct udc_gadget *the_gadget; + +struct udc_endpoint *_udc_endpoint_alloc(unsigned num, unsigned in, unsigned max_pkt) +{ + struct udc_endpoint *ept; + unsigned cfg; + + ept = malloc(sizeof(*ept)); + + ept->maxpkt = max_pkt; + ept->num = num; + ept->in = !!in; + ept->req = 0; + + cfg = CONFIG_MAX_PKT(max_pkt) | CONFIG_ZLT; + + if(ept->in) { + ept->bit = EPT_TX(ept->num); + } else { + ept->bit = EPT_RX(ept->num); + if(num == 0) + cfg |= CONFIG_IOS; + } + + ept->head = epts + (num * 2) + (ept->in); + ept->head->config = cfg; + + ept->next = ept_list; + ept_list = ept; + +// arch_clean_invalidate_cache_range(ept->head, 64); + DBG("ept%d %s @%p/%p max=%d bit=%x\n", + num, in ? "in":"out", ept, ept->head, max_pkt, ept->bit); + + return ept; +} + +static unsigned ept_alloc_table = EPT_TX(0) | EPT_RX(0); + +struct udc_endpoint *udc_endpoint_alloc(unsigned type, unsigned maxpkt) +{ + struct udc_endpoint *ept; + unsigned n; + unsigned in; + + if (type == UDC_TYPE_BULK_IN) { + in = 1; + } else if (type == UDC_TYPE_BULK_OUT) { + in = 0; + } else { + return 0; + } + + for (n = 1; n < 16; n++) { + unsigned bit = in ? EPT_TX(n) : EPT_RX(n); + if (ept_alloc_table & bit) + continue; + ept = _udc_endpoint_alloc(n, in, maxpkt); + if (ept) + ept_alloc_table |= bit; + return ept; + } + return 0; +} + +void udc_endpoint_free(struct udc_endpoint *ept) +{ + /* todo */ +} + +static void endpoint_enable(struct udc_endpoint *ept, unsigned yes) +{ + unsigned n = readl(USB_ENDPTCTRL(ept->num)); + + if(yes) { + if(ept->in) { + n |= (CTRL_TXE | CTRL_TXR | CTRL_TXT_BULK); + } else { + n |= (CTRL_RXE | CTRL_RXR | CTRL_RXT_BULK); + } + + if(ept->num != 0) { + /* XXX should be more dynamic... */ + if(usb_highspeed) { + ept->head->config = CONFIG_MAX_PKT(512) | CONFIG_ZLT; + } else { + ept->head->config = CONFIG_MAX_PKT(64) | CONFIG_ZLT; + } + } + } + writel(n, USB_ENDPTCTRL(ept->num)); +} + +struct udc_request *udc_request_alloc(void) +{ + struct usb_request *req; + req = malloc(sizeof(*req)); + req->req.buf = 0; + req->req.length = 0; + req->item = memalign(32, 32); + return &req->req; +} + +void udc_request_free(struct udc_request *req) +{ + free(req); +} + +int udc_request_queue(struct udc_endpoint *ept, struct udc_request *_req) +{ + struct usb_request *req = (struct usb_request *) _req; + struct ept_queue_item *item = req->item; + unsigned phys = (unsigned) req->req.buf; + + item->next = TERMINATE; + item->info = INFO_BYTES(req->req.length) | INFO_IOC | INFO_ACTIVE; + item->page0 = phys; + item->page1 = (phys & 0xfffff000) + 0x1000; + + enter_critical_section(); + ept->head->next = (unsigned) item; + ept->head->info = 0; + ept->req = req; + +// arch_clean_invalidate_cache_range(item, 32); +// arch_clean_invalidate_cache_range(ept->head, 64); +// arch_clean_invalidate_cache_range(req->req.buf, req->req.length); + DBG("ept%d %s queue req=%p\n", + ept->num, ept->in ? "in" : "out", req); + + writel(ept->bit, USB_ENDPTPRIME); + exit_critical_section(); + return 0; +} + +static void handle_ept_complete(struct udc_endpoint *ept) +{ + struct ept_queue_item *item; + unsigned actual; + int status; + struct usb_request *req; + + DBG("ept%d %s complete req=%p\n", + ept->num, ept->in ? "in" : "out", ept->req); + + req = ept->req; + if(req) { + ept->req = 0; + + item = req->item; + + /* For some reason we are getting the notification for + * transfer completion before the active bit has cleared. + * HACK: wait for the ACTIVE bit to clear: + */ + while (readl(&(item->info)) & INFO_ACTIVE) ; + +// arch_clean_invalidate_cache_range(item, 32); +// arch_clean_invalidate_cache_range(req->req.buf, req->req.length); + + if(item->info & 0xff) { + actual = 0; + status = -1; + dprintf(INFO, "EP%d/%s FAIL nfo=%x pg0=%x\n", + ept->num, ept->in ? "in" : "out", item->info, item->page0); + } else { + actual = req->req.length - ((item->info >> 16) & 0x7fff); + status = 0; + } + if(req->req.complete) + req->req.complete(&req->req, actual, status); + } +} + +static const char *reqname(unsigned r) +{ + switch(r) { + case GET_STATUS: return "GET_STATUS"; + case CLEAR_FEATURE: return "CLEAR_FEATURE"; + case SET_FEATURE: return "SET_FEATURE"; + case SET_ADDRESS: return "SET_ADDRESS"; + case GET_DESCRIPTOR: return "GET_DESCRIPTOR"; + case SET_DESCRIPTOR: return "SET_DESCRIPTOR"; + case GET_CONFIGURATION: return "GET_CONFIGURATION"; + case SET_CONFIGURATION: return "SET_CONFIGURATION"; + case GET_INTERFACE: return "GET_INTERFACE"; + case SET_INTERFACE: return "SET_INTERFACE"; + default: return "*UNKNOWN*"; + } +} + +static struct udc_endpoint *ep0in, *ep0out; +static struct udc_request *ep0req; + +static void setup_ack(void) +{ + ep0req->complete = 0; + ep0req->length = 0; + udc_request_queue(ep0in, ep0req); +} + +static void ep0in_complete(struct udc_request *req, unsigned actual, int status) +{ + DBG("ep0in_complete %p %d %d\n", req, actual, status); + if(status == 0) { + req->length = 0; + req->complete = 0; + udc_request_queue(ep0out, req); + } +} + +static void setup_tx(void *buf, unsigned len) +{ + DBG("setup_tx %p %d\n", buf, len); + memcpy(ep0req->buf, buf, len); + ep0req->complete = ep0in_complete; + ep0req->length = len; + udc_request_queue(ep0in, ep0req); +} + +static unsigned char usb_config_value = 0; + +#define SETUP(type,request) (((type) << 8) | (request)) + +static void handle_setup(struct udc_endpoint *ept) +{ + struct setup_packet s; + + memcpy(&s, ept->head->setup_data, sizeof(s)); + writel(ept->bit, USB_ENDPTSETUPSTAT); + +#if 0 + DBG("handle_setup type=0x%02x req=0x%02x val=%d idx=%d len=%d (%s)\n", + s.type, s.request, s.value, s.index, s.length, + reqname(s.request)); +#endif + switch (SETUP(s.type,s.request)) { + case SETUP(DEVICE_READ, GET_STATUS): { + unsigned zero = 0; + if (s.length == 2) { + setup_tx(&zero, 2); + return; + } + break; + } + case SETUP(DEVICE_READ, GET_DESCRIPTOR): { + struct udc_descriptor *desc; + /* usb_highspeed? */ + for (desc = desc_list; desc; desc = desc->next) { + if (desc->tag == s.value) { + unsigned len = desc->len; + if (len > s.length) len = s.length; + setup_tx(desc->data, len); + return; + } + } + break; + } + case SETUP(DEVICE_READ, GET_CONFIGURATION): + /* disabling this causes data transaction failures on OSX. Why? */ + if ((s.value == 0) && (s.index == 0) && (s.length == 1)) { + setup_tx(&usb_config_value, 1); + return; + } + break; + case SETUP(DEVICE_WRITE, SET_CONFIGURATION): + if (s.value == 1) { + struct udc_endpoint *ept; + /* enable endpoints */ + for (ept = ept_list; ept; ept = ept->next){ + if (ept->num == 0) + continue; + endpoint_enable(ept, s.value); + } + usb_config_value = 1; +#ifdef ENABLE_BATTERY_CHARGING + if(HOST_CHARGER == TRUE) { + charger_usb_i(500); + } +#endif + the_gadget->notify(the_gadget, UDC_EVENT_ONLINE); + } else { + writel(0, USB_ENDPTCTRL(1)); + usb_config_value = 0; + the_gadget->notify(the_gadget, UDC_EVENT_OFFLINE); + } + setup_ack(); + usb_online = s.value ? 1 : 0; + usb_status(s.value ? 1 : 0, usb_highspeed); + return; + case SETUP(DEVICE_WRITE, SET_ADDRESS): + /* write address delayed (will take effect + ** after the next IN txn) + */ + writel((s.value << 25) | (1 << 24), USB_DEVICEADDR); + setup_ack(); + return; + case SETUP(INTERFACE_WRITE, SET_INTERFACE): + /* if we ack this everything hangs */ + /* per spec, STALL is valid if there is not alt func */ + goto stall; + case SETUP(ENDPOINT_WRITE, CLEAR_FEATURE): { + struct udc_endpoint *ept; + unsigned num = s.index & 15; + unsigned in = !!(s.index & 0x80); + + if ((s.value == 0) && (s.length == 0)) { + DBG("clr feat %d %d\n", num, in); + for (ept = ept_list; ept; ept = ept->next) { + if ((ept->num == num) && (ept->in == in)) { + endpoint_enable(ept, 1); + setup_ack(); + return; + } + } + } + break; + } + } + + dprintf(INFO, "STALL %s %d %d %d %d %d\n", + reqname(s.request), + s.type, s.request, s.value, s.index, s.length); + +stall: + writel((1<<16) | (1 << 0), USB_ENDPTCTRL(ept->num)); +} + +unsigned ulpi_read(unsigned reg) +{ + /* initiate read operation */ + writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg), + USB_ULPI_VIEWPORT); + + /* wait for completion */ + while(readl(USB_ULPI_VIEWPORT) & ULPI_RUN) ; + + return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT)); +} + +void ulpi_write(unsigned val, unsigned reg) +{ + /* initiate write operation */ + writel(ULPI_RUN | ULPI_WRITE | + ULPI_ADDR(reg) | ULPI_DATA(val), + USB_ULPI_VIEWPORT); + + /* wait for completion */ + while(readl(USB_ULPI_VIEWPORT) & ULPI_RUN) ; +} + +#define USB_CLK 0x00902910 +#define USB_PHY_CLK 0x00902E20 +#define CLK_RESET_ASSERT 0x1 +#define CLK_RESET_DEASSERT 0x0 +#define CLK_RESET(x,y) writel((y), (x)); + +static int msm_otg_xceiv_reset() +{ + CLK_RESET(USB_CLK, CLK_RESET_ASSERT); + CLK_RESET(USB_PHY_CLK, CLK_RESET_ASSERT); + mdelay(20); + CLK_RESET(USB_PHY_CLK, CLK_RESET_DEASSERT); + CLK_RESET(USB_CLK, CLK_RESET_DEASSERT); + mdelay(20); + + /* select ULPI phy */ + writel(0x81000000, USB_PORTSC); + return 0; +} + +void board_usb_init(void); +void board_ulpi_init(void); + +int udc_init(struct udc_device *dev) +{ + hsusb_clock_init(); + + epts = memalign(4096, 4096); + + dprintf(INFO, "USB init ept @ %p\n", epts); + memset(epts, 0, 32 * sizeof(struct ept_queue_head)); + + //dprintf(INFO, "USB ID %08x\n", readl(USB_ID)); +// board_usb_init(); + + /* select ULPI phy */ +#ifdef PLATFORM_MSM8X60 + msm_otg_xceiv_reset(); +#else + writel(0x81000000, USB_PORTSC); +#endif + /* RESET */ + writel(0x00080002, USB_USBCMD); + + thread_sleep(20); + +// board_ulpi_init(); + +// arch_clean_invalidate_cache_range(epts, 32 * sizeof(struct ept_queue_head)); + writel((unsigned) epts, USB_ENDPOINTLISTADDR); + + /* select DEVICE mode */ + writel(0x02, USB_USBMODE); + + writel(0xffffffff, USB_ENDPTFLUSH); + thread_sleep(20); + + ep0out = _udc_endpoint_alloc(0, 0, 64); + ep0in = _udc_endpoint_alloc(0, 1, 64); + ep0req = udc_request_alloc(); + ep0req->buf = malloc(4096); + + { + /* create and register a language table descriptor */ + /* language 0x0409 is US English */ + struct udc_descriptor *desc = udc_descriptor_alloc(TYPE_STRING, 0, 4); + desc->data[2] = 0x09; + desc->data[3] = 0x04; + udc_descriptor_register(desc); + } + + the_device = dev; + return 0; +} + +enum handler_return udc_interrupt(void *arg) +{ + struct udc_endpoint *ept; + unsigned ret = INT_NO_RESCHEDULE; + unsigned n = readl(USB_USBSTS); + writel(n, USB_USBSTS); + + n &= (STS_SLI | STS_URI | STS_PCI | STS_UI | STS_UEI); + + if (n == 0) + return ret; + + if (n & STS_URI) { + writel(readl(USB_ENDPTCOMPLETE), USB_ENDPTCOMPLETE); + writel(readl(USB_ENDPTSETUPSTAT), USB_ENDPTSETUPSTAT); + writel(0xffffffff, USB_ENDPTFLUSH); + writel(0, USB_ENDPTCTRL(1)); + DBG1("-- reset --\n"); + usb_online = 0; + usb_config_value = 0; + the_gadget->notify(the_gadget, UDC_EVENT_OFFLINE); + + /* error out any pending reqs */ + for (ept = ept_list; ept; ept = ept->next) { + /* ensure that ept_complete considers + * this to be an error state + */ + if (ept->req) { + ept->req->item->info = INFO_HALTED; + handle_ept_complete(ept); + } + } + usb_status(0, usb_highspeed); + } + if (n & STS_SLI) { + DBG1("-- suspend --\n"); +#ifdef ENABLE_BATTERY_CHARGING + if(HOST_CHARGER == TRUE){ + charger_usb_i(2); + } +#endif + } + if (n & STS_PCI) { + DBG1("-- portchange --\n"); + unsigned spd = (readl(USB_PORTSC) >> 26) & 3; + if(spd == 2) { + usb_highspeed = 1; + } else { + usb_highspeed = 0; + } +#ifdef ENABLE_BATTERY_CHARGING + if(HOST_CHARGER == TRUE && usb_config_value){ + charger_usb_i(500); + } + if(HOST_CHARGER == TRUE && !usb_config_value){ + charger_usb_i(100); + } +#endif + } + if (n & STS_UEI) { + dprintf(INFO, "\n", readl(USB_ENDPTCOMPLETE)); + } +#if 0 + DBG("STS: "); + if (n & STS_UEI) DBG("ERROR "); + if (n & STS_SLI) DBG("SUSPEND "); + if (n & STS_URI) DBG("RESET "); + if (n & STS_PCI) DBG("PORTCHANGE "); + if (n & STS_UI) DBG("USB "); + DBG("\n"); +#endif + if ((n & STS_UI) || (n & STS_UEI)) { + n = readl(USB_ENDPTSETUPSTAT); + if (n & EPT_RX(0)) { + handle_setup(ep0out); + ret = INT_RESCHEDULE; + } + + n = readl(USB_ENDPTCOMPLETE); + if (n != 0) { + writel(n, USB_ENDPTCOMPLETE); + } + + for (ept = ept_list; ept; ept = ept->next){ + if (n & ept->bit) { + handle_ept_complete(ept); + ret = INT_RESCHEDULE; + } + } + } + return ret; +} + +int udc_register_gadget(struct udc_gadget *gadget) +{ + if (the_gadget) { + dprintf(CRITICAL, "only one gadget supported\n"); + return -1; + } + the_gadget = gadget; + return 0; +} + +static void udc_ept_desc_fill(struct udc_endpoint *ept, unsigned char *data) +{ + data[0] = 7; + data[1] = TYPE_ENDPOINT; + data[2] = ept->num | (ept->in ? 0x80 : 0x00); + data[3] = 0x02; /* bulk -- the only kind we support */ + data[4] = ept->maxpkt; + data[5] = ept->maxpkt >> 8; + data[6] = ept->in ? 0x00 : 0x01; +} + +static unsigned udc_ifc_desc_size(struct udc_gadget *g) +{ + return 9 + g->ifc_endpoints * 7; +} + +static void udc_ifc_desc_fill(struct udc_gadget *g, unsigned char *data) +{ + unsigned n; + + data[0] = 0x09; + data[1] = TYPE_INTERFACE; + data[2] = 0x00; /* ifc number */ + data[3] = 0x00; /* alt number */ + data[4] = g->ifc_endpoints; + data[5] = g->ifc_class; + data[6] = g->ifc_subclass; + data[7] = g->ifc_protocol; + data[8] = udc_string_desc_alloc(g->ifc_string); + + data += 9; + for (n = 0; n < g->ifc_endpoints; n++) { + udc_ept_desc_fill(g->ept[n], data); + data += 7; + } +} + +int udc_start(void) +{ + struct udc_descriptor *desc; + unsigned char *data; + unsigned size; + + dprintf(ALWAYS, "udc_start()\n"); + + if (!the_device) { + dprintf(CRITICAL, "udc cannot start before init\n"); + return -1; + } + if (!the_gadget) { + dprintf(CRITICAL, "udc has no gadget registered\n"); + return -1; + } + + /* create our device descriptor */ + desc = udc_descriptor_alloc(TYPE_DEVICE, 0, 18); + data = desc->data; + data[2] = 0x10; /* usb spec rev 2.10 */ + data[3] = 0x02; + data[4] = 0x00; /* class */ + data[5] = 0x00; /* subclass */ + data[6] = 0x00; /* protocol */ + data[7] = 0x40; /* max packet size on ept 0 */ + memcpy(data + 8, &the_device->vendor_id, sizeof(short)); + memcpy(data + 10, &the_device->product_id, sizeof(short)); + memcpy(data + 12, &the_device->version_id, sizeof(short)); + data[14] = udc_string_desc_alloc(the_device->manufacturer); + data[15] = udc_string_desc_alloc(the_device->product); + data[16] = udc_string_desc_alloc(the_device->serialno); + data[17] = 1; /* number of configurations */ + udc_descriptor_register(desc); + + /* create our configuration descriptor */ + size = 9 + udc_ifc_desc_size(the_gadget); + desc = udc_descriptor_alloc(TYPE_CONFIGURATION, 0, size); + data = desc->data; + data[0] = 0x09; + data[2] = size; + data[3] = size >> 8; + data[4] = 0x01; /* number of interfaces */ + data[5] = 0x01; /* configuration value */ + data[6] = 0x00; /* configuration string */ + data[7] = 0x80; /* attributes */ + data[8] = 0x80; /* max power (250ma) -- todo fix this */ + udc_ifc_desc_fill(the_gadget, data + 9); + udc_descriptor_register(desc); + + /* go to RUN mode (D+ pullup enable) */ + writel(0x00080001, USB_USBCMD); + register_int_handler(INT_USB_HS, udc_interrupt, (void*) 0); + unmask_interrupt(INT_USB_HS); + writel(STS_URI | STS_SLI | STS_UI | STS_PCI, USB_USBINTR); + return 0; +} + +int udc_stop(void) +{ + int val; + writel(0, USB_USBINTR); + mask_interrupt(INT_USB_HS); + + /* disable pullup */ + writel(0x00080000, USB_USBCMD); +#ifdef PLATFORM_MSM8X60 + /* Voting down PLL8 */ + val = readl(0x009034C0); + val &= ~(1<<8); + writel(val, 0x009034C0); +#endif + thread_sleep(10); + + return 0; +} + +void usb_stop_charging(unsigned stop_charging) +{ + ENABLE_CHARGING = !stop_charging; +} + +static inline unsigned is_usb_charging(void) +{ + return ENABLE_CHARGING; +} + +void usb_charger_reset(void) +{ + usb_stop_charging(TRUE); + charger_usb_disconnected(); +} + +/* Charger detection code + * Set global flags WALL_CHARGER and + * RETURN: type of charger connected + * CHG_WALL + * CHG_HOST_PC + * */ +int usb_chg_detect_type(void) +{ + int ret = CHG_UNDEFINED; + + if ((readl(USB_PORTSC) & PORTSC_LS) == PORTSC_LS) + { + if(charger_usb_is_charger_connected() == TRUE) { + WALL_CHARGER = TRUE; + HOST_CHARGER = FALSE; + charger_usb_i(1500); + ret = CHG_WALL; + } + } + else + { + if(charger_usb_is_pc_connected() == TRUE) { + WALL_CHARGER = FALSE; + HOST_CHARGER = TRUE; + ret = CHG_HOST_PC; + } + } + return ret; +} + +/* check if USB cable is connected + * + * RETURN: If cable connected return 1 + * If cable disconnected return 0 + */ +int is_usb_cable_connected(void) +{ + /*Verify B Session Valid Bit to verify vbus status*/ + if (B_SESSION_VALID & readl(USB_OTGSC)) { + return 1; + } else { + return 0; + } +} + +/* check for USB connection assuming USB is not pulled up. + * It looks for suspend state bit in PORTSC register. + * + * RETURN: If cable connected return 1 + * If cable disconnected return 0 + */ + +int usb_cable_status(void) +{ + unsigned ret = 0; + /*Verify B Session Valid Bit to verify vbus status*/ + writel(0x00080001, USB_USBCMD); + thread_sleep(100); + + /*Check reset value of suspend state bit*/ + if (!((1<<7) & readl(USB_PORTSC))) { + ret=1; + } + udc_stop(); + return ret; +} + +void usb_charger_change_state(void) +{ + int usb_connected; + + //User might have switched from host pc to wall charger. So keep checking + //every time we are in the loop + + if(ENABLE_CHARGING == TRUE) + { + usb_connected = is_usb_cable_connected(); + + if(usb_connected && !charger_connected) + { + //mdelay(20); + thread_sleep(20); + /* go to RUN mode (D+ pullup enable) */ + writel(0x00080001, USB_USBCMD); + //mdelay(10); + thread_sleep(10); + usb_chg_detect_type(); + charger_connected = TRUE; + } + else if(!usb_connected && charger_connected) + { + /* disable D+ pull-up */ + writel(0x00080000, USB_USBCMD); + + /* Applicable only for 8k target */ + /*USB Spoof Disconnect Failure + Symptoms: + In USB peripheral mode, writing '0' to Run/Stop bit of the + USBCMD register doesn't cause USB disconnection (spoof disconnect). + The PC host doesn't detect the disconnection and the phone remains + active on Windows device manager. + + Suggested Workaround: + After writing '0' to Run/Stop bit of USBCMD, also write 0x48 to ULPI + "Function Control" register. This can be done via the ULPI VIEWPORT + register (offset 0x170) by writing a value of 0x60040048. + */ + ulpi_write(0x48, 0x04); + //usb_charger_reset(); + WALL_CHARGER = FALSE; + HOST_CHARGER = FALSE; + charger_usb_i(0); + charger_usb_disconnected(); + charger_connected = FALSE; + } + if(WALL_CHARGER == TRUE || HOST_CHARGER == TRUE){ + //battery_charging_image(); + } + } + else if ((readl(USB_USBCMD) & 0x01) == 0){ + writel(0x00080001, USB_USBCMD); + } +} diff --git a/lk/platform/msm_shared/hsusb.h b/lk/platform/msm_shared/hsusb.h new file mode 100644 index 0000000..23cf7ce --- /dev/null +++ b/lk/platform/msm_shared/hsusb.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * 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 _MSM7200_USB_H_ +#define _MSM7200_USB_H_ + +#ifndef MSM_USB_BASE +#define MSM_USB_BASE 0xA0800000 +#endif + +#define USB_ID (MSM_USB_BASE + 0x0000) +#define USB_HWGENERAL (MSM_USB_BASE + 0x0004) +#define USB_HWHOST (MSM_USB_BASE + 0x0008) +#define USB_HWDEVICE (MSM_USB_BASE + 0x000C) +#define USB_HWTXBUF (MSM_USB_BASE + 0x0010) +#define USB_HWRXBUF (MSM_USB_BASE + 0x0014) +#define USB_SBUSCFG (MSM_USB_BASE + 0x0090) + +#define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ +#define USB_HCIVERSION (MSM_USB_BASE + 0x0102) /* 16 bit */ +#define USB_HCSPARAMS (MSM_USB_BASE + 0x0104) +#define USB_HCCPARAMS (MSM_USB_BASE + 0x0108) +#define USB_DCIVERSION (MSM_USB_BASE + 0x0120) /* 16 bit */ +#define USB_USBCMD (MSM_USB_BASE + 0x0140) +#define USB_USBSTS (MSM_USB_BASE + 0x0144) +#define USB_USBINTR (MSM_USB_BASE + 0x0148) +#define USB_FRINDEX (MSM_USB_BASE + 0x014C) +#define USB_DEVICEADDR (MSM_USB_BASE + 0x0154) +#define USB_ENDPOINTLISTADDR (MSM_USB_BASE + 0x0158) +#define USB_BURSTSIZE (MSM_USB_BASE + 0x0160) +#define USB_TXFILLTUNING (MSM_USB_BASE + 0x0164) +#define USB_ULPI_VIEWPORT (MSM_USB_BASE + 0x0170) +#define USB_ENDPTNAK (MSM_USB_BASE + 0x0178) +#define USB_ENDPTNAKEN (MSM_USB_BASE + 0x017C) +#define USB_PORTSC (MSM_USB_BASE + 0x0184) +#define USB_OTGSC (MSM_USB_BASE + 0x01A4) +#define USB_USBMODE (MSM_USB_BASE + 0x01A8) +#define USB_ENDPTSETUPSTAT (MSM_USB_BASE + 0x01AC) +#define USB_ENDPTPRIME (MSM_USB_BASE + 0x01B0) +#define USB_ENDPTFLUSH (MSM_USB_BASE + 0x01B4) +#define USB_ENDPTSTAT (MSM_USB_BASE + 0x01B8) +#define USB_ENDPTCOMPLETE (MSM_USB_BASE + 0x01BC) +#define USB_ENDPTCTRL(n) (MSM_USB_BASE + 0x01C0 + (4 * (n))) + + +#define USBCMD_RESET 2 +#define USBCMD_ATTACH 1 + +#define USBMODE_DEVICE 2 +#define USBMODE_HOST 3 + +struct ept_queue_head +{ + unsigned config; + unsigned current; /* read-only */ + + unsigned next; + unsigned info; + unsigned page0; + unsigned page1; + unsigned page2; + unsigned page3; + unsigned page4; + unsigned reserved_0; + + unsigned char setup_data[8]; + + unsigned reserved_1; + unsigned reserved_2; + unsigned reserved_3; + unsigned reserved_4; +}; + +#define CONFIG_MAX_PKT(n) ((n) << 16) +#define CONFIG_ZLT (1 << 29) /* stop on zero-len xfer */ +#define CONFIG_IOS (1 << 15) /* IRQ on setup */ + +struct ept_queue_item +{ + unsigned next; + unsigned info; + unsigned page0; + unsigned page1; + unsigned page2; + unsigned page3; + unsigned page4; + unsigned reserved; +}; + +#define TERMINATE 1 + +#define INFO_BYTES(n) ((n) << 16) +#define INFO_IOC (1 << 15) +#define INFO_ACTIVE (1 << 7) +#define INFO_HALTED (1 << 6) +#define INFO_BUFFER_ERROR (1 << 5) +#define INFO_TX_ERROR (1 << 3) + + +#define STS_NAKI (1 << 16) /* */ +#define STS_SLI (1 << 8) /* R/WC - suspend state entered */ +#define STS_SRI (1 << 7) /* R/WC - SOF recv'd */ +#define STS_URI (1 << 6) /* R/WC - RESET recv'd - write to clear */ +#define STS_FRI (1 << 3) /* R/WC - Frame List Rollover */ +#define STS_PCI (1 << 2) /* R/WC - Port Change Detect */ +#define STS_UEI (1 << 1) /* R/WC - USB Error */ +#define STS_UI (1 << 0) /* R/WC - USB Transaction Complete */ + + +/* bits used in all the endpoint status registers */ +#define EPT_TX(n) (1 << ((n) + 16)) +#define EPT_RX(n) (1 << (n)) + + +#define CTRL_TXE (1 << 23) +#define CTRL_TXR (1 << 22) +#define CTRL_TXI (1 << 21) +#define CTRL_TXD (1 << 17) +#define CTRL_TXS (1 << 16) +#define CTRL_RXE (1 << 7) +#define CTRL_RXR (1 << 6) +#define CTRL_RXI (1 << 5) +#define CTRL_RXD (1 << 1) +#define CTRL_RXS (1 << 0) + +#define CTRL_TXT_CTRL (0 << 18) +#define CTRL_TXT_ISOCH (1 << 18) +#define CTRL_TXT_BULK (2 << 18) +#define CTRL_TXT_INT (3 << 18) + +#define CTRL_RXT_CTRL (0 << 2) +#define CTRL_RXT_ISOCH (1 << 2) +#define CTRL_RXT_BULK (2 << 2) +#define CTRL_RXT_INT (3 << 2) + +#define ULPI_WAKEUP (1 << 31) +#define ULPI_RUN (1 << 30) +#define ULPI_WRITE (1 << 29) +#define ULPI_READ (0 << 29) +#define ULPI_STATE_NORMAL (1 << 27) +#define ULPI_ADDR(n) (((n) & 255) << 16) +#define ULPI_DATA(n) ((n) & 255) +#define ULPI_DATA_READ(n) (((n) >> 8) & 255) + +/* for USB charging */ +#define TRUE 1 +#define FALSE 0 +#define PORTSC_LS (3 << 10) /* Read - Port's Line status */ +#define B_SESSION_VALID (1 << 11) + +static unsigned WALL_CHARGER = FALSE; +static unsigned HOST_CHARGER = FALSE; +static unsigned ENABLE_CHARGING = TRUE; +static unsigned charger_connected = FALSE; + +enum charger_type { + CHG_HOST_PC, + CHG_WALL, + CHG_UNDEFINED, +}; + +#endif diff --git a/lk/platform/msm_shared/i2c_qup.c b/lk/platform/msm_shared/i2c_qup.c new file mode 100644 index 0000000..92e355f --- /dev/null +++ b/lk/platform/msm_shared/i2c_qup.c @@ -0,0 +1,840 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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. + */ + +/* + * QUP driver for Qualcomm MSM platforms + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +static struct qup_i2c_dev *dev_addr = NULL; + +/* QUP Registers */ +enum { + QUP_CONFIG = 0x0, + QUP_STATE = 0x4, + QUP_IO_MODE = 0x8, + QUP_SW_RESET = 0xC, + QUP_OPERATIONAL = 0x18, + QUP_ERROR_FLAGS = 0x1C, + QUP_ERROR_FLAGS_EN = 0x20, + QUP_MX_READ_CNT = 0x208, + QUP_MX_INPUT_CNT = 0x200, + QUP_MX_WR_CNT = 0x100, + QUP_OUT_DEBUG = 0x108, + QUP_OUT_FIFO_CNT = 0x10C, + QUP_OUT_FIFO_BASE = 0x110, + QUP_IN_READ_CUR = 0x20C, + QUP_IN_DEBUG = 0x210, + QUP_IN_FIFO_CNT = 0x214, + QUP_IN_FIFO_BASE = 0x218, + QUP_I2C_CLK_CTL = 0x400, + QUP_I2C_STATUS = 0x404, +}; + +/* QUP States and reset values */ +enum { + QUP_RESET_STATE = 0, + QUP_RUN_STATE = 1U, + QUP_STATE_MASK = 3U, + QUP_PAUSE_STATE = 3U, + QUP_STATE_VALID = 1U << 2, + QUP_I2C_MAST_GEN = 1U << 4, + QUP_OPERATIONAL_RESET = 0xFF0, + QUP_I2C_STATUS_RESET = 0xFFFFFC, +}; + +/* QUP OPERATIONAL FLAGS */ +enum { + QUP_OUT_SVC_FLAG = 1U << 8, + QUP_IN_SVC_FLAG = 1U << 9, + QUP_MX_INPUT_DONE = 1U << 11, +}; + +/* I2C mini core related values */ +enum { + I2C_MINI_CORE = 2U << 8, + I2C_N_VAL = 0xF, + +}; + +/* Packing Unpacking words in FIFOs , and IO modes*/ +enum { + QUP_WR_BLK_MODE = 1U << 10, + QUP_RD_BLK_MODE = 1U << 12, + QUP_UNPACK_EN = 1U << 14, + QUP_PACK_EN = 1U << 15, +}; + +/* QUP tags */ +enum { + QUP_OUT_NOP = 0, + QUP_OUT_START = 1U << 8, + QUP_OUT_DATA = 2U << 8, + QUP_OUT_STOP = 3U << 8, + QUP_OUT_REC = 4U << 8, + QUP_IN_DATA = 5U << 8, + QUP_IN_STOP = 6U << 8, + QUP_IN_NACK = 7U << 8, +}; + +/* Status, Error flags */ +enum { + I2C_STATUS_WR_BUFFER_FULL = 1U << 0, + I2C_STATUS_BUS_ACTIVE = 1U << 8, + I2C_STATUS_ERROR_MASK = 0x38000FC, + QUP_I2C_NACK_FLAG = 1U << 3, + QUP_IN_NOT_EMPTY = 1U << 5, + QUP_STATUS_ERROR_FLAGS = 0x7C, +}; + +void set_i2c_clk(struct qup_i2c_dev *dev) +{ + uint32_t md = 0; + uint32_t ns = 0; + + switch (dev->src_clk_freq) { + case 24000000: + ns = I2C_APPS_CLK_NS_24MHz; + md = I2C_APPS_CLK_MD_24MHz; + break; + default: + return; + } + /* Enable the GSBI8 HCLK */ + writel((GSBI8_HCLK_CTL_CLK_ENA << GSBI8_HCLK_CTL_S), + GSBIn_HCLK_CTL(dev->gsbi_number)); + clock_config(ns, + md, + GSBIn_QUP_APPS_NS(dev->gsbi_number), + GSBIn_QUP_APPS_MD(dev->gsbi_number)); +} + +void i2c_gpio_cfg(uint32_t base) +{ + switch (base) { + case GSBI8_BASE: + gpio_tlmm_config(64, 1, GPIO_OUTPUT, GPIO_NO_PULL, + GPIO_2MA, GPIO_DISABLE); + gpio_tlmm_config(65, 1, GPIO_OUTPUT, GPIO_NO_PULL, + GPIO_2MA, GPIO_DISABLE); + break; + default: + break; + } +} + +#ifdef DEBUG +static void qup_print_status(struct qup_i2c_dev *dev) +{ + unsigned val; + val = readl(dev->base + QUP_CONFIG); + dprintf(INFO, "Qup config is :0x%x\n", val); + val = readl(dev->base + QUP_STATE); + dprintf(INFO, "Qup state is :0x%x\n", val); + val = readl(dev->base + QUP_IO_MODE); + dprintf(INFO, "Qup mode is :0x%x\n", val); +} +#else +static inline void qup_print_status(struct qup_i2c_dev *dev) +{ +} +#endif + +void i2c_gpio_cfg(unsigned base); + +static irqreturn_t qup_i2c_interrupt(void) +{ + struct qup_i2c_dev *dev = dev_addr; + if (!dev) { + dprintf(CRITICAL, + "dev_addr is NULL, that means i2c_qup_init failed...\n"); + return IRQ_FAIL; + } + unsigned status = readl(dev->base + QUP_I2C_STATUS); + unsigned status1 = readl(dev->base + QUP_ERROR_FLAGS); + unsigned op_flgs = readl(dev->base + QUP_OPERATIONAL); + int err = 0; + + if (!dev->msg) + return IRQ_HANDLED; + + if (status & I2C_STATUS_ERROR_MASK) { + dprintf(CRITICAL, "QUP: I2C status flags :0x%x \n", status); + err = -status; + /* Clear Error interrupt if it's a level triggered interrupt */ + if (dev->num_irqs == 1) { + writel(QUP_RESET_STATE, dev->base + QUP_STATE); + } + goto intr_done; + } + + if (status1 & 0x7F) { + dprintf(CRITICAL, "QUP: QUP status flags :0x%x\n", status1); + err = -status1; + /* Clear Error interrupt if it's a level triggered interrupt */ + if (dev->num_irqs == 1) + writel((status1 & QUP_STATUS_ERROR_FLAGS), + dev->base + QUP_ERROR_FLAGS); + goto intr_done; + } + + if (op_flgs & QUP_OUT_SVC_FLAG) + writel(QUP_OUT_SVC_FLAG, dev->base + QUP_OPERATIONAL); + if (dev->msg->flags == I2C_M_RD) { + if ((op_flgs & QUP_MX_INPUT_DONE) || (op_flgs & QUP_IN_SVC_FLAG)) + writel(QUP_IN_SVC_FLAG, dev->base + QUP_OPERATIONAL); + else + return IRQ_HANDLED; + } + +intr_done: + dev->err = err; + return IRQ_HANDLED; +} + +static int qup_i2c_poll_writeready(struct qup_i2c_dev *dev) +{ + unsigned retries = 0; + + while (retries != 2000) { + unsigned status = readl(dev->base + QUP_I2C_STATUS); + + if (!(status & I2C_STATUS_WR_BUFFER_FULL)) { + if (!(status & I2C_STATUS_BUS_ACTIVE)) + return 0; + else /* 1-bit delay before we check for bus busy */ + udelay(dev->one_bit_t); + } + if (retries++ == 1000) + udelay(100); + } + qup_print_status(dev); + return -ETIMEDOUT; +} + +static int qup_i2c_poll_state(struct qup_i2c_dev *dev, unsigned state) +{ + unsigned retries = 0; + + dprintf(CRITICAL, "Polling Status for state:0x%x\n", state); + + while (retries != 2000) { + unsigned status = readl(dev->base + QUP_STATE); + + if ((status & (QUP_STATE_VALID | state)) == (QUP_STATE_VALID | state)) + return 0; + else if (retries++ == 1000) + udelay(100); + } + return -ETIMEDOUT; +} + +#ifdef DEBUG +static void qup_verify_fifo(struct qup_i2c_dev *dev, unsigned val, + unsigned addr, int rdwr) +{ + if (rdwr) + dprintf(INFO, "RD:Wrote 0x%x to out_ff:0x%x\n", val, addr); + else + dprintf(INFO, "WR:Wrote 0x%x to out_ff:0x%x\n", val, addr); +} +#else +static inline void qup_verify_fifo(struct qup_i2c_dev *dev, unsigned val, + unsigned addr, int rdwr) +{ +} +#endif + +static void +qup_issue_read(struct qup_i2c_dev *dev, struct i2c_msg *msg, int *idx, + unsigned carry_over) +{ + uint16_t addr = (msg->addr << 1) | 1; + /* QUP limit 256 bytes per read. By HW design, 0 in the 8-bit field is + treated as 256 byte read. */ + uint16_t rd_len = ((dev->cnt == 256) ? 0 : dev->cnt); + + if (*idx % 4) { + writel(carry_over | ((QUP_OUT_START | addr) << 16), + dev->base + QUP_OUT_FIFO_BASE); + + qup_verify_fifo(dev, carry_over | + ((QUP_OUT_START | addr) << 16), (unsigned)dev->base + + QUP_OUT_FIFO_BASE + (*idx - 2), 1); + writel((QUP_OUT_REC | rd_len), dev->base + QUP_OUT_FIFO_BASE); + + qup_verify_fifo(dev, (QUP_OUT_REC | rd_len), + (unsigned)dev->base + QUP_OUT_FIFO_BASE + (*idx + 2), + 1); + } else { + writel(((QUP_OUT_REC | rd_len) << 16) | + QUP_OUT_START | addr, dev->base + QUP_OUT_FIFO_BASE); + + qup_verify_fifo(dev, QUP_OUT_REC << 16 | rd_len << 16 | + QUP_OUT_START | addr, + (unsigned)dev->base + QUP_OUT_FIFO_BASE + (*idx), 1); + } + *idx += 4; +} + +static void +qup_issue_write(struct qup_i2c_dev *dev, struct i2c_msg *msg, int rem, + int *idx, unsigned *carry_over) +{ + int entries = dev->cnt; + int empty_sl = dev->wr_sz - ((*idx) >> 1); + int i = 0; + unsigned val = 0; + unsigned last_entry = 0; + uint16_t addr = msg->addr << 1; + + if (dev->pos == 0) { + if (*idx % 4) { + writel(*carry_over | ((QUP_OUT_START | addr) << 16), + dev->base + QUP_OUT_FIFO_BASE); + + qup_verify_fifo(dev, *carry_over | QUP_OUT_DATA << 16 | + addr << 16, (unsigned)dev->base + + QUP_OUT_FIFO_BASE + (*idx) - 2, 0); + } else + val = QUP_OUT_START | addr; + *idx += 2; + i++; + entries++; + } else { + /* Avoid setp time issue by adding 1 NOP when number of bytes are more + than FIFO/BLOCK size. setup time issue can't appear otherwise since + next byte to be written will always be ready */ + val = (QUP_OUT_NOP | 1); + *idx += 2; + i++; + entries++; + } + if (entries > empty_sl) + entries = empty_sl; + + for (; i < (entries - 1); i++) { + if (*idx % 4) { + writel(val | ((QUP_OUT_DATA | + msg->buf[dev->pos]) << 16), + dev->base + QUP_OUT_FIFO_BASE); + + qup_verify_fifo(dev, val | QUP_OUT_DATA << 16 | + msg->buf[dev->pos] << 16, (unsigned)dev->base + + QUP_OUT_FIFO_BASE + (*idx) - 2, 0); + } else + val = QUP_OUT_DATA | msg->buf[dev->pos]; + (*idx) += 2; + dev->pos++; + } + if (dev->pos < (msg->len - 1)) + last_entry = QUP_OUT_DATA; + else if (rem > 1) /* not last array entry */ + last_entry = QUP_OUT_DATA; + else + last_entry = QUP_OUT_STOP; + if ((*idx % 4) == 0) { + /* + * If read-start and read-command end up in different fifos, it + * may result in extra-byte being read due to extra-read cycle. + * Avoid that by inserting NOP as the last entry of fifo only + * if write command(s) leave 1 space in fifo. + */ + if (rem > 1) { + struct i2c_msg *next = msg + 1; + if (next->addr == msg->addr && (next->flags | I2C_M_RD) + && *idx == ((dev->wr_sz * 2) - 4)) { + writel(((last_entry | msg->buf[dev->pos]) | + ((1 | QUP_OUT_NOP) << 16)), + dev->base + QUP_OUT_FIFO_BASE); + *idx += 2; + } else + *carry_over = (last_entry | msg->buf[dev->pos]); + } else { + writel((last_entry | msg->buf[dev->pos]), + dev->base + QUP_OUT_FIFO_BASE); + + qup_verify_fifo(dev, last_entry | msg->buf[dev->pos], + (unsigned)dev->base + QUP_OUT_FIFO_BASE + + (*idx), 0); + } + } else { + writel(val | ((last_entry | msg->buf[dev->pos]) << 16), + dev->base + QUP_OUT_FIFO_BASE); + + qup_verify_fifo(dev, val | (last_entry << 16) | + (msg->buf[dev->pos] << 16), (unsigned)dev->base + + QUP_OUT_FIFO_BASE + (*idx) - 2, 0); + } + + *idx += 2; + dev->pos++; + dev->cnt = msg->len - dev->pos; +} + +static int qup_update_state(struct qup_i2c_dev *dev, unsigned state) +{ + if (qup_i2c_poll_state(dev, 0) != 0) + return -EIO; + writel(state, dev->base + QUP_STATE); + if (qup_i2c_poll_state(dev, state) != 0) + return -EIO; + return 0; +} + +static int qup_set_read_mode(struct qup_i2c_dev *dev, int rd_len) +{ + unsigned wr_mode = (dev->wr_sz < dev->out_fifo_sz) ? QUP_WR_BLK_MODE : 0; + if (rd_len > 256) { + dprintf(INFO, "HW doesn't support READs > 256 bytes\n"); + return -EPROTONOSUPPORT; + } + if (rd_len <= dev->in_fifo_sz) { + writel(wr_mode | QUP_PACK_EN | QUP_UNPACK_EN, dev->base + QUP_IO_MODE); + writel(rd_len, dev->base + QUP_MX_READ_CNT); + } else { + writel(wr_mode | QUP_RD_BLK_MODE | + QUP_PACK_EN | QUP_UNPACK_EN, dev->base + QUP_IO_MODE); + writel(rd_len, dev->base + QUP_MX_INPUT_CNT); + } + return 0; +} + +static int qup_set_wr_mode(struct qup_i2c_dev *dev, int rem) +{ + int total_len = 0; + int ret = 0; + if (dev->msg->len >= (dev->out_fifo_sz - 1)) { + total_len = dev->msg->len + 1 + (dev->msg->len / (dev->out_blk_sz - 1)); + writel(QUP_WR_BLK_MODE | QUP_PACK_EN | QUP_UNPACK_EN, + dev->base + QUP_IO_MODE); + dev->wr_sz = dev->out_blk_sz; + } else + writel(QUP_PACK_EN | QUP_UNPACK_EN, dev->base + QUP_IO_MODE); + + if (rem > 1) { + struct i2c_msg *next = dev->msg + 1; + if (next->addr == dev->msg->addr && next->flags == I2C_M_RD) { + ret = qup_set_read_mode(dev, next->len); + /* make sure read start & read command are in 1 blk */ + if ((total_len % dev->out_blk_sz) == (dev->out_blk_sz - 1)) + total_len += 3; + else + total_len += 2; + } + } + /* WRITE COUNT register valid/used only in block mode */ + if (dev->wr_sz == dev->out_blk_sz) + writel(total_len, dev->base + QUP_MX_WR_CNT); + return ret; +} + +int qup_i2c_xfer(struct qup_i2c_dev *dev, struct i2c_msg msgs[], int num) +{ + int ret; + int rem = num; + int err; + + if (dev->suspended) { + return -EIO; + } + + /* Set the GSBIn_QUP_APPS_CLK to 24MHz, then below figure out what speed to + run I2C_MASTER_CORE at. */ + if (dev->clk_state == 0) { + if (dev->clk_ctl == 0) { + set_i2c_clk(dev); + } + } + /* Initialize QUP registers during first transfer */ + if (dev->clk_ctl == 0) { + int fs_div; + int hs_div; + unsigned fifo_reg; + /* Configure the GSBI Protocol Code for i2c */ + writel((GSBI_PROTOCOL_CODE_I2C << + GSBI_CTRL_REG_PROTOCOL_CODE_S), dev->base); + + fs_div = ((dev->src_clk_freq / dev->clk_freq) / 2) - 3; + hs_div = 3; + dev->clk_ctl = ((hs_div & 0x7) << 8) | (fs_div & 0xff); + fifo_reg = readl(dev->base + QUP_IO_MODE); + if (fifo_reg & 0x3) + dev->out_blk_sz = (fifo_reg & 0x3) * 16; + else + dev->out_blk_sz = 16; + if (fifo_reg & 0x60) + dev->in_blk_sz = ((fifo_reg & 0x60) >> 5) * 16; + else + dev->in_blk_sz = 16; + /* + * The block/fifo size w.r.t. 'actual data' is 1/2 due to 'tag' + * associated with each byte written/received + */ + dev->out_blk_sz /= 2; + dev->in_blk_sz /= 2; + dev->out_fifo_sz = dev->out_blk_sz * (2 << ((fifo_reg & 0x1C) >> 2)); + dev->in_fifo_sz = dev->in_blk_sz * (2 << ((fifo_reg & 0x380) >> 7)); + dprintf(CRITICAL, "QUP IN:bl:%d, ff:%d, OUT:bl:%d, ff:%d\n", + dev->in_blk_sz, dev->in_fifo_sz, + dev->out_blk_sz, dev->out_fifo_sz); + } + + unmask_interrupt(dev->qup_irq); + writel(1, dev->base + QUP_SW_RESET); + ret = qup_i2c_poll_state(dev, QUP_RESET_STATE); + if (ret) { + dprintf(INFO, "QUP Busy:Trying to recover\n"); + goto out_err; + } + + /* Initialize QUP registers */ + writel(0, dev->base + QUP_CONFIG); + writel(QUP_OPERATIONAL_RESET, dev->base + QUP_OPERATIONAL); + writel(QUP_STATUS_ERROR_FLAGS, dev->base + QUP_ERROR_FLAGS_EN); + + writel(I2C_MINI_CORE | I2C_N_VAL, dev->base + QUP_CONFIG); + + /* Initialize I2C mini core registers */ + writel(0, dev->base + QUP_I2C_CLK_CTL); + writel(QUP_I2C_STATUS_RESET, dev->base + QUP_I2C_STATUS); + + dev->cnt = msgs->len; + dev->pos = 0; + dev->msg = msgs; + while (rem) { + int filled = FALSE; + + dev->wr_sz = dev->out_fifo_sz; + dev->err = 0; + + if (qup_i2c_poll_state(dev, QUP_I2C_MAST_GEN) != 0) { + ret = -EIO; + goto out_err; + } + + qup_print_status(dev); + /* HW limits Read upto 256 bytes in 1 read without stop */ + if (dev->msg->flags & I2C_M_RD) { + ret = qup_set_read_mode(dev, dev->cnt); + if (ret != 0) + goto out_err; + } else { + ret = qup_set_wr_mode(dev, rem); + if (ret != 0) + goto out_err; + /* Don't fill block till we get interrupt */ + if (dev->wr_sz == dev->out_blk_sz) + filled = TRUE; + } + + err = qup_update_state(dev, QUP_RUN_STATE); + if (err < 0) { + ret = err; + goto out_err; + } + + qup_print_status(dev); + writel(dev->clk_ctl, dev->base + QUP_I2C_CLK_CTL); + + do { + int idx = 0; + unsigned carry_over = 0; + + /* Transition to PAUSE state only possible from RUN */ + err = qup_update_state(dev, QUP_PAUSE_STATE); + if (err < 0) { + ret = err; + goto out_err; + } + + qup_print_status(dev); + /* This operation is Write, check the next operation and decide + mode */ + while (filled == FALSE) { + if ((msgs->flags & I2C_M_RD) && (dev->cnt == msgs->len)) + qup_issue_read(dev, msgs, &idx, carry_over); + else if (!(msgs->flags & I2C_M_RD)) + qup_issue_write(dev, msgs, rem, &idx, &carry_over); + if (idx >= (dev->wr_sz << 1)) + filled = TRUE; + /* Start new message */ + if (filled == FALSE) { + if (msgs->flags & I2C_M_RD) + filled = TRUE; + else if (rem > 1) { + /* Only combine operations with same address */ + struct i2c_msg *next = msgs + 1; + if (next->addr != msgs->addr || next->flags == 0) + filled = TRUE; + else { + rem--; + msgs++; + dev->msg = msgs; + dev->pos = 0; + dev->cnt = msgs->len; + } + } else + filled = TRUE; + } + } + err = qup_update_state(dev, QUP_RUN_STATE); + if (err < 0) { + ret = err; + goto out_err; + } + dprintf(CRITICAL, "idx:%d, rem:%d, num:%d, mode:%d\n", + idx, rem, num, dev->mode); + + qup_print_status(dev); + if (dev->err) { + if (dev->err & QUP_I2C_NACK_FLAG) { + dprintf(CRITICAL, + "I2C slave addr:0x%x not connected\n", + dev->msg->addr); + } else { + dprintf(INFO, "QUP data xfer error %d\n", dev->err); + } + ret = dev->err; + goto out_err; + } + if (dev->msg->flags & I2C_M_RD) { + int i; + unsigned dval = 0; + for (i = 0; dev->pos < dev->msg->len; i++, dev->pos++) { + unsigned rd_status = readl(dev->base + QUP_OPERATIONAL); + if (i % 2 == 0) { + if ((rd_status & QUP_IN_NOT_EMPTY) == 0) + break; + dval = readl(dev->base + QUP_IN_FIFO_BASE); + dev->msg->buf[dev->pos] = dval & 0xFF; + } else + dev->msg->buf[dev->pos] = ((dval & 0xFF0000) >> 16); + } + dev->cnt -= i; + } else + filled = FALSE; /* refill output FIFO */ + } while (dev->cnt > 0); + if (dev->cnt == 0) { + rem--; + msgs++; + if (rem) { + dev->pos = 0; + dev->cnt = msgs->len; + dev->msg = msgs; + } + } + /* Wait for I2C bus to be idle */ + ret = qup_i2c_poll_writeready(dev); + if (ret) { + dprintf(INFO, "Error waiting for write ready\n"); + goto out_err; + } + } + + ret = num; +out_err: + dev->msg = NULL; + dev->pos = 0; + dev->err = 0; + dev->cnt = 0; + mask_interrupt(dev->qup_irq); + return ret; +} + +static int set_gsbi_number(struct qup_i2c_dev *dev) +{ + switch (dev->base) { + case GSBI1_QUP_BASE: + dev->gsbi_number = 1; + break; + case GSBI2_QUP_BASE: + dev->gsbi_number = 2; + break; + case GSBI3_QUP_BASE: + dev->gsbi_number = 3; + break; + case GSBI4_QUP_BASE: + dev->gsbi_number = 4; + break; + case GSBI5_QUP_BASE: + dev->gsbi_number = 5; + break; + case GSBI6_QUP_BASE: + dev->gsbi_number = 6; + break; + case GSBI7_QUP_BASE: + dev->gsbi_number = 7; + break; + case GSBI8_QUP_BASE: + dev->gsbi_number = 8; + break; + case GSBI9_QUP_BASE: + dev->gsbi_number = 9; + break; + case GSBI10_QUP_BASE: + dev->gsbi_number = 10; + break; + case GSBI11_QUP_BASE: + dev->gsbi_number = 11; + break; + case GSBI12_QUP_BASE: + dev->gsbi_number = 12; + break; + default: + return 1; + } + return 0; +} + +static int set_qup_irq(struct qup_i2c_dev *dev) +{ + switch (dev->base) { + case GSBI1_QUP_BASE: + dev->qup_irq = GSBI1_QUP_IRQ; + break; + case GSBI2_QUP_BASE: + dev->qup_irq = GSBI2_QUP_IRQ; + break; + case GSBI3_QUP_BASE: + dev->qup_irq = GSBI3_QUP_IRQ; + break; + case GSBI4_QUP_BASE: + dev->qup_irq = GSBI4_QUP_IRQ; + break; + case GSBI5_QUP_BASE: + dev->qup_irq = GSBI5_QUP_IRQ; + break; + case GSBI6_QUP_BASE: + dev->qup_irq = GSBI6_QUP_IRQ; + break; + case GSBI7_QUP_BASE: + dev->qup_irq = GSBI7_QUP_IRQ; + break; + case GSBI8_QUP_BASE: + dev->qup_irq = GSBI8_QUP_IRQ; + break; + case GSBI9_QUP_BASE: + dev->qup_irq = GSBI9_QUP_IRQ; + break; + case GSBI10_QUP_BASE: + dev->qup_irq = GSBI10_QUP_IRQ; + break; + case GSBI11_QUP_BASE: + dev->qup_irq = GSBI11_QUP_IRQ; + break; + case GSBI12_QUP_BASE: + dev->qup_irq = GSBI12_QUP_IRQ; + break; + default: + return 1; + } + return 0; +} + +struct qup_i2c_dev *qup_i2c_init(unsigned base, + unsigned clk_freq, unsigned src_clk_freq) +{ + struct qup_i2c_dev *dev; + if (dev_addr != NULL) { + return dev_addr; + } + + dev = malloc(sizeof(struct qup_i2c_dev)); + if (!dev) { + return NULL; + } + dev = memset(dev, 0, sizeof(struct qup_i2c_dev)); + + /* This must be done for qup_i2c_interrupt to work. */ + dev_addr = dev; + + /* Initialize the GPIO for GSBIn as i2c */ + i2c_gpio_cfg(base); + + /* Configure GSBIn in i2c mode */ + writel(GSBI_CTL_PROTOCOL_CODE_I2C, base); + + /* Set the base address for GSBIn QUP The reason we add 0x80000 is to make + the GSBIn base address be the GSBIn QUP base address, which is what the + i2c driver wants. */ + dev->base = base + 0x80000; + + /* Set clk_freq and src_clk_freq for i2c. */ + dev->clk_freq = clk_freq; + dev->src_clk_freq = src_clk_freq; + + dev->num_irqs = 1; + + dev->one_bit_t = USEC_PER_SEC / dev->clk_freq; + dev->clk_ctl = 0; + + /* Set the IRQ number for GSBIn_BASE address */ + if (set_qup_irq(dev)) { + dprintf(INFO, + "Could not find a valid QUP IRQ value based on GSBIn_BASE: %d\n", + base); + dprintf(INFO, "Please double check the GSBIn_BASE address.\n"); + return NULL; + } + + /* Set the GSBI number based on GSBIn_BASE address */ + if (set_gsbi_number(dev)) { + dprintf(INFO, "Could not find a valid GSBI # based on GSBIn_BASE: %d\n", + base); + dprintf(INFO, "Please double check the GSBIn_BASE address.\n"); + return NULL; + } + + /* Register the GSBIn QUP IRQ */ + register_int_handler(dev->qup_irq, qup_i2c_interrupt, 0); + + /* Then disable it */ + mask_interrupt(dev->qup_irq); + + return dev; +} + +int qup_i2c_deinit(struct qup_i2c_dev *dev) +{ + /* Disable the qup_irq */ + mask_interrupt(dev->qup_irq); + /* Free the memory used for dev */ + free(dev); + return 0; +} diff --git a/lk/platform/msm_shared/include/i2c_qup.h b/lk/platform/msm_shared/include/i2c_qup.h new file mode 100644 index 0000000..2c0baa6 --- /dev/null +++ b/lk/platform/msm_shared/include/i2c_qup.h @@ -0,0 +1,254 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 __I2C_QUP__ +#define __I2C_QUP__ + +/** + * struct i2c_msg - an I2C transaction segment beginning with START + * @addr: Slave address, either seven or ten bits. When this is a ten + * bit address, I2C_M_TEN must be set in @flags and the adapter + * must support I2C_FUNC_10BIT_ADDR. + * @flags: I2C_M_RD is handled by all adapters. No other flags may be + * provided unless the adapter exported the relevant I2C_FUNC_* + * flags through i2c_check_functionality(). + * @len: Number of data bytes in @buf being read from or written to the + * I2C slave address. For read transactions where I2C_M_RECV_LEN + * is set, the caller guarantees that this buffer can hold up to + * 32 bytes in addition to the initial length byte sent by the + * slave (plus, if used, the SMBus PEC); and this value will be + * incremented by the number of block data bytes received. + * @buf: The buffer into which data is read, or from which it's written. + * + * An i2c_msg is the low level representation of one segment of an I2C + * transaction. It is visible to drivers in the @i2c_transfer() procedure, + * to userspace from i2c-dev, and to I2C adapter drivers through the + * @i2c_adapter.@master_xfer() method. + * + * Except when I2C "protocol mangling" is used, all I2C adapters implement + * the standard rules for I2C transactions. Each transaction begins with a + * START. That is followed by the slave address, and a bit encoding read + * versus write. Then follow all the data bytes, possibly including a byte + * with SMBus PEC. The transfer terminates with a NAK, or when all those + * bytes have been transferred and ACKed. If this is the last message in a + * group, it is followed by a STOP. Otherwise it is followed by the next + * @i2c_msg transaction segment, beginning with a (repeated) START. + * + * Alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then + * passing certain @flags may have changed those standard protocol behaviors. + * Those flags are only for use with broken/nonconforming slaves, and with + * adapters which are known to support the specific mangling options they + * need (one or more of IGNORE_NAK, NO_RD_ACK, NOSTART, and REV_DIR_ADDR). + */ +struct i2c_msg { + unsigned short addr; /* slave address */ + unsigned short flags; +#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ +#define I2C_M_WR 0x0000 /* write data, from master to slave */ +#define I2C_M_RD 0x0001 /* read data, from slave to master */ +#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ + unsigned short len; /* msg length */ + unsigned char *buf; /* pointer to msg data */ +}; + +struct qup_i2c_dev { + unsigned int base; + unsigned int gsbi_number; + int qup_irq; + int num_irqs; + struct i2c_msg *msg; + int pos; + int cnt; + int err; + int mode; + int clk_ctl; + int clk_freq; + int src_clk_freq; + int one_bit_t; + int out_fifo_sz; + int in_fifo_sz; + int out_blk_sz; + int in_blk_sz; + int wr_sz; + int suspended; + int clk_state; +}; + +/* Function Definitions */ +struct qup_i2c_dev *qup_i2c_init(unsigned base, + unsigned clk_freq, unsigned src_clk_freq); +int qup_i2c_deinit(struct qup_i2c_dev *dev); +int qup_i2c_xfer(struct qup_i2c_dev *dev, struct i2c_msg msgs[], int num); + +struct device { + struct device *parent; + const char *init_name; /* initial name of the device */ + void (*release) (struct device * dev); +}; + +/** + * enum irqreturn + * @IRQ_NONE interrupt was not from this device + * @IRQ_HANDLED interrupt was handled by this device + * @IRQ_WAKE_THREAD handler requests to wake the handler thread + */ +enum irqreturn { + IRQ_NONE, + IRQ_HANDLED, + IRQ_WAKE_THREAD, + IRQ_FAIL, +}; + +typedef enum irqreturn irqreturn_t; + +#define I2C_SMBUS_BLOCK_MAX 32 +union i2c_smbus_data { + unsigned char byte; + unsigned short word; + unsigned char block[I2C_SMBUS_BLOCK_MAX + 2]; +}; + +/* + * i2c_adapter is the structure used to identify a physical i2c bus along + * with the access algorithms necessary to access it. + */ +struct i2c_adapter { + struct module *owner; + unsigned int id; + unsigned int class; /* classes to allow probing for */ + const struct i2c_algorithm *algo; /* the algorithm to access the bus */ + void *algo_data; + /* data fields that are valid for all devices */ + unsigned int level; /* nesting level for lockdep */ + int timeout; /* in jiffies */ + int retries; + struct device dev; /* the adapter device */ + int nr; + char name[48]; +}; + +/* + * The following structs are for those who like to implement new bus drivers: + * i2c_algorithm is the interface to a class of hardware solutions which can + * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584 + * to name two of the most common. + */ +struct i2c_algorithm { + /* If an adapter algorithm can't do I2C-level access, set master_xfer to + NULL. If an adapter algorithm can do SMBus access, set smbus_xfer. If + set to NULL, the SMBus protocol is simulated using common I2C messages */ + /* master_xfer should return the number of messages successfully processed, + or a negative value on error */ + int (*master_xfer) (struct i2c_adapter * adap, struct i2c_msg * msgs, + int num); + int (*smbus_xfer) (struct i2c_adapter * adap, unsigned short addr, + unsigned short flags, char read_write, + unsigned char command, int size, + union i2c_smbus_data * data); + + /* To determine what the adapter supports */ + unsigned int (*functionality) (struct i2c_adapter *); +}; + +#define EIO 5 +#define ENOMEM 12 +#define EBUSY 16 +#define ENODEV 19 +#define ENOSYS 38 +#define EPROTONOSUPPORT 93 +#define ETIMEDOUT 110 + +#define FALSE 0 +#define TRUE 1 + +#define USEC_PER_SEC 1000000L + +#define IRQF_TRIGGER_NONE 0x00000000 +#define IRQF_TRIGGER_RISING 0x00000001 +#define IRQF_TRIGGER_FALLING 0x00000002 +#define IRQF_TRIGGER_HIGH 0x00000004 +#define IRQF_TRIGGER_LOW 0x00000008 +#define IRQF_TRIGGER_MASK (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \ + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING) +#define IRQF_TRIGGER_PROBE 0x00000010 + +/* To determine what functionality is present */ + +#define I2C_FUNC_I2C 0x00000001 +#define I2C_FUNC_10BIT_ADDR 0x00000002 +#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_NOSTART etc. */ +#define I2C_FUNC_SMBUS_PEC 0x00000008 +#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_QUICK 0x00010000 +#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 +#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 +#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 +#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 +#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 +#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 +#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 +#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 +#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 +#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ +#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ + +#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ + I2C_FUNC_SMBUS_WRITE_BYTE) +#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ + I2C_FUNC_SMBUS_WRITE_BYTE_DATA) +#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ + I2C_FUNC_SMBUS_WRITE_WORD_DATA) +#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) +#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) + +#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \ + I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ + I2C_FUNC_SMBUS_PROC_CALL | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ + I2C_FUNC_SMBUS_I2C_BLOCK | \ + I2C_FUNC_SMBUS_PEC) + +/* GSBI/I2C QUP APPS CLK definitions */ +#define I2C_APPS_CLK_MD_24MHz 0x000100FB +#define I2C_APPS_CLK_NS_24MHz 0x00FC005B + +#define GSBI8_HCLK_CTL_S (4) +#define GSBI8_HCLK_CTL_CLK_ENA (0x1) + +#define GSBI_CTRL_REG_PROTOCOL_CODE_S (4) +#define GSBI_PROTOCOL_CODE_I2C (0x2) + +#endif /* __I2C_QUP__ */ diff --git a/lk/platform/msm_shared/include/jtag.h b/lk/platform/msm_shared/include/jtag.h new file mode 100644 index 0000000..e6476d7 --- /dev/null +++ b/lk/platform/msm_shared/include/jtag.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2008 The Android Open Source 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: + * * 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. + * + * 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 _JTAG_H_ +#define _JTAG_H_ + +void jtag_okay(const char *msg); +void jtag_fail(const char *msg); +void jtag_dputc(unsigned ch); +void jtag_cmd_loop(void (*do_cmd)(const char *, unsigned, unsigned, unsigned)); + + +#endif /*__JTAG_H_ */ + diff --git a/lk/platform/msm_shared/include/mddi.h b/lk/platform/msm_shared/include/mddi.h new file mode 100644 index 0000000..d1d3a77 --- /dev/null +++ b/lk/platform/msm_shared/include/mddi.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2008, Google 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. + * + * 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 __PLATFORM_MDDI_H +#define __PLATFORM_MDDI_H + +struct fbcon_config; + +struct __attribute__((packed)) mddi_client_caps +{ + unsigned short length; + unsigned short type; + unsigned short client_id; + + unsigned short protocol_ver; + unsigned short min_protocol_ver; + unsigned short data_rate_cap; + unsigned char interface_type_cap; + unsigned char num_alt_displays; + unsigned short postcal_data_rate; + unsigned short bitmap_width; + unsigned short bitmap_height; + unsigned short display_window_width; + unsigned short display_window_height; + unsigned cmap_size; + unsigned short cmap_rgb_width; + unsigned short rgb_cap; + unsigned char mono_cap; + unsigned char reserved1; + unsigned short ycbcr_cap; + unsigned short bayer_cap; + unsigned short alpha_cursor_planes; + unsigned client_feature_cap; + unsigned char max_video_frame_rate_cap; + unsigned char min_video_frame_rate_cap; + unsigned short min_sub_frame_rate; + unsigned short audio_buf_depth; + unsigned short audio_channel_cap; + unsigned short audio_sampe_rate_rap; + unsigned char audio_sample_res; + unsigned char mic_audio_sample_res; + unsigned short mic_sample_rate_cap; + unsigned char keyboard_data_fmt; + unsigned char pointing_device_data_fmt; + unsigned short content_protection_type; + unsigned short manufacturer_name; + unsigned short product_code; + unsigned short reserved3; + unsigned serial_no; + unsigned char week_of_manufacture; + unsigned char year_of_manufacture; + + unsigned short crc; +}; + +void mddi_remote_write(unsigned val, unsigned reg); +struct fbcon_config *mddi_init(void); + +#endif /* __PLATFORM_MDDI_H */ diff --git a/lk/platform/msm_shared/include/mipi_dsi.h b/lk/platform/msm_shared/include/mipi_dsi.h new file mode 100644 index 0000000..1849ec8 --- /dev/null +++ b/lk/platform/msm_shared/include/mipi_dsi.h @@ -0,0 +1,449 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _PLATFORM_MSM_SHARED_MIPI_DSI_H_ +#define _PLATFORM_MSM_SHARED_MIPI_DSI_H_ + +#define PASS 0 +#define FAIL 1 + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define MIPI_DSI_BASE (0x04700000) + +#define DSI_CLKOUT_TIMING_CTRL (0x047000C0) +#define MMSS_DSI_PIXEL_MD (0x04000134) +#define MMSS_DSI_PIXEL_NS (0x04000138) +#define MMSS_DSI_PIXEL_CC (0x04000130) +#define MMSS_DSI_CC (0x0400004C) +#define MMSS_DSI_MD (0x04000050) +#define MMSS_DSI_NS (0x04000054) +#define MMSS_MISC_CC2 (0x0400005C) +#define MMSS_MISC_CC (0x04000058) +#define DSI_PHY_SW_RESET (0x04700128) +#define DSI_SOFT_RESET (0x04700114) +#define DSI_CAL_CTRL (0x047000F4) + +#define DSIPHY_REGULATOR_CTRL_0 (0x047002CC) +#define DSIPHY_REGULATOR_CTRL_1 (0x047002D0) +#define DSIPHY_REGULATOR_CTRL_2 (0x047002D4) +#define DSIPHY_REGULATOR_CTRL_3 (0x047002D8) + +#define DSIPHY_TIMING_CTRL_0 (0x04700260) +#define DSIPHY_TIMING_CTRL_1 (0x04700264) +#define DSIPHY_TIMING_CTRL_2 (0x04700268) +#define DSIPHY_TIMING_CTRL_3 (0x0470026C) +#define DSIPHY_TIMING_CTRL_4 (0x04700270) +#define DSIPHY_TIMING_CTRL_5 (0x04700274) +#define DSIPHY_TIMING_CTRL_6 (0x04700278) +#define DSIPHY_TIMING_CTRL_7 (0x0470027C) +#define DSIPHY_TIMING_CTRL_8 (0x04700280) +#define DSIPHY_TIMING_CTRL_9 (0x04700284) +#define DSIPHY_TIMING_CTRL_10 (0x04700288) + +#define DSIPHY_CTRL_0 (0x04700290) +#define DSIPHY_CTRL_1 (0x04700294) +#define DSIPHY_CTRL_2 (0x04700298) +#define DSIPHY_CTRL_3 (0x0470029C) + +#define DSIPHY_STRENGTH_CTRL_0 (0x047002A0) +#define DSIPHY_STRENGTH_CTRL_1 (0x047002A4) +#define DSIPHY_STRENGTH_CTRL_2 (0x047002A8) +#define DSIPHY_STRENGTH_CTRL_3 (0x047002AC) + +#define DSIPHY_PLL_CTRL_0 (0x04700200) +#define DSIPHY_PLL_CTRL_1 (0x04700204) +#define DSIPHY_PLL_CTRL_2 (0x04700208) +#define DSIPHY_PLL_CTRL_3 (0x0470020C) +#define DSIPHY_PLL_CTRL_4 (0x04700210) +#define DSIPHY_PLL_CTRL_5 (0x04700214) +#define DSIPHY_PLL_CTRL_6 (0x04700218) +#define DSIPHY_PLL_CTRL_7 (0x0470021C) +#define DSIPHY_PLL_CTRL_8 (0x04700220) +#define DSIPHY_PLL_CTRL_9 (0x04700224) +#define DSIPHY_PLL_CTRL_10 (0x04700228) +#define DSIPHY_PLL_CTRL_11 (0x0470022C) +#define DSIPHY_PLL_CTRL_12 (0x04700230) +#define DSIPHY_PLL_CTRL_13 (0x04700234) +#define DSIPHY_PLL_CTRL_14 (0x04700238) +#define DSIPHY_PLL_CTRL_15 (0x0470023C) +#define DSIPHY_PLL_CTRL_16 (0x04700240) +#define DSIPHY_PLL_CTRL_17 (0x04700244) +#define DSIPHY_PLL_CTRL_18 (0x04700248) +#define DSIPHY_PLL_CTRL_19 (0x0470024C) + +#define DSI_CMD_DMA_MEM_START_ADDR_PANEL (0x46000000) + +#define DSI_CLK_CTRL (0x04700118) +#define DSI_TRIG_CTRL (0x04700080) +#define DSI_CTRL (0x04700000) +#define DSI_COMMAND_MODE_DMA_CTRL (0x04700038) +#define DSI_COMMAND_MODE_MDP_CTRL (0x0470003C) +#define DSI_COMMAND_MODE_MDP_DCS_CMD_CTRL (0x04700040) +#define DSI_DMA_CMD_OFFSET (0x04700044) +#define DSI_DMA_CMD_LENGTH (0x04700048) +#define DSI_COMMAND_MODE_MDP_STREAM0_CTRL (0x04700054) +#define DSI_COMMAND_MODE_MDP_STREAM0_TOTAL (0x04700058) +#define DSI_COMMAND_MODE_MDP_STREAM1_CTRL (0x0470005C) +#define DSI_COMMAND_MODE_MDP_STREAM1_TOTAL (0x04700060) +#define DSI_ERR_INT_MASK0 (0x04700108) +#define DSI_INT_CTRL (0x0470010C) + +#define DSI_VIDEO_MODE_ACTIVE_H (0x04700020) +#define DSI_VIDEO_MODE_ACTIVE_V (0x04700024) +#define DSI_VIDEO_MODE_TOTAL (0x04700028) +#define DSI_VIDEO_MODE_HSYNC (0x0470002C) +#define DSI_VIDEO_MODE_VSYNC (0x04700030) +#define DSI_VIDEO_MODE_VSYNC_VPOS (0x04700034) + +#define DSI_MISR_CMD_CTRL (0x0470009C) +#define DSI_MISR_VIDEO_CTRL (0x047000A0) +#define DSI_EOT_PACKET_CTRL (0x047000C8) +#define DSI_VIDEO_MODE_CTRL (0x0470000C) +#define DSI_CAL_STRENGTH_CTRL (0x04700100) +#define DSI_CMD_MODE_DMA_SW_TRIGGER (0x0470008C) +#define DSI_CMD_MODE_MDP_SW_TRIGGER (0x04700090) + +#define MDP_OVERLAYPROC0_START (0x05100004) +#define MDP_DMA_P_START (0x0510000C) +#define MDP_DMA_S_START (0x05100010) +#define MDP_AXI_RDMASTER_CONFIG (0x05100028) +#define MDP_AXI_WRMASTER_CONFIG (0x05100030) +#define MDP_DISP_INTF_SEL (0x05100038) +#define MDP_MAX_RD_PENDING_CMD_CONFIG (0x0510004C) +#define MDP_INTR_ENABLE (0x05100050) +#define MDP_DSI_CMD_MODE_ID_MAP (0x051000A0) +#define MDP_DSI_CMD_MODE_TRIGGER_EN (0x051000A4) +#define MDP_OVERLAYPROC0_CFG (0x05110004) +#define MDP_DMA_P_CONFIG (0x05190000) +#define MDP_DMA_P_OUT_XY (0x05190010) +#define MDP_DMA_P_SIZE (0x05190004) +#define MDP_DMA_P_BUF_ADDR (0x05190008) +#define MDP_DMA_P_BUF_Y_STRIDE (0x0519000C) +#define MDP_DMA_P_OP_MODE (0x05190070) +#define MDP_DSI_VIDEO_EN (0x051E0000) +#define MDP_DSI_VIDEO_HSYNC_CTL (0x051E0004) +#define MDP_DSI_VIDEO_VSYNC_PERIOD (0x051E0008) +#define MDP_DSI_VIDEO_VSYNC_PULSE_WIDTH (0x051E000C) +#define MDP_DSI_VIDEO_DISPLAY_HCTL (0x051E0010) +#define MDP_DSI_VIDEO_DISPLAY_V_START (0x051E0014) +#define MDP_DSI_VIDEO_DISPLAY_V_END (0x051E0018) +#define MDP_DSI_VIDEO_BORDER_CLR (0x051E0028) +#define MDP_DSI_VIDEO_HSYNC_SKEW (0x051E0030) +#define MDP_DSI_VIDEO_CTL_POLARITY (0x051E0038) +#define MDP_DSI_VIDEO_TEST_CTL (0x051E0034) + +#define MDP_TEST_MODE_CLK (0x051F0000) +#define MDP_INTR_STATUS (0x05100054) +#define MMSS_SFPB_GPREG (0x05700058) + +//BEGINNING OF Tochiba Config- video mode + +static const unsigned char toshiba_panel_mcap_off[8] = { + 0x02, 0x00, 0x29, 0xc0, + 0xb2, 0x00, 0xff, 0xff +}; + +static const unsigned char toshiba_panel_ena_test_reg[8] = { + 0x03, 0x00, 0x29, 0xc0, + 0xEF, 0x01, 0x01, 0xff +}; + +static const unsigned char toshiba_panel_ena_test_reg_wvga[8] = { + 0x03, 0x00, 0x29, 0xc0, + 0xEF, 0x01, 0x01, 0xff +}; + +static const unsigned char toshiba_panel_num_of_2lane[8] = { + 0x03, 0x00, 0x29, 0xc0, // 63:2lane + 0xEF, 0x60, 0x63, 0xff +}; + +static const unsigned char toshiba_panel_num_of_1lane[8] = { + 0x03, 0x00, 0x29, 0xc0, // 62:1lane + 0xEF, 0x60, 0x62, 0xff +}; + +static const unsigned char toshiba_panel_non_burst_sync_pulse[8] = { + 0x03, 0x00, 0x29, 0xc0, + 0xef, 0x61, 0x09, 0xff +}; + +static const unsigned char toshiba_panel_set_DMODE_WQVGA[8] = { + 0x02, 0x00, 0x29, 0xc0, + 0xB3, 0x01, 0xFF, 0xff +}; + +static const unsigned char toshiba_panel_set_DMODE_WVGA[8] = { + 0x02, 0x00, 0x29, 0xc0, + 0xB3, 0x00, 0xFF, 0xff +}; + +static const unsigned char toshiba_panel_set_intern_WR_clk1_wvga[8] + = { + + 0x03, 0x00, 0x29, 0xC0, // 1 last packet + 0xef, 0x2f, 0xcc, 0xff, +}; + +static const unsigned char toshiba_panel_set_intern_WR_clk2_wvga[8] + = { + + 0x03, 0x00, 0x29, 0xC0, // 1 last packet + 0xef, 0x6e, 0xdd, 0xff, +}; + +static const unsigned char + toshiba_panel_set_intern_WR_clk1_wqvga[8] = { + + 0x03, 0x00, 0x29, 0xC0, // 1 last packet + 0xef, 0x2f, 0x22, 0xff, +}; + +static const unsigned char + toshiba_panel_set_intern_WR_clk2_wqvga[8] = { + + 0x03, 0x00, 0x29, 0xC0, // 1 last packet + 0xef, 0x6e, 0x33, 0xff, +}; + +static const unsigned char toshiba_panel_set_hor_addr_2A_wvga[12] = { + + 0x05, 0x00, 0x39, 0xC0, // 1 last packet + // 0x2A, 0x00, 0x08, 0x00,//100 = 64h + // 0x6b, 0xFF, 0xFF, 0xFF, + 0x2A, 0x00, 0x00, 0x01, // 0X1DF = 480-1 0X13F = 320-1 + 0xdf, 0xFF, 0xFF, 0xFF, +}; + +static const unsigned char toshiba_panel_set_hor_addr_2B_wvga[12] = { + + 0x05, 0x00, 0x39, 0xC0, // 1 last packet + // 0x2B, 0x00, 0x08, 0x00,//0X355 = 854-1; 0X1DF = 480-1 + // 0x6b, 0xFF, 0xFF, 0xFF, + 0x2B, 0x00, 0x00, 0x03, // 0X355 = 854-1; 0X1DF = 480-1 + 0x55, 0xFF, 0xFF, 0xFF, +}; + +static const unsigned char toshiba_panel_set_hor_addr_2A_wqvga[12] + = { + + 0x05, 0x00, 0x39, 0xC0, // 1 last packet + 0x2A, 0x00, 0x00, 0x00, // 0XEF = 240-1 + 0xef, 0xFF, 0xFF, 0xFF, +}; + +static const unsigned char toshiba_panel_set_hor_addr_2B_wqvga[12] + = { + + 0x05, 0x00, 0x39, 0xC0, // 1 last packet + 0x2B, 0x00, 0x00, 0x01, // 0X1aa = 427-1; + 0xaa, 0xFF, 0xFF, 0xFF, +}; + +static const unsigned char toshiba_panel_IFSEL[8] = { + 0x02, 0x00, 0x29, 0xc0, + 0x53, 0x01, 0xff, 0xff +}; + +static const unsigned char toshiba_panel_IFSEL_cmd_mode[8] = { + 0x02, 0x00, 0x29, 0xc0, + 0x53, 0x00, 0xff, 0xff +}; + +static const unsigned char toshiba_panel_exit_sleep[4] = { + 0x11, 0x00, 0x05, 0x80, // 25 Reg 0x29 < Display On>; generic write 1 + // params +}; + +static const unsigned char toshiba_panel_display_on[4] = { + // 0x29, 0x00, 0x05, 0x80,//25 Reg 0x29 < Display On>; generic write 1 + // params + 0x29, 0x00, 0x05, 0x80, // 25 Reg 0x29 < Display On>; generic write 1 + // params +}; + +//color mode off +static const unsigned char dsi_display_config_color_mode_off[4] = { + 0x00, 0x00, 0x02, 0x80, +}; + +//color mode on +static const unsigned char dsi_display_config_color_mode_on[4] = { + 0x00, 0x00, 0x12, 0x80, +}; + +//the end OF Tochiba Config- video mode + +/* NOVATEK BLUE panel */ +static char novatek_panel_sw_reset[4] = {0x01, 0x00, 0x05, 0x00}; /* DTYPE_DCS_WRITE */ +static char novatek_panel_enter_sleep[4] = {0x10, 0x00, 0x05, 0x80}; /* DTYPE_DCS_WRITE */ +static char novatek_panel_exit_sleep[4] = {0x11, 0x00, 0x05, 0x80}; /* DTYPE_DCS_WRITE */ +static char novatek_panel_display_off[4] = {0x28, 0x00, 0x05, 0x80}; /* DTYPE_DCS_WRITE */ +static char novatek_panel_display_on[4] = {0x29, 0x00, 0x05, 0x80}; /* DTYPE_DCS_WRITE */ + +static char novatek_panel_set_onelane[4] = {0xae, 0x01, 0x15, 0x80}; /* DTYPE_DCS_WRITE1 */ +static char novatek_panel_rgb_888[4] = {0x3A, 0x77, 0x15, 0x80}; /* DTYPE_DCS_WRITE1 */ +static char novatek_panel_set_twolane[4] = {0xae, 0x03, 0x15, 0x80}; /* DTYPE_DCS_WRITE1 */ + +/* commands by Novatke */ +static char novatek_panel_f4[4] = {0xf4, 0x55, 0x15, 0x80}; /* DTYPE_DCS_WRITE1 */ +static char novatek_panel_8c[20] = { /* DTYPE_DCS_LWRITE */ + 0x10, 0x00, 0x39, 0xC0, 0x8C, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x08, 0x00, 0x30, 0xC0, 0xB7, 0x37}; +static char novatek_panel_ff[4] = {0xff, 0x55, 0x15, 0x80}; /* DTYPE_DCS_WRITE1 */ + +static char novatek_panel_set_width[12] = { /* DTYPE_DCS_LWRITE */ + 0x05, 0x00, 0x39, 0xC0,//1 last packet + 0x2A, 0x00, 0x00, 0x02,//clmn:0 - 0x21B=539 + 0x1B, 0xFF, 0xFF, 0xFF +}; /* 540 - 1 */ +static char novatek_panel_set_height[12] = { /* DTYPE_DCS_LWRITE */ + 0x05, 0x00, 0x39, 0xC0,//1 last packet + 0x2B, 0x00, 0x00, 0x03,//row:0 - 0x3BF=959 + 0xBF, 0xFF, 0xFF, 0xFF, +}; /* 960 - 1 */ +/* End of Novatek Blue panel commands */ + + +#define MIPI_VIDEO_MODE 1 +#define MIPI_CMD_MODE 2 + +struct mipi_dsi_phy_ctrl { + uint32_t regulator[4]; + uint32_t timing[12]; + uint32_t ctrl[4]; + uint32_t strength[4]; + uint32_t pll[21]; +}; + +struct mipi_dsi_cmd { + int size; + char *payload; +}; + +struct mipi_dsi_panel_config { + char mode; + char num_of_lanes; + struct mipi_dsi_phy_ctrl *dsi_phy_config; + struct mipi_dsi_cmd *panel_cmds; + int num_of_panel_cmds; +}; + +static struct mipi_dsi_cmd toshiba_panel_video_mode_cmds[] = { + {sizeof(toshiba_panel_mcap_off), toshiba_panel_mcap_off}, + {sizeof(toshiba_panel_ena_test_reg), toshiba_panel_ena_test_reg}, + {sizeof(toshiba_panel_num_of_1lane), toshiba_panel_num_of_1lane}, + {sizeof(toshiba_panel_non_burst_sync_pulse), toshiba_panel_non_burst_sync_pulse}, + {sizeof(toshiba_panel_set_DMODE_WVGA), toshiba_panel_set_DMODE_WVGA}, + {sizeof(toshiba_panel_set_intern_WR_clk1_wvga), toshiba_panel_set_intern_WR_clk1_wvga}, + {sizeof(toshiba_panel_set_intern_WR_clk2_wvga), toshiba_panel_set_intern_WR_clk2_wvga}, + {sizeof(toshiba_panel_set_hor_addr_2A_wvga), toshiba_panel_set_hor_addr_2A_wvga}, + {sizeof(toshiba_panel_set_hor_addr_2B_wvga), toshiba_panel_set_hor_addr_2B_wvga}, + {sizeof(toshiba_panel_IFSEL), toshiba_panel_IFSEL}, + {sizeof(toshiba_panel_exit_sleep), toshiba_panel_exit_sleep}, + {sizeof(toshiba_panel_display_on), toshiba_panel_display_on}, + {sizeof(dsi_display_config_color_mode_on), dsi_display_config_color_mode_on}, + {sizeof(dsi_display_config_color_mode_off), dsi_display_config_color_mode_off}, +}; + +static struct mipi_dsi_phy_ctrl mipi_dsi_toshiba_panel_phy_ctrl = { + /* 480*854, RGB888, 1 Lane 60 fps video mode */ + {0x03, 0x01, 0x01, 0x00}, /* regulator */ + /* timing */ + {0x50, 0x0f, 0x14, 0x19, 0x23, 0x0e, 0x12, 0x16, + 0x1b, 0x1c, 0x04}, + {0x7f, 0x00, 0x00, 0x00}, /* phy ctrl */ + {0xee, 0x03, 0x86, 0x03}, /* strength */ + /* pll control */ + +#if defined(DSI_BIT_CLK_366MHZ) + {0x41, 0xdb, 0xb2, 0xf5, 0x00, 0x50, 0x48, 0x63, + 0x31, 0x0f, 0x07, + 0x05, 0x14, 0x03, 0x03, 0x03, 0x54, 0x06, 0x10, 0x04, 0x03 }, +#elif defined(DSI_BIT_CLK_380MHZ) + {0x41, 0xf7, 0xb2, 0xf5, 0x00, 0x50, 0x48, 0x63, + 0x31, 0x0f, 0x07, + 0x05, 0x14, 0x03, 0x03, 0x03, 0x54, 0x06, 0x10, 0x04, 0x03 }, +#elif defined(DSI_BIT_CLK_400MHZ) + {0x41, 0x8f, 0xb1, 0xda, 0x00, 0x50, 0x48, 0x63, + 0x31, 0x0f, 0x07, + 0x05, 0x14, 0x03, 0x03, 0x03, 0x54, 0x06, 0x10, 0x04, 0x03 }, +#else /* 200 mhz */ + {0x41, 0x8f, 0xb1, 0xda, 0x00, 0x50, 0x48, 0x63, + 0x33, 0x1f, 0x1f /* for 1 lane ; 0x0f for 2 lanes*/, + 0x05, 0x14, 0x03, 0x03, 0x03, 0x54, 0x06, 0x10, 0x04, 0x03 }, +#endif +}; + +static struct mipi_dsi_cmd novatek_panel_cmd_mode_cmds[] = { + {sizeof(novatek_panel_sw_reset), novatek_panel_sw_reset}, + {sizeof(novatek_panel_exit_sleep), novatek_panel_exit_sleep}, + {sizeof(novatek_panel_display_on), novatek_panel_display_on}, + {sizeof(novatek_panel_f4), novatek_panel_f4}, + {sizeof(novatek_panel_8c), novatek_panel_8c}, + {sizeof(novatek_panel_ff), novatek_panel_ff}, + {sizeof(novatek_panel_set_twolane), novatek_panel_set_twolane}, + {sizeof(novatek_panel_set_width), novatek_panel_set_width}, + {sizeof(novatek_panel_set_height), novatek_panel_set_height}, + {sizeof(novatek_panel_rgb_888), novatek_panel_rgb_888} +}; + +static struct mipi_dsi_phy_ctrl mipi_dsi_novatek_panel_phy_ctrl = { + /* DSI_BIT_CLK at 500MHz, 2 lane, RGB888 */ + {0x03, 0x01, 0x01, 0x00}, /* regulator */ + /* timing */ + {0x96, 0x26, 0x23, 0x00, 0x50, 0x4B, 0x1e, + 0x28, 0x28, 0x03, 0x04}, + {0x7f, 0x00, 0x00, 0x00}, /* phy ctrl */ + {0xee, 0x02, 0x86, 0x00}, /* strength */ + /* pll control */ + {0x40, 0xf9, 0xb0, 0xda, 0x00, 0x50, 0x48, 0x63, + /* 0x30, 0x07, 0x07, --> One lane configuration */ + 0x30, 0x07, 0x03, /* --> Two lane configuration */ + 0x05, 0x14, 0x03, 0x0, 0x0, 0x54, 0x06, 0x10, 0x04, 0x0}, +}; + +struct mipi_dsi_panel_config toshiba_panel_info = { + .mode = MIPI_VIDEO_MODE, + .num_of_lanes = 1, + .dsi_phy_config = &mipi_dsi_toshiba_panel_phy_ctrl, + .panel_cmds = toshiba_panel_video_mode_cmds, + .num_of_panel_cmds = ARRAY_SIZE(toshiba_panel_video_mode_cmds), +}; + +struct mipi_dsi_panel_config novatek_panel_info = { + .mode = MIPI_CMD_MODE, + .num_of_lanes = 2, + .dsi_phy_config = &mipi_dsi_novatek_panel_phy_ctrl, + .panel_cmds = novatek_panel_cmd_mode_cmds, + .num_of_panel_cmds = ARRAY_SIZE(novatek_panel_cmd_mode_cmds), +}; + +#endif diff --git a/lk/platform/msm_shared/include/mmc.h b/lk/platform/msm_shared/include/mmc.h new file mode 100644 index 0000000..1d230c1 --- /dev/null +++ b/lk/platform/msm_shared/include/mmc.h @@ -0,0 +1,623 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 __MMC_H__ +#define __MMC_H__ + +#ifndef MMC_SLOT +#define MMC_SLOT 0 +#endif + +#define MMC_BOOT_MCI_REG(offset) ((mmc_boot_mci_base) + offset) + +/* + * Define Macros for SDCC Registers + */ +#define MMC_BOOT_MCI_POWER MMC_BOOT_MCI_REG(0x000) /* 8 bit */ + +/* MCICMD output control - 6th bit */ +#ifdef PLATFORM_MSM7X30 +#define MMC_BOOT_MCI_OPEN_DRAIN (1 << 6) +#define MMC_BOOT_MCI_PWR_OFF 0x00 +#define MMC_BOOT_MCI_PWR_UP 0x01 +#define MMC_BOOT_MCI_PWR_ON 0x01 +#else +#define MMC_BOOT_MCI_OPEN_DRAIN (1 << 6) +#define MMC_BOOT_MCI_PWR_OFF 0x00 +#define MMC_BOOT_MCI_PWR_UP 0x02 +#define MMC_BOOT_MCI_PWR_ON 0x03 +#endif + +#define MMC_BOOT_MCI_CLK MMC_BOOT_MCI_REG(0x004) /* 16 bits */ +/* Enable MCI bus clock - 0: clock disabled 1: enabled */ +#define MMC_BOOT_MCI_CLK_ENABLE (1 << 8) +/* Disable clk o/p when bus idle- 0:always enabled 1:enabled when bus active */ +#define MMC_BOOT_MCI_CLK_PWRSAVE (1 << 9) +/* Enable Widebus mode - 00: 1 bit mode 10:4 bit mode 01/11: 8 bit mode */ +#define MMC_BOOT_MCI_CLK_WIDEBUS_MODE (3 << 10) +#define MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT 0 +#define MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT (2 << 10) +#define MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT (1 << 10) +/* Enable flow control- 0: disable 1: enable */ +#define MMC_BOOT_MCI_CLK_ENA_FLOW (1 << 12) +/* Set/clear to select rising/falling edge for data/cmd output */ +#define MMC_BOOT_MCI_CLK_INVERT_OUT (1 << 13) +/* Select to lach data/cmd coming in falling/rising/feedbk/loopbk of MCIclk */ +#define MMC_BOOT_MCI_CLK_IN_FALLING 0x0 +#define MMC_BOOT_MCI_CLK_IN_RISING (1 << 14) +#define MMC_BOOT_MCI_CLK_IN_FEEDBACK (2 << 14) +#define MMC_BOOT_MCI_CLK_IN_LOOPBACK (3 << 14) + +/* Bus Width */ +#define MMC_BOOT_BUS_WIDTH_1_BIT 0 +#define MMC_BOOT_BUS_WIDTH_4_BIT 2 +#define MMC_BOOT_BUS_WIDTH_8_BIT 3 + +#define MMC_BOOT_MCI_ARGUMENT MMC_BOOT_MCI_REG(0x008) /* 32 bits */ + +#define MMC_BOOT_MCI_CMD MMC_BOOT_MCI_REG(0x00C) /* 16 bits */ +/* Command Index: 0 -5 */ +/* Waits for response if set */ +#define MMC_BOOT_MCI_CMD_RESPONSE (1 << 6) +/* Receives a 136-bit long response if set */ +#define MMC_BOOT_MCI_CMD_LONGRSP (1 << 7) +/* If set, CPSM disables command timer and waits for interrupt */ +#define MMC_BOOT_MCI_CMD_INTERRUPT (1 << 8) +/* If set waits for CmdPend before starting to send a command */ +#define MMC_BOOT_MCI_CMD_PENDING (1 << 9) +/* CPSM is enabled if set */ +#define MMC_BOOT_MCI_CMD_ENABLE (1 << 10) +/* If set PROG_DONE status bit asserted when busy is de-asserted */ +#define MMC_BOOT_MCI_CMD_PROG_ENA (1 << 11) +/* To indicate that this is a Command with Data (for SDIO interrupts) */ +#define MMC_BOOT_MCI_CMD_DAT_CMD (1 << 12) +/* Signals the next command to be an abort (stop) command. Always read 0 */ +#define MMC_BOOT_MCI_CMD_MCIABORT (1 << 13) +/* Waits for Command Completion Signal if set */ +#define MMC_BOOT_MCI_CMD_CCS_ENABLE (1 << 14) +/* If set sends CCS disable sequence */ +#define MMC_BOOT_MCI_CMD_CCS_DISABLE (1 << 15) + +#define MMC_BOOT_MCI_RESP_CMD MMC_BOOT_MCI_REG(0x010) + +#define MMC_BOOT_MCI_RESP_0 MMC_BOOT_MCI_REG(0x014) +#define MMC_BOOT_MCI_RESP_1 MMC_BOOT_MCI_REG(0x018) +#define MMC_BOOT_MCI_RESP_2 MMC_BOOT_MCI_REG(0x01C) +#define MMC_BOOT_MCI_RESP_3 MMC_BOOT_MCI_REG(0x020) + +#define MMC_BOOT_MCI_DATA_TIMER MMC_BOOT_MCI_REG(0x024) +#define MMC_BOOT_MCI_DATA_LENGTH MMC_BOOT_MCI_REG(0x028) +#define MMC_BOOT_MCI_DATA_CTL MMC_BOOT_MCI_REG(0x02C) /* 16 bits */ +/* Data transfer enabled */ +#define MMC_BOOT_MCI_DATA_ENABLE (1 << 0) +/* Data transfer direction - 0: controller to card 1:card to controller */ +#define MMC_BOOT_MCI_DATA_DIR (1 << 1) +/* Data transfer mode - 0: block data transfer 1: stream data transfer */ +#define MMC_BOOT_MCI_DATA_MODE (1 << 2) +/* Enable DM interface - 0: DM disabled 1: DM enabled */ +#define MMC_BOOT_MCI_DATA_DM_ENABLE (1 << 3) +/* Data block length in bytes (1-4096) */ +#define MMC_BOOT_MCI_BLKSIZE_POS 4 +#define MMC_BOOT_MCI_DATA_COUNT MMC_BOOT_MCI_REG(0x030) +#define MMC_BOOT_MCI_STATUS MMC_BOOT_MCI_REG(0x034) +/* Command response received - CRC check failed */ +#define MMC_BOOT_MCI_STAT_CMD_CRC_FAIL (1 << 0) +/* Data block sent/received - CRC check failed */ +#define MMC_BOOT_MCI_STAT_DATA_CRC_FAIL (1 << 1) +/* Command resonse timeout */ +#define MMC_BOOT_MCI_STAT_CMD_TIMEOUT (1 << 2) +/* Data timeout */ +#define MMC_BOOT_MCI_STAT_DATA_TIMEOUT (1 << 3) +/* Transmit FIFO underrun error */ +#define MMC_BOOT_MCI_STAT_TX_UNDRUN (1 << 4) +/* Receive FIFO overrun error */ +#define MMC_BOOT_MCI_STAT_RX_OVRRUN (1 << 5) +/* Command response received - CRC check passed */ +#define MMC_BOOT_MCI_STAT_CMD_RESP_END (1 << 6) +/* Command sent - no response required */ +#define MMC_BOOT_MCI_STAT_CMD_SENT (1 << 7) +/* Data end - data counter zero */ +#define MMC_BOOT_MCI_STAT_DATA_END (1 << 8) +/* Start bit not detected on all data signals in wide bus mode */ +#define MMC_BOOT_MCI_STAT_START_BIT_ERR (1 << 9) +/* Data block sent/received - CRC check passed */ +#define MMC_BOOT_MCI_STAT_DATA_BLK_END (1 << 10) +/* Command transfer in progress */ +#define MMC_BOOT_MCI_STAT_CMD_ACTIVE (1 << 11) +/* Data transmit in progress */ +#define MMC_BOOT_MCI_STAT_TX_ACTIVE (1 << 12) +/* Data receive in progress */ +#define MMC_BOOT_MCI_STAT_RX_ACTIVE (1 << 13) +/* Transmit FIFO half full */ +#define MMC_BOOT_MCI_STAT_TX_FIFO_HFULL (1 << 14) +/* Receive FIFO half full */ +#define MMC_BOOT_MCI_STAT_RX_FIFO_HFULL (1 << 15) +/* Transmit FIFO full */ +#define MMC_BOOT_MCI_STAT_TX_FIFO_FULL (1 << 16) +/* Receive FIFO full */ +#define MMC_BOOT_MCI_STAT_RX_FIFO_FULL (1 << 17) +/* Transmit FIFO empty */ +#define MMC_BOOT_MCI_STAT_TX_FIFO_EMPTY (1 << 18) +/* Receive FIFO empty */ +#define MMC_BOOT_MCI_STAT_RX_FIFO_EMPTY (1 << 19) +/* Data available in transmit FIFO */ +#define MMC_BOOT_MCI_STAT_TX_DATA_AVLBL (1 << 20) +/* Data available in receive FIFO */ +#define MMC_BOOT_MCI_STAT_RX_DATA_AVLBL (1 << 21) +/* SDIO interrupt indicator for wake-up */ +#define MMC_BOOT_MCI_STAT_SDIO_INTR (1 << 22) +/* Programming done */ +#define MMC_BOOT_MCI_STAT_PROG_DONE (1 << 23) +/* CE-ATA command completion signal detected */ +#define MMC_BOOT_MCI_STAT_ATA_CMD_CMPL (1 << 24) +/* SDIO interrupt indicator for normal operation */ +#define MMC_BOOT_MCI_STAT_SDIO_INTR_OP (1 << 25) +/* Commpand completion signal timeout */ +#define MMC_BOOT_MCI_STAT_CCS_TIMEOUT (1 << 26) + +#define MMC_BOOT_MCI_STATIC_STATUS (MMC_BOOT_MCI_STAT_CMD_CRC_FAIL| \ + MMC_BOOT_MCI_STAT_DATA_CRC_FAIL| \ + MMC_BOOT_MCI_STAT_CMD_TIMEOUT| \ + MMC_BOOT_MCI_STAT_DATA_TIMEOUT| \ + MMC_BOOT_MCI_STAT_TX_UNDRUN| \ + MMC_BOOT_MCI_STAT_RX_OVRRUN| \ + MMC_BOOT_MCI_STAT_CMD_RESP_END| \ + MMC_BOOT_MCI_STAT_CMD_SENT| \ + MMC_BOOT_MCI_STAT_DATA_END| \ + MMC_BOOT_MCI_STAT_START_BIT_ERR| \ + MMC_BOOT_MCI_STAT_DATA_BLK_END| \ + MMC_BOOT_MCI_SDIO_INTR_CLR| \ + MMC_BOOT_MCI_STAT_PROG_DONE| \ + MMC_BOOT_MCI_STAT_ATA_CMD_CMPL |\ + MMC_BOOT_MCI_STAT_CCS_TIMEOUT) + +#define MMC_BOOT_MCI_CLEAR MMC_BOOT_MCI_REG(0x038) +#define MMC_BOOT_MCI_CMD_CRC_FAIL_CLR (1 << 0) +#define MMC_BOOT_MCI_DATA_CRC_FAIL_CLR (1 << 1) +#define MMC_BOOT_MCI_CMD_TIMEOUT_CLR (1 << 2) +#define MMC_BOOT_MCI_DATA_TIMEOUT_CLR (1 << 3) +#define MMC_BOOT_MCI_TX_UNDERRUN_CLR (1 << 4) +#define MMC_BOOT_MCI_RX_OVERRUN_CLR (1 << 5) +#define MMC_BOOT_MCI_CMD_RESP_END_CLR (1 << 6) +#define MMC_BOOT_MCI_CMD_SENT_CLR (1 << 7) +#define MMC_BOOT_MCI_DATA_END_CLR (1 << 8) +#define MMC_BOOT_MCI_START_BIT_ERR_CLR (1 << 9) +#define MMC_BOOT_MCI_DATA_BLK_END_CLR (1 << 10) +#define MMC_BOOT_MCI_SDIO_INTR_CLR (1 << 22) +#define MMC_BOOT_MCI_PROG_DONE_CLR (1 << 23) +#define MMC_BOOT_MCI_ATA_CMD_COMPLR_CLR (1 << 24) +#define MMC_BOOT_MCI_CCS_TIMEOUT_CLR (1 << 25) + +#define MMC_BOOT_MCI_INT_MASK0 MMC_BOOT_MCI_REG(0x03C) +#define MMC_BOOT_MCI_CMD_CRC_FAIL_MASK (1 << 0) +#define MMC_BOOT_MCI_DATA_CRC_FAIL_MASK (1 << 1) +#define MMC_BOOT_MCI_CMD_TIMEOUT_MASK (1 << 2) +#define MMC_BOOT_MCI_DATA_TIMEOUT_MASK (1 << 3) +#define MMC_BOOT_MCI_TX_OVERRUN_MASK (1 << 4) +#define MMC_BOOT_MCI_RX_OVERRUN_MASK (1 << 5) +#define MMC_BOOT_MCI_CMD_RESP_END_MASK (1 << 6) +#define MMC_BOOT_MCI_CMD_SENT_MASK (1 << 7) +#define MMC_BOOT_MCI_DATA_END_MASK (1 << 8) +#define MMC_BOOT_MCI_START_BIT_ERR_MASK (1 << 9) +#define MMC_BOOT_MCI_DATA_BLK_END_MASK (1 << 10) +#define MMC_BOOT_MCI_CMD_ACTIVE_MASK (1 << 11) +#define MMC_BOOT_MCI_TX_ACTIVE_MASK (1 << 12) +#define MMC_BOOT_MCI_RX_ACTIVE_MASK (1 << 13) +#define MMC_BOOT_MCI_TX_FIFO_HFULL_MASK (1 << 14) +#define MMC_BOOT_MCI_RX_FIFO_HFULL_MASK (1 << 15) +#define MMC_BOOT_MCI_TX_FIFO_FULL_MASK (1 << 16) +#define MMC_BOOT_MCI_RX_FIFO_FULL_MASK (1 << 17) +#define MMC_BOOT_MCI_TX_FIFO_EMPTY_MASK (1 << 18) +#define MMC_BOOT_MCI_RX_FIFO_EMPTY_MASK (1 << 19) +#define MMC_BOOT_MCI_TX_DATA_AVLBL_MASK (1 << 20) +#define MMC_BOOT_MCI_RX_DATA_AVLBL_MASK (1 << 21) +#define MMC_BOOT_MCI_SDIO_INT_MASK (1 << 22) +#define MMC_BOOT_MCI_PROG_DONE_MASK (1 << 23) +#define MMC_BOOT_MCI_ATA_CMD_COMPL_MASK (1 << 24) +#define MMC_BOOT_MCI_SDIO_INT_OPER_MASK (1 << 25) +#define MMC_BOOT_MCI_CCS_TIME_OUT_MASK (1 << 26) + +#define MMC_BOOT_MCI_INT_MASK1 MMC_BOOT_MCI_REG(0x040) + +#define MMC_BOOT_MCI_FIFO_COUNT MMC_BOOT_MCI_REG(0x044) + +#define MMC_BOOT_MCI_CCS_TIMER MMC_BOOT_MCI_REG(0x0058) + +#define MMC_BOOT_MCI_FIFO MMC_BOOT_MCI_REG(0x080) + +/* Card status */ +#define MMC_BOOT_CARD_STATUS(x) ((x>>9) & 0x0F) +#define MMC_BOOT_TRAN_STATE 4 +#define MMC_BOOT_PROG_STATE 7 + +/* SD Memory Card bus commands */ +#define CMD0_GO_IDLE_STATE 0 +#define CMD1_SEND_OP_COND 1 +#define CMD2_ALL_SEND_CID 2 +#define CMD3_SEND_RELATIVE_ADDR 3 +#define CMD4_SET_DSR 4 +#define CMD6_SWITCH_FUNC 6 +#define ACMD6_SET_BUS_WIDTH 6 /* SD card */ +#define CMD7_SELECT_DESELECT_CARD 7 +#define CMD8_SEND_EXT_CSD 8 +#define CMD8_SEND_IF_COND 8 /* SD card */ +#define CMD9_SEND_CSD 9 +#define CMD10_SEND_CID 10 +#define CMD12_STOP_TRANSMISSION 12 +#define CMD13_SEND_STATUS 13 +#define CMD15_GO_INACTIVE_STATUS 15 +#define CMD16_SET_BLOCKLEN 16 +#define CMD17_READ_SINGLE_BLOCK 17 +#define CMD18_READ_MULTIPLE_BLOCK 18 +#define CMD24_WRITE_SINGLE_BLOCK 24 +#define CMD25_WRITE_MULTIPLE_BLOCK 25 +#define CMD28_SET_WRITE_PROTECT 28 +#define CMD29_CLEAR_WRITE_PROTECT 29 +#define CMD31_SEND_WRITE_PROT_TYPE 31 +#define CMD32_ERASE_WR_BLK_START 32 +#define CMD33_ERASE_WR_BLK_END 33 +#define CMD38_ERASE 38 +#define ACMD41_SEND_OP_COND 41 /* SD card */ +#define ACMD51_SEND_SCR 51 /* SD card */ +#define CMD55_APP_CMD 55 /* SD card */ + +/* Switch Function Modes */ +#define MMC_BOOT_SWITCH_FUNC_CHECK 0 +#define MMC_BOOT_SWITCH_FUNC_SET 1 + +/* OCR Register */ +#define MMC_BOOT_OCR_17_19 (1 << 7) +#define MMC_BOOT_OCR_27_36 (0x1FF << 15) +#define MMC_BOOT_OCR_SEC_MODE (2 << 29) +#define MMC_BOOT_OCR_BUSY (1 << 31) + +/* Commands type */ +#define MMC_BOOT_CMD_BCAST (1 << 0) +#define MMC_BOOT_CMD_BCAST_W_RESP (1 << 1) +#define MMC_BOOT_CMD_ADDRESS (1 << 2) +#define MMC_BOOT_CMD_ADDR_DATA_XFER (1 << 3) + +/* Response types */ +#define MMC_BOOT_RESP_NONE 0 +#define MMC_BOOT_RESP_R1 (1 << 0) +#define MMC_BOOT_RESP_R1B (1 << 1) +#define MMC_BOOT_RESP_R2 (1 << 2) +#define MMC_BOOT_RESP_R3 (1 << 3) +#define MMC_BOOT_RESP_R6 (1 << 6) +#define MMC_BOOT_RESP_R7 (1 << 7) + +#define IS_RESP_136_BITS(x) (x & MMC_BOOT_RESP_R2) +#define CHECK_FOR_BUSY_AT_RESP(x) + +/* Card Status bits (R1 register) */ +#define MMC_BOOT_R1_AKE_SEQ_ERROR (1 << 3) +#define MMC_BOOT_R1_APP_CMD (1 << 5) +#define MMC_BOOT_R1_RDY_FOR_DATA (1 << 6) +#define MMC_BOOT_R1_CURR_STATE_IDLE (0 << 9) +#define MMC_BOOT_R1_CURR_STATE_RDY (1 << 9) +#define MMC_BOOT_R1_CURR_STATE_IDENT (2 << 9) +#define MMC_BOOT_R1_CURR_STATE_STBY (3 << 9) +#define MMC_BOOT_R1_CURR_STATE_TRAN (4 << 9) +#define MMC_BOOT_R1_CURR_STATE_DATA (5 << 9) +#define MMC_BOOT_R1_CURR_STATE_RCV (6 << 9) +#define MMC_BOOT_R1_CURR_STATE_PRG (7 << 9) +#define MMC_BOOT_R1_CURR_STATE_DIS (8 << 9) +#define MMC_BOOT_R1_ERASE_RESET (1 << 13) +#define MMC_BOOT_R1_CARD_ECC_DISABLED (1 << 14) +#define MMC_BOOT_R1_WP_ERASE_SKIP (1 << 15) +#define MMC_BOOT_R1_ERROR (1 << 19) +#define MMC_BOOT_R1_CC_ERROR (1 << 20) +#define MMC_BOOT_R1_CARD_ECC_FAILED (1 << 21) +#define MMC_BOOT_R1_ILLEGAL_CMD (1 << 22) +#define MMC_BOOT_R1_COM_CRC_ERR (1 << 23) +#define MMC_BOOT_R1_LOCK_UNLOCK_FAIL (1 << 24) +#define MMC_BOOT_R1_CARD_IS_LOCKED (1 << 25) +#define MMC_BOOT_R1_WP_VIOLATION (1 << 26) +#define MMC_BOOT_R1_ERASE_PARAM (1 << 27) +#define MMC_BOOT_R1_ERASE_SEQ_ERR (1 << 28) +#define MMC_BOOT_R1_BLOCK_LEN_ERR (1 << 29) +#define MMC_BOOT_R1_ADDR_ERR (1 << 30) +#define MMC_BOOT_R1_OUT_OF_RANGE (1 << 31) + +/* Macros for Common Errors */ +#define MMC_BOOT_E_SUCCESS 0 +#define MMC_BOOT_E_FAILURE 1 +#define MMC_BOOT_E_TIMEOUT 2 +#define MMC_BOOT_E_INVAL 3 +#define MMC_BOOT_E_CRC_FAIL 4 +#define MMC_BOOT_E_INIT_FAIL 5 +#define MMC_BOOT_E_CMD_INDX_MISMATCH 6 +#define MMC_BOOT_E_RESP_VERIFY_FAIL 7 +#define MMC_BOOT_E_NOT_SUPPORTED 8 +#define MMC_BOOT_E_CARD_BUSY 9 +#define MMC_BOOT_E_MEM_ALLOC_FAIL 10 +#define MMC_BOOT_E_CLK_ENABLE_FAIL 11 +#define MMC_BOOT_E_CMMC_DECODE_FAIL 12 +#define MMC_BOOT_E_CID_DECODE_FAIL 13 +#define MMC_BOOT_E_BLOCKLEN_ERR 14 +#define MMC_BOOT_E_ADDRESS_ERR 15 +#define MMC_BOOT_E_DATA_CRC_FAIL 16 +#define MMC_BOOT_E_DATA_TIMEOUT 17 +#define MMC_BOOT_E_RX_OVRRUN 18 +#define MMC_BOOT_E_VREG_SET_FAILED 19 +#define MMC_BOOT_E_GPIO_CFG_FAIL 20 + +/* EXT_CSD */ +#define MMC_BOOT_ACCESS_WRITE 0x3 +#define MMC_BOOT_EXT_CMMC_HS_TIMING 185 +#define MMC_BOOT_EXT_CMMC_BUS_WIDTH 183 + +#define MMC_BOOT_EXT_USER_WP 171 +#define MMC_BOOT_EXT_ERASE_GROUP_DEF 175 +#define MMC_BOOT_EXT_HC_WP_GRP_SIZE 221 +#define MMC_BOOT_EXT_HC_ERASE_GRP_SIZE 224 + +#define IS_BIT_SET_EXT_CSD(val, bit) ((ext_csd_buf[val]) & (1<<(bit))) +#define IS_ADDR_OUT_OF_RANGE(resp) ((resp >> 31) & 0x01) + +#define MMC_BOOT_US_PERM_WP_EN 2 +#define MMC_BOOT_US_PWR_WP_DIS 3 + +#define MMC_BOOT_US_PERM_WP_DIS (1<<4) +#define MMC_BOOT_US_PWR_WP_EN 1 + +/* For SD */ +#define MMC_BOOT_SD_HC_VOLT_SUPPLIED 0x000001AA +#define MMC_BOOT_SD_NEG_OCR 0x00FF8000 +#define MMC_BOOT_SD_HC_HCS 0x40000000 +#define MMC_BOOT_SD_DEV_READY 0x80000000 +#define MMC_BOOT_SD_SWITCH_HS 0x80FFFF01 + +/* Data structure definitions */ +struct mmc_boot_command +{ + unsigned int cmd_index; + unsigned int argument; + unsigned int cmd_type; + + unsigned int resp[4]; + unsigned int resp_type; + unsigned int prg_enabled; + unsigned int xfer_mode; +}; + +#define MMC_BOOT_XFER_MODE_BLOCK 0 +#define MMC_BOOT_XFER_MODE_STREAM 1 + +/* CSD Register. + * Note: not all the fields have been defined here + */ +struct mmc_boot_csd +{ + unsigned int cmmc_structure; + unsigned int card_cmd_class; + unsigned int write_blk_len; + unsigned int read_blk_len; + unsigned int r2w_factor; + unsigned int sector_size; + unsigned int c_size_mult; + unsigned int c_size; + unsigned int nsac_clk_cycle; + unsigned int taac_ns; + unsigned int tran_speed; + unsigned int erase_grp_size; + unsigned int erase_grp_mult; + unsigned int wp_grp_size; + unsigned int wp_grp_enable:1; + unsigned int perm_wp:1; + unsigned int temp_wp:1; + unsigned int erase_blk_len:1; + unsigned int read_blk_misalign:1; + unsigned int write_blk_misalign:1; + unsigned int read_blk_partial:1; + unsigned int write_blk_partial:1; +}; + +/* CID Register */ +struct mmc_boot_cid +{ + unsigned int mid; /* 8 bit manufacturer id*/ + unsigned int oid; /* 16 bits 2 character ASCII - OEM ID*/ + unsigned char pnm[7];/* 6 character ASCII - product name*/ + unsigned int prv; /* 8 bits - product revision */ + unsigned int psn; /* 32 bits - product serial number */ + unsigned int month; /* 4 bits manufacturing month */ + unsigned int year; /* 4 bits manufacturing year */ +}; + +/* SCR Register */ +struct mmc_boot_scr +{ + unsigned int scr_structure; + unsigned int mmc_spec; +#define MMC_BOOT_SCR_MMC_SPEC_V1_01 0 +#define MMC_BOOT_SCR_MMC_SPEC_V1_10 1 +#define MMC_BOOT_SCR_MMC_SPEC_V2_00 2 + unsigned int data_stat_after_erase; + unsigned int mmc_security; +#define MMC_BOOT_SCR_NO_SECURITY 0 +#define MMC_BOOT_SCR_SECURITY_UNUSED 1 +#define MMC_BOOT_SCR_SECURITY_V1_01 2 +#define MMC_BOOT_SCR_SECURITY_V2_00 3 + unsigned int mmc_bus_width; +#define MMC_BOOT_SCR_BUS_WIDTH_1_BIT (1<<0) +#define MMC_BOOT_SCR_BUS_WIDTH_4_BIT (1<<2) +}; + +struct mmc_boot_card +{ + unsigned int rca; + unsigned int ocr; + unsigned int capacity; + unsigned int type; +#define MMC_BOOT_TYPE_STD_SD 0 +#define MMC_BOOT_TYPE_SDHC 1 +#define MMC_BOOT_TYPE_SDIO 2 +#define MMC_BOOT_TYPE_MMCHC 3 +#define MMC_BOOT_TYPE_STD_MMC 4 + unsigned int status; +#define MMC_BOOT_STATUS_INACTIVE 0 +#define MMC_BOOT_STATUS_ACTIVE 1 + unsigned int rd_timeout_ns; + unsigned int wr_timeout_ns; + unsigned int rd_block_len; + unsigned int wr_block_len; + //unsigned int data_xfer_len; + struct mmc_boot_cid cid; + struct mmc_boot_csd csd; + struct mmc_boot_scr scr; +}; + +#define MMC_BOOT_XFER_MULTI_BLOCK 0 +#define MMC_BOOT_XFER_SINGLE_BLOCK 1 + +struct mmc_boot_host +{ + unsigned int mclk_rate; + unsigned int pclk_rate; + unsigned int ocr; + unsigned int cmd_retry; + unsigned int clk_enabled; +}; + + +/* MACRO used to evoke regcomp */ +#define REGCOMP_CKRTN(regx, str, errhandle) \ + do { \ + if(regcomp(regx, str, REG_EXTENDED) != 0) { \ + printf("Error building regex: %s\n", str); \ + goto errhandle; \ + } \ + } while(0); + + +#define GET_LWORD_FROM_BYTE(x) ((unsigned)*(x) | \ + ((unsigned)*(x+1) << 8) | \ + ((unsigned)*(x+2) << 16) | \ + ((unsigned)*(x+3) << 24)) + +#define PUT_LWORD_TO_BYTE(x, y) do{*(x) = y & 0xff; \ + *(x+1) = (y >> 8) & 0xff; \ + *(x+2) = (y >> 16) & 0xff; \ + *(x+3) = (y >> 24) & 0xff; }while(0) + +#define GET_PAR_NUM_FROM_POS(x) (((x & 0x0000FF00) >> 8) + (x & 0x000000FF)) + +/* Some useful define used to access the MBR/EBR table */ +#define BLOCK_SIZE 0x200 +#define TABLE_ENTRY_0 0x1BE +#define TABLE_ENTRY_1 0x1CE +#define TABLE_ENTRY_2 0x1DE +#define TABLE_ENTRY_3 0x1EE +#define TABLE_SIGNATURE 0x1FE +#define TABLE_ENTRY_SIZE 0x010 + +#define OFFSET_STATUS 0x00 +#define OFFSET_TYPE 0x04 +#define OFFSET_FIRST_SEC 0x08 +#define OFFSET_SIZE 0x0C +#define COPYBUFF_SIZE (1024 * 16) +#define BINARY_IN_TABLE_SIZE (16 * 512) +#define MAX_FILE_ENTRIES 20 + +#define MMC_MODEM_TYPE 0x06 +#define MMC_MODEM_TYPE2 0x0C +#define MMC_SBL1_TYPE 0x4D +#define MMC_SBL2_TYPE 0x51 +#define MMC_SBL3_TYPE 0x45 +#define MMC_RPM_TYPE 0x47 +#define MMC_TZ_TYPE 0x46 +#define MMC_MODEM_ST1_TYPE 0x4A +#define MMC_MODEM_ST2_TYPE 0x4B +#define MMC_EFS2_TYPE 0x4E + +#define MMC_ABOOT_TYPE 0x4C +#define MMC_BOOT_TYPE 0x48 +#define MMC_SYSTEM_TYPE 0x82 +#define MMC_USERDATA_TYPE 0x83 +#define MMC_RECOVERY_TYPE 0x60 + +#define MMC_RCA 2 + +struct mbr_entry +{ + unsigned dstatus; + unsigned dtype ; + unsigned dfirstsec; + unsigned dsize; + unsigned char name[64]; +}; + +/* Can be used to unpack array of upto 32 bits data */ +#define UNPACK_BITS(array, start, len, size_of) \ + ({ \ + unsigned int indx = (start) / (size_of); \ + unsigned int offset = (start) % (size_of); \ + unsigned int mask = (((len)<(size_of))? 1<<(len):0) - 1; \ + unsigned int unpck = array[indx] >> offset; \ + unsigned int indx2 = ((start) + (len) - 1) / (size_of); \ + if(indx2 > indx) \ + unpck |= array[indx2] << ((size_of) - offset); \ + unpck & mask; \ + }) + +#define MMC_BOOT_MAX_COMMAND_RETRY 10 +#define MMC_BOOT_RD_BLOCK_LEN 512 +#define MMC_BOOT_WR_BLOCK_LEN 512 + +/* We have 16 32-bits FIFO registers */ +#define MMC_BOOT_MCI_FIFO_COUNT 16 +#define MMC_BOOT_MCI_HFIFO_COUNT ( MMC_BOOT_MCI_FIFO_COUNT / 2 ) +#define MMC_BOOT_MCI_FIFO_SIZE ( MMC_BOOT_MCI_FIFO_COUNT * 4 ) + +/*Need to put at proper place*/ +#define SDC1_CLK 19 /* Secure Digital Card clocks */ +#define SDC1_PCLK 20 +#define SDC2_CLK 21 +#define SDC2_PCLK 22 +#define SDC3_CLK 23 +#define SDC3_PCLK 24 +#define SDC4_CLK 25 +#define SDC4_PCLK 26 + +#define MAX_PARTITIONS 64 + +#define MMC_BOOT_CHECK_PATTERN 0xAA /* 10101010b */ + +#define MMC_CLK_400KHZ 400000 +#define MMC_CLK_144KHZ 144000 +#define MMC_CLK_20MHZ 20000000 +#define MMC_CLK_25MHZ 25000000 +#define MMC_CLK_48MHZ 48000000 +#define MMC_CLK_50MHZ 49152000 + +#define MMC_CLK_ENABLE 1 +#define MMC_CLK_DISABLE 0 + +#endif + diff --git a/lk/platform/msm_shared/include/nand.h b/lk/platform/msm_shared/include/nand.h new file mode 100644 index 0000000..1b6b2a6 --- /dev/null +++ b/lk/platform/msm_shared/include/nand.h @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2008, Google 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. + * + * 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 __PLATFORM_MSM_SHARED_NAND_H +#define __PLATFORM_MSM_SHARED_NAND_H + +#ifdef PLATFORM_MSM7X30 +#define MSM_NAND_BASE 0xA0200000 +#else +#define MSM_NAND_BASE 0xA0A00000 +#endif + +#define MSM_NAND_NC01_BASE 0xA0240000 +#define MSM_NAND_NC10_BASE 0xA0280000 +#define MSM_NAND_NC11_BASE 0xA02C0000 +#define EBI2_REG_BASE 0xA0000000 + +#define NC01(off) (MSM_NAND_NC01_BASE + (off)) +#define NC10(off) (MSM_NAND_NC10_BASE + (off)) +#define NC11(off) (MSM_NAND_NC11_BASE + (off)) +#define EBI2_REG(off) (EBI2_REG_BASE + (off)) + +#define NAND_REG(off) (MSM_NAND_BASE + (off)) + +#define NAND_FLASH_CMD NAND_REG(0x0000) +#define NAND_ADDR0 NAND_REG(0x0004) +#define NAND_ADDR1 NAND_REG(0x0008) +#define NAND_FLASH_CHIP_SELECT NAND_REG(0x000C) +#define NAND_EXEC_CMD NAND_REG(0x0010) +#define NAND_FLASH_STATUS NAND_REG(0x0014) +#define NAND_BUFFER_STATUS NAND_REG(0x0018) +#define NAND_DEV0_CFG0 NAND_REG(0x0020) +#define NAND_DEV0_CFG1 NAND_REG(0x0024) +#define NAND_DEV1_CFG0 NAND_REG(0x0030) +#define NAND_DEV1_CFG1 NAND_REG(0x0034) +#define NAND_SFLASHC_CMD NAND_REG(0x0038) +#define NAND_SFLASHC_EXEC_CMD NAND_REG(0x003C) +#define NAND_READ_ID NAND_REG(0x0040) +#define NAND_READ_STATUS NAND_REG(0x0044) +#define NAND_CONFIG_DATA NAND_REG(0x0050) +#define NAND_CONFIG NAND_REG(0x0054) +#define NAND_CONFIG_MODE NAND_REG(0x0058) +#define NAND_CONFIG_STATUS NAND_REG(0x0060) +#define NAND_MACRO1_REG NAND_REG(0x0064) +#define NAND_XFR_STEP1 NAND_REG(0x0070) +#define NAND_XFR_STEP2 NAND_REG(0x0074) +#define NAND_XFR_STEP3 NAND_REG(0x0078) +#define NAND_XFR_STEP4 NAND_REG(0x007C) +#define NAND_XFR_STEP5 NAND_REG(0x0080) +#define NAND_XFR_STEP6 NAND_REG(0x0084) +#define NAND_XFR_STEP7 NAND_REG(0x0088) +#define NAND_GENP_REG0 NAND_REG(0x0090) +#define NAND_GENP_REG1 NAND_REG(0x0094) +#define NAND_GENP_REG2 NAND_REG(0x0098) +#define NAND_GENP_REG3 NAND_REG(0x009C) +#define NAND_SFLASHC_STATUS NAND_REG(0x001C) +#define NAND_DEV_CMD0 NAND_REG(0x00A0) +#define NAND_DEV_CMD1 NAND_REG(0x00A4) +#define NAND_DEV_CMD2 NAND_REG(0x00A8) +#define NAND_DEV_CMD_VLD NAND_REG(0x00AC) +#define NAND_EBI2_MISR_SIG_REG NAND_REG(0x00B0) +#define NAND_ADDR2 NAND_REG(0x00C0) +#define NAND_ADDR3 NAND_REG(0x00C4) +#define NAND_ADDR4 NAND_REG(0x00C8) +#define NAND_ADDR5 NAND_REG(0x00CC) +#define NAND_DEV_CMD3 NAND_REG(0x00D0) +#define NAND_DEV_CMD4 NAND_REG(0x00D4) +#define NAND_DEV_CMD5 NAND_REG(0x00D8) +#define NAND_DEV_CMD6 NAND_REG(0x00DC) +#define NAND_SFLASHC_BURST_CFG NAND_REG(0x00E0) +#define NAND_ADDR6 NAND_REG(0x00E4) +#define NAND_EBI2_ECC_BUF_CFG NAND_REG(0x00F0) +#define NAND_FLASH_BUFFER NAND_REG(0x0100) + +/* device commands */ + +#define NAND_CMD_SOFT_RESET 0x01 +#define NAND_CMD_PAGE_READ 0x32 +#define NAND_CMD_PAGE_READ_ECC 0x33 +#define NAND_CMD_PAGE_READ_ALL 0x34 +#define NAND_CMD_SEQ_PAGE_READ 0x15 +#define NAND_CMD_PRG_PAGE 0x36 +#define NAND_CMD_PRG_PAGE_ECC 0x37 +#define NAND_CMD_PRG_PAGE_ALL 0x39 +#define NAND_CMD_BLOCK_ERASE 0x3A +#define NAND_CMD_FETCH_ID 0x0B +#define NAND_CMD_STATUS 0x0C +#define NAND_CMD_RESET 0x0D + +/* Sflash Commands */ + +#define NAND_SFCMD_DATXS 0x0 +#define NAND_SFCMD_CMDXS 0x1 +#define NAND_SFCMD_BURST 0x0 +#define NAND_SFCMD_ASYNC 0x1 +#define NAND_SFCMD_ABORT 0x1 +#define NAND_SFCMD_REGRD 0x2 +#define NAND_SFCMD_REGWR 0x3 +#define NAND_SFCMD_INTLO 0x4 +#define NAND_SFCMD_INTHI 0x5 +#define NAND_SFCMD_DATRD 0x6 +#define NAND_SFCMD_DATWR 0x7 + + +#define SFLASH_PREPCMD(numxfr, offval, delval, trnstp, mode, opcode) \ + ((numxfr<<20)|(offval<<12)|(delval<<6)|(trnstp<<5)|(mode<<4)|opcode) + +#define SFLASH_BCFG 0x20100327 + +#define CLEAN_DATA_32 0xFFFFFFFF +#define CLEAN_DATA_16 0xFFFF + +/* Onenand addresses */ + +#define ONENAND_MANUFACTURER_ID 0xF000 +#define ONENAND_DEVICE_ID 0xF001 +#define ONENAND_VERSION_ID 0xF002 +#define ONENAND_DATA_BUFFER_SIZE 0xF003 +#define ONENAND_BOOT_BUFFER_SIZE 0xF004 +#define ONENAND_AMOUNT_OF_BUFFERS 0xF005 +#define ONENAND_TECHNOLOGY 0xF006 +#define ONENAND_START_ADDRESS_1 0xF100 +#define ONENAND_START_ADDRESS_2 0xF101 +#define ONENAND_START_ADDRESS_3 0xF102 +#define ONENAND_START_ADDRESS_4 0xF103 +#define ONENAND_START_ADDRESS_5 0xF104 +#define ONENAND_START_ADDRESS_6 0xF105 +#define ONENAND_START_ADDRESS_7 0xF106 +#define ONENAND_START_ADDRESS_8 0xF107 +#define ONENAND_START_BUFFER 0xF200 +#define ONENAND_COMMAND 0xF220 +#define ONENAND_SYSTEM_CONFIG_1 0xF221 +#define ONENAND_SYSTEM_CONFIG_2 0xF222 +#define ONENAND_CONTROLLER_STATUS 0xF240 +#define ONENAND_INTERRUPT_STATUS 0xF241 +#define ONENAND_START_BLOCK_ADDRESS 0xF24C +#define ONENAND_WRITE_PROT_STATUS 0xF24E +#define ONENAND_ECC_STATUS 0xFF00 +#define ONENAND_ECC_ERRPOS_MAIN0 0xFF01 +#define ONENAND_ECC_ERRPOS_SPARE0 0xFF02 +#define ONENAND_ECC_ERRPOS_MAIN1 0xFF03 +#define ONENAND_ECC_ERRPOS_SPARE1 0xFF04 +#define ONENAND_ECC_ERRPOS_MAIN2 0xFF05 +#define ONENAND_ECC_ERRPOS_SPARE2 0xFF06 +#define ONENAND_ECC_ERRPOS_MAIN3 0xFF07 +#define ONENAND_ECC_ERRPOS_SPARE3 0xFF08 + + +/* Onenand commands */ + +#define ONENAND_CMDLOAD 0x0000 +#define ONENAND_CMDLOADSPARE 0x0013 +#define ONENAND_CMDPROG 0x0080 +#define ONENAND_CMDPROGSPARE 0x001A +#define ONENAND_CMDERAS 0x0094 + +#define ONENAND_SYSCFG1_ECCENA 0x40E0 +#define ONENAND_SYSCFG1_ECCDIS 0x41E0 +#define ONENAND_CLRINTR 0x0000 +#define ONENAND_STARTADDR1_RES 0x07FF +#define ONENAND_STARTADDR3_RES 0x07FF + +#define DEVICE_FLASHCORE_0 0 +#define DEVICE_BUFFERRAM_0 0 +#define DATARAM0_0 0x8 + +/* Flash type */ +#define FLASH_UNKNOWN_DEVICE 0x00 +#define FLASH_NAND_DEVICE 0x01 +#define FLASH_8BIT_NAND_DEVICE 0x01 +#define FLASH_16BIT_NAND_DEVICE 0x02 +#define FLASH_ONENAND_DEVICE 0x03 + +#define EBI2_CFG_REG EBI2_REG(0x0004) +#define EBI2_NAND_ADM_MUX EBI2_REG(0x005C) +#define EBI2_CHIP_SELECT_CFG0 EBI2_REG(0x0000) + +#endif /* __PLATFORM_MSM_SHARED_NAND_H */ diff --git a/lk/platform/msm_shared/include/splash.h b/lk/platform/msm_shared/include/splash.h new file mode 100644 index 0000000..5a1b9b6 --- /dev/null +++ b/lk/platform/msm_shared/include/splash.h @@ -0,0 +1,12930 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 __PLATFORM_SPLASH_H +#define __PLATFORM_SPLASH_H + +#define SPLASH_IMAGE_WIDTH 113 +#define SPLASH_IMAGE_HEIGHT 228 + +#if (!DISPLAY_TYPE_MIPI) +/* This image is 228x113 raw Image resembling QuIC logo*/ +static char imageBuffer[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0x43, 0x00, 0xc6, 0x00, + 0x89, 0x01, 0x4e, 0x02, 0xf1, 0x02, 0x32, 0x03, 0x12, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, + 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, 0x32, 0x03, + 0x52, 0x03, 0x52, 0x03, + 0x52, 0x03, 0x52, 0x03, 0x53, 0x03, 0x53, 0x03, 0x53, 0x03, 0x53, 0x03, + 0x32, 0x03, 0xb0, 0x02, + 0x0c, 0x02, 0x28, 0x01, 0x84, 0x00, 0x22, 0x00, 0x01, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x83, 0x00, 0xa9, 0x09, 0x8e, 0x12, 0x51, 0x1b, 0x93, 0x13, + 0x94, 0x0b, 0xb4, 0x0b, + 0xb5, 0x0b, 0xb5, 0x0b, 0xb5, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x03, 0xb4, 0x03, 0xb4, 0x03, 0xb4, 0x03, + 0xb4, 0x03, 0xb4, 0x03, + 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x03, 0xb4, 0x03, + 0xb4, 0x03, 0xb4, 0x03, + 0xb4, 0x03, 0xb4, 0x03, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, + 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x03, 0xd4, 0x0b, 0xd5, 0x0b, 0xd5, 0x0b, + 0xd5, 0x0b, 0xd5, 0x0b, + 0xd5, 0x0b, 0xd5, 0x0b, 0xd5, 0x0b, 0xb4, 0x13, 0x93, 0x1b, 0x30, 0x1b, + 0x2b, 0x0a, 0x06, 0x01, + 0x42, 0x00, 0x21, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0xc5, 0x00, 0x4c, 0x0a, + 0x52, 0x1b, 0xb3, 0x13, + 0xb4, 0x0b, 0xb4, 0x0b, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xf5, 0x03, 0xf5, 0x03, 0xf5, 0x03, 0xf5, 0x03, 0xd5, 0x03, 0xf6, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x0b, 0xd4, 0x13, 0xb3, 0x1b, 0x30, 0x1b, 0x48, 0x01, 0x63, 0x00, + 0x21, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x06, 0x01, + 0xae, 0x1a, 0x72, 0x1b, 0xb4, 0x0b, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xd6, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf5, 0x03, 0xf5, 0x03, 0xf5, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf5, 0x0b, 0xd4, 0x13, + 0x71, 0x23, 0xca, 0x01, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x08, + 0x49, 0x4a, 0x38, 0xc6, + 0xdf, 0xff, 0xbe, 0xf7, 0x14, 0xa5, 0xc7, 0x39, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x92, 0x94, + 0xfb, 0xde, 0xe7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xf3, 0x9c, + 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x08, 0xd3, 0x9c, + 0xff, 0xff, 0x65, 0x29, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xff, 0xff, + 0xef, 0x7b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x86, 0x31, 0xd3, 0x9c, + 0x3c, 0xe7, 0xff, 0xff, 0xba, 0xd6, 0xcf, 0x7b, 0x82, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xa2, 0x10, 0xeb, 0x5a, 0x9a, 0xd6, 0xff, 0xff, 0x7d, 0xef, 0x51, 0x8c, + 0x45, 0x29, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0x9e, 0xf7, 0x6d, 0x6b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6d, 0x6b, 0x9e, 0xf7, 0x92, 0x94, 0x00, 0x00, + 0x00, 0x00, 0x8e, 0x73, + 0xff, 0xff, 0x30, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x42, + 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, 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, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, 0xa4, 0x00, 0xae, 0x1a, 0x93, 0x1b, 0xb4, 0x0b, + 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd6, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0x16, 0x04, + 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xf4, 0x13, 0x71, 0x1b, + 0xa9, 0x01, 0x42, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x2c, 0x63, 0x5d, 0xef, 0x58, 0xce, 0x30, 0x84, 0x51, 0x8c, + 0x5d, 0xef, 0xdb, 0xde, + 0x28, 0x42, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0xfb, 0xde, 0x08, 0x42, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x9c, 0x82, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x45, 0x29, 0x79, 0xce, 0xff, 0xff, 0x51, 0x8c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x86, 0x31, 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa2, 0x10, 0x59, 0xce, 0x7d, 0xef, 0x14, 0xa5, 0x10, 0x84, + 0xd7, 0xbd, 0xdf, 0xff, + 0x51, 0x8c, 0x41, 0x08, 0x00, 0x00, 0x61, 0x08, 0x30, 0x84, 0x9e, 0xf7, + 0xb6, 0xb5, 0x10, 0x84, + 0xb2, 0x94, 0x9e, 0xf7, 0x38, 0xc6, 0x45, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x8c, 0xff, 0xff, + 0xb6, 0xb5, 0xc3, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x18, + 0x96, 0xb5, 0xff, 0xff, + 0x71, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, 0x1c, 0xe7, + 0x61, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0x14, 0xa5, 0xff, 0xff, 0x14, 0xa5, + 0x82, 0x10, 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, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, + 0xeb, 0x09, 0x72, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd6, 0x03, + 0xb5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf4, 0x13, 0x50, 0x23, 0xa5, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x21, 0x18, 0xc6, + 0x7d, 0xef, 0x65, 0x29, + 0x20, 0x00, 0x20, 0x00, 0x2c, 0x63, 0x9e, 0xf7, 0x34, 0xa5, 0x00, 0x00, + 0x00, 0x00, 0x92, 0x94, + 0xfb, 0xde, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x14, 0xa5, + 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x5a, 0xdf, 0xff, + 0xbe, 0xf7, 0x38, 0xc6, + 0xc3, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xff, 0xff, + 0x10, 0x84, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, + 0x9e, 0xf7, 0xcf, 0x7b, + 0x82, 0x10, 0x00, 0x00, 0x04, 0x21, 0xd7, 0xbd, 0xfb, 0xde, 0x08, 0x42, + 0x00, 0x00, 0x86, 0x31, + 0x1c, 0xe7, 0x9a, 0xd6, 0xc3, 0x18, 0x00, 0x00, 0x61, 0x08, 0x10, 0x84, + 0xff, 0xff, 0xcf, 0x7b, + 0x00, 0x00, 0x00, 0x00, 0x92, 0x94, 0xff, 0xff, 0xbe, 0xf7, 0x69, 0x4a, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x69, 0x4a, 0xbe, 0xf7, 0xff, 0xff, 0x92, 0x94, 0x00, 0x00, + 0x00, 0x00, 0x6d, 0x6b, + 0xff, 0xff, 0xff, 0xff, 0x0c, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0x1c, 0xe7, + 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, 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, + 0x00, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x47, 0x01, 0x31, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd6, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x15, 0x0c, + 0xd3, 0x1b, 0x8d, 0x0a, + 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xa6, 0x31, 0x7d, 0xef, 0x34, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x21, 0x38, 0xc6, + 0x3c, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0x1c, 0xe7, 0xe7, 0x39, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xd7, 0xbd, 0xdb, 0xde, 0xb2, 0x94, 0x7d, 0xef, 0xcb, 0x5a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x86, 0x31, 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x75, 0xad, 0xdb, 0xde, 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe7, 0x39, + 0x30, 0x84, 0xc7, 0x39, 0x00, 0x00, 0xaa, 0x52, 0xff, 0xff, 0xcf, 0x7b, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x86, 0x31, 0x3c, 0xe7, 0xb6, 0xb5, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x8c, 0xff, 0xff, + 0xdf, 0xff, 0x59, 0xce, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xbd, + 0xdf, 0xff, 0xff, 0xff, + 0x71, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, 0xdf, 0xff, + 0x79, 0xce, 0x04, 0x21, + 0x00, 0x00, 0x61, 0x08, 0xb2, 0x94, 0xbe, 0xf7, 0xff, 0xff, 0x14, 0xa5, + 0x82, 0x10, 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, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x0b, 0x0a, + 0x73, 0x13, 0xb5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x16, 0x04, 0x15, 0x14, 0x51, 0x13, 0x26, 0x01, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xff, 0xff, + 0x14, 0xa5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe3, 0x18, 0xf7, 0xbd, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x71, 0x8c, + 0x1c, 0xe7, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x14, 0xa5, + 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x18, 0x9e, 0xf7, 0xd3, 0x9c, + 0x45, 0x29, 0xbe, 0xf7, + 0xb2, 0x94, 0x61, 0x08, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xff, 0xff, + 0x10, 0x84, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc6, + 0x79, 0xce, 0x04, 0x21, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8e, 0x73, + 0xff, 0xff, 0x6d, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, + 0xfb, 0xde, 0x79, 0xce, + 0x00, 0x00, 0x00, 0x00, 0x92, 0x94, 0x5d, 0xef, 0x79, 0xce, 0xdf, 0xff, + 0xe7, 0x39, 0x00, 0x00, + 0xa6, 0x31, 0xbe, 0xf7, 0x79, 0xce, 0x5d, 0xef, 0x71, 0x8c, 0x00, 0x00, + 0x00, 0x00, 0x6d, 0x6b, + 0xff, 0xff, 0xb6, 0xb5, 0x9e, 0xf7, 0x4d, 0x6b, 0x00, 0x00, 0xa6, 0x31, + 0xdb, 0xde, 0xb6, 0xb5, + 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, 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, + 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x00, 0xae, 0x12, 0xb4, 0x13, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x16, 0x0c, 0xd3, 0x1b, + 0xea, 0x09, 0x42, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x39, 0xff, 0xff, 0x14, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x21, 0xf7, 0xbd, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0x1c, 0xe7, 0x08, 0x42, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x9c, 0x82, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x4d, 0x6b, + 0x7d, 0xef, 0x0c, 0x63, 0x00, 0x00, 0x18, 0xc6, 0x79, 0xce, 0x45, 0x29, + 0x00, 0x00, 0x00, 0x00, + 0x86, 0x31, 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf7, 0xbd, 0x79, 0xce, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, 0x6d, 0x6b, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x65, 0x29, 0xfb, 0xde, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x8c, 0xfb, 0xde, + 0xef, 0x7b, 0xfb, 0xde, 0x14, 0xa5, 0x61, 0x08, 0x34, 0xa5, 0xfb, 0xde, + 0xef, 0x7b, 0x1c, 0xe7, + 0x71, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x6b, 0xff, 0xff, 0x8a, 0x52, + 0x5d, 0xef, 0x96, 0xb5, + 0xc3, 0x18, 0x71, 0x8c, 0x7d, 0xef, 0x49, 0x4a, 0xff, 0xff, 0x14, 0xa5, + 0x82, 0x10, 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, 0x00, 0x00, 0x00, 0x00, 0x69, 0x01, 0x52, 0x23, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xf5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x37, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0xf4, 0x13, 0x6d, 0x12, 0x83, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xff, 0xff, + 0x14, 0xa5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe3, 0x18, 0xf7, 0xbd, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x92, 0x94, + 0xfb, 0xde, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x14, 0xa5, + 0x82, 0x10, 0x00, 0x00, 0x82, 0x10, 0x38, 0xc6, 0x9a, 0xd6, 0x24, 0x21, + 0x00, 0x00, 0x4d, 0x6b, + 0xdf, 0xff, 0xeb, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xff, 0xff, + 0x10, 0x84, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xbd, + 0x79, 0xce, 0x04, 0x21, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8e, 0x73, + 0xff, 0xff, 0x8e, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, + 0xfb, 0xde, 0x79, 0xce, + 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0x1c, 0xe7, 0x08, 0x42, 0x71, 0x8c, + 0x3c, 0xe7, 0x92, 0x94, + 0x1c, 0xe7, 0x92, 0x94, 0xe7, 0x39, 0x1c, 0xe7, 0x92, 0x94, 0x00, 0x00, + 0x00, 0x00, 0x8e, 0x73, + 0xff, 0xff, 0x08, 0x42, 0x8e, 0x73, 0xbe, 0xf7, 0x6d, 0x6b, 0x7d, 0xef, + 0x14, 0xa5, 0x82, 0x10, + 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, 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, + 0x00, 0x00, 0x00, 0x00, + 0xcb, 0x01, 0x72, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, + 0x16, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x37, 0x04, 0x37, 0x04, 0x37, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x15, 0x14, + 0xce, 0x1a, 0xa4, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0xff, 0xff, 0x14, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x45, 0x29, + 0x24, 0x21, 0xf7, 0xbd, + 0xdf, 0xff, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0xfb, 0xde, 0x08, 0x42, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, 0x00, 0x00, + 0x49, 0x4a, 0x3c, 0xe7, + 0x38, 0xc6, 0x28, 0x42, 0x08, 0x42, 0x4d, 0x6b, 0x5d, 0xef, 0xd7, 0xbd, + 0x00, 0x00, 0x00, 0x00, + 0x65, 0x29, 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf7, 0xbd, 0x79, 0xce, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, 0x8e, 0x73, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x65, 0x29, 0xfb, 0xde, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x92, 0x94, 0xfb, 0xde, + 0x08, 0x42, 0x04, 0x21, 0x9e, 0xf7, 0xbe, 0xf7, 0xbe, 0xf7, 0x65, 0x29, + 0x08, 0x42, 0xfb, 0xde, + 0x71, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, 0x08, 0x42, + 0x45, 0x29, 0x79, 0xce, + 0x7d, 0xef, 0x7d, 0xef, 0xeb, 0x5a, 0x00, 0x00, 0xff, 0xff, 0x14, 0xa5, + 0x61, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x93, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x37, 0x04, 0x37, 0x04, + 0x37, 0x04, 0x36, 0x04, 0x36, 0x04, 0x15, 0x14, 0xef, 0x12, 0xe5, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0x3c, 0xe7, + 0xb6, 0xb5, 0x00, 0x00, + 0xa2, 0x10, 0x96, 0xb5, 0x55, 0xad, 0xdb, 0xde, 0xba, 0xd6, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x84, + 0x3c, 0xe7, 0x69, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x10, + 0xff, 0xff, 0xd3, 0x9c, + 0x61, 0x08, 0x20, 0x00, 0x30, 0x84, 0xdf, 0xff, 0x7d, 0xef, 0xfb, 0xde, + 0x1c, 0xe7, 0x1c, 0xe7, + 0xbe, 0xf7, 0xbe, 0xf7, 0xe3, 0x18, 0x00, 0x00, 0x86, 0x31, 0xff, 0xff, + 0x10, 0x84, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xa5, + 0xfb, 0xde, 0xc7, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x52, 0xf7, 0xbd, 0x8a, 0x52, + 0x00, 0x00, 0x49, 0x4a, + 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x39, + 0x5d, 0xef, 0x55, 0xad, + 0x00, 0x00, 0x00, 0x00, 0x92, 0x94, 0x1c, 0xe7, 0x08, 0x42, 0x00, 0x00, + 0xf3, 0x9c, 0xff, 0xff, + 0x96, 0xb5, 0x00, 0x00, 0x08, 0x42, 0x1c, 0xe7, 0x92, 0x94, 0x00, 0x00, + 0x00, 0x00, 0x8e, 0x73, + 0xff, 0xff, 0xe7, 0x39, 0x20, 0x00, 0xef, 0x7b, 0xbe, 0xf7, 0xf7, 0xbd, + 0xa2, 0x10, 0x00, 0x00, + 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, 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, + 0x00, 0x00, 0x00, 0x00, + 0x0d, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xf5, 0x03, 0xf5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x15, 0x14, + 0xef, 0x12, 0xc5, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xc3, 0x18, 0x96, 0xb5, 0xbe, 0xf7, 0x49, 0x4a, 0xa2, 0x10, 0xae, 0x73, + 0xff, 0xff, 0xff, 0xff, + 0xb2, 0x94, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0x9e, 0xf7, 0x75, 0xad, + 0x86, 0x31, 0xa2, 0x10, + 0x04, 0x21, 0xf3, 0x9c, 0x7d, 0xef, 0xeb, 0x5a, 0x00, 0x00, 0x24, 0x21, + 0x38, 0xc6, 0x1c, 0xe7, + 0xeb, 0x5a, 0xeb, 0x5a, 0xeb, 0x5a, 0xeb, 0x5a, 0x92, 0x94, 0x9e, 0xf7, + 0xef, 0x7b, 0x00, 0x00, + 0x86, 0x31, 0xff, 0xff, 0x92, 0x94, 0x24, 0x21, 0x24, 0x21, 0x24, 0x21, + 0x24, 0x21, 0xe3, 0x18, + 0x41, 0x08, 0xeb, 0x5a, 0xbe, 0xf7, 0xd3, 0x9c, 0x24, 0x21, 0xa2, 0x10, + 0xc7, 0x39, 0x79, 0xce, + 0xba, 0xd6, 0x86, 0x31, 0x00, 0x00, 0x45, 0x29, 0x9a, 0xd6, 0x3c, 0xe7, + 0x86, 0x31, 0xa2, 0x10, + 0xe3, 0x18, 0x14, 0xa5, 0xdf, 0xff, 0x4d, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x8c, 0x1c, 0xe7, + 0x08, 0x42, 0x00, 0x00, 0x04, 0x21, 0x10, 0x84, 0x45, 0x29, 0x00, 0x00, + 0x08, 0x42, 0xfb, 0xde, + 0x71, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, 0x08, 0x42, + 0x00, 0x00, 0xc3, 0x18, + 0xae, 0x73, 0xe7, 0x39, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x9c, + 0x82, 0x10, 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, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0x93, 0x1b, + 0xb4, 0x0b, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf5, 0x03, 0xf5, 0x03, + 0xf5, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x15, 0x14, 0x0f, 0x13, 0xc5, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x4a, + 0xba, 0xd6, 0x3c, 0xe7, + 0x75, 0xad, 0xf7, 0xbd, 0xff, 0xff, 0xdf, 0xff, 0xf3, 0x9c, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xb2, 0x94, 0x9e, 0xf7, 0x59, 0xce, 0x34, 0xa5, 0x18, 0xc6, 0xdf, 0xff, + 0x92, 0x94, 0x82, 0x10, + 0x00, 0x00, 0x69, 0x4a, 0xbe, 0xf7, 0xd3, 0x9c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x65, 0x29, 0xba, 0xd6, 0xf7, 0xbd, 0xa2, 0x10, 0x86, 0x31, 0xff, 0xff, + 0x1c, 0xe7, 0x38, 0xc6, + 0x18, 0xc6, 0x18, 0xc6, 0x18, 0xc6, 0x55, 0xad, 0x86, 0x31, 0x41, 0x08, + 0x75, 0xad, 0xbe, 0xf7, + 0x18, 0xc6, 0x55, 0xad, 0x9a, 0xd6, 0x7d, 0xef, 0x4d, 0x6b, 0x20, 0x00, + 0x00, 0x00, 0x20, 0x00, + 0x2c, 0x63, 0x1c, 0xe7, 0xdb, 0xde, 0x55, 0xad, 0xf7, 0xbd, 0xbe, 0xf7, + 0x34, 0xa5, 0xc3, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0xfb, 0xde, 0x08, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xfb, 0xde, 0x92, 0x94, 0x00, 0x00, + 0x00, 0x00, 0x8e, 0x73, + 0xff, 0xff, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, 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, + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x02, 0x93, 0x1b, 0xb4, 0x0b, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x56, 0x04, 0x35, 0x14, + 0x0f, 0x13, 0xc5, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x24, 0x29, 0x71, 0x94, 0x18, 0xc6, 0xf7, 0xbd, + 0x6d, 0x6b, 0x8e, 0x73, + 0xba, 0xd6, 0xe3, 0x18, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x10, 0xaa, 0x52, + 0x14, 0xa5, 0x59, 0xce, + 0x75, 0xad, 0x0c, 0x63, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x52, + 0xd3, 0x9c, 0xa6, 0x31, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xae, 0x73, + 0x30, 0x84, 0x24, 0x21, + 0xe3, 0x18, 0xd3, 0x9c, 0xb2, 0x94, 0xb2, 0x94, 0xd3, 0x9c, 0xd3, 0x9c, + 0xd3, 0x9c, 0x30, 0x84, + 0x24, 0x21, 0x00, 0x00, 0xc3, 0x18, 0x2c, 0x63, 0x75, 0xad, 0x38, 0xc6, + 0xf3, 0x9c, 0x69, 0x4a, + 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0xa6, 0x31, + 0xf3, 0x9c, 0x38, 0xc6, + 0xb6, 0xb5, 0x0c, 0x63, 0xa2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0x52, 0x30, 0x84, + 0x24, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x21, 0x30, 0x84, + 0xaa, 0x52, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xd3, 0x9c, 0x24, 0x21, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x9c, 0x0c, 0x63, + 0x41, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd6, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf5, 0x03, 0xf5, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x37, 0x04, 0x37, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x37, 0x04, 0x37, 0x04, 0x36, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x36, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x56, 0x04, 0x35, 0x14, 0x0f, 0x13, 0xc5, 0x00, + 0x21, 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, 0x41, 0x08, 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, + 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, 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, + 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd6, 0x03, 0xd6, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xf6, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, 0xd5, 0x03, 0xf5, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x37, 0x04, 0x37, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x35, 0x14, + 0x0f, 0x13, 0xe5, 0x00, 0x21, 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, 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, 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, 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, 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, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb6, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x0b, 0xb5, 0x03, 0xb5, 0x0b, 0xd4, 0x0b, 0xb4, 0x0b, 0xd4, 0x0b, + 0xb4, 0x13, 0xd4, 0x13, + 0xb4, 0x13, 0xb4, 0x0b, 0xd4, 0x0b, 0xd4, 0x0b, 0xf5, 0x0b, 0xd5, 0x0b, + 0xf5, 0x0b, 0xf5, 0x0b, + 0xf5, 0x03, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x37, 0x04, 0x37, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, 0x57, 0x04, 0x35, 0x14, 0x0f, 0x13, 0xe5, 0x00, + 0x21, 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, 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, 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, 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, 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, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, 0xb4, 0x13, 0x93, 0x13, + 0x93, 0x1b, 0x52, 0x1b, + 0x10, 0x13, 0x10, 0x1b, 0x10, 0x1b, 0xef, 0x12, 0xef, 0x12, 0x10, 0x1b, + 0x10, 0x13, 0x31, 0x13, + 0x72, 0x1b, 0x93, 0x1b, 0xd4, 0x1b, 0xd4, 0x13, 0xf5, 0x13, 0xf5, 0x0b, + 0xf5, 0x0b, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x35, 0x14, + 0x0f, 0x13, 0xe5, 0x00, 0x21, 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, 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, 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, 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, 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, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb4, 0x03, 0xb4, 0x0b, 0x93, 0x0b, 0x93, 0x13, 0x93, 0x1b, + 0x51, 0x1b, 0xcf, 0x12, + 0x6d, 0x0a, 0x0b, 0x02, 0xaa, 0x01, 0x89, 0x01, 0x27, 0x01, 0x27, 0x01, + 0x07, 0x01, 0xe6, 0x00, + 0xe6, 0x00, 0x06, 0x01, 0x27, 0x01, 0x47, 0x01, 0x68, 0x01, 0xa9, 0x01, + 0x0b, 0x02, 0x6d, 0x02, + 0xef, 0x12, 0x72, 0x1b, 0xd3, 0x1b, 0xd4, 0x1b, 0xf5, 0x13, 0xf5, 0x0b, + 0x15, 0x0c, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x57, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x37, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, + 0x57, 0x04, 0x77, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x36, 0x14, 0x0f, 0x13, 0xe5, 0x00, + 0x21, 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, 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, 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, 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, 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, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb4, 0x0b, 0x93, 0x13, + 0x52, 0x1b, 0x30, 0x23, + 0x4d, 0x12, 0xa9, 0x01, 0x06, 0x01, 0xa5, 0x00, 0x63, 0x00, 0x42, 0x00, + 0x22, 0x00, 0x22, 0x00, + 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x21, 0x00, 0x42, 0x00, 0x83, 0x00, 0xc4, 0x00, 0x06, 0x01, + 0x89, 0x01, 0x8d, 0x12, + 0x51, 0x23, 0xb3, 0x23, 0xf4, 0x1b, 0xf5, 0x13, 0x16, 0x0c, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x37, 0x04, 0x57, 0x04, 0x57, 0x04, 0x56, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x57, 0x04, 0x35, 0x14, + 0x0f, 0x13, 0xe5, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, + 0x20, 0x00, 0x20, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb4, 0x0b, + 0x94, 0x13, 0x93, 0x13, + 0x10, 0x13, 0x8d, 0x0a, 0x69, 0x01, 0x84, 0x00, 0x43, 0x00, 0x22, 0x00, + 0x21, 0x00, 0x21, 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, + 0x20, 0x00, 0x21, 0x00, 0x42, 0x00, 0x43, 0x00, 0x84, 0x00, 0x68, 0x01, + 0xae, 0x12, 0x51, 0x13, + 0xd3, 0x1b, 0x15, 0x14, 0x15, 0x0c, 0x36, 0x04, 0x36, 0x04, 0x37, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x55, 0x14, 0x0f, 0x13, 0xe5, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x10, 0xef, 0x7b, + 0x30, 0x84, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x34, 0xa5, 0x8e, 0x73, 0x82, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xe3, 0x18, 0x92, 0x94, 0x4d, 0x6b, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, + 0xf3, 0x9c, 0x49, 0x4a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x4a, 0x55, 0xad, + 0x45, 0x29, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc3, 0x18, 0x8a, 0x52, 0xd3, 0x9c, 0x14, 0xa5, + 0x8e, 0x73, 0x86, 0x31, + 0x00, 0x00, 0x00, 0x00, 0xcb, 0x5a, 0xd3, 0x9c, 0xe7, 0x39, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6d, 0x6b, 0xf3, 0x9c, 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0xb2, 0x94, + 0xae, 0x73, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0x34, 0xa5, + 0x34, 0xa5, 0x34, 0xa5, + 0x34, 0xa5, 0x34, 0xa5, 0x34, 0xa5, 0x34, 0xa5, 0x4d, 0x6b, 0x41, 0x08, + 0x45, 0x29, 0x34, 0xa5, + 0x49, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x18, 0x8a, 0x52, + 0xb2, 0x94, 0x14, 0xa5, + 0x8e, 0x73, 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x18, + 0x92, 0x94, 0xae, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x29, 0x92, 0x94, + 0xeb, 0x5a, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb4, 0x0b, 0x92, 0x1b, 0xef, 0x1a, 0xeb, 0x09, 0x06, 0x01, 0x63, 0x00, + 0x42, 0x00, 0x01, 0x00, + 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x21, 0x00, 0x42, 0x00, 0x84, 0x00, 0x06, 0x01, 0x0a, 0x02, 0x50, 0x1b, + 0xf4, 0x1b, 0x15, 0x14, + 0x36, 0x0c, 0x37, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, + 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x55, 0x14, + 0x0f, 0x13, 0xe5, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x04, 0x21, 0x18, 0xc6, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x7d, 0xef, + 0xaa, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xfb, 0xde, + 0xf3, 0x9c, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x63, 0xff, 0xff, 0x18, 0xc6, 0x04, 0x21, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x6d, 0x6b, 0xff, 0xff, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x61, 0x08, + 0x55, 0xad, 0x7d, 0xef, + 0x79, 0xce, 0x18, 0xc6, 0x5d, 0xef, 0x9a, 0xd6, 0x08, 0x42, 0x00, 0x00, + 0x28, 0x42, 0xdf, 0xff, + 0x30, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xde, + 0x79, 0xce, 0x45, 0x29, + 0x00, 0x00, 0x00, 0x00, 0x65, 0x29, 0xff, 0xff, 0x3c, 0xe7, 0x86, 0x31, + 0x00, 0x00, 0x00, 0x00, + 0x28, 0x42, 0xd7, 0xbd, 0xd7, 0xbd, 0x38, 0xc6, 0xff, 0xff, 0xfb, 0xde, + 0xd7, 0xbd, 0xd7, 0xbd, + 0xae, 0x73, 0x61, 0x08, 0x08, 0x42, 0xff, 0xff, 0x8e, 0x73, 0x00, 0x00, + 0x00, 0x00, 0x61, 0x08, + 0x55, 0xad, 0x5d, 0xef, 0x79, 0xce, 0x18, 0xc6, 0x5d, 0xef, 0x9a, 0xd6, + 0x08, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x86, 0x31, 0xfb, 0xde, 0xbe, 0xf7, 0x08, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0xfb, 0xde, 0x92, 0x94, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb4, 0x0b, 0x93, 0x13, 0x31, 0x1b, 0xeb, 0x01, + 0xe6, 0x00, 0x63, 0x00, + 0x21, 0x00, 0x01, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x21, 0x00, + 0x42, 0x00, 0x06, 0x01, 0x0b, 0x02, 0x92, 0x1b, 0xf4, 0x1b, 0x35, 0x14, + 0x36, 0x0c, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x97, 0x04, 0x77, 0x04, 0x56, 0x14, 0x2f, 0x13, 0xe5, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x21, 0xf7, 0xbd, + 0x79, 0xce, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xde, 0x82, 0x10, + 0x00, 0x00, 0x00, 0x00, + 0x86, 0x31, 0xfb, 0xde, 0x14, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x63, + 0xff, 0xff, 0xdf, 0xff, + 0x92, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, + 0x08, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x8e, 0x73, 0xbe, 0xf7, 0xd3, 0x9c, 0x24, 0x21, 0xe3, 0x18, + 0x0c, 0x63, 0x3c, 0xe7, + 0xd7, 0xbd, 0xa2, 0x10, 0x20, 0x00, 0x5d, 0xef, 0xb6, 0xb5, 0xc3, 0x18, + 0x00, 0x00, 0x00, 0x00, + 0x86, 0x31, 0xff, 0xff, 0xb2, 0x94, 0x61, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x84, 0xff, 0xff, + 0xdf, 0xff, 0x8e, 0x73, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0xc3, 0x18, + 0xc3, 0x18, 0x28, 0x42, + 0xff, 0xff, 0x71, 0x8c, 0xc3, 0x18, 0xc3, 0x18, 0x82, 0x10, 0x00, 0x00, + 0x08, 0x42, 0xff, 0xff, + 0x6d, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xdf, 0xff, 0xd3, 0x9c, + 0x24, 0x21, 0xe3, 0x18, + 0x0c, 0x63, 0x3c, 0xe7, 0xd7, 0xbd, 0xa2, 0x10, 0x00, 0x00, 0x86, 0x31, + 0xfb, 0xde, 0xff, 0xff, + 0xf7, 0xbd, 0xe3, 0x18, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xfb, 0xde, + 0x92, 0x94, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb4, 0x0b, 0x93, 0x13, + 0x30, 0x1b, 0x2c, 0x0a, + 0xc5, 0x00, 0x42, 0x00, 0x21, 0x00, 0x01, 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, 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, 0x20, 0x00, 0x21, 0x00, + 0x43, 0x00, 0xa5, 0x00, + 0x6c, 0x12, 0x92, 0x1b, 0x35, 0x1c, 0x56, 0x0c, 0x56, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x56, 0x14, + 0x2f, 0x13, 0xe5, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x04, 0x21, 0x18, 0xc6, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xbe, 0xf7, + 0xdf, 0xff, 0xf3, 0x9c, 0x61, 0x08, 0x00, 0x00, 0x86, 0x31, 0xfb, 0xde, + 0x14, 0xa5, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x63, 0xdf, 0xff, 0xbe, 0xf7, 0xff, 0xff, 0x49, 0x4a, + 0x00, 0x00, 0x00, 0x00, + 0x8e, 0x73, 0xff, 0xff, 0x08, 0x42, 0x00, 0x00, 0x41, 0x08, 0x18, 0xc6, + 0xba, 0xd6, 0x86, 0x31, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xad, 0x1c, 0xe7, 0x28, 0x42, + 0x00, 0x00, 0x34, 0xa5, + 0x7d, 0xef, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x51, 0x8c, 0x7d, 0xef, + 0xcb, 0x5a, 0x00, 0x00, + 0x00, 0x00, 0xe3, 0x18, 0x79, 0xce, 0xfb, 0xde, 0x59, 0xce, 0xba, 0xd6, + 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xff, 0xff, 0x10, 0x84, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xff, 0xff, 0x6d, 0x6b, 0x00, 0x00, + 0x20, 0x00, 0x18, 0xc6, + 0xba, 0xd6, 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xa5, + 0x1c, 0xe7, 0x28, 0x42, + 0x00, 0x00, 0x65, 0x29, 0xfb, 0xde, 0x9e, 0xf7, 0xdf, 0xff, 0x92, 0x94, + 0x61, 0x08, 0x00, 0x00, + 0x08, 0x42, 0xfb, 0xde, 0x71, 0x8c, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb4, 0x03, + 0xb4, 0x03, 0xb4, 0x0b, + 0x93, 0x1b, 0xcf, 0x12, 0x48, 0x01, 0x63, 0x00, 0x21, 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, 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, 0x00, 0x21, 0x00, 0x63, 0x00, 0x88, 0x01, + 0x0f, 0x13, 0x14, 0x1c, + 0x35, 0x14, 0x56, 0x0c, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x56, 0x14, 0x2f, 0x1b, 0xe5, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x21, 0xf7, 0xbd, + 0x79, 0xce, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd7, 0xbd, 0x59, 0xce, 0x5d, 0xef, + 0xcb, 0x5a, 0x00, 0x00, + 0x86, 0x31, 0xfb, 0xde, 0x14, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x63, + 0x9e, 0xf7, 0x75, 0xad, + 0x1c, 0xe7, 0x18, 0xc6, 0x04, 0x21, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, + 0x08, 0x42, 0x00, 0x00, + 0xe3, 0x18, 0x79, 0xce, 0x9a, 0xd6, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x71, 0x8c, + 0x7d, 0xef, 0xeb, 0x5a, 0x00, 0x00, 0xcb, 0x5a, 0xdf, 0xff, 0xcf, 0x7b, + 0x00, 0x00, 0x61, 0x08, + 0x18, 0xc6, 0x79, 0xce, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x52, + 0x5d, 0xef, 0xef, 0x7b, + 0x10, 0x84, 0xdf, 0xff, 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x86, 0x31, + 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0xff, 0xff, + 0x8e, 0x73, 0x00, 0x00, 0xe3, 0x18, 0x79, 0xce, 0x79, 0xce, 0xe3, 0x18, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x71, 0x8c, 0x7d, 0xef, 0xeb, 0x5a, 0x00, 0x00, 0x86, 0x31, + 0x1c, 0xe7, 0xb6, 0xb5, + 0x9a, 0xd6, 0x3c, 0xe7, 0x69, 0x4a, 0x00, 0x00, 0x08, 0x42, 0xfb, 0xde, + 0x71, 0x8c, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0x94, 0x13, 0x51, 0x1b, 0x0b, 0x0a, 0xc5, 0x00, + 0x22, 0x00, 0x01, 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, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x42, 0x00, 0xc5, 0x00, 0x6c, 0x12, 0xd3, 0x23, 0x35, 0x14, + 0x76, 0x0c, 0x77, 0x04, + 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x56, 0x14, + 0x2f, 0x1b, 0xe5, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x04, 0x21, 0xf7, 0xbd, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x14, 0xa5, + 0x49, 0x4a, 0xdf, 0xff, 0x59, 0xce, 0x45, 0x29, 0x86, 0x31, 0x1c, 0xe7, + 0xf3, 0x9c, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x63, 0x7d, 0xef, 0x4d, 0x6b, 0x51, 0x8c, 0xbe, 0xf7, + 0x51, 0x8c, 0x61, 0x08, + 0x8e, 0x73, 0xff, 0xff, 0x08, 0x42, 0x00, 0x00, 0xe3, 0x18, 0x79, 0xce, + 0x79, 0xce, 0x04, 0x21, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x94, 0x7d, 0xef, 0x0c, 0x63, + 0x00, 0x00, 0x45, 0x29, + 0xba, 0xd6, 0x38, 0xc6, 0x00, 0x00, 0x08, 0x42, 0xfb, 0xde, 0x14, 0xa5, + 0x20, 0x00, 0x00, 0x00, + 0x41, 0x08, 0x92, 0x94, 0xff, 0xff, 0x04, 0x21, 0x69, 0x4a, 0x3c, 0xe7, + 0x71, 0x8c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xff, 0xff, 0x10, 0x84, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xff, 0xff, 0x8e, 0x73, 0x00, 0x00, + 0x04, 0x21, 0x9a, 0xd6, + 0x79, 0xce, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, + 0x7d, 0xef, 0x0c, 0x63, + 0x00, 0x00, 0x86, 0x31, 0xfb, 0xde, 0x14, 0xa5, 0xaa, 0x52, 0x7d, 0xef, + 0x9a, 0xd6, 0x61, 0x08, + 0x08, 0x42, 0xfb, 0xde, 0x71, 0x8c, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x0b, 0x93, 0x13, + 0x11, 0x1b, 0x69, 0x01, + 0x63, 0x00, 0x21, 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, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x63, 0x00, + 0xa9, 0x01, 0x71, 0x13, 0x35, 0x1c, 0x76, 0x0c, 0x77, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x77, 0x04, 0x97, 0x04, 0x76, 0x14, 0x30, 0x1b, 0xe5, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x21, 0xf7, 0xbd, + 0x79, 0xce, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, 0xef, 0x7b, + 0xbe, 0xf7, 0x14, 0xa5, + 0x86, 0x31, 0xfb, 0xde, 0x14, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x63, + 0x7d, 0xef, 0x0c, 0x63, + 0x41, 0x08, 0x79, 0xce, 0x7d, 0xef, 0xaa, 0x52, 0x8e, 0x73, 0xff, 0xff, + 0x08, 0x42, 0x00, 0x00, + 0x04, 0x21, 0x79, 0xce, 0x9a, 0xd6, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x71, 0x8c, + 0x7d, 0xef, 0x0c, 0x63, 0x00, 0x00, 0x61, 0x08, 0xd3, 0x9c, 0xff, 0xff, + 0x24, 0x21, 0xcf, 0x7b, + 0xdf, 0xff, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x65, 0x29, 0xfb, 0xde, + 0x38, 0xc6, 0x00, 0x00, + 0x82, 0x10, 0x18, 0xc6, 0x79, 0xce, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x65, 0x29, + 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0xff, 0xff, + 0x8e, 0x73, 0x00, 0x00, 0xe3, 0x18, 0x79, 0xce, 0x79, 0xce, 0x04, 0x21, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x71, 0x8c, 0x7d, 0xef, 0x0c, 0x63, 0x00, 0x00, 0x86, 0x31, + 0xfb, 0xde, 0x14, 0xa5, + 0x41, 0x08, 0x30, 0x84, 0xbe, 0xf7, 0x51, 0x8c, 0x49, 0x4a, 0xfb, 0xde, + 0x71, 0x8c, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb4, 0x0b, + 0x73, 0x13, 0xcf, 0x12, 0x48, 0x01, 0x42, 0x00, 0x21, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x63, 0x00, 0x27, 0x01, + 0x51, 0x1b, 0x35, 0x1c, + 0x56, 0x0c, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0xb7, 0x0c, 0x76, 0x1c, + 0x2f, 0x1b, 0xe5, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x04, 0x21, 0xf7, 0xbd, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xf3, 0x9c, + 0x82, 0x10, 0xe3, 0x18, 0xd7, 0xbd, 0xdf, 0xff, 0xef, 0x7b, 0xfb, 0xde, + 0xf3, 0x9c, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x63, 0x7d, 0xef, 0xeb, 0x5a, 0x00, 0x00, 0x8a, 0x52, + 0x5d, 0xef, 0xba, 0xd6, + 0x30, 0x84, 0xff, 0xff, 0x08, 0x42, 0x00, 0x00, 0x04, 0x21, 0x79, 0xce, + 0x79, 0xce, 0x04, 0x21, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0x9e, 0xf7, 0x0c, 0x63, + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x63, 0x9e, 0xf7, 0xef, 0x7b, 0x75, 0xad, 0x5d, 0xef, 0x41, 0x08, + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x63, 0xdf, 0xff, 0x8e, 0x73, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x7b, + 0x7d, 0xef, 0xcb, 0x5a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x29, 0xff, 0xff, 0x10, 0x84, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xff, 0xff, 0x6d, 0x6b, 0x00, 0x00, + 0x04, 0x21, 0x79, 0xce, + 0x79, 0xce, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, + 0x7d, 0xef, 0x0c, 0x63, + 0x00, 0x00, 0x86, 0x31, 0xfb, 0xde, 0xf3, 0x9c, 0x00, 0x00, 0x24, 0x21, + 0x18, 0xc6, 0x3c, 0xe7, + 0x92, 0x94, 0x1c, 0xe7, 0x92, 0x94, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, 0xb4, 0x0b, 0x93, 0x1b, 0xaf, 0x12, 0x07, 0x01, + 0x42, 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, 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, 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, 0x42, 0x00, 0x47, 0x01, 0x0f, 0x13, 0x35, 0x1c, 0x76, 0x0c, + 0x77, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x0c, 0x76, 0x1c, 0x50, 0x1b, 0xe5, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x21, 0x18, 0xc6, + 0x79, 0xce, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, 0x00, 0x00, + 0x69, 0x4a, 0x1c, 0xe7, + 0x7d, 0xef, 0x9e, 0xf7, 0x14, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x63, + 0x7d, 0xef, 0x0c, 0x63, + 0x00, 0x00, 0x41, 0x08, 0x51, 0x8c, 0xdf, 0xff, 0x1c, 0xe7, 0xff, 0xff, + 0x08, 0x42, 0x00, 0x00, + 0x82, 0x10, 0x38, 0xc6, 0x9a, 0xd6, 0x24, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x92, 0x94, + 0x5d, 0xef, 0x8a, 0x52, 0x00, 0x00, 0x00, 0x00, 0x65, 0x29, 0xba, 0xd6, + 0x3c, 0xe7, 0x1c, 0xe7, + 0xf3, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xbd, 0xff, 0xff, + 0xfb, 0xde, 0x9a, 0xd6, + 0x9a, 0xd6, 0xfb, 0xde, 0xff, 0xff, 0xd3, 0x9c, 0x61, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x65, 0x29, + 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0xff, 0xff, + 0x6d, 0x6b, 0x00, 0x00, 0x82, 0x10, 0x38, 0xc6, 0x79, 0xce, 0x04, 0x21, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x92, 0x94, 0x5d, 0xef, 0x8a, 0x52, 0x00, 0x00, 0x65, 0x29, + 0xfb, 0xde, 0x14, 0xa5, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x42, 0xdf, 0xff, 0x7d, 0xef, 0xbe, 0xf7, + 0x71, 0x8c, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb4, 0x0b, + 0x73, 0x1b, 0xcf, 0x1a, + 0xa5, 0x00, 0x22, 0x00, 0x01, 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, 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, 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, + 0x42, 0x00, 0xe5, 0x00, + 0xee, 0x12, 0x55, 0x1c, 0x76, 0x0c, 0x97, 0x04, 0x98, 0x04, 0xb8, 0x0c, + 0x97, 0x0c, 0x76, 0x1c, + 0x50, 0x1b, 0xe5, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x04, 0x21, 0xf7, 0xbd, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xf3, 0x9c, + 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0xae, 0x73, 0xff, 0xff, 0xff, 0xff, + 0x14, 0xa5, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x63, 0x7d, 0xef, 0x0c, 0x63, 0x00, 0x00, 0x00, 0x00, + 0xc3, 0x18, 0xd7, 0xbd, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x9c, + 0x5d, 0xef, 0x2c, 0x63, + 0x20, 0x00, 0x00, 0x00, 0x24, 0x21, 0x9a, 0xd6, 0xba, 0xd6, 0x65, 0x29, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x14, 0xa5, 0xff, 0xff, 0xdf, 0xff, 0x69, 0x4a, 0x00, 0x00, + 0x00, 0x00, 0xe3, 0x18, + 0xff, 0xff, 0xdb, 0xde, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, 0x75, 0xad, + 0xfb, 0xde, 0xfb, 0xde, + 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xff, 0xff, 0xef, 0x7b, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xff, 0xff, 0x8e, 0x73, 0x00, 0x00, + 0x00, 0x00, 0xd3, 0x9c, + 0x7d, 0xef, 0x2c, 0x63, 0x20, 0x00, 0x00, 0x00, 0x24, 0x21, 0x9a, 0xd6, + 0xba, 0xd6, 0x65, 0x29, + 0x00, 0x00, 0x65, 0x29, 0xfb, 0xde, 0x14, 0xa5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x51, 0x8c, + 0xdf, 0xff, 0xff, 0xff, 0x71, 0x8c, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, + 0xb4, 0x0b, 0x93, 0x13, 0xaf, 0x12, 0xe6, 0x00, 0x22, 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, 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, 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, 0x41, 0x00, 0xe5, 0x00, 0x2f, 0x1b, + 0x55, 0x1c, 0x96, 0x14, + 0x97, 0x0c, 0x97, 0x0c, 0xb7, 0x0c, 0x96, 0x1c, 0x50, 0x23, 0xe5, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x18, 0xf7, 0xbd, + 0x79, 0xce, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x10, + 0x59, 0xce, 0xff, 0xff, 0xf3, 0x9c, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x5a, + 0x7d, 0xef, 0x0c, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, + 0x08, 0x42, 0x00, 0x00, + 0x00, 0x00, 0xa6, 0x31, 0x5d, 0xef, 0xdb, 0xde, 0x30, 0x84, 0xae, 0x73, + 0xd7, 0xbd, 0xdf, 0xff, + 0xef, 0x7b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x52, + 0xff, 0xff, 0xdb, 0xde, + 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0xae, 0x73, 0x9e, 0xf7, 0x4d, 0x6b, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xdf, 0xff, 0x4d, 0x6b, 0x00, 0x00, + 0x00, 0x00, 0x86, 0x31, + 0xff, 0xff, 0xef, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0xff, 0xff, + 0x8e, 0x73, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0x5d, 0xef, 0xdb, 0xde, + 0x30, 0x84, 0xae, 0x73, + 0xd7, 0xbd, 0xdf, 0xff, 0xef, 0x7b, 0x20, 0x00, 0x00, 0x00, 0x86, 0x31, + 0xfb, 0xde, 0x14, 0xa5, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x21, 0x18, 0xc6, 0xff, 0xff, + 0x92, 0x94, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x0b, 0x93, 0x13, 0xef, 0x12, + 0x06, 0x01, 0x22, 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, 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, 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, + 0x41, 0x00, 0x26, 0x01, 0x70, 0x1b, 0x55, 0x24, 0x97, 0x14, 0xb7, 0x0c, + 0xb8, 0x14, 0x76, 0x1c, + 0x50, 0x23, 0xe5, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xe3, 0x18, 0x95, 0xb5, 0x18, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7d, 0xef, 0xb2, 0x94, + 0x61, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x4a, 0x1c, 0xe7, + 0xb2, 0x94, 0x00, 0x00, + 0x00, 0x00, 0xcb, 0x5a, 0xfb, 0xde, 0xcb, 0x5a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xd3, 0x9c, 0x7d, 0xef, 0xc7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x42, 0xb6, 0xb5, + 0x5d, 0xef, 0x3c, 0xe7, 0xdb, 0xde, 0xcf, 0x7b, 0x61, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x41, 0x08, 0x3c, 0xe7, 0xb2, 0x94, 0x82, 0x10, 0x00, 0x00, + 0x61, 0x08, 0x96, 0xb5, + 0x59, 0xce, 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa6, 0x31, 0xdb, 0xde, + 0x96, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x65, 0x29, 0x7d, 0xef, 0xae, 0x73, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc7, 0x39, 0x7d, 0xef, 0x2c, 0x63, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x49, 0x4a, 0xb6, 0xb5, 0x5d, 0xef, 0x3c, 0xe7, 0xdb, 0xde, 0xcf, 0x7b, + 0x61, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x65, 0x29, 0x79, 0xce, 0xb2, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xeb, 0x5a, 0xfb, 0xde, 0x30, 0x84, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xb4, 0x0b, + 0x31, 0x1b, 0x06, 0x01, 0x22, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, + 0x42, 0x00, 0x22, 0x00, + 0x42, 0x00, 0x42, 0x00, 0x22, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, + 0x47, 0x01, 0x91, 0x23, + 0x76, 0x24, 0xb7, 0x14, 0xb7, 0x14, 0x96, 0x24, 0x50, 0x23, 0xe5, 0x00, + 0x21, 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, 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, 0xe3, 0x18, 0x24, 0x21, + 0x41, 0x08, 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, 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, 0x00, 0x00, + 0x04, 0x21, 0x24, 0x21, + 0x41, 0x08, 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, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb4, 0x0b, 0x72, 0x13, 0xca, 0x01, 0x42, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x42, 0x00, + 0x63, 0x00, 0xc5, 0x00, + 0x47, 0x01, 0x88, 0x01, 0xea, 0x01, 0xea, 0x01, 0xeb, 0x01, 0x0b, 0x02, + 0x89, 0x01, 0x47, 0x01, + 0xe5, 0x00, 0x83, 0x00, 0x62, 0x00, 0x21, 0x00, 0x21, 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, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x63, 0x00, 0xa9, 0x01, 0x54, 0x2c, 0x96, 0x1c, + 0xb7, 0x1c, 0x96, 0x24, + 0x50, 0x23, 0xe5, 0x00, 0x21, 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, 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, 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, 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, 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, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd6, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd4, 0x0b, + 0x93, 0x13, 0x4c, 0x0a, + 0x84, 0x00, 0x21, 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, 0x01, 0x00, 0x21, 0x00, + 0x63, 0x00, 0xa4, 0x00, + 0x27, 0x01, 0x2b, 0x0a, 0xef, 0x1a, 0x50, 0x23, 0x71, 0x1b, 0xb2, 0x1b, + 0xd3, 0x1b, 0xd3, 0x1b, + 0xd3, 0x1b, 0xd3, 0x1b, 0xb3, 0x1b, 0x92, 0x1b, 0x71, 0x23, 0x0f, 0x23, + 0x4b, 0x0a, 0x47, 0x01, + 0xa4, 0x00, 0x63, 0x00, 0x41, 0x00, 0x21, 0x00, 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, + 0x01, 0x00, 0x63, 0x00, + 0x8d, 0x0a, 0x75, 0x2c, 0x97, 0x24, 0x96, 0x2c, 0x50, 0x2b, 0xe5, 0x00, + 0x21, 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, 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, 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, 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, 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, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xb3, 0x13, 0xcf, 0x12, 0xe6, 0x00, 0x22, 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, + 0x01, 0x00, 0x21, 0x00, + 0x63, 0x00, 0x27, 0x01, 0x4c, 0x02, 0x51, 0x13, 0xd3, 0x1b, 0xf4, 0x13, + 0xf4, 0x13, 0x15, 0x14, + 0x15, 0x0c, 0x15, 0x0c, 0x35, 0x0c, 0x35, 0x0c, 0x35, 0x0c, 0x36, 0x0c, + 0x35, 0x0c, 0x35, 0x0c, + 0x35, 0x14, 0x15, 0x14, 0x15, 0x1c, 0x14, 0x24, 0x71, 0x1b, 0x4c, 0x02, + 0x47, 0x01, 0x83, 0x00, + 0x21, 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, 0x21, 0x00, 0xe5, 0x00, 0x4f, 0x23, + 0x76, 0x2c, 0x96, 0x2c, + 0x50, 0x2b, 0xe5, 0x00, 0x21, 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, 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, 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, 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, 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, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd6, 0x03, + 0xd6, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xb4, 0x0b, 0x72, 0x1b, + 0x48, 0x01, 0x42, 0x00, + 0x01, 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, 0x21, 0x00, 0x43, 0x00, 0x06, 0x01, 0x4b, 0x0a, 0x50, 0x1b, + 0xf4, 0x1b, 0x15, 0x14, + 0x15, 0x04, 0x36, 0x04, 0x36, 0x04, 0x37, 0x04, 0x36, 0x04, 0x56, 0x04, + 0x56, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x57, 0x04, 0x57, 0x04, 0x56, 0x04, + 0x77, 0x04, 0x56, 0x0c, + 0x56, 0x14, 0x34, 0x1c, 0x92, 0x1b, 0x6c, 0x12, 0x26, 0x01, 0x63, 0x00, + 0x21, 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, + 0x42, 0x00, 0x88, 0x01, 0x13, 0x2c, 0x95, 0x3c, 0x50, 0x2b, 0xe5, 0x00, + 0x21, 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, 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, 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, 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, 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, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd6, 0x03, 0xf6, 0x03, + 0xf5, 0x03, 0xd4, 0x0b, + 0x93, 0x13, 0x6d, 0x0a, 0x63, 0x00, 0x01, 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, 0x42, 0x00, 0xa4, 0x00, + 0xca, 0x01, 0x71, 0x1b, + 0xd3, 0x13, 0x15, 0x14, 0x15, 0x0c, 0x36, 0x04, 0x57, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x77, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x56, 0x0c, + 0x55, 0x0c, 0x34, 0x1c, + 0x92, 0x1b, 0x2b, 0x02, 0xa4, 0x00, 0x42, 0x00, 0x01, 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, 0x01, 0x00, 0x63, 0x00, + 0xad, 0x1a, 0x74, 0x44, + 0x4f, 0x33, 0xe5, 0x00, 0x21, 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, 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, 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, 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, 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, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd4, 0x0b, 0x10, 0x1b, 0x27, 0x01, + 0x21, 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, + 0x01, 0x00, 0x42, 0x00, + 0x26, 0x01, 0xae, 0x12, 0xd3, 0x1b, 0x15, 0x14, 0x35, 0x0c, 0x36, 0x04, + 0x57, 0x04, 0x36, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x76, 0x0c, 0x56, 0x14, 0x34, 0x24, + 0xee, 0x1a, 0x47, 0x01, + 0x63, 0x00, 0x21, 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, 0x21, 0x00, 0xa4, 0x00, 0xf2, 0x4b, 0x4f, 0x3b, 0xc4, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x82, 0x10, 0x08, 0x42, + 0x8a, 0x52, 0x8a, 0x52, 0x65, 0x29, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x65, 0x29, + 0xaa, 0x52, 0xaa, 0x52, 0xaa, 0x52, 0xaa, 0x52, 0xaa, 0x52, 0xaa, 0x52, + 0x08, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x42, 0x08, 0x42, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x41, 0x08, + 0x08, 0x42, 0x28, 0x42, 0x00, 0x00, 0x41, 0x08, 0x28, 0x42, 0xaa, 0x52, + 0xaa, 0x52, 0xaa, 0x52, + 0xaa, 0x52, 0xaa, 0x52, 0xaa, 0x52, 0x49, 0x4a, 0xa2, 0x10, 0x00, 0x00, + 0xaa, 0x52, 0xaa, 0x52, + 0xaa, 0x52, 0xaa, 0x52, 0xaa, 0x52, 0xaa, 0x52, 0x8a, 0x52, 0x04, 0x21, + 0x00, 0x00, 0x82, 0x10, + 0x69, 0x4a, 0xaa, 0x52, 0xaa, 0x52, 0xaa, 0x52, 0xaa, 0x52, 0x28, 0x42, + 0xc3, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa2, 0x10, 0x49, 0x4a, 0x86, 0x31, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x21, + 0x8a, 0x52, 0xe3, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x29, 0xaa, 0x52, + 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0x86, 0x31, + 0x8a, 0x52, 0x8a, 0x52, + 0xe7, 0x39, 0x61, 0x08, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd6, 0x03, 0xd6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xd5, 0x03, 0x93, 0x13, + 0x0b, 0x0a, 0x63, 0x00, 0x01, 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, 0x21, 0x00, 0x43, 0x00, 0x48, 0x01, 0x30, 0x1b, 0xf4, 0x1b, + 0x15, 0x0c, 0x36, 0x04, + 0x36, 0x04, 0x56, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x56, 0x04, + 0x56, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x77, 0x04, 0x97, 0x04, + 0x77, 0x04, 0x97, 0x04, + 0x76, 0x04, 0x76, 0x0c, 0x35, 0x1c, 0x71, 0x1b, 0xa9, 0x01, 0x62, 0x00, + 0x21, 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, + 0x42, 0x00, 0x4a, 0x2a, + 0x2e, 0x43, 0xc4, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x21, 0xb2, 0x94, 0x3c, 0xe7, 0xdf, 0xff, 0xdf, 0xff, + 0x79, 0xce, 0x8e, 0x73, + 0x61, 0x08, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x79, 0xce, + 0x5d, 0xef, 0x8a, 0x52, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x21, 0x18, 0xc6, 0x79, 0xce, + 0x00, 0x00, 0x04, 0x21, + 0x79, 0xce, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x1c, 0xe7, + 0x08, 0x42, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0x7d, 0xef, 0xeb, 0x5a, 0x00, 0x00, 0x86, 0x31, 0xfb, 0xde, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x5d, 0xef, 0x55, 0xad, 0x24, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0x1c, 0xe7, + 0x71, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, 0xf3, 0x9c, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xef, 0x7b, 0xff, 0xff, 0x65, 0x29, 0x00, 0x00, + 0x00, 0x00, 0x61, 0x08, + 0xcf, 0x7b, 0x9a, 0xd6, 0xdf, 0xff, 0xff, 0xff, 0x1c, 0xe7, 0x71, 0x8c, + 0xe3, 0x18, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xd5, 0x03, 0xd5, 0x13, 0x31, 0x13, 0x06, 0x01, 0x21, 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, 0x01, 0x00, 0x42, 0x00, + 0x68, 0x01, 0x50, 0x1b, + 0xf4, 0x13, 0x36, 0x0c, 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, + 0x77, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x98, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x0c, 0x55, 0x1c, + 0xf3, 0x2b, 0x88, 0x01, 0x63, 0x00, 0x01, 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, 0x21, 0x00, 0x05, 0x09, 0x6a, 0x3a, 0xc3, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x10, 0xb2, 0x94, + 0xbe, 0xf7, 0x92, 0x94, + 0xa6, 0x31, 0xc7, 0x39, 0x9a, 0xd6, 0x9e, 0xf7, 0xaa, 0x52, 0x00, 0x00, + 0x00, 0x00, 0x71, 0x8c, + 0x3c, 0xe7, 0xeb, 0x5a, 0x45, 0x29, 0x45, 0x29, 0x45, 0x29, 0x45, 0x29, + 0xe3, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x79, 0xce, 0xff, 0xff, 0xba, 0xd6, 0xa2, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x21, + 0xf7, 0xbd, 0x79, 0xce, 0x00, 0x00, 0x20, 0x00, 0x04, 0x21, 0x45, 0x29, + 0x45, 0x29, 0x59, 0xce, + 0xba, 0xd6, 0x28, 0x42, 0x45, 0x29, 0x24, 0x21, 0x41, 0x08, 0x00, 0x00, + 0xff, 0xff, 0x75, 0xad, + 0xa6, 0x31, 0x45, 0x29, 0x45, 0x29, 0x45, 0x29, 0x24, 0x21, 0x82, 0x10, + 0x00, 0x00, 0x86, 0x31, + 0xfb, 0xde, 0x75, 0xad, 0x45, 0x29, 0x45, 0x29, 0x45, 0x29, 0x30, 0x84, + 0x7d, 0xef, 0x55, 0xad, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xfb, 0xde, 0x71, 0x8c, 0x00, 0x00, + 0x00, 0x00, 0x6d, 0x6b, + 0xff, 0xff, 0xbe, 0xf7, 0x8a, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xef, 0x7b, 0xff, 0xff, + 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x9e, 0xf7, 0xf7, 0xbd, + 0xc7, 0x39, 0xa6, 0x31, + 0x14, 0xa5, 0xbe, 0xf7, 0x51, 0x8c, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xf5, 0x03, 0xf5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xd5, 0x0b, + 0xb3, 0x1b, 0x2c, 0x0a, + 0x63, 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, 0x01, 0x00, + 0x42, 0x00, 0xa9, 0x01, 0x71, 0x1b, 0xf4, 0x13, 0x15, 0x0c, 0x36, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x97, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x0c, 0x77, 0x14, 0x76, 0x1c, 0xf3, 0x23, + 0xc9, 0x01, 0x62, 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, 0x21, 0x00, + 0x04, 0x11, 0x83, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x65, 0x29, 0xfb, 0xde, 0xf7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa6, 0x31, 0x9a, 0xd6, + 0x96, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0xfb, 0xde, 0x08, 0x42, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xce, + 0xdf, 0xff, 0xff, 0xff, + 0x71, 0x8c, 0x61, 0x08, 0x00, 0x00, 0xe3, 0x18, 0xf7, 0xbd, 0x79, 0xce, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xbd, 0x79, 0xce, 0x04, 0x21, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x9c, 0x82, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0x1c, 0xe7, 0x14, 0xa5, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0x18, 0x96, 0xb5, 0x7d, 0xef, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0x1c, 0xe7, + 0x71, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, 0xdf, 0xff, + 0x79, 0xce, 0x65, 0x29, + 0x00, 0x00, 0x00, 0x00, 0xef, 0x7b, 0xff, 0xff, 0x86, 0x31, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0xd6, + 0x9a, 0xd6, 0x45, 0x29, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0x38, 0xc6, + 0x38, 0xc6, 0x45, 0x29, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, 0xf5, 0x03, 0xf5, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf5, 0x03, 0xb4, 0x0b, 0x72, 0x23, 0xe6, 0x00, 0x21, 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, 0x42, 0x00, 0x06, 0x01, 0x51, 0x23, + 0xf4, 0x13, 0x36, 0x0c, + 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x98, 0x04, 0x97, 0x04, 0x98, 0x04, 0xb8, 0x04, 0x97, 0x04, + 0x97, 0x0c, 0x97, 0x0c, + 0xb7, 0x14, 0x76, 0x1c, 0xb1, 0x23, 0x67, 0x01, 0x42, 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, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, + 0xef, 0x7b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0xe7, 0x39, 0x28, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x71, 0x8c, + 0xfb, 0xde, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x79, 0xce, 0xdb, 0xde, 0xfb, 0xde, 0x3c, 0xe7, 0xaa, 0x52, + 0x00, 0x00, 0x04, 0x21, + 0xf7, 0xbd, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf7, 0xbd, + 0x79, 0xce, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x14, 0xa5, + 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x86, 0x31, + 0xfb, 0xde, 0x14, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x10, + 0x55, 0xad, 0x9e, 0xf7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xfb, 0xde, 0x71, 0x8c, 0x00, 0x00, + 0x00, 0x00, 0x6d, 0x6b, + 0xff, 0xff, 0xd7, 0xbd, 0xdf, 0xff, 0xb2, 0x94, 0x82, 0x10, 0x00, 0x00, + 0x10, 0x84, 0xff, 0xff, + 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xf7, 0x55, 0xad, 0xa2, 0x10, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa6, 0x31, 0x28, 0x42, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf5, 0x03, 0xb4, 0x13, + 0xae, 0x1a, 0x43, 0x00, + 0x01, 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, + 0x21, 0x00, 0xc5, 0x00, + 0xef, 0x12, 0x14, 0x1c, 0x15, 0x0c, 0x36, 0x04, 0x56, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x98, 0x04, + 0xb7, 0x04, 0xb8, 0x0c, 0xb7, 0x0c, 0xb7, 0x0c, 0xb8, 0x14, 0x97, 0x14, + 0x75, 0x24, 0x91, 0x23, + 0xa4, 0x00, 0x21, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0xff, 0xff, 0x6d, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0x5d, 0xef, 0xae, 0x73, + 0x49, 0x4a, 0x49, 0x4a, + 0x49, 0x4a, 0x49, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xce, + 0x18, 0xc6, 0xeb, 0x5a, + 0xbe, 0xf7, 0x18, 0xc6, 0x45, 0x29, 0x04, 0x21, 0xf7, 0xbd, 0x79, 0xce, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xbd, 0x79, 0xce, 0x04, 0x21, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd7, 0xbd, 0xaa, 0x52, 0x49, 0x4a, + 0x49, 0x4a, 0x49, 0x4a, + 0x45, 0x29, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xfb, 0xde, 0x55, 0xad, + 0xc3, 0x18, 0xc3, 0x18, + 0xc3, 0x18, 0xae, 0x73, 0x5d, 0xef, 0x55, 0xad, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0xfb, 0xde, + 0x92, 0x94, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, 0x69, 0x4a, + 0x59, 0xce, 0x7d, 0xef, + 0xaa, 0x52, 0x00, 0x00, 0xef, 0x7b, 0xff, 0xff, 0x86, 0x31, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, + 0x14, 0xa5, 0x82, 0x10, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf5, 0x0b, 0xb3, 0x1b, 0xa9, 0x01, 0x22, 0x00, 0x01, 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, 0x83, 0x00, 0x4c, 0x12, 0xf4, 0x1b, 0x16, 0x0c, + 0x36, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x98, 0x0c, 0x98, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x14, + 0xb8, 0x0c, 0xb7, 0x14, 0xb7, 0x1c, 0x75, 0x2c, 0xad, 0x1a, 0x83, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xff, 0xff, + 0x8e, 0x73, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x71, 0x8c, + 0xdf, 0xff, 0x7d, 0xef, 0x5d, 0xef, 0x5d, 0xef, 0x5d, 0xef, 0x5d, 0xef, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x79, 0xce, 0x18, 0xc6, 0xe3, 0x18, 0x30, 0x84, 0xdf, 0xff, + 0xd3, 0x9c, 0x24, 0x21, + 0xf7, 0xbd, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xc6, + 0x79, 0xce, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xdf, 0xff, + 0x5d, 0xef, 0x5d, 0xef, 0x5d, 0xef, 0x5d, 0xef, 0x10, 0x84, 0x00, 0x00, + 0x00, 0x00, 0x86, 0x31, + 0xfb, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, + 0x75, 0xad, 0x45, 0x29, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xfb, 0xde, 0x71, 0x8c, 0x00, 0x00, + 0x00, 0x00, 0x8e, 0x73, + 0xff, 0xff, 0x08, 0x42, 0x08, 0x42, 0x1c, 0xe7, 0x1c, 0xe7, 0xe3, 0x18, + 0xef, 0x7b, 0xff, 0xff, + 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, + 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf5, 0x03, 0xf4, 0x0b, 0x30, 0x13, + 0xe6, 0x00, 0x21, 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, 0x21, 0x00, + 0x68, 0x01, 0x92, 0x1b, + 0x15, 0x14, 0x56, 0x04, 0x37, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, 0x97, 0x04, 0xb7, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd7, 0x14, + 0xd7, 0x1c, 0xb6, 0x24, + 0x13, 0x34, 0xa8, 0x01, 0x41, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0xff, 0xff, 0x6d, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0x5d, 0xef, 0xcf, 0x7b, + 0x69, 0x4a, 0x69, 0x4a, + 0x69, 0x4a, 0x69, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xce, + 0xf7, 0xbd, 0x04, 0x21, + 0x24, 0x21, 0xf7, 0xbd, 0xbe, 0xf7, 0x2c, 0x63, 0xf7, 0xbd, 0x79, 0xce, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xbd, 0x9a, 0xd6, 0x04, 0x21, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf7, 0xbd, 0xcb, 0x5a, 0x69, 0x4a, + 0x69, 0x4a, 0x69, 0x4a, + 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0xfb, 0xde, 0x38, 0xc6, + 0x2c, 0x63, 0xcf, 0x7b, + 0x1c, 0xe7, 0xdb, 0xde, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0xfb, 0xde, + 0x92, 0x94, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x6b, 0xff, 0xff, 0x08, 0x42, + 0x61, 0x08, 0x10, 0x84, + 0xbe, 0xf7, 0x92, 0x94, 0x51, 0x8c, 0xff, 0xff, 0x86, 0x31, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, + 0x14, 0xa5, 0x82, 0x10, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xd5, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf5, 0x0b, + 0xd4, 0x13, 0x8e, 0x0a, 0x84, 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, 0x63, 0x00, 0x0f, 0x1b, 0x14, 0x14, 0x36, 0x0c, 0x36, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x76, 0x04, 0x77, 0x04, 0x97, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0xb8, 0x04, 0xb7, 0x04, + 0xb7, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, + 0xb8, 0x14, 0xb8, 0x14, + 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xb7, 0x24, 0x96, 0x2c, 0x2f, 0x1b, + 0xa4, 0x00, 0x21, 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, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xff, 0xff, + 0xae, 0x73, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xa2, 0x10, 0xc3, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x71, 0x8c, + 0x1c, 0xe7, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x79, 0xce, 0x18, 0xc6, 0x04, 0x21, 0x00, 0x00, 0x69, 0x4a, + 0x1c, 0xe7, 0x1c, 0xe7, + 0xfb, 0xde, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf7, 0xbd, + 0x79, 0xce, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x14, 0xa5, + 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x65, 0x29, + 0xfb, 0xde, 0x14, 0xa5, 0x00, 0x00, 0x20, 0x00, 0x71, 0x8c, 0x9e, 0xf7, + 0x8e, 0x73, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xfb, 0xde, 0x71, 0x8c, 0x00, 0x00, + 0x00, 0x00, 0x8e, 0x73, + 0xff, 0xff, 0x08, 0x42, 0x00, 0x00, 0xc3, 0x18, 0xd7, 0xbd, 0x5d, 0xef, + 0xba, 0xd6, 0xff, 0xff, + 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0xa5, 0x82, 0x10, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x10, 0xc3, 0x18, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xb3, 0x1b, 0x0b, 0x02, + 0x42, 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, 0x41, 0x00, 0x67, 0x01, + 0xf3, 0x1b, 0x36, 0x0c, + 0x56, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0xb8, 0x04, 0xb7, 0x04, 0xb8, 0x0c, 0xb8, 0x0c, 0xb7, 0x0c, + 0xb8, 0x0c, 0xb8, 0x14, + 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd7, 0x1c, + 0xb7, 0x2c, 0x75, 0x3c, 0xc9, 0x09, 0x41, 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, 0x00, 0x00, 0x00, + 0x65, 0x29, 0xfb, 0xde, 0xd7, 0xbd, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa6, 0x31, 0xdb, 0xde, + 0x38, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0x1c, 0xe7, 0x08, 0x42, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xce, + 0x18, 0xc6, 0x04, 0x21, + 0x00, 0x00, 0x20, 0x00, 0xef, 0x7b, 0xff, 0xff, 0xff, 0xff, 0x79, 0xce, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xbd, 0x79, 0xce, 0xe3, 0x18, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x9c, 0x61, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x31, 0xfb, 0xde, 0x14, 0xa5, + 0x00, 0x00, 0x00, 0x00, + 0xe3, 0x18, 0x7d, 0xef, 0xba, 0xd6, 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0xfb, 0xde, + 0x92, 0x94, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x6b, 0xff, 0xff, 0x08, 0x42, + 0x00, 0x00, 0x00, 0x00, + 0xa7, 0x31, 0x7d, 0xef, 0xff, 0xff, 0xff, 0xff, 0x86, 0x31, 0x00, 0x00, + 0x00, 0x00, 0x79, 0xce, + 0x99, 0xd6, 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0x38, 0xc6, + 0xdb, 0xde, 0x65, 0x29, + 0x00, 0x00, 0x41, 0x08, 0xa2, 0x18, 0x61, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0x71, 0x1b, 0x68, 0x01, 0x22, 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, 0x21, 0x00, + 0x83, 0x00, 0xad, 0x12, 0x15, 0x14, 0x56, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x98, 0x04, 0x97, 0x04, 0x98, 0x04, 0xb8, 0x04, 0x98, 0x04, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb7, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, 0xb6, 0x34, + 0x70, 0x33, 0x63, 0x00, + 0x21, 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, 0x00, 0xa2, 0x10, 0x14, 0xa5, + 0x9e, 0xf7, 0xcf, 0x7b, + 0x86, 0x31, 0xa6, 0x31, 0x75, 0xad, 0xbe, 0xf7, 0x4d, 0x6b, 0x00, 0x00, + 0x00, 0x00, 0x92, 0x94, + 0x5d, 0xef, 0xcf, 0x7b, 0x69, 0x4a, 0x69, 0x4a, 0x69, 0x4a, 0x69, 0x4a, + 0xc7, 0x39, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0xd6, 0xf7, 0xbd, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, + 0xa2, 0x10, 0x59, 0xce, + 0xff, 0xff, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf7, 0xbd, + 0x79, 0xce, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xf7, 0xbd, + 0xcb, 0x5a, 0x69, 0x4a, 0x69, 0x4a, 0x69, 0x4a, 0x48, 0x42, 0xe3, 0x18, + 0x00, 0x00, 0x66, 0x31, + 0xfb, 0xde, 0x14, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x84, + 0xff, 0xff, 0xef, 0x7b, + 0x00, 0x00, 0x00, 0x00, 0xaa, 0x52, 0x92, 0x94, 0xc7, 0x39, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0xfb, 0xde, 0x71, 0x8c, 0x00, 0x00, + 0x00, 0x00, 0x8e, 0x6b, + 0xff, 0xff, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x84, + 0xdf, 0xff, 0xff, 0xff, + 0x65, 0x29, 0x00, 0x00, 0x00, 0x00, 0xef, 0x7b, 0x9e, 0xf7, 0x34, 0xa5, + 0xa6, 0x31, 0x86, 0x31, + 0xef, 0x7b, 0xbe, 0xf7, 0xd3, 0x9c, 0x61, 0x08, 0x00, 0x00, 0xcb, 0x5a, + 0xb6, 0xb5, 0x2c, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xf4, 0x13, 0x10, 0x1b, 0xe6, 0x00, + 0x21, 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, 0x21, 0x00, 0x67, 0x01, 0x91, 0x1b, + 0x15, 0x14, 0x56, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x98, 0x04, 0x97, 0x04, 0xb8, 0x04, + 0xb8, 0x04, 0xb8, 0x04, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb7, 0x0c, + 0xb8, 0x14, 0xd8, 0x14, + 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x24, + 0xd8, 0x24, 0xd7, 0x34, 0x75, 0x44, 0x06, 0x01, 0x21, 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, 0x00, + 0x00, 0x00, 0x45, 0x29, 0xb6, 0xb5, 0x3c, 0xe7, 0xfb, 0xde, 0xfb, 0xde, + 0x1c, 0xe7, 0x51, 0x8c, + 0xa2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x84, 0x7d, 0xef, 0x3c, 0xe7, + 0xfb, 0xde, 0xfb, 0xde, + 0xfb, 0xde, 0xfb, 0xde, 0x55, 0xad, 0x00, 0x00, 0x00, 0x00, 0x38, 0xc6, + 0xb6, 0xb5, 0xe3, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x4a, 0x3c, 0xe7, 0x38, 0xc6, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0xb5, 0x18, 0xc6, 0xe3, 0x18, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9e, 0xf7, 0x5d, 0xef, 0x1b, 0xe7, 0xfb, 0xde, + 0xfb, 0xde, 0xfb, 0xde, + 0x9a, 0xd6, 0xaa, 0x52, 0x00, 0x00, 0x65, 0x29, 0x9a, 0xd6, 0xb2, 0x94, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x45, 0x29, 0x38, 0xc6, 0xfb, 0xde, 0x82, 0x10, 0x00, 0x00, + 0x71, 0x8c, 0x7d, 0xef, + 0xeb, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc7, 0x39, 0x9a, 0xd6, + 0x50, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x6b, 0x9e, 0xf7, 0xe7, 0x39, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x21, 0xd7, 0xbd, 0x9e, 0xf7, 0x65, 0x29, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0x18, + 0xb2, 0x94, 0x3c, 0xe7, 0xfb, 0xe6, 0xfb, 0xe6, 0x3c, 0xe7, 0x75, 0xad, + 0x24, 0x21, 0x00, 0x00, + 0x00, 0x00, 0xcf, 0x7b, 0x9e, 0xf7, 0x30, 0x84, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, + 0xce, 0x1a, 0x84, 0x00, 0x21, 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, 0x62, 0x00, + 0x2b, 0x02, 0xf4, 0x1b, 0x36, 0x0c, 0x57, 0x04, 0x77, 0x04, 0x57, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x77, 0x04, + 0x98, 0x04, 0xb8, 0x04, + 0x98, 0x04, 0xb8, 0x04, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x14, + 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xf8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xd7, 0x2c, + 0x96, 0x44, 0x8c, 0x1a, + 0x42, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x8a, 0x52, + 0xae, 0x73, 0x8e, 0x73, 0x86, 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x65, 0x29, + 0x8a, 0x52, 0x8a, 0x52, 0x8a, 0x52, 0x8a, 0x52, 0x8a, 0x52, 0x8a, 0x52, + 0xe7, 0x39, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x42, 0xe7, 0x39, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x41, 0x08, + 0xe7, 0x39, 0x28, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe7, 0x39, + 0x08, 0x42, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8a, 0x52, 0x8a, 0x52, + 0x89, 0x52, 0x89, 0x52, 0x8a, 0x52, 0x8a, 0x52, 0x69, 0x4a, 0xe3, 0x18, + 0x00, 0x00, 0x82, 0x10, + 0x29, 0x42, 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x86, 0x31, 0x8a, 0x52, + 0xa2, 0x10, 0x00, 0x00, 0x91, 0x94, 0x7d, 0xef, 0x0c, 0x63, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa2, 0x10, 0x28, 0x42, 0x65, 0x29, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x21, + 0x8a, 0x52, 0xa2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x29, 0x8a, 0x52, + 0x82, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0xa7, 0x31, + 0x8e, 0x73, 0xae, 0x73, + 0x49, 0x4a, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x29, + 0x8a, 0x52, 0x65, 0x29, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xb5, 0x03, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, 0x4c, 0x12, 0x63, 0x00, + 0x01, 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, 0xa4, 0x00, 0xcf, 0x0a, 0x15, 0x14, + 0x56, 0x0c, 0x57, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x98, 0x04, 0xb8, 0x04, 0x98, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, 0xf8, 0x1c, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xd8, 0x2c, 0xb7, 0x3c, 0x91, 0x33, 0x83, 0x00, 0x21, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x94, 0xf7, 0xbd, + 0x45, 0x29, 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, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xb5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x1b, + 0xc9, 0x01, 0x42, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x06, 0x01, + 0x71, 0x13, 0x35, 0x0c, 0x56, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, 0xb8, 0x04, + 0x98, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, 0xd8, 0x14, 0xb8, 0x14, + 0xb8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xf8, 0x1c, 0xd8, 0x24, + 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xd7, 0x3c, 0x13, 0x3c, + 0x26, 0x01, 0x21, 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, 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, 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, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x4a, 0xe3, 0x18, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xb5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x1b, 0x68, 0x01, 0x21, 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, 0x21, 0x00, 0x67, 0x01, 0xf3, 0x23, 0x36, 0x0c, + 0x76, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0xb8, 0x04, + 0xb8, 0x04, 0xb7, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x14, 0xb8, 0x14, + 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x24, 0xd8, 0x24, + 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf9, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x34, 0x54, 0x3c, 0xa8, 0x09, 0x21, 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, 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, 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, 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, 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, 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, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf4, 0x1b, + 0x07, 0x01, 0x21, 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, + 0x22, 0x00, 0xc9, 0x09, + 0x14, 0x24, 0x56, 0x0c, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0xb8, 0x04, 0xb8, 0x04, 0x98, 0x04, 0xb7, 0x04, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x34, 0xb6, 0x44, + 0x4b, 0x1a, 0x21, 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, 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, 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, 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, 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, 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, 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, + 0x0c, 0x02, 0x73, 0x1b, 0xb4, 0x0b, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, 0xd5, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x16, 0x04, 0xf3, 0x1b, 0x06, 0x01, 0x21, 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, 0x42, 0x00, 0x0b, 0x0a, 0x14, 0x1c, 0x56, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x98, 0x04, + 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, 0x98, 0x04, 0xb8, 0x04, 0xb7, 0x04, + 0xb7, 0x04, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb7, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, + 0xd8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0x18, 0x35, 0xf8, 0x34, 0xf8, 0x34, 0xd7, 0x44, 0x8c, 0x22, 0x22, 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, 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, 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, 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, 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, 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, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb4, 0x0b, 0xd5, 0x03, + 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0xf4, 0x1b, + 0x06, 0x01, 0x21, 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, + 0x42, 0x00, 0x8d, 0x12, + 0x35, 0x1c, 0x56, 0x0c, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x98, 0x04, + 0x98, 0x04, 0x98, 0x04, + 0xb7, 0x04, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x14, 0xd8, 0x14, + 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x19, 0x2d, 0x19, 0x2d, 0x19, 0x35, 0x18, 0x35, 0x18, 0x35, + 0x18, 0x3d, 0xd7, 0x4c, + 0xad, 0x22, 0x42, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x20, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x21, 0x00, 0x01, 0x00, 0x01, 0x00, 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, 0x00, + 0x0c, 0x02, 0x73, 0x1b, 0xb5, 0x0b, 0xd5, 0x03, 0xd5, 0x03, 0xd5, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x36, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0xd4, 0x1b, 0x06, 0x01, 0x21, 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, 0x63, 0x00, 0xad, 0x12, 0x35, 0x1c, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x98, 0x04, 0xb8, 0x04, 0xb8, 0x04, 0xb7, 0x0c, 0xb8, 0x0c, 0xb7, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xd8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xf8, 0x1c, 0xf8, 0x1c, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x2c, + 0xf8, 0x2c, 0x18, 0x2d, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, + 0x18, 0x35, 0x18, 0x35, + 0x19, 0x35, 0x19, 0x35, 0x19, 0x3d, 0xf7, 0x4c, 0x0e, 0x2b, 0x63, 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, 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, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x21, 0x00, 0x22, 0x00, + 0x63, 0x00, 0x63, 0x00, + 0x84, 0x00, 0xc5, 0x00, 0xe6, 0x00, 0xe6, 0x00, 0xa5, 0x00, 0x84, 0x00, + 0x64, 0x00, 0x43, 0x00, + 0x42, 0x00, 0x21, 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, 0x0c, 0x02, 0x73, 0x1b, + 0xb5, 0x0b, 0xd5, 0x03, + 0xd5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf5, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x16, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0xf4, 0x1b, + 0x06, 0x01, 0x21, 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, + 0x62, 0x00, 0xad, 0x12, + 0x35, 0x1c, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x98, 0x04, 0x98, 0x04, 0xb8, 0x04, 0xb8, 0x04, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb7, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, + 0xf8, 0x2c, 0x18, 0x2d, + 0x18, 0x2d, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, 0x19, 0x35, 0x18, 0x35, + 0x18, 0x3d, 0xf7, 0x4c, + 0x0e, 0x33, 0x82, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, + 0xc4, 0x00, 0xe5, 0x00, + 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xe5, 0x00, 0xc4, 0x00, + 0x83, 0x00, 0x21, 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, 0x00, 0x00, 0x00, 0x21, 0x00, 0x42, 0x00, + 0x63, 0x00, 0xa4, 0x00, + 0x06, 0x01, 0xa9, 0x01, 0x4c, 0x12, 0xee, 0x22, 0x30, 0x23, 0x51, 0x23, + 0x51, 0x23, 0x71, 0x23, + 0x30, 0x23, 0x30, 0x23, 0xce, 0x1a, 0x4c, 0x12, 0xa9, 0x01, 0x06, 0x01, + 0xa4, 0x00, 0x63, 0x00, + 0x21, 0x00, 0x21, 0x00, 0x01, 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, + 0x0c, 0x02, 0x93, 0x1b, 0xb5, 0x0b, 0xd5, 0x03, 0xd5, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, + 0x16, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x56, 0x04, 0x36, 0x04, 0xf4, 0x1b, 0x06, 0x01, 0x21, 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, 0x62, 0x00, 0x8c, 0x12, 0x35, 0x1c, 0x77, 0x04, + 0x77, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x98, 0x04, 0x97, 0x04, 0x98, 0x04, 0xb8, 0x04, + 0xb8, 0x04, 0xb8, 0x04, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, + 0xb7, 0x14, 0xb8, 0x14, + 0xd8, 0x1c, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x24, 0xd8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x18, 0x2d, 0x18, 0x2d, 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, + 0x19, 0x35, 0x19, 0x35, + 0x19, 0x35, 0x39, 0x3d, 0x19, 0x3d, 0xf7, 0x4c, 0xac, 0x22, 0x42, 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, 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, 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, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0a, 0x1a, 0x91, 0x2b, 0xd3, 0x1b, 0xb3, 0x1b, 0xb3, 0x1b, + 0xb3, 0x1b, 0xd3, 0x1b, + 0xd3, 0x1b, 0xb2, 0x2b, 0xce, 0x2a, 0x43, 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, + 0x01, 0x00, 0x21, 0x00, + 0xa4, 0x00, 0x68, 0x01, 0x2c, 0x02, 0x10, 0x13, 0xb3, 0x1b, 0xd4, 0x1b, + 0xd4, 0x13, 0xd4, 0x13, + 0xd4, 0x13, 0xd4, 0x13, 0xf4, 0x13, 0xf4, 0x0b, 0xf4, 0x13, 0xd4, 0x13, + 0xd4, 0x13, 0xd4, 0x13, + 0xd4, 0x1b, 0xb3, 0x1b, 0xef, 0x12, 0x2c, 0x0a, 0x68, 0x01, 0x84, 0x00, + 0x42, 0x00, 0x01, 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, 0x0c, 0x02, 0x93, 0x1b, + 0xd5, 0x0b, 0xf6, 0x03, + 0xf5, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, + 0x36, 0x04, 0xf4, 0x1b, + 0x06, 0x01, 0x21, 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, + 0x42, 0x00, 0x2b, 0x0a, + 0x34, 0x1c, 0x76, 0x0c, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x98, 0x04, 0x98, 0x04, + 0xb8, 0x04, 0xb8, 0x04, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x14, 0xb8, 0x14, + 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, 0x18, 0x35, + 0x18, 0x35, 0x18, 0x35, + 0x18, 0x35, 0x39, 0x35, 0x19, 0x35, 0x19, 0x3d, 0x39, 0x3d, 0x38, 0x3d, + 0x18, 0x45, 0xf7, 0x54, + 0x8c, 0x2a, 0x21, 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, 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, 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, 0x00, 0x00, 0x00, 0x42, 0x00, 0x0b, 0x12, + 0xd3, 0x1b, 0xf5, 0x0b, + 0xf5, 0x03, 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x03, 0xf5, 0x0b, 0xd4, 0x13, + 0xef, 0x1a, 0x63, 0x00, + 0x01, 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, + 0x21, 0x00, 0x22, 0x00, 0x63, 0x00, 0x47, 0x01, 0xae, 0x12, 0x71, 0x1b, + 0xd3, 0x1b, 0xf4, 0x0b, + 0xf5, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x03, 0xf6, 0x03, 0xf5, 0x0b, + 0xd5, 0x13, 0xd3, 0x1b, + 0x71, 0x1b, 0x8d, 0x12, 0xa9, 0x01, 0x84, 0x00, 0x22, 0x00, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x02, 0x93, 0x1b, 0xd5, 0x0b, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x36, 0x04, 0x36, 0x04, 0xf4, 0x1b, 0x47, 0x01, 0x21, 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, 0x22, 0x00, 0xc9, 0x01, 0x34, 0x24, 0x76, 0x0c, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, 0xb8, 0x04, 0xb8, 0x04, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xf8, 0x1c, 0xf8, 0x1c, 0xf8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, 0xd8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0x19, 0x2d, 0xf8, 0x2c, 0x18, 0x2d, + 0xf8, 0x2c, 0xf8, 0x2c, + 0x18, 0x35, 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, 0x18, 0x35, + 0x19, 0x3d, 0x39, 0x3d, + 0x39, 0x3d, 0x39, 0x45, 0x18, 0x45, 0xb6, 0x4c, 0x2a, 0x22, 0x21, 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, 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, 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, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x0b, 0x12, 0xd4, 0x13, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, + 0x16, 0x04, 0xd4, 0x13, 0x0f, 0x1b, 0x63, 0x00, 0x01, 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, 0x01, 0x00, 0x63, 0x00, 0x27, 0x01, + 0xae, 0x12, 0x92, 0x1b, + 0xd4, 0x13, 0xf5, 0x0b, 0xf5, 0x0b, 0xf5, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x0b, 0xf5, 0x0b, 0xd4, 0x13, + 0x92, 0x1b, 0xef, 0x1a, + 0x47, 0x01, 0x84, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x93, 0x1b, + 0xd5, 0x0b, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x56, 0x04, + 0x36, 0x04, 0x15, 0x1c, + 0xa9, 0x01, 0x42, 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, + 0x21, 0x00, 0x47, 0x01, + 0xf3, 0x23, 0x76, 0x0c, 0x97, 0x0c, 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, + 0xb8, 0x04, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb7, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xd8, 0x14, + 0xb8, 0x14, 0xd8, 0x1c, + 0xd8, 0x1c, 0xb8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0x19, 0x2d, + 0x18, 0x2d, 0xf8, 0x2c, + 0xf8, 0x2c, 0x19, 0x2d, 0x19, 0x35, 0xf8, 0x2c, 0x18, 0x35, 0x19, 0x35, + 0x19, 0x35, 0x18, 0x3d, + 0x39, 0x3d, 0x39, 0x3d, 0x19, 0x3d, 0x39, 0x3d, 0x39, 0x3d, 0x18, 0x45, + 0x18, 0x4d, 0x75, 0x4c, + 0xa8, 0x11, 0x21, 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, 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, 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, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xf4, 0x13, + 0xef, 0x1a, 0x63, 0x00, + 0x01, 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, + 0x21, 0x00, 0xa4, 0x00, + 0xca, 0x01, 0x71, 0x23, 0xd4, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x0b, 0xd4, 0x13, 0x72, 0x23, 0x4c, 0x12, + 0xe6, 0x00, 0x22, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x2d, 0x02, 0x93, 0x1b, 0xd5, 0x0b, 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x15, 0x1c, 0x0b, 0x0a, 0x42, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x06, 0x01, 0x91, 0x13, 0x76, 0x14, + 0x97, 0x0c, 0x98, 0x04, + 0x98, 0x04, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x14, + 0xd8, 0x14, 0xd7, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xf8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x35, 0xf8, 0x34, 0x18, 0x35, + 0x18, 0x35, 0x18, 0x35, + 0x19, 0x35, 0x39, 0x35, 0x39, 0x3d, 0x18, 0x3d, 0x38, 0x3d, 0x39, 0x3d, + 0x39, 0x3d, 0x39, 0x45, + 0x39, 0x45, 0x38, 0x45, 0x18, 0x4d, 0x33, 0x4c, 0x05, 0x01, 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, 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, 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, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 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, 0x21, 0x00, 0xe5, 0x00, 0x4c, 0x0a, 0x92, 0x1b, 0xd4, 0x13, + 0xf5, 0x0b, 0xf6, 0x03, + 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0xf5, 0x0b, + 0xf4, 0x0b, 0xb3, 0x1b, 0xef, 0x1a, 0x27, 0x01, 0x42, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x02, 0xb3, 0x1b, + 0xd5, 0x0b, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x15, 0x14, + 0xae, 0x1a, 0x63, 0x00, 0x01, 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, 0xa3, 0x00, + 0xee, 0x0a, 0x76, 0x1c, 0x97, 0x14, 0x98, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xf8, 0x1c, 0xd8, 0x1c, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xd8, 0x24, 0xf8, 0x24, + 0xf9, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, + 0xf8, 0x2c, 0x18, 0x35, + 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, 0x19, 0x35, 0x39, 0x3d, + 0x19, 0x3d, 0x38, 0x3d, + 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x38, 0x4d, + 0x17, 0x55, 0xb1, 0x43, + 0x42, 0x00, 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, 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, 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, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x22, 0x00, 0xc5, 0x00, + 0x0f, 0x1b, 0xb3, 0x1b, + 0xf5, 0x0b, 0xf6, 0x03, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0xf5, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x0b, + 0xd4, 0x13, 0x50, 0x1b, + 0x88, 0x01, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x2d, 0x02, 0xb3, 0x1b, 0xd5, 0x0b, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x35, 0x14, 0x30, 0x23, 0xa4, 0x00, + 0x21, 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, 0x42, 0x00, 0x0b, 0x02, 0x34, 0x24, + 0x97, 0x14, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, + 0xd8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xf8, 0x1c, + 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0x18, 0x2d, 0x18, 0x35, 0x18, 0x35, 0x18, 0x35, 0x18, 0x35, 0x18, 0x35, + 0x19, 0x3d, 0x18, 0x3d, + 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x38, 0x4d, 0xf7, 0x5c, 0x4b, 0x1a, 0x41, 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, 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, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0x07, 0x01, 0xcf, 0x12, 0xd4, 0x1b, 0xf5, 0x0b, 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0xf6, 0x03, + 0xf5, 0x0b, 0xf5, 0x0b, 0xf5, 0x0b, 0xf4, 0x0b, 0xf5, 0x0b, 0xf5, 0x0b, + 0x15, 0x04, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd4, 0x13, 0x51, 0x1b, 0xa9, 0x01, + 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x02, 0xb3, 0x1b, + 0xd5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x36, 0x04, + 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x35, 0x14, + 0x71, 0x1b, 0x26, 0x01, 0x21, 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, 0x21, 0x00, + 0x47, 0x01, 0xb2, 0x23, 0x76, 0x1c, 0xb7, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x14, 0xd8, 0x14, + 0xd7, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xb8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x24, 0xd8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x34, + 0xf8, 0x34, 0xf8, 0x34, 0xf8, 0x2c, 0x18, 0x2d, 0x18, 0x35, 0x18, 0x35, + 0x19, 0x35, 0x19, 0x35, + 0x19, 0x35, 0x18, 0x3d, 0x19, 0x3d, 0x19, 0x3d, 0x18, 0x3d, 0x39, 0x3d, + 0x39, 0x3d, 0x39, 0x3d, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x18, 0x4d, + 0xf6, 0x64, 0xe5, 0x00, + 0x21, 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, 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, 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, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0xe6, 0x00, 0xcf, 0x12, 0xb3, 0x1b, + 0xd5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, + 0xf5, 0x0b, 0xf5, 0x0b, 0xd4, 0x13, 0xb3, 0x13, 0xb3, 0x1b, 0xb3, 0x23, + 0x72, 0x1b, 0x72, 0x1b, + 0xb2, 0x23, 0xb3, 0x1b, 0xd4, 0x1b, 0xd4, 0x13, 0xf5, 0x13, 0xf5, 0x0b, + 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x15, 0x04, + 0xf4, 0x13, 0x71, 0x1b, 0x68, 0x01, 0x42, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x2d, 0x02, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x56, 0x0c, 0xd3, 0x1b, 0xc9, 0x01, + 0x22, 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, 0x63, 0x00, 0xad, 0x1a, + 0x76, 0x24, 0xb7, 0x14, + 0xb7, 0x14, 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xf8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf8, 0x2c, 0xd7, 0x3c, 0xf3, 0x23, 0x96, 0x34, 0xf7, 0x3c, + 0xf8, 0x34, 0x18, 0x35, + 0x19, 0x35, 0x19, 0x35, 0x19, 0x35, 0x19, 0x3d, 0x39, 0x3d, 0x39, 0x3d, + 0x39, 0x3d, 0x19, 0x3d, + 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x38, 0x4d, 0x38, 0x55, 0x70, 0x43, 0x42, 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, 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, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0x84, 0x00, 0xae, 0x12, + 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd4, 0x13, 0xb3, 0x1b, 0x51, 0x1b, + 0x8d, 0x12, 0xca, 0x01, + 0x27, 0x01, 0xc6, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xe5, 0x00, 0x27, 0x01, + 0xc9, 0x01, 0xae, 0x1a, + 0x51, 0x1b, 0x93, 0x1b, 0xd4, 0x13, 0xf5, 0x0b, 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0xf5, 0x03, 0xd4, 0x13, + 0x30, 0x1b, 0x47, 0x01, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x02, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x76, 0x0c, + 0x35, 0x1c, 0x6c, 0x02, 0x63, 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, + 0x21, 0x00, 0x06, 0x01, 0x34, 0x2c, 0x96, 0x1c, 0xb7, 0x14, 0xb7, 0x14, + 0xd8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xf8, 0x1c, 0xd8, 0x24, + 0xd8, 0x24, 0xd8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x34, + 0x75, 0x3c, 0x07, 0x01, + 0xae, 0x0a, 0xb6, 0x44, 0xf8, 0x3c, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, + 0x19, 0x3d, 0x39, 0x3d, + 0x18, 0x3d, 0x38, 0x3d, 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x38, 0x4d, 0x38, 0x4d, 0xd6, 0x54, + 0xc9, 0x11, 0x21, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x83, 0x00, 0x0b, 0x02, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x0c, 0xf4, 0x0b, + 0xd3, 0x13, 0xef, 0x0a, + 0x0b, 0x02, 0xe6, 0x00, 0x63, 0x00, 0x42, 0x00, 0x22, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x01, 0x00, + 0x21, 0x00, 0x21, 0x00, 0x42, 0x00, 0x63, 0x00, 0xc6, 0x00, 0xeb, 0x01, + 0x10, 0x13, 0xb3, 0x13, + 0xf5, 0x13, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, + 0x16, 0x04, 0xf5, 0x0b, 0xd4, 0x13, 0xcf, 0x12, 0xc5, 0x00, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x2d, 0x02, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x36, 0x04, 0x16, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x76, 0x04, 0x55, 0x14, 0x2f, 0x0b, + 0xc5, 0x00, 0x21, 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, 0x63, 0x00, + 0x0f, 0x1b, 0x75, 0x2c, + 0xb7, 0x24, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x24, 0xd8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xd8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xd7, 0x3c, 0xf2, 0x33, 0x85, 0x00, 0x27, 0x01, 0xf2, 0x43, + 0xf7, 0x44, 0x18, 0x3d, + 0x19, 0x35, 0x39, 0x3d, 0x39, 0x3d, 0x19, 0x3d, 0x38, 0x3d, 0x39, 0x3d, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x59, 0x45, + 0x39, 0x4d, 0x38, 0x55, + 0x18, 0x5d, 0x90, 0x3b, 0xc4, 0x00, 0x21, 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, 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, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x68, 0x01, + 0x72, 0x1b, 0xf4, 0x0b, + 0x15, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd4, 0x13, 0x92, 0x1b, 0x4c, 0x0a, 0xe5, 0x00, 0x63, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x43, 0x00, 0xe6, 0x00, 0xeb, 0x01, 0x72, 0x1b, 0xd4, 0x13, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0xf5, 0x0b, 0xb3, 0x1b, + 0x0b, 0x0a, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x02, 0xd3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x77, 0x04, + 0x56, 0x0c, 0xf3, 0x1b, 0x67, 0x01, 0x41, 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, 0x21, 0x00, 0x47, 0x01, 0xd2, 0x2b, 0x96, 0x2c, 0xd7, 0x24, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xf8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x19, 0x35, 0xd7, 0x3c, + 0x95, 0x54, 0x84, 0x00, + 0x63, 0x00, 0x4b, 0x1a, 0xd7, 0x4c, 0x18, 0x45, 0x19, 0x3d, 0x39, 0x3d, + 0x39, 0x3d, 0x39, 0x3d, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x59, 0x45, + 0x59, 0x45, 0x59, 0x45, + 0x59, 0x45, 0x39, 0x45, 0x39, 0x4d, 0x38, 0x55, 0x74, 0x54, 0x88, 0x09, + 0x21, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x83, 0x00, + 0x83, 0x00, 0x84, 0x00, + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x83, 0x00, 0x62, 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, 0x42, 0x00, 0x83, 0x00, + 0x83, 0x00, 0x84, 0x00, + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x83, 0x00, 0x42, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, + 0xc5, 0x00, 0xce, 0x12, 0xd4, 0x13, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x0b, 0xd4, 0x13, 0x31, 0x13, 0x89, 0x01, + 0x84, 0x00, 0x21, 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, 0x01, 0x00, + 0x21, 0x00, 0x63, 0x00, + 0x07, 0x01, 0xef, 0x12, 0xb4, 0x13, 0xf5, 0x0b, 0xf6, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf5, 0x03, 0xf5, 0x03, 0xf5, 0x0b, 0xd4, 0x13, 0x71, 0x2b, 0xe6, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x2d, 0x02, 0xd3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x76, 0x0c, 0x55, 0x1c, + 0x4b, 0x0a, 0x63, 0x00, + 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, 0x20, 0x00, + 0x63, 0x00, 0x2b, 0x12, + 0x54, 0x34, 0xd7, 0x2c, 0xd8, 0x24, 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x19, 0x35, + 0x19, 0x35, 0xf8, 0x3c, 0xb5, 0x54, 0xa4, 0x00, 0x22, 0x00, 0x83, 0x00, + 0x33, 0x44, 0xf7, 0x4c, + 0x18, 0x45, 0x19, 0x3d, 0x19, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x59, 0x45, 0x59, 0x45, 0x59, 0x45, 0x59, 0x4d, + 0x38, 0x55, 0x37, 0x5d, + 0xcd, 0x2a, 0x42, 0x00, 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, 0x00, + 0x00, 0x00, 0x21, 0x00, + 0x47, 0x01, 0x8d, 0x1a, 0xae, 0x12, 0xae, 0x0a, 0xcf, 0x0a, 0xcf, 0x0a, + 0xcf, 0x0a, 0xae, 0x12, + 0x8d, 0x12, 0xea, 0x11, 0x42, 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, 0x21, 0x00, + 0x47, 0x01, 0x8d, 0x1a, 0xce, 0x12, 0xce, 0x0a, 0xce, 0x0a, 0xae, 0x0a, + 0xcf, 0x0a, 0xae, 0x12, + 0x8d, 0x1a, 0x88, 0x09, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0xea, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, + 0xd4, 0x13, 0x30, 0x13, + 0x27, 0x01, 0x42, 0x00, 0x01, 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, 0x01, 0x00, 0x42, 0x00, 0xe6, 0x00, + 0x8e, 0x12, 0x92, 0x1b, + 0xd4, 0x13, 0xf5, 0x0b, 0xd5, 0x0b, 0xf5, 0x0b, 0xf5, 0x0b, 0xf5, 0x0b, + 0xf5, 0x0b, 0xd4, 0x13, + 0xb2, 0x23, 0x4c, 0x12, 0x63, 0x00, 0x00, 0x00, 0x4d, 0x02, 0xd4, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x77, 0x04, 0x55, 0x14, 0x91, 0x23, 0x84, 0x00, 0x21, 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, 0x21, 0x00, 0xa4, 0x00, 0x0f, 0x23, 0xb6, 0x34, + 0xb7, 0x2c, 0xd8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x19, 0x35, 0x19, 0x35, 0xf8, 0x3c, + 0xd6, 0x54, 0x06, 0x01, + 0x21, 0x00, 0x22, 0x00, 0x2a, 0x12, 0xd6, 0x54, 0x18, 0x4d, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x38, 0x45, 0x38, 0x45, 0x39, 0x45, 0x59, 0x45, + 0x59, 0x45, 0x59, 0x45, + 0x59, 0x4d, 0x38, 0x55, 0x38, 0x5d, 0x12, 0x4c, 0xa4, 0x00, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0xca, 0x09, 0xb2, 0x23, + 0xd3, 0x1b, 0xd4, 0x13, + 0xd4, 0x0b, 0xf5, 0x13, 0xd4, 0x0b, 0xd4, 0x13, 0xb3, 0x23, 0xce, 0x22, + 0x63, 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, 0x22, 0x00, 0xca, 0x09, 0xb2, 0x2b, + 0xb3, 0x13, 0xf4, 0x13, + 0xd4, 0x13, 0xf4, 0x13, 0xf5, 0x13, 0xd3, 0x13, 0xb2, 0x23, 0x2b, 0x0a, + 0x62, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x64, 0x00, + 0x10, 0x1b, 0xd4, 0x13, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf5, 0x03, 0xf4, 0x13, 0x51, 0x1b, 0x89, 0x01, 0x42, 0x00, 0x01, 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, 0x00, 0x22, 0x00, 0xc5, 0x00, 0xad, 0x1a, 0x92, 0x2b, 0xb2, 0x23, + 0xb2, 0x23, 0xb3, 0x23, + 0xb2, 0x23, 0xb2, 0x23, 0xb3, 0x23, 0xb2, 0x23, 0x91, 0x2b, 0x0e, 0x33, + 0xe4, 0x08, 0x20, 0x00, + 0x4d, 0x02, 0xd3, 0x1b, 0x15, 0x0c, 0x16, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x98, 0x04, 0x76, 0x0c, + 0x55, 0x2c, 0xa9, 0x01, + 0x42, 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, 0x21, 0x00, + 0xc5, 0x00, 0x91, 0x33, 0xb6, 0x3c, 0xd7, 0x2c, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x2c, + 0x18, 0x2d, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x35, 0x18, 0x35, + 0x18, 0x35, 0x18, 0x35, + 0x19, 0x35, 0xf8, 0x44, 0xd6, 0x54, 0x47, 0x01, 0x21, 0x00, 0x21, 0x00, + 0xe5, 0x00, 0x90, 0x3b, + 0x17, 0x4d, 0x38, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x59, 0x45, + 0x59, 0x45, 0x59, 0x45, 0x59, 0x4d, 0x59, 0x4d, 0x58, 0x55, 0x38, 0x5d, + 0x33, 0x54, 0x46, 0x09, + 0x21, 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, + 0x82, 0x08, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xea, 0x01, 0xb2, 0x23, 0xd4, 0x0b, 0xf5, 0x03, 0xf5, 0x03, 0xf5, 0x03, + 0xf5, 0x03, 0xf5, 0x0b, + 0xd3, 0x1b, 0xce, 0x1a, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xea, 0x01, 0xb3, 0x1b, 0xf4, 0x0b, 0xf5, 0x03, 0x15, 0x04, 0x15, 0x04, + 0xf6, 0x03, 0xf5, 0x0b, + 0xb3, 0x1b, 0x4b, 0x0a, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x89, 0x01, 0xd3, 0x1b, 0xf5, 0x0b, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x15, 0x04, 0xf5, 0x0b, 0x72, 0x13, + 0xa9, 0x01, 0x43, 0x00, + 0x21, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x63, 0x00, + 0xa4, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, + 0xc5, 0x00, 0xc5, 0x00, + 0xc5, 0x00, 0xa3, 0x00, 0x42, 0x00, 0x20, 0x00, 0x2d, 0x02, 0xd4, 0x1b, + 0x15, 0x0c, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0xb8, 0x04, + 0x97, 0x04, 0x97, 0x0c, 0x75, 0x1c, 0x0f, 0x13, 0xa4, 0x00, 0x21, 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, 0x22, 0x00, 0x47, 0x01, + 0xb2, 0x33, 0xb6, 0x3c, + 0xd7, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x19, 0x2d, 0xf8, 0x2c, 0x18, 0x2d, + 0x19, 0x35, 0x19, 0x35, + 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, 0x19, 0x3d, 0xf8, 0x44, + 0xd6, 0x54, 0x0a, 0x12, + 0x22, 0x00, 0x21, 0x00, 0x21, 0x00, 0x0a, 0x1a, 0xb5, 0x4c, 0x38, 0x4d, + 0x38, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x59, 0x45, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x55, + 0x38, 0x5d, 0x53, 0x54, 0x88, 0x11, 0x21, 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, 0x62, 0x00, 0xc7, 0x31, 0xc3, 0x08, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x0a, 0x02, 0xd3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0xf5, 0x03, 0xd4, 0x13, 0xef, 0x1a, + 0x63, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x0b, 0x02, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x0a, + 0x63, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0x84, 0x00, 0xae, 0x1a, + 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd4, 0x1b, 0x4d, 0x02, 0x84, 0x00, 0x01, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, + 0x21, 0x00, 0x21, 0x00, + 0x01, 0x00, 0x21, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x4d, 0x02, 0xd4, 0x1b, 0x15, 0x0c, 0x36, 0x04, 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, + 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, 0x98, 0x04, 0x97, 0x0c, + 0x97, 0x14, 0x13, 0x24, + 0xa8, 0x01, 0x41, 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, 0x42, 0x00, 0x47, 0x01, 0xd2, 0x3b, 0xb6, 0x3c, 0xf7, 0x34, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, 0x18, 0x35, 0x18, 0x35, + 0x19, 0x35, 0x19, 0x3d, + 0x19, 0x3d, 0x18, 0x45, 0xf6, 0x54, 0x4b, 0x1a, 0x42, 0x00, 0x00, 0x00, + 0x01, 0x00, 0xa4, 0x00, + 0xb1, 0x43, 0xf7, 0x54, 0x38, 0x4d, 0x59, 0x45, 0x59, 0x45, 0x59, 0x45, + 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x55, 0x38, 0x5d, 0x95, 0x5c, 0x67, 0x09, + 0x42, 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, + 0x21, 0x00, 0x46, 0x19, + 0x6e, 0x5b, 0xc4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xea, 0x01, 0xd3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, + 0xd4, 0x13, 0xef, 0x1a, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xea, 0x01, 0xd3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, + 0xd3, 0x1b, 0x4c, 0x0a, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, 0x47, 0x01, 0x51, 0x1b, 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x13, 0x71, 0x23, 0xe6, 0x00, + 0x22, 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, 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, 0x4d, 0x02, 0xd4, 0x1b, + 0x15, 0x0c, 0x36, 0x04, + 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, 0xb8, 0x04, + 0xb8, 0x04, 0x97, 0x04, + 0xb8, 0x0c, 0xb8, 0x0c, 0x97, 0x14, 0x75, 0x24, 0xee, 0x1a, 0xc4, 0x00, + 0x21, 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, + 0x22, 0x00, 0xc5, 0x00, + 0x91, 0x33, 0xb6, 0x3c, 0xd7, 0x3c, 0xf8, 0x34, 0xf8, 0x34, 0x18, 0x35, + 0x18, 0x35, 0x39, 0x35, + 0x39, 0x3d, 0x19, 0x35, 0x39, 0x3d, 0x19, 0x3d, 0x39, 0x3d, 0x18, 0x45, + 0xf7, 0x54, 0xed, 0x2a, + 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x88, 0x09, 0xf6, 0x5c, + 0x18, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x45, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x55, + 0x38, 0x55, 0xf2, 0x43, + 0x67, 0x09, 0x21, 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, 0x42, 0x00, 0x8f, 0x53, 0xf1, 0x63, 0xe4, 0x08, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0xea, 0x01, 0xd3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x15, 0x04, 0xd4, 0x13, 0xcf, 0x12, + 0x83, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xea, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x0a, + 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, + 0x0b, 0x02, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0xf6, 0x03, + 0xf6, 0x0b, 0xd4, 0x1b, + 0x0b, 0x0a, 0x43, 0x00, 0x01, 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, 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, + 0x4d, 0x02, 0xd4, 0x1b, 0x16, 0x0c, 0x36, 0x04, 0x36, 0x04, 0x57, 0x04, + 0x36, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x98, 0x04, + 0x97, 0x04, 0x97, 0x04, 0xb7, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb7, 0x14, 0x96, 0x1c, + 0x14, 0x2c, 0xc9, 0x01, 0x42, 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, 0x01, 0x00, 0x41, 0x00, 0xe5, 0x00, 0xac, 0x22, + 0x54, 0x44, 0xd7, 0x44, + 0xf8, 0x3c, 0x18, 0x3d, 0x19, 0x3d, 0x19, 0x3d, 0x39, 0x3d, 0x39, 0x3d, + 0x19, 0x3d, 0x19, 0x3d, + 0x39, 0x3d, 0x18, 0x45, 0xf7, 0x54, 0x4f, 0x33, 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x90, 0x43, 0x17, 0x55, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x55, 0xb5, 0x54, 0xc9, 0x09, 0x22, 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, 0x21, 0x00, + 0x67, 0x09, 0x36, 0x7d, + 0x11, 0x5c, 0xe4, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xea, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, + 0xd4, 0x13, 0xef, 0x12, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xeb, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xb3, 0x13, 0x4c, 0x0a, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x00, 0x8d, 0x0a, 0xd4, 0x13, 0x15, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, + 0xf6, 0x03, 0x16, 0x04, 0xf5, 0x0b, 0x72, 0x1b, 0x06, 0x01, 0x21, 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, 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, 0x00, 0x4d, 0x02, 0xf4, 0x1b, + 0x16, 0x0c, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0xb8, 0x04, 0x98, 0x04, 0xb8, 0x04, 0xb7, 0x04, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb7, 0x14, 0xb8, 0x14, 0xb7, 0x1c, 0x96, 0x2c, 0xb1, 0x2b, + 0x83, 0x00, 0x21, 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, + 0x21, 0x00, 0x83, 0x00, 0xa8, 0x01, 0xf2, 0x3b, 0xd6, 0x4c, 0xf7, 0x4c, + 0xf8, 0x44, 0x18, 0x45, + 0x18, 0x3d, 0x18, 0x3d, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x38, 0x45, + 0x17, 0x55, 0xd1, 0x43, + 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x88, 0x11, + 0xb5, 0x54, 0x38, 0x55, + 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x79, 0x4d, 0x59, 0x4d, 0x58, 0x55, + 0x95, 0x54, 0x88, 0x09, + 0x21, 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, + 0x21, 0x00, 0x83, 0x00, 0xf1, 0x4b, 0x78, 0x75, 0x12, 0x5c, 0xe4, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0xeb, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x03, 0xd4, 0x13, 0xef, 0x12, + 0x63, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xeb, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x0a, + 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc5, 0x00, + 0x10, 0x13, 0xd4, 0x0b, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x15, 0x04, + 0xd4, 0x13, 0x8e, 0x0a, + 0x84, 0x00, 0x01, 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, 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, 0x00, + 0x4d, 0x02, 0xf4, 0x1b, 0x36, 0x0c, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, + 0xb8, 0x04, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, + 0xb8, 0x14, 0xb8, 0x1c, + 0xb7, 0x24, 0x76, 0x34, 0x4b, 0x12, 0x62, 0x00, 0x21, 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, 0x01, 0x00, + 0x41, 0x00, 0xa4, 0x00, + 0xe9, 0x11, 0xb1, 0x3b, 0x95, 0x4c, 0xf7, 0x4c, 0x17, 0x4d, 0x18, 0x45, + 0x38, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x38, 0x45, 0x17, 0x55, 0x12, 0x44, 0x83, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x00, 0x2f, 0x33, 0x37, 0x5d, 0x59, 0x55, 0x79, 0x4d, + 0x79, 0x4d, 0x79, 0x4d, + 0x79, 0x4d, 0x59, 0x55, 0x95, 0x54, 0x88, 0x09, 0x21, 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, 0x42, 0x00, 0x8c, 0x2a, + 0x57, 0x6d, 0x99, 0x75, + 0x32, 0x5c, 0xe5, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x22, 0x00, + 0xea, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, + 0xd4, 0x13, 0xef, 0x12, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xeb, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x1b, 0x4c, 0x0a, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x06, 0x01, 0x72, 0x1b, 0xf5, 0x0b, 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, 0xb3, 0x1b, 0xeb, 0x01, 0x42, 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, 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, 0x00, 0x00, 0x00, 0x4d, 0x02, 0xf4, 0x1b, + 0x36, 0x0c, 0x36, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x98, 0x04, 0xb7, 0x04, 0xb8, 0x0c, 0xb7, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x14, 0xb8, 0x14, + 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xb7, 0x2c, + 0x13, 0x34, 0x88, 0x01, + 0x42, 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, 0x01, 0x00, 0x41, 0x00, 0x83, 0x00, + 0x2a, 0x1a, 0x2f, 0x2b, + 0x13, 0x44, 0xf6, 0x54, 0x17, 0x55, 0x17, 0x55, 0x18, 0x4d, 0x17, 0x55, + 0x17, 0x5d, 0x12, 0x4c, + 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0x87, 0x09, 0x94, 0x54, + 0x58, 0x5d, 0x59, 0x55, 0x79, 0x4d, 0x7a, 0x55, 0x79, 0x4d, 0x59, 0x5d, + 0xb6, 0x5c, 0xa9, 0x11, + 0x21, 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, 0x21, 0x00, + 0x87, 0x09, 0xd5, 0x64, 0xb9, 0x6d, 0x99, 0x6d, 0x32, 0x54, 0xe5, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0xea, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x03, 0xd4, 0x13, 0xef, 0x12, + 0x63, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xeb, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x0a, + 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x47, 0x01, + 0xb3, 0x23, 0xf5, 0x0b, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, + 0x72, 0x1b, 0x68, 0x01, + 0x21, 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, 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, 0x00, 0x00, 0x00, + 0x4d, 0x02, 0xf4, 0x1b, 0x36, 0x0c, 0x57, 0x04, 0x57, 0x04, 0x57, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x98, 0x04, 0x98, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb7, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd7, 0x24, 0x96, 0x34, 0x70, 0x23, 0xe5, 0x00, 0x21, 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, 0x00, 0x00, 0x00, 0x41, 0x00, 0x83, 0x00, 0x25, 0x01, 0xc8, 0x11, + 0xac, 0x2a, 0x90, 0x43, + 0x33, 0x54, 0xb5, 0x64, 0xd5, 0x6c, 0x32, 0x64, 0x25, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x0e, 0x33, 0x58, 0x65, 0x79, 0x55, + 0x79, 0x55, 0x7a, 0x55, + 0x79, 0x55, 0x79, 0x5d, 0xf6, 0x5c, 0x0a, 0x1a, 0x21, 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, 0x21, 0x00, 0x63, 0x00, 0x33, 0x54, 0x99, 0x6d, + 0xba, 0x65, 0xb9, 0x6d, + 0x32, 0x5c, 0xe4, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xeb, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, + 0xd4, 0x13, 0xef, 0x12, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xea, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, + 0xd4, 0x1b, 0x4c, 0x0a, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x22, 0x00, 0xa9, 0x01, 0xd3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0xd4, 0x0b, 0x30, 0x1b, 0x06, 0x01, 0x21, 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, 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, 0x00, 0x00, 0x00, 0x4d, 0x02, 0x14, 0x1c, + 0x36, 0x0c, 0x57, 0x04, + 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, 0xb8, 0x04, 0x98, 0x04, + 0x98, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb7, 0x14, 0xd8, 0x14, 0xd8, 0x14, + 0xd8, 0x14, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xf8, 0x1c, 0xd8, 0x1c, 0xd8, 0x24, + 0xd7, 0x2c, 0x96, 0x3c, + 0xee, 0x2a, 0x83, 0x00, 0x21, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, 0x42, 0x00, 0x62, 0x00, 0xa3, 0x00, 0xa4, 0x00, + 0xa4, 0x00, 0x83, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0xc4, 0x00, + 0xf6, 0x5c, 0x58, 0x5d, 0x79, 0x55, 0x79, 0x55, 0x9a, 0x55, 0x79, 0x5d, + 0x17, 0x65, 0x2b, 0x1a, + 0x21, 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, 0x20, 0x00, + 0x83, 0x00, 0x2e, 0x3b, + 0x99, 0x75, 0xba, 0x65, 0xda, 0x65, 0xb9, 0x6d, 0x53, 0x5c, 0xe4, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xeb, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x03, 0xd4, 0x13, 0xef, 0x12, + 0x63, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xea, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd4, 0x1b, 0x4c, 0x0a, + 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xca, 0x09, + 0xd4, 0x1b, 0xf5, 0x0b, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf4, 0x13, + 0x10, 0x1b, 0xe5, 0x00, + 0x21, 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, 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, 0x00, 0x00, 0x00, + 0x6d, 0x02, 0x14, 0x1c, 0x36, 0x0c, 0x57, 0x04, 0x57, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x98, 0x04, + 0xb7, 0x04, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, + 0xb8, 0x14, 0xb8, 0x14, + 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xf8, 0x24, 0xf8, 0x24, 0xd8, 0x2c, 0xb7, 0x34, 0xb5, 0x44, 0x4b, 0x12, + 0x63, 0x00, 0x21, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x21, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x0e, 0x2b, 0x37, 0x65, + 0x79, 0x5d, 0x99, 0x55, + 0x79, 0x55, 0x79, 0x5d, 0xf7, 0x5c, 0x2b, 0x1a, 0x21, 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, 0x62, 0x00, 0x8c, 0x2a, 0x37, 0x6d, 0xb9, 0x6d, 0xda, 0x65, + 0xda, 0x65, 0xb9, 0x6d, + 0x53, 0x5c, 0xe4, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xeb, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, + 0xd4, 0x13, 0xef, 0x12, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xeb, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x1b, 0x4c, 0x0a, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xca, 0x09, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, + 0x16, 0x04, 0xf5, 0x13, 0x10, 0x1b, 0xc5, 0x00, 0x21, 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, 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, 0x00, 0x00, 0x00, 0x6d, 0x02, 0x14, 0x1c, + 0x36, 0x0c, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0xb8, 0x04, 0x98, 0x04, 0xb8, 0x04, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xd7, 0x34, 0x54, 0x3c, 0xe9, 0x09, 0x42, 0x00, 0x01, 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, 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, 0x21, 0x00, + 0x46, 0x01, 0x53, 0x54, 0x78, 0x65, 0x79, 0x55, 0x79, 0x55, 0x79, 0x5d, + 0x17, 0x5d, 0x2a, 0x1a, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xc8, 0x11, + 0x16, 0x6d, 0xb9, 0x6d, + 0xba, 0x65, 0xfb, 0x65, 0xda, 0x65, 0xba, 0x6d, 0x53, 0x5c, 0xe4, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xea, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x03, 0xd4, 0x13, 0xef, 0x12, + 0x63, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xeb, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x0a, + 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0x0f, 0x1b, 0x64, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0xca, 0x09, + 0xb3, 0x1b, 0xf5, 0x0b, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf4, 0x0b, + 0x10, 0x1b, 0xc5, 0x00, + 0x21, 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, 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, 0x00, 0x00, 0x00, + 0x6d, 0x02, 0x14, 0x1c, 0x56, 0x0c, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, 0xd8, 0x24, + 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x34, 0xd7, 0x3c, + 0x54, 0x44, 0xe9, 0x09, + 0x42, 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, 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, 0x42, 0x00, 0x8c, 0x2a, + 0x37, 0x65, 0x99, 0x5d, + 0x99, 0x5d, 0x99, 0x5d, 0x58, 0x65, 0xcd, 0x2a, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x42, 0x00, + 0x87, 0x09, 0x37, 0x6d, 0xb9, 0x6d, 0xda, 0x6d, 0xda, 0x65, 0xda, 0x65, + 0xda, 0x65, 0xb9, 0x6d, + 0x53, 0x5c, 0xe4, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xea, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd4, 0x13, 0xef, 0x12, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xeb, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x1b, 0x4c, 0x02, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xa9, 0x09, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x13, 0x10, 0x1b, 0xe6, 0x00, 0x21, 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, 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, 0x00, 0x00, 0x00, 0x6d, 0x02, 0x14, 0x1c, + 0x56, 0x0c, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, + 0x98, 0x04, 0xb7, 0x04, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x14, 0xd8, 0x14, + 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x24, 0xd8, 0x24, + 0xd8, 0x24, 0xf8, 0x24, 0xd8, 0x24, 0xf8, 0x2c, 0xf8, 0x24, 0xf8, 0x2c, + 0x18, 0x2d, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x34, 0xd7, 0x44, 0x74, 0x44, 0xa8, 0x09, 0x42, 0x00, + 0x01, 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, 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, 0x05, 0x01, 0x53, 0x54, 0x78, 0x65, 0x99, 0x5d, 0x99, 0x5d, + 0x79, 0x6d, 0xed, 0x2a, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xe8, 0x19, 0xd5, 0x64, 0xb9, 0x6d, + 0xda, 0x6d, 0xda, 0x65, + 0xda, 0x65, 0xfb, 0x65, 0xdb, 0x65, 0xda, 0x75, 0x53, 0x5c, 0xe4, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xea, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd4, 0x13, 0xef, 0x12, + 0x63, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xeb, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x13, 0x4c, 0x02, + 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x48, 0x01, + 0xb3, 0x1b, 0xf5, 0x0b, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x0b, + 0x51, 0x1b, 0x47, 0x01, + 0x22, 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, 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, 0x00, 0x00, 0x00, + 0x6d, 0x02, 0x14, 0x1c, 0x56, 0x0c, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, + 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x98, 0x04, + 0x97, 0x04, 0xb8, 0x04, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xd8, 0x14, + 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xf8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, 0x18, 0x35, 0x18, 0x35, + 0x18, 0x3d, 0xf7, 0x44, + 0x34, 0x44, 0x0a, 0x12, 0x63, 0x00, 0x21, 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, 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, 0x21, 0x00, + 0x4b, 0x22, 0x58, 0x6d, + 0x99, 0x5d, 0x99, 0x5d, 0x98, 0x6d, 0xed, 0x2a, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, + 0x4a, 0x22, 0xd5, 0x64, + 0xb9, 0x6d, 0xba, 0x6d, 0xda, 0x65, 0xfa, 0x65, 0xdb, 0x65, 0xdb, 0x65, + 0xfb, 0x65, 0xda, 0x75, + 0x53, 0x5c, 0xe4, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xeb, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd4, 0x13, 0xef, 0x12, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xea, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x13, 0x4c, 0x02, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x06, 0x01, 0x72, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, 0x93, 0x1b, 0xaa, 0x01, 0x42, 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, 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, 0x00, 0x00, 0x00, 0x6d, 0x02, 0x14, 0x1c, + 0x56, 0x0c, 0x77, 0x04, + 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, 0x98, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, + 0x18, 0x2d, 0x18, 0x35, + 0x18, 0x35, 0x18, 0x35, 0x18, 0x35, 0x18, 0x3d, 0xf7, 0x44, 0xb5, 0x4c, + 0x8c, 0x22, 0xa4, 0x00, + 0x21, 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, 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, 0x21, 0x00, 0x63, 0x00, 0x74, 0x5c, 0x79, 0x65, 0x99, 0x65, + 0x78, 0x6d, 0xed, 0x2a, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, + 0x83, 0x00, 0x6b, 0x2a, 0x78, 0x75, 0xba, 0x6d, 0xda, 0x6d, 0xda, 0x65, + 0xda, 0x65, 0xfb, 0x65, + 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xda, 0x75, 0x53, 0x5c, 0xe4, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xeb, 0x01, 0xd3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd4, 0x13, 0xef, 0x12, + 0x63, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xeb, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x13, 0x4c, 0x02, + 0x63, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc5, 0x00, + 0x0f, 0x13, 0xf4, 0x0b, + 0xf5, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x0b, + 0xd4, 0x13, 0x6d, 0x02, + 0x63, 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, 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, 0x00, 0x00, 0x00, + 0x6d, 0x02, 0x34, 0x1c, 0x76, 0x0c, 0x77, 0x04, 0x77, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x98, 0x04, 0x97, 0x04, 0x98, 0x04, + 0xb8, 0x04, 0x98, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, + 0xb8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x24, 0xd8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0x18, 0x2d, 0x18, 0x2d, 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, + 0x19, 0x3d, 0x19, 0x3d, + 0x18, 0x45, 0xf7, 0x4c, 0xf6, 0x54, 0x0e, 0x2b, 0x06, 0x01, 0x42, 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, 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, + 0x22, 0x00, 0x4a, 0x22, + 0x57, 0x6d, 0x99, 0x65, 0x99, 0x6d, 0x2f, 0x33, 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x25, 0x09, 0x6f, 0x43, 0x57, 0x6d, + 0xba, 0x6d, 0xda, 0x6d, + 0xda, 0x65, 0xdb, 0x65, 0xfa, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfa, 0x65, + 0xfb, 0x6d, 0xda, 0x75, + 0x53, 0x5c, 0xe5, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xea, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd4, 0x13, 0xcf, 0x1a, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xeb, 0x01, 0xd3, 0x1b, 0xf5, 0x0b, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x1b, 0x4c, 0x0a, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x00, 0x8e, 0x0a, 0xd4, 0x13, 0x15, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, 0xd5, 0x13, 0x30, 0x13, 0xe6, 0x00, 0x01, 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, 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, 0x00, 0x6d, 0x02, 0x35, 0x1c, + 0x76, 0x0c, 0x77, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x98, 0x04, 0xb8, 0x04, + 0xb8, 0x04, 0x98, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x14, + 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, 0x18, 0x2d, 0x18, 0x35, + 0x19, 0x35, 0x19, 0x35, + 0x19, 0x35, 0x19, 0x35, 0x19, 0x3d, 0x39, 0x3d, 0x19, 0x3d, 0x18, 0x45, + 0x18, 0x4d, 0xf6, 0x54, + 0xf2, 0x43, 0xa8, 0x09, 0x42, 0x00, 0x21, 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, 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, 0xc4, 0x00, 0xf2, 0x4b, 0x78, 0x6d, + 0x78, 0x6d, 0x70, 0x43, + 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, + 0x87, 0x11, 0x53, 0x5c, + 0x98, 0x6d, 0xda, 0x6d, 0xda, 0x65, 0xdb, 0x65, 0xda, 0x65, 0xfb, 0x65, + 0xfb, 0x65, 0xfb, 0x65, + 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x6d, 0xda, 0x75, 0x53, 0x5c, 0xe5, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xea, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd4, 0x13, 0xcf, 0x1a, + 0x63, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xeb, 0x01, 0xd3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x0a, + 0x63, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, + 0x0b, 0x02, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, + 0xf5, 0x0b, 0xb3, 0x1b, + 0xa9, 0x01, 0x42, 0x00, 0x01, 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, 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, + 0x6d, 0x02, 0x35, 0x1c, 0x76, 0x0c, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, + 0x97, 0x04, 0xb8, 0x04, 0xb8, 0x04, 0xb7, 0x04, 0xb7, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xf8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0x18, 0x35, 0x18, 0x35, + 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, 0x19, 0x3d, 0x19, 0x3d, 0x39, 0x3d, + 0x19, 0x3d, 0x19, 0x3d, + 0x39, 0x45, 0x39, 0x45, 0x38, 0x45, 0x18, 0x4d, 0x17, 0x55, 0xd6, 0x54, + 0xcd, 0x22, 0x06, 0x01, + 0x42, 0x00, 0x21, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, + 0x09, 0x1a, 0xf6, 0x6c, 0x78, 0x75, 0x90, 0x43, 0x83, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x22, 0x00, + 0x25, 0x01, 0x0e, 0x33, 0x37, 0x6d, 0xb9, 0x75, 0xd9, 0x6d, 0xda, 0x65, + 0xfa, 0x65, 0xfb, 0x65, + 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, + 0xfb, 0x6d, 0xfa, 0x75, + 0x53, 0x5c, 0xe5, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xea, 0x01, 0xb3, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, + 0xd4, 0x13, 0xef, 0x12, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0x0b, 0x02, 0xd4, 0x1b, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x1b, 0x4c, 0x0a, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, 0x48, 0x01, 0x51, 0x1b, 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x0b, 0x30, 0x1b, 0xa5, 0x00, + 0x21, 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, 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, 0x6d, 0x02, 0x35, 0x1c, + 0x76, 0x0c, 0x97, 0x04, + 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0x97, 0x04, 0xb8, 0x04, 0x97, 0x04, + 0xb7, 0x04, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb7, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, + 0xb8, 0x14, 0xd8, 0x14, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xf8, 0x1c, 0xf8, 0x1c, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x18, 0x2d, + 0x18, 0x2d, 0x18, 0x35, 0x18, 0x35, 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, + 0x19, 0x3d, 0x19, 0x3d, + 0x19, 0x3d, 0x19, 0x3d, 0x39, 0x3d, 0x19, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x4d, 0x18, 0x4d, 0x17, 0x5d, 0x33, 0x4c, 0x4b, 0x22, 0xa4, 0x00, + 0x21, 0x00, 0x21, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x83, 0x00, 0xd1, 0x53, + 0x78, 0x75, 0x90, 0x3b, + 0x83, 0x00, 0x21, 0x00, 0xa4, 0x00, 0x2a, 0x22, 0x74, 0x5c, 0xb9, 0x75, + 0xba, 0x6d, 0xda, 0x65, + 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, + 0xfb, 0x65, 0x1b, 0x66, + 0xfb, 0x6d, 0xfb, 0x6d, 0x1b, 0x6e, 0xfa, 0x75, 0x53, 0x5c, 0xe5, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xea, 0x01, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x03, 0xd4, 0x13, 0xef, 0x12, + 0x84, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x4d, 0x02, 0xd4, 0x13, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x0a, + 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0xa4, 0x00, 0xce, 0x1a, + 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xb3, 0x1b, 0x0b, 0x02, 0x63, 0x00, 0x01, 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, 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, + 0x6d, 0x02, 0x34, 0x1c, 0x76, 0x0c, 0x97, 0x04, 0x97, 0x04, 0x98, 0x04, + 0x98, 0x04, 0xb8, 0x04, + 0xb8, 0x04, 0xb7, 0x04, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb7, 0x0c, + 0xd8, 0x14, 0xb8, 0x14, + 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xf8, 0x1c, + 0xf8, 0x1c, 0xf8, 0x1c, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x35, 0x18, 0x35, 0x18, 0x35, + 0x19, 0x35, 0x19, 0x35, + 0x19, 0x3d, 0x19, 0x3d, 0x19, 0x3d, 0x19, 0x3d, 0x39, 0x3d, 0x39, 0x3d, + 0x39, 0x3d, 0x39, 0x3d, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x38, 0x4d, + 0x38, 0x55, 0x38, 0x55, + 0xd6, 0x5c, 0xb1, 0x3b, 0x0a, 0x12, 0x83, 0x00, 0x21, 0x00, 0x21, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x87, 0x11, 0x57, 0x7d, 0x90, 0x3b, 0xc5, 0x00, 0x2a, 0x1a, + 0x12, 0x54, 0x57, 0x6d, + 0xb9, 0x6d, 0xda, 0x6d, 0xda, 0x65, 0xfa, 0x65, 0xfa, 0x65, 0xfb, 0x65, + 0xfb, 0x65, 0xfb, 0x65, + 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x6d, 0xfb, 0x6d, 0xfb, 0x6d, 0x1b, 0x6e, + 0x1b, 0x6e, 0xfa, 0x75, + 0x53, 0x5c, 0xe5, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x00, + 0xca, 0x01, 0xb3, 0x23, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, + 0xf4, 0x0b, 0x10, 0x13, 0xc5, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x43, 0x00, + 0xcf, 0x0a, 0xf4, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x1b, 0x4c, 0x0a, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xc9, 0x09, 0xd4, 0x1b, 0xf5, 0x0b, + 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd5, 0x0b, 0x51, 0x13, + 0x68, 0x01, 0x42, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, + 0x22, 0x00, 0x42, 0x00, 0x42, 0x00, 0x22, 0x00, 0x21, 0x00, 0x22, 0x00, + 0x22, 0x00, 0x22, 0x00, + 0x42, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x02, 0x55, 0x1c, + 0x76, 0x0c, 0x97, 0x04, + 0x98, 0x04, 0x98, 0x04, 0xb8, 0x04, 0xb8, 0x04, 0xb8, 0x0c, 0xd8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xf8, 0x1c, 0xd8, 0x1c, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0x18, 0x2d, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, 0xf8, 0x2c, + 0x18, 0x35, 0x18, 0x35, + 0x18, 0x35, 0x19, 0x35, 0x39, 0x3d, 0x19, 0x3d, 0x19, 0x3d, 0x19, 0x3d, + 0x19, 0x3d, 0x39, 0x3d, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x59, 0x45, 0x59, 0x4d, 0x39, 0x4d, 0x59, 0x4d, 0x58, 0x55, 0x38, 0x5d, + 0x17, 0x65, 0x33, 0x54, + 0x4b, 0x22, 0x05, 0x01, 0x83, 0x00, 0x21, 0x00, 0x21, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, + 0xb0, 0x4b, 0xf6, 0x64, + 0xd5, 0x5c, 0x98, 0x75, 0xb9, 0x6d, 0xda, 0x6d, 0xda, 0x65, 0xfa, 0x65, + 0xfb, 0x65, 0xfb, 0x65, + 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0x1b, 0x6e, 0x1b, 0x66, + 0xfb, 0x65, 0xfb, 0x6d, + 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0xfa, 0x75, 0x53, 0x5c, 0xe5, 0x00, + 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x68, 0x01, 0xb3, 0x23, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0x51, 0x13, + 0x26, 0x01, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x64, 0x00, 0x72, 0x1b, 0xf5, 0x0b, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x0a, + 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x84, 0x00, + 0x72, 0x23, 0xf5, 0x13, 0xf5, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0xd4, 0x13, 0x10, 0x1b, 0x27, 0x01, 0x42, 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, 0x00, + 0x00, 0x00, 0x21, 0x00, 0x83, 0x00, 0x67, 0x01, 0x89, 0x01, 0xa9, 0x01, + 0xa9, 0x01, 0xa9, 0x01, + 0xa9, 0x01, 0xa9, 0x01, 0xa9, 0x01, 0x89, 0x01, 0x88, 0x09, 0x26, 0x09, + 0x42, 0x00, 0x00, 0x00, + 0x8d, 0x02, 0x35, 0x1c, 0x76, 0x0c, 0xb8, 0x04, 0xb8, 0x04, 0xb8, 0x04, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, 0xb8, 0x14, + 0xd8, 0x14, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, 0x19, 0x35, 0x19, 0x3d, + 0x19, 0x3d, 0x19, 0x3d, + 0x19, 0x3d, 0x39, 0x3d, 0x19, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x59, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x59, 0x45, 0x59, 0x45, 0x59, 0x45, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x55, 0x59, 0x55, 0x58, 0x55, 0x58, 0x5d, 0x37, 0x65, 0x94, 0x54, + 0x4f, 0x3b, 0x0a, 0x1a, + 0x25, 0x01, 0x62, 0x00, 0x21, 0x00, 0x21, 0x00, 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, 0x00, + 0x00, 0x00, 0x21, 0x00, 0xc9, 0x11, 0x37, 0x6d, 0xb9, 0x6d, 0xda, 0x6d, + 0xda, 0x6d, 0xfa, 0x65, + 0xfa, 0x65, 0xfa, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x6d, + 0xfb, 0x6d, 0xfb, 0x6d, + 0x1b, 0x66, 0x1b, 0x66, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0xfa, 0x75, + 0x73, 0x5c, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x22, 0x00, + 0x68, 0x01, 0x92, 0x23, 0xd5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf5, 0x03, 0x92, 0x13, 0xa9, 0x01, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x06, 0x01, + 0xb3, 0x1b, 0xf5, 0x0b, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x1b, 0x4c, 0x0a, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x2b, 0x02, 0xb3, 0x1b, + 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x0b, + 0xd4, 0x13, 0xef, 0x12, + 0xc5, 0x00, 0x42, 0x00, 0x01, 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, 0x21, 0x00, 0xa5, 0x00, + 0x4c, 0x0a, 0x72, 0x1b, + 0xd3, 0x1b, 0xd4, 0x13, 0xd3, 0x13, 0xd3, 0x13, 0xd4, 0x13, 0xd4, 0x1b, + 0xd4, 0x1b, 0xb3, 0x23, + 0x91, 0x2b, 0x4c, 0x1a, 0x62, 0x00, 0x00, 0x00, 0x8d, 0x02, 0x55, 0x24, + 0x76, 0x0c, 0xb7, 0x04, + 0xb8, 0x0c, 0xb7, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, 0xd8, 0x14, + 0xb8, 0x14, 0xd8, 0x14, + 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xf8, 0x1c, + 0xf8, 0x1c, 0xd8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x18, 0x2d, 0x18, 0x35, 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, + 0x19, 0x35, 0x19, 0x35, + 0x19, 0x3d, 0x19, 0x3d, 0x19, 0x3d, 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x59, 0x45, 0x59, 0x45, + 0x59, 0x4d, 0x59, 0x45, + 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x79, 0x4d, 0x79, 0x55, + 0x79, 0x4d, 0x79, 0x55, + 0x59, 0x55, 0x38, 0x5d, 0x58, 0x65, 0xf6, 0x64, 0x53, 0x54, 0xd1, 0x4b, + 0x6b, 0x2a, 0x67, 0x09, + 0xa3, 0x00, 0x62, 0x00, 0x42, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, + 0x21, 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, 0x21, 0x00, + 0x88, 0x11, 0x37, 0x75, + 0xba, 0x6d, 0xfb, 0x65, 0xda, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, + 0xfb, 0x65, 0xfb, 0x65, + 0xfb, 0x65, 0xfb, 0x6d, 0xfb, 0x6d, 0xfb, 0x6d, 0x1b, 0x66, 0x1b, 0x66, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0xfa, 0x75, 0x73, 0x5c, 0xe4, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x47, 0x01, 0x92, 0x23, + 0xf4, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0xd4, 0x13, + 0x6d, 0x0a, 0x84, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x63, 0x00, 0x2c, 0x0a, 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x03, 0xd3, 0x1b, 0x4c, 0x0a, + 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, + 0x06, 0x01, 0x0f, 0x1b, 0xd4, 0x13, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd4, 0x13, 0xce, 0x12, 0x27, 0x01, + 0x43, 0x00, 0x21, 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, + 0x21, 0x00, 0x42, 0x00, + 0xa5, 0x00, 0x8d, 0x12, 0x92, 0x1b, 0xd4, 0x13, 0xf5, 0x0b, 0x15, 0x04, + 0x15, 0x04, 0xf5, 0x03, + 0xf6, 0x03, 0x15, 0x04, 0xf5, 0x0b, 0xd4, 0x13, 0xb2, 0x2b, 0x47, 0x01, + 0x21, 0x00, 0x00, 0x00, + 0x8e, 0x02, 0x55, 0x24, 0x76, 0x14, 0xb7, 0x0c, 0xb8, 0x0c, 0xb8, 0x0c, + 0xb8, 0x0c, 0xb8, 0x0c, + 0xd8, 0x14, 0xd8, 0x14, 0xb8, 0x14, 0xd8, 0x1c, 0xb8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x34, + 0x18, 0x35, 0x18, 0x35, + 0x19, 0x35, 0x19, 0x35, 0x19, 0x35, 0x19, 0x3d, 0x19, 0x3d, 0x39, 0x3d, + 0x39, 0x3d, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x59, 0x45, + 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, + 0x79, 0x4d, 0x79, 0x4d, 0x79, 0x55, 0x79, 0x55, 0x79, 0x55, 0x79, 0x55, + 0x79, 0x5d, 0x79, 0x5d, + 0x78, 0x5d, 0x78, 0x65, 0x58, 0x65, 0x37, 0x6d, 0x37, 0x6d, 0x94, 0x5c, + 0xb1, 0x43, 0x4f, 0x3b, + 0x8c, 0x22, 0x6b, 0x22, 0x2a, 0x22, 0x83, 0x00, 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, 0x01, 0x00, 0xa8, 0x11, 0xb9, 0x7d, 0xda, 0x6d, 0xda, 0x65, + 0xfb, 0x65, 0xfb, 0x65, + 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x6d, 0x1b, 0x6e, 0xfb, 0x6d, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1a, 0x76, + 0x73, 0x5c, 0xe4, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, + 0x06, 0x01, 0x30, 0x1b, 0xf4, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, 0x92, 0x1b, 0xaa, 0x01, 0x43, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, + 0x48, 0x01, 0x51, 0x1b, + 0xd5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x1b, 0x4c, 0x0a, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x22, 0x00, 0x89, 0x01, + 0x92, 0x1b, 0xf5, 0x0b, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0xf5, 0x0b, + 0xd4, 0x13, 0x51, 0x1b, 0xca, 0x01, 0xa4, 0x00, 0x42, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x22, 0x00, 0x84, 0x00, 0x68, 0x01, 0x10, 0x13, 0xb3, 0x13, + 0xd5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0xf5, 0x0b, 0xd3, 0x1b, + 0x6c, 0x12, 0x62, 0x00, 0x21, 0x00, 0x00, 0x00, 0x6d, 0x02, 0x55, 0x24, + 0x97, 0x14, 0xb7, 0x0c, + 0xb8, 0x0c, 0xb8, 0x14, 0xb7, 0x14, 0xd8, 0x14, 0xd8, 0x14, 0xd8, 0x14, + 0xd8, 0x14, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x18, 0x35, + 0xf8, 0x34, 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, 0x19, 0x3d, 0x19, 0x3d, + 0x19, 0x3d, 0x19, 0x3d, + 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x59, 0x45, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, + 0x79, 0x4d, 0x79, 0x4d, 0x59, 0x4d, 0x79, 0x4d, 0x7a, 0x55, 0x7a, 0x55, + 0x79, 0x55, 0x79, 0x55, + 0x79, 0x55, 0x7a, 0x55, 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x55, 0x99, 0x55, + 0x99, 0x5d, 0x99, 0x5d, + 0x79, 0x65, 0x79, 0x65, 0x79, 0x65, 0x79, 0x65, 0x99, 0x6d, 0x78, 0x75, + 0x57, 0x7d, 0x8b, 0x2a, + 0x41, 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, 0x21, 0x00, + 0xa8, 0x11, 0x98, 0x7d, + 0xda, 0x6d, 0xfa, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0x65, + 0x1b, 0x66, 0x1b, 0x66, + 0xfb, 0x65, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, 0x3b, 0x6e, 0x1a, 0x76, 0x73, 0x5c, 0xe4, 0x00, + 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0xa5, 0x00, 0xce, 0x12, + 0xf4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x03, + 0xd4, 0x13, 0x31, 0x13, + 0x27, 0x01, 0x43, 0x00, 0x22, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x21, 0x00, + 0x42, 0x00, 0x06, 0x01, 0xef, 0x12, 0xd4, 0x13, 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x0a, + 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x84, 0x00, 0x4d, 0x0a, 0xb4, 0x1b, 0xf5, 0x0b, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0x15, 0x04, 0xd4, 0x13, + 0xb3, 0x1b, 0x8d, 0x0a, + 0x68, 0x01, 0x84, 0x00, 0x42, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x42, 0x00, 0x63, 0x00, 0x27, 0x01, + 0x6d, 0x12, 0x72, 0x1b, + 0xd4, 0x13, 0xf5, 0x0b, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, 0xd4, 0x13, 0x30, 0x13, 0x06, 0x01, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x6d, 0x02, 0x55, 0x2c, 0x97, 0x1c, 0xb8, 0x14, 0xb7, 0x14, 0xb8, 0x14, + 0xb8, 0x14, 0xd8, 0x14, + 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xf8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x18, 0x2d, 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, + 0x19, 0x3d, 0x18, 0x3d, + 0x19, 0x3d, 0x39, 0x3d, 0x39, 0x3d, 0x38, 0x3d, 0x39, 0x3d, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x59, 0x45, 0x59, 0x45, 0x59, 0x45, + 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x79, 0x4d, 0x79, 0x4d, 0x79, 0x4d, + 0x79, 0x55, 0x79, 0x55, + 0x79, 0x55, 0x7a, 0x55, 0x79, 0x55, 0x9a, 0x55, 0x79, 0x55, 0x7a, 0x55, + 0x9a, 0x55, 0x9a, 0x55, + 0x9a, 0x55, 0x9a, 0x55, 0xba, 0x5d, 0x9a, 0x5d, 0xba, 0x5d, 0x9a, 0x5d, + 0x9a, 0x5d, 0x9a, 0x65, + 0x9a, 0x5d, 0x9a, 0x65, 0x99, 0x6d, 0x74, 0x5c, 0xe5, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, 0xa8, 0x11, 0x99, 0x7d, 0xda, 0x6d, 0xfb, 0x65, + 0xfb, 0x65, 0xfb, 0x6d, + 0x1b, 0x66, 0xfa, 0x65, 0xfb, 0x6d, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x3b, 0x6e, 0x1b, 0x6e, + 0x3b, 0x6e, 0x1a, 0x7e, + 0x73, 0x5c, 0xe4, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0xf5, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x0b, 0xd4, 0x13, 0x30, 0x13, 0x0b, 0x02, + 0xc5, 0x00, 0x63, 0x00, + 0x42, 0x00, 0x42, 0x00, 0x63, 0x00, 0x84, 0x00, 0x68, 0x01, 0x10, 0x13, + 0xd4, 0x13, 0xf5, 0x0b, + 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x1b, 0x4c, 0x0a, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0xc5, 0x00, 0x30, 0x23, + 0xd4, 0x13, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x03, 0xf5, 0x0b, 0xd4, 0x13, 0x72, 0x13, 0xcf, 0x12, + 0xca, 0x01, 0x07, 0x01, + 0x84, 0x00, 0x84, 0x00, 0x63, 0x00, 0x63, 0x00, 0x64, 0x00, 0x84, 0x00, + 0x06, 0x01, 0xea, 0x01, + 0xae, 0x0a, 0x51, 0x13, 0xd4, 0x13, 0xf4, 0x0b, 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf4, 0x0b, + 0x71, 0x1b, 0xa9, 0x01, + 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x02, 0x55, 0x2c, + 0x97, 0x1c, 0xb7, 0x14, + 0xb7, 0x14, 0xd8, 0x14, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xf8, 0x1c, + 0xf8, 0x1c, 0xf8, 0x1c, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, 0x18, 0x35, 0x19, 0x35, + 0x19, 0x35, 0x19, 0x35, + 0x19, 0x35, 0x19, 0x3d, 0x19, 0x3d, 0x19, 0x3d, 0x39, 0x3d, 0x39, 0x3d, + 0x39, 0x3d, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x59, 0x45, + 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, + 0x79, 0x4d, 0x79, 0x4d, + 0x79, 0x4d, 0x79, 0x55, 0x79, 0x55, 0x79, 0x55, 0x7a, 0x55, 0x7a, 0x55, + 0x79, 0x55, 0x99, 0x55, + 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x5d, 0x9a, 0x5d, + 0x9a, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x65, + 0xb9, 0x65, 0x78, 0x6d, + 0x0e, 0x3b, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0xa8, 0x11, 0x98, 0x7d, + 0xda, 0x6d, 0xfb, 0x65, 0xfb, 0x6d, 0xfb, 0x6d, 0x1b, 0x66, 0xfa, 0x65, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x1a, 0x7e, 0x73, 0x5c, 0xe4, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x47, 0x01, + 0x72, 0x13, 0xf5, 0x0b, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd4, 0x13, 0xd3, 0x1b, 0x51, 0x23, 0x8d, 0x12, 0x0b, 0x0a, 0xea, 0x01, + 0x6c, 0x12, 0x0f, 0x1b, + 0xb3, 0x1b, 0xd4, 0x13, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x02, + 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x27, 0x01, 0x10, 0x1b, 0xd4, 0x13, + 0x15, 0x0c, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf5, 0x0b, 0xd4, 0x13, 0xb3, 0x1b, 0x92, 0x23, 0x50, 0x23, 0xef, 0x1a, + 0xae, 0x12, 0xce, 0x1a, + 0xef, 0x1a, 0x50, 0x23, 0x92, 0x23, 0xb3, 0x1b, 0xd4, 0x13, 0xf5, 0x0b, + 0xf5, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf5, 0x0b, 0xb2, 0x1b, 0x0b, 0x0a, 0x63, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xca, 0x01, 0x54, 0x34, 0x96, 0x24, 0xd7, 0x14, 0xd8, 0x14, 0xd8, 0x1c, + 0xd8, 0x1c, 0xf8, 0x1c, + 0xf8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xf8, 0x1c, 0xd8, 0x24, 0xf8, 0x24, + 0xf9, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x19, 0x35, + 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, 0x19, 0x3d, 0x19, 0x3d, 0x19, 0x3d, + 0x19, 0x3d, 0x19, 0x3d, + 0x39, 0x3d, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x79, 0x4d, + 0x7a, 0x4d, 0x59, 0x4d, 0x79, 0x4d, 0x79, 0x4d, 0x79, 0x55, 0x79, 0x55, + 0x79, 0x55, 0x7a, 0x55, + 0x7a, 0x55, 0x9a, 0x55, 0x99, 0x55, 0x9a, 0x55, 0x9a, 0x55, 0x99, 0x55, + 0x9a, 0x5d, 0x9a, 0x5d, + 0x9a, 0x5d, 0x9a, 0x5d, 0x9a, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x65, 0xba, 0x5d, 0x99, 0x6d, 0xb5, 0x64, 0x47, 0x09, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, 0xa8, 0x11, 0xb9, 0x7d, 0xda, 0x6d, 0xfb, 0x6d, + 0xfb, 0x6d, 0xfb, 0x6d, + 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, + 0x3b, 0x6e, 0x1a, 0x7e, + 0xd0, 0x53, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x83, 0x00, 0xae, 0x12, 0xb4, 0x13, 0xf5, 0x0b, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, + 0xf5, 0x13, 0xd4, 0x13, + 0xd4, 0x13, 0xd4, 0x13, 0xd4, 0x13, 0xf4, 0x13, 0xf5, 0x0b, 0x15, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x13, 0x4c, 0x02, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x0a, 0xd4, 0x13, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x42, 0x00, + 0x68, 0x01, 0x51, 0x1b, 0xd4, 0x13, 0xf5, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x03, + 0xf5, 0x0b, 0xf5, 0x0b, + 0xd4, 0x13, 0xd4, 0x13, 0xd4, 0x13, 0xd4, 0x13, 0xd4, 0x13, 0xd4, 0x13, + 0xd5, 0x0b, 0xf5, 0x0b, + 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x0b, 0x92, 0x1b, 0x4c, 0x0a, + 0x63, 0x00, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x01, 0xd2, 0x33, + 0x96, 0x24, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, 0xf8, 0x1c, 0xd8, 0x24, + 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf9, 0x2c, 0xf9, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0x18, 0x2d, 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, 0x19, 0x35, + 0x19, 0x3d, 0x39, 0x3d, + 0x19, 0x3d, 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x59, 0x45, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x79, 0x4d, 0x79, 0x4d, 0x79, 0x4d, + 0x79, 0x55, 0x79, 0x55, + 0x79, 0x55, 0x7a, 0x55, 0x9a, 0x55, 0x7a, 0x55, 0x9a, 0x55, 0x9a, 0x55, + 0x9a, 0x55, 0x9a, 0x55, + 0x9a, 0x55, 0xba, 0x5d, 0x9a, 0x5d, 0x9a, 0x5d, 0xba, 0x5d, 0xba, 0x5d, + 0x9a, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x65, 0xba, 0x5d, + 0xda, 0x65, 0xba, 0x65, + 0x98, 0x75, 0x0e, 0x33, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0x0a, 0x1a, 0xb9, 0x7d, + 0xfa, 0x75, 0xfb, 0x6d, 0xfb, 0x6d, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x76, 0xf9, 0x7d, 0x0d, 0x3b, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, + 0x47, 0x01, 0x92, 0x23, + 0xf4, 0x13, 0x15, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, + 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x02, + 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x0a, + 0xd4, 0x13, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xd4, 0x13, + 0xef, 0x1a, 0x64, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x63, 0x00, 0x68, 0x01, + 0x71, 0x1b, 0xf4, 0x13, + 0xf5, 0x0b, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, + 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x15, 0x04, + 0xf4, 0x0b, 0x93, 0x1b, + 0x4c, 0x0a, 0xa4, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xc5, 0x00, 0xee, 0x22, 0x96, 0x2c, 0xd7, 0x1c, 0xd8, 0x1c, 0xd8, 0x1c, + 0xd8, 0x1c, 0xd8, 0x24, + 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, 0x18, 0x35, 0x18, 0x35, 0x18, 0x35, + 0x19, 0x35, 0x19, 0x35, + 0x19, 0x35, 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x3d, 0x19, 0x3d, 0x39, 0x3d, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x59, 0x45, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x79, 0x4d, + 0x79, 0x4d, 0x79, 0x55, + 0x79, 0x4d, 0x79, 0x4d, 0x7a, 0x55, 0x7a, 0x55, 0x7a, 0x55, 0x9a, 0x55, + 0x9a, 0x55, 0x9a, 0x55, + 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x5d, 0x9a, 0x55, 0x9a, 0x5d, 0x9a, 0x5d, + 0x9a, 0x5d, 0x9a, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x65, + 0xba, 0x5d, 0xda, 0x5d, 0xda, 0x65, 0xda, 0x65, 0xb9, 0x6d, 0x57, 0x75, + 0x26, 0x09, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, 0xac, 0x2a, 0xd9, 0x7d, 0xfa, 0x6d, 0xfb, 0x6d, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x3b, 0x6e, + 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, + 0x1b, 0x76, 0x77, 0x75, + 0xc8, 0x19, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0xca, 0x09, 0x92, 0x1b, 0xd4, 0x0b, + 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x1b, 0x4c, 0x0a, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x42, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, + 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x0b, 0xef, 0x1a, 0x63, 0x00, 0x01, 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, 0x42, 0x00, 0x27, 0x01, 0xcf, 0x1a, 0xb3, 0x1b, 0xf5, 0x0b, + 0xf5, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0xf5, 0x0b, 0xd4, 0x13, 0x71, 0x1b, 0xca, 0x01, 0x84, 0x00, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0xe9, 0x09, + 0x34, 0x34, 0xb7, 0x24, + 0xd8, 0x24, 0xd8, 0x1c, 0xd8, 0x24, 0xd8, 0x24, 0xf8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, 0x18, 0x35, + 0x18, 0x35, 0x18, 0x35, + 0x18, 0x35, 0x19, 0x35, 0x18, 0x35, 0x19, 0x3d, 0x39, 0x3d, 0x19, 0x3d, + 0x39, 0x3d, 0x39, 0x3d, + 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x45, 0x39, 0x45, 0x59, 0x45, 0x59, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x59, 0x45, 0x59, 0x45, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, + 0x79, 0x4d, 0x59, 0x4d, + 0x79, 0x4d, 0x79, 0x4d, 0x79, 0x4d, 0x79, 0x55, 0x79, 0x4d, 0x79, 0x55, + 0x7a, 0x55, 0x7a, 0x55, + 0x7a, 0x55, 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x55, + 0x9a, 0x55, 0x9a, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0x9a, 0x5d, 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xda, 0x65, 0xda, 0x5d, 0xda, 0x65, + 0xda, 0x65, 0xda, 0x65, + 0xda, 0x65, 0xb9, 0x75, 0x90, 0x4b, 0x63, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0xac, 0x22, 0xd9, 0x7d, + 0xfa, 0x6d, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, + 0x3b, 0x6e, 0x3b, 0x6e, + 0x3b, 0x6e, 0x3b, 0x76, 0x1a, 0x7e, 0x32, 0x54, 0x83, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x84, 0x00, + 0x2c, 0x0a, 0x92, 0x1b, 0xf5, 0x13, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xb4, 0x0b, 0xb4, 0x0b, + 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd3, 0x1b, 0x4c, 0x0a, + 0x63, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xd4, 0x13, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf4, 0x13, + 0xef, 0x1a, 0x63, 0x00, + 0x01, 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, 0x20, 0x00, + 0x22, 0x00, 0xe6, 0x00, + 0x4c, 0x0a, 0xb3, 0x1b, 0xd4, 0x13, 0xf5, 0x0b, 0xf5, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0xf6, 0x03, 0xf6, 0x03, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf6, 0x03, 0xf5, 0x0b, 0xd4, 0x13, 0xd3, 0x1b, 0x0f, 0x13, + 0x88, 0x01, 0x43, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0xa4, 0x00, 0x70, 0x2b, 0x96, 0x34, 0xb7, 0x24, 0xd8, 0x24, + 0xd8, 0x24, 0xf8, 0x24, + 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x24, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x18, 0x35, + 0x18, 0x35, 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, 0x19, 0x3d, + 0x19, 0x3d, 0x19, 0x3d, + 0x19, 0x3d, 0x38, 0x3d, 0x39, 0x3d, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x79, 0x4d, 0x79, 0x4d, 0x79, 0x4d, 0x79, 0x55, 0x79, 0x55, + 0x79, 0x55, 0x79, 0x55, + 0x7a, 0x55, 0x7a, 0x55, 0x7a, 0x55, 0x7a, 0x55, 0x7a, 0x55, 0x9a, 0x55, + 0x9a, 0x55, 0x9a, 0x55, + 0x9a, 0x5d, 0x9a, 0x55, 0x9a, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xda, 0x5d, 0xdb, 0x5d, + 0xda, 0x65, 0xda, 0x65, + 0xda, 0x65, 0xda, 0x65, 0xdb, 0x65, 0xdb, 0x65, 0xda, 0x65, 0xda, 0x6d, + 0xf6, 0x64, 0xa8, 0x09, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, 0xac, 0x2a, 0xd9, 0x7d, 0xfa, 0x6d, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, 0x3b, 0x6e, 0x1b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, + 0x3b, 0x6e, 0x3b, 0x6e, + 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3c, 0x6e, 0x3b, 0x76, 0x3b, 0x7e, + 0xfa, 0x85, 0xa8, 0x11, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0xa4, 0x00, 0x2b, 0x12, + 0xb3, 0x23, 0xd4, 0x13, + 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0xf5, 0x0b, 0xd4, 0x13, + 0x8e, 0x02, 0xcf, 0x02, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xf5, 0x0b, + 0xd3, 0x1b, 0x4c, 0x0a, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x43, 0x00, 0x2b, 0x12, 0xd4, 0x13, 0xf5, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0xd4, 0x13, 0xef, 0x1a, 0x63, 0x00, 0x01, 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, 0x01, 0x00, 0x22, 0x00, 0x84, 0x00, 0xc9, 0x01, + 0x30, 0x1b, 0xb3, 0x1b, + 0xd4, 0x13, 0xf5, 0x0b, 0x16, 0x04, 0x16, 0x04, 0xf6, 0x03, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0xf5, 0x0b, 0xd5, 0x0b, + 0xd4, 0x1b, 0x92, 0x23, + 0x2b, 0x0a, 0xe6, 0x00, 0x42, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, + 0x06, 0x01, 0x13, 0x3c, + 0x96, 0x34, 0xd8, 0x2c, 0xf8, 0x2c, 0xf8, 0x24, 0x18, 0x2d, 0xf8, 0x2c, + 0xf8, 0x2c, 0xf8, 0x2c, + 0x18, 0x2d, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, + 0x19, 0x35, 0x19, 0x35, + 0x19, 0x3d, 0x19, 0x3d, 0x19, 0x3d, 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x3d, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x59, 0x45, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x79, 0x4d, 0x79, 0x4d, 0x79, 0x4d, + 0x79, 0x4d, 0x79, 0x4d, + 0x7a, 0x55, 0x7a, 0x55, 0x79, 0x55, 0x7a, 0x55, 0x7a, 0x55, 0x9a, 0x55, + 0x9a, 0x55, 0x9a, 0x55, + 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x5d, 0x9a, 0x5d, 0x9a, 0x5d, 0x9a, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, + 0xdb, 0x5d, 0xda, 0x5d, 0xda, 0x65, 0xda, 0x65, 0xda, 0x65, 0xda, 0x65, + 0xdb, 0x65, 0xdb, 0x65, + 0xda, 0x65, 0xda, 0x6d, 0xd9, 0x75, 0xd0, 0x43, 0xa3, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0xac, 0x2a, 0xf9, 0x7d, + 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x3c, 0x6e, + 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3c, 0x6e, 0x3c, 0x6e, + 0x3c, 0x76, 0x3b, 0x76, + 0x1b, 0x76, 0xd9, 0x7d, 0x4e, 0x43, 0x41, 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, 0x63, 0x00, 0x89, 0x01, 0x10, 0x1b, 0xb3, 0x13, 0xd4, 0x13, + 0xf5, 0x0b, 0xf5, 0x0b, + 0xf5, 0x03, 0x16, 0x04, 0xf6, 0x03, 0xf6, 0x03, 0xf5, 0x03, 0x16, 0x04, + 0x15, 0x04, 0x15, 0x04, + 0xf5, 0x0b, 0xf4, 0x13, 0x93, 0x1b, 0xae, 0x0a, 0xe7, 0x00, 0x6d, 0x0a, + 0xb3, 0x1b, 0xf4, 0x0b, + 0xf4, 0x0b, 0xf5, 0x0b, 0xf5, 0x0b, 0xd4, 0x13, 0xb2, 0x23, 0x2b, 0x0a, + 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x2b, 0x12, + 0xb3, 0x23, 0xf4, 0x13, + 0xf5, 0x13, 0xf5, 0x0b, 0xf5, 0x0b, 0xf5, 0x0b, 0xf5, 0x13, 0xd3, 0x1b, + 0xee, 0x22, 0x63, 0x00, + 0x01, 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, + 0x21, 0x00, 0x42, 0x00, 0xc5, 0x00, 0x0b, 0x02, 0x30, 0x13, 0xb3, 0x13, + 0xd4, 0x13, 0xf5, 0x0b, + 0xf5, 0x0b, 0x16, 0x0c, 0xf6, 0x03, 0xf6, 0x03, 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, + 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x15, 0x04, 0x15, 0x04, 0xf5, 0x0b, + 0xf5, 0x0b, 0xd4, 0x13, + 0xb3, 0x13, 0x51, 0x13, 0x6d, 0x0a, 0x27, 0x01, 0x43, 0x00, 0x21, 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, 0x42, 0x00, 0xa8, 0x09, 0x13, 0x3c, 0xb7, 0x3c, + 0xd8, 0x2c, 0xf8, 0x2c, + 0xf8, 0x2c, 0x18, 0x2d, 0xf8, 0x2c, 0xf8, 0x2c, 0xf8, 0x2c, 0x18, 0x2d, + 0x18, 0x35, 0x18, 0x35, + 0x18, 0x35, 0x19, 0x35, 0x19, 0x3d, 0x39, 0x3d, 0x39, 0x3d, 0x39, 0x3d, + 0x19, 0x3d, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x59, 0x45, + 0x59, 0x45, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, + 0x79, 0x4d, 0x79, 0x4d, 0x79, 0x55, 0x79, 0x55, 0x79, 0x55, 0x79, 0x55, + 0x79, 0x55, 0x9a, 0x55, + 0x79, 0x55, 0x99, 0x55, 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x5d, + 0x9a, 0x5d, 0x9a, 0x5d, + 0xba, 0x5d, 0x9a, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x65, 0xba, 0x5d, 0xda, 0x5d, 0xda, 0x5d, 0xda, 0x5d, + 0xda, 0x65, 0xda, 0x65, + 0xda, 0x65, 0xda, 0x65, 0xdb, 0x65, 0xfb, 0x65, 0xda, 0x65, 0xfa, 0x65, + 0xda, 0x6d, 0x77, 0x75, + 0xe9, 0x19, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x41, 0x00, 0xac, 0x2a, 0xda, 0x7d, 0x1b, 0x6e, 0x1b, 0x6e, + 0x1b, 0x6e, 0x1b, 0x6e, + 0x3b, 0x6e, 0x3b, 0x6e, 0x1b, 0x6e, 0x3c, 0x6e, 0x3b, 0x6e, 0x3c, 0x6e, + 0x3c, 0x6e, 0x3c, 0x6e, + 0x3c, 0x6e, 0x3c, 0x6e, 0x3b, 0x76, 0x3b, 0x7e, 0xd9, 0x7d, 0xd0, 0x4b, + 0xc4, 0x00, 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, + 0x42, 0x00, 0xe6, 0x00, + 0x2b, 0x0a, 0x30, 0x1b, 0xb3, 0x1b, 0xd4, 0x13, 0xf5, 0x13, 0xf5, 0x0b, + 0xf5, 0x0b, 0xf5, 0x0b, + 0xf5, 0x0b, 0xf5, 0x0b, 0xf5, 0x0b, 0xf4, 0x13, 0xd3, 0x1b, 0x30, 0x1b, + 0xea, 0x09, 0xa5, 0x00, + 0x84, 0x00, 0x0a, 0x12, 0x30, 0x23, 0x30, 0x1b, 0x51, 0x1b, 0x51, 0x1b, + 0x51, 0x1b, 0x30, 0x1b, + 0x2f, 0x2b, 0xe9, 0x11, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x42, 0x00, 0xc9, 0x19, 0x2f, 0x23, 0x30, 0x1b, 0x31, 0x1b, 0x31, 0x1b, + 0x51, 0x1b, 0x51, 0x1b, + 0x51, 0x1b, 0x30, 0x23, 0x6c, 0x22, 0x42, 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, + 0x21, 0x00, 0x42, 0x00, + 0xe6, 0x00, 0xea, 0x09, 0xae, 0x12, 0x72, 0x1b, 0xd3, 0x1b, 0xd4, 0x13, + 0xf4, 0x13, 0xf5, 0x0b, + 0xf5, 0x0b, 0xf5, 0x0b, 0xf5, 0x0b, 0xf5, 0x0b, 0xf5, 0x0b, 0xf5, 0x0b, + 0xf5, 0x0b, 0xf5, 0x0b, + 0xd4, 0x13, 0xb3, 0x13, 0x92, 0x1b, 0xef, 0x1a, 0x2b, 0x0a, 0x06, 0x01, + 0x63, 0x00, 0x21, 0x00, + 0x01, 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, 0x62, 0x00, + 0xa9, 0x09, 0x13, 0x3c, 0xb7, 0x44, 0xd7, 0x3c, 0xf8, 0x34, 0xf8, 0x34, + 0xf8, 0x34, 0xf8, 0x34, + 0x18, 0x35, 0x18, 0x35, 0x19, 0x35, 0x19, 0x35, 0x19, 0x3d, 0x39, 0x3d, + 0x19, 0x3d, 0x18, 0x3d, + 0x38, 0x3d, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x38, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, + 0x39, 0x45, 0x59, 0x45, 0x39, 0x45, 0x59, 0x45, 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x79, 0x4d, 0x79, 0x55, 0x79, 0x55, 0x79, 0x4d, 0x79, 0x55, + 0x79, 0x55, 0x79, 0x55, + 0x7a, 0x55, 0x99, 0x55, 0x7a, 0x55, 0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x55, + 0x9a, 0x5d, 0x9a, 0x5d, + 0x9a, 0x5d, 0x9a, 0x5d, 0x9a, 0x5d, 0x9a, 0x5d, 0x9a, 0x5d, 0x9a, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, + 0xba, 0x5d, 0xba, 0x5d, 0xba, 0x65, 0xba, 0x65, 0xba, 0x65, 0xda, 0x65, + 0xda, 0x65, 0xda, 0x65, + 0xda, 0x65, 0xda, 0x65, 0xda, 0x65, 0xda, 0x65, 0xda, 0x65, 0xda, 0x65, + 0xdb, 0x65, 0xdb, 0x65, + 0xfb, 0x65, 0xfa, 0x65, 0xfa, 0x6d, 0xb9, 0x75, 0x32, 0x5c, 0x42, 0x00, + 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0xed, 0x2a, 0xfa, 0x7d, + 0x1a, 0x76, 0x1b, 0x6e, 0x1b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x1b, 0x6e, + 0x3c, 0x6e, 0x3b, 0x6e, + 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x76, 0x3b, 0x76, + 0x3b, 0x7e, 0x1a, 0x86, + 0xb0, 0x4b, 0xe4, 0x00, 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, 0x21, 0x00, 0x83, 0x00, 0x06, 0x01, + 0xeb, 0x01, 0xce, 0x0a, + 0x92, 0x23, 0xb3, 0x23, 0xb3, 0x1b, 0xd3, 0x1b, 0xb3, 0x1b, 0xb3, 0x1b, + 0xb2, 0x23, 0x30, 0x1b, + 0x4c, 0x0a, 0x07, 0x01, 0x63, 0x00, 0x21, 0x00, 0x21, 0x00, 0xa4, 0x00, + 0x06, 0x01, 0x27, 0x01, + 0x07, 0x01, 0x07, 0x01, 0x07, 0x01, 0x06, 0x01, 0x06, 0x01, 0x83, 0x00, + 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x83, 0x00, + 0x06, 0x01, 0x07, 0x01, + 0x07, 0x01, 0x07, 0x01, 0x07, 0x01, 0x27, 0x01, 0x06, 0x01, 0x06, 0x01, + 0xc4, 0x00, 0x21, 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, 0x00, 0x00, 0x00, 0x21, 0x00, 0x43, 0x00, + 0xa5, 0x00, 0x48, 0x01, + 0xca, 0x01, 0xae, 0x0a, 0x51, 0x1b, 0xb2, 0x23, 0xb3, 0x23, 0xb3, 0x1b, + 0xd3, 0x1b, 0xb3, 0x1b, + 0xd3, 0x23, 0xb3, 0x23, 0xb3, 0x23, 0x92, 0x23, 0xcf, 0x12, 0x2c, 0x02, + 0x68, 0x01, 0xc5, 0x00, + 0x63, 0x00, 0x22, 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, 0x20, 0x00, 0x41, 0x00, 0xc4, 0x00, + 0x0e, 0x2b, 0x34, 0x44, + 0xb6, 0x44, 0xd6, 0x3c, 0xf7, 0x3c, 0xf8, 0x3c, 0x18, 0x3d, 0x18, 0x3d, + 0x18, 0x3d, 0x18, 0x3d, + 0x18, 0x3d, 0x18, 0x3d, 0x18, 0x45, 0x18, 0x3d, 0x38, 0x45, 0x38, 0x45, + 0x39, 0x45, 0x38, 0x45, + 0x38, 0x45, 0x38, 0x45, 0x39, 0x4d, 0x38, 0x4d, 0x39, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x4d, + 0x59, 0x4d, 0x59, 0x55, 0x59, 0x55, 0x59, 0x55, 0x79, 0x55, 0x79, 0x55, + 0x79, 0x55, 0x79, 0x55, + 0x79, 0x55, 0x79, 0x55, 0x79, 0x55, 0x79, 0x55, 0x7a, 0x5d, 0x99, 0x5d, + 0x9a, 0x5d, 0x99, 0x5d, + 0x99, 0x5d, 0x99, 0x5d, 0x9a, 0x5d, 0x9a, 0x5d, 0x99, 0x5d, 0x99, 0x5d, + 0x9a, 0x5d, 0x9a, 0x5d, + 0xba, 0x5d, 0x9a, 0x65, 0xba, 0x65, 0xba, 0x65, 0xba, 0x65, 0xba, 0x65, + 0xba, 0x65, 0xba, 0x65, + 0xda, 0x65, 0xda, 0x65, 0xda, 0x65, 0xda, 0x65, 0xda, 0x65, 0xda, 0x65, + 0xda, 0x65, 0xda, 0x65, + 0xda, 0x6d, 0xda, 0x6d, 0xdb, 0x6d, 0xfb, 0x6d, 0xda, 0x65, 0xfb, 0x6d, + 0xfa, 0x6d, 0xd9, 0x75, + 0xb8, 0x7d, 0xe9, 0x19, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0x00, 0xd0, 0x4b, 0xfa, 0x7d, 0x1a, 0x76, 0x1b, 0x6e, + 0x1b, 0x76, 0x1b, 0x76, + 0x3b, 0x76, 0x1b, 0x6e, 0x3b, 0x76, 0x3b, 0x6e, 0x3b, 0x76, 0x3b, 0x76, + 0x3b, 0x76, 0x3b, 0x76, + 0x1a, 0x7e, 0xb8, 0x7d, 0xb4, 0x64, 0x4a, 0x22, 0x42, 0x00, 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, 0x00, 0x21, 0x00, 0x42, 0x00, 0x63, 0x00, 0x84, 0x00, 0xe6, 0x00, + 0x27, 0x01, 0x88, 0x01, + 0x88, 0x01, 0x27, 0x01, 0xc5, 0x00, 0x63, 0x00, 0x43, 0x00, 0x22, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x21, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x21, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x21, 0x00, 0x42, 0x00, 0x43, 0x00, + 0x63, 0x00, 0xc5, 0x00, + 0x06, 0x01, 0x47, 0x01, 0x89, 0x01, 0xa9, 0x01, 0x68, 0x01, 0x07, 0x01, + 0xc5, 0x00, 0x64, 0x00, + 0x63, 0x00, 0x42, 0x00, 0x22, 0x00, 0x21, 0x00, 0x01, 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, 0x00, + 0x00, 0x00, 0x21, 0x00, 0x83, 0x00, 0x88, 0x09, 0xad, 0x1a, 0xb1, 0x33, + 0x34, 0x3c, 0xb6, 0x44, + 0xf7, 0x4c, 0xf7, 0x4c, 0xf7, 0x4c, 0xf7, 0x4c, 0xf7, 0x4c, 0xf7, 0x4c, + 0xf7, 0x54, 0x17, 0x55, + 0x17, 0x55, 0x17, 0x55, 0x18, 0x55, 0x17, 0x55, 0x17, 0x55, 0x17, 0x55, + 0x18, 0x5d, 0x17, 0x5d, + 0x17, 0x5d, 0x17, 0x5d, 0x38, 0x5d, 0x38, 0x5d, 0x38, 0x5d, 0x38, 0x5d, + 0x38, 0x5d, 0x38, 0x5d, + 0x58, 0x65, 0x58, 0x65, 0x58, 0x65, 0x58, 0x65, 0x58, 0x65, 0x58, 0x65, + 0x58, 0x65, 0x58, 0x65, + 0x78, 0x65, 0x58, 0x65, 0x78, 0x65, 0x78, 0x65, 0x78, 0x65, 0x78, 0x65, + 0x78, 0x6d, 0x79, 0x6d, + 0x79, 0x6d, 0x79, 0x6d, 0x99, 0x6d, 0x79, 0x6d, 0x79, 0x6d, 0x99, 0x6d, + 0x99, 0x6d, 0x99, 0x6d, + 0x99, 0x6d, 0x99, 0x6d, 0x99, 0x75, 0x99, 0x75, 0x99, 0x75, 0x99, 0x75, + 0x99, 0x75, 0xb9, 0x75, + 0xb9, 0x75, 0xb9, 0x75, 0xb9, 0x75, 0xba, 0x75, 0xb9, 0x75, 0xb9, 0x75, + 0xb9, 0x75, 0xb9, 0x75, + 0xda, 0x75, 0xda, 0x75, 0xd9, 0x75, 0xd9, 0x7d, 0xb8, 0x85, 0x52, 0x64, + 0xa3, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, + 0xb0, 0x53, 0xf9, 0x85, + 0xf9, 0x7d, 0xfa, 0x7d, 0xfa, 0x7d, 0x1a, 0x7e, 0x1a, 0x7e, 0x1a, 0x7e, + 0x1a, 0x7e, 0x1a, 0x7e, + 0x1a, 0x7e, 0x1a, 0x7e, 0x98, 0x75, 0xf5, 0x64, 0xf1, 0x4b, 0xab, 0x2a, + 0x05, 0x01, 0x41, 0x00, + 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x21, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x21, 0x00, + 0x21, 0x00, 0x01, 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, 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, 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, 0x00, 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x21, 0x00, 0x22, 0x00, + 0x22, 0x00, 0x42, 0x00, + 0x22, 0x00, 0x21, 0x00, 0x21, 0x00, 0x01, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x21, 0x00, + 0x63, 0x00, 0xe5, 0x00, 0x27, 0x01, 0x88, 0x01, 0x88, 0x01, 0x88, 0x01, + 0x88, 0x01, 0x88, 0x01, + 0x88, 0x01, 0x88, 0x01, 0x88, 0x01, 0x88, 0x09, 0x88, 0x09, 0x88, 0x09, + 0x88, 0x09, 0x88, 0x09, + 0x88, 0x09, 0x88, 0x09, 0x88, 0x09, 0x88, 0x09, 0x88, 0x09, 0x88, 0x09, + 0xa8, 0x09, 0xa8, 0x09, + 0x88, 0x09, 0x88, 0x09, 0x88, 0x09, 0x88, 0x09, 0x88, 0x09, 0x88, 0x09, + 0xa8, 0x09, 0xa8, 0x09, + 0x88, 0x09, 0x88, 0x09, 0x88, 0x09, 0x88, 0x09, 0xa8, 0x09, 0x88, 0x09, + 0xa8, 0x09, 0xa8, 0x09, + 0xa8, 0x09, 0xa8, 0x09, 0x88, 0x11, 0xa8, 0x09, 0x88, 0x11, 0xa8, 0x11, + 0xa8, 0x11, 0xa8, 0x11, + 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, + 0xa8, 0x11, 0xa8, 0x11, + 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, + 0xa8, 0x11, 0xa8, 0x11, + 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, 0xa8, 0x11, + 0xa8, 0x11, 0xa8, 0x11, + 0xa8, 0x19, 0x46, 0x11, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0xa8, 0x19, 0xc8, 0x11, 0xc8, 0x11, + 0xc8, 0x11, 0xc8, 0x11, + 0xc8, 0x11, 0xc8, 0x11, 0xc8, 0x11, 0xc8, 0x11, 0xc8, 0x11, 0xc8, 0x11, + 0x87, 0x09, 0x46, 0x09, + 0xa3, 0x00, 0x21, 0x00, 0x21, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#else +/* This image is 228x113 raw Image resembling QuIC logo*/ +static char imageBuffer_rgb888[] = { + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x18, 0x08, 0x00, 0x30, 0x18, 0x00, + 0x48, 0x30, 0x00, 0x70, 0x48, 0x00, 0x88, 0x5c, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x60, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, + 0x90, 0x64, 0x00, 0x90, 0x64, 0x00, 0x90, 0x68, 0x00, 0x90, 0x68, 0x00, + 0x90, 0x68, 0x00, 0x90, 0x68, 0x00, 0x98, 0x68, 0x00, 0x98, 0x68, 0x00, + 0x98, 0x68, 0x00, 0x98, 0x68, 0x00, 0x90, 0x64, 0x00, 0x80, 0x54, 0x00, + 0x60, 0x40, 0x00, 0x40, 0x24, 0x00, 0x20, 0x10, 0x00, 0x10, 0x04, 0x00, + 0x08, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x04, 0x00, 0x18, 0x10, 0x00, 0x48, 0x34, 0x08, 0x70, 0x50, 0x10, + 0x88, 0x68, 0x18, 0x98, 0x70, 0x10, 0xa0, 0x70, 0x08, 0xa0, 0x74, 0x08, + 0xa8, 0x74, 0x08, 0xa8, 0x74, 0x08, 0xa8, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x00, + 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x00, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x00, + 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x00, 0xa0, 0x78, 0x08, + 0xa8, 0x78, 0x08, 0xa8, 0x78, 0x08, 0xa8, 0x78, 0x08, 0xa8, 0x78, 0x08, + 0xa8, 0x78, 0x08, 0xa8, 0x78, 0x08, 0xa8, 0x78, 0x08, 0xa0, 0x74, 0x10, + 0x98, 0x70, 0x18, 0x80, 0x64, 0x18, 0x58, 0x44, 0x08, 0x30, 0x20, 0x00, + 0x10, 0x08, 0x00, 0x08, 0x04, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x28, 0x18, 0x00, 0x60, 0x48, 0x08, 0x90, 0x68, 0x18, 0x98, 0x74, 0x10, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x08, 0xa0, 0x78, 0x10, 0x98, 0x74, 0x18, 0x80, 0x64, 0x18, + 0x40, 0x28, 0x00, 0x18, 0x0c, 0x00, 0x08, 0x04, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x30, 0x20, 0x00, + 0x70, 0x54, 0x18, 0x90, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xb0, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x7c, 0x00, + 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x88, 0x6c, 0x20, 0x50, 0x38, 0x00, 0x18, 0x0c, 0x00, 0x08, 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, 0x0c, 0x08, 0x48, 0x48, 0x48, 0xc0, 0xc4, 0xc0, + 0xf8, 0xf8, 0xf8, 0xf0, 0xf4, 0xf0, 0xa0, 0xa0, 0xa0, 0x38, 0x38, 0x38, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, + 0xd8, 0xdc, 0xd8, 0x38, 0x3c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0x98, 0x9c, 0x98, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x0c, 0x08, 0x98, 0x98, 0x98, 0xf8, 0xfc, 0xf8, 0x28, 0x2c, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xf8, 0xfc, 0xf8, 0x78, 0x7c, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x98, 0x98, 0x98, + 0xe0, 0xe4, 0xe0, 0xf8, 0xfc, 0xf8, 0xd0, 0xd4, 0xd0, 0x78, 0x78, 0x78, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x14, 0x10, 0x58, 0x5c, 0x58, 0xd0, 0xd0, 0xd0, 0xf8, 0xfc, 0xf8, + 0xe8, 0xec, 0xe8, 0x88, 0x88, 0x88, 0x28, 0x28, 0x28, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xf0, 0xf0, 0xf0, + 0x68, 0x6c, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x6c, 0x68, 0xf0, 0xf0, 0xf0, + 0x90, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x80, 0x84, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, + 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 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, 0x04, 0x00, 0x20, 0x14, 0x00, 0x70, 0x54, 0x18, + 0x98, 0x70, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x7c, 0x10, 0x88, 0x6c, 0x18, 0x48, 0x34, 0x00, 0x10, 0x08, 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, 0x04, 0x00, 0x60, 0x64, 0x60, 0xe8, 0xe8, 0xe8, 0xc0, 0xc8, 0xc8, + 0x80, 0x84, 0x80, 0x88, 0x88, 0x88, 0xe8, 0xe8, 0xe8, 0xd8, 0xd8, 0xd8, + 0x40, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xd8, 0xdc, 0xd8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0x98, 0x9c, 0x98, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x28, 0x28, 0xc8, 0xcc, 0xc8, 0xf8, 0xfc, 0xf8, 0x88, 0x88, 0x88, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x14, 0x10, 0xc8, 0xc8, 0xc8, 0xe8, 0xec, 0xe8, + 0xa0, 0xa0, 0xa0, 0x80, 0x80, 0x80, 0xb8, 0xb8, 0xb8, 0xf8, 0xf8, 0xf8, + 0x88, 0x88, 0x88, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x08, 0x0c, 0x08, + 0x80, 0x84, 0x80, 0xf0, 0xf0, 0xf0, 0xb0, 0xb4, 0xb0, 0x80, 0x80, 0x80, + 0x90, 0x94, 0x90, 0xf0, 0xf0, 0xf0, 0xc0, 0xc4, 0xc0, 0x28, 0x28, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xf8, 0xfc, 0xf8, + 0xb0, 0xb4, 0xb0, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xb0, 0xb0, 0xb0, 0xf8, 0xfc, 0xf8, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0xe0, 0xe0, 0xe0, 0x08, 0x0c, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0xa0, 0xa0, 0xa0, + 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 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, 0x00, 0x00, 0x10, 0x08, 0x00, 0x58, 0x3c, 0x08, 0x90, 0x6c, 0x18, + 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x7c, 0x10, 0x80, 0x68, 0x20, 0x28, 0x14, 0x00, + 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xc0, 0xc0, 0xc0, 0xe8, 0xec, 0xe8, 0x28, 0x2c, 0x28, + 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x60, 0x64, 0x60, 0xf0, 0xf0, 0xf0, + 0xa0, 0xa4, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, + 0xd8, 0xdc, 0xd8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x58, 0x58, 0xf8, 0xf8, 0xf8, 0xf0, 0xf4, 0xf0, 0xc0, 0xc4, 0xc0, + 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, 0xf0, 0xf0, 0xf0, 0x78, 0x78, 0x78, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0xb8, 0xb8, 0xb8, + 0xd8, 0xdc, 0xd8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xe0, 0xe0, 0xe0, 0xd0, 0xd0, 0xd0, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x08, 0x0c, 0x08, 0x80, 0x80, 0x80, 0xf8, 0xfc, 0xf8, 0x78, 0x78, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0xf8, 0xfc, 0xf8, + 0xf0, 0xf4, 0xf0, 0x48, 0x4c, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x4c, 0x48, 0xf0, 0xf4, 0xf0, 0xf8, 0xfc, 0xf8, + 0x90, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x6c, 0x68, + 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xe0, 0xe0, 0xe0, + 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 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, + 0x10, 0x04, 0x00, 0x38, 0x28, 0x00, 0x88, 0x64, 0x18, 0xa0, 0x74, 0x08, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x80, 0x08, 0x98, 0x78, 0x18, 0x68, 0x50, 0x08, + 0x18, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x34, 0x30, 0xe8, 0xec, 0xe8, 0xa0, 0xa4, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0xc0, 0xc4, 0xc0, + 0xe0, 0xe4, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xe0, 0xe0, 0xe0, 0x38, 0x3c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0xb8, 0xb8, 0xd8, 0xd8, 0xd8, 0x90, 0x94, 0x90, 0xe8, 0xec, 0xe8, + 0x58, 0x58, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0xac, 0xa8, 0xd8, 0xd8, 0xd8, 0x30, 0x30, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3c, 0x38, + 0x80, 0x84, 0x80, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x50, 0x54, 0x50, + 0xf8, 0xfc, 0xf8, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0xe0, 0xe4, 0xe0, 0xb0, 0xb4, 0xb0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xf8, 0xfc, 0xf8, + 0xf8, 0xf8, 0xf8, 0xc8, 0xc8, 0xc8, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0xbc, 0xb8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xf8, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0xf8, 0xf8, 0xf8, 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x08, 0x0c, 0x08, 0x90, 0x94, 0x90, 0xf0, 0xf4, 0xf0, + 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 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, + 0x20, 0x10, 0x00, 0x58, 0x40, 0x08, 0x98, 0x6c, 0x10, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x80, 0x10, 0x88, 0x68, 0x10, + 0x30, 0x24, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x18, 0xb8, 0xbc, 0xb8, + 0xf8, 0xfc, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xe0, 0xe0, 0xe0, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x18, + 0xf0, 0xf0, 0xf0, 0x98, 0x98, 0x98, 0x28, 0x28, 0x28, 0xf0, 0xf4, 0xf0, + 0x90, 0x94, 0x90, 0x08, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x68, 0x6c, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0xc8, 0xcc, 0xc8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0xe8, 0xe8, 0xe8, + 0xc8, 0xcc, 0xc8, 0xf8, 0xf8, 0xf8, 0x38, 0x3c, 0x38, 0x00, 0x00, 0x00, + 0x30, 0x34, 0x30, 0xf0, 0xf4, 0xf0, 0xc8, 0xcc, 0xc8, 0xe8, 0xe8, 0xe8, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x6c, 0x68, + 0xf8, 0xfc, 0xf8, 0xb0, 0xb4, 0xb0, 0xf0, 0xf0, 0xf0, 0x68, 0x68, 0x68, + 0x00, 0x00, 0x00, 0x30, 0x34, 0x30, 0xd8, 0xd8, 0xd8, 0xb0, 0xb4, 0xb0, + 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 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, + 0x38, 0x1c, 0x00, 0x70, 0x54, 0x10, 0xa0, 0x74, 0x10, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x08, 0x98, 0x78, 0x18, + 0x50, 0x3c, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x3c, 0x38, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0xb8, 0xbc, 0xb8, + 0xf8, 0xfc, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xe0, 0xe0, 0xe0, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0x98, 0x9c, 0x98, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x68, 0x68, + 0xe8, 0xec, 0xe8, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, + 0xc8, 0xcc, 0xc8, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x68, 0x6c, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, 0xd8, 0xdc, 0xd8, 0xc8, 0xcc, 0xc8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xd8, 0xdc, 0xd8, + 0x78, 0x7c, 0x78, 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, 0x08, 0x0c, 0x08, + 0xa0, 0xa4, 0xa0, 0xd8, 0xdc, 0xd8, 0x78, 0x7c, 0x78, 0xe0, 0xe0, 0xe0, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x6c, 0x68, + 0xf8, 0xfc, 0xf8, 0x50, 0x50, 0x50, 0xe8, 0xe8, 0xe8, 0xb0, 0xb0, 0xb0, + 0x18, 0x18, 0x18, 0x88, 0x8c, 0x88, 0xe8, 0xec, 0xe8, 0x48, 0x48, 0x48, + 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 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, 0x2c, 0x00, 0x90, 0x68, 0x20, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb8, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xa0, 0x7c, 0x10, + 0x68, 0x4c, 0x10, 0x18, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x18, 0xb8, 0xbc, 0xb8, + 0xf8, 0xfc, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, + 0xd8, 0xdc, 0xd8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xc0, 0xc4, 0xc0, + 0xd0, 0xd0, 0xd0, 0x20, 0x24, 0x20, 0x00, 0x00, 0x00, 0x68, 0x68, 0x68, + 0xf8, 0xf8, 0xf8, 0x58, 0x5c, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0xc8, 0xcc, 0xc8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xe0, 0xe0, 0xe0, + 0x40, 0x40, 0x40, 0x88, 0x8c, 0x88, 0xe0, 0xe4, 0xe0, 0x90, 0x90, 0x90, + 0xe0, 0xe0, 0xe0, 0x90, 0x90, 0x90, 0x38, 0x3c, 0x38, 0xe0, 0xe0, 0xe0, + 0x90, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x70, 0x70, 0x70, 0xf0, 0xf4, 0xf0, + 0x68, 0x6c, 0x68, 0xe8, 0xec, 0xe8, 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, + 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 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, + 0x58, 0x38, 0x00, 0x90, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x84, 0x00, 0xb8, 0x84, 0x00, + 0xb8, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xa8, 0x80, 0x10, + 0x70, 0x58, 0x18, 0x20, 0x14, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0x20, 0x24, 0x20, 0xb8, 0xbc, 0xb8, + 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xd8, 0xdc, 0xd8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x48, 0x48, 0x48, 0xe0, 0xe4, 0xe0, + 0xc0, 0xc4, 0xc0, 0x40, 0x44, 0x40, 0x40, 0x40, 0x40, 0x68, 0x68, 0x68, + 0xe8, 0xe8, 0xe8, 0xb8, 0xb8, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x2c, 0x28, 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, 0xd8, 0xdc, 0xd8, 0xc8, 0xcc, 0xc8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0xd8, 0xdc, 0xd8, + 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0xf0, 0xf0, 0xf0, 0xf0, 0xf4, 0xf0, + 0xf0, 0xf4, 0xf0, 0x28, 0x2c, 0x28, 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x28, 0x28, 0x28, 0xc8, 0xcc, 0xc8, + 0xe8, 0xec, 0xe8, 0xe8, 0xec, 0xe8, 0x58, 0x5c, 0x58, 0x00, 0x00, 0x00, + 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x08, 0x0c, 0x08, 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, 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, + 0x60, 0x40, 0x00, 0x98, 0x70, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x84, 0x00, 0xb8, 0x84, 0x00, + 0xb8, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xa8, 0x80, 0x10, + 0x78, 0x5c, 0x10, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xe0, 0xe4, 0xe0, 0xb0, 0xb4, 0xb0, 0x00, 0x00, 0x00, + 0x10, 0x14, 0x10, 0xb0, 0xb0, 0xb0, 0xa8, 0xa8, 0xa8, 0xd8, 0xd8, 0xd8, + 0xd0, 0xd4, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, + 0xe0, 0xe4, 0xe0, 0x48, 0x4c, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x14, 0x10, 0xf8, 0xfc, 0xf8, 0x98, 0x98, 0x98, + 0x08, 0x0c, 0x08, 0x00, 0x04, 0x00, 0x80, 0x84, 0x80, 0xf8, 0xf8, 0xf8, + 0xe8, 0xec, 0xe8, 0xd8, 0xdc, 0xd8, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xf0, 0xf4, 0xf0, 0xf0, 0xf4, 0xf0, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0xa4, 0xa0, 0xd8, 0xdc, 0xd8, 0x38, 0x38, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x54, 0x50, + 0xb8, 0xbc, 0xb8, 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x48, 0x48, 0x48, + 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0xe8, 0xe8, 0xe8, 0xa8, 0xa8, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0xe0, 0xe0, 0xe0, + 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x98, 0x9c, 0x98, 0xf8, 0xfc, 0xf8, + 0xb0, 0xb0, 0xb0, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xe0, 0xe0, 0xe0, + 0x90, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x38, 0x3c, 0x38, 0x00, 0x04, 0x00, 0x78, 0x7c, 0x78, + 0xf0, 0xf4, 0xf0, 0xb8, 0xbc, 0xb8, 0x10, 0x14, 0x10, 0x00, 0x00, 0x00, + 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 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, + 0x68, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xa8, 0x80, 0x10, + 0x78, 0x5c, 0x10, 0x28, 0x18, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0xb0, 0xb0, 0xb0, 0xf0, 0xf4, 0xf0, 0x48, 0x48, 0x48, + 0x10, 0x14, 0x10, 0x70, 0x74, 0x70, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, + 0x90, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xf0, 0xf0, 0xf0, 0xa8, 0xac, 0xa8, 0x30, 0x30, 0x30, 0x10, 0x14, 0x10, + 0x20, 0x20, 0x20, 0x98, 0x9c, 0x98, 0xe8, 0xec, 0xe8, 0x58, 0x5c, 0x58, + 0x00, 0x00, 0x00, 0x20, 0x24, 0x20, 0xc0, 0xc4, 0xc0, 0xe0, 0xe0, 0xe0, + 0x58, 0x5c, 0x58, 0x58, 0x5c, 0x58, 0x58, 0x5c, 0x58, 0x58, 0x5c, 0x58, + 0x90, 0x90, 0x90, 0xf0, 0xf0, 0xf0, 0x78, 0x7c, 0x78, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xf8, 0xfc, 0xf8, 0x90, 0x90, 0x90, 0x20, 0x24, 0x20, + 0x20, 0x24, 0x20, 0x20, 0x24, 0x20, 0x20, 0x24, 0x20, 0x18, 0x1c, 0x18, + 0x08, 0x08, 0x08, 0x58, 0x5c, 0x58, 0xf0, 0xf4, 0xf0, 0x98, 0x98, 0x98, + 0x20, 0x24, 0x20, 0x10, 0x14, 0x10, 0x38, 0x38, 0x38, 0xc8, 0xcc, 0xc8, + 0xd0, 0xd4, 0xd0, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, + 0xd0, 0xd0, 0xd0, 0xe0, 0xe4, 0xe0, 0x30, 0x30, 0x30, 0x10, 0x14, 0x10, + 0x18, 0x1c, 0x18, 0xa0, 0xa0, 0xa0, 0xf8, 0xf8, 0xf8, 0x68, 0x68, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xe0, 0xe0, 0xe0, + 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x80, 0x80, 0x80, + 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, + 0x70, 0x74, 0x70, 0x38, 0x3c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf8, 0xfc, 0xf8, 0x98, 0x9c, 0x98, 0x10, 0x10, 0x10, 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, 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, + 0x68, 0x40, 0x00, 0x98, 0x70, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xa8, 0x80, 0x10, + 0x78, 0x60, 0x10, 0x28, 0x18, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x48, 0x48, 0xd0, 0xd4, 0xd0, 0xe0, 0xe4, 0xe0, + 0xa8, 0xac, 0xa8, 0xb8, 0xbc, 0xb8, 0xf8, 0xfc, 0xf8, 0xf8, 0xf8, 0xf8, + 0x98, 0x9c, 0x98, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x90, 0x94, 0x90, 0xf0, 0xf0, 0xf0, 0xc8, 0xc8, 0xc8, 0xa0, 0xa4, 0xa0, + 0xc0, 0xc0, 0xc0, 0xf8, 0xf8, 0xf8, 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, + 0x00, 0x00, 0x00, 0x48, 0x4c, 0x48, 0xf0, 0xf4, 0xf0, 0x98, 0x98, 0x98, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x2c, 0x28, 0xd0, 0xd4, 0xd0, 0xb8, 0xbc, 0xb8, 0x10, 0x14, 0x10, + 0x30, 0x30, 0x30, 0xf8, 0xfc, 0xf8, 0xe0, 0xe0, 0xe0, 0xc0, 0xc4, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xa8, 0xa8, 0xa8, + 0x30, 0x30, 0x30, 0x08, 0x08, 0x08, 0xa8, 0xac, 0xa8, 0xf0, 0xf4, 0xf0, + 0xc0, 0xc0, 0xc0, 0xa8, 0xa8, 0xa8, 0xd0, 0xd0, 0xd0, 0xe8, 0xec, 0xe8, + 0x68, 0x68, 0x68, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x60, 0x64, 0x60, 0xe0, 0xe0, 0xe0, 0xd8, 0xd8, 0xd8, 0xa8, 0xa8, 0xa8, + 0xb8, 0xbc, 0xb8, 0xf0, 0xf4, 0xf0, 0xa0, 0xa4, 0xa0, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xd8, 0xdc, 0xd8, + 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, + 0x90, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 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, + 0x60, 0x40, 0x00, 0x98, 0x70, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb0, 0x88, 0x00, 0xa8, 0x84, 0x10, + 0x78, 0x60, 0x10, 0x28, 0x18, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, 0x24, 0x28, 0x88, 0x8c, 0x90, + 0xc0, 0xc0, 0xc0, 0xb8, 0xbc, 0xb8, 0x68, 0x6c, 0x68, 0x70, 0x70, 0x70, + 0xd0, 0xd4, 0xd0, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x14, 0x10, 0x50, 0x54, 0x50, 0xa0, 0xa0, 0xa0, 0xc8, 0xc8, 0xc8, + 0xa8, 0xac, 0xa8, 0x60, 0x60, 0x60, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x50, 0x50, 0x98, 0x98, 0x98, 0x30, 0x34, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x70, 0x74, 0x70, 0x80, 0x84, 0x80, 0x20, 0x24, 0x20, + 0x18, 0x1c, 0x18, 0x98, 0x98, 0x98, 0x90, 0x94, 0x90, 0x90, 0x94, 0x90, + 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x80, 0x84, 0x80, + 0x20, 0x24, 0x20, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x60, 0x64, 0x60, + 0xa8, 0xac, 0xa8, 0xc0, 0xc4, 0xc0, 0x98, 0x9c, 0x98, 0x48, 0x4c, 0x48, + 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x08, 0x08, 0x30, 0x34, 0x30, 0x98, 0x9c, 0x98, 0xc0, 0xc4, 0xc0, + 0xb0, 0xb4, 0xb0, 0x60, 0x60, 0x60, 0x10, 0x14, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x54, 0x50, 0x80, 0x84, 0x80, + 0x20, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x24, 0x20, 0x80, 0x84, 0x80, + 0x50, 0x54, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, + 0x98, 0x98, 0x98, 0x20, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x98, 0x98, 0x98, 0x60, 0x60, 0x60, 0x08, 0x08, 0x08, 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, 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xb0, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x84, 0x00, 0xb8, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x84, 0x00, 0xb8, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb0, 0x84, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb0, 0x88, 0x00, 0xa8, 0x84, 0x10, + 0x78, 0x60, 0x10, 0x28, 0x18, 0x00, 0x08, 0x04, 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, 0x00, 0x00, + 0x08, 0x08, 0x08, 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, 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, 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, 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, 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, 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, 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, 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x78, 0x00, + 0xb0, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb8, 0x84, 0x00, 0xb8, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xa8, 0x84, 0x10, + 0x78, 0x60, 0x10, 0x28, 0x1c, 0x00, 0x08, 0x04, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xb0, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x08, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x08, 0xa0, 0x78, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x78, 0x08, 0xa0, 0x74, 0x10, 0xa0, 0x78, 0x10, + 0xa0, 0x74, 0x10, 0xa0, 0x74, 0x08, 0xa0, 0x78, 0x08, 0xa0, 0x78, 0x08, + 0xa8, 0x7c, 0x08, 0xa8, 0x78, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb8, 0x84, 0x00, 0xb8, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x88, 0x00, 0xa8, 0x84, 0x10, + 0x78, 0x60, 0x10, 0x28, 0x1c, 0x00, 0x08, 0x04, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, + 0xa0, 0x74, 0x10, 0x98, 0x70, 0x10, 0x98, 0x70, 0x18, 0x90, 0x68, 0x18, + 0x80, 0x60, 0x10, 0x80, 0x60, 0x18, 0x80, 0x60, 0x18, 0x78, 0x5c, 0x10, + 0x78, 0x5c, 0x10, 0x80, 0x60, 0x18, 0x80, 0x60, 0x10, 0x88, 0x64, 0x10, + 0x90, 0x6c, 0x18, 0x98, 0x70, 0x18, 0xa0, 0x78, 0x18, 0xa0, 0x78, 0x10, + 0xa8, 0x7c, 0x10, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xa8, 0x84, 0x10, + 0x78, 0x60, 0x10, 0x28, 0x1c, 0x00, 0x08, 0x04, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x08, 0x98, 0x70, 0x08, + 0x98, 0x70, 0x10, 0x98, 0x70, 0x18, 0x88, 0x68, 0x18, 0x78, 0x58, 0x10, + 0x68, 0x4c, 0x08, 0x58, 0x40, 0x00, 0x50, 0x34, 0x00, 0x48, 0x30, 0x00, + 0x38, 0x24, 0x00, 0x38, 0x24, 0x00, 0x38, 0x20, 0x00, 0x30, 0x1c, 0x00, + 0x30, 0x1c, 0x00, 0x30, 0x20, 0x00, 0x38, 0x24, 0x00, 0x38, 0x28, 0x00, + 0x40, 0x2c, 0x00, 0x48, 0x34, 0x00, 0x58, 0x40, 0x00, 0x68, 0x4c, 0x00, + 0x78, 0x5c, 0x10, 0x90, 0x6c, 0x18, 0x98, 0x78, 0x18, 0xa0, 0x78, 0x18, + 0xa8, 0x7c, 0x10, 0xa8, 0x7c, 0x08, 0xa8, 0x80, 0x08, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb0, 0x84, 0x10, + 0x78, 0x60, 0x10, 0x28, 0x1c, 0x00, 0x08, 0x04, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa0, 0x74, 0x08, 0x98, 0x70, 0x10, 0x90, 0x68, 0x18, 0x80, 0x64, 0x20, + 0x68, 0x48, 0x10, 0x48, 0x34, 0x00, 0x30, 0x20, 0x00, 0x28, 0x14, 0x00, + 0x18, 0x0c, 0x00, 0x10, 0x08, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, 0x18, 0x10, 0x00, + 0x20, 0x18, 0x00, 0x30, 0x20, 0x00, 0x48, 0x30, 0x00, 0x68, 0x50, 0x10, + 0x88, 0x68, 0x20, 0x98, 0x74, 0x20, 0xa0, 0x7c, 0x18, 0xa8, 0x7c, 0x10, + 0xb0, 0x80, 0x08, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb8, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb0, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x88, 0x00, 0xa8, 0x84, 0x10, + 0x78, 0x60, 0x10, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa0, 0x74, 0x08, 0xa0, 0x70, 0x10, 0x98, 0x70, 0x10, + 0x80, 0x60, 0x10, 0x68, 0x50, 0x08, 0x48, 0x2c, 0x00, 0x20, 0x10, 0x00, + 0x18, 0x08, 0x00, 0x10, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, 0x18, 0x08, 0x00, + 0x20, 0x10, 0x00, 0x40, 0x2c, 0x00, 0x70, 0x54, 0x10, 0x88, 0x68, 0x10, + 0x98, 0x78, 0x18, 0xa8, 0x80, 0x10, 0xa8, 0x80, 0x08, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb8, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xa8, 0x88, 0x10, + 0x78, 0x60, 0x10, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x14, 0x10, 0x78, 0x7c, 0x78, 0x80, 0x84, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xa4, 0xa0, 0x70, 0x70, 0x70, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x1c, 0x18, 0x90, 0x90, 0x90, 0x68, 0x68, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x3c, 0x38, 0x98, 0x9c, 0x98, 0x48, 0x48, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x48, 0x48, 0xa8, 0xa8, 0xa8, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x50, 0x50, 0x50, + 0x98, 0x98, 0x98, 0xa0, 0xa0, 0xa0, 0x70, 0x70, 0x70, 0x30, 0x30, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0x98, 0x98, 0x98, + 0x38, 0x3c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x68, 0x6c, 0x68, 0x98, 0x9c, 0x98, 0x28, 0x2c, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x90, 0x94, 0x90, + 0x70, 0x74, 0x70, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x3c, 0x38, 0xa0, 0xa4, 0xa0, 0xa0, 0xa4, 0xa0, 0xa0, 0xa4, 0xa0, + 0xa0, 0xa4, 0xa0, 0xa0, 0xa4, 0xa0, 0xa0, 0xa4, 0xa0, 0xa0, 0xa4, 0xa0, + 0x68, 0x68, 0x68, 0x08, 0x08, 0x08, 0x28, 0x28, 0x28, 0xa0, 0xa4, 0xa0, + 0x48, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x50, 0x50, 0x50, 0x90, 0x94, 0x90, 0xa0, 0xa0, 0xa0, + 0x70, 0x70, 0x70, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x1c, 0x18, 0x90, 0x90, 0x90, 0x70, 0x74, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x28, 0x28, 0x90, 0x90, 0x90, 0x58, 0x5c, 0x58, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa0, 0x74, 0x08, 0x90, 0x70, 0x18, 0x78, 0x5c, 0x18, 0x58, 0x3c, 0x08, + 0x30, 0x20, 0x00, 0x18, 0x0c, 0x00, 0x10, 0x08, 0x00, 0x08, 0x00, 0x00, + 0x08, 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, 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, 0x08, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, 0x20, 0x10, 0x00, 0x30, 0x20, 0x00, + 0x50, 0x40, 0x00, 0x80, 0x68, 0x18, 0xa0, 0x7c, 0x18, 0xa8, 0x80, 0x10, + 0xb0, 0x84, 0x08, 0xb8, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xa8, 0x88, 0x10, + 0x78, 0x60, 0x10, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xc0, 0xc0, 0xc0, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xe8, 0xec, 0xe8, + 0x50, 0x54, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0x98, 0x9c, 0x98, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0xf8, 0xfc, 0xf8, 0xc0, 0xc0, 0xc0, + 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x6c, 0x68, 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x0c, 0x08, 0xa8, 0xa8, 0xa8, 0xe8, 0xec, 0xe8, + 0xc8, 0xcc, 0xc8, 0xc0, 0xc0, 0xc0, 0xe8, 0xe8, 0xe8, 0xd0, 0xd0, 0xd0, + 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x40, 0x44, 0x40, 0xf8, 0xf8, 0xf8, + 0x80, 0x84, 0x80, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xc8, 0xcc, 0xc8, 0x28, 0x28, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, 0xf8, 0xfc, 0xf8, + 0xe0, 0xe4, 0xe0, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x44, 0x40, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xc0, 0xc4, 0xc0, + 0xf8, 0xfc, 0xf8, 0xd8, 0xdc, 0xd8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, + 0x70, 0x74, 0x70, 0x08, 0x0c, 0x08, 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, + 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0c, 0x08, + 0xa8, 0xa8, 0xa8, 0xe8, 0xe8, 0xe8, 0xc8, 0xcc, 0xc8, 0xc0, 0xc0, 0xc0, + 0xe8, 0xe8, 0xe8, 0xd0, 0xd0, 0xd0, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0xf0, 0xf4, 0xf0, + 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, 0x90, 0x90, 0x90, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa0, 0x74, 0x08, 0x98, 0x70, 0x10, + 0x88, 0x64, 0x18, 0x58, 0x3c, 0x00, 0x30, 0x1c, 0x00, 0x18, 0x0c, 0x00, + 0x08, 0x04, 0x00, 0x08, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x10, 0x08, 0x00, 0x30, 0x20, 0x00, 0x58, 0x40, 0x00, 0x90, 0x70, 0x18, + 0xa0, 0x7c, 0x18, 0xa8, 0x84, 0x10, 0xb0, 0x84, 0x08, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, 0xb0, 0x88, 0x10, + 0x78, 0x64, 0x10, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, + 0xd8, 0xdc, 0xd8, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0xf8, 0xfc, 0xf8, 0xf8, 0xf8, 0xf8, + 0x90, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x70, 0x70, 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, 0xf0, 0xf4, 0xf0, 0x98, 0x98, 0x98, + 0x20, 0x24, 0x20, 0x18, 0x1c, 0x18, 0x60, 0x60, 0x60, 0xe0, 0xe4, 0xe0, + 0xb8, 0xb8, 0xb8, 0x10, 0x14, 0x10, 0x00, 0x04, 0x00, 0xe8, 0xe8, 0xe8, + 0xb0, 0xb4, 0xb0, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xf8, 0xfc, 0xf8, 0x90, 0x94, 0x90, 0x08, 0x0c, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xf8, 0xfc, 0xf8, + 0xf8, 0xf8, 0xf8, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x08, 0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x40, 0x44, 0x40, + 0xf8, 0xfc, 0xf8, 0x88, 0x8c, 0x88, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, + 0x68, 0x6c, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xf8, 0xf8, 0x98, 0x98, 0x98, 0x20, 0x24, 0x20, 0x18, 0x1c, 0x18, + 0x60, 0x60, 0x60, 0xe0, 0xe4, 0xe0, 0xb8, 0xb8, 0xb8, 0x10, 0x14, 0x10, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0xf8, 0xfc, 0xf8, + 0xb8, 0xbc, 0xb8, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, 0x90, 0x90, 0x90, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa0, 0x74, 0x08, 0x98, 0x70, 0x10, 0x80, 0x64, 0x18, 0x60, 0x44, 0x08, + 0x28, 0x18, 0x00, 0x10, 0x08, 0x00, 0x08, 0x04, 0x00, 0x08, 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, + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x08, 0x04, 0x00, 0x18, 0x08, 0x00, 0x28, 0x14, 0x00, + 0x60, 0x4c, 0x10, 0x90, 0x70, 0x18, 0xa8, 0x84, 0x18, 0xb0, 0x88, 0x08, + 0xb0, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb0, 0x88, 0x10, + 0x78, 0x64, 0x10, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xc0, 0xc0, 0xc0, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xf0, 0xf4, 0xf0, + 0xf8, 0xf8, 0xf8, 0x98, 0x9c, 0x98, 0x08, 0x0c, 0x08, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0xf8, 0xf8, 0xf8, 0xf0, 0xf4, 0xf0, + 0xf8, 0xfc, 0xf8, 0x48, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x70, 0x70, 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x08, 0x08, 0x08, 0xc0, 0xc0, 0xc0, 0xd0, 0xd4, 0xd0, 0x30, 0x30, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa8, 0xa8, + 0xe0, 0xe0, 0xe0, 0x40, 0x44, 0x40, 0x00, 0x00, 0x00, 0xa0, 0xa4, 0xa0, + 0xe8, 0xec, 0xe8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x88, 0x88, 0xe8, 0xec, 0xe8, 0x58, 0x58, 0x58, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x1c, 0x18, 0xc8, 0xcc, 0xc8, 0xd8, 0xdc, 0xd8, + 0xc8, 0xc8, 0xc8, 0xd0, 0xd4, 0xd0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, + 0x68, 0x6c, 0x68, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xc0, 0xc0, 0xc0, + 0xd0, 0xd4, 0xd0, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0xa4, 0xa0, 0xe0, 0xe0, 0xe0, 0x40, 0x44, 0x40, + 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, 0xd8, 0xdc, 0xd8, 0xf0, 0xf0, 0xf0, + 0xf8, 0xf8, 0xf8, 0x90, 0x90, 0x90, 0x08, 0x0c, 0x08, 0x00, 0x00, 0x00, + 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, 0x88, 0x8c, 0x88, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x00, 0xa0, 0x74, 0x08, + 0x98, 0x70, 0x18, 0x78, 0x58, 0x10, 0x40, 0x28, 0x00, 0x18, 0x0c, 0x00, + 0x08, 0x04, 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, 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, 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, 0x00, 0x08, 0x04, 0x00, + 0x18, 0x0c, 0x00, 0x40, 0x30, 0x00, 0x78, 0x60, 0x10, 0xa0, 0x80, 0x18, + 0xa8, 0x84, 0x10, 0xb0, 0x88, 0x08, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb0, 0x88, 0x10, + 0x78, 0x64, 0x18, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xb8, 0xb8, 0xb8, + 0xc8, 0xc8, 0xc8, 0xe8, 0xe8, 0xe8, 0x58, 0x58, 0x58, 0x00, 0x00, 0x00, + 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0xf0, 0xf0, 0xf0, 0xa8, 0xac, 0xa8, + 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x70, 0x70, 0x70, 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x18, 0x1c, 0x18, 0xc8, 0xcc, 0xc8, 0xd0, 0xd0, 0xd0, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xe8, 0xec, 0xe8, 0x58, 0x5c, 0x58, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, + 0xf8, 0xf8, 0xf8, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00, 0x08, 0x0c, 0x08, + 0xc0, 0xc0, 0xc0, 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x54, 0x50, 0xe8, 0xe8, 0xe8, 0x78, 0x7c, 0x78, + 0x80, 0x80, 0x80, 0xf8, 0xf8, 0xf8, 0x28, 0x2c, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, + 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x18, 0xc8, 0xcc, 0xc8, + 0xc8, 0xcc, 0xc8, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xe8, 0xec, 0xe8, 0x58, 0x5c, 0x58, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0xe0, 0xe0, 0xe0, 0xb0, 0xb4, 0xb0, + 0xd0, 0xd0, 0xd0, 0xe0, 0xe4, 0xe0, 0x48, 0x4c, 0x48, 0x00, 0x00, 0x00, + 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, 0x88, 0x8c, 0x88, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa0, 0x70, 0x10, 0x88, 0x68, 0x18, + 0x58, 0x40, 0x08, 0x28, 0x18, 0x00, 0x10, 0x04, 0x00, 0x08, 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, + 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, 0x28, 0x18, 0x00, 0x60, 0x4c, 0x10, + 0x98, 0x78, 0x20, 0xa8, 0x84, 0x10, 0xb0, 0x8c, 0x08, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb0, 0x88, 0x10, + 0x78, 0x64, 0x18, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, + 0x48, 0x48, 0x48, 0xf8, 0xf8, 0xf8, 0xc8, 0xc8, 0xc8, 0x28, 0x28, 0x28, + 0x30, 0x30, 0x30, 0xe0, 0xe0, 0xe0, 0x98, 0x9c, 0x98, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0xe8, 0xec, 0xe8, 0x68, 0x68, 0x68, + 0x88, 0x88, 0x88, 0xf0, 0xf4, 0xf0, 0x88, 0x88, 0x88, 0x08, 0x0c, 0x08, + 0x70, 0x70, 0x70, 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x18, 0x1c, 0x18, 0xc8, 0xcc, 0xc8, 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, + 0xe8, 0xec, 0xe8, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, + 0xd0, 0xd4, 0xd0, 0xc0, 0xc4, 0xc0, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, + 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x08, 0x08, 0x90, 0x90, 0x90, 0xf8, 0xfc, 0xf8, 0x20, 0x20, 0x20, + 0x48, 0x4c, 0x48, 0xe0, 0xe4, 0xe0, 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3c, 0x38, 0xf8, 0xfc, 0xf8, + 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0xd0, 0xd0, 0xd0, + 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xe8, 0xec, 0xe8, 0x60, 0x60, 0x60, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, + 0x50, 0x54, 0x50, 0xe8, 0xec, 0xe8, 0xd0, 0xd0, 0xd0, 0x08, 0x0c, 0x08, + 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, 0x88, 0x8c, 0x88, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x08, 0x98, 0x70, 0x10, 0x88, 0x60, 0x18, 0x48, 0x2c, 0x00, + 0x18, 0x0c, 0x00, 0x08, 0x04, 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, 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, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x18, 0x0c, 0x00, + 0x48, 0x34, 0x00, 0x88, 0x6c, 0x10, 0xa8, 0x84, 0x18, 0xb0, 0x8c, 0x08, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb0, 0x8c, 0x10, + 0x80, 0x64, 0x18, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, + 0x10, 0x10, 0x10, 0x78, 0x7c, 0x78, 0xf0, 0xf4, 0xf0, 0xa0, 0xa0, 0xa0, + 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0xe8, 0xec, 0xe8, 0x60, 0x60, 0x60, + 0x08, 0x08, 0x08, 0xc8, 0xcc, 0xc8, 0xe8, 0xec, 0xe8, 0x50, 0x54, 0x50, + 0x70, 0x70, 0x70, 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xc8, 0xcc, 0xc8, 0xd0, 0xd0, 0xd0, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xe8, 0xec, 0xe8, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x08, 0x0c, 0x08, + 0x98, 0x98, 0x98, 0xf8, 0xfc, 0xf8, 0x20, 0x24, 0x20, 0x78, 0x78, 0x78, + 0xf8, 0xf8, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x2c, 0x28, 0xd8, 0xdc, 0xd8, 0xc0, 0xc4, 0xc0, 0x00, 0x00, 0x00, + 0x10, 0x10, 0x10, 0xc0, 0xc0, 0xc0, 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, + 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, + 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x18, 0xc8, 0xcc, 0xc8, + 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xe8, 0xec, 0xe8, 0x60, 0x60, 0x60, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, + 0x08, 0x08, 0x08, 0x80, 0x84, 0x80, 0xf0, 0xf4, 0xf0, 0x88, 0x88, 0x88, + 0x48, 0x48, 0x48, 0xd8, 0xdc, 0xd8, 0x88, 0x8c, 0x88, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa0, 0x74, 0x08, + 0x98, 0x6c, 0x10, 0x78, 0x58, 0x10, 0x40, 0x28, 0x00, 0x10, 0x08, 0x00, + 0x08, 0x04, 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, 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, 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, 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, 0x00, 0x00, + 0x18, 0x0c, 0x00, 0x38, 0x24, 0x00, 0x88, 0x68, 0x18, 0xa8, 0x84, 0x18, + 0xb0, 0x88, 0x08, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x94, 0x08, 0xb0, 0x8c, 0x18, + 0x78, 0x64, 0x18, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0x98, 0x9c, 0x98, + 0x10, 0x10, 0x10, 0x18, 0x1c, 0x18, 0xb8, 0xb8, 0xb8, 0xf8, 0xf8, 0xf8, + 0x78, 0x7c, 0x78, 0xd8, 0xdc, 0xd8, 0x98, 0x9c, 0x98, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0xe8, 0xec, 0xe8, 0x58, 0x5c, 0x58, + 0x00, 0x00, 0x00, 0x50, 0x50, 0x50, 0xe8, 0xe8, 0xe8, 0xd0, 0xd4, 0xd0, + 0x80, 0x84, 0x80, 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xc8, 0xcc, 0xc8, 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xf0, 0xf0, 0xf0, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x60, 0x60, 0xf0, 0xf0, 0xf0, 0x78, 0x7c, 0x78, 0xa8, 0xac, 0xa8, + 0xe8, 0xe8, 0xe8, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x60, 0x60, 0xf8, 0xf8, 0xf8, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x78, 0x78, 0x78, 0xe8, 0xec, 0xe8, 0x58, 0x58, 0x58, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, + 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, + 0x68, 0x6c, 0x68, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0xc8, 0xcc, 0xc8, + 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xe8, 0xec, 0xe8, 0x60, 0x60, 0x60, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0x98, 0x9c, 0x98, + 0x00, 0x00, 0x00, 0x20, 0x24, 0x20, 0xc0, 0xc0, 0xc0, 0xe0, 0xe4, 0xe0, + 0x90, 0x90, 0x90, 0xe0, 0xe0, 0xe0, 0x90, 0x90, 0x90, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa0, 0x74, 0x08, 0x98, 0x70, 0x18, + 0x78, 0x54, 0x10, 0x38, 0x20, 0x00, 0x10, 0x08, 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, 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, + 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, 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, 0x10, 0x08, 0x00, 0x38, 0x28, 0x00, 0x78, 0x60, 0x10, + 0xa8, 0x84, 0x18, 0xb0, 0x8c, 0x08, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x08, 0xb0, 0x8c, 0x18, + 0x80, 0x68, 0x18, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xc0, 0xc0, 0xc0, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x48, 0x4c, 0x48, 0xe0, 0xe0, 0xe0, + 0xe8, 0xec, 0xe8, 0xf0, 0xf0, 0xf0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0xe8, 0xec, 0xe8, 0x60, 0x60, 0x60, + 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x88, 0x88, 0x88, 0xf8, 0xf8, 0xf8, + 0xe0, 0xe0, 0xe0, 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x10, 0x10, 0x10, 0xc0, 0xc4, 0xc0, 0xd0, 0xd0, 0xd0, 0x20, 0x24, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, + 0xe8, 0xe8, 0xe8, 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x2c, 0x28, 0xd0, 0xd4, 0xd0, 0xe0, 0xe4, 0xe0, 0xe0, 0xe0, 0xe0, + 0x98, 0x9c, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0xbc, 0xb8, 0xf8, 0xfc, 0xf8, 0xd8, 0xdc, 0xd8, 0xd0, 0xd0, 0xd0, + 0xd0, 0xd0, 0xd0, 0xd8, 0xdc, 0xd8, 0xf8, 0xfc, 0xf8, 0x98, 0x98, 0x98, + 0x08, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, + 0xf8, 0xfc, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, + 0x68, 0x6c, 0x68, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xc0, 0xc4, 0xc0, + 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0xe8, 0xe8, 0xe8, 0x50, 0x50, 0x50, + 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x44, 0x40, 0xf8, 0xf8, 0xf8, + 0xe8, 0xec, 0xe8, 0xf0, 0xf4, 0xf0, 0x88, 0x8c, 0x88, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa0, 0x74, 0x08, 0x98, 0x6c, 0x18, 0x78, 0x58, 0x18, + 0x28, 0x14, 0x00, 0x10, 0x04, 0x00, 0x08, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x28, 0x1c, 0x00, + 0x70, 0x5c, 0x10, 0xa8, 0x88, 0x18, 0xb0, 0x8c, 0x08, 0xb8, 0x90, 0x00, + 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x08, 0xb8, 0x90, 0x08, 0xb0, 0x8c, 0x18, + 0x80, 0x68, 0x18, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0x98, 0x9c, 0x98, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x74, 0x70, + 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0xe8, 0xec, 0xe8, 0x60, 0x60, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xb8, 0xb8, 0xb8, + 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x98, 0x98, 0x98, 0xe8, 0xe8, 0xe8, 0x60, 0x64, 0x60, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x24, 0x20, 0xd0, 0xd0, 0xd0, + 0xd0, 0xd4, 0xd0, 0x28, 0x2c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0xa0, 0xa0, 0xf8, 0xfc, 0xf8, 0xf8, 0xf8, 0xf8, + 0x48, 0x4c, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x18, + 0xf8, 0xfc, 0xf8, 0xd8, 0xd8, 0xd8, 0xa8, 0xac, 0xa8, 0xa8, 0xac, 0xa8, + 0xa8, 0xac, 0xa8, 0xa8, 0xac, 0xa8, 0xd8, 0xdc, 0xd8, 0xd8, 0xdc, 0xd8, + 0x28, 0x2c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xf8, 0xfc, 0xf8, 0x78, 0x7c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, + 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x98, 0x98, + 0xe8, 0xec, 0xe8, 0x60, 0x64, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x24, 0x20, 0xd0, 0xd0, 0xd0, 0xd0, 0xd4, 0xd0, 0x28, 0x2c, 0x28, + 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x88, + 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xf8, 0x88, 0x8c, 0x88, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa0, 0x74, 0x08, 0x98, 0x70, 0x10, 0x78, 0x54, 0x10, 0x30, 0x1c, 0x00, + 0x10, 0x04, 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, 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, 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, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, + 0x28, 0x1c, 0x00, 0x78, 0x64, 0x18, 0xa8, 0x88, 0x18, 0xb0, 0x90, 0x10, + 0xb8, 0x90, 0x08, 0xb8, 0x90, 0x08, 0xb8, 0x94, 0x08, 0xb0, 0x90, 0x18, + 0x80, 0x68, 0x20, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x1c, 0x18, 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, + 0xc8, 0xc8, 0xc8, 0xf8, 0xfc, 0xf8, 0x98, 0x9c, 0x98, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x58, 0x5c, 0x58, 0xe8, 0xec, 0xe8, 0x60, 0x60, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3c, 0x38, + 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x34, 0x30, 0xe8, 0xe8, 0xe8, 0xd8, 0xd8, 0xd8, + 0x80, 0x84, 0x80, 0x70, 0x74, 0x70, 0xb8, 0xb8, 0xb8, 0xf8, 0xf8, 0xf8, + 0x78, 0x7c, 0x78, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x54, 0x50, 0xf8, 0xfc, 0xf8, 0xd8, 0xd8, 0xd8, + 0x28, 0x2c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x74, 0x70, + 0xf0, 0xf0, 0xf0, 0x68, 0x68, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, 0xf8, 0xf8, 0xf8, + 0x68, 0x68, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xf8, 0xfc, 0xf8, 0x78, 0x7c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, + 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x34, 0x30, + 0xe8, 0xe8, 0xe8, 0xd8, 0xd8, 0xd8, 0x80, 0x84, 0x80, 0x70, 0x74, 0x70, + 0xb8, 0xb8, 0xb8, 0xf8, 0xf8, 0xf8, 0x78, 0x7c, 0x78, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x24, 0x20, + 0xc0, 0xc0, 0xc0, 0xf8, 0xfc, 0xf8, 0x90, 0x90, 0x90, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x08, + 0x98, 0x70, 0x10, 0x78, 0x5c, 0x10, 0x30, 0x20, 0x00, 0x10, 0x04, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x08, 0x00, 0x30, 0x24, 0x00, 0x80, 0x6c, 0x18, 0xa8, 0x88, 0x20, + 0xb8, 0x90, 0x10, 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xb0, 0x8c, 0x18, + 0x80, 0x68, 0x20, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x1c, 0x18, 0xa8, 0xb0, 0xb0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xec, 0xe8, 0x90, 0x94, 0x90, + 0x08, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x4c, 0x48, 0xe0, 0xe0, 0xe0, 0x90, 0x94, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xd8, 0xdc, 0xd8, 0x58, 0x58, 0x58, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x98, 0x98, 0x98, 0xe8, 0xec, 0xe8, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x44, 0x40, 0xb0, 0xb4, 0xb0, + 0xe8, 0xe8, 0xe8, 0xe0, 0xe4, 0xe0, 0xd8, 0xd8, 0xd8, 0x78, 0x78, 0x78, + 0x08, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0xe0, 0xe4, 0xe0, 0x90, 0x94, 0x90, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x08, 0x0c, 0x08, 0xb0, 0xb0, 0xb0, + 0xc8, 0xc8, 0xc8, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x34, 0x30, 0xd8, 0xd8, 0xd8, + 0xb0, 0xb0, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, + 0xe8, 0xec, 0xe8, 0x70, 0x74, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0xe8, 0xec, 0xe8, + 0x60, 0x64, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x48, 0x48, 0xb0, 0xb4, 0xb0, 0xe8, 0xe8, 0xe8, 0xe0, 0xe4, 0xe0, + 0xd8, 0xd8, 0xd8, 0x78, 0x78, 0x78, 0x08, 0x0c, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, 0xc8, 0xcc, 0xc8, 0x90, 0x94, 0x90, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x5c, 0x58, 0xd8, 0xdc, 0xd8, 0x80, 0x84, 0x80, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, 0xa0, 0x74, 0x08, + 0x88, 0x64, 0x18, 0x30, 0x20, 0x00, 0x10, 0x04, 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, 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, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, 0x10, 0x04, 0x00, + 0x10, 0x08, 0x00, 0x10, 0x08, 0x00, 0x10, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x00, 0x04, 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, 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, 0x10, 0x08, 0x00, 0x38, 0x28, 0x00, 0x88, 0x70, 0x20, + 0xb0, 0x8c, 0x20, 0xb8, 0x94, 0x10, 0xb8, 0x94, 0x10, 0xb0, 0x90, 0x20, + 0x80, 0x68, 0x20, 0x28, 0x1c, 0x00, 0x08, 0x04, 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, 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, + 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, + 0x18, 0x1c, 0x18, 0x20, 0x24, 0x20, 0x08, 0x08, 0x08, 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, 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, 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, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x24, 0x20, + 0x08, 0x08, 0x08, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa0, 0x74, 0x08, 0x90, 0x6c, 0x10, + 0x50, 0x38, 0x00, 0x10, 0x08, 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, 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, 0x04, 0x00, 0x10, 0x08, 0x00, 0x18, 0x0c, 0x00, 0x28, 0x18, 0x00, + 0x38, 0x28, 0x00, 0x40, 0x30, 0x00, 0x50, 0x3c, 0x00, 0x50, 0x3c, 0x00, + 0x58, 0x3c, 0x00, 0x58, 0x40, 0x00, 0x48, 0x30, 0x00, 0x38, 0x28, 0x00, + 0x28, 0x1c, 0x00, 0x18, 0x10, 0x00, 0x10, 0x0c, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x48, 0x34, 0x00, + 0xa0, 0x88, 0x28, 0xb0, 0x90, 0x18, 0xb8, 0x94, 0x18, 0xb0, 0x90, 0x20, + 0x80, 0x68, 0x20, 0x28, 0x1c, 0x00, 0x08, 0x04, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa0, 0x78, 0x08, 0x98, 0x70, 0x10, 0x60, 0x48, 0x08, + 0x20, 0x10, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, 0x18, 0x0c, 0x00, 0x20, 0x14, 0x00, + 0x38, 0x24, 0x00, 0x58, 0x44, 0x08, 0x78, 0x5c, 0x18, 0x80, 0x68, 0x20, + 0x88, 0x6c, 0x18, 0x90, 0x74, 0x18, 0x98, 0x78, 0x18, 0x98, 0x78, 0x18, + 0x98, 0x78, 0x18, 0x98, 0x78, 0x18, 0x98, 0x74, 0x18, 0x90, 0x70, 0x18, + 0x88, 0x6c, 0x20, 0x78, 0x60, 0x20, 0x58, 0x48, 0x08, 0x38, 0x28, 0x00, + 0x20, 0x14, 0x00, 0x18, 0x0c, 0x00, 0x08, 0x08, 0x00, 0x08, 0x04, 0x00, + 0x00, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x0c, 0x00, + 0x68, 0x50, 0x08, 0xa8, 0x8c, 0x28, 0xb8, 0x90, 0x20, 0xb0, 0x90, 0x28, + 0x80, 0x68, 0x28, 0x28, 0x1c, 0x00, 0x08, 0x04, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0x98, 0x74, 0x10, 0x78, 0x58, 0x10, 0x30, 0x1c, 0x00, + 0x10, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x18, 0x0c, 0x00, 0x38, 0x24, 0x00, 0x60, 0x48, 0x00, 0x88, 0x68, 0x10, + 0x98, 0x78, 0x18, 0xa0, 0x7c, 0x10, 0xa0, 0x7c, 0x10, 0xa8, 0x80, 0x10, + 0xa8, 0x80, 0x08, 0xa8, 0x80, 0x08, 0xa8, 0x84, 0x08, 0xa8, 0x84, 0x08, + 0xa8, 0x84, 0x08, 0xb0, 0x84, 0x08, 0xa8, 0x84, 0x08, 0xa8, 0x84, 0x08, + 0xa8, 0x84, 0x10, 0xa8, 0x80, 0x10, 0xa8, 0x80, 0x18, 0xa0, 0x80, 0x20, + 0x88, 0x6c, 0x18, 0x60, 0x48, 0x00, 0x38, 0x28, 0x00, 0x18, 0x10, 0x00, + 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x28, 0x1c, 0x00, 0x78, 0x68, 0x20, 0xb0, 0x8c, 0x28, 0xb0, 0x90, 0x28, + 0x80, 0x68, 0x28, 0x28, 0x1c, 0x00, 0x08, 0x04, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x74, 0x00, 0xb0, 0x78, 0x00, 0xb0, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa0, 0x74, 0x08, 0x90, 0x6c, 0x18, 0x40, 0x28, 0x00, 0x10, 0x08, 0x00, + 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x18, 0x08, 0x00, 0x30, 0x20, 0x00, + 0x58, 0x48, 0x08, 0x80, 0x68, 0x18, 0xa0, 0x7c, 0x18, 0xa8, 0x80, 0x10, + 0xa8, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x88, 0x00, 0xb0, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb0, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb0, 0x88, 0x08, + 0xb0, 0x88, 0x10, 0xa0, 0x84, 0x18, 0x90, 0x70, 0x18, 0x60, 0x4c, 0x10, + 0x30, 0x24, 0x00, 0x18, 0x0c, 0x00, 0x08, 0x04, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x40, 0x30, 0x00, 0x98, 0x80, 0x28, 0xa8, 0x90, 0x38, + 0x80, 0x68, 0x28, 0x28, 0x1c, 0x00, 0x08, 0x04, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xb0, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xa0, 0x78, 0x08, + 0x98, 0x70, 0x10, 0x68, 0x4c, 0x08, 0x18, 0x0c, 0x00, 0x08, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x20, 0x14, 0x00, 0x50, 0x38, 0x00, 0x88, 0x6c, 0x18, + 0x98, 0x78, 0x10, 0xa8, 0x80, 0x10, 0xa8, 0x80, 0x08, 0xb0, 0x84, 0x00, + 0xb8, 0x88, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb0, 0x88, 0x08, 0xa8, 0x88, 0x08, 0xa0, 0x84, 0x18, + 0x90, 0x70, 0x18, 0x58, 0x44, 0x00, 0x20, 0x14, 0x00, 0x10, 0x08, 0x00, + 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x68, 0x54, 0x18, 0xa0, 0x8c, 0x40, + 0x78, 0x68, 0x30, 0x28, 0x1c, 0x00, 0x08, 0x04, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa0, 0x78, 0x08, + 0x80, 0x60, 0x18, 0x38, 0x24, 0x00, 0x08, 0x04, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x30, 0x24, 0x00, 0x70, 0x54, 0x10, 0x98, 0x78, 0x18, 0xa8, 0x80, 0x10, + 0xa8, 0x84, 0x08, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb0, 0x84, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb0, 0x8c, 0x08, + 0xb0, 0x88, 0x10, 0xa0, 0x84, 0x20, 0x70, 0x5c, 0x18, 0x38, 0x28, 0x00, + 0x18, 0x0c, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x20, 0x14, 0x00, 0x90, 0x7c, 0x48, + 0x78, 0x68, 0x38, 0x20, 0x18, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x40, 0x40, 0x40, + 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x28, 0x2c, 0x28, 0x08, 0x08, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, + 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, + 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x44, 0x40, 0x40, 0x40, 0x40, 0x08, 0x08, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, + 0x40, 0x40, 0x40, 0x40, 0x44, 0x40, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, + 0x40, 0x44, 0x40, 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, + 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, 0x48, 0x48, 0x48, + 0x10, 0x14, 0x10, 0x00, 0x00, 0x00, 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, + 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, + 0x50, 0x50, 0x50, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, + 0x48, 0x4c, 0x48, 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, 0x50, 0x54, 0x50, + 0x50, 0x54, 0x50, 0x40, 0x44, 0x40, 0x18, 0x18, 0x18, 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, 0x10, 0x14, 0x10, 0x48, 0x48, 0x48, + 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x24, 0x20, + 0x50, 0x50, 0x50, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0x50, 0x54, 0x50, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x08, 0x08, 0x30, 0x30, 0x30, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, + 0x38, 0x3c, 0x38, 0x08, 0x0c, 0x08, 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, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x78, 0x00, 0xb0, 0x78, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x78, 0x00, 0x98, 0x70, 0x10, + 0x58, 0x40, 0x08, 0x18, 0x0c, 0x00, 0x08, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x18, 0x08, 0x00, 0x40, 0x28, 0x00, + 0x80, 0x64, 0x18, 0xa0, 0x7c, 0x18, 0xa8, 0x80, 0x08, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb0, 0x88, 0x00, 0xb0, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb0, 0x8c, 0x00, 0xb0, 0x8c, 0x08, 0xa8, 0x84, 0x18, 0x88, 0x6c, 0x18, + 0x48, 0x34, 0x00, 0x10, 0x0c, 0x00, 0x08, 0x04, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x50, 0x48, 0x28, + 0x70, 0x64, 0x40, 0x20, 0x18, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x90, 0x94, 0x90, 0xe0, 0xe4, 0xe0, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xc8, 0xcc, 0xc8, 0x70, 0x70, 0x70, + 0x08, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, + 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0xb8, 0xbc, 0xb8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0xcc, 0xc8, 0xe8, 0xe8, 0xe8, 0x50, 0x50, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, + 0xc0, 0xc0, 0xc0, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, + 0xc8, 0xcc, 0xc8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, + 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0xe0, 0xe0, 0xe0, + 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, + 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, + 0xe8, 0xec, 0xe8, 0x58, 0x5c, 0x58, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xd8, 0xdc, 0xd8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, + 0xf8, 0xfc, 0xf8, 0xe8, 0xe8, 0xe8, 0xa8, 0xa8, 0xa8, 0x20, 0x24, 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, 0x40, 0x40, 0x40, 0xe0, 0xe0, 0xe0, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x98, 0x9c, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x7c, 0x78, 0xf8, 0xfc, 0xf8, + 0x28, 0x2c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0c, 0x08, + 0x78, 0x78, 0x78, 0xd0, 0xd0, 0xd0, 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xf8, + 0xe0, 0xe0, 0xe0, 0x88, 0x8c, 0x88, 0x18, 0x1c, 0x18, 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, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x10, 0x88, 0x64, 0x10, + 0x30, 0x20, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x10, 0x08, 0x00, 0x40, 0x2c, 0x00, 0x80, 0x68, 0x18, + 0xa0, 0x7c, 0x10, 0xb0, 0x84, 0x08, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x08, 0xa8, 0x88, 0x18, + 0x98, 0x7c, 0x28, 0x40, 0x30, 0x00, 0x18, 0x0c, 0x00, 0x08, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x28, 0x20, 0x08, + 0x50, 0x4c, 0x38, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x10, 0x10, 0x90, 0x94, 0x90, 0xf0, 0xf4, 0xf0, 0x90, 0x90, 0x90, + 0x30, 0x34, 0x30, 0x38, 0x38, 0x38, 0xd0, 0xd0, 0xd0, 0xf0, 0xf0, 0xf0, + 0x50, 0x54, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xe0, 0xe4, 0xe0, 0x58, 0x5c, 0x58, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0xcc, 0xc8, 0xf8, 0xfc, 0xf8, 0xd0, 0xd4, 0xd0, + 0x10, 0x14, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, + 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xc8, 0xc8, 0xc8, + 0xd0, 0xd4, 0xd0, 0x40, 0x44, 0x40, 0x28, 0x28, 0x28, 0x20, 0x24, 0x20, + 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa8, 0xac, 0xa8, + 0x30, 0x34, 0x30, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x20, 0x24, 0x20, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xd8, 0xdc, 0xd8, 0xa8, 0xac, 0xa8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x80, 0x84, 0x80, 0xe8, 0xec, 0xe8, 0xa8, 0xa8, 0xa8, + 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, 0x38, 0x3c, 0x38, 0xd8, 0xdc, 0xd8, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x6c, 0x68, + 0xf8, 0xfc, 0xf8, 0xf0, 0xf4, 0xf0, 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x7c, 0x78, 0xf8, 0xfc, 0xf8, + 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x68, 0x68, + 0xf0, 0xf0, 0xf0, 0xb8, 0xbc, 0xb8, 0x38, 0x38, 0x38, 0x30, 0x34, 0x30, + 0xa0, 0xa0, 0xa0, 0xf0, 0xf4, 0xf0, 0x88, 0x88, 0x88, 0x08, 0x08, 0x08, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x78, 0x08, 0x98, 0x74, 0x18, 0x60, 0x44, 0x08, + 0x18, 0x0c, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x48, 0x34, 0x00, 0x88, 0x6c, 0x18, 0xa0, 0x7c, 0x10, + 0xa8, 0x80, 0x08, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x08, 0xb8, 0x8c, 0x10, + 0xb0, 0x8c, 0x18, 0x98, 0x7c, 0x20, 0x48, 0x38, 0x00, 0x10, 0x0c, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x20, 0x20, 0x10, 0x18, 0x10, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x2c, 0x28, 0xd8, 0xdc, 0xd8, 0xb8, 0xbc, 0xb8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x34, 0x30, 0xd0, 0xd0, 0xd0, + 0xb0, 0xb0, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xd8, 0xdc, 0xd8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0xcc, 0xc8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xf8, + 0x88, 0x8c, 0x88, 0x08, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x18, + 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xbc, 0xb8, + 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0x98, 0x9c, 0x98, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xe0, 0xe0, 0xe0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xb0, 0xb0, 0xb0, 0xe8, 0xec, 0xe8, + 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, 0x40, 0x40, 0x40, 0xe0, 0xe0, 0xe0, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0xf8, 0xf8, 0xf8, 0xc8, 0xcc, 0xc8, 0x28, 0x2c, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x7c, 0x78, 0xf8, 0xfc, 0xf8, + 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd0, + 0xd0, 0xd0, 0xd0, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x08, 0x08, 0xc0, 0xc4, 0xc0, 0xc0, 0xc4, 0xc0, 0x28, 0x28, 0x28, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, + 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xa8, 0x7c, 0x00, 0xa0, 0x74, 0x08, 0x90, 0x6c, 0x20, 0x30, 0x1c, 0x00, + 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x30, 0x20, 0x00, 0x88, 0x68, 0x20, 0xa0, 0x7c, 0x10, 0xb0, 0x84, 0x08, + 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, + 0xc0, 0x94, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x08, 0xb8, 0x90, 0x08, + 0xb8, 0x94, 0x10, 0xb0, 0x8c, 0x18, 0x88, 0x74, 0x20, 0x38, 0x2c, 0x00, + 0x10, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x3c, 0x38, 0xf8, 0xf8, 0xf8, 0x78, 0x7c, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x38, 0x3c, 0x38, + 0x40, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xd8, 0xdc, 0xd8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0xcc, 0xc8, 0xd8, 0xd8, 0xd8, 0xd8, 0xdc, 0xd8, + 0xe0, 0xe4, 0xe0, 0x50, 0x54, 0x50, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, + 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xbc, 0xb8, + 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x14, 0x10, 0xa8, 0xa8, 0xa8, 0xf0, 0xf0, 0xf0, + 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, 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x6c, 0x68, + 0xf8, 0xfc, 0xf8, 0xb8, 0xb8, 0xb8, 0xf8, 0xf8, 0xf8, 0x90, 0x94, 0x90, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xf8, 0xfc, 0xf8, + 0x28, 0x2c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf4, 0xf0, + 0xa8, 0xa8, 0xa8, 0x10, 0x14, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x34, 0x30, 0x40, 0x44, 0x40, 0x10, 0x10, 0x10, + 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xa8, 0x7c, 0x00, 0xa0, 0x74, 0x10, 0x70, 0x54, 0x18, 0x18, 0x08, 0x00, + 0x08, 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, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x28, 0x18, 0x00, + 0x78, 0x5c, 0x10, 0xa0, 0x80, 0x18, 0xa8, 0x80, 0x08, 0xb0, 0x84, 0x00, + 0xb0, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, + 0xb8, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, 0xb8, 0x94, 0x08, + 0xc0, 0x94, 0x10, 0xb8, 0x90, 0x10, 0xa8, 0x8c, 0x20, 0x88, 0x70, 0x20, + 0x20, 0x14, 0x00, 0x08, 0x04, 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, 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, + 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, 0x68, 0x6c, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xe8, 0xe8, 0xe8, 0x70, 0x74, 0x70, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, + 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0xcc, 0xc8, 0xc0, 0xc0, 0xc0, 0x58, 0x5c, 0x58, + 0xf0, 0xf4, 0xf0, 0xc0, 0xc0, 0xc0, 0x28, 0x28, 0x28, 0x20, 0x20, 0x20, + 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xbc, 0xb8, + 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xb8, 0xb8, 0xb8, + 0x50, 0x54, 0x50, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, + 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xd8, 0xdc, 0xd8, 0xa8, 0xa8, 0xa8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x70, 0x74, 0x70, 0xe8, 0xe8, 0xe8, 0xa8, 0xa8, 0xa8, + 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, 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, + 0x90, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x48, 0x4c, 0x48, 0xc8, 0xc8, 0xc8, 0xe8, 0xec, 0xe8, + 0x50, 0x54, 0x50, 0x00, 0x00, 0x00, 0x78, 0x7c, 0x78, 0xf8, 0xfc, 0xf8, + 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, + 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xa8, 0x7c, 0x08, 0x98, 0x74, 0x18, 0x48, 0x34, 0x00, 0x10, 0x04, 0x00, + 0x08, 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, 0x08, 0x00, 0x00, 0x18, 0x10, 0x00, 0x60, 0x48, 0x10, + 0xa0, 0x7c, 0x18, 0xb0, 0x80, 0x08, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x08, 0xc0, 0x90, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x10, 0xb8, 0x94, 0x18, 0xa8, 0x8c, 0x28, + 0x68, 0x54, 0x18, 0x18, 0x10, 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, 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, + 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xf8, 0xf8, 0xf8, 0xe8, 0xec, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, + 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0xcc, 0xc8, 0xc0, 0xc0, 0xc0, 0x18, 0x1c, 0x18, + 0x80, 0x84, 0x80, 0xf8, 0xf8, 0xf8, 0x98, 0x98, 0x98, 0x20, 0x24, 0x20, + 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, + 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xf8, 0xf8, 0xf8, + 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, + 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xd8, 0xdc, 0xd8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, + 0xf8, 0xfc, 0xf8, 0xf0, 0xf0, 0xf0, 0xa8, 0xac, 0xa8, 0x28, 0x28, 0x28, + 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, 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xe0, 0xe0, 0xe0, + 0xe0, 0xe0, 0xe0, 0x18, 0x1c, 0x18, 0x78, 0x7c, 0x78, 0xf8, 0xfc, 0xf8, + 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, + 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x78, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x7c, 0x08, 0x80, 0x64, 0x10, 0x30, 0x1c, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x08, 0x04, 0x00, 0x40, 0x2c, 0x00, 0x90, 0x70, 0x18, + 0xa8, 0x80, 0x10, 0xb0, 0x88, 0x00, 0xb8, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x98, 0x10, 0xb8, 0x98, 0x10, 0xb8, 0x98, 0x18, 0xb0, 0x94, 0x20, + 0x98, 0x80, 0x30, 0x40, 0x34, 0x00, 0x08, 0x08, 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, 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, + 0x40, 0x40, 0x40, 0xf8, 0xfc, 0xf8, 0x68, 0x6c, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xe8, 0xe8, 0xe8, 0x78, 0x78, 0x78, 0x48, 0x4c, 0x48, 0x48, 0x4c, 0x48, + 0x48, 0x4c, 0x48, 0x48, 0x4c, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0xcc, 0xc8, 0xb8, 0xbc, 0xb8, 0x20, 0x20, 0x20, + 0x20, 0x24, 0x20, 0xb8, 0xbc, 0xb8, 0xf0, 0xf4, 0xf0, 0x60, 0x64, 0x60, + 0xb8, 0xbc, 0xb8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xbc, 0xb8, + 0xd0, 0xd0, 0xd0, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xb8, 0xbc, 0xb8, + 0x58, 0x58, 0x58, 0x48, 0x4c, 0x48, 0x48, 0x4c, 0x48, 0x48, 0x4c, 0x48, + 0x28, 0x2c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, + 0xd8, 0xdc, 0xd8, 0xc0, 0xc4, 0xc0, 0x60, 0x64, 0x60, 0x78, 0x78, 0x78, + 0xe0, 0xe0, 0xe0, 0xd8, 0xd8, 0xd8, 0x30, 0x34, 0x30, 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, 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, + 0x90, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x6c, 0x68, + 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x08, 0x0c, 0x08, 0x80, 0x80, 0x80, + 0xf0, 0xf4, 0xf0, 0x90, 0x90, 0x90, 0x88, 0x88, 0x88, 0xf8, 0xfc, 0xf8, + 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, + 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 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, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0x70, 0x50, 0x08, 0x20, 0x10, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x78, 0x60, 0x18, 0xa0, 0x80, 0x10, + 0xb0, 0x84, 0x08, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb0, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xb8, 0x94, 0x00, + 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xb8, 0x94, 0x20, + 0xb0, 0x90, 0x28, 0x78, 0x64, 0x18, 0x20, 0x14, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x3c, 0x38, 0xf8, 0xfc, 0xf8, 0x70, 0x74, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x14, 0x10, + 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xe0, 0xe0, 0xe0, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0xcc, 0xc8, 0xc0, 0xc0, 0xc0, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x48, 0x4c, 0x48, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xd8, 0xdc, 0xd8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xbc, 0xb8, + 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xa0, 0xa0, 0xa0, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, + 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x88, 0x8c, 0x88, 0xf0, 0xf0, 0xf0, 0x70, 0x70, 0x70, 0x00, 0x04, 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, 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x70, + 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, + 0xb8, 0xb8, 0xb8, 0xe8, 0xe8, 0xe8, 0xd0, 0xd4, 0xd0, 0xf8, 0xfc, 0xf8, + 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, + 0xa0, 0xa0, 0xa0, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x18, 0x18, 0x18, 0x00, 0x04, 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x74, 0x18, 0x58, 0x40, 0x00, 0x10, 0x08, 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, 0x00, 0x00, + 0x08, 0x08, 0x00, 0x38, 0x2c, 0x00, 0x98, 0x7c, 0x18, 0xb0, 0x84, 0x08, + 0xb0, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xb8, 0x94, 0x00, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xb8, 0x98, 0x18, + 0xb8, 0x94, 0x28, 0xa8, 0x8c, 0x38, 0x48, 0x38, 0x08, 0x08, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x2c, 0x28, 0xd8, 0xdc, 0xd8, 0xb8, 0xb8, 0xb8, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x34, 0x30, 0xd8, 0xd8, 0xd8, + 0xc0, 0xc4, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, + 0xe0, 0xe0, 0xe0, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0xcc, 0xc8, 0xc0, 0xc0, 0xc0, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x78, 0x7c, 0x78, 0xf8, 0xfc, 0xf8, + 0xf8, 0xfc, 0xf8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xbc, 0xb8, + 0xc8, 0xcc, 0xc8, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0x98, 0x9c, 0x98, + 0x08, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x2c, 0x30, + 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x1c, 0x18, 0xe8, 0xec, 0xe8, 0xd0, 0xd4, 0xd0, 0x28, 0x2c, 0x28, + 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, 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, + 0x90, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x70, 0x68, + 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x34, 0x30, 0xe8, 0xec, 0xe8, 0xf8, 0xfc, 0xf8, 0xf8, 0xfc, 0xf8, + 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xcc, 0xc8, + 0xc8, 0xd0, 0xd0, 0x28, 0x2c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x08, 0x08, 0xc0, 0xc4, 0xc0, 0xd8, 0xd8, 0xd8, 0x28, 0x2c, 0x28, + 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x10, 0x14, 0x18, 0x08, 0x0c, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x88, 0x6c, 0x18, 0x40, 0x2c, 0x00, 0x10, 0x04, 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, 0x08, 0x04, 0x00, + 0x18, 0x10, 0x00, 0x68, 0x54, 0x10, 0xa8, 0x80, 0x10, 0xb0, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xc0, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, + 0xc0, 0x98, 0x20, 0xb0, 0x94, 0x30, 0x80, 0x6c, 0x30, 0x18, 0x0c, 0x00, + 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x14, 0x10, 0xa0, 0xa0, 0xa0, 0xf0, 0xf0, 0xf0, 0x78, 0x78, 0x78, + 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0xa8, 0xac, 0xa8, 0xf0, 0xf4, 0xf0, + 0x68, 0x68, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, + 0xe8, 0xe8, 0xe8, 0x78, 0x78, 0x78, 0x48, 0x4c, 0x48, 0x48, 0x4c, 0x48, + 0x48, 0x4c, 0x48, 0x48, 0x4c, 0x48, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd0, 0xb8, 0xbc, 0xb8, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x14, 0x10, 0xc8, 0xc8, 0xc8, + 0xf8, 0xfc, 0xf8, 0xc8, 0xcc, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xbc, 0xb8, + 0xc8, 0xcc, 0xc8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, 0xb8, 0xbc, 0xb8, + 0x58, 0x58, 0x58, 0x48, 0x4c, 0x48, 0x48, 0x4c, 0x48, 0x48, 0x4c, 0x48, + 0x40, 0x48, 0x40, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x2c, 0x30, + 0xd8, 0xdc, 0xd8, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x84, 0x80, 0xf8, 0xfc, 0xf8, 0x78, 0x7c, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x54, 0x50, 0x90, 0x90, 0x90, + 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xd8, 0xdc, 0xd8, + 0x88, 0x8c, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x68, + 0xf8, 0xfc, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x84, 0x80, 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xf8, + 0x28, 0x2c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x7c, 0x78, + 0xf0, 0xf0, 0xf0, 0xa0, 0xa4, 0xa0, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, + 0x78, 0x7c, 0x78, 0xf0, 0xf4, 0xf0, 0x98, 0x98, 0x98, 0x08, 0x0c, 0x08, + 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xb0, 0xb4, 0xb0, 0x60, 0x64, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa0, 0x7c, 0x10, + 0x80, 0x60, 0x18, 0x30, 0x1c, 0x00, 0x08, 0x04, 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, 0x08, 0x04, 0x00, + 0x38, 0x2c, 0x00, 0x88, 0x70, 0x18, 0xa8, 0x80, 0x10, 0xb0, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, + 0xc0, 0x98, 0x20, 0xb8, 0x98, 0x30, 0xa8, 0x8c, 0x40, 0x30, 0x20, 0x00, + 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0xb0, 0xb4, 0xb0, 0xe0, 0xe4, 0xe0, + 0xd8, 0xdc, 0xd8, 0xd8, 0xdc, 0xd8, 0xe0, 0xe0, 0xe0, 0x88, 0x88, 0x88, + 0x10, 0x14, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x84, 0x80, + 0xe8, 0xec, 0xe8, 0xe0, 0xe4, 0xe0, 0xd8, 0xdc, 0xd8, 0xd8, 0xdc, 0xd8, + 0xd8, 0xdc, 0xd8, 0xd8, 0xdc, 0xd8, 0xa8, 0xa8, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0xc4, 0xc0, 0xb0, 0xb4, 0xb0, 0x18, 0x1c, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x4c, 0x48, + 0xe0, 0xe4, 0xe0, 0xc0, 0xc4, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb4, 0xb0, + 0xc0, 0xc0, 0xc0, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xe8, 0xe8, 0xe8, + 0xd8, 0xe0, 0xe0, 0xd8, 0xdc, 0xd8, 0xd8, 0xdc, 0xd8, 0xd8, 0xdc, 0xd8, + 0xd0, 0xd0, 0xd0, 0x50, 0x54, 0x50, 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, + 0xd0, 0xd0, 0xd0, 0x90, 0x94, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0xc0, 0xc4, 0xc0, 0xd8, 0xdc, 0xd8, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xe8, 0xec, 0xe8, + 0x58, 0x5c, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0xd0, 0xd0, 0xd0, + 0x80, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x68, 0x68, + 0xf0, 0xf0, 0xf0, 0x38, 0x3c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x24, 0x20, 0xb8, 0xb8, 0xb8, 0xf0, 0xf0, 0xf0, + 0x28, 0x2c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, + 0x90, 0x94, 0x90, 0xe0, 0xe4, 0xe0, 0xd8, 0xdc, 0xe0, 0xd8, 0xdc, 0xe0, + 0xe0, 0xe4, 0xe0, 0xa8, 0xac, 0xa8, 0x20, 0x24, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x78, 0x78, 0x78, 0xf0, 0xf0, 0xf0, 0x80, 0x84, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, + 0x70, 0x58, 0x18, 0x20, 0x10, 0x00, 0x08, 0x04, 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, 0x10, 0x0c, 0x00, + 0x58, 0x44, 0x00, 0xa0, 0x7c, 0x18, 0xb0, 0x84, 0x08, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xb8, 0x98, 0x28, 0xb0, 0x90, 0x40, 0x60, 0x50, 0x18, + 0x10, 0x08, 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, 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, 0x04, 0x00, 0x50, 0x50, 0x50, + 0x70, 0x74, 0x70, 0x70, 0x70, 0x70, 0x30, 0x30, 0x30, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x2c, 0x28, + 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, + 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x38, 0x3c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x38, 0x3c, 0x38, 0x08, 0x08, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, + 0x38, 0x3c, 0x38, 0x40, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3c, 0x38, + 0x40, 0x40, 0x40, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, + 0x48, 0x50, 0x50, 0x48, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, + 0x48, 0x4c, 0x48, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, + 0x48, 0x44, 0x40, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x30, 0x30, 0x30, 0x50, 0x50, 0x50, + 0x10, 0x14, 0x10, 0x00, 0x00, 0x00, 0x88, 0x90, 0x90, 0xe8, 0xec, 0xe8, + 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x14, 0x10, 0x40, 0x44, 0x40, + 0x28, 0x2c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x24, 0x20, + 0x50, 0x50, 0x50, 0x10, 0x14, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0x50, 0x50, 0x50, + 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x38, 0x34, 0x30, 0x70, 0x70, 0x70, 0x70, 0x74, 0x70, + 0x48, 0x48, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0x50, 0x50, 0x50, 0x28, 0x2c, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, + 0x60, 0x48, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x08, 0x00, 0x00, 0x20, 0x14, 0x00, + 0x78, 0x58, 0x08, 0xa8, 0x80, 0x10, 0xb0, 0x88, 0x08, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x90, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x28, 0xc0, 0x98, 0x28, 0xb8, 0x94, 0x38, 0x88, 0x70, 0x30, + 0x18, 0x10, 0x00, 0x08, 0x04, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x90, 0xb8, 0xbc, 0xb8, + 0x28, 0x28, 0x28, 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, 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, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x74, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x18, + 0x48, 0x38, 0x00, 0x10, 0x08, 0x00, 0x08, 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, 0x08, 0x04, 0x00, 0x30, 0x20, 0x00, + 0x88, 0x6c, 0x10, 0xa8, 0x84, 0x08, 0xb0, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x90, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xb8, 0x98, 0x38, 0x98, 0x80, 0x38, + 0x30, 0x24, 0x00, 0x08, 0x04, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x48, 0x48, 0x18, 0x1c, 0x18, + 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x74, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x18, + 0x40, 0x2c, 0x00, 0x08, 0x04, 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, 0x08, 0x04, 0x00, 0x38, 0x2c, 0x00, + 0x98, 0x7c, 0x20, 0xb0, 0x84, 0x08, 0xb0, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x94, 0x00, 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc8, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x30, 0xa0, 0x88, 0x38, + 0x40, 0x34, 0x08, 0x08, 0x04, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa0, 0x7c, 0x18, + 0x38, 0x20, 0x00, 0x08, 0x04, 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, 0x10, 0x04, 0x00, 0x48, 0x38, 0x08, + 0xa0, 0x80, 0x20, 0xb0, 0x88, 0x08, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x90, 0x00, 0xb8, 0x94, 0x00, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x30, 0xb0, 0x94, 0x40, + 0x58, 0x48, 0x18, 0x08, 0x04, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x00, 0x98, 0x7c, 0x18, + 0x30, 0x20, 0x00, 0x08, 0x04, 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, 0x10, 0x08, 0x00, 0x58, 0x40, 0x08, + 0xa0, 0x80, 0x18, 0xb0, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x90, 0x00, + 0xc0, 0x94, 0x00, 0xb8, 0x94, 0x00, 0xb8, 0x94, 0x00, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x30, 0xc0, 0x9c, 0x30, 0xc0, 0x9c, 0x30, 0xb8, 0x98, 0x40, + 0x60, 0x50, 0x20, 0x10, 0x04, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa0, 0x74, 0x08, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xa0, 0x7c, 0x18, + 0x30, 0x20, 0x00, 0x08, 0x04, 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, 0x10, 0x08, 0x00, 0x68, 0x50, 0x10, + 0xa8, 0x84, 0x18, 0xb0, 0x88, 0x08, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x90, 0x00, + 0xb8, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc8, 0xa0, 0x28, 0xc8, 0xa0, 0x28, 0xc8, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x38, 0xb8, 0x98, 0x48, + 0x68, 0x54, 0x20, 0x10, 0x08, 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, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa8, 0x74, 0x08, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xa0, 0x78, 0x18, + 0x30, 0x20, 0x00, 0x08, 0x04, 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, 0x18, 0x0c, 0x00, 0x68, 0x54, 0x10, + 0xa8, 0x84, 0x18, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xb8, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x98, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xb8, 0x9c, 0x48, + 0x70, 0x60, 0x28, 0x18, 0x0c, 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, 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, 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, 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, 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, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x10, 0x04, 0x00, 0x18, 0x0c, 0x00, 0x18, 0x0c, 0x00, + 0x20, 0x10, 0x00, 0x28, 0x18, 0x00, 0x30, 0x1c, 0x00, 0x30, 0x1c, 0x00, + 0x28, 0x14, 0x00, 0x20, 0x10, 0x00, 0x20, 0x0c, 0x00, 0x18, 0x08, 0x00, + 0x10, 0x08, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x6c, 0x18, 0xa8, 0x74, 0x08, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xa0, 0x7c, 0x18, + 0x30, 0x20, 0x00, 0x08, 0x04, 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, 0x10, 0x0c, 0x00, 0x68, 0x54, 0x10, + 0xa8, 0x84, 0x18, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, + 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x38, 0xb8, 0x9c, 0x48, + 0x70, 0x60, 0x30, 0x10, 0x10, 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, 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, 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, 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, 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, 0x10, 0x0c, 0x00, 0x20, 0x18, 0x00, 0x28, 0x1c, 0x00, + 0x28, 0x18, 0x00, 0x28, 0x18, 0x00, 0x28, 0x18, 0x00, 0x28, 0x18, 0x00, + 0x28, 0x1c, 0x00, 0x20, 0x18, 0x00, 0x18, 0x10, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, 0x18, 0x0c, 0x00, 0x20, 0x14, 0x00, + 0x30, 0x20, 0x00, 0x48, 0x34, 0x00, 0x60, 0x48, 0x10, 0x70, 0x5c, 0x20, + 0x80, 0x64, 0x20, 0x88, 0x68, 0x20, 0x88, 0x68, 0x20, 0x88, 0x6c, 0x20, + 0x80, 0x64, 0x20, 0x80, 0x64, 0x20, 0x70, 0x58, 0x18, 0x60, 0x48, 0x10, + 0x48, 0x34, 0x00, 0x30, 0x20, 0x00, 0x20, 0x14, 0x00, 0x18, 0x0c, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 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, 0x00, 0x00, 0x00, + 0x60, 0x40, 0x00, 0x98, 0x70, 0x18, 0xa8, 0x74, 0x08, 0xa8, 0x78, 0x00, + 0xa8, 0x78, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x88, 0x00, 0xb0, 0x84, 0x00, 0xa0, 0x7c, 0x18, + 0x30, 0x20, 0x00, 0x08, 0x04, 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, 0x10, 0x0c, 0x00, 0x60, 0x50, 0x10, + 0xa8, 0x84, 0x18, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xb8, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, 0xb8, 0x9c, 0x48, + 0x60, 0x54, 0x20, 0x10, 0x08, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x50, 0x40, 0x18, 0x88, 0x70, 0x28, 0x98, 0x78, 0x18, + 0x98, 0x74, 0x18, 0x98, 0x74, 0x18, 0x98, 0x74, 0x18, 0x98, 0x78, 0x18, + 0x98, 0x78, 0x18, 0x90, 0x74, 0x28, 0x70, 0x58, 0x28, 0x18, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x20, 0x14, 0x00, 0x40, 0x2c, 0x00, 0x60, 0x44, 0x00, 0x80, 0x60, 0x10, + 0x98, 0x74, 0x18, 0xa0, 0x78, 0x18, 0xa0, 0x78, 0x10, 0xa0, 0x78, 0x10, + 0xa0, 0x78, 0x10, 0xa0, 0x78, 0x10, 0xa0, 0x7c, 0x10, 0xa0, 0x7c, 0x08, + 0xa0, 0x7c, 0x10, 0xa0, 0x78, 0x10, 0xa0, 0x78, 0x10, 0xa0, 0x78, 0x10, + 0xa0, 0x78, 0x18, 0x98, 0x74, 0x18, 0x78, 0x5c, 0x10, 0x60, 0x44, 0x08, + 0x40, 0x2c, 0x00, 0x20, 0x10, 0x00, 0x10, 0x08, 0x00, 0x08, 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, + 0x60, 0x40, 0x00, 0x98, 0x70, 0x18, 0xa8, 0x78, 0x08, 0xb0, 0x7c, 0x00, + 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb0, 0x84, 0x00, 0xa0, 0x7c, 0x18, + 0x30, 0x20, 0x00, 0x08, 0x04, 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, 0x10, 0x08, 0x00, 0x58, 0x44, 0x08, + 0xa0, 0x84, 0x18, 0xb0, 0x8c, 0x08, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x90, 0x00, + 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc8, 0xa4, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc0, 0xa4, 0x38, 0xc0, 0xa0, 0x40, 0xb8, 0x9c, 0x50, + 0x60, 0x50, 0x28, 0x08, 0x04, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x40, 0x10, 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x00, + 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x18, 0x0c, 0x00, + 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x10, 0x04, 0x00, 0x18, 0x0c, 0x00, 0x38, 0x28, 0x00, + 0x70, 0x54, 0x10, 0x88, 0x6c, 0x18, 0x98, 0x78, 0x18, 0xa0, 0x7c, 0x08, + 0xa8, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa8, 0x78, 0x10, 0x98, 0x78, 0x18, + 0x88, 0x6c, 0x18, 0x68, 0x50, 0x10, 0x48, 0x34, 0x00, 0x20, 0x10, 0x00, + 0x10, 0x04, 0x00, 0x08, 0x04, 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, + 0x60, 0x40, 0x00, 0x98, 0x70, 0x18, 0xa8, 0x78, 0x08, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xa0, 0x7c, 0x18, + 0x38, 0x28, 0x00, 0x08, 0x04, 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, 0x10, 0x04, 0x00, 0x48, 0x38, 0x00, + 0xa0, 0x84, 0x20, 0xb0, 0x8c, 0x08, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, + 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc8, 0xa0, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc0, 0xa0, 0x40, 0xb0, 0x94, 0x48, + 0x50, 0x44, 0x20, 0x08, 0x04, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x40, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x60, 0x18, 0x18, 0x0c, 0x00, + 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x18, 0x0c, 0x00, 0x38, 0x24, 0x00, 0x70, 0x54, 0x10, 0x90, 0x70, 0x18, + 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, 0x90, 0x70, 0x18, 0x78, 0x5c, 0x18, + 0x38, 0x28, 0x00, 0x20, 0x10, 0x00, 0x08, 0x04, 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, + 0x60, 0x40, 0x00, 0x98, 0x70, 0x18, 0xa8, 0x78, 0x08, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb0, 0x88, 0x00, 0xb0, 0x84, 0x00, 0xa8, 0x80, 0x18, + 0x48, 0x34, 0x00, 0x10, 0x08, 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, 0x08, 0x04, 0x00, 0x38, 0x28, 0x00, + 0x98, 0x7c, 0x20, 0xb0, 0x8c, 0x08, 0xb8, 0x90, 0x08, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x98, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x94, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x28, 0xc8, 0xa0, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc8, 0xa0, 0x28, 0xc8, 0xa0, 0x30, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc0, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x38, 0xc0, 0xa0, 0x40, 0xc0, 0xa0, 0x48, 0xa8, 0x8c, 0x48, + 0x40, 0x34, 0x10, 0x08, 0x04, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa0, 0x7c, 0x10, 0x78, 0x5c, 0x18, 0x18, 0x0c, 0x00, + 0x08, 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, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x20, 0x14, 0x00, + 0x50, 0x38, 0x00, 0x88, 0x6c, 0x20, 0xa0, 0x78, 0x18, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x90, 0x6c, 0x20, 0x60, 0x48, 0x10, 0x30, 0x1c, 0x00, 0x10, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x44, 0x00, 0x98, 0x70, 0x18, 0xa8, 0x78, 0x08, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xa8, 0x80, 0x18, + 0x58, 0x40, 0x08, 0x10, 0x08, 0x00, 0x08, 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, 0x08, 0x04, 0x00, 0x30, 0x20, 0x00, + 0x88, 0x70, 0x10, 0xb0, 0x8c, 0x10, 0xb8, 0x90, 0x08, 0xc0, 0x90, 0x00, + 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, + 0xc0, 0x98, 0x10, 0xb8, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x30, + 0xc0, 0x9c, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa4, 0x30, 0xc8, 0xa4, 0x38, 0xc0, 0xa0, 0x38, + 0xc0, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc0, 0xa4, 0x40, 0xc0, 0xa0, 0x48, 0x98, 0x84, 0x48, + 0x28, 0x20, 0x00, 0x00, 0x04, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 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, 0x08, 0x04, 0x00, 0x28, 0x1c, 0x00, 0x60, 0x48, 0x08, + 0x90, 0x70, 0x18, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x7c, 0x08, 0x98, 0x74, 0x18, 0x78, 0x5c, 0x18, 0x38, 0x24, 0x00, + 0x10, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x44, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x78, 0x08, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xa8, 0x80, 0x10, + 0x70, 0x54, 0x18, 0x18, 0x0c, 0x00, 0x08, 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, 0x18, 0x14, 0x00, + 0x70, 0x5c, 0x08, 0xb0, 0x8c, 0x18, 0xb8, 0x90, 0x10, 0xc0, 0x90, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc8, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, 0xc0, 0xa4, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc0, 0xa4, 0x48, 0xb8, 0xa0, 0x50, 0x88, 0x74, 0x40, + 0x10, 0x08, 0x00, 0x00, 0x04, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 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, 0x08, 0x00, 0x00, + 0x10, 0x04, 0x00, 0x28, 0x18, 0x00, 0x78, 0x60, 0x18, 0x98, 0x74, 0x18, + 0xa8, 0x7c, 0x08, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, 0x80, 0x68, 0x18, + 0x40, 0x30, 0x00, 0x18, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x44, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x78, 0x08, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xa8, 0x84, 0x10, + 0x80, 0x64, 0x20, 0x20, 0x14, 0x00, 0x08, 0x04, 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, 0x10, 0x08, 0x00, + 0x58, 0x40, 0x00, 0xa0, 0x84, 0x20, 0xb8, 0x90, 0x10, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc0, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc0, 0xa4, 0x48, 0xb8, 0x9c, 0x58, 0x58, 0x48, 0x18, + 0x08, 0x08, 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, 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, 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, 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, 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, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 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, 0x10, 0x08, 0x00, + 0x38, 0x20, 0x00, 0x78, 0x58, 0x10, 0xa0, 0x78, 0x18, 0xa8, 0x7c, 0x08, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa0, 0x7c, 0x08, + 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x88, 0x68, 0x18, 0x48, 0x34, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x44, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x78, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xa8, 0x84, 0x10, + 0x88, 0x6c, 0x18, 0x30, 0x24, 0x00, 0x08, 0x04, 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, 0x08, 0x04, 0x00, + 0x38, 0x28, 0x00, 0x90, 0x74, 0x20, 0xb0, 0x8c, 0x18, 0xb8, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xb8, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x94, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x30, + 0xc0, 0x9c, 0x30, 0xc0, 0x9c, 0x30, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc0, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc0, 0xa0, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc0, 0xa0, 0x48, 0xb0, 0x9c, 0x60, 0x28, 0x1c, 0x00, + 0x08, 0x04, 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, 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, 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, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 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, 0x04, 0x00, 0x30, 0x1c, 0x00, + 0x78, 0x58, 0x10, 0x98, 0x74, 0x18, 0xa8, 0x78, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, 0x98, 0x74, 0x10, + 0x98, 0x74, 0x18, 0x98, 0x74, 0x20, 0x90, 0x6c, 0x18, 0x90, 0x6c, 0x18, + 0x90, 0x74, 0x20, 0x98, 0x74, 0x18, 0xa0, 0x78, 0x18, 0xa0, 0x78, 0x10, + 0xa8, 0x7c, 0x10, 0xa8, 0x7c, 0x08, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x80, 0x00, + 0xa0, 0x7c, 0x10, 0x88, 0x6c, 0x18, 0x40, 0x2c, 0x00, 0x10, 0x08, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x44, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb0, 0x88, 0x08, + 0x98, 0x78, 0x18, 0x48, 0x38, 0x00, 0x10, 0x04, 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, 0x00, 0x00, + 0x18, 0x0c, 0x00, 0x68, 0x54, 0x18, 0xb0, 0x8c, 0x20, 0xb8, 0x94, 0x10, + 0xb8, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xb8, 0x98, 0x38, 0x98, 0x7c, 0x20, + 0xb0, 0x90, 0x30, 0xb8, 0x9c, 0x38, 0xc0, 0x9c, 0x30, 0xc0, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc0, 0xa4, 0x48, 0xc0, 0xa4, 0x50, 0x80, 0x6c, 0x40, 0x10, 0x08, 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, 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, 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, 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, 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, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 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, 0x04, 0x00, 0x20, 0x10, 0x00, 0x70, 0x54, 0x10, + 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x98, 0x74, 0x18, 0x88, 0x68, 0x18, 0x68, 0x50, 0x10, 0x50, 0x38, 0x00, + 0x38, 0x24, 0x00, 0x30, 0x18, 0x00, 0x28, 0x18, 0x00, 0x28, 0x18, 0x00, + 0x28, 0x1c, 0x00, 0x38, 0x24, 0x00, 0x48, 0x38, 0x00, 0x70, 0x54, 0x18, + 0x88, 0x68, 0x18, 0x98, 0x70, 0x18, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xa8, 0x7c, 0x00, 0xa0, 0x78, 0x10, 0x80, 0x64, 0x18, 0x38, 0x28, 0x00, + 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x44, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb0, 0x8c, 0x08, + 0xa8, 0x84, 0x18, 0x60, 0x4c, 0x00, 0x18, 0x0c, 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, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x30, 0x20, 0x00, 0xa0, 0x84, 0x28, 0xb0, 0x90, 0x18, + 0xb8, 0x94, 0x10, 0xb8, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x30, 0xa8, 0x8c, 0x38, 0x38, 0x20, 0x00, + 0x70, 0x54, 0x08, 0xb0, 0x94, 0x40, 0xc0, 0x9c, 0x38, 0xc0, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, + 0xc0, 0xa0, 0x38, 0xc0, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc0, 0xa4, 0x48, + 0xc0, 0xa4, 0x48, 0xb0, 0x98, 0x50, 0x48, 0x38, 0x10, 0x08, 0x04, 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, 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, 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, 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, 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, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x18, 0x10, 0x00, 0x58, 0x40, 0x00, 0x98, 0x74, 0x18, + 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x08, 0xa0, 0x7c, 0x08, 0x98, 0x78, 0x10, 0x78, 0x5c, 0x08, + 0x58, 0x40, 0x00, 0x30, 0x1c, 0x00, 0x18, 0x0c, 0x00, 0x10, 0x08, 0x00, + 0x10, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, 0x18, 0x0c, 0x00, + 0x30, 0x18, 0x00, 0x58, 0x3c, 0x00, 0x80, 0x60, 0x10, 0x98, 0x74, 0x10, + 0xa8, 0x7c, 0x10, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, 0x78, 0x58, 0x10, + 0x28, 0x18, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x44, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb0, 0x8c, 0x00, + 0xa8, 0x88, 0x10, 0x78, 0x64, 0x08, 0x28, 0x18, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x78, 0x60, 0x18, 0xa8, 0x8c, 0x28, + 0xb8, 0x94, 0x20, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xb8, 0x98, 0x38, 0x90, 0x7c, 0x30, 0x28, 0x10, 0x00, + 0x38, 0x24, 0x00, 0x90, 0x7c, 0x40, 0xb8, 0x9c, 0x40, 0xc0, 0xa0, 0x38, + 0xc8, 0xa0, 0x30, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, + 0xc0, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa4, 0x48, 0xc0, 0xa4, 0x50, + 0xc0, 0xa0, 0x58, 0x80, 0x70, 0x38, 0x20, 0x18, 0x00, 0x08, 0x04, 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, 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, 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, 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, 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, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x04, 0x00, 0x40, 0x2c, 0x00, 0x90, 0x6c, 0x18, 0xa0, 0x7c, 0x08, + 0xa8, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0x90, 0x70, 0x18, 0x60, 0x48, 0x08, 0x28, 0x1c, 0x00, + 0x18, 0x0c, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x18, 0x08, 0x00, 0x30, 0x1c, 0x00, 0x58, 0x3c, 0x00, + 0x90, 0x6c, 0x18, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0x98, 0x74, 0x18, + 0x58, 0x40, 0x08, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x44, 0x00, 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, + 0xb0, 0x88, 0x08, 0x98, 0x7c, 0x18, 0x38, 0x2c, 0x00, 0x08, 0x08, 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, 0x00, 0x00, 0x08, 0x04, 0x00, 0x38, 0x28, 0x00, 0x90, 0x78, 0x28, + 0xb0, 0x90, 0x28, 0xb8, 0x98, 0x20, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc8, 0xa0, 0x30, 0xb8, 0x98, 0x38, 0xa8, 0x90, 0x50, 0x20, 0x10, 0x00, + 0x18, 0x0c, 0x00, 0x58, 0x48, 0x18, 0xb8, 0x98, 0x48, 0xc0, 0xa0, 0x40, + 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x48, 0xc0, 0xa4, 0x50, + 0xa0, 0x8c, 0x50, 0x40, 0x30, 0x08, 0x08, 0x04, 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, 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, + 0x10, 0x08, 0x00, 0x18, 0x10, 0x00, 0x18, 0x10, 0x00, 0x20, 0x10, 0x00, + 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, + 0x18, 0x10, 0x00, 0x10, 0x0c, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x18, 0x10, 0x00, 0x18, 0x10, 0x00, 0x20, 0x10, 0x00, + 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, + 0x18, 0x10, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x28, 0x18, 0x00, 0x70, 0x58, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x88, 0x64, 0x10, 0x48, 0x30, 0x00, 0x20, 0x10, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, 0x18, 0x0c, 0x00, + 0x38, 0x20, 0x00, 0x78, 0x5c, 0x10, 0xa0, 0x74, 0x10, 0xa8, 0x7c, 0x08, + 0xb0, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x88, 0x6c, 0x28, 0x30, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x44, 0x00, 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb8, 0x88, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb0, 0x8c, 0x08, 0xa8, 0x88, 0x18, 0x58, 0x48, 0x08, 0x18, 0x0c, 0x00, + 0x00, 0x04, 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, 0x04, 0x00, 0x18, 0x0c, 0x00, 0x58, 0x44, 0x10, + 0xa0, 0x88, 0x30, 0xb8, 0x98, 0x28, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc0, 0x9c, 0x38, 0xa8, 0x94, 0x50, 0x20, 0x14, 0x00, + 0x10, 0x04, 0x00, 0x18, 0x10, 0x00, 0x98, 0x84, 0x40, 0xb8, 0x9c, 0x48, + 0xc0, 0xa0, 0x40, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, 0xc0, 0xa4, 0x50, 0xb8, 0xa4, 0x58, + 0x68, 0x58, 0x28, 0x10, 0x08, 0x00, 0x00, 0x04, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x38, 0x28, 0x00, 0x68, 0x50, 0x18, 0x70, 0x54, 0x10, 0x70, 0x54, 0x08, + 0x78, 0x58, 0x08, 0x78, 0x58, 0x08, 0x78, 0x58, 0x08, 0x70, 0x54, 0x10, + 0x68, 0x50, 0x10, 0x50, 0x3c, 0x10, 0x10, 0x08, 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, 0x08, 0x04, 0x00, + 0x38, 0x28, 0x00, 0x68, 0x50, 0x18, 0x70, 0x58, 0x10, 0x70, 0x58, 0x08, + 0x70, 0x58, 0x08, 0x70, 0x54, 0x08, 0x78, 0x58, 0x08, 0x70, 0x54, 0x10, + 0x68, 0x50, 0x18, 0x40, 0x30, 0x08, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, 0x80, 0x64, 0x10, + 0x38, 0x24, 0x00, 0x10, 0x08, 0x00, 0x08, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x30, 0x1c, 0x00, 0x70, 0x50, 0x10, 0x90, 0x70, 0x18, + 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, 0xa8, 0x78, 0x08, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x90, 0x74, 0x20, 0x60, 0x48, 0x10, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x48, 0x00, 0xa0, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x8c, 0x00, 0xa8, 0x88, 0x10, 0x88, 0x70, 0x20, 0x20, 0x10, 0x00, + 0x08, 0x04, 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, 0x00, 0x00, 0x08, 0x04, 0x00, 0x20, 0x14, 0x00, + 0x78, 0x60, 0x20, 0xb0, 0x94, 0x30, 0xb8, 0x94, 0x28, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc0, 0x9c, 0x38, 0xb0, 0x98, 0x50, 0x30, 0x20, 0x00, + 0x08, 0x04, 0x00, 0x10, 0x04, 0x00, 0x50, 0x44, 0x10, 0xb0, 0x98, 0x50, + 0xc0, 0xa0, 0x48, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc0, 0xa4, 0x40, 0xc0, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x48, 0xc0, 0xa4, 0x50, 0xc0, 0xa4, 0x58, 0x90, 0x80, 0x48, + 0x20, 0x14, 0x00, 0x08, 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, 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, 0x10, 0x04, 0x00, + 0x50, 0x38, 0x08, 0x90, 0x74, 0x20, 0x98, 0x78, 0x18, 0xa0, 0x78, 0x10, + 0xa0, 0x78, 0x08, 0xa8, 0x7c, 0x10, 0xa0, 0x78, 0x08, 0xa0, 0x78, 0x10, + 0x98, 0x74, 0x20, 0x70, 0x58, 0x20, 0x18, 0x0c, 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, 0x10, 0x04, 0x00, + 0x50, 0x38, 0x08, 0x90, 0x74, 0x28, 0x98, 0x74, 0x10, 0xa0, 0x7c, 0x10, + 0xa0, 0x78, 0x10, 0xa0, 0x7c, 0x10, 0xa8, 0x7c, 0x10, 0x98, 0x78, 0x10, + 0x90, 0x74, 0x20, 0x58, 0x44, 0x08, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x20, 0x0c, 0x00, + 0x80, 0x60, 0x18, 0xa0, 0x78, 0x10, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xa8, 0x7c, 0x00, 0xa0, 0x7c, 0x10, 0x88, 0x68, 0x18, 0x48, 0x30, 0x00, + 0x10, 0x08, 0x00, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, 0x28, 0x18, 0x00, 0x68, 0x54, 0x18, + 0x90, 0x70, 0x28, 0x90, 0x74, 0x20, 0x90, 0x74, 0x20, 0x98, 0x74, 0x20, + 0x90, 0x74, 0x20, 0x90, 0x74, 0x20, 0x98, 0x74, 0x20, 0x90, 0x74, 0x20, + 0x88, 0x70, 0x28, 0x70, 0x60, 0x30, 0x20, 0x1c, 0x08, 0x00, 0x04, 0x00, + 0x68, 0x48, 0x00, 0x98, 0x78, 0x18, 0xa8, 0x80, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xc0, 0x90, 0x00, 0xb0, 0x8c, 0x08, 0xa8, 0x88, 0x28, 0x48, 0x34, 0x00, + 0x10, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x28, 0x18, 0x00, 0x88, 0x70, 0x30, 0xb0, 0x94, 0x38, 0xb8, 0x98, 0x28, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc0, 0x9c, 0x40, 0xb0, 0x98, 0x50, 0x38, 0x28, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x28, 0x1c, 0x00, 0x80, 0x70, 0x38, + 0xb8, 0xa0, 0x48, 0xc0, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc0, 0xa8, 0x50, 0xc0, 0xa4, 0x58, 0x98, 0x84, 0x50, 0x30, 0x28, 0x08, + 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x10, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x90, 0x74, 0x20, 0xa0, 0x78, 0x08, 0xa8, 0x7c, 0x00, + 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x70, 0x58, 0x18, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa0, 0x7c, 0x08, 0xa8, 0x7c, 0x00, + 0xa8, 0x80, 0x00, 0xa8, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x74, 0x18, 0x58, 0x48, 0x08, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, 0x48, 0x30, 0x00, + 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x80, 0x00, + 0xa8, 0x7c, 0x08, 0x90, 0x6c, 0x10, 0x48, 0x34, 0x00, 0x18, 0x08, 0x00, + 0x08, 0x04, 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, 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, 0x04, 0x00, 0x18, 0x0c, 0x00, + 0x20, 0x14, 0x00, 0x28, 0x18, 0x00, 0x28, 0x18, 0x00, 0x28, 0x18, 0x00, + 0x28, 0x18, 0x00, 0x28, 0x18, 0x00, 0x28, 0x18, 0x00, 0x28, 0x18, 0x00, + 0x28, 0x18, 0x00, 0x18, 0x14, 0x00, 0x10, 0x08, 0x00, 0x00, 0x04, 0x00, + 0x68, 0x44, 0x00, 0xa0, 0x78, 0x18, 0xa8, 0x80, 0x08, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x08, 0xa8, 0x8c, 0x18, 0x78, 0x60, 0x10, + 0x20, 0x14, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x04, 0x00, 0x38, 0x28, 0x00, 0x90, 0x74, 0x30, 0xb0, 0x94, 0x38, + 0xb8, 0x98, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc8, 0xa0, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x38, 0xc0, 0x9c, 0x40, 0xb0, 0x98, 0x50, 0x50, 0x40, 0x10, + 0x10, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x50, 0x40, 0x18, + 0xa8, 0x94, 0x48, 0xc0, 0xa4, 0x48, 0xc0, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x50, + 0xc0, 0xa4, 0x58, 0x98, 0x88, 0x50, 0x40, 0x30, 0x10, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0c, 0x00, + 0x38, 0x38, 0x30, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x50, 0x40, 0x00, 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x40, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x20, 0x10, 0x00, 0x70, 0x54, 0x18, + 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x18, 0x68, 0x48, 0x00, 0x20, 0x10, 0x00, 0x08, 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, + 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, + 0x08, 0x04, 0x00, 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x48, 0x00, 0xa0, 0x78, 0x18, 0xa8, 0x80, 0x08, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x90, 0x00, 0xb8, 0x90, 0x08, 0xb8, 0x90, 0x10, 0x98, 0x80, 0x20, + 0x40, 0x34, 0x00, 0x08, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x38, 0x28, 0x00, 0x90, 0x78, 0x38, + 0xb0, 0x94, 0x38, 0xb8, 0x9c, 0x30, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, + 0xc8, 0xa0, 0x38, 0xc0, 0xa0, 0x40, 0xb0, 0x9c, 0x50, 0x58, 0x48, 0x18, + 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x20, 0x14, 0x00, + 0x88, 0x74, 0x40, 0xb8, 0x9c, 0x50, 0xc0, 0xa4, 0x48, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x50, 0xc0, 0xa4, 0x58, + 0xa8, 0x90, 0x58, 0x38, 0x2c, 0x08, 0x10, 0x08, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x30, 0x28, 0x18, + 0x70, 0x6c, 0x58, 0x20, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x38, 0x28, 0x00, 0x88, 0x68, 0x18, + 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x10, + 0x88, 0x6c, 0x20, 0x30, 0x1c, 0x00, 0x10, 0x04, 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, 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, + 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, + 0x68, 0x48, 0x00, 0xa0, 0x78, 0x18, 0xa8, 0x80, 0x08, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xb8, 0x90, 0x00, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xb8, 0x90, 0x10, 0xa8, 0x8c, 0x20, + 0x70, 0x5c, 0x18, 0x20, 0x18, 0x00, 0x08, 0x04, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, 0x28, 0x18, 0x00, + 0x88, 0x70, 0x30, 0xb0, 0x94, 0x38, 0xb8, 0x98, 0x38, 0xc0, 0x9c, 0x30, + 0xc0, 0x9c, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa4, 0x30, + 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x30, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc0, 0xa0, 0x40, 0xb8, 0x9c, 0x50, 0x68, 0x5c, 0x28, + 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x40, 0x30, 0x08, 0xb0, 0x9c, 0x58, 0xc0, 0xa0, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x50, 0xc0, 0xa4, 0x50, 0x90, 0x7c, 0x40, + 0x38, 0x2c, 0x08, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x78, 0x70, 0x50, + 0x88, 0x7c, 0x60, 0x20, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x80, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x58, 0x10, 0x18, 0x10, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x58, 0x40, 0x00, 0x98, 0x74, 0x18, + 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x08, 0xa0, 0x78, 0x18, + 0x58, 0x40, 0x08, 0x18, 0x08, 0x00, 0x08, 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, 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, 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, + 0x68, 0x48, 0x00, 0xa0, 0x78, 0x18, 0xb0, 0x80, 0x08, 0xb0, 0x84, 0x00, + 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, 0xb0, 0x84, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x10, 0xb0, 0x90, 0x18, + 0xa0, 0x80, 0x28, 0x48, 0x38, 0x00, 0x10, 0x08, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, + 0x28, 0x1c, 0x00, 0x60, 0x54, 0x20, 0xa0, 0x88, 0x40, 0xb8, 0x98, 0x40, + 0xc0, 0x9c, 0x38, 0xc0, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc0, 0xa0, 0x40, 0xb8, 0x9c, 0x50, 0x78, 0x68, 0x30, + 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x80, 0x70, 0x40, 0xb8, 0xa0, 0x50, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x50, 0xa8, 0x94, 0x50, 0x48, 0x38, 0x08, + 0x10, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x38, 0x2c, 0x08, 0xb0, 0xa4, 0x78, + 0x88, 0x80, 0x58, 0x20, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x74, 0x10, 0x60, 0x48, 0x08, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x10, 0x00, 0x68, 0x50, 0x08, 0xa0, 0x78, 0x10, + 0xa8, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0x90, 0x6c, 0x18, + 0x30, 0x20, 0x00, 0x08, 0x04, 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, 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, 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, 0x00, + 0x68, 0x48, 0x00, 0xa0, 0x7c, 0x18, 0xb0, 0x80, 0x08, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xb8, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xb8, 0x94, 0x18, + 0xb0, 0x90, 0x28, 0x88, 0x74, 0x28, 0x18, 0x10, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x18, 0x10, 0x00, 0x40, 0x34, 0x00, 0x90, 0x7c, 0x38, + 0xb0, 0x98, 0x48, 0xb8, 0x9c, 0x48, 0xc0, 0x9c, 0x40, 0xc0, 0xa0, 0x40, + 0xc0, 0xa0, 0x38, 0xc0, 0xa0, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc0, 0xa4, 0x40, 0xb8, 0xa0, 0x50, 0x88, 0x78, 0x40, + 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x40, 0x30, 0x10, 0xa8, 0x94, 0x50, 0xc0, 0xa4, 0x50, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, + 0xc8, 0xa8, 0x48, 0xc0, 0xa8, 0x50, 0xa8, 0x90, 0x50, 0x40, 0x30, 0x08, + 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x18, 0x10, 0x00, 0x88, 0x7c, 0x48, 0xc0, 0xac, 0x70, + 0x90, 0x80, 0x58, 0x20, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x28, 0x18, 0x00, 0x80, 0x60, 0x10, 0xa0, 0x78, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x70, 0x50, 0x08, + 0x20, 0x10, 0x00, 0x08, 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, 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, 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, 0x00, 0x00, + 0x68, 0x48, 0x00, 0xa0, 0x7c, 0x18, 0xb0, 0x84, 0x08, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x18, + 0xb8, 0x94, 0x20, 0xb0, 0x8c, 0x30, 0x58, 0x48, 0x10, 0x10, 0x0c, 0x00, + 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x20, 0x14, 0x00, + 0x48, 0x3c, 0x10, 0x88, 0x74, 0x38, 0xa8, 0x90, 0x48, 0xb8, 0x9c, 0x48, + 0xb8, 0xa0, 0x48, 0xc0, 0xa0, 0x40, 0xc0, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc0, 0xa4, 0x40, 0xb8, 0xa0, 0x50, 0x90, 0x80, 0x40, + 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x10, 0x00, 0x78, 0x64, 0x30, 0xb8, 0xa4, 0x58, + 0xc8, 0xa8, 0x50, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, + 0xc8, 0xac, 0x48, 0xc8, 0xa8, 0x50, 0xa8, 0x90, 0x50, 0x40, 0x30, 0x08, + 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x60, 0x50, 0x28, 0xb8, 0xa8, 0x68, 0xc8, 0xb0, 0x70, + 0x90, 0x84, 0x58, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x30, 0x20, 0x00, 0x90, 0x6c, 0x18, 0xa8, 0x7c, 0x08, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0x98, 0x74, 0x18, 0x58, 0x3c, 0x00, + 0x10, 0x08, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x48, 0x00, 0xa0, 0x7c, 0x18, 0xb0, 0x84, 0x08, 0xb0, 0x84, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xc0, 0x90, 0x00, 0xb8, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xb8, 0x94, 0x28, 0x98, 0x80, 0x30, 0x40, 0x30, 0x00, + 0x10, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x08, 0x08, 0x00, 0x18, 0x10, 0x00, 0x50, 0x44, 0x18, 0x78, 0x64, 0x28, + 0x98, 0x80, 0x40, 0xb0, 0x9c, 0x50, 0xb8, 0xa0, 0x50, 0xb8, 0xa0, 0x50, + 0xc0, 0xa0, 0x48, 0xb8, 0xa0, 0x50, 0xb8, 0xa0, 0x58, 0x90, 0x80, 0x48, + 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x38, 0x30, 0x08, 0xa0, 0x90, 0x50, + 0xc0, 0xa8, 0x58, 0xc8, 0xa8, 0x50, 0xc8, 0xac, 0x48, 0xd0, 0xac, 0x50, + 0xc8, 0xac, 0x48, 0xc8, 0xa8, 0x58, 0xb0, 0x94, 0x58, 0x48, 0x34, 0x10, + 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x38, 0x30, 0x08, 0xa8, 0x98, 0x60, 0xc8, 0xb4, 0x68, 0xc8, 0xb0, 0x68, + 0x90, 0x84, 0x50, 0x28, 0x1c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x38, 0x28, 0x00, 0x98, 0x74, 0x20, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0x90, 0x6c, 0x18, 0x40, 0x2c, 0x00, + 0x08, 0x04, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x48, 0x00, 0xa0, 0x7c, 0x18, 0xb0, 0x84, 0x08, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x90, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xb8, 0x98, 0x20, 0xb0, 0x90, 0x30, 0x80, 0x6c, 0x20, + 0x28, 0x1c, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x18, 0x10, 0x00, + 0x28, 0x24, 0x00, 0x40, 0x38, 0x10, 0x60, 0x54, 0x28, 0x80, 0x70, 0x40, + 0x98, 0x84, 0x50, 0xa8, 0x94, 0x60, 0xa8, 0x98, 0x68, 0x90, 0x84, 0x60, + 0x28, 0x24, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x70, 0x60, 0x30, + 0xc0, 0xa8, 0x60, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xd0, 0xac, 0x50, + 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x58, 0xb0, 0x9c, 0x58, 0x50, 0x40, 0x18, + 0x08, 0x04, 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, 0x00, 0x00, 0x08, 0x04, 0x00, 0x18, 0x0c, 0x00, + 0x98, 0x84, 0x50, 0xc8, 0xb0, 0x68, 0xd0, 0xb4, 0x60, 0xc8, 0xb4, 0x68, + 0x90, 0x84, 0x58, 0x20, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x04, 0x00, 0x48, 0x34, 0x00, 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa0, 0x78, 0x08, 0x80, 0x64, 0x18, 0x30, 0x20, 0x00, + 0x08, 0x04, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x48, 0x00, 0xa0, 0x80, 0x18, 0xb0, 0x84, 0x08, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x94, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x90, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xb8, 0x98, 0x28, 0xb0, 0x90, 0x38, + 0x70, 0x5c, 0x28, 0x18, 0x10, 0x00, 0x08, 0x04, 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, 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, 0x04, 0x00, 0x10, 0x08, 0x00, 0x10, 0x0c, 0x00, + 0x18, 0x14, 0x00, 0x20, 0x14, 0x00, 0x20, 0x14, 0x00, 0x18, 0x10, 0x00, + 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x20, 0x18, 0x00, + 0xb0, 0x9c, 0x58, 0xc0, 0xa8, 0x58, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xd0, 0xb0, 0x50, 0xc8, 0xac, 0x58, 0xb8, 0xa0, 0x60, 0x58, 0x44, 0x18, + 0x08, 0x04, 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, 0x04, 0x00, 0x18, 0x10, 0x00, 0x70, 0x64, 0x38, + 0xc8, 0xb0, 0x70, 0xd0, 0xb4, 0x60, 0xd0, 0xb8, 0x60, 0xc8, 0xb4, 0x68, + 0x98, 0x88, 0x58, 0x20, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x50, 0x38, 0x08, 0xa0, 0x78, 0x18, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x7c, 0x10, 0x80, 0x60, 0x18, 0x28, 0x1c, 0x00, + 0x08, 0x04, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa0, 0x80, 0x18, 0xb0, 0x84, 0x08, 0xb8, 0x88, 0x00, + 0xb8, 0x88, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, + 0xb8, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x98, 0x28, 0xb8, 0x94, 0x30, + 0xa8, 0x94, 0x40, 0x58, 0x48, 0x10, 0x18, 0x0c, 0x00, 0x08, 0x04, 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, 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, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 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, 0x10, 0x08, 0x00, + 0x70, 0x60, 0x28, 0xb8, 0xa4, 0x60, 0xc8, 0xac, 0x58, 0xc8, 0xb0, 0x50, + 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x58, 0xb8, 0x9c, 0x58, 0x58, 0x44, 0x18, + 0x08, 0x04, 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, 0x10, 0x0c, 0x00, 0x60, 0x50, 0x28, 0xb8, 0xa4, 0x68, + 0xc8, 0xb4, 0x68, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xc8, 0xb4, 0x68, + 0x98, 0x88, 0x58, 0x20, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x50, 0x38, 0x08, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x10, 0x80, 0x60, 0x18, 0x28, 0x18, 0x00, + 0x08, 0x04, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa0, 0x80, 0x18, 0xb0, 0x84, 0x08, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xc0, 0x94, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xb8, 0x98, 0x30, 0xa0, 0x88, 0x38, 0x48, 0x3c, 0x08, 0x10, 0x08, 0x00, + 0x08, 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, 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, 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, 0x04, 0x00, + 0x30, 0x28, 0x00, 0x98, 0x88, 0x50, 0xc0, 0xac, 0x60, 0xc8, 0xac, 0x50, + 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x58, 0xb8, 0xa0, 0x58, 0x50, 0x44, 0x18, + 0x08, 0x04, 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, + 0x10, 0x08, 0x00, 0x40, 0x38, 0x10, 0xb0, 0xa0, 0x68, 0xc8, 0xb4, 0x68, + 0xd0, 0xb4, 0x60, 0xd8, 0xbc, 0x60, 0xd0, 0xb8, 0x60, 0xd0, 0xb4, 0x68, + 0x98, 0x88, 0x58, 0x20, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x60, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x04, 0x00, 0x50, 0x38, 0x08, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x7c, 0x08, 0x80, 0x60, 0x18, 0x28, 0x18, 0x00, + 0x08, 0x04, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa0, 0x80, 0x18, 0xb0, 0x88, 0x08, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, + 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x30, 0xb8, 0x98, 0x38, 0xa0, 0x88, 0x40, 0x48, 0x3c, 0x08, + 0x10, 0x08, 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, 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, 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, + 0x10, 0x08, 0x00, 0x60, 0x50, 0x28, 0xb8, 0xa4, 0x60, 0xc8, 0xb0, 0x58, + 0xc8, 0xb0, 0x58, 0xc8, 0xb0, 0x58, 0xc0, 0xa8, 0x60, 0x68, 0x58, 0x28, + 0x08, 0x04, 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, 0x04, 0x00, 0x10, 0x08, 0x00, + 0x38, 0x30, 0x08, 0xb8, 0xa4, 0x68, 0xc8, 0xb4, 0x68, 0xd0, 0xb8, 0x68, + 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xc8, 0xb4, 0x68, + 0x98, 0x88, 0x58, 0x20, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x00, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x48, 0x34, 0x08, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x10, 0x80, 0x60, 0x18, 0x30, 0x1c, 0x00, + 0x08, 0x04, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa0, 0x80, 0x18, 0xb0, 0x88, 0x08, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x90, 0x00, 0xb8, 0x94, 0x00, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x30, 0xb8, 0x98, 0x40, 0xa0, 0x8c, 0x40, + 0x40, 0x34, 0x08, 0x10, 0x08, 0x00, 0x08, 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, 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, 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, 0x28, 0x20, 0x00, 0x98, 0x88, 0x50, 0xc0, 0xac, 0x60, + 0xc8, 0xb0, 0x58, 0xc8, 0xb0, 0x58, 0xc8, 0xac, 0x68, 0x68, 0x5c, 0x28, + 0x08, 0x04, 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, 0x10, 0x08, 0x00, 0x40, 0x3c, 0x18, + 0xa8, 0x98, 0x60, 0xc8, 0xb4, 0x68, 0xd0, 0xb8, 0x68, 0xd0, 0xb8, 0x60, + 0xd0, 0xb8, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xb8, 0x60, 0xd0, 0xb8, 0x70, + 0x98, 0x88, 0x58, 0x20, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x10, 0x60, 0x48, 0x00, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x04, 0x00, 0x40, 0x28, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0x88, 0x68, 0x18, 0x38, 0x28, 0x00, + 0x10, 0x04, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa0, 0x80, 0x18, 0xb0, 0x88, 0x08, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x98, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x38, 0xb8, 0x9c, 0x40, + 0xa0, 0x84, 0x40, 0x50, 0x40, 0x10, 0x18, 0x0c, 0x00, 0x08, 0x04, 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, 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, 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, 0x04, 0x00, 0x58, 0x48, 0x20, 0xc0, 0xa8, 0x68, + 0xc8, 0xb0, 0x58, 0xc8, 0xb0, 0x58, 0xc0, 0xb0, 0x68, 0x68, 0x5c, 0x28, + 0x08, 0x04, 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, 0x08, 0x00, 0x50, 0x48, 0x20, 0xa8, 0x98, 0x60, + 0xc8, 0xb4, 0x68, 0xd0, 0xb4, 0x68, 0xd0, 0xb8, 0x60, 0xd0, 0xbc, 0x60, + 0xd8, 0xb8, 0x60, 0xd8, 0xb8, 0x60, 0xd8, 0xbc, 0x60, 0xd0, 0xb8, 0x70, + 0x98, 0x88, 0x58, 0x20, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x10, 0x60, 0x48, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x30, 0x20, 0x00, 0x90, 0x6c, 0x18, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0x98, 0x70, 0x18, 0x50, 0x34, 0x00, + 0x10, 0x08, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa0, 0x80, 0x18, 0xb0, 0x88, 0x08, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x90, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x38, + 0xb8, 0x9c, 0x40, 0xa8, 0x94, 0x48, 0x60, 0x50, 0x20, 0x20, 0x14, 0x00, + 0x08, 0x04, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x18, 0x0c, 0x00, 0xa0, 0x8c, 0x58, + 0xc8, 0xac, 0x60, 0xc8, 0xb0, 0x60, 0xc0, 0xac, 0x68, 0x68, 0x5c, 0x28, + 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x18, 0x10, 0x00, 0x58, 0x4c, 0x28, 0xc0, 0xac, 0x70, 0xd0, 0xb4, 0x68, + 0xd0, 0xb8, 0x68, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd0, 0xb8, 0x70, + 0x98, 0x88, 0x58, 0x20, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x10, 0x60, 0x48, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x28, 0x18, 0x00, 0x78, 0x60, 0x10, 0xa0, 0x7c, 0x08, + 0xa8, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, 0x68, 0x4c, 0x00, + 0x18, 0x0c, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa0, 0x84, 0x18, 0xb0, 0x8c, 0x08, 0xb8, 0x8c, 0x00, + 0xb8, 0x8c, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x90, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc0, 0xa0, 0x40, 0xb8, 0x9c, 0x48, 0xb0, 0x9c, 0x50, 0x70, 0x60, 0x28, + 0x30, 0x20, 0x00, 0x10, 0x08, 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, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, 0x50, 0x48, 0x20, + 0xb8, 0xa8, 0x68, 0xc8, 0xb0, 0x60, 0xc8, 0xb0, 0x68, 0x78, 0x64, 0x30, + 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x28, 0x24, 0x08, + 0x78, 0x6c, 0x40, 0xb8, 0xa8, 0x68, 0xd0, 0xb4, 0x68, 0xd0, 0xb8, 0x68, + 0xd0, 0xb8, 0x60, 0xd8, 0xb8, 0x60, 0xd0, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd0, 0xbc, 0x60, 0xd8, 0xbc, 0x68, 0xd0, 0xb8, 0x70, + 0x98, 0x88, 0x58, 0x28, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0x78, 0x58, 0x18, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x10, 0x00, 0x70, 0x50, 0x08, 0xa0, 0x78, 0x10, + 0xa8, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, 0xa8, 0x78, 0x10, 0x80, 0x64, 0x10, + 0x30, 0x1c, 0x00, 0x08, 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, 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, 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, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa8, 0x84, 0x18, 0xb0, 0x8c, 0x08, 0xb8, 0x8c, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x94, 0x00, 0xc0, 0x90, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, + 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa0, 0x38, 0xc0, 0xa0, 0x40, 0xc0, 0xa0, 0x48, 0xb0, 0x9c, 0x50, + 0x90, 0x7c, 0x40, 0x40, 0x34, 0x08, 0x10, 0x08, 0x00, 0x08, 0x04, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, + 0x90, 0x7c, 0x48, 0xc0, 0xac, 0x68, 0xc0, 0xac, 0x68, 0x80, 0x6c, 0x40, + 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x10, 0x08, 0x00, 0x38, 0x30, 0x10, 0x98, 0x88, 0x58, + 0xc0, 0xb0, 0x68, 0xd0, 0xb8, 0x68, 0xd0, 0xb8, 0x60, 0xd8, 0xb8, 0x60, + 0xd0, 0xb8, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x68, 0xd0, 0xb8, 0x70, + 0x98, 0x88, 0x58, 0x28, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0x78, 0x58, 0x18, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x3c, 0x00, 0x98, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x58, 0x40, 0x00, 0x98, 0x74, 0x18, + 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0x98, 0x74, 0x18, + 0x48, 0x34, 0x00, 0x10, 0x08, 0x00, 0x08, 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, 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, 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, + 0x68, 0x4c, 0x00, 0xa8, 0x84, 0x18, 0xb0, 0x8c, 0x08, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xb8, 0x94, 0x00, + 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, + 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc0, 0xa4, 0x40, 0xc0, 0xa0, 0x48, + 0xb8, 0xa0, 0x50, 0xb0, 0x98, 0x50, 0x68, 0x58, 0x20, 0x30, 0x20, 0x00, + 0x10, 0x08, 0x00, 0x08, 0x04, 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, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x48, 0x40, 0x18, 0xb0, 0x9c, 0x68, 0xc0, 0xac, 0x70, 0x80, 0x70, 0x40, + 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x28, 0x24, 0x00, 0x70, 0x60, 0x30, 0xb8, 0xa4, 0x68, 0xc8, 0xb4, 0x70, + 0xc8, 0xb8, 0x68, 0xd0, 0xb8, 0x60, 0xd0, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x68, 0xd0, 0xbc, 0x70, + 0x98, 0x88, 0x58, 0x28, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x18, 0x0c, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x58, 0x40, 0x00, 0xa0, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x40, 0x28, 0x00, 0x88, 0x68, 0x18, + 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x08, + 0x80, 0x64, 0x18, 0x28, 0x14, 0x00, 0x08, 0x04, 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, 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, + 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, + 0x68, 0x4c, 0x00, 0xa8, 0x84, 0x18, 0xb0, 0x8c, 0x08, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x90, 0x00, + 0xc0, 0x94, 0x00, 0xb8, 0x90, 0x00, 0xb8, 0x94, 0x00, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, + 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x48, 0xc0, 0xa0, 0x48, 0xb8, 0xa0, 0x58, 0x98, 0x84, 0x48, + 0x58, 0x48, 0x20, 0x20, 0x14, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x18, 0x10, 0x00, 0x88, 0x78, 0x50, 0xc0, 0xac, 0x70, 0x80, 0x70, 0x38, + 0x18, 0x10, 0x00, 0x08, 0x04, 0x00, 0x20, 0x14, 0x00, 0x50, 0x44, 0x20, + 0xa0, 0x8c, 0x58, 0xc8, 0xb4, 0x70, 0xd0, 0xb4, 0x68, 0xd0, 0xb8, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xc0, 0x60, + 0xd8, 0xbc, 0x68, 0xd8, 0xbc, 0x68, 0xd8, 0xc0, 0x68, 0xd0, 0xbc, 0x70, + 0x98, 0x88, 0x58, 0x28, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x50, 0x3c, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, 0x20, 0x10, 0x00, 0x08, 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, 0x10, 0x08, 0x00, + 0x68, 0x48, 0x00, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x20, 0x14, 0x00, 0x70, 0x58, 0x18, + 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x74, 0x18, 0x58, 0x40, 0x00, 0x18, 0x0c, 0x00, 0x08, 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, + 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, 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, + 0x68, 0x4c, 0x00, 0xa0, 0x84, 0x18, 0xb0, 0x8c, 0x08, 0xb8, 0x90, 0x00, + 0xb8, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x94, 0x00, 0xb8, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, 0xc0, 0x98, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc0, 0xa4, 0x48, 0xc0, 0xa4, 0x50, 0xc0, 0xa4, 0x50, + 0xb0, 0x98, 0x58, 0x88, 0x74, 0x38, 0x50, 0x40, 0x10, 0x18, 0x10, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 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, 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, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x38, 0x30, 0x10, 0xb8, 0xa8, 0x78, 0x80, 0x70, 0x38, + 0x28, 0x18, 0x00, 0x50, 0x44, 0x18, 0x90, 0x80, 0x50, 0xb8, 0xa8, 0x68, + 0xc8, 0xb4, 0x68, 0xd0, 0xb8, 0x68, 0xd0, 0xb8, 0x60, 0xd0, 0xbc, 0x60, + 0xd0, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x68, 0xd8, 0xbc, 0x68, + 0xd8, 0xbc, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd0, 0xbc, 0x70, + 0x98, 0x88, 0x58, 0x28, 0x1c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x50, 0x38, 0x00, 0x98, 0x74, 0x20, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xa0, 0x7c, 0x08, 0x80, 0x60, 0x10, 0x28, 0x18, 0x00, 0x08, 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, 0x18, 0x08, 0x00, + 0x78, 0x58, 0x08, 0xa0, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x48, 0x38, 0x08, + 0xa0, 0x78, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xa8, 0x78, 0x08, 0x88, 0x68, 0x10, 0x40, 0x2c, 0x00, 0x10, 0x08, 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, 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, 0x08, 0x04, 0x00, + 0x10, 0x04, 0x00, 0x10, 0x08, 0x00, 0x10, 0x08, 0x00, 0x10, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, + 0x10, 0x08, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa8, 0x88, 0x18, 0xb0, 0x8c, 0x08, 0xb8, 0x90, 0x00, + 0xc0, 0x90, 0x00, 0xc0, 0x90, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, + 0xc0, 0x94, 0x08, 0xc0, 0x98, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, 0xc8, 0xa4, 0x48, 0xc8, 0xa8, 0x48, + 0xc0, 0xa8, 0x50, 0xc0, 0xa4, 0x58, 0xb8, 0xa0, 0x60, 0x98, 0x84, 0x50, + 0x58, 0x48, 0x20, 0x28, 0x20, 0x00, 0x18, 0x10, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 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, 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, 0x10, 0x08, 0x00, 0x80, 0x74, 0x48, 0xb0, 0x9c, 0x60, + 0xa8, 0x98, 0x58, 0xc0, 0xb0, 0x70, 0xc8, 0xb4, 0x68, 0xd0, 0xb8, 0x68, + 0xd0, 0xb8, 0x60, 0xd0, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd0, 0xbc, 0x70, + 0x98, 0x88, 0x58, 0x28, 0x1c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x40, 0x2c, 0x00, 0x98, 0x74, 0x20, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xa8, 0x7c, 0x08, 0x88, 0x68, 0x10, 0x30, 0x24, 0x00, 0x08, 0x04, 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, 0x08, 0x00, 0x00, 0x20, 0x0c, 0x00, + 0x90, 0x6c, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x20, 0x10, 0x00, + 0x90, 0x6c, 0x20, 0xa8, 0x7c, 0x10, 0xa8, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa0, 0x78, 0x10, 0x80, 0x60, 0x18, 0x38, 0x24, 0x00, + 0x10, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x18, 0x10, 0x00, 0x38, 0x2c, 0x00, + 0x48, 0x30, 0x00, 0x48, 0x34, 0x00, 0x48, 0x34, 0x00, 0x48, 0x34, 0x00, + 0x48, 0x34, 0x00, 0x48, 0x34, 0x00, 0x48, 0x34, 0x00, 0x48, 0x30, 0x00, + 0x40, 0x30, 0x08, 0x30, 0x24, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x50, 0x00, 0xa8, 0x84, 0x18, 0xb0, 0x8c, 0x08, 0xc0, 0x94, 0x00, + 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x00, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, + 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x50, 0xc8, 0xa8, 0x50, 0xc0, 0xa8, 0x50, 0xc0, 0xa8, 0x58, + 0xb8, 0xa4, 0x60, 0xa0, 0x90, 0x50, 0x78, 0x68, 0x38, 0x50, 0x40, 0x18, + 0x28, 0x24, 0x00, 0x10, 0x0c, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x00, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x48, 0x38, 0x10, 0xb8, 0xa4, 0x68, + 0xc8, 0xb4, 0x68, 0xd0, 0xb8, 0x68, 0xd0, 0xb8, 0x68, 0xd0, 0xbc, 0x60, + 0xd0, 0xbc, 0x60, 0xd0, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x68, 0xd8, 0xbc, 0x68, 0xd8, 0xbc, 0x68, + 0xd8, 0xc0, 0x60, 0xd8, 0xc0, 0x60, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd0, 0xbc, 0x70, + 0x98, 0x8c, 0x58, 0x20, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x40, 0x2c, 0x00, 0x90, 0x70, 0x20, 0xa8, 0x78, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xa8, 0x7c, 0x00, 0x90, 0x70, 0x10, 0x48, 0x34, 0x00, 0x10, 0x08, 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, 0x08, 0x04, 0x00, 0x30, 0x20, 0x00, + 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x58, 0x44, 0x00, 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x10, + 0x28, 0x18, 0x00, 0x10, 0x08, 0x00, 0x08, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x28, 0x14, 0x00, 0x60, 0x48, 0x08, 0x90, 0x6c, 0x18, + 0x98, 0x78, 0x18, 0xa0, 0x78, 0x10, 0x98, 0x78, 0x10, 0x98, 0x78, 0x10, + 0xa0, 0x78, 0x10, 0xa0, 0x78, 0x18, 0xa0, 0x78, 0x18, 0x98, 0x74, 0x20, + 0x88, 0x70, 0x28, 0x60, 0x48, 0x18, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x50, 0x00, 0xa8, 0x88, 0x20, 0xb0, 0x8c, 0x08, 0xb8, 0x94, 0x00, + 0xc0, 0x94, 0x08, 0xb8, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x98, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, + 0xc8, 0xa8, 0x50, 0xc0, 0xa4, 0x58, 0xc0, 0xa8, 0x60, 0xb0, 0x9c, 0x60, + 0x98, 0x88, 0x50, 0x88, 0x78, 0x48, 0x58, 0x4c, 0x28, 0x38, 0x2c, 0x08, + 0x18, 0x14, 0x00, 0x10, 0x0c, 0x00, 0x10, 0x08, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x40, 0x30, 0x10, 0xb8, 0xa4, 0x70, + 0xd0, 0xb4, 0x68, 0xd8, 0xbc, 0x60, 0xd0, 0xb8, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x68, 0xd8, 0xbc, 0x68, 0xd8, 0xbc, 0x68, + 0xd8, 0xc0, 0x60, 0xd8, 0xc0, 0x60, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd0, 0xbc, 0x70, + 0x98, 0x8c, 0x58, 0x20, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x38, 0x28, 0x00, 0x90, 0x70, 0x20, 0xa0, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x68, 0x4c, 0x08, 0x20, 0x10, 0x00, + 0x08, 0x04, 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, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x60, 0x44, 0x08, + 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x30, 0x20, 0x00, 0x78, 0x60, 0x18, 0xa0, 0x78, 0x10, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x70, 0x58, 0x10, 0x38, 0x24, 0x00, 0x18, 0x08, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, + 0x28, 0x14, 0x00, 0x68, 0x50, 0x10, 0x90, 0x70, 0x18, 0xa0, 0x78, 0x10, + 0xa8, 0x7c, 0x08, 0xa8, 0x80, 0x00, 0xa8, 0x80, 0x00, 0xa8, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x90, 0x74, 0x28, 0x38, 0x28, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x50, 0x00, 0xa8, 0x88, 0x20, 0xb0, 0x8c, 0x10, 0xb8, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x08, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x18, + 0xc0, 0x94, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, + 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x58, 0xc8, 0xac, 0x58, + 0xc0, 0xac, 0x58, 0xc0, 0xac, 0x60, 0xc0, 0xa8, 0x60, 0xb8, 0xa4, 0x68, + 0xb8, 0xa4, 0x68, 0xa0, 0x90, 0x58, 0x88, 0x74, 0x40, 0x78, 0x68, 0x38, + 0x60, 0x50, 0x20, 0x58, 0x4c, 0x20, 0x50, 0x44, 0x20, 0x18, 0x10, 0x00, + 0x00, 0x04, 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, 0x08, 0x00, 0x00, 0x40, 0x34, 0x10, 0xc8, 0xb4, 0x78, + 0xd0, 0xb8, 0x68, 0xd0, 0xb8, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xbc, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd0, 0xc0, 0x70, + 0x98, 0x8c, 0x58, 0x20, 0x1c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x30, 0x20, 0x00, 0x80, 0x64, 0x18, 0xa0, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0x90, 0x70, 0x18, 0x50, 0x34, 0x00, + 0x18, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x40, 0x28, 0x00, 0x88, 0x68, 0x18, + 0xa8, 0x78, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x04, 0x00, 0x48, 0x30, 0x00, 0x90, 0x70, 0x18, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0x88, 0x68, 0x18, 0x50, 0x38, 0x00, 0x20, 0x14, 0x00, + 0x10, 0x08, 0x00, 0x08, 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, + 0x08, 0x00, 0x00, 0x10, 0x04, 0x00, 0x20, 0x10, 0x00, 0x40, 0x2c, 0x00, + 0x80, 0x60, 0x10, 0x98, 0x74, 0x10, 0xa8, 0x78, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0x98, 0x78, 0x18, + 0x60, 0x4c, 0x10, 0x10, 0x0c, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa8, 0x88, 0x20, 0xb8, 0x90, 0x10, 0xb8, 0x94, 0x08, + 0xc0, 0x94, 0x08, 0xc0, 0x94, 0x10, 0xb8, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, + 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x30, + 0xc0, 0x9c, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, + 0xd0, 0xac, 0x50, 0xd0, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xc8, 0xac, 0x50, 0xd0, 0xac, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x50, 0xc8, 0xb0, 0x50, 0xc8, 0xb0, 0x58, 0xc8, 0xb0, 0x58, + 0xc8, 0xac, 0x60, 0xc8, 0xac, 0x60, 0xc8, 0xac, 0x60, 0xc8, 0xac, 0x60, + 0xc8, 0xb0, 0x68, 0xc0, 0xac, 0x70, 0xb8, 0xa8, 0x78, 0x58, 0x50, 0x28, + 0x08, 0x08, 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, 0x08, 0x04, 0x00, 0x40, 0x34, 0x10, 0xc0, 0xb0, 0x78, + 0xd0, 0xb8, 0x68, 0xd0, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xc0, 0x60, 0xd8, 0xc0, 0x60, + 0xd8, 0xbc, 0x60, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc4, 0x68, 0xd0, 0xc0, 0x70, + 0x98, 0x8c, 0x58, 0x20, 0x1c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x28, 0x14, 0x00, 0x70, 0x58, 0x10, 0xa0, 0x7c, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, 0xa0, 0x78, 0x10, 0x88, 0x64, 0x10, + 0x38, 0x24, 0x00, 0x18, 0x08, 0x00, 0x10, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x10, 0x08, 0x00, 0x30, 0x20, 0x00, 0x78, 0x5c, 0x10, 0xa0, 0x78, 0x10, + 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x20, 0x10, 0x00, 0x68, 0x48, 0x08, 0xa0, 0x74, 0x18, + 0xa8, 0x7c, 0x08, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xa8, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x98, 0x74, 0x18, 0x68, 0x50, 0x08, + 0x40, 0x2c, 0x00, 0x20, 0x10, 0x00, 0x10, 0x08, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, + 0x18, 0x0c, 0x00, 0x38, 0x24, 0x00, 0x68, 0x4c, 0x10, 0x90, 0x6c, 0x18, + 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, 0xa0, 0x78, 0x10, 0x80, 0x64, 0x10, + 0x30, 0x20, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa8, 0x88, 0x28, 0xb8, 0x90, 0x18, 0xc0, 0x94, 0x10, + 0xb8, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x94, 0x10, 0xc0, 0x98, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc0, 0xa0, 0x38, + 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc0, 0xa4, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xc8, 0xac, 0x50, 0xd0, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xd0, 0xb0, 0x50, + 0xc8, 0xac, 0x50, 0xd0, 0xac, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb4, 0x58, 0xd0, 0xb0, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x60, + 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x60, 0xc8, 0xb0, 0x68, 0xa0, 0x8c, 0x58, + 0x28, 0x1c, 0x00, 0x08, 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, 0x08, 0x04, 0x00, 0x40, 0x34, 0x10, 0xc8, 0xb0, 0x78, + 0xd0, 0xb8, 0x68, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x68, + 0xd8, 0xc0, 0x60, 0xd0, 0xbc, 0x60, 0xd8, 0xbc, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc4, 0x68, 0xd0, 0xc0, 0x78, + 0x98, 0x8c, 0x58, 0x20, 0x1c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x0c, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x80, 0x64, 0x10, 0x58, 0x40, 0x00, 0x28, 0x18, 0x00, 0x18, 0x0c, 0x00, + 0x10, 0x08, 0x00, 0x10, 0x08, 0x00, 0x18, 0x0c, 0x00, 0x20, 0x10, 0x00, + 0x40, 0x2c, 0x00, 0x80, 0x60, 0x10, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 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, 0x04, 0x00, 0x28, 0x18, 0x00, 0x80, 0x64, 0x20, + 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x90, 0x6c, 0x10, 0x78, 0x58, 0x10, 0x50, 0x38, 0x00, 0x38, 0x20, 0x00, + 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x18, 0x0c, 0x00, 0x18, 0x0c, 0x00, + 0x20, 0x0c, 0x00, 0x20, 0x10, 0x00, 0x30, 0x20, 0x00, 0x50, 0x3c, 0x00, + 0x70, 0x54, 0x08, 0x88, 0x68, 0x10, 0xa0, 0x78, 0x10, 0xa0, 0x7c, 0x08, + 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x7c, 0x08, 0x88, 0x6c, 0x18, 0x48, 0x34, 0x00, + 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x4c, 0x00, 0xa8, 0x88, 0x28, 0xb8, 0x90, 0x18, 0xb8, 0x94, 0x10, + 0xb8, 0x94, 0x10, 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x9c, 0x18, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, + 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xd0, 0xac, 0x50, 0xd0, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xb0, 0x50, + 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x60, 0xc8, 0xb4, 0x60, 0xc0, 0xac, 0x68, + 0x70, 0x60, 0x38, 0x10, 0x0c, 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, 0x08, 0x04, 0x00, 0x40, 0x34, 0x10, 0xc0, 0xb0, 0x78, + 0xd0, 0xb8, 0x68, 0xd8, 0xbc, 0x60, 0xd8, 0xbc, 0x68, 0xd8, 0xbc, 0x68, + 0xd8, 0xc0, 0x60, 0xd0, 0xbc, 0x60, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd0, 0xc0, 0x78, + 0x98, 0x8c, 0x58, 0x20, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x38, 0x28, 0x00, 0x90, 0x6c, 0x10, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0x98, 0x78, 0x18, 0x88, 0x68, 0x20, 0x68, 0x50, 0x10, + 0x58, 0x40, 0x08, 0x50, 0x3c, 0x00, 0x60, 0x4c, 0x10, 0x78, 0x60, 0x18, + 0x98, 0x74, 0x18, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x00, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 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, 0x10, 0x04, 0x00, 0x38, 0x24, 0x00, + 0x80, 0x60, 0x18, 0xa0, 0x78, 0x10, 0xa8, 0x80, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, 0x98, 0x74, 0x18, 0x90, 0x70, 0x20, + 0x80, 0x68, 0x20, 0x78, 0x5c, 0x18, 0x70, 0x54, 0x10, 0x70, 0x58, 0x18, + 0x78, 0x5c, 0x18, 0x80, 0x68, 0x20, 0x90, 0x70, 0x20, 0x98, 0x74, 0x18, + 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xa8, 0x7c, 0x08, 0x90, 0x74, 0x18, 0x58, 0x40, 0x08, 0x18, 0x0c, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x38, 0x00, 0xa0, 0x88, 0x30, 0xb0, 0x90, 0x20, 0xb8, 0x98, 0x10, + 0xc0, 0x98, 0x10, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x9c, 0x18, + 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc8, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc8, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, + 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, + 0xd0, 0xac, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, + 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xd0, 0xac, 0x50, + 0xd0, 0xac, 0x50, 0xd0, 0xb0, 0x50, 0xc8, 0xb0, 0x50, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x50, 0xc8, 0xb0, 0x50, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, + 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x60, 0xd0, 0xb4, 0x58, 0xc8, 0xb0, 0x68, + 0xa8, 0x94, 0x60, 0x38, 0x28, 0x08, 0x08, 0x04, 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, 0x08, 0x04, 0x00, 0x40, 0x34, 0x10, 0xc8, 0xb4, 0x78, + 0xd0, 0xb8, 0x68, 0xd8, 0xbc, 0x68, 0xd8, 0xbc, 0x68, 0xd8, 0xbc, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd0, 0xc0, 0x78, + 0x80, 0x78, 0x50, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x18, 0x10, 0x00, 0x70, 0x54, 0x10, 0xa0, 0x74, 0x10, + 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x10, 0xa0, 0x78, 0x10, + 0xa0, 0x78, 0x10, 0xa0, 0x78, 0x10, 0xa0, 0x78, 0x10, 0xa0, 0x7c, 0x10, + 0xa8, 0x7c, 0x08, 0xa8, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x10, 0x60, 0x48, 0x00, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x08, 0xa0, 0x78, 0x10, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 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, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x40, 0x2c, 0x00, 0x88, 0x68, 0x18, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0xa0, 0x78, 0x10, 0xa0, 0x78, 0x10, 0xa0, 0x78, 0x10, + 0xa0, 0x78, 0x10, 0xa0, 0x78, 0x10, 0xa8, 0x78, 0x08, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, + 0x90, 0x70, 0x18, 0x60, 0x48, 0x08, 0x18, 0x0c, 0x00, 0x08, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x2c, 0x00, 0x90, 0x78, 0x30, 0xb0, 0x90, 0x20, 0xc0, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, + 0xc0, 0x9c, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc8, 0x9c, 0x28, 0xc8, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xc8, 0xac, 0x50, 0xd0, 0xac, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xac, 0x50, + 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x50, 0xd0, 0xb4, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x60, 0xd0, 0xb4, 0x58, 0xd0, 0xb8, 0x60, 0xd0, 0xb4, 0x60, + 0xc0, 0xb0, 0x70, 0x70, 0x60, 0x30, 0x10, 0x08, 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, 0x08, 0x04, 0x00, 0x50, 0x40, 0x18, 0xc8, 0xb4, 0x78, + 0xd0, 0xbc, 0x70, 0xd8, 0xbc, 0x68, 0xd8, 0xbc, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x70, 0xc8, 0xbc, 0x78, + 0x68, 0x60, 0x38, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x38, 0x28, 0x00, 0x90, 0x70, 0x20, + 0xa0, 0x7c, 0x10, 0xa8, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x00, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x08, 0xa0, 0x78, 0x10, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x20, 0x0c, 0x00, + 0x08, 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, 0x08, 0x04, 0x00, + 0x18, 0x0c, 0x00, 0x40, 0x2c, 0x00, 0x88, 0x6c, 0x18, 0xa0, 0x7c, 0x10, + 0xa8, 0x7c, 0x08, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa8, 0x80, 0x00, 0xa0, 0x7c, 0x08, 0x98, 0x70, 0x18, + 0x60, 0x48, 0x08, 0x20, 0x14, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x18, 0x00, 0x70, 0x5c, 0x20, 0xb0, 0x90, 0x28, 0xb8, 0x98, 0x18, + 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, + 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xd0, 0xac, 0x50, 0xd0, 0xac, 0x50, + 0xd0, 0xac, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x60, + 0xd0, 0xb4, 0x58, 0xd0, 0xb8, 0x58, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, + 0xc8, 0xb4, 0x68, 0xb8, 0xa8, 0x70, 0x30, 0x24, 0x08, 0x08, 0x04, 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, 0x04, 0x00, 0x60, 0x54, 0x28, 0xc8, 0xb8, 0x78, + 0xd0, 0xbc, 0x68, 0xd8, 0xbc, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc4, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc0, 0x70, 0xb8, 0xac, 0x70, + 0x40, 0x38, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x08, 0x00, 0x50, 0x38, 0x08, + 0x90, 0x70, 0x18, 0xa0, 0x78, 0x08, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x7c, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x08, 0x78, 0x5c, 0x18, 0x18, 0x0c, 0x00, + 0x08, 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, + 0x08, 0x00, 0x00, 0x10, 0x08, 0x00, 0x38, 0x24, 0x00, 0x78, 0x58, 0x18, + 0x98, 0x74, 0x18, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, 0x88, 0x6c, 0x18, 0x50, 0x38, 0x00, + 0x20, 0x10, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x48, 0x3c, 0x08, 0xa0, 0x84, 0x30, 0xb8, 0x94, 0x20, + 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x18, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, 0xd0, 0xac, 0x50, 0xd0, 0xac, 0x50, + 0xd0, 0xac, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb0, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb8, 0x60, + 0xd0, 0xb8, 0x58, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, + 0xd0, 0xb8, 0x60, 0xc8, 0xb4, 0x70, 0x80, 0x70, 0x48, 0x18, 0x0c, 0x00, + 0x00, 0x04, 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, 0x04, 0x00, 0x60, 0x54, 0x20, 0xc8, 0xb8, 0x78, + 0xd0, 0xbc, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x70, 0xd0, 0xc0, 0x78, 0x90, 0x84, 0x50, + 0x18, 0x10, 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, 0x00, 0x00, 0x20, 0x10, 0x00, + 0x60, 0x44, 0x08, 0x90, 0x70, 0x18, 0xa8, 0x7c, 0x10, 0xa8, 0x7c, 0x08, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0xa0, 0x74, 0x08, 0xa0, 0x74, 0x08, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x7c, 0x10, 0x78, 0x5c, 0x18, 0x18, 0x0c, 0x00, + 0x08, 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, 0x00, 0x04, 0x00, 0x10, 0x04, 0x00, 0x30, 0x1c, 0x00, + 0x60, 0x48, 0x08, 0x98, 0x74, 0x18, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x98, 0x78, 0x18, 0x78, 0x60, 0x10, 0x40, 0x30, 0x00, 0x18, 0x08, 0x00, + 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x20, 0x14, 0x00, 0x80, 0x6c, 0x28, 0xb0, 0x90, 0x30, + 0xb8, 0x94, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x98, 0x20, 0xc0, 0x9c, 0x20, + 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x20, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, + 0xc8, 0xa0, 0x38, 0xc0, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, + 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xd0, 0xac, 0x50, 0xd0, 0xac, 0x50, 0xd0, 0xac, 0x50, 0xd0, 0xac, 0x50, + 0xd0, 0xac, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb8, 0x58, 0xd8, 0xb8, 0x58, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, + 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd8, 0xb8, 0x60, 0xd8, 0xb8, 0x60, + 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x68, 0xb0, 0x9c, 0x60, 0x40, 0x34, 0x08, + 0x08, 0x04, 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, 0x04, 0x00, 0x60, 0x54, 0x28, 0xc8, 0xb8, 0x78, + 0xd0, 0xbc, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xe0, 0xc4, 0x68, + 0xd8, 0xc4, 0x70, 0xd8, 0xc4, 0x78, 0xd0, 0xbc, 0x80, 0x40, 0x34, 0x10, + 0x08, 0x04, 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, 0x08, 0x04, 0x00, + 0x20, 0x14, 0x00, 0x58, 0x44, 0x10, 0x98, 0x74, 0x20, 0xa0, 0x78, 0x10, + 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x70, 0x50, 0x00, 0x78, 0x58, 0x00, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x7c, 0x08, + 0x98, 0x78, 0x18, 0x60, 0x48, 0x08, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x08, 0x00, 0x58, 0x44, 0x10, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xa0, 0x78, 0x10, 0x78, 0x5c, 0x18, 0x18, 0x0c, 0x00, + 0x08, 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, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x20, 0x10, 0x00, 0x48, 0x38, 0x00, 0x80, 0x64, 0x18, 0x98, 0x74, 0x18, + 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xa8, 0x7c, 0x08, 0xa8, 0x78, 0x08, 0xa0, 0x78, 0x18, 0x90, 0x70, 0x20, + 0x58, 0x44, 0x08, 0x30, 0x1c, 0x00, 0x10, 0x08, 0x00, 0x08, 0x04, 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, 0x10, 0x08, 0x00, 0x30, 0x20, 0x00, 0x98, 0x80, 0x38, + 0xb0, 0x90, 0x30, 0xc0, 0x98, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x20, + 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, + 0xd0, 0xac, 0x50, 0xd0, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xd0, 0xac, 0x50, + 0xd0, 0xac, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, + 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd8, 0xb8, 0x58, 0xd0, 0xb8, 0x58, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, + 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd8, 0xb8, 0x60, 0xd8, 0xb8, 0x60, + 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x68, 0xc8, 0xb8, 0x70, 0x80, 0x78, 0x40, + 0x18, 0x14, 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, 0x04, 0x00, 0x60, 0x54, 0x28, 0xc8, 0xbc, 0x78, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xe0, 0xc4, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, + 0xe0, 0xc4, 0x68, 0xe0, 0xc4, 0x68, 0xe0, 0xc4, 0x70, 0xd8, 0xc4, 0x70, + 0xd8, 0xc0, 0x70, 0xc8, 0xb8, 0x78, 0x70, 0x68, 0x40, 0x08, 0x08, 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, + 0x08, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x48, 0x30, 0x00, 0x80, 0x60, 0x18, + 0x98, 0x74, 0x10, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xa8, 0x7c, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x80, 0x00, 0xa8, 0x80, 0x00, + 0xa8, 0x7c, 0x08, 0xa0, 0x7c, 0x10, 0x98, 0x70, 0x18, 0x70, 0x54, 0x08, + 0x38, 0x1c, 0x00, 0x68, 0x4c, 0x08, 0x98, 0x74, 0x18, 0xa0, 0x7c, 0x08, + 0xa0, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x90, 0x74, 0x20, 0x58, 0x44, 0x08, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x58, 0x44, 0x10, 0x98, 0x74, 0x20, 0xa0, 0x7c, 0x10, + 0xa8, 0x7c, 0x10, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x10, 0x98, 0x78, 0x18, 0x70, 0x5c, 0x20, 0x18, 0x0c, 0x00, + 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, 0x28, 0x18, 0x00, 0x58, 0x40, 0x00, + 0x80, 0x64, 0x10, 0x98, 0x74, 0x10, 0xa0, 0x78, 0x10, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x08, 0xb0, 0x80, 0x08, 0xb0, 0x7c, 0x00, 0xb0, 0x7c, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, + 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xb0, 0x80, 0x00, 0xa8, 0x80, 0x00, + 0xa8, 0x80, 0x00, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa0, 0x78, 0x10, + 0x98, 0x74, 0x10, 0x88, 0x68, 0x10, 0x68, 0x4c, 0x08, 0x38, 0x24, 0x00, + 0x18, 0x08, 0x00, 0x08, 0x04, 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, 0x10, 0x08, 0x00, 0x40, 0x34, 0x08, + 0x98, 0x80, 0x38, 0xb8, 0x94, 0x38, 0xc0, 0x98, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0x9c, 0x28, 0xc0, 0x9c, 0x28, + 0xc0, 0x9c, 0x28, 0xc0, 0xa0, 0x28, 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, + 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, + 0xc8, 0xa4, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x40, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xd0, 0xb0, 0x50, + 0xc8, 0xac, 0x50, 0xc8, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x60, 0xd0, 0xb4, 0x58, 0xd0, 0xb8, 0x58, + 0xd0, 0xb8, 0x58, 0xd0, 0xb8, 0x58, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, + 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd8, 0xb8, 0x60, 0xd8, 0xbc, 0x60, + 0xd0, 0xb8, 0x60, 0xd0, 0xbc, 0x60, 0xd0, 0xb8, 0x68, 0xb8, 0xac, 0x70, + 0x48, 0x3c, 0x18, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x60, 0x54, 0x28, 0xd0, 0xb8, 0x78, + 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc0, 0x68, 0xe0, 0xc4, 0x68, + 0xd8, 0xc4, 0x68, 0xe0, 0xc4, 0x68, 0xe0, 0xc4, 0x68, 0xe0, 0xc4, 0x68, + 0xe0, 0xc4, 0x68, 0xe0, 0xc4, 0x68, 0xd8, 0xc4, 0x70, 0xd8, 0xc4, 0x78, + 0xc8, 0xb8, 0x78, 0x80, 0x78, 0x48, 0x20, 0x18, 0x00, 0x00, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x30, 0x1c, 0x00, + 0x58, 0x44, 0x08, 0x80, 0x64, 0x18, 0x98, 0x74, 0x18, 0xa0, 0x78, 0x10, + 0xa8, 0x7c, 0x10, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa0, 0x7c, 0x10, + 0x98, 0x78, 0x18, 0x80, 0x64, 0x18, 0x50, 0x3c, 0x08, 0x28, 0x14, 0x00, + 0x20, 0x10, 0x00, 0x50, 0x40, 0x10, 0x80, 0x64, 0x20, 0x80, 0x64, 0x18, + 0x88, 0x68, 0x18, 0x88, 0x68, 0x18, 0x88, 0x68, 0x18, 0x80, 0x64, 0x18, + 0x78, 0x64, 0x28, 0x48, 0x3c, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x48, 0x38, 0x18, 0x78, 0x64, 0x20, 0x80, 0x64, 0x18, + 0x88, 0x64, 0x18, 0x88, 0x64, 0x18, 0x88, 0x68, 0x18, 0x88, 0x68, 0x18, + 0x88, 0x68, 0x18, 0x80, 0x64, 0x20, 0x60, 0x4c, 0x20, 0x10, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, + 0x30, 0x1c, 0x00, 0x50, 0x3c, 0x08, 0x70, 0x54, 0x10, 0x90, 0x6c, 0x18, + 0x98, 0x78, 0x18, 0xa0, 0x78, 0x10, 0xa0, 0x7c, 0x10, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, + 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, 0xa8, 0x7c, 0x08, + 0xa0, 0x78, 0x10, 0x98, 0x74, 0x10, 0x90, 0x70, 0x18, 0x78, 0x5c, 0x18, + 0x58, 0x44, 0x08, 0x30, 0x20, 0x00, 0x18, 0x0c, 0x00, 0x08, 0x04, 0x00, + 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0c, 0x00, + 0x48, 0x34, 0x08, 0x98, 0x80, 0x38, 0xb8, 0x94, 0x40, 0xb8, 0x98, 0x38, + 0xc0, 0x9c, 0x30, 0xc0, 0x9c, 0x30, 0xc0, 0x9c, 0x30, 0xc0, 0x9c, 0x30, + 0xc0, 0xa0, 0x30, 0xc0, 0xa0, 0x30, 0xc8, 0xa0, 0x30, 0xc8, 0xa0, 0x30, + 0xc8, 0xa0, 0x38, 0xc8, 0xa4, 0x38, 0xc8, 0xa0, 0x38, 0xc0, 0xa0, 0x38, + 0xc0, 0xa4, 0x38, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc0, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa4, 0x40, + 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, 0xc8, 0xa4, 0x40, 0xc8, 0xa8, 0x40, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xc8, 0xac, 0x48, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xd0, 0xac, 0x50, 0xc8, 0xb0, 0x50, 0xd0, 0xac, 0x50, 0xd0, 0xb0, 0x50, + 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x50, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, + 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, + 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x58, 0xd0, 0xb4, 0x60, 0xd0, 0xb4, 0x60, + 0xd0, 0xb4, 0x60, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, + 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, + 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd8, 0xb8, 0x60, 0xd8, 0xb8, 0x60, + 0xd8, 0xbc, 0x60, 0xd0, 0xbc, 0x60, 0xd0, 0xbc, 0x68, 0xc8, 0xb4, 0x70, + 0x90, 0x84, 0x58, 0x10, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x68, 0x5c, 0x28, 0xd0, 0xbc, 0x78, + 0xd0, 0xc0, 0x70, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x68, 0xd8, 0xc4, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc0, 0x68, 0xe0, 0xc4, 0x68, 0xd8, 0xc4, 0x68, + 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, 0xd8, 0xc4, 0x68, + 0xd8, 0xc4, 0x70, 0xd8, 0xc4, 0x70, 0xd8, 0xc4, 0x78, 0xd0, 0xc0, 0x80, + 0x80, 0x74, 0x48, 0x20, 0x1c, 0x00, 0x00, 0x04, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x18, 0x10, 0x00, 0x30, 0x20, 0x00, 0x58, 0x3c, 0x00, 0x70, 0x58, 0x08, + 0x90, 0x70, 0x20, 0x98, 0x74, 0x20, 0x98, 0x74, 0x18, 0x98, 0x78, 0x18, + 0x98, 0x74, 0x18, 0x98, 0x74, 0x18, 0x90, 0x74, 0x20, 0x80, 0x64, 0x18, + 0x60, 0x48, 0x08, 0x38, 0x20, 0x00, 0x18, 0x0c, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x20, 0x14, 0x00, 0x30, 0x20, 0x00, 0x38, 0x24, 0x00, + 0x38, 0x20, 0x00, 0x38, 0x20, 0x00, 0x38, 0x20, 0x00, 0x30, 0x20, 0x00, + 0x30, 0x20, 0x00, 0x18, 0x10, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x18, 0x10, 0x00, 0x30, 0x20, 0x00, 0x38, 0x20, 0x00, + 0x38, 0x20, 0x00, 0x38, 0x20, 0x00, 0x38, 0x20, 0x00, 0x38, 0x24, 0x00, + 0x30, 0x20, 0x00, 0x30, 0x20, 0x00, 0x20, 0x18, 0x00, 0x08, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x18, 0x08, 0x00, 0x28, 0x14, 0x00, 0x40, 0x28, 0x00, + 0x50, 0x38, 0x00, 0x70, 0x54, 0x08, 0x88, 0x68, 0x18, 0x90, 0x74, 0x20, + 0x98, 0x74, 0x20, 0x98, 0x74, 0x18, 0x98, 0x78, 0x18, 0x98, 0x74, 0x18, + 0x98, 0x78, 0x20, 0x98, 0x74, 0x20, 0x98, 0x74, 0x20, 0x90, 0x70, 0x20, + 0x78, 0x58, 0x10, 0x60, 0x44, 0x00, 0x40, 0x2c, 0x00, 0x28, 0x18, 0x00, + 0x18, 0x0c, 0x00, 0x10, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x08, 0x08, 0x00, 0x20, 0x18, 0x00, 0x70, 0x60, 0x28, 0xa0, 0x84, 0x40, + 0xb0, 0x94, 0x40, 0xb0, 0x98, 0x38, 0xb8, 0x9c, 0x38, 0xc0, 0x9c, 0x38, + 0xc0, 0xa0, 0x38, 0xc0, 0xa0, 0x38, 0xc0, 0xa0, 0x38, 0xc0, 0xa0, 0x38, + 0xc0, 0xa0, 0x38, 0xc0, 0xa0, 0x38, 0xc0, 0xa0, 0x40, 0xc0, 0xa0, 0x38, + 0xc0, 0xa4, 0x40, 0xc0, 0xa4, 0x40, 0xc8, 0xa4, 0x40, 0xc0, 0xa4, 0x40, + 0xc0, 0xa4, 0x40, 0xc0, 0xa4, 0x40, 0xc8, 0xa4, 0x48, 0xc0, 0xa4, 0x48, + 0xc8, 0xa4, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x48, + 0xc8, 0xa8, 0x48, 0xc8, 0xa8, 0x50, 0xc8, 0xa8, 0x50, 0xc8, 0xa8, 0x50, + 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, 0xc8, 0xac, 0x50, + 0xd0, 0xac, 0x58, 0xc8, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xc8, 0xb0, 0x58, + 0xc8, 0xb0, 0x58, 0xc8, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, + 0xc8, 0xb0, 0x58, 0xc8, 0xb0, 0x58, 0xd0, 0xb0, 0x58, 0xd0, 0xb0, 0x58, + 0xd0, 0xb4, 0x58, 0xd0, 0xb0, 0x60, 0xd0, 0xb4, 0x60, 0xd0, 0xb4, 0x60, + 0xd0, 0xb4, 0x60, 0xd0, 0xb4, 0x60, 0xd0, 0xb4, 0x60, 0xd0, 0xb4, 0x60, + 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, + 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, 0xd0, 0xb8, 0x60, + 0xd0, 0xb8, 0x68, 0xd0, 0xb8, 0x68, 0xd8, 0xb8, 0x68, 0xd8, 0xbc, 0x68, + 0xd0, 0xb8, 0x60, 0xd8, 0xbc, 0x68, 0xd0, 0xbc, 0x68, 0xc8, 0xb8, 0x70, + 0xc0, 0xb4, 0x78, 0x48, 0x3c, 0x18, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x80, 0x78, 0x48, 0xd0, 0xbc, 0x78, + 0xd0, 0xc0, 0x70, 0xd8, 0xc0, 0x68, 0xd8, 0xc0, 0x70, 0xd8, 0xc0, 0x70, + 0xd8, 0xc4, 0x70, 0xd8, 0xc0, 0x68, 0xd8, 0xc4, 0x70, 0xd8, 0xc4, 0x68, + 0xd8, 0xc4, 0x70, 0xd8, 0xc4, 0x70, 0xd8, 0xc4, 0x70, 0xd8, 0xc4, 0x70, + 0xd0, 0xc0, 0x78, 0xc0, 0xb4, 0x78, 0xa0, 0x94, 0x60, 0x50, 0x48, 0x20, + 0x10, 0x08, 0x00, 0x00, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x10, 0x08, 0x00, 0x18, 0x0c, 0x00, + 0x20, 0x10, 0x00, 0x30, 0x1c, 0x00, 0x38, 0x24, 0x00, 0x40, 0x30, 0x00, + 0x40, 0x30, 0x00, 0x38, 0x24, 0x00, 0x28, 0x18, 0x00, 0x18, 0x0c, 0x00, + 0x18, 0x08, 0x00, 0x10, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 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, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 0x04, 0x00, 0x08, 0x04, 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, 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, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x10, 0x08, 0x00, 0x18, 0x08, 0x00, 0x18, 0x0c, 0x00, 0x28, 0x18, 0x00, + 0x30, 0x20, 0x00, 0x38, 0x28, 0x00, 0x48, 0x30, 0x00, 0x48, 0x34, 0x00, + 0x40, 0x2c, 0x00, 0x38, 0x20, 0x00, 0x28, 0x18, 0x00, 0x20, 0x0c, 0x00, + 0x18, 0x0c, 0x00, 0x10, 0x08, 0x00, 0x10, 0x04, 0x00, 0x08, 0x04, 0x00, + 0x08, 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, 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, 0x04, 0x00, 0x18, 0x10, 0x00, 0x40, 0x30, 0x08, + 0x68, 0x54, 0x18, 0x88, 0x74, 0x30, 0xa0, 0x84, 0x38, 0xb0, 0x94, 0x40, + 0xb8, 0x9c, 0x48, 0xb8, 0x9c, 0x48, 0xb8, 0x9c, 0x48, 0xb8, 0x9c, 0x48, + 0xb8, 0x9c, 0x48, 0xb8, 0x9c, 0x48, 0xb8, 0x9c, 0x50, 0xb8, 0xa0, 0x50, + 0xb8, 0xa0, 0x50, 0xb8, 0xa0, 0x50, 0xc0, 0xa0, 0x50, 0xb8, 0xa0, 0x50, + 0xb8, 0xa0, 0x50, 0xb8, 0xa0, 0x50, 0xc0, 0xa0, 0x58, 0xb8, 0xa0, 0x58, + 0xb8, 0xa0, 0x58, 0xb8, 0xa0, 0x58, 0xc0, 0xa4, 0x58, 0xc0, 0xa4, 0x58, + 0xc0, 0xa4, 0x58, 0xc0, 0xa4, 0x58, 0xc0, 0xa4, 0x58, 0xc0, 0xa4, 0x58, + 0xc0, 0xa8, 0x60, 0xc0, 0xa8, 0x60, 0xc0, 0xa8, 0x60, 0xc0, 0xa8, 0x60, + 0xc0, 0xa8, 0x60, 0xc0, 0xa8, 0x60, 0xc0, 0xa8, 0x60, 0xc0, 0xa8, 0x60, + 0xc0, 0xac, 0x60, 0xc0, 0xa8, 0x60, 0xc0, 0xac, 0x60, 0xc0, 0xac, 0x60, + 0xc0, 0xac, 0x60, 0xc0, 0xac, 0x60, 0xc0, 0xac, 0x68, 0xc8, 0xac, 0x68, + 0xc8, 0xac, 0x68, 0xc8, 0xac, 0x68, 0xc8, 0xb0, 0x68, 0xc8, 0xac, 0x68, + 0xc8, 0xac, 0x68, 0xc8, 0xb0, 0x68, 0xc8, 0xb0, 0x68, 0xc8, 0xb0, 0x68, + 0xc8, 0xb0, 0x68, 0xc8, 0xb0, 0x68, 0xc8, 0xb0, 0x70, 0xc8, 0xb0, 0x70, + 0xc8, 0xb0, 0x70, 0xc8, 0xb0, 0x70, 0xc8, 0xb0, 0x70, 0xc8, 0xb4, 0x70, + 0xc8, 0xb4, 0x70, 0xc8, 0xb4, 0x70, 0xc8, 0xb4, 0x70, 0xd0, 0xb4, 0x70, + 0xc8, 0xb4, 0x70, 0xc8, 0xb4, 0x70, 0xc8, 0xb4, 0x70, 0xc8, 0xb4, 0x70, + 0xd0, 0xb8, 0x70, 0xd0, 0xb8, 0x70, 0xc8, 0xb8, 0x70, 0xc8, 0xb8, 0x78, + 0xc0, 0xb4, 0x80, 0x90, 0x88, 0x60, 0x18, 0x14, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x80, 0x74, 0x50, 0xc8, 0xbc, 0x80, + 0xc8, 0xbc, 0x78, 0xd0, 0xbc, 0x78, 0xd0, 0xbc, 0x78, 0xd0, 0xc0, 0x78, + 0xd0, 0xc0, 0x78, 0xd0, 0xc0, 0x78, 0xd0, 0xc0, 0x78, 0xd0, 0xc0, 0x78, + 0xd0, 0xc0, 0x78, 0xd0, 0xc0, 0x78, 0xc0, 0xb0, 0x70, 0xa8, 0x9c, 0x60, + 0x88, 0x7c, 0x48, 0x58, 0x54, 0x28, 0x28, 0x20, 0x00, 0x08, 0x08, 0x00, + 0x00, 0x04, 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, 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, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, + 0x10, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 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, + 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, 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, 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, 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, 0x04, 0x00, 0x08, 0x00, 0x00, + 0x08, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x04, 0x00, 0x10, 0x08, 0x00, + 0x10, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 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, + 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, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, + 0x18, 0x0c, 0x00, 0x28, 0x1c, 0x00, 0x38, 0x24, 0x00, 0x40, 0x30, 0x00, + 0x40, 0x30, 0x00, 0x40, 0x30, 0x00, 0x40, 0x30, 0x00, 0x40, 0x30, 0x00, + 0x40, 0x30, 0x00, 0x40, 0x30, 0x00, 0x40, 0x30, 0x00, 0x40, 0x30, 0x08, + 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, + 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, + 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, 0x40, 0x34, 0x08, 0x40, 0x34, 0x08, + 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, + 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, 0x40, 0x34, 0x08, 0x40, 0x34, 0x08, + 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, 0x40, 0x30, 0x08, + 0x40, 0x34, 0x08, 0x40, 0x30, 0x08, 0x40, 0x34, 0x08, 0x40, 0x34, 0x08, + 0x40, 0x34, 0x08, 0x40, 0x34, 0x08, 0x40, 0x30, 0x10, 0x40, 0x34, 0x08, + 0x40, 0x30, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, + 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, + 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, + 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, + 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, + 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, + 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, 0x40, 0x34, 0x10, + 0x40, 0x34, 0x18, 0x30, 0x28, 0x10, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x20, 0x08, 0x40, 0x34, 0x18, + 0x40, 0x38, 0x10, 0x40, 0x38, 0x10, 0x40, 0x38, 0x10, 0x40, 0x38, 0x10, + 0x40, 0x38, 0x10, 0x40, 0x38, 0x10, 0x40, 0x38, 0x10, 0x40, 0x38, 0x10, + 0x40, 0x38, 0x10, 0x40, 0x38, 0x10, 0x38, 0x30, 0x08, 0x30, 0x28, 0x08, + 0x18, 0x14, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +#endif + +#endif diff --git a/lk/platform/msm_shared/include/uart_dm.h b/lk/platform/msm_shared/include/uart_dm.h new file mode 100644 index 0000000..bf386c4 --- /dev/null +++ b/lk/platform/msm_shared/include/uart_dm.h @@ -0,0 +1,273 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 __UART_DM_H__ +#define __UART_DM_H__ + +#define MSM_BOOT_UART_DM_EXTR_BITS(value, start_pos, end_pos) \ + ((value << (32 - end_pos))\ + >> (32 - (end_pos - start_pos))) + +/* GPIO pins - 2 wire using UART2 */ +#define MSM_BOOT_UART_DM_RX_GPIO 117 +#define MSM_BOOT_UART_DM_TX_GPIO 118 + + +/* UART Parity Mode */ +enum MSM_BOOT_UART_DM_PARITY_MODE +{ + MSM_BOOT_UART_DM_NO_PARITY, + MSM_BOOT_UART_DM_ODD_PARITY, + MSM_BOOT_UART_DM_EVEN_PARITY, + MSM_BOOT_UART_DM_SPACE_PARITY +}; + +/* UART Stop Bit Length */ +enum MSM_BOOT_UART_DM_STOP_BIT_LEN +{ + MSM_BOOT_UART_DM_SBL_9_16, + MSM_BOOT_UART_DM_SBL_1, + MSM_BOOT_UART_DM_SBL_1_9_16, + MSM_BOOT_UART_DM_SBL_2 +}; + +/* UART Bits per Char */ +enum MSM_BOOT_UART_DM_BITS_PER_CHAR +{ + MSM_BOOT_UART_DM_5_BPS, + MSM_BOOT_UART_DM_6_BPS, + MSM_BOOT_UART_DM_7_BPS, + MSM_BOOT_UART_DM_8_BPS +}; + +/* 8-N-1 Configuration */ +#define MSM_BOOT_UART_DM_8_N_1_MODE (MSM_BOOT_UART_DM_NO_PARITY | \ + (MSM_BOOT_UART_DM_SBL_1 << 2) | \ + (MSM_BOOT_UART_DM_8_BPS << 4)) + +/* CSR is used to further divide fundamental frequency. + * Using EE we are dividing gsbi_uart_clk by 2 so as to get + * 115.2k bit rate for fundamental frequency of 3.6864 MHz */ +#define MSM_BOOT_UART_DM_RX_TX_BIT_RATE 0xEE + +/* + * Define Macros for GSBI and UARTDM Registers + */ + +/* Clocks */ + +#define MSM_BOOT_CLK_CTL_BASE 0x00900000 + +#define MSM_BOOT_PLL_ENABLE_SC0 (MSM_BOOT_CLK_CTL_BASE + 0x34C0) + +#define MSM_BOOT_PLL8_STATUS (MSM_BOOT_CLK_CTL_BASE + 0x3158) + +#define MSM_BOOT_GSBIn_HCLK_CTL(n) (MSM_BOOT_CLK_CTL_BASE + 0x29A0 +\ + ( 32 * n )) + +#define MSM_BOOT_GSBIn_UART_APPS_MD(n) (MSM_BOOT_CLK_CTL_BASE + 0x29B0 +\ + ( 32 * n)) + +#define MSM_BOOT_GSBIn_UART_APPS_NS(n) (MSM_BOOT_CLK_CTL_BASE + 0x29B4 +\ + (32 * n)) + +#define MSM_BOOT_UART_DM_GSBI_HCLK_CTL MSM_BOOT_GSBIn_HCLK_CTL(12) + +#define MSM_BOOT_UART_DM_APPS_MD MSM_BOOT_GSBIn_UART_APPS_MD(12) + +#define MSM_BOOT_UART_DM_APPS_NS MSM_BOOT_GSBIn_UART_APPS_NS(12) + + +/* Using GSBI12 for UART */ +#define MSM_BOOT_GSBI_BASE 0x19C00000 + +#define MSM_BOOT_GSBI_CTRL_REG MSM_BOOT_GSBI_BASE + +#define MSM_BOOT_UART_DM_BASE (MSM_BOOT_GSBI_BASE+0x40000) + +#define MSM_BOOT_UART_DM_REG(offset) (MSM_BOOT_UART_DM_BASE + offset) + +/* UART Operational Mode Register */ +#define MSM_BOOT_UART_DM_MR1 MSM_BOOT_UART_DM_REG(0x0000) +#define MSM_BOOT_UART_DM_MR2 MSM_BOOT_UART_DM_REG(0x0004) +#define MSM_BOOT_UART_DM_RXBRK_ZERO_CHAR_OFF (1 << 8) +#define MSM_BOOT_UART_DM_LOOPBACK (1 << 7) + +/* UART Clock Selection Register */ +#define MSM_BOOT_UART_DM_CSR MSM_BOOT_UART_DM_REG(0x0008) + +/* UART DM TX FIFO Registers - 4 */ +#define MSM_BOOT_UART_DM_TF(x) MSM_BOOT_UART_DM_REG(0x0070+(4*x)) + +/* UART Command Register */ +#define MSM_BOOT_UART_DM_CR MSM_BOOT_UART_DM_REG(0x0010) +#define MSM_BOOT_UART_DM_CR_RX_ENABLE (1 << 0) +#define MSM_BOOT_UART_DM_CR_RX_DISABLE (1 << 1) +#define MSM_BOOT_UART_DM_CR_TX_ENABLE (1 << 2) +#define MSM_BOOT_UART_DM_CR_TX_DISABLE (1 << 3) + +/* UART Channel Command */ +#define MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) ((x & 0x0f) << 4) +#define MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x) ((x >> 4 ) << 11 ) +#define MSM_BOOT_UART_DM_CR_CH_CMD(x) (MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) | \ + MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x)) +#define MSM_BOOT_UART_DM_CMD_NULL MSM_BOOT_UART_DM_CR_CH_CMD(0) +#define MSM_BOOT_UART_DM_CMD_RESET_RX MSM_BOOT_UART_DM_CR_CH_CMD(1) +#define MSM_BOOT_UART_DM_CMD_RESET_TX MSM_BOOT_UART_DM_CR_CH_CMD(2) +#define MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT MSM_BOOT_UART_DM_CR_CH_CMD(3) +#define MSM_BOOT_UART_DM_CMD_RES_BRK_CHG_INT MSM_BOOT_UART_DM_CR_CH_CMD(4) +#define MSM_BOOT_UART_DM_CMD_START_BRK MSM_BOOT_UART_DM_CR_CH_CMD(5) +#define MSM_BOOT_UART_DM_CMD_STOP_BRK MSM_BOOT_UART_DM_CR_CH_CMD(6) +#define MSM_BOOT_UART_DM_CMD_RES_CTS_N MSM_BOOT_UART_DM_CR_CH_CMD(7) +#define MSM_BOOT_UART_DM_CMD_RES_STALE_INT MSM_BOOT_UART_DM_CR_CH_CMD(8) +#define MSM_BOOT_UART_DM_CMD_PACKET_MODE MSM_BOOT_UART_DM_CR_CH_CMD(9) +#define MSM_BOOT_UART_DM_CMD_MODE_RESET MSM_BOOT_UART_DM_CR_CH_CMD(C) +#define MSM_BOOT_UART_DM_CMD_SET_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(D) +#define MSM_BOOT_UART_DM_CMD_RES_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(E) +#define MSM_BOOT_UART_DM_CMD_RES_TX_ERR MSM_BOOT_UART_DM_CR_CH_CMD(10) +#define MSM_BOOT_UART_DM_CMD_CLR_TX_DONE MSM_BOOT_UART_DM_CR_CH_CMD(11) +#define MSM_BOOT_UART_DM_CMD_RES_BRKSTRT_INT MSM_BOOT_UART_DM_CR_CH_CMD(12) +#define MSM_BOOT_UART_DM_CMD_RES_BRKEND_INT MSM_BOOT_UART_DM_CR_CH_CMD(13) +#define MSM_BOOT_UART_DM_CMD_RES_PER_FRM_INT MSM_BOOT_UART_DM_CR_CH_CMD(14) + +/*UART General Command */ +#define MSM_BOOT_UART_DM_CR_GENERAL_CMD(x) ((x) << 8) + +#define MSM_BOOT_UART_DM_GCMD_NULL MSM_BOOT_UART_DM_CR_GENERAL_CMD(0) +#define MSM_BOOT_UART_DM_GCMD_CR_PROT_EN MSM_BOOT_UART_DM_CR_GENERAL_CMD(1) +#define MSM_BOOT_UART_DM_GCMD_CR_PROT_DIS MSM_BOOT_UART_DM_CR_GENERAL_CMD(2) +#define MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT MSM_BOOT_UART_DM_CR_GENERAL_CMD(3) +#define MSM_BOOT_UART_DM_GCMD_SW_FORCE_STALE MSM_BOOT_UART_DM_CR_GENERAL_CMD(4) +#define MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT MSM_BOOT_UART_DM_CR_GENERAL_CMD(5) +#define MSM_BOOT_UART_DM_GCMD_DIS_STALE_EVT MSM_BOOT_UART_DM_CR_GENERAL_CMD(6) + +/* UART Interrupt Mask Register */ +#define MSM_BOOT_UART_DM_IMR MSM_BOOT_UART_DM_REG(0x0014) +#define MSM_BOOT_UART_DM_TXLEV (1 << 0) +#define MSM_BOOT_UART_DM_RXHUNT (1 << 1) +#define MSM_BOOT_UART_DM_RXBRK_CHNG (1 << 2) +#define MSM_BOOT_UART_DM_RXSTALE (1 << 3) +#define MSM_BOOT_UART_DM_RXLEV (1 << 4) +#define MSM_BOOT_UART_DM_DELTA_CTS (1 << 5) +#define MSM_BOOT_UART_DM_CURRENT_CTS (1 << 6) +#define MSM_BOOT_UART_DM_TX_READY (1 << 7) +#define MSM_BOOT_UART_DM_TX_ERROR (1 << 8) +#define MSM_BOOT_UART_DM_TX_DONE (1 << 9) +#define MSM_BOOT_UART_DM_RXBREAK_START (1 << 10) +#define MSM_BOOT_UART_DM_RXBREAK_END (1 << 11) +#define MSM_BOOT_UART_DM_PAR_FRAME_ERR_IRQ (1 << 12) + +#define MSM_BOOT_UART_DM_IMR_ENABLED (MSM_BOOT_UART_DM_TX_READY | \ + MSM_BOOT_UART_DM_TXLEV | \ + MSM_BOOT_UART_DM_RXLEV | \ + MSM_BOOT_UART_DM_RXSTALE) + +/* UART Interrupt Programming Register */ +#define MSM_BOOT_UART_DM_IPR MSM_BOOT_UART_DM_REG(0x0018) +#define MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB 0x0f +#define MSM_BOOT_UART_DM_STALE_TIMEOUT_MSB 0 /* Not used currently */ + +/* UART Transmit/Receive FIFO Watermark Register */ +#define MSM_BOOT_UART_DM_TFWR MSM_BOOT_UART_DM_REG(0x001C) +/* Interrupt is generated when FIFO level is less than or equal to this value */ +#define MSM_BOOT_UART_DM_TFW_VALUE 0 + +#define MSM_BOOT_UART_DM_RFWR MSM_BOOT_UART_DM_REG(0x0020) +/*Interrupt generated when no of words in RX FIFO is greater than this value */ +#define MSM_BOOT_UART_DM_RFW_VALUE 0 + +/* UART Hunt Character Register */ +#define MSM_BOOT_UART_DM_HCR MSM_BOOT_UART_DM_REG(0x0024) + +/* Used for RX transfer initialization */ +#define MSM_BOOT_UART_DM_DMRX MSM_BOOT_UART_DM_REG(0x0034) + +/* Default DMRX value - any value bigger than FIFO size would be fine */ +#define MSM_BOOT_UART_DM_DMRX_DEF_VALUE 0x220 + +/* Register to enable IRDA function */ +#define MSM_BOOT_UART_DM_IRDA MSM_BOOT_UART_DM_REG(0x0038) + +/* UART Data Mover Enable Register */ +#define MSM_BOOT_UART_DM_DMEN MSM_BOOT_UART_DM_REG(0x003C) + +/* Number of characters for Transmission */ +#define MSM_BOOT_UART_DM_NO_CHARS_FOR_TX MSM_BOOT_UART_DM_REG(0x0040) + +/* UART RX FIFO Base Address */ +#define MSM_BOOT_UART_DM_BADR MSM_BOOT_UART_DM_REG(0x0044) + +/* UART Status Register */ +#define MSM_BOOT_UART_DM_SR MSM_BOOT_UART_DM_REG(0x0008) +#define MSM_BOOT_UART_DM_SR_RXRDY (1 << 0) +#define MSM_BOOT_UART_DM_SR_RXFULL (1 << 1) +#define MSM_BOOT_UART_DM_SR_TXRDY (1 << 2) +#define MSM_BOOT_UART_DM_SR_TXEMT (1 << 3) +#define MSM_BOOT_UART_DM_SR_UART_OVERRUN (1 << 4) +#define MSM_BOOT_UART_DM_SR_PAR_FRAME_ERR (1 << 5) +#define MSM_BOOT_UART_DM_RX_BREAK (1 << 6) +#define MSM_BOOT_UART_DM_HUNT_CHAR (1 << 7) +#define MSM_BOOT_UART_DM_RX_BRK_START_LAST (1 << 8) + +/* UART Receive FIFO Registers - 4 in numbers */ +#define MSM_BOOT_UART_DM_RF(x) MSM_BOOT_UART_DM_REG(0x0070+(4*x)) + +/* UART Masked Interrupt Status Register */ +#define MSM_BOOT_UART_DM_MISR MSM_BOOT_UART_DM_REG(0x0010) + +/* UART Interrupt Status Register */ +#define MSM_BOOT_UART_DM_ISR MSM_BOOT_UART_DM_REG(0x0014) + +/* Number of characters received since the end of last RX transfer */ +#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP MSM_BOOT_UART_DM_REG(0x0038) + +/* UART TX FIFO Status Register */ +#define MSM_BOOT_UART_DM_TXFS MSM_BOOT_UART_DM_REG(0x004C) +#define MSM_BOOT_UART_DM_TXFS_STATE_LSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,0,6) +#define MSM_BOOT_UART_DM_TXFS_STATE_MSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,14,31) +#define MSM_BOOT_UART_DM_TXFS_BUF_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,7,9) +#define MSM_BOOT_UART_DM_TXFS_ASYNC_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,10,13) + +/* UART RX FIFO Status Register */ +#define MSM_BOOT_UART_DM_RXFS MSM_BOOT_UART_DM_REG(0x0050) +#define MSM_BOOT_UART_DM_RXFS_STATE_LSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,0,6) +#define MSM_BOOT_UART_DM_RXFS_STATE_MSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,14,31) +#define MSM_BOOT_UART_DM_RXFS_BUF_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,7,9) +#define MSM_BOOT_UART_DM_RXFS_ASYNC_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,10,13) + + + +/* Macros for Common Errors */ +#define MSM_BOOT_UART_DM_E_SUCCESS 0 +#define MSM_BOOT_UART_DM_E_FAILURE 1 +#define MSM_BOOT_UART_DM_E_TIMEOUT 2 +#define MSM_BOOT_UART_DM_E_INVAL 3 +#define MSM_BOOT_UART_DM_E_MALLOC_FAIL 4 +#define MSM_BOOT_UART_DM_E_RX_NOT_READY 5 + +#endif /* __UART_DM_H__*/ diff --git a/lk/platform/msm_shared/jtag.c b/lk/platform/msm_shared/jtag.c new file mode 100644 index 0000000..ca45404 --- /dev/null +++ b/lk/platform/msm_shared/jtag.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2008 The Android Open Source 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: + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#define STATUS_NOMSG 0 +#define STATUS_OKAY 1 +#define STATUS_FAIL 2 +#define STATUS_PRINT 3 + +volatile unsigned _jtag_cmd = 0; +volatile unsigned _jtag_msg = 0; +unsigned char _jtag_cmd_buffer[128]; +unsigned char _jtag_msg_buffer[128]; + +volatile unsigned _jtag_arg0 = 0; +volatile unsigned _jtag_arg1 = 0; +volatile unsigned _jtag_arg2 = 0; + + +void jtag_hook(void); + +static void jtag_msg(unsigned status, const char *msg) +{ + unsigned char *out = _jtag_msg_buffer; + while((*out++ = *msg++) != 0) ; + _jtag_msg = status; + do { + jtag_hook(); + } while(_jtag_msg != 0); +} + +void jtag_okay(const char *msg) +{ + if(msg == 0) msg = "OKAY"; + jtag_msg(STATUS_OKAY, msg); +} + +void jtag_fail(const char *msg) +{ + if(msg == 0) msg = "FAIL"; + jtag_msg(STATUS_FAIL, msg); +} + +int jtag_cmd_pending() +{ + jtag_hook(); + return (int) _jtag_cmd; +} + +void jtag_cmd_loop(void (*do_cmd)(const char *, unsigned, unsigned, unsigned)) +{ + unsigned n; + for(;;) { + if(jtag_cmd_pending()){ + do_cmd((const char*) _jtag_cmd_buffer, _jtag_arg0, _jtag_arg1, _jtag_arg2); + for(n = 0; n < 256; n++) _jtag_cmd_buffer[n] = 0; + _jtag_arg0 = 0; + _jtag_arg1 = 0; + _jtag_arg2 = 0; + _jtag_cmd = 0; + } + } +} + +static char jtag_putc_buffer[128]; +static unsigned jtag_putc_count = 0; + +static void jtag_push_buffer(void) +{ + jtag_putc_buffer[jtag_putc_count] = 0; + jtag_putc_count = 0; + jtag_msg(STATUS_PRINT, jtag_putc_buffer); +} + +void jtag_dputc(unsigned c) +{ + if((c < 32) || (c > 127)) { + if(c == '\n') { + jtag_push_buffer(); + } + return; + } + + jtag_putc_buffer[jtag_putc_count++] = c; + if(jtag_putc_count == 127) { + jtag_push_buffer(); + } +} + diff --git a/lk/platform/msm_shared/jtag_hook.S b/lk/platform/msm_shared/jtag_hook.S new file mode 100644 index 0000000..df41bbb --- /dev/null +++ b/lk/platform/msm_shared/jtag_hook.S @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 The Android Open Source 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: + * * 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. + * + * 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. + */ + +.global jtag_hook, func + +jtag_hook: + bx lr + diff --git a/lk/platform/msm_shared/lcdc.c b/lk/platform/msm_shared/lcdc.c new file mode 100644 index 0000000..675c5fb --- /dev/null +++ b/lk/platform/msm_shared/lcdc.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#if PLATFORM_MSM7X30 +#define MSM_MDP_BASE1 0xA3F00000 +#define LCDC_BASE 0xC0000 +#elif PLATFORM_MSM8X60 +#define MSM_MDP_BASE1 0x05100000 +#define LCDC_BASE 0xC0000 +#define LCDC_FB_ADDR 0x43E00000 +#else +#define MSM_MDP_BASE1 0xAA200000 +#define LCDC_BASE 0xE0000 +#endif + +#define LCDC_PIXCLK_IN_PS 26 +#define LCDC_FB_PHYS 0x16600000 +#define LCDC_FB_BPP 16 + +#define BIT(x) (1<<(x)) +#define DMA_DSTC0G_8BITS (BIT(1)|BIT(0)) +#define DMA_DSTC1B_8BITS (BIT(3)|BIT(2)) +#define DMA_DSTC2R_8BITS (BIT(5)|BIT(4)) +#define CLR_G 0x0 +#define CLR_B 0x1 +#define CLR_R 0x2 +#define MDP_GET_PACK_PATTERN(a,x,y,z,bit) (((a)<<(bit*3))|((x)<<(bit*2))|((y)< +#include +#include +#include +#include +#include +#include +#include + +#include "mddi_hw.h" + +static mddi_llentry *mlist = NULL; +static mddi_llentry *mlist_remote_write = NULL; + +#define MDDI_MAX_REV_PKT_SIZE 0x60 +#define MDDI_REV_PKT_BUF_SIZE 256 +static void *rev_pkt_buf; + +/* functions provided by the target specific panel code */ +void panel_init(struct mddi_client_caps *client_caps); +void panel_poweron(void); +void panel_backlight(int on); + +/* forward decls */ +static void mddi_start_update(void); +static int mddi_update_done(void); + +static struct fbcon_config fb_cfg = { + .format = FB_FORMAT_RGB565, + .bpp = 16, + .update_start = mddi_start_update, + .update_done = mddi_update_done, +}; + +static void printcaps(struct mddi_client_caps *c) +{ + if ((c->length != 0x4a) || (c->type != 0x42)) { + dprintf(INFO, "bad caps header\n"); + memset(c, 0, sizeof(*c)); + return; + } + + dprintf(INFO, "mddi: bm: %d,%d win %d,%d rgb %x\n", + c->bitmap_width, c->bitmap_height, + c->display_window_width, c->display_window_height, + c->rgb_cap); + dprintf(INFO, "mddi: vend %x prod %x\n", + c->manufacturer_name, c->product_code); +} + +/* TODO: add timeout */ +static int mddi_wait_status(unsigned statmask) +{ + while ((readl(MDDI_STAT) & statmask) == 0); + return 0; +} + +/* TODO: add timeout */ +static int mddi_wait_interrupt(unsigned intmask) +{ + while ((readl(MDDI_INT) & intmask) == 0); + return 0; +} + +void mddi_remote_write(unsigned val, unsigned reg) +{ + mddi_llentry *ll; + mddi_register_access *ra; + + ll = mlist_remote_write; + + ra = &(ll->u.r); + ra->length = 14 + 4; + ra->type = TYPE_REGISTER_ACCESS; + ra->client_id = 0; + ra->rw_info = MDDI_WRITE | 1; + ra->crc = 0; + + ra->reg_addr = reg; + ra->reg_data = val; + + ll->flags = 1; + ll->header_count = 14; + ll->data_count = 4; + ll->data = &ra->reg_data; + ll->next = (void *) 0; + ll->reserved = 0; + + writel((unsigned) ll, MDDI_PRI_PTR); + + mddi_wait_status(MDDI_STAT_PRI_LINK_LIST_DONE); +} + +static void mddi_start_update(void) +{ + writel((unsigned) mlist, MDDI_PRI_PTR); +} + +static int mddi_update_done(void) +{ + return !!(readl(MDDI_STAT) & MDDI_STAT_PRI_LINK_LIST_DONE); +} + +static void mddi_do_cmd(unsigned cmd) +{ + writel(cmd, MDDI_CMD); + mddi_wait_interrupt(MDDI_INT_NO_REQ_PKTS_PENDING); +} + +static void mddi_init_rev_encap(void) +{ + memset(rev_pkt_buf, 0xee, MDDI_REV_PKT_BUF_SIZE); + writel((unsigned) rev_pkt_buf, MDDI_REV_PTR); + writel((unsigned) rev_pkt_buf, MDDI_REV_PTR); + writel(MDDI_REV_PKT_BUF_SIZE, MDDI_REV_SIZE); + writel(MDDI_REV_PKT_BUF_SIZE, MDDI_REV_ENCAP_SZ); + mddi_do_cmd(CMD_FORCE_NEW_REV_PTR); +} + +static void mddi_set_auto_hibernate(unsigned on) +{ + writel(CMD_POWER_DOWN, MDDI_CMD); + mddi_wait_interrupt(MDDI_INT_IN_HIBERNATION); + mddi_do_cmd(CMD_HIBERNATE | !!on); +} + +void mddi_set_caps(mddi_client_caps *c) +{ + /* Hardcoding the capability values */ + c->length = 74; + c->type = 66; + c->client_id = 0; + c->protocol_ver = 1; + c->min_protocol_ver = 1; + c->data_rate_cap = 400; + c->interface_type_cap = 0; + c->num_alt_displays = 1; + c->postcal_data_rate = 400; + c->bitmap_width = TARGET_XRES; + c->bitmap_height = TARGET_YRES; + c->display_window_width = TARGET_XRES; + c->display_window_height = TARGET_YRES; + c->cmap_size = 0; + c->cmap_rgb_width = 0; + c->rgb_cap = 34592; + c->mono_cap = 0; + c->reserved1 = 0; + c->ycbcr_cap = 0; + c->bayer_cap = 0; + c->alpha_cursor_planes = 0; + c->client_feature_cap = 4489216; + c->max_video_frame_rate_cap = 60; + c->min_video_frame_rate_cap = 0; + c->min_sub_frame_rate = 0; + c->audio_buf_depth = 0; + c->audio_channel_cap = 0; + c->audio_sampe_rate_rap = 0; + c->audio_sample_res = 0; + c->mic_audio_sample_res = 0; + c->mic_sample_rate_cap = 0; + c->keyboard_data_fmt = 0; + c->pointing_device_data_fmt = 0; + c->content_protection_type = 0; + c->manufacturer_name = 53859; + c->product_code = 34594; + c->reserved3 = 0; + c->serial_no = 1; + c->week_of_manufacture = 0; + c->year_of_manufacture = 0; + c->crc = 53536; +} + +static void mddi_get_caps(struct mddi_client_caps *caps) +{ + unsigned timeout = 100000; + unsigned n; + + writel(0xffffffff, MDDI_INT); + mddi_do_cmd(CMD_LINK_ACTIVE); + + /* sometimes this will fail -- do it three times for luck... */ + mddi_do_cmd(CMD_RTD_MEASURE); + thread_sleep(1);//mdelay(1); + + mddi_do_cmd(CMD_RTD_MEASURE); + thread_sleep(1);//mdelay(1); + + mddi_do_cmd(CMD_RTD_MEASURE); + thread_sleep(1);//mdelay(1); + + mddi_do_cmd(CMD_GET_CLIENT_CAP); + + do { + n = readl(MDDI_INT); + } while (!(n & MDDI_INT_REV_DATA_AVAIL) && (--timeout)); + + if (timeout == 0) + dprintf(INFO, "timeout\n"); + + memcpy(caps, rev_pkt_buf, sizeof(struct mddi_client_caps)); +} + +static unsigned mddi_init_regs(void) +{ + mddi_do_cmd(CMD_RESET); + + mddi_do_cmd(CMD_PERIODIC_REV_ENC); + + writel(0x0001, MDDI_VERSION); + writel(0x3C00, MDDI_BPS); + writel(0x0003, MDDI_SPM); + + writel(0x0005, MDDI_TA1_LEN); + writel(0x001A, MDDI_TA2_LEN); + writel(0x0096, MDDI_DRIVE_HI); + writel(0x0050, MDDI_DRIVE_LO); + writel(0x003C, MDDI_DISP_WAKE); + writel(0x0004, MDDI_REV_RATE_DIV); + + /* needs to settle for 5uS */ + if (readl(MDDI_PAD_CTL) == 0) { + writel(0x08000, MDDI_PAD_CTL); + udelay(5); + } + + writel(0xA850F, MDDI_PAD_CTL); + writel(0x60006, MDDI_DRIVER_START_CNT); + + mddi_init_rev_encap(); + + /* disable hibernate */ + mddi_do_cmd(CMD_HIBERNATE | 0); + + return readl(MDDI_CORE_VER) & 0xffff; +} + +struct fbcon_config *mddi_init(void) +{ + unsigned n; + struct mddi_client_caps client_caps; + + dprintf(INFO, "mddi_init()\n"); + + rev_pkt_buf = memalign(32, MDDI_REV_PKT_BUF_SIZE); + mlist_remote_write = memalign(32, sizeof(struct mddi_llentry)); + + n = mddi_init_regs(); + dprintf(INFO, "mddi version: 0x%08x\n", n); + + //mddi_get_caps(&client_caps); + //if(!(client_caps.length == 0x4a && client_caps.type == 0x42)) + { + mddi_set_caps(&client_caps); + } + + fb_cfg.width = client_caps.bitmap_width; + fb_cfg.stride = fb_cfg.width; + fb_cfg.height = client_caps.bitmap_height; + + panel_init(&client_caps); + + panel_backlight(0); + panel_poweron(); + + /* v > 8? v > 8 && < 0x19 ? */ + writel(2, MDDI_TEST); + + dprintf(INFO, "panel is %d x %d\n", fb_cfg.width, fb_cfg.height); + + fb_cfg.base = + memalign(4096, fb_cfg.width * fb_cfg.height * (fb_cfg.bpp / 8)); + + mlist = memalign(32, sizeof(mddi_llentry) * (fb_cfg.height / 8)); + dprintf(INFO, "FB @ %p mlist @ %x\n", fb_cfg.base, (unsigned) mlist); + + for(n = 0; n < (fb_cfg.height / 8); n++) { + unsigned y = n * 8; + unsigned pixels = fb_cfg.width * 8; + mddi_video_stream *vs = &(mlist[n].u.v); + + vs->length = sizeof(mddi_video_stream) - 2 + (pixels * 2); + vs->type = TYPE_VIDEO_STREAM; + vs->client_id = 0; + vs->format = 0x5565; // FORMAT_16BPP; + vs->pixattr = PIXATTR_BOTH_EYES | PIXATTR_TO_ALL; + + vs->left = 0; + vs->right = fb_cfg.width - 1; + vs->top = y; + vs->bottom = y + 7; + + vs->start_x = 0; + vs->start_y = y; + + vs->pixels = pixels; + vs->crc = 0; + vs->reserved = 0; + + mlist[n].header_count = sizeof(mddi_video_stream) - 2; + mlist[n].data_count = pixels * 2; + mlist[n].reserved = 0; + mlist[n].data = fb_cfg.base + (y * fb_cfg.width * 2); + mlist[n].next = &mlist[n + 1]; + mlist[n].flags = 0; + } + + mlist[n-1].flags = 1; + mlist[n-1].next = 0; + + mddi_set_auto_hibernate(1); + mddi_do_cmd(CMD_LINK_ACTIVE); + + panel_backlight(1); + + return &fb_cfg; +} diff --git a/lk/platform/msm_shared/mddi_hw.h b/lk/platform/msm_shared/mddi_hw.h new file mode 100644 index 0000000..016ee54 --- /dev/null +++ b/lk/platform/msm_shared/mddi_hw.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2008, Google 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. + * + * 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 __PLATFORM_MSM7K_MDDI_HW_H +#define __PLATFORM_MSM7K_MDDI_HW_H + +#ifdef TARGET_MSM7630_SURF +#define MSM_MDDI_BASE 0xAD600000 +#else +#define MSM_MDDI_BASE 0xAA600000 +#endif + +#if MDP4 +#define MSM_MDP_BASE1 0xA3F00000 +#define LCDC_BASE 0xC0000 +#else +#define MSM_MDP_BASE1 0xAA200000 +#define LCDC_BASE 0xE0000 +#endif + +enum { /* display configuration for MDP4 */ + PRIMARY_INTF_SEL, + SECONDARY_INTF_SEL, + EXTERNAL_INTF_SEL +}; + +#define outp32(port, val) (*((volatile unsigned *) (port)) = ((unsigned) (val))) + +/* see 80-VA736-2 C pp 776-787 */ + +#define MDDI_REG(off) (MSM_MDDI_BASE + (off)) + +#define MDDI_CMD MDDI_REG(0x0000) +#define MDDI_VERSION MDDI_REG(0x0004) +#define MDDI_PRI_PTR MDDI_REG(0x0008) +#define MDDI_SEC_PTR MDDI_REG(0x000C) +#define MDDI_BPS MDDI_REG(0x0010) +#define MDDI_SPM MDDI_REG(0x0014) +#define MDDI_INT MDDI_REG(0x0018) + +#define MDDI_INT_PRI_PTR_READ (1 << 0) +#define MDDI_INT_SEC_PTR_READ (1 << 1) +#define MDDI_INT_REV_DATA_AVAIL (1 << 2) +#define MDDI_INT_DISP_REQ (1 << 3) +#define MDDI_INT_PRI_UNDERFLOW (1 << 4) +#define MDDI_INT_SEC_UNDERFLOW (1 << 5) +#define MDDI_INT_REV_OVERFLOW (1 << 6) +#define MDDI_INT_CRC_ERROR (1 << 7) +#define MDDI_INT_MDDI_IN (1 << 8) +#define MDDI_INT_PRI_OVERWRITE (1 << 9) +#define MDDI_INT_SEC_OVERWRITE (1 << 10) +#define MDDI_INT_REV_OVERWRITE (1 << 11) +#define MDDI_INT_DMA_FAILURE (1 << 12) +#define MDDI_INT_LINK_ACTIVE (1 << 13) +#define MDDI_INT_IN_HIBERNATION (1 << 14) +#define MDDI_INT_PRI_LINK_LIST_DONE (1 << 15) +#define MDDI_INT_SEC_LINK_LIST_DONE (1 << 16) +#define MDDI_INT_NO_REQ_PKTS_PENDING (1 << 17) +#define MDDI_INT_RTD_FAILURE (1 << 18) +#define MDDI_INT_REV_PKT_RECEIVED (1 << 19) +#define MDDI_INT_REV_PKTS_AVAIL (1 << 20) + +#define MDDI_INTEN MDDI_REG(0x001C) +#define MDDI_REV_PTR MDDI_REG(0x0020) +#define MDDI_REV_SIZE MDDI_REG(0x0024) +#define MDDI_STAT MDDI_REG(0x0028) + +#define MDDI_STAT_LINK_ACTIVE (1 << 0) +#define MDDI_STAT_NEW_REV_PTR (1 << 1) +#define MDDI_STAT_NEW_PRI_PTR (1 << 2) +#define MDDI_STAT_NEW_SEC_PTR (1 << 3) +#define MDDI_STAT_IN_HIBERNATION (1 << 4) +#define MDDI_STAT_PRI_LINK_LIST_DONE (1 << 5) +#define MDDI_STAT_SEC_LINK_LIST_DONE (1 << 6) +#define MDDI_STAT_SEND_TIMING_PKT (1 << 7) +#define MDDI_STAT_SEND_REV_ENCAP_WITH_FLAGS (1 << 8) +#define MDDI_STAT_SEND_POWER_DOWN (1 << 9) +#define MDDI_STAT_DO_HANDSHAKE (1 << 10) +#define MDDI_STAT_RTD_MEAS_FAIL (1 << 11) +#define MDDI_STAT_CLIENT_WAKEUP_REQ (1 << 12) +#define MDDI_STAT_DMA_ABORT (1 << 13) +#define MDDI_STAT_REV_OVERFLOW_RESET (1 << 14) +#define MDDI_STAT_FORCE_NEW_REV_PTR (1 << 15) +#define MDDI_STAT_CRC_ERRORS (1 << 16) + +#define MDDI_REV_RATE_DIV MDDI_REG(0x002C) +#define MDDI_REV_CRC_ERR MDDI_REG(0x0030) +#define MDDI_TA1_LEN MDDI_REG(0x0034) +#define MDDI_TA2_LEN MDDI_REG(0x0038) +#define MDDI_TEST_BUS MDDI_REG(0x003C) +#define MDDI_TEST MDDI_REG(0x0040) +#define MDDI_REV_PKT_CNT MDDI_REG(0x0044) +#define MDDI_DRIVE_HI MDDI_REG(0x0048) +#define MDDI_DRIVE_LO MDDI_REG(0x004C) +#define MDDI_DISP_WAKE MDDI_REG(0x0050) +#define MDDI_REV_ENCAP_SZ MDDI_REG(0x0054) +#define MDDI_RTD_VAL MDDI_REG(0x0058) +#define MDDI_MDP_VID_FMT_DES MDDI_REG(0x005C) +#define MDDI_MDP_VID_PIX_ATTR MDDI_REG(0x0060) +#define MDDI_MDP_VID_CLIENTID MDDI_REG(0x0064) +#define MDDI_PAD_CTL MDDI_REG(0x0068) +#define MDDI_DRIVER_START_CNT MDDI_REG(0x006C) +#define MDDI_NEXT_PRI_PTR MDDI_REG(0x0070) +#define MDDI_NEXT_SEC_PTR MDDI_REG(0x0074) +#define MDDI_MISR_CTL MDDI_REG(0x0078) +#define MDDI_MISR_DATA MDDI_REG(0x007C) +#define MDDI_SF_CNT MDDI_REG(0x0080) +#define MDDI_MF_CNT MDDI_REG(0x0084) +#define MDDI_CURR_REV_PTR MDDI_REG(0x0088) +#define MDDI_CORE_VER MDDI_REG(0x008C) +#define MDDI_PAD_IO_CTL MDDI_REG(0x00a0) +#define MDDI_PAD_CAL MDDI_REG(0x00a4) + + +#define CMD_POWER_DOWN 0x0100 +#define CMD_POWER_UP 0x0200 +#define CMD_HIBERNATE 0x0300 +#define CMD_RESET 0x0400 +#define CMD_IGNORE 0x0501 +#define CMD_LISTEN 0x0500 +#define CMD_REV_ENC_REQ 0x0600 +#define CMD_RTD_MEASURE 0x0700 +#define CMD_LINK_ACTIVE 0x0900 +#define CMD_PERIODIC_REV_ENC 0x0A00 +#define CMD_FORCE_NEW_REV_PTR 0x0C00 + +#define CMD_GET_CLIENT_CAP 0x0601 +#define CMD_GET_CLIENT_STATUS 0x0602 + +#if 1 +#define FORMAT_18BPP 0x5666 +#define FORMAT_24BPP 0x5888 +#define FORMAT_16BPP 0x5565 +#else +#define FORMAT_MONOCHROME (0 << 13) +#define FORMAT_PALETTE (1 << 13) +#define FORMAT_RGB (2 << 13) +#define FORMAT_YCBCR422 (3 << 13) +#define FORMAT_BAYER (4 << 13) +#endif + +#define PIXATTR_BOTH_EYES 3 +#define PIXATTR_LEFT_EYE 2 +#define PIXATTR_RIGHT_EYE 1 +#define PIXATTR_ALT_DISPLAY 0 + +#define PIXATTR_PROGRESSIVE 0 +#define PIXATTR_INTERLACED (1 << 2) +#define PIXATTR_ALTERNATE (1 << 3) + +#define PIXATTR_IGNORE_LRTB (1 << 5) + +#define PIXATTR_TO_REFRESH (0 << 6) +#define PIXATTR_TO_OFFLINE (1 << 6) +#define PIXATTR_TO_ALL (3 << 6) + +#define PIXATTR_LAST_ROW (1 << 15) + +#define TYPE_VIDEO_STREAM 16 +#define TYPE_CLIENT_CAPS 66 +#define TYPE_REGISTER_ACCESS 146 +#define TYPE_CLIENT_STATUS 70 + +typedef struct mddi_video_stream mddi_video_stream; +typedef struct mddi_register_access mddi_register_access; +typedef struct mddi_client_caps mddi_client_caps; + +typedef struct mddi_llentry mddi_llentry; + +struct __attribute__((packed)) mddi_video_stream +{ + unsigned short length; /* length in bytes excluding this field */ + unsigned short type; /* MDDI_TYPE_VIDEO_STREAM */ + unsigned short client_id; /* set to zero */ + + unsigned short format; + unsigned short pixattr; + + unsigned short left; + unsigned short top; + unsigned short right; + unsigned short bottom; + + unsigned short start_x; + unsigned short start_y; + + unsigned short pixels; + + unsigned short crc; + unsigned short reserved; +}; + +struct __attribute__((packed)) mddi_register_access +{ + unsigned short length; + unsigned short type; + unsigned short client_id; + + unsigned short rw_info; /* flag below | count of reg_data */ +#define MDDI_WRITE (0 << 14) +#define MDDI_READ (2 << 14) +#define MDDI_READ_RESP (3 << 14) + + unsigned reg_addr; + unsigned short crc; /* 16 bit crc of the above */ + + unsigned reg_data; /* "list" of 3byte data values */ +}; + +struct __attribute__((packed)) mddi_llentry { + unsigned short flags; + unsigned short header_count; + unsigned short data_count; + void *data; + mddi_llentry *next; + unsigned short reserved; + union { + mddi_video_stream v; + mddi_register_access r; + unsigned _[12]; + } u; +}; + +#endif /* __PLATFORM_MSM7K_MDDI_HW_H */ diff --git a/lk/platform/msm_shared/mipi_dsi.c b/lk/platform/msm_shared/mipi_dsi.c new file mode 100644 index 0000000..4d2a515 --- /dev/null +++ b/lk/platform/msm_shared/mipi_dsi.c @@ -0,0 +1,652 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +#define MIPI_FB_ADDR 0x43E00000 + +#if DISPLAY_MIPI_PANEL_TOSHIBA +static struct fbcon_config mipi_fb_cfg = { + .height = TSH_MIPI_FB_HEIGHT, + .width = TSH_MIPI_FB_WIDTH, + .stride = TSH_MIPI_FB_WIDTH, + .format = FB_FORMAT_RGB888, + .bpp = 24, + .update_start = NULL, + .update_done = NULL, +}; +#elif DISPLAY_MIPI_PANEL_NOVATEK_BLUE +static struct fbcon_config mipi_fb_cfg = { + .height = NOV_MIPI_FB_HEIGHT, + .width = NOV_MIPI_FB_WIDTH, + .stride = NOV_MIPI_FB_WIDTH, + .format = FB_FORMAT_RGB888, + .bpp = 24, + .update_start = NULL, + .update_done = NULL, +}; +#else +static struct fbcon_config mipi_fb_cfg = { + .height = 0, + .width = 0, + .stride = 0, + .format = 0, + .bpp = 0, + .update_start = NULL, + .update_done = NULL, +}; +#endif + +static int cmd_mode_status = 0; + +void configure_dsicore_dsiclk() +{ + unsigned char mnd_mode, root_en, clk_en; + unsigned long src_sel = 0x3; // dsi_phy_pll0_src + unsigned long pre_div_func = 0x00; // predivide by 1 + unsigned long pmxo_sel; + + writel(pre_div_func << 14 | src_sel, MMSS_DSI_NS); + mnd_mode = 0; // Bypass MND + root_en = 1; + clk_en = 1; + pmxo_sel = 0; + + writel((pmxo_sel << 8) | (mnd_mode << 6), MMSS_DSI_CC); + writel(readl(MMSS_DSI_CC) | root_en << 2, MMSS_DSI_CC); + writel(readl(MMSS_DSI_CC) | clk_en, MMSS_DSI_CC); +} + +void configure_dsicore_byteclk(void) +{ + writel(0x00400401, MMSS_MISC_CC2); // select pxo +} + +void configure_dsicore_pclk(void) +{ + unsigned char mnd_mode, root_en, clk_en; + unsigned long src_sel = 0x3; // dsi_phy_pll0_src + unsigned long pre_div_func = 0x01; // predivide by 2 + + writel(pre_div_func << 12 | src_sel, MMSS_DSI_PIXEL_NS); + + mnd_mode = 0; // Bypass MND + root_en = 1; + clk_en = 1; + writel(mnd_mode << 6, MMSS_DSI_PIXEL_CC); + writel(readl(MMSS_DSI_PIXEL_CC) | root_en << 2, MMSS_DSI_PIXEL_CC); + writel(readl(MMSS_DSI_PIXEL_CC) | clk_en, MMSS_DSI_PIXEL_CC); +} + +int mipi_dsi_phy_ctrl_config(struct mipi_dsi_panel_config *pinfo) +{ + + unsigned char lane_1 = 1; + unsigned char lane_2 = 2; + unsigned i; + unsigned off = 0; + struct mipi_dsi_phy_ctrl *pd; + + writel(0x00000001, DSI_PHY_SW_RESET); + mdelay(50); + writel(0x00000000, DSI_PHY_SW_RESET); + + pd = (pinfo->dsi_phy_config); + + off = 0x02cc; /* regulator ctrl 0 */ + for (i = 0; i < 4; i++) { + writel(pd->regulator[i], MIPI_DSI_BASE + off); + off += 4; + } + + off = 0x0260; /* phy timig ctrl 0 */ + for (i = 0; i < 11; i++) { + writel(pd->timing[i], MIPI_DSI_BASE + off); + off += 4; + } + + // T_CLK_POST, T_CLK_PRE for CLK lane P/N HS 200 mV timing length should > + // data lane HS timing length + writel(0xa1e, DSI_CLKOUT_TIMING_CTRL); + + off = 0x0290; /* ctrl 0 */ + for (i = 0; i < 4; i++) { + writel(pd->ctrl[i], MIPI_DSI_BASE + off); + off += 4; + } + + off = 0x02a0; /* strength 0 */ + for (i = 0; i < 4; i++) { + writel(pd->strength[i], MIPI_DSI_BASE + off); + off += 4; + } + + off = 0x0204; /* pll ctrl 1, skip 0 */ + for (i = 1; i < 21; i++) { + writel(pd->pll[i], MIPI_DSI_BASE + off); + off += 4; + } + + /* pll ctrl 0 */ + writel(pd->pll[0], MIPI_DSI_BASE + 0x200); + writel((pd->pll[0] | 0x01), MIPI_DSI_BASE + 0x200); + + return (0); +} + +struct mipi_dsi_panel_config *get_panel_info(void) +{ +#if DISPLAY_MIPI_PANEL_TOSHIBA + return &toshiba_panel_info; +#elif DISPLAY_MIPI_PANEL_NOVATEK_BLUE + return &novatek_panel_info; +#endif + return NULL; + +} + +int dsi_cmd_dma_trigger_for_panel() +{ + unsigned long ReadValue; + unsigned long count = 0; + int status = 0; + + writel(0x03030303, DSI_INT_CTRL); + mdelay(10); + writel(0x1, DSI_CMD_MODE_DMA_SW_TRIGGER); + ReadValue = readl(DSI_INT_CTRL) & 0x00000001; + while (ReadValue != 0x00000001) { + ReadValue = readl(DSI_INT_CTRL) & 0x00000001; + count++; + if (count > 0xffff) { + status = FAIL; + printf("\n\nThis command mode dma test is failed"); + return status; + } + } + + writel((readl(DSI_INT_CTRL) | 0x01000001), DSI_INT_CTRL); + printf + ("\n\nThis command mode is tested successfully, continue on next command mode test"); + return status; +} + +int mipi_dsi_cmds_tx(struct mipi_dsi_cmd *cmds, int count) +{ + int ret = 0; + struct mipi_dsi_cmd *cm; + int i = 0; + + cm = cmds; + for (i = 0; i < count; i++) { + memcpy(DSI_CMD_DMA_MEM_START_ADDR_PANEL, (cm->payload), cm->size); + writel(DSI_CMD_DMA_MEM_START_ADDR_PANEL, DSI_DMA_CMD_OFFSET); + writel(cm->size, DSI_DMA_CMD_LENGTH); // reg 0x48 for this build + ret += dsi_cmd_dma_trigger_for_panel(); + mdelay(10); + cm++; + } + return ret; +} + +int mipi_dsi_panel_initialize(struct mipi_dsi_panel_config *pinfo) +{ + unsigned char DMA_STREAM1 = 0; // for mdp display processor path + unsigned char EMBED_MODE1 = 1; // from frame buffer + unsigned char POWER_MODE2 = 1; // from frame buffer + unsigned char PACK_TYPE1 = 1; // long packet + unsigned char VC1 = 0; + unsigned char DT1 = 0; // non embedded mode + unsigned short WC1 = 0; // for non embedded mode only + int status = 0; + unsigned char DLNx_EN; + unsigned char lane_1 = 1; + unsigned char lane_2 = 2; + + switch (pinfo->num_of_lanes) { + default: + case 1: + DLNx_EN = 1; // 1 lane + break; + case 2: + DLNx_EN = 3; // 2 lane + break; + case 3: + DLNx_EN = 7; // 3 lane + break; + } + + writel(0x0001, DSI_SOFT_RESET); + writel(0x0000, DSI_SOFT_RESET); + + writel((0 << 16) | 0x3f, DSI_CLK_CTRL); // reg:0x118 + writel(DMA_STREAM1 << 8 | 0x04, DSI_TRIG_CTRL); // reg 0x80 dma trigger: sw + // trigger 0x4; dma stream1 + writel(0 << 30 | DLNx_EN << 4 | 0x105, DSI_CTRL); // reg 0x00 for this + // build + writel(EMBED_MODE1 << 28 | POWER_MODE2 << 26 + | PACK_TYPE1 << 24 | VC1 << 22 | DT1 << 16 | WC1, + DSI_COMMAND_MODE_DMA_CTRL); + + status = mipi_dsi_cmds_tx(pinfo->panel_cmds, pinfo->num_of_panel_cmds); + + return status; +} + +int config_dsi_video_mode(unsigned short disp_width, unsigned short disp_height, + unsigned short img_width, unsigned short img_height, + unsigned short hsync_porch0_fp, + unsigned short hsync_porch0_bp, + unsigned short vsync_porch0_fp, + unsigned short vsync_porch0_bp, + unsigned short hsync_width, + unsigned short vsync_width, unsigned short dst_format, + unsigned short traffic_mode, + unsigned short datalane_num) +{ + + unsigned char DST_FORMAT; + unsigned char TRAFIC_MODE; + unsigned char DLNx_EN; + // video mode data ctrl + int status = 0; + unsigned long low_pwr_stop_mode = 0; + unsigned char eof_bllp_pwr = 0x9; + unsigned char interleav = 0; + + // disable mdp first + writel(0x00000000, MDP_DSI_VIDEO_EN); + + writel(0x00000000, DSI_CLK_CTRL); + writel(0x00000000, DSI_CLK_CTRL); + writel(0x00000000, DSI_CLK_CTRL); + writel(0x00000000, DSI_CLK_CTRL); + writel(0x00000002, DSI_CLK_CTRL); + writel(0x00000006, DSI_CLK_CTRL); + writel(0x0000000e, DSI_CLK_CTRL); + writel(0x0000001e, DSI_CLK_CTRL); + writel(0x0000003e, DSI_CLK_CTRL); + + writel(0, DSI_CTRL); + + writel(0, DSI_ERR_INT_MASK0); + + DST_FORMAT = 0; // RGB565 + printf("\nDSI_Video_Mode - Dst Format: RGB565"); + + DLNx_EN = 1; // 1 lane with clk programming + printf("\nData Lane: 1 lane\n"); + + TRAFIC_MODE = 0; // non burst mode with sync pulses + printf("\nTraffic mode: non burst mode with sync pulses\n"); + + writel(0x02020202, DSI_INT_CTRL); + + writel(((img_width + hsync_porch0_bp) << 16) | hsync_porch0_bp, + DSI_VIDEO_MODE_ACTIVE_H); + + writel(((img_height + vsync_porch0_bp) << 16) | (vsync_porch0_bp), + DSI_VIDEO_MODE_ACTIVE_V); + + writel(((img_height + vsync_porch0_fp + vsync_porch0_bp) << 16) + | img_width + hsync_porch0_fp + hsync_porch0_bp, + DSI_VIDEO_MODE_TOTAL); + + writel((hsync_width << 16) | 0, DSI_VIDEO_MODE_HSYNC); + + writel(0 << 16 | 0, DSI_VIDEO_MODE_VSYNC); + + writel(vsync_width << 16 | 0, DSI_VIDEO_MODE_VSYNC_VPOS); + + writel(1, DSI_EOT_PACKET_CTRL); + + writel(0x00000100, DSI_MISR_VIDEO_CTRL); + + writel(low_pwr_stop_mode << 16 | eof_bllp_pwr << 12 | TRAFIC_MODE << 8 + | DST_FORMAT << 4 | 0x0, DSI_VIDEO_MODE_CTRL); + + writel(0x67, DSI_CAL_STRENGTH_CTRL); + + writel(0x80006711, DSI_CAL_CTRL); + + writel(0x00010100, DSI_MISR_VIDEO_CTRL); + + writel(0x00010100, DSI_INT_CTRL); + writel(0x02010202, DSI_INT_CTRL); + + writel(0x02030303, DSI_INT_CTRL); + + writel(interleav << 30 | 0 << 24 | 0 << 20 | DLNx_EN << 4 + | 0x103, DSI_CTRL); + mdelay(10); + + return status; +} + +int config_dsi_cmd_mode(unsigned short disp_width, unsigned short disp_height, + unsigned short img_width, unsigned short img_height, + unsigned short dst_format, + unsigned short traffic_mode, + unsigned short datalane_num) +{ + unsigned char DST_FORMAT; + unsigned char TRAFIC_MODE; + unsigned char DLNx_EN; + // video mode data ctrl + int status = 0; + unsigned long low_pwr_stop_mode = 0; + unsigned char eof_bllp_pwr = 0x9; + unsigned char interleav = 0; + unsigned char ystride = 0x03; + // disable mdp first + + writel(0x00000000, DSI_CLK_CTRL); + writel(0x00000000, DSI_CLK_CTRL); + writel(0x00000000, DSI_CLK_CTRL); + writel(0x00000000, DSI_CLK_CTRL); + writel(0x00000002, DSI_CLK_CTRL); + writel(0x00000006, DSI_CLK_CTRL); + writel(0x0000000e, DSI_CLK_CTRL); + writel(0x0000001e, DSI_CLK_CTRL); + writel(0x0000003e, DSI_CLK_CTRL); + + writel(0x10000000, DSI_ERR_INT_MASK0); + + // writel(0, DSI_CTRL); + + // writel(0, DSI_ERR_INT_MASK0); + + DST_FORMAT = 8; // RGB888 + printf("\nDSI_Cmd_Mode - Dst Format: RGB888"); + + DLNx_EN = 3; // 2 lane with clk programming + printf("\nData Lane: 2 lane\n"); + + TRAFIC_MODE = 0; // non burst mode with sync pulses + printf("\nTraffic mode: non burst mode with sync pulses\n"); + + writel(0x02020202, DSI_INT_CTRL); + + writel(0x00100000 | DST_FORMAT, DSI_COMMAND_MODE_MDP_CTRL); + writel((img_width * ystride + 1) << 16 | 0x0039, + DSI_COMMAND_MODE_MDP_STREAM0_CTRL); + writel((img_width * ystride + 1) << 16 | 0x0039, + DSI_COMMAND_MODE_MDP_STREAM1_CTRL); + writel(img_height << 16 | img_width, DSI_COMMAND_MODE_MDP_STREAM0_TOTAL); + writel(img_height << 16 | img_width, DSI_COMMAND_MODE_MDP_STREAM1_TOTAL); + writel(0xEE, DSI_CAL_STRENGTH_CTRL); + writel(0x80000000, DSI_CAL_CTRL); + writel(0x40, DSI_TRIG_CTRL); + writel(0x13c2c, DSI_COMMAND_MODE_MDP_DCS_CMD_CTRL); + writel(interleav << 30 | 0 << 24 | 0 << 20 | DLNx_EN << 4 | 0x105, + DSI_CTRL); + mdelay(10); + writel(0x10000000, DSI_COMMAND_MODE_DMA_CTRL); + writel(0x10000000, DSI_MISR_CMD_CTRL); + writel(0x00000040, DSI_ERR_INT_MASK0); + writel(0x1, DSI_EOT_PACKET_CTRL); + // writel(0x0, MDP_OVERLAYPROC0_START); + writel(0x00000001, MDP_DMA_P_START); + mdelay(10); + writel(0x1, DSI_CMD_MODE_MDP_SW_TRIGGER); + + status = 1; + return status; +} + +int mdp_setup_dma_p_video_mode(unsigned short disp_width, + unsigned short disp_height, + unsigned short img_width, + unsigned short img_height, + unsigned short hsync_porch0_fp, + unsigned short hsync_porch0_bp, + unsigned short vsync_porch0_fp, + unsigned short vsync_porch0_bp, + unsigned short hsync_width, + unsigned short vsync_width, + unsigned long input_img_addr, + unsigned short img_width_full_size, + unsigned short pack_pattern, + unsigned char ystride) +{ + + // unsigned long mdp_intr_status; + int status = FAIL; + unsigned long hsync_period; + unsigned long vsync_period; + unsigned long vsync_period_intmd; + + printf("\nHi setup MDP4.1 for DSI Video Mode\n"); + + hsync_period = img_width + hsync_porch0_fp + hsync_porch0_bp + 1; + vsync_period_intmd = img_height + vsync_porch0_fp + vsync_porch0_bp + 1; + vsync_period = vsync_period_intmd * hsync_period; + + // ----- programming MDP_AXI_RDMASTER_CONFIG -------- + /* MDP_AXI_RDMASTER_CONFIG set all master to read from AXI port 0, that's + the only port connected */ + writel(0x00290000, MDP_AXI_RDMASTER_CONFIG); + writel(0x00000004, MDP_AXI_WRMASTER_CONFIG); + writel(0x00007777, MDP_MAX_RD_PENDING_CMD_CONFIG); + writel(0x00000049, MDP_DISP_INTF_SEL); + writel(0x0000000b, MDP_OVERLAYPROC0_CFG); + + // ------------- programming MDP_DMA_P_CONFIG --------------------- + writel(pack_pattern << 8 | 0xbf | (0 << 25), MDP_DMA_P_CONFIG); // rgb888 + + writel(0x00000000, MDP_DMA_P_OUT_XY); + writel(img_height << 16 | img_width, MDP_DMA_P_SIZE); + writel(input_img_addr, MDP_DMA_P_BUF_ADDR); + writel(img_width_full_size * ystride, MDP_DMA_P_BUF_Y_STRIDE); + writel(0x00ff0000, MDP_DMA_P_OP_MODE); + writel(hsync_period << 16 | hsync_width, MDP_DSI_VIDEO_HSYNC_CTL); + writel(vsync_period, MDP_DSI_VIDEO_VSYNC_PERIOD); + writel(vsync_width * hsync_period, MDP_DSI_VIDEO_VSYNC_PULSE_WIDTH); + writel((img_width + hsync_porch0_bp - 1) << 16 | hsync_porch0_bp, + MDP_DSI_VIDEO_DISPLAY_HCTL); + writel(vsync_porch0_bp * hsync_period, MDP_DSI_VIDEO_DISPLAY_V_START); + writel((img_height + vsync_porch0_bp) * hsync_period, + MDP_DSI_VIDEO_DISPLAY_V_END); + writel(0x00ABCDEF, MDP_DSI_VIDEO_BORDER_CLR); + writel(0x00000000, MDP_DSI_VIDEO_HSYNC_SKEW); + writel(0x00000000, MDP_DSI_VIDEO_CTL_POLARITY); + // end of cmd mdp + + writel(0x00000001, MDP_DSI_VIDEO_EN); // MDP_DSI_EN ENABLE + + status = PASS; + return status; +} + +int mipi_dsi_video_config(unsigned short num_of_lanes) +{ + + int status = 0; + unsigned long ReadValue; + unsigned long count = 0; + unsigned long low_pwr_stop_mode = 0; // low power mode 0x1111 start from + // bit16, high spd mode 0x0 + unsigned char eof_bllp_pwr = 0x9; // bit 12, 15, 1:low power stop mode or + // let cmd mode eng send packets in hs + // or lp mode + unsigned short display_wd = mipi_fb_cfg.width; + unsigned short display_ht = mipi_fb_cfg.height; + unsigned short image_wd = mipi_fb_cfg.width; + unsigned short image_ht = mipi_fb_cfg.height; + unsigned short hsync_porch_fp = MIPI_HSYNC_FRONT_PORCH_DCLK; + unsigned short hsync_porch_bp = MIPI_HSYNC_BACK_PORCH_DCLK; + unsigned short vsync_porch_fp = MIPI_VSYNC_FRONT_PORCH_LINES; + unsigned short vsync_porch_bp = MIPI_VSYNC_BACK_PORCH_LINES; + unsigned short hsync_width = MIPI_HSYNC_PULSE_WIDTH; + unsigned short vsync_width = MIPI_VSYNC_PULSE_WIDTH; + unsigned short dst_format = 0; + unsigned short traffic_mode = 0; + unsigned short pack_pattern = 0x12; + unsigned char ystride = 3; + + low_pwr_stop_mode = 0x1111; // low pwr mode bit16:HSA, bit20:HBA, + // bit24:HFP, bit28:PULSE MODE, need enough + // time for swithc from LP to HS + eof_bllp_pwr = 0x9; // low power stop mode or let cmd mode eng send + // packets in hs or lp mode + + status += config_dsi_video_mode(display_wd, display_ht, image_wd, image_ht, + hsync_porch_fp, hsync_porch_bp, + vsync_porch_fp, vsync_porch_bp, hsync_width, + vsync_width, dst_format, traffic_mode, + num_of_lanes); + + status += + mdp_setup_dma_p_video_mode(display_wd, display_ht, image_wd, image_ht, + hsync_porch_fp, hsync_porch_bp, + vsync_porch_fp, vsync_porch_bp, hsync_width, + vsync_width, MIPI_FB_ADDR, image_wd, + pack_pattern, ystride); + + ReadValue = readl(DSI_INT_CTRL) & 0x00010000; + while (ReadValue != 0x00010000) { + ReadValue = readl(DSI_INT_CTRL) & 0x00010000; + count++; + if (count > 0xffff) { + status = FAIL; + printf("\nToshiba Video 565 pulse 1 lane test is failed\n"); + return status; + } + } + + printf("\nToshiba Video 565 pulse 1 lane is tested successfully \n"); + return status; +} + +int mipi_dsi_cmd_config(unsigned short num_of_lanes) +{ + + int status = 0; + unsigned long ReadValue; + unsigned long count = 0; + unsigned long input_img_addr = MIPI_FB_ADDR; + unsigned long low_pwr_stop_mode = 0; // low power mode 0x1111 start from + // bit16, high spd mode 0x0 + unsigned char eof_bllp_pwr = 0x9; // bit 12, 15, 1:low power stop mode or + // let cmd mode eng send packets in hs + // or lp mode + unsigned short display_wd = mipi_fb_cfg.width; + unsigned short display_ht = mipi_fb_cfg.height; + unsigned short image_wd = mipi_fb_cfg.width; + unsigned short image_ht = mipi_fb_cfg.height; + unsigned short hsync_porch_fp = MIPI_HSYNC_FRONT_PORCH_DCLK; + unsigned short hsync_porch_bp = MIPI_HSYNC_BACK_PORCH_DCLK; + unsigned short vsync_porch_fp = MIPI_VSYNC_FRONT_PORCH_LINES; + unsigned short vsync_porch_bp = MIPI_VSYNC_BACK_PORCH_LINES; + unsigned short hsync_width = MIPI_HSYNC_PULSE_WIDTH; + unsigned short vsync_width = MIPI_VSYNC_PULSE_WIDTH; + unsigned short dst_format = 0; + unsigned short traffic_mode = 0; + unsigned short pack_pattern = 0x12; + unsigned char ystride = 3; + + writel(0x03ffffff, MDP_INTR_ENABLE); + writel(0x0000000b, MDP_OVERLAYPROC0_CFG); + + // ------------- programming MDP_DMA_P_CONFIG --------------------- + writel(pack_pattern << 8 | 0x3f | (0 << 25), MDP_DMA_P_CONFIG); // rgb888 + + writel(0x00000000, MDP_DMA_P_OUT_XY); + writel(image_ht << 16 | image_wd, MDP_DMA_P_SIZE); + writel(input_img_addr, MDP_DMA_P_BUF_ADDR); + + writel(image_wd * ystride, MDP_DMA_P_BUF_Y_STRIDE); + + writel(0x00000000, MDP_DMA_P_OP_MODE); + + writel(0x10, MDP_DSI_CMD_MODE_ID_MAP); + writel(0x01, MDP_DSI_CMD_MODE_TRIGGER_EN); + + writel(0x0001a000, MDP_AXI_RDMASTER_CONFIG); + writel(0x00000004, MDP_AXI_WRMASTER_CONFIG); + writel(0x00007777, MDP_MAX_RD_PENDING_CMD_CONFIG); + writel(0x8a, MDP_DISP_INTF_SEL); + + return status; +} + +int is_cmd_mode_enabled(void) +{ + return cmd_mode_status; +} + +void mipi_dsi_cmd_mode_trigger(void) +{ + int status = 0; + unsigned short display_wd = mipi_fb_cfg.width; + unsigned short display_ht = mipi_fb_cfg.height; + unsigned short image_wd = mipi_fb_cfg.width; + unsigned short image_ht = mipi_fb_cfg.height; + unsigned short dst_format = 0; + unsigned short traffic_mode = 0; + struct mipi_dsi_panel_config *panel_info = &novatek_panel_info; + status += mipi_dsi_cmd_config(panel_info->num_of_lanes); + mdelay(50); + config_dsi_cmd_mode(display_wd, display_ht, image_wd, image_ht, + dst_format, traffic_mode, + panel_info->num_of_lanes /* num_of_lanes */ ); +} + +void mipi_dsi_shutdown(void) +{ + writel(0, DSI_CTRL); + writel(0x00000001, DSI_PHY_SW_RESET); + writel(0x0, DSI_INT_CTRL); + writel(0x00000000, MDP_DSI_VIDEO_EN); +} + +struct fbcon_config *mipi_init(void) +{ + int status = 0; + unsigned char num_of_lanes = 1; + struct mipi_dsi_panel_config *panel_info = get_panel_info(); + writel(0x00001800, MMSS_SFPB_GPREG); + configure_dsicore_dsiclk(); + configure_dsicore_byteclk(); + configure_dsicore_pclk(); + mipi_dsi_phy_ctrl_config(panel_info); + status += mipi_dsi_panel_initialize(panel_info); + mipi_fb_cfg.base = MIPI_FB_ADDR; + + if (panel_info->mode == MIPI_VIDEO_MODE) + status += mipi_dsi_video_config(panel_info->num_of_lanes); + + if (panel_info->mode == MIPI_CMD_MODE) + cmd_mode_status = 1; + + return &mipi_fb_cfg; +} diff --git a/lk/platform/msm_shared/mmc.c b/lk/platform/msm_shared/mmc.c new file mode 100644 index 0000000..ecdd90f --- /dev/null +++ b/lk/platform/msm_shared/mmc.c @@ -0,0 +1,2796 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include "mmc.h" +#include + +#ifndef NULL +#define NULL 0 +#endif + +#define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y))) + +/* data access time unit in ns */ +static const unsigned int taac_unit[] = +{ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 }; +/* data access time value x 10 */ +static const unsigned int taac_value[] = +{ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 }; + +/* data transfer rate in kbit/s */ +static const unsigned int xfer_rate_unit[] = +{ 100, 1000, 10000, 100000, 0, 0, 0, 0 }; +/* data transfer rate value x 10*/ +static const unsigned int xfer_rate_value[] = +{ 0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80 }; + +char *ext3_partitions[] = {"system", "userdata", "persist"}; +unsigned int ext3_count = 0; + +static unsigned mmc_sdc_clk[] = { SDC1_CLK, SDC2_CLK, SDC3_CLK, SDC4_CLK}; +static unsigned mmc_sdc_pclk[] = { SDC1_PCLK, SDC2_PCLK, SDC3_PCLK, SDC4_PCLK}; + +unsigned char mmc_slot = 0; +unsigned int mmc_boot_mci_base = 0; + +static unsigned char ext_csd_buf[512]; +static unsigned char wp_status_buf[8]; + +int mmc_clock_enable_disable(unsigned id, unsigned enable); +int mmc_clock_get_rate(unsigned id); +int mmc_clock_set_rate(unsigned id, unsigned rate); +void mdelay(unsigned msecs); + +struct mmc_boot_host mmc_host; +struct mmc_boot_card mmc_card; +struct mbr_entry mbr[MAX_PARTITIONS]; +unsigned mmc_partition_count = 0; + +static void mbr_fill_name (struct mbr_entry *mbr_ent, unsigned int type); +unsigned int mmc_read (unsigned long long data_addr, unsigned int* out, unsigned int data_len); +static unsigned int mmc_wp(unsigned int addr, unsigned int size, unsigned char set_clear_wp); + +unsigned int SWAP_ENDIAN(unsigned int val) +{ + return ((val & 0xFF) << 24) | + (((val >> 8) & 0xFF) << 16) | + (((val >> 16) & 0xFF) << 8) | + (val >> 24); +} + +/* + * Function to enable and set master and peripheral clock for + * MMC card. + */ +static unsigned int mmc_boot_enable_clock( struct mmc_boot_host* host, + unsigned int mclk) +{ + unsigned int mmc_clk = 0; + +#ifndef PLATFORM_MSM8X60 + int mmc_signed_ret = 0; + unsigned SDC_CLK = mmc_sdc_clk[mmc_slot - 1]; + unsigned SDC_PCLK = mmc_sdc_pclk[mmc_slot - 1]; + + if( host == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + if( !host->clk_enabled ) + { + /* set clock */ + if( mmc_clock_enable_disable(SDC_PCLK, MMC_CLK_ENABLE) < 0 ) + { + dprintf(CRITICAL, "Failure enabling PCLK!\n"); + goto error_pclk; + } + + if( mmc_clock_enable_disable(SDC_CLK, MMC_CLK_ENABLE) < 0 ) + { + dprintf(CRITICAL, "Failure enabling MMC Clock!\n"); + goto error; + } + host->clk_enabled = 1; + } + if( host->mclk_rate != mclk ) + { + if( mmc_clock_set_rate(SDC_CLK, mclk) < 0 ) + { + dprintf(CRITICAL, "Failure setting clock rate for MCLK - clk_rate: %d\n!", mclk ); + goto error_mclk; + } + + if( ( mmc_signed_ret = mmc_clock_get_rate(SDC_CLK) ) < 0 ) + { + dprintf(CRITICAL, "Failure getting clock rate for MCLK - clk_rate: %d\n!", host->mclk_rate ); + goto error_mclk; + } + + host->mclk_rate = (unsigned int)mmc_signed_ret; + } + + if( ( mmc_signed_ret = mmc_clock_get_rate(SDC_PCLK) ) < 0 ) + { + dprintf(CRITICAL, "Failure getting clock rate for PCLK - clk_rate: %d\n!", host->pclk_rate ); + goto error_pclk; + } + + host->pclk_rate = ( unsigned int )mmc_signed_ret; + dprintf(INFO, "Clock rate - mclk: %dHz pclk: %dHz\n", host->mclk_rate, host->pclk_rate ); +#else + clock_set_enable(mclk); + host->mclk_rate = mclk; + host->pclk_rate = mclk; + host->clk_enabled = 1; +#endif + //enable mci clock + mmc_clk |= MMC_BOOT_MCI_CLK_ENABLE; + //enable flow control + mmc_clk |= MMC_BOOT_MCI_CLK_ENA_FLOW; + //latch data and command using feedback clock + mmc_clk |= MMC_BOOT_MCI_CLK_IN_FEEDBACK; + writel( mmc_clk, MMC_BOOT_MCI_CLK ); + return MMC_BOOT_E_SUCCESS; + +#ifndef PLATFORM_MSM8X60 +error_pclk: + mmc_clock_enable_disable(SDC_PCLK, MMC_CLK_DISABLE); +error_mclk: + mmc_clock_enable_disable(SDC_CLK, MMC_CLK_DISABLE); +error: + return MMC_BOOT_E_CLK_ENABLE_FAIL; +#endif +} + + +/* Sets a timeout for read operation. + */ +static unsigned int mmc_boot_set_read_timeout( struct mmc_boot_host* host, + struct mmc_boot_card* card ) +{ + unsigned int timeout_ns = 0; + + if( ( host == NULL ) || ( card == NULL ) ) + { + return MMC_BOOT_E_INVAL; + } + + if( (card->type == MMC_BOOT_TYPE_MMCHC) || (card->type == MMC_BOOT_TYPE_SDHC) ) + { + card->rd_timeout_ns = 100000000; + } + else if( (card->type == MMC_BOOT_TYPE_STD_SD) || (card->type == MMC_BOOT_TYPE_STD_MMC) ) + { + timeout_ns = 10 * ( (card->csd.taac_ns ) + + ( card->csd.nsac_clk_cycle / (host->mclk_rate/1000000000))); + card->rd_timeout_ns = timeout_ns; + } + else + { + return MMC_BOOT_E_NOT_SUPPORTED; + } + + dprintf(INFO, " Read timeout set: %d ns\n", card->rd_timeout_ns ); + + return MMC_BOOT_E_SUCCESS; +} + +/* Sets a timeout for write operation. + */ +static unsigned int mmc_boot_set_write_timeout( struct mmc_boot_host* host, + struct mmc_boot_card* card ) +{ + unsigned int timeout_ns = 0; + + if( ( host == NULL ) || ( card == NULL ) ) + { + return MMC_BOOT_E_INVAL; + } + + if( (card->type == MMC_BOOT_TYPE_MMCHC) || (card->type == MMC_BOOT_TYPE_SDHC) ) + { + card->wr_timeout_ns = 100000000; + } + else if( card->type == MMC_BOOT_TYPE_STD_SD || (card->type == MMC_BOOT_TYPE_STD_MMC) ) + { + timeout_ns = 10 * ( ( card->csd.taac_ns ) + + ( card->csd.nsac_clk_cycle / ( host->mclk_rate/1000000000 ) ) ); + timeout_ns = timeout_ns << card->csd.r2w_factor; + card->wr_timeout_ns = timeout_ns; + } + else + { + return MMC_BOOT_E_NOT_SUPPORTED; + } + + dprintf(INFO, " Write timeout set: %d ns\n", card->wr_timeout_ns ); + + return MMC_BOOT_E_SUCCESS; +} + + +/* + * Decodes CSD response received from the card. Note that we have defined only + * few of the CSD elements in csd structure. We'll only decode those values. + */ +static unsigned int mmc_boot_decode_and_save_csd( struct mmc_boot_card* card, + unsigned int* raw_csd ) +{ + unsigned int mmc_sizeof = 0; + unsigned int mmc_unit = 0; + unsigned int mmc_value = 0; + unsigned int mmc_temp = 0; + + struct mmc_boot_csd mmc_csd; + + if( ( card == NULL ) || ( raw_csd == NULL ) ) + { + return MMC_BOOT_E_INVAL; + } + + /* CSD register is little bit differnet for CSD version 2.0 High Capacity + * and CSD version 1.0/2.0 Standard memory cards. In Version 2.0 some of + * the fields have fixed values and it's not necessary for host to refer + * these fields in CSD sent by card */ + + mmc_sizeof = sizeof(unsigned int) * 8; + + mmc_csd.cmmc_structure = UNPACK_BITS( raw_csd, 126, 2, mmc_sizeof ); + + /* cmmc_structure- 0: Version 1.0 1: Version 2.0 */ + if( mmc_csd.cmmc_structure ) + { + mmc_csd.card_cmd_class = UNPACK_BITS( raw_csd, 84, 12, mmc_sizeof ); + mmc_csd.write_blk_len = 512; /* Fixed value is 9 = 2^9 = 512 */ + mmc_csd.read_blk_len = 512; /* Fixed value is 9 = 512 */ + mmc_csd.r2w_factor = UNPACK_BITS( raw_csd, 26, 3, mmc_sizeof ); /* Fixed value: 010b */ + mmc_csd.c_size_mult = 0; /* not there in version 2.0 */ + mmc_csd.c_size = UNPACK_BITS( raw_csd, 62, 12, mmc_sizeof ); + mmc_csd.nsac_clk_cycle = UNPACK_BITS( raw_csd, 104, 8, mmc_sizeof) * 100; + + mmc_unit = UNPACK_BITS( raw_csd, 112, 3, mmc_sizeof ); + mmc_value = UNPACK_BITS( raw_csd, 115, 4, mmc_sizeof ); + mmc_csd.taac_ns = ( taac_value[mmc_value] * taac_unit[mmc_unit]) / 10; + + mmc_csd.erase_blk_len = 1; + mmc_csd.read_blk_misalign = 0; + mmc_csd.write_blk_misalign = 0; + mmc_csd.read_blk_partial = 0; + mmc_csd.write_blk_partial = 0; + + mmc_unit = UNPACK_BITS( raw_csd, 96, 3, mmc_sizeof ); + mmc_value = UNPACK_BITS( raw_csd, 99, 4, mmc_sizeof ); + mmc_csd.tran_speed = ( xfer_rate_value[mmc_value] * xfer_rate_unit[mmc_unit]) / 10; + + /* Calculate card capcity now itself */ + card->capacity = ( 1 + mmc_csd.c_size ) * 512000; + } + else + { + mmc_csd.card_cmd_class = UNPACK_BITS( raw_csd, 84, 12, mmc_sizeof ); + + mmc_temp = UNPACK_BITS( raw_csd, 22, 4, mmc_sizeof ); + mmc_csd.write_blk_len = ( mmc_temp > 8 && mmc_temp < 12 )? ( 1 << mmc_temp ) : 512; + + mmc_temp = UNPACK_BITS( raw_csd, 80, 4, mmc_sizeof ); + mmc_csd.read_blk_len = ( mmc_temp > 8 && mmc_temp < 12 )? ( 1 << mmc_temp ) : 512; + + mmc_unit = UNPACK_BITS( raw_csd, 112, 3, mmc_sizeof ); + mmc_value = UNPACK_BITS( raw_csd, 115, 4, mmc_sizeof ); + mmc_csd.taac_ns = ( taac_value[mmc_value] * taac_unit[mmc_unit]) / 10; + + mmc_unit = UNPACK_BITS( raw_csd, 96, 3, mmc_sizeof ); + mmc_value = UNPACK_BITS( raw_csd, 99, 4, mmc_sizeof ); + mmc_csd.tran_speed = ( xfer_rate_value[mmc_value] * xfer_rate_unit[mmc_unit]) / 10; + + mmc_csd.nsac_clk_cycle = UNPACK_BITS( raw_csd, 104, 8, mmc_sizeof ) * 100; + + mmc_csd.r2w_factor = UNPACK_BITS( raw_csd, 26, 3, mmc_sizeof ); + mmc_csd.sector_size = UNPACK_BITS( raw_csd, 39, 7, mmc_sizeof ) + 1; + + mmc_csd.erase_blk_len = UNPACK_BITS( raw_csd, 46, 1, mmc_sizeof ); + mmc_csd.read_blk_misalign = UNPACK_BITS( raw_csd, 77, 1, mmc_sizeof ); + mmc_csd.write_blk_misalign = UNPACK_BITS( raw_csd, 78, 1, mmc_sizeof ); + mmc_csd.read_blk_partial = UNPACK_BITS( raw_csd, 79, 1, mmc_sizeof ); + mmc_csd.write_blk_partial = UNPACK_BITS( raw_csd, 21, 1, mmc_sizeof ); + + mmc_csd.c_size_mult = UNPACK_BITS( raw_csd, 47, 3, mmc_sizeof ); + mmc_csd.c_size = UNPACK_BITS( raw_csd, 62, 12, mmc_sizeof ); + mmc_temp = ( 1 << ( mmc_csd.c_size_mult + 2 ) ) * ( mmc_csd.c_size + 1 ); + card->capacity = mmc_temp * mmc_csd.read_blk_len; + } + + mmc_csd.erase_grp_size = UNPACK_BITS( raw_csd, 42, 5, mmc_sizeof ); + mmc_csd.erase_grp_mult = UNPACK_BITS( raw_csd, 37, 5, mmc_sizeof ); + mmc_csd.wp_grp_size = UNPACK_BITS( raw_csd, 32, 5, mmc_sizeof ); + mmc_csd.wp_grp_enable = UNPACK_BITS( raw_csd, 31, 1, mmc_sizeof ); + mmc_csd.perm_wp = UNPACK_BITS( raw_csd, 13, 1, mmc_sizeof ); + mmc_csd.temp_wp = UNPACK_BITS( raw_csd, 12, 1, mmc_sizeof ); + + /* save the information in card structure */ + memcpy( (struct mmc_boot_csd *)&card->csd, (struct mmc_boot_csd *)&mmc_csd, + sizeof(struct mmc_boot_csd) ); + + dprintf(INFO, "Decoded CSD fields:\n" ); + dprintf(INFO, "cmmc_structure: %d\n", mmc_csd.cmmc_structure ); + dprintf(INFO, "card_cmd_class: %x\n", mmc_csd.card_cmd_class ); + dprintf(INFO, "write_blk_len: %d\n", mmc_csd.write_blk_len ); + dprintf(INFO, "read_blk_len: %d\n", mmc_csd.read_blk_len ); + dprintf(INFO, "r2w_factor: %d\n", mmc_csd.r2w_factor ); + dprintf(INFO, "sector_size: %d\n", mmc_csd.sector_size ); + dprintf(INFO, "c_size_mult:%d\n", mmc_csd.c_size_mult ); + dprintf(INFO, "c_size: %d\n", mmc_csd.c_size ); + dprintf(INFO, "nsac_clk_cycle: %d\n", mmc_csd.nsac_clk_cycle ); + dprintf(INFO, "taac_ns: %d\n", mmc_csd.taac_ns ); + dprintf(INFO, "tran_speed: %d kbps\n", mmc_csd.tran_speed ); + dprintf(INFO, "erase_blk_len: %d\n", mmc_csd.erase_blk_len ); + dprintf(INFO, "read_blk_misalign: %d\n", mmc_csd.read_blk_misalign ); + dprintf(INFO, "write_blk_misalign: %d\n", mmc_csd.write_blk_misalign ); + dprintf(INFO, "read_blk_partial: %d\n", mmc_csd.read_blk_partial ); + dprintf(INFO, "write_blk_partial: %d\n", mmc_csd.write_blk_partial ); + dprintf(INFO, "Card Capacity: %d Bytes\n", card->capacity ); + + return MMC_BOOT_E_SUCCESS; + +} + +/* + * Decode CID sent by the card. + */ +static unsigned int mmc_boot_decode_and_save_cid( struct mmc_boot_card* card, + unsigned int* raw_cid ) +{ + struct mmc_boot_cid mmc_cid; + unsigned int mmc_sizeof = 0; + int i = 0; + + if( ( card == NULL ) || ( raw_cid == NULL ) ) + { + return MMC_BOOT_E_INVAL; + } + + mmc_sizeof = sizeof( unsigned int ) * 8; + mmc_cid.mid = UNPACK_BITS( raw_cid, 120, 8, mmc_sizeof ); + mmc_cid.oid = UNPACK_BITS( raw_cid, 104, 16, mmc_sizeof ); + + for( i = 0; i < 6; i++ ) + { + mmc_cid.pnm[i] = (unsigned char) UNPACK_BITS(raw_cid, \ + (104 - 8 * (i+1)), 8, mmc_sizeof ); + } + mmc_cid.pnm[6] = 0; + + mmc_cid.prv = UNPACK_BITS( raw_cid, 48, 8, mmc_sizeof ); + mmc_cid.psn = UNPACK_BITS( raw_cid, 16, 32, mmc_sizeof ); + mmc_cid.month = UNPACK_BITS( raw_cid, 12, 4, mmc_sizeof ); + mmc_cid.year = UNPACK_BITS( raw_cid, 8, 4, mmc_sizeof ); + + /* save it in card database */ + memcpy( ( struct mmc_boot_cid * )&card->cid, \ + ( struct mmc_boot_cid * )&mmc_cid, \ + sizeof( struct mmc_boot_cid ) ); + + dprintf(INFO, "Decoded CID fields:\n" ); + dprintf(INFO, "Manufacturer ID: %x\n", mmc_cid.mid ); + dprintf(INFO, "OEM ID: 0x%x\n", mmc_cid.oid ); + dprintf(INFO, "Product Name: %s\n", mmc_cid.pnm ); + dprintf(INFO, "Product revision: %d.%d\n", (mmc_cid.prv >> 4), (mmc_cid.prv & 0xF) ); + dprintf(INFO, "Product serial number: %X\n", mmc_cid.psn ); + dprintf(INFO, "Manufacturing date: %d %d\n", mmc_cid.month, mmc_cid.year + 1997 ); + + return MMC_BOOT_E_SUCCESS; +} + +/* + * Sends specified command to a card and waits for a response. + */ +static unsigned int mmc_boot_send_command( struct mmc_boot_command* cmd ) +{ + unsigned int mmc_cmd = 0; + unsigned int mmc_status = 0; + unsigned int mmc_resp = 0; + unsigned int mmc_return = MMC_BOOT_E_SUCCESS; + unsigned int cmd_index = 0; + int i = 0; + + /* basic check */ + if( cmd == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + /* 1. Write command argument to MMC_BOOT_MCI_ARGUMENT register */ + writel( cmd->argument, MMC_BOOT_MCI_ARGUMENT ); + + /* 2. Set appropriate fields and write MMC_BOOT_MCI_CMD */ + /* 2a. Write command index in CMD_INDEX field */ + cmd_index = cmd->cmd_index; + mmc_cmd |= cmd->cmd_index; + /* 2b. Set RESPONSE bit to 1 for all cmds except CMD0 */ + if( cmd_index != CMD0_GO_IDLE_STATE ) + { + mmc_cmd |= MMC_BOOT_MCI_CMD_RESPONSE; + } + + /* 2c. Set LONGRESP bit to 1 for CMD2, CMD9 and CMD10 */ + if( IS_RESP_136_BITS(cmd->resp_type) ) + { + mmc_cmd |= MMC_BOOT_MCI_CMD_LONGRSP; + } + + /* 2d. Set INTERRUPT bit to 1 to disable command timeout */ + + /* 2e. Set PENDING bit to 1 for CMD12 in the beginning of stream + mode data transfer*/ + if( cmd->xfer_mode == MMC_BOOT_XFER_MODE_STREAM ) + { + mmc_cmd |= MMC_BOOT_MCI_CMD_PENDING; + } + + /* 2f. Set ENABLE bit to 1 */ + mmc_cmd |= MMC_BOOT_MCI_CMD_ENABLE; + + /* 2g. Set PROG_ENA bit to 1 for CMD12, CMD13 issued at the end of + write data transfer */ + if( ( cmd_index == CMD12_STOP_TRANSMISSION || + cmd_index == CMD13_SEND_STATUS ) && cmd->prg_enabled ) + { + mmc_cmd |= MMC_BOOT_MCI_CMD_PROG_ENA; + } + + /* 2h. Set MCIABORT bit to 1 for CMD12 when working with SDIO card */ + /* 2i. Set CCS_ENABLE bit to 1 for CMD61 when Command Completion Signal + of CE-ATA device is enabled */ + + /* 2j. clear all static status bits */ + writel( MMC_BOOT_MCI_STATIC_STATUS, MMC_BOOT_MCI_CLEAR ); + + /* 2k. Write to MMC_BOOT_MCI_CMD register */ + writel( mmc_cmd, MMC_BOOT_MCI_CMD ); + + dprintf(INFO, "Command sent: CMD%d MCI_CMD_REG:%x MCI_ARG:%x\n", + cmd_index, mmc_cmd, cmd->argument ); + + /* 3. Wait for interrupt or poll on the following bits of MCI_STATUS + register */ + do{ + /* 3a. Read MCI_STATUS register */ + while(readl( MMC_BOOT_MCI_STATUS ) \ + & MMC_BOOT_MCI_STAT_CMD_ACTIVE); + + mmc_status = readl( MMC_BOOT_MCI_STATUS ); + + /* 3b. CMD_SENT bit supposed to be set to 1 only after CMD0 is sent - + no response required. */ + if( ( cmd->resp_type == MMC_BOOT_RESP_NONE ) && + (mmc_status & MMC_BOOT_MCI_STAT_CMD_SENT ) ) + { + break; + } + + /* 3c. If CMD_TIMEOUT bit is set then no response was received */ + else if( mmc_status & MMC_BOOT_MCI_STAT_CMD_TIMEOUT ) + { + mmc_return = MMC_BOOT_E_TIMEOUT; + break; + } + + /* 3d. If CMD_RESPONSE_END bit is set to 1 then command's response was + received and CRC check passed + Spcial case for ACMD41: it seems to always fail CRC even if + the response is valid + */ + else if (( mmc_status & MMC_BOOT_MCI_STAT_CMD_RESP_END ) || (cmd_index == CMD1_SEND_OP_COND) + || (cmd_index == CMD8_SEND_IF_COND)) + { + /* 3i. Read MCI_RESP_CMD register to verify that response index is + equal to command index */ + mmc_resp = readl( MMC_BOOT_MCI_RESP_CMD ) & 0x3F; + + /* However, long response does not contain the command index field. + * In that case, response index field must be set to 111111b (0x3F) */ + if( ( mmc_resp == cmd_index ) || + ( cmd->resp_type == MMC_BOOT_RESP_R2 || + cmd->resp_type == MMC_BOOT_RESP_R3 || + cmd->resp_type == MMC_BOOT_RESP_R6 || + cmd->resp_type == MMC_BOOT_RESP_R7 ) ) + { + /* 3j. If resp index is equal to cmd index, read command resp + from MCI_RESPn registers + - MCI_RESP0/1/2/3 for CMD2/9/10 + - MCI_RESP0 for all other registers */ + if( IS_RESP_136_BITS( cmd->resp_type ) ) + { + for( i = 0; i < 4; i++ ) + { + cmd->resp[3-i] = readl( MMC_BOOT_MCI_RESP_0 + ( i * 4 ) ); + + } + } + else + { + cmd->resp[0] = readl( MMC_BOOT_MCI_RESP_0 ); + } + } + else + { + /* command index mis-match */ + mmc_return = MMC_BOOT_E_CMD_INDX_MISMATCH; + } + + dprintf(INFO, "Command response received: %X\n", cmd->resp[0] ); + break; + } + + /* 3e. If CMD_CRC_FAIL bit is set to 1 then cmd's response was recvd, + but CRC check failed. */ + else if( ( mmc_status & MMC_BOOT_MCI_STAT_CMD_CRC_FAIL ) ) + { + if(cmd_index == ACMD41_SEND_OP_COND) + { + cmd->resp[0] = readl( MMC_BOOT_MCI_RESP_0); + } + else + mmc_return = MMC_BOOT_E_CRC_FAIL; + break; + } + + }while(1); + + return mmc_return; +} + +/* + * Reset all the cards to idle condition (CMD 0) + */ +static unsigned int mmc_boot_reset_cards( void ) +{ + struct mmc_boot_command cmd; + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + cmd.cmd_index = CMD0_GO_IDLE_STATE; + cmd.argument = 0; // stuff bits - ignored + cmd.cmd_type = MMC_BOOT_CMD_BCAST; + cmd.resp_type = MMC_BOOT_RESP_NONE; + + /* send command */ + return mmc_boot_send_command( &cmd ); +} + +/* + * Send CMD1 to know whether the card supports host VDD profile or not. + */ +static unsigned int mmc_boot_send_op_cond( struct mmc_boot_host* host, + struct mmc_boot_card* card ) +{ + struct mmc_boot_command cmd; + unsigned int mmc_resp = 0; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( ( host == NULL ) || ( card == NULL ) ) + { + return MMC_BOOT_E_INVAL; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* CMD1 format: + * [31] Busy bit + * [30:29] Access mode + * [28:24] reserved + * [23:15] 2.7-3.6 + * [14:8] 2.0-2.6 + * [7] 1.7-1.95 + * [6:0] reserved + */ + + cmd.cmd_index = CMD1_SEND_OP_COND; + cmd.argument = host->ocr; + cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP; + cmd.resp_type = MMC_BOOT_RESP_R3; + + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + /* Now it's time to examine response */ + mmc_resp = cmd.resp[0]; + + /* Response contains card's ocr. Update card's information */ + card->ocr = mmc_resp; + + /* Check the response for busy status */ + if( !( mmc_resp & MMC_BOOT_OCR_BUSY ) ) + { + return MMC_BOOT_E_CARD_BUSY; + } + + if(mmc_resp & MMC_BOOT_OCR_SEC_MODE) + { + card->type = MMC_BOOT_TYPE_MMCHC; + } + else + { + card->type = MMC_BOOT_TYPE_STD_MMC; + } + return MMC_BOOT_E_SUCCESS; +} + +/* + * Request any card to send its uniquie card identification (CID) number (CMD2). + */ +static unsigned int mmc_boot_all_send_cid( struct mmc_boot_card* card ) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( card == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* CMD2 Format: + * [31:0] stuff bits + */ + cmd.cmd_index = CMD2_ALL_SEND_CID; + cmd.argument = 0; + cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP; + cmd.resp_type = MMC_BOOT_RESP_R2; + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + /* Response contains card's 128 bits CID register */ + mmc_ret = mmc_boot_decode_and_save_cid( card, cmd.resp ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + return MMC_BOOT_E_SUCCESS; +} + +/* + * Ask any card to send it's relative card address (RCA).This RCA number is + * shorter than CID and is used by the host to address the card in future (CMD3) + */ +static unsigned int mmc_boot_send_relative_address( struct mmc_boot_card* card ) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( card == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* CMD3 Format: + * [31:0] stuff bits + */ + if(card->type == MMC_BOOT_TYPE_SDHC || card->type == MMC_BOOT_TYPE_STD_SD) + { + cmd.cmd_index = CMD3_SEND_RELATIVE_ADDR; + cmd.argument = 0; + cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP; + cmd.resp_type = MMC_BOOT_RESP_R6; + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + /* For sD, card will send RCA. Store it */ + card->rca = (cmd.resp[0] >> 16); + } + else + { + cmd.cmd_index = CMD3_SEND_RELATIVE_ADDR; + cmd.argument = (MMC_RCA << 16); + card->rca = (cmd.argument >> 16); + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1; + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + } + + return MMC_BOOT_E_SUCCESS; +} + +/* + * Requests card to send it's CSD register's contents. (CMD9) + */ +static unsigned int mmc_boot_send_csd( struct mmc_boot_card* card ) +{ + struct mmc_boot_command cmd; + unsigned int mmc_arg = 0; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( card == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* CMD9 Format: + * [31:16] RCA + * [15:0] stuff bits + */ + mmc_arg |= card->rca << 16; + + cmd.cmd_index = CMD9_SEND_CSD; + cmd.argument = mmc_arg; + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R2; + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + /* Response contains card's 128 bits CSD register */ + /* Decode and save the register */ + mmc_ret = mmc_boot_decode_and_save_csd( card, cmd.resp ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + return MMC_BOOT_E_SUCCESS; +} + +/* + * Selects a card by sending CMD7 to the card with its RCA. + * If RCA field is set as 0 ( or any other address ), + * the card will be de-selected. (CMD7) + */ +static unsigned int mmc_boot_select_card( struct mmc_boot_card* card, + unsigned int rca ) +{ + struct mmc_boot_command cmd; + unsigned int mmc_arg = 0; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( card == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* CMD7 Format: + * [31:16] RCA + * [15:0] stuff bits + */ + mmc_arg |= rca << 16; + + cmd.cmd_index = CMD7_SELECT_DESELECT_CARD; + cmd.argument = mmc_arg; + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + /* If we are deselecting card, we do not get response */ + if( rca == card->rca && rca) + { + if(card->type == MMC_BOOT_TYPE_SDHC || card->type == MMC_BOOT_TYPE_STD_SD) + cmd.resp_type = MMC_BOOT_RESP_R1B; + else + cmd.resp_type = MMC_BOOT_RESP_R1; + } + else + { + cmd.resp_type = MMC_BOOT_RESP_NONE; + } + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + /* As of now no need to look into a response. If it's required + * we'll explore later on */ + + return MMC_BOOT_E_SUCCESS; +} + +/* + * Send command to set block length. + */ +static unsigned int mmc_boot_set_block_len( struct mmc_boot_card* card, + unsigned int block_len ) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( card == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* CMD16 Format: + * [31:0] block length + */ + + cmd.cmd_index = CMD16_SET_BLOCKLEN; + cmd.argument = block_len; + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1; + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + /* If blocklength is larger than 512 bytes, + * the card sets BLOCK_LEN_ERROR bit. */ + if( cmd.resp[0] & MMC_BOOT_R1_BLOCK_LEN_ERR ) + { + return MMC_BOOT_E_BLOCKLEN_ERR; + } + return MMC_BOOT_E_SUCCESS; +} + +/* + * Requests the card to stop transmission of data. + */ +static unsigned int mmc_boot_send_stop_transmission( struct mmc_boot_card* card, + unsigned int prg_enabled ) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( card == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* CMD12 Format: + * [31:0] stuff bits + */ + + cmd.cmd_index = CMD12_STOP_TRANSMISSION; + cmd.argument = 0; + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1B; + cmd.xfer_mode = MMC_BOOT_XFER_MODE_BLOCK; + cmd.prg_enabled = prg_enabled; + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + return MMC_BOOT_E_SUCCESS; +} + +/* + * Get the card's current status + */ +static unsigned int mmc_boot_get_card_status( struct mmc_boot_card* card, + unsigned int prg_enabled, unsigned int* status ) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( card == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* CMD13 Format: + * [31:16] RCA + * [15:0] stuff bits + */ + cmd.cmd_index = CMD13_SEND_STATUS; + cmd.argument = card->rca << 16; + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1; + cmd.prg_enabled = prg_enabled; + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + /* Checking ADDR_OUT_OF_RANGE error in CMD13 response */ + if(IS_ADDR_OUT_OF_RANGE(cmd.resp[0])) + { + return MMC_BOOT_E_FAILURE; + } + + *status = cmd.resp[0]; + return MMC_BOOT_E_SUCCESS; +} + +/* + * Decode type of error caused during read and write + */ +static unsigned int mmc_boot_status_error(unsigned mmc_status) +{ + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* If DATA_CRC_FAIL bit is set to 1 then CRC error was detected by + card/device during the data transfer */ + if( mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL ) + { + mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL; + } + /* If DATA_TIMEOUT bit is set to 1 then the data transfer time exceeded + the data timeout period without completing the transfer */ + else if( mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT ) + { + mmc_ret = MMC_BOOT_E_DATA_TIMEOUT; + } + /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to receive data from + the card before empty storage for new received data was available. + Verify that bit FLOW_ENA in MCI_CLK is set to 1 during the data xfer.*/ + else if( mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN ) + { + /* Note: We've set FLOW_ENA bit in MCI_CLK to 1. so no need to verify + for now */ + mmc_ret = MMC_BOOT_E_RX_OVRRUN; + } + /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send data to + the card before new data for sending was available. Verify that bit + FLOW_ENA in MCI_CLK is set to 1 during the data xfer.*/ + else if( mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN ) + { + /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.so skipping it now*/ + mmc_ret = MMC_BOOT_E_RX_OVRRUN; + } + return mmc_ret; +} + +/* + * Send ext csd command. + */ +static unsigned int mmc_boot_send_ext_cmd (struct mmc_boot_card* card, unsigned char* buf) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + unsigned int mmc_reg = 0; + unsigned int mmc_status = 0; + unsigned int* mmc_ptr = (unsigned int *)buf; + unsigned int mmc_count = 0; + unsigned int read_error; + + memset(buf,0, 512); + + /* basic check */ + if( card == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + /* set block len */ + if( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) ) + { + mmc_ret = mmc_boot_set_block_len( card, 512); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure setting block length for Card (RCA:%s)\n", + mmc_ret, (char *)(card->rca) ); + return mmc_ret; + } + } + + /* Set the FLOW_ENA bit of MCI_CLK register to 1 */ + mmc_reg = readl( MMC_BOOT_MCI_CLK ); + mmc_reg |= MMC_BOOT_MCI_CLK_ENA_FLOW ; + writel( mmc_reg, MMC_BOOT_MCI_CLK ); + + /* Write data timeout period to MCI_DATA_TIMER register. */ + /* Data timeout period should be in card bus clock periods */ + mmc_reg =0xFFFFFFFF; + writel( mmc_reg, MMC_BOOT_MCI_DATA_TIMER ); + writel( 512, MMC_BOOT_MCI_DATA_LENGTH ); + + /* Set appropriate fields and write the MCI_DATA_CTL register. */ + /* Set ENABLE bit to 1 to enable the data transfer. */ + mmc_reg = MMC_BOOT_MCI_DATA_ENABLE | MMC_BOOT_MCI_DATA_DIR | (512 << MMC_BOOT_MCI_BLKSIZE_POS); + writel( mmc_reg, MMC_BOOT_MCI_DATA_CTL ); + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + /* CMD8 */ + cmd.cmd_index = CMD8_SEND_EXT_CSD; + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1; + cmd.xfer_mode = MMC_BOOT_XFER_MODE_BLOCK; + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \ + MMC_BOOT_MCI_STAT_DATA_TIMEOUT | \ + MMC_BOOT_MCI_STAT_RX_OVRRUN; + + /* Read the transfer data from SDCC2 FIFO. If Data Mover is not used + read the data from the MCI_FIFO register as long as RXDATA_AVLBL + bit of MCI_STATUS register is set to 1 and bits DATA_CRC_FAIL, + DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS register are cleared to 0. + Continue the reads until the whole transfer data is received */ + + do + { + mmc_ret = MMC_BOOT_E_SUCCESS; + mmc_status = readl( MMC_BOOT_MCI_STATUS ); + + if( mmc_status & read_error ) + { + mmc_ret = mmc_boot_status_error(mmc_status); + break; + } + + if( mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL ) + { + unsigned read_count = 1; + if ( mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL) + { + read_count = MMC_BOOT_MCI_HFIFO_COUNT; + } + + for (int i=0; i= 512) + break; + } + else if( mmc_status & MMC_BOOT_MCI_STAT_DATA_END ) + { + break; + } + }while(1); + + return MMC_BOOT_E_SUCCESS; + +} + +/* + * Switch command + */ +static unsigned int mmc_boot_switch_cmd (struct mmc_boot_card* card, + unsigned access, + unsigned index, + unsigned value) +{ + + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( card == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* CMD6 Format: + * [31:26] set to 0 + * [25:24] access + * [23:16] index + * [15:8] value + * [7:3] set to 0 + * [2:0] cmd set + */ + cmd.cmd_index = CMD6_SWITCH_FUNC; + cmd.argument |= (access << 24); + cmd.argument |= (index << 16); + cmd.argument |= (value << 8); + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1B; + + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + return MMC_BOOT_E_SUCCESS; +} + +/* + * A command to set the data bus width for card. Set width to either + */ +static unsigned int mmc_boot_set_bus_width( struct mmc_boot_card* card, + unsigned int width ) +{ + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + unsigned int mmc_reg = 0; + unsigned int mmc_width = 0; + unsigned int status; + + if( width != MMC_BOOT_BUS_WIDTH_1_BIT) + { + mmc_width = width-1; + } + + + do + { + mmc_ret = mmc_boot_get_card_status(card, 1, &status); + if(mmc_ret != MMC_BOOT_E_SUCCESS) + { + return mmc_ret; + } + }while(MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE); + + if(MMC_BOOT_CARD_STATUS(status) != MMC_BOOT_TRAN_STATE) + return MMC_BOOT_E_FAILURE; + + mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE, MMC_BOOT_EXT_CMMC_BUS_WIDTH, mmc_width); + + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + /* set MCI_CLK accordingly */ + mmc_reg = readl( MMC_BOOT_MCI_CLK ); + mmc_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE; + if ( width == MMC_BOOT_BUS_WIDTH_1_BIT ) + { + mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT; + } + else if (width == MMC_BOOT_BUS_WIDTH_4_BIT ) + { + mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT; + } + else if (width == MMC_BOOT_BUS_WIDTH_8_BIT ) + { + mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT; + } + writel( mmc_reg, MMC_BOOT_MCI_CLK ); + + mdelay(10); // Giving some time to card to stabilize. + + return MMC_BOOT_E_SUCCESS; +} + + +/* + * A command to start data read from card. Either a single block or + * multiple blocks can be read. Multiple blocks read will continuously + * transfer data from card to host unless requested to stop by issuing + * CMD12 - STOP_TRANSMISSION. + */ +static unsigned int mmc_boot_send_read_command( struct mmc_boot_card* card, + unsigned int xfer_type, + unsigned int data_addr ) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( card == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* CMD17/18 Format: + * [31:0] Data Address + */ + if( xfer_type == MMC_BOOT_XFER_MULTI_BLOCK ) + { + cmd.cmd_index = CMD18_READ_MULTIPLE_BLOCK; + } + else + { + cmd.cmd_index = CMD17_READ_SINGLE_BLOCK; + } + + cmd.argument = data_addr; + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1; + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + /* Response contains 32 bit Card status. Here we'll check + BLOCK_LEN_ERROR and ADDRESS_ERROR */ + if( cmd.resp[0] & MMC_BOOT_R1_BLOCK_LEN_ERR ) + { + return MMC_BOOT_E_BLOCKLEN_ERR; + } + /* Misaligned address not matching block length */ + if( cmd.resp[0] & MMC_BOOT_R1_ADDR_ERR ) + { + return MMC_BOOT_E_ADDRESS_ERR; + } + + return MMC_BOOT_E_SUCCESS; +} + +/* + * A command to start data write to card. Either a single block or + * multiple blocks can be written. Multiple block write will continuously + * transfer data from host to card unless requested to stop by issuing + * CMD12 - STOP_TRANSMISSION. + */ +static unsigned int mmc_boot_send_write_command( struct mmc_boot_card* card, + unsigned int xfer_type, + unsigned int data_addr ) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( card == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* CMD24/25 Format: + * [31:0] Data Address + */ + if( xfer_type == MMC_BOOT_XFER_MULTI_BLOCK ) + { + cmd.cmd_index = CMD25_WRITE_MULTIPLE_BLOCK; + } + else + { + cmd.cmd_index = CMD24_WRITE_SINGLE_BLOCK; + } + + cmd.argument = data_addr; + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1; + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + /* Response contains 32 bit Card status. Here we'll check + BLOCK_LEN_ERROR and ADDRESS_ERROR */ + if( cmd.resp[0] & MMC_BOOT_R1_BLOCK_LEN_ERR ) + { + return MMC_BOOT_E_BLOCKLEN_ERR; + } + /* Misaligned address not matching block length */ + if( cmd.resp[0] & MMC_BOOT_R1_ADDR_ERR ) + { + return MMC_BOOT_E_ADDRESS_ERR; + } + + return MMC_BOOT_E_SUCCESS; +} + + +/* + * Write data_len data to address specified by data_addr. data_len is + * multiple of blocks for block data transfer. + */ +static unsigned int mmc_boot_write_to_card( struct mmc_boot_host* host, + struct mmc_boot_card* card, + unsigned long long data_addr, + unsigned int data_len, + unsigned int* in ) +{ + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + unsigned int mmc_status = 0; + unsigned int* mmc_ptr = in; + unsigned int mmc_count = 0; + unsigned int mmc_reg = 0; + unsigned int addr; + unsigned int xfer_type; + unsigned int write_error; + unsigned int status; + + if( ( host == NULL ) || ( card == NULL ) ) + { + return MMC_BOOT_E_INVAL; + } + + /* Set block length. High Capacity MMC/SD card uses fixed 512 bytes block + length. So no need to send CMD16. */ + if( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) ) + { + mmc_ret = mmc_boot_set_block_len( card, card->wr_block_len ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure setting block length for Card\ + (RCA:%s)\n", mmc_ret, (char *)(card->rca) ); + return mmc_ret; + } + } + + /* use multi-block mode to transfer for data larger than a block */ + xfer_type = (data_len > card->rd_block_len) ? MMC_BOOT_XFER_MULTI_BLOCK : + MMC_BOOT_XFER_SINGLE_BLOCK; + + /* For MMCHC/SDHC data address is specified in unit of 512B */ + addr = ( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) ) + ? (unsigned int) data_addr : (unsigned int) (data_addr / 512); + + /* Set the FLOW_ENA bit of MCI_CLK register to 1 */ + mmc_reg = readl( MMC_BOOT_MCI_CLK ); + mmc_reg |= MMC_BOOT_MCI_CLK_ENA_FLOW ; + writel( mmc_reg, MMC_BOOT_MCI_CLK ); + + /* Write data timeout period to MCI_DATA_TIMER register */ + /* Data timeout period should be in card bus clock periods */ + /*TODO: Fix timeout value*/ + mmc_reg = 0xFFFFFFFF; + writel( mmc_reg, MMC_BOOT_MCI_DATA_TIMER ); + + /* Write the total size of the transfer data to MCI_DATA_LENGTH register */ + writel( data_len, MMC_BOOT_MCI_DATA_LENGTH ); + + /* Send command to the card/device in order to start the write data xfer. + The possible commands are CMD24/25/53/60/61 */ + mmc_ret = mmc_boot_send_write_command( card, xfer_type, addr ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure sending write command to the\ + Card(RCA:%x)\n", mmc_ret, card->rca ); + return mmc_ret; + } + + /* Set appropriate fields and write the MCI_DATA_CTL register */ + /* Set ENABLE bit to 1 to enable the data transfer. */ + mmc_reg = 0; + mmc_reg |= MMC_BOOT_MCI_DATA_ENABLE; + /* Clear DIRECTION bit to 0 to enable transfer from host to card */ + /* Clear MODE bit to 0 to enable block oriented data transfer. For + MMC cards only, if stream data transfer mode is desired, set + MODE bit to 1. */ + /* Set DM_ENABLE bit to 1 in order to enable DMA, otherwise set 0 */ + /* Write size of block to be used during the data transfer to + BLOCKSIZE field */ + mmc_reg |= card->wr_block_len << MMC_BOOT_MCI_BLKSIZE_POS; + writel( mmc_reg, MMC_BOOT_MCI_DATA_CTL ); + + write_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \ + MMC_BOOT_MCI_STAT_DATA_TIMEOUT | \ + MMC_BOOT_MCI_STAT_TX_UNDRUN; + + /* Write the transfer data to SDCC3 FIFO */ + /* If Data Mover is used for data transfer, prepare a command list entry + and enable the Data Mover to work with SDCC2 */ + /* If Data Mover is NOT used for data xfer: */ + do + { + mmc_ret = MMC_BOOT_E_SUCCESS; + mmc_status = readl( MMC_BOOT_MCI_STATUS ); + + if( mmc_status & write_error ) + { + mmc_ret = mmc_boot_status_error(mmc_status); + break; + } + + /* Write the data in MCI_FIFO register as long as TXFIFO_FULL bit of + MCI_STATUS register is 0. Continue the writes until the whole + transfer data is written. */ + if (((data_len-mmc_count) >= MMC_BOOT_MCI_FIFO_SIZE/2) && + ( mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_HFULL )) + { + for (int i=0; i < MMC_BOOT_MCI_HFIFO_COUNT; i++ ) + { + /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/ + writel( *mmc_ptr, MMC_BOOT_MCI_FIFO + + ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) ); + mmc_ptr++; + /* increase mmc_count by word size */ + mmc_count += sizeof( unsigned int ); + } + + } + else if( !( mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_FULL ) && (mmc_count != data_len)) + { + /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/ + writel( *mmc_ptr, MMC_BOOT_MCI_FIFO + + ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) ); + mmc_ptr++; + /* increase mmc_count by word size */ + mmc_count += sizeof( unsigned int ); + } + else if((mmc_status & MMC_BOOT_MCI_STAT_DATA_END)) + { + break; //success + } + + } while(1); + + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure on data transfer from the \ + Card(RCA:%x)\n", mmc_ret, card->rca ); + /* In case of any failure happening for multi block transfer */ + if( xfer_type == MMC_BOOT_XFER_MULTI_BLOCK ) + mmc_boot_send_stop_transmission( card, 1 ); + return mmc_ret; + } + + /* Send command to the card/device in order to poll the de-assertion of + card/device BUSY condition. It is important to set PROG_ENA bit in + MCI_CLK register before sending the command. Possible commands are + CMD12/13. */ + if( xfer_type == MMC_BOOT_XFER_MULTI_BLOCK ) + { + mmc_ret = mmc_boot_send_stop_transmission( card, 1 ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure sending Stop Transmission \ + command to the Card(RCA:%x)\n", mmc_ret, card->rca ); + return mmc_ret; + } + } + else + { + mmc_ret = mmc_boot_get_card_status( card, 1, &status ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure getting card status of Card(RCA:%x)\n", + mmc_ret, card->rca ); + return mmc_ret; + } + } + + /* Wait for interrupt or poll on PROG_DONE bit of MCI_STATUS register. If + PROG_DONE bit is set to 1 it means that the card finished it programming + and stopped driving DAT0 line to 0 */ + do + { + mmc_status = readl( MMC_BOOT_MCI_STATUS ); + if( mmc_status & MMC_BOOT_MCI_STAT_PROG_DONE ) + { + break; + } + } while(1); + + return MMC_BOOT_E_SUCCESS; +} + + +/* + * Adjust the interface speed to optimal speed + */ +static unsigned int mmc_boot_adjust_interface_speed( struct mmc_boot_host* host, + struct mmc_boot_card* card ) +{ + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + unsigned int status; + + + do + { + mmc_ret = mmc_boot_get_card_status(card, 1, &status); + if(mmc_ret != MMC_BOOT_E_SUCCESS) + { + return mmc_ret; + } + }while(MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE); + + if(MMC_BOOT_CARD_STATUS(status) != MMC_BOOT_TRAN_STATE) + return MMC_BOOT_E_FAILURE; + + /* Setting HS_TIMING in EXT_CSD (CMD6) */ + mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE, MMC_BOOT_EXT_CMMC_HS_TIMING, 1); + + if(mmc_ret!= MMC_BOOT_E_SUCCESS) + { + return mmc_ret; + } +#ifdef PLATFORM_MSM8X60 + mmc_ret = mmc_boot_enable_clock( host, MMC_CLK_48MHZ); +#else + mmc_ret = mmc_boot_enable_clock( host, MMC_CLK_50MHZ); +#endif + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return MMC_BOOT_E_CLK_ENABLE_FAIL; + } + return MMC_BOOT_E_SUCCESS; +} + +/* + * Reads a data of data_len from the address specified. data_len + * should be multiple of block size for block data transfer. + */ +static unsigned int mmc_boot_read_from_card( struct mmc_boot_host* host, + struct mmc_boot_card* card, + unsigned long long data_addr, + unsigned int data_len, + unsigned int* out ) +{ + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + unsigned int mmc_status = 0; + unsigned int* mmc_ptr = out; + unsigned int mmc_count = 0; + unsigned int mmc_reg = 0; + unsigned int xfer_type; + unsigned int addr = 0; + unsigned int read_error; + + if( ( host == NULL ) || ( card == NULL ) ) + { + return MMC_BOOT_E_INVAL; + } + + /* Set block length. High Capacity MMC/SD card uses fixed 512 bytes block + length. So no need to send CMD16. */ + if( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) ) + { + mmc_ret = mmc_boot_set_block_len( card, card->rd_block_len ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure setting block length for Card (RCA:%s)\n", + mmc_ret, (char *)(card->rca) ); + return mmc_ret; + } + } + + /* use multi-block mode to transfer for data larger than a block */ + xfer_type = (data_len > card->rd_block_len) ? MMC_BOOT_XFER_MULTI_BLOCK : + MMC_BOOT_XFER_SINGLE_BLOCK; + + /* Set the FLOW_ENA bit of MCI_CLK register to 1 */ + /* Note: It's already enabled */ + + /* If Data Mover is used for data transfer then prepare Command + List Entry and enable the Data mover to work with SDCC2 */ + /* Note: Data Mover not used */ + + /* Write data timeout period to MCI_DATA_TIMER register. */ + /* Data timeout period should be in card bus clock periods */ + mmc_reg = (unsigned long)(card->rd_timeout_ns / 1000000) * + (host->mclk_rate / 1000); + mmc_reg += 1000; // add some extra clock cycles to be safe + mmc_reg = mmc_reg/2; + writel( mmc_reg, MMC_BOOT_MCI_DATA_TIMER ); + + /* Write the total size of the transfer data to MCI_DATA_LENGTH + register. For block xfer it must be multiple of the block + size. */ + writel( data_len, MMC_BOOT_MCI_DATA_LENGTH ); + + /* For MMCHC/SDHC data address is specified in unit of 512B */ + addr = ( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) ) + ? (unsigned int) data_addr :(unsigned int) (data_addr / 512); + + /* Set appropriate fields and write the MCI_DATA_CTL register. */ + /* Set ENABLE bit to 1 to enable the data transfer. */ + mmc_reg = 0; + mmc_reg |= MMC_BOOT_MCI_DATA_ENABLE; + /* Clear DIRECTION bit to 1 to enable transfer from card to host */ + mmc_reg |= MMC_BOOT_MCI_DATA_DIR; + /* Clear MODE bit to 0 to enable block oriented data transfer. For + MMC cards only, if stream data transfer mode is desired, set + MODE bit to 1. */ + /* Set DM_ENABLE bit to 1 in order to enable DMA, otherwise set 0 */ + /* Write size of block to be used during the data transfer to + BLOCKSIZE field */ + mmc_reg |= (card->rd_block_len << MMC_BOOT_MCI_BLKSIZE_POS); + writel( mmc_reg, MMC_BOOT_MCI_DATA_CTL ); + + /* Send command to the card/device in order to start the read data + transfer. Possible commands: CMD17/18/53/60/61. */ + mmc_ret = mmc_boot_send_read_command( card, xfer_type, addr ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure sending read command to the Card(RCA:%x)\n", + mmc_ret, card->rca ); + return mmc_ret; + } + + read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \ + MMC_BOOT_MCI_STAT_DATA_TIMEOUT | \ + MMC_BOOT_MCI_STAT_RX_OVRRUN; + + /* Read the transfer data from SDCC2 FIFO. If Data Mover is not used + read the data from the MCI_FIFO register as long as RXDATA_AVLBL + bit of MCI_STATUS register is set to 1 and bits DATA_CRC_FAIL, + DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS register are cleared to 0. + Continue the reads until the whole transfer data is received */ + + do + { + mmc_ret = MMC_BOOT_E_SUCCESS; + mmc_status = readl( MMC_BOOT_MCI_STATUS ); + + if( mmc_status & read_error ) + { + mmc_ret = mmc_boot_status_error(mmc_status); + break; + } + + if( mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL ) + { + unsigned read_count = 1; + if ( mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL) + { + read_count = MMC_BOOT_MCI_HFIFO_COUNT; + } + + for (int i=0; irca ); + return mmc_ret; + } + + /* In case a multiple block transfer was performed, send CMD12 to the + card/device in order to indicate the end of read data transfer */ + if( xfer_type == MMC_BOOT_XFER_MULTI_BLOCK ) + { + mmc_ret = mmc_boot_send_stop_transmission( card, 0 ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure sending Stop Transmission \ + command to the Card(RCA:%x)\n", mmc_ret, card->rca ); + return mmc_ret; + } + } + + return MMC_BOOT_E_SUCCESS; +} + +/* + * Initialize host structure, set and enable clock-rate and power mode. + */ +unsigned int mmc_boot_init( struct mmc_boot_host* host ) +{ + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + unsigned int mmc_pwr = 0; + + + host->ocr = MMC_BOOT_OCR_27_36 | MMC_BOOT_OCR_SEC_MODE; + host->cmd_retry = MMC_BOOT_MAX_COMMAND_RETRY; + host->clk_enabled = 0; + + /* clock frequency should be less than 400KHz in identification mode */ + mmc_ret = mmc_boot_enable_clock( host, MMC_CLK_400KHZ); + + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return MMC_BOOT_E_CLK_ENABLE_FAIL; + } + + /* set power mode*/ + /* give some time to reach minimum voltate */ + mdelay(2); + mmc_pwr &= ~MMC_BOOT_MCI_PWR_UP; + mmc_pwr |= MMC_BOOT_MCI_PWR_ON; + mmc_pwr |= MMC_BOOT_MCI_PWR_UP; + writel( mmc_pwr, MMC_BOOT_MCI_POWER ); + /* some more time to stabilize voltage */ + mdelay(2); + + return MMC_BOOT_E_SUCCESS; +} + +/* + * Performs card identification process by getting card's unique identification + * number (CID) and relative card address (RCA). After that card will be in + * stand-by state. + */ +static unsigned int mmc_boot_identify_card( struct mmc_boot_host* host, + struct mmc_boot_card* card) +{ + unsigned int mmc_return = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( ( host == NULL ) || ( card == NULL ) ) + { + return MMC_BOOT_E_INVAL; + } + + /* Ask card to send its unique card identification (CID) number (CMD2) */ + mmc_return = mmc_boot_all_send_cid( card ); + if( mmc_return != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No. %d: Failure getting card's CID number!\n", + mmc_return ); + return mmc_return; + } + + /* Ask card to send a relative card address (RCA) (CMD3) */ + mmc_return = mmc_boot_send_relative_address( card ); + if( mmc_return != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No. %d: Failure getting card's RCA!\n", + mmc_return ); + return mmc_return; + } + + /* Set the card status as active */ + card->status = MMC_BOOT_STATUS_ACTIVE; + + /* Get card's CSD register (CMD9) */ + mmc_return = mmc_boot_send_csd( card ); + if( mmc_return != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure getting card's CSD information!\n", + mmc_return ); + return mmc_return; + } + + /* Once CSD is received, set read and write timeout value now itself */ + mmc_return = mmc_boot_set_read_timeout( host, card ); + if( mmc_return != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure setting Read Timeout value!\n", + mmc_return ); + return mmc_return; + } + + mmc_return = mmc_boot_set_write_timeout( host, card ); + if( mmc_return != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure setting Write Timeout value!\n", + mmc_return ); + return mmc_return; + } + + return MMC_BOOT_E_SUCCESS; +} + +static unsigned int mmc_boot_send_app_cmd(unsigned int rca) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + cmd.cmd_index = CMD55_APP_CMD; + cmd.argument = (rca << 16); + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1; + + mmc_ret = mmc_boot_send_command(&cmd); + + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + return MMC_BOOT_E_SUCCESS; +} + +static unsigned int mmc_boot_sd_init_card(struct mmc_boot_card* card) +{ + unsigned int i,mmc_ret; + unsigned int ocr_cmd_arg; + struct mmc_boot_command cmd; + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* Send CMD8 to set interface condition */ + for(i=0;i<3;i++) + { + cmd.cmd_index = CMD8_SEND_IF_COND; + cmd.argument = MMC_BOOT_SD_HC_VOLT_SUPPLIED; + cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP; + cmd.resp_type = MMC_BOOT_RESP_R7; + + mmc_ret = mmc_boot_send_command(&cmd); + if( mmc_ret == MMC_BOOT_E_SUCCESS ) + { + if(cmd.resp[0] != MMC_BOOT_SD_HC_VOLT_SUPPLIED) + return MMC_BOOT_E_FAILURE; + /* Set argument for ACMD41 */ + ocr_cmd_arg = MMC_BOOT_SD_NEG_OCR | MMC_BOOT_SD_HC_HCS; + break; + } + mdelay(1); + } + + /* Send ACMD41 to set operating condition */ + /* Try for a max of 1 sec as per spec */ + for(i=0;i<20;i++) + { + mmc_ret = mmc_boot_send_app_cmd(0); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + cmd.cmd_index = ACMD41_SEND_OP_COND; + cmd.argument = ocr_cmd_arg; + cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP; + cmd.resp_type = MMC_BOOT_RESP_R3; + + mmc_ret = mmc_boot_send_command(&cmd); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + else if (cmd.resp[0] & MMC_BOOT_SD_DEV_READY) + { + /* Check for HC */ + if(cmd.resp[0] & (1 << 30)) + { + card->type = MMC_BOOT_TYPE_SDHC; + } + else + { + card->type = MMC_BOOT_TYPE_STD_SD; + } + break; + } + mdelay(50); + } + return MMC_BOOT_E_SUCCESS; +} + +/* + * Routine to initialize MMC card. It resets a card to idle state, verify operating + * voltage and set the card inready state. + */ +static unsigned int mmc_boot_init_card( struct mmc_boot_host* host, + struct mmc_boot_card* card ) +{ + unsigned int mmc_retry = 0; + unsigned int mmc_return = MMC_BOOT_E_SUCCESS; + + /* basic check */ + if( ( host == NULL ) || ( card == NULL ) ) + { + return MMC_BOOT_E_INVAL; + } + + /* 1. Card Reset - CMD0 */ + mmc_return = mmc_boot_reset_cards(); + if( mmc_return != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.:%d: Failure resetting MMC cards!\n", mmc_return); + return mmc_return; + } + + /* 2. Card Initialization process */ + + /* Send CMD1 to identify and reject cards that do not match host's VDD range + profile. Cards sends its OCR register in response. + */ + mmc_retry = 0; + do + { + mmc_return = mmc_boot_send_op_cond( host, card ); + /* Card returns busy status. We'll retry again! */ + if( mmc_return == MMC_BOOT_E_CARD_BUSY ) + { + mmc_retry++; + mdelay(200); + continue; + } + else if( mmc_return == MMC_BOOT_E_SUCCESS ) + { + break; + } + else + { + dprintf(CRITICAL, "Error No. %d: Failure Initializing MMC Card!\n", + mmc_return ); + + /* Check for sD card */ + mmc_return = mmc_boot_sd_init_card(card); + return mmc_return; + } + }while( mmc_retry < host->cmd_retry ); + + /* If card still returned busy status we are out of luck. + * Card cannot be initialized */ + if( mmc_return == MMC_BOOT_E_CARD_BUSY ) + { + dprintf(CRITICAL, "Error No. %d: Card has busy status set. \ + Initialization not completed\n", mmc_return ); + return MMC_BOOT_E_CARD_BUSY; + } + return MMC_BOOT_E_SUCCESS; +} + + +static unsigned int mmc_boot_set_sd_bus_width(struct mmc_boot_card* card, unsigned int width) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + unsigned int sd_reg; + + mmc_ret = mmc_boot_send_app_cmd(card->rca); + + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* Send ACMD6 to set bus width */ + cmd.cmd_index = ACMD6_SET_BUS_WIDTH; + /* 10 => 4 bit wide */ + cmd.argument = (1<<1); + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1; + + mmc_ret = mmc_boot_send_command(&cmd); + + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + /* set MCI_CLK accordingly */ + sd_reg = readl( MMC_BOOT_MCI_CLK ); + sd_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE; + if ( width == MMC_BOOT_BUS_WIDTH_1_BIT ) + { + sd_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT; + } + else if (width == MMC_BOOT_BUS_WIDTH_4_BIT ) + { + sd_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT; + } + else if (width == MMC_BOOT_BUS_WIDTH_8_BIT ) + { + sd_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT; + } + writel( sd_reg, MMC_BOOT_MCI_CLK ); + + mdelay(10); // Giving some time to card to stabilize. + + return MMC_BOOT_E_SUCCESS; +} + +static unsigned int mmc_boot_set_sd_hs(struct mmc_boot_host* host, struct mmc_boot_card* card) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret; + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* Send CMD6 function mode 1 to set high speed */ + /* Not using mode 0 to read current consumption */ + cmd.cmd_index = CMD6_SWITCH_FUNC; + cmd.argument = MMC_BOOT_SD_SWITCH_HS; + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1; + + mmc_ret = mmc_boot_send_command(&cmd); + + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + mdelay(1); + +#ifdef PLATFORM_MSM8X60 + mmc_ret = mmc_boot_enable_clock( host, MMC_CLK_48MHZ); +#else + mmc_ret = mmc_boot_enable_clock( host, MMC_CLK_50MHZ); +#endif + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return MMC_BOOT_E_CLK_ENABLE_FAIL; + } + + return MMC_BOOT_E_SUCCESS; +} + +/* + * Performs initialization and identification of all the MMC cards connected + * to the host. + */ + +static unsigned int mmc_boot_init_and_identify_cards( struct mmc_boot_host* host, struct mmc_boot_card* card ) +{ + unsigned int mmc_return = MMC_BOOT_E_SUCCESS; + unsigned int status; + + /* Basic check */ + if( host == NULL ) + { + return MMC_BOOT_E_INVAL; + } + + /* Initialize MMC card structure */ + card->status = MMC_BOOT_STATUS_INACTIVE; + card->rd_block_len = MMC_BOOT_RD_BLOCK_LEN; + card->wr_block_len = MMC_BOOT_WR_BLOCK_LEN; + + /* Start initialization process (CMD0 & CMD1) */ + mmc_return = mmc_boot_init_card( host, card ); + if( mmc_return != MMC_BOOT_E_SUCCESS ) + { + return mmc_return; + } + + /* Start card identification process (CMD2, CMD3 & CMD9)*/ + mmc_return = mmc_boot_identify_card( host, card ); + if( mmc_return != MMC_BOOT_E_SUCCESS ) + { + return mmc_return; + } + + /* Select the card (CMD7) */ + mmc_return = mmc_boot_select_card( card, card->rca ); + if( mmc_return != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure selecting the Card with RCA: %x\n", + mmc_return, card->rca ); + return mmc_return; + } + + if(card->type == MMC_BOOT_TYPE_SDHC || card->type == MMC_BOOT_TYPE_STD_SD) + { + mmc_return = mmc_boot_set_sd_hs(host, card); + if(mmc_return != MMC_BOOT_E_SUCCESS) + { + return mmc_return; + } + + mmc_return = mmc_boot_set_sd_bus_width(card, MMC_BOOT_BUS_WIDTH_4_BIT); + if(mmc_return != MMC_BOOT_E_SUCCESS) + { + return mmc_return; + } + } + else + { + /* set interface speed */ + mmc_return = mmc_boot_adjust_interface_speed( host, card ); + if( mmc_return != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Error adjusting interface speed!\n", + mmc_return ); + return mmc_return; + } + + /* enable wide bus */ + mmc_return = mmc_boot_set_bus_width( card, MMC_BOOT_BUS_WIDTH_4_BIT ); + if( mmc_return != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "Error No.%d: Failure to set wide bus for Card(RCA:%x)\n", + mmc_return, card->rca ); + return mmc_return; + } + } + + /* Just checking whether we're in TRAN state after changing speed and bus width */ + mmc_return = mmc_boot_get_card_status(card, 1, &status); + if(mmc_return != MMC_BOOT_E_SUCCESS) + { + return mmc_return; + } + + if(MMC_BOOT_CARD_STATUS(status) != MMC_BOOT_TRAN_STATE) + return MMC_BOOT_E_FAILURE; + + return MMC_BOOT_E_SUCCESS; +} + +/* + * Read MBR from MMC card and fill partition table. + */ +static unsigned int mmc_boot_read_MBR(void) +{ + unsigned char buffer[MMC_BOOT_RD_BLOCK_LEN]; + unsigned int dtype; + unsigned int dfirstsec; + unsigned int EBR_first_sec; + unsigned int EBR_current_sec; + int ret = 0; + int idx, i; + + /* Print out the MBR first */ + ret = mmc_boot_read_from_card( &mmc_host, &mmc_card, 0, \ + MMC_BOOT_RD_BLOCK_LEN, \ + (unsigned int *)buffer); + if (ret) + { + return ret; + } + + /* Check to see if signature exists */ + if ((buffer[TABLE_SIGNATURE] != 0x55) || \ + (buffer[TABLE_SIGNATURE + 1] != 0xAA)) + { + return -1; + } + + /* Print out the first 4 partition */ + idx = TABLE_ENTRY_0; + for (i = 0; i < 4; i++) + { + mbr[mmc_partition_count].dstatus = \ + buffer[idx + i * TABLE_ENTRY_SIZE + OFFSET_STATUS]; + mbr[mmc_partition_count].dtype = \ + buffer[idx + i * TABLE_ENTRY_SIZE + OFFSET_TYPE]; + mbr[mmc_partition_count].dfirstsec = \ + GET_LWORD_FROM_BYTE(&buffer[idx + \ + i * TABLE_ENTRY_SIZE + \ + OFFSET_FIRST_SEC]); + mbr[mmc_partition_count].dsize = \ + GET_LWORD_FROM_BYTE(&buffer[idx + \ + i * TABLE_ENTRY_SIZE + \ + OFFSET_SIZE]); + dtype = mbr[mmc_partition_count].dtype; + dfirstsec = mbr[mmc_partition_count].dfirstsec; + mbr_fill_name(&mbr[mmc_partition_count], \ + mbr[mmc_partition_count].dtype); + mmc_partition_count++; + if (mmc_partition_count == MAX_PARTITIONS) + return ret; + } + + /* See if the last partition is EBR, if not, parsing is done */ + if (dtype != 0x05) + { + return ret; + } + + EBR_first_sec = dfirstsec; + EBR_current_sec = dfirstsec; + + ret = mmc_boot_read_from_card( &mmc_host, &mmc_card, \ + (EBR_first_sec * 512), \ + MMC_BOOT_RD_BLOCK_LEN, \ + (unsigned int *)buffer); + if (ret) + { + return ret; + } + /* Loop to parse the EBR */ + for (i = 0;; i++) + { + if ((buffer[TABLE_SIGNATURE] != 0x55) || (buffer[TABLE_SIGNATURE + 1] != 0xAA)) + { + break; + } + mbr[mmc_partition_count].dstatus = \ + buffer[TABLE_ENTRY_0 + OFFSET_STATUS]; + mbr[mmc_partition_count].dtype = \ + buffer[TABLE_ENTRY_0 + OFFSET_TYPE]; + mbr[mmc_partition_count].dfirstsec = \ + GET_LWORD_FROM_BYTE(&buffer[TABLE_ENTRY_0 + \ + OFFSET_FIRST_SEC]) + \ + EBR_current_sec; + mbr[mmc_partition_count].dsize = \ + GET_LWORD_FROM_BYTE(&buffer[TABLE_ENTRY_0 + \ + OFFSET_SIZE]); + mbr_fill_name(&(mbr[mmc_partition_count]), \ + mbr[mmc_partition_count].dtype); + mmc_partition_count++; + if (mmc_partition_count == MAX_PARTITIONS) + return ret; + + dfirstsec = GET_LWORD_FROM_BYTE(&buffer[TABLE_ENTRY_1 + OFFSET_FIRST_SEC]); + if(dfirstsec == 0) + { + /* Getting to the end of the EBR tables */ + break; + } + /* More EBR to follow - read in the next EBR sector */ + ret = mmc_boot_read_from_card( &mmc_host, &mmc_card, \ + ((EBR_first_sec + dfirstsec) * 512), \ + MMC_BOOT_RD_BLOCK_LEN, \ + (unsigned int *)buffer); + if (ret) + { + return ret; + } + EBR_current_sec = EBR_first_sec + dfirstsec; + } + return ret; +} + + +/* + * Entry point to MMC boot process + */ +unsigned int mmc_boot_main(unsigned char slot, unsigned int base) +{ + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + + memset( (struct mmc_boot_host*)&mmc_host, 0, sizeof( struct mmc_boot_host ) ); + memset( (struct mmc_boot_card*)&mmc_card, 0, sizeof(struct mmc_boot_card) ); + + mmc_slot = slot; + mmc_boot_mci_base = base; + +#ifndef PLATFORM_MSM8X60 + /* Waiting for modem to come up */ + while (readl(MSM_SHARED_BASE + 0x14) != 1); +#endif + /* Initialize necessary data structure and enable/set clock and power */ + dprintf(INFO," Initializing MMC host data structure and clock!\n" ); + mmc_ret = mmc_boot_init( &mmc_host ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "MMC Boot: Error Initializing MMC Card!!!\n" ); + return MMC_BOOT_E_FAILURE; + } + + /* Initialize and identify cards connected to host */ + mmc_ret = mmc_boot_init_and_identify_cards( &mmc_host, &mmc_card ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "MMC Boot: Failure detecting MMC card!!!\n" ); + return MMC_BOOT_E_FAILURE; + } + + mmc_display_csd(); + mmc_display_ext_csd(); + + /* Read MBR of the card */ + mmc_ret = mmc_boot_read_MBR(); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + dprintf(CRITICAL, "MMC Boot: MBR read failed!\n" ); + return MMC_BOOT_E_FAILURE; + } + + return MMC_BOOT_E_SUCCESS; +} + +/* + * MMC write function + */ +unsigned int mmc_write (unsigned long long data_addr, unsigned int data_len, unsigned int* in) +{ + int val = 0; + unsigned int write_size = ((unsigned)(0xFFFFFF/512))*512; + unsigned offset = 0; + unsigned int *sptr = in; + + if(data_len % 512) + data_len = ROUND_TO_PAGE(data_len, 511); + + while(data_len > write_size) + { + val = mmc_boot_write_to_card( &mmc_host, &mmc_card, \ + data_addr + offset, \ + write_size, sptr); + if(val) + { + return val; + } + + sptr += (write_size/sizeof(unsigned)); + offset += write_size; + data_len -= write_size; + } + if (data_len) + { + val = mmc_boot_write_to_card( &mmc_host, &mmc_card, \ + data_addr + offset, \ + data_len, sptr); + } + return val; +} + +/* + * MMC read function + */ +unsigned int mmc_read (unsigned long long data_addr, unsigned int* out, unsigned int data_len) +{ + int val = 0; + val = mmc_boot_read_from_card( &mmc_host, &mmc_card, data_addr, data_len, out); + return val; +} + +/* + * Fill name for android partition found. + */ +static void mbr_fill_name (struct mbr_entry *mbr_ent, unsigned int type) +{ + switch(type) + { + memset(mbr_ent->name, 0, 64); + case MMC_MODEM_TYPE: + case MMC_MODEM_TYPE2: + /* if there are more than one with type "modem", mmc_ptn_offset will return the first one */ + memcpy(mbr_ent->name,"modem",5); + break; + case MMC_SBL1_TYPE: + memcpy(mbr_ent->name,"sbl1",4); + break; + case MMC_SBL2_TYPE: + memcpy(mbr_ent->name,"sbl2",4); + break; + case MMC_SBL3_TYPE: + memcpy(mbr_ent->name,"sbl3",4); + break; + case MMC_RPM_TYPE: + memcpy(mbr_ent->name,"rpm",3); + break; + case MMC_TZ_TYPE: + memcpy(mbr_ent->name,"tz",2); + break; + case MMC_ABOOT_TYPE: + memcpy(mbr_ent->name,"aboot",5); + break; + case MMC_BOOT_TYPE: + memcpy(mbr_ent->name,"boot",4); + break; + case MMC_MODEM_ST1_TYPE: + memcpy(mbr_ent->name,"modem_st1",9); + break; + case MMC_MODEM_ST2_TYPE: + memcpy(mbr_ent->name,"modem_st2",9); + break; + case MMC_EFS2_TYPE: + memcpy(mbr_ent->name,"efs2",4); + break; + case MMC_USERDATA_TYPE: + strcpy((char *)mbr_ent->name,(const char *)ext3_partitions[ext3_count]); + ext3_count++; + break; + case MMC_RECOVERY_TYPE: + memcpy(mbr_ent->name,"recovery",8); + break; + }; +} + +/* + * Returns offset of given partition + */ +unsigned long long mmc_ptn_offset (unsigned char * name) +{ + unsigned n; + for(n = 0; n < mmc_partition_count; n++) { + if(!strcmp((const char *)mbr[n].name, (const char *)name)) { + return (mbr[n].dfirstsec * MMC_BOOT_RD_BLOCK_LEN); + } + } + return 0; +} + +unsigned long long mmc_ptn_size (unsigned char * name) +{ + unsigned n; + for(n = 0; n < mmc_partition_count; n++) { + if(!strcmp((const char *)mbr[n].name, (const char *)name)) { + return (mbr[n].dsize * MMC_BOOT_RD_BLOCK_LEN); + } + } + return 0; +} + +/* + * Function to read registers from MMC or SD card + */ +static unsigned int mmc_boot_read_reg(struct mmc_boot_card *card, + unsigned int data_len, + unsigned int command, unsigned int addr, + unsigned int *out) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + unsigned int mmc_status = 0; + unsigned int* mmc_ptr = out; + unsigned int mmc_count = 0; + unsigned int mmc_reg = 0; + unsigned int xfer_type; + unsigned int read_error; + + /* Set the FLOW_ENA bit of MCI_CLK register to 1 */ + mmc_reg = readl( MMC_BOOT_MCI_CLK ); + mmc_reg |= MMC_BOOT_MCI_CLK_ENA_FLOW ; + writel( mmc_reg, MMC_BOOT_MCI_CLK ); + + /* Write data timeout period to MCI_DATA_TIMER register. */ + /* Data timeout period should be in card bus clock periods */ + mmc_reg =0xFFFFFFFF; + writel( mmc_reg, MMC_BOOT_MCI_DATA_TIMER ); + writel( data_len, MMC_BOOT_MCI_DATA_LENGTH ); + + /* Set appropriate fields and write the MCI_DATA_CTL register. */ + /* Set ENABLE bit to 1 to enable the data transfer. */ + mmc_reg = MMC_BOOT_MCI_DATA_ENABLE | MMC_BOOT_MCI_DATA_DIR | (data_len << MMC_BOOT_MCI_BLKSIZE_POS); + writel( mmc_reg, MMC_BOOT_MCI_DATA_CTL ); + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + cmd.cmd_index = command; + cmd.argument = addr; + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1; + + /* send command */ + mmc_ret = mmc_boot_send_command( &cmd ); + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \ + MMC_BOOT_MCI_STAT_DATA_TIMEOUT | \ + MMC_BOOT_MCI_STAT_RX_OVRRUN; + + do + { + mmc_ret = MMC_BOOT_E_SUCCESS; + mmc_status = readl( MMC_BOOT_MCI_STATUS ); + + if( mmc_status & read_error ) + { + mmc_ret = mmc_boot_status_error(mmc_status); + break; + } + + if( mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL ) + { + unsigned read_count = 1; + if ( mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL) + { + read_count = MMC_BOOT_MCI_HFIFO_COUNT; + } + + for (int i=0; irca ); + return mmc_ret; + } + + return MMC_BOOT_E_SUCCESS; +} + +/* + * Function to set/clear power-on write protection for the user area partitions + */ +static unsigned int mmc_boot_set_clr_power_on_wp_user(struct mmc_boot_card* card, + unsigned int addr, + unsigned int size, + unsigned char set_clear_wp) +{ + struct mmc_boot_command cmd; + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + unsigned int wp_group_size, loop_count; + unsigned int status; + + memset( (struct mmc_boot_command *)&cmd, 0, + sizeof(struct mmc_boot_command) ); + + /* Disabling PERM_WP for USER AREA (CMD6) */ + mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE, + MMC_BOOT_EXT_USER_WP, + MMC_BOOT_US_PERM_WP_DIS); + + if(mmc_ret != MMC_BOOT_E_SUCCESS) + { + return mmc_ret; + } + + /* Sending CMD13 to check card status */ + do + { + mmc_ret = mmc_boot_get_card_status( card, 0 ,&status); + if(MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_TRAN_STATE) + break; + } while( (mmc_ret == MMC_BOOT_E_SUCCESS) && + (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE)); + + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + mmc_ret = mmc_boot_send_ext_cmd (card,ext_csd_buf); + + if(mmc_ret != MMC_BOOT_E_SUCCESS) + { + return mmc_ret; + } + + /* Make sure power-on write protection for user area is not disabled + and permanent write protection for user area is not enabled */ + + if((IS_BIT_SET_EXT_CSD(MMC_BOOT_EXT_USER_WP, MMC_BOOT_US_PERM_WP_EN)) || + (IS_BIT_SET_EXT_CSD(MMC_BOOT_EXT_USER_WP, MMC_BOOT_US_PWR_WP_DIS))) + { + return MMC_BOOT_E_FAILURE; + } + + if(ext_csd_buf[MMC_BOOT_EXT_ERASE_GROUP_DEF]) + { + /* wp_group_size = 512KB * HC_WP_GRP_SIZE * HC_ERASE_GRP_SIZE. + Getting write protect group size in sectors here. */ + + wp_group_size = (512*1024) * ext_csd_buf[MMC_BOOT_EXT_HC_WP_GRP_SIZE] * + ext_csd_buf[MMC_BOOT_EXT_HC_ERASE_GRP_SIZE] / + MMC_BOOT_WR_BLOCK_LEN; + } + else + { + /* wp_group_size = (WP_GRP_SIZE + 1) * (ERASE_GRP_SIZE + 1) + * (ERASE_GRP_MULT + 1). + This is defined as the number of write blocks directly */ + + wp_group_size = (card->csd.erase_grp_size + 1) * + (card->csd.erase_grp_mult + 1) * + (card->csd.wp_grp_size + 1); + } + + if(wp_group_size == 0) + { + return MMC_BOOT_E_FAILURE; + } + + /* Setting POWER_ON_WP for USER AREA (CMD6) */ + + mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE, + MMC_BOOT_EXT_USER_WP, + MMC_BOOT_US_PWR_WP_EN); + + if(mmc_ret != MMC_BOOT_E_SUCCESS) + { + return mmc_ret; + } + + /* Sending CMD13 to check card status */ + do + { + mmc_ret = mmc_boot_get_card_status( card, 0 ,&status); + if(MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_TRAN_STATE) + break; + } while( (mmc_ret == MMC_BOOT_E_SUCCESS) && + (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE)); + + if( mmc_ret != MMC_BOOT_E_SUCCESS ) + { + return mmc_ret; + } + + /* Calculating the loop count for sending SET_WRITE_PROTECT (CMD28) + or CLEAR_WRITE_PROTECT (CMD29). + We are write protecting the partitions in blocks of write protect + group sizes only */ + + if(size % wp_group_size) + { + loop_count = (size / wp_group_size) + 1; + } + else + { + loop_count = (size / wp_group_size); + } + + if(set_clear_wp) + cmd.cmd_index = CMD28_SET_WRITE_PROTECT; + else + cmd.cmd_index = CMD29_CLEAR_WRITE_PROTECT; + + cmd.cmd_type = MMC_BOOT_CMD_ADDRESS; + cmd.resp_type = MMC_BOOT_RESP_R1B; + + for(int i=0;i +#include +#include +#include +#include +#include +#include + +#include "dmov.h" + +#define VERBOSE 0 +#define VERIFY_WRITE 0 + +static void *flash_spare; +static void *flash_data; +void platform_config_interleaved_mode_gpios(void); + +typedef struct dmov_ch dmov_ch; +struct dmov_ch +{ + volatile unsigned cmd; + volatile unsigned result; + volatile unsigned status; + volatile unsigned config; +}; + +static void dmov_prep_ch(dmov_ch *ch, unsigned id) +{ + ch->cmd = DMOV_CMD_PTR(id); + ch->result = DMOV_RSLT(id); + ch->status = DMOV_STATUS(id); + ch->config = DMOV_CONFIG(id); +} + +#define SRC_CRCI_NAND_CMD CMD_SRC_CRCI(DMOV_NAND_CRCI_CMD) +#define DST_CRCI_NAND_CMD CMD_DST_CRCI(DMOV_NAND_CRCI_CMD) +#define SRC_CRCI_NAND_DATA CMD_SRC_CRCI(DMOV_NAND_CRCI_DATA) +#define DST_CRCI_NAND_DATA CMD_DST_CRCI(DMOV_NAND_CRCI_DATA) + +#define NAND_CFG0_RAW 0xA80420C0 +#define NAND_CFG1_RAW 0x5045D + +static unsigned CFG0, CFG1; +static unsigned CFG0_M, CFG1_M; +static unsigned CFG0_A, CFG1_A; + +#define CFG1_WIDE_FLASH (1U << 1) + +#define paddr(n) ((unsigned) (n)) + +static int dmov_exec_cmdptr(unsigned id, unsigned *ptr) +{ + dmov_ch ch; + unsigned n; + + dmov_prep_ch(&ch, id); + + writel(DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(paddr(ptr)), ch.cmd); + + while(!(readl(ch.status) & DMOV_STATUS_RSLT_VALID)) ; + + n = readl(ch.status); + while(DMOV_STATUS_RSLT_COUNT(n)) { + n = readl(ch.result); + if(n != 0x80000002) { + dprintf(CRITICAL, "ERROR: result: %x\n", n); + dprintf(CRITICAL, "ERROR: flush: %x %x %x %x\n", + readl(DMOV_FLUSH0(DMOV_NAND_CHAN)), + readl(DMOV_FLUSH1(DMOV_NAND_CHAN)), + readl(DMOV_FLUSH2(DMOV_NAND_CHAN)), + readl(DMOV_FLUSH3(DMOV_NAND_CHAN))); + } + n = readl(ch.status); + } + + return 0; +} + +static struct flash_info flash_info; +static unsigned flash_pagesize = 0; +static int interleaved_mode = 0; + +struct flash_identification { + unsigned flash_id; + unsigned mask; + unsigned density; + unsigned widebus; + unsigned pagesize; + unsigned blksize; + unsigned oobsize; + unsigned onenand; +}; + +static struct flash_identification supported_flash[] = +{ + /* Flash ID ID Mask Density(MB) Wid Pgsz Blksz oobsz onenand Manuf */ + {0x00000000, 0xFFFFFFFF, 0, 0, 0, 0, 0, 0}, /*ONFI*/ + {0x1500aaec, 0xFF00FFFF, (256<<20), 0, 2048, (2048<<6), 64, 0}, /*Sams*/ + {0x5500baec, 0xFF00FFFF, (256<<20), 1, 2048, (2048<<6), 64, 0}, /*Sams*/ + {0x1500aa98, 0xFFFFFFFF, (256<<20), 0, 2048, (2048<<6), 64, 0}, /*Tosh*/ + {0x5500ba98, 0xFFFFFFFF, (256<<20), 1, 2048, (2048<<6), 64, 0}, /*Tosh*/ + {0xd580b12c, 0xFFFFFFFF, (256<<20), 1, 2048, (2048<<6), 64, 0}, /*Micr*/ + {0x5590bc2c, 0xFFFFFFFF, (512<<20), 1, 2048, (2048<<6), 64, 0}, /*Micr*/ + {0x1580aa2c, 0xFFFFFFFF, (256<<20), 0, 2048, (2048<<6), 64, 0}, /*Micr*/ + {0x1590aa2c, 0xFFFFFFFF, (256<<20), 0, 2048, (2048<<6), 64, 0}, /*Micr*/ + {0x1590ac2c, 0xFFFFFFFF, (512<<20), 0, 2048, (2048<<6), 64, 0}, /*Micr*/ + {0x5580baad, 0xFFFFFFFF, (256<<20), 1, 2048, (2048<<6), 64, 0}, /*Hynx*/ + {0x5510baad, 0xFFFFFFFF, (256<<20), 1, 2048, (2048<<6), 64, 0}, /*Hynx*/ + {0x004000ec, 0xFFFFFFFF, (256<<20), 0, 2048, (2048<<6), 64, 1}, /*Sams*/ + {0x005c00ec, 0xFFFFFFFF, (256<<20), 0, 2048, (2048<<6), 64, 1}, /*Sams*/ + {0x005800ec, 0xFFFFFFFF, (256<<20), 0, 2048, (2048<<6), 64, 1}, /*Sams*/ + {0x6600bcec, 0xFF00FFFF, (512<<20), 1, 4096, (4096<<6), 128, 0}, /*Sams*/ + /* Note: Width flag is 0 for 8 bit Flash and 1 for 16 bit flash */ + /* Note: Onenand flag is 0 for NAND Flash and 1 for OneNAND flash */ + /* Note: The First row will be filled at runtime during ONFI probe */ +}; +static void set_nand_configuration(char type) +{ + if(type == TYPE_MODEM_PARTITION) + { + CFG0 = CFG0_M; + CFG1 = CFG1_M; + } + else + { + CFG0 = CFG0_A; + CFG1 = CFG1_A; + } +} + +static void flash_nand_read_id(dmov_s *cmdlist, unsigned *ptrlist) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + unsigned *data = ptrlist + 4; + + data[0] = 0 | 4; + data[1] = NAND_CMD_FETCH_ID; + data[2] = 1; + data[3] = 0; + data[4] = 0; + data[5] = 0; + data[6] = 0; + data[7] = 0xAAD40000; /* Default value for CFG0 for reading device id */ + + /* Read NAND device id */ + cmd[0].cmd = 0 | CMD_OCB; + cmd[0].src = paddr(&data[7]); + cmd[0].dst = NAND_DEV0_CFG0; + cmd[0].len = 4; + + cmd[1].cmd = 0; + cmd[1].src = NAND_SFLASHC_BURST_CFG; + cmd[1].dst = paddr(&data[5]); + cmd[1].len = 4; + + cmd[2].cmd = 0; + cmd[2].src = paddr(&data[6]); + cmd[2].dst = NAND_SFLASHC_BURST_CFG; + cmd[2].len = 4; + + cmd[3].cmd = 0; + cmd[3].src = paddr(&data[0]); + cmd[3].dst = NAND_FLASH_CHIP_SELECT; + cmd[3].len = 4; + + cmd[4].cmd = DST_CRCI_NAND_CMD; + cmd[4].src = paddr(&data[1]); + cmd[4].dst = NAND_FLASH_CMD; + cmd[4].len = 4; + + cmd[5].cmd = 0; + cmd[5].src = paddr(&data[2]); + cmd[5].dst = NAND_EXEC_CMD; + cmd[5].len = 4; + + cmd[6].cmd = SRC_CRCI_NAND_DATA; + cmd[6].src = NAND_FLASH_STATUS; + cmd[6].dst = paddr(&data[3]); + cmd[6].len = 4; + + cmd[7].cmd = 0; + cmd[7].src = NAND_READ_ID; + cmd[7].dst = paddr(&data[4]); + cmd[7].len = 4; + + cmd[8].cmd = CMD_OCU | CMD_LC; + cmd[8].src = paddr(&data[5]); + cmd[8].dst = NAND_SFLASHC_BURST_CFG; + cmd[8].len = 4; + + ptr[0] = (paddr(cmd) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "status: %x\n", data[3]); +#endif + + flash_info.id = data[4]; + flash_info.vendor = data[4] & 0xff; + flash_info.device = (data[4] >> 8) & 0xff; + return; +} + +static int flash_nand_block_isbad(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + unsigned *data = ptrlist + 4; + char buf[4]; + unsigned cwperpage; + + cwperpage = (flash_pagesize >> 9); + + /* Check first page of this block */ + if(page & 63) + page = page - (page & 63); + + /* Check bad block marker */ + data[0] = NAND_CMD_PAGE_READ; /* command */ + + /* addr0 */ + if (CFG1 & CFG1_WIDE_FLASH) + data[1] = (page << 16) | ((528*(cwperpage-1)) >> 1); + else + data[1] = (page << 16) | (528*(cwperpage-1)); + + data[2] = (page >> 16) & 0xff; /* addr1 */ + data[3] = 0 | 4; /* chipsel */ + data[4] = NAND_CFG0_RAW & ~(7U << 6); /* cfg0 */ + data[5] = NAND_CFG1_RAW | (CFG1 & CFG1_WIDE_FLASH); /* cfg1 */ + data[6] = 1; + data[7] = CLEAN_DATA_32; /* flash status */ + data[8] = CLEAN_DATA_32; /* buf status */ + + cmd[0].cmd = DST_CRCI_NAND_CMD | CMD_OCB; + cmd[0].src = paddr(&data[0]); + cmd[0].dst = NAND_FLASH_CMD; + cmd[0].len = 16; + + cmd[1].cmd = 0; + cmd[1].src = paddr(&data[4]); + cmd[1].dst = NAND_DEV0_CFG0; + cmd[1].len = 8; + + cmd[2].cmd = 0; + cmd[2].src = paddr(&data[6]); + cmd[2].dst = NAND_EXEC_CMD; + cmd[2].len = 4; + + cmd[3].cmd = SRC_CRCI_NAND_DATA; + cmd[3].src = NAND_FLASH_STATUS; + cmd[3].dst = paddr(&data[7]); + cmd[3].len = 8; + + cmd[4].cmd = CMD_OCU | CMD_LC; + cmd[4].src = NAND_FLASH_BUFFER + (flash_pagesize - (528*(cwperpage-1))); + cmd[4].dst = paddr(&buf); + cmd[4].len = 4; + + ptr[0] = (paddr(cmd) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "status: %x\n", data[7]); +#endif + + /* we fail if there was an operation error, a mpu error, or the + ** erase success bit was not set. + */ + if(data[7] & 0x110) return -1; + + /* Check for bad block marker byte */ + if (CFG1 & CFG1_WIDE_FLASH) { + if (buf[0] != 0xFF || buf[1] != 0xFF) + return 1; + } else { + if (buf[0] != 0xFF) + return 1; + } + + return 0; +} + +static int flash_nand_block_isbad_interleave(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + unsigned *data = ptrlist + 4; + char buf01[4]; + char buf10[4]; + unsigned cwperpage; + + cwperpage = ((flash_pagesize >> 1)>> 9); + + /* Check first page of this block */ + if(page & 63) + page = page - (page & 63); + + /* Check bad block marker */ + data[0] = NAND_CMD_PAGE_READ; /* command */ + + /* addr0 */ + if (CFG1 & CFG1_WIDE_FLASH) + data[1] = (page << 16) | ((528*(cwperpage-1)) >> 1); + else + data[1] = (page << 16) | (528*(cwperpage-1)); + + data[2] = (page >> 16) & 0xff; /* addr1 */ + data[3] = 0 | 4; /* chipsel CS0 */ + data[4] = 0 | 5; /* chipsel CS1 */ + data[5] = NAND_CFG0_RAW & ~(7U << 6); /* cfg0 */ + data[6] = NAND_CFG1_RAW | (CFG1 & CFG1_WIDE_FLASH); /* cfg1 */ + data[7] = 1; + data[8] = CLEAN_DATA_32; /* NC01 flash status */ + data[9] = CLEAN_DATA_32; /* NC01 buf01 status */ + data[10] = CLEAN_DATA_32; /* NC10 flash status */ + data[11] = CLEAN_DATA_32; /* NC10 buf10 status */ + data[12] = 0x00000A3C; /* adm_mux_data_ack_req_nc01 */ + data[13] = 0x0000053C; /* adm_mux_cmd_ack_req_nc01 */ + data[14] = 0x00000F28; /* adm_mux_data_ack_req_nc10 */ + data[15] = 0x00000F14; /* adm_mux_cmd_ack_req_nc10 */ + data[16] = 0x00000FC0; /* adm_default_mux */ + data[17] = 0x00000805; /* enable CS1 */ + data[18] = 0x00000801; /* disable CS1 */ + + /* enable CS1 */ + cmd[0].cmd = 0; + cmd[0].src = paddr(data[17]); + cmd[0].dst = EBI2_CHIP_SELECT_CFG0; + cmd[0].len = 4; + + /* Reading last code word from NC01 */ + /* 0xF14 */ + cmd[1].cmd = 0; + cmd[1].src = paddr(data[15]); + cmd[1].dst = EBI2_NAND_ADM_MUX; + cmd[1].len = 4; + + cmd[2].cmd = DST_CRCI_NAND_CMD; + cmd[2].src = paddr(&data[0]); + cmd[2].dst = NC01(NAND_FLASH_CMD); + cmd[2].len = 16; + + cmd[3].cmd = 0; + cmd[3].src = paddr(&data[5]); + cmd[3].dst = NC01(NAND_DEV0_CFG0); + cmd[3].len = 8; + + cmd[4].cmd = 0; + cmd[4].src = paddr(&data[7]); + cmd[4].dst = NC01(NAND_EXEC_CMD); + cmd[4].len = 4; + + /* 0xF28 */ + cmd[5].cmd = 0; + cmd[5].src = paddr(data[14]); + cmd[5].dst = EBI2_NAND_ADM_MUX; + cmd[5].len = 4; + + cmd[6].cmd = SRC_CRCI_NAND_DATA; + cmd[6].src = NC01(NAND_FLASH_STATUS); + cmd[6].dst = paddr(&data[8]); + cmd[6].len = 8; + + cmd[7].cmd = 0; + cmd[7].src = NC01(NAND_FLASH_BUFFER) + (flash_pagesize - (528*(cwperpage-1))); + cmd[7].dst = paddr(&buf01); + cmd[7].len = 4; + + /* Reading last code word from NC10 */ + /* 0x53C */ + cmd[8].cmd = 0; + cmd[8].src = paddr(data[13]); + cmd[8].dst = EBI2_NAND_ADM_MUX; + cmd[8].len = 4; + + cmd[9].cmd = DST_CRCI_NAND_CMD; + cmd[9].src = paddr(&data[0]); + cmd[9].dst = NC10(NAND_FLASH_CMD); + cmd[9].len = 12; + + cmd[10].cmd = 0; + cmd[10].src = paddr(&data[4]); + cmd[10].dst = NC10(NAND_FLASH_CHIP_SELECT); + cmd[10].len = 4; + + cmd[11].cmd = 0; + cmd[11].src = paddr(&data[5]); + cmd[11].dst = NC10(NAND_DEV1_CFG0); + cmd[11].len = 8; + + cmd[12].cmd = 0; + cmd[12].src = paddr(&data[7]); + cmd[12].dst = NC10(NAND_EXEC_CMD); + cmd[12].len = 4; + + /* 0xA3C */ + cmd[13].cmd = 0; + cmd[13].src = paddr(data[12]); + cmd[13].dst = EBI2_NAND_ADM_MUX; + cmd[13].len = 4; + + cmd[14].cmd = SRC_CRCI_NAND_DATA; + cmd[14].src = NC10(NAND_FLASH_STATUS); + cmd[14].dst = paddr(&data[10]); + cmd[14].len = 8; + + cmd[15].cmd = 0; + cmd[15].src = NC10(NAND_FLASH_BUFFER) + (flash_pagesize - (528*(cwperpage-1))); + cmd[15].dst = paddr(&buf10); + cmd[15].len = 4; + + cmd[16].cmd = 0; + cmd[16].src = paddr(&data[16]); + cmd[16].dst = EBI2_NAND_ADM_MUX; + cmd[16].len = 4; + + /* setting default value */ + cmd[17].cmd = CMD_OCU | CMD_LC; + cmd[17].src = paddr(&data[18]); + cmd[17].dst = EBI2_CHIP_SELECT_CFG0; + cmd[17].len = 4; + + ptr[0] = (paddr(cmd) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "NC01 status: %x\n", data[8]); + dprintf(INFO, "NC10 status: %x\n", data[10]); +#endif + + /* we fail if there was an operation error, a mpu error, or the + ** erase success bit was not set. + */ + if((data[8] & 0x110) || (data[10] & 0x110)) return -1; + + /* Check for bad block marker byte */ + if (CFG1 & CFG1_WIDE_FLASH) { + if ((buf01[0] != 0xFF || buf01[1] != 0xFF) || + (buf10[0] != 0xFF || buf10[1] != 0xFF)) + return 1; + } else { + if (buf01[0] != 0xFF || buf10[0] != 0xFF) + return 1; + } + + return 0; +} + +static int flash_nand_erase_block(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + unsigned *data = ptrlist + 4; + int isbad = 0; + + /* only allow erasing on block boundaries */ + if(page & 63) return -1; + + /* Check for bad block and erase only if block is not marked bad */ + isbad = flash_nand_block_isbad(cmdlist, ptrlist, page); + + if (isbad) { + dprintf(INFO, "skipping @ %d (bad block)\n", page >> 6); + return -1; + } + + /* Erase block */ + data[0] = NAND_CMD_BLOCK_ERASE; + data[1] = page; + data[2] = 0; + data[3] = 0 | 4; + data[4] = 1; + data[5] = 0xeeeeeeee; + data[6] = CFG0 & (~(7 << 6)); /* CW_PER_PAGE = 0 */ + data[7] = CFG1; + data[8] = 0x00000020; + data[9] = 0x000000C0; + + cmd[0].cmd = DST_CRCI_NAND_CMD | CMD_OCB; + cmd[0].src = paddr(&data[0]); + cmd[0].dst = NAND_FLASH_CMD; + cmd[0].len = 16; + + cmd[1].cmd = 0; + cmd[1].src = paddr(&data[6]); + cmd[1].dst = NAND_DEV0_CFG0; + cmd[1].len = 8; + + cmd[2].cmd = 0; + cmd[2].src = paddr(&data[4]); + cmd[2].dst = NAND_EXEC_CMD; + cmd[2].len = 4; + + cmd[3].cmd = SRC_CRCI_NAND_DATA; + cmd[3].src = NAND_FLASH_STATUS; + cmd[3].dst = paddr(&data[5]); + cmd[3].len = 4; + + cmd[4].cmd = 0; + cmd[4].src = paddr(&data[8]); + cmd[4].dst = NAND_FLASH_STATUS; + cmd[4].len = 4; + + cmd[5].cmd = CMD_OCU | CMD_LC; + cmd[5].src = paddr(&data[9]); + cmd[5].dst = NAND_READ_STATUS; + cmd[5].len = 4; + + ptr[0] = (paddr(cmd) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "status: %x\n", data[5]); +#endif + + /* we fail if there was an operation error, a mpu error, or the + ** erase success bit was not set. + */ + if(data[5] & 0x110) return -1; + if(!(data[5] & 0x80)) return -1; + + return 0; +} + +static int flash_nand_erase_block_interleave(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + unsigned *data = ptrlist + 4; + int isbad = 0; + + /* only allow erasing on block boundaries */ + if(page & 63) return -1; + + /* Check for bad block and erase only if block is not marked bad */ + isbad = flash_nand_block_isbad(cmdlist, ptrlist, page); + + if (isbad) { + dprintf(INFO, "skipping @ %d (bad block)\n", page >> 6); + return -1; + } + + /* Erase block */ + data[0] = NAND_CMD_BLOCK_ERASE; + data[1] = page; + data[2] = 0; + data[3] = 0 | 4; /* chipselect CS0 */ + data[4] = 0 | 5; /* chipselect CS1 */ + data[5] = 1; + data[6] = 0xeeeeeeee; + data[7] = 0xeeeeeeee; + data[8] = CFG0 & (~(7 << 6)); /* CW_PER_PAGE = 0 */ + data[9] = CFG1; + data[10] = 0x00000A3C; /* adm_mux_data_ack_req_nc01 */ + data[11] = 0x0000053C; /* adm_mux_cmd_ack_req_nc01 */ + data[12] = 0x00000F28; /* adm_mux_data_ack_req_nc10 */ + data[13] = 0x00000F14; /* adm_mux_cmd_ack_req_nc10 */ + data[14] = 0x00000FC0; /* adm_default_mux */ + data[15] = 0x00000805; /* enable CS1 */ + data[16] = 0x00000801; /* disable CS1 */ + + /* enable CS1 */ + cmd[0].cmd = 0 | CMD_OCB; + cmd[0].src = paddr(data[15]); + cmd[0].dst = EBI2_CHIP_SELECT_CFG0; + cmd[0].len = 4; + + /* Reading last code word from NC01 */ + /* 0xF14 */ + cmd[1].cmd = 0; + cmd[1].src = paddr(data[13]); + cmd[1].dst = EBI2_NAND_ADM_MUX; + cmd[1].len = 4; + + cmd[2].cmd = DST_CRCI_NAND_CMD; + cmd[2].src = paddr(&data[0]); + cmd[2].dst = NC01(NAND_FLASH_CMD); + cmd[2].len = 16; + + cmd[3].cmd = 0; + cmd[3].src = paddr(&data[8]); + cmd[3].dst = NC01(NAND_DEV0_CFG0); + cmd[3].len = 8; + + cmd[4].cmd = 0; + cmd[4].src = paddr(&data[5]); + cmd[4].dst = NC01(NAND_EXEC_CMD); + cmd[4].len = 4; + + /* 0xF28 */ + cmd[5].cmd = 0; + cmd[5].src = paddr(data[12]); + cmd[5].dst = EBI2_NAND_ADM_MUX; + cmd[5].len = 4; + + cmd[6].cmd = SRC_CRCI_NAND_DATA; + cmd[6].src = NC01(NAND_FLASH_STATUS); + cmd[6].dst = paddr(&data[6]); + cmd[6].len = 4; + + /* Reading last code word from NC10 */ + /* 0x53C */ + cmd[7].cmd = 0; + cmd[7].src = paddr(data[11]); + cmd[7].dst = EBI2_NAND_ADM_MUX; + cmd[7].len = 4; + + cmd[8].cmd = DST_CRCI_NAND_CMD; + cmd[8].src = paddr(&data[0]); + cmd[8].dst = NC10(NAND_FLASH_CMD); + cmd[8].len = 12; + + cmd[9].cmd = 0; + cmd[9].src = paddr(&data[4]); + cmd[9].dst = NC10(NAND_FLASH_CHIP_SELECT); + cmd[9].len = 4; + + cmd[10].cmd = 0; + cmd[10].src = paddr(&data[8]); + cmd[10].dst = NC10(NAND_DEV1_CFG0); + cmd[10].len = 8; + + cmd[11].cmd = 0; + cmd[11].src = paddr(&data[5]); + cmd[11].dst = NC10(NAND_EXEC_CMD); + cmd[11].len = 4; + + /* 0xA3C */ + cmd[12].cmd = 0; + cmd[12].src = paddr(data[10]); + cmd[12].dst = EBI2_NAND_ADM_MUX; + cmd[12].len = 4; + + cmd[13].cmd = SRC_CRCI_NAND_DATA; + cmd[13].src = NC10(NAND_FLASH_STATUS); + cmd[13].dst = paddr(&data[7]); + cmd[13].len = 4; + + /* adm default mux state */ + /* 0xFCO */ + cmd[14].cmd = 0; + cmd[14].src = paddr(data[14]); + cmd[14].dst = EBI2_NAND_ADM_MUX; + cmd[14].len = 4; + + /* disable CS1 */ + cmd[15].cmd = CMD_OCU | CMD_LC; + cmd[15].src = paddr(data[16]); + cmd[15].dst = EBI2_CHIP_SELECT_CFG0; + cmd[15].len = 4; + + ptr[0] = (paddr(cmd) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "NC01 status: %x\n", data[6]); + dprintf(INFO, "NC10 status: %x\n", data[7]); +#endif + + /* we fail if there was an operation error, a mpu error, or the + ** erase success bit was not set. + */ + if(data[6] & 0x110 || data[7] & 0x110) return -1; + if(!(data[6] & 0x80) || !(data[7] & 0x80)) return -1; + + return 0; +} + +struct data_flash_io { + unsigned cmd; + unsigned addr0; + unsigned addr1; + unsigned chipsel; + unsigned cfg0; + unsigned cfg1; + unsigned exec; + unsigned ecc_cfg; + unsigned ecc_cfg_save; + unsigned clrfstatus; + unsigned clrrstatus; + struct { + unsigned flash_status; + unsigned buffer_status; + } result[8]; +}; + +struct interleave_data_flash_io { + uint32_t cmd; + uint32_t addr0; + uint32_t addr1; + uint32_t chipsel_cs0; + uint32_t chipsel_cs1; + uint32_t cfg0; + uint32_t cfg1; + uint32_t exec; + uint32_t ecc_cfg; + uint32_t ecc_cfg_save; + uint32_t ebi2_chip_select_cfg0; + uint32_t adm_mux_data_ack_req_nc01; + uint32_t adm_mux_cmd_ack_req_nc01; + uint32_t adm_mux_data_ack_req_nc10; + uint32_t adm_mux_cmd_ack_req_nc10; + uint32_t adm_default_mux; + uint32_t default_ebi2_chip_select_cfg0; + struct { + uint32_t flash_status; + } result[16]; +}; + +static int _flash_nand_read_page(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page, void *_addr, void *_spareaddr) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + struct data_flash_io *data = (void*) (ptrlist + 4); + unsigned addr = (unsigned) _addr; + unsigned spareaddr = (unsigned) _spareaddr; + unsigned n; + int isbad = 0; + unsigned cwperpage; + cwperpage = (flash_pagesize >> 9); + + /* Check for bad block and read only from a good block */ + isbad = flash_nand_block_isbad(cmdlist, ptrlist, page); + if (isbad) + return -2; + + data->cmd = NAND_CMD_PAGE_READ_ECC; + data->addr0 = page << 16; + data->addr1 = (page >> 16) & 0xff; + data->chipsel = 0 | 4; /* flash0 + undoc bit */ + + /* GO bit for the EXEC register */ + data->exec = 1; + + data->cfg0 = CFG0; + data->cfg1 = CFG1; + + data->ecc_cfg = 0x203; + + /* save existing ecc config */ + cmd->cmd = CMD_OCB; + cmd->src = NAND_EBI2_ECC_BUF_CFG; + cmd->dst = paddr(&data->ecc_cfg_save); + cmd->len = 4; + cmd++; + + for(n = 0; n < cwperpage; n++) { + /* write CMD / ADDR0 / ADDR1 / CHIPSEL regs in a burst */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NAND_FLASH_CMD; + cmd->len = ((n == 0) ? 16 : 4); + cmd++; + + if (n == 0) { + /* block on cmd ready, set configuration */ + cmd->cmd = 0; + cmd->src = paddr(&data->cfg0); + cmd->dst = NAND_DEV0_CFG0; + cmd->len = 8; + cmd++; + + /* set our ecc config */ + cmd->cmd = 0; + cmd->src = paddr(&data->ecc_cfg); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + cmd++; + } + /* kick the execute register */ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NAND_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* block on data ready, then read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_FLASH_STATUS; + cmd->dst = paddr(&data->result[n]); + cmd->len = 8; + cmd++; + + /* read data block */ + cmd->cmd = 0; + cmd->src = NAND_FLASH_BUFFER; + cmd->dst = addr + n * 516; + cmd->len = ((n < (cwperpage -1 )) ? 516 : (512 - ((cwperpage - 1) << 2))); + cmd++; + } + + /* read extra data */ + cmd->cmd = 0; + cmd->src = NAND_FLASH_BUFFER + 500; + cmd->dst = spareaddr; + cmd->len = 16; + cmd++; + + /* restore saved ecc config */ + cmd->cmd = CMD_OCU | CMD_LC; + cmd->src = paddr(&data->ecc_cfg_save); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + + ptr[0] = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "read page %d: status: %x %x %x %x\n", + page, data[5], data[6], data[7], data[8]); + for(n = 0; n < 4; n++) { + ptr = (unsigned*)(addr + 512 * n); + dprintf(INFO, "data%d: %x %x %x %x\n", n, ptr[0], ptr[1], ptr[2], ptr[3]); + ptr = (unsigned*)(spareaddr + 16 * n); + dprintf(INFO, "spare data%d %x %x %x %x\n", n, ptr[0], ptr[1], ptr[2], ptr[3]); + } +#endif + + /* if any of the writes failed (0x10), or there was a + ** protection violation (0x100), we lose + */ + for(n = 0; n < cwperpage; n++) { + if (data->result[n].flash_status & 0x110) { + return -1; + } + } + + return 0; +} + +static int flash_nand_read_page_interleave(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page, void *_addr, void *_spareaddr) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + struct interleave_data_flash_io *data = (void*) (ptrlist + 4); + unsigned addr = (unsigned) _addr; + unsigned spareaddr = (unsigned) _spareaddr; + unsigned n; + int isbad = 0; + unsigned cwperpage; + cwperpage = (flash_pagesize >> 9); + + /* Check for bad block and read only from a good block */ + isbad = flash_nand_block_isbad(cmdlist, ptrlist, page); + if (isbad) + return -2; + + data->cmd = NAND_CMD_PAGE_READ_ECC; + data->addr0 = page << 16; + data->addr1 = (page >> 16) & 0xff; + data->chipsel_cs0 = 0 | 4; /* flash0 + undoc bit */ + data->chipsel_cs1 = 0 | 5; /* flash0 + undoc bit */ + data->ebi2_chip_select_cfg0 = 0x00000805; + data->adm_mux_data_ack_req_nc01 = 0x00000A3C; + data->adm_mux_cmd_ack_req_nc01 = 0x0000053C; + data->adm_mux_data_ack_req_nc10 = 0x00000F28; + data->adm_mux_cmd_ack_req_nc10 = 0x00000F14; + data->adm_default_mux = 0x00000FC0; + data->default_ebi2_chip_select_cfg0 = 0x00000801; + + /* GO bit for the EXEC register */ + data->exec = 1; + + data->cfg0 = CFG0; + data->cfg1 = CFG1; + + data->ecc_cfg = 0x203; + + for (n = 0; n < cwperpage; n++) { + /* flash + buffer status return words */ + data->result[n].flash_status = 0xeeeeeeee; + + if (n == 0) { + /* enable CS1 */ + cmd->cmd = CMD_OCB; + cmd->src = paddr(&data->ebi2_chip_select_cfg0); + cmd->dst = EBI2_CHIP_SELECT_CFG0; + cmd->len = 4; + cmd++; + + /* save existing ecc config */ + cmd->cmd = 0; + cmd->src = NAND_EBI2_ECC_BUF_CFG; + cmd->dst = paddr(&data->ecc_cfg_save); + cmd->len = 4; + cmd++; + + /* NC01, NC10 --> ADDR0/ADDR1 */ + cmd->cmd = 0; + cmd->src = paddr(&data->addr0); + cmd->dst = NC11(NAND_ADDR0); + cmd->len = 8; + cmd++; + + /* Select the CS0, + * for NC01! + */ + cmd->cmd = 0; + cmd->src = paddr(&data->chipsel_cs0); + cmd->dst = NC01(NAND_FLASH_CHIP_SELECT); + cmd->len = 4; + cmd++; + + /* Select the CS1, + * for NC10! + */ + cmd->cmd = 0; + cmd->src = paddr(&data->chipsel_cs1); + cmd->dst = NC10(NAND_FLASH_CHIP_SELECT); + cmd->len = 4; + cmd++; + + cmd->cmd = 0; + cmd->src = paddr(&data->cfg0); + cmd->dst = NC01(NAND_DEV0_CFG0); + cmd->len = 8; + cmd++; + + /* config DEV1 for CS1 */ + cmd->cmd = 0; + cmd->src = paddr(&data->cfg0); + cmd->dst = NC10(NAND_DEV1_CFG0); + cmd->len = 8; + cmd++; + + cmd->cmd = 0; + cmd->src = paddr(&data->ecc_cfg); + cmd->dst = NC11(NAND_EBI2_ECC_BUF_CFG); + cmd->len = 4; + cmd++; + + /* if 'only' the last code word */ + if (n == cwperpage - 1) { + /* MASK CMD ACK/REQ --> NC01 (0x53C)*/ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_cmd_ack_req_nc01); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* CMD */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NC10(NAND_FLASH_CMD); + cmd->len = 4; + cmd++; + + /* kick the execute register for NC10 */ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NC10(NAND_EXEC_CMD); + cmd->len = 4; + cmd++; + + /* MASK DATA ACK/REQ --> NC01 (0xA3C)*/ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_data_ack_req_nc01); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* block on data ready from NC10, then + * read the status register + */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NC10(NAND_FLASH_STATUS); + cmd->dst = paddr(&data->result[n]); + /* NAND_FLASH_STATUS + + * NAND_BUFFER_STATUS + */ + cmd->len = 4; + cmd++; + } else { + /* MASK CMD ACK/REQ --> NC10 (0xF14)*/ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_cmd_ack_req_nc10); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* CMD */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NC01(NAND_FLASH_CMD); + cmd->len = 4; + cmd++; + + /* kick the execute register for NC01*/ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NC01(NAND_EXEC_CMD); + cmd->len = 4; + cmd++; + } + } + + + if (n % 2 == 0) { + /* MASK CMD ACK/REQ --> NC01 (0x53C)*/ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_cmd_ack_req_nc01); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* CMD */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NC10(NAND_FLASH_CMD); + cmd->len = 4; + cmd++; + + /* kick the execute register for NC10 */ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NC10(NAND_EXEC_CMD); + cmd->len = 4; + cmd++; + + /* MASK DATA ACK/REQ --> NC10 (0xF28)*/ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_data_ack_req_nc10); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* block on data ready from NC01, then + * read the status register + */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NC01(NAND_FLASH_STATUS); + cmd->dst = paddr(&data->result[n]); + /* NAND_FLASH_STATUS + + * NAND_BUFFER_STATUS + */ + cmd->len = 4; + cmd++; + + /* read data block */ + cmd->cmd = 0; + cmd->src = NC01(NAND_FLASH_BUFFER); + cmd->dst = addr + n * 516; + cmd->len = ((n < (cwperpage -1 )) ? 516 : (512 - ((cwperpage - 1) << 2))); + cmd++; + } else { + if (n != cwperpage - 1) { + /* MASK CMD ACK/REQ --> + * NC10 (0xF14) + */ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_cmd_ack_req_nc10); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* CMD */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NC01(NAND_FLASH_CMD); + cmd->len = 4; + cmd++; + + /* EXEC */ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NC01(NAND_EXEC_CMD); + cmd->len = 4; + cmd++; + + /* MASK DATA ACK/REQ --> + * NC01 (0xA3C) + */ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_data_ack_req_nc01); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* block on data ready from NC10 + * then read the status register + */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NC10(NAND_FLASH_STATUS); + cmd->dst = paddr(&data->result[n]); + /* NAND_FLASH_STATUS + + * NAND_BUFFER_STATUS + */ + cmd->len = 4; + cmd++; + } else { + /* MASK DATA ACK/REQ -> + * NC01 (0xA3C) + */ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_data_ack_req_nc01); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* block on data ready from NC10 + * then read the status register + */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NC10(NAND_FLASH_STATUS); + cmd->dst = paddr(&data->result[n]); + /* NAND_FLASH_STATUS + + * NAND_BUFFER_STATUS + */ + cmd->len = 4; + cmd++; + } + /* read data block */ + cmd->cmd = 0; + cmd->src = NC10(NAND_FLASH_BUFFER); + cmd->dst = addr + n * 516; + cmd->len = ((n < (cwperpage -1 )) ? 516 : (512 - ((cwperpage - 1) << 2))); + cmd++; + + if (n == (cwperpage - 1)) { + /* Use NC10 for reading the + * last codeword!!! + */ + cmd->cmd = 0; + cmd->src = NC10(NAND_FLASH_BUFFER) + + (512 - ((cwperpage -1) << 2)); + cmd->dst = spareaddr; + cmd->len = 16; + cmd++; + } + } + } + /* restore saved ecc config */ + cmd->cmd = CMD_OCU | CMD_LC; + cmd->src = paddr(&data->ecc_cfg_save); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + + /* ADM --> Default mux state (0xFC0) */ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_default_mux); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* disable CS1 */ + cmd->cmd = 0; + cmd->src = paddr(&data->default_ebi2_chip_select_cfg0); + cmd->dst = EBI2_CHIP_SELECT_CFG0; + cmd->len = 4; + cmd++; + + ptr[0] = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "read page %d: status: %x %x %x %x %x %x %x %x \ + %x %x %x %x %x %x %x %x \n", page, + data->result[0].flash_status[0], + data->result[1].flash_status[1], + data->result[2].flash_status[2], + data->result[3].flash_status[3], + data->result[4].flash_status[4], + data->result[5].flash_status[5], + data->result[6].flash_status[6], + data->result[7].flash_status[7], + data->result[8].flash_status[8], + data->result[9].flash_status[9], + data->result[10].flash_status[10], + data->result[11].flash_status[11], + data->result[12].flash_status[12], + data->result[13].flash_status[13], + data->result[14].flash_status[14], + data->result[15].flash_status[15]); + + for(n = 0; n < 4; n++) { + ptr = (unsigned*)(addr + 512 * n); + dprintf(INFO, "data%d: %x %x %x %x\n", n, ptr[0], ptr[1], ptr[2], ptr[3]); + ptr = (unsigned*)(spareaddr + 16 * n); + dprintf(INFO, "spare data%d %x %x %x %x\n", n, ptr[0], ptr[1], ptr[2], ptr[3]); + } +#endif + + /* if any of the writes failed (0x10), or there was a + ** protection violation (0x100), we lose + */ + for(n = 0; n < cwperpage; n++) { + if (data->result[n].flash_status & 0x110) { + return -1; + } + } + + return 0; +} + +static int _flash_nand_write_page(dmov_s *cmdlist, unsigned *ptrlist, unsigned page, + const void *_addr, const void *_spareaddr, unsigned raw_mode) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + struct data_flash_io *data = (void*) (ptrlist + 4); + unsigned addr = (unsigned) _addr; + unsigned spareaddr = (unsigned) _spareaddr; + unsigned n; + unsigned cwperpage; + cwperpage = (flash_pagesize >> 9); + unsigned modem_partition = 0; + if (CFG0 == CFG0_M) + { + modem_partition = 1; + } + + data->cmd = NAND_CMD_PRG_PAGE; + data->addr0 = page << 16; + data->addr1 = (page >> 16) & 0xff; + data->chipsel = 0 | 4; /* flash0 + undoc bit */ + data->clrfstatus = 0x00000020; + data->clrrstatus = 0x000000C0; + + if (!raw_mode){ + data->cfg0 = CFG0; + data->cfg1 = CFG1; + }else{ + data->cfg0 = (NAND_CFG0_RAW & ~(7 << 6)) |((cwperpage-1) << 6); + data->cfg1 = NAND_CFG1_RAW | (CFG1 & CFG1_WIDE_FLASH); + } + + /* GO bit for the EXEC register */ + data->exec = 1; + + if (modem_partition) + data->ecc_cfg = 0x1FF; + else + data->ecc_cfg = 0x203; + + /* save existing ecc config */ + cmd->cmd = CMD_OCB; + cmd->src = NAND_EBI2_ECC_BUF_CFG; + cmd->dst = paddr(&data->ecc_cfg_save); + cmd->len = 4; + cmd++; + + for(n = 0; n < cwperpage; n++) { + /* write CMD / ADDR0 / ADDR1 / CHIPSEL regs in a burst */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NAND_FLASH_CMD; + cmd->len = ((n == 0) ? 16 : 4); + cmd++; + + if (n == 0) { + /* set configuration */ + cmd->cmd = 0; + cmd->src = paddr(&data->cfg0); + cmd->dst = NAND_DEV0_CFG0; + cmd->len = 8; + cmd++; + + /* set our ecc config */ + cmd->cmd = 0; + cmd->src = paddr(&data->ecc_cfg); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + cmd++; + } + + /* write data block */ + cmd->cmd = 0; + cmd->dst = NAND_FLASH_BUFFER; + if (!raw_mode){ + if(modem_partition){ + cmd->src = addr + n * 512; + cmd->len = 512; + }else{ + cmd->src = addr + n * 516; + cmd->len = ((n < (cwperpage - 1)) ? 516 : (512 - ((cwperpage - 1) << 2))); + } + }else{ + cmd->src = addr; + cmd->len = 528; + } + cmd++; + + if ((n == (cwperpage - 1)) && (!raw_mode) && (!modem_partition)) { + /* write extra data */ + cmd->cmd = 0; + cmd->src = spareaddr; + cmd->dst = NAND_FLASH_BUFFER + (512 - ((cwperpage - 1) << 2)); + cmd->len = (cwperpage << 2); + cmd++; + } + + /* kick the execute register */ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NAND_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* block on data ready, then read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_FLASH_STATUS; + cmd->dst = paddr(&data->result[n]); + cmd->len = 8; + cmd++; + + cmd->cmd = 0; + cmd->src = paddr(&data->clrfstatus); + cmd->dst = NAND_FLASH_STATUS; + cmd->len = 4; + cmd++; + + cmd->cmd = 0; + cmd->src = paddr(&data->clrrstatus); + cmd->dst = NAND_READ_STATUS; + cmd->len = 4; + cmd++; + } + + /* restore saved ecc config */ + cmd->cmd = CMD_OCU | CMD_LC; + cmd->src = paddr(&data->ecc_cfg_save); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + + ptr[0] = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "write page %d: status: %x %x %x %x\n", + page, data[5], data[6], data[7], data[8]); +#endif + + /* if any of the writes failed (0x10), or there was a + ** protection violation (0x100), or the program success + ** bit (0x80) is unset, we lose + */ + for(n = 0; n < cwperpage; n++) { + if(data->result[n].flash_status & 0x110) return -1; + if(!(data->result[n].flash_status & 0x80)) return -1; + } + +#if VERIFY_WRITE + n = _flash_read_page(cmdlist, ptrlist, page, flash_data, + flash_data + 2048); + if (n != 0) + return -1; + if (memcmp(flash_data, _addr, 2048) || + memcmp(flash_data + 2048, _spareaddr, 16)) { + dprintf(CRITICAL, "verify error @ page %d\n", page); + return -1; + } +#endif + return 0; +} + +static int flash_nand_write_page_interleave(dmov_s *cmdlist, unsigned *ptrlist, unsigned page, + const void *_addr, const void *_spareaddr, unsigned raw_mode) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + struct interleave_data_flash_io *data = (void*) (ptrlist + 4); + unsigned addr = (unsigned) _addr; + unsigned spareaddr = (unsigned) _spareaddr; + unsigned n; + unsigned cwperpage, cwcount; + + cwperpage = (flash_pagesize >> 9) * 2; /* double for interleave mode */ + cwcount = (cwperpage << 1); + + data->cmd = NAND_CMD_PRG_PAGE; + data->addr0 = page << 16; + data->addr1 = (page >> 16) & 0xff; + data->chipsel_cs0 = 0 | 4; /* flash0 + undoc bit */ + data->chipsel_cs1 = 0 | 5; /* flash0 + undoc bit */ + data->ebi2_chip_select_cfg0 = 0x00000805; + data->adm_mux_data_ack_req_nc01 = 0x00000A3C; + data->adm_mux_cmd_ack_req_nc01 = 0x0000053C; + data->adm_mux_data_ack_req_nc10 = 0x00000F28; + data->adm_mux_cmd_ack_req_nc10 = 0x00000F14; + data->adm_default_mux = 0x00000FC0; + data->default_ebi2_chip_select_cfg0 = 0x00000801; + + if (!raw_mode){ + data->cfg0 = CFG0; + data->cfg1 = CFG1; + }else{ + data->cfg0 = (NAND_CFG0_RAW & ~(7 << 6)) |((cwcount-1) << 6); + data->cfg1 = NAND_CFG1_RAW | (CFG1 & CFG1_WIDE_FLASH); + } + + /* GO bit for the EXEC register */ + data->exec = 1; + data->ecc_cfg = 0x203; + + for (n = 0; n < cwperpage; n++) { + /* status return words */ + data->result[n].flash_status = 0xeeeeeeee; + + if (n == 0) { + /* enable CS1 */ + cmd->cmd = CMD_OCB; + cmd->src = paddr(&data->ebi2_chip_select_cfg0); + cmd->dst = EBI2_CHIP_SELECT_CFG0; + cmd->len = 4; + cmd++; + + /* save existing ecc config */ + cmd->cmd = 0; + cmd->src = NC11(NAND_EBI2_ECC_BUF_CFG); + cmd->dst = paddr(&data->ecc_cfg_save); + cmd->len = 4; + cmd++; + + cmd->cmd = 0; + cmd->src = paddr(&data->ecc_cfg); + cmd->dst = NC11(NAND_EBI2_ECC_BUF_CFG); + cmd->len = 4; + cmd++; + + cmd->cmd = 0; + cmd->src = paddr(&data->addr0); + cmd->dst = NC11(NAND_ADDR0); + cmd->len = 8; + cmd++; + + /* enable CS0 */ + cmd->cmd = 0; + cmd->src = paddr(&data->chipsel_cs0); + cmd->dst = NC01(NAND_FLASH_CHIP_SELECT); + cmd->len = 4; + cmd++; + + /* enable CS1 */ + cmd->cmd = 0; + cmd->src = paddr(&data->chipsel_cs1); + cmd->dst = NC10(NAND_FLASH_CHIP_SELECT); + cmd->len = 4; + cmd++; + + cmd->cmd = 0; + cmd->src =paddr(&data->cfg0); + cmd->dst = NC01(NAND_DEV0_CFG0); + cmd->len = 8; + cmd++; + + /* config CFG1 for CS1 */ + cmd->cmd = 0; + cmd->src =paddr(&data->cfg0); + cmd->dst = NC10(NAND_DEV1_CFG0); + cmd->len = 8; + cmd++; + } + + if (n % 2 == 0) { + /* MASK CMD ACK/REQ --> NC10 (0xF14)*/ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_cmd_ack_req_nc10); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* CMD */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NC01(NAND_FLASH_CMD); + cmd->len = 4; + cmd++; + } else { + /* MASK CMD ACK/REQ --> NC01 (0x53C)*/ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_cmd_ack_req_nc01); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* CMD */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NC10(NAND_FLASH_CMD); + cmd->len = 4; + cmd++; + } + + cmd->cmd = 0; + if (!raw_mode){ + cmd->src = addr + n * 516; + cmd->len = ((n < (cwperpage - 1)) ? 516 : (512 - ((cwperpage - 1) << 2))); + }else{ + cmd->src = addr; + cmd->len = 528; + } + + if (n % 2 == 0) + cmd->dst = NC01(NAND_FLASH_BUFFER); + else + cmd->dst = NC10(NAND_FLASH_BUFFER); + cmd++; + + if ((n == (cwperpage - 1)) && (!raw_mode)) { + /* write extra data */ + cmd->cmd = 0; + cmd->src = spareaddr; + cmd->dst = NC10(NAND_FLASH_BUFFER) + (512 - ((cwperpage - 1) << 2)); + cmd->len = (cwperpage << 2); + cmd++; + } + + if (n % 2 == 0) { + /* kick the NC01 execute register */ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NC01(NAND_EXEC_CMD); + cmd->len = 4; + cmd++; + if (n != 0) { + /* MASK DATA ACK/REQ --> NC01 (0xA3C)*/ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_data_ack_req_nc01); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* block on data ready from NC10, then + * read the status register + */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NC10(NAND_FLASH_STATUS); + cmd->dst = paddr(&data->result[n-1]); + cmd->len = 4; + cmd++; + } + } else { + /* kick the execute register */ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NC10(NAND_EXEC_CMD); + cmd->len = 4; + cmd++; + + /* MASK DATA ACK/REQ --> NC10 (0xF28)*/ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_data_ack_req_nc10); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* block on data ready from NC01, then + * read the status register + */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NC01(NAND_FLASH_STATUS); + cmd->dst = paddr(&data->result[n-1]); + cmd->len = 4; + cmd++; + } + } + + /* MASK DATA ACK/REQ --> NC01 (0xA3C)*/ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_mux_data_ack_req_nc01); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* we should process outstanding request */ + /* block on data ready, then + * read the status register + */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NC10(NAND_FLASH_STATUS); + cmd->dst = paddr(&data->result[n-1]); + cmd->len = 4; + cmd++; + + /* restore saved ecc config */ + cmd->cmd = 0; + cmd->src = paddr(&data->ecc_cfg_save); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + + /* MASK DATA ACK/REQ --> NC01 (0xFC0)*/ + cmd->cmd = 0; + cmd->src = paddr(&data->adm_default_mux); + cmd->dst = EBI2_NAND_ADM_MUX; + cmd->len = 4; + cmd++; + + /* disable CS1 */ + cmd->cmd = CMD_OCU | CMD_LC; + cmd->src = paddr(&data->default_ebi2_chip_select_cfg0); + cmd->dst = EBI2_CHIP_SELECT_CFG0; + cmd->len = 4; + cmd++; + + ptr[0] = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE +dprintf(INFO, "write page %d: status: %x %x %x %x %x %x %x %x \ + %x %x %x %x %x %x %x %x \n", page, + data->result[0].flash_status[0], + data->result[1].flash_status[1], + data->result[2].flash_status[2], + data->result[3].flash_status[3], + data->result[4].flash_status[4], + data->result[5].flash_status[5], + data->result[6].flash_status[6], + data->result[7].flash_status[7], + data->result[8].flash_status[8], + data->result[9].flash_status[9], + data->result[10].flash_status[10], + data->result[11].flash_status[11], + data->result[12].flash_status[12], + data->result[13].flash_status[13], + data->result[14].flash_status[14], + data->result[15].flash_status[15]); +#endif + + /* if any of the writes failed (0x10), or there was a + ** protection violation (0x100), or the program success + ** bit (0x80) is unset, we lose + */ + for(n = 0; n < cwperpage; n++) { + if(data->result[n].flash_status & 0x110) return -1; + if(!(data->result[n].flash_status & 0x80)) return -1; + } + +#if VERIFY_WRITE + n = _flash_read_page(cmdlist, ptrlist, page, flash_data, + flash_data + 2048); + if (n != 0) + return -1; + if (memcmp(flash_data, _addr, 2048) || + memcmp(flash_data + 2048, _spareaddr, 16)) { + dprintf(CRITICAL, "verify error @ page %d\n", page); + return -1; + } +#endif + return 0; +} + +char empty_buf[528]; +static int flash_nand_mark_badblock(dmov_s *cmdlist, unsigned *ptrlist, unsigned page) +{ + memset(empty_buf,0,528); + /* Going to first page of the block */ + if(page & 63) + page = page - (page & 63); + return _flash_nand_write_page(cmdlist, ptrlist, page, empty_buf, 0, 1); +} + +unsigned nand_cfg0; +unsigned nand_cfg1; + +static int flash_nand_read_config(dmov_s *cmdlist, unsigned *ptrlist) +{ + static unsigned CFG0_TMP, CFG1_TMP; + cmdlist[0].cmd = CMD_OCB; + cmdlist[0].src = NAND_DEV0_CFG0; + cmdlist[0].dst = paddr(&CFG0_TMP); + cmdlist[0].len = 4; + + cmdlist[1].cmd = CMD_OCU | CMD_LC; + cmdlist[1].src = NAND_DEV0_CFG1; + cmdlist[1].dst = paddr(&CFG1_TMP); + cmdlist[1].len = 4; + + *ptrlist = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptrlist); + + if((CFG0_TMP == 0) || (CFG1_TMP == 0)) { + return -1; + } + + CFG0_A = CFG0_TMP; + CFG1_A = CFG1_TMP; + if (flash_info.type == FLASH_16BIT_NAND_DEVICE) { + nand_cfg1 |= CFG1_WIDE_FLASH; + } + dprintf(INFO, "nandcfg: %x %x (initial)\n", CFG0, CFG1); + + CFG0_A = (((flash_pagesize >> 9) - 1) << 6) /* 4/8 cw/pg for 2/4k */ + | (516 << 9) /* 516 user data bytes */ + | (10 << 19) /* 10 parity bytes */ + | (5 << 27) /* 5 address cycles */ + | (0 << 30) /* Do not read status before data */ + | (1 << 31) /* Send read cmd */ + /* 0 spare bytes for 16 bit nand or 1 spare bytes for 8 bit */ + | ((nand_cfg1 & CFG1_WIDE_FLASH) ? (0 << 23) : (1 << 23)); + CFG1_A = (0 << 0) /* Enable ecc */ + | (7 << 2) /* 8 recovery cycles */ + | (0 << 5) /* Allow CS deassertion */ + | ((flash_pagesize - (528 * ((flash_pagesize >> 9) - 1)) + 1) << 6) /* Bad block marker location */ + | (0 << 16) /* Bad block in user data area */ + | (2 << 17) /* 6 cycle tWB/tRB */ + | (nand_cfg1 & CFG1_WIDE_FLASH); /* preserve wide flash flag */ + + dprintf(INFO, "nandcfg(Apps): %x %x (used)\n", CFG0_A, CFG1_A); + + CFG0_M = CFG0_TMP; + CFG1_M = CFG1_TMP; + if (flash_info.type == FLASH_16BIT_NAND_DEVICE) { + nand_cfg1 |= CFG1_WIDE_FLASH; + } + CFG0_M = (((flash_pagesize >> 9) - 1) << 6) /* 4/8 cw/pg for 2/4k */ + | (512 << 9) /* 512 user data bytes */ + | (10 << 19) /* 10 parity bytes */ + | (5 << 27) /* 5 address cycles */ + | (0 << 30) /* Do not read status before data */ + | (1 << 31) /* Send read cmd */ + | ((nand_cfg1 & CFG1_WIDE_FLASH) ? (4 << 23) : (5 << 23)); + CFG1_M = (0 << 0) /* Enable ecc */ + | (7 << 2) /* 8 recovery cycles */ + | (0 << 5) /* Allow CS deassertion */ + | ((flash_pagesize - (528 * ((flash_pagesize >> 9) - 1)) + 1) << 6) /* Bad block marker location */ + | (0 << 16) /* Bad block in user data area */ + | (2 << 17) /* 6 cycle tWB/tRB */ + | (nand_cfg1 & CFG1_WIDE_FLASH); /* preserve wide flash flag */ + dprintf(INFO, "nandcfg(Modem): %x %x (used)\n", CFG0_M, CFG1_M); + return 0; +} + +/* OneNAND programming functions */ + +static void flash_onenand_read_id(dmov_s *cmdlist, unsigned *ptrlist) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + unsigned *data = ptrlist + 4; + + data[0] = SFLASH_BCFG; + data[1] = SFLASH_PREPCMD(8, 0, 0, NAND_SFCMD_DATXS, NAND_SFCMD_ASYNC, NAND_SFCMD_REGRD); + data[2] = (ONENAND_DEVICE_ID << 16) | (ONENAND_MANUFACTURER_ID); + data[3] = (ONENAND_DATA_BUFFER_SIZE << 16) | (ONENAND_VERSION_ID); + data[4] = (ONENAND_AMOUNT_OF_BUFFERS << 16) | (ONENAND_BOOT_BUFFER_SIZE); + data[5] = (CLEAN_DATA_16 << 16) | (ONENAND_TECHNOLOGY); + data[6] = CLEAN_DATA_32; //status + data[7] = CLEAN_DATA_32; //register read + data[8] = CLEAN_DATA_32; //register read + data[9] = CLEAN_DATA_32; //register read + data[10] = CLEAN_DATA_32; //register read + data[11] = 1; + data[12] = 0 | 4; + + /* Setup controller in SFLASH mode */ + cmd[0].cmd = 0 | CMD_OCB; + cmd[0].src = paddr(&data[0]); + cmd[0].dst = NAND_SFLASHC_BURST_CFG; + cmd[0].len = 4; + + /* Enable data mover for controller */ + cmd[1].cmd = 0; + cmd[1].src = paddr(&data[12]); + cmd[1].dst = NAND_FLASH_CHIP_SELECT; + cmd[1].len = 4; + + /* Setup SFLASHC_CMD with xfers in async mode */ + cmd[2].cmd = DST_CRCI_NAND_CMD; + cmd[2].src = paddr(&data[1]); + cmd[2].dst = NAND_SFLASHC_CMD; + cmd[2].len = 4; + + /* Setup to read device information */ + cmd[3].cmd = 0; + cmd[3].src = paddr(&data[2]); + cmd[3].dst = NAND_ADDR0; + cmd[3].len = 8; + + cmd[4].cmd = 0; + cmd[4].src = paddr(&data[4]); + cmd[4].dst = NAND_ADDR2; + cmd[4].len = 8; + + /* Set execute bit */ + cmd[5].cmd = 0; + cmd[5].src = paddr(&data[11]); + cmd[5].dst = NAND_SFLASHC_EXEC_CMD; + cmd[5].len = 4; + + /* Check status */ + cmd[6].cmd = SRC_CRCI_NAND_DATA; + cmd[6].src = NAND_SFLASHC_STATUS; + cmd[6].dst = paddr(&data[6]); + cmd[6].len = 4; + + /* Read result device registers */ + cmd[7].cmd = 0 | CMD_OCU | CMD_LC; + cmd[7].src = NAND_GENP_REG0; + cmd[7].dst = paddr(&data[7]); + cmd[7].len = 16; + + ptr[0] = (paddr(cmd) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "status: %x\n", data[6]); +#endif + + flash_info.id = data[7]; + flash_info.vendor = data[7] & CLEAN_DATA_16; + flash_info.device = (data[7] >> 16) & CLEAN_DATA_16; + return; +} + + +struct data_onenand_erase { + unsigned sfbcfg; + unsigned sfcmd[4]; + unsigned sfexec; + unsigned sfstat[4]; + unsigned addr0; + unsigned addr1; + unsigned addr2; + unsigned addr3; + unsigned addr4; + unsigned addr5; + unsigned addr6; + unsigned data0; + unsigned data1; + unsigned data2; + unsigned data3; + unsigned data4; + unsigned data5; + unsigned data6; +}; + + +static int _flash_onenand_read_page(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page, void *_addr, + void *_spareaddr, unsigned raw_mode); + + +static int flash_onenand_block_isbad(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page) +{ + unsigned char page_data[2112]; + unsigned char *oobptr = &(page_data[2048]); + + /* Going to first page of the block */ + if(page & 63) + page = page - (page & 63); + + /* Reading page in raw mode */ + if (_flash_onenand_read_page(cmdlist, ptrlist,page, page_data, 0, 1)) + return 1; + + /* Checking if block is bad */ + if ((oobptr[0] != 0xFF) || (oobptr[1] != 0xFF) || + (oobptr[16] != 0xFF) || (oobptr[17] != 0xFF) || + (oobptr[32] != 0xFF) || (oobptr[33] != 0xFF) || + (oobptr[48] != 0xFF) || (oobptr[49] != 0xFF) + ) + { + return 1; + } + return 0; +} + +static int flash_onenand_erase_block(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + struct data_onenand_erase *data = (void *)ptrlist + 4; + int isbad = 0; + unsigned erasesize = (flash_pagesize << 6); + unsigned onenand_startaddr1 = DEVICE_FLASHCORE_0 | (page * flash_pagesize)/erasesize; + unsigned onenand_startaddr8 = 0x0000; + unsigned onenand_startaddr2 = DEVICE_BUFFERRAM_0 << 15; + unsigned onenand_startbuffer = DATARAM0_0 << 8; + + unsigned controller_status; + unsigned interrupt_status; + unsigned ecc_status; + + if((page * flash_pagesize) & (erasesize-1)) return -1; + + /* Check for bad block and erase only if block is not marked bad */ + isbad = flash_onenand_block_isbad(cmdlist, ptrlist, page); + if (isbad) + { + dprintf(INFO, "skipping @ %d (bad block)\n", page >> 6); + return -1; + } + + /*Erase block*/ + onenand_startaddr1 = DEVICE_FLASHCORE_0 | + ((page * flash_pagesize) / (erasesize)); + onenand_startaddr8 = 0x0000; + onenand_startaddr2 = DEVICE_BUFFERRAM_0 << 15; + onenand_startbuffer = DATARAM0_0 << 8; + + + data->sfbcfg = SFLASH_BCFG; + data->sfcmd[0] = SFLASH_PREPCMD(7, 0, 0, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_REGWR); + data->sfcmd[1] = SFLASH_PREPCMD(0, 0, 32, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_INTHI); + data->sfcmd[2] = SFLASH_PREPCMD(3, 7, 0, + NAND_SFCMD_DATXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_REGRD); + data->sfcmd[3] = SFLASH_PREPCMD(4, 10, 0, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_REGWR); + data->sfexec = 1; + data->sfstat[0] = CLEAN_DATA_32; + data->sfstat[1] = CLEAN_DATA_32; + data->sfstat[2] = CLEAN_DATA_32; + data->sfstat[3] = CLEAN_DATA_32; + data->addr0 = (ONENAND_INTERRUPT_STATUS << 16) | + (ONENAND_SYSTEM_CONFIG_1); + data->addr1 = (ONENAND_START_ADDRESS_8 << 16) | + (ONENAND_START_ADDRESS_1); + data->addr2 = (ONENAND_START_BUFFER << 16) | + (ONENAND_START_ADDRESS_2); + data->addr3 = (ONENAND_ECC_STATUS << 16) | + (ONENAND_COMMAND); + data->addr4 = (ONENAND_CONTROLLER_STATUS << 16) | + (ONENAND_INTERRUPT_STATUS); + data->addr5 = (ONENAND_INTERRUPT_STATUS << 16) | + (ONENAND_SYSTEM_CONFIG_1); + data->addr6 = (ONENAND_START_ADDRESS_3 << 16) | + (ONENAND_START_ADDRESS_1); + data->data0 = (ONENAND_CLRINTR << 16) | + (ONENAND_SYSCFG1_ECCENA); + data->data1 = (onenand_startaddr8 << 16) | + (onenand_startaddr1); + data->data2 = (onenand_startbuffer << 16) | + (onenand_startaddr2); + data->data3 = (CLEAN_DATA_16 << 16) | + (ONENAND_CMDERAS); + data->data4 = (CLEAN_DATA_16 << 16) | + (CLEAN_DATA_16); + data->data5 = (ONENAND_CLRINTR << 16) | + (ONENAND_SYSCFG1_ECCENA); + data->data6 = (ONENAND_STARTADDR3_RES << 16) | + (ONENAND_STARTADDR1_RES); + + /***************************************************************/ + /* Write the necessary address registers in the onenand device */ + /***************************************************************/ + + /* Enable and configure the SFlash controller */ + cmd->cmd = 0 | CMD_OCB; + cmd->src = paddr(&data->sfbcfg); + cmd->dst = NAND_SFLASHC_BURST_CFG; + cmd->len = 4; + cmd++; + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[0]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Write the ADDR0 and ADDR1 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->addr0); + cmd->dst = NAND_ADDR0; + cmd->len = 8; + cmd++; + + /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->addr2); + cmd->dst = NAND_ADDR2; + cmd->len = 16; + cmd++; + + /* Write the ADDR6 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->addr6); + cmd->dst = NAND_ADDR6; + cmd->len = 4; + cmd++; + + /* Write the GENP0, GENP1, GENP2, GENP3, GENP4 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->data0); + cmd->dst = NAND_GENP_REG0; + cmd->len = 16; + cmd++; + + /* Write the FLASH_DEV_CMD4,5,6 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->data4); + cmd->dst = NAND_DEV_CMD4; + cmd->len = 12; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[0]); + cmd->len = 4; + cmd++; + + /***************************************************************/ + /* Wait for the interrupt from the Onenand device controller */ + /***************************************************************/ + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[1]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[1]); + cmd->len = 4; + cmd++; + + /***************************************************************/ + /* Read the necessary status registers from the onenand device */ + /***************************************************************/ + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[2]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[2]); + cmd->len = 4; + cmd++; + + /* Read the GENP3 register */ + cmd->cmd = 0; + cmd->src = NAND_GENP_REG3; + cmd->dst = paddr(&data->data3); + cmd->len = 4; + cmd++; + + /* Read the DEVCMD4 register */ + cmd->cmd = 0; + cmd->src = NAND_DEV_CMD4; + cmd->dst = paddr(&data->data4); + cmd->len = 4; + cmd++; + + /***************************************************************/ + /* Restore the necessary registers to proper values */ + /***************************************************************/ + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[3]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA | CMD_OCU | CMD_LC; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[3]); + cmd->len = 4; + cmd++; + + ptr[0] = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + + ecc_status = (data->data3 >> 16) & 0x0000FFFF; + interrupt_status = (data->data4 >> 0) & 0x0000FFFF; + controller_status = (data->data4 >> 16) & 0x0000FFFF; + +#if VERBOSE + dprintf(INFO, "\n%s: sflash status %x %x %x %x\n", __func__, + data->sfstat[0], + data->sfstat[1], + data->sfstat[2], + data->sfstat[3]); + + dprintf(INFO, "%s: controller_status = %x\n", __func__, + controller_status); + dprintf(INFO, "%s: interrupt_status = %x\n", __func__, + interrupt_status); + dprintf(INFO, "%s: ecc_status = %x\n", __func__, + ecc_status); +#endif + /* Check for errors, protection violations etc */ + if ((controller_status != 0) + || (data->sfstat[0] & 0x110) + || (data->sfstat[1] & 0x110) + || (data->sfstat[2] & 0x110) + || (data->sfstat[3] & 0x110)) { + dprintf(CRITICAL, "%s: ECC/MPU/OP error\n", __func__); + return -1; + } + + +#if VERBOSE + dprintf(INFO, "status: %x\n", data[5]); +#endif + + return 0; +} + + +struct data_onenand_read { + unsigned sfbcfg; + unsigned sfcmd[9]; + unsigned sfexec; + unsigned sfstat[9]; + unsigned addr0; + unsigned addr1; + unsigned addr2; + unsigned addr3; + unsigned addr4; + unsigned addr5; + unsigned addr6; + unsigned data0; + unsigned data1; + unsigned data2; + unsigned data3; + unsigned data4; + unsigned data5; + unsigned data6; + unsigned macro[5]; +}; + + +static int _flash_onenand_read_page(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page, void *_addr, void *_spareaddr, + unsigned raw_mode) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + struct data_onenand_read *data = (void*) (ptrlist + 4); + unsigned addr = (unsigned) _addr; + unsigned curr_addr = (unsigned) _addr; + unsigned spareaddr = (unsigned) _spareaddr; + unsigned i; + unsigned erasesize = (flash_pagesize<<6); + unsigned writesize = flash_pagesize; + + unsigned onenand_startaddr1 = DEVICE_FLASHCORE_0 | + ((unsigned)(page * flash_pagesize) / erasesize); + unsigned onenand_startaddr8 = (((unsigned)(page * flash_pagesize) & + (erasesize - 1)) / writesize) << 2; + unsigned onenand_startaddr2 = DEVICE_BUFFERRAM_0 << 15; + unsigned onenand_startbuffer = DATARAM0_0 << 8; + unsigned onenand_sysconfig1 = (raw_mode == 1) ? ONENAND_SYSCFG1_ECCDIS :\ + ONENAND_SYSCFG1_ECCENA; + + unsigned controller_status; + unsigned interrupt_status; + unsigned ecc_status; + if (raw_mode != 1) + { + int isbad = 0; + isbad = flash_onenand_block_isbad(cmdlist, ptrlist, page); + if (isbad) + return -2; + } + + //static int oobfree_offset[8] = {2, 14, 18, 30, 34, 46, 50, 62}; + //static int oobfree_length[8] = {3, 2, 3, 2, 3, 2, 3, 2}; + + data->sfbcfg = SFLASH_BCFG; + data->sfcmd[0] = SFLASH_PREPCMD(7, 0, 0, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_REGWR); + data->sfcmd[1] = SFLASH_PREPCMD(0, 0, 32, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_INTHI); + data->sfcmd[2] = SFLASH_PREPCMD(3, 7, 0, + NAND_SFCMD_DATXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_REGRD); + data->sfcmd[3] = SFLASH_PREPCMD(256, 0, 0, + NAND_SFCMD_DATXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_DATRD); + data->sfcmd[4] = SFLASH_PREPCMD(256, 0, 0, + NAND_SFCMD_DATXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_DATRD); + data->sfcmd[5] = SFLASH_PREPCMD(256, 0, 0, + NAND_SFCMD_DATXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_DATRD); + data->sfcmd[6] = SFLASH_PREPCMD(256, 0, 0, + NAND_SFCMD_DATXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_DATRD); + data->sfcmd[7] = SFLASH_PREPCMD(32, 0, 0, + NAND_SFCMD_DATXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_DATRD); + data->sfcmd[8] = SFLASH_PREPCMD(4, 10, 0, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_REGWR); + data->sfexec = 1; + data->sfstat[0] = CLEAN_DATA_32; + data->sfstat[1] = CLEAN_DATA_32; + data->sfstat[2] = CLEAN_DATA_32; + data->sfstat[3] = CLEAN_DATA_32; + data->sfstat[4] = CLEAN_DATA_32; + data->sfstat[5] = CLEAN_DATA_32; + data->sfstat[6] = CLEAN_DATA_32; + data->sfstat[7] = CLEAN_DATA_32; + data->sfstat[8] = CLEAN_DATA_32; + + data->addr0 = (ONENAND_INTERRUPT_STATUS << 16) | + (ONENAND_SYSTEM_CONFIG_1); + data->addr1 = (ONENAND_START_ADDRESS_8 << 16) | + (ONENAND_START_ADDRESS_1); + data->addr2 = (ONENAND_START_BUFFER << 16) | + (ONENAND_START_ADDRESS_2); + data->addr3 = (ONENAND_ECC_STATUS << 16) | + (ONENAND_COMMAND); + data->addr4 = (ONENAND_CONTROLLER_STATUS << 16) | + (ONENAND_INTERRUPT_STATUS); + data->addr5 = (ONENAND_INTERRUPT_STATUS << 16) | + (ONENAND_SYSTEM_CONFIG_1); + data->addr6 = (ONENAND_START_ADDRESS_3 << 16) | + (ONENAND_START_ADDRESS_1); + data->data0 = (ONENAND_CLRINTR << 16) | + (onenand_sysconfig1); + data->data1 = (onenand_startaddr8 << 16) | + (onenand_startaddr1); + data->data2 = (onenand_startbuffer << 16) | + (onenand_startaddr2); + data->data3 = (CLEAN_DATA_16 << 16) | + (ONENAND_CMDLOADSPARE); + data->data4 = (CLEAN_DATA_16 << 16) | + (CLEAN_DATA_16); + data->data5 = (ONENAND_CLRINTR << 16) | + (ONENAND_SYSCFG1_ECCENA); + data->data6 = (ONENAND_STARTADDR3_RES << 16) | + (ONENAND_STARTADDR1_RES); + data->macro[0] = 0x0200; + data->macro[1] = 0x0300; + data->macro[2] = 0x0400; + data->macro[3] = 0x0500; + data->macro[4] = 0x8010; + + /*************************************************************/ + /* Write necessary address registers in the onenand device */ + /*************************************************************/ + + /* Enable and configure the SFlash controller */ + cmd->cmd = 0 | CMD_OCB; + cmd->src = paddr(&data->sfbcfg); + cmd->dst = NAND_SFLASHC_BURST_CFG; + cmd->len = 4; + cmd++; + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[0]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Write the ADDR0 and ADDR1 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->addr0); + cmd->dst = NAND_ADDR0; + cmd->len = 8; + cmd++; + + /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->addr2); + cmd->dst = NAND_ADDR2; + cmd->len = 16; + cmd++; + + /* Write the ADDR6 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->addr6); + cmd->dst = NAND_ADDR6; + cmd->len = 4; + cmd++; + + /* Write the GENP0, GENP1, GENP2, GENP3 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->data0); + cmd->dst = NAND_GENP_REG0; + cmd->len = 16; + cmd++; + + /* Write the FLASH_DEV_CMD4,5,6 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->data4); + cmd->dst = NAND_DEV_CMD4; + cmd->len = 12; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[0]); + cmd->len = 4; + cmd++; + + /*************************************************************/ + /* Wait for the interrupt from the Onenand device controller */ + /*************************************************************/ + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[1]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[1]); + cmd->len = 4; + cmd++; + + + /*************************************************************/ + /* Read necessary status registers from the onenand device */ + /*************************************************************/ + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[2]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[2]); + cmd->len = 4; + cmd++; + + /* Read the GENP3 register */ + cmd->cmd = 0; + cmd->src = NAND_GENP_REG3; + cmd->dst = paddr(&data->data3); + cmd->len = 4; + cmd++; + + /* Read the DEVCMD4 register */ + cmd->cmd = 0; + cmd->src = NAND_DEV_CMD4; + cmd->dst = paddr(&data->data4); + cmd->len = 4; + cmd++; + + + /*************************************************************/ + /* Read the data ram area from the onenand buffer ram */ + /*************************************************************/ + + if (addr) { + + data->data3 = (CLEAN_DATA_16 << 16) | + (ONENAND_CMDLOAD); + + for (i = 0; i < 4; i++) { + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[3+i]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Write the MACRO1 register */ + cmd->cmd = 0; + cmd->src = paddr(&data->macro[i]); + cmd->dst = NAND_MACRO1_REG; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data rdy, & read status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[3+i]); + cmd->len = 4; + cmd++; + + /* Transfer nand ctlr buf contents to usr buf */ + cmd->cmd = 0; + cmd->src = NAND_FLASH_BUFFER; + cmd->dst = curr_addr; + cmd->len = 512; + curr_addr += 512; + cmd++; + } + } + + /* Read oob bytes in Raw Mode */ + if (raw_mode == 1) + { + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[7]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Write the MACRO1 register */ + cmd->cmd = 0; + cmd->src = paddr(&data->macro[4]); + cmd->dst = NAND_MACRO1_REG; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data rdy, & read status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[7]); + cmd->len = 4; + cmd++; + + /* Transfer nand ctlr buf contents to usr buf */ + cmd->cmd = 0; + cmd->src = NAND_FLASH_BUFFER; + cmd->dst = curr_addr; + cmd->len = 64; + curr_addr += 64; + cmd++; + } + + /*************************************************************/ + /* Restore the necessary registers to proper values */ + /*************************************************************/ + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[8]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA | CMD_OCU | CMD_LC; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[8]); + cmd->len = 4; + cmd++; + + + ptr[0] = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + + + ecc_status = (data->data3 >> 16) & + 0x0000FFFF; + interrupt_status = (data->data4 >> 0) & + 0x0000FFFF; + controller_status = (data->data4 >> 16) & + 0x0000FFFF; + +#if VERBOSE + dprintf(INFO, "\n%s: sflash status %x %x %x %x %x %x %x" + "%x %x\n", __func__, + data->sfstat[0], + data->sfstat[1], + data->sfstat[2], + data->sfstat[3], + data->sfstat[4], + data->sfstat[5], + data->sfstat[6], + data->sfstat[7]); + + dprintf(INFO, "%s: controller_status = %x\n", __func__, + controller_status); + dprintf(INFO, "%s: interrupt_status = %x\n", __func__, + interrupt_status); + dprintf(INFO, "%s: ecc_status = %x\n", __func__, + ecc_status); +#endif + /* Check for errors, protection violations etc */ + if ((controller_status != 0) + || (data->sfstat[0] & 0x110) + || (data->sfstat[1] & 0x110) + || (data->sfstat[2] & 0x110) + || ((data->sfstat[3] & 0x110) && + (addr)) + || ((data->sfstat[4] & 0x110) && + (addr)) + || ((data->sfstat[5] & 0x110) && + (addr)) + || ((data->sfstat[6] & 0x110) && + (addr))) { + dprintf(INFO, "%s: ECC/MPU/OP error\n", __func__); + return -1; + } + +#if VERBOSE + dprintf(INFO, "read page %d: status: %x %x %x %x\n", + page, data[5], data[6], data[7], data[8]); + for(n = 0; n < 4; n++) { + ptr = (unsigned*)(addr + 512 * n); + dprintf(INFO, "data%d: %x %x %x %x\n", n, ptr[0], ptr[1], ptr[2], ptr[3]); + ptr = (unsigned*)(spareaddr + 16 * n); + dprintf(INFO, "spare data%d %x %x %x %x\n", n, ptr[0], ptr[1], ptr[2], ptr[3]); + } +#endif + + return 0; +} + + +struct data_onenand_write { + unsigned sfbcfg; + unsigned sfcmd[9]; + unsigned sfexec; + unsigned sfstat[9]; + unsigned addr0; + unsigned addr1; + unsigned addr2; + unsigned addr3; + unsigned addr4; + unsigned addr5; + unsigned addr6; + unsigned data0; + unsigned data1; + unsigned data2; + unsigned data3; + unsigned data4; + unsigned data5; + unsigned data6; + unsigned macro[5]; +}; + +static int _flash_onenand_write_page(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page, const void *_addr, + const void *_spareaddr, unsigned raw_mode) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + struct data_onenand_write *data = (void*) (ptrlist + 4); + unsigned addr = (unsigned) _addr; + unsigned addr_curr = (unsigned) _addr; + char * spareaddr = (char *) _spareaddr; + unsigned i, j, k; + + unsigned erasesize = (flash_pagesize<<6); + unsigned writesize = flash_pagesize; + + unsigned onenand_startaddr1 = (page * flash_pagesize) / erasesize; + unsigned onenand_startaddr8 = (((unsigned)(page * flash_pagesize) & + (erasesize-1)) / writesize) << 2; + unsigned onenand_startaddr2 = DEVICE_BUFFERRAM_0 << 15; + unsigned onenand_startbuffer = DATARAM0_0 << 8; + unsigned onenand_sysconfig1 = (raw_mode == 1) ? ONENAND_SYSCFG1_ECCDIS :\ + ONENAND_SYSCFG1_ECCENA; + + unsigned controller_status; + unsigned interrupt_status; + unsigned ecc_status; + + char flash_oob[64]; + + unsigned oobfree_offset[8] = {2, 14, 18, 30, 34, 46, 50, 62}; + unsigned oobfree_length[8] = {3, 2, 3, 2, 3, 2, 3, 2}; + + for (i = 0; i < 64; i++) + flash_oob[i] = 0xFF; + + data->sfbcfg = SFLASH_BCFG; + data->sfcmd[0] = SFLASH_PREPCMD(256, 0, 0, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_DATWR); + data->sfcmd[1] = SFLASH_PREPCMD(256, 0, 0, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_DATWR); + data->sfcmd[2] = SFLASH_PREPCMD(256, 0, 0, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_DATWR); + data->sfcmd[3] = SFLASH_PREPCMD(256, 0, 0, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_DATWR); + data->sfcmd[4] = SFLASH_PREPCMD(32, 0, 0, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_DATWR); + data->sfcmd[5] = SFLASH_PREPCMD(7, 0, 0, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_REGWR); + data->sfcmd[6] = SFLASH_PREPCMD(0, 0, 32, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_INTHI); + data->sfcmd[7] = SFLASH_PREPCMD(3, 7, 0, + NAND_SFCMD_DATXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_REGRD); + data->sfcmd[8] = SFLASH_PREPCMD(4, 10, 0, + NAND_SFCMD_CMDXS, + NAND_SFCMD_ASYNC, + NAND_SFCMD_REGWR); + data->sfexec = 1; + + data->sfstat[0] = CLEAN_DATA_32; + data->sfstat[1] = CLEAN_DATA_32; + data->sfstat[2] = CLEAN_DATA_32; + data->sfstat[3] = CLEAN_DATA_32; + data->sfstat[4] = CLEAN_DATA_32; + data->sfstat[5] = CLEAN_DATA_32; + data->sfstat[6] = CLEAN_DATA_32; + data->sfstat[7] = CLEAN_DATA_32; + data->sfstat[8] = CLEAN_DATA_32; + data->addr0 = (ONENAND_INTERRUPT_STATUS << 16) | + (ONENAND_SYSTEM_CONFIG_1); + data->addr1 = (ONENAND_START_ADDRESS_8 << 16) | + (ONENAND_START_ADDRESS_1); + data->addr2 = (ONENAND_START_BUFFER << 16) | + (ONENAND_START_ADDRESS_2); + data->addr3 = (ONENAND_ECC_STATUS << 16) | + (ONENAND_COMMAND); + data->addr4 = (ONENAND_CONTROLLER_STATUS << 16) | + (ONENAND_INTERRUPT_STATUS); + data->addr5 = (ONENAND_INTERRUPT_STATUS << 16) | + (ONENAND_SYSTEM_CONFIG_1); + data->addr6 = (ONENAND_START_ADDRESS_3 << 16) | + (ONENAND_START_ADDRESS_1); + data->data0 = (ONENAND_CLRINTR << 16) | + (onenand_sysconfig1); + data->data1 = (onenand_startaddr8 << 16) | + (onenand_startaddr1); + data->data2 = (onenand_startbuffer << 16) | + (onenand_startaddr2); + data->data3 = (CLEAN_DATA_16 << 16) | + (ONENAND_CMDPROGSPARE); + data->data3 = (CLEAN_DATA_16 << 16) | + (ONENAND_CMDPROGSPARE); + data->data4 = (CLEAN_DATA_16 << 16) | + (CLEAN_DATA_16); + data->data5 = (ONENAND_CLRINTR << 16) | + (ONENAND_SYSCFG1_ECCENA); + data->data6 = (ONENAND_STARTADDR3_RES << 16) | + (ONENAND_STARTADDR1_RES); + data->macro[0] = 0x0200; + data->macro[1] = 0x0300; + data->macro[2] = 0x0400; + data->macro[3] = 0x0500; + data->macro[4] = 0x8010; + + + /*************************************************************/ + /* Write the data ram area in the onenand buffer ram */ + /*************************************************************/ + + /* Enable and configure the SFlash controller */ + cmd->cmd = 0 | CMD_OCB; + cmd->src = paddr(&data->sfbcfg); + cmd->dst = NAND_SFLASHC_BURST_CFG; + cmd->len = 4; + cmd++; + + if (addr) { + data->data3 = (CLEAN_DATA_16 << 16) | + (ONENAND_CMDPROG); + + for (i = 0; i < 4; i++) { + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[i]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Trnsfr usr buf contents to nand ctlr buf */ + cmd->cmd = 0; + cmd->src = paddr(addr_curr); + cmd->dst = NAND_FLASH_BUFFER; + cmd->len = 512; + if(!raw_mode) + addr_curr += 512; + cmd++; + + /* Write the MACRO1 register */ + cmd->cmd = 0; + cmd->src = paddr(&data->macro[i]); + cmd->dst = NAND_MACRO1_REG; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data rdy, & read status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[i]); + cmd->len = 4; + cmd++; + + } + } + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[4]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + if (spareaddr) + { + // Auto mode + for (i = 0, k = 0; i < 8; i++) { + for (j = 0; j < oobfree_length[i]; j++) { + flash_oob[j+oobfree_offset[i]] = spareaddr[k]; + k++; + } + } + + cmd->cmd = 0; + cmd->src = paddr(&flash_oob); + cmd->dst = NAND_FLASH_BUFFER; + cmd->len = 64; + cmd++; + } + + if (raw_mode){ + cmd->cmd = 0; + cmd->src = paddr(addr_curr); + cmd->dst = NAND_FLASH_BUFFER; + cmd->len = 64; + cmd++; + } + + /* Write the MACRO1 register */ + cmd->cmd = 0; + cmd->src = paddr(&data->macro[4]); + cmd->dst = NAND_MACRO1_REG; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[4]); + cmd->len = 4; + cmd++; + + /*************************************************************/ + /* Write necessary address registers in the onenand device */ + /*************************************************************/ + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[5]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Write the ADDR0 and ADDR1 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->addr0); + cmd->dst = NAND_ADDR0; + cmd->len = 8; + cmd++; + + /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->addr2); + cmd->dst = NAND_ADDR2; + cmd->len = 16; + cmd++; + + /* Write the ADDR6 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->addr6); + cmd->dst = NAND_ADDR6; + cmd->len = 4; + cmd++; + + /* Write the GENP0, GENP1, GENP2, GENP3 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->data0); + cmd->dst = NAND_GENP_REG0; + cmd->len = 16; + cmd++; + + /* Write the FLASH_DEV_CMD4,5,6 registers */ + cmd->cmd = 0; + cmd->src = paddr(&data->data4); + cmd->dst = NAND_DEV_CMD4; + cmd->len = 12; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[5]); + cmd->len = 4; + cmd++; + + /*************************************************************/ + /* Wait for the interrupt from the Onenand device controller */ + /*************************************************************/ + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[6]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[6]); + cmd->len = 4; + cmd++; + + /*************************************************************/ + /* Read necessary status registers from the onenand device */ + /*************************************************************/ + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[7]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[7]); + cmd->len = 4; + cmd++; + + /* Read the GENP3 register */ + cmd->cmd = 0; + cmd->src = NAND_GENP_REG3; + cmd->dst = paddr(&data->data3); + cmd->len = 4; + cmd++; + + /* Read the DEVCMD4 register */ + cmd->cmd = 0; + cmd->src = NAND_DEV_CMD4; + cmd->dst = paddr(&data->data4); + cmd->len = 4; + cmd++; + + + /*************************************************************/ + /* Restore the necessary registers to proper values */ + /*************************************************************/ + + /* Block on cmd ready and write CMD register */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->sfcmd[8]); + cmd->dst = NAND_SFLASHC_CMD; + cmd->len = 4; + cmd++; + + /* Kick the execute command */ + cmd->cmd = 0; + cmd->src = paddr(&data->sfexec); + cmd->dst = NAND_SFLASHC_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* Block on data ready, and read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA | CMD_OCU | CMD_LC; + cmd->src = NAND_SFLASHC_STATUS; + cmd->dst = paddr(&data->sfstat[8]); + cmd->len = 4; + cmd++; + + + ptr[0] = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + + ecc_status = (data->data3 >> 16) & 0x0000FFFF; + interrupt_status = (data->data4 >> 0)&0x0000FFFF; + controller_status = (data->data4 >> 16)&0x0000FFFF; + +#if VERBOSE + dprintf(INFO, "\n%s: sflash status %x %x %x %x %x %x %x %x %x\n", __func__, + data->sfstat[0], + data->sfstat[1], + data->sfstat[2], + data->sfstat[3], + data->sfstat[4], + data->sfstat[5], + data->sfstat[6], + data->sfstat[7], + data->sfstat[8]); + + dprintf(INFO, "%s: controller_status = %x\n", __func__, + controller_status); + dprintf(INFO, "%s: interrupt_status = %x\n", __func__, + interrupt_status); + dprintf(INFO, "%s: ecc_status = %x\n", __func__, + ecc_status); +#endif + /* Check for errors, protection violations etc */ + if ((controller_status != 0) + || (data->sfstat[5] & 0x110) + || (data->sfstat[6] & 0x110) + || (data->sfstat[7] & 0x110) + || (data->sfstat[8] & 0x110) + || ((data->sfstat[0] & 0x110) && + (addr)) + || ((data->sfstat[1] & 0x110) && + (addr)) + || ((data->sfstat[2] & 0x110) && + (addr)) + || ((data->sfstat[3] & 0x110) && + (addr))) { + dprintf(CRITICAL, "%s: ECC/MPU/OP error\n", __func__); + return -1; + } + + + return 0; +} + +static int flash_onenand_mark_badblock(dmov_s *cmdlist, unsigned *ptrlist, unsigned page) +{ + memset(empty_buf,0,528); + /* Going to first page of the block */ + if(page & 63) + page = page - (page & 63); + return _flash_onenand_write_page(cmdlist, ptrlist, page, empty_buf, 0, 1); +} + +static int flash_mark_badblock(dmov_s *cmdlist, unsigned *ptrlist, unsigned page) +{ + switch(flash_info.type) { + case FLASH_8BIT_NAND_DEVICE: + case FLASH_16BIT_NAND_DEVICE: + return flash_nand_mark_badblock(cmdlist, ptrlist, page); + case FLASH_ONENAND_DEVICE: + return flash_onenand_mark_badblock(cmdlist, ptrlist, page); + default: + return -1; + } +} + + +/* Wrapper functions */ +static void flash_read_id(dmov_s *cmdlist, unsigned *ptrlist) +{ + int dev_found = 0; + unsigned index; + + // Try to read id + flash_nand_read_id(cmdlist, ptrlist); + // Check if we support the device + for (index=1; + index < (sizeof(supported_flash)/sizeof(struct flash_identification)); + index++) + { + if ((flash_info.id & supported_flash[index].mask) == + (supported_flash[index].flash_id & + (supported_flash[index].mask))) { + dev_found = 1; + break; + } + } + + if(!dev_found) { + flash_onenand_read_id(cmdlist, ptrlist); + for (index=1; + index < (sizeof(supported_flash)/sizeof(struct flash_identification)); + index++) + { + if ((flash_info.id & supported_flash[index].mask) == + (supported_flash[index].flash_id & + (supported_flash[index].mask))) { + dev_found = 1; + break; + } + } + } + + + + if(dev_found) { + if (supported_flash[index].widebus) + flash_info.type = FLASH_16BIT_NAND_DEVICE; + else + flash_info.type = FLASH_8BIT_NAND_DEVICE; + if (supported_flash[index].onenand) + flash_info.type = FLASH_ONENAND_DEVICE; + flash_info.page_size = supported_flash[index].pagesize; + flash_pagesize = flash_info.page_size; + flash_info.block_size = supported_flash[index].blksize; + flash_info.spare_size = supported_flash[index].oobsize; + if (flash_info.block_size && flash_info.page_size) + { + flash_info.num_blocks = supported_flash[index].density; + flash_info.num_blocks /= (flash_info.block_size); + } + else + { + flash_info.num_blocks = 0; + } + ASSERT(flash_info.num_blocks); + return; + } + + // Assume 8 bit nand device for backward compatability + if (dev_found == 0) { + dprintf(INFO, "Device not supported. Assuming 8 bit NAND device\n"); + flash_info.type = FLASH_8BIT_NAND_DEVICE; + } + dprintf(INFO, "nandid: 0x%x maker=0x%02x device=0x%02x page_size=%d\n", + flash_info.id, flash_info.vendor, flash_info.device, + flash_info.page_size); + dprintf(INFO, " spare_size=%d block_size=%d num_blocks=%d\n", + flash_info.spare_size, flash_info.block_size, + flash_info.num_blocks); +} + +static int flash_erase_block(dmov_s *cmdlist, unsigned *ptrlist, unsigned page) +{ + switch(flash_info.type) { + case FLASH_8BIT_NAND_DEVICE: + case FLASH_16BIT_NAND_DEVICE: + return flash_nand_erase_block(cmdlist, ptrlist, page); + case FLASH_ONENAND_DEVICE: + return flash_onenand_erase_block(cmdlist, ptrlist, page); + default: + return -1; + } +} + +static int _flash_read_page(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page, void *_addr, void *_spareaddr) +{ + switch(flash_info.type) { + case FLASH_8BIT_NAND_DEVICE: + case FLASH_16BIT_NAND_DEVICE: + if(interleaved_mode) + return flash_nand_read_page_interleave(cmdlist, ptrlist, page, _addr, _spareaddr); + else + return _flash_nand_read_page(cmdlist, ptrlist, page, _addr, _spareaddr); + case FLASH_ONENAND_DEVICE: + return _flash_onenand_read_page(cmdlist, ptrlist, page, _addr, _spareaddr, 0); + default: + return -1; + } +} + +static int _flash_block_isbad(dmov_s *cmdlist, unsigned *ptrlist, unsigned page) +{ + switch(flash_info.type) { + case FLASH_8BIT_NAND_DEVICE: + case FLASH_16BIT_NAND_DEVICE: + return flash_nand_block_isbad(cmdlist, ptrlist, page); + case FLASH_ONENAND_DEVICE: + return flash_onenand_block_isbad(cmdlist, ptrlist, page); + default: + return -1; + } +} + +static int _flash_write_page(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page, const void *_addr, + const void *_spareaddr) +{ + switch(flash_info.type) { + case FLASH_8BIT_NAND_DEVICE: + case FLASH_16BIT_NAND_DEVICE: + if(interleaved_mode) + return flash_nand_write_page_interleave(cmdlist, ptrlist, page, _addr, _spareaddr, 0); + else + return _flash_nand_write_page(cmdlist, ptrlist, page, _addr, _spareaddr, 0); + case FLASH_ONENAND_DEVICE: + return _flash_onenand_write_page(cmdlist, ptrlist, page, _addr, _spareaddr, 0); + default: + return -1; + } +} + +static unsigned *flash_ptrlist; +static dmov_s *flash_cmdlist; + +static struct ptable *flash_ptable = NULL; + +void flash_init(void) +{ + ASSERT(flash_ptable == NULL); + + flash_ptrlist = memalign(32, 1024); + flash_cmdlist = memalign(32, 1024); + flash_data = memalign(32, 4096 + 128); + flash_spare = memalign(32, 128); + + flash_read_id(flash_cmdlist, flash_ptrlist); + if((FLASH_8BIT_NAND_DEVICE == flash_info.type) + ||(FLASH_16BIT_NAND_DEVICE == flash_info.type)) { + if(flash_nand_read_config(flash_cmdlist, flash_ptrlist)) { + dprintf(CRITICAL, "ERROR: could not read CFG0/CFG1 state\n"); + ASSERT(0); + } + } +} + +struct ptable *flash_get_ptable(void) +{ + return flash_ptable; +} + +void flash_set_ptable(struct ptable *new_ptable) +{ + ASSERT(flash_ptable == NULL && new_ptable != NULL); + flash_ptable = new_ptable; +} + +struct flash_info *flash_get_info(void) +{ + return &flash_info; +} + +int flash_erase(struct ptentry *ptn) +{ + unsigned block = ptn->start; + unsigned count = ptn->length; + + set_nand_configuration(ptn->type); + while(count-- > 0) { + if(flash_erase_block(flash_cmdlist, flash_ptrlist, block * 64)) { + dprintf(INFO, "cannot erase @ %d (bad block?)\n", block); + } + block++; + } + return 0; +} + +int flash_read_ext(struct ptentry *ptn, unsigned extra_per_page, + unsigned offset, void *data, unsigned bytes) +{ + unsigned page = (ptn->start * 64) + (offset / flash_pagesize); + unsigned lastpage = (ptn->start + ptn->length) * 64; + unsigned count = (bytes + flash_pagesize - 1 + extra_per_page) / (flash_pagesize + extra_per_page); + unsigned *spare = (unsigned*) flash_spare; + unsigned errors = 0; + unsigned char *image = data; + unsigned current_block = (page - (page & 63)) >> 6; + unsigned start_block = ptn->start; + int result = 0; + int isbad = 0; + int start_block_count = 0; + + ASSERT(ptn->type == TYPE_APPS_PARTITION); + set_nand_configuration(TYPE_APPS_PARTITION); + + if(offset & (flash_pagesize - 1)) + return -1; + +// Adjust page offset based on number of bad blocks from start to current page + if (start_block < current_block) + { + start_block_count = (current_block - start_block); + while (start_block_count && (start_block < (ptn->start + ptn->length))) { + isbad = _flash_block_isbad(flash_cmdlist, flash_ptrlist, start_block*64); + if (isbad) + page += 64; + else + start_block_count--; + start_block++; + } + } + + while((page < lastpage) && !start_block_count) { + if(count == 0) { + dprintf(INFO, "flash_read_image: success (%d errors)\n", errors); + return 0; + } + + result = _flash_read_page(flash_cmdlist, flash_ptrlist, page, image, spare); + + if (result == -1) { + // bad page, go to next page + page++; + errors++; + continue; + } + else if (result == -2) { + // bad block, go to next block same offset + page += 64; + errors++; + continue; + } + + page++; + image += flash_pagesize; + memcpy(image, spare, extra_per_page); + image += extra_per_page; + count -= 1; + } + + /* could not find enough valid pages before we hit the end */ + dprintf(INFO, "flash_read_image: failed (%d errors)\n", errors); + return 0xffffffff; +} + +int flash_write(struct ptentry *ptn, unsigned extra_per_page, const void *data, + unsigned bytes) +{ + unsigned page = ptn->start * 64; + unsigned lastpage = (ptn->start + ptn->length) * 64; + unsigned *spare = (unsigned*) flash_spare; + const unsigned char *image = data; + unsigned wsize = flash_pagesize + extra_per_page; + unsigned n; + int r; + + if ((flash_info.type == FLASH_ONENAND_DEVICE) && (ptn->type == TYPE_MODEM_PARTITION)) + { + dprintf(CRITICAL, "flash_write_image: feature not supported\n"); + return -1; + } + + set_nand_configuration(ptn->type); + for(n = 0; n < 16; n++) spare[n] = 0xffffffff; + + while(bytes > 0) { + if(bytes < wsize) { + dprintf(CRITICAL, "flash_write_image: image undersized (%d < %d)\n", bytes, wsize); + return -1; + } + if(page >= lastpage) { + dprintf(CRITICAL, "flash_write_image: out of space\n"); + return -1; + } + + if((page & 63) == 0) { + if(flash_erase_block(flash_cmdlist, flash_ptrlist, page)) { + dprintf(INFO, "flash_write_image: bad block @ %d\n", page >> 6); + page += 64; + continue; + } + } + + if(extra_per_page) { + r = _flash_write_page(flash_cmdlist, flash_ptrlist, page, image, image + flash_pagesize); + } else { + r = _flash_write_page(flash_cmdlist, flash_ptrlist, page, image, spare); + } + if(r) { + dprintf(INFO, "flash_write_image: write failure @ page %d (src %d)\n", page, image - (const unsigned char *)data); + image -= (page & 63) * wsize; + bytes += (page & 63) * wsize; + page &= ~63; + if(flash_erase_block(flash_cmdlist, flash_ptrlist, page)) { + dprintf(INFO, "flash_write_image: erase failure @ page %d\n", page); + } + if (ptn->type != TYPE_MODEM_PARTITION) { + flash_mark_badblock(flash_cmdlist, flash_ptrlist, page); + } + dprintf(INFO, "flash_write_image: restart write @ page %d (src %d)\n", page, image - (const unsigned char *)data); + page += 64; + continue; + } + page++; + image += wsize; + bytes -= wsize; + } + + /* erase any remaining pages in the partition */ + page = (page + 63) & (~63); + while(page < lastpage){ + if(flash_erase_block(flash_cmdlist, flash_ptrlist, page)) { + dprintf(INFO, "flash_write_image: bad block @ %d\n", page >> 6); + } + page += 64; + } + + dprintf(INFO, "flash_write_image: success\n"); + return 0; +} + +#if 0 +static int flash_read_page(unsigned page, void *data, void *extra) +{ + return _flash_read_page(flash_cmdlist, flash_ptrlist, + page, data, extra); +} +#endif + +unsigned flash_page_size(void) +{ + return flash_pagesize; +} + +void enable_interleave_mode(int status) +{ + interleaved_mode = status; + if(status) + { + flash_pagesize *= 2; + platform_config_interleaved_mode_gpios(); + } + return; +} diff --git a/lk/platform/msm_shared/proc_comm.c b/lk/platform/msm_shared/proc_comm.c new file mode 100644 index 0000000..48d2040 --- /dev/null +++ b/lk/platform/msm_shared/proc_comm.c @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include +#ifndef PLATFORM_MSM8X60 +#define ACPU_CLK 0 /* Applications processor clock */ +#define ADM_CLK 1 /* Applications data mover clock */ +#define ADSP_CLK 2 /* ADSP clock */ +#define EBI1_CLK 3 /* External bus interface 1 clock */ +#define EBI2_CLK 4 /* External bus interface 2 clock */ +#define ECODEC_CLK 5 /* External CODEC clock */ +#define EMDH_CLK 6 /* External MDDI host clock */ +#define GP_CLK 7 /* General purpose clock */ +#define GRP_CLK 8 /* Graphics clock */ +#define I2C_CLK 9 /* I2C clock */ +#define ICODEC_RX_CLK 10 /* Internal CODEX RX clock */ +#define ICODEC_TX_CLK 11 /* Internal CODEX TX clock */ +#define IMEM_CLK 12 /* Internal graphics memory clock */ +#define MDC_CLK 13 /* MDDI client clock */ +#define MDP_CLK 14 /* Mobile display processor clock */ +#define PBUS_CLK 15 /* Peripheral bus clock */ +#define PCM_CLK 16 /* PCM clock */ +#define PMDH_CLK 17 /* Primary MDDI host clock */ +#define SDAC_CLK 18 /* Stereo DAC clock */ +#define SDC1_CLK 19 /* Secure Digital Card clocks */ +#define SDC1_PCLK 20 +#define SDC2_CLK 21 +#define SDC2_PCLK 22 +#define SDC3_CLK 23 +#define SDC3_PCLK 24 +#define SDC4_CLK 25 +#define SDC4_PCLK 26 +#define TSIF_CLK 27 /* Transport Stream Interface clocks */ +#define TSIF_REF_CLK 28 +#define TV_DAC_CLK 29 /* TV clocks */ +#define TV_ENC_CLK 30 +#define UART1_CLK 31 /* UART clocks */ +#define UART2_CLK 32 +#define UART3_CLK 33 +#define UART1DM_CLK 34 +#define UART2DM_CLK 35 +#define USB_HS_CLK 36 /* High speed USB core clock */ +#define USB_HS_PCLK 37 /* High speed USB pbus clock */ +#define USB_OTG_CLK 38 /* Full speed USB clock */ +#define VDC_CLK 39 /* Video controller clock */ +#define VFE_CLK 40 /* Camera / Video Front End clock */ +#define VFE_MDC_CLK 41 /* VFE MDDI client clock */ + +/* qsd8k adds... */ +#define MDP_LCDC_PCLK_CLK 42 +#define MDP_LCDC_PAD_PCLK_CLK 43 +#define MDP_VSYNC_CLK 44 + +#define P_USB_HS_CORE_CLK 53 /* High speed USB 1 core clock */ +/* msm7x30 adds... */ +#define PMDH_P_CLK 82 +#define MDP_P_CLK 86 + +enum { + PCOM_CMD_IDLE = 0x0, + PCOM_CMD_DONE, + PCOM_RESET_APPS, + PCOM_RESET_CHIP, + PCOM_CONFIG_NAND_MPU, + PCOM_CONFIG_USB_CLKS, + PCOM_GET_POWER_ON_STATUS, + PCOM_GET_WAKE_UP_STATUS, + PCOM_GET_BATT_LEVEL, + PCOM_CHG_IS_CHARGING, + PCOM_POWER_DOWN, + PCOM_USB_PIN_CONFIG, + PCOM_USB_PIN_SEL, + PCOM_SET_RTC_ALARM, + PCOM_NV_READ, + PCOM_NV_WRITE, + PCOM_GET_UUID_HIGH, + PCOM_GET_UUID_LOW, + PCOM_GET_HW_ENTROPY, + PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE, + PCOM_CLKCTL_RPC_ENABLE, + PCOM_CLKCTL_RPC_DISABLE, + PCOM_CLKCTL_RPC_RESET, + PCOM_CLKCTL_RPC_SET_FLAGS, + PCOM_CLKCTL_RPC_SET_RATE, + PCOM_CLKCTL_RPC_MIN_RATE, + PCOM_CLKCTL_RPC_MAX_RATE, + PCOM_CLKCTL_RPC_RATE, + PCOM_CLKCTL_RPC_PLL_REQUEST, + PCOM_CLKCTL_RPC_ENABLED, + PCOM_VREG_SWITCH, + PCOM_VREG_SET_LEVEL, + PCOM_GPIO_TLMM_CONFIG_GROUP, + PCOM_GPIO_TLMM_UNCONFIG_GROUP, + PCOM_NV_READ_HIGH_BITS, + PCOM_NV_WRITE_HIGH_BITS, + PCOM_RPC_GPIO_TLMM_CONFIG_EX = 0x25, + PCOM_RESERVED_101 = 0x65, + PCOM_MSM_HSUSB_PHY_RESET, + PCOM_GET_BATT_MV_LEVEL, + PCOM_CHG_USB_IS_PC_CONNECTED, + PCOM_CHG_USB_IS_CHARGER_CONNECTED, + PCOM_CHG_USB_IS_DISCONNECTED, + PCOM_CHG_USB_I_AVAILABLE, + PCOM_NUM_CMDS, +}; + +enum { + PCOM_INVALID_STATUS = 0x0, + PCOM_READY, + PCOM_CMD_RUNNING, + PCOM_CMD_SUCCESS, + PCOM_CMD_FAIL, +}; + +#ifndef PLATFORM_MSM7X30 +#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4) +#endif +static inline void notify_other_proc_comm(void) +{ +#ifndef PLATFORM_MSM7X30 + writel(1, MSM_A2M_INT(6)); +#else + writel(1<<6, (MSM_GCC_BASE + 0x8)); +#endif +} + +#define APP_COMMAND (MSM_SHARED_BASE + 0x00) +#define APP_STATUS (MSM_SHARED_BASE + 0x04) +#define APP_DATA1 (MSM_SHARED_BASE + 0x08) +#define APP_DATA2 (MSM_SHARED_BASE + 0x0C) + +#define MDM_COMMAND (MSM_SHARED_BASE + 0x10) +#define MDM_STATUS (MSM_SHARED_BASE + 0x14) +#define MDM_DATA1 (MSM_SHARED_BASE + 0x18) +#define MDM_DATA2 (MSM_SHARED_BASE + 0x1C) + +int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2) +{ + int ret = -1; + unsigned status; + +// dprintf(INFO, "proc_comm(%d,%d,%d)\n", +// cmd, data1 ? *data1 : 0, data2 ? *data2 : 0); + while (readl(MDM_STATUS) != PCOM_READY) { + /* XXX check for A9 reset */ + } + + writel(cmd, APP_COMMAND); + if (data1) + writel(*data1, APP_DATA1); + if (data2) + writel(*data2, APP_DATA2); + +// dprintf(INFO, "proc_comm tx\n"); + notify_other_proc_comm(); + while (readl(APP_COMMAND) != PCOM_CMD_DONE) { + /* XXX check for A9 reset */ + } + + status = readl(APP_STATUS); +// dprintf(INFO, "proc_comm status %d\n", status); + + if (status != PCOM_CMD_FAIL) { + if (data1) + *data1 = readl(APP_DATA1); + if (data2) + *data2 = readl(APP_DATA2); + ret = 0; + } + + return ret; +} + +static int clock_enable(unsigned id) +{ + return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, 0); +} + +static int clock_disable(unsigned id) +{ + return msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, 0); +} + +static int clock_set_rate(unsigned id, unsigned rate) +{ + return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate); +} + +static int clock_get_rate(unsigned id) +{ + if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, 0)) { + return -1; + } else { + return (int) id; + } +} + +void usb_clock_init() +{ + clock_enable(USB_HS_PCLK); + clock_enable(USB_HS_CLK); + clock_enable(P_USB_HS_CORE_CLK); +} + +void lcdc_clock_init(unsigned rate) +{ + clock_set_rate(MDP_LCDC_PCLK_CLK, rate); + clock_enable(MDP_LCDC_PCLK_CLK); + clock_enable(MDP_LCDC_PAD_PCLK_CLK); +} + +void mdp_clock_init (unsigned rate) +{ + clock_set_rate(MDP_CLK, rate); + clock_enable(MDP_CLK); + clock_enable(MDP_P_CLK); +} + +void uart3_clock_init(void) +{ + clock_enable(UART3_CLK); + clock_set_rate(UART3_CLK, 19200000 / 4); +} + +void uart2_clock_init(void) +{ + clock_enable(UART2_CLK); + clock_set_rate(UART2_CLK, 19200000); +} + +void mddi_clock_init(unsigned num, unsigned rate) +{ + unsigned clock_id; + + if (num == 0) + clock_id = PMDH_CLK; + else + clock_id = EMDH_CLK; + + clock_enable(clock_id); + clock_set_rate(clock_id, rate); +#ifdef PLATFORM_MSM7X30 + clock_enable (PMDH_P_CLK); +#endif +} + +void reboot(unsigned reboot_reason) +{ + msm_proc_comm(PCOM_RESET_CHIP, &reboot_reason, 0); + for (;;) ; +} + +/* Apps processor calls this API to tell modem processor that a PC USB + * is connected return true if the USB HOST PC charger charging is + * supported */ +int charger_usb_is_pc_connected(void) +{ + unsigned charging_supported = 0; + unsigned m = 0; + msm_proc_comm(PCOM_CHG_USB_IS_PC_CONNECTED, &charging_supported, &m); + return charging_supported; +} + +/* Apps processor calls this API to tell modem processor that a USB Wall + * charger is connected returns true if the USB WALL charger charging is + * supported */ +int charger_usb_is_charger_connected(void) +{ + unsigned charging_supported = 0; + unsigned m = 0; + msm_proc_comm(PCOM_CHG_USB_IS_CHARGER_CONNECTED, &charging_supported, &m); + return charging_supported; +} + +/* Apps processor calls this API to tell modem processor that a USB cable is + * disconnected return true is charging is supported in the system */ +int charger_usb_disconnected(void) +{ + unsigned charging_supported = 0; + unsigned m = 0; + msm_proc_comm(PCOM_CHG_USB_IS_DISCONNECTED, &charging_supported, &m); + return charging_supported; +} + +/* current parameter passed is the amount of current that the charger needs + * to draw from USB */ +int charger_usb_i(unsigned current) +{ + unsigned charging_supported = 0; + msm_proc_comm(PCOM_CHG_USB_I_AVAILABLE, ¤t, &charging_supported); + return charging_supported; +} + +int mmc_clock_enable_disable (unsigned id, unsigned enable) +{ + if(enable) + { + return clock_enable(id); //Enable mmc clock rate + } + else + { + return clock_disable(id); //Disable mmc clock rate + } +} + +int mmc_clock_set_rate(unsigned id, unsigned rate) +{ + return clock_set_rate(id, rate); //Set mmc clock rate +} + +int mmc_clock_get_rate(unsigned id) +{ + return clock_get_rate(id); //Get mmc clock rate +} + +int gpio_tlmm_config(unsigned config, unsigned disable) +{ + return msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, &disable); +} + +int vreg_set_level(unsigned id, unsigned mv) +{ + return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv); +} + +int vreg_enable(unsigned id) +{ + int enable = 1; + return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); + +} + +int vreg_disable(unsigned id) +{ + int enable = 0; + return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); +} +#endif diff --git a/lk/platform/msm_shared/rules.mk b/lk/platform/msm_shared/rules.mk new file mode 100644 index 0000000..6b895da --- /dev/null +++ b/lk/platform/msm_shared/rules.mk @@ -0,0 +1,31 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += \ + -I$(LOCAL_DIR)/include + +DEFINES += $(TARGET_XRES) +DEFINES += $(TARGET_YRES) + +OBJS += \ + $(LOCAL_DIR)/timer.o \ + $(LOCAL_DIR)/proc_comm.o \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/smem.o \ + $(LOCAL_DIR)/smem_ptable.o \ + $(LOCAL_DIR)/hsusb.o \ + $(LOCAL_DIR)/jtag_hook.o \ + $(LOCAL_DIR)/jtag.o \ + $(LOCAL_DIR)/lcdc.o \ + $(LOCAL_DIR)/mddi.o \ + $(LOCAL_DIR)/mmc.o + +ifeq ($(PLATFORM),msm8x60) + OBJS += $(LOCAL_DIR)/mipi_dsi.o \ + $(LOCAL_DIR)/i2c_qup.o +endif + +ifeq ($(PLATFORM),msm8x60) + OBJS += $(LOCAL_DIR)/uart_dm.o +else + OBJS += $(LOCAL_DIR)/uart.o +endif diff --git a/lk/platform/msm_shared/smem.c b/lk/platform/msm_shared/smem.c new file mode 100644 index 0000000..63df5c3 --- /dev/null +++ b/lk/platform/msm_shared/smem.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009, Google 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "smem.h" + +static struct smem *smem = (void *)(MSM_SHARED_BASE); + +/* buf MUST be 4byte aligned, and len MUST be a multiple of 8. */ +unsigned smem_read_alloc_entry(smem_mem_type_t type, void *buf, int len) +{ + struct smem_alloc_info *ainfo; + unsigned *dest = buf; + unsigned src; + unsigned size; + + if (((len & 0x3) != 0) || (((unsigned)buf & 0x3) != 0)) + return 1; + + if (type < SMEM_FIRST_VALID_TYPE || type > SMEM_LAST_VALID_TYPE) + return 1; + + /* TODO: Use smem spinlocks */ + ainfo = &smem->alloc_info[type]; + if (readl(&ainfo->allocated) == 0) + return 1; + + size = readl(&ainfo->size); + + if (size != (unsigned)((len + 7) & ~0x00000007)) + return 1; + + src = MSM_SHARED_BASE + readl(&ainfo->offset); + for (; len > 0; src += 4, len -= 4) + *(dest++) = readl(src); + + return 0; +} + +unsigned smem_read_alloc_entry_offset(smem_mem_type_t type, void *buf, int len, int offset) +{ + struct smem_alloc_info *ainfo; + unsigned *dest = buf; + unsigned src; + unsigned size = len; + + if (((len & 0x3) != 0) || (((unsigned)buf & 0x3) != 0)) + return 1; + + if (type < SMEM_FIRST_VALID_TYPE || type > SMEM_LAST_VALID_TYPE) + return 1; + + ainfo = &smem->alloc_info[type]; + if (readl(&ainfo->allocated) == 0) + return 1; + + src = MSM_SHARED_BASE + readl(&ainfo->offset) + offset; + for (; size > 0; src += 4, size -= 4) + *(dest++) = readl(src); + + return 0; +} diff --git a/lk/platform/msm_shared/smem.h b/lk/platform/msm_shared/smem.h new file mode 100644 index 0000000..7e78293 --- /dev/null +++ b/lk/platform/msm_shared/smem.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009, Code Aurora Forum. 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. + * + * 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 __PLATFORM_MSM_SHARED_SMEM_H +#define __PLATFORM_MSM_SHARED_SMEM_H + +#include + +struct smem_proc_comm +{ + unsigned command; + unsigned status; + unsigned data1; + unsigned data2; +}; + +struct smem_heap_info +{ + unsigned initialized; + unsigned free_offset; + unsigned heap_remaining; + unsigned reserved; +}; + +struct smem_alloc_info +{ + unsigned allocated; + unsigned offset; + unsigned size; + unsigned reserved; +}; + +struct smem { + struct smem_proc_comm proc_comm[4]; + unsigned version_info[32]; + struct smem_heap_info heap_info; + struct smem_alloc_info alloc_info[128]; +}; + +struct smem_board_info_v3 +{ + unsigned format; + unsigned msm_id; + unsigned msm_version; + char build_id[32]; + unsigned raw_msm_id; + unsigned raw_msm_version; + unsigned hw_platform; +}; + +struct smem_board_info_v4 +{ + struct smem_board_info_v3 board_info_v3; + unsigned platform_version; + unsigned buffer_align; //Need for 8 bytes alignment while reading from shared memory. +}; + +struct smem_board_info_v5 +{ + struct smem_board_info_v3 board_info_v3; + unsigned platform_version; + unsigned fused_chip; +}; + +/* chip information */ +enum { + UNKNOWN = 0, + MDM9200 = 57, + MDM9600 = 58, +}; + +enum platform +{ + HW_PLATFORM_UNKNOWN = 0, + HW_PLATFORM_SURF = 1, + HW_PLATFORM_FFA = 2, + HW_PLATFORM_FLUID = 3, + HW_PLATFORM_SVLTE = 4, + HW_PLATFORM_32BITS = 0x7FFFFFFF +}; + + +typedef enum { + SMEM_SPINLOCK_ARRAY = 7, + + SMEM_AARM_PARTITION_TABLE = 9, + + SMEM_APPS_BOOT_MODE = 106, + + SMEM_BOARD_INFO_LOCATION = 137, + + SMEM_USABLE_RAM_PARTITION_TABLE = 402, + + SMEM_POWER_ON_STATUS_INFO = 403, + + SMEM_FIRST_VALID_TYPE = SMEM_SPINLOCK_ARRAY, + SMEM_LAST_VALID_TYPE = SMEM_POWER_ON_STATUS_INFO, +} smem_mem_type_t; + +/* Note: buf MUST be 4byte aligned, and max_len MUST be a multiple of 4. */ +unsigned smem_read_alloc_entry(smem_mem_type_t type, void *buf, int max_len); + +/* SMEM RAM Partition */ +enum { + DEFAULT_ATTRB = ~0x0, + READ_ONLY = 0x0, + READWRITE, +}; + +enum { + DEFAULT_CATEGORY = ~0x0, + SMI = 0x0, + EBI1, + EBI2, + QDSP6, + IRAM, + IMEM, + EBI0_CS0, + EBI0_CS1, + EBI1_CS0, + EBI1_CS1, +}; + +enum { + DEFAULT_DOMAIN = 0x0, + APPS_DOMAIN, + MODEM_DOMAIN, + SHARED_DOMAIN, +}; + +enum { + SYS_MEMORY = 1, /* system memory*/ + BOOT_REGION_MEMORY1, /* boot loader memory 1*/ + BOOT_REGION_MEMORY2, /* boot loader memory 2,reserved*/ + APPSBL_MEMORY, /* apps boot loader memory*/ + APPS_MEMORY, /* apps usage memory*/ +}; + +struct smem_ram_ptn { + char name[16]; + unsigned start; + unsigned size; + + /* RAM Partition attribute: READ_ONLY, READWRITE etc. */ + unsigned attr; + + /* RAM Partition category: EBI0, EBI1, IRAM, IMEM */ + unsigned category; + + /* RAM Partition domain: APPS, MODEM, APPS & MODEM (SHARED) etc. */ + unsigned domain; + + /* RAM Partition type: system, bootloader, appsboot, apps etc. */ + unsigned type; + + /* reserved for future expansion without changing version number */ + unsigned reserved2, reserved3, reserved4, reserved5; +} __attribute__ ((__packed__)); + +struct smem_ram_ptable { +#define _SMEM_RAM_PTABLE_MAGIC_1 0x9DA5E0A8 +#define _SMEM_RAM_PTABLE_MAGIC_2 0xAF9EC4E2 + unsigned magic[2]; + unsigned version; + unsigned reserved1; + unsigned len; + struct smem_ram_ptn parts[32]; + unsigned buf; +} __attribute__ ((__packed__)); + +/* Power on reason/status info */ +#define PWR_ON_EVENT_USB_CHG 0x20 + +#endif /* __PLATFORM_MSM_SHARED_SMEM_H */ diff --git a/lk/platform/msm_shared/smem_ptable.c b/lk/platform/msm_shared/smem_ptable.c new file mode 100644 index 0000000..60d0e26 --- /dev/null +++ b/lk/platform/msm_shared/smem_ptable.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include "smem.h" + +struct smem_ptn { + char name[16]; + unsigned start; + unsigned size; + unsigned attr; +} __attribute__ ((__packed__)); + +struct smem_ptable { +#define _SMEM_PTABLE_MAGIC_1 0x55ee73aa +#define _SMEM_PTABLE_MAGIC_2 0xe35ebddb + unsigned magic[2]; + unsigned version; + unsigned len; + struct smem_ptn parts[16]; +} __attribute__ ((__packed__)); + +/* partition table from SMEM */ +static struct smem_ptable smem_ptable; +static unsigned smem_apps_flash_start; + +static void dump_smem_ptable(void) +{ + int i; + + for (i = 0; i < 16; i++) { + struct smem_ptn *p = &smem_ptable.parts[i]; + if (p->name[0] == '\0') + continue; + dprintf(SPEW, "%d: %s offs=0x%08x size=0x%08x attr: 0x%08x\n", + i, p->name, p->start, p->size, p->attr); + } +} + +void smem_ptable_init(void) +{ + unsigned i; + + smem_apps_flash_start = 0xffffffff; + + i = smem_read_alloc_entry(SMEM_AARM_PARTITION_TABLE, + &smem_ptable, sizeof(smem_ptable)); + if (i != 0) + return; + + if (smem_ptable.magic[0] != _SMEM_PTABLE_MAGIC_1 || + smem_ptable.magic[1] != _SMEM_PTABLE_MAGIC_2) + return; + + dump_smem_ptable(); + dprintf(INFO, "smem ptable found: ver: %d len: %d\n", + smem_ptable.version, smem_ptable.len); + + for (i = 0; i < smem_ptable.len; i++) { + if (!strcmp(smem_ptable.parts[i].name, "0:APPS")) + break; + } + if (i == smem_ptable.len) + return; + + smem_apps_flash_start = smem_ptable.parts[i].start; +} + +unsigned smem_get_apps_flash_start(void) +{ + return smem_apps_flash_start; +} + +void smem_add_modem_partitions(struct ptable *flash_ptable) +{ + int i; + + if (smem_ptable.magic[0] != _SMEM_PTABLE_MAGIC_1 || + smem_ptable.magic[1] != _SMEM_PTABLE_MAGIC_2) + return; + + for (i = 0; i < 16; i++) + { + char * token; + char * pname = NULL; + struct smem_ptn *p = &smem_ptable.parts[i]; + if (p->name[0] == '\0') + continue; + token = strtok(p->name, ":"); + while (token) + { + pname = token; + token = strtok (NULL, ":"); + } + if(pname) + { + ptable_add(flash_ptable, pname, p->start, + p->size, 0, TYPE_MODEM_PARTITION, PERM_WRITEABLE); + } + } +} + +/* RAM Partition table from SMEM */ +int smem_ram_ptable_init(struct smem_ram_ptable *smem_ram_ptable) +{ + unsigned i; + + i = smem_read_alloc_entry(SMEM_USABLE_RAM_PARTITION_TABLE, + smem_ram_ptable, sizeof(struct smem_ram_ptable)); + if (i != 0) + return 0; + + if (smem_ram_ptable->magic[0] != _SMEM_RAM_PTABLE_MAGIC_1 || + smem_ram_ptable->magic[1] != _SMEM_RAM_PTABLE_MAGIC_2) + return 0; + + dprintf(INFO, "smem ram ptable found: ver: %d len: %d\n", + smem_ram_ptable->version, smem_ram_ptable->len); + + return 1; +} + + diff --git a/lk/platform/msm_shared/timer.c b/lk/platform/msm_shared/timer.c new file mode 100644 index 0000000..9f98ffa --- /dev/null +++ b/lk/platform/msm_shared/timer.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#if PLATFORM_MSM7X30 || PLATFORM_MSM8X60 + +#define MSM_GPT_BASE (MSM_TMR_BASE + 0x4) +#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24) +#define GPT_REG(off) (MSM_GPT_BASE + (off)) +#define DGT_REG(off) (MSM_DGT_BASE + (off)) +#define SPSS_TIMER_STATUS (MSM_TMR_BASE + 0x88) + +#define GPT_MATCH_VAL GPT_REG(0x0000) +#define GPT_COUNT_VAL GPT_REG(0x0004) +#define GPT_ENABLE GPT_REG(0x0008) +#define GPT_ENABLE_CLR_ON_MATCH_EN 2 +#define GPT_ENABLE_EN 1 +#define GPT_CLEAR GPT_REG(0x000C) + +#define DGT_MATCH_VAL DGT_REG(0x0000) +#define DGT_COUNT_VAL DGT_REG(0x0004) +#define DGT_ENABLE DGT_REG(0x0008) +#define DGT_ENABLE_CLR_ON_MATCH_EN 2 +#define DGT_ENABLE_EN 1 +#define DGT_CLEAR DGT_REG(0x000C) +#define DGT_CLK_CTL DGT_REG(0x0010) + +#define HW_REVISION_NUMBER 0xABC00270 + + +#else +#define GPT_REG(off) (MSM_GPT_BASE + (off)) + +#define GPT_MATCH_VAL GPT_REG(0x0000) +#define GPT_COUNT_VAL GPT_REG(0x0004) +#define GPT_ENABLE GPT_REG(0x0008) +#define GPT_ENABLE_CLR_ON_MATCH_EN 2 +#define GPT_ENABLE_EN 1 +#define GPT_CLEAR GPT_REG(0x000C) + +#define DGT_MATCH_VAL GPT_REG(0x0010) +#define DGT_COUNT_VAL GPT_REG(0x0014) +#define DGT_ENABLE GPT_REG(0x0018) +#define DGT_ENABLE_CLR_ON_MATCH_EN 2 +#define DGT_ENABLE_EN 1 +#define DGT_CLEAR GPT_REG(0x001C) + +#define SPSS_TIMER_STATUS GPT_REG(0x0034) +#endif + +#if defined PLATFORM_QSD8K +#define DGT_HZ 4800000 /* Uses TCXO/4 (19.2 MHz / 4) */ +#elif defined PLATFORM_MSM7X30 +#if _EMMC_BOOT +#define DGT_HZ 19200000 /* Uses TCXO (19.2 MHz) */ +#else +#define DGT_HZ 6144000 /* Uses LPXO/4 (24.576 MHz / 4) */ +#endif +#elif defined PLATFORM_MSM8X60 +#define DGT_HZ 6750000 /* Uses LPXO/4 (27.0 MHz / 4) */ +#else +#define DGT_HZ 19200000 /* Uses TCXO (19.2 MHz) */ +#endif + + +static platform_timer_callback timer_callback; +static void *timer_arg; +static time_t timer_interval; + +static volatile uint32_t ticks; + +static enum handler_return timer_irq(void *arg) +{ + ticks += timer_interval; + return timer_callback(timer_arg, ticks); +} + +status_t platform_set_periodic_timer( + platform_timer_callback callback, + void *arg, time_t interval) +{ +#ifdef PLATFORM_MSM7X30 + unsigned val = 0; + //Check for the hardware revision + val = readl(HW_REVISION_NUMBER); + val = (val >> 28) & 0x0F; + if(val >= 1) + writel(1, DGT_CLK_CTL); +#endif +#ifdef PLATFORM_MSM8X60 + writel(3, DGT_CLK_CTL); +#endif + enter_critical_section(); + + timer_callback = callback; + timer_arg = arg; + timer_interval = interval; + + writel(timer_interval * (DGT_HZ / 1000), DGT_MATCH_VAL); + writel(0, DGT_CLEAR); + writel(DGT_ENABLE_EN | DGT_ENABLE_CLR_ON_MATCH_EN, DGT_ENABLE); + + register_int_handler(INT_DEBUG_TIMER_EXP, timer_irq, 0); + unmask_interrupt(INT_DEBUG_TIMER_EXP); + + exit_critical_section(); + return 0; +} + + +time_t current_time(void) +{ + return ticks; +} + +void platform_init_timer(void) +{ + writel(0, DGT_ENABLE); +} + +static void wait_for_timer_op(void) +{ +#if PLATFORM_QSD8K || PLATFORM_MSM7X30 || PLATFORM_MSM8X60 + while(readl(SPSS_TIMER_STATUS)) ; +#endif +} + +void platform_uninit_timer(void) +{ + writel(0, DGT_ENABLE); + wait_for_timer_op(); + writel(0, DGT_CLEAR); + wait_for_timer_op(); +} + +void mdelay(unsigned msecs) +{ + msecs *= 33; + + writel(0, GPT_CLEAR); + writel(0, GPT_ENABLE); + while(readl(GPT_COUNT_VAL) != 0) ; + + writel(GPT_ENABLE_EN, GPT_ENABLE); + while(readl(GPT_COUNT_VAL) < msecs) ; + + writel(0, GPT_ENABLE); + writel(0, GPT_CLEAR); +} + +void udelay(unsigned usecs) +{ + usecs = (usecs * 33 + 1000 - 33) / 1000; + + writel(0, GPT_CLEAR); + writel(0, GPT_ENABLE); + while(readl(GPT_COUNT_VAL) != 0); + + writel(GPT_ENABLE_EN, GPT_ENABLE); + while(readl(GPT_COUNT_VAL) < usecs); + + writel(0, GPT_ENABLE); + writel(0, GPT_CLEAR); +} diff --git a/lk/platform/msm_shared/uart.c b/lk/platform/msm_shared/uart.c new file mode 100644 index 0000000..7f5c7e2 --- /dev/null +++ b/lk/platform/msm_shared/uart.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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. + */ + +#include + +#include +#include +#include + +#define UART_MR1 0x0000 + +#define UART_MR1_AUTO_RFR_LEVEL0(n) (((n) & 0x3f) << 8) +#define UART_MR1_RX_RDY_CTL (1 << 7) +#define UART_MR1_CTS_CTL (1 << 6) +#define UART_MR1_AUTO_RFR_LEVEL1(n) ((n) & 0x3f) + +#define UART_MR2 0x0004 +#define UART_MR2_ERROR_MODE (1 << 6) +#define UART_MR2_BITS_PER_CHAR_5 (0 << 4) +#define UART_MR2_BITS_PER_CHAR_6 (1 << 4) +#define UART_MR2_BITS_PER_CHAR_7 (2 << 4) +#define UART_MR2_BITS_PER_CHAR_8 (3 << 4) +#define UART_MR2_STOP_BIT_LEN_0563 (0 << 2) +#define UART_MR2_STOP_BIT_LEN_1000 (1 << 2) +#define UART_MR2_STOP_BIT_LEN_1563 (2 << 2) +#define UART_MR2_STOP_BIT_LEN_2000 (3 << 2) +#define UART_MR2_PARITY_MODE_NONE (0) +#define UART_MR2_PARITY_MODE_ODD (1) +#define UART_MR2_PARITY_MODE_EVEN (2) +#define UART_MR2_PARITY_MODE_SPACE (3) + +#define UART_CSR 0x0008 +#define UART_CSR_115200 0xFF +#define UART_CSR_57600 0xEE +#define UART_CSR_38400 0xDD +#define UART_CSR_19200 0xBB + +#define UART_TF 0x000C + +#define UART_CR 0x0010 +#define UART_CR_CMD_NULL (0 << 4) +#define UART_CR_CMD_RESET_RX (1 << 4) +#define UART_CR_CMD_RESET_TX (2 << 4) +#define UART_CR_CMD_RESET_ERR (3 << 4) +#define UART_CR_CMD_RESET_BCI (4 << 4) +#define UART_CR_CMD_START_BREAK (5 << 4) +#define UART_CR_CMD_STOP_BREAK (6 << 4) +#define UART_CR_CMD_RESET_CTS_N (7 << 4) +#define UART_CR_CMD_PACKET_MODE (9 << 4) +#define UART_CR_CMD_MODE_RESET (12<< 4) +#define UART_CR_CMD_SET_RFR_N (13<< 4) +#define UART_CR_CMD_RESET_RFR_ND (14<< 4) +#define UART_CR_TX_DISABLE (1 << 3) +#define UART_CR_TX_ENABLE (1 << 3) +#define UART_CR_RX_DISABLE (1 << 3) +#define UART_CR_RX_ENABLE (1 << 3) + +#define UART_IMR 0x0014 +#define UART_IMR_RXLEV (1 << 4) +#define UART_IMR_TXLEV (1 << 0) + +#define UART_IPR 0x0018 +#define UART_TFWR 0x001C +#define UART_RFWR 0x0020 +#define UART_HCR 0x0024 + +#define UART_MREG 0x0028 +#define UART_NREG 0x002C +#define UART_DREG 0x0030 +#define UART_MNDREG 0x0034 +#define UART_IRDA 0x0038 +#define UART_MISR_MODE 0x0040 +#define UART_MISR_RESET 0x0044 +#define UART_MISR_EXPORT 0x0048 +#define UART_MISR_VAL 0x004C +#define UART_TEST_CTRL 0x0050 + +#define UART_SR 0x0008 +#define UART_SR_HUNT_CHAR (1 << 7) +#define UART_SR_RX_BREAK (1 << 6) +#define UART_SR_PAR_FRAME_ERR (1 << 5) +#define UART_SR_OVERRUN (1 << 4) +#define UART_SR_TX_EMPTY (1 << 3) +#define UART_SR_TX_READY (1 << 2) +#define UART_SR_RX_FULL (1 << 1) +#define UART_SR_RX_READY (1 << 0) + +#define UART_RF 0x000C +#define UART_MISR 0x0010 +#define UART_ISR 0x0014 + + +static unsigned uart_ready = 0; +#if PLATFORM_MSM7X30 +static unsigned uart_base = MSM_UART2_BASE; +#else +static unsigned uart_base = MSM_UART3_BASE; +#endif + +#define uwr(v,a) writel(v, uart_base + (a)) +#define urd(a) readl(uart_base + (a)) + +void uart_init(void) +{ + uwr(0x0A, UART_CR); /* disable TX and RX */ + + uwr(0x30, UART_CR); /* reset error status */ + uwr(0x10, UART_CR); /* reset receiver */ + uwr(0x20, UART_CR); /* reset transmitter */ + +#if PLATFORM_QSD8K || PLATFORM_MSM7X30 + /* TCXO */ + uwr(0x06, UART_MREG); + uwr(0xF1, UART_NREG); + uwr(0x0F, UART_DREG); + uwr(0x1A, UART_MNDREG); +#else + /* TCXO/4 */ + uwr(0xC0, UART_MREG); + uwr(0xAF, UART_NREG); + uwr(0x80, UART_DREG); + uwr(0x19, UART_MNDREG); +#endif + + uwr(0x10, UART_CR); /* reset RX */ + uwr(0x20, UART_CR); /* reset TX */ + uwr(0x30, UART_CR); /* reset error status */ + uwr(0x40, UART_CR); /* reset RX break */ + uwr(0x70, UART_CR); /* rest? */ + uwr(0xD0, UART_CR); /* reset */ + + uwr(0x7BF, UART_IPR); /* stale timeout = 630 * bitrate */ + uwr(0, UART_IMR); + uwr(115, UART_RFWR); /* RX watermark = 58 * 2 - 1 */ + uwr(10, UART_TFWR); /* TX watermark */ + + uwr(0, UART_RFWR); + + uwr(UART_CSR_115200, UART_CSR); + uwr(0, UART_IRDA); + uwr(0x1E, UART_HCR); +// uwr(0x7F4, UART_MR1); /* RFS/ CTS/ 500chr RFR */ + uwr(16, UART_MR1); + uwr(0x34, UART_MR2); /* 8N1 */ + + uwr(0x05, UART_CR); /* enable TX & RX */ + + uart_ready = 1; +} + +static int _uart_putc(int port, char c) +{ + if (!uart_ready) + return -1; + while (!(urd(UART_SR) & UART_SR_TX_READY)) ; + uwr(c, UART_TF); + return 0; +} + +int uart_putc (int port, char c) +{ + if(c == '\n') + { + _uart_putc(0, '\r'); + } + _uart_putc(0, c); +} + +int uart_getc(int port, bool wait) +{ + if (!uart_ready) + return -1; + while (!(urd(UART_SR) & UART_SR_RX_READY)) + if (!wait) + return -1; + + return urd(UART_RF); +} + diff --git a/lk/platform/msm_shared/uart_dm.c b/lk/platform/msm_shared/uart_dm.c new file mode 100644 index 0000000..9e06cd0 --- /dev/null +++ b/lk/platform/msm_shared/uart_dm.c @@ -0,0 +1,526 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "uart_dm.h" + + +#ifndef NULL +#define NULL 0 +#endif + +/* Note: + * This is a basic implementation of UART_DM protocol. More focus has been + * given on simplicity than efficiency. Few of the things to be noted are: + * - RX path may not be suitable for multi-threaded scenaraio because of the + * use of static variables. TX path shouldn't have any problem though. If + * multi-threaded support is required, a simple data-structure can + * be maintained for each thread. + * - Right now we are using polling method than interrupt based. + * - We are using legacy UART protocol without Data Mover. + * - Not all interrupts and error events are handled. + * - While waiting Watchdog hasn't been taken into consideration. + */ + + +#define PACK_CHARS_INTO_WORDS(a, cnt, word) { \ + word = 0; \ + for(int j=0; j < (int)cnt; j++) \ + { \ + word |= (a[j] & 0xff) \ + << (j * 8); \ + } \ + } + + +/* Static Function Prototype Declarations */ +static unsigned int msm_boot_uart_config_gpios(void); +static unsigned int msm_boot_uart_dm_config_clock(void); +static unsigned int msm_boot_uart_dm_gsbi_init(void); +static unsigned int msm_boot_uart_replace_lr_with_cr(char* data_in, + int num_of_chars, + char *data_out, + int *num_of_chars_out); +static unsigned int msm_boot_uart_dm_init(void); +static unsigned int msm_boot_uart_dm_read(unsigned int* data, + int wait); +static unsigned int msm_boot_uart_dm_write(char* data, + unsigned int num_of_chars); +static unsigned int msm_boot_uart_dm_init_rx_transfer(void); +static unsigned int msm_boot_uart_dm_reset(void); + + +/* Extern functions */ +void clock_config(unsigned int ns, unsigned int md, + unsigned int ns_addr, unsigned int md_addr); + +void gpio_tlmm_config(uint32_t gpio, uint8_t func, + uint8_t dir, uint8_t pull, + uint8_t drvstr, uint32_t enable ); + +void udelay(unsigned usecs); + + +/* + * Helper function to replace Line Feed char "\n" with + * Carriage Return "\r\n". + * Currently keeping it simple than efficient + */ +static unsigned int msm_boot_uart_replace_lr_with_cr(char* data_in, + int num_of_chars, + char *data_out, + int *num_of_chars_out ) +{ + int i = 0, j = 0; + + if ((data_in == NULL) || (data_out == NULL) || (num_of_chars < 0)) + { + return MSM_BOOT_UART_DM_E_INVAL; + } + + for (i=0, j=0; i < num_of_chars; i++, j++) + { + if ( data_in[i] == '\n' ) + { + data_out[j++] = '\r'; + } + + data_out[j] = data_in[i]; + } + + *num_of_chars_out = j; + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + + +static unsigned int msm_boot_uart_dm_config_gpios(void) +{ + /* GPIO Pin: MSM_BOOT_UART_DM_RX_GPIO (117) + Function: 2 + Direction: IN + Pull: No PULL + Drive Strength: 8 ma + Output Enable: Disable + */ + gpio_tlmm_config(MSM_BOOT_UART_DM_RX_GPIO, 2, GPIO_INPUT, + GPIO_NO_PULL, GPIO_8MA, GPIO_DISABLE); + + /* GPIO Pin: MSM_BOOT_UART_DM_TX_GPIO (118) + Function: 2 + Direction: OUT + Pull: No PULL + Drive Strength: 8 ma + Output Enable: Disable + */ + gpio_tlmm_config(MSM_BOOT_UART_DM_TX_GPIO, 2, GPIO_OUTPUT, + GPIO_NO_PULL, GPIO_8MA, GPIO_DISABLE); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + + + +static unsigned int msm_boot_uart_dm_config_clock(void) +{ + unsigned int curr_value = 0; + + /* Vote for PLL8 to be enabled */ + curr_value = readl(MSM_BOOT_PLL_ENABLE_SC0); + curr_value |= (1 << 8); + writel(curr_value, MSM_BOOT_PLL_ENABLE_SC0); + + /* Proceed only after PLL is enabled */ + while (!(readl(MSM_BOOT_PLL8_STATUS) & (1<<16))); + + /* PLL8 is enabled. Enable gsbi_uart_clk */ + + /* GSBI clock frequencies for UART protocol + * Operating mode gsbi_uart_clk + * UART up to 115.2 Kbps 1.8432 MHz + * UART up to 460.8 Kbps 7.3728 MHz + * UART up to 4 Mbit/s 64 MHz + * + + * Choosing lowest supported value + * Rate (KHz) NS MD + * 3686400 0xFD940043 0x0006FD8E + */ + + clock_config(0xFD940043, 0x0006FD8E, + MSM_BOOT_UART_DM_APPS_NS, + MSM_BOOT_UART_DM_APPS_MD); + + /* Enable gsbi_pclk */ + writel(0x10, MSM_BOOT_UART_DM_GSBI_HCLK_CTL); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + + +/* + * Initialize and configure GSBI for operation + */ +static unsigned int msm_boot_uart_dm_gsbi_init(void) +{ + /* Configure the clock block */ + msm_boot_uart_dm_config_clock(); + + /* Configure TLMM/GPIO to provide connectivity between GSBI + product ports and chip pads */ + msm_boot_uart_dm_config_gpios(); + + + /* Configure Data Mover for GSBI operation. + * Currently not supported. */ + + /* Configure GSBI for UART_DM protocol. + * I2C on 2 ports, UART (without HS flow control) on the other 2. */ + writel(0x60, MSM_BOOT_GSBI_CTRL_REG); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + +/* + * Reset the UART + */ +static unsigned int msm_boot_uart_dm_reset(void) +{ + writel(MSM_BOOT_UART_DM_CMD_RESET_RX, MSM_BOOT_UART_DM_CR); + writel(MSM_BOOT_UART_DM_CMD_RESET_TX, MSM_BOOT_UART_DM_CR); + writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT, MSM_BOOT_UART_DM_CR); + writel(MSM_BOOT_UART_DM_CMD_RES_TX_ERR, MSM_BOOT_UART_DM_CR); + writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT, MSM_BOOT_UART_DM_CR); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + + +/* + * Initialize UART_DM - configure clock and required registers. + */ +static unsigned int msm_boot_uart_dm_init(void) +{ + /* Configure GSB12 for uart dm */ + msm_boot_uart_dm_gsbi_init(); + + + /* Configure clock selection register for tx and rx rates. + * Selecting 115.2k for both RX and TX */ + writel(MSM_BOOT_UART_DM_RX_TX_BIT_RATE, MSM_BOOT_UART_DM_CSR); + + /* Configure UART mode registers MR1 and MR2 */ + /* Hardware flow control isn't supported */ + writel(0x0, MSM_BOOT_UART_DM_MR1); + + /* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */ + writel(MSM_BOOT_UART_DM_8_N_1_MODE, MSM_BOOT_UART_DM_MR2); + + /* Configure Interrupt Mask register IMR */ + writel(MSM_BOOT_UART_DM_IMR_ENABLED, MSM_BOOT_UART_DM_IMR); + + /* Configure Tx and Rx watermarks configuration registers */ + /* TX watermark value is set to 0 - interrupt is generated when + * FIFO level is less than or equal to 0 */ + writel(MSM_BOOT_UART_DM_TFW_VALUE, MSM_BOOT_UART_DM_TFWR); + + /* RX watermark value*/ + writel(MSM_BOOT_UART_DM_RFW_VALUE, MSM_BOOT_UART_DM_RFWR); + + /* Configure Interrupt Programming Register*/ + /* Set initial Stale timeout value*/ + writel(MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB, MSM_BOOT_UART_DM_IPR); + + /* Configure IRDA if required */ + /* Disabling IRDA mode */ + writel(0x0, MSM_BOOT_UART_DM_IRDA); + + /* Configure and enable sim interface if required */ + + /* Configure hunt character value in HCR register */ + /* Keep it in reset state */ + writel(0x0, MSM_BOOT_UART_DM_HCR); + + /* Configure Rx FIFO base address */ + /* Both TX/RX shares same SRAM and default is half-n-half. + * Sticking with default value now. + * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries). + * We have found RAM_ADDR_WIDTH = 0x7f */ + + /* Issue soft reset command */ + msm_boot_uart_dm_reset(); + + /* Enable/Disable Rx/Tx DM interfaces */ + /* Data Mover not currently utilized. */ + writel(0x0, MSM_BOOT_UART_DM_DMEN); + + + /* Enable transmitter and receiver */ + writel(MSM_BOOT_UART_DM_CR_RX_ENABLE, MSM_BOOT_UART_DM_CR); + writel(MSM_BOOT_UART_DM_CR_TX_ENABLE, MSM_BOOT_UART_DM_CR); + + /* Initialize Receive Path */ + msm_boot_uart_dm_init_rx_transfer(); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + + +/* + * Initialize Receive Path + */ +static unsigned int msm_boot_uart_dm_init_rx_transfer(void) +{ + writel(MSM_BOOT_UART_DM_GCMD_DIS_STALE_EVT, MSM_BOOT_UART_DM_CR); + writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT, MSM_BOOT_UART_DM_CR); + writel(MSM_BOOT_UART_DM_DMRX_DEF_VALUE, MSM_BOOT_UART_DM_DMRX); + writel(MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT, MSM_BOOT_UART_DM_CR); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + +/* + * UART Receive operation + * Reads a word from the RX FIFO. + */ +static unsigned int msm_boot_uart_dm_read(unsigned int* data, int wait) +{ + static int rx_last_snap_count = 0; + static int rx_chars_read_since_last_xfer = 0; + + if (data == NULL) + { + return MSM_BOOT_UART_DM_E_INVAL; + } + + + + /* We will be polling RXRDY status bit */ + while (!(readl(MSM_BOOT_UART_DM_SR) & MSM_BOOT_UART_DM_SR_RXRDY)) + { + /* if this is not a blocking call, we'll just return */ + if (!wait) + { + return MSM_BOOT_UART_DM_E_RX_NOT_READY; + } + } + + /* Check for Overrun error. We'll just reset Error Status */ + if (readl(MSM_BOOT_UART_DM_SR) & MSM_BOOT_UART_DM_SR_UART_OVERRUN) + { + writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT, MSM_BOOT_UART_DM_CR); + } + + /* RX FIFO is ready; read a word. */ + *data = readl(MSM_BOOT_UART_DM_RF(0)); + + /* increment the total count of chars we've read so far */ + rx_chars_read_since_last_xfer += 4; + + /* Rx transfer ends when one of the conditions is met: + * - The number of characters received since the end of the previous xfer + * equals the value written to DMRX at Transfer Initialization + * - A stale event occurred + */ + + /* If RX transfer has not ended yet */ + if (rx_last_snap_count == 0) + { + /* Check if we've received stale event */ + if (readl(MSM_BOOT_UART_DM_MISR) & MSM_BOOT_UART_DM_RXSTALE) + { + /* Send command to reset stale interrupt */ + writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT, MSM_BOOT_UART_DM_CR); + } + + /* Check if we haven't read more than DMRX value */ + else if ((unsigned int)rx_chars_read_since_last_xfer < + readl(MSM_BOOT_UART_DM_DMRX)) + { + /* We can still continue reading before initializing RX transfer */ + return MSM_BOOT_UART_DM_E_SUCCESS; + } + + /* If we've reached here it means RX xfer end conditions been met */ + + /* Read UART_DM_RX_TOTAL_SNAP register to know how many valid chars + * we've read so far since last transfer */ + rx_last_snap_count = readl(MSM_BOOT_UART_DM_RX_TOTAL_SNAP); + + } + + /* If there are still data left in FIFO we'll read them before + * initializing RX Transfer again */ + if ((rx_last_snap_count - rx_chars_read_since_last_xfer) >= 0 ) + { + return MSM_BOOT_UART_DM_E_SUCCESS; + } + + msm_boot_uart_dm_init_rx_transfer(); + rx_last_snap_count = 0; + rx_chars_read_since_last_xfer = 0; + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + + +/* + * UART transmit operation + */ +static unsigned int msm_boot_uart_dm_write(char* data, + unsigned int num_of_chars) +{ + unsigned int tx_word_count = 0; + unsigned int tx_char_left = 0, tx_char = 0; + unsigned int tx_word = 0; + int i = 0; + char* tx_data = NULL; + char new_data[1024]; + + if ((data == NULL) || (num_of_chars <= 0)) + { + return MSM_BOOT_UART_DM_E_INVAL; + } + + /* Replace line-feed (/n) with carriage-return + line-feed (/r/n) */ + + msm_boot_uart_replace_lr_with_cr(data, num_of_chars, new_data, &i); + + tx_data = new_data; + num_of_chars = i; + + /* Write to NO_CHARS_FOR_TX register number of characters + * to be transmitted. However, before writing TX_FIFO must + * be empty as indicated by TX_READY interrupt in IMR register + */ + + /* Check if transmit FIFO is empty. + * If not we'll wait for TX_READY interrupt. */ + if (!(readl(MSM_BOOT_UART_DM_SR) & MSM_BOOT_UART_DM_SR_TXEMT)) + { + while (!(readl(MSM_BOOT_UART_DM_ISR) & MSM_BOOT_UART_DM_TX_READY)) + { + udelay(1); + /* Kick watchdog? */ + } + } + + /* We are here. FIFO is ready to be written. */ + /* Write number of characters to be written */ + writel(num_of_chars, MSM_BOOT_UART_DM_NO_CHARS_FOR_TX); + + /* Clear TX_READY interrupt */ + writel(MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT, MSM_BOOT_UART_DM_CR); + + /* We use four-character word FIFO. So we need to divide data into + * four characters and write in UART_DM_TF register */ + tx_word_count = (num_of_chars % 4)? ((num_of_chars / 4) + 1) : + (num_of_chars / 4); + tx_char_left = num_of_chars; + + for (i = 0; i < (int)tx_word_count; i++) + { + tx_char = (tx_char_left < 4)? tx_char_left : 4; + PACK_CHARS_INTO_WORDS(tx_data, tx_char, tx_word); + + /* Wait till TX FIFO has space */ + while (!(readl(MSM_BOOT_UART_DM_SR) & MSM_BOOT_UART_DM_SR_TXRDY)) + { + udelay(1); + } + + /* TX FIFO has space. Write the chars */ + writel(tx_word, MSM_BOOT_UART_DM_TF(0)); + tx_char_left = num_of_chars - (i+1)*4; + tx_data = tx_data + 4; + } + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + + +/* Defining functions that's exposed to outside world and in coformance to + * existing uart implemention. These functions are being called to initialize + * UART and print debug messages in bootloader. */ + +void uart_init(void) +{ + char *data = "Android Bootloader - UART_DM Initialized!!!\n"; + + msm_boot_uart_dm_init(); + msm_boot_uart_dm_write(data, 44); + +} + +/* UART_DM uses four character word FIFO where as UART core + * uses a character FIFO. so it's really inefficient to try + * to write single character. But that's how dprintf has been + * implemented. + */ +int uart_putc(int port, char c) +{ + + msm_boot_uart_dm_write(&c, 1); + + return 0; +} + +/* UART_DM uses four character word FIFO whereas uart_getc + * is supposed to read only one character. So we need to + * read a word and keep track of each character in the word. + */ +int uart_getc(int port, bool wait) +{ + int byte; + static unsigned int word = 0; + + if (!word) + { + /* Read from FIFO only if it's a first read or all the four + * characters out of a word have been read */ + if (msm_boot_uart_dm_read( &word, wait) != MSM_BOOT_UART_DM_E_SUCCESS) + { + return -1; + } + + } + + byte = (int) word & 0xff; + word = word >> 8; + + return byte; +} + diff --git a/lk/platform/omap3/cpu_early_init.S b/lk/platform/omap3/cpu_early_init.S new file mode 100644 index 0000000..ca026bc --- /dev/null +++ b/lk/platform/omap3/cpu_early_init.S @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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. + */ +.text +.globl __cpu_early_init + +__cpu_early_init: + /* do an omap3 specific setup of the L2 */ + mov r12, #1 + .word 0xe1600070 + bx lr \ No newline at end of file diff --git a/lk/platform/omap3/debug.c b/lk/platform/omap3/debug.c new file mode 100644 index 0000000..ac6300d --- /dev/null +++ b/lk/platform/omap3/debug.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include +#include + +void _dputc(char c) +{ + if (c == '\n') + uart_putc(DEBUG_UART, '\r'); + uart_putc(DEBUG_UART, c); +} + +int dgetc(char *c) +{ + int _c; + + if ((_c = uart_getc(DEBUG_UART, false)) < 0) + return -1; + + *c = _c; + return 0; +} + +void debug_dump_regs(void) +{ + PANIC_UNIMPLEMENTED; +} + +void platform_halt(void) +{ + dprintf(ALWAYS, "HALT: spinning forever...\n"); + for(;;); +} + +void debug_dump_memory_bytes(void *mem, int len) +{ + PANIC_UNIMPLEMENTED; +} + +void debug_dump_memory_halfwords(void *mem, int len) +{ + PANIC_UNIMPLEMENTED; +} + +void debug_dump_memory_words(void *mem, int len) +{ + PANIC_UNIMPLEMENTED; +} + +void debug_set_trace_level(int trace_type, int level) +{ + PANIC_UNIMPLEMENTED; +} + +uint32_t debug_cycle_count(void) +{ +// PANIC_UNIMPLEMENTED; + return 0; +} diff --git a/lk/platform/omap3/i2c.c b/lk/platform/omap3/i2c.c new file mode 100644 index 0000000..8736c02 --- /dev/null +++ b/lk/platform/omap3/i2c.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include + +#define LOCAL_TRACE 0 + +#define I2C_TIMEOUT 200 + +static const addr_t i2c_reg_base[] = { + I2C1_BASE, + I2C2_BASE, + I2C3_BASE, +}; + +#define I2C_REG_ADDR(bus, reg) (i2c_reg_base[bus] + (reg)) +#define I2C_REG(bus, reg) (*REG16(I2C_REG_ADDR(bus, reg))) +#define I2C_RMW_REG(bus, reg, startbit, width, val) RMWREG16(I2C_REG_ADDR(bus, reg), startbit, width, val) + +static void i2c_dump_bus(int bus) +{ + hexdump((void *)i2c_reg_base[bus], 128); +} + +static void i2c_reset_bus(int bus) +{ + I2C_REG(bus, I2C_CON) &= ~(1<<15); // make sure the bus is disabled + + /* reset the bus */ + I2C_REG(bus, I2C_SYSC) = (1<<1); + I2C_REG(bus, I2C_CON) = (1<<15); // enable the bus + while ((I2C_REG(bus, I2C_SYSS) & 1) == 0) + ; + + /* disable the bus again and set up some internals */ + I2C_REG(bus, I2C_CON) &= ~(1<<15); // make sure the bus is disabled + + /* set up the clock */ + I2C_REG(bus, I2C_PSC) = 23; // 96Mhz / 23 == 4Mhz + I2C_REG(bus, I2C_SCLL) = 13; + I2C_REG(bus, I2C_SCLH) = 15; // 4Mhz / combined divider of 40 (13+7 + 15+5) == 100khz + + /* slave address */ + I2C_REG(bus, I2C_OA0) = 1; // XXX made this up + + /* fifo is set to 1 byte trigger */ + I2C_REG(bus, I2C_BUF) = 0; + + /* disable all interrupts */ + I2C_REG(bus, I2C_IE) = 0; + + /* enable the bus */ + I2C_REG(bus, I2C_CON) = (1<<15)|(1<<10)|(1<<9); // enable, master, transmitter mode +} + +static void i2c_wait_for_bb(int bus) +{ + I2C_REG(bus, I2C_STAT) = 0xffff; // clear whatever is pending + while (I2C_REG(bus, I2C_STAT) & (1<<12)) { + I2C_REG(bus, I2C_STAT) = 0xffff; // clear whatever is pending + } + I2C_REG(bus, I2C_STAT) = 0xffff; // clear whatever is pending +} + +int i2c_transmit(int bus, uint8_t address, const void *buf, size_t count) +{ + int err; + + LTRACEF("bus %d, address 0x%hhx, buf %p, count %zd\n", bus, address, buf, count); + + i2c_wait_for_bb(bus); + + I2C_REG(bus, I2C_SA) = address; + I2C_REG(bus, I2C_CNT) = count; + I2C_REG(bus, I2C_CON) = (1<<15)|(1<<10)|(1<<9)|(1<<1)|(1<<0); // enable, master, transmit, STP, STT + + time_t t = current_time(); + + const uint8_t *ptr = (const uint8_t *)buf; + for(;;) { + uint16_t stat = I2C_REG(bus, I2C_STAT); + if (stat & (1<<1)) { + // NACK +// printf("NACK\n"); + err = -1; + goto out; + } + if (stat & (1<<0)) { + // AL (arbitration lost) +// printf("arbitration lost!\n"); + err = -1; + goto out; + } + if (stat & (1<<2)) { + // ARDY +// printf("ARDY, completed\n"); + break; + } + if (stat & (1<<4)) { + // RRDY +// printf("XRDY\n"); + + // transmit a byte + *REG8(I2C_REG_ADDR(bus, I2C_DATA)) = *ptr; + ptr++; + } + I2C_REG(bus, I2C_STAT) = stat; + + if (current_time() - t > I2C_TIMEOUT) { +// printf("i2c timeout\n"); + err = ERR_TIMED_OUT; + goto out; + } + } + + err = 0; + +out: + I2C_REG(bus, I2C_STAT) = 0xffff; + I2C_REG(bus, I2C_CNT) = 0; + + return err; +} + +int i2c_receive(int bus, uint8_t address, void *buf, size_t count) +{ + int err; + + LTRACEF("bus %d, address 0x%hhx, buf %p, count %zd\n", bus, address, buf, count); + + i2c_wait_for_bb(bus); + + I2C_REG(bus, I2C_SA) = address; + I2C_REG(bus, I2C_CNT) = count; + I2C_REG(bus, I2C_CON) = (1<<15)|(1<<10)|(1<<1)|(1<<0); // enable, master, STP, STT + + time_t t = current_time(); + + uint8_t *ptr = (uint8_t *)buf; + for(;;) { + uint16_t stat = I2C_REG(bus, I2C_STAT); + if (stat & (1<<1)) { + // NACK +// printf("NACK\n"); + err = -1; + goto out; + } + if (stat & (1<<0)) { + // AL (arbitration lost) +// printf("arbitration lost!\n"); + err = -1; + goto out; + } + if (stat & (1<<2)) { + // ARDY +// printf("ARDY, completed\n"); + break; + } + if (stat & (1<<3)) { + // RRDY +// printf("RRDY\n"); + + // read a byte, since our fifo threshold is set to 1 byte + *ptr = *REG8(I2C_REG_ADDR(bus, I2C_DATA)); + ptr++; + } + I2C_REG(bus, I2C_STAT) = stat; + + if (current_time() - t > I2C_TIMEOUT) { +// printf("i2c timeout\n"); + err = ERR_TIMED_OUT; + goto out; + } + } + + err = 0; + +out: + I2C_REG(bus, I2C_STAT) = 0xffff; + I2C_REG(bus, I2C_CNT) = 0; + + return err; +} + +int i2c_write_reg(int bus, uint8_t address, uint8_t reg, uint8_t val) +{ + uint8_t buf[2]; + + buf[0] = reg; + buf[1] = val; + + return i2c_transmit(bus, address, buf, 2); +} + +int i2c_read_reg(int bus, uint8_t address, uint8_t reg, uint8_t *val) +{ + int err = i2c_transmit(bus, address, ®, 1); + if (err < 0) + return err; + + return i2c_receive(bus, address, val, 1); +} + + +void i2c_init_early(void) +{ + LTRACE_ENTRY; + + /* enable clocks on i2c 0-2 */ + RMWREG32(CM_FCLKEN1_CORE, 15, 3, 0x7), + RMWREG32(CM_ICLKEN1_CORE, 15, 3, 0x7), + + i2c_reset_bus(0); + i2c_reset_bus(1); + i2c_reset_bus(2); + +#if 0 + // write something into a reg + char buf[2]; + i2c_write_reg(0, 0x4b, 0x14, 0x99); + i2c_write_reg(0, 0x4b, 0x15, 0x98); + + i2c_read_reg(0, 0x4b, 0x15, buf); + printf("0x%hhx\n", buf[0]); + i2c_read_reg(0, 0x4b, 0x14, buf); + printf("0x%hhx\n", buf[0]); + + int i; + for (i=0; i < 255; i++) { + char buf[1]; + buf[0] = i; + i2c_transmit(0, 0x4b, buf, 1); + i2c_receive(0, 0x4b, buf, sizeof(buf)); + printf("0x%hhx\n", buf[0]); + } +#endif + + LTRACE_EXIT; +} + +void i2c_init(void) +{ +} + +#if WITH_LIB_CONSOLE + +#include + +static int cmd_i2c(int argc, const cmd_args *argv); + +STATIC_COMMAND_START + { "i2c", "i2c read/write commands", &cmd_i2c }, +STATIC_COMMAND_END(i2c); + +static int cmd_i2c(int argc, const cmd_args *argv) +{ + int err; + + if (argc < 5) { + printf("not enough arguments\n"); +usage: + printf("%s read_reg \n", argv[0].str); + printf("%s write_reg \n", argv[0].str); + return -1; + } + + int bus = argv[2].u; + uint8_t i2c_address = argv[3].u; + + if (!strcmp(argv[1].str, "read_reg")) { + uint8_t reg = argv[4].u; + uint8_t val; + + err = i2c_read_reg(bus, i2c_address, reg, &val); + printf("i2c_read_reg err %d, val 0x%hhx\n", err, val); + } else if (!strcmp(argv[1].str, "write_reg")) { + uint8_t reg = argv[4].u; + uint8_t val = argv[5].u; + err = i2c_write_reg(bus, i2c_address, reg, val); + printf("i2c_write_reg err %d\n", err); + } else { + printf("unrecognized subcommand\n"); + goto usage; + } + + return 0; +} + +#endif // WITH_APP_CONSOLE + + diff --git a/lk/platform/omap3/include/platform/omap3.h b/lk/platform/omap3/include/platform/omap3.h new file mode 100644 index 0000000..4a2534e --- /dev/null +++ b/lk/platform/omap3/include/platform/omap3.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __PLATFORM_OMAP3_H +#define __PLATFORM_OMAP3_H + +#define SDRAM_BASE 0x80000000 + +#define L4_BASE 0x48000000 +#define L4_WKUP_BASE 0x48300000 +#define L4_PER_BASE 0x49000000 +#define L4_EMU_BASE 0x54000000 +#define GFX_BASE 0x50000000 +#define L3_BASE 0x68000000 +#define SMS_BASE 0x6C000000 +#define SDRC_BASE 0x6D000000 +#define GPMC_BASE 0x6E000000 +#define SCM_BASE 0x48002000 + +/* clocks */ +#define CM_CLKSEL_PER (L4_BASE + 0x5040) + +/* PRCM */ +#define CM_FCLKEN_IVA2 (L4_BASE + 0x4000) +#define CM_CLKEN_PLL_IVA2 (L4_BASE + 0x4004) +#define CM_IDLEST_PLL_IVA2 (L4_BASE + 0x4024) +#define CM_CLKSEL1_PLL_IVA2 (L4_BASE + 0x4040) +#define CM_CLKSEL2_PLL_IVA2 (L4_BASE + 0x4044) +#define CM_CLKEN_PLL_MPU (L4_BASE + 0x4904) +#define CM_IDLEST_PLL_MPU (L4_BASE + 0x4924) +#define CM_CLKSEL1_PLL_MPU (L4_BASE + 0x4940) +#define CM_CLKSEL2_PLL_MPU (L4_BASE + 0x4944) +#define CM_FCLKEN1_CORE (L4_BASE + 0x4a00) +#define CM_ICLKEN1_CORE (L4_BASE + 0x4a10) +#define CM_ICLKEN2_CORE (L4_BASE + 0x4a14) +#define CM_CLKSEL_CORE (L4_BASE + 0x4a40) +#define CM_FCLKEN_GFX (L4_BASE + 0x4b00) +#define CM_ICLKEN_GFX (L4_BASE + 0x4b10) +#define CM_CLKSEL_GFX (L4_BASE + 0x4b40) +#define CM_FCLKEN_WKUP (L4_BASE + 0x4c00) +#define CM_ICLKEN_WKUP (L4_BASE + 0x4c10) +#define CM_CLKSEL_WKUP (L4_BASE + 0x4c40) +#define CM_IDLEST_WKUP (L4_BASE + 0x4c20) +#define CM_CLKEN_PLL (L4_BASE + 0x4d00) +#define CM_IDLEST_CKGEN (L4_BASE + 0x4d20) +#define CM_CLKSEL1_PLL (L4_BASE + 0x4d40) +#define CM_CLKSEL2_PLL (L4_BASE + 0x4d44) +#define CM_CLKSEL3_PLL (L4_BASE + 0x4d48) +#define CM_FCLKEN_DSS (L4_BASE + 0x4e00) +#define CM_ICLKEN_DSS (L4_BASE + 0x4e10) +#define CM_CLKSEL_DSS (L4_BASE + 0x4e40) +#define CM_FCLKEN_CAM (L4_BASE + 0x4f00) +#define CM_ICLKEN_CAM (L4_BASE + 0x4f10) +#define CM_CLKSEL_CAM (L4_BASE + 0x4F40) +#define CM_FCLKEN_PER (L4_BASE + 0x5000) +#define CM_ICLKEN_PER (L4_BASE + 0x5010) +#define CM_CLKSEL_PER (L4_BASE + 0x5040) +#define CM_CLKSEL1_EMU (L4_BASE + 0x5140) + +#define PRM_CLKSEL (L4_BASE + 0x306d40) +#define PRM_RSTCTRL (L4_BASE + 0x307250) +#define PRM_CLKSRC_CTRL (L4_BASE + 0x307270) + +/* General Purpose Timers */ +#define OMAP34XX_GPT1 (L4_BASE + 0x318000) +#define OMAP34XX_GPT2 (L4_BASE + 0x1032000) +#define OMAP34XX_GPT3 (L4_BASE + 0x1034000) +#define OMAP34XX_GPT4 (L4_BASE + 0x1036000) +#define OMAP34XX_GPT5 (L4_BASE + 0x1038000) +#define OMAP34XX_GPT6 (L4_BASE + 0x103A000) +#define OMAP34XX_GPT7 (L4_BASE + 0x103C000) +#define OMAP34XX_GPT8 (L4_BASE + 0x103E000) +#define OMAP34XX_GPT9 (L4_BASE + 0x1040000) +#define OMAP34XX_GPT10 (L4_BASE + 0x86000) +#define OMAP34XX_GPT11 (L4_BASE + 0x88000) +#define OMAP34XX_GPT12 (L4_BASE + 0x304000) + +#define TIDR 0x00 +#define TIOCP_CFG 0x10 +#define TISTAT 0x14 +#define TISR 0x18 +#define TIER 0x1C +#define TWER 0x20 +#define TCLR 0x24 +#define TCRR 0x28 +#define TLDR 0x2C +#define TTGR 0x30 +#define TWPS 0x34 +#define TMAR 0x38 +#define TCAR1 0x3C +#define TSICR 0x40 +#define TCAR2 0x44 +#define TPIR 0x48 +#define TNIR 0x4C +#define TCVR 0x50 +#define TOCR 0x54 +#define TOWR 0x58 + +/* WatchDog Timers (1 secure, 3 GP) */ +#define WD1_BASE (0x4830C000) +#define WD2_BASE (0x48314000) +#define WD3_BASE (0x49030000) + +#define WIDR 0x00 +#define WD_SYSCONFIG 0x10 +#define WD_SYSSTATUS 0x14 +#define WISR 0x18 +#define WIER 0x1C +#define WCLR 0x24 +#define WCRR 0x28 +#define WLDR 0x2C +#define WTGR 0x30 +#define WWPS 0x34 +#define WSPR 0x48 + +#define W_PEND_WCLR (1<<0) +#define W_PEND_WCRR (1<<1) +#define W_PEND_WLDR (1<<2) +#define W_PEND_WTGR (1<<3) +#define W_PEND_WSPR (1<<4) + +#define WD_UNLOCK1 0xAAAA +#define WD_UNLOCK2 0x5555 + +/* 32KTIMER */ +#define TIMER32K_BASE (L4_BASE + 0x320000) +#define TIMER32K_REV (TIMER32K_BASE + 0x00) +#define TIMER32K_CR (TIMER32K_BASE + 0x10) + +/* UART */ +#define OMAP_UART1_BASE (L4_BASE + 0x6a000) +#define OMAP_UART2_BASE (L4_BASE + 0x6c000) +#define OMAP_UART3_BASE (L4_BASE + 0x01020000) + +#define UART_RHR 0 +#define UART_THR 0 +#define UART_DLL 0 +#define UART_IER 1 +#define UART_DLH 1 +#define UART_IIR 2 +#define UART_FCR 2 +#define UART_EFR 2 +#define UART_LCR 3 +#define UART_MCR 4 +#define UART_LSR 5 +#define UART_MSR 6 +#define UART_TCR 6 +#define UART_SPR 7 +#define UART_TLR 7 +#define UART_MDR1 8 +#define UART_MDR2 9 +#define UART_SFLSR 10 +#define UART_RESUME 11 +#define UART_TXFLL 10 +#define UART_TXFLH 11 +#define UART_SFREGL 12 +#define UART_SFREGH 13 +#define UART_RXFLL 12 +#define UART_RXFLH 13 +#define UART_BLR 14 +#define UART_UASR 14 +#define UART_ACREG 15 +#define UART_SCR 16 +#define UART_SSR 17 +#define UART_EBLR 18 +#define UART_MVR 19 +#define UART_SYSC 20 + +/* MPU INTC */ +#define INTC_BASE (L4_BASE + 0x200000) +#define INTC_REVISION (INTC_BASE + 0x000) +#define INTC_SYSCONFIG (INTC_BASE + 0x010) +#define INTC_SYSSTATUS (INTC_BASE + 0x014) +#define INTC_SIR_IRQ (INTC_BASE + 0x040) +#define INTC_SIR_FIQ (INTC_BASE + 0x044) +#define INTC_CONTROL (INTC_BASE + 0x048) +#define INTC_PROTECTION (INTC_BASE + 0x04C) +#define INTC_IDLE (INTC_BASE + 0x050) +#define INTC_IRQ_PRIORITY (INTC_BASE + 0x060) +#define INTC_FIQ_PRIORITY (INTC_BASE + 0x064) +#define INTC_THRESHOLD (INTC_BASE + 0x068) +#define INTC_ITR(n) (INTC_BASE + 0x080 + (n) * 0x20) +#define INTC_MIR(n) (INTC_BASE + 0x084 + (n) * 0x20) +#define INTC_MIR_CLEAR(n) (INTC_BASE + 0x088 + (n) * 0x20) +#define INTC_MIR_SET(n) (INTC_BASE + 0x08C + (n) * 0x20) +#define INTC_ISR_SET(n) (INTC_BASE + 0x090 + (n) * 0x20) +#define INTC_ISR_CLEAR(n) (INTC_BASE + 0x094 + (n) * 0x20) +#define INTC_PENDING_IRQ(n) (INTC_BASE + 0x098 + (n) * 0x20) +#define INTC_PENDING_FIQ(n) (INTC_BASE + 0x09C + (n) * 0x20) +#define INTC_ILR(n) (INTC_BASE + 0x100 + (n) * 4) + +/* interrupts */ +#define INT_VECTORS 96 +#define GPT2_IRQ 38 + +/* HS USB */ +#define USB_HS_BASE (L4_BASE + 0xab000) + +/* USB OTG */ +#define OTG_BASE (L4_BASE + 0xab400) + +#define OTG_REVISION (OTG_BASE + 0x00) +#define OTG_SYSCONFIG (OTG_BASE + 0x04) +#define OTG_SYSSTATUS (OTG_BASE + 0x08) +#define OTG_INTERFSEL (OTG_BASE + 0x0C) +#define OTG_SIMENABLE (OTG_BASE + 0x10) +#define OTG_FORCESTDBY (OTG_BASE + 0x14) + +/* I2C */ +#define I2C1_BASE (L4_BASE + 0x70000) +#define I2C2_BASE (L4_BASE + 0x72000) +#define I2C3_BASE (L4_BASE + 0x60000) + +#define I2C_REV (0x00) +#define I2C_IE (0x04) +#define I2C_STAT (0x08) +#define I2C_WE (0x0C) +#define I2C_SYSS (0x10) +#define I2C_BUF (0x14) +#define I2C_CNT (0x18) +#define I2C_DATA (0x1C) +#define I2C_SYSC (0x20) +#define I2C_CON (0x24) +#define I2C_OA0 (0x28) +#define I2C_SA (0x2C) +#define I2C_PSC (0x30) +#define I2C_SCLL (0x34) +#define I2C_SCLH (0x38) +#define I2C_SYSTEST (0x3C) +#define I2C_BUFSTAT (0x40) +#define I2C_OA1 (0x44) +#define I2C_OA2 (0x48) +#define I2C_OA3 (0x4C) +#define I2C_ACTOA (0x50) +#define I2C_SBLOCK (0x54) + +#endif + diff --git a/lk/platform/omap3/interrupts.c b/lk/platform/omap3/interrupts.c new file mode 100644 index 0000000..77c632d --- /dev/null +++ b/lk/platform/omap3/interrupts.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include +#include "platform_p.h" +#include + +struct int_handler_struct { + int_handler handler; + void *arg; +}; + +static struct int_handler_struct int_handler_table[INT_VECTORS]; + +#define vectorToController(vector) ((vector) / 32) + +void platform_init_interrupts(void) +{ + unsigned int i; + + // reset the controller + *REG32(INTC_SYSCONFIG) = 0x2; // start a reset + while ((*REG32(INTC_SYSSTATUS) & 0x1) == 0) + ; + + // mask all interrupts + *REG32(INTC_MIR(0)) = 0xffffffff; + *REG32(INTC_MIR(1)) = 0xffffffff; + *REG32(INTC_MIR(2)) = 0xffffffff; + + // set up each of the interrupts + for (i = 0; i < INT_VECTORS; i++) { + // set each vector up as high priority IRQ + *REG32(INTC_ILR(i)) = 0; + //*ICReg(i / 32, INTCON_ILR_BASE + 4*(i%32)) = ((level_trigger[i/32] & (1<<(i%32))) ? (1<<1) : (0<<1)) | 0; + } + + // disable the priority threshold + *REG32(INTC_THRESHOLD) = 0xff; + + // clear any pending sw interrupts + *REG32(INTC_ISR_CLEAR(0)) = 0xffffffff; + *REG32(INTC_ISR_CLEAR(1)) = 0xffffffff; + *REG32(INTC_ISR_CLEAR(2)) = 0xffffffff; + + // globally unmask interrupts + *REG32(INTC_CONTROL) = 3; // reset and enable the controller +} + +status_t mask_interrupt(unsigned int vector) +{ + if (vector >= INT_VECTORS) + return ERR_INVALID_ARGS; + +// dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector); + + enter_critical_section(); + + *REG32(INTC_MIR_SET(vectorToController(vector))) = 1 << (vector % 32); + + exit_critical_section(); + + return NO_ERROR; +} + + +void platform_mask_irqs(void) +{ + int i; + for (i=0; i= INT_VECTORS) + return ERR_INVALID_ARGS; + +// dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector); + + enter_critical_section(); + + *REG32(INTC_MIR_CLEAR(vectorToController(vector))) = 1 << (vector % 32); + + exit_critical_section(); + + return NO_ERROR; +} + +enum handler_return platform_irq(struct arm_iframe *frame) +{ + // get the current vector + unsigned int vector; + + // read the currently active IRQ + vector = *REG32(INTC_SIR_IRQ) & 0x7f; + +// TRACEF("spsr 0x%x, pc 0x%x, currthread %p, vector %d, handler %p\n", frame->spsr, frame->pc, current_thread, vector, int_handler_table[vector].handler); + +#if THREAD_STATS + thread_stats.interrupts++; +#endif + + // deliver the interrupt + enum handler_return ret; + + ret = INT_NO_RESCHEDULE; + if (int_handler_table[vector].handler) + ret = int_handler_table[vector].handler(int_handler_table[vector].arg); + + // ack the interrupt + *REG32(INTC_CONTROL) = 0x1; + + return ret; +} + +void platform_fiq(struct arm_iframe *frame) +{ + PANIC_UNIMPLEMENTED; +} + +void register_int_handler(unsigned int vector, int_handler handler, void *arg) +{ + if (vector >= INT_VECTORS) + panic("register_int_handler: vector out of range %d\n", vector); + + enter_critical_section(); + + int_handler_table[vector].arg = arg; + int_handler_table[vector].handler = handler; + + exit_critical_section(); +} + + diff --git a/lk/platform/omap3/platform.c b/lk/platform/omap3/platform.c new file mode 100644 index 0000000..cba7a26 --- /dev/null +++ b/lk/platform/omap3/platform.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 "platform_p.h" +#include +#include +#include +#include + +void platform_init_mmu_mappings(void) +{ + /* do some memory map initialization */ + addr_t addr; + arm_mmu_map_section(SDRAM_BASE, 0, MMU_FLAG_CACHED|MMU_FLAG_BUFFERED); + for (addr = SDRAM_BASE; addr < SDRAM_BASE + SDRAM_SIZE; addr += (1024*1024)) { + arm_mmu_map_section(addr, addr, MMU_FLAG_CACHED|MMU_FLAG_BUFFERED|MMU_FLAG_READWRITE); + } +} + +void platform_early_init(void) +{ + /* initialize the interrupt controller */ + platform_init_interrupts(); + + /* initialize the timer block */ + platform_init_timer(); + + /* initialize the uart */ + uart_init_early(); + + i2c_init_early(); +} + +void platform_init(void) +{ + i2c_init(); + + uart_init(); + + usbc_init(); +} + diff --git a/lk/platform/omap3/platform_p.h b/lk/platform/omap3/platform_p.h new file mode 100644 index 0000000..872ea2b --- /dev/null +++ b/lk/platform/omap3/platform_p.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __PLATFORM_P_H +#define __PLATFORM_P_H + +void platform_init_interrupts(void); +void platform_init_timer(void); + +#endif + diff --git a/lk/platform/omap3/rules.mk b/lk/platform/omap3/rules.mk new file mode 100644 index 0000000..8d80d4b --- /dev/null +++ b/lk/platform/omap3/rules.mk @@ -0,0 +1,37 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +ARCH := arm +ARM_CPU := cortex-a8 +CPU := generic + +DEVS += usb + +# provides a few devices +DEFINES += \ + WITH_DEV_USBC=1 \ + WITH_DEV_UART=1 + +MODULES += \ + dev/usb + +INCLUDES += \ + -I$(LOCAL_DIR)/include + +OBJS += \ + $(LOCAL_DIR)/cpu_early_init.Ao \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/i2c.o \ + $(LOCAL_DIR)/interrupts.o \ + $(LOCAL_DIR)/platform.o \ + $(LOCAL_DIR)/timer.o \ + $(LOCAL_DIR)/uart.o \ + $(LOCAL_DIR)/usbc.o + +MEMBASE := 0x80000000 + +DEFINES += MEMBASE=$(MEMBASE) \ + WITH_CPU_EARLY_INIT=1 + +LINKER_SCRIPT += \ + $(BUILDDIR)/system-onesegment.ld + diff --git a/lk/platform/omap3/timer.c b/lk/platform/omap3/timer.c new file mode 100644 index 0000000..f101f50 --- /dev/null +++ b/lk/platform/omap3/timer.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include +#include +#include "platform_p.h" + +static time_t tick_interval; +static platform_timer_callback t_callback; +static void *callback_arg; + +/* timer 2 */ +static const ulong timer_base = OMAP34XX_GPT2; + +#define TIMER_TICK_RATE 32768 + +#define TIMER_REG(reg) *REG32(timer_base + (reg)) + +status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, time_t interval) +{ + enter_critical_section(); + + t_callback = callback; + callback_arg = arg; + tick_interval = interval; + uint32_t ticks_per_interval = (uint64_t)interval * TIMER_TICK_RATE / 1000; // interval is in ms + + TIMER_REG(TCLR) = 0; // stop the timer + TIMER_REG(TLDR) = -ticks_per_interval; + TIMER_REG(TTGR) = 1; + TIMER_REG(TIER) = 0x2; + TIMER_REG(TCLR) = 0x3; // autoreload, start + + unmask_interrupt(GPT2_IRQ); + + exit_critical_section(); + + return NO_ERROR; +} + +time_t current_time(void) +{ + uint32_t delta_ticks; + uint32_t delta_ticks2; + +retry: + delta_ticks = *REG32(TIMER32K_CR); + delta_ticks2 = *REG32(TIMER32K_CR); + if (delta_ticks2 != delta_ticks) + goto retry; + + uint64_t longtime = delta_ticks * 1000ULL / 32768ULL; + + return (time_t)longtime; +} + +bigtime_t current_time_hires(void) +{ + uint32_t delta_ticks; + uint32_t delta_ticks2; + +retry: + delta_ticks = *REG32(TIMER32K_CR); + delta_ticks2 = *REG32(TIMER32K_CR); + if (delta_ticks2 != delta_ticks) + goto retry; + + uint64_t longtime = delta_ticks * 1000000ULL / 32768ULL; + + return (bigtime_t)longtime; +} +static enum handler_return os_timer_tick(void *arg) +{ + TIMER_REG(TISR) = TIMER_REG(TISR); + + return t_callback(callback_arg, current_time()); +} + +void platform_init_timer(void) +{ + /* GPT2 */ + RMWREG32(CM_CLKSEL_PER, 0, 1, 1); + RMWREG32(CM_ICLKEN_PER, 3, 1, 1); + RMWREG32(CM_FCLKEN_PER, 3, 1, 1); + + // reset the GP timer + TIMER_REG(TIOCP_CFG) = 0x2; + while ((TIMER_REG(TISTAT) & 1) == 0) + ; + + // set GPT2-9 clock inputs over to 32k + *REG32(CM_CLKSEL_PER) = 0; + + // disable ints + TIMER_REG(TIER) = 0; + TIMER_REG(TISR) = 0x7; // clear any pending bits + + // XXX make sure 32K timer is running + + register_int_handler(GPT2_IRQ, &os_timer_tick, NULL); +} + +void platform_halt_timers(void) +{ + TIMER_REG(TCLR) = 0; +} + diff --git a/lk/platform/omap3/uart.c b/lk/platform/omap3/uart.c new file mode 100644 index 0000000..27eee9f --- /dev/null +++ b/lk/platform/omap3/uart.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +struct uart_stat { + addr_t base; + uint shift; +}; + +static struct uart_stat uart[3] = { + { OMAP_UART1_BASE, 2 }, + { OMAP_UART2_BASE, 2 }, + { OMAP_UART3_BASE, 2 }, +}; + +static inline void write_uart_reg(int port, uint reg, unsigned char data) +{ + *(volatile unsigned char *)(uart[port].base + (reg << uart[port].shift)) = data; +} + +static inline unsigned char read_uart_reg(int port, uint reg) +{ + return *(volatile unsigned char *)(uart[port].base + (reg << uart[port].shift)); +} + +#define LCR_8N1 0x03 + +#define FCR_FIFO_EN 0x01 /* Fifo enable */ +#define FCR_RXSR 0x02 /* Receiver soft reset */ +#define FCR_TXSR 0x04 /* Transmitter soft reset */ + +#define MCR_DTR 0x01 +#define MCR_RTS 0x02 +#define MCR_DMA_EN 0x04 +#define MCR_TX_DFR 0x08 + +#define LCR_WLS_MSK 0x03 /* character length select mask */ +#define LCR_WLS_5 0x00 /* 5 bit character length */ +#define LCR_WLS_6 0x01 /* 6 bit character length */ +#define LCR_WLS_7 0x02 /* 7 bit character length */ +#define LCR_WLS_8 0x03 /* 8 bit character length */ +#define LCR_STB 0x04 /* Number of stop Bits, off = 1, on = 1.5 or 2) */ +#define LCR_PEN 0x08 /* Parity eneble */ +#define LCR_EPS 0x10 /* Even Parity Select */ +#define LCR_STKP 0x20 /* Stick Parity */ +#define LCR_SBRK 0x40 /* Set Break */ +#define LCR_BKSE 0x80 /* Bank select enable */ + +#define LSR_DR 0x01 /* Data ready */ +#define LSR_OE 0x02 /* Overrun */ +#define LSR_PE 0x04 /* Parity error */ +#define LSR_FE 0x08 /* Framing error */ +#define LSR_BI 0x10 /* Break */ +#define LSR_THRE 0x20 /* Xmit holding register empty */ +#define LSR_TEMT 0x40 /* Xmitter empty */ +#define LSR_ERR 0x80 /* Error */ + +#define LCRVAL LCR_8N1 /* 8 data, 1 stop, no parity */ +#define MCRVAL (MCR_DTR | MCR_RTS) /* RTS/DTR */ +#define FCRVAL (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR) /* Clear & enable FIFOs */ + +#define V_NS16550_CLK (48000000) /* 48MHz (APLL96/2) */ + +void uart_init_port(int port, uint baud) +{ + /* clear the tx & rx fifo and disable */ + uint16_t baud_divisor = (V_NS16550_CLK / 16 / baud); + + write_uart_reg(port, UART_IER, 0); + write_uart_reg(port, UART_LCR, LCR_BKSE | LCRVAL); // config mode A + write_uart_reg(port, UART_DLL, baud_divisor & 0xff); + write_uart_reg(port, UART_DLH, (baud_divisor >> 8) & 0xff); + write_uart_reg(port, UART_LCR, LCRVAL); // operational mode + write_uart_reg(port, UART_MCR, MCRVAL); + write_uart_reg(port, UART_FCR, FCRVAL); + write_uart_reg(port, UART_MDR1, 0); // UART 16x mode + +// write_uart_reg(port, UART_LCR, 0xBF); // config mode B +// write_uart_reg(port, UART_EFR, (1<<7)|(1<<6)); // hw flow control +// write_uart_reg(port, UART_LCR, LCRVAL); // operational mode +} + +void uart_init_early(void) +{ + /* UART1 */ + RMWREG32(CM_FCLKEN1_CORE, 13, 1, 1), + RMWREG32(CM_ICLKEN1_CORE, 13, 1, 1), + + /* UART2 */ + RMWREG32(CM_FCLKEN1_CORE, 14, 1, 1), + RMWREG32(CM_ICLKEN1_CORE, 14, 1, 1), + + /* UART3 */ + RMWREG32(CM_FCLKEN_PER, 11, 1, 1), + RMWREG32(CM_ICLKEN_PER, 11, 1, 1), + + uart_init_port(DEBUG_UART, 115200); +} + +void uart_init(void) +{ +} + +int uart_putc(int port, char c ) +{ + while (!(read_uart_reg(port, UART_LSR) & (1<<6))) // wait for the last char to get out + ; + write_uart_reg(port, UART_THR, c); + return 0; +} + +int uart_getc(int port, bool wait) /* returns -1 if no data available */ +{ + if (wait) { + while (!(read_uart_reg(port, UART_LSR) & (1<<0))) // wait for data to show up in the rx fifo + ; + } else { + if (!(read_uart_reg(port, UART_LSR) & (1<<0))) + return -1; + } + return read_uart_reg(port, UART_RHR); +} + +void uart_flush_tx(int port) +{ + while (!(read_uart_reg(port, UART_LSR) & (1<<6))) // wait for the last char to get out + ; +} + +void uart_flush_rx(int port) +{ + // empty the rx fifo + while (read_uart_reg(port, UART_LSR) & (1<<0)) { + volatile char c = read_uart_reg(port, UART_RHR); + (void)c; + } +} + + diff --git a/lk/platform/omap3/usbc.c b/lk/platform/omap3/usbc.c new file mode 100644 index 0000000..5bb9906 --- /dev/null +++ b/lk/platform/omap3/usbc.c @@ -0,0 +1,882 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include +#include +#include + +#define LOCAL_TRACE 0 + +#define hsusb_reg8(reg) *REG8(USB_HS_BASE + (reg)) +#define hsusb_reg16(reg) *REG16(USB_HS_BASE + (reg)) +#define hsusb_reg32(reg) *REG32(USB_HS_BASE + (reg)) + +/* registers */ +#define FADDR 0x0 +#define POWER 0x1 +#define INTRTX 0x2 +#define INTRRX 0x4 +#define INTRTXE 0x6 +#define INTRRXE 0x8 +#define INTRUSB 0xa +#define INTRUSBE 0xb +#define FRAME 0xc +#define INDEX 0xe +#define TESTMODE 0xf + +// indexed endpoint regs +#define IDX_TXMAXP 0x10 +#define IDX_TXCSR 0x12 +#define IDX_TXCSRL 0x12 +#define IDX_TXCSRH 0x13 +#define IDX_RXMAXP 0x14 +#define IDX_RXCSR 0x16 +#define IDX_RXCSRL 0x16 +#define IDX_RXCSRH 0x17 +#define IDX_RXCOUNT 0x18 +#define IDX_FIFOSIZE 0x1f + +// if endpoint 0 is selected +#define IDX_CSR0 0x12 +#define IDX_CONFIGDATA 0x1f + +// endpoint FIFOs +#define FIFOBASE 0x20 + +#define DEVCTL 0x60 +#define TXFIFOSZ 0x62 +#define RXFIFOSZ 0x63 +#define TXFIFOADD 0x64 +#define RXFIFOADD 0x66 +#define HWVERS 0x6c +#define EPINFO 0x78 +#define RAMINFO 0x79 +#define LINKINFO 0x7a + +static void setup_dynamic_fifos(void); + +enum usb_state { + USB_DEFAULT = 0, + USB_ADDRESS, + USB_CONFIGURED +}; + +struct usbc_ep { + bool active; + uint width; + uint blocksize; + + /* current data buffer */ + usbc_transfer *transfer; + + /* callback when tx or rx happens on the endpoint */ + int (*callback)(ep_t endpoint, usbc_callback_op_t op, usbc_transfer *transfer); +}; + +struct usbc_stat { + bool active; + enum usb_state state; + uint8_t active_config; + + // callback for device events + usb_callback callback; + + // ep0 pending tx + const void *ep0_tx_buf; + size_t ep0_tx_len; + uint ep0_tx_pos; + + struct usbc_ep inep[16]; // IN endpoints (device to host) + struct usbc_ep outep[16]; // OUT endpoint (host to device) +}; + +static struct usbc_stat *usbc; + +struct usbc_callback { + struct list_node node; + usb_callback callback; +}; + +static struct list_node usbc_callback_list; + +static void call_all_callbacks(usbc_callback_op_t op, const union usb_callback_args *arg) +{ + struct usbc_callback *cb; + + list_for_every_entry(&usbc_callback_list, cb, struct usbc_callback, node) { + LTRACEF("calling %p, op %d, arg %p\n", cb->callback, op, arg); + cb->callback(op, arg); + } +} + +static void print_usb_setup(const struct usb_setup *setup) +{ + printf("usb_setup:\n"); + printf("\ttype 0x%hhx\n", setup->request_type); + printf("\trequest 0x%hhx\n", setup->request); + printf("\tvalue 0x%hx\n", setup->value); + printf("\tindex 0x%hx\n", setup->index); + printf("\tlength 0x%hx\n", setup->length); +} + +static void select_ep(uint ep) +{ + DEBUG_ASSERT(ep < 16); + hsusb_reg8(INDEX) = ep; +} + +static void dump_ep_regs(uint ep) +{ +#if 0 + select_ep(ep); + + LTRACEF("%d txmaxp 0x%hx\n", ep, hsusb_reg16(IDX_TXMAXP)); + LTRACEF("%d rxmaxp 0x%hx\n", ep, hsusb_reg16(IDX_RXMAXP)); + LTRACEF("%d txfifosz 0x%hhx\n", ep, hsusb_reg8(TXFIFOSZ)); + LTRACEF("%d rxfifosz 0x%hhx\n", ep, hsusb_reg8(RXFIFOSZ)); + LTRACEF("%d txfifoadd 0x%hx\n", ep, hsusb_reg16(TXFIFOADD)); + LTRACEF("%d rxfifoadd 0x%hx\n", ep, hsusb_reg16(RXFIFOADD)); +#endif +} + +#define MULOF4(val) (((uint32_t)(val) & 0x3) == 0) + +static int read_ep_fifo(uint ep, void *_buf, size_t maxlen) +{ + char *buf = (void *)_buf; + + select_ep(ep); + + uint8_t fifo_reg = FIFOBASE + ep * 4; + size_t rxcount = hsusb_reg16(IDX_RXCOUNT); + + if (rxcount > maxlen) + rxcount = maxlen; + + if (MULOF4(buf) && MULOF4(rxcount)) { + uint i; + uint32_t *buf32 = (uint32_t *)_buf; + for (i=0; i < rxcount / 4; i++) { + buf32[i] = hsusb_reg32(fifo_reg); + } + } else { + /* slow path */ + uint i; + for (i=0; i < rxcount; i++) { + buf[i] = hsusb_reg8(fifo_reg); + } + } + + return rxcount; +} + +static int write_ep_fifo(uint ep, const void *_buf, size_t len) +{ + char *buf = (void *)_buf; + + select_ep(ep); + + uint8_t fifo_reg = FIFOBASE + ep * 4; + + if (MULOF4(buf) && MULOF4(len)) { + uint i; + uint32_t *buf32 = (uint32_t *)_buf; + for (i=0; i < len / 4; i++) { + hsusb_reg32(fifo_reg) = buf32[i]; + } + } else { + /* slow path */ + uint i; + for (i=0; i < len; i++) { + hsusb_reg8(fifo_reg) = buf[i]; + } + } + + return len; +} + +#undef MULOF4 + +void usbc_ep0_send(const void *buf, size_t len, size_t maxlen) +{ + LTRACEF("buf %p, len %zu, maxlen %zu\n", buf, len, maxlen); + + // trim the transfer + len = MIN(len, maxlen); + + size_t transfer_len = MIN(64, len); + + // write the first 64 bytes + write_ep_fifo(0, buf, transfer_len); + + // set txpktready + select_ep(0); + if (len > 64) { + // we have more data to send, don't mark data end + hsusb_reg16(IDX_CSR0) |= (1<<1); // TxPktRdy + + // save our position so we can continue + usbc->ep0_tx_buf = buf; + usbc->ep0_tx_pos = 64; + usbc->ep0_tx_len = len; + } else { + hsusb_reg16(IDX_CSR0) |= (1<<3) | (1<<1); // DataEnd, TxPktRdy + usbc->ep0_tx_buf = NULL; + } +} + +static void ep0_control_send_resume(void) +{ + DEBUG_ASSERT(usbc->ep0_tx_buf != NULL); + DEBUG_ASSERT(usbc->ep0_tx_len > usbc->ep0_tx_pos); + + LTRACEF("buf %p pos %d len %d\n", usbc->ep0_tx_buf, usbc->ep0_tx_pos, usbc->ep0_tx_len); + + size_t transfer_len = MIN(64, usbc->ep0_tx_len - usbc->ep0_tx_pos); + + write_ep_fifo(0, (const uint8_t *)usbc->ep0_tx_buf + usbc->ep0_tx_pos, transfer_len); + + usbc->ep0_tx_pos += transfer_len; + + if (usbc->ep0_tx_pos >= usbc->ep0_tx_len) { + // completes the transfer + hsusb_reg16(IDX_CSR0) |= (1<<3) | (1<<1); // DataEnd, TxPktRdy + usbc->ep0_tx_buf = NULL; + } else { + hsusb_reg16(IDX_CSR0) |= (1<<1); // TxPktRdy + } +} + +void usbc_ep0_ack(void) +{ + hsusb_reg16(IDX_CSR0) |= (1<<6)|(1<<3); // servicedrxpktrdy & dataend +} + +void usbc_ep0_stall(void) +{ + printf("USB STALL\n"); +} + +static void usb_shutdown_endpoints(void) +{ + // iterate through all the endpoints, cancelling any pending io and shut down the endpoint + ep_t i; + for (i=1; i < 16; i++) { + if (usbc->inep[i].active && usbc->inep[i].transfer) { + // pool's closed + usbc_transfer *t = usbc->inep[i].transfer; + usbc->inep[i].transfer = NULL; + t->result = USB_TRANSFER_RESULT_CANCELLED; + usbc->inep[i].callback(i, CB_EP_TRANSFER_CANCELLED, t); + } + if (usbc->outep[i].active && usbc->outep[i].transfer) { + // pool's closed + usbc_transfer *t = usbc->outep[i].transfer; + usbc->outep[i].transfer = NULL; + t->result = USB_TRANSFER_RESULT_CANCELLED; + usbc->outep[i].callback(i, CB_EP_TRANSFER_CANCELLED, t); + } + } + + // clear pending ep0 data + usbc->ep0_tx_buf = 0; +} + +static void usb_enable_endpoints(void) +{ + setup_dynamic_fifos(); +} + +static void usb_disconnect(void) +{ + // we've been disconnected + usbc->state = USB_DEFAULT; + usbc->active_config = 0; + + usb_shutdown_endpoints(); +} + +static void usb_reset(void) +{ + // this wipes out our endpoint interrupt disables + hsusb_reg16(INTRTXE) = (1<<0); + hsusb_reg16(INTRRXE) = 0; + + usb_shutdown_endpoints(); +} + +static int handle_ep_rx(int ep) +{ + struct usbc_ep *e = &usbc->outep[ep]; + + DEBUG_ASSERT(e->active); + + DEBUG_ASSERT(e->transfer); // can't rx to no transfer + usbc_transfer *t = e->transfer; + + uint rxcount = hsusb_reg16(IDX_RXCOUNT); + uint readcount = MIN(rxcount, t->buflen - t->bufpos); + readcount = MIN(readcount, e->blocksize); + + int len = read_ep_fifo(ep, (uint8_t *)t->buf + t->bufpos, readcount); + LTRACEF("read %d bytes from the fifo\n", len); + + // no more packet ready + hsusb_reg16(IDX_RXCSRL) &= ~(1<<0); // clear rxpktrdy + + t->bufpos += len; + + if (rxcount < e->blocksize || t->bufpos >= t->buflen) { + // we're done with this transfer, clear it and disable the endpoint + e->transfer = NULL; + hsusb_reg16(INTRRXE) &= ~(1<result = USB_TRANSFER_RESULT_OK; + + DEBUG_ASSERT(e->callback); + e->callback(ep, CB_EP_RXCOMPLETE, t); + + return 1; + } + + return 0; +} + +bool usbc_is_highspeed(void) +{ + return (hsusb_reg8(POWER) & (1<<4)) ? true : false; +} + +static enum handler_return hsusb_interrupt(void *arg) +{ + uint16_t intrtx = hsusb_reg16(INTRTX); + uint16_t intrrx = hsusb_reg16(INTRRX); + uint8_t intrusb = hsusb_reg8(INTRUSB); + enum handler_return ret = INT_NO_RESCHEDULE; + + LTRACEF("intrtx 0x%hx (0x%x), intrrx 0x%hx (0x%x), intrusb 0x%hhx, intrusbe 0x%hhx\n", + intrtx, hsusb_reg16(INTRTXE), intrrx, hsusb_reg16(INTRRXE), intrusb, hsusb_reg8(INTRUSBE)); + + dump_ep_regs(2); + + // look for global usb interrupts + intrusb &= hsusb_reg8(INTRUSBE); + if (intrusb) { + if (intrusb & (1<<0)) { + // suspend + TRACEF("suspend\n"); + call_all_callbacks(CB_SUSPEND, 0); + ret = INT_RESCHEDULE; + } + if (intrusb & (1<<1)) { + // resume + TRACEF("resume\n"); + call_all_callbacks(CB_RESUME, 0); + ret = INT_RESCHEDULE; + } + if (intrusb & (1<<2)) { + // reset + TRACEF("reset\n"); + TRACEF("high speed %d\n", hsusb_reg8(POWER) & (1<<4) ? 1 : 0); + call_all_callbacks(CB_RESET, 0); + usb_reset(); + ret = INT_RESCHEDULE; + } + if (intrusb & (1<<3)) { + // SOF + TRACEF("sof\n"); + } + if (intrusb & (1<<4)) { + // connect (host only) + TRACEF("connect\n"); + } + if (intrusb & (1<<5)) { + // disconnect + TRACEF("disconnect\n"); + call_all_callbacks(CB_DISCONNECT, 0); + usb_disconnect(); + ret = INT_RESCHEDULE; + } + if (intrusb & (1<<6)) { + // session request (A device only) + TRACEF("session request\n"); + } + if (intrusb & (1<<7)) { + // vbus error (A device only) + TRACEF("vbus error\n"); + } + } + + // look for endpoint 0 interrupt + if (intrtx & 1) { + select_ep(0); + uint16_t csr = hsusb_reg16(IDX_CSR0); + LTRACEF("ep0 csr 0x%hhx\n", csr); + + // clear the stall bit + if (csr & (1<<2)) + hsusb_reg16(IDX_CSR0) &= ~(1<<2); + + // do we have any pending tx data? + if (usbc->ep0_tx_buf != NULL) { + if (csr & (1<<4)) { // setup end + // we got an abort on the data transfer + usbc->ep0_tx_buf = NULL; + } else { + // send more data + ep0_control_send_resume(); + } + } + + // clear the setup end bit + if (csr & (1<<4)) { + hsusb_reg16(IDX_CSR0) |= (1<<7); // servicedsetupend + } + + if (csr & 0x1) { + // rxpktrdy + LTRACEF("ep0: rxpktrdy, count %d\n", hsusb_reg16(IDX_RXCOUNT)); + + struct usb_setup setup; + read_ep_fifo(0, (void *)&setup, sizeof(setup)); +// print_usb_setup(&setup); + + hsusb_reg16(IDX_CSR0) |= (1<<6); // servicedrxpktrdy + + union usb_callback_args args; + args.setup = &setup; + call_all_callbacks(CB_SETUP_MSG, &args); + + switch (setup.request) { + case SET_ADDRESS: { + LTRACEF("got SET_ADDRESS: value %d\n", setup.value); + dprintf(INFO, "usb: got assigned address %d\n", setup.value); + usbc_ep0_ack(); + + hsusb_reg8(FADDR) = setup.value; + if (setup.value == 0) + usbc->state = USB_DEFAULT; + else + usbc->state = USB_ADDRESS; + + break; + } + case SET_CONFIGURATION: + LTRACEF("got SET_CONFIGURATION, config %d\n", setup.value); + + if (setup.value == 0) { + if (usbc->state == USB_CONFIGURED) + usbc->state = USB_ADDRESS; + call_all_callbacks(CB_OFFLINE, 0); + } else { + usbc->state = USB_CONFIGURED; + call_all_callbacks(CB_ONLINE, 0); + } + usbc->active_config = setup.value; + ret = INT_RESCHEDULE; + + // set up all of the endpoints + usb_enable_endpoints(); + break; + } + } + } + + // handle endpoint interrupts + + // mask out ones we don't want to play with + intrtx &= hsusb_reg16(INTRTXE); + intrrx &= hsusb_reg16(INTRRXE); + + int i; + for (i=1; i < 16; i++) { + if (intrtx & (1<inep[i]; + + DEBUG_ASSERT(e->transfer); // interrupts shouldn't be enabled if there isn't a transfer queued + usbc_transfer *t = e->transfer; + + if (t->bufpos < t->buflen) { + // cram more stuff in the buffer + uint queuelen = MIN(e->blocksize, t->buflen - t->bufpos); + LTRACEF("writing more tx data into fifo: len %u, remaining %zu\n", queuelen, t->buflen - t->bufpos); + write_ep_fifo(i, (uint8_t *)t->buf + t->bufpos, queuelen); + t->bufpos += queuelen; + + // start the transfer + hsusb_reg16(IDX_TXCSR) |= (1<<0); // txpktrdy + } else { + // we're done, callback + e->transfer = NULL; + hsusb_reg16(INTRTXE) &= ~(1<result = USB_TRANSFER_RESULT_OK; + + DEBUG_ASSERT(e->callback); + e->callback(i, CB_EP_TXCOMPLETE, t); + ret = INT_RESCHEDULE; + } + } + if (intrrx & (1<outep[i]; + if (!e->active) { + // stall it + hsusb_reg16(IDX_RXCSR) |= (1<<6); // stall + hsusb_reg16(IDX_RXCSR) |= (1<<4); // flush fifo + panic("rx on inactive endpoint\n"); + continue; + } + + if (handle_ep_rx(i) > 0) + ret = INT_RESCHEDULE; + } + } + } + + return ret; +} + +static enum handler_return hsusb_dma_interrupt(void *arg) +{ + LTRACE; + + return INT_NO_RESCHEDULE; +} + +void usbc_setup_endpoint(ep_t ep, ep_dir_t dir, bool active, ep_callback callback, uint width, uint blocksize) +{ + DEBUG_ASSERT(ep != 0); + DEBUG_ASSERT(ep < 16); + DEBUG_ASSERT(dir == IN || dir == OUT); + + struct usbc_ep *e; + if (dir == IN) + e = &usbc->inep[ep]; + else + e = &usbc->outep[ep]; + + // for now we can only make active + e->active = active; + e->callback = callback; + e->width = width; + e->blocksize = blocksize; +} + +int usbc_queue_rx(ep_t ep, usbc_transfer *transfer) +{ + LTRACE; + struct usbc_ep *e = &usbc->outep[ep]; + + DEBUG_ASSERT(ep != 0); + DEBUG_ASSERT(ep < 16); + DEBUG_ASSERT(e->active); + + DEBUG_ASSERT(transfer); + DEBUG_ASSERT(transfer->buf); + + DEBUG_ASSERT(e->transfer == NULL); + + // can only queue up multiples of the endpoint blocksize + DEBUG_ASSERT(transfer->buflen >= e->blocksize && (transfer->buflen % e->blocksize) == 0); + + enter_critical_section(); + + if (usbc->state != USB_CONFIGURED) { + // can't transfer now + exit_critical_section(); + return -1; + } + + e->transfer = transfer; + + // make sure the ep is set up right +// select_ep(ep); +// hsusb_reg8(IDX_RXCSRH) = 0; + dump_ep_regs(ep); + + select_ep(ep); + if (hsusb_reg16(IDX_RXCSR) & (1<<0)) { + // packet already ready + LTRACEF("****packet already ready (%d)\n", hsusb_reg16(IDX_RXCOUNT)); + + int rc = handle_ep_rx(ep); + if (rc > 0) { + // the transfer was completed + goto done; + } + } + + // unmask irqs for this endpoint + hsusb_reg16(INTRRXE) |= (1<buf, transfer->buflen); + struct usbc_ep *e = &usbc->inep[ep]; + + DEBUG_ASSERT(ep != 0); + DEBUG_ASSERT(ep < 16); + DEBUG_ASSERT(e->active); + + DEBUG_ASSERT(e->transfer == NULL); + + enter_critical_section(); + + if (usbc->state != USB_CONFIGURED) { + // can't transfer now + exit_critical_section(); + return -1; + } + +e->transfer = transfer; + + select_ep(ep); + + // set this endpoint in tx mode +// hsusb_reg8(IDX_TXCSRH) = (1<<7)|(1<<5); // autoset, tx direction + dump_ep_regs(ep); + + // unmask irqs for this endpoint + hsusb_reg16(INTRTXE) |= (1<blocksize, transfer->buflen); + write_ep_fifo(ep, transfer->buf, queuelen); + transfer->bufpos = queuelen; + + // start the transfer + hsusb_reg16(IDX_TXCSR) |= (1<<0); // txpktrdy + } + + exit_critical_section(); + + return 0; +} + +int usbc_set_callback(usb_callback callback) +{ + DEBUG_ASSERT(callback != NULL); + + struct usbc_callback *cb = malloc(sizeof(struct usbc_callback)); + + enter_critical_section(); + + cb->callback = callback; + list_add_head(&usbc_callback_list, &cb->node); + + exit_critical_section(); + return 0; +} + +int usbc_set_active(bool active) +{ + LTRACEF("active %d\n", active); + if (active) { + DEBUG_ASSERT(!usbc->active); + + hsusb_reg8(POWER) |= (1<<6); // soft conn + twl4030_set_usb_pullup(true); + usbc->active = true; + } else { + hsusb_reg8(POWER) &= ~(1<<6); // soft conn + twl4030_set_usb_pullup(false); + usbc->active = false; + } + + return 0; +} + +static void setup_dynamic_fifos(void) +{ +// LTRACE; + +#if LOCAL_TRACE + uint8_t raminfo = hsusb_reg8(RAMINFO); + size_t ramsize = (1 << ((raminfo & 0xf) + 2)); + LTRACEF("%zd bytes of onboard ram\n", ramsize); +#endif + + uint32_t offset = 128; + + int highspeed = hsusb_reg8(POWER) & (1<<4); + + int i; + for (i=1; i < 16; i++) { + select_ep(i); + if (usbc->inep[i].active) { + hsusb_reg8(TXFIFOSZ) = (1<<4)|(0x6); // 512 byte, double buffered + hsusb_reg8(RXFIFOSZ) = 0; + hsusb_reg16(TXFIFOADD) = offset / 8; + hsusb_reg16(RXFIFOADD) = 0; + if (highspeed) { + hsusb_reg16(IDX_TXMAXP) = usbc->inep[i].width; + } else { + hsusb_reg16(IDX_TXMAXP) = (((usbc->inep[i].blocksize / 64) - 1) << 11) | 64; +// hsusb_reg16(IDX_TXMAXP) = 64; +// usbc->inep[i].blocksize = 64; + } + + hsusb_reg16(IDX_RXMAXP) = 0; + LTRACEF("%d: txmaxp 0x%hx\n", i, hsusb_reg16(IDX_TXMAXP)); + hsusb_reg8(IDX_TXCSRH) = (1<<5)|(1<<3); + hsusb_reg8(IDX_TXCSRL) = (1<<3); + hsusb_reg8(IDX_TXCSRL) = (1<<3); + offset += 512*2; + } else { + hsusb_reg8(TXFIFOSZ) = 0; + hsusb_reg16(TXFIFOADD) = 0; + hsusb_reg16(IDX_TXMAXP) = 0; + } + if (usbc->outep[i].active) { + hsusb_reg8(TXFIFOSZ) = 0; + hsusb_reg8(RXFIFOSZ) = (0<<4)|(0x6); // 512 byte, single buffered + hsusb_reg16(TXFIFOADD) = 0; + hsusb_reg16(RXFIFOADD) = offset / 8; + hsusb_reg16(IDX_TXMAXP) = 0; + if (highspeed) { + hsusb_reg16(IDX_RXMAXP) = usbc->inep[i].width; + } else { + hsusb_reg16(IDX_RXMAXP) = (((usbc->outep[i].blocksize / 64) - 1) << 11) | 64; +// hsusb_reg16(IDX_RXMAXP) = 64; +// usbc->outep[i].blocksize = 64; + } + LTRACEF("%d: rxmaxp 0x%hx\n", i, hsusb_reg16(IDX_RXMAXP)); + offset += 512; + hsusb_reg8(IDX_RXCSRH) = (1<<7); + hsusb_reg8(IDX_RXCSRL) = (1<<7); + +// LTRACEF("rxcsr 0x%hx\n", hsusb_reg16(IDX_RXCSR)); + } else { + hsusb_reg8(RXFIFOSZ) = 0; + hsusb_reg16(RXFIFOADD) = 0; + hsusb_reg16(IDX_RXMAXP) = 0; + } +// LTRACEF("%d txfifosz 0x%hhx\n", i, hsusb_reg8(TXFIFOSZ)); +// LTRACEF("%d rxfifosz 0x%hhx\n", i, hsusb_reg8(RXFIFOSZ)); +// LTRACEF("%d txfifoadd 0x%hx\n", i, hsusb_reg16(TXFIFOADD)); +// LTRACEF("%d rxfifoadd 0x%hx\n", i, hsusb_reg16(RXFIFOADD)); + } +} + +static void otg_reset(void) +{ + /* reset the chip */ + *REG32(OTG_SYSCONFIG) |= (1<<1); + while ((*REG32(OTG_SYSSTATUS) & 1) == 0) + ; + + /* power up the controller */ + *REG32(OTG_FORCESTDBY) = 0; // disable forced standby + *REG32(OTG_SYSCONFIG) &= ~(1<<1); // autoidle off + *REG32(OTG_SYSCONFIG) = (2<<12) | (2<<3) | (0<<0); // master in smart-standby, periph in smart-idle, autoidle off + + *REG32(OTG_SYSCONFIG) |= 1; // autoidle on + + *REG32(OTG_INTERFSEL) = 1; // 8 bit ULPI +} + +static void hsusb_init(void) +{ + LTRACE_ENTRY; + + // select endpoint 0 + dprintf(SPEW, "hwvers 0x%hx\n", hsusb_reg16(HWVERS)); + dprintf(SPEW, "epinfo 0x%hhx\n", hsusb_reg8(EPINFO)); + dprintf(SPEW, "raminfo 0x%hhx\n", hsusb_reg8(RAMINFO)); + hsusb_reg8(INDEX) = 0; + dprintf(SPEW, "config 0x%hhx\n", hsusb_reg8(IDX_CONFIGDATA)); + + // assert that we have dynamic fifo sizing + DEBUG_ASSERT(hsusb_reg8(IDX_CONFIGDATA) & (1<<2)); + + // mask all the interrupts for the endpoints (except 0) + hsusb_reg16(INTRTXE) = (1<<0); + hsusb_reg16(INTRRXE) = 0; + + twl4030_usb_reset(); + twl4030_init_hs(); + + hsusb_reg8(DEVCTL) = 0; // peripheral mode +// hsusb_reg8(POWER) &= (1<<5); // disable high speed + hsusb_reg8(POWER) |= (1<<5); // enable high speed + + hsusb_reg8(INTRUSBE) = (1<<5)|(1<<2)|(1<<1)|(1<<0); // disconnect, reset, resume, suspend + + LTRACE_EXIT; +} + +void usbc_init(void) +{ + LTRACE_ENTRY; + + // enable the clock + RMWREG32(CM_ICLKEN1_CORE, 4, 1, 1); + + // allocate some ram for the usb struct + usbc = malloc(sizeof(struct usbc_stat)); + memset(usbc, 0, sizeof(struct usbc_stat)); + + usbc->state = USB_DEFAULT; + + // initialize the callback list + list_initialize(&usbc_callback_list); + + // register the interrupt handlers + register_int_handler(92, hsusb_interrupt, NULL); +// register_int_handler(93, hsusb_dma_interrupt, NULL); + + otg_reset(); + hsusb_init(); + + unmask_interrupt(92); +// unmask_interrupt(93); + + LTRACE_EXIT; +} + diff --git a/lk/platform/omap5912/debug.c b/lk/platform/omap5912/debug.c new file mode 100644 index 0000000..d190fa0 --- /dev/null +++ b/lk/platform/omap5912/debug.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include + +static void write_uart_reg(int uart, int reg, unsigned char data) +{ + unsigned long base; + int mul = 4; + + switch(uart) { + case 0: base = UART0_BASE; break; + case 1: base = UART1_BASE; break; + case 2: base = UART2_BASE; break; + default: return; + } + + *(volatile unsigned char *)(base + reg * mul) = data; +} + +static unsigned char read_uart_reg(int uart, int reg) +{ + unsigned long base; + int mul = 4; + + switch(uart) { + case 0: base = UART0_BASE; break; + case 1: base = UART1_BASE; break; + case 2: base = UART2_BASE; break; + default: return 0; + } + + return *(volatile unsigned char *)(base + reg * mul); +} + +static int uart_init(void) +{ + /* clear the tx & rx fifo and disable */ + write_uart_reg(0, UART_FCR, 0x6); + + return 0; +} + +static int uart_putc(int port, char c ) +{ + while (!(read_uart_reg(port, UART_LSR) & (1<<6))) // wait for the shift register to empty + ; + write_uart_reg(port, UART_THR, c); + return 0; +} + +static int uart_getc(int port, bool wait) /* returns -1 if no data available */ +{ + if (wait) { + while (!(read_uart_reg(port, UART_LSR) & (1<<0))) // wait for data to show up in the rx fifo + ; + } else { + if (!(read_uart_reg(port, UART_LSR) & (1<<0))) + return -1; + } + return read_uart_reg(port, UART_RHR); +} + +void _dputc(char c) +{ + if (c == '\n') + uart_putc(0, '\r'); + uart_putc(0, c); +} + +int dgetc(char *c) +{ + int _c; + + if ((_c = uart_getc(0, false)) < 0) + return -1; + + *c = _c; + return 0; +} + +void debug_dump_regs(void) +{ + PANIC_UNIMPLEMENTED; +} + +void platform_halt(void) +{ + dprintf(ALWAYS, "HALT: spinning forever...\n"); + for(;;); +} + +void debug_dump_memory_bytes(void *mem, int len) +{ + PANIC_UNIMPLEMENTED; +} + +void debug_dump_memory_halfwords(void *mem, int len) +{ + PANIC_UNIMPLEMENTED; +} + +void debug_dump_memory_words(void *mem, int len) +{ + PANIC_UNIMPLEMENTED; +} + +void debug_set_trace_level(int trace_type, int level) +{ + PANIC_UNIMPLEMENTED; +} + +uint32_t debug_cycle_count(void) +{ +// PANIC_UNIMPLEMENTED; + return 0; +} diff --git a/lk/platform/omap5912/include/platform/omap5912.h b/lk/platform/omap5912/include/platform/omap5912.h new file mode 100644 index 0000000..0255b82 --- /dev/null +++ b/lk/platform/omap5912/include/platform/omap5912.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __OMAP5912_H +#define __OMAP5912_H + +/* memory map */ +#define SDRAM_BASE 0x10000000 + +/* clocks */ +#define DPLL_CTRL (*(volatile unsigned short *)0xfffecf00) +#define ARM_CKCTL (*(volatile unsigned int *)0xfffece00) +#define ARM_SYSST (*(volatile unsigned int *)0xfffece18) + +/* uart */ +#define UART0_BASE 0xfffb0000 +#define UART1_BASE 0xfffb0800 +#define UART2_BASE 0xfffb9800 + +#define UART_RHR 0 +#define UART_THR 0 +#define UART_DLL 0 +#define UART_IER 1 +#define UART_DLH 1 +#define UART_IIR 2 +#define UART_FCR 2 +#define UART_EFR 2 +#define UART_LCR 3 +#define UART_MCR 4 +#define UART_LSR 5 +#define UART_MSR 6 +#define UART_TCR 6 +#define UART_SPR 7 +#define UART_TLR 7 +#define UART_MDR1 8 +#define UART_MDR2 9 +#define UART_SFLSR 10 +#define UART_RESUME 11 +#define UART_TXFLL 10 +#define UART_TXFLH 11 +#define UART_SFREGL 12 +#define UART_SFREGH 13 +#define UART_RXFLL 12 +#define UART_RXFLH 13 +#define UART_BLR 14 +#define UART_UASR 14 +#define UART_ACREG 15 +#define UART_SCR 16 +#define UART_SSR 17 +#define UART_EBLR 18 +#define UART_MVR 19 +#define UART_SYSC 20 + +/* timers */ +#define MPU_TIMER0_BASE 0xfffec500 +#define MPU_TIMER1_BASE 0xfffec600 +#define MPU_TIMER2_BASE 0xfffec700 +#define WATCHDOG_TIMER_BASE 0xfffec800 +#define OS_TIMER_BASE 0xfffb9000 +#define GP_TIMER1_BASE 0xfffb1400 +#define GP_TIMER2_BASE 0xfffb1c00 +#define GP_TIMER3_BASE 0xfffb2400 +#define GP_TIMER4_BASE 0xfffb2c00 +#define GP_TIMER5_BASE 0xfffb3400 +#define GP_TIMER6_BASE 0xfffb3c00 +#define GP_TIMER7_BASE 0xfffb4400 +#define GP_TIMER8_BASE 0xfffb5c00 + +#define MPU_CNTL_TIMER1 (*(volatile unsigned int *)(MPU_TIMER1_BASE + 0x00)) +#define MPU_LOAD_TIMER1 (*(volatile unsigned int *)(MPU_TIMER1_BASE + 0x04)) +#define MPU_READ_TIMER1 (*(volatile unsigned int *)(MPU_TIMER1_BASE + 0x08)) +#define MPU_CNTL_TIMER2 (*(volatile unsigned int *)(MPU_TIMER2_BASE + 0x00)) +#define MPU_LOAD_TIMER2 (*(volatile unsigned int *)(MPU_TIMER2_BASE + 0x04)) +#define MPU_READ_TIMER2 (*(volatile unsigned int *)(MPU_TIMER2_BASE + 0x08)) +#define MPU_CNTL_TIMER3 (*(volatile unsigned int *)(MPU_TIMER3_BASE + 0x00)) +#define MPU_LOAD_TIMER3 (*(volatile unsigned int *)(MPU_TIMER3_BASE + 0x04)) +#define MPU_READ_TIMER3 (*(volatile unsigned int *)(MPU_TIMER3_BASE + 0x08)) + +#define OS_TIMER_TICK_VALUE_REG (*(volatile unsigned int *)(OS_TIMER_BASE + 0x00)) +#define OS_TIMER_TICK_COUNTER_REG (*(volatile unsigned int *)(OS_TIMER_BASE + 0x04)) +#define OS_TIMER_CTRL_REG (*(volatile unsigned int *)(OS_TIMER_BASE + 0x08)) + + +/* interrupt controller */ +#define INT_VECTORS (32 + 128) +#define INTCON0_BASE 0xfffecb00 +#define INTCON1_BASE 0xfffe0000 +#define INTCON2_BASE 0xfffe0100 +#define INTCON3_BASE 0xfffe0200 +#define INTCON4_BASE 0xfffe0300 + +#define INTCON_ITR 0x00 +#define INTCON_MIR 0x04 +#define INTCON_SIR_IRQ 0x10 +#define INTCON_SIR_FIQ 0x14 +#define INTCON_CONTROL 0x18 +#define INTCON_ILR_BASE 0x1c +#define INTCON_SISR 0x9c +#define INTCON_GMR 0xa0 /* only on first level controller */ +#define INTCON_STATUS 0xa0 /* only on second level controllers */ +#define INTCON_OCP_CFG 0xa4 +#define INTCON_INTH_REV 0xa8 + +/* interrupts */ +#define IRQ_TIMER3 16 +#define IRQ_GPTIMER1 17 +#define IRQ_GPTIMER2 18 +#define IRQ_TIMER1 26 +#define IRQ_WD_TIMER 27 +#define IRQ_TIMER2 30 +#define IRQ_OS_TIMER (32 + 22) +#define IRQ_GPTIMER3 (32 + 34) +#define IRQ_GPTIMER4 (32 + 35) +#define IRQ_GPTIMER5 (32 + 36) +#define IRQ_GPTIMER6 (32 + 37) +#define IRQ_GPTIMER7 (32 + 38) +#define IRQ_GPTIMER8 (32 + 39) + +#endif + diff --git a/lk/platform/omap5912/interrupts.c b/lk/platform/omap5912/interrupts.c new file mode 100644 index 0000000..730618f --- /dev/null +++ b/lk/platform/omap5912/interrupts.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include +#include "platform_p.h" +#include + +struct int_handler_struct { + int_handler handler; + void *arg; +}; + +static struct int_handler_struct int_handler_table[INT_VECTORS]; + +static const uint32_t icBase[5] = { + INTCON0_BASE, INTCON1_BASE, INTCON2_BASE, INTCON3_BASE, INTCON4_BASE }; + +/* a bitmap of the level triggered interrupt vectors */ +static uint32_t level_trigger[5] = { + 0xb3fefe8f, // level 1 0-31 + 0xfdb3c1fd, // level 2 0-31 + 0xfffff7ff, // level 2 32-63 + 0xbfffffff, // level 2 64-95 + 0xffffffff // level 2 96-128 +}; + +static inline volatile uint32_t *ICReg(uint controller, uint reg) +{ + return (volatile uint32_t *)(icBase[controller] + reg); +} + +static inline uint32_t readICReg(uint controller, uint reg) +{ + return *ICReg(controller, reg); +} +static inline void writeICReg(uint controller, uint reg, uint val) +{ + *ICReg(controller, reg) = val; +} + +static inline uint vectorToController(uint vector) +{ + return vector / 32; +} + +void platform_init_interrupts(void) +{ + unsigned int i; + + // mask all interrupts + *ICReg(0, INTCON_MIR) = 0xfffffffa; + *ICReg(1, INTCON_MIR) = 0xffffffff; + *ICReg(2, INTCON_MIR) = 0xffffffff; + *ICReg(3, INTCON_MIR) = 0xffffffff; + *ICReg(4, INTCON_MIR) = 0xffffffff; + + // set up each of the interrupts + for (i = 0; i < INT_VECTORS; i++) { + // set each vector up as high priority, IRQ, and default edge/level sensitivity + *ICReg(i / 32, INTCON_ILR_BASE + 4*(i%32)) = ((level_trigger[i/32] & (1<<(i%32))) ? (1<<1) : (0<<1)) | 0; + } + + // clear any pending interrupts + *ICReg(0, INTCON_ITR) = 0; + *ICReg(1, INTCON_ITR) = 0; + *ICReg(2, INTCON_ITR) = 0; + *ICReg(3, INTCON_ITR) = 0; + *ICReg(4, INTCON_ITR) = 0; + + // globally unmask interrupts + *ICReg(1, INTCON_CONTROL) = 3; + *ICReg(0, INTCON_CONTROL) = 3; + *ICReg(0, INTCON_GMR) = 0; +} + +status_t mask_interrupt(unsigned int vector) +{ + if (vector >= INT_VECTORS) + return ERR_INVALID_ARGS; + +// dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector); + + enter_critical_section(); + + volatile uint32_t *mir = ICReg(vectorToController(vector), INTCON_MIR); + *mir = *mir | (1<<(vector % 32)); + + exit_critical_section(); + + return NO_ERROR; +} + +status_t unmask_interrupt(unsigned int vector) +{ + if (vector >= INT_VECTORS) + return ERR_INVALID_ARGS; + +// dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector); + + enter_critical_section(); + + volatile uint32_t *mir = ICReg(vectorToController(vector), INTCON_MIR); + *mir = *mir & ~(1<<(vector % 32)); + + exit_critical_section(); + + return NO_ERROR; +} + +enum handler_return platform_irq(struct arm_iframe *frame) +{ + // get the current vector + unsigned int vector; + +#if THREAD_STATS + thread_stats.interrupts++; +#endif + + // read from the first level int handler + vector = *ICReg(0, INTCON_SIR_IRQ); + + // see if it's coming from the second level handler + if (vector == 0) { + vector = *ICReg(1, INTCON_SIR_IRQ) + 32; + } + +// dprintf("platform_irq: spsr 0x%x, pc 0x%x, currthread %p, vector %d\n", frame->spsr, frame->pc, current_thread, vector); + + // deliver the interrupt + enum handler_return ret; + + ret = INT_NO_RESCHEDULE; + if (int_handler_table[vector].handler) + ret = int_handler_table[vector].handler(int_handler_table[vector].arg); + + // ack the interrupt + if (vector >= 32) { + // interrupt is chained, so ack the second level first, and then the first + *ICReg(vector / 32, INTCON_ITR) = ~(1 << (vector % 32)); + *ICReg(1, INTCON_CONTROL) |= 1; + vector = 0; // force the following code to ack the chained first level vector + } + + *ICReg(0, INTCON_ITR) = ~(1 << vector); + *ICReg(0, INTCON_CONTROL) = 1; + + return ret; +} + +void platform_fiq(struct arm_iframe *frame) +{ + PANIC_UNIMPLEMENTED; +} + +void register_int_handler(unsigned int vector, int_handler handler, void *arg) +{ + if (vector >= INT_VECTORS) + panic("register_int_handler: vector out of range %d\n", vector); + + enter_critical_section(); + + int_handler_table[vector].handler = handler; + int_handler_table[vector].arg = arg; + + exit_critical_section(); +} + diff --git a/lk/platform/omap5912/platform.c b/lk/platform/omap5912/platform.c new file mode 100644 index 0000000..1dd703d --- /dev/null +++ b/lk/platform/omap5912/platform.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 "platform_p.h" +#include +#include + +void platform_init_mmu_mappings(void) +{ + /* do some memory map initialization */ + addr_t addr; + arm_mmu_map_section(SDRAM_BASE, 0, MMU_FLAG_CACHED|MMU_FLAG_BUFFERED); + for (addr = SDRAM_BASE; addr < SDRAM_BASE + SDRAM_SIZE; addr += (1024*1024)) { + arm_mmu_map_section(addr, addr, MMU_FLAG_CACHED|MMU_FLAG_BUFFERED|MMU_FLAG_READWRITE); + } +} + +void platform_early_init(void) +{ + /* initialize the interrupt controller */ + platform_init_interrupts(); + + /* initialize the timer block */ + platform_init_timer(); +} + +void platform_init(void) +{ +} + diff --git a/lk/platform/omap5912/platform_p.h b/lk/platform/omap5912/platform_p.h new file mode 100644 index 0000000..872ea2b --- /dev/null +++ b/lk/platform/omap5912/platform_p.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __PLATFORM_P_H +#define __PLATFORM_P_H + +void platform_init_interrupts(void); +void platform_init_timer(void); + +#endif + diff --git a/lk/platform/omap5912/rules.mk b/lk/platform/omap5912/rules.mk new file mode 100644 index 0000000..e1bddc1 --- /dev/null +++ b/lk/platform/omap5912/rules.mk @@ -0,0 +1,24 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +ARCH := arm +ARM_CPU := arm926ej-s +CPU := generic + +INCLUDES += \ + -I$(LOCAL_DIR)/include + +OBJS += \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/interrupts.o \ + $(LOCAL_DIR)/platform.o \ + $(LOCAL_DIR)/timer.o + + +# $(LOCAL_DIR)/console.o \ + +MEMBASE := 0x10000000 +#MEMSIZE := 0x02000000 # 32MB + +LINKER_SCRIPT += \ + $(BUILDDIR)/system-onesegment.ld + diff --git a/lk/platform/omap5912/timer.c b/lk/platform/omap5912/timer.c new file mode 100644 index 0000000..2bc09ce --- /dev/null +++ b/lk/platform/omap5912/timer.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 +#include +#include +#include +#include "platform_p.h" + +static time_t system_time = 0; + +static time_t tick_interval; +static uint32_t ticks_per_interval; +static platform_timer_callback t_callback; +static void *callback_arg; + +status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, time_t interval) +{ + enter_critical_section(); + + t_callback = callback; + callback_arg = arg; + tick_interval = interval; + ticks_per_interval = interval * 32768 / 1000; // interval is in ms + + OS_TIMER_CTRL_REG = 0; // stop it + OS_TIMER_TICK_VALUE_REG = ticks_per_interval; + OS_TIMER_CTRL_REG = (1<<3) | (1<<2) | (1<<1) | (1<<0); + + exit_critical_section(); + + return NO_ERROR; +} + +time_t current_time(void) +{ + time_t t; + uint32_t delta_ticks; + uint32_t delta_ticks2; + +retry: + delta_ticks = OS_TIMER_TICK_COUNTER_REG; + t = system_time; + delta_ticks2 = OS_TIMER_TICK_COUNTER_REG; + if (delta_ticks2 > delta_ticks) + goto retry; + + t += ((ticks_per_interval - delta_ticks2) * tick_interval) / ticks_per_interval; + + return t; +} + +bigtime_t current_time_hires(void) +{ + time_t t; + uint32_t delta_ticks; + uint32_t delta_ticks2; + +retry: + delta_ticks = OS_TIMER_TICK_COUNTER_REG; + t = system_time; + delta_ticks2 = OS_TIMER_TICK_COUNTER_REG; + if (delta_ticks2 > delta_ticks) + goto retry; + + t += ((ticks_per_interval - delta_ticks2) * tick_interval) / ticks_per_interval; + + return t * 1000ULL; +} + + +static enum handler_return os_timer_tick(void *arg) +{ + system_time += tick_interval; +// dprintf("os_timer_tick %d\n", system_time); + + return t_callback(callback_arg, system_time); +} + +void platform_init_timer(void) +{ + OS_TIMER_CTRL_REG = 0; // stop the timer if it's already running + + register_int_handler(IRQ_OS_TIMER, &os_timer_tick, NULL); + unmask_interrupt(IRQ_OS_TIMER); +} + diff --git a/lk/platform/qsd8650a/acpuclock.c b/lk/platform/qsd8650a/acpuclock.c new file mode 100644 index 0000000..259a2d4 --- /dev/null +++ b/lk/platform/qsd8650a/acpuclock.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#define A11S_CLK_CNTL 0xAC100100 +#define A11S_CLK_SEL 0xAC100104 + +#define SCPLL_CTL 0xA8800004 +#define SCPLL_CAL 0xA8800008 +#define SCPLL_CTLE 0xA8800024 +#define SCPLL_STAT 0xA8800010 + +void acpu_clock_init(void) +{ + unsigned val; + + /* Go to standby */ + writel(0x2, SCPLL_CTL); + thread_sleep(100); + + /* Calibrate for 384-1497 MHz */ + writel(0x270A0000, SCPLL_CAL); + writel(0x4, SCPLL_CTL); + thread_sleep(10); + while(readl(SCPLL_STAT) & 0x2); + + /* Shot-switch directly to 768MHz */ + writel(0x001400A4, SCPLL_CTLE); + writel(0x7, SCPLL_CTL); + thread_sleep(10); + while(readl(SCPLL_STAT) & 0x3); + + val = readl(A11S_CLK_SEL); + val &= ~(0x3 << 1); + val |= (1 << 1); + writel(val, A11S_CLK_SEL); +} + diff --git a/lk/platform/qsd8650a/arch_init.S b/lk/platform/qsd8650a/arch_init.S new file mode 100644 index 0000000..bb2474a --- /dev/null +++ b/lk/platform/qsd8650a/arch_init.S @@ -0,0 +1,631 @@ +/* + * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. + * Copyright (c) 2008, Google 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 Google, Inc. 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. + */ + + +/* TODO: + * - style cleanup + * - do we need to do *all* of this at boot? + */ + +.text +.code 32 + +#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5 +#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5 + +/* + ; LVT Ring Osc counter + ; used to determine sense amp settings + ; Clobbers registers r0, r4, r5, r6, r7, r9, r10, r11 +*/ +.equ CLK_CTL_BASE, 0xA8600000 +.equ A_GLBL_CLK_ENA, 0x0000 +.equ A_PRPH_WEB_NS_REG,0x0080 +.equ A_MSM_CLK_RINGOSC,0x00D0 +.equ A_TCXO_CNT, 0x00D4 +.equ A_TCXO_CNT_DONE, 0x00D8 +.equ A_RINGOSC_CNT, 0x00DC +.equ A_MISC_CLK_CTL, 0x0108 +.equ CLK_TEST, 0xA8600114 +.equ SPSS_CSR_BASE, 0xAC100000 +.equ A_SCRINGOSC, 0x0510 + +//;; Number of TCXO cycles to count ring oscillations +.equ TCXO_CNT_VAL, 0x100 + +//; Raptor addresses +.equ TCSR_SPARE2, 0xA8700060 + + +.globl SET_SA +SET_SA: + //; no stack at this point and any registers we use will be 0'd + //; after we return + LDR r0, =TCSR_SPARE2 + LDR r1, [r0] + LDR r0, = 0x010F + AND r2, r1, r0 //; concerned with bits [8, 3:0] + + //;-------------------------------------------------------------------- + //; Fuse bits used to determine sense amp settings + //;-------------------------------------------------------------------- + + LDR r0, = 0x0105 + AND r4, r2, r0 //; mask off all but L1 ACC2, L1 ACC1 and L1 ACC0 + //;set to default of FC00 + LDR r5, =PVR0F0_6bits //; point to PVR0F0 + LDR r3, =PVR2F0_6bits //; point to PVR2F0 + +ck_0: + //; if L1_[2:0] == 000 then ACC setting = FC00 + LDR r1, = 0x0 + CMP r4, r1 + BNE ck_1 + B WRITE_L1_SA_SETTINGS + +ck_1: + //; if L1_[2:0] == 001 then ACC setting = FC00 + LDR r1, = 0x01 + CMP r4, r1 + BNE ck_2 + B WRITE_L1_SA_SETTINGS + +ck_2: + //; if L1_[2:0] == 010 then ACC setting = 7C00 + LDR r1, = 0x04 + CMP r4, r1 + BNE ck_3 + LDR r5, =PVR0F0_5bits //; point to PVR0F0 + LDR r3, =PVR2F0_5bits //; point to PVR2F0 + B WRITE_L1_SA_SETTINGS + +ck_3: + //; if L1_[2:0] == 011 then ACC setting = FC00 + LDR r1, = 0x05 + CMP r4, r1 + BNE ck_4 + LDR r5, =PVR0F0_6bits //; point to PVR0F0 + LDR r3, =PVR2F0_6bits //; point to PVR2F0 + B WRITE_L1_SA_SETTINGS + +ck_4: + //; if L1_[2:0] == 0100 then ACC setting = 3C00 + LDR r1, = 0x0100 + CMP r4, r1 + BNE ck_5 + LDR r5, =PVR0F0_4bits //; point to PVR0F0 + LDR r3, =PVR2F0_4bits //; point to PVR2F0 + B WRITE_L1_SA_SETTINGS + +ck_5: + //; if L1_[2:0] == 0101 then ACC setting = 0400 + LDR r1, = 0x0101 + CMP r4, r1 + BNE ck_6 + LDR r5, =PVR0F0_1bits //; point to PVR0F0 + LDR r3, =PVR2F0_1bits //; point to PVR2F0 + B WRITE_L1_SA_SETTINGS + +ck_6: + //; if L1_[2:0] == 0110 then ACC setting = 0C00 + LDR r1, = 0x0104 + CMP r4, r1 + BNE ck_7 + LDR r5, =PVR0F0_2bits //; point to PVR0F0 + LDR r3, =PVR2F0_2bits //; point to PVR2F0 + B WRITE_L1_SA_SETTINGS + +ck_7: + //; if L1_[2:0] == 0111 then ACC setting = 1C00 + LDR r1, = 0x0105 + CMP r4, r1 + LDREQ r5, =PVR0F0_3bits //; point to PVR0F0 + LDREQ r3, =PVR2F0_3bits //; point to PVR2F0 + +WRITE_L1_SA_SETTINGS: + + LDR r5, [r5] + LDR r3, [r3] + + //;WCP15_PVR0F0 r5 + MCR p15,0x0,r5,c15,c15,0 //; write R5 to PVR0F0 + + //;WCP15_PVR2F0 r3 + MCR p15,0x2,r3,c15,c15,0 //; write R3 to PVR2F0 + + AND r4, r2, #0x000A //; mask off all but L2 array SA settings + LDR r5, =HVT_010102 //; point to L2VR3F1 setting + //;it gets ovewritten if its one of the other two cases + //; if L2_1 and L2_0 == 0 ACC setting = 010102 + LDR r1, = 0x0000 + CMP r4, r1 + BEQ WRITE_L2_SA_SETTINGS + + //; if L2_1 = 0 & L2_0 = 1 ACC setting = 010102 + LDR R1, = 0x0002 + CMP r4, r1 + BEQ WRITE_L2_SA_SETTINGS + + //; if L2_1 = 1 & L2_0 = 0 ACC setting = 010101 + LDR r5, =HVT_010101 + LDR R1, = 0x0008 + CMP r4, r1 + BEQ WRITE_L2_SA_SETTINGS + + //; else L2_1 = 1 & L2_0 = 1 ACC setting = 212102 + LDR r5, =HVT_212102 + + +WRITE_L2_SA_SETTINGS: + //;WCP15_L2VR3F1 r4 + LDR r5, [r5] + MCR p15,0x3,r5,c15,c15,1 //;write r4 to L2VR3F1 + + LDR r0, =0 //;make sure the registers we touched + LDR r1, =0 //;are cleared when we return + LDR r2, =0 + LDR r3, =0 + LDR r4, =0 + LDR r5, =0 + + //; routine complete + BX LR + +//; L1 SA settings according to LVT speed +PVR0F0_0bits: +.word 0x38000000 //; PVR0F0 +PVR2F0_0bits: +.word 0x00000000 //; PVR2F0 0 bits set + +PVR0F0_1bits: +.word 0x38000400 //; PVR0F0 +PVR2F0_1bits: +.word 0x04000000 //; PVR2F0 1 bits set + +PVR0F0_2bits: +.word 0x38000C00 //; PVR0F0 +PVR2F0_2bits: +.word 0x0C000000 //; PVR2F0 2 bits set + +PVR0F0_3bits: +.word 0x38001C00 //; PVR0F0 +PVR2F0_3bits: +.word 0x1C000000 //; PVR2F0 3 bits set + +PVR0F0_4bits: +.word 0x38003C00 //; PVR0F0 +PVR2F0_4bits: +.word 0x3C000000 //; PVR2F0 4 bits set + +PVR0F0_5bits: +.word 0x38007C00 //; PVR0F0 +PVR2F0_5bits: +.word 0x7C000000 //; PVR2F0 5 bits set + +PVR0F0_6bits: +.word 0x3800FC00 //; PVR0F0 +PVR2F0_6bits: +.word 0xFC000000 //; PVR2F0 6 bits set + +//; L2 SA settings according to HVT speed +HVT_212102: +.word 0x00212102 //; L2VR3F1 + +HVT_010102: +.word 0x00010102 //; L2VR3F1 + +HVT_010101: +.word 0x00010101 //; L2VR3F1 + + +.ltorg + + +.globl __cpu_early_init +__cpu_early_init: + //; Zero out r0 for use throughout this code. All other GPRs + //; (r1-r3) are set throughout this code to help establish + //; a consistent startup state for any code that follows. + //; Users should add code at the end of this routine to establish + //; their own stack address (r13), add translation page tables, enable + //; the caches, etc. + MOV r0, #0x0 + + + //; Remove hardcoded cache settings. appsbl_handler.s calls Set_SA + //; API to dynamically configure cache for slow/nominal/fast parts + + //; DCIALL to invalidate L2 cache bank (needs to be run 4 times, once per bank) + //; This must be done early in code (prior to enabling the caches) + MOV r1, #0x2 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank D ([15:14] == 2'b00) + ORR r1, r1, #0x00004000 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank C ([15:14] == 2'b01) + ADD r1, r1, #0x00004000 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank B ([15:14] == 2'b10) + ADD r1, r1, #0x00004000 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank A ([15:14] == 2'b11) + + //; Initialize the BPCR - setup Global History Mask (GHRM) to all 1's + //; and have all address bits (AM) participate. + //; Different settings can be used to improve performance + // MOVW r1, #0x01FF +.word 0xe30011ff // hardcoded MOVW instruction due to lack of compiler support + // MOVT r1, #0x01FF +.word 0xe34011ff // hardcoded MOVT instruction due to lack of compiler support + MCR p15, 7, r1, c15, c0, 2 //; WCP15_BPCR + + + //; Initialize all I$ Victim Registers to 0 for startup + MCR p15, 0, r0, c9, c1, 0 //; WCP15_ICVIC0 r0 + MCR p15, 0, r0, c9, c1, 1 //; WCP15_ICVIC1 r0 + MCR p15, 0, r0, c9, c1, 2 //; WCP15_ICVIC2 r0 + MCR p15, 0, r0, c9, c1, 3 //; WCP15_ICVIC3 r0 + MCR p15, 0, r0, c9, c1, 4 //; WCP15_ICVIC4 r0 + MCR p15, 0, r0, c9, c1, 5 //; WCP15_ICVIC5 r0 + MCR p15, 0, r0, c9, c1, 6 //; WCP15_ICVIC5 r0 + MCR p15, 0, r0, c9, c1, 7 //; WCP15_ICVIC7 r0 + + //; Initialize all I$ Locked Victim Registers (Unlocked Floors) to 0 + MCR p15, 1, r0, c9, c1, 0 //; WCP15_ICFLOOR0 r0 + MCR p15, 1, r0, c9, c1, 1 //; WCP15_ICFLOOR1 r0 + MCR p15, 1, r0, c9, c1, 2 //; WCP15_ICFLOOR2 r0 + MCR p15, 1, r0, c9, c1, 3 //; WCP15_ICFLOOR3 r0 + MCR p15, 1, r0, c9, c1, 4 //; WCP15_ICFLOOR4 r0 + MCR p15, 1, r0, c9, c1, 5 //; WCP15_ICFLOOR5 r0 + MCR p15, 1, r0, c9, c1, 6 //; WCP15_ICFLOOR6 r0 + MCR p15, 1, r0, c9, c1, 7 //; WCP15_ICFLOOR7 r0 + + //; Initialize all D$ Victim Registers to 0 + MCR p15, 2, r0, c9, c1, 0 //; WP15_DCVIC0 r0 + MCR p15, 2, r0, c9, c1, 1 //; WP15_DCVIC1 r0 + MCR p15, 2, r0, c9, c1, 2 //; WP15_DCVIC2 r0 + MCR p15, 2, r0, c9, c1, 3 //; WP15_DCVIC3 r0 + MCR p15, 2, r0, c9, c1, 4 //; WP15_DCVIC4 r0 + MCR p15, 2, r0, c9, c1, 5 //; WP15_DCVIC5 r0 + MCR p15, 2, r0, c9, c1, 6 //; WP15_DCVIC6 r0 + MCR p15, 2, r0, c9, c1, 7 //; WP15_DCVIC7 r0 + + //; Initialize all D$ Locked VDCtim Registers (Unlocked Floors) to 0 + MCR p15, 3, r0, c9, c1, 0 //; WCP15_DCFLOOR0 r0 + MCR p15, 3, r0, c9, c1, 1 //; WCP15_DCFLOOR1 r0 + MCR p15, 3, r0, c9, c1, 2 //; WCP15_DCFLOOR2 r0 + MCR p15, 3, r0, c9, c1, 3 //; WCP15_DCFLOOR3 r0 + MCR p15, 3, r0, c9, c1, 4 //; WCP15_DCFLOOR4 r0 + MCR p15, 3, r0, c9, c1, 5 //; WCP15_DCFLOOR5 r0 + MCR p15, 3, r0, c9, c1, 6 //; WCP15_DCFLOOR6 r0 + MCR p15, 3, r0, c9, c1, 7 //; WCP15_DCFLOOR7 r0 + + //; Initialize ASID to zero + MCR p15, 0, r0, c13, c0, 1 //; WCP15_CONTEXTIDR r0 + + //; ICIALL to invalidate entire I-Cache + MCR p15, 0, r0, c7, c5, 0 //; ICIALLU + + //; DCIALL to invalidate entire D-Cache + MCR p15, 0, r0, c9, c0, 6 //; DCIALL r0 + + //; Initialize ADFSR to zero + MCR p15, 0, r0, c5, c1, 0 //; ADFSR r0 + + //; Initialize EFSR to zero + MCR p15, 7, r0, c15, c0, 1 //; EFSR r0 + + //; The VBAR (Vector Base Address Register) should be initialized + //; early in your code. We are setting it to zero + MCR p15, 0, r0, c12, c0, 0 //; WCP15_VBAR r0 + + //; Ensure the MCR's above have completed their operation before continuing + DSB + ISB + + //;------------------------------------------------------------------- + //; There are a number of registers that must be set prior to enabling + //; the MMU. The DCAR is one of these registers. We are setting + //; it to zero (no access) to easily detect improper setup in subsequent + //; code sequences + //;------------------------------------------------------------------- + //; Setup DACR (Domain Access Control Register) to zero + MCR p15, 0, r0, c3, c0, 0 //; WCP15_DACR r0 + + //; Setup DCLKCR to allow normal D-Cache line fills + MCR p15, 1, r0, c9, c0, 7 //; WCP15_DCLKCR r0 + + //; Setup the TLBLKCR + //; Victim = 6'b000000; Floor = 6'b000000; + //; IASIDCFG = 2'b00 (State-Machine); IALLCFG = 2'b01 (Flash); BNA = 1'b0; + MOV r1, #0x02 + MCR p15, 0, r1, c10, c1, 3 //; WCP15_TLBLKCR r1 + + //;Make sure TLBLKCR is complete before continuing + ISB + + //; Invalidate the UTLB + MCR p15, 0, r0, c8, c7, 0 //; UTLBIALL + + //; Make sure UTLB request has been presented to macro before continuing + ISB + +SYSI2: + //; setup L2CR1 to some default Instruction and data prefetching values + //; Users may want specific settings for various performance enhancements + MOV r2, #0x33 + MCR p15, 3, r2, c15, c0, 3 //; WCP15_L2CR1 r0 + + + //; Enable Z bit to enable branch prediction (default is off) + MRC p15, 0, r2, c1, c0, 0 //; RCP15_SCTLR r2 + ORR r2, r2, #0x00000800 + MCR p15, 0, r2, c1, c0, 0 //; WCP15_SCTLR r2 + + //; Make sure Link stack is initialized with branch and links to sequential addresses + //; This aids in creating a predictable startup environment +//; BL SEQ1 +//;SEQ1: BL SEQ2 +//;SEQ2: BL SEQ3 +//;SEQ3: BL SEQ4 +//;SEQ4: BL SEQ5 +//;SEQ5: BL SEQ6 +//;SEQ6: BL SEQ7 +//;SEQ7: BL SEQ8 +//;SEQ8: + + //; REMOVE FOLLOWING THREE INSTRUCTIONS WHEN POWER COLLAPSE IS ENA + //;Make sure the DBGOSLSR[LOCK] bit is cleared to allow access to the debug registers + //; Writing anything but the "secret code" to the DBGOSLAR clears the DBGOSLSR[LOCK] bit + MCR p14, 0, r0, c1, c0, 4 //; WCP14_DBGOSLAR r0 + + + //; Read the DBGPRSR to clear the DBGPRSR[STICKYPD] + //; Any read to DBGPRSR clear the STICKYPD bit + //; ISB guarantees the read completes before attempting to + //; execute a CP14 instruction. + MRC p14, 0, r3, c1, c5, 4 //; RCP14_DBGPRSR r3 + ISB + + //; Initialize the Watchpoint Control Registers to zero (optional) + //;;; MCR p14, 0, r0, c0, c0, 7 ; WCP14_DBGWCR0 r0 + //;;; MCR p14, 0, r0, c0, c1, 7 ; WCP14_DBGWCR1 r0 + + + //;---------------------------------------------------------------------- + //; The saved Program Status Registers (SPSRs) should be setup + //; prior to any automatic mode switches. The following + //; code sets these registers up to a known state. Users will need to + //; customize these settings to meet their needs. + //;---------------------------------------------------------------------- + MOV r2, #0x1f + MOV r1, #0xd7 //;ABT mode + msr cpsr_c, r1 //;ABT mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xdb //;UND mode + msr cpsr_c, r1 //;UND mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd1 //;FIQ mode + msr cpsr_c, r1 //;FIQ mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd2 //;IRQ mode + msr cpsr_c, r1 //;IRQ mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd6 //;Monitor mode + msr cpsr_c, r1 //;Monitor mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd3 //;SVC mode + msr cpsr_c, r1 //;SVC mode + msr spsr_cxfs, r2 //;clear the spsr + + + //;---------------------------------------------------------------------- + //; Enabling Error reporting is something users may want to do at + //; some other point in time. We have chosen some default settings + //; that should be reviewed. Most of these registers come up in an + //; unpredictable state after reset. + //;---------------------------------------------------------------------- +//;Start of error and control setting + + //; setup L2CR0 with various L2/TCM control settings + //; enable out of order bus attributes and error reporting + //; this register comes up unpredictable after reset + // MOVW r1, #0x0F0F +.word 0xe3001f0f // hardcoded MOVW instruction due to lack of compiler support + // MOVT r1, #0xC005 +.word 0xe34c1005 // hardcoded MOVW instruction due to lack of compiler support + MCR p15, 3, r1, c15, c0, 1 //; WCP15_L2CR0 r1 + + //; setup L2CPUCR + //; MOV r2, #0xFF + //; Enable I and D cache parity + //;L2CPUCR[7:5] = 3~Rh7 ~V enable parity error reporting for modified, + //;tag, and data parity errors + MOV r2, #0xe0 + MCR p15, 3, r2, c15, c0, 2 //; WCP15_L2CPUCR r2 + + //; setup SPCR + //; enable all error reporting (reset value is unpredicatble for most bits) + MOV r3, #0x0F + MCR p15, 0, r3, c9, c7, 0 //; WCP15_SPCR r3 + + //; setup DMACHCRs (reset value unpredictable) + //; control setting and enable all error reporting + MOV r1, #0x0F + + //; DMACHCR0 = 0000000F + MOV r2, #0x00 //; channel 0 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; DMACHCR1 = 0000000F + MOV r2, #0x01 //; channel 1 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; DMACHCR2 = 0000000F + MOV r2, #0x02 //; channel 2 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; DMACHCR3 = 0000000F + MOV r2, #0x03 //; channel 3 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; Set ACTLR (reset unpredictable) + //; Set AVIVT control, error reporting, etc. + //; MOV r3, #0x07 + //; Enable I and D cache parity + //;ACTLR[2:0] = 3'h7 - enable parity error reporting from L2/I$/D$) + //;ACTLR[5:4] = 2'h3 - enable parity + //;ACTLR[19:18] =2'h3 - always generate and check parity(when MMU disabled). + //;Value to be written #0xC0037 + // MOVW r3, #0x0037 +.word 0xe3003037 // hardcoded MOVW instruction due to lack of compiler support + // MOVT r3, #0x000C +.word 0xe340300c // hardcoded MOVW instruction due to lack of compiler support + //; read the version_id to determine if d-cache should be disabled + LDR r2, = 0xa8e00270 //;Read HW_REVISION_NUMBER, HWIO_HW_REVISION_NUMBER_ADDR + LDR r2,[r2] + AND r2,r2,#0xf0000000 //;hw_revision mask off bits 28-31 + //;if HW_revision is 1.0 or older, (revision==0) + CMP r2,#0 + //; Disable d-cache on older QSD8650 (Rev 1.0) silicon + //;orreq r3, r3, #0x4000 //;disable dcache + //;MCR p15, 0, r3, c1, c0, 1 //; WCP15_ACTLR r3 + +//;End of error and control setting + + //;---------------------------------------------------------------------- + //; Unlock ETM and read StickyPD to halt the ETM clocks from running. + //; This is required for power saving whether the ETM is used or not. + //;---------------------------------------------------------------------- + + //;Clear ETMOSLSR[LOCK] bit + MOV r1, #0x00000000 + MCR p14, 1, r1, c1, c0, 4 //; WCP14_ETMOSLAR r1 + + //;Clear ETMPDSR[STICKYPD] bit + MRC p14, 1, r2, c1, c5, 4 //; RCP14_ETMPDSR r2 + +/* +#ifdef APPSBL_ETM_ENABLE + ;---------------------------------------------------------------------- + ; Optionally Enable the ETM (Embedded Trace Macro) which is used for debug + ;---------------------------------------------------------------------- + + ; enable ETM clock if disabled + MRC p15, 7, r1, c15, c0, 5 ; RCP15_CPMR r1 + ORR r1, r1, #0x00000008 + MCR p15, 7, r1, c15, c0, 5 ; WCP15_CPMR r1 + ISB + + ; set trigger event to counter1 being zero + MOV r3, #0x00000040 + MCR p14, 1, r3, c0, c2, 0 ; WCP14_ETMTRIGGER r3 + + ; clear ETMSR + MOV r2, #0x00000000 + MCR p14, 1, r2, c0, c4, 0 ; WCP14_ETMSR r2 + + ; clear trace enable single address comparator usage + MCR p14, 1, r2, c0, c7, 0 ; WCP14_ETMTECR2 r2 + + ; set trace enable to always + MOV r2, #0x0000006F + MCR p14, 1, r2, c0, c8, 0 ; WCP14_ETMTEEVR r2 + + ; clear trace enable address range comparator usage and exclude nothing + MOV r2, #0x01000000 + MCR p14, 1, r2, c0, c9, 0 ; WCP14_ETMTECR1 r2 + + ; set view data to always + MOV r2, #0x0000006F + MCR p14, 1, r2, c0, c12, 0 ; WCP14_ETMVDEVR r2 + + ; clear view data single address comparator usage + MOV r2, #0x00000000 + MCR p14, 1, r2, c0, c13, 0 ; WCP14_ETMVDCR1 r2 + + ; clear view data address range comparator usage and exclude nothing + MOV r2, #0x00010000 + MCR p14, 1, r2, c0, c15, 0 ; WCP14_ETMVDCR3 r2 + + ; set counter1 to 194 + MOV r2, #0x000000C2 + MCR p14, 1, r2, c0, c0, 5 ; WCP14_ETMCNTRLDVR1 r2 + + ; set counter1 to never reload + MOV r2, #0x0000406F + MCR p14, 1, r2, c0, c8, 5 ; WCP14_ETMCNTRLDEVR1 r2 + + ; set counter1 to decrement every cycle + MOV r2, #0x0000006F + MCR p14, 1, r2, c0, c4, 5 ; WCP14_ETMCNTENR1 r2 + + ; Set trace synchronization frequency 1024 bytes + MOV r2, #0x00000400 + MCR p14, 1, r2, c0, c8, 7 ; WCP14_ETMSYNCFR r2 + + ; Program etm control register + ; - Set the CPU to ETM clock ratio to 1:1 + ; - Set the ETM to perform data address tracing + MOV r2, #0x00002008 + MCR p14, 1, r2, c0, c0, 0 ; WCP14_ETMCR r2 + ISB +#endif *//* APPSBL_ETM_ENABLE */ + +/* +#ifdef APPSBL_VFP_ENABLE + ;---------------------------------------------------------------------- + ; Perform the following operations if you intend to make use of + ; the VFP/Neon unit. Note that the FMXR instruction requires a CPU ID + ; indicating the VFP unit is present (i.e.Cortex-A8). . + ; Some tools will require full double precision floating point support + ; which will become available in Scorpion pass 2 + ;---------------------------------------------------------------------- + ; allow full access to CP 10 and 11 space for VFP/NEON use + MRC p15, 0, r1, c1, c0, 2 ; Read CP Access Control Register + ORR r1, r1, #0x00F00000 ; enable full access for p10,11 + MCR p15, 0, r1, c1, c0, 2 ; Write CPACR + + ;make sure the CPACR is complete before continuing + ISB + + ; Enable VFP itself (certain OSes may want to dynamically set/clear + ; the enable bit based on the application being executed + MOV r1, #0x40000000 + FMXR FPEXC, r1 +#endif *//* APPSBL_VFP_ENABLE */ + + /* we have no stack, so just tail-call into the SET_SA routine... */ + b SET_SA + + +.ltorg diff --git a/lk/platform/qsd8650a/gpio.c b/lk/platform/qsd8650a/gpio.c new file mode 100644 index 0000000..0b1272b --- /dev/null +++ b/lk/platform/qsd8650a/gpio.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2008, Google 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "gpio_hw.h" + +typedef struct gpioregs gpioregs; + +struct gpioregs +{ + unsigned out; + unsigned in; + unsigned int_status; + unsigned int_clear; + unsigned int_en; + unsigned int_edge; + unsigned int_pos; + unsigned oe; +}; + +static gpioregs GPIO_REGS[] = { + { + .out = GPIO_OUT_0, + .in = GPIO_IN_0, + .int_status = GPIO_INT_STATUS_0, + .int_clear = GPIO_INT_CLEAR_0, + .int_en = GPIO_INT_EN_0, + .int_edge = GPIO_INT_EDGE_0, + .int_pos = GPIO_INT_POS_0, + .oe = GPIO_OE_0, + }, + { + .out = GPIO_OUT_1, + .in = GPIO_IN_1, + .int_status = GPIO_INT_STATUS_1, + .int_clear = GPIO_INT_CLEAR_1, + .int_en = GPIO_INT_EN_1, + .int_edge = GPIO_INT_EDGE_1, + .int_pos = GPIO_INT_POS_1, + .oe = GPIO_OE_1, + }, + { + .out = GPIO_OUT_2, + .in = GPIO_IN_2, + .int_status = GPIO_INT_STATUS_2, + .int_clear = GPIO_INT_CLEAR_2, + .int_en = GPIO_INT_EN_2, + .int_edge = GPIO_INT_EDGE_2, + .int_pos = GPIO_INT_POS_2, + .oe = GPIO_OE_2, + }, + { + .out = GPIO_OUT_3, + .in = GPIO_IN_3, + .int_status = GPIO_INT_STATUS_3, + .int_clear = GPIO_INT_CLEAR_3, + .int_en = GPIO_INT_EN_3, + .int_edge = GPIO_INT_EDGE_3, + .int_pos = GPIO_INT_POS_3, + .oe = GPIO_OE_3, + }, + { + .out = GPIO_OUT_4, + .in = GPIO_IN_4, + .int_status = GPIO_INT_STATUS_4, + .int_clear = GPIO_INT_CLEAR_4, + .int_en = GPIO_INT_EN_4, + .int_edge = GPIO_INT_EDGE_4, + .int_pos = GPIO_INT_POS_4, + .oe = GPIO_OE_4, + }, + { + .out = GPIO_OUT_5, + .in = GPIO_IN_5, + .int_status = GPIO_INT_STATUS_5, + .int_clear = GPIO_INT_CLEAR_5, + .int_en = GPIO_INT_EN_5, + .int_edge = GPIO_INT_EDGE_5, + .int_pos = GPIO_INT_POS_5, + .oe = GPIO_OE_5, + }, + { + .out = GPIO_OUT_6, + .in = GPIO_IN_6, + .int_status = GPIO_INT_STATUS_6, + .int_clear = GPIO_INT_CLEAR_6, + .int_en = GPIO_INT_EN_6, + .int_edge = GPIO_INT_EDGE_6, + .int_pos = GPIO_INT_POS_6, + .oe = GPIO_OE_6, + }, + { + .out = GPIO_OUT_7, + .in = GPIO_IN_7, + .int_status = GPIO_INT_STATUS_7, + .int_clear = GPIO_INT_CLEAR_7, + .int_en = GPIO_INT_EN_7, + .int_edge = GPIO_INT_EDGE_7, + .int_pos = GPIO_INT_POS_7, + .oe = GPIO_OE_7, + }, +}; + +static gpioregs *find_gpio(unsigned n, unsigned *bit) +{ + if(n > 164) return 0; + if(n > 152) { + *bit = 1 << (n - 153); + return GPIO_REGS + 7; + } + if(n > 121) { + *bit = 1 << (n - 122); + return GPIO_REGS + 6; + } + if(n > 103) { + *bit = 1 << (n - 104); + return GPIO_REGS + 5; + } + if(n > 94) { + *bit = 1 << (n - 95); + return GPIO_REGS + 4; + } + if(n > 67) { + *bit = 1 << (n - 68); + return GPIO_REGS + 3; + } + if(n > 42) { + *bit = 1 << (n - 43); + return GPIO_REGS + 2; + } + if(n > 15) { + *bit = 1 << (n - 16); + return GPIO_REGS + 1; + } + *bit = 1 << n; + return GPIO_REGS + 0; +} + +int gpio_config(unsigned n, unsigned flags) +{ + gpioregs *r; + unsigned b; + unsigned v; + + if ((r = find_gpio(n, &b)) == 0) + return -1; + + v = readl(r->oe); + if (flags & GPIO_OUTPUT) { + writel(v | b, r->oe); + } else { + writel(v & (~b), r->oe); + } + return 0; +} + +void gpio_set(unsigned n, unsigned on) +{ + gpioregs *r; + unsigned b; + unsigned v; + + if((r = find_gpio(n, &b)) == 0) return; + + v = readl(r->out); + if(on) { + writel(v | b, r->out); + } else { + writel(v & (~b), r->out); + } +} + +int gpio_get(unsigned n) +{ + gpioregs *r; + unsigned b; + + if((r = find_gpio(n, &b)) == 0) return 0; + + return (readl(r->in) & b) ? 1 : 0; +} + + diff --git a/lk/platform/qsd8650a/gpio_hw.h b/lk/platform/qsd8650a/gpio_hw.h new file mode 100644 index 0000000..3ef40f6 --- /dev/null +++ b/lk/platform/qsd8650a/gpio_hw.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2008, Google 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. + * + * 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 __PLATFORM_QSD8K_GPIO_HW_H +#define __PLATFORM_QSD8K_GPIO_HW_H + +#define MSM_GPIO1_BASE 0xA9000000 +#define MSM_GPIO2_BASE 0xA9100000 + +#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off)) +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off)) + +/* output value */ +#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */ +#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 42-16 */ +#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-43 */ +#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */ +#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 103-95 */ +#define GPIO_OUT_5 GPIO1_REG(0x10) /* gpio 121-104 */ +#define GPIO_OUT_6 GPIO1_REG(0x14) /* gpio 152-122 */ +#define GPIO_OUT_7 GPIO1_REG(0x18) /* gpio 164-153 */ + +/* same pin map as above, output enable */ +#define GPIO_OE_0 GPIO1_REG(0x20) +#define GPIO_OE_1 GPIO2_REG(0x08) +#define GPIO_OE_2 GPIO1_REG(0x24) +#define GPIO_OE_3 GPIO1_REG(0x28) +#define GPIO_OE_4 GPIO1_REG(0x2C) +#define GPIO_OE_5 GPIO1_REG(0x30) +#define GPIO_OE_6 GPIO1_REG(0x34) +#define GPIO_OE_7 GPIO1_REG(0x38) + +/* same pin map as above, input read */ +#define GPIO_IN_0 GPIO1_REG(0x50) +#define GPIO_IN_1 GPIO2_REG(0x20) +#define GPIO_IN_2 GPIO1_REG(0x54) +#define GPIO_IN_3 GPIO1_REG(0x58) +#define GPIO_IN_4 GPIO1_REG(0x5C) +#define GPIO_IN_5 GPIO1_REG(0x60) +#define GPIO_IN_6 GPIO1_REG(0x64) +#define GPIO_IN_7 GPIO1_REG(0x68) + +/* same pin map as above, 1=edge 0=level interrup */ +#define GPIO_INT_EDGE_0 GPIO1_REG(0x70) +#define GPIO_INT_EDGE_1 GPIO2_REG(0x50) +#define GPIO_INT_EDGE_2 GPIO1_REG(0x74) +#define GPIO_INT_EDGE_3 GPIO1_REG(0x78) +#define GPIO_INT_EDGE_4 GPIO1_REG(0x7C) +#define GPIO_INT_EDGE_5 GPIO1_REG(0x80) +#define GPIO_INT_EDGE_6 GPIO1_REG(0x84) +#define GPIO_INT_EDGE_7 GPIO1_REG(0x88) + +/* same pin map as above, 1=positive 0=negative */ +#define GPIO_INT_POS_0 GPIO1_REG(0x90) +#define GPIO_INT_POS_1 GPIO2_REG(0x58) +#define GPIO_INT_POS_2 GPIO1_REG(0x94) +#define GPIO_INT_POS_3 GPIO1_REG(0x98) +#define GPIO_INT_POS_4 GPIO1_REG(0x9C) +#define GPIO_INT_POS_5 GPIO1_REG(0xA0) +#define GPIO_INT_POS_6 GPIO1_REG(0xA4) +#define GPIO_INT_POS_7 GPIO1_REG(0xA8) + +/* same pin map as above, interrupt enable */ +#define GPIO_INT_EN_0 GPIO1_REG(0xB0) +#define GPIO_INT_EN_1 GPIO2_REG(0x60) +#define GPIO_INT_EN_2 GPIO1_REG(0xB4) +#define GPIO_INT_EN_3 GPIO1_REG(0xB8) +#define GPIO_INT_EN_4 GPIO1_REG(0xBC) +#define GPIO_INT_EN_5 GPIO1_REG(0xC0) +#define GPIO_INT_EN_6 GPIO1_REG(0xC4) +#define GPIO_INT_EN_7 GPIO1_REG(0xC8) + +/* same pin map as above, write 1 to clear interrupt */ +#define GPIO_INT_CLEAR_0 GPIO1_REG(0xD0) +#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68) +#define GPIO_INT_CLEAR_2 GPIO1_REG(0xD4) +#define GPIO_INT_CLEAR_3 GPIO1_REG(0xD8) +#define GPIO_INT_CLEAR_4 GPIO1_REG(0xDC) +#define GPIO_INT_CLEAR_5 GPIO1_REG(0xE0) +#define GPIO_INT_CLEAR_6 GPIO1_REG(0xE4) +#define GPIO_INT_CLEAR_7 GPIO1_REG(0xE8) + +/* same pin map as above, 1=interrupt pending */ +#define GPIO_INT_STATUS_0 GPIO1_REG(0xF0) +#define GPIO_INT_STATUS_1 GPIO2_REG(0x70) +#define GPIO_INT_STATUS_2 GPIO1_REG(0xF4) +#define GPIO_INT_STATUS_3 GPIO1_REG(0xF8) +#define GPIO_INT_STATUS_4 GPIO1_REG(0xFC) +#define GPIO_INT_STATUS_5 GPIO1_REG(0x100) +#define GPIO_INT_STATUS_6 GPIO1_REG(0x103) +#define GPIO_INT_STATUS_7 GPIO1_REG(0x108) + +#endif diff --git a/lk/platform/qsd8650a/include/platform/iomap.h b/lk/platform/qsd8650a/include/platform/iomap.h new file mode 100644 index 0000000..dc8048a --- /dev/null +++ b/lk/platform/qsd8650a/include/platform/iomap.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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 _PLATFORM_MSM7K_IOMAP_H_ +#define _PLATFORM_MSM7K_IOMAP_H_ + +#define MSM_UART1_BASE 0xA9A00000 +#define MSM_UART2_BASE 0xA9B00000 +#define MSM_UART3_BASE 0xA9C00000 + +#define MSM_VIC_BASE 0xAC000000 +#define MSM_GPT_BASE 0xAC100000 +#define MSM_CSR_BASE 0xAC100000 + +#define MSM_SHARED_BASE 0xE0100000 +#endif diff --git a/lk/platform/qsd8650a/include/platform/irqs.h b/lk/platform/qsd8650a/include/platform/irqs.h new file mode 100644 index 0000000..3548218 --- /dev/null +++ b/lk/platform/qsd8650a/include/platform/irqs.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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 _PLATFORM_MSM7K_IRQS_H_ +#define _PLATFORM_MSM7K_IRQS_H_ + +#define INT_A9_M2A_0 0 +#define INT_A9_M2A_1 1 +#define INT_A9_M2A_2 2 +#define INT_A9_M2A_3 3 +#define INT_A9_M2A_4 4 +#define INT_A9_M2A_5 5 +#define INT_A9_M2A_6 6 +#define INT_GP_TIMER_EXP 7 +#define INT_DEBUG_TIMER_EXP 8 +#define INT_SIRC_0 9 +#define INT_SDC3_0 10 +#define INT_SDC3_1 11 +#define INT_SDC4_0 12 +#define INT_SDC4_1 13 +#define INT_AD6_EXT_VFR 14 +#define INT_USB_OTG 15 +#define INT_MDDI_PRI 16 +#define INT_MDDI_EXT 17 +#define INT_MDDI_CLIENT 18 +#define INT_MDP 19 +#define INT_GRAPHICS 20 +#define INT_ADM_AARM 21 +#define INT_ADSP_A11 22 +#define INT_ADSP_A9_A11 23 +#define INT_SDC1_0 24 +#define INT_SDC1_1 25 +#define INT_SDC2_0 26 +#define INT_SDC2_1 27 +#define INT_KEYSENSE 28 +#define INT_TCHSCRN_SSBI 29 +#define INT_TCHSCRN1 30 +#define INT_TCHSCRN2 31 + +#define INT_TCSR_MPRPH_SC1 (32 + 0) +#define INT_USB_FS2 (32 + 1) +#define INT_PWB_I2C (32 + 2) +#define INT_SOFTRESET (32 + 3) +#define INT_NAND_WR_ER_DONE (32 + 4) +#define INT_NAND_OP_DONE (32 + 5) +#define INT_TCSR_MPRPH_SC2 (32 + 6) +#define INT_OP_PEN (32 + 7) +#define INT_AD_HSSD (32 + 8) +#define INT_ARM11_PM (32 + 9) +#define INT_SDMA_NON_SECURE (32 + 10) +#define INT_TSIF_IRQ (32 + 11) +#define INT_UART1DM_IRQ (32 + 12) +#define INT_UART1DM_RX (32 + 13) +#define INT_SDMA_SECURE (32 + 14) +#define INT_SI2S_SLAVE (32 + 15) +#define INT_SC_I2CPU (32 + 16) +#define INT_SC_DBG_RDTRFULL (32 + 17) +#define INT_SC_DBG_WDTRFULL (32 + 18) +#define INT_SCPLL_CTL_DONE (32 + 19) +#define INT_UART2DM_IRQ (32 + 20) +#define INT_UART2DM_RX (32 + 21) +#define INT_VDC_MEC (32 + 22) +#define INT_VDC_DB (32 + 23) +#define INT_VDC_AXI (32 + 24) +#define INT_VFE (32 + 25) +#define INT_USB_HS (32 + 26) +#define INT_AUDIO_OUT0 (32 + 27) +#define INT_AUDIO_OUT1 (32 + 28) +#define INT_CRYPTO (32 + 29) +#define INT_AD6M_IDLE (32 + 30) +#define INT_SIRC_1 (32 + 31) + +/* secondary interrupt controller */ + +#define INT_UART1_IRQ (64 + 0) +#define INT_UART2_IRQ (64 + 1) +#define INT_UART3_IRQ (64 + 2) +#define INT_UART1_RX (64 + 3) +#define INT_UART2_RX (64 + 4) +#define INT_UART3_RX (64 + 5) +#define INT_SPI_INPUT (64 + 6) +#define INT_SPI_OUTPUT (64 + 7) +#define INT_SPI_ERROR (64 + 8) +#define INT_GPIO1_SHADOW (64 + 9) +#define INT_GPIO2_SHADOW (64 + 10) +#define INT_GPIO1_SECURE (64 + 11) +#define INT_GPIO2_SECURE (64 + 12) +#define INT_SC_AVS_SVIC (64 + 13) +#define INT_SC_AVS_REQ_UP (64 + 14) +#define INT_SC_AVS_REQ_DOWN (64 + 15) +#define INT_PBUS_ERR (64 + 16) +#define INT_AXI (64 + 17) +#define INT_SMI (64 + 18) +#define INT_EBI (64 + 19) +#define INT_IMEM (64 + 20) +#define INT_SC_TEMP_SENSOR (64 + 21) +#define INT_TV_ENC (64 + 22) + +#define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) + +#define NR_IRQS 64 + +#endif diff --git a/lk/platform/qsd8650a/interrupts.c b/lk/platform/qsd8650a/interrupts.c new file mode 100644 index 0000000..9071677 --- /dev/null +++ b/lk/platform/qsd8650a/interrupts.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define VIC_REG(off) (MSM_VIC_BASE + (off)) + +#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_EN0 VIC_REG(0x0010) +#define VIC_INT_EN1 VIC_REG(0x0014) +#define VIC_INT_ENCLEAR0 VIC_REG(0x0020) +#define VIC_INT_ENCLEAR1 VIC_REG(0x0024) +#define VIC_INT_ENSET0 VIC_REG(0x0030) +#define VIC_INT_ENSET1 VIC_REG(0x0034) +#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */ +#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */ +#define VIC_NO_PEND_VAL VIC_REG(0x0060) +#define VIC_INT_MASTEREN VIC_REG(0x0068) /* 1: IRQ, 2: FIQ */ +#define VIC_CONFIG VIC_REG(0x006C) /* 1: USE ARM1136 VIC */ +#define VIC_SECURITY0 VIC_REG(0x0070) +#define VIC_SECURITY1 VIC_REG(0x0074) +#define VIC_IRQ_STATUS0 VIC_REG(0x0080) +#define VIC_IRQ_STATUS1 VIC_REG(0x0084) +#define VIC_FIQ_STATUS0 VIC_REG(0x0090) +#define VIC_FIQ_STATUS1 VIC_REG(0x0094) +#define VIC_RAW_STATUS0 VIC_REG(0x00A0) +#define VIC_RAW_STATUS1 VIC_REG(0x00A4) +#define VIC_INT_CLEAR0 VIC_REG(0x00B0) +#define VIC_INT_CLEAR1 VIC_REG(0x00B4) +#define VIC_SOFTINT0 VIC_REG(0x00C0) +#define VIC_SOFTINT1 VIC_REG(0x00C4) +#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */ +#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */ +#define VIC_IRQ_VEC_WR VIC_REG(0x00D8) +#define VIC_FIQ_VEC_RD VIC_REG(0x00DC) /* pending int # */ +#define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0) /* pending vector addr */ +#define VIC_FIQ_VEC_WR VIC_REG(0x00E4) +#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E8) +#define VIC_IRQ_IN_STACK VIC_REG(0x00EC) +#define VIC_FIQ_IN_SERVICE VIC_REG(0x00F0) +#define VIC_FIQ_IN_STACK VIC_REG(0x00F4) +#define VIC_TEST_BUS_SEL VIC_REG(0x00F8) + +#define SIRC_REG(off) (MSM_SIRC_BASE + (off)) + +#define SIRC_INT_SELECT SIRC_REG(0x0000) /* 0: IRQ0 1: IRQ1 */ +#define SIRC_INT_ENABLE SIRC_REG(0x0004) +#define SIRC_INT_ENCLEAR SIRC_REG(0x0008) +#define SIRC_INT_ENSET SIRC_REG(0x000C) +#define SIRC_INT_TYPE SIRC_REG(0x0010) /* 1: EDGE, 0: LEVEL */ +#define SIRC_INT_POLARITY SIRC_REG(0x0014) /* 1: NEG, 0: POS */ +#define SIRC_SECURITY SIRC_REG(0x0018) /* 0: SEC, 1: NSEC */ +#define SIRC_IRQ0_STATUS SIRC_REG(0x001C) +#define SIRC_IRQ1_STATUS SIRC_REG(0x0020) +#define SIRC_RAW_STATUS SIRC_REG(0x0024) + +struct ihandler { + int_handler func; + void *arg; +}; + +static struct ihandler handler[NR_IRQS]; + +void platform_init_interrupts(void) +{ + writel(0xffffffff, VIC_INT_CLEAR0); + writel(0xffffffff, VIC_INT_CLEAR1); + writel(0, VIC_INT_SELECT0); + writel(0, VIC_INT_SELECT1); + writel(0xffffffff, VIC_INT_TYPE0); + writel(0xffffffff, VIC_INT_TYPE1); + writel(0, VIC_CONFIG); + writel(1, VIC_INT_MASTEREN); +} + +enum handler_return platform_irq(struct arm_iframe *frame) +{ + unsigned num; + enum handler_return ret; + num = readl(VIC_IRQ_VEC_RD); + num = readl(VIC_IRQ_VEC_PEND_RD); + if (num > NR_IRQS) + return 0; + writel(1 << (num & 31), (num > 31) ? VIC_INT_CLEAR1 : VIC_INT_CLEAR0); + ret = handler[num].func(handler[num].arg); + writel(0, VIC_IRQ_VEC_WR); + return ret; +} + +void platform_fiq(struct arm_iframe *frame) +{ + PANIC_UNIMPLEMENTED; +} + +status_t mask_interrupt(unsigned int vector) +{ + unsigned reg = (vector > 31) ? VIC_INT_ENCLEAR1 : VIC_INT_ENCLEAR0; + unsigned bit = 1 << (vector & 31); + writel(bit, reg); + return 0; +} + +status_t unmask_interrupt(unsigned int vector) +{ + unsigned reg = (vector > 31) ? VIC_INT_ENSET1 : VIC_INT_ENSET0; + unsigned bit = 1 << (vector & 31); + writel(bit, reg); + return 0; +} + +void register_int_handler(unsigned int vector, int_handler func, void *arg) +{ + if (vector >= NR_IRQS) + return; + + enter_critical_section(); + handler[vector].func = func; + handler[vector].arg = arg; + exit_critical_section(); +} + diff --git a/lk/platform/qsd8650a/platform.c b/lk/platform/qsd8650a/platform.c new file mode 100644 index 0000000..5a64ca0 --- /dev/null +++ b/lk/platform/qsd8650a/platform.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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. + */ + +#include + +#include +#include +#include + +void platform_init_interrupts(void); +void platform_init_timer(); + +void uart3_clock_init(void); +void uart_init(void); + +struct fbcon_config *lcdc_init(void); + +void platform_early_init(void) +{ + //uart3_clock_init(); + //uart_init(); + + platform_init_interrupts(); + platform_init_timer(); +} + +void platform_init(void) +{ + dprintf(INFO, "platform_init()\n"); +#if (!ENABLE_NANDWRITE) + acpu_clock_init(); +#endif +} + +void display_init(void) +{ + struct fbcon_config *fb_cfg; + fb_cfg = lcdc_init(); + fbcon_setup(fb_cfg); +} + diff --git a/lk/platform/qsd8650a/rules.mk b/lk/platform/qsd8650a/rules.mk new file mode 100644 index 0000000..bc38e84 --- /dev/null +++ b/lk/platform/qsd8650a/rules.mk @@ -0,0 +1,25 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +ARCH := arm +ARM_CPU := cortex-a8 +#arm1136j-s +CPU := generic + +DEFINES += WITH_CPU_EARLY_INIT=1 WITH_CPU_WARM_BOOT=1 + +INCLUDES += -I$(LOCAL_DIR)/include + +DEVS += fbcon +MODULES += dev/fbcon + +OBJS += \ + $(LOCAL_DIR)/arch_init.o \ + $(LOCAL_DIR)/platform.o \ + $(LOCAL_DIR)/interrupts.o \ + $(LOCAL_DIR)/gpio.o \ + $(LOCAL_DIR)/acpuclock.o + +LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld + +include platform/msm_shared/rules.mk + diff --git a/lk/platform/qsd8k/acpuclock.c b/lk/platform/qsd8k/acpuclock.c new file mode 100644 index 0000000..d2de674 --- /dev/null +++ b/lk/platform/qsd8k/acpuclock.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#define A11S_CLK_CNTL 0xAC100100 +#define A11S_CLK_SEL 0xAC100104 + +#define SCPLL_CTL 0xA8800004 +#define SCPLL_CTLE 0xA8800010 +#define SCPLL_STAT 0xA8800018 + +void acpu_clock_init(void) +{ + unsigned val; + + /* Init Scorpion PLL */ + writel(0x0, SCPLL_CTL); + writel(0x00400002, SCPLL_CTL); + writel(0x00600004, SCPLL_CTL); + thread_sleep(1); + while(readl(SCPLL_STAT) & 0x2); + writel(0x0, SCPLL_CTL); + + /* Enable pll */ + while(readl(SCPLL_STAT) & 0x1); + val = readl(SCPLL_CTL); + val &= ~(0x7); + val |= 0x2; + writel(val, SCPLL_CTL); + thread_sleep(1); + val = readl(SCPLL_CTL); + val |= 0x7; + writel(val, SCPLL_CTL); + thread_sleep(1); + + /* For Scorpion PLL, must first SHOT to 384MHz then HOP to 768MHz */ + + /* Set pll to 384 MHz */ + while(readl(SCPLL_STAT) & 0x3); + val = readl(SCPLL_CTLE); + val &= ~(0x3F << 3); + val |= (0xA << 3); + val &= ~(0x3 << 0); + val |= (4 << 0); // SHOT method + writel(val, SCPLL_CTLE); + writel(0x00600007, SCPLL_CTL); + thread_sleep(1); + + /* HOP to 768MHz */ + while(readl(SCPLL_STAT) & 0x3); + val = readl(SCPLL_CTLE); + val &= ~(0x3F << 3); + val |= (0x14 << 3); // Use 0x1A instead of 0x14 for 998MHz + val &= ~(0x3 << 0); + val |= (5 << 0); // HOP method + writel(val, SCPLL_CTLE); + writel(0x00600007, SCPLL_CTL); + thread_sleep(1); + + val = readl(A11S_CLK_SEL); + val &= ~(0x3 << 1); + val |= (1 << 1); + writel(val, A11S_CLK_SEL); +} + diff --git a/lk/platform/qsd8k/arch_init.S b/lk/platform/qsd8k/arch_init.S new file mode 100644 index 0000000..1e93696 --- /dev/null +++ b/lk/platform/qsd8k/arch_init.S @@ -0,0 +1,648 @@ +/* + * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. + * Copyright (c) 2008, Google 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 Google, Inc. 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. + */ + + +/* TODO: + * - style cleanup + * - do we need to do *all* of this at boot? + */ + +.text +.code 32 + +#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5 +#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5 + +/* + ; LVT Ring Osc counter + ; used to determine sense amp settings + ; Clobbers registers r0, r4, r5, r6, r7, r9, r10, r11 +*/ +.equ CLK_CTL_BASE, 0xA8600000 +.equ A_GLBL_CLK_ENA, 0x0000 +.equ A_PRPH_WEB_NS_REG,0x0080 +.equ A_MSM_CLK_RINGOSC,0x00D0 +.equ A_TCXO_CNT, 0x00D4 +.equ A_TCXO_CNT_DONE, 0x00D8 +.equ A_RINGOSC_CNT, 0x00DC +.equ A_MISC_CLK_CTL, 0x0108 +.equ CLK_TEST, 0xA8600114 +.equ SPSS_CSR_BASE, 0xAC100000 +.equ A_SCRINGOSC, 0x0510 + +//;; Number of TCXO cycles to count ring oscillations +.equ TCXO_CNT_VAL, 0x100 + +//; Raptor addresses +.equ TCSR_SPARE2, 0xA8700060 + + +.globl SET_SA +SET_SA: + //; no stack at this point and any registers we use will be 0'd + //; after we return + LDR r0, =TCSR_SPARE2 + LDR r1, [r0] + LDR r0, = 0x010F + AND r2, r1, r0 //; concerned with bits [8, 3:0] + + //;-------------------------------------------------------------------- + //; Fuse bits used to determine sense amp settings + //;-------------------------------------------------------------------- + + LDR r0, = 0x0105 + AND r4, r2, r0 //; mask off all but L1 ACC2, L1 ACC1 and L1 ACC0 + //;set to default of FC00 + LDR r5, =PVR0F0_6bits //; point to PVR0F0 + LDR r3, =PVR2F0_6bits //; point to PVR2F0 + +ck_0: + //; if L1_[2:0] == 000 then ACC setting = FC00 + LDR r1, = 0x0 + CMP r4, r1 + BNE ck_1 + B WRITE_L1_SA_SETTINGS + +ck_1: + //; if L1_[2:0] == 001 then ACC setting = FC00 + LDR r1, = 0x01 + CMP r4, r1 + BNE ck_2 + B WRITE_L1_SA_SETTINGS + +ck_2: + //; if L1_[2:0] == 010 then ACC setting = 7C00 + LDR r1, = 0x04 + CMP r4, r1 + BNE ck_3 + LDR r5, =PVR0F0_5bits //; point to PVR0F0 + LDR r3, =PVR2F0_5bits //; point to PVR2F0 + B WRITE_L1_SA_SETTINGS + +ck_3: + //; if L1_[2:0] == 011 then ACC setting = FC00 + LDR r1, = 0x05 + CMP r4, r1 + BNE ck_4 + LDR r5, =PVR0F0_6bits //; point to PVR0F0 + LDR r3, =PVR2F0_6bits //; point to PVR2F0 + B WRITE_L1_SA_SETTINGS + +ck_4: + //; if L1_[2:0] == 0100 then ACC setting = 3C00 + LDR r1, = 0x0100 + CMP r4, r1 + BNE ck_5 + LDR r5, =PVR0F0_4bits //; point to PVR0F0 + LDR r3, =PVR2F0_4bits //; point to PVR2F0 + B WRITE_L1_SA_SETTINGS + +ck_5: + //; if L1_[2:0] == 0101 then ACC setting = 0400 + LDR r1, = 0x0101 + CMP r4, r1 + BNE ck_6 + LDR r5, =PVR0F0_1bits //; point to PVR0F0 + LDR r3, =PVR2F0_1bits //; point to PVR2F0 + B WRITE_L1_SA_SETTINGS + +ck_6: + //; if L1_[2:0] == 0110 then ACC setting = 0C00 + LDR r1, = 0x0104 + CMP r4, r1 + BNE ck_7 + LDR r5, =PVR0F0_2bits //; point to PVR0F0 + LDR r3, =PVR2F0_2bits //; point to PVR2F0 + B WRITE_L1_SA_SETTINGS + +ck_7: + //; if L1_[2:0] == 0111 then ACC setting = 1C00 + LDR r1, = 0x0105 + CMP r4, r1 + LDREQ r5, =PVR0F0_3bits //; point to PVR0F0 + LDREQ r3, =PVR2F0_3bits //; point to PVR2F0 + +WRITE_L1_SA_SETTINGS: + + LDR r5, [r5] + LDR r3, [r3] + + //;WCP15_PVR0F0 r5 + MCR p15,0x0,r5,c15,c15,0 //; write R5 to PVR0F0 + + //;WCP15_PVR2F0 r3 + MCR p15,0x2,r3,c15,c15,0 //; write R3 to PVR2F0 + + AND r4, r2, #0x000A //; mask off all but L2 array SA settings + LDR r5, =HVT_010102 //; point to L2VR3F1 setting + //;it gets ovewritten if its one of the other two cases + //; if L2_1 and L2_0 == 0 ACC setting = 010102 + LDR r1, = 0x0000 + CMP r4, r1 + BEQ WRITE_L2_SA_SETTINGS + + //; if L2_1 = 0 & L2_0 = 1 ACC setting = 010102 + LDR R1, = 0x0002 + CMP r4, r1 + BEQ WRITE_L2_SA_SETTINGS + + //; if L2_1 = 1 & L2_0 = 0 ACC setting = 010101 + LDR r5, =HVT_010101 + LDR R1, = 0x0008 + CMP r4, r1 + BEQ WRITE_L2_SA_SETTINGS + + //; else L2_1 = 1 & L2_0 = 1 ACC setting = 212102 + LDR r5, =HVT_212102 + + +WRITE_L2_SA_SETTINGS: + //;WCP15_L2VR3F1 r4 + LDR r5, [r5] + MCR p15,0x3,r5,c15,c15,1 //;write r4 to L2VR3F1 + + LDR r0, =0 //;make sure the registers we touched + LDR r1, =0 //;are cleared when we return + LDR r2, =0 + LDR r3, =0 + LDR r4, =0 + LDR r5, =0 + + //; routine complete + B _cpu_early_init_complete + +//; L1 SA settings according to LVT speed +PVR0F0_0bits: +.word 0x38000000 //; PVR0F0 +PVR2F0_0bits: +.word 0x00000000 //; PVR2F0 0 bits set + +PVR0F0_1bits: +.word 0x38000400 //; PVR0F0 +PVR2F0_1bits: +.word 0x04000000 //; PVR2F0 1 bits set + +PVR0F0_2bits: +.word 0x38000C00 //; PVR0F0 +PVR2F0_2bits: +.word 0x0C000000 //; PVR2F0 2 bits set + +PVR0F0_3bits: +.word 0x38001C00 //; PVR0F0 +PVR2F0_3bits: +.word 0x1C000000 //; PVR2F0 3 bits set + +PVR0F0_4bits: +.word 0x38003C00 //; PVR0F0 +PVR2F0_4bits: +.word 0x3C000000 //; PVR2F0 4 bits set + +PVR0F0_5bits: +.word 0x38007C00 //; PVR0F0 +PVR2F0_5bits: +.word 0x7C000000 //; PVR2F0 5 bits set + +PVR0F0_6bits: +.word 0x3800FC00 //; PVR0F0 +PVR2F0_6bits: +.word 0xFC000000 //; PVR2F0 6 bits set + +//; L2 SA settings according to HVT speed +HVT_212102: +.word 0x00212102 //; L2VR3F1 + +HVT_010102: +.word 0x00010102 //; L2VR3F1 + +HVT_010101: +.word 0x00010101 //; L2VR3F1 + + +.ltorg + + +.globl __cpu_early_init +__cpu_early_init: + //; Zero out r0 for use throughout this code. All other GPRs + //; (r1-r3) are set throughout this code to help establish + //; a consistent startup state for any code that follows. + //; Users should add code at the end of this routine to establish + //; their own stack address (r13), add translation page tables, enable + //; the caches, etc. + MOV r0, #0x0 + + + //; Remove hardcoded cache settings. appsbl_handler.s calls Set_SA + //; API to dynamically configure cache for slow/nominal/fast parts + + //; DCIALL to invalidate L2 cache bank (needs to be run 4 times, once per bank) + //; This must be done early in code (prior to enabling the caches) + MOV r1, #0x2 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank D ([15:14] == 2'b00) + ORR r1, r1, #0x00004000 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank C ([15:14] == 2'b01) + ADD r1, r1, #0x00004000 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank B ([15:14] == 2'b10) + ADD r1, r1, #0x00004000 + MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank A ([15:14] == 2'b11) + + //; Initialize the BPCR - setup Global History Mask (GHRM) to all 1's + //; and have all address bits (AM) participate. + //; Different settings can be used to improve performance + // MOVW r1, #0x01FF +.word 0xe30011ff // hardcoded MOVW instruction due to lack of compiler support + // MOVT r1, #0x01FF +.word 0xe34011ff // hardcoded MOVT instruction due to lack of compiler support + MCR p15, 7, r1, c15, c0, 2 //; WCP15_BPCR + + + //; Initialize all I$ Victim Registers to 0 for startup + MCR p15, 0, r0, c9, c1, 0 //; WCP15_ICVIC0 r0 + MCR p15, 0, r0, c9, c1, 1 //; WCP15_ICVIC1 r0 + MCR p15, 0, r0, c9, c1, 2 //; WCP15_ICVIC2 r0 + MCR p15, 0, r0, c9, c1, 3 //; WCP15_ICVIC3 r0 + MCR p15, 0, r0, c9, c1, 4 //; WCP15_ICVIC4 r0 + MCR p15, 0, r0, c9, c1, 5 //; WCP15_ICVIC5 r0 + MCR p15, 0, r0, c9, c1, 6 //; WCP15_ICVIC5 r0 + MCR p15, 0, r0, c9, c1, 7 //; WCP15_ICVIC7 r0 + + //; Initialize all I$ Locked Victim Registers (Unlocked Floors) to 0 + MCR p15, 1, r0, c9, c1, 0 //; WCP15_ICFLOOR0 r0 + MCR p15, 1, r0, c9, c1, 1 //; WCP15_ICFLOOR1 r0 + MCR p15, 1, r0, c9, c1, 2 //; WCP15_ICFLOOR2 r0 + MCR p15, 1, r0, c9, c1, 3 //; WCP15_ICFLOOR3 r0 + MCR p15, 1, r0, c9, c1, 4 //; WCP15_ICFLOOR4 r0 + MCR p15, 1, r0, c9, c1, 5 //; WCP15_ICFLOOR5 r0 + MCR p15, 1, r0, c9, c1, 6 //; WCP15_ICFLOOR6 r0 + MCR p15, 1, r0, c9, c1, 7 //; WCP15_ICFLOOR7 r0 + + //; Initialize all D$ Victim Registers to 0 + MCR p15, 2, r0, c9, c1, 0 //; WP15_DCVIC0 r0 + MCR p15, 2, r0, c9, c1, 1 //; WP15_DCVIC1 r0 + MCR p15, 2, r0, c9, c1, 2 //; WP15_DCVIC2 r0 + MCR p15, 2, r0, c9, c1, 3 //; WP15_DCVIC3 r0 + MCR p15, 2, r0, c9, c1, 4 //; WP15_DCVIC4 r0 + MCR p15, 2, r0, c9, c1, 5 //; WP15_DCVIC5 r0 + MCR p15, 2, r0, c9, c1, 6 //; WP15_DCVIC6 r0 + MCR p15, 2, r0, c9, c1, 7 //; WP15_DCVIC7 r0 + + //; Initialize all D$ Locked VDCtim Registers (Unlocked Floors) to 0 + MCR p15, 3, r0, c9, c1, 0 //; WCP15_DCFLOOR0 r0 + MCR p15, 3, r0, c9, c1, 1 //; WCP15_DCFLOOR1 r0 + MCR p15, 3, r0, c9, c1, 2 //; WCP15_DCFLOOR2 r0 + MCR p15, 3, r0, c9, c1, 3 //; WCP15_DCFLOOR3 r0 + MCR p15, 3, r0, c9, c1, 4 //; WCP15_DCFLOOR4 r0 + MCR p15, 3, r0, c9, c1, 5 //; WCP15_DCFLOOR5 r0 + MCR p15, 3, r0, c9, c1, 6 //; WCP15_DCFLOOR6 r0 + MCR p15, 3, r0, c9, c1, 7 //; WCP15_DCFLOOR7 r0 + + //; Initialize ASID to zero + MCR p15, 0, r0, c13, c0, 1 //; WCP15_CONTEXTIDR r0 + + //; ICIALL to invalidate entire I-Cache + MCR p15, 0, r0, c7, c5, 0 //; ICIALLU + + //; DCIALL to invalidate entire D-Cache + MCR p15, 0, r0, c9, c0, 6 //; DCIALL r0 + + //; Initialize ADFSR to zero + MCR p15, 0, r0, c5, c1, 0 //; ADFSR r0 + + //; Initialize EFSR to zero + MCR p15, 7, r0, c15, c0, 1 //; EFSR r0 + + //; The VBAR (Vector Base Address Register) should be initialized + //; early in your code. We are setting it to zero + MCR p15, 0, r0, c12, c0, 0 //; WCP15_VBAR r0 + + //; Ensure the MCR's above have completed their operation before continuing + DSB + ISB + + //;------------------------------------------------------------------- + //; There are a number of registers that must be set prior to enabling + //; the MMU. The DCAR is one of these registers. We are setting + //; it to zero (no access) to easily detect improper setup in subsequent + //; code sequences + //;------------------------------------------------------------------- + //; Setup DACR (Domain Access Control Register) to zero + MCR p15, 0, r0, c3, c0, 0 //; WCP15_DACR r0 + + //; Setup DCLKCR to allow normal D-Cache line fills + MCR p15, 1, r0, c9, c0, 7 //; WCP15_DCLKCR r0 + + //; Setup the TLBLKCR + //; Victim = 6'b000000; Floor = 6'b000000; + //; IASIDCFG = 2'b00 (State-Machine); IALLCFG = 2'b01 (Flash); BNA = 1'b0; + MOV r1, #0x02 + MCR p15, 0, r1, c10, c1, 3 //; WCP15_TLBLKCR r1 + + //;Make sure TLBLKCR is complete before continuing + ISB + + //; Invalidate the UTLB + MCR p15, 0, r0, c8, c7, 0 //; UTLBIALL + + //; Make sure UTLB request has been presented to macro before continuing + ISB + + // Disable predecode repair cache on certain Scorpion revisions + // (Raptor V2 and earlier, or Halcyon V1) + MRC p15, 0, r1, c0, c0, 0 //; MIDR + BIC r2, r1, #0xf7 //; check for Raptor2 or below + LDR r3, =0x510f0000 + CMP r2, r3 + BEQ DPRC + BIC r2, r1, #0xf0 //; check for Halcyon V1 + LDR r3, =0x511f0000 + CMP r2, r3 + BNE SYSI2 + +DPRC: + MRC p15, 0, r1, c15, c15, 2 //; PVR0F2 + ORR r1, r1, #0x10 //; enable bit 4 + MCR p15, 0, r1, c15, c15, 2 //; disable predecode repair cache + +SYSI2: + //; setup L2CR1 to some default Instruction and data prefetching values + //; Users may want specific settings for various performance enhancements + MOV r2, #0x33 + MCR p15, 3, r2, c15, c0, 3 //; WCP15_L2CR1 r0 + + + //; Enable Z bit to enable branch prediction (default is off) + MRC p15, 0, r2, c1, c0, 0 //; RCP15_SCTLR r2 + ORR r2, r2, #0x00000800 + MCR p15, 0, r2, c1, c0, 0 //; WCP15_SCTLR r2 + + //; Make sure Link stack is initialized with branch and links to sequential addresses + //; This aids in creating a predictable startup environment + BL SEQ1 +SEQ1: BL SEQ2 +SEQ2: BL SEQ3 +SEQ3: BL SEQ4 +SEQ4: BL SEQ5 +SEQ5: BL SEQ6 +SEQ6: BL SEQ7 +SEQ7: BL SEQ8 +SEQ8: + + //; REMOVE FOLLOWING THREE INSTRUCTIONS WHEN POWER COLLAPSE IS ENA + //;Make sure the DBGOSLSR[LOCK] bit is cleared to allow access to the debug registers + //; Writing anything but the "secret code" to the DBGOSLAR clears the DBGOSLSR[LOCK] bit + MCR p14, 0, r0, c1, c0, 4 //; WCP14_DBGOSLAR r0 + + + //; Read the DBGPRSR to clear the DBGPRSR[STICKYPD] + //; Any read to DBGPRSR clear the STICKYPD bit + //; ISB guarantees the read completes before attempting to + //; execute a CP14 instruction. + MRC p14, 0, r3, c1, c5, 4 //; RCP14_DBGPRSR r3 + ISB + + //; Initialize the Watchpoint Control Registers to zero (optional) + //;;; MCR p14, 0, r0, c0, c0, 7 ; WCP14_DBGWCR0 r0 + //;;; MCR p14, 0, r0, c0, c1, 7 ; WCP14_DBGWCR1 r0 + + + //;---------------------------------------------------------------------- + //; The saved Program Status Registers (SPSRs) should be setup + //; prior to any automatic mode switches. The following + //; code sets these registers up to a known state. Users will need to + //; customize these settings to meet their needs. + //;---------------------------------------------------------------------- + MOV r2, #0x1f + MOV r1, #0xd7 //;ABT mode + msr cpsr_c, r1 //;ABT mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xdb //;UND mode + msr cpsr_c, r1 //;UND mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd1 //;FIQ mode + msr cpsr_c, r1 //;FIQ mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd2 //;IRQ mode + msr cpsr_c, r1 //;IRQ mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd6 //;Monitor mode + msr cpsr_c, r1 //;Monitor mode + msr spsr_cxfs, r2 //;clear the spsr + MOV r1, #0xd3 //;SVC mode + msr cpsr_c, r1 //;SVC mode + msr spsr_cxfs, r2 //;clear the spsr + + + //;---------------------------------------------------------------------- + //; Enabling Error reporting is something users may want to do at + //; some other point in time. We have chosen some default settings + //; that should be reviewed. Most of these registers come up in an + //; unpredictable state after reset. + //;---------------------------------------------------------------------- +//;Start of error and control setting + + //; setup L2CR0 with various L2/TCM control settings + //; enable out of order bus attributes and error reporting + //; this register comes up unpredictable after reset + // MOVW r1, #0x0F0F +.word 0xe3001f0f // hardcoded MOVW instruction due to lack of compiler support + // MOVT r1, #0xC005 +.word 0xe34c1005 // hardcoded MOVW instruction due to lack of compiler support + MCR p15, 3, r1, c15, c0, 1 //; WCP15_L2CR0 r1 + + //; setup L2CPUCR + //; MOV r2, #0xFF + //; Enable I and D cache parity + //;L2CPUCR[7:5] = 3~Rh7 ~V enable parity error reporting for modified, + //;tag, and data parity errors + MOV r2, #0xe0 + MCR p15, 3, r2, c15, c0, 2 //; WCP15_L2CPUCR r2 + + //; setup SPCR + //; enable all error reporting (reset value is unpredicatble for most bits) + MOV r3, #0x0F + MCR p15, 0, r3, c9, c7, 0 //; WCP15_SPCR r3 + + //; setup DMACHCRs (reset value unpredictable) + //; control setting and enable all error reporting + MOV r1, #0x0F + + //; DMACHCR0 = 0000000F + MOV r2, #0x00 //; channel 0 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; DMACHCR1 = 0000000F + MOV r2, #0x01 //; channel 1 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; DMACHCR2 = 0000000F + MOV r2, #0x02 //; channel 2 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; DMACHCR3 = 0000000F + MOV r2, #0x03 //; channel 3 + MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2 + MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1 + + //; Set ACTLR (reset unpredictable) + //; Set AVIVT control, error reporting, etc. + //; MOV r3, #0x07 + //; Enable I and D cache parity + //;ACTLR[2:0] = 3'h7 - enable parity error reporting from L2/I$/D$) + //;ACTLR[5:4] = 2'h3 - enable parity + //;ACTLR[19:18] =2'h3 - always generate and check parity(when MMU disabled). + //;Value to be written #0xC0037 + // MOVW r3, #0x0037 +.word 0xe3003037 // hardcoded MOVW instruction due to lack of compiler support + // MOVT r3, #0x000C +.word 0xe340300c // hardcoded MOVW instruction due to lack of compiler support + //; read the version_id to determine if d-cache should be disabled + LDR r2, = 0xa8e00270 //;Read HW_REVISION_NUMBER, HWIO_HW_REVISION_NUMBER_ADDR + LDR r2,[r2] + AND r2,r2,#0xf0000000 //;hw_revision mask off bits 28-31 + //;if HW_revision is 1.0 or older, (revision==0) + CMP r2,#0 + //; Disable d-cache on older QSD8650 (Rev 1.0) silicon + //;orreq r3, r3, #0x4000 //;disable dcache + //;MCR p15, 0, r3, c1, c0, 1 //; WCP15_ACTLR r3 + +//;End of error and control setting + + //;---------------------------------------------------------------------- + //; Unlock ETM and read StickyPD to halt the ETM clocks from running. + //; This is required for power saving whether the ETM is used or not. + //;---------------------------------------------------------------------- + + //;Clear ETMOSLSR[LOCK] bit + MOV r1, #0x00000000 + MCR p14, 1, r1, c1, c0, 4 //; WCP14_ETMOSLAR r1 + + //;Clear ETMPDSR[STICKYPD] bit + MRC p14, 1, r2, c1, c5, 4 //; RCP14_ETMPDSR r2 + +/* +#ifdef APPSBL_ETM_ENABLE + ;---------------------------------------------------------------------- + ; Optionally Enable the ETM (Embedded Trace Macro) which is used for debug + ;---------------------------------------------------------------------- + + ; enable ETM clock if disabled + MRC p15, 7, r1, c15, c0, 5 ; RCP15_CPMR r1 + ORR r1, r1, #0x00000008 + MCR p15, 7, r1, c15, c0, 5 ; WCP15_CPMR r1 + ISB + + ; set trigger event to counter1 being zero + MOV r3, #0x00000040 + MCR p14, 1, r3, c0, c2, 0 ; WCP14_ETMTRIGGER r3 + + ; clear ETMSR + MOV r2, #0x00000000 + MCR p14, 1, r2, c0, c4, 0 ; WCP14_ETMSR r2 + + ; clear trace enable single address comparator usage + MCR p14, 1, r2, c0, c7, 0 ; WCP14_ETMTECR2 r2 + + ; set trace enable to always + MOV r2, #0x0000006F + MCR p14, 1, r2, c0, c8, 0 ; WCP14_ETMTEEVR r2 + + ; clear trace enable address range comparator usage and exclude nothing + MOV r2, #0x01000000 + MCR p14, 1, r2, c0, c9, 0 ; WCP14_ETMTECR1 r2 + + ; set view data to always + MOV r2, #0x0000006F + MCR p14, 1, r2, c0, c12, 0 ; WCP14_ETMVDEVR r2 + + ; clear view data single address comparator usage + MOV r2, #0x00000000 + MCR p14, 1, r2, c0, c13, 0 ; WCP14_ETMVDCR1 r2 + + ; clear view data address range comparator usage and exclude nothing + MOV r2, #0x00010000 + MCR p14, 1, r2, c0, c15, 0 ; WCP14_ETMVDCR3 r2 + + ; set counter1 to 194 + MOV r2, #0x000000C2 + MCR p14, 1, r2, c0, c0, 5 ; WCP14_ETMCNTRLDVR1 r2 + + ; set counter1 to never reload + MOV r2, #0x0000406F + MCR p14, 1, r2, c0, c8, 5 ; WCP14_ETMCNTRLDEVR1 r2 + + ; set counter1 to decrement every cycle + MOV r2, #0x0000006F + MCR p14, 1, r2, c0, c4, 5 ; WCP14_ETMCNTENR1 r2 + + ; Set trace synchronization frequency 1024 bytes + MOV r2, #0x00000400 + MCR p14, 1, r2, c0, c8, 7 ; WCP14_ETMSYNCFR r2 + + ; Program etm control register + ; - Set the CPU to ETM clock ratio to 1:1 + ; - Set the ETM to perform data address tracing + MOV r2, #0x00002008 + MCR p14, 1, r2, c0, c0, 0 ; WCP14_ETMCR r2 + ISB +#endif *//* APPSBL_ETM_ENABLE */ + +/* +#ifdef APPSBL_VFP_ENABLE + ;---------------------------------------------------------------------- + ; Perform the following operations if you intend to make use of + ; the VFP/Neon unit. Note that the FMXR instruction requires a CPU ID + ; indicating the VFP unit is present (i.e.Cortex-A8). . + ; Some tools will require full double precision floating point support + ; which will become available in Scorpion pass 2 + ;---------------------------------------------------------------------- + ; allow full access to CP 10 and 11 space for VFP/NEON use + MRC p15, 0, r1, c1, c0, 2 ; Read CP Access Control Register + ORR r1, r1, #0x00F00000 ; enable full access for p10,11 + MCR p15, 0, r1, c1, c0, 2 ; Write CPACR + + ;make sure the CPACR is complete before continuing + ISB + + ; Enable VFP itself (certain OSes may want to dynamically set/clear + ; the enable bit based on the application being executed + MOV r1, #0x40000000 + FMXR FPEXC, r1 +#endif *//* APPSBL_VFP_ENABLE */ + + /* we have no stack, so just tail-call into the SET_SA routine... */ + b SET_SA + + +.ltorg diff --git a/lk/platform/qsd8k/gpio.c b/lk/platform/qsd8k/gpio.c new file mode 100644 index 0000000..0b1272b --- /dev/null +++ b/lk/platform/qsd8k/gpio.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2008, Google 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "gpio_hw.h" + +typedef struct gpioregs gpioregs; + +struct gpioregs +{ + unsigned out; + unsigned in; + unsigned int_status; + unsigned int_clear; + unsigned int_en; + unsigned int_edge; + unsigned int_pos; + unsigned oe; +}; + +static gpioregs GPIO_REGS[] = { + { + .out = GPIO_OUT_0, + .in = GPIO_IN_0, + .int_status = GPIO_INT_STATUS_0, + .int_clear = GPIO_INT_CLEAR_0, + .int_en = GPIO_INT_EN_0, + .int_edge = GPIO_INT_EDGE_0, + .int_pos = GPIO_INT_POS_0, + .oe = GPIO_OE_0, + }, + { + .out = GPIO_OUT_1, + .in = GPIO_IN_1, + .int_status = GPIO_INT_STATUS_1, + .int_clear = GPIO_INT_CLEAR_1, + .int_en = GPIO_INT_EN_1, + .int_edge = GPIO_INT_EDGE_1, + .int_pos = GPIO_INT_POS_1, + .oe = GPIO_OE_1, + }, + { + .out = GPIO_OUT_2, + .in = GPIO_IN_2, + .int_status = GPIO_INT_STATUS_2, + .int_clear = GPIO_INT_CLEAR_2, + .int_en = GPIO_INT_EN_2, + .int_edge = GPIO_INT_EDGE_2, + .int_pos = GPIO_INT_POS_2, + .oe = GPIO_OE_2, + }, + { + .out = GPIO_OUT_3, + .in = GPIO_IN_3, + .int_status = GPIO_INT_STATUS_3, + .int_clear = GPIO_INT_CLEAR_3, + .int_en = GPIO_INT_EN_3, + .int_edge = GPIO_INT_EDGE_3, + .int_pos = GPIO_INT_POS_3, + .oe = GPIO_OE_3, + }, + { + .out = GPIO_OUT_4, + .in = GPIO_IN_4, + .int_status = GPIO_INT_STATUS_4, + .int_clear = GPIO_INT_CLEAR_4, + .int_en = GPIO_INT_EN_4, + .int_edge = GPIO_INT_EDGE_4, + .int_pos = GPIO_INT_POS_4, + .oe = GPIO_OE_4, + }, + { + .out = GPIO_OUT_5, + .in = GPIO_IN_5, + .int_status = GPIO_INT_STATUS_5, + .int_clear = GPIO_INT_CLEAR_5, + .int_en = GPIO_INT_EN_5, + .int_edge = GPIO_INT_EDGE_5, + .int_pos = GPIO_INT_POS_5, + .oe = GPIO_OE_5, + }, + { + .out = GPIO_OUT_6, + .in = GPIO_IN_6, + .int_status = GPIO_INT_STATUS_6, + .int_clear = GPIO_INT_CLEAR_6, + .int_en = GPIO_INT_EN_6, + .int_edge = GPIO_INT_EDGE_6, + .int_pos = GPIO_INT_POS_6, + .oe = GPIO_OE_6, + }, + { + .out = GPIO_OUT_7, + .in = GPIO_IN_7, + .int_status = GPIO_INT_STATUS_7, + .int_clear = GPIO_INT_CLEAR_7, + .int_en = GPIO_INT_EN_7, + .int_edge = GPIO_INT_EDGE_7, + .int_pos = GPIO_INT_POS_7, + .oe = GPIO_OE_7, + }, +}; + +static gpioregs *find_gpio(unsigned n, unsigned *bit) +{ + if(n > 164) return 0; + if(n > 152) { + *bit = 1 << (n - 153); + return GPIO_REGS + 7; + } + if(n > 121) { + *bit = 1 << (n - 122); + return GPIO_REGS + 6; + } + if(n > 103) { + *bit = 1 << (n - 104); + return GPIO_REGS + 5; + } + if(n > 94) { + *bit = 1 << (n - 95); + return GPIO_REGS + 4; + } + if(n > 67) { + *bit = 1 << (n - 68); + return GPIO_REGS + 3; + } + if(n > 42) { + *bit = 1 << (n - 43); + return GPIO_REGS + 2; + } + if(n > 15) { + *bit = 1 << (n - 16); + return GPIO_REGS + 1; + } + *bit = 1 << n; + return GPIO_REGS + 0; +} + +int gpio_config(unsigned n, unsigned flags) +{ + gpioregs *r; + unsigned b; + unsigned v; + + if ((r = find_gpio(n, &b)) == 0) + return -1; + + v = readl(r->oe); + if (flags & GPIO_OUTPUT) { + writel(v | b, r->oe); + } else { + writel(v & (~b), r->oe); + } + return 0; +} + +void gpio_set(unsigned n, unsigned on) +{ + gpioregs *r; + unsigned b; + unsigned v; + + if((r = find_gpio(n, &b)) == 0) return; + + v = readl(r->out); + if(on) { + writel(v | b, r->out); + } else { + writel(v & (~b), r->out); + } +} + +int gpio_get(unsigned n) +{ + gpioregs *r; + unsigned b; + + if((r = find_gpio(n, &b)) == 0) return 0; + + return (readl(r->in) & b) ? 1 : 0; +} + + diff --git a/lk/platform/qsd8k/gpio_hw.h b/lk/platform/qsd8k/gpio_hw.h new file mode 100644 index 0000000..3ef40f6 --- /dev/null +++ b/lk/platform/qsd8k/gpio_hw.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2008, Google 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. + * + * 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 __PLATFORM_QSD8K_GPIO_HW_H +#define __PLATFORM_QSD8K_GPIO_HW_H + +#define MSM_GPIO1_BASE 0xA9000000 +#define MSM_GPIO2_BASE 0xA9100000 + +#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off)) +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off)) + +/* output value */ +#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */ +#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 42-16 */ +#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-43 */ +#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */ +#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 103-95 */ +#define GPIO_OUT_5 GPIO1_REG(0x10) /* gpio 121-104 */ +#define GPIO_OUT_6 GPIO1_REG(0x14) /* gpio 152-122 */ +#define GPIO_OUT_7 GPIO1_REG(0x18) /* gpio 164-153 */ + +/* same pin map as above, output enable */ +#define GPIO_OE_0 GPIO1_REG(0x20) +#define GPIO_OE_1 GPIO2_REG(0x08) +#define GPIO_OE_2 GPIO1_REG(0x24) +#define GPIO_OE_3 GPIO1_REG(0x28) +#define GPIO_OE_4 GPIO1_REG(0x2C) +#define GPIO_OE_5 GPIO1_REG(0x30) +#define GPIO_OE_6 GPIO1_REG(0x34) +#define GPIO_OE_7 GPIO1_REG(0x38) + +/* same pin map as above, input read */ +#define GPIO_IN_0 GPIO1_REG(0x50) +#define GPIO_IN_1 GPIO2_REG(0x20) +#define GPIO_IN_2 GPIO1_REG(0x54) +#define GPIO_IN_3 GPIO1_REG(0x58) +#define GPIO_IN_4 GPIO1_REG(0x5C) +#define GPIO_IN_5 GPIO1_REG(0x60) +#define GPIO_IN_6 GPIO1_REG(0x64) +#define GPIO_IN_7 GPIO1_REG(0x68) + +/* same pin map as above, 1=edge 0=level interrup */ +#define GPIO_INT_EDGE_0 GPIO1_REG(0x70) +#define GPIO_INT_EDGE_1 GPIO2_REG(0x50) +#define GPIO_INT_EDGE_2 GPIO1_REG(0x74) +#define GPIO_INT_EDGE_3 GPIO1_REG(0x78) +#define GPIO_INT_EDGE_4 GPIO1_REG(0x7C) +#define GPIO_INT_EDGE_5 GPIO1_REG(0x80) +#define GPIO_INT_EDGE_6 GPIO1_REG(0x84) +#define GPIO_INT_EDGE_7 GPIO1_REG(0x88) + +/* same pin map as above, 1=positive 0=negative */ +#define GPIO_INT_POS_0 GPIO1_REG(0x90) +#define GPIO_INT_POS_1 GPIO2_REG(0x58) +#define GPIO_INT_POS_2 GPIO1_REG(0x94) +#define GPIO_INT_POS_3 GPIO1_REG(0x98) +#define GPIO_INT_POS_4 GPIO1_REG(0x9C) +#define GPIO_INT_POS_5 GPIO1_REG(0xA0) +#define GPIO_INT_POS_6 GPIO1_REG(0xA4) +#define GPIO_INT_POS_7 GPIO1_REG(0xA8) + +/* same pin map as above, interrupt enable */ +#define GPIO_INT_EN_0 GPIO1_REG(0xB0) +#define GPIO_INT_EN_1 GPIO2_REG(0x60) +#define GPIO_INT_EN_2 GPIO1_REG(0xB4) +#define GPIO_INT_EN_3 GPIO1_REG(0xB8) +#define GPIO_INT_EN_4 GPIO1_REG(0xBC) +#define GPIO_INT_EN_5 GPIO1_REG(0xC0) +#define GPIO_INT_EN_6 GPIO1_REG(0xC4) +#define GPIO_INT_EN_7 GPIO1_REG(0xC8) + +/* same pin map as above, write 1 to clear interrupt */ +#define GPIO_INT_CLEAR_0 GPIO1_REG(0xD0) +#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68) +#define GPIO_INT_CLEAR_2 GPIO1_REG(0xD4) +#define GPIO_INT_CLEAR_3 GPIO1_REG(0xD8) +#define GPIO_INT_CLEAR_4 GPIO1_REG(0xDC) +#define GPIO_INT_CLEAR_5 GPIO1_REG(0xE0) +#define GPIO_INT_CLEAR_6 GPIO1_REG(0xE4) +#define GPIO_INT_CLEAR_7 GPIO1_REG(0xE8) + +/* same pin map as above, 1=interrupt pending */ +#define GPIO_INT_STATUS_0 GPIO1_REG(0xF0) +#define GPIO_INT_STATUS_1 GPIO2_REG(0x70) +#define GPIO_INT_STATUS_2 GPIO1_REG(0xF4) +#define GPIO_INT_STATUS_3 GPIO1_REG(0xF8) +#define GPIO_INT_STATUS_4 GPIO1_REG(0xFC) +#define GPIO_INT_STATUS_5 GPIO1_REG(0x100) +#define GPIO_INT_STATUS_6 GPIO1_REG(0x103) +#define GPIO_INT_STATUS_7 GPIO1_REG(0x108) + +#endif diff --git a/lk/platform/qsd8k/include/platform/iomap.h b/lk/platform/qsd8k/include/platform/iomap.h new file mode 100644 index 0000000..eadcf6a --- /dev/null +++ b/lk/platform/qsd8k/include/platform/iomap.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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 _PLATFORM_MSM7K_IOMAP_H_ +#define _PLATFORM_MSM7K_IOMAP_H_ + +#define MSM_UART1_BASE 0xA9A00000 +#define MSM_UART2_BASE 0xA9B00000 +#define MSM_UART3_BASE 0xA9C00000 + +#define MSM_VIC_BASE 0xAC000000 +#define MSM_GPT_BASE 0xAC100000 +#define MSM_CSR_BASE 0xAC100000 + +#if defined(PLATFORM_QSD8K) +#define MSM_SHARED_BASE 0x00100000 +#else +#define MSM_SHARED_BASE 0x01F00000 +#endif +#endif diff --git a/lk/platform/qsd8k/include/platform/irqs.h b/lk/platform/qsd8k/include/platform/irqs.h new file mode 100644 index 0000000..3548218 --- /dev/null +++ b/lk/platform/qsd8k/include/platform/irqs.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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 _PLATFORM_MSM7K_IRQS_H_ +#define _PLATFORM_MSM7K_IRQS_H_ + +#define INT_A9_M2A_0 0 +#define INT_A9_M2A_1 1 +#define INT_A9_M2A_2 2 +#define INT_A9_M2A_3 3 +#define INT_A9_M2A_4 4 +#define INT_A9_M2A_5 5 +#define INT_A9_M2A_6 6 +#define INT_GP_TIMER_EXP 7 +#define INT_DEBUG_TIMER_EXP 8 +#define INT_SIRC_0 9 +#define INT_SDC3_0 10 +#define INT_SDC3_1 11 +#define INT_SDC4_0 12 +#define INT_SDC4_1 13 +#define INT_AD6_EXT_VFR 14 +#define INT_USB_OTG 15 +#define INT_MDDI_PRI 16 +#define INT_MDDI_EXT 17 +#define INT_MDDI_CLIENT 18 +#define INT_MDP 19 +#define INT_GRAPHICS 20 +#define INT_ADM_AARM 21 +#define INT_ADSP_A11 22 +#define INT_ADSP_A9_A11 23 +#define INT_SDC1_0 24 +#define INT_SDC1_1 25 +#define INT_SDC2_0 26 +#define INT_SDC2_1 27 +#define INT_KEYSENSE 28 +#define INT_TCHSCRN_SSBI 29 +#define INT_TCHSCRN1 30 +#define INT_TCHSCRN2 31 + +#define INT_TCSR_MPRPH_SC1 (32 + 0) +#define INT_USB_FS2 (32 + 1) +#define INT_PWB_I2C (32 + 2) +#define INT_SOFTRESET (32 + 3) +#define INT_NAND_WR_ER_DONE (32 + 4) +#define INT_NAND_OP_DONE (32 + 5) +#define INT_TCSR_MPRPH_SC2 (32 + 6) +#define INT_OP_PEN (32 + 7) +#define INT_AD_HSSD (32 + 8) +#define INT_ARM11_PM (32 + 9) +#define INT_SDMA_NON_SECURE (32 + 10) +#define INT_TSIF_IRQ (32 + 11) +#define INT_UART1DM_IRQ (32 + 12) +#define INT_UART1DM_RX (32 + 13) +#define INT_SDMA_SECURE (32 + 14) +#define INT_SI2S_SLAVE (32 + 15) +#define INT_SC_I2CPU (32 + 16) +#define INT_SC_DBG_RDTRFULL (32 + 17) +#define INT_SC_DBG_WDTRFULL (32 + 18) +#define INT_SCPLL_CTL_DONE (32 + 19) +#define INT_UART2DM_IRQ (32 + 20) +#define INT_UART2DM_RX (32 + 21) +#define INT_VDC_MEC (32 + 22) +#define INT_VDC_DB (32 + 23) +#define INT_VDC_AXI (32 + 24) +#define INT_VFE (32 + 25) +#define INT_USB_HS (32 + 26) +#define INT_AUDIO_OUT0 (32 + 27) +#define INT_AUDIO_OUT1 (32 + 28) +#define INT_CRYPTO (32 + 29) +#define INT_AD6M_IDLE (32 + 30) +#define INT_SIRC_1 (32 + 31) + +/* secondary interrupt controller */ + +#define INT_UART1_IRQ (64 + 0) +#define INT_UART2_IRQ (64 + 1) +#define INT_UART3_IRQ (64 + 2) +#define INT_UART1_RX (64 + 3) +#define INT_UART2_RX (64 + 4) +#define INT_UART3_RX (64 + 5) +#define INT_SPI_INPUT (64 + 6) +#define INT_SPI_OUTPUT (64 + 7) +#define INT_SPI_ERROR (64 + 8) +#define INT_GPIO1_SHADOW (64 + 9) +#define INT_GPIO2_SHADOW (64 + 10) +#define INT_GPIO1_SECURE (64 + 11) +#define INT_GPIO2_SECURE (64 + 12) +#define INT_SC_AVS_SVIC (64 + 13) +#define INT_SC_AVS_REQ_UP (64 + 14) +#define INT_SC_AVS_REQ_DOWN (64 + 15) +#define INT_PBUS_ERR (64 + 16) +#define INT_AXI (64 + 17) +#define INT_SMI (64 + 18) +#define INT_EBI (64 + 19) +#define INT_IMEM (64 + 20) +#define INT_SC_TEMP_SENSOR (64 + 21) +#define INT_TV_ENC (64 + 22) + +#define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) + +#define NR_IRQS 64 + +#endif diff --git a/lk/platform/qsd8k/interrupts.c b/lk/platform/qsd8k/interrupts.c new file mode 100644 index 0000000..9071677 --- /dev/null +++ b/lk/platform/qsd8k/interrupts.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define VIC_REG(off) (MSM_VIC_BASE + (off)) + +#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_EN0 VIC_REG(0x0010) +#define VIC_INT_EN1 VIC_REG(0x0014) +#define VIC_INT_ENCLEAR0 VIC_REG(0x0020) +#define VIC_INT_ENCLEAR1 VIC_REG(0x0024) +#define VIC_INT_ENSET0 VIC_REG(0x0030) +#define VIC_INT_ENSET1 VIC_REG(0x0034) +#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */ +#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */ +#define VIC_NO_PEND_VAL VIC_REG(0x0060) +#define VIC_INT_MASTEREN VIC_REG(0x0068) /* 1: IRQ, 2: FIQ */ +#define VIC_CONFIG VIC_REG(0x006C) /* 1: USE ARM1136 VIC */ +#define VIC_SECURITY0 VIC_REG(0x0070) +#define VIC_SECURITY1 VIC_REG(0x0074) +#define VIC_IRQ_STATUS0 VIC_REG(0x0080) +#define VIC_IRQ_STATUS1 VIC_REG(0x0084) +#define VIC_FIQ_STATUS0 VIC_REG(0x0090) +#define VIC_FIQ_STATUS1 VIC_REG(0x0094) +#define VIC_RAW_STATUS0 VIC_REG(0x00A0) +#define VIC_RAW_STATUS1 VIC_REG(0x00A4) +#define VIC_INT_CLEAR0 VIC_REG(0x00B0) +#define VIC_INT_CLEAR1 VIC_REG(0x00B4) +#define VIC_SOFTINT0 VIC_REG(0x00C0) +#define VIC_SOFTINT1 VIC_REG(0x00C4) +#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */ +#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */ +#define VIC_IRQ_VEC_WR VIC_REG(0x00D8) +#define VIC_FIQ_VEC_RD VIC_REG(0x00DC) /* pending int # */ +#define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0) /* pending vector addr */ +#define VIC_FIQ_VEC_WR VIC_REG(0x00E4) +#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E8) +#define VIC_IRQ_IN_STACK VIC_REG(0x00EC) +#define VIC_FIQ_IN_SERVICE VIC_REG(0x00F0) +#define VIC_FIQ_IN_STACK VIC_REG(0x00F4) +#define VIC_TEST_BUS_SEL VIC_REG(0x00F8) + +#define SIRC_REG(off) (MSM_SIRC_BASE + (off)) + +#define SIRC_INT_SELECT SIRC_REG(0x0000) /* 0: IRQ0 1: IRQ1 */ +#define SIRC_INT_ENABLE SIRC_REG(0x0004) +#define SIRC_INT_ENCLEAR SIRC_REG(0x0008) +#define SIRC_INT_ENSET SIRC_REG(0x000C) +#define SIRC_INT_TYPE SIRC_REG(0x0010) /* 1: EDGE, 0: LEVEL */ +#define SIRC_INT_POLARITY SIRC_REG(0x0014) /* 1: NEG, 0: POS */ +#define SIRC_SECURITY SIRC_REG(0x0018) /* 0: SEC, 1: NSEC */ +#define SIRC_IRQ0_STATUS SIRC_REG(0x001C) +#define SIRC_IRQ1_STATUS SIRC_REG(0x0020) +#define SIRC_RAW_STATUS SIRC_REG(0x0024) + +struct ihandler { + int_handler func; + void *arg; +}; + +static struct ihandler handler[NR_IRQS]; + +void platform_init_interrupts(void) +{ + writel(0xffffffff, VIC_INT_CLEAR0); + writel(0xffffffff, VIC_INT_CLEAR1); + writel(0, VIC_INT_SELECT0); + writel(0, VIC_INT_SELECT1); + writel(0xffffffff, VIC_INT_TYPE0); + writel(0xffffffff, VIC_INT_TYPE1); + writel(0, VIC_CONFIG); + writel(1, VIC_INT_MASTEREN); +} + +enum handler_return platform_irq(struct arm_iframe *frame) +{ + unsigned num; + enum handler_return ret; + num = readl(VIC_IRQ_VEC_RD); + num = readl(VIC_IRQ_VEC_PEND_RD); + if (num > NR_IRQS) + return 0; + writel(1 << (num & 31), (num > 31) ? VIC_INT_CLEAR1 : VIC_INT_CLEAR0); + ret = handler[num].func(handler[num].arg); + writel(0, VIC_IRQ_VEC_WR); + return ret; +} + +void platform_fiq(struct arm_iframe *frame) +{ + PANIC_UNIMPLEMENTED; +} + +status_t mask_interrupt(unsigned int vector) +{ + unsigned reg = (vector > 31) ? VIC_INT_ENCLEAR1 : VIC_INT_ENCLEAR0; + unsigned bit = 1 << (vector & 31); + writel(bit, reg); + return 0; +} + +status_t unmask_interrupt(unsigned int vector) +{ + unsigned reg = (vector > 31) ? VIC_INT_ENSET1 : VIC_INT_ENSET0; + unsigned bit = 1 << (vector & 31); + writel(bit, reg); + return 0; +} + +void register_int_handler(unsigned int vector, int_handler func, void *arg) +{ + if (vector >= NR_IRQS) + return; + + enter_critical_section(); + handler[vector].func = func; + handler[vector].arg = arg; + exit_critical_section(); +} + diff --git a/lk/platform/qsd8k/panel.c b/lk/platform/qsd8k/panel.c new file mode 100644 index 0000000..a5e7752 --- /dev/null +++ b/lk/platform/qsd8k/panel.c @@ -0,0 +1,657 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#define MDDI_CLIENT_CORE_BASE 0x108000 +#define LCD_CONTROL_BLOCK_BASE 0x110000 +#define SPI_BLOCK_BASE 0x120000 +#define I2C_BLOCK_BASE 0x130000 +#define PWM_BLOCK_BASE 0x140000 +#define GPIO_BLOCK_BASE 0x150000 +#define SYSTEM_BLOCK1_BASE 0x160000 +#define SYSTEM_BLOCK2_BASE 0x170000 + + +#define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00) +#define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04) +#define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08) +#define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C) +#define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10) +#define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14) +#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18) +#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C) +#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20) +#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24) +#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28) +#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C) +#define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30) +#define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34) +#define INTMONI (MDDI_CLIENT_CORE_BASE|0x38) +#define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C) +#define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40) +#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44) +#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48) +#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C) +#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50) +#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54) + + +#define SRST (LCD_CONTROL_BLOCK_BASE|0x00) +#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04) +#define START (LCD_CONTROL_BLOCK_BASE|0x08) +#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C) +#define CMN (LCD_CONTROL_BLOCK_BASE|0x10) +#define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14) +#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18) +#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C) +#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20) +#define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24) +#define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28) + +#define PXL (LCD_CONTROL_BLOCK_BASE|0x30) +#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34) +#define HSW (LCD_CONTROL_BLOCK_BASE|0x38) +#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C) +#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40) +#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44) +#define VSW (LCD_CONTROL_BLOCK_BASE|0x48) +#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C) +#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50) +#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54) +#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58) +#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C) +#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60) +#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64) +#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68) +#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C) +#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70) +#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74) +#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78) +#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C) +#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80) +#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84) +#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88) +#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C) + +#define MONI (LCD_CONTROL_BLOCK_BASE|0xB0) + +#define Current (LCD_CONTROL_BLOCK_BASE|0xC0) +#define LCD (LCD_CONTROL_BLOCK_BASE|0xC4) +#define COMMAND (LCD_CONTROL_BLOCK_BASE|0xC8) + + +#define SSICTL (SPI_BLOCK_BASE|0x00) +#define SSITIME (SPI_BLOCK_BASE|0x04) +#define SSITX (SPI_BLOCK_BASE|0x08) +#define SSIRX (SPI_BLOCK_BASE|0x0C) +#define SSIINTC (SPI_BLOCK_BASE|0x10) +#define SSIINTS (SPI_BLOCK_BASE|0x14) +#define SSIDBG1 (SPI_BLOCK_BASE|0x18) +#define SSIDBG2 (SPI_BLOCK_BASE|0x1C) +#define SSIID (SPI_BLOCK_BASE|0x20) + + +#define I2CSETUP (I2C_BLOCK_BASE|0x00) +#define I2CCTRL (I2C_BLOCK_BASE|0x04) + + +#define TIMER0LOAD (PWM_BLOCK_BASE|0x00) +#define TIMER0VALUE (PWM_BLOCK_BASE|0x04) +#define TIMER0CONTROL (PWM_BLOCK_BASE|0x08) +#define TIMER0INTCLR (PWM_BLOCK_BASE|0x0C) +#define TIMER0RIS (PWM_BLOCK_BASE|0x10) +#define TIMER0MIS (PWM_BLOCK_BASE|0x14) +#define TIMER0BGLOAD (PWM_BLOCK_BASE|0x18) +#define PWM0OFF (PWM_BLOCK_BASE|0x1C) +#define TIMER1LOAD (PWM_BLOCK_BASE|0x20) +#define TIMER1VALUE (PWM_BLOCK_BASE|0x24) +#define TIMER1CONTROL (PWM_BLOCK_BASE|0x28) +#define TIMER1INTCLR (PWM_BLOCK_BASE|0x2C) +#define TIMER1RIS (PWM_BLOCK_BASE|0x30) +#define TIMER1MIS (PWM_BLOCK_BASE|0x34) +#define TIMER1BGLOAD (PWM_BLOCK_BASE|0x38) +#define PWM1OFF (PWM_BLOCK_BASE|0x3C) +#define TIMERITCR (PWM_BLOCK_BASE|0x60) +#define TIMERITOP (PWM_BLOCK_BASE|0x64) +#define PWMCR (PWM_BLOCK_BASE|0x68) +#define PWMID (PWM_BLOCK_BASE|0x6C) +#define PWMMON (PWM_BLOCK_BASE|0x70) + + +#define GPIODATA (GPIO_BLOCK_BASE|0x00) +#define GPIODIR (GPIO_BLOCK_BASE|0x04) +#define GPIOIS (GPIO_BLOCK_BASE|0x08) +#define GPIOIBE (GPIO_BLOCK_BASE|0x0C) +#define GPIOIEV (GPIO_BLOCK_BASE|0x10) +#define GPIOIE (GPIO_BLOCK_BASE|0x14) +#define GPIORIS (GPIO_BLOCK_BASE|0x18) +#define GPIOMIS (GPIO_BLOCK_BASE|0x1C) +#define GPIOIC (GPIO_BLOCK_BASE|0x20) +#define GPIOOMS (GPIO_BLOCK_BASE|0x24) +#define GPIOPC (GPIO_BLOCK_BASE|0x28) + +#define GPIOID (GPIO_BLOCK_BASE|0x30) + + +#define WKREQ (SYSTEM_BLOCK1_BASE|0x00) +#define CLKENB (SYSTEM_BLOCK1_BASE|0x04) +#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08) +#define CNT_DIS (SYSTEM_BLOCK1_BASE|0x10) +#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C) +#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00) + +struct init_table { + unsigned int reg; + unsigned int val; +}; + +static struct init_table toshiba_480x800_init_table[] = { + { DPSET0, 0x4BEC0066 }, // # MDC.DPSET0 # Setup DPLL parameters + { DPSET1, 0x00000113 }, // # MDC.DPSET1 + { DPSUS, 0x00000000 }, // # MDC.DPSUS # Set DPLL oscillation enable + { DPRUN, 0x00000001 }, // # MDC.DPRUN # Release reset signal for DPLL + { 0, 15 }, // wait_ms(15); + { SYSCKENA, 0x00000001 }, // # MDC.SYSCKENA # Enable system clock output + { CLKENB, 0x000000E9 }, // # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) + + { GPIO_BLOCK_BASE, 0x03FF0000 }, // # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 + { GPIODIR, 0x0000024D }, // # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) + { SYSTEM_BLOCK2_BASE, 0x00000173 }, // # SYS.GPIOSEL # GPIO port multiplexing control + { GPIOPC, 0x03C300C0 }, // # GPI .GPIOPC # GPIO2,3 PD cut + { SYSTEM_BLOCK1_BASE, 0x00000000 }, // # SYS.WKREQ # Wake-up request event is VSYNC alignment + { GPIOIS, 0x00000000 }, // # GPI .GPIOIS # Set interrupt sense of GPIO + { GPIOIEV, 0x00000001 }, // # GPI .GPIOIEV # Set interrupt event of GPIO + { GPIOIC, 0x000003FF }, // # GPI .GPIOIC # GPIO interrupt clear + { GPIO_BLOCK_BASE, 0x00040004 }, // # GPI .GPIODATA # Release LCDD reset + { GPIO_BLOCK_BASE, 0x00080008 }, // # GPI .GPIODATA # eDRAM VD supply + { DRAMPWR, 0x00000001 }, // # SYS.DRAMPWR # eDRAM power up + { CLKENB, 0x0000A0EB }, // # enable eDRAM clock + + { PWMCR, 0x00000000 }, // # PWM.PWMCR # PWM output enable + { 0, 1 }, // wait_ms(1); + { SPI_BLOCK_BASE, 0x00060399}, // # SPI .SSICTL # SPI operation mode setting + { SSITIME, 0x00000100 }, // # SPI .SSITIME # SPI serial interface timing setting + { CNT_DIS, 0x00000100 }, // # SPI .SSITIME # SPI serial interface timing setting + { SPI_BLOCK_BASE, 0x0006039B }, // # SPI .SSICTL # Set SPI active mode + + { SSITX, 0x00000000 }, // # SPI.SSITX # Release from Deep Stanby mode + { 0, 2 }, // wait_ms(2); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 2 }, // wait_ms(2); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 2 }, // wait_ms(2); + + { SSITX, 0x000800BA }, // # SPI.SSITX *NOTE 1 # Command setting of SPI block + { SSITX, 0x00000111 }, // # Display mode setup(1) : Normaly Black + { SSITX, 0x00080036 }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Memory access control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x0008003A }, // # Command setting of SPI block + { SSITX, 0x00000160 }, // # Display mode setup(2) + { SSITX, 0x000800B1 }, // # Command setting of SPI block + { SSITX, 0x0000015D }, // # RGB Interface data format + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B2 }, // # Command setting of SPI block + { SSITX, 0x00000133 }, // # Drivnig method + { SSITX, 0x000800B3 }, // # Command setting of SPI block + { SSITX, 0x00000122 }, // # Booster operation setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B4 }, // # Command setting of SPI block + { SSITX, 0x00000102 }, // # OP-amp capability/System clock freq. division setup + { SSITX, 0x000800B5 }, // # Command setting of SPI block + { SSITX, 0x0000011E }, // # VCS Voltage adjustment (1C->1F for Rev 2) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B6 }, // # Command setting of SPI block + { SSITX, 0x00000127 }, // # VCOM Voltage adjustment + { SSITX, 0x000800B7 }, // # Command setting of SPI block + { SSITX, 0x00000103 }, // # Configure an external display signal + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B9 }, // # Command setting of SPI block + { SSITX, 0x00000124 }, // # DCCK/DCEV timing setup + { SSITX, 0x000800BD }, // # Command setting of SPI block + { SSITX, 0x000001A1 }, // # ASW signal control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BB }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Dummy display (white/black) count setup for QUAD Data operation + { SSITX, 0x000800BF }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Dummy display (white/black) count setup for QUAD Data operation + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BE }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # wait_ms(-out FR count setup (A) + { SSITX, 0x000800C0 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (A) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C1 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (B) + { SSITX, 0x000800C2 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (C) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C3 }, // # Command setting of SPI block + { SSITX, 0x00080132 }, // # wait_ms(-in line clock count setup (D) + { SSITX, 0x00000132 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C4 }, // # Command setting of SPI block + { SSITX, 0x00080132 }, // # Seep-in line clock count setup (E) + { SSITX, 0x00000132 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C5 }, // # Command setting of SPI block + { SSITX, 0x00080132 }, // # wait_ms(-in line clock count setup (F) + { SSITX, 0x00000132 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C6 }, // # Command setting of SPI block + { SSITX, 0x00080132 }, // # wait_ms(-in line clock setup (G) + { SSITX, 0x00000132 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C7 }, // # Command setting of SPI block + { SSITX, 0x00080164 }, // # Gamma 1 fine tuning (1) + { SSITX, 0x00000145 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C8 }, // # Command setting of SPI block + { SSITX, 0x00000144 }, // # Gamma 1 fine tuning (2) + { SSITX, 0x000800C9 }, // # Command setting of SPI block + { SSITX, 0x00000152 }, // # Gamma 1 inclination adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CA }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Gamma 1 blue offset adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800EC }, // # Command setting of SPI block + { SSITX, 0x00080101 }, // # Total number of horizontal clock cycles (1) [PCLK Sync. VGA setting] + { SSITX, 0x000001FC }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CF }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Blanking period control (1) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D0 }, // # Command setting of SPI block + { SSITX, 0x00080110 }, // # Blanking period control (2) [PCLK Sync. Table1 for VGA] + { SSITX, 0x00000104 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D1 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # CKV timing control on/off [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D2 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV1,2 timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x00000128 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D3 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # OEV timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x00000128 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D4 }, // # Command setting of SPI block + { SSITX, 0x00080126 }, // # ASW timing control (1) [PCLK Sync. Table1 for VGA] + { SSITX, 0x000001A4 }, // + { 0, 1 }, // wait_ms(1); // # Wait SPI fifo empty + { SSITX, 0x000800D5 }, // # Command setting of SPI block + { SSITX, 0x00000120 }, // # ASW timing control (2) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800EF }, // # Command setting of SPI block + { SSITX, 0x00080132 }, // # Total number of horizontal clock cycles (2) [PCLK Sync. Table1 for QVGA ] + { SSITX, 0x00000100 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + + { BITMAP0, 0x032001E0 }, // MDC.BITMAP0 ); // Setup of PITCH size to Frame buffer1 + { BITMAP1, 0x032001E0 }, // MDC.BITMAP1 ); // Setup of PITCH size to Frame buffer1 + { BITMAP2, 0x014000F0 }, // MDC.BITMAP3 ); // Setup of PITCH size to Frame buffer2 + { BITMAP3, 0x014000F0 }, // MDC.BITMAP4 ); // Setup of PITCH size to Frame buffer3 + { BITMAP4, 0x014000F0 }, // MDC.BITMAP5 ); // Setup of PITCH size to Frame buffer4 + { CLKENB, 0x0000A1EB }, // SYS.CLKENB ); // DCLK supply + { PORT_ENB, 0x00000001 }, // LCD.PORT_ENB ); // Synchronous port enable + { PORT, 0x00000004 }, // LCD.PORT ); // Polarity of DE is set to high active + { PXL, 0x00000002 }, // LCD.PXL ); // ACTMODE 2 set (1st frame black data output) + { MPLFBUF, 0x00000000 }, // LCD.MPLFBUF ); // Select the reading buffer + { HCYCLE, 0x000000FD }, // LCD.HCYCLE ); // Setup to VGA size + { HSW, 0x00000003 }, // LCD.HSW + { HDE_START, 0x00000007 }, // LCD.HDE_START + { HDE_SIZE, 0x000000EF }, // LCD.HDE_SIZE + { VCYCLE, 0x00000325 }, // LCD.VCYCLE + { VSW, 0x00000001 }, // LCD.VSW + { VDE_START, 0x00000003 }, // LCD.VDE_START + { VDE_SIZE, 0x0000031F }, // LCD.VDE_SIZE + + { START, 0x00000001 }, // LCD.START ); // LCDC - Pixel data transfer start + + { 0, 10 }, // wait_ms( 10 ); + { SSITX, 0x000800BC }, // SPI.SSITX ); // Command setting of SPI block + { SSITX, 0x00000180 }, // Display data setup + { SSITX, 0x0008003B }, // Command setting of SPI block + { SSITX, 0x00000100 }, // Quad Data configuration - VGA + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B0 }, // Command setting of SPI block + { SSITX, 0x00000116 }, // Power supply ON/OFF control + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B8 }, // Command setting of SPI block + { SSITX, 0x000801FF }, // Output control + { SSITX, 0x000001F5 }, + { 0, 1 }, // wait_ms( 1); // Wait SPI fifo empty + { SSITX, 0x00000011 }, // wait_ms(-out (Command only) + { SSITX, 0x00000029 }, // Display on (Command only) + + //{ SYSTEM_BLOCK1_BASE, 0x00000002 }, // # wakeREQ -> GPIO + + { 0, 0 } +}; + +static struct init_table toshiba_480x640_init_table[] = { + { DPSET0, 0x4BEC0066 }, // # MDC.DPSET0 # Setup DPLL parameters + { DPSET1, 0x00000113 }, // # MDC.DPSET1 + { DPSUS, 0x00000000 }, // # MDC.DPSUS # Set DPLL oscillation enable + { DPRUN, 0x00000001 }, // # MDC.DPRUN # Release reset signal for DPLL + { 0, 14 }, // wait_ms(14); + { SYSCKENA, 0x00000001 }, // # MDC.SYSCKENA # Enable system clock output + { CLKENB, 0x000000EF }, // # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) + { GPIO_BLOCK_BASE, 0x03FF0000 }, // # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 + { GPIODIR, 0x0000024D }, // # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) + { SYSTEM_BLOCK2_BASE, 0x00000173 }, // # SYS.GPIOSEL # GPIO port multiplexing control + { GPIOPC, 0x03C300C0 }, // # GPI .GPIOPC # GPIO2,3 PD cut + { SYSTEM_BLOCK1_BASE, 0x00000000 }, // # SYS.WKREQ # Wake-up request event is VSYNC alignment + { GPIOIS, 0x00000000 }, // # GPI .GPIOIS # Set interrupt sense of GPIO + { GPIOIEV, 0x00000001 }, // # GPI .GPIOIEV # Set interrupt event of GPIO + { GPIOIC, 0x000003FF }, // # GPI .GPIOIC # GPIO interrupt clear + { GPIO_BLOCK_BASE, 0x00060006 }, // # GPI .GPIODATA # Release LCDD reset + { GPIO_BLOCK_BASE, 0x00080008 }, // # GPI .GPIODATA # eDRAM VD supply + { GPIO_BLOCK_BASE, 0x02000200 }, // # GPI .GPIODATA # TEST LED ON + { DRAMPWR, 0x00000001 }, // # SYS.DRAMPWR # eDRAM power up + { TIMER0CONTROL, 0x00000060 }, // # PWM.Timer0Control # PWM0 output stop + { PWM_BLOCK_BASE, 0x00001388 }, // # PWM.Timer0Load # PWM0 10kHz , Duty 99 (BackLight OFF) + //{PWM0OFF, 0x00000001 }, // # PWM.PWM0OFF +#if 0 + { PWM0OFF, 0x00001387 }, // SURF 100% backlight + { PWM0OFF, 0x00000000 }, // FFA 100% backlight +#endif + { PWM0OFF, 0x000009C3 }, // 50% BL + { TIMER1CONTROL, 0x00000060 }, // # PWM.Timer1Control # PWM1 output stop + { TIMER1LOAD, 0x00001388 }, // # PWM.Timer1Load # PWM1 10kHz , Duty 99 (BackLight OFF) + //{PWM1OFF, 0x00000001 }, // # PWM.PWM1OFF + { PWM1OFF, 0x00001387 }, + { TIMER0CONTROL, 0x000000E0 }, // # PWM.Timer0Control # PWM0 output start + { TIMER1CONTROL, 0x000000E0 }, // # PWM.Timer1Control # PWM1 output start + { PWMCR, 0x00000003 }, // # PWM.PWMCR # PWM output enable + { 0, 1 }, // wait_ms(1); + { SPI_BLOCK_BASE, 0x00000799 }, // # SPI .SSICTL # SPI operation mode setting + { SSITIME, 0x00000100 }, // # SPI .SSITIME # SPI serial interface timing setting + { SPI_BLOCK_BASE, 0x0000079b }, // # SPI .SSICTL # Set SPI active mode + + { SSITX, 0x00000000 }, // # SPI.SSITX # Release from Deep Stanby mode + { 0, 1 }, // wait_ms(1); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 1 }, // wait_ms(1); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 1 }, // wait_ms(1); + { SSITX, 0x000800BA }, // # SPI.SSITX *NOTE 1 # Command setting of SPI block + { SSITX, 0x00000111 }, // # Display mode setup(1) : Normaly Black + { SSITX, 0x00080036 }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Memory access control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BB }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Display mode setup(2) + { SSITX, 0x0008003A }, // # Command setting of SPI block + { SSITX, 0x00000160 }, // # RGB Interface data format + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BF }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Drivnig method + { SSITX, 0x000800B1 }, // # Command setting of SPI block + { SSITX, 0x0000015D }, // # Booster operation setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B2 }, // # Command setting of SPI block + { SSITX, 0x00000133 }, // # Booster mode setup + { SSITX, 0x000800B3 }, // # Command setting of SPI block + { SSITX, 0x00000122 }, // # Booster frequencies setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B4 }, // # Command setting of SPI block + { SSITX, 0x00000102 }, // # OP-amp capability/System clock freq. division setup + { SSITX, 0x000800B5 }, // # Command setting of SPI block + { SSITX, 0x0000011F }, // # VCS Voltage adjustment (1C->1F for Rev 2) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B6 }, // # Command setting of SPI block + { SSITX, 0x00000128 }, // # VCOM Voltage adjustment + { SSITX, 0x000800B7 }, // # Command setting of SPI block + { SSITX, 0x00000103 }, // # Configure an external display signal + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B9 }, // # Command setting of SPI block + { SSITX, 0x00000120 }, // # DCCK/DCEV timing setup + { SSITX, 0x000800BD }, // # Command setting of SPI block + { SSITX, 0x00000102 }, // # ASW signal control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BE }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Dummy display (white/black) count setup for QUAD Data operation + { SSITX, 0x000800C0 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (A) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C1 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (B) + { SSITX, 0x000800C2 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (C) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C3 }, // # Command setting of SPI block + { SSITX, 0x0008010A }, // # wait_ms(-in line clock count setup (D) + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C4 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # Seep-in line clock count setup (E) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C5 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # wait_ms(-in line clock count setup (F) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C6 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # wait_ms(-in line clock setup (G) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C7 }, // # Command setting of SPI block + { SSITX, 0x00080133 }, // # Gamma 1 fine tuning (1) + { SSITX, 0x00000143 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C8 }, // # Command setting of SPI block + { SSITX, 0x00000144 }, // # Gamma 1 fine tuning (2) + { SSITX, 0x000800C9 }, // # Command setting of SPI block + { SSITX, 0x00000133 }, // # Gamma 1 inclination adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CA }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Gamma 1 blue offset adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800EC }, // # Command setting of SPI block + { SSITX, 0x00080102 }, // # Total number of horizontal clock cycles (1) [PCLK Sync. VGA setting] + { SSITX, 0x00000118 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CF }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Blanking period control (1) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D0 }, // # Command setting of SPI block + { SSITX, 0x00080110 }, // # Blanking period control (2) [PCLK Sync. Table1 for VGA] + { SSITX, 0x00000104 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D1 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # CKV timing control on/off [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D2 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV1,2 timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000013A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D3 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # OEV timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000013A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D4 }, // # Command setting of SPI block + { SSITX, 0x00080124 }, // # ASW timing control (1) [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000016E }, // + { 0, 1 }, // wait_ms(1); // # Wait SPI fifo empty + { SSITX, 0x000800D5 }, // # Command setting of SPI block + { SSITX, 0x00000124 }, // # ASW timing control (2) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800ED }, // # Command setting of SPI block + { SSITX, 0x00080101 }, // # Total number of horizontal clock cycles (2) [PCLK Sync. Table1 for QVGA ] + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D6 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Blanking period control (1) [PCLK Sync. Table2 for QVGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D7 }, // # Command setting of SPI block + { SSITX, 0x00080110 }, // # Blanking period control (2) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D8 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # CKV timing control on/off [PCLK Sync. Table2 for QVGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D9 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV1,2 timing control [PCLK Sync. Table2 for QVGA] + { SSITX, 0x00000114 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800DE }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # OEV timing control [PCLK Sync. Table2 for QVGA] + { SSITX, 0x00000114 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800DF }, // # Command setting of SPI block + { SSITX, 0x00080112 }, // # ASW timing control (1) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x0000013F }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E0 }, // # Command setting of SPI block + { SSITX, 0x0000010B }, // # ASW timing control (2) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x000800E2 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Built-in oscillator frequency division setup [Frequency division ratio : 2 (60Hq) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E3 }, // # Command setting of SPI block + { SSITX, 0x00000136 }, // # Built-in oscillator clock count setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E4 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV timing control for using build-in osc + { SSITX, 0x00000103 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E5 }, // # Command setting of SPI block + { SSITX, 0x00080102 }, // # OEV timing control for using build-in osc + { SSITX, 0x00000104 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E6 }, // # Command setting of SPI block + { SSITX, 0x00000103 }, // # DCEV timing control for using build-in osc + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E7 }, // # Command setting of SPI block + { SSITX, 0x00080104 }, // # ASW timing setup for using build-in osc(1) + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E8 }, // # Command setting of SPI block + { SSITX, 0x00000104 }, // # ASW timing setup for using build-in osc(2) + + + { CLKENB, 0x000001EF }, // # SYS.CLKENB # DCLK enable + { START, 0x00000000 }, // # LCD.START # LCDC wait_ms( mode + { WRSTB, 0x0000003F }, // # LCD.WRSTB # write_client_reg( strobe + { RDSTB, 0x00000432 }, // # LCD.RDSTB # Read strobe + { PORT_ENB, 0x00000002 }, // # LCD.PORT_ENB # Asynchronous port enable + { VSYNIF, 0x00000000 }, // # LCD.VSYNCIF # VSYNC I/F mode set + { ASY_DATA, 0x80000000 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00000001 }, // # Oscillator start + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + { 0, 10 }, // wait_ms(10); + { ASY_DATA, 0x80000000 }, // # LCD.ASY_DATx # DUMMY write_client_reg(@*NOTE2 + { ASY_DATB, 0x80000000 }, // + { ASY_DATC, 0x80000000 }, // + { ASY_DATD, 0x80000000 }, // + { ASY_CMDSET, 0x00000009 }, // # LCD.ASY_CMDSET + { ASY_CMDSET, 0x00000008 }, // # LCD.ASY_CMDSET + { ASY_DATA, 0x80000007 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00004005 }, // # LCD driver control + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + { 0, 20 }, // wait_ms(20); + { ASY_DATA, 0x80000059 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00000000 }, // # LTPS I/F control + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + + { VSYNIF, 0x00000001 }, // # LCD.VSYNCIF # VSYNC I/F mode OFF + { PORT_ENB, 0x00000001 }, // # LCD.PORT_ENB # SYNC I/F output select + + /******************************/ + + { VSYNIF, 0x00000001 }, // VSYNC I/F mode OFF + { PORT_ENB, 0x00000001 }, // SYNC I/F mode ON + + { BITMAP1, 0x01E000F0 }, // MDC.BITMAP2 ); // Setup of PITCH size to Frame buffer1 + { BITMAP2, 0x01E000F0 }, // MDC.BITMAP3 ); // Setup of PITCH size to Frame buffer2 + { BITMAP3, 0x01E000F0 }, // MDC.BITMAP4 ); // Setup of PITCH size to Frame buffer3 + { BITMAP4, 0x00DC00B0 }, // MDC.BITMAP5 ); // Setup of PITCH size to Frame buffer4 + { CLKENB, 0x000001EF }, // SYS.CLKENB ); // DCLK supply + { PORT_ENB, 0x00000001 }, // LCD.PORT_ENB ); // Synchronous port enable + { PORT, 0x00000004 }, // LCD.PORT ); // Polarity of DE is set to high active + { PXL, 0x00000002 }, // LCD.PXL ); // ACTMODE 2 set (1st frame black data output) + { MPLFBUF, 0x00000000 }, // LCD.MPLFBUF ); // Select the reading buffer + { HCYCLE, 0x0000010b }, // LCD.HCYCLE ); // Setup to VGA size + { HSW, 0x00000003 }, // LCD.HSW + { HDE_START, 0x00000007 }, // LCD.HDE_START + { HDE_SIZE, 0x000000EF }, // LCD.HDE_SIZE + { VCYCLE, 0x00000285 }, // LCD.VCYCLE + { VSW, 0x00000001 }, // LCD.VSW + { VDE_START, 0x00000003 }, // LCD.VDE_START + { VDE_SIZE, 0x0000027F }, // LCD.VDE_SIZE + + { START, 0x00000001 }, // LCD.START ); // LCDC - Pixel data transfer start + + { 0, 10 }, // wait_ms( 10 ); + { SSITX, 0x000800BC }, // SPI.SSITX ); // Command setting of SPI block + { SSITX, 0x00000180 }, // Display data setup + { SSITX, 0x0008003B }, // Command setting of SPI block + { SSITX, 0x00000100 }, // Quad Data configuration - VGA + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B0 }, // Command setting of SPI block + { SSITX, 0x00000116 }, // Power supply ON/OFF control + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B8 }, // Command setting of SPI block + { SSITX, 0x000801FF }, // Output control + { SSITX, 0x000001F5 }, + { 0, 1 }, // wait_ms( 1); // Wait SPI fifo empty + { SSITX, 0x00000011 }, // wait_ms(-out (Command only) + { SSITX, 0x00000029 }, // Display on (Command only) + + { SYSTEM_BLOCK1_BASE, 0x00000002 }, // # wakeREQ -> GPIO + + { 0, 0 } +}; + +static void _panel_init(struct init_table *init_table) +{ + unsigned n; + + dprintf(INFO, "panel_init()\n"); + + n = 0; + while (init_table[n].reg != 0 || init_table[n].val != 0) { + if (init_table[n].reg != 0) + mddi_remote_write(init_table[n].val, init_table[n].reg); + else + mdelay(init_table[n].val); + n++; + } + + dprintf(INFO, "panel_init() done\n"); +} + +void panel_init(struct mddi_client_caps *client_caps) +{ + switch(client_caps->manufacturer_name) { + case 0xd263: // Toshiba + dprintf(INFO, "Found Toshiba panel\n"); + _panel_init(toshiba_480x800_init_table); + break; + case 0x4474: //?? + if (client_caps->product_code == 0xc065) + dprintf(INFO, "Found WVGA panel\n"); + break; + } +} + +void panel_poweron(void) +{ + gpio_set(88, 0); + gpio_config(88, GPIO_OUTPUT); + udelay(10); + gpio_set(88, 1); + mdelay(10); + + //mdelay(1000); // uncomment for second stage boot +} + +void panel_backlight(int on) +{} diff --git a/lk/platform/qsd8k/platform.c b/lk/platform/qsd8k/platform.c new file mode 100644 index 0000000..46ffa37 --- /dev/null +++ b/lk/platform/qsd8k/platform.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2008, Google 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 Google, Inc. 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. + */ + +#include + +#include +#include +#include +#include + +static struct fbcon_config *fb_config; + +void platform_init_interrupts(void); +void platform_init_timer(); + +void uart3_clock_init(void); +void uart_init(void); + +struct fbcon_config *lcdc_init(void); + +void platform_early_init(void) +{ + //uart3_clock_init(); + //uart_init(); + + platform_init_interrupts(); + platform_init_timer(); +} + +void platform_init(void) +{ + dprintf(INFO, "platform_init()\n"); +#if (!ENABLE_NANDWRITE) + //cedesmith: this will hang + //acpu_clock_init(); +#endif +} + +void display_init(void) +{ + struct fbcon_config *fb_cfg; + +#if DISPLAY_TYPE_MDDI + fb_config = mddi_init(); + ASSERT(fb_config); + fbcon_setup(fb_config); +#endif + +#if DISPLAY_TYPE_LCDC + fb_config = lcdc_init(); + ASSERT(fb_config); + fbcon_setup(fb_config); +#endif + +} + diff --git a/lk/platform/qsd8k/rules.mk b/lk/platform/qsd8k/rules.mk new file mode 100644 index 0000000..e49e05d --- /dev/null +++ b/lk/platform/qsd8k/rules.mk @@ -0,0 +1,26 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +ARCH := arm +ARM_CPU := cortex-a8 +#arm1136j-s +CPU := generic + +#DEFINES += WITH_CPU_EARLY_INIT=1 WITH_CPU_WARM_BOOT=1 MEMBASE=0 +DEFINES += WITH_CPU_EARLY_INIT=1 + +INCLUDES += -I$(LOCAL_DIR)/include + +DEVS += fbcon +MODULES += dev/fbcon + +OBJS += \ + $(LOCAL_DIR)/arch_init.o \ + $(LOCAL_DIR)/platform.o \ + $(LOCAL_DIR)/interrupts.o \ + $(LOCAL_DIR)/gpio.o \ + $(LOCAL_DIR)/acpuclock.o + +LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld + +include platform/msm_shared/rules.mk + diff --git a/lk/platform/rules.mk b/lk/platform/rules.mk new file mode 100644 index 0000000..c1acc50 --- /dev/null +++ b/lk/platform/rules.mk @@ -0,0 +1,7 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +# shared platform code +OBJS += \ + $(LOCAL_DIR)/debug.o \ + $(LOCAL_DIR)/init.o + diff --git a/lk/project/aboot-surf7k.mk b/lk/project/aboot-surf7k.mk new file mode 100644 index 0000000..70750dc --- /dev/null +++ b/lk/project/aboot-surf7k.mk @@ -0,0 +1,11 @@ +# top level project rules for the aboot-surf7k project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := surf-msm7k + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +DEFINES += WITH_DEBUG_UART=1 +DEFINES += WITH_DEBUG_FBCON=1 \ No newline at end of file diff --git a/lk/project/aboot-surf8k.mk b/lk/project/aboot-surf8k.mk new file mode 100644 index 0000000..7f52726 --- /dev/null +++ b/lk/project/aboot-surf8k.mk @@ -0,0 +1,11 @@ +# top level project rules for the aboot-surf8k project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := surf-qsd8k + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +DEFINES += WITH_DEBUG_UART=1 +DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/armemu-test.mk b/lk/project/armemu-test.mk new file mode 100644 index 0000000..151beed --- /dev/null +++ b/lk/project/armemu-test.mk @@ -0,0 +1,16 @@ +# top level project rules for the armemu-test project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := armemu +MODULES += \ + app/tests \ + app/shell + +# extra rules to copy the armemu.conf file to the build dir +#$(BUILDDIR)/armemu.conf: $(LOCAL_DIR)/armemu.conf +# @echo copy $< to $@ +# $(NOECHO)cp $< $@ + +#EXTRA_BUILDDEPS += $(BUILDDIR)/armemu.conf +#GENERATED += $(BUILDDIR)/armemu.conf diff --git a/lk/project/beagle-test.mk b/lk/project/beagle-test.mk new file mode 100644 index 0000000..6f4cbec --- /dev/null +++ b/lk/project/beagle-test.mk @@ -0,0 +1,11 @@ +# top level project rules for the armemu-test project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := beagle + +MODULES += \ + app/tests \ + app/stringtests \ + app/shell + diff --git a/lk/project/htcleo.mk b/lk/project/htcleo.mk new file mode 100644 index 0000000..f5b6bec --- /dev/null +++ b/lk/project/htcleo.mk @@ -0,0 +1,11 @@ +# top level project rules for the qsd8250_surf project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := htcleo + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/msm7625_ffa.mk b/lk/project/msm7625_ffa.mk new file mode 100644 index 0000000..c3e804c --- /dev/null +++ b/lk/project/msm7625_ffa.mk @@ -0,0 +1,11 @@ +# top level project rules for the msm7625_ffa project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7625_ffa + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/msm7625_ffa_nandwrite.mk b/lk/project/msm7625_ffa_nandwrite.mk new file mode 100644 index 0000000..b8eebff --- /dev/null +++ b/lk/project/msm7625_ffa_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the msm7625_ffa_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7625_ffa + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/msm7625_surf.mk b/lk/project/msm7625_surf.mk new file mode 100644 index 0000000..5658a0e --- /dev/null +++ b/lk/project/msm7625_surf.mk @@ -0,0 +1,11 @@ +# top level project rules for the msm7625_surf project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7625_surf + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 \ No newline at end of file diff --git a/lk/project/msm7625_surf_nandwrite.mk b/lk/project/msm7625_surf_nandwrite.mk new file mode 100644 index 0000000..401d2c5 --- /dev/null +++ b/lk/project/msm7625_surf_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the msm7625_surf_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7625_surf + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/msm7627_7x_ffa.mk b/lk/project/msm7627_7x_ffa.mk new file mode 100644 index 0000000..5baefed --- /dev/null +++ b/lk/project/msm7627_7x_ffa.mk @@ -0,0 +1,11 @@ +# top level project rules for the msm7627_ffa project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7627_ffa + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/msm7627_7x_ffa_nandwrite.mk b/lk/project/msm7627_7x_ffa_nandwrite.mk new file mode 100644 index 0000000..db0da10 --- /dev/null +++ b/lk/project/msm7627_7x_ffa_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the msm7627_ffa_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7627_ffa + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/msm7627_7x_surf.mk b/lk/project/msm7627_7x_surf.mk new file mode 100644 index 0000000..0b98025 --- /dev/null +++ b/lk/project/msm7627_7x_surf.mk @@ -0,0 +1,11 @@ +# top level project rules for the msm7627_surf project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7627_surf + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/msm7627_7x_surf_nandwrite.mk b/lk/project/msm7627_7x_surf_nandwrite.mk new file mode 100644 index 0000000..7daac2c --- /dev/null +++ b/lk/project/msm7627_7x_surf_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the msm7627_surf_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7627_surf + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/msm7627_ffa.mk b/lk/project/msm7627_ffa.mk new file mode 100644 index 0000000..3943bb2 --- /dev/null +++ b/lk/project/msm7627_ffa.mk @@ -0,0 +1,11 @@ +# top level project rules for the msm7627_ffa project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7627_ffa + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/msm7627_ffa_nandwrite.mk b/lk/project/msm7627_ffa_nandwrite.mk new file mode 100644 index 0000000..db0da10 --- /dev/null +++ b/lk/project/msm7627_ffa_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the msm7627_ffa_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7627_ffa + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/msm7627_surf.mk b/lk/project/msm7627_surf.mk new file mode 100644 index 0000000..0b98025 --- /dev/null +++ b/lk/project/msm7627_surf.mk @@ -0,0 +1,11 @@ +# top level project rules for the msm7627_surf project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7627_surf + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/msm7627_surf_nandwrite.mk b/lk/project/msm7627_surf_nandwrite.mk new file mode 100644 index 0000000..7daac2c --- /dev/null +++ b/lk/project/msm7627_surf_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the msm7627_surf_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7627_surf + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/msm7630_1x.mk b/lk/project/msm7630_1x.mk new file mode 100644 index 0000000..91aa635 --- /dev/null +++ b/lk/project/msm7630_1x.mk @@ -0,0 +1,11 @@ +# top level project rules for the msm7630_surf project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7630_1x + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/msm7630_1x_nandwrite.mk b/lk/project/msm7630_1x_nandwrite.mk new file mode 100644 index 0000000..2efe688 --- /dev/null +++ b/lk/project/msm7630_1x_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the msm7630_surf_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7630_surf + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/msm7630_fusion.mk b/lk/project/msm7630_fusion.mk new file mode 100644 index 0000000..5eac133 --- /dev/null +++ b/lk/project/msm7630_fusion.mk @@ -0,0 +1,5 @@ +# top level project rules for the msm7630_surf project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +include $(LOCAL_DIR)/msm7630_surf.mk diff --git a/lk/project/msm7630_fusion_nandwrite.mk b/lk/project/msm7630_fusion_nandwrite.mk new file mode 100644 index 0000000..7da3585 --- /dev/null +++ b/lk/project/msm7630_fusion_nandwrite.mk @@ -0,0 +1,5 @@ +# top level project rules for the msm7630_surf_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +include $(LOCAL_DIR)/msm7630_surf_nandwrite.mk diff --git a/lk/project/msm7630_surf.mk b/lk/project/msm7630_surf.mk new file mode 100644 index 0000000..d107e94 --- /dev/null +++ b/lk/project/msm7630_surf.mk @@ -0,0 +1,11 @@ +# top level project rules for the msm7630_surf project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7630_surf + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/msm7630_surf_nandwrite.mk b/lk/project/msm7630_surf_nandwrite.mk new file mode 100644 index 0000000..2efe688 --- /dev/null +++ b/lk/project/msm7630_surf_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the msm7630_surf_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7630_surf + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/msm8655_surf.mk b/lk/project/msm8655_surf.mk new file mode 100644 index 0000000..d107e94 --- /dev/null +++ b/lk/project/msm8655_surf.mk @@ -0,0 +1,11 @@ +# top level project rules for the msm7630_surf project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7630_surf + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/msm8655_surf_nandwrite.mk b/lk/project/msm8655_surf_nandwrite.mk new file mode 100644 index 0000000..2efe688 --- /dev/null +++ b/lk/project/msm8655_surf_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the msm7630_surf_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm7630_surf + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/msm8660_csfb.mk b/lk/project/msm8660_csfb.mk new file mode 100644 index 0000000..482a048 --- /dev/null +++ b/lk/project/msm8660_csfb.mk @@ -0,0 +1,11 @@ +# top level project rules for the msm8660_csfb project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm8660_surf + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/msm8660_surf.mk b/lk/project/msm8660_surf.mk new file mode 100644 index 0000000..a42d832 --- /dev/null +++ b/lk/project/msm8660_surf.mk @@ -0,0 +1,11 @@ +# top level project rules for the msm7630_surf project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm8660_surf + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 \ No newline at end of file diff --git a/lk/project/osk5912-test.mk b/lk/project/osk5912-test.mk new file mode 100644 index 0000000..a72a251 --- /dev/null +++ b/lk/project/osk5912-test.mk @@ -0,0 +1,10 @@ +# top level project rules for the armemu-test project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := osk5912 +MODULES += \ + app/tests \ + app/stringtests \ + app/shell + diff --git a/lk/project/qemu-arm-test.mk b/lk/project/qemu-arm-test.mk new file mode 100644 index 0000000..2b1403c --- /dev/null +++ b/lk/project/qemu-arm-test.mk @@ -0,0 +1,9 @@ +# top level project rules for the qemu-arm-test project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := qemu-arm +MODULES += \ + app/tests \ + app/shell + diff --git a/lk/project/qsd8250_ffa.mk b/lk/project/qsd8250_ffa.mk new file mode 100644 index 0000000..fbc932c --- /dev/null +++ b/lk/project/qsd8250_ffa.mk @@ -0,0 +1,11 @@ +# top level project rules for the qsd8250_ffa project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := qsd8250_ffa + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/qsd8250_ffa_nandwrite.mk b/lk/project/qsd8250_ffa_nandwrite.mk new file mode 100644 index 0000000..cf8b2dc --- /dev/null +++ b/lk/project/qsd8250_ffa_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the qsd8250_ffa_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := qsd8250_ffa + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/qsd8250_surf.mk b/lk/project/qsd8250_surf.mk new file mode 100644 index 0000000..4e69b22 --- /dev/null +++ b/lk/project/qsd8250_surf.mk @@ -0,0 +1,11 @@ +# top level project rules for the qsd8250_surf project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := qsd8250_surf + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/qsd8250_surf_nandwrite.mk b/lk/project/qsd8250_surf_nandwrite.mk new file mode 100644 index 0000000..2867174 --- /dev/null +++ b/lk/project/qsd8250_surf_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the qsd8250_surf_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := qsd8250_surf + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/qsd8650a_st1x.mk b/lk/project/qsd8650a_st1x.mk new file mode 100644 index 0000000..e2ef0f7 --- /dev/null +++ b/lk/project/qsd8650a_st1x.mk @@ -0,0 +1,11 @@ +# top level project rules for the qsd8650_st1x project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := qsd8650a_st1x + +MODULES += app/aboot + +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 diff --git a/lk/project/qsd8650a_st1x_nandwrite.mk b/lk/project/qsd8650a_st1x_nandwrite.mk new file mode 100644 index 0000000..4cd91ee --- /dev/null +++ b/lk/project/qsd8650a_st1x_nandwrite.mk @@ -0,0 +1,14 @@ +# top level project rules for the qsd8650_st1x_nandwrite project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := qsd8650a_st1x + +MODULES += app/nandwrite + +DEFINES += WITH_DEBUG_JTAG=1 +DEFINES += ENABLE_NANDWRITE=1 +#DEFINES += WITH_DEBUG_DCC=1 +#DEFINES += WITH_DEBUG_UART=1 +#DEFINES += WITH_DEBUG_FBCON=1 + diff --git a/lk/project/sam7ex256-test.mk b/lk/project/sam7ex256-test.mk new file mode 100644 index 0000000..3bd574e --- /dev/null +++ b/lk/project/sam7ex256-test.mk @@ -0,0 +1,9 @@ +# top level project rules for the sam7ex256-test project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := sam7ex256 +MODULES += \ + app/tests \ + app/shell + diff --git a/lk/project/surf-test.mk b/lk/project/surf-test.mk new file mode 100644 index 0000000..3e7ee8e --- /dev/null +++ b/lk/project/surf-test.mk @@ -0,0 +1,14 @@ +# top level project rules for the armemu-test project +# +LOCAL_DIR := $(GET_LOCAL_DIR) + +ifeq ($(PROJECT_TARGET),) +TARGET := surf-msm7k +else +TARGET := $(PROJECT_TARGET) +endif + +MODULES += \ + app/tests \ + app/shell + diff --git a/lk/scripts/attach.cmm b/lk/scripts/attach.cmm new file mode 100644 index 0000000..a158e28 --- /dev/null +++ b/lk/scripts/attach.cmm @@ -0,0 +1,10 @@ +sys.down + +do config_scorpion.cmm + +sys.mode attach + +if state.run() +( + break +) \ No newline at end of file diff --git a/lk/scripts/buildall b/lk/scripts/buildall new file mode 100644 index 0000000..5601d7c --- /dev/null +++ b/lk/scripts/buildall @@ -0,0 +1,7 @@ +#!/bin/sh + +PROJECTS="armemu-test sam7ex256-test osk5912-test qemu-arm-test beagle-test surf-test" + +for p in $PROJECTS; do + PROJECT=$p make -j2 +done diff --git a/lk/scripts/config_a11.cmm b/lk/scripts/config_a11.cmm new file mode 100644 index 0000000..569ae4f --- /dev/null +++ b/lk/scripts/config_a11.cmm @@ -0,0 +1,16 @@ +; MSM7200 ARM11 in JTAG Direct Mode + +system.option.TRST ON +system.option.CFLUSH ON +system.option.ResBreak ON +system.option.EnReset ON +system.option.WaitReset ON +system.jtagclock RTCK + +sys.cpu arm1136j +system.multicore irpre 0. +system.multicore drpre 0. +system.multicore irpost 0. +system.multicore drpost 0. +sys.mode attach + diff --git a/lk/scripts/config_scorpion.cmm b/lk/scripts/config_scorpion.cmm new file mode 100644 index 0000000..48a8e4a --- /dev/null +++ b/lk/scripts/config_scorpion.cmm @@ -0,0 +1,14 @@ + +system.option.TRST ON +system.option.CFLUSH ON +system.option.ResBreak ON +system.option.EnReset ON +system.option.WaitReset ON +system.jtagclock 5.0mhz + +sys.cpu scorpion +system.multicore irpre 0. +system.multicore drpre 0. +system.multicore irpost 0. +system.multicore drpost 0. + diff --git a/lk/scripts/do-armemu-test b/lk/scripts/do-armemu-test new file mode 100644 index 0000000..1d910f6 --- /dev/null +++ b/lk/scripts/do-armemu-test @@ -0,0 +1,7 @@ +#!/bin/sh + +export PROJECT=armemu-test + +make -C ../armemu && +make && +(cd build-$PROJECT; ../../armemu/build-generic/armemu) diff --git a/lk/scripts/do-beagle-test b/lk/scripts/do-beagle-test new file mode 100644 index 0000000..7c695f7 --- /dev/null +++ b/lk/scripts/do-beagle-test @@ -0,0 +1,6 @@ +#!/bin/sh + +export PROJECT=beagle-test + +make && +scp build-beagle-test/lk.bin mbp:/Volumes/FOO/lk.bin diff --git a/lk/scripts/do-osk5912-test b/lk/scripts/do-osk5912-test new file mode 100644 index 0000000..175d102 --- /dev/null +++ b/lk/scripts/do-osk5912-test @@ -0,0 +1,6 @@ +#!/bin/sh + +export PROJECT=osk5912-test + +make && +scp build-osk5912-test/lk.bin four:/tftproot diff --git a/lk/scripts/do-sam7ex256-test b/lk/scripts/do-sam7ex256-test new file mode 100644 index 0000000..4505ad6 --- /dev/null +++ b/lk/scripts/do-sam7ex256-test @@ -0,0 +1,6 @@ +#!/bin/sh + +export DEBUG=true +export PROJECT=sam7ex256-test + +make diff --git a/lk/scripts/lk.cmm b/lk/scripts/lk.cmm new file mode 100644 index 0000000..5dc1cfd --- /dev/null +++ b/lk/scripts/lk.cmm @@ -0,0 +1,49 @@ + +global &KERNEL_SRC +global &KERNEL_ELF + +&KERNEL_SRC="../" + +sys.down + +global &SURF + +if ("&SURF"=="7k") +( + &KERNEL_ELF="../build-aboot-surf7k/lk" + do config_a11.cmm +) +else +( + &KERNEL_ELF="../build-aboot-surf8k/lk" + do config_scorpion.cmm +) + +sys.mode attach + +if state.run() +( + break +) + +data.load.ELF &KERNEL_ELF /RELPATH /PATH &KERNEL_SRC + +register.set pc 0 +register.set r0 0 +;register.set r1 &MACHINE_ID +;register.set r2 &TAGS_ADDR + +tronchip.set dabort off +tronchip.set pabort off + +term.reset +term.size 70 100 +term.scroll.on +term + +break.select program onchip +break.delete +;break.set platform_early_init + +go + diff --git a/lk/scripts/tagit b/lk/scripts/tagit new file mode 100644 index 0000000..bf11a1e --- /dev/null +++ b/lk/scripts/tagit @@ -0,0 +1,7 @@ +#!/bin/sh + +FILES=`find . -type f -regex ".*\.[chS]\|.*\.cpp"` + +echo running ctags +exuberant-ctags $FILES + diff --git a/lk/target/armemu/rules.mk b/lk/target/armemu/rules.mk new file mode 100644 index 0000000..d79834a --- /dev/null +++ b/lk/target/armemu/rules.mk @@ -0,0 +1,6 @@ +# mostly null target configuration for the arm emulator, since there's only one real +# implementation. +LOCAL_DIR := $(GET_LOCAL_DIR) + +PLATFORM := armemu + diff --git a/lk/target/beagle/include/target/debugconfig.h b/lk/target/beagle/include/target/debugconfig.h new file mode 100644 index 0000000..0928eea --- /dev/null +++ b/lk/target/beagle/include/target/debugconfig.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 __TARGET_DEBUGCONFIG_H +#define __TARGET_DEBUGCONFIG_H + +#define DEBUG_UART 2 + +#endif diff --git a/lk/target/beagle/rules.mk b/lk/target/beagle/rules.mk new file mode 100644 index 0000000..1c6d1c1 --- /dev/null +++ b/lk/target/beagle/rules.mk @@ -0,0 +1,15 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += \ + -I$(LOCAL_DIR)/include + +PLATFORM := omap3 + +MODULES += \ + dev/pmic/twl4030 + +MEMSIZE := 0x08000000 # 128MB + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) + diff --git a/lk/target/htcleo/atags.c b/lk/target/htcleo/atags.c new file mode 100644 index 0000000..2c87b94 --- /dev/null +++ b/lk/target/htcleo/atags.c @@ -0,0 +1,17 @@ + +//cedesmith: from kernel board-htcleo. +#define MSM_EBI1_BANK0_BASE 0x11800000 +//#define MSM_EBI1_BANK0_SIZE 0x1E800000 /* 488MB */ +//CONFIG_USING_BRAVOS_DSP +//#define MSM_EBI1_BANK0_SIZE 0x1CFC0000 /* 488MB - DESIRE DSP - 0x00040000 RAM CONSOLE*/ +#define MSM_EBI1_BANK0_SIZE 0x1E7C0000 /* 488MB - 0x00040000 RAM CONSOLE*/ + +unsigned* target_atag_mem(unsigned* ptr) +{ + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = MSM_EBI1_BANK0_SIZE; + *ptr++ = MSM_EBI1_BANK0_BASE; + + return ptr; +} diff --git a/lk/target/htcleo/include/target/display.h b/lk/target/htcleo/include/target/display.h new file mode 100644 index 0000000..01c1066 --- /dev/null +++ b/lk/target/htcleo/include/target/display.h @@ -0,0 +1,46 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _TARGET_QSD8250_SURF_DISPLAY_H +#define _TARGET_QSD8250_SURF_DISPLAY_H + +#define TARGET_XRES 480 +#define TARGET_YRES 800 + +#define LCDC_FB_WIDTH 480 +#define LCDC_FB_HEIGHT 800 + +#define LCDC_HSYNC_PULSE_WIDTH_DCLK 60 +#define LCDC_HSYNC_BACK_PORCH_DCLK 144 +#define LCDC_HSYNC_FRONT_PORCH_DCLK 33 +#define LCDC_HSYNC_SKEW_DCLK 0 + +#define LCDC_VSYNC_PULSE_WIDTH_LINES 2 +#define LCDC_VSYNC_BACK_PORCH_LINES 2 +#define LCDC_VSYNC_FRONT_PORCH_LINES 2 +#endif diff --git a/lk/target/htcleo/init.c b/lk/target/htcleo/init.c new file mode 100644 index 0000000..606529c --- /dev/null +++ b/lk/target/htcleo/init.c @@ -0,0 +1,205 @@ +/* + * author: cedesmith + * license: GPL + */ + +#include +#include +#include +#include +#include +#include + +#define LINUX_MACHTYPE 2524 +#define HTCLEO_FLASH_OFFSET 0x219 + +static struct ptable flash_ptable; + +// align data on a 512 boundary so will not be interrupted in nbh +#if 1 +//generic partition table +static struct ptentry board_part_list[MAX_PTABLE_PARTS] __attribute__ ((aligned (512))) = { + { + .name = "PTABLE-MB", // PTABLE-BLK or PTABLE-MB for length in MB or BLOCKS + }, + { + .name = "recovery", + .length = 5 /* In MB */, + }, + { + .name = "boot", + .length = 5 /* In MB */, + }, + { + .name = "system", + .length = 250 /* In MB */, + }, + { + .length = 10 /* In MB */, + .name = "cache", + }, + { + .name = "userdata", + }, +}; +#else +// partition table matching cotulla's build +static struct ptentry board_part_list[MAX_PTABLE_PARTS] __attribute__ ((aligned (512))) = { + { + .name = "PTABLE-BLK", // or PTABLE-MB for len in MB + }, + { + .name = "boot", + .start = 0x219, + .length = 0x25 /* In blocks */, + }, + { + .name = "system", + .start = 0x23E, + .length = 0x831 /* In blocks */, + }, + { + .name = "cache", + .start = 0xA70, + .length = 0x140 /* In blocks */, + }, + { + .name = "userdata", + .start = 0xBB0, + .length = 0x390, + }, +}; +#endif +static unsigned num_parts = sizeof(board_part_list)/sizeof(struct ptentry); +//#define part_empty(p) (p->name[0]==0 && p->start==0 && p->length==0 && p->flags==0 && p->type==0 && p->perm==0) +#define IS_PART_EMPTY(p) (p->name[0]==0) + + +void keypad_init(void); +void display_init(void); +void htcleo_ptable_dump(struct ptable *ptable); +void cmd_dmesg(const char *arg, void *data, unsigned sz); +void reboot(unsigned reboot_reason); +void target_display_init(); +void target_init(void) +{ + struct flash_info *flash_info; + unsigned start_block; + unsigned blocks_per_plen = 1; //blocks per partition length + unsigned nand_num_blocks; + + keys_init(); + keypad_init(); + + uint16_t keys[] = {KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_SOFT1, KEY_SEND, KEY_CLEAR, KEY_BACK, KEY_HOME}; + for(unsigned i=0; i< sizeof(keys)/sizeof(uint16_t); i++) + if (keys_get_state(keys[i]) != 0) + { + display_init(); + _dputs("cedesmith's LK (CLK) v1.1\n"); + break; + } + dprintf(INFO, "htcleo_init\n"); + + // SPL seams to pass something somehow to kernel. + // Without this it hangs on 1st boot and when battery charger is pluged + // with this it just auto restarts + char* cold_boot=(char*)(MEMBASE-1); + if(*cold_boot==0) + { + *cold_boot=1; + dprintf(INFO, "cold boot detected... reboot\n"); + reboot(0); + } + + /** + * cedesmith notes: + * DON'T use smem_ptable_init and smem_get_apps_flash_start as 0:APPS points to wrong place + */ + + dprintf(INFO, "flash init\n"); + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + ASSERT(flash_info->num_blocks); + nand_num_blocks = flash_info->num_blocks; + + ptable_init(&flash_ptable); + + // cedesmith:DON'T USE SMEM ptable + + if( strcmp(board_part_list[0].name,"PTABLE-BLK")==0 ) blocks_per_plen =1 ; + else if( strcmp(board_part_list[0].name,"PTABLE-MB")==0 ) blocks_per_plen = (1024*1024) /flash_info->block_size; + else panic("Invalid partition table\n"); + + start_block = HTCLEO_FLASH_OFFSET; + for (unsigned i = 1; i < num_parts; i++) + { + struct ptentry *ptn = &board_part_list[i]; + if( IS_PART_EMPTY(ptn) ) break; + int len = ((ptn->length) * blocks_per_plen); + + if( ptn->start == 0 ) ptn->start = start_block; + else if( ptn->start < start_block) panic("Partition %s start %x < %x\n", ptn->name, ptn->start, start_block); + + if(ptn->length == 0) + { + unsigned length_for_prt = 0; + if( istart; + } + else + { + for (unsigned j = i+1; j < num_parts; j++) + { + struct ptentry *temp_ptn = &board_part_list[j]; + if( IS_PART_EMPTY(temp_ptn) ) break; + if( temp_ptn->length==0 ) panic("partition %s and %s have variable length\n", ptn->name, temp_ptn->name); + length_for_prt += ((temp_ptn->length) * blocks_per_plen); + } + } + len = (nand_num_blocks - 1 - 186 - 4) - (ptn->start + length_for_prt); + ASSERT(len >= 0); + } + + start_block = ptn->start + len; + ptable_add(&flash_ptable, ptn->name, ptn->start, len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); + } + + htcleo_ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +unsigned board_machtype(void) +{ + return LINUX_MACHTYPE; +} + +void reboot_device(unsigned reboot_reason) +{ + reboot(reboot_reason); +} + +int target_is_emmc_boot(void) +{ + return 0; +} + +void htcleo_ptable_dump(struct ptable *ptable) +{ + struct ptentry *ptn; + int i; + + for (i = 0; i < ptable->count; ++i) { + ptn = &ptable->parts[i]; + dprintf(INFO, "ptn %d name='%s' start=%08x len=%08x end=%08x \n",i, ptn->name, ptn->start, ptn->length, ptn->start+ptn->length); + } +} + +//cedesmith: current version of qsd8k platform missing display_shutdown so add it +void lcdc_shutdown(void); +void display_shutdown(void) +{ + lcdc_shutdown(); +} diff --git a/lk/target/htcleo/keypad.c b/lk/target/htcleo/keypad.c new file mode 100644 index 0000000..a402c3a --- /dev/null +++ b/lk/target/htcleo/keypad.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2009, Google 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 Google, Inc. 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. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + + +/* Keypad */ +#define HTCLEO_GPIO_KP_MKOUT0 33 +#define HTCLEO_GPIO_KP_MKOUT1 32 +#define HTCLEO_GPIO_KP_MKOUT2 31 +#define HTCLEO_GPIO_KP_MPIN0 42 +#define HTCLEO_GPIO_KP_MPIN1 41 +#define HTCLEO_GPIO_KP_MPIN2 40 + +/* + * cedesmith + * NOTE: htcleo kernel differs by havin row swaped to col + */ +static unsigned int halibut_row_gpios[] = { 33, 32, 31 }; +static unsigned int halibut_col_gpios[] = { 42, 41, 40 }; + +#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(halibut_col_gpios) + (col)) + +static const unsigned short halibut_keymap[ARRAY_SIZE(halibut_col_gpios) * ARRAY_SIZE(halibut_row_gpios)] = { + [KEYMAP_INDEX(0, 0)] = KEY_VOLUMEUP, // Volume Up + [KEYMAP_INDEX(0, 1)] = KEY_VOLUMEDOWN, // Volume Down + [KEYMAP_INDEX(1, 0)] = KEY_SOFT1, // Windows Button + [KEYMAP_INDEX(1, 1)] = KEY_SEND, // Dial Button + [KEYMAP_INDEX(1, 2)] = KEY_CLEAR, // Hangup Button + [KEYMAP_INDEX(2, 0)] = KEY_BACK, // Back Button + [KEYMAP_INDEX(2, 1)] = KEY_HOME, // Home Button +}; + +static struct gpio_keypad_info halibut_keypad_info = { + .keymap = halibut_keymap, + .output_gpios = halibut_row_gpios, + .input_gpios = halibut_col_gpios, + .noutputs = ARRAY_SIZE(halibut_row_gpios), + .ninputs = ARRAY_SIZE(halibut_col_gpios), + .settle_time = 40 /* msec */, + .poll_time = 20 /* msec */, + .flags = GPIOKPF_DRIVE_INACTIVE, +}; + +void keypad_init(void) +{ + gpio_keypad_init(&halibut_keypad_info); +} diff --git a/lk/target/htcleo/nand.c b/lk/target/htcleo/nand.c new file mode 100644 index 0000000..9baef2e --- /dev/null +++ b/lk/target/htcleo/nand.c @@ -0,0 +1,1091 @@ + /* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +//#include +#include "nand.h" + +#include "dmov.h" + +#define VERBOSE 0 +#define VERIFY_WRITE 0 + +#define NUM_PROTECTED_BLOCKS 0x212 + +static void *flash_spare; +static void *flash_data; + + +typedef struct dmov_ch dmov_ch; +struct dmov_ch +{ + volatile unsigned cmd; + volatile unsigned result; + volatile unsigned status; + volatile unsigned config; +}; + +static void dmov_prep_ch(dmov_ch *ch, unsigned id) +{ + ch->cmd = DMOV_CMD_PTR(id); + ch->result = DMOV_RSLT(id); + ch->status = DMOV_STATUS(id); + ch->config = DMOV_CONFIG(id); +} + +#define SRC_CRCI_NAND_CMD CMD_SRC_CRCI(DMOV_NAND_CRCI_CMD) +#define DST_CRCI_NAND_CMD CMD_DST_CRCI(DMOV_NAND_CRCI_CMD) +#define SRC_CRCI_NAND_DATA CMD_SRC_CRCI(DMOV_NAND_CRCI_DATA) +#define DST_CRCI_NAND_DATA CMD_DST_CRCI(DMOV_NAND_CRCI_DATA) + +#define NAND_CFG0_RAW 0xA80420C0 +#define NAND_CFG1_RAW 0x5045D + +static unsigned CFG0, CFG1; + +#define CFG1_WIDE_FLASH (1U << 1) + +#define paddr(n) ((unsigned) (n)) + +static int dmov_exec_cmdptr(unsigned id, unsigned *ptr) +{ + dmov_ch ch; + unsigned n; + + dmov_prep_ch(&ch, id); + + writel(DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(paddr(ptr)), ch.cmd); + + while(!(readl(ch.status) & DMOV_STATUS_RSLT_VALID)) ; + + n = readl(ch.status); + while(DMOV_STATUS_RSLT_COUNT(n)) { + n = readl(ch.result); + if(n != 0x80000002) { + dprintf(CRITICAL, "ERROR: result: %x\n", n); + dprintf(CRITICAL, "ERROR: flush: %x %x %x %x\n", + readl(DMOV_FLUSH0(DMOV_NAND_CHAN)), + readl(DMOV_FLUSH1(DMOV_NAND_CHAN)), + readl(DMOV_FLUSH2(DMOV_NAND_CHAN)), + readl(DMOV_FLUSH3(DMOV_NAND_CHAN))); + return -1; + } + n = readl(ch.status); + } + return 0; +} + +static struct flash_info flash_info; +static unsigned flash_pagesize = 0; + +struct flash_identification { + unsigned flash_id; + unsigned mask; + unsigned density; + unsigned widebus; + unsigned pagesize; + unsigned blksize; + unsigned oobsize; +}; + +static struct flash_identification supported_flash[] = +{ + /* Flash ID ID Mask Density(MB) Wid Pgsz Blksz oobsz Manuf */ + {0x00000000, 0xFFFFFFFF, 0, 0, 0, 0, 0}, /*ONFI*/ + {0x1500aaec, 0xFF00FFFF, (256<<20), 0, 2048, (2048<<6), 64}, /*Sams*/ + {0x5500baec, 0xFF00FFFF, (256<<20), 1, 2048, (2048<<6), 64}, /*Sams*/ + {0x1500aa98, 0xFFFFFFFF, (256<<20), 0, 2048, (2048<<6), 64}, /*Tosh*/ + {0x5500ba98, 0xFFFFFFFF, (256<<20), 1, 2048, (2048<<6), 64}, /*Tosh*/ + {0xd580b12c, 0xFFFFFFFF, (256<<20), 1, 2048, (2048<<6), 64}, /*Micr*/ + {0x5590bc2c, 0xFFFFFFFF, (512<<20), 1, 2048, (2048<<6), 64}, /*Micr*/ + {0x1580aa2c, 0xFFFFFFFF, (256<<20), 0, 2048, (2048<<6), 64}, /*Micr*/ + {0x1590aa2c, 0xFFFFFFFF, (256<<20), 0, 2048, (2048<<6), 64}, /*Micr*/ + {0x1590ac2c, 0xFFFFFFFF, (512<<20), 0, 2048, (2048<<6), 64}, /*Micr*/ + {0x5580baad, 0xFFFFFFFF, (256<<20), 1, 2048, (2048<<6), 64}, /*Hynx*/ + {0x5510baad, 0xFFFFFFFF, (256<<20), 1, 2048, (2048<<6), 64}, /*Hynx*/ + {0x6600bcec, 0xFF00FFFF, (512<<20), 1, 4096, (4096<<6), 128}, /*Sams*/ + + /*added from kernel nand */ + {0x0000aaec, 0x0000FFFF, (256<<20), 1, 2048, (2048<<6), 64}, /*Samsung 2Gbit*/ + {0x0000acec, 0x0000FFFF, (512<<20), 1, 2048, (2048<<6), 64}, /*Samsung 4Gbit*/ + {0x0000bcec, 0x0000FFFF, (512<<20), 1, 2048, (2048<<6), 64}, /*Samsung 4Gbit*/ + {0x6601b3ec, 0xFFFFFFFF, (1024<<20),1, 4096, (4096<<6), 128}, /*Samsung 8Gbit 4Kpage*/ + {0x0000b3ec, 0x0000FFFF, (1024<<20),1, 2048, (2048<<6), 64}, /*Samsung 8Gbit*/ + {0x0000ba2c, 0x0000FFFF, (256<<20), 1, 2048, (2048<<6), 64}, /*Micron 2Gbit*/ + {0x0000bc2c, 0x0000FFFF, (512<<20), 1, 2048, (2048<<6), 64}, /*Micron 4Gbit*/ + {0x0000b32c, 0x0000FFFF, (1024<<20),1, 2048, (2048<<6), 64}, /*Micron 8Gbit*/ + {0x0000baad, 0x0000FFFF, (256<<20), 1, 2048, (2048<<6), 64}, /*Hynix 2Gbit*/ + {0x0000bcad, 0x0000FFFF, (512<<20), 1, 2048, (2048<<6), 64}, /*Hynix 4Gbit*/ + {0x0000b3ad, 0x0000FFFF, (1024<<20),1, 2048, (2048<<6), 64}, /*Hynix 8Gbit*/ + + /* Note: Width flag is 0 for 8 bit Flash and 1 for 16 bit flash */ + /* Note: The First row will be filled at runtime during ONFI probe */ + +}; +static void set_nand_configuration(char type) +{ + ASSERT(type==TYPE_APPS_PARTITION); +} + +static void flash_nand_read_id(dmov_s *cmdlist, unsigned *ptrlist) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + unsigned *data = ptrlist + 4; + + data[0] = 0 | 4; + data[1] = NAND_CMD_FETCH_ID; + data[2] = 1; + data[3] = 0; + data[4] = 0; + data[5] = 0; + data[6] = 0; + data[7] = 0xAAD40000; /* Default value for CFG0 for reading device id */ + + /* Read NAND device id */ + cmd[0].cmd = 0 | CMD_OCB; + cmd[0].src = paddr(&data[7]); + cmd[0].dst = NAND_DEV0_CFG0; + cmd[0].len = 4; + + cmd[1].cmd = 0; + cmd[1].src = NAND_SFLASHC_BURST_CFG; + cmd[1].dst = paddr(&data[5]); + cmd[1].len = 4; + + cmd[2].cmd = 0; + cmd[2].src = paddr(&data[6]); + cmd[2].dst = NAND_SFLASHC_BURST_CFG; + cmd[2].len = 4; + + cmd[3].cmd = 0; + cmd[3].src = paddr(&data[0]); + cmd[3].dst = NAND_FLASH_CHIP_SELECT; + cmd[3].len = 4; + + cmd[4].cmd = DST_CRCI_NAND_CMD; + cmd[4].src = paddr(&data[1]); + cmd[4].dst = NAND_FLASH_CMD; + cmd[4].len = 4; + + cmd[5].cmd = 0; + cmd[5].src = paddr(&data[2]); + cmd[5].dst = NAND_EXEC_CMD; + cmd[5].len = 4; + + cmd[6].cmd = SRC_CRCI_NAND_DATA; + cmd[6].src = NAND_FLASH_STATUS; + cmd[6].dst = paddr(&data[3]); + cmd[6].len = 4; + + cmd[7].cmd = 0; + cmd[7].src = NAND_READ_ID; + cmd[7].dst = paddr(&data[4]); + cmd[7].len = 4; + + cmd[8].cmd = CMD_OCU | CMD_LC; + cmd[8].src = paddr(&data[5]); + cmd[8].dst = NAND_SFLASHC_BURST_CFG; + cmd[8].len = 4; + + ptr[0] = (paddr(cmd) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "status: %x\n", data[3]); +#endif + + flash_info.id = data[4]; + flash_info.vendor = data[4] & 0xff; + flash_info.device = (data[4] >> 8) & 0xff; + return; +} + +static int flash_nand_block_isbad(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + unsigned *data = ptrlist + 4; + char buf[4]; + unsigned cwperpage; + + if (page < (NUM_PROTECTED_BLOCKS<<6)) + { + //protected blocks are always good + return 0; + } + + cwperpage = (flash_pagesize >> 9); + + /* Check first page of this block */ + if(page & 63) + page = page - (page & 63); + + /* Check bad block marker */ + data[0] = NAND_CMD_PAGE_READ; /* command */ + + /* addr0 */ + if (CFG1 & CFG1_WIDE_FLASH) + data[1] = (page << 16) | ((528*(cwperpage-1)) >> 1); + else + data[1] = (page << 16) | (528*(cwperpage-1)); + + data[2] = (page >> 16) & 0xff; /* addr1 */ + data[3] = 0 | 4; /* chipsel */ + data[4] = NAND_CFG0_RAW & ~(7U << 6); /* cfg0 */ + data[5] = NAND_CFG1_RAW | (CFG1 & CFG1_WIDE_FLASH); /* cfg1 */ + data[6] = 1; + data[7] = CLEAN_DATA_32; /* flash status */ + data[8] = CLEAN_DATA_32; /* buf status */ + + cmd[0].cmd = DST_CRCI_NAND_CMD | CMD_OCB; + cmd[0].src = paddr(&data[0]); + cmd[0].dst = NAND_FLASH_CMD; + cmd[0].len = 16; + + cmd[1].cmd = 0; + cmd[1].src = paddr(&data[4]); + cmd[1].dst = NAND_DEV0_CFG0; + cmd[1].len = 8; + + cmd[2].cmd = 0; + cmd[2].src = paddr(&data[6]); + cmd[2].dst = NAND_EXEC_CMD; + cmd[2].len = 4; + + cmd[3].cmd = SRC_CRCI_NAND_DATA; + cmd[3].src = NAND_FLASH_STATUS; + cmd[3].dst = paddr(&data[7]); + cmd[3].len = 8; + + cmd[4].cmd = CMD_OCU | CMD_LC; + cmd[4].src = NAND_FLASH_BUFFER + (flash_pagesize - (528*(cwperpage-1))); + cmd[4].dst = paddr(&buf); + cmd[4].len = 4; + + ptr[0] = (paddr(cmd) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "status: %x\n", data[7]); +#endif + + /* we fail if there was an operation error, a mpu error, or the + ** erase success bit was not set. + */ + if(data[7] & 0x110) return -1; + + /* Check for bad block marker byte */ + if (CFG1 & CFG1_WIDE_FLASH) { + if (buf[0] != 0xFF || buf[1] != 0xFF) + return 1; + } else { + if (buf[0] != 0xFF) + return 1; + } + + return 0; +} + + + +static int flash_nand_erase_block(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + unsigned *data = ptrlist + 4; + int isbad = 0; + + if (page < (NUM_PROTECTED_BLOCKS<<6)) + { + dprintf(INFO, "protected block not errased: %x\n", (page>>6)); + return -1; + } + /* only allow erasing on block boundaries */ + if(page & 63) return -1; + + /* Check for bad block and erase only if block is not marked bad */ + isbad = flash_nand_block_isbad(cmdlist, ptrlist, page); + + if (isbad) { + dprintf(INFO, "skipping @ %d (bad block)\n", page >> 6); + return -1; + } + + /* Erase block */ + data[0] = NAND_CMD_BLOCK_ERASE; + data[1] = page; + data[2] = 0; + data[3] = 0 | 4; + data[4] = 1; + data[5] = 0xeeeeeeee; + data[6] = CFG0 & (~(7 << 6)); /* CW_PER_PAGE = 0 */ + data[7] = CFG1; + data[8] = 0x00000020; + data[9] = 0x000000C0; + + cmd[0].cmd = DST_CRCI_NAND_CMD | CMD_OCB; + cmd[0].src = paddr(&data[0]); + cmd[0].dst = NAND_FLASH_CMD; + cmd[0].len = 16; + + cmd[1].cmd = 0; + cmd[1].src = paddr(&data[6]); + cmd[1].dst = NAND_DEV0_CFG0; + cmd[1].len = 8; + + cmd[2].cmd = 0; + cmd[2].src = paddr(&data[4]); + cmd[2].dst = NAND_EXEC_CMD; + cmd[2].len = 4; + + cmd[3].cmd = SRC_CRCI_NAND_DATA; + cmd[3].src = NAND_FLASH_STATUS; + cmd[3].dst = paddr(&data[5]); + cmd[3].len = 4; + + cmd[4].cmd = 0; + cmd[4].src = paddr(&data[8]); + cmd[4].dst = NAND_FLASH_STATUS; + cmd[4].len = 4; + + cmd[5].cmd = CMD_OCU | CMD_LC; + cmd[5].src = paddr(&data[9]); + cmd[5].dst = NAND_READ_STATUS; + cmd[5].len = 4; + + ptr[0] = (paddr(cmd) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "status: %x\n", data[5]); +#endif + + /* we fail if there was an operation error, a mpu error, or the + ** erase success bit was not set. + */ + if(data[5] & 0x110) return -1; + if(!(data[5] & 0x80)) return -1; + + return 0; +} + + +struct data_flash_io { + unsigned cmd; + unsigned addr0; + unsigned addr1; + unsigned chipsel; + unsigned cfg0; + unsigned cfg1; + unsigned exec; + unsigned ecc_cfg; + unsigned ecc_cfg_save; + unsigned clrfstatus; + unsigned clrrstatus; + struct { + unsigned flash_status; + unsigned buffer_status; + } result[8]; +}; + +static int _flash_nand_read_page(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page, void *_addr, void *_spareaddr) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + struct data_flash_io *data = (void*) (ptrlist + 4); + unsigned addr = (unsigned) _addr; + unsigned spareaddr = (unsigned) _spareaddr; + unsigned n; + int isbad = 0; + unsigned cwperpage; + unsigned cwdatasize; + unsigned cwoobsize; + cwperpage = (flash_pagesize >> 9); + cwdatasize = flash_pagesize/cwperpage; + cwoobsize = /*oobavail*/ 16 / cwperpage; //spare size - ecc size (64 - 4*10) + + /* Check for bad block and read only from a good block */ + isbad = flash_nand_block_isbad(cmdlist, ptrlist, page); + if (isbad) + { + dprintf(INFO, "bad block %x:\n",page); + return -2; + } + + data->cmd = NAND_CMD_PAGE_READ_ALL; + data->addr0 = page << 16; + data->addr1 = (page >> 16) & 0xff; + data->chipsel = 0 | 4; /* flash0 + undoc bit */ + + /* GO bit for the EXEC register */ + data->exec = 1; + + data->cfg0 = (CFG0 & ~(7U << 6)) | ((cwperpage-1) << 6); + data->cfg1 = CFG1; + + data->ecc_cfg = 0x1FF; + + /* save existing ecc config */ + cmd->cmd = CMD_OCB; + cmd->src = NAND_EBI2_ECC_BUF_CFG; + cmd->dst = paddr(&data->ecc_cfg_save); + cmd->len = 4; + cmd++; + + for(n = 0; n < cwperpage; n++) { + /* write CMD / ADDR0 / ADDR1 / CHIPSEL regs in a burst */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NAND_FLASH_CMD; + cmd->len = ((n == 0) ? 16 : 4); + cmd++; + + if (n == 0) { + /* block on cmd ready, set configuration */ + cmd->cmd = 0; + cmd->src = paddr(&data->cfg0); + cmd->dst = NAND_DEV0_CFG0; + cmd->len = 8; + cmd++; + + /* set our ecc config */ + cmd->cmd = 0; + cmd->src = paddr(&data->ecc_cfg); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + cmd++; + } + /* kick the execute register */ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NAND_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* block on data ready, then read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_FLASH_STATUS; + cmd->dst = paddr(&data->result[n]); + cmd->len = 8; + cmd++; + + /* read data block */ + cmd->cmd = 0; + cmd->src = NAND_FLASH_BUFFER; + cmd->dst = addr + n * cwdatasize; + cmd->len = cwdatasize; + cmd++; + + /* read extra data */ + cmd->cmd = 0; + cmd->src = NAND_FLASH_BUFFER + cwdatasize + 10; // adter data and 10 bytes of ECC + cmd->dst = spareaddr + n*cwoobsize; + cmd->len = cwoobsize; + cmd++; + } + + /* restore saved ecc config */ + cmd->cmd = CMD_OCU | CMD_LC; + cmd->src = paddr(&data->ecc_cfg_save); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + + ptr[0] = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + int result = dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + if(result!=0) + { + dprintf(INFO, "read page failed %x (block %x)\n",page, page>>6); + return -1; + } + +#if VERBOSE + dprintf(INFO, "read page %d: status: %x %x %x %x\n", + page, data[5], data[6], data[7], data[8]); + for(n = 0; n < 4; n++) { + ptr = (unsigned*)(addr + 512 * n); + dprintf(INFO, "data%d: %x %x %x %x\n", n, ptr[0], ptr[1], ptr[2], ptr[3]); + ptr = (unsigned*)(spareaddr + 16 * n); + dprintf(INFO, "spare data%d %x %x %x %x\n", n, ptr[0], ptr[1], ptr[2], ptr[3]); + } +#endif + + /* if any of the writes failed (0x10), or there was a + ** protection violation (0x100), we lose + */ + for(n = 0; n < cwperpage; n++) { + if (data->result[n].flash_status & 0x110) { + return -1; + } + } + + return 0; +} + +static int _flash_nand_write_page(dmov_s *cmdlist, unsigned *ptrlist, unsigned page, + const void *_addr, const void *_spareaddr, unsigned raw_mode) +{ + if (page < (NUM_PROTECTED_BLOCKS<<6)) + { + dprintf(INFO, "write disabled block %x is protected\n", (page>>6)); + return -1; + } + + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + struct data_flash_io *data = (void*) (ptrlist + 4); + unsigned addr = (unsigned) _addr; + unsigned spareaddr = (unsigned) _spareaddr; + unsigned n; + unsigned cwperpage; + unsigned cwdatasize; + unsigned cwoobsize; + cwperpage = (flash_pagesize >> 9); + cwdatasize = flash_pagesize/cwperpage; + cwoobsize = /*oobavail*/ 16 / cwperpage; //spare size - ecc size (64 - 4*10) + + data->cmd = NAND_CMD_PRG_PAGE_ALL; + data->addr0 = page << 16; + data->addr1 = (page >> 16) & 0xff; + data->chipsel = 0 | 4; /* flash0 + undoc bit */ + data->clrfstatus = 0x00000020; + data->clrrstatus = 0x000000C0; + + if (!raw_mode){ + data->cfg0 = CFG0; + data->cfg1 = CFG1; + }else{ + data->cfg0 = (NAND_CFG0_RAW & ~(7 << 6)) |((cwperpage-1) << 6); + data->cfg1 = NAND_CFG1_RAW | (CFG1 & CFG1_WIDE_FLASH); + } + + /* GO bit for the EXEC register */ + data->exec = 1; + + data->ecc_cfg = 0x1FF; + + /* save existing ecc config */ + cmd->cmd = CMD_OCB; + cmd->src = NAND_EBI2_ECC_BUF_CFG; + cmd->dst = paddr(&data->ecc_cfg_save); + cmd->len = 4; + cmd++; + + for(n = 0; n < cwperpage; n++) { + /* write CMD / ADDR0 / ADDR1 / CHIPSEL regs in a burst */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NAND_FLASH_CMD; + cmd->len = ((n == 0) ? 16 : 4); + cmd++; + + if (n == 0) { + /* set configuration */ + cmd->cmd = 0; + cmd->src = paddr(&data->cfg0); + cmd->dst = NAND_DEV0_CFG0; + cmd->len = 8; + cmd++; + + /* set our ecc config */ + cmd->cmd = 0; + cmd->src = paddr(&data->ecc_cfg); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + cmd++; + } + + /* write data block */ + cmd->cmd = 0; + cmd->dst = NAND_FLASH_BUFFER; + if (!raw_mode){ + cmd->src = addr + n * cwdatasize; + cmd->len = cwdatasize; + }else{ + cmd->src = addr; + cmd->len = 528; + } + cmd++; + + if ((!raw_mode)) { + /* write extra data */ + cmd->cmd = 0; + cmd->src = spareaddr+n*cwoobsize; + cmd->dst = NAND_FLASH_BUFFER + cwdatasize; + cmd->len = cwoobsize; + cmd++; + } + + /* kick the execute register */ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NAND_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* block on data ready, then read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_FLASH_STATUS; + cmd->dst = paddr(&data->result[n]); + cmd->len = 8; + cmd++; + + cmd->cmd = 0; + cmd->src = paddr(&data->clrfstatus); + cmd->dst = NAND_FLASH_STATUS; + cmd->len = 4; + cmd++; + + cmd->cmd = 0; + cmd->src = paddr(&data->clrrstatus); + cmd->dst = NAND_READ_STATUS; + cmd->len = 4; + cmd++; + } + + /* restore saved ecc config */ + cmd->cmd = CMD_OCU | CMD_LC; + cmd->src = paddr(&data->ecc_cfg_save); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + + ptr[0] = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf(INFO, "write page %d: status: %x %x %x %x\n", + page, data[5], data[6], data[7], data[8]); +#endif + + /* if any of the writes failed (0x10), or there was a + ** protection violation (0x100), or the program success + ** bit (0x80) is unset, we lose + */ + for(n = 0; n < cwperpage; n++) { + if(data->result[n].flash_status & 0x110) return -1; + if(!(data->result[n].flash_status & 0x80)) return -1; + } + +#if VERIFY_WRITE + n = _flash_read_page(cmdlist, ptrlist, page, flash_data, + flash_data + 2048); + if (n != 0) + return -1; + if (memcmp(flash_data, _addr, 2048) || + memcmp(flash_data + 2048, _spareaddr, 16)) { + dprintf(CRITICAL, "verify error @ page %d\n", page); + return -1; + } +#endif + return 0; +} + + +char empty_buf[528]; +static int flash_nand_mark_badblock(dmov_s *cmdlist, unsigned *ptrlist, unsigned page) +{ + if (page < (NUM_PROTECTED_BLOCKS<<6)) + { + dprintf(INFO, "protected block %x cannot be marked bad: \n", (page>>6)); + return -1; + } + memset(empty_buf,0,528); + /* Going to first page of the block */ + if(page & 63) + page = page - (page & 63); + return _flash_nand_write_page(cmdlist, ptrlist, page, empty_buf, 0, 1); +} + +unsigned nand_cfg0; +unsigned nand_cfg1; + +static int flash_nand_read_config(dmov_s *cmdlist, unsigned *ptrlist) +{ + static unsigned CFG0_TMP, CFG1_TMP; + cmdlist[0].cmd = CMD_OCB; + cmdlist[0].src = NAND_DEV0_CFG0; + cmdlist[0].dst = paddr(&CFG0_TMP); + cmdlist[0].len = 4; + + cmdlist[1].cmd = CMD_OCU | CMD_LC; + cmdlist[1].src = NAND_DEV0_CFG1; + cmdlist[1].dst = paddr(&CFG1_TMP); + cmdlist[1].len = 4; + + *ptrlist = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptrlist); + + if((CFG0_TMP == 0) || (CFG1_TMP == 0)) { + return -1; + } + + CFG0 = CFG0_TMP; + CFG1 = CFG1_TMP; + if (flash_info.type == FLASH_16BIT_NAND_DEVICE) { + nand_cfg1 |= CFG1_WIDE_FLASH; + } + dprintf(INFO, "nandcfg: %x %x (initial)\n", CFG0_TMP, CFG1_TMP); + + CFG0 = (((flash_pagesize >> 9) - 1) << 6) /* 4/8 cw/pg for 2/4k */ + | (512 << 9) /* 516 user data bytes */ + | (10 << 19) /* 10 parity bytes */ + | (4 << 23) /* spare size */ + | (5 << 27) /* 5 address cycles */ + | (1 << 30) /* Do not read status before data */ + | (1 << 31); /* Send read cmd */ + + CFG1 = CFG1 +#if 0 + | (7 << 2) /* 8 recovery cycles */ + | (0 << 5) /* Allow CS deassertion */ + | (2 << 17) /* 6 cycle tWB/tRB */ +#endif + | ((flash_pagesize - (528 * ((flash_pagesize >> 9) - 1)) + 1) << 6) /* Bad block marker location */ + | (nand_cfg1 & CFG1_WIDE_FLASH); /* preserve wide flash flag */ + CFG1 = CFG1 + & ~(1 << 0) /* Enable ecc */ + & ~(1 << 16); /* Bad block in user data area */ + dprintf(INFO, "nandcfg: %x %x (used)\n", CFG0, CFG1); + + return 0; +} + +static int flash_mark_badblock(dmov_s *cmdlist, unsigned *ptrlist, unsigned page) +{ + return flash_nand_mark_badblock(cmdlist, ptrlist, page); +} + + +/* Wrapper functions */ +static void flash_read_id(dmov_s *cmdlist, unsigned *ptrlist) +{ + int dev_found = 0; + unsigned index; + + // Try to read id + flash_nand_read_id(cmdlist, ptrlist); + // Check if we support the device + for (index=1; + index < (sizeof(supported_flash)/sizeof(struct flash_identification)); + index++) + { + if ((flash_info.id & supported_flash[index].mask) == + (supported_flash[index].flash_id & + (supported_flash[index].mask))) { + dev_found = 1; + break; + } + } + + if(dev_found) { + if (supported_flash[index].widebus) + flash_info.type = FLASH_16BIT_NAND_DEVICE; + else + flash_info.type = FLASH_8BIT_NAND_DEVICE; + + flash_info.page_size = supported_flash[index].pagesize; + flash_pagesize = flash_info.page_size; + flash_info.block_size = supported_flash[index].blksize; + flash_info.spare_size = supported_flash[index].oobsize; + if (flash_info.block_size && flash_info.page_size) + { + flash_info.num_blocks = supported_flash[index].density; + flash_info.num_blocks /= (flash_info.block_size); + } + else + { + flash_info.num_blocks = 0; + } + ASSERT(flash_info.num_blocks); + //return; + } + + // Assume 8 bit nand device for backward compatability + if (dev_found == 0) { + dprintf(INFO, "Device not supported. Assuming 8 bit NAND device\n"); + flash_info.type = FLASH_8BIT_NAND_DEVICE; + } + dprintf(INFO, "nandid: 0x%x maker=0x%02x device=0x%02x page_size=%d\n", + flash_info.id, flash_info.vendor, flash_info.device, + flash_info.page_size); + dprintf(INFO, " spare_size=%d block_size=%d num_blocks=%d\n", + flash_info.spare_size, flash_info.block_size, + flash_info.num_blocks); +} + +static int flash_erase_block(dmov_s *cmdlist, unsigned *ptrlist, unsigned page) +{ + return flash_nand_erase_block(cmdlist, ptrlist, page); +} + +static int _flash_read_page(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page, void *_addr, void *_spareaddr) +{ + return _flash_nand_read_page(cmdlist, ptrlist, page, _addr, _spareaddr); +} + +static int _flash_block_isbad(dmov_s *cmdlist, unsigned *ptrlist, unsigned page) +{ + return flash_nand_block_isbad(cmdlist, ptrlist, page); +} + +static int _flash_write_page(dmov_s *cmdlist, unsigned *ptrlist, + unsigned page, const void *_addr, + const void *_spareaddr) +{ + return _flash_nand_write_page(cmdlist, ptrlist, page, _addr, _spareaddr, 0); +} + +static unsigned *flash_ptrlist; +static dmov_s *flash_cmdlist; + +static struct ptable *flash_ptable = NULL; + +void flash_init(void) +{ + ASSERT(flash_ptable == NULL); + + flash_ptrlist = memalign(32, 1024); + flash_cmdlist = memalign(32, 1024); + flash_data = memalign(32, 4096 + 128); + flash_spare = memalign(32, 128); + + flash_read_id(flash_cmdlist, flash_ptrlist); + if((FLASH_8BIT_NAND_DEVICE == flash_info.type) + ||(FLASH_16BIT_NAND_DEVICE == flash_info.type)) { + if(flash_nand_read_config(flash_cmdlist, flash_ptrlist)) { + dprintf(CRITICAL, "ERROR: could not read CFG0/CFG1 state\n"); + ASSERT(0); + } + } +} + +struct ptable *flash_get_ptable(void) +{ + return flash_ptable; +} + +void flash_set_ptable(struct ptable *new_ptable) +{ + ASSERT(flash_ptable == NULL && new_ptable != NULL); + flash_ptable = new_ptable; +} + +struct flash_info *flash_get_info(void) +{ + return &flash_info; +} + +int flash_erase(struct ptentry *ptn) +{ + unsigned block = ptn->start; + unsigned count = ptn->length; + + set_nand_configuration(ptn->type); + while(count-- > 0) { + if(flash_erase_block(flash_cmdlist, flash_ptrlist, block * 64)) { + dprintf(INFO, "cannot erase @ %d (bad block?)\n", block); + } + block++; + } + return 0; +} + +int flash_read_ext(struct ptentry *ptn, unsigned extra_per_page, + unsigned offset, void *data, unsigned bytes) +{ + unsigned page = (ptn->start * 64) + (offset / flash_pagesize); + unsigned lastpage = (ptn->start + ptn->length) * 64; + unsigned count = (bytes + flash_pagesize - 1 + extra_per_page) / (flash_pagesize + extra_per_page); + unsigned *spare = (unsigned*) flash_spare; + unsigned errors = 0; + unsigned char *image = data; + unsigned current_block = (page - (page & 63)) >> 6; + unsigned start_block = ptn->start; + int result = 0; + int isbad = 0; + int start_block_count = 0; + + dprintf(INFO, "flash read: %s %x %x\n", ptn->name, offset, bytes); + ASSERT(ptn->type == TYPE_APPS_PARTITION); + set_nand_configuration(TYPE_APPS_PARTITION); + + if(offset & (flash_pagesize - 1)) + return -1; + +// Adjust page offset based on number of bad blocks from start to current page + if (start_block < current_block) + { + start_block_count = (current_block - start_block); + while (start_block_count && (start_block < (ptn->start + ptn->length))) { + isbad = _flash_block_isbad(flash_cmdlist, flash_ptrlist, start_block*64); + if (isbad) + page += 64; + else + start_block_count--; + start_block++; + } + } + + while((page < lastpage) && !start_block_count) { + if(count == 0) { + dprintf(INFO, "flash_read_image: success (%d errors)\n", errors); + return 0; + } + + result = _flash_read_page(flash_cmdlist, flash_ptrlist, page, image, spare); + + if (result == -1) { + // bad page, go to next page + page++; + errors++; + continue; + } + else if (result == -2) { + // bad block, go to next block same offset + page += 64; + errors++; + continue; + } + + page++; + image += flash_pagesize; + memcpy(image, spare, extra_per_page); + image += extra_per_page; + count -= 1; + } + + /* could not find enough valid pages before we hit the end */ + dprintf(INFO, "flash_read_image: failed (%d errors)\n", errors); + return 0xffffffff; +} + +int flash_write(struct ptentry *ptn, unsigned extra_per_page, const void *data, + unsigned bytes) +{ + unsigned page = ptn->start * 64; + unsigned lastpage = (ptn->start + ptn->length) * 64; + unsigned *spare = (unsigned*) flash_spare; + const unsigned char *image = data; + unsigned wsize = flash_pagesize + extra_per_page; + unsigned n; + int r; + + if (ptn->type == TYPE_MODEM_PARTITION) + { + dprintf(CRITICAL, "flash_write_image: model partition not supported\n"); + return -1; + } + + set_nand_configuration(ptn->type); + for(n = 0; n < 16; n++) spare[n] = 0xffffffff; + + while(bytes > 0) { + if(bytes < wsize) { + dprintf(CRITICAL, "flash_write_image: image undersized (%d < %d)\n", bytes, wsize); + return -1; + } + if(page >= lastpage) { + dprintf(CRITICAL, "flash_write_image: out of space\n"); + return -1; + } + + if((page & 63) == 0) { + if(flash_erase_block(flash_cmdlist, flash_ptrlist, page)) { + dprintf(INFO, "flash_write_image: bad block @ %d\n", page >> 6); + page += 64; + continue; + } + } + + if(extra_per_page) { + r = _flash_write_page(flash_cmdlist, flash_ptrlist, page, image, image + flash_pagesize); + } else { + r = _flash_write_page(flash_cmdlist, flash_ptrlist, page, image, spare); + } + if(r) { + dprintf(INFO, "flash_write_image: write failure @ page %d (src %d)\n", page, image - (const unsigned char *)data); + image -= (page & 63) * wsize; + bytes += (page & 63) * wsize; + page &= ~63; + if(flash_erase_block(flash_cmdlist, flash_ptrlist, page)) { + dprintf(INFO, "flash_write_image: erase failure @ page %d\n", page); + } + if (ptn->type != TYPE_MODEM_PARTITION) { + flash_mark_badblock(flash_cmdlist, flash_ptrlist, page); + } + dprintf(INFO, "flash_write_image: restart write @ page %d (src %d)\n", page, image - (const unsigned char *)data); + page += 64; + continue; + } + page++; + image += wsize; + bytes -= wsize; + } + + /* erase any remaining pages in the partition */ + page = (page + 63) & (~63); + while(page < lastpage){ + if(flash_erase_block(flash_cmdlist, flash_ptrlist, page)) { + dprintf(INFO, "flash_write_image: bad block @ %d\n", page >> 6); + } + page += 64; + } + + dprintf(INFO, "flash_write_image: success\n"); + return 0; +} + +#if 0 +static int flash_read_page(unsigned page, void *data, void *extra) +{ + return _flash_read_page(flash_cmdlist, flash_ptrlist, + page, data, extra); +} +#endif + +unsigned flash_page_size(void) +{ + return flash_pagesize; +} + diff --git a/lk/target/htcleo/nand.h b/lk/target/htcleo/nand.h new file mode 100644 index 0000000..aac9415 --- /dev/null +++ b/lk/target/htcleo/nand.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2008, Google 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. + * + * 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 __PLATFORM_MSM_SHARED_NAND_H +#define __PLATFORM_MSM_SHARED_NAND_H + +#define MSM_NAND_BASE 0xA0A00000 + +/* see 80-VA736-2 C pp 354-414 */ + +#define NAND_REG(off) (MSM_NAND_BASE + (off)) + +#define NAND_FLASH_CMD NAND_REG(0x0000) +#define NAND_ADDR0 NAND_REG(0x0004) +#define NAND_ADDR1 NAND_REG(0x0008) +#define NAND_FLASH_CHIP_SELECT NAND_REG(0x000C) +#define NAND_EXEC_CMD NAND_REG(0x0010) +#define NAND_FLASH_STATUS NAND_REG(0x0014) +#define NAND_BUFFER_STATUS NAND_REG(0x0018) +#define NAND_DEV0_CFG0 NAND_REG(0x0020) +#define NAND_DEV0_CFG1 NAND_REG(0x0024) +#define NAND_DEV1_CFG0 NAND_REG(0x0030) +#define NAND_DEV1_CFG1 NAND_REG(0x0034) +#define NAND_READ_ID NAND_REG(0x0040) +#define NAND_READ_STATUS NAND_REG(0x0044) +#define NAND_CONFIG_DATA NAND_REG(0x0050) +#define NAND_CONFIG NAND_REG(0x0054) +#define NAND_CONFIG_MODE NAND_REG(0x0058) +#define NAND_CONFIG_STATUS NAND_REG(0x0060) +#define NAND_MACRO1_REG NAND_REG(0x0064) +#define NAND_XFR_STEP1 NAND_REG(0x0070) +#define NAND_XFR_STEP2 NAND_REG(0x0074) +#define NAND_XFR_STEP3 NAND_REG(0x0078) +#define NAND_XFR_STEP4 NAND_REG(0x007C) +#define NAND_XFR_STEP5 NAND_REG(0x0080) +#define NAND_XFR_STEP6 NAND_REG(0x0084) +#define NAND_XFR_STEP7 NAND_REG(0x0088) +#define NAND_DEV_CMD0 NAND_REG(0x00A0) +#define NAND_DEV_CMD1 NAND_REG(0x00A4) +#define NAND_DEV_CMD2 NAND_REG(0x00A8) +#define NAND_DEV_CMD_VLD NAND_REG(0x00AC) +#define NAND_EBI2_MISR_SIG_REG NAND_REG(0x00B0) +#define NAND_SFLASHC_BURST_CFG NAND_REG(0x00E0) +#define NAND_EBI2_ECC_BUF_CFG NAND_REG(0x00F0) +#define NAND_FLASH_BUFFER NAND_REG(0x0100) + +/* device commands */ + +#define NAND_CMD_SOFT_RESET 0x01 +#define NAND_CMD_PAGE_READ 0x32 +#define NAND_CMD_PAGE_READ_ECC 0x33 +#define NAND_CMD_PAGE_READ_ALL 0x34 +#define NAND_CMD_SEQ_PAGE_READ 0x15 +#define NAND_CMD_PRG_PAGE 0x36 +#define NAND_CMD_PRG_PAGE_ECC 0x37 +#define NAND_CMD_PRG_PAGE_ALL 0x39 +#define NAND_CMD_BLOCK_ERASE 0x3A +#define NAND_CMD_FETCH_ID 0x0B +#define NAND_CMD_STATUS 0x0C +#define NAND_CMD_RESET 0x0D + +#define CLEAN_DATA_32 0xFFFFFFFF +#define CLEAN_DATA_16 0xFFFF +/* Flash type */ +#define FLASH_UNKNOWN_DEVICE 0x00 +#define FLASH_NAND_DEVICE 0x01 +#define FLASH_8BIT_NAND_DEVICE 0x01 +#define FLASH_16BIT_NAND_DEVICE 0x02 + +#endif /* __PLATFORM_MSM_SHARED_NAND_H */ diff --git a/lk/target/htcleo/rules.mk b/lk/target/htcleo/rules.mk new file mode 100644 index 0000000..caf4bda --- /dev/null +++ b/lk/target/htcleo/rules.mk @@ -0,0 +1,55 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared + +PLATFORM := qsd8k + +#cedesmith note: MEMBASE requires edit in platform/qsd8k/rules.mk +#MEMBASE := 0x20000000 +#MEMBASE := 0x27000000 +MEMBASE := 0x2E000000 +#MEMSIZE := 0x00100000 +MEMSIZE := 0x00800000 + + + +BASE_ADDR := 0x11800000 + +TAGS_ADDR := "(BASE_ADDR+0x00000100)" +KERNEL_ADDR := "(BASE_ADDR+0x00008000)" +RAMDISK_ADDR := "(BASE_ADDR+0x00a00000)" +#SCRATCH_ADDR := "(BASE_ADDR+0x04000000)" +SCRATCH_ADDR := "(BASE_ADDR+0x01400000)" + +#BASE_ADDR + 0x04000000 +#MEMBASE := 0x15800000 +#SCRATCH_ADDR := 0x16800000 +#SCRATCH_ADDR := "(MEMBASE+0x02000000)" +#MEMBASE := SCRATCH_ADDR+0x19000000 + +KEYS_USE_GPIO_KEYPAD := 1 + +#DEFINES += ENABLE_BATTERY_CHARGING=1 +#DEFINES += DISPLAY_SPLASH_SCREEN=1 +DEFINES += DISPLAY_TYPE_LCDC=1 + +CFLAGS += -mlittle-endian +LDFLAGS += -EL + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + MEMBASE=$(MEMBASE)\ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/nand.o \ + $(LOCAL_DIR)/keypad.o \ + $(LOCAL_DIR)/atags.o diff --git a/lk/target/htcleo/tools/makefile b/lk/target/htcleo/tools/makefile new file mode 100644 index 0000000..9d3897d --- /dev/null +++ b/lk/target/htcleo/tools/makefile @@ -0,0 +1,30 @@ +#Makefile to generate appsboot.mbn + +ifeq ($(BOOTLOADER_OUT),.) +APPSBOOTHEADER_DIR := $(BUILDDIR) +else +APPSBOOTHEADER_DIR := $(BOOTLOADER_OUT)/../../ +endif + +SRC_DIR := target/$(TARGET)/tools +COMPILER := gcc + +ifeq ($(BUILD_NANDWRITE), 1) + APPSBOOTHDR_FILES := +else + APPSBOOTHDR_FILES := appsboot.mbn +endif + +APPSBOOTHEADER: $(APPSBOOTHDR_FILES) + + +appsboot.mbn: appsboothd.mbn $(OUTBIN) + cat $(APPSBOOTHEADER_DIR)/appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/appsboot.mbn + rm -rf $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +mkheader: $(SRC_DIR)/mkheader.c + ${COMPILER} $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader + diff --git a/lk/target/htcleo/tools/mkheader.c b/lk/target/htcleo/tools/mkheader.c new file mode 100644 index 0000000..302bea2 --- /dev/null +++ b/lk/target/htcleo/tools/mkheader.c @@ -0,0 +1,55 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + struct stat s; + unsigned size, base; + unsigned magic[10]; + int fd; + + if(argc != 3) { + fprintf(stderr,"usage: mkheader \n"); + return -1; + } + + if(stat(argv[1], &s)) { + perror("cannot stat binary"); + return -1; + } + + size = s.st_size; + base = 0; + + magic[0] = 0x00000005; /* appsbl */ + magic[1] = 0x00000002; /* nand */ + magic[2] = 0x00000000; + magic[3] = base; + magic[4] = size; + magic[5] = size; + magic[6] = size + base; + magic[7] = 0x00000000; + magic[8] = size + base; + magic[9] = 0x00000000; + + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd < 0) { + perror("cannot open header for writing"); + return -1; + } + if(write(fd, magic, sizeof(magic)) != sizeof(magic)) { + perror("cannot write header"); + close(fd); + unlink(argv[2]); + return -1; + } + close(fd); + + return 0; +} diff --git a/lk/target/init.c b/lk/target/init.c new file mode 100644 index 0000000..a65a6ec --- /dev/null +++ b/lk/target/init.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +/* + * default implementations of these routines, if the target code + * chooses not to implement. + */ + +__WEAK void target_early_init(void) +{ +} + +__WEAK void target_init(void) +{ +} + +__WEAK void *target_get_scratch_address(void) +{ + return (void *)(SCRATCH_ADDR); +} + +__WEAK int target_is_emmc_boot(void) +{ +#if _EMMC_BOOT + return 1; +#else + return 0; +#endif +} + +__WEAK unsigned check_reboot_mode(void) +{ + return 0; +} + +__WEAK void reboot_device(unsigned reboot_reason) +{ +} + +__WEAK void target_battery_charging_enable + (unsigned enable, unsigned disconnect) +{ +} + +__WEAK unsigned target_pause_for_battery_charge(void) +{ + return 0; +} diff --git a/lk/target/msm7625_ffa/atags.c b/lk/target/msm7625_ffa/atags.c new file mode 100644 index 0000000..9029ad2 --- /dev/null +++ b/lk/target/msm7625_ffa/atags.c @@ -0,0 +1,32 @@ +/* Copyright (c) 2009, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT 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. + * + */ + +unsigned* target_atag_mem(unsigned* ptr) +{ + return ptr; +} diff --git a/lk/target/msm7625_ffa/include/target/display.h b/lk/target/msm7625_ffa/include/target/display.h new file mode 100644 index 0000000..166dc19 --- /dev/null +++ b/lk/target/msm7625_ffa/include/target/display.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _TARGET_MSM7625_FFA_DISPLAY_H +#define _TARGET_MSM7625_FFA_DISPLAY_H + +#define TARGET_XRES 480 +#define TARGET_YRES 800 + +#define LCDC_FB_WIDTH 480 +#define LCDC_FB_HEIGHT 640 + +#define LCDC_HSYNC_PULSE_WIDTH_DCLK 60 +#define LCDC_HSYNC_BACK_PORCH_DCLK 144 +#define LCDC_HSYNC_FRONT_PORCH_DCLK 33 +#define LCDC_HSYNC_SKEW_DCLK 0 + +#define LCDC_VSYNC_PULSE_WIDTH_LINES 2 +#define LCDC_VSYNC_BACK_PORCH_LINES 2 +#define LCDC_VSYNC_FRONT_PORCH_LINES 2 + +#endif diff --git a/lk/target/msm7625_ffa/init.c b/lk/target/msm7625_ffa/init.c new file mode 100644 index 0000000..0ca3fef --- /dev/null +++ b/lk/target/msm7625_ffa/init.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include +#include + +#define LINUX_MACHTYPE 2704 + +#define VARIABLE_LENGTH 0x10101010 +#define DIFF_START_ADDR 0xF0F0F0F0 +#define NUM_PAGES_PER_BLOCK 0x40 + +static struct ptable flash_ptable; + +/* for these partitions, start will be offset by either what we get from + * smem, or from the above offset if smem is not useful. Also, we should + * probably have smem_ptable code populate our flash_ptable. + * + * When smem provides us with a full partition table, we can get rid of + * this altogether. + * + */ +static struct ptentry board_part_list[] = { + { + .start = 0, + .length = 5 /* In MB */, + .name = "boot", + }, + { + .start = DIFF_START_ADDR, + .length = 95 /* In MB */, + .name = "system", + }, + { + .start = DIFF_START_ADDR, + .length = 1 /* In MB */, + .name = "cache", + }, + { + .start = DIFF_START_ADDR, + .length = 1 /* In MB */, + .name = "misc", + }, + { + .start = DIFF_START_ADDR, + .length = VARIABLE_LENGTH, + .name = "userdata", + }, + { + .start = DIFF_START_ADDR, + .length = 2 /* In MB */, + .name = "persist", + }, + { + .start = DIFF_START_ADDR, + .length = 5 /* In MB */, + .name = "recovery", + }, +}; +static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry); + +void smem_ptable_init(void); +unsigned smem_get_apps_flash_start(void); + +void keypad_init(void); + +int target_is_emmc_boot(void); + +void target_init(void) +{ + unsigned offset; + struct flash_info *flash_info; + unsigned total_num_of_blocks; + unsigned next_ptr_start_adr = 0; + unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/ + int i; + + dprintf(INFO, "target_init()\n"); + +#if (!ENABLE_NANDWRITE) + keys_init(); + keypad_init(); +#endif + + if (target_is_emmc_boot()) + return; + + ptable_init(&flash_ptable); + smem_ptable_init(); + + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + + offset = smem_get_apps_flash_start(); + if (offset == 0xffffffff) + while(1); + + total_num_of_blocks = flash_info->num_blocks; + blocks_per_1MB = (1 << 20) / (flash_info->block_size); + + for (i = 0; i < num_parts; i++) { + struct ptentry *ptn = &board_part_list[i]; + unsigned len = ((ptn->length) * blocks_per_1MB); + + if(ptn->start != 0) + ASSERT(ptn->start == DIFF_START_ADDR); + + ptn->start = next_ptr_start_adr; + + if(ptn->length == VARIABLE_LENGTH) + { + unsigned length_for_prt = 0; + unsigned j; + for (j = i+1; j < num_parts; j++) + { + struct ptentry *temp_ptn = &board_part_list[j]; + ASSERT(temp_ptn->length != VARIABLE_LENGTH); + length_for_prt += ((temp_ptn->length) * blocks_per_1MB); + } + len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); + ASSERT(len >= 0); + } + next_ptr_start_adr = ptn->start + len; + ptable_add(&flash_ptable, ptn->name, offset + ptn->start, + len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); + } + + smem_add_modem_partitions(&flash_ptable); + + ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +unsigned board_machtype(void) +{ + return LINUX_MACHTYPE; +} + +void reboot_device(unsigned reboot_reason) +{ + reboot(reboot_reason); +} + +unsigned check_reboot_mode(void) +{ + unsigned mode[2] = {0, 0}; + unsigned int mode_len = sizeof(mode); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE, + &mode, mode_len ); + if(smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n"); + return 0; + } + return mode[0]; +} diff --git a/lk/target/msm7625_ffa/keypad.c b/lk/target/msm7625_ffa/keypad.c new file mode 100644 index 0000000..7550ed5 --- /dev/null +++ b/lk/target/msm7625_ffa/keypad.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +/* don't turn this on without updating the ffa support */ +#define SCAN_FUNCTION_KEYS 0 + +static unsigned int halibut_row_gpios[] = { + 31, 32, 33, 34, 35, 41 +#if SCAN_FUNCTION_KEYS + , 42 +#endif +}; + +static unsigned int halibut_col_gpios[] = { 36, 37, 38, 39, 40 }; + +#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(halibut_col_gpios) + (col)) + +static const unsigned short halibut_keymap[ARRAY_SIZE(halibut_col_gpios) * ARRAY_SIZE(halibut_row_gpios)] = { + //[KEYMAP_INDEX(0, 0)] = KEY_5, + //[KEYMAP_INDEX(0, 1)] = KEY_9, + [KEYMAP_INDEX(0, 2)] = KEY_1, + [KEYMAP_INDEX(0, 3)] = KEY_SEND, + [KEYMAP_INDEX(0, 4)] = KEY_LEFT, + + [KEYMAP_INDEX(1, 0)] = KEY_3, + [KEYMAP_INDEX(1, 1)] = KEY_RIGHT, + [KEYMAP_INDEX(1, 2)] = KEY_VOLUMEUP, + //[KEYMAP_INDEX(1, 3)] = KEY_SHARP, + [KEYMAP_INDEX(1, 4)] = KEY_6, + + [KEYMAP_INDEX(2, 0)] = KEY_HOME, /* A */ + [KEYMAP_INDEX(2, 1)] = KEY_BACK, /* B */ + [KEYMAP_INDEX(2, 2)] = KEY_0, + [KEYMAP_INDEX(2, 3)] = KEY_SHARP, + [KEYMAP_INDEX(2, 4)] = KEY_9, + + [KEYMAP_INDEX(3, 0)] = KEY_UP, + [KEYMAP_INDEX(3, 1)] = KEY_CENTER, + [KEYMAP_INDEX(3, 2)] = KEY_4, + //[KEYMAP_INDEX(3, 3)] = KEY_MUTE, /* SPKR */ + [KEYMAP_INDEX(3, 4)] = KEY_2, + + [KEYMAP_INDEX(4, 0)] = KEY_VOLUMEDOWN, + [KEYMAP_INDEX(4, 1)] = KEY_SOUND, + [KEYMAP_INDEX(4, 2)] = KEY_DOWN, + [KEYMAP_INDEX(4, 3)] = KEY_8, + [KEYMAP_INDEX(4, 4)] = KEY_5, + + //[KEYMAP_INDEX(5, 0)] = KEY_VOLUMEDOWN, + [KEYMAP_INDEX(5, 1)] = KEY_STAR, + [KEYMAP_INDEX(5, 2)] = KEY_SOFT2, + [KEYMAP_INDEX(5, 3)] = KEY_MENU, + [KEYMAP_INDEX(5, 4)] = KEY_7, + +#if SCAN_FUNCTION_KEYS + [KEYMAP_INDEX(6, 0)] = KEY_F5, + [KEYMAP_INDEX(6, 1)] = KEY_F4, + [KEYMAP_INDEX(6, 2)] = KEY_F3, + [KEYMAP_INDEX(6, 3)] = KEY_F2, + [KEYMAP_INDEX(6, 4)] = KEY_F1 +#endif +}; + +static struct gpio_keypad_info halibut_keypad_info = { + .keymap = halibut_keymap, + .output_gpios = halibut_row_gpios, + .input_gpios = halibut_col_gpios, + .noutputs = ARRAY_SIZE(halibut_row_gpios), + .ninputs = ARRAY_SIZE(halibut_col_gpios), + .settle_time = 5 /* msec */, + .poll_time = 20 /* msec */, + .flags = GPIOKPF_DRIVE_INACTIVE, +}; + +void keypad_init(void) +{ + gpio_keypad_init(&halibut_keypad_info); +} diff --git a/lk/target/msm7625_ffa/rules.mk b/lk/target/msm7625_ffa/rules.mk new file mode 100644 index 0000000..372f1f2 --- /dev/null +++ b/lk/target/msm7625_ffa/rules.mk @@ -0,0 +1,39 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared + +PLATFORM := msm7k + +MEMBASE := 0x00000000 # SMI +MEMSIZE := 0x00100000 # 1MB + +BASE_ADDR := 0x00200000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00008000 +RAMDISK_ADDR := BASE_ADDR+0x01000000 +SCRATCH_ADDR := BASE_ADDR+0x02008000 + +KEYS_USE_GPIO_KEYPAD := 1 + +DEFINES += DISPLAY_TYPE_MDDI=0 +DEFINES += ENABLE_PLL3=1 + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + MEMBASE=$(MEMBASE) \ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/keypad.o \ + $(LOCAL_DIR)/atags.o diff --git a/lk/target/msm7625_ffa/tools/makefile b/lk/target/msm7625_ffa/tools/makefile new file mode 100644 index 0000000..b6c2ac0 --- /dev/null +++ b/lk/target/msm7625_ffa/tools/makefile @@ -0,0 +1,38 @@ +#Makefile to generate appsboot.mbn + +ifeq ($(BOOTLOADER_OUT),.) +APPSBOOTHEADER_DIR := $(BUILDDIR) +else +APPSBOOTHEADER_DIR := $(BOOTLOADER_OUT)/../../ +endif + +SRC_DIR := target/$(TARGET)/tools +COMPILER := gcc + +ifeq ($(EMMC_BOOT), 1) + APPSBOOTHDR_FILES := EMMCBOOT.MBN emmc_appsboothd.mbn +else + ifeq ($(BUILD_NANDWRITE), 1) + APPSBOOTHDR_FILES := + else + APPSBOOTHDR_FILES := appsboot.mbn appsboothd.mbn + endif +endif + +APPSBOOTHEADER: $(APPSBOOTHDR_FILES) + +appsboot.mbn: $(OUTBIN) + cp -f $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboot.mbn + +appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +EMMCBOOT.MBN: $(OUTBIN) + cp -f $(OUTBIN) $(APPSBOOTHEADER_DIR)/EMMCBOOT.MBN + +emmc_appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn unified-boot + +mkheader: $(SRC_DIR)/mkheader.c + ${COMPILER} $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader + diff --git a/lk/target/msm7625_ffa/tools/mkheader.c b/lk/target/msm7625_ffa/tools/mkheader.c new file mode 100644 index 0000000..9b03907 --- /dev/null +++ b/lk/target/msm7625_ffa/tools/mkheader.c @@ -0,0 +1,87 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + struct stat s; + unsigned size, base; + int unified_boot = 0; + unsigned unified_boot_magic[20]; + unsigned non_unified_boot_magic[10]; + unsigned magic_len = 0; + unsigned *magic; + int fd; + + if(argc < 3) { + fprintf(stderr,"usage: mkheader \n"); + return -1; + } + + if (argc == 4) { + if(!strcmp("unified-boot",argv[3])) { + unified_boot = 1; + } + } + + if(stat(argv[1], &s)) { + perror("cannot stat binary"); + return -1; + } + + if(unified_boot) { + magic = unified_boot_magic; + magic_len = sizeof(unified_boot_magic); + } else { + magic = non_unified_boot_magic; + magic_len = sizeof(non_unified_boot_magic); + } + + size = s.st_size; + base = 0; + + magic[0] = 0x00000005; /* appsbl */ + magic[1] = 0x00000002; /* nand */ + magic[2] = 0x00000000; + magic[3] = base; + magic[4] = size; + magic[5] = size; + magic[6] = size + base; + magic[7] = 0x00000000; + magic[8] = size + base; + magic[9] = 0x00000000; + + if (unified_boot == 1) + { + magic[10] = 0x33836685; /* cookie magic number */ + magic[11] = 0x00000001; /* cookie version */ + magic[12] = 0x00000002; /* file formats */ + magic[13] = 0x00000000; + magic[14] = 0x00500000; /* 5M for boot.img */ + magic[15] = 0x00000000; + magic[16] = 0x00000000; + magic[17] = 0x00000000; + magic[18] = 0x00000000; + magic[19] = 0x00000000; + } + + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd < 0) { + perror("cannot open header for writing"); + return -1; + } + if(write(fd, magic, magic_len) != magic_len) { + perror("cannot write header"); + close(fd); + unlink(argv[2]); + return -1; + } + close(fd); + + return 0; +} diff --git a/lk/target/msm7625_surf/atags.c b/lk/target/msm7625_surf/atags.c new file mode 100644 index 0000000..9029ad2 --- /dev/null +++ b/lk/target/msm7625_surf/atags.c @@ -0,0 +1,32 @@ +/* Copyright (c) 2009, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT 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. + * + */ + +unsigned* target_atag_mem(unsigned* ptr) +{ + return ptr; +} diff --git a/lk/target/msm7625_surf/include/target/display.h b/lk/target/msm7625_surf/include/target/display.h new file mode 100644 index 0000000..51e7558 --- /dev/null +++ b/lk/target/msm7625_surf/include/target/display.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _TARGET_MSM7625_SURF_DISPLAY_H +#define _TARGET_MSM7625_SURF_DISPLAY_H + +#define TARGET_XRES 800 +#define TARGET_YRES 480 + +#define LCDC_FB_WIDTH 800 +#define LCDC_FB_HEIGHT 480 + +#define LCDC_HSYNC_PULSE_WIDTH_DCLK 60 +#define LCDC_HSYNC_BACK_PORCH_DCLK 81 +#define LCDC_HSYNC_FRONT_PORCH_DCLK 81 +#define LCDC_HSYNC_SKEW_DCLK 0 + +#define LCDC_VSYNC_PULSE_WIDTH_LINES 2 +#define LCDC_VSYNC_BACK_PORCH_LINES 20 +#define LCDC_VSYNC_FRONT_PORCH_LINES 27 + +#endif diff --git a/lk/target/msm7625_surf/init.c b/lk/target/msm7625_surf/init.c new file mode 100644 index 0000000..4e227c5 --- /dev/null +++ b/lk/target/msm7625_surf/init.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include +#include + +#define LINUX_MACHTYPE 2703 + +#define VARIABLE_LENGTH 0x10101010 +#define DIFF_START_ADDR 0xF0F0F0F0 +#define NUM_PAGES_PER_BLOCK 0x40 + +static struct ptable flash_ptable; + +/* for these partitions, start will be offset by either what we get from + * smem, or from the above offset if smem is not useful. Also, we should + * probably have smem_ptable code populate our flash_ptable. + * + * When smem provides us with a full partition table, we can get rid of + * this altogether. + * + */ +static struct ptentry board_part_list[] = { + { + .start = 0, + .length = 5 /* In MB */, + .name = "boot", + }, + { + .start = DIFF_START_ADDR, + .length = 95 /* In MB */, + .name = "system", + }, + { + .start = DIFF_START_ADDR, + .length = 1 /* In MB */, + .name = "cache", + }, + { + .start = DIFF_START_ADDR, + .length = 1 /* In MB */, + .name = "misc", + }, + { + .start = DIFF_START_ADDR, + .length = VARIABLE_LENGTH, + .name = "userdata", + }, + { + .start = DIFF_START_ADDR, + .length = 2 /* In MB */, + .name = "persist", + }, + { + .start = DIFF_START_ADDR, + .length = 5 /* In MB */, + .name = "recovery", + }, +}; +static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry); + +void smem_ptable_init(void); +unsigned smem_get_apps_flash_start(void); + +void keypad_init(void); + +int target_is_emmc_boot(void); + +void target_init(void) +{ + unsigned offset; + struct flash_info *flash_info; + unsigned total_num_of_blocks; + unsigned next_ptr_start_adr = 0; + unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/ + int i; + + dprintf(INFO, "target_init()\n"); + +#if (!ENABLE_NANDWRITE) + keys_init(); + keypad_init(); +#endif + + if (target_is_emmc_boot()) + return; + + ptable_init(&flash_ptable); + smem_ptable_init(); + + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + + offset = smem_get_apps_flash_start(); + if (offset == 0xffffffff) + while(1); + + total_num_of_blocks = flash_info->num_blocks; + blocks_per_1MB = (1 << 20) / (flash_info->block_size); + + for (i = 0; i < num_parts; i++) { + struct ptentry *ptn = &board_part_list[i]; + unsigned len = ((ptn->length) * blocks_per_1MB); + + if(ptn->start != 0) + ASSERT(ptn->start == DIFF_START_ADDR); + + ptn->start = next_ptr_start_adr; + + if(ptn->length == VARIABLE_LENGTH) + { + unsigned length_for_prt = 0; + unsigned j; + for (j = i+1; j < num_parts; j++) + { + struct ptentry *temp_ptn = &board_part_list[j]; + ASSERT(temp_ptn->length != VARIABLE_LENGTH); + length_for_prt += ((temp_ptn->length) * blocks_per_1MB); + } + len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); + ASSERT(len >= 0); + } + next_ptr_start_adr = ptn->start + len; + ptable_add(&flash_ptable, ptn->name, offset + ptn->start, + len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); + } + + smem_add_modem_partitions(&flash_ptable); + + ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +unsigned board_machtype(void) +{ + return LINUX_MACHTYPE; +} + +void reboot_device(unsigned reboot_reason) +{ + reboot(reboot_reason); +} + +unsigned check_reboot_mode(void) +{ + unsigned mode[2] = {0, 0}; + unsigned int mode_len = sizeof(mode); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE, + &mode, mode_len ); + if(smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n"); + return 0; + } + return mode[0]; +} diff --git a/lk/target/msm7625_surf/keypad.c b/lk/target/msm7625_surf/keypad.c new file mode 100644 index 0000000..c44b06d --- /dev/null +++ b/lk/target/msm7625_surf/keypad.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +/* don't turn this on without updating the ffa support */ +#define SCAN_FUNCTION_KEYS 0 + +static unsigned int halibut_row_gpios[] = { + 31, 32, 33, 34, 35, 41 +#if SCAN_FUNCTION_KEYS + , 42 +#endif +}; + +static unsigned int halibut_col_gpios[] = { 36, 37, 38, 39, 40 }; + +#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(halibut_col_gpios) + (col)) + +static const unsigned short halibut_keymap[ARRAY_SIZE(halibut_col_gpios) * ARRAY_SIZE(halibut_row_gpios)] = { + [KEYMAP_INDEX(0, 0)] = KEY_5, + [KEYMAP_INDEX(0, 1)] = KEY_9, + [KEYMAP_INDEX(0, 2)] = KEY_SOFT1, + [KEYMAP_INDEX(0, 3)] = KEY_6, + [KEYMAP_INDEX(0, 4)] = KEY_LEFT, + + [KEYMAP_INDEX(1, 0)] = KEY_0, + [KEYMAP_INDEX(1, 1)] = KEY_RIGHT, + [KEYMAP_INDEX(1, 2)] = KEY_1, + [KEYMAP_INDEX(1, 3)] = KEY_SHARP, + [KEYMAP_INDEX(1, 4)] = KEY_SEND, + + [KEYMAP_INDEX(2, 0)] = KEY_VOLUMEUP, + [KEYMAP_INDEX(2, 1)] = KEY_HOME, /* FA */ + [KEYMAP_INDEX(2, 2)] = KEY_F8, /* QCHT */ + [KEYMAP_INDEX(2, 3)] = KEY_F6, /* R+ */ + [KEYMAP_INDEX(2, 4)] = KEY_F7, /* R- */ + + [KEYMAP_INDEX(3, 0)] = KEY_UP, + [KEYMAP_INDEX(3, 1)] = KEY_CLEAR, + [KEYMAP_INDEX(3, 2)] = KEY_4, + [KEYMAP_INDEX(3, 3)] = KEY_MUTE, /* SPKR */ + [KEYMAP_INDEX(3, 4)] = KEY_2, + + [KEYMAP_INDEX(4, 0)] = KEY_SOFT2, /* SOFT2 */ + [KEYMAP_INDEX(4, 1)] = KEY_CENTER, /* KEY_CENTER */ + [KEYMAP_INDEX(4, 2)] = KEY_DOWN, + [KEYMAP_INDEX(4, 3)] = KEY_BACK, /* FB */ + [KEYMAP_INDEX(4, 4)] = KEY_8, + + [KEYMAP_INDEX(5, 0)] = KEY_VOLUMEDOWN, + [KEYMAP_INDEX(5, 1)] = KEY_STAR, /* KEY_STAR */ + [KEYMAP_INDEX(5, 2)] = KEY_MAIL, /* MESG */ + [KEYMAP_INDEX(5, 3)] = KEY_3, + [KEYMAP_INDEX(5, 4)] = KEY_7, + +#if SCAN_FUNCTION_KEYS + [KEYMAP_INDEX(6, 0)] = KEY_F5, + [KEYMAP_INDEX(6, 1)] = KEY_F4, + [KEYMAP_INDEX(6, 2)] = KEY_F3, + [KEYMAP_INDEX(6, 3)] = KEY_F2, + [KEYMAP_INDEX(6, 4)] = KEY_F1 +#endif +}; + +static struct gpio_keypad_info halibut_keypad_info = { + .keymap = halibut_keymap, + .output_gpios = halibut_row_gpios, + .input_gpios = halibut_col_gpios, + .noutputs = ARRAY_SIZE(halibut_row_gpios), + .ninputs = ARRAY_SIZE(halibut_col_gpios), + .settle_time = 5 /* msec */, + .poll_time = 20 /* msec */, + .flags = GPIOKPF_DRIVE_INACTIVE, +}; + +void keypad_init(void) +{ + gpio_keypad_init(&halibut_keypad_info); +} diff --git a/lk/target/msm7625_surf/rules.mk b/lk/target/msm7625_surf/rules.mk new file mode 100644 index 0000000..372f1f2 --- /dev/null +++ b/lk/target/msm7625_surf/rules.mk @@ -0,0 +1,39 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared + +PLATFORM := msm7k + +MEMBASE := 0x00000000 # SMI +MEMSIZE := 0x00100000 # 1MB + +BASE_ADDR := 0x00200000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00008000 +RAMDISK_ADDR := BASE_ADDR+0x01000000 +SCRATCH_ADDR := BASE_ADDR+0x02008000 + +KEYS_USE_GPIO_KEYPAD := 1 + +DEFINES += DISPLAY_TYPE_MDDI=0 +DEFINES += ENABLE_PLL3=1 + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + MEMBASE=$(MEMBASE) \ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/keypad.o \ + $(LOCAL_DIR)/atags.o diff --git a/lk/target/msm7625_surf/tools/makefile b/lk/target/msm7625_surf/tools/makefile new file mode 100644 index 0000000..2b36900 --- /dev/null +++ b/lk/target/msm7625_surf/tools/makefile @@ -0,0 +1,37 @@ +#Makefile to generate appsboot.mbn + +ifeq ($(BOOTLOADER_OUT),.) +APPSBOOTHEADER_DIR := $(BUILDDIR) +else +APPSBOOTHEADER_DIR := $(BOOTLOADER_OUT)/../../ +endif + +SRC_DIR := target/$(TARGET)/tools +COMPILER := gcc + +ifeq ($(EMMC_BOOT), 1) + APPSBOOTHDR_FILES := EMMCBOOT.MBN emmc_appsboothd.mbn +else + ifeq ($(BUILD_NANDWRITE), 1) + APPSBOOTHDR_FILES := + else + APPSBOOTHDR_FILES := appsboot.mbn appsboothd.mbn + endif +endif + +APPSBOOTHEADER: $(APPSBOOTHDR_FILES) + +appsboot.mbn: $(OUTBIN) + cp -f $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboot.mbn + +appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +EMMCBOOT.MBN: $(OUTBIN) + cp -f $(OUTBIN) $(APPSBOOTHEADER_DIR)/EMMCBOOT.MBN + +emmc_appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn unified-boot + +mkheader: $(SRC_DIR)/mkheader.c + ${COMPILER} $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader diff --git a/lk/target/msm7625_surf/tools/mkheader.c b/lk/target/msm7625_surf/tools/mkheader.c new file mode 100644 index 0000000..9b03907 --- /dev/null +++ b/lk/target/msm7625_surf/tools/mkheader.c @@ -0,0 +1,87 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + struct stat s; + unsigned size, base; + int unified_boot = 0; + unsigned unified_boot_magic[20]; + unsigned non_unified_boot_magic[10]; + unsigned magic_len = 0; + unsigned *magic; + int fd; + + if(argc < 3) { + fprintf(stderr,"usage: mkheader \n"); + return -1; + } + + if (argc == 4) { + if(!strcmp("unified-boot",argv[3])) { + unified_boot = 1; + } + } + + if(stat(argv[1], &s)) { + perror("cannot stat binary"); + return -1; + } + + if(unified_boot) { + magic = unified_boot_magic; + magic_len = sizeof(unified_boot_magic); + } else { + magic = non_unified_boot_magic; + magic_len = sizeof(non_unified_boot_magic); + } + + size = s.st_size; + base = 0; + + magic[0] = 0x00000005; /* appsbl */ + magic[1] = 0x00000002; /* nand */ + magic[2] = 0x00000000; + magic[3] = base; + magic[4] = size; + magic[5] = size; + magic[6] = size + base; + magic[7] = 0x00000000; + magic[8] = size + base; + magic[9] = 0x00000000; + + if (unified_boot == 1) + { + magic[10] = 0x33836685; /* cookie magic number */ + magic[11] = 0x00000001; /* cookie version */ + magic[12] = 0x00000002; /* file formats */ + magic[13] = 0x00000000; + magic[14] = 0x00500000; /* 5M for boot.img */ + magic[15] = 0x00000000; + magic[16] = 0x00000000; + magic[17] = 0x00000000; + magic[18] = 0x00000000; + magic[19] = 0x00000000; + } + + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd < 0) { + perror("cannot open header for writing"); + return -1; + } + if(write(fd, magic, magic_len) != magic_len) { + perror("cannot write header"); + close(fd); + unlink(argv[2]); + return -1; + } + close(fd); + + return 0; +} diff --git a/lk/target/msm7627_ffa/atags.c b/lk/target/msm7627_ffa/atags.c new file mode 100644 index 0000000..8c3ff6c --- /dev/null +++ b/lk/target/msm7627_ffa/atags.c @@ -0,0 +1,67 @@ +/* Copyright (c) 2009-2010, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#define SIZE_1M 0x00100000 + +unsigned* target_atag_mem(unsigned* ptr) +{ + struct smem_ram_ptable ram_ptable; + unsigned i = 0; + + if (smem_ram_ptable_init(&ram_ptable)) + { + for (i = 0; i < ram_ptable.len; i++) + { + if ((ram_ptable.parts[i].attr == READWRITE) + && (ram_ptable.parts[i].domain == APPS_DOMAIN) + && (ram_ptable.parts[i].start != 0x0) + && (!(ram_ptable.parts[i].size < SIZE_1M))) + { + /* ATAG_MEM */ + *ptr++ = 4; + *ptr++ = 0x54410002; + /* FIXME: RAM partition table currently reports 2M extra + Fix this by subracting 2M, until modem ram partition table + starts reporting the right values */ + *ptr++ = ram_ptable.parts[i].size - (2*SIZE_1M); + *ptr++ = ram_ptable.parts[i].start; + } + } + } + else + { + dprintf(CRITICAL, "ERROR: Unable to read RAM partition\n"); + ASSERT(0); + } + return ptr; +} + diff --git a/lk/target/msm7627_ffa/include/target/display.h b/lk/target/msm7627_ffa/include/target/display.h new file mode 100644 index 0000000..af30276 --- /dev/null +++ b/lk/target/msm7627_ffa/include/target/display.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _TARGET_MSM7627_FFA_DISPLAY_H +#define _TARGET_MSM7627_FFA_DISPLAY_H + +#define TARGET_XRES 480 +#define TARGET_YRES 640 + +#define LCDC_FB_WIDTH 480 +#define LCDC_FB_HEIGHT 640 + +#define LCDC_HSYNC_PULSE_WIDTH_DCLK 60 +#define LCDC_HSYNC_BACK_PORCH_DCLK 144 +#define LCDC_HSYNC_FRONT_PORCH_DCLK 33 +#define LCDC_HSYNC_SKEW_DCLK 0 + +#define LCDC_VSYNC_PULSE_WIDTH_LINES 2 +#define LCDC_VSYNC_BACK_PORCH_LINES 2 +#define LCDC_VSYNC_FRONT_PORCH_LINES 2 + +#endif diff --git a/lk/target/msm7627_ffa/init.c b/lk/target/msm7627_ffa/init.c new file mode 100644 index 0000000..f2125fc --- /dev/null +++ b/lk/target/msm7627_ffa/init.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include +#include + +#define LINUX_MACHTYPE 2706 + +#define VARIABLE_LENGTH 0x10101010 +#define DIFF_START_ADDR 0xF0F0F0F0 +#define NUM_PAGES_PER_BLOCK 0x40 + +static struct ptable flash_ptable; + +/* for these partitions, start will be offset by either what we get from + * smem, or from the above offset if smem is not useful. Also, we should + * probably have smem_ptable code populate our flash_ptable. + * + * When smem provides us with a full partition table, we can get rid of + * this altogether. + * + */ +static struct ptentry board_part_list[] = { + { + .start = 0, + .length = 5 /* In MB */, + .name = "boot", + }, + { + .start = DIFF_START_ADDR, + .length = 105 /* In MB */, + .name = "system", + }, + { + .start = DIFF_START_ADDR, + .length = 1 /* In MB */, + .name = "cache", + }, + { + .start = DIFF_START_ADDR, + .length = 1 /* In MB */, + .name = "misc", + }, + { + .start = DIFF_START_ADDR, + .length = VARIABLE_LENGTH, + .name = "userdata", + }, + { + .start = DIFF_START_ADDR, + .length = 2 /* In MB */, + .name = "persist", + }, + { + .start = DIFF_START_ADDR, + .length = 5 /* In MB */, + .name = "recovery", + }, +}; +static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry); + +void smem_ptable_init(void); +unsigned smem_get_apps_flash_start(void); + +void keypad_init(void); + +int target_is_emmc_boot(void); + +void target_init(void) +{ + unsigned offset; + struct flash_info *flash_info; + unsigned total_num_of_blocks; + unsigned next_ptr_start_adr = 0; + unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/ + int i; + + dprintf(INFO, "target_init()\n"); + +#if (!ENABLE_NANDWRITE) + keys_init(); + keypad_init(); +#endif + + if (target_is_emmc_boot()) + return; + + ptable_init(&flash_ptable); + smem_ptable_init(); + + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + + offset = smem_get_apps_flash_start(); + if (offset == 0xffffffff) + while(1); + + total_num_of_blocks = flash_info->num_blocks; + blocks_per_1MB = (1 << 20) / (flash_info->block_size); + + for (i = 0; i < num_parts; i++) { + struct ptentry *ptn = &board_part_list[i]; + unsigned len = ((ptn->length) * blocks_per_1MB); + + if(ptn->start != 0) + ASSERT(ptn->start == DIFF_START_ADDR); + + ptn->start = next_ptr_start_adr; + + if(ptn->length == VARIABLE_LENGTH) + { + unsigned length_for_prt = 0; + unsigned j; + for (j = i+1; j < num_parts; j++) + { + struct ptentry *temp_ptn = &board_part_list[j]; + ASSERT(temp_ptn->length != VARIABLE_LENGTH); + length_for_prt += ((temp_ptn->length) * blocks_per_1MB); + } + len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); + ASSERT(len >= 0); + } + next_ptr_start_adr = ptn->start + len; + ptable_add(&flash_ptable, ptn->name, offset + ptn->start, + len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); + } + + smem_add_modem_partitions(&flash_ptable); + + ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +unsigned board_machtype(void) +{ + return LINUX_MACHTYPE; +} + +void reboot_device(unsigned reboot_reason) +{ + reboot(reboot_reason); +} + +unsigned check_reboot_mode(void) +{ + unsigned mode[2] = {0, 0}; + unsigned int mode_len = sizeof(mode); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE, + &mode, mode_len ); + if(smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n"); + return 0; + } + return mode[0]; +} + +static unsigned target_check_power_on_reason(void) +{ + unsigned power_on_status = 0; + unsigned int status_len = sizeof(power_on_status); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_POWER_ON_STATUS_INFO, + &power_on_status, status_len); + if (!smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for power on reason\n"); + } + + return power_on_status; +} + +unsigned target_pause_for_battery_charge(void) +{ + if (target_check_power_on_reason() == PWR_ON_EVENT_USB_CHG) + return 1; + return 0; +} + +void target_battery_charging_enable(unsigned enable, unsigned disconnect) +{ +} diff --git a/lk/target/msm7627_ffa/keypad.c b/lk/target/msm7627_ffa/keypad.c new file mode 100644 index 0000000..7550ed5 --- /dev/null +++ b/lk/target/msm7627_ffa/keypad.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +/* don't turn this on without updating the ffa support */ +#define SCAN_FUNCTION_KEYS 0 + +static unsigned int halibut_row_gpios[] = { + 31, 32, 33, 34, 35, 41 +#if SCAN_FUNCTION_KEYS + , 42 +#endif +}; + +static unsigned int halibut_col_gpios[] = { 36, 37, 38, 39, 40 }; + +#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(halibut_col_gpios) + (col)) + +static const unsigned short halibut_keymap[ARRAY_SIZE(halibut_col_gpios) * ARRAY_SIZE(halibut_row_gpios)] = { + //[KEYMAP_INDEX(0, 0)] = KEY_5, + //[KEYMAP_INDEX(0, 1)] = KEY_9, + [KEYMAP_INDEX(0, 2)] = KEY_1, + [KEYMAP_INDEX(0, 3)] = KEY_SEND, + [KEYMAP_INDEX(0, 4)] = KEY_LEFT, + + [KEYMAP_INDEX(1, 0)] = KEY_3, + [KEYMAP_INDEX(1, 1)] = KEY_RIGHT, + [KEYMAP_INDEX(1, 2)] = KEY_VOLUMEUP, + //[KEYMAP_INDEX(1, 3)] = KEY_SHARP, + [KEYMAP_INDEX(1, 4)] = KEY_6, + + [KEYMAP_INDEX(2, 0)] = KEY_HOME, /* A */ + [KEYMAP_INDEX(2, 1)] = KEY_BACK, /* B */ + [KEYMAP_INDEX(2, 2)] = KEY_0, + [KEYMAP_INDEX(2, 3)] = KEY_SHARP, + [KEYMAP_INDEX(2, 4)] = KEY_9, + + [KEYMAP_INDEX(3, 0)] = KEY_UP, + [KEYMAP_INDEX(3, 1)] = KEY_CENTER, + [KEYMAP_INDEX(3, 2)] = KEY_4, + //[KEYMAP_INDEX(3, 3)] = KEY_MUTE, /* SPKR */ + [KEYMAP_INDEX(3, 4)] = KEY_2, + + [KEYMAP_INDEX(4, 0)] = KEY_VOLUMEDOWN, + [KEYMAP_INDEX(4, 1)] = KEY_SOUND, + [KEYMAP_INDEX(4, 2)] = KEY_DOWN, + [KEYMAP_INDEX(4, 3)] = KEY_8, + [KEYMAP_INDEX(4, 4)] = KEY_5, + + //[KEYMAP_INDEX(5, 0)] = KEY_VOLUMEDOWN, + [KEYMAP_INDEX(5, 1)] = KEY_STAR, + [KEYMAP_INDEX(5, 2)] = KEY_SOFT2, + [KEYMAP_INDEX(5, 3)] = KEY_MENU, + [KEYMAP_INDEX(5, 4)] = KEY_7, + +#if SCAN_FUNCTION_KEYS + [KEYMAP_INDEX(6, 0)] = KEY_F5, + [KEYMAP_INDEX(6, 1)] = KEY_F4, + [KEYMAP_INDEX(6, 2)] = KEY_F3, + [KEYMAP_INDEX(6, 3)] = KEY_F2, + [KEYMAP_INDEX(6, 4)] = KEY_F1 +#endif +}; + +static struct gpio_keypad_info halibut_keypad_info = { + .keymap = halibut_keymap, + .output_gpios = halibut_row_gpios, + .input_gpios = halibut_col_gpios, + .noutputs = ARRAY_SIZE(halibut_row_gpios), + .ninputs = ARRAY_SIZE(halibut_col_gpios), + .settle_time = 5 /* msec */, + .poll_time = 20 /* msec */, + .flags = GPIOKPF_DRIVE_INACTIVE, +}; + +void keypad_init(void) +{ + gpio_keypad_init(&halibut_keypad_info); +} diff --git a/lk/target/msm7627_ffa/rules.mk b/lk/target/msm7627_ffa/rules.mk new file mode 100644 index 0000000..92299f9 --- /dev/null +++ b/lk/target/msm7627_ffa/rules.mk @@ -0,0 +1,41 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared + +PLATFORM := msm7k + +MEMBASE := 0x00000000 # SMI +MEMSIZE := 0x00100000 # 1MB + +BASE_ADDR := 0x00200000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00008000 +RAMDISK_ADDR := BASE_ADDR+0x01000000 +SCRATCH_ADDR := BASE_ADDR+0x04000000 + +KEYS_USE_GPIO_KEYPAD := 1 + +DEFINES += DISPLAY_TYPE_MDDI=0 +DEFINES += DISPLAY_TYPE_LCDC=1 + +DEFINES += DISPLAY_SPLASH_SCREEN=1 + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + MEMBASE=$(MEMBASE) \ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/keypad.o \ + $(LOCAL_DIR)/atags.o diff --git a/lk/target/msm7627_ffa/tools/makefile b/lk/target/msm7627_ffa/tools/makefile new file mode 100644 index 0000000..f01f7ad --- /dev/null +++ b/lk/target/msm7627_ffa/tools/makefile @@ -0,0 +1,39 @@ +#Makefile to generate appsboot.mbn + +ifeq ($(BOOTLOADER_OUT),.) +APPSBOOTHEADER_DIR := $(BUILDDIR) +else +APPSBOOTHEADER_DIR := $(BOOTLOADER_OUT)/../../ +endif + +SRC_DIR := target/$(TARGET)/tools +COMPILER := gcc + +ifeq ($(EMMC_BOOT), 1) + APPSBOOTHDR_FILES := EMMCBOOT.MBN emmc_appsboothd.mbn +else + ifeq ($(BUILD_NANDWRITE), 1) + APPSBOOTHDR_FILES := + else + APPSBOOTHDR_FILES := appsboot.mbn appsboothd.mbn + endif +endif + +APPSBOOTHEADER: $(APPSBOOTHDR_FILES) + +appsboot.mbn: $(OUTBIN) + cp -f $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboot.mbn + +appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +EMMCBOOT.MBN: $(OUTBIN) + cp -f $(OUTBIN) $(APPSBOOTHEADER_DIR)/EMMCBOOT.MBN + cp -f $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboot.mbn + +emmc_appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn unified-boot + +mkheader: $(SRC_DIR)/mkheader.c + ${COMPILER} $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader + diff --git a/lk/target/msm7627_ffa/tools/mkheader.c b/lk/target/msm7627_ffa/tools/mkheader.c new file mode 100644 index 0000000..2bd3479 --- /dev/null +++ b/lk/target/msm7627_ffa/tools/mkheader.c @@ -0,0 +1,87 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + struct stat s; + unsigned size, base; + int unified_boot = 0; + unsigned unified_boot_magic[20]; + unsigned non_unified_boot_magic[10]; + unsigned magic_len = 0; + unsigned *magic; + int fd; + + if(argc < 3) { + fprintf(stderr,"usage: mkheader \n"); + return -1; + } + + if (argc == 4) { + if(!strcmp("unified-boot",argv[3])) { + unified_boot = 1; + } + } + + if(stat(argv[1], &s)) { + perror("cannot stat binary"); + return -1; + } + + if(unified_boot) { + magic = unified_boot_magic; + magic_len = sizeof(unified_boot_magic); + } else { + magic = non_unified_boot_magic; + magic_len = sizeof(non_unified_boot_magic); + } + + size = s.st_size; + base = 0; + + magic[0] = 0x00000005; /* appsbl */ + magic[1] = 0x00000002; /* nand */ + magic[2] = 0x00000000; + magic[3] = base; + magic[4] = size; + magic[5] = size; + magic[6] = size + base; + magic[7] = 0x00000000; + magic[8] = size + base; + magic[9] = 0x00000000; + + if (unified_boot == 1) + { + magic[10] = 0x33836685; /* cookie magic number */ + magic[11] = 0x00000001; /* cookie version */ + magic[12] = 0x00000002; /* file formats */ + magic[13] = 0x00000000; + magic[14] = 0x00000000; /* not setting size for boot.img */ + magic[15] = 0x00000000; + magic[16] = 0x00000000; + magic[17] = 0x00000000; + magic[18] = 0x00000000; + magic[19] = 0x00000000; + } + + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd < 0) { + perror("cannot open header for writing"); + return -1; + } + if(write(fd, magic, magic_len) != magic_len) { + perror("cannot write header"); + close(fd); + unlink(argv[2]); + return -1; + } + close(fd); + + return 0; +} diff --git a/lk/target/msm7627_surf/atags.c b/lk/target/msm7627_surf/atags.c new file mode 100644 index 0000000..a2e1db7 --- /dev/null +++ b/lk/target/msm7627_surf/atags.c @@ -0,0 +1,72 @@ +/* Copyright (c) 2009-2010, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#define SIZE_1M 0x00100000 + +unsigned* target_atag_mem(unsigned* ptr) +{ + struct smem_ram_ptable ram_ptable; + unsigned i = 0; + + if (smem_ram_ptable_init(&ram_ptable)) + { + for (i = 0; i < ram_ptable.len; i++) + { + if ((ram_ptable.parts[i].attr == READWRITE) + && (ram_ptable.parts[i].domain == APPS_DOMAIN) + && (ram_ptable.parts[i].start != 0x0) + && (!(ram_ptable.parts[i].size < SIZE_1M))) + { + /* ATAG_MEM */ + *ptr++ = 4; + *ptr++ = 0x54410002; + /* FIXME: RAM partition table currently reports 2M extra + Fix this by subracting 2M, until modem ram partition table + starts reporting the right values. Also need fixes for + RAM partition table to have emmc entries correct */ + if (target_is_emmc_boot()) + *ptr++ = ram_ptable.parts[i].size - (2*SIZE_1M) - (6*SIZE_1M); + else + *ptr++ = ram_ptable.parts[i].size - (2*SIZE_1M); + + *ptr++ = ram_ptable.parts[i].start; + } + } + } + else + { + dprintf(CRITICAL, "ERROR: Unable to read RAM partition\n"); + ASSERT(0); + } + return ptr; +} + diff --git a/lk/target/msm7627_surf/include/target/display.h b/lk/target/msm7627_surf/include/target/display.h new file mode 100644 index 0000000..9c1bea0 --- /dev/null +++ b/lk/target/msm7627_surf/include/target/display.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _TARGET_MSM7627_SURF_DISPLAY_H +#define _TARGET_MSM7627_SURF_DISPLAY_H + +#define TARGET_XRES 800 +#define TARGET_YRES 480 + +#define LCDC_FB_WIDTH 800 +#define LCDC_FB_HEIGHT 480 + +#define LCDC_HSYNC_PULSE_WIDTH_DCLK 60 +#define LCDC_HSYNC_BACK_PORCH_DCLK 81 +#define LCDC_HSYNC_FRONT_PORCH_DCLK 81 +#define LCDC_HSYNC_SKEW_DCLK 0 + +#define LCDC_VSYNC_PULSE_WIDTH_LINES 2 +#define LCDC_VSYNC_BACK_PORCH_LINES 20 +#define LCDC_VSYNC_FRONT_PORCH_LINES 27 + +#endif diff --git a/lk/target/msm7627_surf/init.c b/lk/target/msm7627_surf/init.c new file mode 100644 index 0000000..7a09c4a --- /dev/null +++ b/lk/target/msm7627_surf/init.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define LINUX_MACHTYPE 2705 + +#define VARIABLE_LENGTH 0x10101010 +#define DIFF_START_ADDR 0xF0F0F0F0 +#define NUM_PAGES_PER_BLOCK 0x40 + +static struct ptable flash_ptable; + +/* for these partitions, start will be offset by either what we get from + * smem, or from the above offset if smem is not useful. Also, we should + * probably have smem_ptable code populate our flash_ptable. + * + * When smem provides us with a full partition table, we can get rid of + * this altogether. + * + */ +static struct ptentry board_part_list[] = { + { + .start = 0, + .length = 5 /* In MB */, + .name = "boot", + }, + { + .start = DIFF_START_ADDR, + .length = 105 /* In MB */, + .name = "system", + }, + { + .start = DIFF_START_ADDR, + .length = 1 /* In MB */, + .name = "cache", + }, + { + .start = DIFF_START_ADDR, + .length = 1 /* In MB */, + .name = "misc", + }, + { + .start = DIFF_START_ADDR, + .length = VARIABLE_LENGTH, + .name = "userdata", + }, + { + .start = DIFF_START_ADDR, + .length = 2 /* In MB */, + .name = "persist", + }, + { + .start = DIFF_START_ADDR, + .length = 5 /* In MB */, + .name = "recovery", + }, +}; +static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry); + +void smem_ptable_init(void); +unsigned smem_get_apps_flash_start(void); + +void keypad_init(void); + +int target_is_emmc_boot(void); + +void target_init(void) +{ + unsigned offset; + struct flash_info *flash_info; + unsigned total_num_of_blocks; + unsigned next_ptr_start_adr = 0; + unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/ + int i; + + dprintf(INFO, "target_init()\n"); + +#if (!ENABLE_NANDWRITE) + keys_init(); + keypad_init(); +#endif + + if (target_is_emmc_boot()) + { + if(mmc_boot_main(MMC_SLOT, MSM_SDC1_BASE)) + { + dprintf(CRITICAL, "mmc init failed!"); + ASSERT(0); + } + return; + } + + ptable_init(&flash_ptable); + smem_ptable_init(); + + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + + offset = smem_get_apps_flash_start(); + if (offset == 0xffffffff) + while(1); + + total_num_of_blocks = flash_info->num_blocks; + blocks_per_1MB = (1 << 20) / (flash_info->block_size); + + for (i = 0; i < num_parts; i++) { + struct ptentry *ptn = &board_part_list[i]; + unsigned len = ((ptn->length) * blocks_per_1MB); + + if(ptn->start != 0) + ASSERT(ptn->start == DIFF_START_ADDR); + + ptn->start = next_ptr_start_adr; + + if(ptn->length == VARIABLE_LENGTH) + { + unsigned length_for_prt = 0; + unsigned j; + for (j = i+1; j < num_parts; j++) + { + struct ptentry *temp_ptn = &board_part_list[j]; + ASSERT(temp_ptn->length != VARIABLE_LENGTH); + length_for_prt += ((temp_ptn->length) * blocks_per_1MB); + } + len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); + ASSERT(len >= 0); + } + next_ptr_start_adr = ptn->start + len; + ptable_add(&flash_ptable, ptn->name, offset + ptn->start, + len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); + } + + smem_add_modem_partitions(&flash_ptable); + + ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +unsigned board_machtype(void) +{ + return LINUX_MACHTYPE; +} + +void reboot_device(unsigned reboot_reason) +{ + reboot(reboot_reason); +} + +unsigned check_reboot_mode(void) +{ + unsigned mode[2] = {0, 0}; + unsigned int mode_len = sizeof(mode); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE, + &mode, mode_len ); + if(smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n"); + return 0; + } + return mode[0]; +} + +static unsigned target_check_power_on_reason(void) +{ + unsigned power_on_status = 0; + unsigned int status_len = sizeof(power_on_status); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_POWER_ON_STATUS_INFO, + &power_on_status, status_len); + if (!smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for power on reason\n"); + } + + return power_on_status; +} + +unsigned target_pause_for_battery_charge(void) +{ + if (target_check_power_on_reason() == PWR_ON_EVENT_USB_CHG) + return 1; + return 0; +} + +void target_battery_charging_enable(unsigned enable, unsigned disconnect) +{ +} diff --git a/lk/target/msm7627_surf/keypad.c b/lk/target/msm7627_surf/keypad.c new file mode 100644 index 0000000..c44b06d --- /dev/null +++ b/lk/target/msm7627_surf/keypad.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +/* don't turn this on without updating the ffa support */ +#define SCAN_FUNCTION_KEYS 0 + +static unsigned int halibut_row_gpios[] = { + 31, 32, 33, 34, 35, 41 +#if SCAN_FUNCTION_KEYS + , 42 +#endif +}; + +static unsigned int halibut_col_gpios[] = { 36, 37, 38, 39, 40 }; + +#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(halibut_col_gpios) + (col)) + +static const unsigned short halibut_keymap[ARRAY_SIZE(halibut_col_gpios) * ARRAY_SIZE(halibut_row_gpios)] = { + [KEYMAP_INDEX(0, 0)] = KEY_5, + [KEYMAP_INDEX(0, 1)] = KEY_9, + [KEYMAP_INDEX(0, 2)] = KEY_SOFT1, + [KEYMAP_INDEX(0, 3)] = KEY_6, + [KEYMAP_INDEX(0, 4)] = KEY_LEFT, + + [KEYMAP_INDEX(1, 0)] = KEY_0, + [KEYMAP_INDEX(1, 1)] = KEY_RIGHT, + [KEYMAP_INDEX(1, 2)] = KEY_1, + [KEYMAP_INDEX(1, 3)] = KEY_SHARP, + [KEYMAP_INDEX(1, 4)] = KEY_SEND, + + [KEYMAP_INDEX(2, 0)] = KEY_VOLUMEUP, + [KEYMAP_INDEX(2, 1)] = KEY_HOME, /* FA */ + [KEYMAP_INDEX(2, 2)] = KEY_F8, /* QCHT */ + [KEYMAP_INDEX(2, 3)] = KEY_F6, /* R+ */ + [KEYMAP_INDEX(2, 4)] = KEY_F7, /* R- */ + + [KEYMAP_INDEX(3, 0)] = KEY_UP, + [KEYMAP_INDEX(3, 1)] = KEY_CLEAR, + [KEYMAP_INDEX(3, 2)] = KEY_4, + [KEYMAP_INDEX(3, 3)] = KEY_MUTE, /* SPKR */ + [KEYMAP_INDEX(3, 4)] = KEY_2, + + [KEYMAP_INDEX(4, 0)] = KEY_SOFT2, /* SOFT2 */ + [KEYMAP_INDEX(4, 1)] = KEY_CENTER, /* KEY_CENTER */ + [KEYMAP_INDEX(4, 2)] = KEY_DOWN, + [KEYMAP_INDEX(4, 3)] = KEY_BACK, /* FB */ + [KEYMAP_INDEX(4, 4)] = KEY_8, + + [KEYMAP_INDEX(5, 0)] = KEY_VOLUMEDOWN, + [KEYMAP_INDEX(5, 1)] = KEY_STAR, /* KEY_STAR */ + [KEYMAP_INDEX(5, 2)] = KEY_MAIL, /* MESG */ + [KEYMAP_INDEX(5, 3)] = KEY_3, + [KEYMAP_INDEX(5, 4)] = KEY_7, + +#if SCAN_FUNCTION_KEYS + [KEYMAP_INDEX(6, 0)] = KEY_F5, + [KEYMAP_INDEX(6, 1)] = KEY_F4, + [KEYMAP_INDEX(6, 2)] = KEY_F3, + [KEYMAP_INDEX(6, 3)] = KEY_F2, + [KEYMAP_INDEX(6, 4)] = KEY_F1 +#endif +}; + +static struct gpio_keypad_info halibut_keypad_info = { + .keymap = halibut_keymap, + .output_gpios = halibut_row_gpios, + .input_gpios = halibut_col_gpios, + .noutputs = ARRAY_SIZE(halibut_row_gpios), + .ninputs = ARRAY_SIZE(halibut_col_gpios), + .settle_time = 5 /* msec */, + .poll_time = 20 /* msec */, + .flags = GPIOKPF_DRIVE_INACTIVE, +}; + +void keypad_init(void) +{ + gpio_keypad_init(&halibut_keypad_info); +} diff --git a/lk/target/msm7627_surf/rules.mk b/lk/target/msm7627_surf/rules.mk new file mode 100644 index 0000000..701feaa --- /dev/null +++ b/lk/target/msm7627_surf/rules.mk @@ -0,0 +1,40 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared + +PLATFORM := msm7k + +MEMBASE := 0x00000000 # SMI +MEMSIZE := 0x00100000 # 1MB + +BASE_ADDR := 0x00200000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00008000 +RAMDISK_ADDR := BASE_ADDR+0x01000000 +SCRATCH_ADDR := BASE_ADDR+0x04000000 + +KEYS_USE_GPIO_KEYPAD := 1 + +DEFINES += DISPLAY_TYPE_MDDI=0 +DEFINES += DISPLAY_TYPE_LCDC=1 +DEFINES += DISPLAY_SPLASH_SCREEN=1 + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + MEMBASE=$(MEMBASE) \ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/keypad.o \ + $(LOCAL_DIR)/atags.o diff --git a/lk/target/msm7627_surf/tools/makefile b/lk/target/msm7627_surf/tools/makefile new file mode 100644 index 0000000..09bc134 --- /dev/null +++ b/lk/target/msm7627_surf/tools/makefile @@ -0,0 +1,38 @@ +#Makefile to generate appsboot.mbn + +ifeq ($(BOOTLOADER_OUT),.) +APPSBOOTHEADER_DIR := $(BUILDDIR) +else +APPSBOOTHEADER_DIR := $(BOOTLOADER_OUT)/../../ +endif + +SRC_DIR := target/$(TARGET)/tools +COMPILER := gcc + +ifeq ($(EMMC_BOOT), 1) + APPSBOOTHDR_FILES := EMMCBOOT.MBN emmc_appsboothd.mbn +else + ifeq ($(BUILD_NANDWRITE), 1) + APPSBOOTHDR_FILES := + else + APPSBOOTHDR_FILES := appsboot.mbn appsboothd.mbn + endif +endif + +APPSBOOTHEADER: $(APPSBOOTHDR_FILES) + +appsboot.mbn: $(OUTBIN) + cp -f $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboot.mbn + +appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +EMMCBOOT.MBN: $(OUTBIN) + cp -f $(OUTBIN) $(APPSBOOTHEADER_DIR)/EMMCBOOT.MBN + cp -f $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboot.mbn + +emmc_appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn unified-boot + +mkheader: $(SRC_DIR)/mkheader.c + ${COMPILER} $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader diff --git a/lk/target/msm7627_surf/tools/mkheader.c b/lk/target/msm7627_surf/tools/mkheader.c new file mode 100644 index 0000000..2bd3479 --- /dev/null +++ b/lk/target/msm7627_surf/tools/mkheader.c @@ -0,0 +1,87 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + struct stat s; + unsigned size, base; + int unified_boot = 0; + unsigned unified_boot_magic[20]; + unsigned non_unified_boot_magic[10]; + unsigned magic_len = 0; + unsigned *magic; + int fd; + + if(argc < 3) { + fprintf(stderr,"usage: mkheader \n"); + return -1; + } + + if (argc == 4) { + if(!strcmp("unified-boot",argv[3])) { + unified_boot = 1; + } + } + + if(stat(argv[1], &s)) { + perror("cannot stat binary"); + return -1; + } + + if(unified_boot) { + magic = unified_boot_magic; + magic_len = sizeof(unified_boot_magic); + } else { + magic = non_unified_boot_magic; + magic_len = sizeof(non_unified_boot_magic); + } + + size = s.st_size; + base = 0; + + magic[0] = 0x00000005; /* appsbl */ + magic[1] = 0x00000002; /* nand */ + magic[2] = 0x00000000; + magic[3] = base; + magic[4] = size; + magic[5] = size; + magic[6] = size + base; + magic[7] = 0x00000000; + magic[8] = size + base; + magic[9] = 0x00000000; + + if (unified_boot == 1) + { + magic[10] = 0x33836685; /* cookie magic number */ + magic[11] = 0x00000001; /* cookie version */ + magic[12] = 0x00000002; /* file formats */ + magic[13] = 0x00000000; + magic[14] = 0x00000000; /* not setting size for boot.img */ + magic[15] = 0x00000000; + magic[16] = 0x00000000; + magic[17] = 0x00000000; + magic[18] = 0x00000000; + magic[19] = 0x00000000; + } + + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd < 0) { + perror("cannot open header for writing"); + return -1; + } + if(write(fd, magic, magic_len) != magic_len) { + perror("cannot write header"); + close(fd); + unlink(argv[2]); + return -1; + } + close(fd); + + return 0; +} diff --git a/lk/target/msm7630_1x/atags.c b/lk/target/msm7630_1x/atags.c new file mode 100644 index 0000000..e24dafd --- /dev/null +++ b/lk/target/msm7630_1x/atags.c @@ -0,0 +1,119 @@ +/* Copyright (c) 2009, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#define EBI1_ADDR_128M 0x08000000 +#define SIZE_256M 0x10000000 +#define SIZE_128M 0x08000000 +#define SIZE_1M 0x00100000 + +static int scratch_addr = -1; +int smem_ram_ptable_init(struct smem_ram_ptable *); + +unsigned* target_atag_mem(unsigned* ptr) +{ + struct smem_ram_ptable ram_ptable; + unsigned i = 0; + + if (smem_ram_ptable_init(&ram_ptable)) + { + for (i = 0; i < ram_ptable.len; i++) + { + if ((ram_ptable.parts[i].attr == READWRITE) + && (ram_ptable.parts[i].domain == APPS_DOMAIN) + && (ram_ptable.parts[i].start != 0x0) + && (!(ram_ptable.parts[i].size < SIZE_1M))) + { + /* ATAG_MEM */ + *ptr++ = 4; + // Tag EBI-1 memory as unstable. + if(ram_ptable.parts[i].category == EBI1_CS0) { + // if EBI-1 CS-0 is 256Mb then this is a 2x256 target and + // the kernel can reserve this mem region as unstable. + // This memory region can be activated when the kernel + // receives a request from Android init scripts. + if(ram_ptable.parts[i].size == SIZE_256M) + *ptr++ = 0x5441000A; //Deep-Power-Down Tag. + + //if EBI-1 CS-0 s 128Mb then this is a 2x128 target. + //Android + Kernel + PMEM regions account for more than + //128Mb and the target will not be able to boot with just + //one memory bank active and the second memory bank is reserved. + //In the case of 2x128 the tag is set to SelfRefresh Only. + else if(ram_ptable.parts[i].size == SIZE_128M) + *ptr++ = 0x5441000B; //Self-Refresh Tag. + } + else + *ptr++ = 0x54410002; + + *ptr++ = ram_ptable.parts[i].size; + *ptr++ = ram_ptable.parts[i].start; + } + } + } + else + { + dprintf(CRITICAL, "ERROR: Unable to read RAM partition\n"); + ASSERT(0); + } + + return ptr; +} + +void *target_get_scratch_address(void) +{ + struct smem_ram_ptable ram_ptable; + unsigned i = 0; + + if (smem_ram_ptable_init(&ram_ptable)) + { + for (i = 0; i < ram_ptable.len; i++) + { + if ((ram_ptable.parts[i].attr == READWRITE) + && (ram_ptable.parts[i].domain == APPS_DOMAIN) + && (ram_ptable.parts[i].start != 0x0)) + { + if (ram_ptable.parts[i].size >= FASTBOOT_BUF_SIZE) + { + scratch_addr = ram_ptable.parts[i].start; + break; + } + } + } + } + else + { + dprintf(CRITICAL, "ERROR: Unable to read RAM partition\n"); + ASSERT(0); + } + + return (void *)((scratch_addr == -1) ? EBI1_ADDR_128M : scratch_addr); +} diff --git a/lk/target/msm7630_1x/include/target/display.h b/lk/target/msm7630_1x/include/target/display.h new file mode 100644 index 0000000..69cd4ac --- /dev/null +++ b/lk/target/msm7630_1x/include/target/display.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _TARGET_MSM7630_SURF_DISPLAY_H +#define _TARGET_MSM7630_SURF_DISPLAY_H + +#define TARGET_XRES 480 +#define TARGET_YRES 800 + +#define LCDC_FB_WIDTH 480 +#define LCDC_FB_HEIGHT 800 + +#define LCDC_HSYNC_PULSE_WIDTH_DCLK 8 +#define LCDC_HSYNC_BACK_PORCH_DCLK 184 +#define LCDC_HSYNC_FRONT_PORCH_DCLK 4 +#define LCDC_HSYNC_SKEW_DCLK 0 + +#define LCDC_VSYNC_PULSE_WIDTH_LINES 1 +#define LCDC_VSYNC_BACK_PORCH_LINES 2 +#define LCDC_VSYNC_FRONT_PORCH_LINES 3 + +#endif diff --git a/lk/target/msm7630_1x/init.c b/lk/target/msm7630_1x/init.c new file mode 100644 index 0000000..cc87cd2 --- /dev/null +++ b/lk/target/msm7630_1x/init.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include +#include + +#define LINUX_MACHTYPE_7x30_SURF 2679 +#define LINUX_MACHTYPE_7x30_FFA 2707 +#define LINUX_MACHTYPE_7x30_FLUID 2741 +#define LINUX_MACHTYPE_8x55_SURF 2768 +#define LINUX_MACHTYPE_8x55_FFA 2769 + +#define MSM8255_ID 74 +#define MSM8655_ID 75 +#define APQ8055_ID 85 + +#define VARIABLE_LENGTH 0x10101010 +#define DIFF_START_ADDR 0xF0F0F0F0 +#define NUM_PAGES_PER_BLOCK 0x40 + +static struct ptable flash_ptable; +static int hw_platform_type = -1; + +/* for these partitions, start will be offset by either what we get from + * smem, or from the above offset if smem is not useful. Also, we should + * probably have smem_ptable code populate our flash_ptable. + * + * When smem provides us with a full partition table, we can get rid of + * this altogether. + * + */ +static struct ptentry board_part_list[] = { + { + .start = 0, + .length = 20 /* 5MB */, + .name = "boot", + }, + { + .start = 20, + .length = 480 /* 120MB */, + .name = "system", + }, + { + .start = 500, + .length = 120 /* 30MB */, + .name = "cache", + }, + { + .start = 620, + .length = 4, /* 1MB */ + .name = "misc", + }, + { + .start = 624, + .length = VARIABLE_LENGTH, + .name = "userdata", + }, + { + .start = DIFF_START_ADDR, + .length = 12 /* 3MB */, + .name = "persist", + }, + { + .start = DIFF_START_ADDR, + .length = 20 /* 5MB */, + .name = "recovery", + }, +}; +static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry); + +void smem_ptable_init(void); +unsigned smem_get_apps_flash_start(void); + +void keypad_init(void); + +static int emmc_boot = -1; /* set to uninitialized */ +int target_is_emmc_boot(void); +static int platform_version = -1; +static int target_msm_id = -1; + +void target_init(void) +{ + unsigned offset; + struct flash_info *flash_info; + unsigned total_num_of_blocks; + bool start_addr_changed = false; + unsigned next_ptr_start_adr = 0; + int i; + + dprintf(INFO, "target_init()\n"); + +#if (!ENABLE_NANDWRITE) + keys_init(); + keypad_init(); +#endif + + if (target_is_emmc_boot()) + return; + + ptable_init(&flash_ptable); + smem_ptable_init(); + + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + + offset = smem_get_apps_flash_start(); + if (offset == 0xffffffff) + while(1); + + total_num_of_blocks = flash_info->num_blocks; + + for (i = 0; i < num_parts; i++) { + struct ptentry *ptn = &board_part_list[i]; + unsigned len = ptn->length; + + if(len == VARIABLE_LENGTH) + { + start_addr_changed = true; + unsigned length_for_prt = 0; + unsigned j; + for (j = i+1; j < num_parts; j++) + { + struct ptentry *temp_ptn = &board_part_list[j]; + ASSERT(temp_ptn->length != VARIABLE_LENGTH); + length_for_prt += temp_ptn->length; + } + len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); + ASSERT(len >= 0); + next_ptr_start_adr = ptn->start + len; + } + if((ptn->start == DIFF_START_ADDR) && (start_addr_changed)) + { + ASSERT(next_ptr_start_adr); + ptn->start = next_ptr_start_adr; + next_ptr_start_adr = ptn->start + ptn->length; + } + ptable_add(&flash_ptable, ptn->name, offset + ptn->start, + len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); + } + + smem_add_modem_partitions(&flash_ptable); + + ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +int target_platform_version(void) +{ + return platform_version; +} + +int target_is_msm8x55(void) +{ + if ((target_msm_id == MSM8255_ID) || + (target_msm_id == MSM8655_ID) || + (target_msm_id == APQ8055_ID)) + return 1; + else + return 0; +} + +unsigned board_machtype(void) +{ + struct smem_board_info_v4 board_info_v4; + unsigned int board_info_len = 0; + enum platform platform_type = 0; + unsigned smem_status; + unsigned format = 0; + if(hw_platform_type != -1) + return hw_platform_type; + + smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, + &format, sizeof(format), 0); + if(!smem_status) + { + if ((format == 3) || (format == 4)) + { + if (format == 4) + board_info_len = sizeof(board_info_v4); + else + board_info_len = sizeof(board_info_v4.board_info_v3); + + smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, + &board_info_v4, board_info_len); + if(!smem_status) + { + if(format == 4) + platform_version = board_info_v4.platform_version; + + platform_type = board_info_v4.board_info_v3.hw_platform; + target_msm_id = board_info_v4.board_info_v3.msm_id; + switch (platform_type) + { + case HW_PLATFORM_SURF: + hw_platform_type = ((target_is_msm8x55()) ? + LINUX_MACHTYPE_8x55_SURF : LINUX_MACHTYPE_7x30_SURF); break; + case HW_PLATFORM_FFA: + hw_platform_type = ((target_is_msm8x55()) ? + LINUX_MACHTYPE_8x55_FFA : LINUX_MACHTYPE_7x30_FFA); break; + case HW_PLATFORM_FLUID: + hw_platform_type = LINUX_MACHTYPE_7x30_FLUID; break; + default: + hw_platform_type = ((target_is_msm8x55()) ? + LINUX_MACHTYPE_8x55_SURF : LINUX_MACHTYPE_7x30_SURF); break; + } + return hw_platform_type; + } + } + } + hw_platform_type = LINUX_MACHTYPE_7x30_SURF; + return hw_platform_type; +} + +void reboot_device(unsigned reboot_reason) +{ + reboot(reboot_reason); +} + +unsigned check_reboot_mode(void) +{ + unsigned mode[2] = {0, 0}; + unsigned int mode_len = sizeof(mode); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE, + &mode, mode_len ); + if(smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n"); + return 0; + } + return mode[0]; +} + +void target_battery_charging_enable(unsigned enable, unsigned disconnect) +{ +} diff --git a/lk/target/msm7630_1x/keypad.c b/lk/target/msm7630_1x/keypad.c new file mode 100644 index 0000000..7261126 --- /dev/null +++ b/lk/target/msm7630_1x/keypad.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) +#define BITS_IN_ELEMENT(x) (sizeof(x)[0] * 8) + +static unsigned char qwerty_keys_old[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static unsigned char qwerty_keys_new[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define KEYMAP_INDEX(row, col) (row)* BITS_IN_ELEMENT(qwerty_keys_new) + (col) + +static unsigned int qwerty_keymap[] = { + [KEYMAP_INDEX(4, 2)] = KEY_BACK, /* -L on SURF & FFA */ + [KEYMAP_INDEX(3, 4)] = KEY_HOME, /* +R on SURF & FFA */ + [KEYMAP_INDEX(1, 4)] = KEY_CLEAR, /* '-' of left side switch on FLUID */ +}; + +static struct qwerty_keypad_info qwerty_keypad = { + .keymap = qwerty_keymap, + .old_keys = qwerty_keys_old, + .rec_keys = qwerty_keys_new, + .rows = 5, + .columns = 5, + .num_of_reads = 6, + .rd_func = &i2c_ssbi_read_bytes, + .wr_func = &i2c_ssbi_write_bytes, + .settle_time = 5 /* msec */, + .poll_time = 20 /* msec */, +}; + +void keypad_init(void) +{ + ssbi_keypad_init(&qwerty_keypad); +} diff --git a/lk/target/msm7630_1x/panel.c b/lk/target/msm7630_1x/panel.c new file mode 100644 index 0000000..c2b56a1 --- /dev/null +++ b/lk/target/msm7630_1x/panel.c @@ -0,0 +1,471 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#define MDDI_CLIENT_CORE_BASE 0x108000 +#define LCD_CONTROL_BLOCK_BASE 0x110000 +#define SPI_BLOCK_BASE 0x120000 +#define I2C_BLOCK_BASE 0x130000 +#define PWM_BLOCK_BASE 0x140000 +#define GPIO_BLOCK_BASE 0x150000 +#define SYSTEM_BLOCK1_BASE 0x160000 +#define SYSTEM_BLOCK2_BASE 0x170000 + + +#define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00) +#define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04) +#define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08) +#define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C) +#define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10) +#define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14) +#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18) +#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C) +#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20) +#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24) +#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28) +#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C) +#define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30) +#define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34) +#define INTMONI (MDDI_CLIENT_CORE_BASE|0x38) +#define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C) +#define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40) +#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44) +#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48) +#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C) +#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50) +#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54) + + +#define SRST (LCD_CONTROL_BLOCK_BASE|0x00) +#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04) +#define START (LCD_CONTROL_BLOCK_BASE|0x08) +#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C) +#define CMN (LCD_CONTROL_BLOCK_BASE|0x10) +#define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14) +#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18) +#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C) +#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20) +#define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24) +#define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28) + +#define PXL (LCD_CONTROL_BLOCK_BASE|0x30) +#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34) +#define HSW (LCD_CONTROL_BLOCK_BASE|0x38) +#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C) +#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40) +#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44) +#define VSW (LCD_CONTROL_BLOCK_BASE|0x48) +#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C) +#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50) +#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54) +#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58) +#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C) +#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60) +#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64) +#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68) +#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C) +#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70) +#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74) +#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78) +#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C) +#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80) +#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84) +#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88) +#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C) + +#define MONI (LCD_CONTROL_BLOCK_BASE|0xB0) + +#define Current (LCD_CONTROL_BLOCK_BASE|0xC0) +#define LCD (LCD_CONTROL_BLOCK_BASE|0xC4) +#define COMMAND (LCD_CONTROL_BLOCK_BASE|0xC8) + + +#define SSICTL (SPI_BLOCK_BASE|0x00) +#define SSITIME (SPI_BLOCK_BASE|0x04) +#define SSITX (SPI_BLOCK_BASE|0x08) +#define SSIRX (SPI_BLOCK_BASE|0x0C) +#define SSIINTC (SPI_BLOCK_BASE|0x10) +#define SSIINTS (SPI_BLOCK_BASE|0x14) +#define SSIDBG1 (SPI_BLOCK_BASE|0x18) +#define SSIDBG2 (SPI_BLOCK_BASE|0x1C) +#define SSIID (SPI_BLOCK_BASE|0x20) + + +#define I2CSETUP (I2C_BLOCK_BASE|0x00) +#define I2CCTRL (I2C_BLOCK_BASE|0x04) + + +#define TIMER0LOAD (PWM_BLOCK_BASE|0x00) +#define TIMER0VALUE (PWM_BLOCK_BASE|0x04) +#define TIMER0CONTROL (PWM_BLOCK_BASE|0x08) +#define TIMER0INTCLR (PWM_BLOCK_BASE|0x0C) +#define TIMER0RIS (PWM_BLOCK_BASE|0x10) +#define TIMER0MIS (PWM_BLOCK_BASE|0x14) +#define TIMER0BGLOAD (PWM_BLOCK_BASE|0x18) +#define PWM0OFF (PWM_BLOCK_BASE|0x1C) +#define TIMER1LOAD (PWM_BLOCK_BASE|0x20) +#define TIMER1VALUE (PWM_BLOCK_BASE|0x24) +#define TIMER1CONTROL (PWM_BLOCK_BASE|0x28) +#define TIMER1INTCLR (PWM_BLOCK_BASE|0x2C) +#define TIMER1RIS (PWM_BLOCK_BASE|0x30) +#define TIMER1MIS (PWM_BLOCK_BASE|0x34) +#define TIMER1BGLOAD (PWM_BLOCK_BASE|0x38) +#define PWM1OFF (PWM_BLOCK_BASE|0x3C) +#define TIMERITCR (PWM_BLOCK_BASE|0x60) +#define TIMERITOP (PWM_BLOCK_BASE|0x64) +#define PWMCR (PWM_BLOCK_BASE|0x68) +#define PWMID (PWM_BLOCK_BASE|0x6C) +#define PWMMON (PWM_BLOCK_BASE|0x70) + + +#define GPIODATA (GPIO_BLOCK_BASE|0x00) +#define GPIODIR (GPIO_BLOCK_BASE|0x04) +#define GPIOIS (GPIO_BLOCK_BASE|0x08) +#define GPIOIBE (GPIO_BLOCK_BASE|0x0C) +#define GPIOIEV (GPIO_BLOCK_BASE|0x10) +#define GPIOIE (GPIO_BLOCK_BASE|0x14) +#define GPIORIS (GPIO_BLOCK_BASE|0x18) +#define GPIOMIS (GPIO_BLOCK_BASE|0x1C) +#define GPIOIC (GPIO_BLOCK_BASE|0x20) +#define GPIOOMS (GPIO_BLOCK_BASE|0x24) +#define GPIOPC (GPIO_BLOCK_BASE|0x28) + +#define GPIOID (GPIO_BLOCK_BASE|0x30) + + +#define WKREQ (SYSTEM_BLOCK1_BASE|0x00) +#define CLKENB (SYSTEM_BLOCK1_BASE|0x04) +#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08) +#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C) +#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00) + +struct init_table { + unsigned int reg; + unsigned int val; +}; + +static struct init_table toshiba_480x640_init_table[] = { + { DPSET0, 0x4BEC0066 }, // # MDC.DPSET0 # Setup DPLL parameters + { DPSET1, 0x00000113 }, // # MDC.DPSET1 + { DPSUS, 0x00000000 }, // # MDC.DPSUS # Set DPLL oscillation enable + { DPRUN, 0x00000001 }, // # MDC.DPRUN # Release reset signal for DPLL + { 0, 14 }, // wait_ms(14); + { SYSCKENA, 0x00000001 }, // # MDC.SYSCKENA # Enable system clock output + { CLKENB, 0x000000EF }, // # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) + { GPIO_BLOCK_BASE, 0x03FF0000 }, // # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 + { GPIODIR, 0x0000024D }, // # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) + { SYSTEM_BLOCK2_BASE, 0x00000173 }, // # SYS.GPIOSEL # GPIO port multiplexing control + { GPIOPC, 0x03C300C0 }, // # GPI .GPIOPC # GPIO2,3 PD cut + { SYSTEM_BLOCK1_BASE, 0x00000000 }, // # SYS.WKREQ # Wake-up request event is VSYNC alignment + { GPIOIS, 0x00000000 }, // # GPI .GPIOIS # Set interrupt sense of GPIO + { GPIOIEV, 0x00000001 }, // # GPI .GPIOIEV # Set interrupt event of GPIO + { GPIOIC, 0x000003FF }, // # GPI .GPIOIC # GPIO interrupt clear + { GPIO_BLOCK_BASE, 0x00060006 }, // # GPI .GPIODATA # Release LCDD reset + { GPIO_BLOCK_BASE, 0x00080008 }, // # GPI .GPIODATA # eDRAM VD supply + { GPIO_BLOCK_BASE, 0x02000200 }, // # GPI .GPIODATA # TEST LED ON + { DRAMPWR, 0x00000001 }, // # SYS.DRAMPWR # eDRAM power up + { TIMER0CONTROL, 0x00000060 }, // # PWM.Timer0Control # PWM0 output stop + { PWM_BLOCK_BASE, 0x00001388 }, // # PWM.Timer0Load # PWM0 10kHz , Duty 99 (BackLight OFF) + //{PWM0OFF, 0x00000001 }, // # PWM.PWM0OFF +#if 0 + { PWM0OFF, 0x00001387 }, // SURF 100% backlight + { PWM0OFF, 0x00000000 }, // FFA 100% backlight +#endif + { PWM0OFF, 0x000009C3 }, // 50% BL + { TIMER1CONTROL, 0x00000060 }, // # PWM.Timer1Control # PWM1 output stop + { TIMER1LOAD, 0x00001388 }, // # PWM.Timer1Load # PWM1 10kHz , Duty 99 (BackLight OFF) + //{PWM1OFF, 0x00000001 }, // # PWM.PWM1OFF + { PWM1OFF, 0x00001387 }, + { TIMER0CONTROL, 0x000000E0 }, // # PWM.Timer0Control # PWM0 output start + { TIMER1CONTROL, 0x000000E0 }, // # PWM.Timer1Control # PWM1 output start + { PWMCR, 0x00000003 }, // # PWM.PWMCR # PWM output enable + { 0, 1 }, // wait_ms(1); + { SPI_BLOCK_BASE, 0x00000799 }, // # SPI .SSICTL # SPI operation mode setting + { SSITIME, 0x00000100 }, // # SPI .SSITIME # SPI serial interface timing setting + { SPI_BLOCK_BASE, 0x0000079b }, // # SPI .SSICTL # Set SPI active mode + + { SSITX, 0x00000000 }, // # SPI.SSITX # Release from Deep Stanby mode + { 0, 1 }, // wait_ms(1); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 1 }, // wait_ms(1); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 1 }, // wait_ms(1); + { SSITX, 0x000800BA }, // # SPI.SSITX *NOTE 1 # Command setting of SPI block + { SSITX, 0x00000111 }, // # Display mode setup(1) : Normaly Black + { SSITX, 0x00080036 }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Memory access control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BB }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Display mode setup(2) + { SSITX, 0x0008003A }, // # Command setting of SPI block + { SSITX, 0x00000160 }, // # RGB Interface data format + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BF }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Drivnig method + { SSITX, 0x000800B1 }, // # Command setting of SPI block + { SSITX, 0x0000015D }, // # Booster operation setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B2 }, // # Command setting of SPI block + { SSITX, 0x00000133 }, // # Booster mode setup + { SSITX, 0x000800B3 }, // # Command setting of SPI block + { SSITX, 0x00000122 }, // # Booster frequencies setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B4 }, // # Command setting of SPI block + { SSITX, 0x00000102 }, // # OP-amp capability/System clock freq. division setup + { SSITX, 0x000800B5 }, // # Command setting of SPI block + { SSITX, 0x0000011F }, // # VCS Voltage adjustment (1C->1F for Rev 2) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B6 }, // # Command setting of SPI block + { SSITX, 0x00000128 }, // # VCOM Voltage adjustment + { SSITX, 0x000800B7 }, // # Command setting of SPI block + { SSITX, 0x00000103 }, // # Configure an external display signal + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B9 }, // # Command setting of SPI block + { SSITX, 0x00000120 }, // # DCCK/DCEV timing setup + { SSITX, 0x000800BD }, // # Command setting of SPI block + { SSITX, 0x00000102 }, // # ASW signal control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BE }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Dummy display (white/black) count setup for QUAD Data operation + { SSITX, 0x000800C0 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (A) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C1 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (B) + { SSITX, 0x000800C2 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (C) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C3 }, // # Command setting of SPI block + { SSITX, 0x0008010A }, // # wait_ms(-in line clock count setup (D) + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C4 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # Seep-in line clock count setup (E) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C5 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # wait_ms(-in line clock count setup (F) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C6 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # wait_ms(-in line clock setup (G) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C7 }, // # Command setting of SPI block + { SSITX, 0x00080133 }, // # Gamma 1 fine tuning (1) + { SSITX, 0x00000143 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C8 }, // # Command setting of SPI block + { SSITX, 0x00000144 }, // # Gamma 1 fine tuning (2) + { SSITX, 0x000800C9 }, // # Command setting of SPI block + { SSITX, 0x00000133 }, // # Gamma 1 inclination adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CA }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Gamma 1 blue offset adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800EC }, // # Command setting of SPI block + { SSITX, 0x00080102 }, // # Total number of horizontal clock cycles (1) [PCLK Sync. VGA setting] + { SSITX, 0x00000118 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CF }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Blanking period control (1) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D0 }, // # Command setting of SPI block + { SSITX, 0x00080110 }, // # Blanking period control (2) [PCLK Sync. Table1 for VGA] + { SSITX, 0x00000104 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D1 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # CKV timing control on/off [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D2 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV1,2 timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000013A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D3 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # OEV timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000013A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D4 }, // # Command setting of SPI block + { SSITX, 0x00080124 }, // # ASW timing control (1) [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000016E }, // + { 0, 1 }, // wait_ms(1); // # Wait SPI fifo empty + { SSITX, 0x000800D5 }, // # Command setting of SPI block + { SSITX, 0x00000124 }, // # ASW timing control (2) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800ED }, // # Command setting of SPI block + { SSITX, 0x00080101 }, // # Total number of horizontal clock cycles (2) [PCLK Sync. Table1 for QVGA ] + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D6 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Blanking period control (1) [PCLK Sync. Table2 for QVGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D7 }, // # Command setting of SPI block + { SSITX, 0x00080110 }, // # Blanking period control (2) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D8 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # CKV timing control on/off [PCLK Sync. Table2 for QVGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D9 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV1,2 timing control [PCLK Sync. Table2 for QVGA] + { SSITX, 0x00000114 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800DE }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # OEV timing control [PCLK Sync. Table2 for QVGA] + { SSITX, 0x00000114 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800DF }, // # Command setting of SPI block + { SSITX, 0x00080112 }, // # ASW timing control (1) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x0000013F }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E0 }, // # Command setting of SPI block + { SSITX, 0x0000010B }, // # ASW timing control (2) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x000800E2 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Built-in oscillator frequency division setup [Frequency division ratio : 2 (60Hq) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E3 }, // # Command setting of SPI block + { SSITX, 0x00000136 }, // # Built-in oscillator clock count setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E4 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV timing control for using build-in osc + { SSITX, 0x00000103 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E5 }, // # Command setting of SPI block + { SSITX, 0x00080102 }, // # OEV timing control for using build-in osc + { SSITX, 0x00000104 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E6 }, // # Command setting of SPI block + { SSITX, 0x00000103 }, // # DCEV timing control for using build-in osc + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E7 }, // # Command setting of SPI block + { SSITX, 0x00080104 }, // # ASW timing setup for using build-in osc(1) + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E8 }, // # Command setting of SPI block + { SSITX, 0x00000104 }, // # ASW timing setup for using build-in osc(2) + + + { CLKENB, 0x000001EF }, // # SYS.CLKENB # DCLK enable + { START, 0x00000000 }, // # LCD.START # LCDC wait_ms( mode + { WRSTB, 0x0000003F }, // # LCD.WRSTB # write_client_reg( strobe + { RDSTB, 0x00000432 }, // # LCD.RDSTB # Read strobe + { PORT_ENB, 0x00000002 }, // # LCD.PORT_ENB # Asynchronous port enable + { VSYNIF, 0x00000000 }, // # LCD.VSYNCIF # VSYNC I/F mode set + { ASY_DATA, 0x80000000 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00000001 }, // # Oscillator start + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + { 0, 10 }, // wait_ms(10); + { ASY_DATA, 0x80000000 }, // # LCD.ASY_DATx # DUMMY write_client_reg(@*NOTE2 + { ASY_DATB, 0x80000000 }, // + { ASY_DATC, 0x80000000 }, // + { ASY_DATD, 0x80000000 }, // + { ASY_CMDSET, 0x00000009 }, // # LCD.ASY_CMDSET + { ASY_CMDSET, 0x00000008 }, // # LCD.ASY_CMDSET + { ASY_DATA, 0x80000007 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00004005 }, // # LCD driver control + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + { 0, 20 }, // wait_ms(20); + { ASY_DATA, 0x80000059 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00000000 }, // # LTPS I/F control + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + + { VSYNIF, 0x00000001 }, // # LCD.VSYNCIF # VSYNC I/F mode OFF + { PORT_ENB, 0x00000001 }, // # LCD.PORT_ENB # SYNC I/F output select + + /******************************/ + + { VSYNIF, 0x00000001 }, // VSYNC I/F mode OFF + { PORT_ENB, 0x00000001 }, // SYNC I/F mode ON + + { BITMAP1, 0x01E000F0 }, // MDC.BITMAP2 ); // Setup of PITCH size to Frame buffer1 + { BITMAP2, 0x01E000F0 }, // MDC.BITMAP3 ); // Setup of PITCH size to Frame buffer2 + { BITMAP3, 0x01E000F0 }, // MDC.BITMAP4 ); // Setup of PITCH size to Frame buffer3 + { BITMAP4, 0x00DC00B0 }, // MDC.BITMAP5 ); // Setup of PITCH size to Frame buffer4 + { CLKENB, 0x000001EF }, // SYS.CLKENB ); // DCLK supply + { PORT_ENB, 0x00000001 }, // LCD.PORT_ENB ); // Synchronous port enable + { PORT, 0x00000004 }, // LCD.PORT ); // Polarity of DE is set to high active + { PXL, 0x00000002 }, // LCD.PXL ); // ACTMODE 2 set (1st frame black data output) + { MPLFBUF, 0x00000000 }, // LCD.MPLFBUF ); // Select the reading buffer + { HCYCLE, 0x0000010b }, // LCD.HCYCLE ); // Setup to VGA size + { HSW, 0x00000003 }, // LCD.HSW + { HDE_START, 0x00000007 }, // LCD.HDE_START + { HDE_SIZE, 0x000000EF }, // LCD.HDE_SIZE + { VCYCLE, 0x00000285 }, // LCD.VCYCLE + { VSW, 0x00000001 }, // LCD.VSW + { VDE_START, 0x00000003 }, // LCD.VDE_START + { VDE_SIZE, 0x0000027F }, // LCD.VDE_SIZE + + { START, 0x00000001 }, // LCD.START ); // LCDC - Pixel data transfer start + + { 0, 10 }, // wait_ms( 10 ); + { SSITX, 0x000800BC }, // SPI.SSITX ); // Command setting of SPI block + { SSITX, 0x00000180 }, // Display data setup + { SSITX, 0x0008003B }, // Command setting of SPI block + { SSITX, 0x00000100 }, // Quad Data configuration - VGA + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B0 }, // Command setting of SPI block + { SSITX, 0x00000116 }, // Power supply ON/OFF control + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B8 }, // Command setting of SPI block + { SSITX, 0x000801FF }, // Output control + { SSITX, 0x000001F5 }, + { 0, 1 }, // wait_ms( 1); // Wait SPI fifo empty + { SSITX, 0x00000011 }, // wait_ms(-out (Command only) + { SSITX, 0x00000029 }, // Display on (Command only) + + { SYSTEM_BLOCK1_BASE, 0x00000002 }, // # wakeREQ -> GPIO + + { 0, 0 } +}; + +static void _panel_init(struct init_table *init_table) +{ + unsigned n; + + dprintf(INFO, "panel_init()\n"); + + n = 0; + while (init_table[n].reg != 0 || init_table[n].val != 0) { + if (init_table[n].reg != 0) + mddi_remote_write(init_table[n].val, init_table[n].reg); + else + thread_sleep(init_table[n].val);//mdelay(init_table[n].val); + n++; + } + + dprintf(INFO, "panel_init() done\n"); +} + +void panel_init(struct mddi_client_caps *client_caps) +{ + switch(client_caps->manufacturer_name) { + case 0xd263: // Toshiba + dprintf(INFO, "Found Toshiba panel\n"); + _panel_init(toshiba_480x640_init_table); + break; + case 0x4474: //?? + if (client_caps->product_code == 0xc065) + dprintf(INFO, "Found WVGA panel\n"); + break; + } +} + +void panel_poweron(void) +{ + gpio_set(88, 0); + gpio_config(88, GPIO_OUTPUT); + thread_sleep(1); //udelay(10); + gpio_set(88, 1); + thread_sleep(10); //mdelay(10); + + //mdelay(1000); // uncomment for second stage boot +} + +void panel_backlight(int on) +{} diff --git a/lk/target/msm7630_1x/rules.mk b/lk/target/msm7630_1x/rules.mk new file mode 100644 index 0000000..a5647aa --- /dev/null +++ b/lk/target/msm7630_1x/rules.mk @@ -0,0 +1,40 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared + +PLATFORM := msm7x30 + +MEMBASE := 0x00000000 # EBI +MEMSIZE := 0x00100000 # 1MB + +BASE_ADDR := 0x00200000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00008000 +RAMDISK_ADDR := BASE_ADDR+0x01000000 +SCRATCH_ADDR := 0x08008000 +FASTBOOT_BUF_SIZE := 0x07800000 + +KEYS_USE_GPIO_KEYPAD := 1 + +DEFINES += DISPLAY_TYPE_MDDI=1 + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + MEMBASE=$(MEMBASE) \ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) \ + FASTBOOT_BUF_SIZE=$(FASTBOOT_BUF_SIZE) + + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/atags.o \ + $(LOCAL_DIR)/keypad.o diff --git a/lk/target/msm7630_1x/tools/makefile b/lk/target/msm7630_1x/tools/makefile new file mode 100644 index 0000000..3c0a451 --- /dev/null +++ b/lk/target/msm7630_1x/tools/makefile @@ -0,0 +1,41 @@ +#Makefile to generate appsboot.mbn + +ifeq ($(BOOTLOADER_OUT),.) +APPSBOOTHEADER_DIR := $(BUILDDIR) +else +APPSBOOTHEADER_DIR := $(BOOTLOADER_OUT)/../../ +endif + +SRC_DIR := target/$(TARGET)/tools +COMPILER := gcc + +ifeq ($(EMMC_BOOT), 1) + APPSBOOTHDR_FILES := EMMCBOOT.MBN +else + ifeq ($(BUILD_NANDWRITE), 1) + APPSBOOTHDR_FILES := + else + APPSBOOTHDR_FILES := appsboot.mbn + endif +endif + +APPSBOOTHEADER: $(APPSBOOTHDR_FILES) + + +appsboot.mbn: appsboothd.mbn $(OUTBIN) + cat $(APPSBOOTHEADER_DIR)/appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/appsboot.mbn + rm -f $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +EMMCBOOT.MBN: emmc_appsboothd.mbn $(OUTBIN) + cat $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/EMMCBOOT.MBN + rm -f $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn + +emmc_appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn unified-boot + +mkheader: $(SRC_DIR)/mkheader.c + ${COMPILER} -DMEMBASE=$(MEMBASE) $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader + diff --git a/lk/target/msm7630_1x/tools/mkheader.c b/lk/target/msm7630_1x/tools/mkheader.c new file mode 100644 index 0000000..8701007 --- /dev/null +++ b/lk/target/msm7630_1x/tools/mkheader.c @@ -0,0 +1,91 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + struct stat s; + unsigned size, base; + int unified_boot = 0; + unsigned unified_boot_magic[20]; + unsigned non_unified_boot_magic[10]; + unsigned magic_len = 0; + unsigned *magic; + int fd; + + if(argc < 3) { + fprintf(stderr,"usage: mkheader \n"); + return -1; + } + + if (argc == 4) { + if(!strcmp("unified-boot",argv[3])) { + unified_boot = 1; + } + } + + if(stat(argv[1], &s)) { + perror("cannot stat binary"); + return -1; + } + + if(unified_boot) { + magic = unified_boot_magic; + magic_len = sizeof(unified_boot_magic); + } else { + magic = non_unified_boot_magic; + magic_len = sizeof(non_unified_boot_magic); + } + + size = s.st_size; +#if MEMBASE + base = MEMBASE; +#else + base = 0; +#endif + + magic[0] = 0x00000005; /* appsbl */ + magic[1] = 0x00000002; /* nand */ + magic[2] = 0x00000000; + magic[3] = base; + magic[4] = size; + magic[5] = size; + magic[6] = size + base; + magic[7] = 0x00000000; + magic[8] = size + base; + magic[9] = 0x00000000; + + if (unified_boot == 1) + { + magic[10] = 0x33836685; /* cookie magic number */ + magic[11] = 0x00000001; /* cookie version */ + magic[12] = 0x00000002; /* file formats */ + magic[13] = 0x00000000; + magic[14] = 0x00500000; /* 5M for boot.img */ + magic[15] = 0x00000000; + magic[16] = 0x00000000; + magic[17] = 0x00000000; + magic[18] = 0x00000000; + magic[19] = 0x00000000; + } + + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd < 0) { + perror("cannot open header for writing"); + return -1; + } + if(write(fd, magic, magic_len) != magic_len) { + perror("cannot write header"); + close(fd); + unlink(argv[2]); + return -1; + } + close(fd); + + return 0; +} diff --git a/lk/target/msm7630_surf/atags.c b/lk/target/msm7630_surf/atags.c new file mode 100644 index 0000000..f87c525 --- /dev/null +++ b/lk/target/msm7630_surf/atags.c @@ -0,0 +1,130 @@ +/* Copyright (c) 2009, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#define EBI1_ADDR_128M 0x08000000 +#define SIZE_256M 0x10000000 +#define SIZE_128M 0x08000000 +#define SIZE_1M 0x00100000 + +static int scratch_addr = -1; +int smem_ram_ptable_init(struct smem_ram_ptable *); + +unsigned* target_atag_mem(unsigned* ptr) +{ + struct smem_ram_ptable ram_ptable; + unsigned i = 0; + + if (smem_ram_ptable_init(&ram_ptable)) + { + for (i = 0; i < ram_ptable.len; i++) + { + if ((ram_ptable.parts[i].attr == READWRITE) + && (ram_ptable.parts[i].domain == APPS_DOMAIN) + && (ram_ptable.parts[i].type == APPS_MEMORY)) + { + /* ATAG_MEM */ + *ptr++ = 4; + // Tag EBI-1 memory as unstable. + if(ram_ptable.parts[i].category == EBI1_CS0) { + // if EBI-1 CS-0 is 256Mb then this is a 2x256 target and + // the kernel can reserve this mem region as unstable. + // This memory region can be activated when the kernel + // receives a request from Android init scripts. + if(ram_ptable.parts[i].size == SIZE_256M) + *ptr++ = 0x5441000A; //Deep-Power-Down Tag. + + //if EBI-1 CS-0 s 128Mb then this is a 2x128 target. + //Android + Kernel + PMEM regions account for more than + //128Mb and the target will not be able to boot with just + //one memory bank active and the second memory bank is reserved. + //In the case of 2x128 the tag is set to SelfRefresh Only. + else if(ram_ptable.parts[i].size == SIZE_128M) + *ptr++ = 0x5441000B; //Self-Refresh Tag. + } + else + *ptr++ = 0x54410002; + + *ptr++ = ram_ptable.parts[i].size; + *ptr++ = ram_ptable.parts[i].start; + } + + /* Check for modem bootloader memory that can be reclaimed */ + if ((ram_ptable.parts[i].attr == READWRITE) + && (ram_ptable.parts[i].domain == APPS_DOMAIN) + && (ram_ptable.parts[i].type == BOOT_REGION_MEMORY1)) + { + /* ATAG_MEM_OSBL */ + *ptr++ = 4; + *ptr++ = 0x5441000C; + *ptr++ = ram_ptable.parts[i].size; + *ptr++ = ram_ptable.parts[i].start; + } + } + } + else + { + dprintf(CRITICAL, "ERROR: Unable to read RAM partition\n"); + ASSERT(0); + } + + return ptr; +} + +void *target_get_scratch_address(void) +{ + struct smem_ram_ptable ram_ptable; + unsigned i = 0; + + if (smem_ram_ptable_init(&ram_ptable)) + { + for (i = 0; i < ram_ptable.len; i++) + { + if ((ram_ptable.parts[i].attr == READWRITE) + && (ram_ptable.parts[i].domain == APPS_DOMAIN) + && (ram_ptable.parts[i].start != 0x0)) + { + if (ram_ptable.parts[i].size >= FASTBOOT_BUF_SIZE) + { + scratch_addr = ram_ptable.parts[i].start; + break; + } + } + } + } + else + { + dprintf(CRITICAL, "ERROR: Unable to read RAM partition\n"); + ASSERT(0); + } + + return (void *)((scratch_addr == -1) ? EBI1_ADDR_128M : scratch_addr); +} diff --git a/lk/target/msm7630_surf/include/target/display.h b/lk/target/msm7630_surf/include/target/display.h new file mode 100644 index 0000000..69cd4ac --- /dev/null +++ b/lk/target/msm7630_surf/include/target/display.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _TARGET_MSM7630_SURF_DISPLAY_H +#define _TARGET_MSM7630_SURF_DISPLAY_H + +#define TARGET_XRES 480 +#define TARGET_YRES 800 + +#define LCDC_FB_WIDTH 480 +#define LCDC_FB_HEIGHT 800 + +#define LCDC_HSYNC_PULSE_WIDTH_DCLK 8 +#define LCDC_HSYNC_BACK_PORCH_DCLK 184 +#define LCDC_HSYNC_FRONT_PORCH_DCLK 4 +#define LCDC_HSYNC_SKEW_DCLK 0 + +#define LCDC_VSYNC_PULSE_WIDTH_LINES 1 +#define LCDC_VSYNC_BACK_PORCH_LINES 2 +#define LCDC_VSYNC_FRONT_PORCH_LINES 3 + +#endif diff --git a/lk/target/msm7630_surf/init.c b/lk/target/msm7630_surf/init.c new file mode 100644 index 0000000..28dd553 --- /dev/null +++ b/lk/target/msm7630_surf/init.c @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LINUX_MACHTYPE_7x30_SURF 2679 +#define LINUX_MACHTYPE_7x30_FFA 2707 +#define LINUX_MACHTYPE_7x30_FLUID 2741 +#define LINUX_MACHTYPE_8x55_SURF 2768 +#define LINUX_MACHTYPE_8x55_FFA 2769 +#define LINUX_MACHTYPE_8x55_SVLTE_FFA 2863 +#define LINUX_MACHTYPE_8x55_SVLTE_SURF 2864 + +#define MSM8255_ID 74 +#define MSM8655_ID 75 +#define APQ8055_ID 85 + +#define VARIABLE_LENGTH 0x10101010 +#define DIFF_START_ADDR 0xF0F0F0F0 +#define NUM_PAGES_PER_BLOCK 0x40 + +static unsigned mmc_sdc_base[] = { MSM_SDC1_BASE, MSM_SDC2_BASE, MSM_SDC3_BASE, MSM_SDC4_BASE}; + +static struct ptable flash_ptable; +static int hw_platform_type = -1; + +/* for these partitions, start will be offset by either what we get from + * smem, or from the above offset if smem is not useful. Also, we should + * probably have smem_ptable code populate our flash_ptable. + * + * When smem provides us with a full partition table, we can get rid of + * this altogether. + * + */ +static struct ptentry board_part_list[] = { + { + .start = 0, + .length = 5 /* In MB */, + .name = "boot", + }, + { + .start = DIFF_START_ADDR, + .length = 120 /* In MB */, + .name = "system", + }, + { + .start = DIFF_START_ADDR, + .length = 30 /* In MB */, + .name = "cache", + }, + { + .start = DIFF_START_ADDR, + .length = 1 /* In MB */, + .name = "misc", + }, + { + .start = DIFF_START_ADDR, + .length = VARIABLE_LENGTH, + .name = "userdata", + }, + { + .start = DIFF_START_ADDR, + .length = 3 /* In MB */, + .name = "persist", + }, + { + .start = DIFF_START_ADDR, + .length = 5 /* In MB */, + .name = "recovery", + }, +}; +static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry); + +void smem_ptable_init(void); +unsigned smem_get_apps_flash_start(void); +unsigned smem_read_alloc_entry_offset(smem_mem_type_t, void *, int, int); + +void keypad_init(void); + +static int emmc_boot = -1; /* set to uninitialized */ +int target_is_emmc_boot(void); +static int platform_version = -1; +static int target_msm_id = -1; +static int interleaved_mode_enabled = -1; +void enable_interleave_mode(int); + +int target_is_interleaved_mode(void) +{ + struct smem_board_info_v4 board_info_v4; + unsigned int board_info_len = 0; + unsigned smem_status; + char *build_type; + unsigned format = 0; + + if (interleaved_mode_enabled != -1) + { + return interleaved_mode_enabled; + } + + smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, + &format, sizeof(format), 0); + if(!smem_status) + { + if ((format == 3) || (format == 4)) + { + if (format == 4) + board_info_len = sizeof(board_info_v4); + else + board_info_len = sizeof(board_info_v4.board_info_v3); + + smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, + &board_info_v4, board_info_len); + if(!smem_status) + { + build_type = (char *)(board_info_v4.board_info_v3.build_id) + 9; + + interleaved_mode_enabled = 0; + + if (*build_type == 'C') + { + interleaved_mode_enabled = 1; + } + } + } + } + + return interleaved_mode_enabled; +} + +void target_init(void) +{ + unsigned offset; + struct flash_info *flash_info; + unsigned total_num_of_blocks; + unsigned next_ptr_start_adr = 0; + unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/ + unsigned base_addr; + unsigned char slot; + int i; + + dprintf(INFO, "target_init()\n"); + +#if (!ENABLE_NANDWRITE) + keys_init(); + keypad_init(); +#endif + + if (target_is_emmc_boot()) + { + /* Trying Slot 2 first */ + slot = 2; + base_addr = mmc_sdc_base[slot-1]; + if(mmc_boot_main(slot, base_addr)) + { + /* Trying Slot 4 next */ + slot = 4; + base_addr = mmc_sdc_base[slot-1]; + if(mmc_boot_main(slot, base_addr)) + { + dprintf(CRITICAL, "mmc init failed!"); + ASSERT(0); + } + } + return; + } + + ptable_init(&flash_ptable); + smem_ptable_init(); + + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + enable_interleave_mode(target_is_interleaved_mode()); + + offset = smem_get_apps_flash_start(); + if (offset == 0xffffffff) + while(1); + + total_num_of_blocks = flash_info->num_blocks; + blocks_per_1MB = (1 << 20) / (flash_info->block_size); + + for (i = 0; i < num_parts; i++) { + struct ptentry *ptn = &board_part_list[i]; + unsigned len = ((ptn->length) * blocks_per_1MB); + + if(ptn->start != 0) + ASSERT(ptn->start == DIFF_START_ADDR); + + ptn->start = next_ptr_start_adr; + + if(ptn->length == VARIABLE_LENGTH) + { + unsigned length_for_prt = 0; + unsigned j; + for (j = i+1; j < num_parts; j++) + { + struct ptentry *temp_ptn = &board_part_list[j]; + ASSERT(temp_ptn->length != VARIABLE_LENGTH); + length_for_prt += ((temp_ptn->length) * blocks_per_1MB); + } + len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); + ASSERT(len >= 0); + } + next_ptr_start_adr = ptn->start + len; + if(target_is_interleaved_mode()) { + ptable_add(&flash_ptable, ptn->name, offset + (ptn->start / 2), + (len / 2), ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); + } + else { + ptable_add(&flash_ptable, ptn->name, offset + ptn->start, + len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); + } + } + + smem_add_modem_partitions(&flash_ptable); + + ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +int target_platform_version(void) +{ + return platform_version; +} + +int target_is_msm8x55(void) +{ + if ((target_msm_id == MSM8255_ID) || + (target_msm_id == MSM8655_ID) || + (target_msm_id == APQ8055_ID)) + return 1; + else + return 0; +} + +unsigned board_machtype(void) +{ + struct smem_board_info_v4 board_info_v4; + unsigned int board_info_len = 0; + enum platform platform_type = 0; + unsigned smem_status; + unsigned format = 0; + if(hw_platform_type != -1) + return hw_platform_type; + + smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, + &format, sizeof(format), 0); + if(!smem_status) + { + if ((format == 3) || (format == 4)) + { + if (format == 4) + board_info_len = sizeof(board_info_v4); + else + board_info_len = sizeof(board_info_v4.board_info_v3); + + smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, + &board_info_v4, board_info_len); + if(!smem_status) + { + if(format == 4) + platform_version = board_info_v4.platform_version; + + platform_type = board_info_v4.board_info_v3.hw_platform; + target_msm_id = board_info_v4.board_info_v3.msm_id; + switch (platform_type) + { + case HW_PLATFORM_SURF: + hw_platform_type = ((target_is_msm8x55()) ? + LINUX_MACHTYPE_8x55_SURF : LINUX_MACHTYPE_7x30_SURF); break; + case HW_PLATFORM_FFA: + hw_platform_type = ((target_is_msm8x55()) ? + LINUX_MACHTYPE_8x55_FFA : LINUX_MACHTYPE_7x30_FFA); break; + case HW_PLATFORM_FLUID: + hw_platform_type = LINUX_MACHTYPE_7x30_FLUID; break; + case HW_PLATFORM_SVLTE: + hw_platform_type = LINUX_MACHTYPE_8x55_SVLTE_FFA; break; + default: + hw_platform_type = ((target_is_msm8x55()) ? + LINUX_MACHTYPE_8x55_SURF : LINUX_MACHTYPE_7x30_SURF); break; + } + return hw_platform_type; + } + } + } + hw_platform_type = LINUX_MACHTYPE_7x30_SURF; + return hw_platform_type; +} + +void reboot_device(unsigned reboot_reason) +{ + reboot(reboot_reason); +} + +unsigned check_reboot_mode(void) +{ + unsigned mode[2] = {0, 0}; + unsigned int mode_len = sizeof(mode); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE, + &mode, mode_len ); + if(smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n"); + return 0; + } + return mode[0]; +} + +static unsigned target_check_power_on_reason(void) +{ + unsigned power_on_status = 0; + unsigned int status_len = sizeof(power_on_status); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_POWER_ON_STATUS_INFO, + &power_on_status, status_len); + + if (!smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for power on reason\n"); + } + + return power_on_status; +} + +unsigned target_pause_for_battery_charge(void) +{ + //check power on reason only for fluid devices + if( hw_platform_type != LINUX_MACHTYPE_7x30_FLUID) + return 0; + + if (target_check_power_on_reason() == PWR_ON_EVENT_USB_CHG) + return 1; + return 0; +} + +void target_battery_charging_enable(unsigned enable, unsigned disconnect) +{ +} diff --git a/lk/target/msm7630_surf/keypad.c b/lk/target/msm7630_surf/keypad.c new file mode 100644 index 0000000..7261126 --- /dev/null +++ b/lk/target/msm7630_surf/keypad.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) +#define BITS_IN_ELEMENT(x) (sizeof(x)[0] * 8) + +static unsigned char qwerty_keys_old[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static unsigned char qwerty_keys_new[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define KEYMAP_INDEX(row, col) (row)* BITS_IN_ELEMENT(qwerty_keys_new) + (col) + +static unsigned int qwerty_keymap[] = { + [KEYMAP_INDEX(4, 2)] = KEY_BACK, /* -L on SURF & FFA */ + [KEYMAP_INDEX(3, 4)] = KEY_HOME, /* +R on SURF & FFA */ + [KEYMAP_INDEX(1, 4)] = KEY_CLEAR, /* '-' of left side switch on FLUID */ +}; + +static struct qwerty_keypad_info qwerty_keypad = { + .keymap = qwerty_keymap, + .old_keys = qwerty_keys_old, + .rec_keys = qwerty_keys_new, + .rows = 5, + .columns = 5, + .num_of_reads = 6, + .rd_func = &i2c_ssbi_read_bytes, + .wr_func = &i2c_ssbi_write_bytes, + .settle_time = 5 /* msec */, + .poll_time = 20 /* msec */, +}; + +void keypad_init(void) +{ + ssbi_keypad_init(&qwerty_keypad); +} diff --git a/lk/target/msm7630_surf/rules.mk b/lk/target/msm7630_surf/rules.mk new file mode 100644 index 0000000..e318b14 --- /dev/null +++ b/lk/target/msm7630_surf/rules.mk @@ -0,0 +1,42 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared -I$(LK_TOP_DIR)/platform/msm7x30 + +PLATFORM := msm7x30 + +MEMBASE := 0x00000000 # EBI +MEMSIZE := 0x00100000 # 1MB + +BASE_ADDR := 0x00200000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00008000 +RAMDISK_ADDR := BASE_ADDR+0x01000000 +SCRATCH_ADDR := 0x08008000 +FASTBOOT_BUF_SIZE := 0x07800000 + +KEYS_USE_GPIO_KEYPAD := 1 + +DEFINES += DISPLAY_SPLASH_SCREEN=0 +DEFINES += DISPLAY_TYPE_MDDI=0 +DEFINES += DISPLAY_TYPE_LCDC=0 + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + MEMBASE=$(MEMBASE) \ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) \ + FASTBOOT_BUF_SIZE=$(FASTBOOT_BUF_SIZE) + + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/atags.o \ + $(LOCAL_DIR)/keypad.o \ diff --git a/lk/target/msm7630_surf/tools/makefile b/lk/target/msm7630_surf/tools/makefile new file mode 100644 index 0000000..94f47ca --- /dev/null +++ b/lk/target/msm7630_surf/tools/makefile @@ -0,0 +1,45 @@ +#Makefile to generate appsboot.mbn + +ifeq ($(BOOTLOADER_OUT),.) +APPSBOOTHEADER_DIR := $(BUILDDIR) +else +APPSBOOTHEADER_DIR := $(BOOTLOADER_OUT)/../../ +endif + +SRC_DIR := target/$(TARGET)/tools +COMPILER := gcc + +ifeq ($(EMMC_BOOT), 1) + APPSBOOTHDR_FILES := EMMCBOOT.MBN +else + ifeq ($(BUILD_NANDWRITE), 1) + APPSBOOTHDR_FILES := + else + APPSBOOTHDR_FILES := appsboot.mbn + endif +endif + +APPSBOOTHEADER: $(APPSBOOTHDR_FILES) + + +appsboot.mbn: appsboothd.mbn $(OUTBIN) + cp $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboot.raw + cat $(APPSBOOTHEADER_DIR)/appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/appsboot.mbn + rm -f $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +EMMCBOOT.MBN: emmc_appsboothd.mbn $(OUTBIN) + cp $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboot.raw + cat $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/EMMCBOOT.MBN + cat $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/emmc_appsboot.mbn + rm -f $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn + +emmc_appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn + +mkheader: $(SRC_DIR)/mkheader.c + ${COMPILER} -DMEMBASE=$(MEMBASE) $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader + cp $(SRC_DIR)/mkheader $(APPSBOOTHEADER_DIR)/mkheader + diff --git a/lk/target/msm7630_surf/tools/mkheader.c b/lk/target/msm7630_surf/tools/mkheader.c new file mode 100644 index 0000000..fda8b67 --- /dev/null +++ b/lk/target/msm7630_surf/tools/mkheader.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2007, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include + +#include + +int print_usage(){ + fprintf(stderr,"usage: mkheader \n"); + fprintf(stderr," mkheader \n"); + fprintf(stderr," mkheader \n"); + fprintf(stderr," mkheader \n\n"); + fprintf(stderr,"bin: Input raw appsbl binary\n"); + fprintf(stderr,"hdr: Output of appsbl header location\n"); + fprintf(stderr,"outbin: Output of the signed or unsigned apps boot location\n"); + fprintf(stderr,"maxsize: Maximum size for certificate chain\n"); + fprintf(stderr,"certchain: Output of the certchain location\n"); + fprintf(stderr,"files: Input format ...\n"); + fprintf(stderr,"certificate chain: Files will be concatenated in order to create the certificate chain\n\n"); + return -1; +} + +int cat(FILE * in, FILE * out, unsigned size, unsigned buff_size){ + unsigned bytes_left = size; + char buf[buff_size]; + int ret = 0; + + while(bytes_left){ + fread(buf, sizeof(char), buff_size, in); + if(!feof(in)){ + bytes_left -= fwrite(buf, sizeof(char), buff_size, out); + }else + bytes_left = 0; + } + ret = ferror(in) | ferror(out); + if(ret) + fprintf(stderr, "ERROR: Occured during file concatenation\n"); + return ret; +} + +int main(int argc, char *argv[]) +{ + struct stat s; + unsigned size, base; + int unified_boot = 0; + unsigned unified_boot_magic[20]; + unsigned non_unified_boot_magic[10]; + unsigned magic_len = 0; + unsigned *magic; + unsigned cert_chain_size = 0; + unsigned signature_size = 0; + int secure_boot = 0; + int fd; + + if(argc < 3) { + return print_usage(); + } + + if (argc == 4) { + if(!strcmp("unified-boot",argv[3])) { + unified_boot = 1; + }else if(!strcmp("secure-boot",argv[3])){ + fprintf(stderr, + "ERROR: Missing arguments: [outbin maxsize] | [outbin, maxsize, certchain, signature + certifcate(s)]\n"); + return print_usage(); + } + else if(!strcmp("unsecure-boot",argv[3])){ + fprintf(stderr,"ERROR: Missing arguments: outbin directory\n"); + return print_usage(); + } + } + + if (argc > 4) { + if(!strcmp("secure-boot",argv[3])) { + if(argc < 9 && argc != 6){ + fprintf(stderr, + "ERROR: Missing argument(s): [outbin maxsize] | [outbin, maxsize, certchain, signature + certifcate(s)]\n"); + return print_usage(); + } + secure_boot = 1; + signature_size = 256; //Support SHA 256 + cert_chain_size = atoi(argv[5]); + } + } + + if(stat(argv[1], &s)) { + perror("cannot stat binary"); + return -1; + } + + if(unified_boot) { + magic = unified_boot_magic; + magic_len = sizeof(unified_boot_magic); + } else { + magic = non_unified_boot_magic; + magic_len = sizeof(non_unified_boot_magic); + } + + size = s.st_size; +#if MEMBASE + base = MEMBASE; +#else + base = 0; +#endif + + printf("Image Destination Pointer: 0x%x\n", base); + + magic[0] = 0x00000005; /* appsbl */ + magic[1] = 0x00000003; //Flash_partition_version /* nand */ + magic[2] = 0x00000000; //image source pointer + magic[3] = base; //image destination pointer + magic[4] = size + cert_chain_size + signature_size; //image size + magic[5] = size; //code size + magic[6] = base + size; + magic[7] = signature_size; + magic[8] = size + base + signature_size; + magic[9] = cert_chain_size; + + if (unified_boot == 1) + { + magic[10] = 0x33836685; /* cookie magic number */ + magic[11] = 0x00000001; /* cookie version */ + magic[12] = 0x00000002; /* file formats */ + magic[13] = 0x00000000; + magic[14] = 0x00000000; /* not setting size for boot.img */ + magic[15] = 0x00000000; + magic[16] = 0x00000000; + magic[17] = 0x00000000; + magic[18] = 0x00000000; + magic[19] = 0x00000000; + } + + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd < 0) { + perror("cannot open header for writing"); + return -1; + } + if(write(fd, magic, magic_len) != magic_len) { + perror("cannot write header"); + close(fd); + unlink(argv[2]); + return -1; + } + close(fd); + + if (secure_boot && argc > 6){ + FILE * input_file; + FILE * output_file; + unsigned buff_size = 1; + char buf[buff_size]; + unsigned bytes_left; + unsigned current_cert_chain_size = 0; + int padding_size = 0; + int i; + + if((output_file = fopen(argv[6], "wb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + printf("Certificate Chain Output File: %s\n", argv[6]); + + for (i = 8; i < argc; i++){ + if((input_file = fopen(argv[i], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[i], &s); + bytes_left = s.st_size; + current_cert_chain_size += bytes_left; + if (cat(input_file, output_file, bytes_left, buff_size)) + return -1; + fclose(input_file); + } + + //Pad certifcate chain to the max expected size from input + memset(buf, 0xFF, sizeof(buf)); + padding_size = cert_chain_size - current_cert_chain_size; + + if(padding_size <0){ + fprintf(stderr, "ERROR: Input certificate chain (Size=%d) is larger than the maximum specified (Size=%d)\n", + current_cert_chain_size, cert_chain_size); + return -1; + } + + bytes_left = (padding_size > 0) ? padding_size : 0; + while(bytes_left){ + if(!ferror(output_file)) + bytes_left -= fwrite(buf, sizeof(buf), buff_size, output_file); + else{ + fprintf(stderr, "ERROR: Occured during certifcate chain padding\n"); + return -1; + } + } + fclose(output_file); + + //Concat and combine to signed image. Format [HDR][RAW APPSBOOT][PADDED CERT CHAIN] + if((output_file = fopen(argv[4], "wb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + printf("Image Output File: %s\n", argv[4]); + + //Header + if((input_file = fopen(argv[2], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[2], &s); + if (cat(input_file, output_file, s.st_size, buff_size)) + return -1; + fclose(input_file); + + //Raw Appsbl + if((input_file = fopen(argv[1], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[1], &s); + if(cat(input_file, output_file, s.st_size, buff_size)) + return -1; + fclose(input_file); + + //Signature + if((input_file = fopen(argv[7], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[7], &s); + if(cat(input_file, output_file, s.st_size, buff_size)) + return -1; + fclose(input_file); + + //Certifcate Chain + if((input_file = fopen(argv[6], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + if(cat(input_file, output_file, (current_cert_chain_size + padding_size), buff_size)) + return -1; + fclose(input_file); + + fclose(output_file); + + }else if(argc == 5 || argc == 6){ + FILE * input_file; + FILE * output_file; + unsigned buff_size = 1; + char buf[buff_size]; + + //Concat and combine to unsigned image. Format [HDR][RAW APPSBOOT] + if((output_file = fopen(argv[4], "wb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + printf("Image Output File: %s\n", argv[4]); + + //Header + if((input_file = fopen(argv[2], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[2], &s); + if (cat(input_file, output_file, s.st_size, buff_size)) + return -1; + fclose(input_file); + + //Raw Appsbl + if((input_file = fopen(argv[1], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[1], &s); + if(cat(input_file, output_file, s.st_size, buff_size)) + return -1; + fclose(input_file); + fclose(output_file); + } + + printf("Done execution\n"); + + return 0; +} diff --git a/lk/target/msm8660_surf/atags.c b/lk/target/msm8660_surf/atags.c new file mode 100644 index 0000000..ebbf203 --- /dev/null +++ b/lk/target/msm8660_surf/atags.c @@ -0,0 +1,87 @@ +/* Copyright (c) 2009-2010, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#define SIZE_45M 0x02D00000 // 45M +#define EBI1_ADDR_1026M 0x40200000 + +#define SIZE_128M 0x08000000 // 128M +#define EBI1_ADDR_1152M 0x48000000 + +#define SIZE_256M 0x10000000 // 256M +#define EBI1_ADDR_1280M 0x50000000 + +#define SIZE_768M 0x30000000 // 256M + 512M + +#define EBI1_CS1_ADDR_BASE 0x00A40024 + +unsigned* target_atag_mem(unsigned* ptr) +{ + unsigned value = 0; + + /* ATAG_MEM */ + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = SIZE_45M; + *ptr++ = EBI1_ADDR_1026M; + + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = SIZE_128M; + *ptr++ = EBI1_ADDR_1152M; + + value = readl(EBI1_CS1_ADDR_BASE); + value = (value >> 8) & 0xFF; + + if (value == 0x50) + { + /* For 512MB RAM*/ + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = SIZE_256M; + *ptr++ = EBI1_ADDR_1280M; + } + else if (value == 0x60) + { + /* For 1GB RAM*/ + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = SIZE_768M; + *ptr++ = EBI1_ADDR_1280M; + } + + return ptr; +} + +void *target_get_scratch_address(void) +{ + return ((void *)SCRATCH_ADDR); +} diff --git a/lk/target/msm8660_surf/include/target/display.h b/lk/target/msm8660_surf/include/target/display.h new file mode 100644 index 0000000..1a1eab0 --- /dev/null +++ b/lk/target/msm8660_surf/include/target/display.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _TARGET_QSD8660_SURF_DISPLAY_H +#define _TARGET_QSD8660_SURF_DISPLAY_H + +#define TARGET_XRES 1024 +#define TARGET_YRES 600 + +#define LCDC_FB_WIDTH 1024 +#define LCDC_FB_HEIGHT 600 + +#define LCDC_HSYNC_PULSE_WIDTH_DCLK 32 +#define LCDC_HSYNC_BACK_PORCH_DCLK 80 +#define LCDC_HSYNC_FRONT_PORCH_DCLK 48 +#define LCDC_HSYNC_SKEW_DCLK 0 + +#define LCDC_VSYNC_PULSE_WIDTH_LINES 1 +#define LCDC_VSYNC_BACK_PORCH_LINES 4 +#define LCDC_VSYNC_FRONT_PORCH_LINES 3 + +/* Toshiba MIPI panel */ +#define TSH_MIPI_FB_WIDTH 480 +#define TSH_MIPI_FB_HEIGHT 854 + +/* NOVATEK MIPI panel */ +#define NOV_MIPI_FB_WIDTH 540 +#define NOV_MIPI_FB_HEIGHT 960 + +#define MIPI_HSYNC_PULSE_WIDTH 50 +#define MIPI_HSYNC_BACK_PORCH_DCLK 500 +#define MIPI_HSYNC_FRONT_PORCH_DCLK 500 + +#define MIPI_VSYNC_PULSE_WIDTH 5 +#define MIPI_VSYNC_BACK_PORCH_LINES 20 +#define MIPI_VSYNC_FRONT_PORCH_LINES 20 + +#endif diff --git a/lk/target/msm8660_surf/init.c b/lk/target/msm8660_surf/init.c new file mode 100644 index 0000000..16dd618 --- /dev/null +++ b/lk/target/msm8660_surf/init.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LINUX_MACHTYPE_8660_SURF 2755 +#define LINUX_MACHTYPE_8660_FFA 3017 +#define LINUX_MACHTYPE_8660_FLUID 3124 +#define LINUX_MACHTYPE_8660_CHARM_SURF 3181 +#define LINUX_MACHTYPE_8660_CHARM_FFA 3199 + +void keypad_init(void); + +static int emmc_boot = -1; /* set to uninitialized */ +int target_is_emmc_boot(void); +void debug_led_write(char); +char debug_led_read(); +uint32_t platform_id_read (void); + +void target_init(void) +{ + + dprintf(INFO, "target_init()\n"); + + setup_fpga(); + + /* Setting Debug LEDs ON */ + debug_led_write(0xFF); +#if (!ENABLE_NANDWRITE) + keys_init(); + keypad_init(); +#endif + if(mmc_boot_main(MMC_SLOT,MSM_SDC1_BASE)) + { + dprintf(CRITICAL, "mmc init failed!"); + ASSERT(0); + } +} + +unsigned board_machtype(void) +{ + struct smem_board_info_v5 board_info_v5; + unsigned int board_info_len = 0; + unsigned smem_status = 0; + unsigned format = 0; + unsigned id = 0; + unsigned hw_platform = 0; + unsigned fused_chip = 0; + unsigned mach_id = LINUX_MACHTYPE_8660_FFA; + + /* Detect external msm if this is a "fusion" */ + smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, + &format, sizeof(format), 0); + if(!smem_status) + { + if (format >= 5) + { + board_info_len = sizeof(board_info_v5); + + smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, + &board_info_v5, board_info_len); + if(!smem_status) + { + fused_chip = board_info_v5.fused_chip; + } + } + } + + /* Detect SURF v/s FFA v/s Fluid */ + id = board_info_v5.board_info_v3.hw_platform; + switch(id) + { + case 0x1: + hw_platform = HW_PLATFORM_SURF; + break; + case 0x2: + hw_platform = HW_PLATFORM_FFA; + break; + case 0x3: + hw_platform = HW_PLATFORM_FLUID; + break; + default: + /* Writing to Debug LED register and reading back to auto detect + SURF and FFA. If we read back, it is SURF */ + debug_led_write(0xA5); + + if((debug_led_read() & 0xFF) == 0xA5) + { + debug_led_write(0); + hw_platform = HW_PLATFORM_SURF; + } + else + hw_platform = HW_PLATFORM_FFA; + }; + + /* Use hw_platform and fused_chip information to determine machine id */ + switch(fused_chip) + { + case UNKNOWN: + if (hw_platform == HW_PLATFORM_SURF) + mach_id = LINUX_MACHTYPE_8660_SURF; + else if (hw_platform == HW_PLATFORM_FFA) + mach_id = LINUX_MACHTYPE_8660_FFA; + else if (hw_platform == HW_PLATFORM_FLUID) + mach_id = LINUX_MACHTYPE_8660_FLUID; + break; + + case MDM9200: + case MDM9600: + if (hw_platform == HW_PLATFORM_SURF) + mach_id = LINUX_MACHTYPE_8660_CHARM_SURF; + else if (hw_platform == HW_PLATFORM_FFA) + mach_id = LINUX_MACHTYPE_8660_CHARM_FFA; + break; + + default: + mach_id = LINUX_MACHTYPE_8660_FFA; + } + + return mach_id; +} + +void reboot_device(unsigned reboot_reason) +{ + /* Reset WDG0 counter */ + writel(1,MSM_WDT0_RST); + /* Disable WDG0 */ + writel(0,MSM_WDT0_EN); + /* Set WDG0 bark time */ + writel(0x31F3,MSM_WDT0_BT); + /* Enable WDG0 */ + writel(3,MSM_WDT0_EN); + dmb(); + /* Enable WDG output */ + writel(3,MSM_TCSR_BASE + TCSR_WDOG_CFG); + mdelay(10000); + dprintf (CRITICAL, "Rebooting failed\n"); + return; +} + +unsigned check_reboot_mode(void) +{ + unsigned restart_reason = 0; + void *restart_reason_addr = 0x401FFFFC; + + /* Read reboot reason and scrub it */ + restart_reason = readl(restart_reason_addr); + writel(0x00, restart_reason_addr); + + return restart_reason; +} + +void target_battery_charging_enable(unsigned enable, unsigned disconnect) +{ +} + +void setup_fpga() +{ + writel(0x147, GPIO_CFG133_ADDR); + writel(0x144, GPIO_CFG135_ADDR); + writel(0x144, GPIO_CFG136_ADDR); + writel(0x144, GPIO_CFG137_ADDR); + writel(0x144, GPIO_CFG138_ADDR); + writel(0x144, GPIO_CFG139_ADDR); + writel(0x144, GPIO_CFG140_ADDR); + writel(0x144, GPIO_CFG141_ADDR); + writel(0x144, GPIO_CFG142_ADDR); + writel(0x144, GPIO_CFG143_ADDR); + writel(0x144, GPIO_CFG144_ADDR); + writel(0x144, GPIO_CFG145_ADDR); + writel(0x144, GPIO_CFG146_ADDR); + writel(0x144, GPIO_CFG147_ADDR); + writel(0x144, GPIO_CFG148_ADDR); + writel(0x144, GPIO_CFG149_ADDR); + writel(0x144, GPIO_CFG150_ADDR); + writel(0x147, GPIO_CFG151_ADDR); + writel(0x147, GPIO_CFG152_ADDR); + writel(0x147, GPIO_CFG153_ADDR); + writel(0x3, GPIO_CFG154_ADDR); + writel(0x147, GPIO_CFG155_ADDR); + writel(0x147, GPIO_CFG156_ADDR); + writel(0x147, GPIO_CFG157_ADDR); + writel(0x3, GPIO_CFG158_ADDR); + + writel(0x00000B31, EBI2_CHIP_SELECT_CFG0); + writel(0xA3030020, EBI2_XMEM_CS3_CFG1); +} + +void debug_led_write(char val) +{ + writeb(val,SURF_DEBUG_LED_ADDR); +} + +char debug_led_read() +{ + return readb(SURF_DEBUG_LED_ADDR); +} diff --git a/lk/target/msm8660_surf/keypad.c b/lk/target/msm8660_surf/keypad.c new file mode 100644 index 0000000..2ae3ece --- /dev/null +++ b/lk/target/msm8660_surf/keypad.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#define BITS_IN_ELEMENT(x) (sizeof(x)[0] * 8) + +static unsigned char qwerty_keys_old[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static unsigned char qwerty_keys_new[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define KEYMAP_INDEX(row, col) (row)* BITS_IN_ELEMENT(qwerty_keys_new) + (col) + +static unsigned int qwerty_keymap[] = { + [KEYMAP_INDEX(1, 3)] = KEY_BACK, /* Volume down key */ +}; + +static struct qwerty_keypad_info qwerty_keypad = { + .keymap = qwerty_keymap, + .old_keys = qwerty_keys_old, + .rec_keys = qwerty_keys_new, + .rows = 6, + .columns = 5, + .num_of_reads = 6, + .rd_func = &pa1_ssbi2_read_bytes, + .wr_func = &pa1_ssbi2_write_bytes, + .settle_time = 5 /* msec */, + .poll_time = 20 /* msec */, +}; + +void keypad_init(void) +{ + ssbi_keypad_init(&qwerty_keypad); +} diff --git a/lk/target/msm8660_surf/rules.mk b/lk/target/msm8660_surf/rules.mk new file mode 100644 index 0000000..960d8be --- /dev/null +++ b/lk/target/msm8660_surf/rules.mk @@ -0,0 +1,41 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared + +PLATFORM := msm8x60 + +MEMBASE := 0x40100000 # SMI +MEMSIZE := 0x00100000 # 1MB + +BASE_ADDR := 0x40200000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00008000 +RAMDISK_ADDR := BASE_ADDR+0x01000000 +SCRATCH_ADDR := 0x48000000 + +KEYS_USE_GPIO_KEYPAD := 1 + +DEFINES += DISPLAY_SPLASH_SCREEN=1 +DEFINES += DISPLAY_TYPE_LCDC=1 +DEFINES += DISPLAY_TYPE_MIPI=0 +DEFINES += DISPLAY_MIPI_PANEL_NOVATEK_BLUE=0 +DEFINES += DISPLAY_MIPI_PANEL_TOSHIBA=0 + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + MEMBASE=$(MEMBASE) \ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/atags.o \ + $(LOCAL_DIR)/keypad.o diff --git a/lk/target/msm8660_surf/tools/makefile b/lk/target/msm8660_surf/tools/makefile new file mode 100644 index 0000000..7da7c6d --- /dev/null +++ b/lk/target/msm8660_surf/tools/makefile @@ -0,0 +1,44 @@ +#Makefile to generate appsboot.mbn + +ifeq ($(BOOTLOADER_OUT),.) +APPSBOOTHEADER_DIR := $(BUILDDIR) +else +APPSBOOTHEADER_DIR := $(BOOTLOADER_OUT)/../../ +endif + +SRC_DIR := target/$(TARGET)/tools +COMPILER := gcc + +ifeq ($(EMMC_BOOT), 1) + APPSBOOTHDR_FILES := EMMCBOOT.MBN +else + ifeq ($(BUILD_NANDWRITE), 1) + APPSBOOTHDR_FILES := + else + APPSBOOTHDR_FILES := appsboot.mbn + endif +endif + +APPSBOOTHEADER: $(APPSBOOTHDR_FILES) + + +appsboot.mbn: appsboothd.mbn $(OUTBIN) + cp $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboot.raw + cat $(APPSBOOTHEADER_DIR)/appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/appsboot.mbn + rm -f $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +EMMCBOOT.MBN: emmc_appsboothd.mbn $(OUTBIN) + cp $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboot.raw + cat $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/EMMCBOOT.MBN + cat $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/emmc_appsboot.mbn + rm -f $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn + +emmc_appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn + +mkheader: $(SRC_DIR)/mkheader.c + ${COMPILER} -DMEMBASE=$(MEMBASE) $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader + cp $(SRC_DIR)/mkheader $(APPSBOOTHEADER_DIR)/mkheader diff --git a/lk/target/msm8660_surf/tools/mkheader.c b/lk/target/msm8660_surf/tools/mkheader.c new file mode 100644 index 0000000..fda8b67 --- /dev/null +++ b/lk/target/msm8660_surf/tools/mkheader.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2007, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include + +#include + +int print_usage(){ + fprintf(stderr,"usage: mkheader \n"); + fprintf(stderr," mkheader \n"); + fprintf(stderr," mkheader \n"); + fprintf(stderr," mkheader \n\n"); + fprintf(stderr,"bin: Input raw appsbl binary\n"); + fprintf(stderr,"hdr: Output of appsbl header location\n"); + fprintf(stderr,"outbin: Output of the signed or unsigned apps boot location\n"); + fprintf(stderr,"maxsize: Maximum size for certificate chain\n"); + fprintf(stderr,"certchain: Output of the certchain location\n"); + fprintf(stderr,"files: Input format ...\n"); + fprintf(stderr,"certificate chain: Files will be concatenated in order to create the certificate chain\n\n"); + return -1; +} + +int cat(FILE * in, FILE * out, unsigned size, unsigned buff_size){ + unsigned bytes_left = size; + char buf[buff_size]; + int ret = 0; + + while(bytes_left){ + fread(buf, sizeof(char), buff_size, in); + if(!feof(in)){ + bytes_left -= fwrite(buf, sizeof(char), buff_size, out); + }else + bytes_left = 0; + } + ret = ferror(in) | ferror(out); + if(ret) + fprintf(stderr, "ERROR: Occured during file concatenation\n"); + return ret; +} + +int main(int argc, char *argv[]) +{ + struct stat s; + unsigned size, base; + int unified_boot = 0; + unsigned unified_boot_magic[20]; + unsigned non_unified_boot_magic[10]; + unsigned magic_len = 0; + unsigned *magic; + unsigned cert_chain_size = 0; + unsigned signature_size = 0; + int secure_boot = 0; + int fd; + + if(argc < 3) { + return print_usage(); + } + + if (argc == 4) { + if(!strcmp("unified-boot",argv[3])) { + unified_boot = 1; + }else if(!strcmp("secure-boot",argv[3])){ + fprintf(stderr, + "ERROR: Missing arguments: [outbin maxsize] | [outbin, maxsize, certchain, signature + certifcate(s)]\n"); + return print_usage(); + } + else if(!strcmp("unsecure-boot",argv[3])){ + fprintf(stderr,"ERROR: Missing arguments: outbin directory\n"); + return print_usage(); + } + } + + if (argc > 4) { + if(!strcmp("secure-boot",argv[3])) { + if(argc < 9 && argc != 6){ + fprintf(stderr, + "ERROR: Missing argument(s): [outbin maxsize] | [outbin, maxsize, certchain, signature + certifcate(s)]\n"); + return print_usage(); + } + secure_boot = 1; + signature_size = 256; //Support SHA 256 + cert_chain_size = atoi(argv[5]); + } + } + + if(stat(argv[1], &s)) { + perror("cannot stat binary"); + return -1; + } + + if(unified_boot) { + magic = unified_boot_magic; + magic_len = sizeof(unified_boot_magic); + } else { + magic = non_unified_boot_magic; + magic_len = sizeof(non_unified_boot_magic); + } + + size = s.st_size; +#if MEMBASE + base = MEMBASE; +#else + base = 0; +#endif + + printf("Image Destination Pointer: 0x%x\n", base); + + magic[0] = 0x00000005; /* appsbl */ + magic[1] = 0x00000003; //Flash_partition_version /* nand */ + magic[2] = 0x00000000; //image source pointer + magic[3] = base; //image destination pointer + magic[4] = size + cert_chain_size + signature_size; //image size + magic[5] = size; //code size + magic[6] = base + size; + magic[7] = signature_size; + magic[8] = size + base + signature_size; + magic[9] = cert_chain_size; + + if (unified_boot == 1) + { + magic[10] = 0x33836685; /* cookie magic number */ + magic[11] = 0x00000001; /* cookie version */ + magic[12] = 0x00000002; /* file formats */ + magic[13] = 0x00000000; + magic[14] = 0x00000000; /* not setting size for boot.img */ + magic[15] = 0x00000000; + magic[16] = 0x00000000; + magic[17] = 0x00000000; + magic[18] = 0x00000000; + magic[19] = 0x00000000; + } + + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd < 0) { + perror("cannot open header for writing"); + return -1; + } + if(write(fd, magic, magic_len) != magic_len) { + perror("cannot write header"); + close(fd); + unlink(argv[2]); + return -1; + } + close(fd); + + if (secure_boot && argc > 6){ + FILE * input_file; + FILE * output_file; + unsigned buff_size = 1; + char buf[buff_size]; + unsigned bytes_left; + unsigned current_cert_chain_size = 0; + int padding_size = 0; + int i; + + if((output_file = fopen(argv[6], "wb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + printf("Certificate Chain Output File: %s\n", argv[6]); + + for (i = 8; i < argc; i++){ + if((input_file = fopen(argv[i], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[i], &s); + bytes_left = s.st_size; + current_cert_chain_size += bytes_left; + if (cat(input_file, output_file, bytes_left, buff_size)) + return -1; + fclose(input_file); + } + + //Pad certifcate chain to the max expected size from input + memset(buf, 0xFF, sizeof(buf)); + padding_size = cert_chain_size - current_cert_chain_size; + + if(padding_size <0){ + fprintf(stderr, "ERROR: Input certificate chain (Size=%d) is larger than the maximum specified (Size=%d)\n", + current_cert_chain_size, cert_chain_size); + return -1; + } + + bytes_left = (padding_size > 0) ? padding_size : 0; + while(bytes_left){ + if(!ferror(output_file)) + bytes_left -= fwrite(buf, sizeof(buf), buff_size, output_file); + else{ + fprintf(stderr, "ERROR: Occured during certifcate chain padding\n"); + return -1; + } + } + fclose(output_file); + + //Concat and combine to signed image. Format [HDR][RAW APPSBOOT][PADDED CERT CHAIN] + if((output_file = fopen(argv[4], "wb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + printf("Image Output File: %s\n", argv[4]); + + //Header + if((input_file = fopen(argv[2], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[2], &s); + if (cat(input_file, output_file, s.st_size, buff_size)) + return -1; + fclose(input_file); + + //Raw Appsbl + if((input_file = fopen(argv[1], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[1], &s); + if(cat(input_file, output_file, s.st_size, buff_size)) + return -1; + fclose(input_file); + + //Signature + if((input_file = fopen(argv[7], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[7], &s); + if(cat(input_file, output_file, s.st_size, buff_size)) + return -1; + fclose(input_file); + + //Certifcate Chain + if((input_file = fopen(argv[6], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + if(cat(input_file, output_file, (current_cert_chain_size + padding_size), buff_size)) + return -1; + fclose(input_file); + + fclose(output_file); + + }else if(argc == 5 || argc == 6){ + FILE * input_file; + FILE * output_file; + unsigned buff_size = 1; + char buf[buff_size]; + + //Concat and combine to unsigned image. Format [HDR][RAW APPSBOOT] + if((output_file = fopen(argv[4], "wb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + printf("Image Output File: %s\n", argv[4]); + + //Header + if((input_file = fopen(argv[2], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[2], &s); + if (cat(input_file, output_file, s.st_size, buff_size)) + return -1; + fclose(input_file); + + //Raw Appsbl + if((input_file = fopen(argv[1], "rb"))==NULL){ + perror("ERROR: Occured during fopen"); + return -1; + } + stat(argv[1], &s); + if(cat(input_file, output_file, s.st_size, buff_size)) + return -1; + fclose(input_file); + fclose(output_file); + } + + printf("Done execution\n"); + + return 0; +} diff --git a/lk/target/osk5912/init.c b/lk/target/osk5912/init.c new file mode 100644 index 0000000..6c4a907 --- /dev/null +++ b/lk/target/osk5912/init.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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 + +void target_init(void) +{ + smc91c96_init(); +} + diff --git a/lk/target/osk5912/rules.mk b/lk/target/osk5912/rules.mk new file mode 100644 index 0000000..1fe75de --- /dev/null +++ b/lk/target/osk5912/rules.mk @@ -0,0 +1,17 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +PLATFORM := omap5912 + +MODULES += \ + dev/net/smc91c96 + +OBJS += \ + $(LOCAL_DIR)/init.o + +MEMSIZE := 0x02000000 # 32MB + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + SMC91C96_BASE_ADDR=0x04800300 \ + SMC91C96_IRQ=0 + diff --git a/lk/target/qemu-arm/rules.mk b/lk/target/qemu-arm/rules.mk new file mode 100644 index 0000000..22c583a --- /dev/null +++ b/lk/target/qemu-arm/rules.mk @@ -0,0 +1,7 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +PLATFORM := integrator + +MEMBASE := 0x10000 # this is where qemu loads us +MEMSIZE := 0x08000000 # 128MB + diff --git a/lk/target/qsd8250_ffa/atags.c b/lk/target/qsd8250_ffa/atags.c new file mode 100644 index 0000000..77a1fb8 --- /dev/null +++ b/lk/target/qsd8250_ffa/atags.c @@ -0,0 +1,82 @@ +/* Copyright (c) 2009, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#define EBI1_SIZE1 0x0E800000 //232MB for 256/512/1024MB RAM +#define EBI1_ADDR1 0x20000000 + +#define EBI1_SIZE2_512M 0x10000000 //256MB for 512MB RAM +#define EBI1_SIZE2_1G 0x30000000 //768MB for 1GB RAM +#define EBI1_ADDR2 0x30000000 + +static unsigned check_1gb_mem() +{ + // check for 1GB + unsigned adr1 = 0x57000000; + unsigned adr2 = 0x5F000000; + unsigned value1 = 0x55555555; + unsigned value2 = 0xAAAAAAAA; + + writel(value1, adr1); + writel(value2, adr2); + + return ((value1 == readl(adr1)) && (value2 == readl(adr2))); +} + + +unsigned* target_atag_mem(unsigned* ptr) +{ + unsigned size; + + /* ATAG_MEM */ + /* 1st segment */ + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = EBI1_SIZE1; + *ptr++ = EBI1_ADDR1; + + /* 2nd segment */ +#ifdef USE_512M_RAM + size = EBI1_SIZE2_512M; +#else + size = 0; +#endif + if (check_1gb_mem()) { + size = EBI1_SIZE2_1G; + } + + if (size > 0) { + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = size; + *ptr++ = EBI1_ADDR2; + } + + return ptr; +} diff --git a/lk/target/qsd8250_ffa/include/target/display.h b/lk/target/qsd8250_ffa/include/target/display.h new file mode 100644 index 0000000..5a246ee --- /dev/null +++ b/lk/target/qsd8250_ffa/include/target/display.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _TARGET_QSD8250_FFA_DISPLAY_H +#define _TARGET_QSD8250_FFA_DISPLAY_H + +#define TARGET_XRES 480 +#define TARGET_YRES 800 + +#define LCDC_FB_WIDTH 800 +#define LCDC_FB_HEIGHT 480 + +#define LCDC_HSYNC_PULSE_WIDTH_DCLK 60 +#define LCDC_HSYNC_BACK_PORCH_DCLK 81 +#define LCDC_HSYNC_FRONT_PORCH_DCLK 81 +#define LCDC_HSYNC_SKEW_DCLK 0 + +#define LCDC_VSYNC_PULSE_WIDTH_LINES 2 +#define LCDC_VSYNC_BACK_PORCH_LINES 20 +#define LCDC_VSYNC_FRONT_PORCH_LINES 27 + +#endif diff --git a/lk/target/qsd8250_ffa/init.c b/lk/target/qsd8250_ffa/init.c new file mode 100644 index 0000000..2481043 --- /dev/null +++ b/lk/target/qsd8250_ffa/init.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include +#include + +#define LINUX_MACHTYPE 2710 + +#define VARIABLE_LENGTH 0x10101010 +#define DIFF_START_ADDR 0xF0F0F0F0 +#define NUM_PAGES_PER_BLOCK 0x40 + +static struct ptable flash_ptable; + +/* for these partitions, start will be offset by either what we get from + * smem, or from the above offset if smem is not useful. Also, we should + * probably have smem_ptable code populate our flash_ptable. + * + * When smem provides us with a full partition table, we can get rid of + * this altogether. + * + */ +static struct ptentry board_part_list[] = { + { + .start = 0, + .length = 5 /* In MB */, + .name = "boot", + }, + { + .start = DIFF_START_ADDR, + .length = 100 /* In MB */, + .name = "system", + }, + { + .start = DIFF_START_ADDR, + .length = 30 /* In MB */, + .name = "cache", + }, + { + .start = DIFF_START_ADDR, + .length = 1 /* In MB */, + .name = "misc", + }, + { + .start = DIFF_START_ADDR, + .length = VARIABLE_LENGTH, + .name = "userdata", + }, + { + .start = DIFF_START_ADDR, + .length = 5 /* In MB */, + .name = "recovery", + }, +}; +static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry); + +void smem_ptable_init(void); +unsigned smem_get_apps_flash_start(void); +void usb_charger_change_state(void); +void usb_charger_reset(void); +void usb_stop_charging(unsigned); +void keypad_init(void); + +void target_init(void) +{ + unsigned offset; + struct flash_info *flash_info; + unsigned total_num_of_blocks; + unsigned next_ptr_start_adr = 0; + unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/ + int i; + + dprintf(INFO, "target_init()\n"); + +#if (!ENABLE_NANDWRITE) + keys_init(); + keypad_init(); +#endif + ptable_init(&flash_ptable); + smem_ptable_init(); + + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + + offset = smem_get_apps_flash_start(); + if (offset == 0xffffffff) + while(1); + + total_num_of_blocks = flash_info->num_blocks; + blocks_per_1MB = (1 << 20) / (flash_info->block_size); + + for (i = 0; i < num_parts; i++) { + struct ptentry *ptn = &board_part_list[i]; + unsigned len = ((ptn->length) * blocks_per_1MB); + + if(ptn->start != 0) + ASSERT(ptn->start == DIFF_START_ADDR); + + ptn->start = next_ptr_start_adr; + + if(ptn->length == VARIABLE_LENGTH) + { + unsigned length_for_prt = 0; + unsigned j; + for (j = i+1; j < num_parts; j++) + { + struct ptentry *temp_ptn = &board_part_list[j]; + ASSERT(temp_ptn->length != VARIABLE_LENGTH); + length_for_prt += ((temp_ptn->length) * blocks_per_1MB); + } + len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); + ASSERT(len >= 0); + } + + next_ptr_start_adr = ptn->start + len; + ptable_add(&flash_ptable, ptn->name, offset + ptn->start, + len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); + } + + smem_add_modem_partitions(&flash_ptable); + + ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +unsigned board_machtype(void) +{ + return LINUX_MACHTYPE; +} + +void reboot_device(unsigned reboot_reason) +{ + reboot(reboot_reason); +} + +unsigned check_reboot_mode(void) +{ + unsigned mode[2] = {0, 0}; + unsigned int mode_len = sizeof(mode); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE, + &mode, mode_len ); + if(smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n"); + return 0; + } + return mode[0]; +} + +void target_battery_charging_enable(unsigned enable, unsigned disconnect) +{ + if(disconnect){ + usb_charger_reset(); + return; + } + else + usb_stop_charging(!enable); + + for(;;) + { + thread_sleep(10); + usb_charger_change_state(); + } +} diff --git a/lk/target/qsd8250_ffa/keypad.c b/lk/target/qsd8250_ffa/keypad.c new file mode 100644 index 0000000..2956336 --- /dev/null +++ b/lk/target/qsd8250_ffa/keypad.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +/* don't turn this on without updating the ffa support */ +#define SCAN_FUNCTION_KEYS 0 + +static unsigned int halibut_row_gpios[] = { + 31, 32, 33, 34, 35, 36 +#if SCAN_FUNCTION_KEYS + , 42 +#endif +}; + +static unsigned int halibut_col_gpios[] = { 38, 39, 40, 41, 42 }; + +#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(halibut_col_gpios) + (col)) + +static const unsigned short halibut_keymap[ARRAY_SIZE(halibut_col_gpios) * ARRAY_SIZE(halibut_row_gpios)] = { + [KEYMAP_INDEX(0, 0)] = KEY_VOLUMEDOWN, + /*[KEYMAP_INDEX(0, 1)] = ,*/ + [KEYMAP_INDEX(0, 2)] = KEY_DOWN, + [KEYMAP_INDEX(0, 3)] = KEY_8, + [KEYMAP_INDEX(0, 4)] = KEY_5, + + [KEYMAP_INDEX(1, 0)] = KEY_UP, + [KEYMAP_INDEX(1, 1)] = KEY_CLEAR, + [KEYMAP_INDEX(1, 2)] = KEY_4, + /*[KEYMAP_INDEX(1, 3)] = ,*/ + [KEYMAP_INDEX(1, 4)] = KEY_2, + + [KEYMAP_INDEX(2, 0)] = KEY_HOME, /* A */ + [KEYMAP_INDEX(2, 1)] = KEY_BACK, /* B */ + [KEYMAP_INDEX(2, 2)] = KEY_0, + [KEYMAP_INDEX(2, 3)] = 228, /* KEY_SHARP */ + [KEYMAP_INDEX(2, 4)] = KEY_9, + + [KEYMAP_INDEX(3, 0)] = KEY_3, + [KEYMAP_INDEX(3, 1)] = KEY_RIGHT, + [KEYMAP_INDEX(3, 2)] = KEY_VOLUMEUP, + /*[KEYMAP_INDEX(3, 3)] = ,*/ + [KEYMAP_INDEX(3, 4)] = KEY_6, + + [KEYMAP_INDEX(4, 0)] = 232, /* OK */ + [KEYMAP_INDEX(4, 1)] = KEY_SOUND, + [KEYMAP_INDEX(4, 2)] = KEY_1, + [KEYMAP_INDEX(4, 3)] = KEY_SEND, + [KEYMAP_INDEX(4, 4)] = KEY_LEFT, + + /*[KEYMAP_INDEX(5, 0)] = ,*/ + [KEYMAP_INDEX(5, 1)] = 227, /* KEY_STAR */ + [KEYMAP_INDEX(5, 2)] = 230, /* (SOFT2)2 */ + [KEYMAP_INDEX(5, 3)] = KEY_MENU, /* 1 */ + [KEYMAP_INDEX(5, 4)] = KEY_7, + +#if SCAN_FUNCTION_KEYS + [KEYMAP_INDEX(6, 0)] = KEY_F5, + [KEYMAP_INDEX(6, 1)] = KEY_F4, + [KEYMAP_INDEX(6, 2)] = KEY_F3, + [KEYMAP_INDEX(6, 3)] = KEY_F2, + [KEYMAP_INDEX(6, 4)] = KEY_F1 +#endif +}; + +static struct gpio_keypad_info halibut_keypad_info = { + .keymap = halibut_keymap, + .output_gpios = halibut_row_gpios, + .input_gpios = halibut_col_gpios, + .noutputs = ARRAY_SIZE(halibut_row_gpios), + .ninputs = ARRAY_SIZE(halibut_col_gpios), + .settle_time = 5 /* msec */, + .poll_time = 20 /* msec */, + .flags = GPIOKPF_DRIVE_INACTIVE, +}; + +void keypad_init(void) +{ + gpio_keypad_init(&halibut_keypad_info); +} diff --git a/lk/target/qsd8250_ffa/rules.mk b/lk/target/qsd8250_ffa/rules.mk new file mode 100644 index 0000000..1a639fc --- /dev/null +++ b/lk/target/qsd8250_ffa/rules.mk @@ -0,0 +1,38 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared + +PLATFORM := qsd8k + +MEMBASE := 0x00000000 # SMI +MEMSIZE := 0x00100000 # 1MB + +BASE_ADDR := 0x20000000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00008000 +RAMDISK_ADDR := BASE_ADDR+0x01000000 +SCRATCH_ADDR := BASE_ADDR+0x04000000 + +KEYS_USE_GPIO_KEYPAD := 1 + +DEFINES += ENABLE_BATTERY_CHARGING=1 +DEFINES += DISPLAY_SPLASH_SCREEN=1 +DEFINES += DISPLAY_TYPE_MDDI=1 + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/atags.o \ + $(LOCAL_DIR)/keypad.o diff --git a/lk/target/qsd8250_ffa/tools/makefile b/lk/target/qsd8250_ffa/tools/makefile new file mode 100644 index 0000000..9d3897d --- /dev/null +++ b/lk/target/qsd8250_ffa/tools/makefile @@ -0,0 +1,30 @@ +#Makefile to generate appsboot.mbn + +ifeq ($(BOOTLOADER_OUT),.) +APPSBOOTHEADER_DIR := $(BUILDDIR) +else +APPSBOOTHEADER_DIR := $(BOOTLOADER_OUT)/../../ +endif + +SRC_DIR := target/$(TARGET)/tools +COMPILER := gcc + +ifeq ($(BUILD_NANDWRITE), 1) + APPSBOOTHDR_FILES := +else + APPSBOOTHDR_FILES := appsboot.mbn +endif + +APPSBOOTHEADER: $(APPSBOOTHDR_FILES) + + +appsboot.mbn: appsboothd.mbn $(OUTBIN) + cat $(APPSBOOTHEADER_DIR)/appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/appsboot.mbn + rm -rf $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +mkheader: $(SRC_DIR)/mkheader.c + ${COMPILER} $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader + diff --git a/lk/target/qsd8250_ffa/tools/mkheader.c b/lk/target/qsd8250_ffa/tools/mkheader.c new file mode 100644 index 0000000..302bea2 --- /dev/null +++ b/lk/target/qsd8250_ffa/tools/mkheader.c @@ -0,0 +1,55 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + struct stat s; + unsigned size, base; + unsigned magic[10]; + int fd; + + if(argc != 3) { + fprintf(stderr,"usage: mkheader \n"); + return -1; + } + + if(stat(argv[1], &s)) { + perror("cannot stat binary"); + return -1; + } + + size = s.st_size; + base = 0; + + magic[0] = 0x00000005; /* appsbl */ + magic[1] = 0x00000002; /* nand */ + magic[2] = 0x00000000; + magic[3] = base; + magic[4] = size; + magic[5] = size; + magic[6] = size + base; + magic[7] = 0x00000000; + magic[8] = size + base; + magic[9] = 0x00000000; + + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd < 0) { + perror("cannot open header for writing"); + return -1; + } + if(write(fd, magic, sizeof(magic)) != sizeof(magic)) { + perror("cannot write header"); + close(fd); + unlink(argv[2]); + return -1; + } + close(fd); + + return 0; +} diff --git a/lk/target/qsd8250_surf/atags.c b/lk/target/qsd8250_surf/atags.c new file mode 100644 index 0000000..77a1fb8 --- /dev/null +++ b/lk/target/qsd8250_surf/atags.c @@ -0,0 +1,82 @@ +/* Copyright (c) 2009, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#define EBI1_SIZE1 0x0E800000 //232MB for 256/512/1024MB RAM +#define EBI1_ADDR1 0x20000000 + +#define EBI1_SIZE2_512M 0x10000000 //256MB for 512MB RAM +#define EBI1_SIZE2_1G 0x30000000 //768MB for 1GB RAM +#define EBI1_ADDR2 0x30000000 + +static unsigned check_1gb_mem() +{ + // check for 1GB + unsigned adr1 = 0x57000000; + unsigned adr2 = 0x5F000000; + unsigned value1 = 0x55555555; + unsigned value2 = 0xAAAAAAAA; + + writel(value1, adr1); + writel(value2, adr2); + + return ((value1 == readl(adr1)) && (value2 == readl(adr2))); +} + + +unsigned* target_atag_mem(unsigned* ptr) +{ + unsigned size; + + /* ATAG_MEM */ + /* 1st segment */ + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = EBI1_SIZE1; + *ptr++ = EBI1_ADDR1; + + /* 2nd segment */ +#ifdef USE_512M_RAM + size = EBI1_SIZE2_512M; +#else + size = 0; +#endif + if (check_1gb_mem()) { + size = EBI1_SIZE2_1G; + } + + if (size > 0) { + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = size; + *ptr++ = EBI1_ADDR2; + } + + return ptr; +} diff --git a/lk/target/qsd8250_surf/include/target/display.h b/lk/target/qsd8250_surf/include/target/display.h new file mode 100644 index 0000000..6ccea86 --- /dev/null +++ b/lk/target/qsd8250_surf/include/target/display.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _TARGET_QSD8250_SURF_DISPLAY_H +#define _TARGET_QSD8250_SURF_DISPLAY_H + +#define TARGET_XRES 800 +#define TARGET_YRES 480 + +#define LCDC_FB_WIDTH 800 +#define LCDC_FB_HEIGHT 480 + +#define LCDC_HSYNC_PULSE_WIDTH_DCLK 60 +#define LCDC_HSYNC_BACK_PORCH_DCLK 81 +#define LCDC_HSYNC_FRONT_PORCH_DCLK 81 +#define LCDC_HSYNC_SKEW_DCLK 0 + +#define LCDC_VSYNC_PULSE_WIDTH_LINES 2 +#define LCDC_VSYNC_BACK_PORCH_LINES 20 +#define LCDC_VSYNC_FRONT_PORCH_LINES 27 + +#endif diff --git a/lk/target/qsd8250_surf/init.c b/lk/target/qsd8250_surf/init.c new file mode 100644 index 0000000..58e84a4 --- /dev/null +++ b/lk/target/qsd8250_surf/init.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include +#include + +#define LINUX_MACHTYPE 2708 + +#define VARIABLE_LENGTH 0x10101010 +#define DIFF_START_ADDR 0xF0F0F0F0 +#define NUM_PAGES_PER_BLOCK 0x40 + +static struct ptable flash_ptable; + +/* for these partitions, start will be offset by either what we get from + * smem, or from the above offset if smem is not useful. Also, we should + * probably have smem_ptable code populate our flash_ptable. + * + * When smem provides us with a full partition table, we can get rid of + * this altogether. + * + */ +static struct ptentry board_part_list[] = { + { + .start = 0, + .length = 5 /* In MB */, + .name = "boot", + }, + { + .start = DIFF_START_ADDR, + .length = 100 /* In MB */, + .name = "system", + }, + { + .start = DIFF_START_ADDR, + .length = 30 /* In MB */, + .name = "cache", + }, + { + .start = DIFF_START_ADDR, + .length = 1 /* In MB */, + .name = "misc", + }, + { + .start = DIFF_START_ADDR, + .length = VARIABLE_LENGTH, + .name = "userdata", + }, + { + .start = DIFF_START_ADDR, + .length = 5 /* In MB */, + .name = "recovery", + }, +}; +static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry); + +void smem_ptable_init(void); +unsigned smem_get_apps_flash_start(void); +void usb_charger_change_state(void); +void usb_charger_reset(void); +void usb_stop_charging(unsigned); +void keypad_init(void); + +void target_init(void) +{ + unsigned offset; + struct flash_info *flash_info; + unsigned total_num_of_blocks; + unsigned next_ptr_start_adr = 0; + unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/ + int i; + + dprintf(INFO, "target_init()\n"); + +#if (!ENABLE_NANDWRITE) + keys_init(); + keypad_init(); +#endif + ptable_init(&flash_ptable); + smem_ptable_init(); + + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + + offset = smem_get_apps_flash_start(); + if (offset == 0xffffffff) + while(1); + + total_num_of_blocks = flash_info->num_blocks; + blocks_per_1MB = (1 << 20) / (flash_info->block_size); + + for (i = 0; i < num_parts; i++) { + struct ptentry *ptn = &board_part_list[i]; + unsigned len = ((ptn->length) * blocks_per_1MB); + + if(ptn->start != 0) + ASSERT(ptn->start == DIFF_START_ADDR); + + ptn->start = next_ptr_start_adr; + + if(ptn->length == VARIABLE_LENGTH) + { + unsigned length_for_prt = 0; + unsigned j; + for (j = i+1; j < num_parts; j++) + { + struct ptentry *temp_ptn = &board_part_list[j]; + ASSERT(temp_ptn->length != VARIABLE_LENGTH); + length_for_prt += ((temp_ptn->length) * blocks_per_1MB); + } + len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); + ASSERT(len >= 0); + } + + next_ptr_start_adr = ptn->start + len; + ptable_add(&flash_ptable, ptn->name, offset + ptn->start, + len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); + } + + smem_add_modem_partitions(&flash_ptable); + + ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +unsigned board_machtype(void) +{ + return LINUX_MACHTYPE; +} + +void reboot_device(unsigned reboot_reason) +{ + reboot(reboot_reason); +} + +unsigned check_reboot_mode(void) +{ + unsigned mode[2] = {0, 0}; + unsigned int mode_len = sizeof(mode); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE, + &mode, mode_len ); + if(smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n"); + return 0; + } + return mode[0]; +} + +void target_battery_charging_enable(unsigned enable, unsigned disconnect) +{ + if(disconnect){ + usb_charger_reset(); + return; + } + else + usb_stop_charging(!enable); + + for(;;) + { + thread_sleep(10); + usb_charger_change_state(); + } +} diff --git a/lk/target/qsd8250_surf/keypad.c b/lk/target/qsd8250_surf/keypad.c new file mode 100644 index 0000000..c44b06d --- /dev/null +++ b/lk/target/qsd8250_surf/keypad.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +/* don't turn this on without updating the ffa support */ +#define SCAN_FUNCTION_KEYS 0 + +static unsigned int halibut_row_gpios[] = { + 31, 32, 33, 34, 35, 41 +#if SCAN_FUNCTION_KEYS + , 42 +#endif +}; + +static unsigned int halibut_col_gpios[] = { 36, 37, 38, 39, 40 }; + +#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(halibut_col_gpios) + (col)) + +static const unsigned short halibut_keymap[ARRAY_SIZE(halibut_col_gpios) * ARRAY_SIZE(halibut_row_gpios)] = { + [KEYMAP_INDEX(0, 0)] = KEY_5, + [KEYMAP_INDEX(0, 1)] = KEY_9, + [KEYMAP_INDEX(0, 2)] = KEY_SOFT1, + [KEYMAP_INDEX(0, 3)] = KEY_6, + [KEYMAP_INDEX(0, 4)] = KEY_LEFT, + + [KEYMAP_INDEX(1, 0)] = KEY_0, + [KEYMAP_INDEX(1, 1)] = KEY_RIGHT, + [KEYMAP_INDEX(1, 2)] = KEY_1, + [KEYMAP_INDEX(1, 3)] = KEY_SHARP, + [KEYMAP_INDEX(1, 4)] = KEY_SEND, + + [KEYMAP_INDEX(2, 0)] = KEY_VOLUMEUP, + [KEYMAP_INDEX(2, 1)] = KEY_HOME, /* FA */ + [KEYMAP_INDEX(2, 2)] = KEY_F8, /* QCHT */ + [KEYMAP_INDEX(2, 3)] = KEY_F6, /* R+ */ + [KEYMAP_INDEX(2, 4)] = KEY_F7, /* R- */ + + [KEYMAP_INDEX(3, 0)] = KEY_UP, + [KEYMAP_INDEX(3, 1)] = KEY_CLEAR, + [KEYMAP_INDEX(3, 2)] = KEY_4, + [KEYMAP_INDEX(3, 3)] = KEY_MUTE, /* SPKR */ + [KEYMAP_INDEX(3, 4)] = KEY_2, + + [KEYMAP_INDEX(4, 0)] = KEY_SOFT2, /* SOFT2 */ + [KEYMAP_INDEX(4, 1)] = KEY_CENTER, /* KEY_CENTER */ + [KEYMAP_INDEX(4, 2)] = KEY_DOWN, + [KEYMAP_INDEX(4, 3)] = KEY_BACK, /* FB */ + [KEYMAP_INDEX(4, 4)] = KEY_8, + + [KEYMAP_INDEX(5, 0)] = KEY_VOLUMEDOWN, + [KEYMAP_INDEX(5, 1)] = KEY_STAR, /* KEY_STAR */ + [KEYMAP_INDEX(5, 2)] = KEY_MAIL, /* MESG */ + [KEYMAP_INDEX(5, 3)] = KEY_3, + [KEYMAP_INDEX(5, 4)] = KEY_7, + +#if SCAN_FUNCTION_KEYS + [KEYMAP_INDEX(6, 0)] = KEY_F5, + [KEYMAP_INDEX(6, 1)] = KEY_F4, + [KEYMAP_INDEX(6, 2)] = KEY_F3, + [KEYMAP_INDEX(6, 3)] = KEY_F2, + [KEYMAP_INDEX(6, 4)] = KEY_F1 +#endif +}; + +static struct gpio_keypad_info halibut_keypad_info = { + .keymap = halibut_keymap, + .output_gpios = halibut_row_gpios, + .input_gpios = halibut_col_gpios, + .noutputs = ARRAY_SIZE(halibut_row_gpios), + .ninputs = ARRAY_SIZE(halibut_col_gpios), + .settle_time = 5 /* msec */, + .poll_time = 20 /* msec */, + .flags = GPIOKPF_DRIVE_INACTIVE, +}; + +void keypad_init(void) +{ + gpio_keypad_init(&halibut_keypad_info); +} diff --git a/lk/target/qsd8250_surf/rules.mk b/lk/target/qsd8250_surf/rules.mk new file mode 100644 index 0000000..49ff8dd --- /dev/null +++ b/lk/target/qsd8250_surf/rules.mk @@ -0,0 +1,39 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared + +PLATFORM := qsd8k + +MEMBASE := 0x00000000 # SMI +MEMSIZE := 0x00100000 # 1MB + +BASE_ADDR := 0x20000000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00008000 +RAMDISK_ADDR := BASE_ADDR+0x01000000 +SCRATCH_ADDR := BASE_ADDR+0x04000000 + +KEYS_USE_GPIO_KEYPAD := 1 + +DEFINES += ENABLE_BATTERY_CHARGING=1 +DEFINES += DISPLAY_SPLASH_SCREEN=1 +DEFINES += DISPLAY_TYPE_LCDC=1 + + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/atags.o \ + $(LOCAL_DIR)/keypad.o diff --git a/lk/target/qsd8250_surf/tools/makefile b/lk/target/qsd8250_surf/tools/makefile new file mode 100644 index 0000000..9d3897d --- /dev/null +++ b/lk/target/qsd8250_surf/tools/makefile @@ -0,0 +1,30 @@ +#Makefile to generate appsboot.mbn + +ifeq ($(BOOTLOADER_OUT),.) +APPSBOOTHEADER_DIR := $(BUILDDIR) +else +APPSBOOTHEADER_DIR := $(BOOTLOADER_OUT)/../../ +endif + +SRC_DIR := target/$(TARGET)/tools +COMPILER := gcc + +ifeq ($(BUILD_NANDWRITE), 1) + APPSBOOTHDR_FILES := +else + APPSBOOTHDR_FILES := appsboot.mbn +endif + +APPSBOOTHEADER: $(APPSBOOTHDR_FILES) + + +appsboot.mbn: appsboothd.mbn $(OUTBIN) + cat $(APPSBOOTHEADER_DIR)/appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/appsboot.mbn + rm -rf $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +mkheader: $(SRC_DIR)/mkheader.c + ${COMPILER} $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader + diff --git a/lk/target/qsd8250_surf/tools/mkheader.c b/lk/target/qsd8250_surf/tools/mkheader.c new file mode 100644 index 0000000..302bea2 --- /dev/null +++ b/lk/target/qsd8250_surf/tools/mkheader.c @@ -0,0 +1,55 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + struct stat s; + unsigned size, base; + unsigned magic[10]; + int fd; + + if(argc != 3) { + fprintf(stderr,"usage: mkheader \n"); + return -1; + } + + if(stat(argv[1], &s)) { + perror("cannot stat binary"); + return -1; + } + + size = s.st_size; + base = 0; + + magic[0] = 0x00000005; /* appsbl */ + magic[1] = 0x00000002; /* nand */ + magic[2] = 0x00000000; + magic[3] = base; + magic[4] = size; + magic[5] = size; + magic[6] = size + base; + magic[7] = 0x00000000; + magic[8] = size + base; + magic[9] = 0x00000000; + + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd < 0) { + perror("cannot open header for writing"); + return -1; + } + if(write(fd, magic, sizeof(magic)) != sizeof(magic)) { + perror("cannot write header"); + close(fd); + unlink(argv[2]); + return -1; + } + close(fd); + + return 0; +} diff --git a/lk/target/qsd8650a_st1x/atags.c b/lk/target/qsd8650a_st1x/atags.c new file mode 100644 index 0000000..90dfa75 --- /dev/null +++ b/lk/target/qsd8650a_st1x/atags.c @@ -0,0 +1,56 @@ +/* Copyright (c) 2009-2010, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#define EBI1_SIZE1 0x0E000000 //224M +#define EBI1_ADDR1 0x00000000 + +#define EBI1_SIZE2 0x30000000 //768M +#define EBI1_ADDR2 0x10000000 + + +unsigned* target_atag_mem(unsigned* ptr) +{ + unsigned size; + + /* ATAG_MEM */ + /* 1st segment */ + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = EBI1_SIZE1; + *ptr++ = EBI1_ADDR1; + + /* 2nd segment */ + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = EBI1_SIZE2; + *ptr++ = EBI1_ADDR2; + + return ptr; +} diff --git a/lk/target/qsd8650a_st1x/include/target/display.h b/lk/target/qsd8650a_st1x/include/target/display.h new file mode 100644 index 0000000..03f2676 --- /dev/null +++ b/lk/target/qsd8650a_st1x/include/target/display.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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 _TARGET_QSD8650A_ST1X_DISPLAY_H +#define _TARGET_QSD8650A_ST1X_DISPLAY_H + +#define TARGET_XRES 800 +#define TARGET_YRES 480 + +#define LCDC_FB_WIDTH 800 +#define LCDC_FB_HEIGHT 480 + +#define LCDC_HSYNC_PULSE_WIDTH_DCLK 60 +#define LCDC_HSYNC_BACK_PORCH_DCLK 81 +#define LCDC_HSYNC_FRONT_PORCH_DCLK 81 +#define LCDC_HSYNC_SKEW_DCLK 0 + +#define LCDC_VSYNC_PULSE_WIDTH_LINES 2 +#define LCDC_VSYNC_BACK_PORCH_LINES 20 +#define LCDC_VSYNC_FRONT_PORCH_LINES 27 + +#endif diff --git a/lk/target/qsd8650a_st1x/init.c b/lk/target/qsd8650a_st1x/init.c new file mode 100644 index 0000000..68ef80a --- /dev/null +++ b/lk/target/qsd8650a_st1x/init.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include +#include + +#define LINUX_MACHTYPE 2627 + +#define VARIABLE_LENGTH 0x10101010 +#define DIFF_START_ADDR 0xF0F0F0F0 +#define NUM_PAGES_PER_BLOCK 0x40 + +static struct ptable flash_ptable; + +/* for these partitions, start will be offset by either what we get from + * smem, or from the above offset if smem is not useful. Also, we should + * probably have smem_ptable code populate our flash_ptable. + * + * When smem provides us with a full partition table, we can get rid of + * this altogether. + * + */ +static struct ptentry board_part_list[] = { + { + .start = 0, + .length = 40 /* 5MB */, + .name = "boot", + }, + { + .start = 40, + .length = 800 /* 100MB */, + .name = "system", + }, + { + .start = 840, + .length = 240 /* 30MB */, + .name = "cache", + }, + { + .start = 1080, + .length = 3 /* 384KB */, + .name = "misc", + }, + { + .start = 1083, + .length = VARIABLE_LENGTH, + .name = "userdata", + }, + { + .start = DIFF_START_ADDR, + .length = 40 /* 5MB */, + .name = "recovery", + }, +}; +static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry); + +void smem_ptable_init(void); +unsigned smem_get_apps_flash_start(void); +void usb_charger_change_state(void); +void usb_charger_reset(void); +void usb_stop_charging(unsigned); +void keypad_init(void); + +void target_init(void) +{ + unsigned offset; + struct flash_info *flash_info; + unsigned total_num_of_blocks; + bool start_addr_changed = false; + unsigned next_ptr_start_adr = 0; + int i; + + dprintf(INFO, "target_init()\n"); + +#if (!ENABLE_NANDWRITE) + keys_init(); + keypad_init(); +#endif + ptable_init(&flash_ptable); + smem_ptable_init(); + + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + + offset = smem_get_apps_flash_start(); + if (offset == 0xffffffff) + while(1); + + total_num_of_blocks = flash_info->num_blocks; + + for (i = 0; i < num_parts; i++) { + struct ptentry *ptn = &board_part_list[i]; + unsigned len = ptn->length; + + if(len == VARIABLE_LENGTH) + { + start_addr_changed = true; + unsigned length_for_prt = 0; + unsigned j; + for (j = i+1; j < num_parts; j++) + { + struct ptentry *temp_ptn = &board_part_list[j]; + ASSERT(temp_ptn->length != VARIABLE_LENGTH); + length_for_prt += temp_ptn->length; + } + len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt); + ASSERT(len >= 0); + next_ptr_start_adr = ptn->start + len; + } + if((ptn->start == DIFF_START_ADDR) && (start_addr_changed)) + { + ASSERT(next_ptr_start_adr); + ptn->start = next_ptr_start_adr; + next_ptr_start_adr = ptn->start + ptn->length; + } + ptable_add(&flash_ptable, ptn->name, offset + ptn->start, + len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE); + } + + smem_add_modem_partitions(&flash_ptable); + + ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +unsigned board_machtype(void) +{ + return LINUX_MACHTYPE; +} + +void reboot_device(unsigned reboot_reason) +{ + reboot(reboot_reason); +} + +unsigned check_reboot_mode(void) +{ + unsigned mode[2] = {0, 0}; + unsigned int mode_len = sizeof(mode); + unsigned smem_status; + + smem_status = smem_read_alloc_entry(SMEM_APPS_BOOT_MODE, + &mode, mode_len ); + if(smem_status) + { + dprintf(CRITICAL, "ERROR: unable to read shared memory for reboot mode\n"); + return 0; + } + return mode[0]; +} + +void target_battery_charging_enable(unsigned enable, unsigned disconnect) +{ + if(disconnect){ + usb_charger_reset(); + return; + } + else + usb_stop_charging(!enable); + + for(;;) + { + thread_sleep(10); + usb_charger_change_state(); + } +} diff --git a/lk/target/qsd8650a_st1x/keypad.c b/lk/target/qsd8650a_st1x/keypad.c new file mode 100644 index 0000000..aeaa57f --- /dev/null +++ b/lk/target/qsd8650a_st1x/keypad.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009, Code Aurora Forum. 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 Google, Inc. 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. + */ + +#include +#include + +void keypad_init(void) +{ +} diff --git a/lk/target/qsd8650a_st1x/rules.mk b/lk/target/qsd8650a_st1x/rules.mk new file mode 100644 index 0000000..f8e8a79 --- /dev/null +++ b/lk/target/qsd8650a_st1x/rules.mk @@ -0,0 +1,38 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared + +PLATFORM := qsd8650a + +MEMBASE := 0xE0000000 # SMI +MEMSIZE := 0x00100000 # 1MB + +BASE_ADDR := 0x00000000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00008000 +RAMDISK_ADDR := BASE_ADDR+0x04000000 +SCRATCH_ADDR := BASE_ADDR+0x00008000 + +KEYS_USE_GPIO_KEYPAD := 1 + +DEFINES += ENABLE_BATTERY_CHARGING=0 +DEFINES += NO_KEYPAD_DRIVER=1 + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + MEMBASE=$(MEMBASE) \ + SDRAM_SIZE=$(MEMSIZE) \ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/atags.o \ + $(LOCAL_DIR)/keypad.o diff --git a/lk/target/qsd8650a_st1x/tools/makefile b/lk/target/qsd8650a_st1x/tools/makefile new file mode 100644 index 0000000..9d3897d --- /dev/null +++ b/lk/target/qsd8650a_st1x/tools/makefile @@ -0,0 +1,30 @@ +#Makefile to generate appsboot.mbn + +ifeq ($(BOOTLOADER_OUT),.) +APPSBOOTHEADER_DIR := $(BUILDDIR) +else +APPSBOOTHEADER_DIR := $(BOOTLOADER_OUT)/../../ +endif + +SRC_DIR := target/$(TARGET)/tools +COMPILER := gcc + +ifeq ($(BUILD_NANDWRITE), 1) + APPSBOOTHDR_FILES := +else + APPSBOOTHDR_FILES := appsboot.mbn +endif + +APPSBOOTHEADER: $(APPSBOOTHDR_FILES) + + +appsboot.mbn: appsboothd.mbn $(OUTBIN) + cat $(APPSBOOTHEADER_DIR)/appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/appsboot.mbn + rm -rf $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +appsboothd.mbn: mkheader $(OUTBIN) + $(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn + +mkheader: $(SRC_DIR)/mkheader.c + ${COMPILER} $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader + diff --git a/lk/target/qsd8650a_st1x/tools/mkheader.c b/lk/target/qsd8650a_st1x/tools/mkheader.c new file mode 100644 index 0000000..a6633db --- /dev/null +++ b/lk/target/qsd8650a_st1x/tools/mkheader.c @@ -0,0 +1,55 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + struct stat s; + unsigned size, base; + unsigned magic[10]; + int fd; + + if(argc != 3) { + fprintf(stderr,"usage: mkheader \n"); + return -1; + } + + if(stat(argv[1], &s)) { + perror("cannot stat binary"); + return -1; + } + + size = s.st_size; + base = 0xE0000000; + + magic[0] = 0x00000005; /* appsbl */ + magic[1] = 0x00000002; /* nand */ + magic[2] = 0x00000000; + magic[3] = base; + magic[4] = size; + magic[5] = size; + magic[6] = size + base; + magic[7] = 0x00000000; + magic[8] = size + base; + magic[9] = 0x00000000; + + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd < 0) { + perror("cannot open header for writing"); + return -1; + } + if(write(fd, magic, sizeof(magic)) != sizeof(magic)) { + perror("cannot write header"); + close(fd); + unlink(argv[2]); + return -1; + } + close(fd); + + return 0; +} diff --git a/lk/target/rules.mk b/lk/target/rules.mk new file mode 100644 index 0000000..8f1d297 --- /dev/null +++ b/lk/target/rules.mk @@ -0,0 +1,6 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +OBJS += \ + $(LOCAL_DIR)/init.o + + diff --git a/lk/target/sam7ex256/README b/lk/target/sam7ex256/README new file mode 100644 index 0000000..edf7b3d --- /dev/null +++ b/lk/target/sam7ex256/README @@ -0,0 +1,6 @@ +Olimex SAM7-EX256 Board +http://olimex.com/dev/sam7-ex256.html +http://olimex.com/dev/images/sam7-ex256-sch.gif + +This platform is a specialization of the generic platform/at91sam7 + diff --git a/lk/target/sam7ex256/include/platform/mux.def b/lk/target/sam7ex256/include/platform/mux.def new file mode 100644 index 0000000..3672df3 --- /dev/null +++ b/lk/target/sam7ex256/include/platform/mux.def @@ -0,0 +1,9 @@ +# debug uart +# +PA27 DRXD +PA28 DTXD + +# CAN +# +PA19 CANRX +PA20 CANTX diff --git a/lk/target/sam7ex256/include/platform/mux.h b/lk/target/sam7ex256/include/platform/mux.h new file mode 100644 index 0000000..3aa8940 --- /dev/null +++ b/lk/target/sam7ex256/include/platform/mux.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * 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. + */ +/* DO NOT EDIT -- AUTOGENERATED FROM 'include/platform/mux.def' */ + +#ifndef __BOARD_DEFINITION_FILE__ +#define __BOARD_DEFINITION_FILE__ + +#define PIN_DRXD (1 << 27) +#define PIN_DTXD (1 << 28) +#define PIN_CANRX (1 << 19) +#define PIN_CANTX (1 << 20) + +#define BOARD_OUTPUT_DISABLE 0xffffffff +#define BOARD_OUTPUT_ENABLE 0x00000000 +#define BOARD_PULLUP_DISABLE 0x18180000 +#define BOARD_PULLUP_ENABLE 0xe7e7ffff +#define BOARD_PIO_DISABLE 0x18180000 +#define BOARD_PIO_ENABLE 0xe7e7ffff +#define BOARD_SELECT_A 0x18180000 +#define BOARD_SELECT_B 0x00000000 + +#endif diff --git a/lk/target/sam7ex256/mkmux.sh b/lk/target/sam7ex256/mkmux.sh new file mode 100644 index 0000000..5f88abd --- /dev/null +++ b/lk/target/sam7ex256/mkmux.sh @@ -0,0 +1 @@ +../../platform/at91sam7/mkboard.py ../../platform/at91sam7/at91sam7x.pins include/platform/mux.def diff --git a/lk/target/sam7ex256/rules.mk b/lk/target/sam7ex256/rules.mk new file mode 100644 index 0000000..bcd3568 --- /dev/null +++ b/lk/target/sam7ex256/rules.mk @@ -0,0 +1,10 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +AT91CHIP := sam7x256 + +PLATFORM := at91sam7 + +INCLUDES += -I$(LOCAL_DIR)/include + +OBJS += + diff --git a/lk/target/surf-msm7k/atags.c b/lk/target/surf-msm7k/atags.c new file mode 100644 index 0000000..de0b95e --- /dev/null +++ b/lk/target/surf-msm7k/atags.c @@ -0,0 +1,43 @@ +/* Copyright (c) 2009, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#define EBI1_SIZE1 0x0CB00000 //203MB for 256 RAM +#define EBI1_ADDR1 0x00200000 + +unsigned* target_atag_mem(unsigned* ptr) +{ + /* ATAG_MEM */ + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = EBI1_SIZE1; + *ptr++ = EBI1_ADDR1; + + return ptr; +} diff --git a/lk/target/surf-msm7k/init.c b/lk/target/surf-msm7k/init.c new file mode 100644 index 0000000..956ea49 --- /dev/null +++ b/lk/target/surf-msm7k/init.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2009, Google 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include + +#define BOARD_FLASH_OFFSET 378 + +#define LINUX_MACHTYPE 0x0000059F + +static struct ptable flash_ptable; + +/* for these partitions, start will be offset by either what we get from + * smem, or from the above offset if smem is not useful. Also, we should + * probably have smem_ptable code populate our flash_ptable. + * + * When smem provides us with a full partition table, we can get rid of + * this altogether. + * + */ +static struct ptentry board_part_list[] = { + { + .start = 0, + .length = 40, + .name = "boot", + }, + { + .start = 56, + .length = 608 /* 76MB */, + .name = "system", + }, + { + .start = 664, + .length = 608 /* 76MB */, + .name = "cache", + }, + { + .start = 1272, + .length = 0, + .name = "userdata", + }, +}; +static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry); + +void smem_ptable_init(void); +unsigned smem_get_apps_flash_start(void); + +void keypad_init(void); + +void target_init(void) +{ + unsigned offset; + struct flash_info *flash_info; + int i; + + dprintf(INFO, "target_init()\n"); + + keys_init(); + keypad_init(); + + ptable_init(&flash_ptable); + smem_ptable_init(); + + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + + offset = smem_get_apps_flash_start(); + if (offset == 0xffffffff) + offset = BOARD_FLASH_OFFSET; + + for (i = 0; i < num_parts; i++) { + struct ptentry *ptn = &board_part_list[i]; + unsigned len = ptn->length; + + if ((len == 0) && (i == num_parts - 1)) + len = flash_info->num_blocks - offset - ptn->start; + ptable_add(&flash_ptable, ptn->name, offset + ptn->start, + len, ptn->flags); + } + + ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +unsigned board_machtype(void) +{ + return LINUX_MACHTYPE; +} diff --git a/lk/target/surf-msm7k/keypad.c b/lk/target/surf-msm7k/keypad.c new file mode 100644 index 0000000..f44032f --- /dev/null +++ b/lk/target/surf-msm7k/keypad.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009, Google 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 Google, Inc. 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. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +/* don't turn this on without updating the ffa support */ +#define SCAN_FUNCTION_KEYS 0 + +static unsigned int halibut_row_gpios[] = { + 31, 32, 33, 34, 35, 41 +#if SCAN_FUNCTION_KEYS + , 42 +#endif +}; + +static unsigned int halibut_col_gpios[] = { 36, 37, 38, 39, 40 }; + +#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(halibut_col_gpios) + (col)) + +static const unsigned short halibut_keymap[ARRAY_SIZE(halibut_col_gpios) * ARRAY_SIZE(halibut_row_gpios)] = { + [KEYMAP_INDEX(0, 0)] = KEY_5, + [KEYMAP_INDEX(0, 1)] = KEY_9, + [KEYMAP_INDEX(0, 2)] = KEY_SOFT1, + [KEYMAP_INDEX(0, 3)] = KEY_6, + [KEYMAP_INDEX(0, 4)] = KEY_LEFT, + + [KEYMAP_INDEX(1, 0)] = KEY_0, + [KEYMAP_INDEX(1, 1)] = KEY_RIGHT, + [KEYMAP_INDEX(1, 2)] = KEY_1, + [KEYMAP_INDEX(1, 3)] = KEY_SHARP, + [KEYMAP_INDEX(1, 4)] = KEY_SEND, + + [KEYMAP_INDEX(2, 0)] = KEY_VOLUMEUP, + [KEYMAP_INDEX(2, 1)] = KEY_HOME, /* FA */ + [KEYMAP_INDEX(2, 2)] = KEY_F8, /* QCHT */ + [KEYMAP_INDEX(2, 3)] = KEY_F6, /* R+ */ + [KEYMAP_INDEX(2, 4)] = KEY_F7, /* R- */ + + [KEYMAP_INDEX(3, 0)] = KEY_UP, + [KEYMAP_INDEX(3, 1)] = KEY_CLEAR, + [KEYMAP_INDEX(3, 2)] = KEY_4, + [KEYMAP_INDEX(3, 3)] = KEY_MUTE, /* SPKR */ + [KEYMAP_INDEX(3, 4)] = KEY_2, + + [KEYMAP_INDEX(4, 0)] = KEY_SOFT2, /* SOFT2 */ + [KEYMAP_INDEX(4, 1)] = KEY_CENTER, /* KEY_CENTER */ + [KEYMAP_INDEX(4, 2)] = KEY_DOWN, + [KEYMAP_INDEX(4, 3)] = KEY_BACK, /* FB */ + [KEYMAP_INDEX(4, 4)] = KEY_8, + + [KEYMAP_INDEX(5, 0)] = KEY_VOLUMEDOWN, + [KEYMAP_INDEX(5, 1)] = KEY_STAR, /* KEY_STAR */ + [KEYMAP_INDEX(5, 2)] = KEY_MAIL, /* MESG */ + [KEYMAP_INDEX(5, 3)] = KEY_3, + [KEYMAP_INDEX(5, 4)] = KEY_7, + +#if SCAN_FUNCTION_KEYS + [KEYMAP_INDEX(6, 0)] = KEY_F5, + [KEYMAP_INDEX(6, 1)] = KEY_F4, + [KEYMAP_INDEX(6, 2)] = KEY_F3, + [KEYMAP_INDEX(6, 3)] = KEY_F2, + [KEYMAP_INDEX(6, 4)] = KEY_F1 +#endif +}; + +static struct gpio_keypad_info halibut_keypad_info = { + .keymap = halibut_keymap, + .output_gpios = halibut_row_gpios, + .input_gpios = halibut_col_gpios, + .noutputs = ARRAY_SIZE(halibut_row_gpios), + .ninputs = ARRAY_SIZE(halibut_col_gpios), + .settle_time = 5 /* msec */, + .poll_time = 20 /* msec */, + .flags = GPIOKPF_DRIVE_INACTIVE, +}; + +void keypad_init(void) +{ + gpio_keypad_init(&halibut_keypad_info); +} diff --git a/lk/target/surf-msm7k/panel.c b/lk/target/surf-msm7k/panel.c new file mode 100644 index 0000000..c2b56a1 --- /dev/null +++ b/lk/target/surf-msm7k/panel.c @@ -0,0 +1,471 @@ +/* Copyright 2007, Google Inc. */ + +#include +#include +#include +#include + +#define MDDI_CLIENT_CORE_BASE 0x108000 +#define LCD_CONTROL_BLOCK_BASE 0x110000 +#define SPI_BLOCK_BASE 0x120000 +#define I2C_BLOCK_BASE 0x130000 +#define PWM_BLOCK_BASE 0x140000 +#define GPIO_BLOCK_BASE 0x150000 +#define SYSTEM_BLOCK1_BASE 0x160000 +#define SYSTEM_BLOCK2_BASE 0x170000 + + +#define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00) +#define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04) +#define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08) +#define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C) +#define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10) +#define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14) +#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18) +#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C) +#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20) +#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24) +#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28) +#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C) +#define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30) +#define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34) +#define INTMONI (MDDI_CLIENT_CORE_BASE|0x38) +#define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C) +#define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40) +#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44) +#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48) +#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C) +#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50) +#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54) + + +#define SRST (LCD_CONTROL_BLOCK_BASE|0x00) +#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04) +#define START (LCD_CONTROL_BLOCK_BASE|0x08) +#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C) +#define CMN (LCD_CONTROL_BLOCK_BASE|0x10) +#define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14) +#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18) +#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C) +#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20) +#define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24) +#define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28) + +#define PXL (LCD_CONTROL_BLOCK_BASE|0x30) +#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34) +#define HSW (LCD_CONTROL_BLOCK_BASE|0x38) +#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C) +#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40) +#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44) +#define VSW (LCD_CONTROL_BLOCK_BASE|0x48) +#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C) +#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50) +#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54) +#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58) +#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C) +#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60) +#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64) +#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68) +#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C) +#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70) +#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74) +#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78) +#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C) +#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80) +#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84) +#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88) +#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C) + +#define MONI (LCD_CONTROL_BLOCK_BASE|0xB0) + +#define Current (LCD_CONTROL_BLOCK_BASE|0xC0) +#define LCD (LCD_CONTROL_BLOCK_BASE|0xC4) +#define COMMAND (LCD_CONTROL_BLOCK_BASE|0xC8) + + +#define SSICTL (SPI_BLOCK_BASE|0x00) +#define SSITIME (SPI_BLOCK_BASE|0x04) +#define SSITX (SPI_BLOCK_BASE|0x08) +#define SSIRX (SPI_BLOCK_BASE|0x0C) +#define SSIINTC (SPI_BLOCK_BASE|0x10) +#define SSIINTS (SPI_BLOCK_BASE|0x14) +#define SSIDBG1 (SPI_BLOCK_BASE|0x18) +#define SSIDBG2 (SPI_BLOCK_BASE|0x1C) +#define SSIID (SPI_BLOCK_BASE|0x20) + + +#define I2CSETUP (I2C_BLOCK_BASE|0x00) +#define I2CCTRL (I2C_BLOCK_BASE|0x04) + + +#define TIMER0LOAD (PWM_BLOCK_BASE|0x00) +#define TIMER0VALUE (PWM_BLOCK_BASE|0x04) +#define TIMER0CONTROL (PWM_BLOCK_BASE|0x08) +#define TIMER0INTCLR (PWM_BLOCK_BASE|0x0C) +#define TIMER0RIS (PWM_BLOCK_BASE|0x10) +#define TIMER0MIS (PWM_BLOCK_BASE|0x14) +#define TIMER0BGLOAD (PWM_BLOCK_BASE|0x18) +#define PWM0OFF (PWM_BLOCK_BASE|0x1C) +#define TIMER1LOAD (PWM_BLOCK_BASE|0x20) +#define TIMER1VALUE (PWM_BLOCK_BASE|0x24) +#define TIMER1CONTROL (PWM_BLOCK_BASE|0x28) +#define TIMER1INTCLR (PWM_BLOCK_BASE|0x2C) +#define TIMER1RIS (PWM_BLOCK_BASE|0x30) +#define TIMER1MIS (PWM_BLOCK_BASE|0x34) +#define TIMER1BGLOAD (PWM_BLOCK_BASE|0x38) +#define PWM1OFF (PWM_BLOCK_BASE|0x3C) +#define TIMERITCR (PWM_BLOCK_BASE|0x60) +#define TIMERITOP (PWM_BLOCK_BASE|0x64) +#define PWMCR (PWM_BLOCK_BASE|0x68) +#define PWMID (PWM_BLOCK_BASE|0x6C) +#define PWMMON (PWM_BLOCK_BASE|0x70) + + +#define GPIODATA (GPIO_BLOCK_BASE|0x00) +#define GPIODIR (GPIO_BLOCK_BASE|0x04) +#define GPIOIS (GPIO_BLOCK_BASE|0x08) +#define GPIOIBE (GPIO_BLOCK_BASE|0x0C) +#define GPIOIEV (GPIO_BLOCK_BASE|0x10) +#define GPIOIE (GPIO_BLOCK_BASE|0x14) +#define GPIORIS (GPIO_BLOCK_BASE|0x18) +#define GPIOMIS (GPIO_BLOCK_BASE|0x1C) +#define GPIOIC (GPIO_BLOCK_BASE|0x20) +#define GPIOOMS (GPIO_BLOCK_BASE|0x24) +#define GPIOPC (GPIO_BLOCK_BASE|0x28) + +#define GPIOID (GPIO_BLOCK_BASE|0x30) + + +#define WKREQ (SYSTEM_BLOCK1_BASE|0x00) +#define CLKENB (SYSTEM_BLOCK1_BASE|0x04) +#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08) +#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C) +#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00) + +struct init_table { + unsigned int reg; + unsigned int val; +}; + +static struct init_table toshiba_480x640_init_table[] = { + { DPSET0, 0x4BEC0066 }, // # MDC.DPSET0 # Setup DPLL parameters + { DPSET1, 0x00000113 }, // # MDC.DPSET1 + { DPSUS, 0x00000000 }, // # MDC.DPSUS # Set DPLL oscillation enable + { DPRUN, 0x00000001 }, // # MDC.DPRUN # Release reset signal for DPLL + { 0, 14 }, // wait_ms(14); + { SYSCKENA, 0x00000001 }, // # MDC.SYSCKENA # Enable system clock output + { CLKENB, 0x000000EF }, // # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) + { GPIO_BLOCK_BASE, 0x03FF0000 }, // # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 + { GPIODIR, 0x0000024D }, // # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) + { SYSTEM_BLOCK2_BASE, 0x00000173 }, // # SYS.GPIOSEL # GPIO port multiplexing control + { GPIOPC, 0x03C300C0 }, // # GPI .GPIOPC # GPIO2,3 PD cut + { SYSTEM_BLOCK1_BASE, 0x00000000 }, // # SYS.WKREQ # Wake-up request event is VSYNC alignment + { GPIOIS, 0x00000000 }, // # GPI .GPIOIS # Set interrupt sense of GPIO + { GPIOIEV, 0x00000001 }, // # GPI .GPIOIEV # Set interrupt event of GPIO + { GPIOIC, 0x000003FF }, // # GPI .GPIOIC # GPIO interrupt clear + { GPIO_BLOCK_BASE, 0x00060006 }, // # GPI .GPIODATA # Release LCDD reset + { GPIO_BLOCK_BASE, 0x00080008 }, // # GPI .GPIODATA # eDRAM VD supply + { GPIO_BLOCK_BASE, 0x02000200 }, // # GPI .GPIODATA # TEST LED ON + { DRAMPWR, 0x00000001 }, // # SYS.DRAMPWR # eDRAM power up + { TIMER0CONTROL, 0x00000060 }, // # PWM.Timer0Control # PWM0 output stop + { PWM_BLOCK_BASE, 0x00001388 }, // # PWM.Timer0Load # PWM0 10kHz , Duty 99 (BackLight OFF) + //{PWM0OFF, 0x00000001 }, // # PWM.PWM0OFF +#if 0 + { PWM0OFF, 0x00001387 }, // SURF 100% backlight + { PWM0OFF, 0x00000000 }, // FFA 100% backlight +#endif + { PWM0OFF, 0x000009C3 }, // 50% BL + { TIMER1CONTROL, 0x00000060 }, // # PWM.Timer1Control # PWM1 output stop + { TIMER1LOAD, 0x00001388 }, // # PWM.Timer1Load # PWM1 10kHz , Duty 99 (BackLight OFF) + //{PWM1OFF, 0x00000001 }, // # PWM.PWM1OFF + { PWM1OFF, 0x00001387 }, + { TIMER0CONTROL, 0x000000E0 }, // # PWM.Timer0Control # PWM0 output start + { TIMER1CONTROL, 0x000000E0 }, // # PWM.Timer1Control # PWM1 output start + { PWMCR, 0x00000003 }, // # PWM.PWMCR # PWM output enable + { 0, 1 }, // wait_ms(1); + { SPI_BLOCK_BASE, 0x00000799 }, // # SPI .SSICTL # SPI operation mode setting + { SSITIME, 0x00000100 }, // # SPI .SSITIME # SPI serial interface timing setting + { SPI_BLOCK_BASE, 0x0000079b }, // # SPI .SSICTL # Set SPI active mode + + { SSITX, 0x00000000 }, // # SPI.SSITX # Release from Deep Stanby mode + { 0, 1 }, // wait_ms(1); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 1 }, // wait_ms(1); + { SSITX, 0x00000000 }, // # SPI.SSITX + { 0, 1 }, // wait_ms(1); + { SSITX, 0x000800BA }, // # SPI.SSITX *NOTE 1 # Command setting of SPI block + { SSITX, 0x00000111 }, // # Display mode setup(1) : Normaly Black + { SSITX, 0x00080036 }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Memory access control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BB }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Display mode setup(2) + { SSITX, 0x0008003A }, // # Command setting of SPI block + { SSITX, 0x00000160 }, // # RGB Interface data format + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BF }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Drivnig method + { SSITX, 0x000800B1 }, // # Command setting of SPI block + { SSITX, 0x0000015D }, // # Booster operation setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B2 }, // # Command setting of SPI block + { SSITX, 0x00000133 }, // # Booster mode setup + { SSITX, 0x000800B3 }, // # Command setting of SPI block + { SSITX, 0x00000122 }, // # Booster frequencies setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B4 }, // # Command setting of SPI block + { SSITX, 0x00000102 }, // # OP-amp capability/System clock freq. division setup + { SSITX, 0x000800B5 }, // # Command setting of SPI block + { SSITX, 0x0000011F }, // # VCS Voltage adjustment (1C->1F for Rev 2) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B6 }, // # Command setting of SPI block + { SSITX, 0x00000128 }, // # VCOM Voltage adjustment + { SSITX, 0x000800B7 }, // # Command setting of SPI block + { SSITX, 0x00000103 }, // # Configure an external display signal + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800B9 }, // # Command setting of SPI block + { SSITX, 0x00000120 }, // # DCCK/DCEV timing setup + { SSITX, 0x000800BD }, // # Command setting of SPI block + { SSITX, 0x00000102 }, // # ASW signal control + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800BE }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Dummy display (white/black) count setup for QUAD Data operation + { SSITX, 0x000800C0 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (A) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C1 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (B) + { SSITX, 0x000800C2 }, // # Command setting of SPI block + { SSITX, 0x00000111 }, // # wait_ms(-out FR count setup (C) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C3 }, // # Command setting of SPI block + { SSITX, 0x0008010A }, // # wait_ms(-in line clock count setup (D) + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C4 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # Seep-in line clock count setup (E) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C5 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # wait_ms(-in line clock count setup (F) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C6 }, // # Command setting of SPI block + { SSITX, 0x00080160 }, // # wait_ms(-in line clock setup (G) + { SSITX, 0x00000160 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C7 }, // # Command setting of SPI block + { SSITX, 0x00080133 }, // # Gamma 1 fine tuning (1) + { SSITX, 0x00000143 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800C8 }, // # Command setting of SPI block + { SSITX, 0x00000144 }, // # Gamma 1 fine tuning (2) + { SSITX, 0x000800C9 }, // # Command setting of SPI block + { SSITX, 0x00000133 }, // # Gamma 1 inclination adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CA }, // # Command setting of SPI block + { SSITX, 0x00000100 }, // # Gamma 1 blue offset adjustment + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800EC }, // # Command setting of SPI block + { SSITX, 0x00080102 }, // # Total number of horizontal clock cycles (1) [PCLK Sync. VGA setting] + { SSITX, 0x00000118 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800CF }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Blanking period control (1) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D0 }, // # Command setting of SPI block + { SSITX, 0x00080110 }, // # Blanking period control (2) [PCLK Sync. Table1 for VGA] + { SSITX, 0x00000104 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D1 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # CKV timing control on/off [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D2 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV1,2 timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000013A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D3 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # OEV timing control [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000013A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D4 }, // # Command setting of SPI block + { SSITX, 0x00080124 }, // # ASW timing control (1) [PCLK Sync. Table1 for VGA] + { SSITX, 0x0000016E }, // + { 0, 1 }, // wait_ms(1); // # Wait SPI fifo empty + { SSITX, 0x000800D5 }, // # Command setting of SPI block + { SSITX, 0x00000124 }, // # ASW timing control (2) [PCLK Sync. Table1 for VGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800ED }, // # Command setting of SPI block + { SSITX, 0x00080101 }, // # Total number of horizontal clock cycles (2) [PCLK Sync. Table1 for QVGA ] + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D6 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Blanking period control (1) [PCLK Sync. Table2 for QVGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D7 }, // # Command setting of SPI block + { SSITX, 0x00080110 }, // # Blanking period control (2) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D8 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # CKV timing control on/off [PCLK Sync. Table2 for QVGA] + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800D9 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV1,2 timing control [PCLK Sync. Table2 for QVGA] + { SSITX, 0x00000114 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800DE }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # OEV timing control [PCLK Sync. Table2 for QVGA] + { SSITX, 0x00000114 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800DF }, // # Command setting of SPI block + { SSITX, 0x00080112 }, // # ASW timing control (1) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x0000013F }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E0 }, // # Command setting of SPI block + { SSITX, 0x0000010B }, // # ASW timing control (2) [PCLK Sync. Table2 for QVGA] + { SSITX, 0x000800E2 }, // # Command setting of SPI block + { SSITX, 0x00000101 }, // # Built-in oscillator frequency division setup [Frequency division ratio : 2 (60Hq) + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E3 }, // # Command setting of SPI block + { SSITX, 0x00000136 }, // # Built-in oscillator clock count setup + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E4 }, // # Command setting of SPI block + { SSITX, 0x00080100 }, // # CKV timing control for using build-in osc + { SSITX, 0x00000103 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E5 }, // # Command setting of SPI block + { SSITX, 0x00080102 }, // # OEV timing control for using build-in osc + { SSITX, 0x00000104 }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E6 }, // # Command setting of SPI block + { SSITX, 0x00000103 }, // # DCEV timing control for using build-in osc + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E7 }, // # Command setting of SPI block + { SSITX, 0x00080104 }, // # ASW timing setup for using build-in osc(1) + { SSITX, 0x0000010A }, // + { 0, 2 }, // wait_ms(2); // # Wait SPI fifo empty + { SSITX, 0x000800E8 }, // # Command setting of SPI block + { SSITX, 0x00000104 }, // # ASW timing setup for using build-in osc(2) + + + { CLKENB, 0x000001EF }, // # SYS.CLKENB # DCLK enable + { START, 0x00000000 }, // # LCD.START # LCDC wait_ms( mode + { WRSTB, 0x0000003F }, // # LCD.WRSTB # write_client_reg( strobe + { RDSTB, 0x00000432 }, // # LCD.RDSTB # Read strobe + { PORT_ENB, 0x00000002 }, // # LCD.PORT_ENB # Asynchronous port enable + { VSYNIF, 0x00000000 }, // # LCD.VSYNCIF # VSYNC I/F mode set + { ASY_DATA, 0x80000000 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00000001 }, // # Oscillator start + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + { 0, 10 }, // wait_ms(10); + { ASY_DATA, 0x80000000 }, // # LCD.ASY_DATx # DUMMY write_client_reg(@*NOTE2 + { ASY_DATB, 0x80000000 }, // + { ASY_DATC, 0x80000000 }, // + { ASY_DATD, 0x80000000 }, // + { ASY_CMDSET, 0x00000009 }, // # LCD.ASY_CMDSET + { ASY_CMDSET, 0x00000008 }, // # LCD.ASY_CMDSET + { ASY_DATA, 0x80000007 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00004005 }, // # LCD driver control + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + { 0, 20 }, // wait_ms(20); + { ASY_DATA, 0x80000059 }, // # LCD.ASY_DATx # Index setting of SUB LCDD + { ASY_DATB, 0x00000000 }, // # LTPS I/F control + { ASY_CMDSET, 0x00000005 }, // # LCD.ASY_CMDSET # Direct command transfer enable + { ASY_CMDSET, 0x00000004 }, // # LCD.ASY_CMDSET # Direct command transfer disable + + { VSYNIF, 0x00000001 }, // # LCD.VSYNCIF # VSYNC I/F mode OFF + { PORT_ENB, 0x00000001 }, // # LCD.PORT_ENB # SYNC I/F output select + + /******************************/ + + { VSYNIF, 0x00000001 }, // VSYNC I/F mode OFF + { PORT_ENB, 0x00000001 }, // SYNC I/F mode ON + + { BITMAP1, 0x01E000F0 }, // MDC.BITMAP2 ); // Setup of PITCH size to Frame buffer1 + { BITMAP2, 0x01E000F0 }, // MDC.BITMAP3 ); // Setup of PITCH size to Frame buffer2 + { BITMAP3, 0x01E000F0 }, // MDC.BITMAP4 ); // Setup of PITCH size to Frame buffer3 + { BITMAP4, 0x00DC00B0 }, // MDC.BITMAP5 ); // Setup of PITCH size to Frame buffer4 + { CLKENB, 0x000001EF }, // SYS.CLKENB ); // DCLK supply + { PORT_ENB, 0x00000001 }, // LCD.PORT_ENB ); // Synchronous port enable + { PORT, 0x00000004 }, // LCD.PORT ); // Polarity of DE is set to high active + { PXL, 0x00000002 }, // LCD.PXL ); // ACTMODE 2 set (1st frame black data output) + { MPLFBUF, 0x00000000 }, // LCD.MPLFBUF ); // Select the reading buffer + { HCYCLE, 0x0000010b }, // LCD.HCYCLE ); // Setup to VGA size + { HSW, 0x00000003 }, // LCD.HSW + { HDE_START, 0x00000007 }, // LCD.HDE_START + { HDE_SIZE, 0x000000EF }, // LCD.HDE_SIZE + { VCYCLE, 0x00000285 }, // LCD.VCYCLE + { VSW, 0x00000001 }, // LCD.VSW + { VDE_START, 0x00000003 }, // LCD.VDE_START + { VDE_SIZE, 0x0000027F }, // LCD.VDE_SIZE + + { START, 0x00000001 }, // LCD.START ); // LCDC - Pixel data transfer start + + { 0, 10 }, // wait_ms( 10 ); + { SSITX, 0x000800BC }, // SPI.SSITX ); // Command setting of SPI block + { SSITX, 0x00000180 }, // Display data setup + { SSITX, 0x0008003B }, // Command setting of SPI block + { SSITX, 0x00000100 }, // Quad Data configuration - VGA + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B0 }, // Command setting of SPI block + { SSITX, 0x00000116 }, // Power supply ON/OFF control + { 0, 1 }, // wait_ms( 1 ); // Wait SPI fifo empty + { SSITX, 0x000800B8 }, // Command setting of SPI block + { SSITX, 0x000801FF }, // Output control + { SSITX, 0x000001F5 }, + { 0, 1 }, // wait_ms( 1); // Wait SPI fifo empty + { SSITX, 0x00000011 }, // wait_ms(-out (Command only) + { SSITX, 0x00000029 }, // Display on (Command only) + + { SYSTEM_BLOCK1_BASE, 0x00000002 }, // # wakeREQ -> GPIO + + { 0, 0 } +}; + +static void _panel_init(struct init_table *init_table) +{ + unsigned n; + + dprintf(INFO, "panel_init()\n"); + + n = 0; + while (init_table[n].reg != 0 || init_table[n].val != 0) { + if (init_table[n].reg != 0) + mddi_remote_write(init_table[n].val, init_table[n].reg); + else + thread_sleep(init_table[n].val);//mdelay(init_table[n].val); + n++; + } + + dprintf(INFO, "panel_init() done\n"); +} + +void panel_init(struct mddi_client_caps *client_caps) +{ + switch(client_caps->manufacturer_name) { + case 0xd263: // Toshiba + dprintf(INFO, "Found Toshiba panel\n"); + _panel_init(toshiba_480x640_init_table); + break; + case 0x4474: //?? + if (client_caps->product_code == 0xc065) + dprintf(INFO, "Found WVGA panel\n"); + break; + } +} + +void panel_poweron(void) +{ + gpio_set(88, 0); + gpio_config(88, GPIO_OUTPUT); + thread_sleep(1); //udelay(10); + gpio_set(88, 1); + thread_sleep(10); //mdelay(10); + + //mdelay(1000); // uncomment for second stage boot +} + +void panel_backlight(int on) +{} diff --git a/lk/target/surf-msm7k/rules.mk b/lk/target/surf-msm7k/rules.mk new file mode 100644 index 0000000..53828fc --- /dev/null +++ b/lk/target/surf-msm7k/rules.mk @@ -0,0 +1,39 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include + +PLATFORM := msm7k + +MEMBASE := 0x00000000 # SMI +MEMSIZE := 0x00800000 # 8MB + +BASE_ADDR := 0x10000000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00800000 +RAMDISK_ADDR := BASE_ADDR+0x01000000 +SCRATCH_ADDR := BASE_ADDR+0x02000000 + +KEYS_USE_GPIO_KEYPAD := 1 + +DEFINES += DISPLAY_TYPE_MDDI=1 + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + MEMBASE=$(MEMBASE) \ + BASE_ADDR=$(BASE_ADDR) \ + TAGS_ADDR=$(TAGS_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/keypad.o \ + $(LOCAL_DIR)/atags.o \ + $(LOCAL_DIR)/panel.o diff --git a/lk/target/surf-qsd8k/atags.c b/lk/target/surf-qsd8k/atags.c new file mode 100644 index 0000000..e9836e1 --- /dev/null +++ b/lk/target/surf-qsd8k/atags.c @@ -0,0 +1,43 @@ +/* Copyright (c) 2009, Code Aurora Forum. 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 Code Aurora 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, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#define EBI1_SIZE1 0x0E800000 //232MB for 256MB RAM +#define EBI1_ADDR1 0x20000000 + +unsigned* target_atag_mem(unsigned* ptr) +{ + /* ATAG_MEM */ + *ptr++ = 4; + *ptr++ = 0x54410002; + *ptr++ = EBI1_SIZE1; + *ptr++ = EBI1_ADDR1; + + return ptr; +} diff --git a/lk/target/surf-qsd8k/init.c b/lk/target/surf-qsd8k/init.c new file mode 100644 index 0000000..ac21f56 --- /dev/null +++ b/lk/target/surf-qsd8k/init.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2009, Google 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 Google, Inc. 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. + */ + +#include +#include +#include +#include +#include + +#define BOARD_FLASH_OFFSET 378 + +#define LINUX_MACHTYPE 0x00000811 + +static struct ptable flash_ptable; + +/* for these partitions, start will be offset by either what we get from + * smem, or from the above offset if smem is not useful. Also, we should + * probably have smem_ptable code populate our flash_ptable. + * + * When smem provides us with a full partition table, we can get rid of + * this altogether. + * + */ +static struct ptentry board_part_list[] = { + { + .start = 0, + .length = 40, + .name = "boot", + }, + { + .start = 56, + .length = 608 /* 76MB */, + .name = "system", + }, + { + .start = 664, + .length = 608 /* 76MB */, + .name = "cache", + }, + { + .start = 1272, + .length = 0, + .name = "userdata", + }, +}; +static int num_parts = sizeof(board_part_list)/sizeof(struct ptentry); + +void smem_ptable_init(void); +unsigned smem_get_apps_flash_start(void); + +void keypad_init(void); + +void target_init(void) +{ + unsigned offset; + struct flash_info *flash_info; + int i; + + dprintf(INFO, "target_init()\n"); + + keys_init(); + keypad_init(); + + ptable_init(&flash_ptable); + smem_ptable_init(); + + flash_init(); + flash_info = flash_get_info(); + ASSERT(flash_info); + + offset = smem_get_apps_flash_start(); + if (offset == 0xffffffff) + offset = BOARD_FLASH_OFFSET; + + for (i = 0; i < num_parts; i++) { + struct ptentry *ptn = &board_part_list[i]; + unsigned len = ptn->length; + + if ((len == 0) && (i == num_parts - 1)) + len = flash_info->num_blocks - offset - ptn->start; + ptable_add(&flash_ptable, ptn->name, offset + ptn->start, + len, ptn->flags); + } + + ptable_dump(&flash_ptable); + flash_set_ptable(&flash_ptable); +} + +unsigned board_machtype(void) +{ + return LINUX_MACHTYPE; +} diff --git a/lk/target/surf-qsd8k/keypad.c b/lk/target/surf-qsd8k/keypad.c new file mode 100644 index 0000000..f44032f --- /dev/null +++ b/lk/target/surf-qsd8k/keypad.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009, Google 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 Google, Inc. 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. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +/* don't turn this on without updating the ffa support */ +#define SCAN_FUNCTION_KEYS 0 + +static unsigned int halibut_row_gpios[] = { + 31, 32, 33, 34, 35, 41 +#if SCAN_FUNCTION_KEYS + , 42 +#endif +}; + +static unsigned int halibut_col_gpios[] = { 36, 37, 38, 39, 40 }; + +#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(halibut_col_gpios) + (col)) + +static const unsigned short halibut_keymap[ARRAY_SIZE(halibut_col_gpios) * ARRAY_SIZE(halibut_row_gpios)] = { + [KEYMAP_INDEX(0, 0)] = KEY_5, + [KEYMAP_INDEX(0, 1)] = KEY_9, + [KEYMAP_INDEX(0, 2)] = KEY_SOFT1, + [KEYMAP_INDEX(0, 3)] = KEY_6, + [KEYMAP_INDEX(0, 4)] = KEY_LEFT, + + [KEYMAP_INDEX(1, 0)] = KEY_0, + [KEYMAP_INDEX(1, 1)] = KEY_RIGHT, + [KEYMAP_INDEX(1, 2)] = KEY_1, + [KEYMAP_INDEX(1, 3)] = KEY_SHARP, + [KEYMAP_INDEX(1, 4)] = KEY_SEND, + + [KEYMAP_INDEX(2, 0)] = KEY_VOLUMEUP, + [KEYMAP_INDEX(2, 1)] = KEY_HOME, /* FA */ + [KEYMAP_INDEX(2, 2)] = KEY_F8, /* QCHT */ + [KEYMAP_INDEX(2, 3)] = KEY_F6, /* R+ */ + [KEYMAP_INDEX(2, 4)] = KEY_F7, /* R- */ + + [KEYMAP_INDEX(3, 0)] = KEY_UP, + [KEYMAP_INDEX(3, 1)] = KEY_CLEAR, + [KEYMAP_INDEX(3, 2)] = KEY_4, + [KEYMAP_INDEX(3, 3)] = KEY_MUTE, /* SPKR */ + [KEYMAP_INDEX(3, 4)] = KEY_2, + + [KEYMAP_INDEX(4, 0)] = KEY_SOFT2, /* SOFT2 */ + [KEYMAP_INDEX(4, 1)] = KEY_CENTER, /* KEY_CENTER */ + [KEYMAP_INDEX(4, 2)] = KEY_DOWN, + [KEYMAP_INDEX(4, 3)] = KEY_BACK, /* FB */ + [KEYMAP_INDEX(4, 4)] = KEY_8, + + [KEYMAP_INDEX(5, 0)] = KEY_VOLUMEDOWN, + [KEYMAP_INDEX(5, 1)] = KEY_STAR, /* KEY_STAR */ + [KEYMAP_INDEX(5, 2)] = KEY_MAIL, /* MESG */ + [KEYMAP_INDEX(5, 3)] = KEY_3, + [KEYMAP_INDEX(5, 4)] = KEY_7, + +#if SCAN_FUNCTION_KEYS + [KEYMAP_INDEX(6, 0)] = KEY_F5, + [KEYMAP_INDEX(6, 1)] = KEY_F4, + [KEYMAP_INDEX(6, 2)] = KEY_F3, + [KEYMAP_INDEX(6, 3)] = KEY_F2, + [KEYMAP_INDEX(6, 4)] = KEY_F1 +#endif +}; + +static struct gpio_keypad_info halibut_keypad_info = { + .keymap = halibut_keymap, + .output_gpios = halibut_row_gpios, + .input_gpios = halibut_col_gpios, + .noutputs = ARRAY_SIZE(halibut_row_gpios), + .ninputs = ARRAY_SIZE(halibut_col_gpios), + .settle_time = 5 /* msec */, + .poll_time = 20 /* msec */, + .flags = GPIOKPF_DRIVE_INACTIVE, +}; + +void keypad_init(void) +{ + gpio_keypad_init(&halibut_keypad_info); +} diff --git a/lk/target/surf-qsd8k/rules.mk b/lk/target/surf-qsd8k/rules.mk new file mode 100644 index 0000000..6a7e330 --- /dev/null +++ b/lk/target/surf-qsd8k/rules.mk @@ -0,0 +1,34 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +INCLUDES += -I$(LOCAL_DIR)/include + +PLATFORM := qsd8k + +MEMBASE := 0x00000000 # SMI +MEMSIZE := 0x00800000 # 8MB + +BASE_ADDR := 0x20000000 + +TAGS_ADDR := BASE_ADDR+0x00000100 +KERNEL_ADDR := BASE_ADDR+0x00800000 +RAMDISK_ADDR := BASE_ADDR+0x01000000 +SCRATCH_ADDR := BASE_ADDR+0x02000000 + +KEYS_USE_GPIO_KEYPAD := 1 + +MODULES += \ + dev/keys \ + lib/ptable + +DEFINES += \ + SDRAM_SIZE=$(MEMSIZE) \ + TAGS_ADDR=$(TAGS_ADDR) \ + BASE_ADDR=$(BASE_ADDR) \ + KERNEL_ADDR=$(KERNEL_ADDR) \ + RAMDISK_ADDR=$(RAMDISK_ADDR) \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + +OBJS += \ + $(LOCAL_DIR)/init.o \ + $(LOCAL_DIR)/atags.o \ + $(LOCAL_DIR)/keypad.o diff --git a/nbfix.c b/nbfix.c new file mode 100644 index 0000000..006394d --- /dev/null +++ b/nbfix.c @@ -0,0 +1,39 @@ +/** + author: cedesmith + license: GPL + small utility to fix nb by removing unneeded partitions +*/ +#include +#include + +int main() +{ + char empty[0x200] = {0} ; + + FILE *f = fopen("os.nb.payload", "r+"); + if(f==NULL) + { + printf("Failed to open RUU_signed.nbh"); + return 1; + } + + //change from BOOT to XIP + fseek(f, 0x1C2, SEEK_SET); + //fwrite( "\0x23", 1, 1, f); + char xipType = 0x23; + fwrite( &xipType, 1, 1, f); + + //remove other partitions + fseek(f, 0x1CE, SEEK_SET); + fwrite( empty, 1, 0x30, f); + + //clean MSFLSH50 header + fseek(f, 0x808, SEEK_SET); + fwrite( empty, 1, 0x5C, f); + + fclose(f); + + truncate("os.nb.payload", 0x40000); + + +} diff --git a/readme_boot.img.txt b/readme_boot.img.txt new file mode 100644 index 0000000..678ec95 --- /dev/null +++ b/readme_boot.img.txt @@ -0,0 +1,2 @@ +#make ARCH=arm CROSS_COMPILE=arm-none-eabi- +mkbootimg --kernel zImage --ramdisk initrd.gz --cmdline "console=null" --base 0x11800000 -o android_boot.img diff --git a/tinboot/tinboot.S b/tinboot/tinboot.S new file mode 100644 index 0000000..91e3834 --- /dev/null +++ b/tinboot/tinboot.S @@ -0,0 +1,49 @@ +@ author: cedesmith +@ license: GPL +@ version 1.0 +@ tiny bootloader wrapper for HTC WM6 phones +@ inspired by Martin Johnson Tinboot for htc vogue + +.equ KERNEL_OFFSET, 0x8000 + .org 0 + b boot + + .org 0x40 + .word 0x43454345 + .word romhdr+0x80000000 @ location of wince romhdr + .word romhdr + + + .org 0x00001000 + +boot: + b kernel + +romhdr: + .word 0x0 @ dllfirst + .word 0x0 @ dlllast + .word 0x80000000 @ physfirst + .word 0x80000000+fin @ physlast + .word 0 @ nummods + .word 0x80000000+fin @ ulRAMStart + .word 0x80000000+fin @ ulRAMFree + .word 0x8E600000 @ ulRAMEnd + .word 0 @ ulCopyEntries + .word 0x80000000+fin @ ulCopyOffset + .word 0 @ ulProfileLen + .word 0 @ ulProfileOffset + .word 0 @ numfiles + .word 0 @ ulKernelFlags + .word 0x04 @ ulFSRamPercent + .word 0 @ ulDrivglobStart + .word 0 @ ulDrivglobLen + .word 0x201c2 @ usCPUType and usMiscFlags (2 shorts) + .word 0x80000000 @ pExtensions + .word 0 @ ulTrackingStart + .word 0 @ ulTrackingLen + + .org KERNEL_OFFSET +kernel: + .incbin "../lk/build-htcleo/lk.bin" + +fin: