Compare commits

..

13 Commits

Author SHA1 Message Date
Kostas Missos
4a90476e97 v2.3 2018-06-04 11:11:07 +03:00
nwert
96dbcf8476 Fixed sleep mode [test on 1.0.0, 2.0.0 and 5.1.0]. 2018-06-04 11:08:26 +03:00
Kostas Missos
9be1a36e79 v2.2 (and like always, transfer unmerged PRs) 2018-06-03 09:37:37 +03:00
Kostas Missos
d4103efaa9 SD errata, bugfixes, replace hardcoded values 2018-06-03 09:07:03 +03:00
Robin Lambertz
3a0a226c4c Add SVC verification disable on 5.x 2018-06-03 01:21:34 +03:00
Kostas Missos
919bf99cb2 [HOS] Add sd unmount and proper secmon signaling 2018-06-02 00:12:22 +03:00
Kostas Missos
59d25a3be5 Oups. Remove unmerged functions 2018-06-01 19:58:25 +03:00
Kostas Missos
5796ead851 [PKG1] Move 1.0.0 secmon to 0x4002B020
So, it's time to move 1.0.0 secmon.
If we want to continue having a full featured bootloader, this change is a must.

It will move the secmon to 0x4002B000 + 0x20 (to keep the values addresses aligned).
It fixes relocator patch.

So now the payload size limit is 160KB - .bss (~158KB).
2018-06-01 19:28:22 +03:00
Kostas Missos
240e465d86 [PKG1] Add kernel patching
Add Disable Svc Verification and Debug mode.
Can be enabled via the hekate .ini

https://gist.github.com/roblabla/440f3ceaa0b2d3ca530c2a43fe258420
2018-06-01 19:22:11 +03:00
Kostas Missos
b74dde3b6d [LP0] Inform user that console halted :P
Actually this corrects sdram cfg parsing in LP0.
The cfg is missing 3 variables, which ultimately are unused in T210.

Remove them and fix LP0 configuration saving.
The console sleep, still does not work. But now it tries to enter/leave sleep and halts with backlight on.

At least, this reminds the user to power off the console to not deplete the battery completely.
2018-06-01 19:08:21 +03:00
Kostas Missos
1521315450 Bug fixes, wording, etc 2018-06-01 19:02:13 +03:00
Kostas Missos
236ac03331 [Backup] Add dump verification 2018-06-01 18:48:59 +03:00
Kostas Missos
55d920bf00 [GFX] Fix hedump print last 1-16 bytes 2018-06-01 18:40:24 +03:00
38 changed files with 1252 additions and 777 deletions

View File

@@ -2,7 +2,9 @@ ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/base_rules
CC = $(DEVKITARM)/bin/arm-none-eabi-gcc
LD = $(DEVKITARM)/bin/arm-none-eabi-ld
OBJCOPY = $(DEVKITARM)/bin/arm-none-eabi-objcopy
TARGET := ipl
BUILD := build_ipl
@@ -42,7 +44,7 @@ OBJS = $(addprefix $(BUILD)/, \
OBJS += $(addprefix $(BUILD)/, diskio.o ff.o ffunicode.o)
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11# -Wall
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections
.PHONY: all clean

View File

@@ -1,35 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ARM64_H_
#define _ARM64_H_
#include "types.h"
#define LSL0 0
#define LSL16 16
#define LSL32 32
#define _PAGEOFF(x) ((x) & 0xFFFFF000)
#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F)
#define _BL(a, o) 0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
#define _B(a, o) 0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
#define _NOP() 0xD503201F
#endif

View File

@@ -18,7 +18,6 @@
#include "i2c.h"
#include "gpio.h"
#include "t210.h"
#include "util.h"
u32 btn_read()
{
@@ -37,38 +36,22 @@ u32 btn_wait()
u32 res = 0, btn = btn_read();
int pwr = 0;
//Power button down, raise a filter.
// Power button down, raise a filter.
if (btn & BTN_POWER)
{
pwr = 1;
btn &= ~BTN_POWER;
btn &= 0xFFFFFFFE;
}
do
{
res = btn_read();
//Power button up, remove filter.
// Power button up, remove filter.
if (!(res & BTN_POWER) && pwr)
pwr = 0;
else if (pwr) //Power button still down.
res &= ~BTN_POWER;
// Power button still down.
else if (pwr)
res &= 0xFFFFFFFE;
} while (btn == res);
return res;
}
u32 btn_wait_timeout(u32 time_ms)
{
u32 timeout = get_tmr() + (time_ms * 1000);
u32 res = btn_read();
u32 btn = res;
do
{
//Keep the new value until timeout is reached
if (btn == res)
res = btn_read();
} while (get_tmr() < timeout);
return res;
}

View File

@@ -25,6 +25,5 @@
u32 btn_read();
u32 btn_wait();
u32 btn_wait_timeout(u32 time_ms);
#endif

View File

@@ -51,14 +51,14 @@ static clock_t _clock_coresight = { 0xC, 0x18, 0x1D4, 9, 0, 4};
void clock_enable(const clock_t *clk)
{
//Put clock into reset.
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index);
CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index);
//Disable.
CLOCK(clk->enable) &= ~(1 << clk->index);
//Configure clock source if required.
if (clk->source)
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
//Enable.
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~(1 << clk->index)) | (1 << clk->index);
CLOCK(clk->enable) = CLOCK(clk->enable) & ~(1 << clk->index) | (1 << clk->index);
//Take clock off reset.
CLOCK(clk->reset) &= ~(1 << clk->index);
}
@@ -66,14 +66,14 @@ void clock_enable(const clock_t *clk)
void clock_disable(const clock_t *clk)
{
//Put clock into reset.
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index);
CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index);
//Disable.
CLOCK(clk->enable) &= ~(1 << clk->index);
}
void clock_enable_fuse(u32 enable)
{
CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) = (CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) & 0xEFFFFFFF) | ((enable & 1) << 28);
CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) = CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) & 0xEFFFFFFF | ((enable & 1) << 28) & 0x10000000;
}
void clock_enable_uart(u32 idx)
@@ -144,9 +144,9 @@ void clock_disable_sor1()
void clock_enable_kfuse()
{
//clock_enable(&_clock_kfuse);
CLOCK(0x8) = (CLOCK(0x8) & 0xFFFFFEFF) | 0x100;
CLOCK(0x8) = CLOCK(0x8) & 0xFFFFFEFF | 0x100;
CLOCK(0x14) &= 0xFFFFFEFF;
CLOCK(0x14) = (CLOCK(0x14) & 0xFFFFFEFF) | 0x100;
CLOCK(0x14) = CLOCK(0x14) & 0xFFFFFEFF | 0x100;
sleep(10);
CLOCK(0x8) &= 0xFFFFFEFF;
sleep(20);
@@ -259,7 +259,7 @@ static int _clock_sdmmc_is_enabled(u32 id)
return 0;
}
static void _clock_sdmmc_set_enable(u32 id)
static int _clock_sdmmc_set_enable(u32 id)
{
switch (id)
{
@@ -274,7 +274,7 @@ static void _clock_sdmmc_set_enable(u32 id)
}
}
static void _clock_sdmmc_clear_enable(u32 id)
static int _clock_sdmmc_clear_enable(u32 id)
{
switch (id)
{

View File

@@ -77,15 +77,15 @@ void cluster_boot_cpu0(u32 entry)
sleep(2);
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x80404E02;
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x404E02;
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) = (CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) & 0xFFFBFFFF) | 0x40000;
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) = CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) & 0xFFFBFFFF | 0x40000;
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x40404E02;
}
while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x8000000))
;
//Configure MSELECT source and enable clock.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) & 0xFFFFFFF7) | 8;
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00 | 6;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) & 0xFFFFFFF7 | 8;
//Configure initial CPU clock frequency and enable clock.
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888;
@@ -95,7 +95,7 @@ void cluster_boot_cpu0(u32 entry)
clock_enable_coresight();
//CAR2PMC_CPU_ACK_WIDTH should be set to 0.
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) = CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) & 0xFFFFF000;
//Enable CPU rail.
_cluster_pmc_enable_partition(1, 0);

693
ipl/ctc_logo2.h Normal file
View File

@@ -0,0 +1,693 @@
#define SZ_HEKATE_LOGO 36024
#define SZ_HEKATE_LOGOLZ 10993
static unsigned char Kc_HEKATE_LOGOlz[SZ_HEKATE_LOGOLZ] =
{
0xAE, 0x1B, 0x1B, 0x1B,
0x1B, 0xAE, 0x04, 0x04, 0xAE, 0x08, 0x08, 0xAE, 0x10, 0x10, 0xAE, 0x07, 0x07, 0x1C, 0x1B, 0x1B,
0x1E, 0x1B, 0x1B, 0x1F, 0x1B, 0x1B, 0x1F, 0xAE, 0x05, 0x06, 0x1E, 0x1B, 0x1B, 0x1D, 0xAE, 0x05,
0x15, 0xAE, 0x24, 0x39, 0x1D, 0xAE, 0x05, 0x2D, 0xAE, 0x06, 0x06, 0xAE, 0x0C, 0x0C, 0xAE, 0x18,
0x18, 0xAE, 0x1E, 0x1E, 0xAE, 0x24, 0x75, 0xAE, 0x09, 0x78, 0xAE, 0x0F, 0x81, 0x34, 0xAE, 0x27,
0x3C, 0xAE, 0x27, 0x82, 0x14, 0xAE, 0x4D, 0x4D, 0xAE, 0x6D, 0x6D, 0xAE, 0x07, 0x83, 0x4E, 0x1A,
0x1B, 0x23, 0x1A, 0x1B, 0x27, 0x1A, 0x1B, 0x2B, 0x19, 0x1B, 0x2F, 0x19, 0x1B, 0x30, 0x18, 0x1B,
0x30, 0x19, 0x1B, 0x2E, 0x19, 0x1B, 0x2A, 0x19, 0x1B, 0x26, 0x1A, 0x1B, 0x22, 0x1A, 0x1B, 0x1F,
0xAE, 0x17, 0x82, 0x71, 0x1D, 0xAE, 0x05, 0x3C, 0x24, 0x1A, 0x1B, 0x28, 0x1A, 0x1B, 0x29, 0x19,
0x1B, 0x29, 0x19, 0xAE, 0x06, 0x06, 0xAE, 0x0C, 0x0C, 0xAE, 0x18, 0x18, 0xAE, 0x16, 0x18, 0x28,
0xAE, 0x0B, 0x72, 0xAE, 0x18, 0x83, 0x24, 0xAE, 0x04, 0x75, 0x1B, 0x1B, 0x21, 0x1A, 0xAE, 0x04,
0x2A, 0x2A, 0xAE, 0x05, 0x81, 0x28, 0x30, 0xAE, 0x05, 0x81, 0x34, 0x2F, 0x19, 0x1B, 0x2B, 0x19,
0x1B, 0x28, 0xAE, 0x05, 0x81, 0x4C, 0x1F, 0x1A, 0xAE, 0x81, 0x7A, 0x83, 0x66, 0xAE, 0x06, 0x83,
0x54, 0x22, 0xAE, 0x05, 0x83, 0x12, 0x32, 0x18, 0x1C, 0x3D, 0x17, 0x1C, 0x47, 0x16, 0x1C, 0x4F,
0x15, 0x1C, 0x55, 0x14, 0x1C, 0x59, 0x14, 0x1C, 0x58, 0x14, 0x1C, 0x53, 0x14, 0x1C, 0x4D, 0x15,
0x1C, 0x45, 0x16, 0x1C, 0x3B, 0x17, 0x1C, 0x31, 0x18, 0x1B, 0x28, 0x1A, 0x1B, 0x21, 0x1A, 0x1B,
0x1D, 0xAE, 0x0E, 0x42, 0x20, 0xAE, 0x05, 0x84, 0x0D, 0x39, 0x18, 0x1C, 0x44, 0x16, 0x1C, 0x4B,
0x15, 0xAE, 0x04, 0x30, 0x4D, 0xAE, 0x06, 0x06, 0xAE, 0x0C, 0x0C, 0xAE, 0x18, 0x18, 0xAE, 0x11,
0x12, 0x4C, 0x15, 0x1C, 0x49, 0x16, 0x1C, 0x41, 0x17, 0x1C, 0x33, 0x18, 0x1C, 0x26, 0xAE, 0x05,
0x83, 0x1B, 0xAE, 0x12, 0x83, 0x54, 0x20, 0xAE, 0x05, 0x84, 0x46, 0x30, 0x18, 0x1B, 0x3A, 0x17,
0xAE, 0x04, 0x75, 0x4E, 0x15, 0x1C, 0x54, 0xAE, 0x05, 0x81, 0x2E, 0x58, 0x14, 0x1C, 0x55, 0x14,
0x1C, 0x4F, 0x15, 0x1C, 0x47, 0x16, 0x1C, 0x3E, 0xAE, 0x05, 0x42, 0x2A, 0x19, 0x1B, 0x22, 0xAE,
0x81, 0x72, 0x83, 0x60, 0xAE, 0x06, 0x83, 0x15, 0x28, 0x19, 0x1B, 0x37, 0x18, 0x1C, 0x49, 0x16,
0x1C, 0x5A, 0x13, 0x1C, 0x6B, 0x11, 0x1D, 0x80, 0x0F, 0x1D, 0xA2, 0x0B, 0x1E, 0xC4, 0x06, 0x1F,
0xC5, 0x06, 0x1F, 0xC5, 0x06, 0x1F, 0xC4, 0x06, 0x1F, 0xAA, 0x0A, 0x1E, 0x94, 0x0D, 0x1E, 0x69,
0x12, 0x1D, 0x58, 0x14, 0x1C, 0x45, 0x16, 0x1C, 0x34, 0x18, 0x1C, 0x27, 0xAE, 0x0B, 0x86, 0x4E,
0x1D, 0x1B, 0x1B, 0x27, 0x1A, 0x1B, 0x3B, 0x17, 0x1C, 0x74, 0x11, 0x1D, 0x9B, 0x0C, 0x1E, 0xA0,
0x0B, 0x1E, 0xA2, 0x0B, 0x1E, 0xA2, 0xAE, 0x06, 0x06, 0xAE, 0x0C, 0x0C, 0xAE, 0x18, 0x18, 0xAE,
0x11, 0x12, 0xA1, 0x0B, 0x1E, 0x9F, 0x0B, 0x1E, 0x97, 0x0D, 0x1E, 0x7A, 0x11, 0x1D, 0x31, 0x18,
0x1B, 0x21, 0x1A, 0xAE, 0x0D, 0x81, 0x31, 0x1F, 0x1B, 0x1B, 0x26, 0x1A, 0x1B, 0x32, 0x18, 0x1C,
0x43, 0x16, 0x1C, 0x56, 0x14, 0x1C, 0x67, 0x12, 0x1D, 0x73, 0x11, 0x1D, 0xA2, 0x0B, 0x1E, 0xBD,
0x07, 0x1E, 0xAE, 0x09, 0x81, 0x31, 0xB4, 0x09, 0x1E, 0x9E, 0x0B, 0x1E, 0x6B, 0x11, 0x1D, 0x5C,
0x13, 0x1C, 0x49, 0x15, 0x1C, 0x38, 0x18, 0x1C, 0x29, 0x19, 0x1B, 0x20, 0xAE, 0x0E, 0x85, 0x11,
0xAE, 0x81, 0x5B, 0x83, 0x57, 0x1D, 0xAE, 0x05, 0x87, 0x2B, 0x2F, 0x19, 0x1B, 0x42, 0x16, 0x1C,
0x5D, 0x13, 0x1C, 0x7F, 0x0F, 0x1D, 0xBD, 0x07, 0x1E, 0xEA, 0x02, 0x1F, 0xFF, 0x00, 0x20, 0xFF,
0x00, 0x20, 0xAE, 0x06, 0x06, 0xAE, 0x0C, 0x0C, 0xF8, 0x01, 0x20, 0xD4, 0x04, 0x1F, 0x9C, 0x0C,
0x1E, 0x59, 0x14, 0x1C, 0x3F, 0x17, 0x1C, 0x2B, 0xAE, 0x05, 0x82, 0x2C, 0xAE, 0x06, 0x87, 0x73,
0x2C, 0x19, 0x1B, 0x4C, 0x15, 0x1C, 0xC1, 0x06, 0xAE, 0x19, 0x3C, 0xAE, 0x18, 0x18, 0xAE, 0x1E,
0x1E, 0xDF, 0x03, 0x1F, 0x3C, 0x17, 0x1C, 0x24, 0xAE, 0x08, 0x83, 0x5A, 0xAE, 0x09, 0x88, 0x1D,
0x3D, 0x17, 0x1C, 0x56, 0x14, 0x1C, 0x6F, 0x11, 0x1D, 0xB4, 0x08, 0x1E, 0xDC, 0x03, 0xAE, 0x1C,
0x75, 0xDC, 0x03, 0x1F, 0xB1, 0x09, 0x1E, 0x5F, 0x13, 0x1C, 0x45, 0x16, 0x1C, 0x30, 0x19, 0x1B,
0x23, 0xAE, 0x81, 0x63, 0x83, 0x5D, 0x1D, 0x1B, 0x1B, 0x23, 0xAE, 0x05, 0x85, 0x7A, 0x4B, 0x15,
0x1C, 0x6B, 0x11, 0x1D, 0xAC, 0x09, 0x1E, 0xF8, 0x01, 0xAE, 0x28, 0x82, 0x71, 0xDB, 0x03, 0x1F,
0x73, 0x11, 0x1D, 0x45, 0x16, 0x1C, 0x2E, 0xAE, 0x05, 0x83, 0x5D, 0x1F, 0x1A, 0x1B, 0x30, 0x19,
0x1B, 0x55, 0x14, 0x1C, 0xC4, 0xAE, 0x50, 0x83, 0x5A, 0xE1, 0x03, 0x1F, 0x42, 0x16, 0x1C, 0x25,
0xAE, 0x05, 0x83, 0x5A, 0x1C, 0xAE, 0x05, 0x8E, 0x53, 0x2E, 0x19, 0x1B, 0x44, 0x16, 0x1C, 0x63,
0x12, 0x1D, 0x9A, 0x0C, 0xAE, 0x1C, 0x85, 0x05, 0xAE, 0x0F, 0x0F, 0xEA, 0x02, 0x1F, 0x90, 0x0D,
0x1E, 0x4D, 0x15, 0x1C, 0x32, 0x18, 0x1C, 0xAE, 0x81, 0x5E, 0x83, 0x5D, 0x1C, 0xAE, 0x05, 0x87,
0x2E, 0x32, 0x18, 0x1C, 0x4F, 0x15, 0x1C, 0x73, 0x11, 0x1D, 0xD5, 0x04, 0xAE, 0x31, 0x83, 0x12,
0xF8, 0x01, 0x20, 0x8E, 0x0E, 0x1E, 0x46, 0x16, 0x1C, 0x2C, 0xAE, 0x05, 0x8D, 0x46, 0x2F, 0x19,
0x1B, 0x52, 0xAE, 0x56, 0x83, 0x5A, 0x41, 0x17, 0x1C, 0x25, 0xAE, 0x05, 0x88, 0x1A, 0x20, 0x1A,
0x1B, 0x2D, 0x19, 0x1B, 0x47, 0x16, 0x1C, 0x6A, 0x12, 0x1D, 0xB5, 0x08, 0x1E, 0xAE, 0x33, 0x4E,
0xB0, 0x09, 0x1E, 0x4F, 0x15, 0x1C, 0xAE, 0x06, 0x8B, 0x5F, 0xAE, 0x81, 0x58, 0x8E, 0x74, 0x1F,
0xAE, 0x05, 0x83, 0x0C, 0x4B, 0xAE, 0x05, 0x83, 0x57, 0xE3, 0xAE, 0x1D, 0x89, 0x4E, 0xAE, 0x1E,
0x83, 0x5D, 0x8B, 0x0E, 0x1E, 0x40, 0x17, 0x1C, 0x29, 0x19, 0x1B, 0x2C, 0x19, 0x1B, 0x46, 0x16,
0x1C, 0xBE, 0x07, 0xAE, 0x4F, 0x83, 0x5A, 0xDE, 0x03, 0x1F, 0x39, 0xAE, 0x05, 0x86, 0x66, 0x1F,
0x1B, 0x1B, 0x29, 0x19, 0x1B, 0x43, 0x16, 0x1C, 0x69, 0x12, 0x1D, 0xC5, 0xAE, 0x3B, 0x84, 0x40,
0xAF, 0x09, 0x1E, 0x49, 0x16, 0x1C, 0x2B, 0x19, 0xAE, 0x04, 0x51, 0xAE, 0x81, 0x52, 0x83, 0x57,
0x1E, 0x1B, 0x1B, 0x28, 0x1A, 0x1B, 0x41, 0x16, 0x1C, 0x6B, 0x12, 0xAE, 0x19, 0x87, 0x2E, 0xD1,
0x04, 0x1F, 0xAB, 0x0A, 0x1E, 0x93, 0x0E, 0x1E, 0x93, 0x0E, 0x1E, 0xA2, 0x0C, 0x1E, 0xC1, 0x06,
0x1F, 0xF1, 0xAE, 0x14, 0x8B, 0x2C, 0xF1, 0x01, 0x20, 0x68, 0x13, 0x1C, 0x36, 0xAE, 0x05, 0x95,
0x00, 0x35, 0x18, 0x1C, 0x86, 0x0F, 0x1D, 0xBA, 0x08, 0x1E, 0xBD, 0x07, 0x1F, 0xBE, 0x07, 0x1F,
0xBE, 0xAE, 0x06, 0x06, 0xAE, 0x05, 0x06, 0xBF, 0x07, 0x1F, 0xAE, 0x06, 0x93, 0x10, 0xAE, 0x12,
0x42, 0xC4, 0x06, 0x1F, 0xC1, 0xAE, 0x11, 0x30, 0xBE, 0x07, 0x1F, 0xBC, 0x07, 0x1F, 0xB8, 0x08,
0x1E, 0x9A, 0x0D, 0x1E, 0x2C, 0x19, 0x1B, 0x21, 0xAE, 0x05, 0x9A, 0x50, 0x39, 0x17, 0x1C, 0x60,
0x13, 0xAE, 0x19, 0x87, 0x2E, 0xE2, 0x03, 0x1F, 0xB5, 0x09, 0xAE, 0x07, 0x81, 0x31, 0x96, 0x0D,
0x1E, 0xC1, 0x07, 0x1F, 0xAE, 0x18, 0x85, 0x32, 0x8A, 0x0E, 0x1E, 0x3C, 0xAE, 0x08, 0x88, 0x08,
0xAE, 0x81, 0x4F, 0x83, 0x5A, 0x21, 0x1A, 0x1B, 0x35, 0x18, 0x1C, 0x5A, 0x13, 0x1C, 0xAC, 0x09,
0xAE, 0x13, 0x82, 0x26, 0xD9, 0x04, 0x1F, 0x65, 0x13, 0x1C, 0x43, 0x16, 0x1C, 0x39, 0x17, 0x1C,
0x36, 0x18, 0x1C, 0x36, 0x18, 0x1C, 0x3B, 0x17, 0x1C, 0x48, 0x16, 0x1C, 0x5E, 0x13, 0x1C, 0xBB,
0x07, 0xAE, 0x13, 0x8F, 0x0C, 0xC9, 0x06, 0x1F, 0x47, 0xAE, 0x05, 0x8B, 0x14, 0x28, 0xAE, 0x05,
0x88, 0x08, 0x37, 0xAE, 0x05, 0x30, 0x3C, 0x17, 0x1C, 0x3C, 0xAE, 0x06, 0x06, 0xAE, 0x05, 0x06,
0x42, 0x16, 0x1C, 0x5B, 0x13, 0x1C, 0x7C, 0x10, 0x1D, 0xAE, 0x12, 0x6F, 0x68, 0x12, 0x1D, 0x49,
0x16, 0xAE, 0x10, 0x30, 0x3C, 0x17, 0x1C, 0x3A, 0x17, 0x1C, 0x34, 0x18, 0x1C, 0x2B, 0xAE, 0x05,
0x8B, 0x6B, 0xAE, 0x06, 0x8E, 0x5F, 0x4F, 0x15, 0x1C, 0x8E, 0x0E, 0x1D, 0xAE, 0x12, 0x81, 0x01,
0xE9, 0x02, 0x1F, 0x84, 0x0F, 0x1D, 0x48, 0xAE, 0x05, 0x9B, 0x15, 0xAE, 0x06, 0x81, 0x31, 0x39,
0xAE, 0x05, 0x9A, 0x08, 0x58, 0x14, 0x1C, 0x9D, 0x0C, 0x1E, 0xAE, 0x12, 0x85, 0x11, 0xEA, 0x02,
0x1F, 0x51, 0x15, 0x1C, 0x2E, 0xAE, 0x1A, 0x87, 0x37, 0x1C, 0x1C, 0x1C, 0x1E, 0x1E, 0x1E, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E,
0x1E, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0xAE, 0x31, 0x84, 0x0F, 0xAE, 0x0F, 0x4E, 0xAE, 0x06, 0x09,
0x1E, 0x1E, 0x1E, 0xAE, 0x24, 0x4B, 0xAE, 0x0F, 0x24, 0xAE, 0x0C, 0x4B, 0xAE, 0x06, 0x06, 0xAE,
0x0C, 0x81, 0x13, 0x1D, 0xAE, 0x05, 0x87, 0x31, 0x45, 0x16, 0x1C, 0x73, 0x11, 0x1D, 0xAE, 0x12,
0x81, 0x76, 0xD1, 0x04, 0x1F, 0x4A, 0xAE, 0x05, 0x8D, 0x0A, 0x26, 0xAE, 0x05, 0x82, 0x50, 0x1F,
0x1A, 0x1B, 0x20, 0xAE, 0x05, 0xA0, 0x2F, 0x28, 0xAE, 0x05, 0x9D, 0x2C, 0x57, 0x14, 0x1C, 0xAA,
0x0A, 0xAE, 0x13, 0x84, 0x0D, 0x68, 0x13, 0x1C, 0x33, 0x18, 0x1C, 0xAE, 0x06, 0x30, 0x21, 0xAE,
0x05, 0x30, 0x22, 0xAE, 0x06, 0x06, 0xAE, 0x08, 0x09, 0x29, 0xAE, 0x05, 0x8B, 0x2C, 0x73, 0x11,
0xAE, 0x13, 0x83, 0x5A, 0x54, 0x14, 0x1C, 0x30, 0x18, 0xAE, 0x13, 0x33, 0x21, 0xAE, 0x05, 0x7B,
0xAE, 0x06, 0xA4, 0x4E, 0x24, 0x1A, 0x1B, 0x3C, 0x17, 0x1C, 0x68, 0xAE, 0x14, 0x88, 0x62, 0xE9,
0x02, 0x1F, 0x62, 0x13, 0x1C, 0x37, 0x18, 0x1C, 0x28, 0xAE, 0x05, 0x84, 0x04, 0xAE, 0x06, 0x93,
0x4F, 0x21, 0xAE, 0x05, 0xA2, 0x6D, 0x33, 0x18, 0x1C, 0x4D, 0x15, 0x1C, 0x8A, 0x0F, 0xAE, 0x13,
0x84, 0x0D, 0xA0, 0x0C, 0x1E, 0x39, 0x17, 0x1C, 0x22, 0xAE, 0x0B, 0x9A, 0x4D, 0xAE, 0x09, 0x82,
0x38, 0x20, 0x20, 0x20, 0x26, 0x26, 0x26, 0x2B, 0x2B, 0x2B, 0x30, 0x30, 0x30, 0x33, 0x33, 0x33,
0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x30, 0x30, 0x30, 0x2C, 0x2C, 0x2C, 0x27, 0x27, 0x27, 0x21,
0x21, 0x21, 0x1F, 0x1F, 0x1F, 0xAE, 0x27, 0x83, 0x60, 0x1D, 0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x25,
0x25, 0x25, 0x2A, 0x2A, 0x2A, 0x2F, 0x2F, 0x2F, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x32, 0x32,
0x32, 0x2F, 0x2F, 0x2F, 0x29, 0x29, 0x29, 0x24, 0x24, 0x24, 0xAE, 0x1B, 0x4B, 0xAE, 0x06, 0x3C,
0xAE, 0x0C, 0x84, 0x55, 0x1F, 0x1F, 0x1F, 0x24, 0x24, 0x24, 0x2A, 0x2A, 0x2A, 0x30, 0x30, 0x30,
0x32, 0x32, 0x32, 0x31, 0x31, 0x31, 0x2C, 0x2C, 0x2C, 0x25, 0x25, 0x25, 0xAE, 0x09, 0x45, 0x1F,
0x1A, 0x1B, 0x31, 0x18, 0x1B, 0x59, 0x14, 0x1C, 0xAE, 0x12, 0x89, 0x57, 0xF1, 0x01, 0x20, 0x60,
0x14, 0x1C, 0x2F, 0xAE, 0x08, 0x99, 0x4C, 0xAE, 0x0F, 0x96, 0x49, 0x25, 0x1A, 0x1B, 0x3A, 0x17,
0x1C, 0x63, 0xAE, 0x14, 0x82, 0x5F, 0xB5, 0x08, 0x1E, 0x3D, 0x17, 0x1C, 0x23, 0xAE, 0x0E, 0x82,
0x29, 0xAE, 0x0C, 0x0C, 0x22, 0x1A, 0x1B, 0x40, 0x17, 0x1C, 0x70, 0xAE, 0x14, 0x83, 0x5A, 0x4F,
0x15, 0x1C, 0x2A, 0x19, 0xAE, 0x1F, 0x8C, 0x3C, 0x2B, 0xAE, 0x05, 0x9A, 0x53, 0x8E, 0x0E, 0xAE,
0x13, 0x3F, 0x82, 0x0F, 0x1D, 0x35, 0xAE, 0x14, 0x95, 0x6F, 0xAE, 0x06, 0x96, 0x49, 0x32, 0x18,
0x1C, 0x58, 0x14, 0x1C, 0xB4, 0xAE, 0x11, 0x81, 0x6A, 0xDA, 0x03, 0x1F, 0x47, 0x16, 0x1C, 0x28,
0xAE, 0x0B, 0x81, 0x67, 0x1D, 0x1D, 0x1D, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x31, 0x31, 0x31,
0x3C, 0x3C, 0x3C, 0x46, 0x46, 0x46, 0x4C, 0x4C, 0x4C, 0x4F, 0x4F, 0x4F, 0x50, 0x50, 0x50, 0x4F,
0x4F, 0x4F, 0x4C, 0x4C, 0x4C, 0x47, 0x47, 0x47, 0x3F, 0x3F, 0x3F, 0x35, 0x35, 0x35, 0x2A, 0x2A,
0x2A, 0x21, 0x21, 0x21, 0x1D, 0x1D, 0xAE, 0x1C, 0x96, 0x60, 0x1C, 0x1C, 0x1C, 0xAE, 0x06, 0x83,
0x54, 0x2F, 0x2F, 0x2F, 0x39, 0x39, 0x39, 0x43, 0x43, 0x43, 0x4A, 0x4A, 0x4A, 0x4E, 0x4E, 0x4E,
0xAE, 0x06, 0x4E, 0x4A, 0x4A, 0x4A, 0x43, 0x43, 0x43, 0x39, 0x39, 0x39, 0x2D, 0x2D, 0x2D, 0x23,
0x23, 0x23, 0x1E, 0x1E, 0xAE, 0x10, 0xA3, 0x0A, 0x1C, 0x1C, 0x1C, 0x21, 0x21, 0x21, 0x28, 0x28,
0x28, 0x2D, 0x2D, 0x2D, 0x2A, 0x2A, 0x2A, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x2E, 0x2E, 0x2E,
0x39, 0x39, 0x39, 0x44, 0x44, 0x44, 0x4B, 0x4B, 0x4B, 0x4E, 0x4E, 0x4E, 0x4A, 0x4A, 0x4A, 0x40,
0x40, 0x40, 0x30, 0x30, 0x30, 0x24, 0x24, 0x24, 0xAE, 0x06, 0x81, 0x0D, 0x23, 0xAE, 0x05, 0x86,
0x00, 0x6A, 0x12, 0xAE, 0x13, 0x92, 0x39, 0xA8, 0x0B, 0x1E, 0x39, 0x18, 0x1C, 0x22, 0xAE, 0x17,
0x8D, 0x01, 0xAE, 0x06, 0x82, 0x62, 0x4E, 0x15, 0xAE, 0x13, 0x87, 0x37, 0xE2, 0x03, 0x1F, 0x45,
0x16, 0x1C, 0x27, 0xAE, 0x56, 0x83, 0x5A, 0x1F, 0x1A, 0x1B, 0x34, 0x18, 0x1C, 0x5D, 0x13, 0x1C,
0xAE, 0x12, 0x8F, 0x27, 0xD0, 0x04, 0x1F, 0x41, 0x16, 0x1C, 0x26, 0xAE, 0x17, 0x99, 0x46, 0x1C,
0xAE, 0x05, 0xA2, 0x40, 0x43, 0x16, 0x1C, 0x7D, 0xAE, 0x14, 0x8C, 0x06, 0x51, 0x15, 0x1C, 0x2C,
0x19, 0xAE, 0x07, 0x39, 0x1E, 0x1E, 0x1E, 0x23, 0x23, 0x23, 0x2E, 0x2E, 0x2E, 0x3D, 0x3D, 0x3D,
0x4B, 0x4B, 0x4B, 0x57, 0x57, 0x57, 0x97, 0x97, 0x97, 0xB4, 0xB4, 0xB4, 0xD6, 0xD6, 0xD6, 0xD6,
0xAE, 0x04, 0x04, 0xD6, 0xCE, 0xCE, 0xCE, 0xB3, 0xB3, 0xB3, 0x8A, 0x8A, 0x8A, 0x4F, 0x4F, 0x4F,
0x41, 0x41, 0x41, 0x31, 0x31, 0x31, 0x25, 0x25, 0x25, 0xAE, 0x12, 0x83, 0x12, 0xAE, 0x09, 0x84,
0x25, 0x21, 0x21, 0x21, 0x2A, 0x2A, 0x2A, 0x39, 0x39, 0x39, 0x48, 0x48, 0x48, 0x54, 0x54, 0x54,
0x80, 0x80, 0x80, 0xB4, 0xB4, 0xB4, 0xCE, 0xCE, 0xCE, 0xAE, 0x06, 0x4E, 0xC6, 0xC6, 0xC6, 0xA1,
0xA1, 0xA1, 0x62, 0x62, 0x62, 0x45, 0x45, 0x45, 0x35, 0x35, 0x35, 0x28, 0x28, 0x28, 0x1F, 0x1F,
0xAE, 0x0D, 0x8C, 0x1A, 0x1E, 0x1E, 0x1E, 0x28, 0x28, 0x28, 0x37, 0x37, 0x37, 0x6F, 0x6F, 0x6F,
0x5E, 0x5E, 0x5E, 0x36, 0x36, 0x36, 0x39, 0x39, 0x39, 0x45, 0x45, 0x45, 0x53, 0x53, 0x53, 0x81,
0x81, 0x81, 0xAE, 0x06, 0x81, 0x19, 0xD5, 0xD5, 0xD5, 0xD3, 0xD3, 0xD3, 0x85, 0x85, 0x85, 0x27,
0x27, 0x27, 0x1E, 0x1E, 0x1E, 0xAE, 0x06, 0x8B, 0x0B, 0x48, 0x16, 0x1C, 0x80, 0x0F, 0xAE, 0x10,
0x81, 0x6D, 0xF8, 0x01, 0x20, 0x4F, 0x15, 0x1C, 0x2B, 0x19, 0xAE, 0x13, 0xA7, 0x4B, 0xAE, 0x09,
0x82, 0x29, 0x24, 0x1A, 0x1B, 0x3E, 0x17, 0x1C, 0x69, 0x12, 0xAE, 0x13, 0x82, 0x29, 0xAE, 0x06,
0x86, 0x03, 0xAE, 0x54, 0x83, 0x5A, 0x23, 0x1A, 0x1B, 0x3D, 0x17, 0x1C, 0x6B, 0x11, 0x1D, 0xAE,
0x12, 0x9D, 0x3E, 0x82, 0x0F, 0x1D, 0x32, 0x18, 0x1C, 0x1F, 0xAE, 0x1A, 0x78, 0x21, 0x1A, 0x1B,
0x36, 0xAE, 0x05, 0x84, 0x16, 0xAE, 0x12, 0x85, 0x47, 0x8A, 0x0F, 0x1D, 0x2F, 0xAE, 0x05, 0x81,
0x6D, 0x1D, 0x1D, 0x1D, 0x24, 0x24, 0x24, 0x31, 0x31, 0x31, 0x44, 0x44, 0x44, 0x55, 0x55, 0x55,
0xA2, 0xA2, 0xA2, 0xE6, 0xE6, 0xE6, 0xF5, 0xF5, 0xF5, 0xD5, 0xD5, 0xD5, 0xBB, 0xBB, 0xBB, 0xB1,
0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xBB, 0xBB, 0xBB, 0xD6, 0xD6, 0xD6, 0xF5, 0xF5, 0xF5, 0xE6, 0xE6,
0xE6, 0x9F, 0x9F, 0x9F, 0x48, 0x48, 0x48, 0x33, 0x33, 0x33, 0x25, 0x25, 0x25, 0xAE, 0x12, 0x87,
0x3A, 0xAE, 0x06, 0x86, 0x6F, 0x2D, 0x2D, 0x2D, 0x3F, 0x3F, 0x3F, 0x51, 0x51, 0x51, 0x8D, 0x8D,
0x8D, 0xAE, 0x06, 0x39, 0xDD, 0xDD, 0xDD, 0xAE, 0x06, 0x4E, 0xB2, 0xB2, 0xB2, 0xCE, 0xCE, 0xCE,
0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xB4, 0xB4, 0xB4, 0x4E, 0x4E, 0x4E, 0x39, 0x39, 0x39, 0xAE,
0x0F, 0x83, 0x5D, 0x1F, 0x1F, 0x1F, 0x30, 0x30, 0x30, 0x45, 0x45, 0x45, 0xD4, 0xD4, 0xD4, 0xB0,
0xB0, 0xB0, 0x4E, 0x4E, 0x4E, 0x51, 0x51, 0x51, 0x80, 0x80, 0x80, 0xAE, 0x06, 0x4B, 0xDE, 0xDE,
0xDE, 0xBA, 0xBA, 0xBA, 0xAF, 0xAF, 0xAF, 0xAB, 0xAB, 0xAB, 0x83, 0x83, 0x83, 0xAE, 0x06, 0x84,
0x64, 0x1E, 0x1B, 0x1B, 0x2D, 0xAE, 0x05, 0x9C, 0x79, 0xAC, 0xAE, 0x11, 0x86, 0x78, 0xD1, 0x04,
0xAE, 0x07, 0x9C, 0x3A, 0xAE, 0x1E, 0x86, 0x3F, 0x30, 0x18, 0x1B, 0x4F, 0x15, 0x1C, 0xE1, 0xAE,
0x11, 0x82, 0x29, 0x62, 0x14, 0x1D, 0x26, 0xAE, 0x1A, 0x94, 0x6E, 0xAE, 0x39, 0x83, 0x5A, 0xAE,
0x06, 0x86, 0x78, 0x47, 0xAE, 0x14, 0x85, 0x0B, 0xF1, 0x01, 0x20, 0x4B, 0x15, 0x1C, 0x29, 0x19,
0xAE, 0x1C, 0x95, 0x63, 0x1F, 0xAE, 0x05, 0x88, 0x68, 0x47, 0x16, 0x1C, 0xBD, 0xAE, 0x11, 0x9B,
0x0F, 0x9C, 0x0D, 0x1E, 0x2B, 0x19, 0x1B, 0x1F, 0xAE, 0x05, 0x83, 0x09, 0x30, 0x30, 0x30, 0x46,
0x46, 0x46, 0x67, 0x67, 0x67, 0xD6, 0xD6, 0xD6, 0xED, 0xED, 0xED, 0xB0, 0xB0, 0xB0, 0x59, 0x59,
0x59, 0x41, 0x41, 0x41, 0x3B, 0x3B, 0x3B, 0x39, 0x39, 0x39, 0x3A, 0x3A, 0x3A, 0x3E, 0x3E, 0x3E,
0x45, 0x45, 0x45, 0x5F, 0x5F, 0x5F, 0xB3, 0xB3, 0xB3, 0xEE, 0xEE, 0xEE, 0xC4, 0xC4, 0xC4, 0x48,
0x48, 0x48, 0x30, 0x30, 0x30, 0x21, 0x21, 0x21, 0xAE, 0x0F, 0x83, 0x57, 0x20, 0x20, 0x20, 0x2C,
0x2C, 0x2C, 0x40, 0x40, 0x40, 0x55, 0x55, 0x55, 0xB4, 0xB4, 0xB4, 0xF5, 0xF5, 0xF5, 0xC3, 0xC3,
0xC3, 0x68, 0x68, 0x68, 0x41, 0x41, 0x41, 0x3C, 0x3C, 0x3C, 0x3B, 0x3B, 0x3B, 0x3D, 0x3D, 0x3D,
0x45, 0x45, 0x45, 0x60, 0x60, 0x60, 0xAB, 0xAB, 0xAB, 0xEE, 0xEE, 0xEE, 0xDE, 0xDE, 0xDE, 0x60,
0x60, 0x60, 0x39, 0x39, 0x39, 0x26, 0x26, 0x26, 0xAE, 0x09, 0x88, 0x05, 0x20, 0x20, 0x20, 0x33,
0x33, 0x33, 0x4F, 0x4F, 0x4F, 0xD7, 0xD7, 0xD7, 0xB8, 0xB8, 0xB8, 0x65, 0x65, 0x65, 0x85, 0x85,
0x85, 0xED, 0xED, 0xED, 0xCC, 0xCC, 0xCC, 0x69, 0x69, 0x69, 0xAE, 0x06, 0x81, 0x19, 0x37, 0x37,
0x37, 0x30, 0x30, 0x30, 0x28, 0x28, 0x28, 0x20, 0x20, 0x20, 0x1C, 0x1C, 0x1C, 0x1F, 0x1B, 0x1B,
0x32, 0x18, 0x1C, 0x5C, 0xAE, 0x14, 0x89, 0x5A, 0xA9, 0x0A, 0x1E, 0x39, 0x18, 0x1C, 0x20, 0xAE,
0x1D, 0x83, 0x5A, 0xAE, 0x06, 0x8E, 0x6E, 0x35, 0x18, 0x1C, 0x77, 0x12, 0x1D, 0x8C, 0x0F, 0x1D,
0x8F, 0x0E, 0x1D, 0x8F, 0x0E, 0x1D, 0x8A, 0x0F, 0x1D, 0x81, 0x10, 0x1D, 0x45, 0x17, 0xAE, 0x0D,
0xAB, 0x5E, 0xAE, 0x48, 0x83, 0x5A, 0xAE, 0x06, 0x8C, 0x03, 0x50, 0x15, 0x1C, 0xA2, 0x0B, 0xAE,
0x14, 0x85, 0x0B, 0xAE, 0x08, 0xA5, 0x1F, 0xAE, 0x1B, 0x84, 0x19, 0x23, 0xAE, 0x05, 0x90, 0x58,
0x65, 0x13, 0x1D, 0x8A, 0xAE, 0x08, 0x81, 0x31, 0x8B, 0x0F, 0x1D, 0x84, 0x10, 0x1D, 0x5B, 0x15,
0x1D, 0x25, 0x1A, 0x1B, 0x21, 0x1F, 0x1F, 0x2A, 0x2A, 0x2A, 0x41, 0x41, 0x41, 0x66, 0x66, 0x66,
0xDE, 0xDE, 0xDE, 0xDD, 0xDD, 0xDD, 0x59, 0x59, 0x59, 0x39, 0x39, 0x39, 0x2E, 0x2E, 0x2E, 0x28,
0x28, 0x28, 0x24, 0x24, 0x24, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0xAE, 0x06, 0x92, 0x54, 0x36,
0x36, 0x36, 0x48, 0x48, 0x48, 0x80, 0x80, 0x80, 0xEE, 0xEE, 0xEE, 0xBB, 0xBB, 0xBB, 0x40, 0x40,
0x40, 0x28, 0x28, 0x28, 0xAE, 0x0C, 0x87, 0x37, 0xAE, 0x06, 0x8A, 0x46, 0x3B, 0x3B, 0x3B, 0x53,
0x53, 0x53, 0xBD, 0xBD, 0xBD, 0xED, 0xED, 0xED, 0x84, 0x84, 0x84, 0x3D, 0x3D, 0x3D, 0xAE, 0x06,
0x83, 0x03, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x2B, 0x2B, 0x2B, 0x35, 0x35,
0x35, 0x46, 0x46, 0x46, 0x7F, 0x7F, 0x7F, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0x5B, 0x5B, 0x5B,
0x32, 0x32, 0x32, 0xAE, 0x09, 0x84, 0x28, 0x20, 0x20, 0x20, 0x35, 0x35, 0x35, 0x55, 0x55, 0x55,
0xD9, 0xD9, 0xD9, 0xBE, 0xBE, 0xBE, 0x91, 0x91, 0x91, 0xEE, 0xEE, 0xEE, 0xA6, 0xA6, 0xA6, 0x40,
0x40, 0x40, 0x31, 0x31, 0x31, 0xAE, 0x06, 0x4B, 0x22, 0x22, 0x22, 0xAE, 0x06, 0x92, 0x60, 0xAE,
0x06, 0x81, 0x01, 0x20, 0x1A, 0x1B, 0x38, 0x18, 0x1C, 0x64, 0xAE, 0x14, 0x8E, 0x65, 0x8F, 0x0E,
0xAE, 0x05, 0x89, 0x5A, 0xAE, 0x20, 0xA5, 0x3A, 0x1F, 0xAE, 0x05, 0x8B, 0x14, 0x2B, 0xAE, 0x05,
0xB6, 0x2D, 0x32, 0x18, 0x1C, 0x32, 0x18, 0x1C, 0x30, 0xAE, 0x05, 0xB6, 0x75, 0xAE, 0x06, 0xB2,
0x4D, 0xAE, 0x51, 0x83, 0x5A, 0x1F, 0x1B, 0x1B, 0x30, 0x19, 0x1B, 0x58, 0x14, 0xAE, 0x13, 0x85,
0x0B, 0xBE, 0x07, 0x1F, 0x3B, 0xAE, 0x11, 0x95, 0x60, 0xAE, 0x15, 0x84, 0x1C, 0xAE, 0x06, 0x97,
0x1D, 0x2F, 0xAE, 0x05, 0xB5, 0x4A, 0x32, 0x18, 0x1C, 0x30, 0x18, 0x1B, 0x2B, 0x19, 0x1B, 0x25,
0x1A, 0x1B, 0x20, 0x1C, 0x1C, 0x23, 0x22, 0x22, 0x35, 0x35, 0x35, 0x50, 0x50, 0x50, 0xBE, 0xBE,
0xBE, 0xE6, 0xE6, 0xE6, 0x59, 0x59, 0x59, 0x31, 0x31, 0x31, 0x24, 0x24, 0x24, 0xAE, 0x12, 0x99,
0x16, 0x1D, 0x1D, 0x1D, 0x22, 0x22, 0x22, 0x31, 0x31, 0x31, 0x49, 0x49, 0x49, 0x98, 0x98, 0x98,
0xF5, 0xF5, 0xF5, 0x6A, 0x6A, 0x6A, 0x31, 0x31, 0x31, 0xAE, 0x09, 0x8A, 0x46, 0x1C, 0x1C, 0x1C,
0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x4C, 0x4C, 0x4C, 0xA2, 0xA2, 0xA2, 0xF5, 0xF5, 0xF5, 0x76,
0x76, 0x76, 0x37, 0x37, 0x37, 0x27, 0x27, 0x27, 0xAE, 0x0F, 0x96, 0x04, 0xAE, 0x06, 0x8F, 0x09,
0x2E, 0x2E, 0x2E, 0x43, 0x43, 0x43, 0x75, 0x75, 0x75, 0xEE, 0xEE, 0xEE, 0xBC, 0xBC, 0xBC, 0x41,
0x41, 0x41, 0x29, 0x29, 0x29, 0xAE, 0x06, 0x87, 0x37, 0x20, 0x20, 0x20, 0x36, 0x36, 0x36, 0x59,
0x59, 0x59, 0xDB, 0xDB, 0xDB, 0xBF, 0xBF, 0xBF, 0xD9, 0xD9, 0xD9, 0xBA, 0xBA, 0xBA, 0x3C, 0x3C,
0x3C, 0x29, 0x29, 0x29, 0xAE, 0x18, 0x96, 0x4F, 0x21, 0xAE, 0x05, 0xB3, 0x12, 0x6B, 0xAE, 0x14,
0x83, 0x5A, 0x72, 0x11, 0x1D, 0x2E, 0xAE, 0x08, 0x90, 0x52, 0xAE, 0x21, 0xAC, 0x71, 0xAE, 0x0C,
0xBD, 0x64, 0xAE, 0x24, 0xBD, 0x67, 0xAE, 0x3A, 0x83, 0x5A, 0xAE, 0x05, 0x99, 0x3D, 0xAE, 0x15,
0x92, 0x3F, 0xA9, 0x0A, 0x1E, 0x38, 0xAE, 0x20, 0x88, 0x65, 0xAE, 0x15, 0xC0, 0x49, 0xAE, 0x0A,
0xC0, 0x4C, 0x1C, 0x1C, 0x26, 0x26, 0x26, 0x3C, 0x3C, 0x3C, 0x63, 0x63, 0x63, 0xF5, 0xF5, 0xF5,
0x90, 0x90, 0x90, 0x36, 0x36, 0x36, 0x22, 0x22, 0x22, 0xAE, 0x18, 0x99, 0x0A, 0x1C, 0x1C, 0x1C,
0x25, 0x25, 0x25, 0x3A, 0x3A, 0x3A, 0x56, 0x56, 0x56, 0xAE, 0x06, 0x8D, 0x6D, 0x39, 0x39, 0x39,
0x23, 0x23, 0x23, 0xAE, 0x09, 0x87, 0x31, 0x29, 0x29, 0x29, 0xAE, 0x06, 0x87, 0x7F, 0xED, 0xED,
0xED, 0xA6, 0xA6, 0xA6, 0x39, 0x39, 0x39, 0xAE, 0x18, 0x92, 0x69, 0xAE, 0x06, 0x8F, 0x0F, 0x30,
0x30, 0x30, 0x49, 0x49, 0x49, 0xA3, 0xA3, 0xA3, 0xF5, 0xF5, 0xF5, 0x6C, 0x6C, 0x6C, 0x33, 0x33,
0x33, 0x20, 0x20, 0x20, 0xAE, 0x06, 0x83, 0x5A, 0x37, 0x37, 0x37, 0x5C, 0x5C, 0x5C, 0xDB, 0xDB,
0xDB, 0xDB, 0xDB, 0xDB, 0xE7, 0xE7, 0xE7, 0x46, 0x46, 0x46, 0x2B, 0x2B, 0x2B, 0xAE, 0x0F, 0x92,
0x69, 0xAE, 0x0F, 0x83, 0x5A, 0x3D, 0x17, 0x1C, 0x6D, 0x11, 0xAE, 0x13, 0x9B, 0x63, 0x52, 0xAE,
0x05, 0x92, 0x3F, 0xAE, 0x57, 0xA2, 0x1C, 0xAE, 0x3C, 0x83, 0x5A, 0x36, 0x18, 0x1C, 0x62, 0x13,
0x1D, 0xAE, 0x12, 0xB3, 0x51, 0x92, 0x0E, 0x1E, 0x35, 0xAE, 0x1D, 0x92, 0x3F, 0xAE, 0x24, 0x9C,
0x70, 0x27, 0x27, 0x27, 0x3B, 0x3B, 0x3B, 0x9B, 0x9B, 0x9B, 0xF5, 0xF5, 0xF5, 0x3F, 0x3F, 0x3F,
0x2A, 0x2A, 0x2A, 0xAE, 0x1E, 0x99, 0x4F, 0x1F, 0x1F, 0x1F, 0x31, 0x31, 0x31, 0x4E, 0x4E, 0x4E,
0xB5, 0xB5, 0xB5, 0xD5, 0xD5, 0xD5, 0x3F, 0x3F, 0x3F, 0x27, 0x27, 0x27, 0xAE, 0x07, 0x82, 0x5C,
0x21, 0x21, 0x33, 0x33, 0x33, 0x4D, 0x4D, 0x4D, 0xB4, 0xB4, 0xB4, 0xD5, 0xD5, 0xD5, 0xAE, 0x0C,
0x87, 0x04, 0xAE, 0x18, 0x84, 0x28, 0x24, 0x24, 0x24, 0x39, 0x39, 0x39, 0x57, 0x57, 0x57, 0xE6,
0xE6, 0xE6, 0xC4, 0xC4, 0xC4, 0x3D, 0x3D, 0x3D, 0x25, 0x25, 0x25, 0xAE, 0x06, 0x83, 0x5A, 0x38,
0x38, 0x38, 0x5E, 0x5E, 0x5E, 0xDB, 0xDB, 0xDB, 0xF5, 0xF5, 0xF5, 0xA0, 0xA0, 0xA0, 0x37, 0x37,
0x37, 0xAE, 0x0F, 0x8F, 0x54, 0xAE, 0x12, 0x82, 0x62, 0x3F, 0x17, 0x1C, 0x6F, 0xAE, 0x35, 0x95,
0x24, 0xAE, 0x75, 0x83, 0x5A, 0xAE, 0x06, 0x8C, 0x3F, 0x65, 0xAE, 0x14, 0x88, 0x65, 0x90, 0x0E,
0x1D, 0x33, 0xAE, 0x20, 0x8C, 0x3F, 0xAE, 0x21, 0xA3, 0x62, 0xAE, 0x06, 0x96, 0x16, 0x93, 0x93,
0x93, 0xB3, 0xB3, 0xB3, 0x2F, 0x2F, 0x2F, 0x22, 0x22, 0x22, 0xAE, 0x1F, 0x8B, 0x5C, 0x1E, 0x1E,
0x2D, 0x2D, 0x2D, 0x49, 0x49, 0x49, 0xA2, 0xA2, 0xA2, 0xED, 0xED, 0xED, 0x41, 0x41, 0x41, 0x28,
0x28, 0x28, 0xAE, 0x06, 0x84, 0x25, 0x26, 0x26, 0x26, 0x3D, 0x3D, 0x3D, 0x56, 0x56, 0x56, 0xED,
0xED, 0xED, 0x9A, 0x9A, 0x9A, 0x34, 0x34, 0x34, 0xAE, 0x1E, 0x83, 0x0C, 0xAE, 0x06, 0x84, 0x28,
0x2F, 0x2F, 0x2F, 0x4B, 0x4B, 0x4B, 0xAC, 0xAC, 0xAC, 0xE6, 0xE6, 0xE6, 0x45, 0x45, 0x45, 0x2A,
0x2A, 0x2A, 0xAE, 0x06, 0x93, 0x07, 0x38, 0x38, 0x38, 0x5B, 0x5B, 0x5B, 0xDA, 0xDA, 0xDA, 0xF5,
0xF5, 0xF5, 0x5D, 0x5D, 0x5D, 0x2D, 0x2D, 0x2D, 0xAE, 0x1B, 0x84, 0x25, 0xAE, 0x3F, 0x98, 0x7E,
0xAE, 0x78, 0x83, 0x5A, 0x39, 0x18, 0x1C, 0x66, 0xAE, 0x59, 0x83, 0x5A, 0xAE, 0x09, 0xA4, 0x24,
0x29, 0x29, 0x29, 0xAE, 0x15, 0xA0, 0x35, 0xAE, 0x12, 0x87, 0x67, 0x2B, 0x2B, 0x2B, 0x47, 0x47,
0x47, 0x8E, 0x8E, 0x8E, 0xF5, 0xF5, 0xF5, 0x43, 0x43, 0x43, 0x29, 0x29, 0x29, 0xAE, 0x06, 0x83,
0x72, 0x2C, 0x2C, 0x2C, 0x47, 0x47, 0x47, 0x97, 0x97, 0x97, 0xED, 0xED, 0xED, 0x49, 0x49, 0x49,
0x30, 0x30, 0x30, 0xAE, 0x06, 0x91, 0x65, 0xAE, 0x06, 0xA9, 0x20, 0xAE, 0x09, 0x09, 0xAE, 0x0C,
0x0C, 0x22, 0x22, 0x22, 0x2D, 0x2D, 0x2D, 0x47, 0x47, 0x47, 0x83, 0x83, 0x83, 0xF5, 0xF5, 0xF5,
0x68, 0x68, 0x68, 0x2F, 0x2F, 0x2F, 0xAE, 0x06, 0xA6, 0x08, 0x36, 0x36, 0x36, 0x57, 0x57, 0x57,
0xD8, 0xD8, 0xD8, 0xD6, 0xD6, 0xD6, 0x42, 0x42, 0x42, 0xAE, 0x09, 0x88, 0x1A, 0xAE, 0x82, 0x26,
0x87, 0x34, 0xAE, 0x0F, 0xAB, 0x0A, 0xAE, 0x06, 0xAB, 0x04, 0x1C, 0x1C, 0x1C, 0xAE, 0x06, 0xA7,
0x4B, 0x1F, 0x1F, 0x1F, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0xAE, 0x04,
0x04, 0xAE, 0x04, 0x04, 0x24, 0x24, 0x24, 0x30, 0x30, 0x30, 0x4B, 0x4B, 0x4B, 0x8F, 0x8F, 0x8F,
0xF5, 0xF5, 0xF5, 0x44, 0x44, 0x44, 0x2A, 0x2A, 0x2A, 0xAE, 0x09, 0x8B, 0x26, 0x50, 0x50, 0x50,
0xC0, 0xC0, 0xC0, 0xD0, 0xD0, 0xD0, 0x53, 0x53, 0x53, 0xAE, 0x06, 0xA5, 0x31, 0x35, 0xAE, 0x04,
0x04, 0xAE, 0x08, 0x08, 0xAE, 0x10, 0x10, 0xAE, 0x04, 0x04, 0x3D, 0x3D, 0x3D, 0x52, 0x52, 0x52,
0x65, 0x65, 0x65, 0xF5, 0xF5, 0xF5, 0x84, 0x84, 0x84, 0xAE, 0x06, 0x93, 0x13, 0xAE, 0x06, 0x96,
0x1C, 0x52, 0x52, 0x52, 0xD7, 0xD7, 0xD7, 0xB2, 0xB2, 0xB2, 0x3C, 0x3C, 0x3C, 0x24, 0x24, 0x24,
0xAE, 0x21, 0xB0, 0x0C, 0x3E, 0xAE, 0x05, 0x8E, 0x68, 0xAE, 0x15, 0xA3, 0x14, 0xAE, 0x81, 0x19,
0x8E, 0x68, 0x63, 0x13, 0xAE, 0x13, 0x83, 0x5A, 0x91, 0x0E, 0x1D, 0x34, 0xAE, 0x3E, 0x8E, 0x68,
0xAE, 0x15, 0xAB, 0x2B, 0x23, 0x23, 0x23, 0x28, 0x28, 0x28, 0x2E, 0x2E, 0x2E, 0x32, 0x32, 0x32,
0xAE, 0x06, 0xA3, 0x7D, 0xAE, 0x06, 0x9D, 0x53, 0x3A, 0xAE, 0x04, 0x04, 0x3A, 0x3C, 0x3C, 0x3C,
0x47, 0x47, 0x47, 0x5D, 0x5D, 0x5D, 0x95, 0x95, 0x95, 0xF5, 0xF5, 0xF5, 0xAE, 0x06, 0x8A, 0x40,
0xAE, 0x09, 0x91, 0x74, 0x58, 0x58, 0x58, 0xD9, 0xD9, 0xD9, 0xBC, 0xBC, 0xBC, 0x67, 0x67, 0x67,
0x56, 0x56, 0x56, 0x51, 0x51, 0x51, 0x51, 0xAE, 0x04, 0x04, 0xAE, 0x08, 0x08, 0xAE, 0x10, 0x10,
0xAE, 0x04, 0x04, 0x55, 0x55, 0x55, 0x63, 0x63, 0x63, 0x6E, 0x6E, 0x6E, 0xF5, 0xF5, 0xF5, 0x83,
0x83, 0x83, 0x30, 0x30, 0x30, 0xAE, 0x09, 0x83, 0x5A, 0x51, 0x51, 0x51, 0xD6, 0xD6, 0xD6, 0xB0,
0xB0, 0xB0, 0xAE, 0x0C, 0x93, 0x28, 0xAE, 0x1B, 0x83, 0x5A, 0x3B, 0xAE, 0x05, 0xA3, 0x50, 0xAE,
0x12, 0xB0, 0x0C, 0x54, 0x14, 0x1C, 0x2D, 0xAE, 0x1D, 0x9F, 0x76, 0xAE, 0x78, 0x83, 0x5A, 0x34,
0x18, 0x1C, 0x5F, 0x13, 0x1C, 0xAE, 0x12, 0xAD, 0x2D, 0x93, 0x0E, 0x1E, 0x36, 0xAE, 0x26, 0x96,
0x1C, 0xAE, 0x2A, 0x8B, 0x17, 0xAE, 0x06, 0xAB, 0x1C, 0x41, 0x41, 0x41, 0x49, 0x49, 0x49, 0x4F,
0x4F, 0x4F, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x56, 0x56, 0x56, 0x56, 0xAE,
0x04, 0x04, 0x56, 0x58, 0x58, 0x58, 0x61, 0x61, 0x61, 0x72, 0x72, 0x72, 0x9E, 0x9E, 0x9E, 0xF5,
0xF5, 0xF5, 0x47, 0x47, 0x47, 0xAE, 0x06, 0x83, 0x5A, 0x21, 0x21, 0x21, 0x39, 0x39, 0x39, 0x5D,
0x5D, 0x5D, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xD9, 0xD9, 0xD9, 0xD7, 0xD7, 0xD7, 0xAE, 0x09,
0xA9, 0x1D, 0xAE, 0x09, 0x09, 0xAE, 0x12, 0x12, 0xD6, 0xD6, 0xD6, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
0xD8, 0xF5, 0xF5, 0xF5, 0x7E, 0x7E, 0x7E, 0x2B, 0x2B, 0x2B, 0xAE, 0x06, 0x8B, 0x0E, 0xAE, 0x0F,
0x83, 0x5A, 0xAE, 0x21, 0x90, 0x01, 0xAE, 0x1B, 0x8D, 0x37, 0x76, 0x11, 0x1D, 0x30, 0x18, 0xAE,
0x1C, 0x9D, 0x14, 0xAE, 0x0F, 0xD5, 0x3D, 0xAE, 0x09, 0xB3, 0x54, 0xAE, 0x06, 0xB3, 0x63, 0xAE,
0x1E, 0x99, 0x79, 0xAE, 0x3C, 0x9D, 0x50, 0x31, 0x18, 0x1B, 0x5A, 0xAE, 0x14, 0x9D, 0x50, 0xAB,
0x0A, 0x1E, 0x39, 0x17, 0x1C, 0xAE, 0x1B, 0xA2, 0x1F, 0xAE, 0x27, 0x81, 0x31, 0xAE, 0x12, 0xAB,
0x67, 0x75, 0x75, 0x75, 0xA2, 0xA2, 0xA2, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xD6, 0xEE, 0xEE, 0xEE,
0xF5, 0xF5, 0xF5, 0xF5, 0xAE, 0x04, 0x04, 0xAE, 0x08, 0x08, 0xAE, 0x0B, 0x0B, 0x48, 0x48, 0x48,
0xAE, 0x06, 0x83, 0x5A, 0x22, 0x22, 0x22, 0x3B, 0x3B, 0x3B, 0x5D, 0x5D, 0x5D, 0xF5, 0xF5, 0xF5,
0xCB, 0xCB, 0xCB, 0xB6, 0xB6, 0xB6, 0xB1, 0xB1, 0xB1, 0xB0, 0xB0, 0xB0, 0xB0, 0xAE, 0x04, 0x04,
0xAE, 0x08, 0x08, 0xAE, 0x10, 0x10, 0xAE, 0x07, 0x07, 0xB1, 0xB1, 0xB1, 0xAF, 0xAF, 0xAF, 0xAC,
0xAC, 0xAC, 0x59, 0x59, 0x59, 0xAE, 0x06, 0xA9, 0x32, 0xAE, 0x33, 0x83, 0x5A, 0x1F, 0xAE, 0x05,
0xA4, 0x42, 0x61, 0xAE, 0x14, 0x89, 0x5D, 0xAE, 0x06, 0x86, 0x03, 0xAE, 0x1E, 0x89, 0x5D, 0xAE,
0x06, 0xC5, 0x33, 0x29, 0x19, 0x1B, 0x34, 0xAE, 0x05, 0xBB, 0x05, 0x3F, 0x17, 0x1C, 0x3F, 0x17,
0x1C, 0x39, 0xAE, 0x05, 0xD5, 0x2B, 0xAE, 0x06, 0xD1, 0x4B, 0xAE, 0x54, 0xA5, 0x04, 0x2E, 0x19,
0x1B, 0x53, 0xAE, 0x14, 0xC7, 0x08, 0xBF, 0x07, 0x1F, 0x3F, 0xAE, 0x0B, 0xCD, 0x7D, 0xAE, 0x19,
0xA2, 0x5B, 0xAE, 0x05, 0xD5, 0x3D, 0x31, 0xAE, 0x05, 0xD5, 0x3D, 0xAE, 0x06, 0x81, 0x31, 0x3B,
0xAE, 0x05, 0xD5, 0x2B, 0xAE, 0x07, 0xD1, 0x4B, 0xAE, 0x05, 0x9C, 0x58, 0x2E, 0x2E, 0x2E, 0x40,
0x40, 0x40, 0x52, 0x52, 0x52, 0x84, 0x84, 0x84, 0xCF, 0xCF, 0xCF, 0xF5, 0xF5, 0xF5, 0xED, 0xED,
0xED, 0xCD, 0xCD, 0xCD, 0xB0, 0xB0, 0xB0, 0x91, 0x91, 0x91, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84,
0x84, 0xAE, 0x04, 0x04, 0x84, 0x85, 0x85, 0x85, 0x8B, 0x8B, 0x8B, 0x95, 0x95, 0x95, 0xB5, 0xB5,
0xB5, 0xAE, 0x0C, 0x87, 0x34, 0x22, 0x22, 0x22, 0x3A, 0x3A, 0x3A, 0x5A, 0x5A, 0x5A, 0xAE, 0x06,
0x9E, 0x18, 0x4F, 0x4F, 0x4F, 0x3C, 0x3C, 0x3C, 0xAE, 0x06, 0x8B, 0x4A, 0xAE, 0x06, 0x06, 0xAE,
0x0C, 0x0C, 0xAE, 0x12, 0x12, 0x35, 0x35, 0x35, 0x2F, 0x2F, 0x2F, 0x26, 0x26, 0x26, 0xAE, 0x06,
0x9D, 0x32, 0xAE, 0x34, 0x83, 0x5A, 0x1B, 0x1B, 0x30, 0xAE, 0x05, 0xB7, 0x43, 0xCD, 0x05, 0xAE,
0x10, 0x82, 0x29, 0xAC, 0x09, 0xAE, 0x1F, 0xB7, 0x0A, 0xAE, 0x06, 0x3F, 0x2A, 0x19, 0x1B, 0x40,
0x17, 0x1C, 0x59, 0x14, 0x1C, 0x6B, 0x12, 0x1D, 0x6F, 0x11, 0x1D, 0x6E, 0x11, 0x1D, 0x64, 0x12,
0x1D, 0x4E, 0x15, 0x1C, 0xAE, 0x06, 0xB6, 0x4B, 0xAE, 0x51, 0xAC, 0x38, 0x1D, 0xAE, 0x05, 0xC6,
0x25, 0x4C, 0xAE, 0x14, 0xB4, 0x61, 0xD2, 0x04, 0xAE, 0x07, 0xB7, 0x0A, 0xAE, 0x1E, 0xA2, 0x55,
0x27, 0xAE, 0x05, 0xC3, 0x0D, 0x52, 0xAE, 0x05, 0xD5, 0x3D, 0x6F, 0x11, 0x1D, 0x6F, 0x11, 0x1D,
0x67, 0x12, 0x1D, 0x54, 0x14, 0x1C, 0x3B, 0x17, 0xAE, 0x04, 0x3C, 0x22, 0x1F, 0x1F, 0x2C, 0x2C,
0x2C, 0x41, 0x41, 0x41, 0x59, 0x59, 0x59, 0xB6, 0xB6, 0xB6, 0xAE, 0x06, 0xB0, 0x09, 0x90, 0x90,
0x90, 0x45, 0x45, 0x45, 0x3D, 0x3D, 0x3D, 0xAE, 0x06, 0x82, 0x74, 0xAE, 0x06, 0xBB, 0x23, 0x33,
0xAE, 0x04, 0x04, 0x33, 0x35, 0x35, 0x35, 0x40, 0x40, 0x40, 0x58, 0x58, 0x58, 0x94, 0x94, 0x94,
0xAE, 0x0C, 0x8E, 0x68, 0xAE, 0x06, 0x8B, 0x0E, 0x55, 0x55, 0x55, 0xF5, 0xF5, 0xF5, 0x89, 0x89,
0x89, 0x3D, 0x3D, 0x3D, 0x28, 0x28, 0x28, 0xAE, 0x0C, 0x92, 0x7B, 0xAE, 0x0C, 0x0C, 0xAE, 0x12,
0x12, 0xAE, 0x06, 0xBB, 0x77, 0xAE, 0x09, 0xA5, 0x79, 0xAE, 0x33, 0x83, 0x5A, 0xAE, 0x09, 0xB7,
0x0A, 0xB3, 0xAE, 0x11, 0xC2, 0x4E, 0xAE, 0x09, 0x82, 0x29, 0xAE, 0x1E, 0x8A, 0x55, 0x38, 0xAE,
0x17, 0xB2, 0x3B, 0x73, 0x12, 0x1D, 0xAE, 0x1B, 0x3C, 0xAE, 0x3C, 0xB0, 0x12, 0x25, 0x1A, 0x1B,
0x42, 0x16, 0x1C, 0x88, 0xAE, 0x14, 0xB0, 0x12, 0x52, 0x15, 0x1C, 0x2D, 0xAE, 0x1A, 0xB5, 0x1D,
0xAE, 0x09, 0xBD, 0x0D, 0x52, 0x14, 0x1C, 0xC3, 0xAE, 0x12, 0xA5, 0x43, 0x0B, 0x1E, 0x2F, 0x1B,
0x1D, 0x29, 0x26, 0x26, 0x3B, 0x3B, 0x3B, 0x56, 0x56, 0x56, 0xC7, 0xC7, 0xC7, 0xF5, 0xF5, 0xF5,
0x9E, 0x9E, 0x9E, 0x42, 0x42, 0x42, 0x34, 0x34, 0x34, 0x2B, 0x2B, 0x2B, 0xAE, 0x0C, 0xAB, 0x1C,
0xAE, 0x09, 0xC1, 0x44, 0x20, 0x20, 0x20, 0xAE, 0x06, 0x9D, 0x50, 0xAE, 0x06, 0x99, 0x76, 0xAE,
0x09, 0x96, 0x1C, 0xAE, 0x06, 0x99, 0x28, 0x52, 0x52, 0x52, 0xDE, 0xDE, 0xDE, 0xB1, 0xB1, 0xB1,
0x3A, 0x3A, 0x3A, 0xAE, 0x21, 0x91, 0x74, 0xAE, 0x1C, 0x8E, 0x35, 0xAE, 0x32, 0x83, 0x5A, 0x1C,
0xAE, 0x05, 0xDB, 0x04, 0x42, 0x16, 0x1C, 0x87, 0xAE, 0x14, 0x82, 0x29, 0x58, 0x14, 0x1C, 0x31,
0x18, 0x1B, 0xAE, 0x18, 0x8B, 0x11, 0x1D, 0x1B, 0x1B, 0x28, 0x19, 0x1B, 0x48, 0x16, 0x1C, 0x74,
0xAE, 0x14, 0xB9, 0x6F, 0xAE, 0x5A, 0xB7, 0x46, 0x21, 0xAE, 0x05, 0x90, 0x1C, 0x65, 0x12, 0xAE,
0x13, 0x93, 0x76, 0x7D, 0x10, 0x1D, 0xAE, 0x1B, 0xBC, 0x51, 0xAE, 0x06, 0xB8, 0x77, 0x3F, 0xAE,
0x17, 0xAA, 0x4E, 0x8A, 0x0F, 0x1D, 0x31, 0x1D, 0x1F, 0x31, 0x2F, 0x2F, 0x49, 0x49, 0x49, 0x9A,
0x9A, 0x9A, 0xAE, 0x06, 0x83, 0x57, 0x3D, 0x3D, 0x3D, 0x2A, 0x2A, 0x2A, 0x20, 0x20, 0x20, 0xAE,
0x18, 0xA5, 0x0A, 0x1D, 0x1D, 0x1D, 0x2A, 0x2A, 0x2A, 0x46, 0x46, 0x46, 0x8D, 0x8D, 0x8D, 0xAE,
0x12, 0x99, 0x76, 0x4E, 0x4E, 0x4E, 0xD6, 0xD6, 0xD6, 0xBB, 0xBB, 0xBB, 0xAE, 0x0C, 0xA5, 0x1C,
0xAE, 0x66, 0x83, 0x5A, 0xAE, 0x06, 0x82, 0x29, 0x37, 0xAE, 0x05, 0xA7, 0x30, 0xAE, 0x12, 0xB9,
0x6F, 0x9B, 0x0C, 0x1E, 0x43, 0x16, 0x1C, 0x28, 0xAE, 0x14, 0x86, 0x06, 0xAE, 0x06, 0xC1, 0x23,
0x35, 0xAE, 0x05, 0xB4, 0x28, 0xAD, 0xAE, 0x11, 0x87, 0x70, 0xE1, 0x03, 0xAE, 0x1F, 0xB2, 0x77,
0xAE, 0x3D, 0xBE, 0x7A, 0x1B, 0x1B, 0x2F, 0xAE, 0x05, 0xD9, 0x4D, 0xCC, 0xAE, 0x11, 0x8C, 0x42,
0xC2, 0x06, 0x1F, 0x4D, 0xAE, 0x06, 0xC9, 0x52, 0xAE, 0x14, 0x83, 0x5D, 0x1F, 0xAE, 0x05, 0xCA,
0x3E, 0x51, 0x15, 0x1C, 0x85, 0xAE, 0x11, 0x85, 0x47, 0xFF, 0x00, 0x20, 0x4B, 0x15, 0x1C, 0x2F,
0x1F, 0x21, 0x38, 0x37, 0x37, 0x54, 0x54, 0x54, 0xDF, 0xDF, 0xDF, 0xC5, 0xC5, 0xC5, 0xAE, 0x06,
0x83, 0x27, 0xAE, 0x1B, 0xAB, 0x1C, 0xAE, 0x06, 0xA1, 0x12, 0x2B, 0x2B, 0x2B, 0x49, 0x49, 0x49,
0xAE, 0x06, 0x9D, 0x50, 0xAE, 0x09, 0x8B, 0x0E, 0xAE, 0x06, 0xA1, 0x2A, 0x48, 0x48, 0x48, 0xB4,
0xB4, 0xB4, 0xDE, 0xDE, 0xDE, 0x48, 0x48, 0x48, 0xAE, 0x21, 0xA4, 0x36, 0xAE, 0x51, 0x83, 0x5A,
0xAE, 0x06, 0xDF, 0x50, 0xAE, 0x15, 0x8B, 0x11, 0xEA, 0x02, 0x1F, 0x62, 0x13, 0x1D, 0x3D, 0xAE,
0x05, 0xD4, 0x66, 0x20, 0xAE, 0x05, 0x94, 0x3E, 0x1E, 0xAE, 0x08, 0xAE, 0x4C, 0x23, 0xAE, 0x05,
0xDC, 0x2C, 0x4B, 0x15, 0x1C, 0x74, 0x10, 0xAE, 0x13, 0xAB, 0x43, 0xB2, 0x09, 0x1E, 0x37, 0xAE,
0x1D, 0x99, 0x01, 0xAE, 0x3C, 0x83, 0x5A, 0xAE, 0x06, 0x8E, 0x2C, 0x43, 0xAE, 0x14, 0x88, 0x68,
0xF8, 0x01, 0x20, 0x83, 0x0F, 0x1D, 0x45, 0x16, 0x1C, 0x2D, 0xAE, 0x05, 0xB4, 0x6D, 0xAE, 0x06,
0xAF, 0x6B, 0xAE, 0x06, 0x81, 0x31, 0x21, 0xAE, 0x05, 0xB5, 0x11, 0x43, 0xAE, 0x05, 0xD3, 0x20,
0xBE, 0x07, 0xAE, 0x10, 0x81, 0x6A, 0xD8, 0x04, 0x1F, 0x3F, 0x17, 0x1C, 0x2C, 0x22, 0x23, 0x3C,
0x3C, 0x3C, 0xAE, 0x06, 0x91, 0x77, 0x94, 0x94, 0x94, 0xAE, 0x25, 0x91, 0x29, 0xAE, 0x05, 0x87,
0x1C, 0x52, 0x52, 0x52, 0xAE, 0x06, 0x8E, 0x68, 0xAE, 0x09, 0x92, 0x42, 0xAE, 0x06, 0xAD, 0x03,
0x3F, 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0xF5, 0xF5, 0xF5, 0x6F, 0x6F, 0x6F, 0x38, 0x38, 0x38, 0xAE,
0x1B, 0xB0, 0x5D, 0xAE, 0x54, 0x83, 0x5A, 0xAE, 0x06, 0x89, 0x24, 0x3C, 0xAE, 0x05, 0xE7, 0x04,
0xAE, 0x12, 0xB0, 0x18, 0xD4, 0x04, 0x1F, 0x62, 0x13, 0x1D, 0x46, 0x16, 0x1C, 0x35, 0x18, 0x1C,
0x2E, 0xAE, 0x05, 0xED, 0x52, 0x2C, 0x19, 0x1B, 0x31, 0x18, 0x1B, 0x3B, 0x17, 0x1C, 0x50, 0x15,
0x1C, 0x6F, 0x11, 0x1D, 0xAE, 0x12, 0x87, 0x31, 0xFF, 0x00, 0x20, 0x6E, 0x12, 0x1D, 0x2C, 0xAE,
0x1D, 0x8D, 0x70, 0xAE, 0x3F, 0xA9, 0x56, 0x20, 0xAE, 0x05, 0x9D, 0x56, 0x5A, 0xAE, 0x14, 0x8F,
0x60, 0xEA, 0x02, 0x1F, 0x77, 0x11, 0x1D, 0x4B, 0x15, 0x1C, 0x39, 0x18, 0x1C, 0xAE, 0x06, 0xEF,
0x03, 0x2B, 0xAE, 0x05, 0xEF, 0x12, 0x39, 0x18, 0x1C, 0x49, 0x15, 0x1C, 0x67, 0x12, 0x1D, 0x92,
0x0D, 0xAE, 0x13, 0x81, 0x67, 0xA4, 0x0B, 0x1E, 0x33, 0x18, 0x1C, 0x28, 0x23, 0x24, 0x3E, 0x3E,
0x3E, 0x80, 0x80, 0x80, 0xF5, 0xF5, 0xF5, 0x87, 0x87, 0x87, 0x36, 0x36, 0x36, 0xAE, 0x06, 0xB2,
0x6B, 0xAE, 0x1B, 0xA1, 0x4B, 0x25, 0x25, 0x25, 0x3D, 0x3D, 0x3D, 0x61, 0x61, 0x61, 0xBD, 0xBD,
0xBD, 0xF5, 0xF5, 0xF5, 0x49, 0x49, 0x49, 0xAE, 0x06, 0x83, 0x5A, 0xAE, 0x06, 0x92, 0x45, 0xAE,
0x06, 0xA4, 0x39, 0xE6, 0xE6, 0xE6, 0xC5, 0xC5, 0xC5, 0x46, 0x46, 0x46, 0x2C, 0x2C, 0x2C, 0xAE,
0x1E, 0x88, 0x02, 0xAE, 0x0C, 0xA6, 0x05, 0xAE, 0x0C, 0xB8, 0x38, 0xAE, 0x36, 0x83, 0x5A, 0xAE,
0x06, 0x89, 0x60, 0x2D, 0x19, 0x1B, 0x4D, 0x15, 0x1C, 0xB1, 0xAE, 0x14, 0x83, 0x27, 0xD4, 0x04,
0x1F, 0x7D, 0x10, 0x1D, 0x5F, 0x13, 0x1C, 0x53, 0x14, 0x1C, 0x50, 0x15, 0x1C, 0x52, 0x15, 0x1C,
0x59, 0x14, 0x1C, 0x68, 0x12, 0x1D, 0x78, 0x10, 0x1D, 0xBE, 0xAE, 0x14, 0xD5, 0x16, 0xCE, 0x05,
0x1F, 0x3B, 0xAE, 0x05, 0x98, 0x7E, 0xAE, 0x54, 0x9D, 0x50, 0xAE, 0x0C, 0xD2, 0x70, 0x43, 0x16,
0x1C, 0x84, 0xAE, 0x14, 0x8A, 0x58, 0xEA, 0x02, 0x1F, 0x8B, 0x0E, 0x1D, 0x63, 0x12, 0x1D, 0x55,
0xAE, 0x05, 0x81, 0x31, 0x50, 0x15, 0x1C, 0x56, 0x14, 0x1C, 0x63, 0x12, 0x1D, 0x74, 0x10, 0x1D,
0xA5, 0x0A, 0xAE, 0x13, 0xD5, 0x16, 0xF0, 0x01, 0x20, 0x45, 0xAE, 0x05, 0x90, 0x16, 0x25, 0x23,
0x23, 0x3B, 0x3B, 0x3B, 0x66, 0x66, 0x66, 0xAE, 0x06, 0x95, 0x51, 0xAE, 0x1E, 0x91, 0x77, 0x1D,
0x1D, 0x1D, 0x23, 0x23, 0x23, 0x31, 0x31, 0x31, 0x4F, 0x4F, 0x4F, 0x7D, 0x7D, 0x7D, 0xEF, 0xEF,
0xEF, 0xAE, 0x0F, 0x83, 0x5A, 0xAE, 0x06, 0x8B, 0x29, 0x44, 0x44, 0x44, 0xA1, 0xA1, 0xA1, 0xF5,
0xF5, 0xF5, 0x72, 0x72, 0x72, 0x3C, 0x3C, 0x3C, 0xAE, 0x12, 0xC9, 0x64, 0xAE, 0x0F, 0x8B, 0x5C,
0x22, 0x22, 0x22, 0x28, 0x28, 0x28, 0xAE, 0x06, 0xBE, 0x4D, 0xAE, 0x09, 0xBA, 0x7C, 0xAE, 0x39,
0x83, 0x5A, 0xAE, 0x06, 0xC0, 0x6A, 0x37, 0x18, 0x1C, 0x5A, 0x14, 0x1C, 0xDB, 0xAE, 0x14, 0xDA,
0x6F, 0xF8, 0x01, 0x20, 0xCD, 0x05, 0x1F, 0xAC, 0x09, 0x1E, 0xA2, 0x0B, 0x1E, 0xA3, 0x0B, 0x1E,
0xAD, 0x09, 0x1E, 0xCD, 0x05, 0xAE, 0x16, 0xDC, 0x4A, 0xF8, 0x01, 0x20, 0x5A, 0x14, 0x1C, 0x2C,
0xAE, 0x20, 0xDE, 0x73, 0xAE, 0x42, 0xB1, 0x0A, 0x20, 0xAE, 0x05, 0x8C, 0x0F, 0x50, 0x15, 0x1C,
0xBA, 0xAE, 0x11, 0x8A, 0x5B, 0xAE, 0x06, 0x06, 0xD5, 0x04, 0x1F, 0xB5, 0x08, 0xAE, 0x07, 0xEF,
0x4B, 0xA3, 0x0A, 0x1E, 0xC5, 0x06, 0x1F, 0xAE, 0x18, 0xE7, 0x76, 0x8B, 0x0F, 0x1D, 0x31, 0x18,
0xAE, 0x04, 0x51, 0xAE, 0x06, 0x86, 0x66, 0x53, 0x53, 0x53, 0xEE, 0xEE, 0xEE, 0xAC, 0xAC, 0xAC,
0x47, 0x47, 0x47, 0x2D, 0x2D, 0x2D, 0xAE, 0x06, 0xC4, 0x7D, 0xAE, 0x12, 0xA8, 0x76, 0x27, 0x27,
0x27, 0x33, 0x33, 0x33, 0x46, 0x46, 0x46, 0x62, 0x62, 0x62, 0xDB, 0xDB, 0xDB, 0xE2, 0xE2, 0xE2,
0xAE, 0x0F, 0x83, 0x5A, 0x1C, 0x1C, 0x1C, 0x23, 0x23, 0x23, 0x35, 0x35, 0x35, 0x4F, 0x4F, 0x4F,
0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0x52, 0x52, 0x52, 0x3A, 0x3A, 0x3A, 0x29, 0x29, 0x29, 0xAE,
0x12, 0x93, 0x13, 0xAE, 0x09, 0x54, 0x32, 0x32, 0x32, 0x3A, 0x3A, 0x3A, 0x4C, 0x4C, 0x4C, 0x2F,
0x2F, 0x2F, 0x23, 0x23, 0x23, 0xAE, 0x07, 0xC2, 0x21, 0xAE, 0x38, 0x83, 0x5A, 0xAE, 0x06, 0x8E,
0x6E, 0x27, 0xAE, 0x05, 0xBB, 0x2C, 0x6E, 0x12, 0xAE, 0x13, 0x92, 0x4B, 0xAE, 0x2A, 0xE3, 0x7E,
0x7D, 0x11, 0x1D, 0x32, 0xAE, 0x05, 0xD8, 0x6A, 0xAE, 0x57, 0xBE, 0x7A, 0xAE, 0x0F, 0x85, 0x0E,
0x36, 0xAE, 0x05, 0xD9, 0x74, 0xD3, 0xAE, 0x32, 0xE9, 0x06, 0xAE, 0x09, 0x09, 0xA5, 0x0B, 0x1E,
0x39, 0xAE, 0x05, 0xCB, 0x6F, 0x1D, 0xAE, 0x05, 0x8E, 0x35, 0x2D, 0x2D, 0x2D, 0x48, 0x48, 0x48,
0xC6, 0xC6, 0xC6, 0xE7, 0xE7, 0xE7, 0x67, 0x67, 0x67, 0x42, 0x42, 0x42, 0x30, 0x30, 0x30, 0x26,
0x26, 0x26, 0xAE, 0x06, 0x9C, 0x64, 0x21, 0x21, 0x21, 0xAE, 0x06, 0xAC, 0x47, 0x30, 0x30, 0x30,
0x3B, 0x3B, 0x3B, 0x4A, 0x4A, 0x4A, 0x5A, 0x5A, 0x5A, 0xC8, 0xC8, 0xC8, 0xE1, 0xE1, 0xE1, 0xA8,
0xA8, 0xA8, 0xAE, 0x06, 0x83, 0x5A, 0x2C, 0x2C, 0x2C, 0xAE, 0x09, 0x84, 0x0A, 0xAE, 0x06, 0xC6,
0x2E, 0x3C, 0x3C, 0x3C, 0x6F, 0x6F, 0x6F, 0xEE, 0xEE, 0xEE, 0xC6, 0xC6, 0xC6, 0x53, 0x53, 0x53,
0xAE, 0x06, 0xD1, 0x6C, 0x28, 0x28, 0x28, 0x23, 0x23, 0x23, 0xAE, 0x09, 0x54, 0x27, 0x27, 0x27,
0x2F, 0x2F, 0x2F, 0x3B, 0x3B, 0x3B, 0x49, 0x49, 0x49, 0x5F, 0x5F, 0x5F, 0xDB, 0xDB, 0xDB, 0x91,
0x91, 0x91, 0xAE, 0x09, 0xCE, 0x33, 0xAE, 0x3C, 0x83, 0x5A, 0xAE, 0x06, 0x8B, 0x14, 0x29, 0x19,
0x1B, 0x3F, 0x17, 0x1C, 0x6D, 0x12, 0xAE, 0x13, 0x8D, 0x40, 0xAE, 0x27, 0x83, 0x57, 0x35, 0x18,
0x1C, 0x24, 0xAE, 0x23, 0xED, 0x5B, 0xAE, 0x06, 0xB4, 0x64, 0x6E, 0xAE, 0x14, 0x83, 0x5A, 0x4D,
0xAE, 0x05, 0xCD, 0x26, 0xAE, 0x27, 0x85, 0x0E, 0x26, 0xAE, 0x05, 0x9A, 0x02, 0x56, 0x14, 0x1C,
0xCA, 0xAE, 0x11, 0x96, 0x28, 0xAE, 0x24, 0x81, 0x34, 0xA4, 0x0B, 0x1E, 0x3B, 0x17, 0x1C, 0x27,
0xAE, 0x08, 0xC7, 0x59, 0xAE, 0x06, 0x8E, 0x38, 0x39, 0x39, 0x39, 0x61, 0x61, 0x61, 0xEE, 0xEE,
0xEE, 0xDF, 0xDF, 0xDF, 0x69, 0x69, 0x69, 0x4B, 0x4B, 0x4B, 0x3F, 0x3F, 0x3F, 0x39, 0x39, 0x39,
0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x3A, 0x3A, 0x3A, 0x41, 0x41, 0x41, 0x4A, 0x4A, 0x4A, 0x54,
0x54, 0x54, 0x81, 0x81, 0x81, 0xAE, 0x06, 0x87, 0x0D, 0x71, 0x71, 0x71, 0xAE, 0x06, 0xB0, 0x12,
0x4A, 0x4A, 0x4A, 0x2F, 0x2F, 0x2F, 0xAE, 0x0C, 0x87, 0x10, 0x1F, 0x1F, 0x1F, 0x2B, 0x2B, 0x2B,
0x3F, 0x3F, 0x3F, 0x7C, 0x7C, 0x7C, 0xEE, 0xEE, 0xEE, 0xD7, 0xD7, 0xD7, 0x74, 0x74, 0x74, 0x4D,
0x4D, 0x4D, 0x41, 0x41, 0x41, 0x3A, 0x3A, 0x3A, 0xAE, 0x06, 0x54, 0x39, 0x39, 0x39, 0x40, 0x40,
0x40, 0x49, 0x49, 0x49, 0x55, 0x55, 0x55, 0x80, 0x80, 0x80, 0xDD, 0xDD, 0xDD, 0xC0, 0xC0, 0xC0,
0x31, 0x31, 0x31, 0xAE, 0x09, 0x92, 0x72, 0x20, 0x20, 0x20, 0x34, 0x34, 0x34, 0x4F, 0x4F, 0x4F,
0xD6, 0xD6, 0xD6, 0xAF, 0xAF, 0xAF, 0xAE, 0x06, 0x93, 0x0D, 0xAE, 0x2E, 0xEB, 0x38, 0xAE, 0x05,
0x9D, 0x23, 0x3A, 0x17, 0x1C, 0x55, 0x14, 0x1C, 0xC0, 0x07, 0x1F, 0xAE, 0x2A, 0xF2, 0x66, 0xCE,
0x05, 0x1F, 0x5B, 0x14, 0x1C, 0x32, 0xAE, 0x26, 0x83, 0x57, 0xAE, 0x09, 0x9D, 0x14, 0x63, 0xAE,
0x14, 0xD5, 0x4F, 0xAE, 0x06, 0x8D, 0x73, 0xAE, 0x2A, 0x88, 0x6B, 0xAE, 0x06, 0xCE, 0x63, 0x4E,
0x15, 0x1C, 0xA2, 0xAE, 0x14, 0xE3, 0x5A, 0xAE, 0x18, 0x81, 0x31, 0xE0, 0x03, 0x1F, 0x7D, 0x11,
0x1D, 0x38, 0xAE, 0x08, 0xFB, 0x51, 0xAE, 0x0C, 0x83, 0x09, 0x2A, 0x2A, 0x2A, 0x3E, 0x3E, 0x3E,
0xAE, 0x06, 0x83, 0x09, 0xE7, 0xE7, 0xE7, 0xA3, 0xA3, 0xA3, 0x67, 0x67, 0x67, 0x55, 0x55, 0x55,
0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x55, 0x55, 0x55, 0x5A, 0x5A, 0x5A, 0x97, 0x97, 0x97, 0xC5,
0xC5, 0xC5, 0xF5, 0xF5, 0xF5, 0xB8, 0xB8, 0xB8, 0x57, 0x57, 0x57, 0x4B, 0x4B, 0x4B, 0x7E, 0x7E,
0x7E, 0xF5, 0xF5, 0xF5, 0x7F, 0x7F, 0x7F, 0xAE, 0x06, 0xBA, 0x52, 0xAE, 0x12, 0xD1, 0x3F, 0x3E,
0x3E, 0x3E, 0x7A, 0x7A, 0x7A, 0xDE, 0xDE, 0xDE, 0xEE, 0xEE, 0xEE, 0xBD, 0xBD, 0xBD, 0x75, 0x75,
0x75, 0x56, 0x56, 0x56, 0xAE, 0x06, 0x54, 0x54, 0x54, 0x54, 0x59, 0x59, 0x59, 0x82, 0x82, 0x82,
0xAE, 0x06, 0x54, 0xB7, 0xB7, 0xB7, 0xAE, 0x0F, 0xD5, 0x19, 0xAE, 0x06, 0xD5, 0x16, 0x47, 0x47,
0x47, 0xD4, 0xD4, 0xD4, 0xAC, 0xAC, 0xAC, 0x33, 0x33, 0x33, 0xAE, 0x21, 0xBF, 0x45, 0xAE, 0x15,
0x83, 0x5D, 0x25, 0xAE, 0x05, 0xA3, 0x29, 0x45, 0x16, 0x1C, 0x68, 0x12, 0x1C, 0xBF, 0x07, 0xAE,
0x16, 0x8E, 0x50, 0xAE, 0x09, 0x87, 0x28, 0xCF, 0x05, 0x1F, 0x7D, 0x10, 0x1D, 0x3D, 0x17, 0x1C,
0xAE, 0x06, 0xEA, 0x49, 0xAE, 0x27, 0xF5, 0x09, 0xAE, 0x06, 0xCD, 0x29, 0x4C, 0x15, 0x1C, 0xAE,
0x12, 0x54, 0xAE, 0x06, 0xEE, 0x6B, 0xAE, 0x2D, 0xEC, 0x6F, 0x23, 0xAE, 0x05, 0x9D, 0x29, 0x3F,
0xAE, 0x05, 0x85, 0x11, 0xAC, 0x0A, 0x1E, 0xE9, 0xAE, 0x1D, 0x8C, 0x4E, 0xD8, 0x04, 0x1F, 0x98,
0x0D, 0x1D, 0x41, 0x16, 0x1C, 0x30, 0x18, 0x1B, 0x24, 0xAE, 0x11, 0xCF, 0x07, 0xAE, 0x06, 0x83,
0x09, 0x2B, 0x2B, 0x2B, 0xAE, 0x06, 0xAF, 0x50, 0xC4, 0xC4, 0xC4, 0xAE, 0x06, 0xAF, 0x6B, 0xDE,
0xDE, 0xDE, 0xAE, 0x06, 0xB3, 0x09, 0xAE, 0x06, 0xD8, 0x7C, 0xED, 0xED, 0xED, 0xC2, 0xC2, 0xC2,
0x72, 0x72, 0x72, 0x37, 0x37, 0x37, 0x2F, 0x2F, 0x2F, 0x35, 0x35, 0x35, 0x41, 0x41, 0x41, 0xAE,
0x06, 0xA1, 0x5D, 0x2A, 0x2A, 0x2A, 0xAE, 0x0F, 0x9D, 0x38, 0xAE, 0x06, 0x54, 0x29, 0x29, 0x29,
0x38, 0x38, 0x38, 0x48, 0x48, 0x48, 0x9E, 0x9E, 0x9E, 0xAE, 0x06, 0x45, 0xEE, 0xEE, 0xEE, 0xAE,
0x09, 0xB3, 0x60, 0xAE, 0x06, 0x66, 0xCB, 0xCB, 0xCB, 0x7F, 0x7F, 0x7F, 0x36, 0x36, 0x36, 0xAE,
0x06, 0x83, 0x57, 0xAE, 0x09, 0x8B, 0x56, 0x1F, 0x1F, 0x1F, 0x29, 0x29, 0x29, 0x39, 0x39, 0x39,
0xD2, 0xD2, 0xD2, 0xA8, 0xA8, 0xA8, 0xAE, 0x1E, 0xCA, 0x02, 0xAE, 0x1E, 0x94, 0x7A, 0xAE, 0x06,
0x81, 0x83, 0x74, 0x33, 0x18, 0x1C, 0x40, 0x17, 0x1C, 0x4D, 0x15, 0x1C, 0x75, 0x11, 0x1D, 0x9E,
0x0C, 0xAE, 0x07, 0xEE, 0x53, 0xBD, 0xAE, 0x05, 0xEE, 0x17, 0x90, 0x0E, 0x1D, 0x7E, 0x10, 0xAE,
0x07, 0xEA, 0x16, 0x2F, 0xAE, 0x05, 0xCF, 0x79, 0xAE, 0x1B, 0x81, 0x88, 0x19, 0xAE, 0x18, 0xD5,
0x4F, 0x32, 0x18, 0x1C, 0x41, 0x16, 0x1C, 0x4B, 0x15, 0x1C, 0x4F, 0x15, 0xAE, 0x07, 0x81, 0x85,
0x79, 0x39, 0xAE, 0x05, 0xE7, 0x10, 0xAE, 0x30, 0x81, 0x35, 0xAE, 0x06, 0xAF, 0x68, 0x26, 0xAE,
0x05, 0x92, 0x54, 0x3D, 0x17, 0x1C, 0x49, 0x15, 0x1C, 0x65, 0x13, 0x1C, 0x92, 0x0E, 0xAE, 0x0A,
0xF0, 0x04, 0xBC, 0x07, 0x1F, 0x9C, 0x0C, 0x1D, 0x8C, 0x0F, 0x1D, 0x4B, 0x15, 0x1C, 0x3E, 0xAE,
0x09, 0xB1, 0x31, 0xAE, 0x18, 0xA5, 0x2B, 0xAE, 0x05, 0xB7, 0x43, 0x28, 0x28, 0x28, 0x32, 0x32,
0x32, 0x3F, 0x3F, 0x3F, 0x59, 0x59, 0x59, 0x85, 0x85, 0x85, 0xAE, 0x06, 0xB3, 0x06, 0xAF, 0xAF,
0xAF, 0x9B, 0x9B, 0x9B, 0x81, 0x81, 0x81, 0x41, 0x41, 0x41, 0x37, 0x37, 0x37, 0x2D, 0x2D, 0x2D,
0x25, 0x25, 0x25, 0x21, 0x21, 0x21, 0x25, 0x25, 0x25, 0x2C, 0x2C, 0x2C, 0x30, 0x30, 0x30, 0x2B,
0x2B, 0x2B, 0x22, 0x22, 0x22, 0xAE, 0x15, 0xDC, 0x50, 0xAE, 0x0C, 0xE3, 0x7E, 0x45, 0x45, 0x45,
0x77, 0x77, 0x77, 0x9C, 0x9C, 0x9C, 0xAE, 0x06, 0x54, 0xAF, 0xAF, 0xAF, 0x82, 0x82, 0x82, 0x53,
0x53, 0x53, 0xAE, 0x06, 0xD5, 0x7F, 0xAE, 0x06, 0x96, 0x16, 0xAE, 0x12, 0xE0, 0x66, 0xAE, 0x09,
0xE3, 0x7E, 0xAE, 0x09, 0x92, 0x5A, 0xAE, 0x39, 0xFE, 0x03, 0x1F, 0x1A, 0x1B, 0x25, 0x1A, 0x1B,
0x2A, 0xAE, 0x05, 0xD4, 0x72, 0x36, 0x18, 0x1C, 0x3A, 0xAE, 0x05, 0xB2, 0x17, 0x3A, 0x17, 0x1C,
0x38, 0x18, 0x1C, 0x33, 0xAE, 0x05, 0x9D, 0x5F, 0xAE, 0x07, 0x81, 0x8B, 0x2E, 0xAE, 0x35, 0x81,
0x87, 0x4B, 0x1E, 0xAE, 0x08, 0x81, 0x8C, 0x05, 0x28, 0x19, 0xAE, 0x04, 0x63, 0x29, 0xAE, 0x3E,
0x4E, 0xAE, 0x09, 0xD6, 0x23, 0x23, 0xAE, 0x05, 0x51, 0x2F, 0xAE, 0x05, 0xF3, 0x64, 0x39, 0xAE,
0x05, 0x81, 0x31, 0x3B, 0x17, 0x1C, 0x39, 0x18, 0x1C, 0x34, 0xAE, 0x05, 0x9D, 0x5F, 0x29, 0x19,
0x1B, 0x24, 0xAE, 0x05, 0x83, 0x54, 0xAE, 0x21, 0x82, 0x18, 0x1E, 0x1E, 0x1E, 0xAE, 0x06, 0x82,
0x4D, 0x2E, 0x2E, 0x2E, 0x33, 0x33, 0x33, 0x37, 0x37, 0x37, 0x38, 0x38, 0x38, 0x37, 0x37, 0x37,
0x33, 0x33, 0x33, 0x2F, 0x2F, 0x2F, 0xAE, 0x06, 0x92, 0x00, 0xAE, 0x06, 0x86, 0x57, 0xAE, 0x09,
0x9D, 0x02, 0xAE, 0x09, 0xAF, 0x47, 0xAE, 0x21, 0xBB, 0x77, 0x2B, 0x2B, 0x2B, 0x31, 0x31, 0x31,
0x35, 0x35, 0x35, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x35, 0x35, 0x35, 0x30, 0x30, 0x30, 0x2A,
0x2A, 0x2A, 0xAE, 0x06, 0xEB, 0x35, 0xAE, 0x15, 0x83, 0x36, 0xAE, 0x0F, 0xEB, 0x32, 0xAE, 0x48,
0x81, 0x81, 0x66, 0x1F, 0xAE, 0x05, 0x87, 0x46, 0xAE, 0x06, 0xB9, 0x51, 0xAE, 0x09, 0xEE, 0x14,
0xAE, 0x2A, 0x81, 0x93, 0x1E, 0xAE, 0x78, 0x81, 0x91, 0x70, 0xAE, 0x09, 0x81, 0x31, 0xAE, 0x24,
0xBC, 0x33, 0xAE, 0x1E, 0xA0, 0x38, 0xAE, 0x06, 0x95, 0x45, 0xAE, 0x0F, 0xB3, 0x03, 0xAE, 0x3F,
0xC3, 0x2E, 0x20, 0x20, 0x20, 0xAE, 0x06, 0x54, 0xAE, 0x0C, 0xDC, 0x02, 0xAE, 0x82, 0x07, 0x81,
0x95, 0x34, 0xAE, 0x82, 0x0A, 0x82, 0x0A, 0xAE, 0x84, 0x14, 0x84, 0x14, 0xAE, 0x88, 0x28, 0x88,
0x28, 0xAE, 0x82, 0x40, 0x82, 0x40, 0xAE, 0x09, 0x81, 0x83, 0x0E, 0xAE, 0x09, 0x93, 0x2B, 0xAE,
0x09, 0x94, 0x08, 0xAE, 0x0F, 0x0F, 0xAE, 0x1E, 0x1E, 0xAE, 0x3C, 0x3C, 0xAE, 0x78, 0x78, 0xAE,
0x81, 0x4F, 0x81, 0x4F, 0x20, 0x20, 0x20, 0xAE, 0x06, 0x81, 0x85, 0x43, 0xAE, 0x09, 0xA2, 0x1F,
0xAE, 0x06, 0x81, 0x81, 0x75, 0x32, 0x32, 0x32, 0x34, 0x34, 0x34, 0x34, 0xAE, 0x04, 0x04, 0xAE,
0x08, 0x08, 0xAE, 0x10, 0x10, 0xAE, 0x20, 0x20, 0xAE, 0x40, 0x40, 0xAE, 0x81, 0x00, 0x81, 0x00,
0xAE, 0x81, 0x3C, 0x81, 0x3C, 0xAE, 0x06, 0x9E, 0x69, 0x29, 0x29, 0x29, 0xAE, 0x06, 0xA2, 0x2B,
0xAE, 0x06, 0xB8, 0x65, 0x2E, 0x2E, 0x2E, 0x3B, 0x3B, 0x3B, 0x44, 0x44, 0x44, 0x47, 0x47, 0x47,
0x47, 0xAE, 0x04, 0x04, 0xAE, 0x08, 0x08, 0xAE, 0x10, 0x10, 0xAE, 0x20, 0x20, 0xAE, 0x40, 0x40,
0xAE, 0x81, 0x00, 0x81, 0x00, 0xAE, 0x81, 0x3C, 0x81, 0x3C, 0x45, 0x45, 0x45, 0x3E, 0x3E, 0x3E,
0x33, 0x33, 0x33, 0xAE, 0x06, 0xFE, 0x2D, 0xAE, 0x09, 0x81, 0x83, 0x14, 0xAE, 0x06, 0xF3, 0x19,
0xAE, 0x06, 0x06, 0xAE, 0x0C, 0x0C, 0xAE, 0x18, 0x18, 0xAE, 0x30, 0x30, 0xAE, 0x60, 0x60, 0xAE,
0x81, 0x40, 0x81, 0x40, 0xAE, 0x4B, 0x4B, 0xAE, 0x09, 0xAC, 0x74, 0xAE, 0x06, 0xAD, 0x2D, 0x32,
0x32, 0x32, 0x38, 0x38, 0x38, 0xAE, 0x09, 0xE5, 0x2F, 0xAE, 0x09, 0x09, 0xAE, 0x12, 0x12, 0xAE,
0x24, 0x24, 0xAE, 0x48, 0x48, 0xAE, 0x81, 0x10, 0x81, 0x10, 0xAE, 0x81, 0x1C, 0x81, 0x1C, 0xAE,
0x06, 0xDA, 0x0C, 0x2C, 0x2C, 0x2C, 0xAE, 0x09, 0xAC, 0x56, 0xAE, 0x06, 0xE0, 0x5D, 0xAE, 0x06,
0x81, 0x82, 0x7C, 0xAE, 0x06, 0xC3, 0x28, 0xAE, 0x06, 0x06, 0xAE, 0x0C, 0x0C, 0xAE, 0x18, 0x18,
0xAE, 0x30, 0x30, 0xAE, 0x60, 0x60, 0xAE, 0x81, 0x40, 0x81, 0x40, 0xAE, 0x3C, 0x3C, 0x27, 0x27,
0x27, 0xAE, 0x06, 0xC0, 0x22, 0xAE, 0x42, 0xA9, 0x7D, 0xAE, 0x93, 0x10, 0xA9, 0x65, 0xAE, 0x83,
0x33, 0xAD, 0x15, 0xAE, 0x06, 0xC0, 0x3D, 0xAE, 0x06, 0x97, 0x0B, 0xAE, 0x09, 0x81, 0x87, 0x4B,
0xAE, 0x06, 0x97, 0x17, 0xAE, 0x06, 0x1E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0xAE, 0x06, 0xDA,
0x5D, 0xAE, 0x06, 0xAD, 0x42, 0xAE, 0x2D, 0xC0, 0x5E, 0xAE, 0x06, 0x9F, 0x13, 0xAE, 0x15, 0x36,
0xAE, 0x09, 0xAE, 0x13, 0xAE, 0x48, 0x51, 0xAE, 0x73, 0x81, 0xC7, 0x37, 0xAE, 0x08, 0xC2, 0x7E,
0xAE, 0x21, 0x81, 0xAE, 0x66, 0xAE, 0x12, 0xE4, 0x34, 0xAE, 0x5D, 0x81, 0x19, 0xAE, 0x06, 0xF4,
0x5F, 0x36, 0x36, 0x36, 0x2B, 0x2B, 0x2B, 0xAE, 0x06, 0x9E, 0x36, 0x2D, 0x2D, 0x2D, 0xAE, 0x06,
0x0C, 0xAE, 0x09, 0x1E, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x2F, 0x2F, 0x2F, 0xAE, 0x06, 0x81,
0xB3, 0x08, 0x2F, 0x2F, 0x2F, 0xAE, 0x15, 0x81, 0xA8, 0x75, 0xAE, 0x1B, 0x63, 0x31, 0x31, 0x31,
0x37, 0x37, 0x37, 0xAE, 0x06, 0x81, 0x96, 0x15, 0xAE, 0x0F, 0x1B, 0xAE, 0x06, 0x81, 0xB4, 0x72,
0xAE, 0x2D, 0xF5, 0x3C, 0xAE, 0x1B, 0x51, 0xAE, 0x21, 0x83, 0x03, 0xAE, 0x4E, 0xC5, 0x75, 0xAE,
0x06, 0x81, 0x9B, 0x59, 0x2C, 0x2C, 0x2C, 0x2E, 0x2E, 0x2E, 0xAE, 0x1E, 0x81, 0x43, 0x1E, 0x1E,
0x1E, 0x27, 0x27, 0x27, 0xAE, 0x06, 0x81, 0xA4, 0x1D, 0xAE, 0x48, 0xCA, 0x26, 0xAE, 0x1E, 0x1E,
0x23, 0x23, 0x23, 0x3F, 0x3F, 0x3F, 0xA5, 0xA5, 0xA5, 0x63, 0x63, 0x63, 0x23, 0x23, 0x23, 0x29,
0x29, 0x29, 0x6C, 0x6C, 0x6C, 0x83, 0x83, 0x83, 0x24, 0x24, 0x24, 0xAE, 0x06, 0x81, 0x9E, 0x0B,
0x41, 0x41, 0x41, 0x93, 0x93, 0x93, 0xAA, 0xAA, 0xAA, 0x8A, 0x8A, 0x8A, 0xAE, 0x06, 0xE2, 0x50,
0x9A, 0x9A, 0x9A, 0x46, 0x46, 0x46, 0xAE, 0x2A, 0x82, 0x20, 0x25, 0x25, 0x25, 0x48, 0x48, 0x48,
0xBB, 0xBB, 0xBB, 0x31, 0x31, 0x31, 0xAE, 0x12, 0x7E, 0x3D, 0x3D, 0x3D, 0xA3, 0xA3, 0xA3, 0x2B,
0x2B, 0x2B, 0xAE, 0x2A, 0x81, 0x34, 0xAE, 0x1B, 0x51, 0xAE, 0x1B, 0x83, 0x03, 0xAE, 0x06, 0xAE,
0x7F, 0x2E, 0x2E, 0x2E, 0xAE, 0x30, 0xDB, 0x64, 0xAE, 0x1E, 0x57, 0x25, 0x25, 0x25, 0x4E, 0x4E,
0x4E, 0x9A, 0x9A, 0x9A, 0x26, 0x26, 0x26, 0xAE, 0x1E, 0x85, 0x0E, 0x34, 0x34, 0x34, 0x87, 0x87,
0x87, 0x60, 0x60, 0x60, 0xAE, 0x12, 0xD9, 0x0B, 0xAE, 0x09, 0x8A, 0x0D, 0x22, 0x22, 0x22, 0xAE,
0x09, 0x8A, 0x22, 0xAE, 0x06, 0xE8, 0x44, 0xAE, 0x06, 0x81, 0xA8, 0x24, 0xAE, 0x0F, 0x81, 0xA3,
0x3D, 0xAE, 0x1B, 0x1B, 0xAE, 0x06, 0xD2, 0x46, 0x23, 0x23, 0x23, 0x2B, 0x2B, 0x2B, 0x4A, 0x4A,
0x4A, 0xA7, 0xA7, 0xA7, 0x67, 0x67, 0x67, 0xAE, 0x06, 0x81, 0xA8, 0x18, 0x56, 0x56, 0x56, 0x68,
0x68, 0x68, 0xAE, 0x06, 0x5D, 0x32, 0x32, 0x32, 0x6A, 0x6A, 0x6A, 0xA6, 0xA6, 0xA6, 0x3F, 0x3F,
0x3F, 0xAE, 0x06, 0xD0, 0x0E, 0x2E, 0x2E, 0x2E, 0x7B, 0x7B, 0x7B, 0x36, 0x36, 0x36, 0xAE, 0x0C,
0xA6, 0x20, 0xAE, 0x0C, 0x8B, 0x2F, 0xAE, 0x0C, 0x88, 0x7D, 0xAE, 0x06, 0x81, 0x28, 0x2E, 0x2E,
0x2E, 0x54, 0x54, 0x54, 0xBB, 0xBB, 0xBB, 0x36, 0x36, 0x36, 0xAE, 0x12, 0x83, 0x24, 0x43, 0x43,
0x43, 0xA4, 0xA4, 0xA4, 0x33, 0x33, 0x33, 0xAE, 0x12, 0x45, 0xAE, 0x12, 0x60, 0xAE, 0x06, 0x81,
0x43, 0x28, 0x28, 0x28, 0x51, 0x51, 0x51, 0xAE, 0x06, 0x51, 0xAE, 0x09, 0x8B, 0x50, 0xAE, 0x0C,
0xD1, 0x27, 0xAE, 0x09, 0x81, 0x76, 0xAE, 0x09, 0x33, 0xAE, 0x06, 0x87, 0x67, 0x65, 0x65, 0x65,
0x90, 0x90, 0x90, 0xAE, 0x0C, 0xDC, 0x4A, 0xAE, 0x15, 0x60, 0xAE, 0x2D, 0x83, 0x5A, 0x23, 0x23,
0x23, 0xAE, 0x06, 0xDD, 0x03, 0x25, 0x25, 0x25, 0xAE, 0x09, 0x81, 0x0D, 0xAE, 0x06, 0x82, 0x5C,
0xAE, 0x0C, 0x54, 0xAE, 0x06, 0x81, 0x86, 0x17, 0x8A, 0x8A, 0x8A, 0x63, 0x63, 0x63, 0xAE, 0x0F,
0x84, 0x5B, 0xAE, 0x06, 0x45, 0x2D, 0x2D, 0x2D, 0x35, 0x35, 0x35, 0xAE, 0x06, 0x81, 0xAF, 0x40,
0x3D, 0x3D, 0x3D, 0x34, 0x34, 0x34, 0x30, 0x30, 0x30, 0x38, 0x38, 0x38, 0x3F, 0x3F, 0x3F, 0x3D,
0x3D, 0x3D, 0x2E, 0x2E, 0x2E, 0x21, 0x21, 0x21, 0xAE, 0x06, 0x81, 0x61, 0xAE, 0x06, 0x89, 0x69,
0x3A, 0x3A, 0x3A, 0x40, 0x40, 0x40, 0xAE, 0x06, 0x81, 0xAB, 0x57, 0xAE, 0x09, 0xA9, 0x2F, 0xAE,
0x06, 0xD7, 0x2D, 0x38, 0x38, 0x38, 0x3E, 0x3E, 0x3E, 0x42, 0x42, 0x42, 0x56, 0x56, 0x56, 0xAE,
0x06, 0x83, 0x5A, 0x23, 0x23, 0x23, 0xAE, 0x06, 0x81, 0x8F, 0x08, 0xAE, 0x06, 0x81, 0xBA, 0x54,
0x27, 0x27, 0x27, 0x43, 0x43, 0x43, 0x7C, 0x7C, 0x7C, 0x92, 0x92, 0x92, 0x41, 0x41, 0x41, 0xAE,
0x06, 0xD7, 0x39, 0x2C, 0x2C, 0x2C, 0xAE, 0x06, 0x81, 0xB7, 0x60, 0xAE, 0x09, 0xE3, 0x0C, 0x32,
0x32, 0x32, 0x3D, 0x3D, 0x3D, 0x3E, 0x3E, 0x3E, 0x34, 0x34, 0x34, 0xAE, 0x06, 0x8B, 0x26, 0xAE,
0x06, 0x7E, 0x2D, 0x2D, 0x2D, 0x3B, 0x3B, 0x3B, 0x3E, 0x3E, 0x3E, 0x43, 0x43, 0x43, 0x5D, 0x5D,
0x5D, 0xAE, 0x18, 0x83, 0x5A, 0x44, 0x44, 0x44, 0xA5, 0xA5, 0xA5, 0x42, 0x42, 0x42, 0x3D, 0x3D,
0x3D, 0x3F, 0x3F, 0x3F, 0x37, 0x37, 0x37, 0x26, 0x26, 0x26, 0xAE, 0x06, 0x81, 0x28, 0xAE, 0x06,
0x89, 0x42, 0x35, 0x35, 0x35, 0xAE, 0x06, 0x81, 0x5E, 0x31, 0x31, 0x31, 0xAE, 0x06, 0x81, 0x43,
0xAE, 0x09, 0x83, 0x5A, 0xAE, 0x06, 0x81, 0xA1, 0x5C, 0x2D, 0x2D, 0x2D, 0x33, 0x33, 0x33, 0xAE,
0x06, 0xFD, 0x7A, 0xAE, 0x0F, 0x81, 0x76, 0xAE, 0x06, 0x33, 0xAE, 0x06, 0x48, 0x45, 0x45, 0x45,
0x7F, 0x7F, 0x7F, 0xA9, 0xA9, 0xA9, 0x44, 0x44, 0x44, 0xAE, 0x06, 0x81, 0x28, 0xAE, 0x18, 0x60,
0xAE, 0x33, 0x8D, 0x4F, 0xAE, 0x06, 0x81, 0xAB, 0x30, 0xAE, 0x06, 0x0C, 0xAE, 0x06, 0x81, 0x95,
0x0E, 0xAE, 0x06, 0x82, 0x14, 0x33, 0x33, 0x33, 0xAE, 0x06, 0x81, 0xBC, 0x5C, 0xAE, 0x1B, 0x83,
0x5A, 0xAE, 0x06, 0xF0, 0x13, 0x61, 0x61, 0x61, 0x80, 0x80, 0x80, 0x77, 0x77, 0x77, 0x9E, 0x9E,
0x9E, 0xA5, 0xA5, 0xA5, 0x80, 0x80, 0x80, 0x4E, 0x4E, 0x4E, 0x7D, 0x7D, 0x7D, 0xA5, 0xA5, 0xA5,
0xA5, 0xA5, 0xA5, 0x73, 0x73, 0x73, 0x2F, 0x2F, 0x2F, 0xAE, 0x06, 0x8C, 0x4E, 0x2E, 0x2E, 0x2E,
0x44, 0x44, 0x44, 0x7F, 0x7F, 0x7F, 0xAE, 0x06, 0x1B, 0x7C, 0x7C, 0x7C, 0x36, 0x36, 0x36, 0xAE,
0x06, 0x81, 0x67, 0x29, 0x29, 0x29, 0x3F, 0x3F, 0x3F, 0x77, 0x77, 0x77, 0xA4, 0xA4, 0xA4, 0x9F,
0x9F, 0x9F, 0x83, 0x83, 0x83, 0xA8, 0xA8, 0xA8, 0x68, 0x68, 0x68, 0x25, 0x25, 0x25, 0x29, 0x29,
0x29, 0x5A, 0x5A, 0x5A, 0x74, 0x74, 0x74, 0x27, 0x27, 0x27, 0x2A, 0x2A, 0x2A, 0x7B, 0x7B, 0x7B,
0xAD, 0xAD, 0xAD, 0xB1, 0xB1, 0xB1, 0xA3, 0xA3, 0xA3, 0x50, 0x50, 0x50, 0x25, 0x25, 0x25, 0x38,
0x38, 0x38, 0x8E, 0x8E, 0x8E, 0x29, 0x29, 0x29, 0xAE, 0x06, 0x84, 0x6A, 0x37, 0x37, 0x37, 0x5D,
0x5D, 0x5D, 0x98, 0x98, 0x98, 0xA4, 0xA4, 0xA4, 0x90, 0x90, 0x90, 0x46, 0x46, 0x46, 0x25, 0x25,
0x25, 0x20, 0x20, 0x20, 0x2E, 0x2E, 0x2E, 0x45, 0x45, 0x45, 0x8C, 0x8C, 0x8C, 0xA4, 0xA4, 0xA4,
0x99, 0x99, 0x99, 0x7B, 0x7B, 0x7B, 0xAE, 0x18, 0x83, 0x5A, 0x46, 0x46, 0x46, 0xA7, 0xA7, 0xA7,
0x5C, 0x5C, 0x5C, 0x97, 0x97, 0x97, 0xA5, 0xA5, 0xA5, 0x98, 0x98, 0x98, 0x46, 0x46, 0x46, 0xAE,
0x09, 0x83, 0x42, 0x3D, 0x3D, 0x3D, 0x6F, 0x6F, 0x6F, 0x9E, 0x9E, 0x9E, 0xA4, 0xA4, 0xA4, 0x82,
0x82, 0x82, 0x35, 0x35, 0x35, 0xAE, 0x06, 0xEB, 0x11, 0xAE, 0x06, 0x83, 0x5A, 0x3D, 0x3D, 0x3D,
0x32, 0x32, 0x32, 0x47, 0x47, 0x47, 0x8F, 0x8F, 0x8F, 0x71, 0x71, 0x71, 0x23, 0x23, 0x23, 0xAE,
0x06, 0xE4, 0x19, 0x83, 0x83, 0x83, 0xA4, 0xA4, 0xA4, 0xAE, 0x09, 0x33, 0xAE, 0x06, 0x90, 0x1F,
0x7C, 0x7C, 0x7C, 0xAD, 0xAD, 0xAD, 0xB6, 0xB6, 0xB6, 0xA4, 0xA4, 0xA4, 0x50, 0x50, 0x50, 0xAE,
0x06, 0x81, 0xC1, 0x04, 0xAE, 0x15, 0x60, 0xAE, 0x30, 0x8D, 0x4F, 0xAE, 0x09, 0x82, 0x14, 0xAE,
0x06, 0x85, 0x29, 0xA1, 0xA1, 0xA1, 0x6C, 0x6C, 0x6C, 0xAE, 0x06, 0x81, 0x4F, 0x8B, 0x8B, 0x8B,
0x38, 0x38, 0x38, 0x23, 0x23, 0x23, 0xAE, 0x1E, 0x83, 0x5A, 0x31, 0x31, 0x31, 0x72, 0x72, 0x72,
0xAC, 0xAC, 0xAC, 0x81, 0x81, 0x81, 0x38, 0x38, 0x38, 0x54, 0x54, 0x54, 0xA8, 0xA8, 0xA8, 0xA1,
0xA1, 0xA1, 0x80, 0x80, 0x80, 0x3A, 0x3A, 0x3A, 0x54, 0x54, 0x54, 0xAB, 0xAB, 0xAB, 0x66, 0x66,
0x66, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x40, 0x40, 0x40, 0x93, 0x93, 0x93, 0x96, 0x96, 0x96,
0x45, 0x45, 0x45, 0x4D, 0x4D, 0x4D, 0x99, 0x99, 0x99, 0x90, 0x90, 0x90, 0xAE, 0x06, 0x8F, 0x69,
0x3A, 0x3A, 0x3A, 0x79, 0x79, 0x79, 0xA4, 0xA4, 0xA4, 0x45, 0x45, 0x45, 0x3F, 0x3F, 0x3F, 0x8C,
0x8C, 0x8C, 0xB6, 0xB6, 0xB6, 0xAE, 0x06, 0x83, 0x5A, 0x2E, 0x2E, 0x2E, 0x6A, 0x6A, 0x6A, 0x87,
0x87, 0x87, 0xAE, 0x06, 0x8A, 0x7C, 0x3A, 0x3A, 0x3A, 0x72, 0x72, 0x72, 0x8C, 0x8C, 0x8C, 0x34,
0x34, 0x34, 0x20, 0x20, 0x20, 0x25, 0x25, 0x25, 0x41, 0x41, 0x41, 0xA4, 0xA4, 0xA4, 0x2E, 0x2E,
0x2E, 0xAE, 0x06, 0xFC, 0x4C, 0x56, 0x56, 0x56, 0xAB, 0xAB, 0xAB, 0x6A, 0x6A, 0x6A, 0x41, 0x41,
0x41, 0x71, 0x71, 0x71, 0xA5, 0xA5, 0xA5, 0xAE, 0x06, 0x81, 0xBE, 0x67, 0xAE, 0x06, 0x7E, 0x8F,
0x8F, 0x8F, 0x37, 0x37, 0x37, 0x4F, 0x4F, 0x4F, 0x99, 0x99, 0x99, 0xAE, 0x18, 0x83, 0x5A, 0x47,
0x47, 0x47, 0xA7, 0xA7, 0xA7, 0x98, 0x98, 0x98, 0xAE, 0x06, 0x81, 0xBF, 0x71, 0x8E, 0x8E, 0x8E,
0x98, 0x98, 0x98, 0x2C, 0x2C, 0x2C, 0xAE, 0x06, 0x81, 0x8B, 0x7C, 0x72, 0x72, 0x72, 0xA5, 0xA5,
0xA5, 0x56, 0x56, 0x56, 0x43, 0x43, 0x43, 0x87, 0x87, 0x87, 0x90, 0x90, 0x90, 0x2D, 0x2D, 0x2D,
0x29, 0x29, 0x29, 0xAE, 0x06, 0x83, 0x5A, 0x4E, 0x4E, 0x4E, 0x4C, 0x4C, 0x4C, 0x9A, 0x9A, 0x9A,
0x95, 0x95, 0x95, 0x28, 0x28, 0x28, 0xAE, 0x06, 0x81, 0x90, 0x4E, 0x8E, 0x8E, 0x8E, 0x7F, 0x7F,
0x7F, 0x3A, 0x3A, 0x3A, 0x42, 0x42, 0x42, 0x8D, 0x8D, 0x8D, 0x8F, 0x8F, 0x8F, 0x2B, 0x2B, 0x2B,
0xAE, 0x06, 0x8F, 0x51, 0x7A, 0x7A, 0x7A, 0xA7, 0xA7, 0xA7, 0x3A, 0x3A, 0x3A, 0xAE, 0x06, 0x8D,
0x52, 0xAE, 0x18, 0x60, 0xAE, 0x0F, 0x8D, 0x37, 0xAE, 0x06, 0x94, 0x59, 0xAE, 0x06, 0x81, 0x89,
0x5F, 0xAE, 0x12, 0x91, 0x7D, 0xAE, 0x0C, 0x82, 0x14, 0xAE, 0x09, 0x84, 0x73, 0x91, 0x91, 0x91,
0x43, 0x43, 0x43, 0x4D, 0x4D, 0x4D, 0x9A, 0x9A, 0x9A, 0x91, 0x91, 0x91, 0xAE, 0x06, 0x8A, 0x04,
0xAE, 0x18, 0x83, 0x5A, 0xAE, 0x06, 0x82, 0x4A, 0xAE, 0x06, 0x82, 0x3E, 0x32, 0x32, 0x32, 0xAE,
0x06, 0x86, 0x30, 0x79, 0x79, 0x79, 0x98, 0x98, 0x98, 0xAE, 0x06, 0x8A, 0x6A, 0x37, 0x37, 0x37,
0x7D, 0x7D, 0x7D, 0x88, 0x88, 0x88, 0xAE, 0x06, 0x95, 0x3F, 0x5E, 0x5E, 0x5E, 0xA5, 0xA5, 0xA5,
0xAE, 0x06, 0x83, 0x12, 0x29, 0x29, 0x29, 0x46, 0x46, 0x46, 0xA5, 0xA5, 0xA5, 0x50, 0x50, 0x50,
0x2B, 0x2B, 0x2B, 0x45, 0x45, 0x45, 0xAB, 0xAB, 0xAB, 0x52, 0x52, 0x52, 0x22, 0x22, 0x22, 0x2A,
0x2A, 0x2A, 0x4E, 0x4E, 0x4E, 0xAC, 0xAC, 0xAC, 0xAE, 0x06, 0x83, 0x5A, 0x2F, 0x2F, 0x2F, 0x6B,
0x6B, 0x6B, 0xAE, 0x06, 0x83, 0x5A, 0xAE, 0x06, 0x81, 0xA8, 0x18, 0xAE, 0x09, 0x0F, 0xAE, 0x0C,
0x8E, 0x17, 0xAE, 0x06, 0xF4, 0x3B, 0x3F, 0x3F, 0x3F, 0x96, 0x96, 0x96, 0x7B, 0x7B, 0x7B, 0x43,
0x43, 0x43, 0x42, 0x42, 0x42, 0x55, 0x55, 0x55, 0x96, 0x96, 0x96, 0x71, 0x71, 0x71, 0x34, 0x34,
0x34, 0x55, 0x55, 0x55, 0xB0, 0xB0, 0xB0, 0x35, 0x35, 0x35, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x2F,
0x61, 0x61, 0x61, 0xAE, 0x18, 0x83, 0x5A, 0x45, 0x45, 0x45, 0xA6, 0xA6, 0xA6, 0x51, 0x51, 0x51,
0x22, 0x22, 0x22, 0x2B, 0x2B, 0x2B, 0x50, 0x50, 0x50, 0xB0, 0xB0, 0xB0, 0xAE, 0x06, 0x81, 0xBF,
0x74, 0x47, 0x47, 0x47, 0xAC, 0xAC, 0xAC, 0x5C, 0x5C, 0x5C, 0x3F, 0x3F, 0x3F, 0x45, 0x45, 0x45,
0x5B, 0x5B, 0x5B, 0xAC, 0xAC, 0xAC, 0x43, 0x43, 0x43, 0x2B, 0x2B, 0x2B, 0xAE, 0x06, 0x8F, 0x39,
0x68, 0x68, 0x68, 0x9C, 0x9C, 0x9C, 0x97, 0x97, 0x97, 0x2C, 0x2C, 0x2C, 0x1E, 0x1E, 0x1E, 0xAE,
0x06, 0xF2, 0x33, 0x56, 0x56, 0x56, 0x38, 0x38, 0x38, 0xAE, 0x06, 0x81, 0xC6, 0x75, 0x58, 0x58,
0x58, 0xA5, 0xA5, 0xA5, 0xAE, 0x06, 0x85, 0x08, 0x33, 0x33, 0x33, 0xAE, 0x06, 0x83, 0x48, 0x2F,
0x2F, 0x2F, 0xAE, 0x09, 0x84, 0x55, 0xAE, 0x15, 0x60, 0xAE, 0x09, 0x83, 0x3F, 0xAE, 0x06, 0x81,
0xB5, 0x5B, 0x30, 0x30, 0x30, 0x3E, 0x3E, 0x3E, 0x40, 0x40, 0x40, 0x36, 0x36, 0x36, 0xAE, 0x12,
0x98, 0x15, 0xAE, 0x0C, 0x82, 0x14, 0x28, 0x28, 0x28, 0x52, 0x52, 0x52, 0xAE, 0x06, 0x88, 0x4D,
0xAE, 0x06, 0x8C, 0x18, 0x4B, 0x4B, 0x4B, 0xB0, 0xB0, 0xB0, 0x43, 0x43, 0x43, 0xAE, 0x06, 0x81,
0xB2, 0x67, 0xAE, 0x18, 0x83, 0x5A, 0x30, 0x30, 0x30, 0x6C, 0x6C, 0x6C, 0x88, 0x88, 0x88, 0xAE,
0x06, 0x81, 0xB5, 0x6A, 0xAE, 0x09, 0x0F, 0xAE, 0x06, 0x83, 0x06, 0xAE, 0x09, 0x0F, 0xAE, 0x06,
0x99, 0x46, 0x7F, 0x7F, 0x7F, 0x8A, 0x8A, 0x8A, 0xAE, 0x06, 0x81, 0xA8, 0x18, 0xAE, 0x06, 0x85,
0x32, 0x8D, 0x8D, 0x8D, 0x78, 0x78, 0x78, 0x30, 0x30, 0x30, 0x48, 0x48, 0x48, 0xAE, 0x06, 0x82,
0x3E, 0xAE, 0x06, 0x93, 0x5B, 0xAE, 0x06, 0x86, 0x36, 0x67, 0x67, 0x67, 0xAE, 0x2D, 0x83, 0x5A,
0xAE, 0x06, 0x8A, 0x49, 0xA8, 0xA8, 0xA8, 0x8F, 0x8F, 0x8F, 0x8A, 0x8A, 0x8A, 0x8B, 0x8B, 0x8B,
0x8E, 0x8E, 0x8E, 0xA5, 0xA5, 0xA5, 0x86, 0x86, 0x86, 0x37, 0x37, 0x37, 0x6E, 0x6E, 0x6E, 0xAE,
0x06, 0x82, 0x71, 0xAE, 0x0F, 0x91, 0x71, 0xAE, 0x18, 0x92, 0x42, 0x31, 0x31, 0x31, 0x1C, 0x1C,
0x1C, 0x28, 0x28, 0x28, 0x4F, 0x4F, 0x4F, 0xBB, 0xBB, 0xBB, 0x35, 0x35, 0x35, 0x25, 0x25, 0x25,
0x4C, 0x4C, 0x4C, 0xB2, 0xB2, 0xB2, 0xAE, 0x09, 0x60, 0x8F, 0x8F, 0x8F, 0xB0, 0xB0, 0xB0, 0x60,
0x60, 0x60, 0x2B, 0x2B, 0x2B, 0x56, 0x56, 0x56, 0xBB, 0xBB, 0xBB, 0xA0, 0xA0, 0xA0, 0xA8, 0xA8,
0xA8, 0x3F, 0x3F, 0x3F, 0xAE, 0x06, 0x8A, 0x43, 0xAE, 0x06, 0x8D, 0x31, 0x3E, 0x3E, 0x3E, 0x5A,
0x5A, 0x5A, 0x83, 0x83, 0x83, 0x8C, 0x8C, 0x8C, 0x91, 0x91, 0x91, 0xA6, 0xA6, 0xA6, 0xAE, 0x06,
0x8D, 0x22, 0xAE, 0x12, 0x83, 0x5A, 0xAE, 0x18, 0x60, 0xAE, 0x0C, 0x81, 0xB9, 0x35, 0x23, 0x23,
0x23, 0x56, 0x56, 0x56, 0xA3, 0xA3, 0xA3, 0xA4, 0xA4, 0xA4, 0xA1, 0xA1, 0xA1, 0x50, 0x50, 0x50,
0xAE, 0x1E, 0x83, 0x5A, 0xAE, 0x0C, 0x81, 0x6A, 0x25, 0x25, 0x25, 0x42, 0x42, 0x42, 0x9F, 0x9F,
0x9F, 0x64, 0x64, 0x64, 0x27, 0x27, 0x27, 0xAE, 0x1B, 0x83, 0x5A, 0xAE, 0x1B, 0x82, 0x77, 0xAE,
0x0C, 0x0F, 0xAE, 0x06, 0x92, 0x66, 0x8C, 0x8C, 0x8C, 0x8A, 0x8A, 0x8A, 0x2B, 0x2B, 0x2B, 0xAE,
0x06, 0x81, 0x1F, 0xAE, 0x06, 0x83, 0x5A, 0x87, 0x87, 0x87, 0xAE, 0x06, 0xF0, 0x0D, 0xAE, 0x06,
0x87, 0x4F, 0xAE, 0x3F, 0x83, 0x5A, 0x45, 0x45, 0x45, 0xA7, 0xA7, 0xA7, 0x6F, 0x6F, 0x6F, 0x65,
0x65, 0x65, 0x63, 0x63, 0x63, 0x64, 0x64, 0x64, 0x62, 0x62, 0x62, 0xAE, 0x06, 0x81, 0xC6, 0x66,
0x6E, 0x6E, 0x6E, 0x8A, 0x8A, 0x8A, 0xAE, 0x06, 0x89, 0x5A, 0x29, 0x29, 0x29, 0xAE, 0x06, 0x85,
0x4A, 0xAE, 0x1B, 0x83, 0x5A, 0xAE, 0x06, 0x82, 0x6E, 0xAE, 0x0C, 0x82, 0x1A, 0x25, 0x25, 0x25,
0x4A, 0x4A, 0x4A, 0xAC, 0xAC, 0xAC, 0x6F, 0x6F, 0x6F, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x65,
0x65, 0x65, 0x61, 0x61, 0x61, 0x36, 0x36, 0x36, 0x2A, 0x2A, 0x2A, 0x55, 0x55, 0x55, 0xBB, 0xBB,
0xBB, 0x94, 0x94, 0x94, 0xA6, 0xA6, 0xA6, 0x73, 0x73, 0x73, 0xAE, 0x06, 0x81, 0x8C, 0x17, 0x23,
0x23, 0x23, 0x3C, 0x3C, 0x3C, 0x80, 0x80, 0x80, 0xA4, 0xA4, 0xA4, 0x6F, 0x6F, 0x6F, 0x68, 0x68,
0x68, 0x74, 0x74, 0x74, 0xAE, 0x06, 0x83, 0x4B, 0x1E, 0x1E, 0x1E, 0x32, 0x32, 0x32, 0xAE, 0x0F,
0x83, 0x5A, 0xAE, 0x18, 0x60, 0xAE, 0x0F, 0xF6, 0x5E, 0x25, 0x25, 0x25, 0x2D, 0x2D, 0x2D, 0xAE,
0x06, 0x8A, 0x6D, 0xAE, 0x12, 0x96, 0x40, 0xAE, 0x15, 0x83, 0x5A, 0x37, 0x37, 0x37, 0xAE, 0x06,
0x82, 0x5C, 0x42, 0x42, 0x42, 0x93, 0x93, 0x93, 0xAE, 0x48, 0x83, 0x5A, 0x2B, 0x2B, 0x2B, 0x2D,
0x2D, 0x2D, 0x6D, 0x6D, 0x6D, 0x92, 0x92, 0x92, 0xAE, 0x06, 0x9F, 0x4F, 0x2D, 0x2D, 0x2D, 0x46,
0x46, 0x46, 0x92, 0x92, 0x92, 0x62, 0x62, 0x62, 0x2A, 0x2A, 0x2A, 0x45, 0x45, 0x45, 0xB6, 0xB6,
0xB6, 0x3E, 0x3E, 0x3E, 0xAE, 0x06, 0xCE, 0x39, 0x4F, 0x4F, 0x4F, 0xA7, 0xA7, 0xA7, 0xAE, 0x33,
0x8B, 0x0E, 0x3E, 0x3E, 0x3E, 0xA6, 0xA6, 0xA6, 0x5C, 0x5C, 0x5C, 0x31, 0x31, 0x31, 0xAE, 0x06,
0x75, 0x2B, 0x2B, 0x2B, 0x24, 0x24, 0x24, 0x2B, 0x2B, 0x2B, 0x65, 0x65, 0x65, 0xA5, 0xA5, 0xA5,
0xAE, 0x06, 0x81, 0xBB, 0x3D, 0x33, 0x33, 0x33, 0x59, 0x59, 0x59, 0xAE, 0x33, 0x83, 0x5A, 0x45,
0x45, 0x45, 0xB0, 0xB0, 0xB0, 0x45, 0x45, 0x45, 0x2E, 0x2E, 0x2E, 0xAE, 0x06, 0x60, 0xAE, 0x06,
0x81, 0x80, 0x68, 0xAE, 0x09, 0x89, 0x75, 0x4A, 0x4A, 0x4A, 0x4F, 0x4F, 0x4F, 0xAB, 0xAB, 0xAB,
0x56, 0x56, 0x56, 0xAE, 0x06, 0xBD, 0x5B, 0xAE, 0x06, 0x33, 0x42, 0x42, 0x42, 0xAE, 0x06, 0x81,
0xA6, 0x6A, 0x54, 0x54, 0x54, 0xA5, 0xA5, 0xA5, 0x30, 0x30, 0x30, 0x1E, 0x1E, 0x1E, 0x2F, 0x2F,
0x2F, 0x71, 0x71, 0x71, 0xA6, 0xA6, 0xA6, 0x34, 0x34, 0x34, 0x1E, 0x1E, 0x1E, 0xAE, 0x1B, 0x60,
0xAE, 0x2D, 0x92, 0x42, 0xAE, 0x15, 0x8B, 0x0E, 0x40, 0x40, 0x40, 0x25, 0x25, 0x25, 0x30, 0x30,
0x30, 0x4D, 0x4D, 0x4D, 0xA5, 0xA5, 0xA5, 0x58, 0x58, 0x58, 0xAE, 0x1B, 0x8B, 0x0E, 0xAE, 0x06,
0x81, 0xB6, 0x5C, 0x68, 0x68, 0x68, 0x86, 0x86, 0x86, 0xAE, 0x06, 0x81, 0xCF, 0x4B, 0xAE, 0x0F,
0x0F, 0xAE, 0x09, 0x0F, 0xAE, 0x06, 0x81, 0xC6, 0x03, 0x3D, 0x3D, 0x3D, 0xAB, 0xAB, 0xAB, 0xAE,
0x06, 0xFF, 0x70, 0x46, 0x46, 0x46, 0x61, 0x61, 0x61, 0xAA, 0xAA, 0xAA, 0xAE, 0x06, 0x90, 0x4C,
0x38, 0x38, 0x38, 0x99, 0x99, 0x99, 0x7F, 0x7F, 0x7F, 0x42, 0x42, 0x42, 0x45, 0x45, 0x45, 0x65,
0x65, 0x65, 0xB1, 0xB1, 0xB1, 0xAE, 0x06, 0x87, 0x34, 0xAE, 0x1B, 0x63, 0xAE, 0x06, 0x81, 0x46,
0x3F, 0x3F, 0x3F, 0xA3, 0xA3, 0xA3, 0x2D, 0x2D, 0x2D, 0xAE, 0x06, 0x8F, 0x78, 0x7D, 0x7D, 0x7D,
0x9F, 0x9F, 0x9F, 0x46, 0x46, 0x46, 0x3E, 0x3E, 0x3E, 0x3F, 0x3F, 0x3F, 0x58, 0x58, 0x58, 0xAE,
0x06, 0x8A, 0x49, 0x3F, 0x3F, 0x3F, 0xB0, 0xB0, 0xB0, 0x5F, 0x5F, 0x5F, 0x3F, 0x3F, 0x3F, 0x48,
0x48, 0x48, 0x76, 0x76, 0x76, 0xBB, 0xBB, 0xBB, 0x34, 0x34, 0x34, 0xAE, 0x12, 0x82, 0x17, 0xAE,
0x09, 0x51, 0x1B, 0x1B, 0x1B, 0x27, 0x27, 0x27, 0x4C, 0x4C, 0x4C, 0xAE, 0x06, 0x2A, 0x21, 0x21,
0x21, 0xAE, 0x06, 0x81, 0x28, 0x86, 0x86, 0x86, 0x42, 0x42, 0x42, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E,
0x3E, 0x5F, 0x5F, 0x5F, 0x22, 0x22, 0x22, 0xAE, 0x09, 0x27, 0xAE, 0x06, 0xF2, 0x48, 0x61, 0x61,
0x61, 0xA4, 0xA4, 0xA4, 0x43, 0x43, 0x43, 0x2A, 0x2A, 0x2A, 0x40, 0x40, 0x40, 0xB0, 0xB0, 0xB0,
0x4B, 0x4B, 0x4B, 0x3D, 0x3D, 0x3D, 0x48, 0x48, 0x48, 0x85, 0x85, 0x85, 0xAE, 0x06, 0x8B, 0x0E,
0x1D, 0x1D, 0x1D, 0x29, 0x29, 0x29, 0x5C, 0x5C, 0x5C, 0xA6, 0xA6, 0xA6, 0x41, 0x41, 0x41, 0x27,
0x27, 0x27, 0xAE, 0x09, 0x82, 0x08, 0xAE, 0x12, 0x60, 0xAE, 0x30, 0x83, 0x5A, 0xAE, 0x09, 0x81,
0x43, 0x28, 0x28, 0x28, 0xAE, 0x06, 0x90, 0x01, 0x6E, 0x6E, 0x6E, 0xAE, 0x06, 0x81, 0x79, 0x6E,
0x6E, 0x6E, 0xAF, 0xAF, 0xAF, 0xAE, 0x06, 0xC6, 0x22, 0x37, 0x37, 0x37, 0x88, 0x88, 0x88, 0x62,
0x62, 0x62, 0xAE, 0x0F, 0x63, 0xAE, 0x06, 0x81, 0xBA, 0x1E, 0x60, 0x60, 0x60, 0x82, 0x82, 0x82,
0xAE, 0x06, 0x98, 0x15, 0xAE, 0x0F, 0x0F, 0xAE, 0x0C, 0x0F, 0xAE, 0x06, 0x8C, 0x72, 0x5F, 0x5F,
0x5F, 0xAA, 0xAA, 0xAA, 0x92, 0x92, 0x92, 0x91, 0x91, 0x91, 0xAA, 0xAA, 0xAA, 0x56, 0x56, 0x56,
0xAE, 0x06, 0x81, 0xD8, 0x45, 0x27, 0x27, 0x27, 0x49, 0x49, 0x49, 0xAA, 0xAA, 0xAA, 0x91, 0x91,
0x91, 0x8A, 0x8A, 0x8A, 0x9F, 0x9F, 0x9F, 0xAA, 0xAA, 0xAA, 0x5F, 0x5F, 0x5F, 0x21, 0x21, 0x21,
0xAE, 0x1B, 0x54, 0xAE, 0x09, 0x81, 0xBE, 0x79, 0xA1, 0xA1, 0xA1, 0x26, 0x26, 0x26, 0xAE, 0x09,
0x99, 0x76, 0x90, 0x90, 0x90, 0xA4, 0xA4, 0xA4, 0x8A, 0x8A, 0x8A, 0x96, 0x96, 0x96, 0x9A, 0x9A,
0x9A, 0xAE, 0x06, 0x81, 0xC2, 0x62, 0x2C, 0x2C, 0x2C, 0x61, 0x61, 0x61, 0xAF, 0xAF, 0xAF, 0x8A,
0x8A, 0x8A, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, 0xBB, 0xBB, 0xBB, 0xAE, 0x12, 0xA4, 0x69, 0xAE,
0x0C, 0x51, 0xAE, 0x06, 0x90, 0x10, 0x3A, 0x3A, 0x3A, 0xAE, 0x06, 0x2A, 0xAE, 0x06, 0x81, 0x28,
0x48, 0x48, 0x48, 0xA4, 0xA4, 0xA4, 0x98, 0x98, 0x98, 0x8A, 0x8A, 0x8A, 0xA3, 0xA3, 0xA3, 0x7A,
0x7A, 0x7A, 0xAE, 0x06, 0xA0, 0x05, 0xAE, 0x09, 0x27, 0x20, 0x20, 0x20, 0x30, 0x30, 0x30, 0x75,
0x75, 0x75, 0x91, 0x91, 0x91, 0x26, 0x26, 0x26, 0x30, 0x30, 0x30, 0x7A, 0x7A, 0x7A, 0xAE, 0x06,
0x81, 0x10, 0x97, 0x97, 0x97, 0x85, 0x85, 0x85, 0xB5, 0xB5, 0xB5, 0xAE, 0x06, 0x88, 0x71, 0x23,
0x23, 0x23, 0x3B, 0x3B, 0x3B, 0xAA, 0xAA, 0xAA, 0x8F, 0x8F, 0x8F, 0x5C, 0x5C, 0x5C, 0x21, 0x21,
0x21, 0xAE, 0x18, 0x60, 0xAE, 0x2E, 0x81, 0xE5, 0x0D, 0xAE, 0x0B, 0x81, 0x43, 0xAE, 0x09, 0x83,
0x5A, 0x9C, 0x9C, 0x9C, 0x90, 0x90, 0x90, 0x8C, 0x8C, 0x8C, 0xAF, 0xAF, 0xAF, 0xAE, 0x06, 0x82,
0x77, 0x1F, 0x1F, 0x1F, 0x2C, 0x2C, 0x2C, 0x83, 0x83, 0x83, 0x5C, 0x5C, 0x5C, 0xAE, 0x0F, 0xF6,
0x7C, 0xAE, 0x09, 0xAF, 0x1D, 0xAE, 0x06, 0xD5, 0x2E, 0xAE, 0x0F, 0x0F, 0xAE, 0x0F, 0x0F, 0xAE,
0x06, 0x8B, 0x3E, 0xAE, 0x06, 0x81, 0x8A, 0x09, 0x63, 0x63, 0x63, 0xAE, 0x06, 0x90, 0x76, 0xAE,
0x06, 0xA1, 0x45, 0xAE, 0x09, 0xA0, 0x62, 0x31, 0x31, 0x31, 0x62, 0x62, 0x62, 0x56, 0x56, 0x56,
0xAE, 0x0C, 0xD6, 0x05, 0xAE, 0x1E, 0x54, 0xAE, 0x06, 0x9E, 0x72, 0xAE, 0x06, 0xF4, 0x44, 0xAE,
0x09, 0x81, 0x8F, 0x17, 0x2B, 0x2B, 0x2B, 0x40, 0x40, 0x40, 0x61, 0x61, 0x61, 0x4A, 0x4A, 0x4A,
0xAE, 0x06, 0x87, 0x6A, 0xAE, 0x06, 0x9F, 0x40, 0xAE, 0x06, 0x99, 0x7C, 0x60, 0x60, 0x60, 0x4A,
0x4A, 0x4A, 0xAE, 0x09, 0x8D, 0x25, 0xAE, 0x12, 0xA6, 0x56, 0xAE, 0x0F, 0x51, 0xAE, 0x06, 0xCB,
0x6F, 0xAE, 0x06, 0x2A, 0xAE, 0x06, 0x81, 0x28, 0x2E, 0x2E, 0x2E, 0x4D, 0x4D, 0x4D, 0x60, 0x60,
0x60, 0xAE, 0x06, 0x81, 0xB7, 0x69, 0xAE, 0x06, 0xD7, 0x2A, 0xAE, 0x09, 0x27, 0xAE, 0x06, 0xA2,
0x16, 0xAE, 0x06, 0x81, 0xCE, 0x59, 0xAE, 0x06, 0xF2, 0x6C, 0x2B, 0x2B, 0x2B, 0x4C, 0x4C, 0x4C,
0x60, 0x60, 0x60, 0x3D, 0x3D, 0x3D, 0x2B, 0x2B, 0x2B, 0xAE, 0x09, 0x78, 0xAE, 0x06, 0x85, 0x29,
0xAE, 0x06, 0x87, 0x19, 0x42, 0x42, 0x42, 0xAE, 0x06, 0xD4, 0x18, 0xAE, 0x15, 0x60, 0xAE, 0x30,
0xB0, 0x12, 0xAE, 0x09, 0x81, 0x43, 0xAE, 0x09, 0x8B, 0x0E, 0x48, 0x48, 0x48, 0x57, 0x57, 0x57,
0x61, 0x61, 0x61, 0x3B, 0x3B, 0x3B, 0xAE, 0x06, 0x81, 0x85, 0x4C, 0xAE, 0x06, 0x81, 0x28, 0xAE,
0x36, 0xA5, 0x6A, 0xAE, 0x1B, 0xE0, 0x5D, 0xAE, 0x12, 0x81, 0xCC, 0x33, 0xAE, 0x09, 0x1B, 0xAE,
0x42, 0xB0, 0x7B, 0xAE, 0x18, 0x4B, 0xAE, 0x48, 0x63, 0xAE, 0x30, 0xAF, 0x4A, 0xAE, 0x1B, 0x30,
0xAE, 0x15, 0x81, 0x13, 0xAE, 0x4B, 0xB0, 0x2A, 0xAE, 0x09, 0x8C, 0x27, 0xAE, 0x06, 0x81, 0x99,
0x03, 0xAE, 0x81, 0x07, 0xB5, 0x0E, 0xAE, 0x82, 0x44, 0xBA, 0x13, 0xAE, 0x0C, 0x8C, 0x27, 0xAE,
0x83, 0x4E, 0xBD, 0x6D, 0xAE, 0x0F, 0x8C, 0x4E, 0xAE, 0x83, 0x78, 0xC1, 0x74
} ;

View File

@@ -14,16 +14,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "di.h"
#include "t210.h"
#include "util.h"
#include "i2c.h"
#include "pmc.h"
#include "max77620.h"
#include "gpio.h"
#include "pinmux.h"
#include "di.inl"
@@ -58,25 +54,25 @@ void display_init()
PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000;
//Config pins.
PINMUX_AUX(PINMUX_AUX_NFC_EN) &= 0xFFFFFFEF;
PINMUX_AUX(PINMUX_AUX_NFC_INT) &= 0xFFFFFFEF;
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= 0xFFFFFFEF;
PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= 0xFFFFFFEF;
PINMUX_AUX(PINMUX_AUX_LCD_RST) &= 0xFFFFFFEF;
PINMUX_AUX(0x1D0) &= 0xFFFFFFEF;
PINMUX_AUX(0x1D4) &= 0xFFFFFFEF;
PINMUX_AUX(0x1FC) &= 0xFFFFFFEF;
PINMUX_AUX(0x200) &= 0xFFFFFFEF;
PINMUX_AUX(0x204) &= 0xFFFFFFEF;
gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); //Backlight +-5V.
gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE); //Backlight +-5V.
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); //Backlight +5V enable.
GPIO_3(0x00) = GPIO_3(0x00) & 0xFFFFFFFC | 0x3;
GPIO_3(0x10) = GPIO_3(0x10) & 0xFFFFFFFC | 0x3;
GPIO_3(0x20) = GPIO_3(0x20) & 0xFFFFFFFE | 0x1;
sleep(10000u);
GPIO_3(0x20) = GPIO_3(0x20) & 0xFFFFFFFD | 0x2;
sleep(10000);
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); //Backlight -5V enable.
sleep(10000);
gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO); //Backlight PWM, Enable, Reset.
gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE);
gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); //Backlight Enable enable.
GPIO_6(0x04) = GPIO_6(0x04) & 0xFFFFFFF8 | 0x7;
GPIO_6(0x14) = GPIO_6(0x14) & 0xFFFFFFF8 | 0x7;
GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFD | 0x2;
//Config display interface and display.
MIPI_CAL(0x60) = 0;
@@ -87,7 +83,7 @@ void display_init()
sleep(10000);
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH); //Backlight Reset enable.
GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFB | 0x4;
sleep(60000);
@@ -135,18 +131,10 @@ void display_init()
exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_11, 113);
}
void display_backlight(u8 enable)
{
gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); //Backlight PWM.
}
void display_end()
{
display_backlight(0);
//TODO: figure out why this freezes.
/*DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 1;
GPIO_6(0x24) &= 0xFFFFFFFE;
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 1;
DSI(_DSIREG(DSI_WR_DATA)) = 0x2805;
u32 end = HOST1X(0x30A4) + 5;
@@ -169,17 +157,17 @@ void display_end()
sleep(50000);
//gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); //Backlight Reset disable.
GPIO_6(0x24) &= 0xFFFFFFFB;
//sleep(10000);
sleep(10000);
//gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); //Backlight -5V disable.
GPIO_3(0x20) &= 0xFFFFFFFD;
//sleep(10000);
sleep(10000);
//gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); //Backlight +5V disable.
GPIO_3(0x20) = (GPIO_3(0x20) >> 1) << 1;
//sleep(10000);
sleep(10000);
//Disable clocks.
CLOCK(0x308) = 0x1010000;
@@ -188,12 +176,12 @@ void display_end()
CLOCK(0x324) = 0x18000000;
DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);
DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;*/
DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); //Backlight PWM.
GPIO_6(0x04) &= 0xFFFFFFFE;
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & 0xFFFFFFEF) | 0x10;
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1;
PINMUX_AUX(0x1FC) = PINMUX_AUX(0x1FC) & 0xFFFFFFEF | 0x10;
PINMUX_AUX(0x1FC) = (PINMUX_AUX(0x1FC) >> 2) << 2 | 1;
}
void display_color_screen(u32 color)
@@ -205,24 +193,21 @@ void display_color_screen(u32 color)
DISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0;
DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;
DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE | GENERAL_ACT_REQ;
sleep(35000);
display_backlight(1);
GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFE | 1;
}
u32 *display_init_framebuffer(u32 *fb)
{
//Sanitize framebuffer area. Aligned to 4MB.
memset((u32 *)0xC0000000, 0, 0x400000);
//This configures the framebuffer @ 0xC0000000 with a resolution of 1280x720 (line stride 768).
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32);
sleep(35000);
//Enable backlight
//display_backlight(1);
GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFE | 1;
return (u32 *)0xC0000000;
}

View File

@@ -341,9 +341,6 @@ void display_end();
/*! Show one single color on the display. */
void display_color_screen(u32 color);
/*! Switches screen backlight ON/OFF. */
void display_backlight(u8 enable);
/*! Init display in full 1280x720 resolution (32bpp, line stride 768, framebuffer size = 1280*768*4 bytes). */
u32 *display_init_framebuffer();

View File

@@ -50,7 +50,7 @@
/* This option switches f_expand function. (0:Disable or 1:Enable) */
#define FF_USE_CHMOD 1
#define FF_USE_CHMOD 0
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */

View File

@@ -15,7 +15,6 @@
*/
#include <stdarg.h>
#include <string.h>
#include "gfx.h"
static const u8 _gfx_font[] = {
@@ -77,17 +76,18 @@ void gfx_init_ctxt(gfx_ctxt_t *ctxt, u32 *fb, u32 width, u32 height, u32 stride)
ctxt->stride = stride;
}
void gfx_clear_grey(gfx_ctxt_t *ctxt, u8 color)
{
memset(ctxt->fb, color, 0x400000);
}
void gfx_clear_color(gfx_ctxt_t *ctxt, u32 color)
void gfx_clear(gfx_ctxt_t *ctxt, u32 color)
{
for (u32 i = 0; i < ctxt->height * ctxt->stride; i++)
ctxt->fb[i] = color;
}
void gfx_con_setfontsz(gfx_con_t *con, u8 font_size)
{
con->fntsz = font_size;
con->fontmult = font_size / 8;
}
void gfx_con_init(gfx_con_t *con, gfx_ctxt_t *ctxt)
{
con->gfx_ctxt = ctxt;
@@ -96,6 +96,7 @@ void gfx_con_init(gfx_con_t *con, gfx_ctxt_t *ctxt)
con->fgcol = 0xFFCCCCCC;
con->fillbg = 0;
con->bgcol = 0xFF1B1B1B;
gfx_con_setfontsz(con, 16);
}
void gfx_con_setcol(gfx_con_t *con, u32 fgcol, int fillbg, u32 bgcol)
@@ -123,27 +124,45 @@ void gfx_putc(gfx_con_t *con, char c)
{
u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];
u32 *fb = con->gfx_ctxt->fb + con->x + con->y * con->gfx_ctxt->stride;
for (u32 i = 0; i < 8; i++)
for (u32 i = 0; i < con->fntsz; i+=con->fontmult)
{
u8 v = *cbuf++;
for (u32 j = 0; j < 8; j++)
for (u32 k = 0; k < con->fontmult; k++)
{
if (v & 1)
*fb = con->fgcol;
else if (con->fillbg)
*fb = con->bgcol;
v >>= 1;
fb++;
for (u32 j = 0; j < con->fntsz; j+=con->fontmult)
{
if (v & 1)
{
*fb = con->fgcol;
for(u32 l = 0; l < con->fontmult - 1; l++)
{
fb++;
*fb = con->fgcol;
}
}
else if (con->fillbg)
{
*fb = con->bgcol;
for(u32 l = 0; l < con->fontmult - 1; l++)
{
fb++;
*fb = con->bgcol;
}
}
v >>= 1;
fb++;
}
fb += con->gfx_ctxt->stride - con->fntsz;
v = *cbuf;
}
fb += con->gfx_ctxt->stride - 8;
}
con->x += 8;
con->x += con->fntsz;
}
else if (c == '\n')
{
con->x = 0;
con->y += 8;
if (con->y > con->gfx_ctxt->height - 8)
con->y += con->fntsz;
if (con->y > con->gfx_ctxt->height - con->fntsz)
con->y = 0;
}
}
@@ -188,6 +207,13 @@ static void _gfx_putn(gfx_con_t *con, u32 v, int base, char fill, int fcnt)
gfx_puts(con, p);
}
void gfx_putsep(gfx_con_t *con)
{
gfx_con_setfontsz(con, 8);
gfx_putc(con, '\n');
gfx_con_setfontsz(con, 16);
}
void gfx_printf(gfx_con_t *con, const char *fmt, ...)
{
va_list ap;
@@ -261,6 +287,8 @@ void gfx_printf(gfx_con_t *con, const char *fmt, ...)
void gfx_hexdump(gfx_con_t *con, u32 base, const u8 *buf, u32 len)
{
u8 prevFontSize = con->fntsz;
gfx_con_setfontsz(con, 8);
for(u32 i = 0; i < len; i++)
{
if(i % 0x10 == 0)
@@ -287,7 +315,7 @@ void gfx_hexdump(gfx_con_t *con, u32 base, const u8 *buf, u32 len)
u32 k = 0x10 - 1;
if (ln)
{
k = (len & 0xF) - 1;
k = len & 0xF - 1;
for (u32 j = 0; j < 0x10 - k; j++)
gfx_puts(con, " ");
}
@@ -304,6 +332,7 @@ void gfx_hexdump(gfx_con_t *con, u32 base, const u8 *buf, u32 len)
}
}
gfx_putc(con, '\n');
gfx_con_setfontsz(con, prevFontSize);
}
static int abs(int x)
@@ -320,8 +349,8 @@ void gfx_set_pixel(gfx_ctxt_t *ctxt, u32 x, u32 y, u32 color)
void gfx_line(gfx_ctxt_t *ctxt, int x0, int y0, int x1, int y1, u32 color)
{
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
int dx = abs(x1-x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1-y0), sy = y0 < y1 ? 1 : -1;
int err = (dx > dy ? dx : -dy) / 2, e2;
while (1)
@@ -330,15 +359,20 @@ void gfx_line(gfx_ctxt_t *ctxt, int x0, int y0, int x1, int y1, u32 color)
if (x0 == x1 && y0 == y1)
break;
e2 = err;
if (e2 >-dx)
if (e2 >-dx) { err -= dy; x0 += sx; }
if (e2 < dy) { err += dx; y0 += sy; }
}
}
void gfx_set_logo(gfx_ctxt_t *ctxt, const u8 *buf)
{
u32 pos = 0;
for (u32 y = 1180; y < 1256; y++)
{
for (u32 x = 538; x < 696; x++)
{
err -= dy;
x0 += sx;
}
if (e2 < dy)
{
err += dx;
y0 += sy;
ctxt->fb[x + y*ctxt->stride] = (0xFF << 24) | buf[pos] | (buf[pos + 1] << 8) | (buf[pos + 2] << 16);
pos+=3;
}
}
}

View File

@@ -35,15 +35,17 @@ typedef struct _gfx_con_t
u32 fgcol;
int fillbg;
u32 bgcol;
u32 fntsz;
u32 fontmult;
} gfx_con_t;
void gfx_init_ctxt(gfx_ctxt_t *ctxt, u32 *fb, u32 width, u32 height, u32 stride);
void gfx_clear_grey(gfx_ctxt_t *ctxt, u8 color);
void gfx_clear_color(gfx_ctxt_t *ctxt, u32 color);
void gfx_clear(gfx_ctxt_t *ctxt, u32 color);
void gfx_con_init(gfx_con_t *con, gfx_ctxt_t *ctxt);
void gfx_con_setcol(gfx_con_t *con, u32 fgcol, int fillbg, u32 bgcol);
void gfx_con_getpos(gfx_con_t *con, u32 *x, u32 *y);
void gfx_con_setpos(gfx_con_t *con, u32 x, u32 y);
void gfx_con_setfontsz(gfx_con_t *con, u8 font_size);
void gfx_putc(gfx_con_t *con, char c);
void gfx_puts(gfx_con_t *con, const char *s);
void gfx_printf(gfx_con_t *con, const char *fmt, ...);
@@ -51,5 +53,7 @@ void gfx_hexdump(gfx_con_t *con, u32 base, const u8 *buf, u32 len);
void gfx_set_pixel(gfx_ctxt_t *ctxt, u32 x, u32 y, u32 color);
void gfx_line(gfx_ctxt_t *ctxt, int x0, int y0, int x1, int y1, u32 color);
void gfx_putsep(gfx_con_t *con);
void gfx_set_logo(gfx_ctxt_t *ctxt, const u8 *buf);
#endif

View File

@@ -90,5 +90,5 @@ void gpio_write(u32 port, u32 pins, int high)
int gpio_read(u32 port, u32 pins)
{
return (GPIO(_gpio_in[port]) & pins) ? 1 : 0;
return GPIO(_gpio_in[port]) & pins ? 1 : 0;
}

View File

@@ -97,7 +97,6 @@ static void _heap_free(heap_t *heap, u32 addr)
while (node)
{
if (!node->used)
{
if (node->prev && !node->prev->used)
{
node->prev->size += node->size + sizeof(hnode_t);
@@ -105,7 +104,6 @@ static void _heap_free(heap_t *heap, u32 addr)
if (node->next)
node->next->prev = node->prev;
}
}
node = node->next;
}
}
@@ -131,6 +129,5 @@ void *calloc(u32 num, u32 size)
void free(void *buf)
{
if (buf != NULL)
_heap_free(&_heap, (u32)buf);
_heap_free(&_heap, (u32)buf);
}

364
ipl/hos.c
View File

@@ -31,7 +31,6 @@
#include "pkg1.h"
#include "pkg2.h"
#include "ff.h"
#include "di.h"
#include "gfx.h"
extern gfx_ctxt_t gfx_ctxt;
@@ -39,44 +38,17 @@ extern gfx_con_t gfx_con;
//#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
#define DPRINTF(...)
typedef struct _launch_ctxt_t
{
void *keyblob;
enum KB_FIRMWARE_VERSION {
KB_FIRMWARE_VERSION_100_200 = 0,
KB_FIRMWARE_VERSION_300 = 1,
KB_FIRMWARE_VERSION_301 = 2,
KB_FIRMWARE_VERSION_400 = 3,
KB_FIRMWARE_VERSION_500 = 4,
KB_FIRMWARE_VERSION_MAX
};
void *pkg1;
const pkg1_id_t *pkg1_id;
const pkg2_kernel_id_t *pkg2_kernel_id;
void *warmboot;
u32 warmboot_size;
void *secmon;
u32 secmon_size;
void *pkg2;
u32 pkg2_size;
void *kernel;
u32 kernel_size;
link_t kip1_list;
int svcperm;
int debugmode;
} launch_ctxt_t;
typedef struct _merge_kip_t
{
void *kip1;
link_t link;
} merge_kip_t;
#define KB_FIRMWARE_VERSION_100_200 0
#define KB_FIRMWARE_VERSION_300 1
#define KB_FIRMWARE_VERSION_301 2
#define KB_FIRMWARE_VERSION_400 3
#define KB_FIRMWARE_VERSION_500 4
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_500
static const u8 keyblob_keyseeds[][0x10] = {
#define NUM_KEYBLOB_KEYS 5
static const u8 keyblob_keyseeds[NUM_KEYBLOB_KEYS][0x10] = {
{ 0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3 }, //1.0.0
{ 0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC }, //3.0.0
{ 0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B }, //3.0.1
@@ -96,10 +68,10 @@ static const u8 console_keyseed[0x10] =
static const u8 key8_keyseed[] =
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
static const u8 master_keyseed_4xx_5xx[0x10] =
static const u8 master_keyseed_4xx[0x10] =
{ 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66 };
static const u8 console_keyseed_4xx_5xx[0x10] =
static const u8 console_keyseed_4xx[0x10] =
{ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
@@ -130,30 +102,28 @@ static void _se_lock()
gfx_hexdump(&gfx_con, SE_BASE, (void *)SE_BASE, 0x400);*/
}
// <-- key derivation algorithm
int keygen(u8 *keyblob, u32 kb, void *tsec_fw)
{
u8 tmp[0x10];
if (kb > KB_FIRMWARE_VERSION_MAX)
return 0;
se_key_acc_ctrl(13, 0x15);
se_key_acc_ctrl(14, 0x15);
se_key_acc_ctrl(0x0D, 0x15);
se_key_acc_ctrl(0x0E, 0x15);
//Get TSEC key.
if (tsec_query(tmp, 1, tsec_fw) < 0)
return 0;
se_aes_key_set(13, tmp, 0x10);
se_aes_key_set(0x0D, tmp, 0x10);
//Derive keyblob keys from TSEC+SBK.
se_aes_crypt_block_ecb(13, 0, tmp, keyblob_keyseeds[0]);
se_aes_unwrap_key(15, 14, tmp);
se_aes_crypt_block_ecb(13, 0, tmp, keyblob_keyseeds[kb]);
se_aes_unwrap_key(13, 14, tmp);
se_aes_crypt_block_ecb(0x0D, 0x00, tmp, keyblob_keyseeds[0]);
se_aes_unwrap_key(0x0F, 0x0E, tmp);
se_aes_crypt_block_ecb(0xD, 0x00, tmp, keyblob_keyseeds[kb]);
se_aes_unwrap_key(0x0D, 0x0E, tmp);
//Clear SBK.
se_aes_key_clear(14);
// Clear SBK
se_aes_key_clear(0x0E);
//TODO: verify keyblob CMAC.
//se_aes_unwrap_key(11, 13, cmac_keyseed);
@@ -161,46 +131,76 @@ int keygen(u8 *keyblob, u32 kb, void *tsec_fw)
//if (!memcmp(keyblob, tmp, 0x10))
// return 0;
se_aes_crypt_block_ecb(13, 0, tmp, cmac_keyseed);
se_aes_unwrap_key(11, 13, cmac_keyseed);
se_aes_crypt_block_ecb(0x0D, 0, tmp, cmac_keyseed);
se_aes_unwrap_key(0x0B, 0x0D, cmac_keyseed);
//Decrypt keyblob and set keyslots.
se_aes_crypt_ctr(13, keyblob + 0x20, 0x90, keyblob + 0x20, 0x90, keyblob + 0x10);
se_aes_key_set(11, keyblob + 0x20 + 0x80, 0x10); //Package1 key.
se_aes_key_set(12, keyblob + 0x20, 0x10);
se_aes_key_set(13, keyblob + 0x20, 0x10);
se_aes_crypt_ctr(0x0D, keyblob + 0x20, 0x90, keyblob + 0x20, 0x90, keyblob + 0x10);
se_aes_key_set(0x0B, keyblob + 0x20 + 0x80, 0x10); // package1 key
se_aes_key_set(0x0C, keyblob + 0x20, 0x10);
se_aes_key_set(0x0D, keyblob + 0x20, 0x10);
se_aes_crypt_block_ecb(12, 0, tmp, master_keyseed_retail);
se_aes_crypt_block_ecb(0x0C, 0, tmp, master_keyseed_retail);
switch (kb)
{
switch (kb) {
case KB_FIRMWARE_VERSION_100_200:
case KB_FIRMWARE_VERSION_300:
case KB_FIRMWARE_VERSION_301:
se_aes_unwrap_key(13, 15, console_keyseed);
se_aes_unwrap_key(12, 12, master_keyseed_retail);
se_aes_unwrap_key(0x0D, 0x0F, console_keyseed);
se_aes_unwrap_key(0x0C, 0x0C, master_keyseed_retail);
break;
case KB_FIRMWARE_VERSION_400:
se_aes_unwrap_key(13, 15, console_keyseed_4xx_5xx);
se_aes_unwrap_key(15, 15, console_keyseed);
se_aes_unwrap_key(14, 12, master_keyseed_4xx_5xx);
se_aes_unwrap_key(12, 12, master_keyseed_retail);
se_aes_unwrap_key(0x0D, 0x0F, console_keyseed_4xx);
se_aes_unwrap_key(0x0F, 0x0F, console_keyseed);
se_aes_unwrap_key(0x0E, 0x0C, master_keyseed_4xx);
se_aes_unwrap_key(0x0C, 0x0C, master_keyseed_retail);
break;
case KB_FIRMWARE_VERSION_500:
se_aes_unwrap_key(10, 15, console_keyseed_4xx_5xx);
se_aes_unwrap_key(15, 15, console_keyseed);
se_aes_unwrap_key(14, 12, master_keyseed_4xx_5xx);
se_aes_unwrap_key(12, 12, master_keyseed_retail);
default:
se_aes_unwrap_key(0x0A, 0x0F, console_keyseed_4xx);
se_aes_unwrap_key(0x0F, 0x0F, console_keyseed);
se_aes_unwrap_key(0x0E, 0x0C, master_keyseed_4xx);
se_aes_unwrap_key(0x0C, 0x0C, master_keyseed_retail);
break;
}
//Package2 key.
se_key_acc_ctrl(8, 0x15);
se_aes_unwrap_key(8, 12, key8_keyseed);
return 1;
// Package2 key
se_key_acc_ctrl(0x08, 0x15);
se_aes_unwrap_key(0x08, 0x0C, key8_keyseed);
}
typedef struct _launch_ctxt_t
{
void *keyblob;
void *pkg1;
const pkg1_id_t *pkg1_id;
void *warmboot;
u32 warmboot_size;
void *secmon;
u32 secmon_size;
void *pkg2;
u32 pkg2_size;
void *kernel;
u32 kernel_size;
link_t kip1_list;
u8 *svcperm;
u8 *debugmode;
} launch_ctxt_t;
typedef struct _merge_kip_t
{
void *kip1;
link_t link;
} merge_kip_t;
static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
{
int res = 0;
@@ -216,10 +216,10 @@ static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
ctxt->pkg1_id = pkg1_identify(ctxt->pkg1);
if (!ctxt->pkg1_id)
{
gfx_printf(&gfx_con, "%kCould not identify package1 version (= '%s').%k\n", 0xFF0000FF, (char *)ctxt->pkg1 + 0x10, 0xFFFFFFFF);
gfx_printf(&gfx_con, "%kCould not identify package1,\nVersion (= '%s').%k\n", 0xFF0000FF, (char *)ctxt->pkg1 + 0x10, 0xFFFFFFFF);
goto out;
}
gfx_printf(&gfx_con, "Identified package1 ('%s'), Keyblob version %d\n\n", (char *)(ctxt->pkg1 + 0x10), ctxt->pkg1_id->kb);
gfx_printf(&gfx_con, "Identified package1 ('%s'),\nKeyblob version %d\n\n", (char *)(ctxt->pkg1 + 0x10), ctxt->pkg1_id->kb);
//Read the correct keyblob.
ctxt->keyblob = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
@@ -326,22 +326,22 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
static int _config_svcperm(launch_ctxt_t *ctxt, const char *value)
{
if (*value == '1')
if (*(u8 *)value == '1')
{
DPRINTF("Disabled SVC verification\n");
ctxt->svcperm = 1;
ctxt->svcperm = malloc(1);
}
return 1;
}
static int _config_debugmode(launch_ctxt_t *ctxt, const char *value)
{
if (*value == '1')
if (*(u8 *)value == '1')
{
DPRINTF("Enabled Debug mode\n");
ctxt->debugmode = 1;
ctxt->debugmode = malloc(1);
}
return 1;
}
typedef struct _cfg_handler_t
@@ -372,21 +372,18 @@ static int _config(launch_ctxt_t *ctxt, ini_sec_t *cfg)
int hos_launch(ini_sec_t *cfg)
{
int bootStateDramPkg2;
int bootStatePkg2Continue;
int end_di = 0;
int bootStatePackage2;
int bootStateContinue;
launch_ctxt_t ctxt;
memset(&ctxt, 0, sizeof(launch_ctxt_t));
list_init(&ctxt.kip1_list);
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear(&gfx_ctxt, 0xFF1B1B1B);
gfx_con_setpos(&gfx_con, 0, 0);
//Try to parse config if present.
if (cfg && !_config(&ctxt, cfg))
return 0;
gfx_printf(&gfx_con, "Initializing...\n\n");
//Read package1 and the correct keyblob.
@@ -394,131 +391,131 @@ int hos_launch(ini_sec_t *cfg)
return 0;
gfx_printf(&gfx_con, "Loaded package1 and keyblob\n");
//Generate keys.
keygen(ctxt.keyblob, ctxt.pkg1_id->kb, (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off);
DPRINTF("Generated keys\n");
//Decrypt and unpack package1 if we require parts of it.
if (!ctxt.warmboot || !ctxt.secmon)
{
pkg1_decrypt(ctxt.pkg1_id, ctxt.pkg1);
pkg1_unpack((void *)ctxt.pkg1_id->warmboot_base, (void *)ctxt.pkg1_id->secmon_base, NULL, ctxt.pkg1_id, ctxt.pkg1);
pkg1_unpack((void *)ctxt.pkg1_id->warmboot_base, (void *)ctxt.pkg1_id->secmon_base, ctxt.pkg1_id, ctxt.pkg1);
gfx_printf(&gfx_con, "Decrypted and unpacked package1\n");
}
//Replace 'warmboot.bin' if requested.
if (ctxt.warmboot)
memcpy((void *)ctxt.pkg1_id->warmboot_base, ctxt.warmboot, ctxt.warmboot_size);
//Set warmboot address in PMC if required.
if (ctxt.pkg1_id->set_warmboot)
PMC(APBDEV_PMC_SCRATCH1) = ctxt.pkg1_id->warmboot_base;
PMC(APBDEV_PMC_SCRATCH1) = 0x8000D000;
//Replace 'SecureMonitor' if requested.
if (ctxt.secmon)
if (ctxt.secmon) {
memcpy((void *)ctxt.pkg1_id->secmon_base, ctxt.secmon, ctxt.secmon_size);
}
else
{
//Else we patch it to allow for an unsigned package2 and patched kernel.
//Else we patch it to allow for an unsigned package2.
patch_t *secmon_patchset = ctxt.pkg1_id->secmon_patchset;
gfx_printf(&gfx_con, "%kPatching Security Monitor%k\n", 0xFF00BAFF, 0xFFCCCCCC);
for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++)
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
}
gfx_printf(&gfx_con, "Loaded warmboot.bin and secmon\n");
//Read package2.
if (!_read_emmc_pkg2(&ctxt))
return 0;
gfx_printf(&gfx_con, "Read package2\n");
//Decrypt package2 and parse KIP1 blobs in INI1 section.
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(ctxt.pkg2);
LIST_INIT(kip1_info);
pkg2_parse_kips(&kip1_info, pkg2_hdr);
gfx_printf(&gfx_con, "Parsed ini1\n");
//Use the kernel included in package2 in case we didn't load one already.
if (!ctxt.kernel)
{
ctxt.kernel = pkg2_hdr->data;
ctxt.kernel_size = pkg2_hdr->sec_size[PKG2_SEC_KERNEL];
if (ctxt.svcperm || ctxt.debugmode)
{
u32 kernel_crc32 = crc32c(ctxt.kernel, ctxt.kernel_size);
ctxt.pkg2_kernel_id = pkg2_identify(kernel_crc32);
//In case a kernel patch option is set; allows to disable SVC verification or/and enable debug mode.
patch_t *kernel_patchset = ctxt.pkg2_kernel_id->kernel_patchset;
if (kernel_patchset != NULL)
//In case a kernel patch option is set. Allows to disable Svc Verififcation or/and enable Debug mode
patch_t *kernel_patchset = ctxt.pkg1_id->kernel_patchset;
if (secmon_patchset != NULL || (kernel_patchset != NULL && (ctxt.svcperm || ctxt.debugmode))) {
if (secmon_patchset != NULL)
{
gfx_printf(&gfx_con, "%kPatching kernel%k\n", 0xFF00BAFF, 0xFFCCCCCC);
//TODO: this is a bit ugly, perhaps attach a 'key' to the patchset and pass it via ini.
if (ctxt.svcperm && kernel_patchset[0].off != 0xFFFFFFFF)
*(vu32 *)(ctxt.kernel + kernel_patchset[0].off) = kernel_patchset[0].val;
if (ctxt.debugmode && kernel_patchset[1].off != 0xFFFFFFFF)
*(vu32 *)(ctxt.kernel + kernel_patchset[1].off) = kernel_patchset[1].val;
gfx_printf(&gfx_con, "%kPatching Security Monitor%k\n", 0xFF00BAFF, 0xFFCCCCCC);
for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++)
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
}
gfx_printf(&gfx_con, "Loaded warmboot.bin and secmon\n");
//Read package2.
if (!_read_emmc_pkg2(&ctxt))
return 0;
gfx_printf(&gfx_con, "Read package2\n");
//Decrypt package2 and parse KIP1 blobs in INI1 section.
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(ctxt.pkg2);
LIST_INIT(kip1_info);
pkg2_parse_kips(&kip1_info, pkg2_hdr);
gfx_printf(&gfx_con, "Parsed ini1\n");
//Use the kernel included in package2 in case we didn't load one already.
if (!ctxt.kernel)
{
ctxt.kernel = pkg2_hdr->data;
ctxt.kernel_size = pkg2_hdr->sec_size[PKG2_SEC_KERNEL];
if (kernel_patchset != NULL && (ctxt.svcperm || ctxt.debugmode))
{
gfx_printf(&gfx_con, "%kPatching kernel%k\n", 0xFF00BAFF, 0xFFCCCCCC);
if (ctxt.svcperm && kernel_patchset[0].off != 0xFFFFFFFF)
*(vu32 *)(ctxt.kernel + kernel_patchset[0].off) = kernel_patchset[0].val;
if (ctxt.debugmode && kernel_patchset[1].off != 0xFFFFFFFF)
*(vu32 *)(ctxt.kernel + kernel_patchset[1].off) = kernel_patchset[1].val;
}
}
//Merge extra KIP1s into loaded ones.
gfx_printf(&gfx_con, "%kPatching kernel initial processes%k\n", 0xFF00BAFF, 0xFFCCCCCC);
LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1);
//Rebuild and encrypt package2.
pkg2_build_encrypt((void *)0xA9800000, ctxt.kernel, ctxt.kernel_size, &kip1_info);
gfx_printf(&gfx_con, "Rebuilt and loaded package2\n");
} else {
//Read package2.
if (!_read_emmc_pkg2(&ctxt))
return 0;
gfx_printf(&gfx_con, "Loaded package2\n");
memcpy((void *)0xA9800000, ctxt.pkg2, ctxt.pkg2_size);
}
}
//Merge extra KIP1s into loaded ones.
gfx_printf(&gfx_con, "%kPatching kernel initial processes%k\n", 0xFF00BAFF, 0xFFCCCCCC);
LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1);
//Rebuild and encrypt package2.
pkg2_build_encrypt((void *)0xA9800000, ctxt.kernel, ctxt.kernel_size, &kip1_info);
gfx_printf(&gfx_con, "Rebuilt and loaded package2\n");
//Unmount SD card.
// Unmount SD Card
f_mount(NULL, "", 1);
gfx_printf(&gfx_con, "\n%kBooting...%k\n", 0xFF00FF96, 0xFFCCCCCC);
se_aes_key_clear(8);
se_aes_key_clear(11);
se_aes_key_clear(0x8);
se_aes_key_clear(0xB);
switch (ctxt.pkg1_id->kb)
{
case KB_FIRMWARE_VERSION_100_200:
case KB_FIRMWARE_VERSION_300:
case KB_FIRMWARE_VERSION_301:
se_key_acc_ctrl(12, 0xFF);
se_key_acc_ctrl(13, 0xFF);
bootStateDramPkg2 = 2;
bootStatePkg2Continue = 3;
end_di = 1;
break;
default:
case KB_FIRMWARE_VERSION_400:
case KB_FIRMWARE_VERSION_500:
se_key_acc_ctrl(12, 0xFF);
se_key_acc_ctrl(15, 0xFF);
bootStateDramPkg2 = 2;
bootStatePkg2Continue = 4;
break;
switch (ctxt.pkg1_id->kb) {
case KB_FIRMWARE_VERSION_100_200:
case KB_FIRMWARE_VERSION_300:
case KB_FIRMWARE_VERSION_301:
se_key_acc_ctrl(0xC, 0xFF);
se_key_acc_ctrl(0xD, 0xFF);
bootStatePackage2 = 2;
bootStateContinue = 3;
break;
default:
case KB_FIRMWARE_VERSION_400:
case KB_FIRMWARE_VERSION_500:
se_key_acc_ctrl(0xC, 0xFF);
se_key_acc_ctrl(0xF, 0xFF);
bootStatePackage2 = 3;
bootStateContinue = 4;
break;
}
//TODO: Don't Clear 'BootConfig' for retail >1.0.0.
//Clear 'BootConfig' for retail systems.
memset((void *)0x4003D000, 0, 0x3000);
//pkg2_decrypt((void *)0xA9800000);
//sleep(10000);
//btn_wait();
//return 0;
//Lock SE before starting 'SecureMonitor'.
_se_lock();
//< 4.0.0 Signals. 0: Nothing ready, 1: BCT ready, 2: DRAM and pkg2 ready, 3: Continue boot
//>=4.0.0 Signals. 0: Nothing ready, 1: BCT ready, 2: DRAM ready, 4: pkg2 ready and continue boot
vu32 *mb_in = (vu32 *)0x40002EF8;
//Non-zero: Secmon ready
vu32 *mb_out = (vu32 *)0x40002EFC;
//Start from DRAM ready signal
*mb_in = bootStateDramPkg2;
*mb_in = bootStatePackage2;
*mb_out = 0;
//Wait for secmon to get ready.
@@ -526,6 +523,10 @@ int hos_launch(ini_sec_t *cfg)
while (!*mb_out)
sleep(1);
//Signal 'BootConfig'.
//*mb_in = 1;
//sleep(100);
//TODO: pkg1.1 locks PMC scratches, we can do that too at some point.
/*PMC(0x4) = 0x7FFFF3;
PMC(0x2C4) = 0xFFFFFFFF;
@@ -536,12 +537,11 @@ int hos_launch(ini_sec_t *cfg)
PMC(0x5BC) = 0xFFFFFFFF;
PMC(0x5C0) = 0xFFAAFFFF;*/
//Disable display.
if (end_di)
display_end();
//TODO: Cleanup.
//display_end();
//Signal to pkg2 ready and continue boot.
*mb_in = bootStatePkg2Continue;
//Signal to continue boot.
*mb_in = bootStateContinue;
//Halt ourselves in waitevent state.
while (1)

View File

@@ -46,7 +46,7 @@ static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
base[0] = (2 * size - 2) | 0x2800; //Set size and send mode.
_i2c_wait(base); //Kick transaction.
base[0] = (base[0] & 0xFFFFFDFF) | 0x200;
base[0] = base[0] & 0xFFFFFDFF | 0x200;
while (base[7] & 0x100)
;
@@ -66,7 +66,7 @@ static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
base[0] = (2 * size - 2) | 0x2840; //Set size and recv mode.
_i2c_wait(base); //Kick transaction.
base[0] = (base[0] & 0xFFFFFDFF) | 0x200;
base[0] = base[0] & 0xFFFFFDFF | 0x200;
while (base[7] & 0x100)
;
@@ -94,11 +94,11 @@ void i2c_init(u32 idx)
break;
}
(vu32)base[0x22];
vu32 dummy = base[0x22];
base[0x1A] = base[0x1A];
}
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
u32 i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
{
u8 tmp[4];
@@ -108,7 +108,7 @@ int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
tmp[0] = y;
memcpy(tmp + 1, buf, size);
return _i2c_send_pkt(idx, x, tmp, size + 1);
_i2c_send_pkt(idx, x, tmp, size + 1);
}
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
@@ -119,9 +119,9 @@ int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
return res;
}
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)
u32 i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)
{
return i2c_send_buf_small(idx, x, y, &b, 1);
i2c_send_buf_small(idx, x, y, &b, 1);
}
u8 i2c_recv_byte(u32 idx, u32 x, u32 y)

View File

@@ -27,9 +27,9 @@
#define I2C_6 5
void i2c_init(u32 idx);
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
u32 i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
u32 i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
u8 i2c_recv_byte(u32 idx, u32 x, u32 y);
#endif

View File

@@ -91,51 +91,3 @@ int ini_parse(link_t *dst, char *ini_path)
return 1;
}
void ini_free(link_t *dst)
{
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, dst, link)
{
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
{
free(kv->key);
free(kv->val);
free(kv);
}
free(ini_sec->name);
free(ini_sec);
}
}
ini_sec_t *ini_clone_section(ini_sec_t *cfg)
{
if (cfg == NULL)
return NULL;
ini_sec_t *csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
list_init(&csec->kvs);
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link)
{
ini_kv_t *kvcfg = (ini_kv_t *)malloc(sizeof(ini_kv_t));
kvcfg->key = _strdup(kv->key);
kvcfg->val = _strdup(kv->val);
list_append(&csec->kvs, &kvcfg->link);
}
return csec;
}
void ini_free_section(ini_sec_t *cfg)
{
if (cfg == NULL)
return;
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link)
{
free(kv->key);
free(kv->val);
free(kv);
}
free(cfg);
}

View File

@@ -35,8 +35,5 @@ typedef struct _ini_sec_t
} ini_sec_t;
int ini_parse(link_t *dst, char *ini_path);
void ini_free(link_t *dst);
ini_sec_t *ini_clone_section(ini_sec_t *cfg);
void ini_free_section(ini_sec_t *cfg);
#endif

View File

@@ -38,6 +38,7 @@
#include "gpio.h"
#include "sdmmc.h"
#include "ff.h"
#include "ctc_logo2.h"
#include "tui.h"
#include "heap.h"
#include "list.h"
@@ -47,6 +48,7 @@
#include "hos.h"
#include "pkg1.h"
#include "mmc.h"
#include "lz.h"
//TODO: ugly.
gfx_ctxt_t gfx_ctxt;
@@ -61,6 +63,7 @@ sdmmc_t sd_sdmmc;
sdmmc_storage_t sd_storage;
FATFS sd_fs;
int sd_mounted;
u8 *Kc_HEKATE_LOGO;
int sd_mount()
{
@@ -93,9 +96,9 @@ void sd_unmount()
{
if (sd_mounted)
{
gfx_puts(&gfx_con, "Unmounting SD card...\n");
f_mount(NULL, "", 1);
sdmmc_storage_end(&sd_storage);
sd_mounted = 0;
}
}
@@ -156,17 +159,17 @@ void panic(u32 val)
void config_oscillators()
{
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4;
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3 | 4;
SYSCTR0(SYSCTR0_CNTFID0) = 19200000;
TMR(0x14) = 0x45F;
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071;
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE;
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | 0x400000;
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | 0x1000;
PMC(APBDEV_PMC_SCRATCH188) = (PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF) | 0x2000000;
PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81 | 0xE;
PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF | 0x400000;
PMC(APBDEV_PMC_CNTRL2) = PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF | 0x1000;
PMC(APBDEV_PMC_SCRATCH188) = PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF | 0x2000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10;
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF;
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
PMC(APBDEV_PMC_TSC_MULT) = PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000 | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444;
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2;
@@ -247,9 +250,9 @@ void mbist_workaround()
CLOCK(0x554) = 0;
CLOCK(0xD0) &= 0x1F7FFFFF;
CLOCK(0x410) &= 0xFFFF3FFF;
CLOCK(0x148) = (CLOCK(0x148) & 0x1FFFFFFF) | 0x80000000;
CLOCK(0x180) = (CLOCK(0x180) & 0x1FFFFFFF) | 0x80000000;
CLOCK(0x6A0) = (CLOCK(0x6A0) & 0x1FFFFFFF) | 0x80000000;
CLOCK(0x148) = CLOCK(0x148) & 0x1FFFFFFF | 0x80000000;
CLOCK(0x180) = CLOCK(0x180) & 0x1FFFFFFF | 0x80000000;
CLOCK(0x6A0) = CLOCK(0x6A0) & 0x1FFFFFFF | 0x80000000;
}
void config_se_brom()
@@ -268,6 +271,7 @@ void config_se_brom()
// Clear the boot reason to avoid problems later
PMC(APBDEV_PMC_SCRATCH200) = 0x0;
PMC(APBDEV_PMC_RST_STATUS_0) = 0x0;
PMC(APBDEV_PMC_SCRATCH49_0) = 0x0;
}
void config_hw()
@@ -324,7 +328,7 @@ void config_hw()
config_pmc_scratch();
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = (CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888) | 0x3333;
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888 | 0x3333;
mc_config_carveout();
@@ -335,7 +339,7 @@ void config_hw()
void print_fuseinfo()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear(&gfx_ctxt, 0xFF1B1B1B);
gfx_con_setpos(&gfx_con, 0, 0);
gfx_printf(&gfx_con, "%k(Unlocked) fuse cache:\n\n%k", 0xFFFFDD00, 0xFFCCCCCC);
@@ -364,7 +368,7 @@ void print_fuseinfo()
void print_kfuseinfo()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear(&gfx_ctxt, 0xFF1B1B1B);
gfx_con_setpos(&gfx_con, 0, 0);
gfx_printf(&gfx_con, "%kKFuse contents:\n\n%k", 0xFFFFDD00, 0xFFCCCCCC);
@@ -397,7 +401,7 @@ void print_kfuseinfo()
void print_mmc_info()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear(&gfx_ctxt, 0xFF1B1B1B);
gfx_con_setpos(&gfx_con, 0, 0);
static const u32 SECTORS_TO_MIB_COEFF = 11;
@@ -502,21 +506,29 @@ void print_mmc_info()
Cmd Classes: %02X\n\
Capacity: %s\n\
Max Speed: %d MB/s (%d MHz)\n\
Type Support: %s\n\n",
Type Support: ",
storage.csd.mmca_vsn, storage.ext_csd.rev, storage.ext_csd.dev_version, storage.csd.cmdclass,
storage.csd.capacity == (4096 * 512) ? "High" : "Low", speed & 0xFFFF, (speed >> 16) & 0xFFFF, card_type_support);
storage.csd.capacity == (4096 * 512) ? "High" : "Low", speed & 0xFFFF, (speed >> 16) & 0xFFFF);
gfx_con_setfontsz(&gfx_con, 8);
gfx_printf(&gfx_con, "%s", card_type_support);
gfx_con_setfontsz(&gfx_con, 16);
gfx_printf(&gfx_con, "\n\n", card_type_support);
u32 boot_size = storage.ext_csd.boot_mult << 17;
u32 rpmb_size = storage.ext_csd.rpmb_mult << 17;
gfx_printf(&gfx_con, "%keMMC Partitions:%k\n", 0xFFFFDD00, 0xFFCCCCCC);
gfx_printf(&gfx_con, " 1: %kBOOT0 %kSize: %5d KiB (LBA Sectors: 0x%07X)\n", 0xFF00FF96, 0xFFCCCCCC,
gfx_printf(&gfx_con, " 1: %kBOOT0 %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", 0xFF00FF96, 0xFFCCCCCC,
boot_size / 1024, boot_size / 1024 / 512);
gfx_printf(&gfx_con, " 2: %kBOOT1 %kSize: %5d KiB (LBA Sectors: 0x%07X)\n", 0xFF00FF96, 0xFFCCCCCC,
gfx_putsep(&gfx_con);
gfx_printf(&gfx_con, " 2: %kBOOT1 %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", 0xFF00FF96, 0xFFCCCCCC,
boot_size / 1024, boot_size / 1024 / 512);
gfx_printf(&gfx_con, " 3: %kRPMB %kSize: %5d KiB (LBA Sectors: 0x%07X)\n", 0xFF00FF96, 0xFFCCCCCC,
gfx_putsep(&gfx_con);
gfx_printf(&gfx_con, " 3: %kRPMB %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", 0xFF00FF96, 0xFFCCCCCC,
rpmb_size / 1024, rpmb_size / 1024 / 512);
gfx_printf(&gfx_con, " 0: %kGPP (USER) %kSize: %5d MiB (LBA Sectors: 0x%07X)\n\n", 0xFF00FF96, 0xFFCCCCCC,
gfx_putsep(&gfx_con);
gfx_printf(&gfx_con, " 0: %kGPP (USER) %k\n Size: %5d MiB (LBA Sectors: 0x%07X)\n\n", 0xFF00FF96, 0xFFCCCCCC,
storage.sec_cnt >> SECTORS_TO_MIB_COEFF, storage.sec_cnt);
gfx_putsep(&gfx_con);
gfx_printf(&gfx_con, "%kGPP (eMMC USER) partition table:%k\n", 0xFFFFDD00, 0xFFCCCCCC);
sdmmc_storage_set_mmc_partition(&storage, 0);
@@ -525,9 +537,10 @@ void print_mmc_info()
int gpp_idx = 0;
LIST_FOREACH_ENTRY(emmc_part_t, part, &gpt, link)
{
gfx_printf(&gfx_con, " %02d: %k%s%k\n Size: % 5d MiB (LBA Sectors 0x%07X, LBA Range: %08X-%08X)\n",
gfx_printf(&gfx_con, " %02d: %k%s%k\n Size: % 5d MiB (LBA Sectors 0x%07X)\n LBA Range: %08X-%08X\n",
gpp_idx++, 0xFF14FDAE, part->name, 0xFFCCCCCC, (part->lba_end - part->lba_start + 1) >> SECTORS_TO_MIB_COEFF,
part->lba_end - part->lba_start + 1, part->lba_start, part->lba_end);
gfx_putsep(&gfx_con);
}
}
}
@@ -540,7 +553,7 @@ out:
void print_sdcard_info()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear(&gfx_ctxt, 0xFF1B1B1B);
gfx_con_setpos(&gfx_con, 0, 0);
static const u32 SECTORS_TO_MIB_COEFF = 11;
@@ -591,7 +604,7 @@ void print_sdcard_info()
void print_tsec_key()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear(&gfx_ctxt, 0xFF1B1B1B);
gfx_con_setpos(&gfx_con, 0, 0);
sdmmc_storage_t storage;
@@ -606,6 +619,7 @@ void print_tsec_key()
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
if (!pkg1_id)
{
gfx_con_setfontsz(&gfx_con, 8);
EPRINTFARGS("Could not identify package1 version to read TSEC firmware (= '%s').",
(char *)pkg1 + 0x10);
goto out;
@@ -638,12 +652,14 @@ out:;
void reboot_normal()
{
sd_unmount();
free(Kc_HEKATE_LOGO);
panic(0x21); //Bypass fuse programming in package1.
}
void reboot_rcm()
{
sd_unmount();
free(Kc_HEKATE_LOGO);
PMC(APBDEV_PMC_SCRATCH0) = 2; //Reboot into rcm.
PMC(0) |= 0x10;
while (1)
@@ -653,6 +669,7 @@ void reboot_rcm()
void power_off()
{
sd_unmount();
free(Kc_HEKATE_LOGO);
//TODO: we should probably make sure all regulators are powered off properly.
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);
}
@@ -679,6 +696,7 @@ int dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char* outFilename,
if(!sdmmc_storage_read(storage, lbaCurrVer, num, bufEm))
{
gfx_con_setfontsz(&gfx_con, 16);
EPRINTFARGS("\nFailed to read %d blocks @ LBA %08X\nfrom eMMC. Aborting..\n",
num, lbaCurrVer);
@@ -689,6 +707,7 @@ int dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char* outFilename,
}
if (!(f_read(&fp, bufSd, num, NULL) == FR_OK))
{
gfx_con_setfontsz(&gfx_con, 16);
EPRINTFARGS("\nFailed to read %d blocks from sd card.\nVerification failed..\n", num);
free(bufEm);
@@ -699,6 +718,7 @@ int dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char* outFilename,
if(!memcmp(bufEm, bufSd, num << 9))
{
gfx_con_setfontsz(&gfx_con, 16);
EPRINTFARGS("\nVerification failed.\nVerification failed..\n", num);
free(bufEm);
@@ -727,6 +747,7 @@ int dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char* outFilename,
}
else
{
gfx_con_setfontsz(&gfx_con, 16);
EPRINTF("\nFile not found or could not be loaded.\nVerification failed..\n");
return 1;
}
@@ -753,7 +774,8 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
memcpy(partialIdxFilename, "partial.idx", 11);
partialIdxFilename[11] = 0;
gfx_printf(&gfx_con, "\nSD Card free space: %d MiB, Total backup size %d MiB\n\n",
gfx_con_setfontsz(&gfx_con, 8);
gfx_printf(&gfx_con, "\nSD Card free space: %d MiB, Total dump size %d MiB\n\n",
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF,
totalSectors >> SECTORS_TO_MIB_COEFF);
@@ -768,19 +790,20 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
{
isSmallSdCard = 1;
gfx_printf(&gfx_con, "%k\nSD card free space is smaller than total backup size.%k\n", 0xFF00BAFF, 0xFFCCCCCC);
gfx_printf(&gfx_con, "%k\nSD card free space is smaller than dump total size.%k\n", 0xFF00BAFF, 0xFFCCCCCC);
if (!maxSplitParts)
{
EPRINTF("Not enough free space for Partial Backup.");
gfx_con_setfontsz(&gfx_con, 16);
EPRINTF("Not enough free space for partial dumping.");
return 0;
}
}
// Check if we continuing a previous raw eMMC backup in progress.
// Check if we continuing a previous raw eMMC dump in progress.
if (f_open(&partialIdxFp, partialIdxFilename, FA_READ) == FR_OK)
{
gfx_printf(&gfx_con, "%kFound Partial Backup in progress. Continuing...%k\n\n", 0xFF14FDAE, 0xFFCCCCCC);
gfx_printf(&gfx_con, "%kFound partial dump in progress. Continuing...%k\n\n", 0xFF14FDAE, 0xFFCCCCCC);
partialDumpInProgress = 1;
// Force partial dumping, even if the card is larger.
@@ -791,18 +814,19 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
if (!maxSplitParts)
{
EPRINTF("Not enough free space for Partial Backup.");
gfx_con_setfontsz(&gfx_con, 16);
EPRINTF("Not enough free space for partial dumping.");
return 0;
}
// Increase maxSplitParts to accommodate previously backed up parts
// Increase maxSplitParts to accommodate previously dumped parts
maxSplitParts += currPartIdx;
}
else if (isSmallSdCard)
gfx_printf(&gfx_con, "%kPartial Backup enabled (with %d MiB parts)...%k\n\n", 0xFF00BAFF, multipartSplitSize >> 20, 0xFFCCCCCC);
gfx_printf(&gfx_con, "%kPartial dumping enabled (with %d MiB parts)...%k\n\n", 0xFF00BAFF, multipartSplitSize >> 20, 0xFFCCCCCC);
// Check if filesystem is FAT32 or the free space is smaller and backup in parts
// Check if filesystem is FAT32 or the free space is smaller and dump in parts
if (((sd_fs.fs_type != FS_EXFAT) && totalSectors > (FAT32_FILESIZE_LIMIT / NX_EMMC_BLOCKSIZE)) | isSmallSdCard)
{
u32 multipartSplitSectors = multipartSplitSize / NX_EMMC_BLOCKSIZE;
@@ -823,7 +847,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
else
outFilename[sdPathLen + 1] = 0;
}
// Continue from where we left, if Partial Backup in progress.
// Continue from where we left, if partial dump in progress.
else
{
if (numSplitParts >= 10 && currPartIdx < 10)
@@ -839,6 +863,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
FIL fp;
if (f_open(&fp, outFilename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
{
gfx_con_setfontsz(&gfx_con, 16);
EPRINTFARGS("Error creating file %s.\n", outFilename);
return 0;
@@ -852,7 +877,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
u32 prevPct = 200;
int retryCount = 0;
// Continue from where we left, if Partial Backup in progress.
// Continue from where we left, if partial dump in progress.
if (partialDumpInProgress)
{
lba_curr += currPartIdx * (multipartSplitSize / NX_EMMC_BLOCKSIZE);
@@ -870,7 +895,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
// Verify part
if (dump_emmc_verify(storage, lba_curr, outFilename, NUM_SECTORS_PER_ITER, part))
{
EPRINTF("\nPress any key and try again...\n");
EPRINTF("\nPress any key and try again.\n");
free(buf);
return 0;
@@ -887,7 +912,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
// Always create partial.idx before next part, in case a fatal error occurs.
if (isSmallSdCard)
{
// Create partial backup index file
// Create partial dump index file
if (f_open(&partialIdxFp, partialIdxFilename, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
{
f_write(&partialIdxFp, &currPartIdx, 4, NULL);
@@ -895,20 +920,22 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
}
else
{
gfx_con_setfontsz(&gfx_con, 16);
EPRINTF("\nError creating partial.idx file.\n");
free(buf);
return 0;
}
// More parts to backup that do not currently fit the sd card free space or fatal error
// More parts to dump that do not currently fit the sd card free space or fatal error
if (currPartIdx >= maxSplitParts)
{
gfx_puts(&gfx_con, "\n\n1. Press any key and Power off Switch from the main menu.\n\
2. Move the files from SD card to free space.\n\
Don\'t move the partial.idx file!\n\
3. Unplug and re-plug USB while pressing Vol+.\n\
4. Run hekate again and press Backup eMMC RAW GPP (or eMMC USER) to continue.\n");
4. Run hekate - ipl again and press Dump RAW eMMC or eMMC USER to continue\n");
gfx_con_setfontsz(&gfx_con, 16);
free(buf);
return 1;
@@ -918,6 +945,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
// Create next part
if (f_open(&fp, outFilename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
{
gfx_con_setfontsz(&gfx_con, 16);
EPRINTFARGS("Error creating file %s.\n", outFilename);
free(buf);
@@ -936,9 +964,10 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
sleep(150000);
if (retryCount >= 3)
{
EPRINTFARGS("\nFailed to read %d blocks @ LBA %08X from eMMC. Aborting..\n",
gfx_con_setfontsz(&gfx_con, 16);
EPRINTFARGS("\nFailed to read %d blocks @ LBA %08X\nfrom eMMC. Aborting..\n",
num, lba_curr);
EPRINTF("\nPress any key and try again...\n");
EPRINTF("\nPress any key and try again.\n");
free(buf);
f_close(&fp);
@@ -948,8 +977,9 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
res = f_write(&fp, buf, NX_EMMC_BLOCKSIZE * num, NULL);
if (res)
{
gfx_con_setfontsz(&gfx_con, 16);
EPRINTFARGS("\nFatal error (%d) when writing to SD Card", res);
EPRINTF("\nPress any key and try again...\n");
EPRINTF("\nPress any key and try again.\n");
free(buf);
f_close(&fp);
@@ -975,14 +1005,14 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
}
tui_pbar(&gfx_con, 0, gfx_con.y, 100, 0xFFCCCCCC, 0xFF555555);
// Backup operation ended successfully
// Dumping process ended successfully
free(buf);
f_close(&fp);
// Verify last part or single file backup
// Verify last part or single file dump
if (dump_emmc_verify(storage, lba_curr, outFilename, NUM_SECTORS_PER_ITER, part))
{
EPRINTF("\nPress any key and try again...\n");
EPRINTF("\nPress any key and try again.\n");
free(buf);
return 0;
@@ -990,11 +1020,12 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
else
tui_pbar(&gfx_con, 0, gfx_con.y, 100, 0xFF00FF96, 0xFF005515);
// Remove partial backup index file if no fatal errors occurred.
gfx_con_setfontsz(&gfx_con, 16);
// Remove partial dump index file if no fatal errors occurred.
if(isSmallSdCard)
{
f_unlink(partialIdxFilename);
gfx_printf(&gfx_con, "%k\n\nYou can now join the files\nand get the complete eMMC RAW GPP backup.", 0xFFCCCCCC);
gfx_printf(&gfx_con, "%k\n\nYou can now join the files\nand get the complete raw eMMC dump.", 0xFFCCCCCC);
}
gfx_puts(&gfx_con, "\n\n");
@@ -1013,14 +1044,14 @@ static void dump_emmc_selected(dumpType_t dumpType)
{
int res = 0;
u32 timer = 0;
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear(&gfx_ctxt, 0xFF1B1B1B);
gfx_con_setpos(&gfx_con, 0, 0);
if (!sd_mount())
goto out;
gfx_puts(&gfx_con, "Checking for available free space...\n\n");
// Get SD Card free space for Partial Backup
// Get SD Card free space for partial dumping
f_getfree("", &sd_fs.free_clst, NULL);
sdmmc_storage_t storage;
@@ -1047,7 +1078,7 @@ static void dump_emmc_selected(dumpType_t dumpType)
bootPart.name[4] = (u8)('0' + i);
bootPart.name[5] = 0;
gfx_printf(&gfx_con, "%k%02d: %s (%08X-%08X)%k\n", 0xFFFFDD00, i,
gfx_printf(&gfx_con, "%k%02d: %s (%07X-%07X)%k\n", 0xFFFFDD00, i,
bootPart.name, bootPart.lba_start, bootPart.lba_end, 0xFFCCCCCC);
sdmmc_storage_set_mmc_partition(&storage, i+1);
@@ -1070,7 +1101,7 @@ static void dump_emmc_selected(dumpType_t dumpType)
if ((dumpType & DUMP_SYSTEM) == 0 && strcmp(part->name, "USER"))
continue;
gfx_printf(&gfx_con, "%k%02d: %s (%08X-%08X)%k\n", 0xFFFFDD00, i++,
gfx_printf(&gfx_con, "%k%02d: %s (%07X-%07X)%k\n", 0xFFFFDD00, i++,
part->name, part->lba_start, part->lba_end, 0xFFCCCCCC);
res = dump_emmc_part(part->name, &storage, part);
@@ -1087,7 +1118,7 @@ static void dump_emmc_selected(dumpType_t dumpType)
rawPart.lba_end = RAW_AREA_NUM_SECTORS-1;
strcpy(rawPart.name, "rawnand.bin");
{
gfx_printf(&gfx_con, "%k%02d: %s (%08X-%08X)%k\n", 0xFFFFDD00, i++,
gfx_printf(&gfx_con, "%k%02d: %s (%07X-%07X)%k\n", 0xFFFFDD00, i++,
rawPart.name, rawPart.lba_start, rawPart.lba_end, 0xFFCCCCCC);
res = dump_emmc_part(rawPart.name, &storage, &rawPart);
@@ -1099,7 +1130,7 @@ static void dump_emmc_selected(dumpType_t dumpType)
gfx_printf(&gfx_con, "Time taken: %d seconds.\n", (get_tmr() - timer) / 1000000);
sdmmc_storage_end(&storage);
if (res)
gfx_printf(&gfx_con, "\n%kFinished and verified!%k\nPress any key...\n",0xFF00FF96, 0xFFCCCCCC);
gfx_printf(&gfx_con, "\n%kFinished and verified!%k\nPress any key.\n",0xFF00FF96, 0xFFCCCCCC);
out:;
btn_wait();
@@ -1112,12 +1143,11 @@ void dump_emmc_rawnand() { dump_emmc_selected(DUMP_RAW); }
void dump_package1()
{
u8 *pkg1 = (u8 *)calloc(1, 0x40000);
u8 *warmboot = (u8 *)calloc(1, 0x40000);
u8 *secmon = (u8 *)calloc(1, 0x40000);
u8 *loader = (u8 *)calloc(1, 0x40000);
u8 * pkg1 = (u8 *)malloc(0x40000);
u8 * warmboot = (u8 *)malloc(0x40000);
u8 * secmon = (u8 *)malloc(0x40000);
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear(&gfx_ctxt, 0xFF1B1B1B);
gfx_con_setpos(&gfx_con, 0, 0);
if (!sd_mount())
@@ -1132,61 +1162,49 @@ void dump_package1()
}
sdmmc_storage_set_mmc_partition(&storage, 1);
// Read package1.
//Read package1.
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
const pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + pkg1_id->pkg11_off + 0x20);
if (!pkg1_id)
{
gfx_con_setfontsz(&gfx_con, 8);
EPRINTFARGS("Could not identify package1 version to read TSEC firmware (= '%s').", (char *)pkg1 + 0x10);
goto out;
}
// Read keyblob
u8 * keyblob = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + pkg1_id->kb, 1, keyblob);
// Decrypt
// decrypt
keygen(keyblob, pkg1_id->kb, (u8 *)pkg1 + pkg1_id->tsec_off);
pkg1_decrypt(pkg1_id, pkg1);
pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1);
pkg1_unpack(warmboot, secmon, pkg1_id, pkg1);
// Display info
gfx_printf(&gfx_con, "%kNX Bootloader size: %k0x%05X\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->ldr_size);
gfx_printf(&gfx_con, "%kNX Bootloader ofst: %k0x%05X\n\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->ldr_off);
// display info
gfx_printf(&gfx_con, "%kSecure monitor addr: %k%08X\n", 0xFF46EAC7, 0xFFCCCCCC, pkg1_id->secmon_base);
gfx_printf(&gfx_con, "%kSecure monitor size: %k%08X\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->sm_size);
gfx_printf(&gfx_con, "%kSecure monitor ofst: %k%08X\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->sm_off);
gfx_printf(&gfx_con, "%kSecure monitor addr: %k0x%05X\n", 0xFF46EAC7, 0xFFCCCCCC, pkg1_id->secmon_base);
gfx_printf(&gfx_con, "%kSecure monitor size: %k0x%05X\n\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->sm_size);
gfx_printf(&gfx_con, "%kSecure monitor ofst: %k0x%05X\n\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->sm_off);
gfx_printf(&gfx_con, "%kWarmboot addr: %k0x%05X\n", 0xFF46EAC7, 0xFFCCCCCC, pkg1_id->warmboot_base);
gfx_printf(&gfx_con, "%kWarmboot size: %k0x%05X\n\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->wb_size);
gfx_printf(&gfx_con, "%kWarmboot ofst: %k0x%05X\n\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->wb_off);
// Dump package1
if (sd_save_to_file(pkg1, 0x40000, "pkg1_decr.bin")) {
EPRINTF("\nFailed to create pkg1_decr.bin");
// dump package1
if (sd_save_to_file(pkg1, 0x40000, "pkg_decr.bin")) {
EPRINTF("\nFailed to create pkg_decr.bin");
goto out;
}
gfx_puts(&gfx_con, "\npackage1 dumped to pkg1_decr.bin\n");
gfx_puts(&gfx_con, "\npackage1 dumped to pkg_decr.bin\n");
// Dump nxbootloader
if (sd_save_to_file(loader, hdr->ldr_size, "nxloader.bin")) {
EPRINTF("\nFailed to create nxloader.bin");
// dump sm
if (sd_save_to_file(secmon, 0x40000, "sm.bin")) {
EPRINTF("\nFailed to create sm.bin");
goto out;
}
gfx_puts(&gfx_con, "NX Bootloader dumped to nxloader.bin\n");
gfx_puts(&gfx_con, "Secure Monitor dumped to sm.bin\n");
// Dump secmon
if (sd_save_to_file(secmon, hdr->sm_size, "secmon.bin")) {
EPRINTF("\nFailed to create secmon.bin");
goto out;
}
gfx_puts(&gfx_con, "Secure Monitor dumped to secmon.bin\n");
// Dump warmboot
if (sd_save_to_file(warmboot, hdr->wb_size, "warmboot.bin")) {
// dump warmboot
if (sd_save_to_file(warmboot, 0x40000, "warmboot.bin")) {
EPRINTF("\nFailed to create warmboot.bin");
goto out;
}
@@ -1194,33 +1212,30 @@ void dump_package1()
sdmmc_storage_end(&storage);
gfx_puts(&gfx_con, "\nDone. Press any key...\n");
gfx_puts(&gfx_con, "\nDone. Press any key.\n");
out:;
free(pkg1);
free(secmon);
free(warmboot);
free(loader);
btn_wait();
}
void launch_firmware()
{
u8 max_entries = 16;
ini_sec_t *cfg_sec = NULL;
LIST_INIT(ini_sections);
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear(&gfx_ctxt, 0xFF1B1B1B);
gfx_con_setpos(&gfx_con, 0, 0);
if (sd_mount())
{
if (ini_parse(&ini_sections, "hekate_ipl.ini"))
{
// Build configuration menu.
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * max_entries);
//Build configuration menu.
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 16);
ments[0].type = MENT_BACK;
ments[0].caption = "Back";
u32 i = 1;
@@ -1232,9 +1247,6 @@ void launch_firmware()
ments[i].caption = ini_sec->name;
ments[i].data = ini_sec;
i++;
if (i > max_entries)
break;
}
if (i > 1)
{
@@ -1242,18 +1254,13 @@ void launch_firmware()
menu_t menu = {
ments, "Launch configurations", 0, 0
};
cfg_sec = ini_clone_section((ini_sec_t *)tui_do_menu(&gfx_con, &menu));
cfg_sec = (ini_sec_t *)tui_do_menu(&gfx_con, &menu);
if (!cfg_sec)
{
free(ments);
ini_free(&ini_sections);
return;
}
}
else
EPRINTF("No launch configurations found.");
free(ments);
ini_free(&ini_sections);
}
else
EPRINTF("Could not find or open 'hekate_ipl.ini'.\nMake sure it exists in SD Card!.");
@@ -1261,25 +1268,27 @@ void launch_firmware()
if (!cfg_sec)
{
gfx_printf(&gfx_con, "\nUsing default launch configuration...\n");
sleep(3000000);
gfx_printf(&gfx_con, "Using default launch configuration...\n");
}
free(Kc_HEKATE_LOGO);
if (!hos_launch(cfg_sec))
{
Kc_HEKATE_LOGO = (u8 *)malloc(36864);
LZ_Uncompress(Kc_HEKATE_LOGOlz, Kc_HEKATE_LOGO, SZ_HEKATE_LOGOLZ);
EPRINTF("Failed to launch firmware.");
}
ini_free_section(cfg_sec);
//TODO: free ini.
out:;
btn_wait();
}
void toggle_autorcm(){
sdmmc_storage_t storage;
sdmmc_t sdmmc;
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_con_setpos(&gfx_con, 0, 0);
if(!sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4))
{
EPRINTF("Failed to init eMMC.");
@@ -1294,95 +1303,22 @@ void toggle_autorcm(){
{
sect = (0x200 + (0x4000 * i)) / NX_EMMC_BLOCKSIZE;
sdmmc_storage_read(&storage, sect, 1, tempbuf);
tempbuf[0x10] ^= 0x77; // !IMPORTANT: DO NOT CHANGE! XOR by arbitrary number to corrupt
tempbuf[0x10] ^= 0x77; //xor by arbitrary number to corrupt
sdmmc_storage_write(&storage, sect, 1, tempbuf);
}
free(tempbuf);
sdmmc_storage_end(&storage);
gfx_printf(&gfx_con, "%kAutoRCM mode toggled!%k\n\nPress any key...\n", 0xFF00FF96, 0xFFCCCCCC);
gfx_printf(&gfx_con, "%kAutoRCM mode toggled!%k\n", 0xFF00EE2C, 0xFFCCCCCC);
out:;
btn_wait();
}
int fix_attributes(char *path, u32 *total)
{
FRESULT res;
DIR dir;
u32 i = 0;
u32 k = 0;
static FILINFO fno;
// Open directory
res = f_opendir(&dir, path);
if (res == FR_OK)
{
for (;;)
{
// Read a directory item.
res = f_readdir(&dir, &fno);
// Break on error or end of dir.
if (res != FR_OK || fno.fname[0] == 0)
break;
// Set new directory
i = strlen(path);
memcpy(&path[i], "/", 1);
for (k = 0; k < 256; k++)
{
if (fno.fname[k] == 0)
break;
}
memcpy(&path[i+1], fno.fname, k + 1);
path[i + k + 2] = 0;
// Check if archive bit is set
if (fno.fattrib & AM_ARC)
{
*(u32 *)total = *(u32 *)total + 1;
f_chmod(path, 0, AM_ARC);
}
// Is it a directory?
if (fno.fattrib & AM_DIR)
{
// Enter the directory.
res = fix_attributes(path, total);
if (res != FR_OK)
break;
}
// Clear file or folder path.
path[i] = 0;
}
f_closedir(&dir);
}
return res;
}
void fix_sd_attr(){
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_con_setpos(&gfx_con, 0, 0);
char buff[256];
u32 total = 0;
if (sd_mount())
{
gfx_printf(&gfx_con, "Traversing all sd card files!\nThis may take some time, please wait...\n");
buff[0] = '/';
buff[1] = 0;
fix_attributes(buff, &total);
gfx_printf(&gfx_con, "\n%kTotal archive bits cleared: %d!%k\n\nDone! Press any key...", 0xFF00FF96, total, 0xFFCCCCCC);
}
btn_wait();
}
void about()
{
gfx_con_setfontsz(&gfx_con, 8);
static const char octopus[] =
"hekate (C) 2018 naehrwert, st4rk\n\n"
"Thanks to: %kderrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8%k\n\n"
@@ -1409,7 +1345,7 @@ void about()
" (/` ( (` ) ) '-; %k[switchbrew]%k\n"
" ` '-; (-'%k";
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear(&gfx_ctxt, 0xFF1B1B1B);
gfx_con_setpos(&gfx_con, 0, 0);
gfx_printf(&gfx_con, octopus, 0xFFFFCC00, 0xFFCCCCCC,
@@ -1459,16 +1395,15 @@ ment_t ment_tools[] = {
MDEF_BACK(),
MDEF_CHGLINE(),
MDEF_CAPTION("------ Full --------", 0xFFE6B90A),
MDEF_HANDLER("Backup eMMC RAW GPP", dump_emmc_rawnand),
MDEF_HANDLER("Backup eMMC BOOT0/1", dump_emmc_boot),
MDEF_HANDLER("Dump RAW eMMC", dump_emmc_rawnand),
MDEF_HANDLER("Dump eMMC BOOT", dump_emmc_boot),
MDEF_CHGLINE(),
MDEF_CAPTION("-- GPP Partitions --", 0xFFE6B90A),
MDEF_HANDLER("Backup eMMC SYS", dump_emmc_system),
MDEF_HANDLER("Backup eMMC USER", dump_emmc_user),
MDEF_CAPTION("-- GP Partitions --", 0xFFE6B90A),
MDEF_HANDLER("Dump eMMC SYS", dump_emmc_system),
MDEF_HANDLER("Dump eMMC USER", dump_emmc_user),
MDEF_CHGLINE(),
MDEF_CAPTION("------ Misc -------", 0xFFE6B90A),
MDEF_HANDLER("Dump package1", dump_package1),
MDEF_HANDLER("Fix SD files attributes", fix_sd_attr),
MDEF_CHGLINE(),
MDEF_CAPTION("---- Dangerous ----", 0xFF0000FF),
MDEF_MENU("AutoRCM", &menu_autorcm),
@@ -1495,7 +1430,7 @@ ment_t ment_top[] = {
};
menu_t menu_top = {
ment_top,
"hekate - ipl", 0, 0
"hekate - ipl (CTCaer mod v2.3)", 0, 0
};
extern void pivot_stack(u32 stack_top);
@@ -1517,12 +1452,11 @@ void ipl_main()
//display_color_screen(0xAABBCCDD);
u32 *fb = display_init_framebuffer();
gfx_init_ctxt(&gfx_ctxt, fb, 720, 1280, 768);
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear(&gfx_ctxt, 0xFF1B1B1B);
Kc_HEKATE_LOGO = (u8 *)malloc(36864);
LZ_Uncompress(Kc_HEKATE_LOGOlz, Kc_HEKATE_LOGO, SZ_HEKATE_LOGOLZ);
gfx_con_init(&gfx_con, &gfx_ctxt);
// Enable backlight after initializing gfx
display_backlight(1);
while (1)
tui_do_menu(&gfx_con, &menu_top);

View File

@@ -73,8 +73,8 @@ int max77620_regulator_get_status(u32 id)
const max77620_regulator_t *reg = &_pmic_regulators[id];
if (reg->type == REGULATOR_SD)
return (i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_STATSD) & reg->status_mask) ? 0 : 1;
return (i2c_recv_byte(I2C_5, 0x3C, reg->cfg_addr) & 8) ? 1 : 0;
return i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_STATSD) & reg->status_mask ? 0 : 1;
return i2c_recv_byte(I2C_5, 0x3C, reg->cfg_addr) & 8 ? 1 : 0;
}
int max77620_regulator_config_fps(u32 id)

View File

@@ -102,7 +102,7 @@ void mc_config_carveout()
void mc_enable_ahb_redirect()
{
CLOCK(0x3A4) = (CLOCK(0x3A4) & 0xFFF7FFFF) | 0x80000;
CLOCK(0x3A4) = CLOCK(0x3A4) & 0xFFF7FFFF | 0x80000;
//MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE;
MC(MC_IRAM_BOM) = 0x40000000;
MC(MC_IRAM_TOM) = 0x4003F000;
@@ -119,13 +119,13 @@ void mc_disable_ahb_redirect()
void mc_enable()
{
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | 0x40000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF | 0x40000000;
//Enable MIPI CAL clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFDFFFFFF) | 0x2000000;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFDFFFFFF | 0x2000000;
//Enable MC clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE) | 1;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE | 1;
//Enable EMC DLL clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & 0xFFFFBFFF) | 0x4000;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & 0xFFFFBFFF | 0x4000;
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x2000001; //Clear EMC and MC reset.
sleep(5);

View File

@@ -37,7 +37,7 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
//HACK
for (u32 i = 0; i < 36; i++)
part->name[i] = ent->name[i];
part->name[36] = 0;
part->name[37] = 0;
list_append(gpt, &part->link);
}

View File

@@ -59,7 +59,7 @@ typedef struct _emmc_part_t
u32 lba_start;
u32 lba_end;
u64 attrs;
s8 name[37];
u8 name[37];
link_t link;
} emmc_part_t;

View File

@@ -41,11 +41,6 @@
#define PINMUX_AUX_DMIC3_CLK 0xB4
#define PINMUX_AUX_UART2_TX 0xF4
#define PINMUX_AUX_UART3_TX 0x104
#define PINMUX_AUX_NFC_EN 0x1D0
#define PINMUX_AUX_NFC_INT 0x1D4
#define PINMUX_AUX_LCD_BL_PWM 0x1FC
#define PINMUX_AUX_LCD_BL_EN 0x200
#define PINMUX_AUX_LCD_RST 0x204
#define PINMUX_AUX_GPIO_PE6 0x248
#define PINMUX_AUX_GPIO_PH6 0x250
#define PINMUX_AUX_GPIO_PZ1 0x280

View File

@@ -16,13 +16,20 @@
#include <string.h>
#include "pkg1.h"
#include "arm64.h"
#include "se.h"
#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F)
#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
#define _BL(a, o) 0x94000000 | (((o) - (a)) >> 2) & 0x3FFFFFF
#define _NOP() 0xD503201F
//#define SM_100_ADR 0x40014020
#define SM_100_ADR 0x4002B020
PATCHSET_DEF(_secmon_1_patchset,
//Patch the relocator to be able to run from SM_100_ADR.
{ 0x1E0, _ADRP(0, 0x7C013000 - _PAGEOFF(SM_100_ADR)) },
{ 0x1E0, _ADRP(0, 0x7C013000 - (SM_100_ADR - 0x40)) },
//Patch package2 decryption and signature/hash checks.
{ 0x9F0 + 0xADC, _NOP() }, //Header signature.
{ 0x9F0 + 0xB8C, _NOP() }, //Version.
@@ -38,26 +45,53 @@ PATCHSET_DEF(_secmon_2_patchset,
PATCHSET_DEF(_secmon_3_patchset,
//Patch package2 decryption and signature/hash checks.
{ 0xAC8 + 0xAB4, _NOP() },
{ 0xAC8 + 0xA30, _NOP() }, //Header signature.
{ 0xAC8 + 0xAB4, _NOP() }, //package2 structure.
{ 0xAC8 + 0xAC0, _NOP() }, //Version.
{ 0xAC8 + 0xADC, _NOP() } //Sections SHA2.
);
PATCHSET_DEF(_secmon_4_patchset,
//Patch package2 decryption and signature/hash checks.
{ 0x2300 + 0x5D80, _NOP() }, //package2 structure.
{ 0x2300 + 0x5D8C, _NOP() }, //Version.
{ 0x2300 + 0x5EFC, _NOP() }, //Header signature.
{ 0xAC8 + 0xA2C, _NOP() } //Sections SHA2.
{ 0x1218 + 0x6E68, _NOP() }, //Header signature.
{ 0x1218 + 0x6E74, _NOP() }, //Version.
{ 0x1218 + 0x6FE4, _NOP() }, //Sections SHA2.
{ 0x1218 + 0x2DC, _NOP() } //Unknown.
);
PATCHSET_DEF(_secmon_5_patchset,
//Patch package2 decryption and signature/hash checks.
{ 0xDA8 + 0x9D8 , _NOP() }, //package2 structure.
{ 0xDA8 + 0x9E4 , _NOP() }, //Version.
{ 0xDA8 + 0xC9C , _NOP() }, //Header signature.
{ 0xDA8 + 0x1038 , _NOP() } //Sections SHA2.
{ 0x12b0 + 0x4d0, _NOP() },
{ 0x12b0 + 0x4dc, _NOP() },
{ 0x12b0 + 0x794, _NOP() },
{ 0x12b0 + 0xb30, _NOP() }//,
//{ 0x12b0 + 0xa18 , _NOP() } // BootConfig Retail Check
);
// Include kernel patches here, so we can utilize pkg1 id
PATCHSET_DEF(_kernel_1_patchset,
{ 0x3764C, _NOP() }, // Disable SVC verifications
{ 0x44074, _MOVZX(8, 1, 0) } // Enable Debug Patch
);
PATCHSET_DEF(_kernel_2_patchset,
{ 0x54834, _NOP() }, // Disable SVC verifications
{ 0x6086C, _MOVZX(8, 1, 0) } // Enable Debug Patch
);
PATCHSET_DEF(_kernel_3_patchset,
{ 0x3BD24, _NOP() }, // Disable SVC verifications
{ 0x483FC, _MOVZX(8, 1, 0) } // Enable Debug Patch
);
PATCHSET_DEF(_kernel_4_patchset,
{ 0x41EB4, _NOP() }, // Disable SVC verifications
{ 0x4EBFC, _MOVZX(8, 1, 0) } // Enable Debug Patch
);
PATCHSET_DEF(_kernel_5_patchset,
{ 0x45E6C, _NOP() }, // Disable SVC verifications
{ 0x5513C, _MOVZX(8, 1, 0) } // Enable Debug Patch
);
/*
@@ -72,13 +106,13 @@ PATCHSET_DEF(_secmon_5_patchset,
*/
static const pkg1_id_t _pkg1_ids[] = {
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, 1, _secmon_1_patchset }, //1.0.0 (Patched relocator)
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_2_patchset }, //2.0.0 - 2.3.0
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_3_patchset }, //3.0.0
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_3_patchset }, //3.0.1 - 3.0.2
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, 0, _secmon_4_patchset }, //4.0.0 - 4.1.0
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, 0, _secmon_5_patchset }, //5.0.0 - 5.1.0
{ NULL } //End.
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, 1, _secmon_1_patchset, _kernel_1_patchset }, //1.0.0 (Patched relocator)
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_2_patchset, _kernel_2_patchset }, //2.0.0 - 2.3.0
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_3_patchset, _kernel_3_patchset }, //3.0.0
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, 1, _secmon_3_patchset, _kernel_3_patchset }, //3.0.1 - 3.0.2
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, 0, _secmon_4_patchset, _kernel_4_patchset }, //4.0.0 - 4.1.0
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, 0, _secmon_5_patchset, _kernel_5_patchset }, //5.0.0 - 5.0.2
{ NULL, 0, 0, 0, 0 } //End.
};
@@ -98,7 +132,7 @@ void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1)
se_aes_crypt_ctr(11, pkg11 + 0x20, pkg11_size, pkg11 + 0x20, pkg11_size, pkg11 + 0x10);
}
void pkg1_unpack(void *warmboot_dst, void *secmon_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1)
void pkg1_unpack(void *warmboot_dst, void *secmon_dst, const pkg1_id_t *id, u8 *pkg1)
{
pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + id->pkg11_off + 0x20);
@@ -110,8 +144,6 @@ void pkg1_unpack(void *warmboot_dst, void *secmon_dst, void *ldr_dst, const pkg1
{
if (id->sec_map[i] == 0 && warmboot_dst)
memcpy(warmboot_dst, pdata, sec_size[id->sec_map[i]]);
else if (id->sec_map[i] == 1 && ldr_dst)
memcpy(ldr_dst, pdata, sec_size[id->sec_map[i]]);
else if (id->sec_map[i] == 2 && secmon_dst)
memcpy(secmon_dst, pdata, sec_size[id->sec_map[i]]);
pdata += sec_size[id->sec_map[i]];

View File

@@ -25,6 +25,12 @@
{ 0xFFFFFFFF, 0xFFFFFFFF } \
}
typedef struct _patch_t
{
u32 off;
u32 val;
} patch_t;
typedef struct _pkg1_id_t
{
const char *id;
@@ -36,6 +42,7 @@ typedef struct _pkg1_id_t
u32 warmboot_base;
int set_warmboot;
patch_t *secmon_patchset;
patch_t *kernel_patchset;
} pkg1_id_t;
typedef struct _pk11_hdr_t
@@ -52,6 +59,6 @@ typedef struct _pk11_hdr_t
const pkg1_id_t *pkg1_identify(u8 *pkg1);
void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1);
void pkg1_unpack(void *warmboot_dst, void *secmon_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1);
void pkg1_unpack(void *warmboot_dst, void *secmon_dst, const pkg1_id_t *id, u8 *pkg1);
#endif

View File

@@ -16,7 +16,6 @@
#include <string.h>
#include "pkg2.h"
#include "arm64.h"
#include "heap.h"
#include "se.h"
@@ -26,55 +25,6 @@ extern gfx_con_t gfx_con;
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)*/
#define DPRINTF(...)
// Include kernel patches here, so we can utilize pkg1 id
PATCHSET_DEF(_kernel_1_patchset,
{ 0x3764C, _NOP() }, // Disable SVC verifications
{ 0x44074, _MOVZX(8, 1, 0) } // Enable Debug Patch
);
PATCHSET_DEF(_kernel_2_patchset,
{ 0x54834, _NOP() }, // Disable SVC verifications
{ 0x6086C, _MOVZX(8, 1, 0) } // Enable Debug Patch
);
PATCHSET_DEF(_kernel_3_patchset,
{ 0x3BD24, _NOP() }, // Disable SVC verifications
{ 0x483FC, _MOVZX(8, 1, 0) } // Enable Debug Patch
);
PATCHSET_DEF(_kernel_302_patchset,
{ 0x3BD24, _NOP() }, // Disable SVC verifications
{ 0x48414, _MOVZX(8, 1, 0) } // Enable Debug Patch
);
PATCHSET_DEF(_kernel_4_patchset,
{ 0x41EB4, _NOP() }, // Disable SVC verifications
{ 0x4EBFC, _MOVZX(8, 1, 0) } // Enable Debug Patch
);
PATCHSET_DEF(_kernel_5_patchset,
{ 0x45E6C, _NOP() }, // Disable SVC verifications
{ 0x5513C, _MOVZX(8, 1, 0) } // Enable Debug Patch
);
static const pkg2_kernel_id_t _pkg2_kernel_ids[] = {
{ 0x427f2647, _kernel_1_patchset }, //1.0.0
{ 0xae19cf1b, _kernel_2_patchset }, //2.0.0 - 2.3.0
{ 0x73c9e274, _kernel_3_patchset }, //3.0.0 - 3.0.1
{ 0xe0e8cdc4, _kernel_302_patchset }, //3.0.2
{ 0x485d0157, _kernel_4_patchset }, //4.0.0 - 4.1.0
{ 0xf3c363f2, _kernel_5_patchset }, //5.0.0 - 5.1.0
{ 0, 0 } //End.
};
const pkg2_kernel_id_t *pkg2_identify(u32 id)
{
for (u32 i = 0; _pkg2_kernel_ids[i].crc32c_id; i++)
if (id == _pkg2_kernel_ids[i].crc32c_id)
return &_pkg2_kernel_ids[i];
return NULL;
}
static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
{
u32 size = sizeof(pkg2_kip1_t);

View File

@@ -27,12 +27,6 @@
#define INI1_MAGIC 0x31494E49
#define PATCHSET_DEF(name, ...) \
patch_t name[] = { \
__VA_ARGS__, \
{ 0xFFFFFFFF, 0xFFFFFFFF } \
}
typedef struct _pkg2_hdr_t
{
u8 ctr[0x10];
@@ -88,19 +82,12 @@ typedef struct _pkg2_kip1_info_t
link_t link;
} pkg2_kip1_info_t;
typedef struct _pkg2_kernel_id_t
{
u32 crc32c_id;
patch_t *kernel_patchset;
} pkg2_kernel_id_t;
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2);
int pkg2_has_kip(link_t *info, u64 tid);
void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1);
void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1);
void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1);
const pkg2_kernel_id_t *pkg2_identify(u32 id);
pkg2_hdr_t *pkg2_decrypt(void *data);
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info);

View File

@@ -174,7 +174,8 @@ static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 nu
else
retries--;
sleep(100000);
sleep(500000);
} while (retries);
return 0;
@@ -307,7 +308,7 @@ static void _mmc_storage_parse_csd(sdmmc_storage_t *storage)
storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);
}
static void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf)
static int _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf)
{
storage->ext_csd.rev = buf[EXT_CSD_REV];
storage->ext_csd.ext_struct = buf[EXT_CSD_STRUCTURE];
@@ -433,9 +434,9 @@ static int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type
return _mmc_storage_enable_HS400(storage);
if (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 ||
(sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_4
sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_4
&& card_type & EXT_CSD_CARD_TYPE_HS200_1_8V
&& (type == 4 || type == 3)))
&& (type == 4 || type == 3))
return _mmc_storage_enable_HS200(storage);
out:;
@@ -767,12 +768,12 @@ int _sd_storage_enable_highspeed(sdmmc_storage_t *storage, u32 hs_type, u8 *buf)
if (type_out != hs_type)
return 0;
if ((((u16)buf[0] << 8) | buf[1]) < 0x320)
if (((u16)buf[0] << 8) | buf[1] < 0x320)
{
if (!_sd_storage_switch(storage, buf, 1, hs_type))
return 0;
if (type_out != (buf[16] & 0xF))
if (type_out != buf[16] & 0xF)
return 0;
}
@@ -849,7 +850,7 @@ static void _sd_storage_parse_ssr(sdmmc_storage_t *storage)
raw_ssr2[1] = *(u32 *)&storage->raw_ssr[20];
raw_ssr2[0] = *(u32 *)&storage->raw_ssr[16];
storage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1;
storage->ssr.bus_width = unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4 ? 4 : 1;
switch(unstuff_bits(raw_ssr1, 440 - 384, 8))
{
case 0:

View File

@@ -129,7 +129,7 @@ static int _sdmmc_config_ven_ceata_clk(sdmmc_t *sdmmc, u32 id)
static const u32 tap_values[] = { 4, 0, 3, 0 };
tap_val = tap_values[sdmmc->id];
}
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16);
sdmmc->regs->venclkctl = sdmmc->regs->venclkctl & 0xFF00FFFF | (tap_val << 16);
return 1;
}
@@ -624,7 +624,7 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)
break;
}
sdmmc->regs->autocalcfg = (((sdmmc->regs->autocalcfg & 0xFFFF80FF) | (off_pd << 8)) >> 7 << 7) | off_pu;
sdmmc->regs->autocalcfg = ((sdmmc->regs->autocalcfg & 0xFFFF80FF | (off_pd << 8)) >> 7 << 7) | off_pu;
return 1;
}

View File

@@ -64,7 +64,7 @@ static void _sdram_config(const sdram_params_t *params)
sleep(10);
break_nosleep:
CLOCK(0x19C) = ((params->mc_emem_arb_misc0 >> 11) & 0x10000) | (params->emc_clock_source & 0xFFFEFFFF);
CLOCK(0x19C) = (params->mc_emem_arb_misc0 >> 11) & 0x10000 | params->emc_clock_source & 0xFFFEFFFF;
if (params->emc_clock_source_dll)
CLOCK(0x664) = params->emc_clock_source_dll;
if (params->clear_clock2_mc1)
@@ -97,7 +97,7 @@ break_nosleep:
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
EMC(EMC_PMACRO_BRICK_MAPPING_1) = params->emc_pmacro_brick_mapping1;
EMC(EMC_PMACRO_BRICK_MAPPING_2) = params->emc_pmacro_brick_mapping2;
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1120112) | 0x1EED1EED;
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1 & 0x1120112 | 0x1EED1EED;
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
EMC(EMC_SWIZZLE_RANK0_BYTE0) = params->emc_swizzle_rank0_byte0;
@@ -142,7 +142,7 @@ break_nosleep:
EMC(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1;
EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF) | 0x1E401E40;
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF | 0x1E401E40;
EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;
EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F;
@@ -232,7 +232,7 @@ break_nosleep:
EMC(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0;
EMC(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1;
EMC(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2;
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = (params->emc_pmacro_common_pad_tx_ctrl & 1) | 0xE;
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl & 1 | 0xE;
if (params->emc_bct_spare4)
*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;
EMC(EMC_TIMING_CONTROL) = 1;
@@ -386,7 +386,7 @@ break_nosleep:
EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
EMC(EMC_CFG) = params->emc_cfg & 0xE | 0x3C00000;
if (params->boot_rom_patch_control & 0x80000000)
{
*(vu32 *)(4 * (params->boot_rom_patch_control + 0x1C000000)) = params->boot_rom_patch_data;
@@ -481,7 +481,7 @@ break_nosleep:
EMC(EMC_TIMING_CONTROL) = 1;
EMC(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;
SYSREG(AHB_ARBITRATION_XBAR_CTRL) = (SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF) | ((params->ahb_arbitration_xbar_ctrl_meminit_done & 0xFFFF) << 16);
SYSREG(AHB_ARBITRATION_XBAR_CTRL) = SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF | ((params->ahb_arbitration_xbar_ctrl_meminit_done & 0xFFFF) << 16);
MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;
MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;

View File

@@ -44,9 +44,8 @@ void sdram_lp0_save_params(const void *params)
/* 32 bits version c macro */
#define c32(value, pmcreg) pmc->pmcreg = value
//TODO: pkg1.1 (1.X - 3.X) reads them from MC.
//Patch carveout parameters.
/*sdram->McGeneralizedCarveout1Bom = 0;
//TODO: pkg1.1 reads them from MC.
sdram->McGeneralizedCarveout1Bom = 0;
sdram->McGeneralizedCarveout1BomHi = 0;
sdram->McGeneralizedCarveout1Size128kb = 0;
sdram->McGeneralizedCarveout1Access0 = 0;
@@ -115,28 +114,7 @@ void sdram_lp0_save_params(const void *params)
sdram->McGeneralizedCarveout5ForceInternalAccess2 = 0;
sdram->McGeneralizedCarveout5ForceInternalAccess3 = 0;
sdram->McGeneralizedCarveout5ForceInternalAccess4 = 0;
sdram->McGeneralizedCarveout5Cfg0 = 0x8F;*/
//TODO: this is 4.X+ behaviour which seems to work fine for < 4.X.
//Patch carveout parameters.
sdram->McGeneralizedCarveout1Cfg0 = 0;
sdram->McGeneralizedCarveout2Cfg0 = 0;
sdram->McGeneralizedCarveout3Cfg0 = 0;
sdram->McGeneralizedCarveout4Cfg0 = 0;
sdram->McGeneralizedCarveout5Cfg0 = 0;
//Patch SDRAM parameters.
u32 t0 = sdram->EmcSwizzleRank0Byte0 << 5 >> 29 > sdram->EmcSwizzleRank0Byte0 << 1 >> 29;
u32 t1 = (t0 & 0xFFFFFFEF) | ((sdram->EmcSwizzleRank1Byte0 << 5 >> 29 > sdram->EmcSwizzleRank1Byte0 << 1 >> 29) << 4);
u32 t2 = (t1 & 0xFFFFFFFD) | ((sdram->EmcSwizzleRank0Byte1 << 5 >> 29 > sdram->EmcSwizzleRank0Byte1 << 1 >> 29) << 1);
u32 t3 = (t2 & 0xFFFFFFDF) | ((sdram->EmcSwizzleRank1Byte1 << 5 >> 29 > sdram->EmcSwizzleRank1Byte1 << 1 >> 29) << 5);
u32 t4 = (t3 & 0xFFFFFFFB) | ((sdram->EmcSwizzleRank0Byte2 << 5 >> 29 > sdram->EmcSwizzleRank0Byte2 << 1 >> 29) << 2);
u32 t5 = (t4 & 0xFFFFFFBF) | ((sdram->EmcSwizzleRank1Byte2 << 5 >> 29 > sdram->EmcSwizzleRank1Byte2 << 1 >> 29) << 6);
u32 t6 = (t5 & 0xFFFFFFF7) | ((sdram->EmcSwizzleRank0Byte3 << 5 >> 29 > sdram->EmcSwizzleRank0Byte3 << 1 >> 29) << 3);
u32 t7 = (t6 & 0xFFFFFF7F) | ((sdram->EmcSwizzleRank1Byte3 << 5 >> 29 > sdram->EmcSwizzleRank1Byte3 << 1 >> 29) << 7);
sdram->SwizzleRankByteEncode = t7;
sdram->EmcBctSpare2 = 0x40000DD8;
sdram->EmcBctSpare3 = t7;
sdram->McGeneralizedCarveout5Cfg0 = 0x8F;
s(EmcClockSource, 7:0, scratch6, 15:8);
s(EmcClockSourceDll, 7:0, scratch6, 23:16);
@@ -808,8 +786,9 @@ void sdram_lp0_save_params(const void *params)
s32(EmcBctSpare6, scratch40);
s32(EmcBctSpare5, scratch42);
s32(EmcBctSpare4, scratch44);
s32(EmcBctSpare3, scratch45);
s32(EmcBctSpare2, scratch46);
s32(SwizzleRankByteEncode, scratch45);
//s32(EmcBctSpare2, scratch46);
pmc->scratch46 = 0x40000DD8;
s32(EmcBctSpare1, scratch47);
s32(EmcBctSpare0, scratch48);
s32(EmcBctSpare9, scratch50);

View File

@@ -124,7 +124,7 @@ static void _se_aes_ctr_set(void *ctr)
void se_rsa_acc_ctrl(u32 rs, u32 flags)
{
if (flags & 0x7F)
SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = ((flags >> 4) & 4 | flags & 3) ^ 7;
if (flags & 0x80)
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs);
}

View File

@@ -17,6 +17,8 @@
#include "tui.h"
#include "btn.h"
extern u8 *Kc_HEKATE_LOGO;
void tui_pbar(gfx_con_t *con, int x, int y, u32 val, u32 fgcol, u32 bgcol)
{
u32 cx, cy;
@@ -27,9 +29,9 @@ void tui_pbar(gfx_con_t *con, int x, int y, u32 val, u32 fgcol, u32 bgcol)
gfx_printf(con, "%k[%3d%%]%k", fgcol, val, 0xFFCCCCCC);
x += 7 * 8;
x += 7 * con->fntsz;
for (int i = 0; i < 6; i++)
for (int i = 0; i < con->fontmult * 6; i++)
{
gfx_line(con->gfx_ctxt, x, y + i + 1, x + 3 * val, y + i + 1, fgcol);
gfx_line(con->gfx_ctxt, x + 3 * val, y + i + 1, x + 3 * 100, y + i + 1, bgcol);
@@ -40,9 +42,11 @@ void tui_pbar(gfx_con_t *con, int x, int y, u32 val, u32 fgcol, u32 bgcol)
void *tui_do_menu(gfx_con_t *con, menu_t *menu)
{
int idx = 0, prev_idx = 0, cnt = 0x7FFFFFFF;
int idx = 0, cnt;
int prev_idx = 0;
gfx_clear_grey(con->gfx_ctxt, 0x1B);
gfx_clear(con->gfx_ctxt, 0xFF1B1B1B);
gfx_set_logo(con->gfx_ctxt, Kc_HEKATE_LOGO);
while (1)
{
@@ -50,12 +54,12 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu)
gfx_con_setpos(con, menu->x, menu->y);
gfx_printf(con, "[%s]\n\n", menu->caption);
// Skip caption or seperator lines selection.
// Skip caption or seperator lines selection
while (menu->ents[idx].type == MENT_CAPTION ||
menu->ents[idx].type == MENT_CHGLINE)
{
if (prev_idx <= idx || (!idx && prev_idx == cnt - 1))
{
if (prev_idx <= idx || (!idx && prev_idx == cnt - 1))
{
idx++;
if (idx > (cnt - 1))
{
@@ -75,16 +79,16 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu)
}
prev_idx = idx;
//Draw the menu.
// Draw the menu
for (cnt = 0; menu->ents[cnt].type != MENT_END; cnt++)
{
if (cnt == idx)
gfx_con_setcol(con, 0xFF1B1B1B, 1, 0xFFCCCCCC);
else
gfx_con_setcol(con, 0xFFCCCCCC, 1, 0xFF1B1B1B);
if (menu->ents[cnt].type == MENT_CAPTION)
if (cnt != idx && menu->ents[cnt].type == MENT_CAPTION)
gfx_printf(con, "%k %s", menu->ents[cnt].color, menu->ents[cnt].caption);
else if (menu->ents[cnt].type != MENT_CHGLINE)
else
gfx_printf(con, " %s", menu->ents[cnt].caption);
if(menu->ents[cnt].type == MENT_MENU)
gfx_printf(con, "%k...", 0xFFEE9900);
@@ -123,7 +127,9 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu)
default:
break;
}
gfx_clear_grey(con->gfx_ctxt, 0x1B);
gfx_con_setfontsz(con, 16);
gfx_clear(con->gfx_ctxt, 0xFF1B1B1B);
gfx_set_logo(con->gfx_ctxt, Kc_HEKATE_LOGO);
}
}

View File

@@ -26,10 +26,6 @@
#define OFFSET_OF(t, m) ((u32)&((t *)NULL)->m)
#define CONTAINER_OF(mp, t, mn) ((t *)((u32)mp - OFFSET_OF(t, mn)))
typedef char s8;
typedef short s16;
typedef int s32;
typedef long long int s64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
@@ -38,10 +34,4 @@ typedef volatile unsigned char vu8;
typedef volatile unsigned short vu16;
typedef volatile unsigned int vu32;
typedef struct _patch_t
{
u32 off;
u32 val;
} patch_t;
#endif

View File

@@ -35,16 +35,3 @@ void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops)
base[ops[i].off] = ops[i].val;
}
#define CRC32C_POLY 0x82F63B78
u32 crc32c(const void *buf, u32 len)
{
const u8 *cbuf = (const u8 *)buf;
u32 crc = 0xFFFFFFFF;
while (len--)
{
crc ^= *cbuf++;
for (int i = 0; i < 8; i++)
crc = crc & 1 ? (crc >> 1) ^ CRC32C_POLY : crc >> 1;
}
return ~crc;
}

View File

@@ -28,6 +28,5 @@ typedef struct _cfg_op_t
u32 get_tmr();
void sleep(u32 ticks);
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
u32 crc32c(const void *buf, u32 len);
#endif