diff --git a/bin/NBMerge.exe b/bin/NBMerge.exe new file mode 100644 index 0000000..c68108e Binary files /dev/null and b/bin/NBMerge.exe differ diff --git a/bin/osnbtool.exe b/bin/osnbtool.exe new file mode 100644 index 0000000..39227d2 Binary files /dev/null and b/bin/osnbtool.exe differ diff --git a/bin/template_os.nb.payload b/bin/template_os.nb.payload new file mode 100644 index 0000000..43363b0 Binary files /dev/null and b/bin/template_os.nb.payload differ diff --git a/bin/yang.exe b/bin/yang.exe new file mode 100644 index 0000000..66844e5 Binary files /dev/null and b/bin/yang.exe differ diff --git a/compile b/compile new file mode 100644 index 0000000..e7b40c5 --- /dev/null +++ b/compile @@ -0,0 +1,55 @@ +#!/bin/bash + +#use codesourcery toolchain +TOOLCHAIN_PREFIX=arm-none-eabi- +export TOOLCHAIN_PREFIX + +if [ "$1" = "clean" ]; then + rm -rf lk/build-htcleo + rm bin/nbfix + rm bin/lk.bin + rm bin/tinboot + rm tinboot/tinboot + rm tinboot/tinboot.o + rm bin/os.nb.payload + rm bin/os.nb + rm bin/RUU_signed.nbh +fi + + +TOOLCHAIN_PREFIX="arm-none-eabi-" +export TOOLCHAIN_PREFIX + +if [ ! -f bin/nbfix ]; then + gcc nbfix.c -o bin/nbfix +fi + +if [ ! -f bin/lk.bin ]; then + cd lk + make htcleo EMMC_BOOT=0 DEBUG=1 + [ $? -eq 0 ] || exit 1 + cp build-htcleo/lk.bin ../bin/ + cd .. +fi + +if [ ! -f bin/tinboot ]; then + cd tinboot + ${TOOLCHAIN_PREFIX}as tinboot.S -o tinboot.o + ${TOOLCHAIN_PREFIX}objcopy tinboot.o -O binary tinboot + cp tinboot ../bin/ + cd .. +fi + +if [ ! -f bin/RUU_signed.nbh ]; then + cd bin + cp template_os.nb.payload os.nb.payload + wine osnbtool.exe -c os.nb.payload 0 tinboot + mv os.nb.payload.NEW os.nb.payload + ./nbfix + wine NBMerge.exe -kaiser os.nb + wine yang.exe -F RUU_signed.nbh -f os.nb -t 0x400 -s 64 -d PB8110000 -c 11111111 -v CLK1.1 -l WWE + + cd .. +fi + + diff --git a/lk/AndroidBoot.mk b/lk/AndroidBoot.mk new file mode 100644 index 0000000..fbe0527 --- /dev/null +++ b/lk/AndroidBoot.mk @@ -0,0 +1,66 @@ +#Android makefile to build lk bootloader as a part of Android Build + +TARGET_BOOTLOADER := $(PRODUCT_OUT)/appsboot.mbn +BOOTLOADER_OUT := $(TOP)/$(TARGET_OUT_INTERMEDIATES)/BOOTLOADER_OBJ + +# Force GCC 4.4.0 crosstool chain for Android builds +CROSS_TOOL := ../../../prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- + +# Remove bootloader binary to trigger recompile when source changes +appsbootldr_clean: + $(hide) rm -f $(TARGET_BOOTLOADER) + $(hide) rm -rf $(BOOTLOADER_OUT) + +$(BOOTLOADER_OUT): + mkdir -p $(BOOTLOADER_OUT) + + +TARGET_EMMC := 0 +ifeq ($(TARGET_USERIMAGES_USE_EXT2),true) + TARGET_EMMC := 1 +endif +ifeq ($(TARGET_USERIMAGES_USE_EXT3),true) + TARGET_EMMC := 1 +endif +ifeq ($(TARGET_USERIMAGES_USE_EXT4),true) + TARGET_EMMC := 1 +endif + + +ifeq ($(TARGET_EMMC),1) +TARGET_BOOTLOADER_EMMC := $(PRODUCT_OUT)/EMMCBOOT.MBN +BOOTLOADER_EMMC_OUT := $(TOP)/$(TARGET_OUT_INTERMEDIATES)/BOOTLOADER_EMMC_OBJ + +emmc_appsbootldr_clean: + $(hide) rm -f $(TARGET_BOOTLOADER_EMMC) + $(hide) rm -rf $(BOOTLOADER_EMMC_OUT) + +$(BOOTLOADER_EMMC_OUT): + mkdir -p $(BOOTLOADER_EMMC_OUT) + +$(TARGET_BOOTLOADER): appsbootldr_clean emmc_appsbootldr_clean $(BOOTLOADER_OUT) $(BOOTLOADER_EMMC_OUT) + $(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_TOOL) BOOTLOADER_OUT=../../../$(BOOTLOADER_OUT) $(TARGET_PRODUCT) + $(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_TOOL) BOOTLOADER_OUT=../../../$(BOOTLOADER_EMMC_OUT) $(TARGET_PRODUCT) EMMC_BOOT=1 + +else + +$(TARGET_BOOTLOADER): appsbootldr_clean $(BOOTLOADER_OUT) + $(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_TOOL) BOOTLOADER_OUT=../../../$(BOOTLOADER_OUT) $(TARGET_PRODUCT) + +endif + +#build nandwrite as a part of Android Build +TARGET_NANDWRITE := $(PRODUCT_OUT)/obj/nandwrite/build-$(TARGET_PRODUCT)_nandwrite/lk +NANDWRITE_OUT := $(TOP)/$(TARGET_OUT_INTERMEDIATES)/nandwrite + +nandwrite_clean: + $(hide) rm -f $(TARGET_NANDWRITE) + $(hide) rm -rf $(NANDWRITE_OUT) + +$(NANDWRITE_OUT): + mkdir -p $(NANDWRITE_OUT) + +$(TARGET_NANDWRITE): nandwrite_clean $(NANDWRITE_OUT) + @echo $(TARGET_PRODUCT)_nandwrite + $(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_TOOL) BOOTLOADER_OUT=../../../$(NANDWRITE_OUT) $(TARGET_PRODUCT)_nandwrite BUILD_NANDWRITE=1 + diff --git a/lk/app/aboot/aboot.c b/lk/app/aboot/aboot.c new file mode 100644 index 0000000..0835fe1 --- /dev/null +++ b/lk/app/aboot/aboot.c @@ -0,0 +1,735 @@ +/* + * 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 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 +#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: