Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
867977e416 | ||
|
|
5f39808923 | ||
|
|
b842342790 | ||
|
|
5ec3efbff6 | ||
|
|
8cf3b62443 | ||
|
|
7c90abcb06 | ||
|
|
5ae9f5655a |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,3 @@
|
||||
.vs
|
||||
.vscode
|
||||
build/*
|
||||
output/*
|
||||
build_ipl/*
|
||||
|
||||
62
Makefile
62
Makefile
@@ -2,20 +2,16 @@ 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 := hekate
|
||||
BLVERSION_MAJOR := 4
|
||||
BLVERSION_MINOR := 2
|
||||
BUILD := build
|
||||
OUTPUT := output
|
||||
SOURCEDIR = bootloader
|
||||
VPATH = $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
|
||||
|
||||
OBJS = $(addprefix $(BUILD)/$(TARGET)/, \
|
||||
TARGET := ipl
|
||||
BUILD := build_ipl
|
||||
SOURCEDIR := ipl
|
||||
OBJS = $(addprefix $(BUILD)/, \
|
||||
start.o \
|
||||
main.o \
|
||||
config.o \
|
||||
btn.o \
|
||||
clock.o \
|
||||
cluster.o \
|
||||
@@ -25,14 +21,14 @@ OBJS = $(addprefix $(BUILD)/$(TARGET)/, \
|
||||
hos.o \
|
||||
i2c.o \
|
||||
kfuse.o \
|
||||
bq24193.o \
|
||||
lz.o \
|
||||
max7762x.o \
|
||||
max17050.o \
|
||||
mc.o \
|
||||
nx_emmc.o \
|
||||
sdmmc.o \
|
||||
sdmmc_driver.o \
|
||||
sdram.o \
|
||||
sdram_lp0.o \
|
||||
tui.o \
|
||||
util.o \
|
||||
di.o \
|
||||
@@ -43,52 +39,32 @@ OBJS = $(addprefix $(BUILD)/$(TARGET)/, \
|
||||
se.o \
|
||||
tsec.o \
|
||||
uart.o \
|
||||
dirlist.o \
|
||||
ini.o \
|
||||
ianos.o \
|
||||
)
|
||||
|
||||
OBJS += $(addprefix $(BUILD)/$(TARGET)/, \
|
||||
lz.o blz.o \
|
||||
diskio.o ff.o ffunicode.o ffsystem.o \
|
||||
elfload.o elfreloc_arm.o \
|
||||
)
|
||||
OBJS += $(addprefix $(BUILD)/, diskio.o ff.o ffunicode.o)
|
||||
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
||||
CUSTOMDEFINES := -DBLVERSIONMJ=$(BLVERSION_MAJOR) -DBLVERSIONMN=$(BLVERSION_MINOR)
|
||||
CUSTOMDEFINES += -DMENU_LOGO_ENABLE #-DDEBUG
|
||||
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall $(CUSTOMDEFINES)
|
||||
CFLAGS = $(ARCH) -Os -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11# -Wall
|
||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections
|
||||
|
||||
MODULEDIRS := $(wildcard modules/*)
|
||||
|
||||
.PHONY: all clean $(MODULEDIRS)
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(TARGET).bin
|
||||
@echo -n "Payload size is "
|
||||
@wc -c < $(OUTPUT)/$(TARGET).bin
|
||||
@echo "Max size is 126296 Bytes."
|
||||
|
||||
clean:
|
||||
@rm -rf $(OBJS)
|
||||
@rm -rf $(BUILD)
|
||||
@rm -rf $(OUTPUT)
|
||||
@rm -rf $(TARGET).bin
|
||||
|
||||
$(MODULEDIRS):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
$(TARGET).bin: $(BUILD)/$(TARGET).elf
|
||||
$(OBJCOPY) -S -O binary $< $@
|
||||
|
||||
$(TARGET).bin: $(BUILD)/$(TARGET)/$(TARGET).elf $(MODULEDIRS)
|
||||
$(OBJCOPY) -S -O binary $< $(OUTPUT)/$@
|
||||
@printf ICTC$(BLVERSION_MAJOR)$(BLVERSION_MINOR) >> $(OUTPUT)/$@
|
||||
$(BUILD)/$(TARGET).elf: $(OBJS)
|
||||
$(CC) $(LDFLAGS) -T ipl/link.ld $^ -o $@
|
||||
|
||||
$(BUILD)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
||||
$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
||||
|
||||
$(BUILD)/$(TARGET)/%.o: %.c
|
||||
$(BUILD)/%.o: $(SOURCEDIR)/%.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(BUILD)/$(TARGET)/%.o: %.S
|
||||
$(BUILD)/%.o: $(SOURCEDIR)/%.S
|
||||
@mkdir -p "$(BUILD)"
|
||||
@mkdir -p "$(BUILD)/$(TARGET)"
|
||||
@mkdir -p "$(OUTPUT)"
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
100
README.md
100
README.md
@@ -1,96 +1,16 @@
|
||||
# hekate - CTCaer mod
|
||||
# hekate
|
||||
|
||||

|
||||

|
||||
|
||||
Nintendo Switch bootloader, firmware patcher, and more.
|
||||
|
||||
Custom Nintendo Switch bootloader, firmware patcher, and more.
|
||||
## ipl config
|
||||
|
||||
The ipl can be configured via 'hekate_ipl.ini' (if it is present on the SD card). Each ini section represents a boot entry, except for the special section 'config' that controls the global configuration.
|
||||
|
||||
## Bootloader folders and files
|
||||
Possible key/value combinations:
|
||||
|
||||
| Folder/File | Description |
|
||||
| -------------------- | --------------------------------------------------------------------- |
|
||||
| bootloader | Main folder. |
|
||||
| \|__ bootlogo.bmp | It is used when custom is on and no logopath found. Can be skipped. |
|
||||
| \|__ hekate_ipl.ini | Main bootloader configuration and boot entries. |
|
||||
| \|__ update.bin | If newer, it is loaded at boot. For modchips. Can be skipped. |
|
||||
| bootloader/ini/ | For individual inis. 'More configs...' menu. Autoboot is supported. |
|
||||
| bootloader/sys/ | For system modules. |
|
||||
| \|__ libsys_lp0.bso | LP0 (sleep mode) module. Important! |
|
||||
| bootloader/payloads/ | For payloads. 'Payloads...' menu. Autoboot only supported by including them into an ini. All CFW bootloaders, tools, Linux payloads are supported. |
|
||||
| bootloader/libtools/ | Future reserved |
|
||||
|
||||
|
||||
## Bootloader configuration
|
||||
|
||||
The bootloader can be configured via 'bootloader/hekate_ipl.ini' (if it is present on the SD card). Each ini section represents a boot entry, except for the special section 'config' that controls the global configuration.
|
||||
|
||||
|
||||
There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Caption, "**#**": Comment, "*newline*": .ini cosmetic newline.
|
||||
|
||||
|
||||
### Configuration keys/values when boot entry is **config**:
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| autoboot=0 | 0: Disable, #: Boot entry number to auto boot. |
|
||||
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. |
|
||||
| customlogo=0 | 0: Use default hekate bootlogo, 1: Use bootlogo.bmp. |
|
||||
| verification=2 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and not 100% reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||
| autohosoff=1 | If woke up from HOS via an rtc alarm, power off completely.|
|
||||
| backlight=100 | Screen backlight level. 0-255. |
|
||||
|
||||
|
||||
### Possible boot entry key/value combinations:
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| logopath={SD path} | If global customlogo is 1 and logopath empty, bootlogo.bmp will be used. If logopath exists, it will load the specified bitmap. |
|
||||
| warmboot={SD path} | Replaces the warmboot binary |
|
||||
| secmon={SD path} | Replaces the security monitor binary |
|
||||
| kernel={SD path} | Replaces the kernel binary |
|
||||
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
||||
| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||
| kip1patch=patchname| Enables a kip1 patch. Specify with multiple lines and/or as CSV. Implemented patches right now are nosigchk,nogc |
|
||||
| fullsvcperm=1 | Disables SVC verification (full services permission) |
|
||||
| debugmode=1 | Enables Debug mode |
|
||||
| atmosphere=1 | Enables Atmosphère patching |
|
||||
| payload={SD path} | Payload launching. Tools, Linux, CFW bootloaders, etc. |
|
||||
|
||||
|
||||
You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
|
||||
If the main .ini is not found, it is created on the first hekate boot.
|
||||
|
||||
|
||||
```
|
||||
hekate (C) 2018 naehrwert, st4rk
|
||||
CTCaer mod (C) 2018 CTCaer.
|
||||
|
||||
Thanks to: derrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8.
|
||||
Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute.
|
||||
|
||||
Open source and free packages used:
|
||||
- FatFs R0.13a, Copyright (C) 2017, ChaN
|
||||
- bcl-1.2.0, Copyright (C) 2003-2006, Marcus Geelnard
|
||||
- Atmosphère (SE sha256, prc id kernel patches), Copyright (C) 2018, Atmosphère-NX
|
||||
- elfload, Copyright (C) 2014 Owen Shepherd, Copyright (C) 2018 M4xw
|
||||
|
||||
___
|
||||
.-' `'.
|
||||
/ \
|
||||
| ;
|
||||
| | ___.--,
|
||||
_.._ |0) = (0) | _.---'`__.-( (_.
|
||||
__.--'`_.. '.__.\ '--. \_.-' ,.--'` `""`
|
||||
( ,.--'` ',__ /./; ;, '.__.'` __
|
||||
_`) ) .---.__.' / | |\ \__..--"" """--.,_
|
||||
`---' .'.''-._.-'`_./ /\ '. \ _.--''````'''--._`-.__.'
|
||||
| | .' _.-' | | \ \ '. `----`
|
||||
\ \/ .' \ \ '. '-._)
|
||||
\/ / \ \ `=.__`'-.
|
||||
/ /\ `) ) / / `"".`\
|
||||
, _.-'.'\ \ / / ( ( / /
|
||||
`--'` ) ) .-'.' '.'. | (
|
||||
(/` ( (` ) ) '-; [switchbrew]
|
||||
```
|
||||
- warmboot={SD path}
|
||||
- secmon={SD path}
|
||||
- kernel={SD path}
|
||||
- kip1={SD path}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# hekate - Bootlogo
|
||||
|
||||
The bootlogo can be any size with a maximum of 720 x 1280.
|
||||
|
||||
When it's smaller than 720 x 1280, it is automatically centered and the background takes the color of the first pixel.
|
||||
|
||||
When saving a landscape bootlogo, it should be rotated 90 degrees counterclockwise.
|
||||
|
||||
Lastly, the supported format is 32-bit (ARGB) BMP. Classic 24-bit (RGB) BMPs are not supported for performance reasons.
|
||||
|
||||
|
||||
## How to configure
|
||||
|
||||
If the custom logo option is enabled, it will try to load /bootlogo.bmp. If this is not found, the default hekate's logo will be used.
|
||||
|
||||
If a boot entry specifies a custom logo path, this is one will be loaded. Again if this is not found, bootlogo.bmp will be loaded and if that fails, hekate's built-in will be used.
|
||||
@@ -1,699 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../utils/btn.h"
|
||||
#include "config.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "ini.h"
|
||||
#include "../utils/list.h"
|
||||
#include "../gfx/tui.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../gfx/gfx.h"
|
||||
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
//TODO: Create more macros (info, header, debug, etc) with different colors and utilize them for consistency.
|
||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
||||
|
||||
extern hekate_config h_cfg;
|
||||
extern int sd_mount();
|
||||
extern int sd_unmount();
|
||||
|
||||
void set_default_configuration()
|
||||
{
|
||||
h_cfg.autoboot = 0;
|
||||
h_cfg.autoboot_list = 0;
|
||||
h_cfg.bootwait = 3;
|
||||
h_cfg.customlogo = 0;
|
||||
h_cfg.verification = 2;
|
||||
h_cfg.se_keygen_done = 0;
|
||||
h_cfg.sbar_time_keeping = 0;
|
||||
h_cfg.backlight = 100;
|
||||
h_cfg.autohosoff = 1;
|
||||
h_cfg.errors = 0;
|
||||
}
|
||||
|
||||
int create_config_entry()
|
||||
{
|
||||
if (!sd_mount())
|
||||
return 1;
|
||||
|
||||
char lbuf[16];
|
||||
FIL fp;
|
||||
bool mainIniFound = false;
|
||||
|
||||
LIST_INIT(ini_sections);
|
||||
|
||||
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false))
|
||||
mainIniFound = true;
|
||||
else
|
||||
{
|
||||
u8 res = f_open(&fp, "bootloader/hekate_ipl.ini", FA_READ);
|
||||
if (res == FR_NO_FILE || res == FR_NO_PATH)
|
||||
{
|
||||
f_mkdir("bootloader");
|
||||
f_mkdir("bootloader/ini");
|
||||
f_mkdir("bootloader/payloads");
|
||||
f_mkdir("bootloader/sys");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!res)
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (f_open(&fp, "bootloader/hekate_ipl.ini", FA_WRITE | FA_CREATE_ALWAYS) != FR_OK)
|
||||
return 1;
|
||||
// Add config entry.
|
||||
f_puts("[config]\nautoboot=", &fp);
|
||||
itoa(h_cfg.autoboot, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nautoboot_list=", &fp);
|
||||
itoa(h_cfg.autoboot_list, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nbootwait=", &fp);
|
||||
itoa(h_cfg.bootwait, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\ncustomlogo=", &fp);
|
||||
itoa(h_cfg.customlogo, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nverification=", &fp);
|
||||
itoa(h_cfg.verification, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nbacklight=", &fp);
|
||||
itoa(h_cfg.backlight, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nautohosoff=", &fp);
|
||||
itoa(h_cfg.autohosoff, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\n", &fp);
|
||||
|
||||
if (mainIniFound)
|
||||
{
|
||||
// Re-construct existing entries.
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
||||
{
|
||||
if (!strcmp(ini_sec->name, "config"))
|
||||
continue;
|
||||
|
||||
switch (ini_sec->type)
|
||||
{
|
||||
case INI_CHOICE: // Re-construct Boot entry [ ].
|
||||
f_puts("[", &fp);
|
||||
f_puts(ini_sec->name, &fp);
|
||||
f_puts("]\n", &fp);
|
||||
// Re-construct boot entry's config.
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
|
||||
{
|
||||
f_puts(kv->key, &fp);
|
||||
f_puts("=", &fp);
|
||||
f_puts(kv->val, &fp);
|
||||
f_puts("\n", &fp);
|
||||
}
|
||||
break;
|
||||
case INI_CAPTION: // Re-construct caption entry { }.
|
||||
f_puts("{", &fp);
|
||||
f_puts(ini_sec->name, &fp);
|
||||
f_puts("}\n", &fp);
|
||||
break;
|
||||
case INI_NEWLINE: // Re-construct cosmetic newline \n.
|
||||
f_puts("\n", &fp);
|
||||
break;
|
||||
case INI_COMMENT: // Re-construct comment entry #.
|
||||
f_puts("#", &fp);
|
||||
f_puts(ini_sec->name, &fp);
|
||||
f_puts("\n", &fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f_close(&fp);
|
||||
sd_unmount();
|
||||
|
||||
if (mainIniFound)
|
||||
ini_free(&ini_sections);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _config_autoboot_list()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
u32 *temp_autoboot = NULL;
|
||||
|
||||
LIST_INIT(ini_sections);
|
||||
|
||||
u8 max_entries = 30;
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3));
|
||||
u32 *boot_values = (u32 *)malloc(sizeof(u32) * max_entries);
|
||||
char *boot_text = (char *)malloc(512 * max_entries);
|
||||
|
||||
for (u32 j = 0; j < max_entries; j++)
|
||||
boot_values[j] = j;
|
||||
|
||||
if (sd_mount())
|
||||
{
|
||||
if (ini_parse(&ini_sections, "bootloader/ini", true))
|
||||
{
|
||||
// Build configuration menu.
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
u32 i = 2;
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
||||
{
|
||||
// Skip other ini entries for autoboot.
|
||||
if (ini_sec->type == INI_CHOICE)
|
||||
{
|
||||
if (!strcmp(ini_sec->name, "config"))
|
||||
continue;
|
||||
|
||||
if (strlen(ini_sec->name) > 510)
|
||||
ments[i].caption = ini_sec->name;
|
||||
else
|
||||
{
|
||||
if (h_cfg.autoboot != (i - 1) || !h_cfg.autoboot_list)
|
||||
boot_text[(i - 1) * 512] = ' ';
|
||||
|
||||
else
|
||||
boot_text[(i - 1) * 512] = '*';
|
||||
memcpy(boot_text + (i - 1) * 512 + 1, ini_sec->name, strlen(ini_sec->name) + 1);
|
||||
boot_text[strlen(ini_sec->name) + (i - 1) * 512 + 1] = 0;
|
||||
ments[i].caption = &boot_text[(i - 1) * 512];
|
||||
}
|
||||
ments[i].type = ini_sec->type;
|
||||
ments[i].data = &boot_values[i - 1];
|
||||
i++;
|
||||
|
||||
if ((i - 1) > max_entries)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&ments[i], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Select a list entry to auto boot", 0, 0};
|
||||
temp_autoboot = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_autoboot != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.autoboot = *(u32 *)temp_autoboot;
|
||||
h_cfg.autoboot_list = 1;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
}
|
||||
else
|
||||
goto out2;
|
||||
}
|
||||
else
|
||||
{
|
||||
EPRINTF("Could not open 'bootloader/hekate_ipl.ini'.\nMake sure it exists in SD Card!.");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:;
|
||||
btn_wait();
|
||||
out2:;
|
||||
free(ments);
|
||||
free(boot_values);
|
||||
free(boot_text);
|
||||
ini_free(&ini_sections);
|
||||
|
||||
sd_unmount();
|
||||
|
||||
if (temp_autoboot == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
void config_autoboot()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
u32 *temp_autoboot = NULL;
|
||||
|
||||
LIST_INIT(ini_sections);
|
||||
|
||||
u8 max_entries = 30;
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 5));
|
||||
u32 *boot_values = (u32 *)malloc(sizeof(u32) * max_entries);
|
||||
char *boot_text = (char *)malloc(512 * max_entries);
|
||||
|
||||
for (u32 j = 0; j < max_entries; j++)
|
||||
boot_values[j] = j;
|
||||
|
||||
if (sd_mount())
|
||||
{
|
||||
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false))
|
||||
{
|
||||
// Build configuration menu.
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
ments[2].type = MENT_DATA;
|
||||
if (!h_cfg.autoboot)
|
||||
ments[2].caption = "*Disable";
|
||||
else
|
||||
ments[2].caption = " Disable";
|
||||
ments[2].data = &boot_values[0];
|
||||
|
||||
ments[3].type = MENT_HANDLER;
|
||||
if (h_cfg.autoboot_list)
|
||||
ments[3].caption = "*More configs...";
|
||||
else
|
||||
ments[3].caption = " More configs...";
|
||||
ments[3].handler = _config_autoboot_list;
|
||||
ments[3].data = NULL;
|
||||
|
||||
ments[4].type = MENT_CHGLINE;
|
||||
|
||||
u32 i = 5;
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
||||
{
|
||||
// Skip other ini entries for autoboot.
|
||||
if (ini_sec->type == INI_CHOICE)
|
||||
{
|
||||
if (!strcmp(ini_sec->name, "config"))
|
||||
continue;
|
||||
|
||||
if (strlen(ini_sec->name) > 510)
|
||||
ments[i].caption = ini_sec->name;
|
||||
else
|
||||
{
|
||||
if (h_cfg.autoboot != (i - 4) || h_cfg.autoboot_list)
|
||||
boot_text[(i - 4) * 512] = ' ';
|
||||
|
||||
else
|
||||
boot_text[(i - 4) * 512] = '*';
|
||||
memcpy(boot_text + (i - 4) * 512 + 1, ini_sec->name, strlen(ini_sec->name) + 1);
|
||||
boot_text[strlen(ini_sec->name) + (i - 4) * 512 + 1] = 0;
|
||||
ments[i].caption = &boot_text[(i - 4) * 512];
|
||||
}
|
||||
ments[i].type = ini_sec->type;
|
||||
ments[i].data = &boot_values[i - 4];
|
||||
i++;
|
||||
|
||||
if ((i - 4) > max_entries)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < 6 && !h_cfg.autoboot_list)
|
||||
{
|
||||
ments[i].type = MENT_CAPTION;
|
||||
ments[i].caption = "No main configurations found...";
|
||||
ments[i].color = 0xFFFFDD00;
|
||||
i++;
|
||||
}
|
||||
|
||||
memset(&ments[i], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Disable or select entry to auto boot", 0, 0};
|
||||
temp_autoboot = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_autoboot != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.autoboot = *(u32 *)temp_autoboot;
|
||||
h_cfg.autoboot_list = 0;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
}
|
||||
else
|
||||
goto out2;
|
||||
}
|
||||
else
|
||||
{
|
||||
EPRINTF("Could not open 'bootloader/hekate_ipl.ini'.\nMake sure it exists in SD Card!.");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:;
|
||||
btn_wait();
|
||||
out2:;
|
||||
free(ments);
|
||||
free(boot_values);
|
||||
free(boot_text);
|
||||
ini_free(&ini_sections);
|
||||
|
||||
sd_unmount();
|
||||
|
||||
if (temp_autoboot == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
void config_bootdelay()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
u32 delay_entries = 6;
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (delay_entries + 3));
|
||||
u32 *delay_values = (u32 *)malloc(sizeof(u32) * delay_entries);
|
||||
char *delay_text = (char *)malloc(32 * delay_entries);
|
||||
|
||||
for (u32 j = 0; j < delay_entries; j++)
|
||||
delay_values[j] = j;
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
ments[2].type = MENT_DATA;
|
||||
if (h_cfg.bootwait)
|
||||
ments[2].caption = " 0 seconds (Bootlogo disabled)";
|
||||
else
|
||||
ments[2].caption = "*0 seconds (Bootlogo disabled)";
|
||||
ments[2].data = &delay_values[0];
|
||||
|
||||
u32 i = 0;
|
||||
for (i = 1; i < delay_entries; i++)
|
||||
{
|
||||
if (h_cfg.bootwait != i)
|
||||
delay_text[i * 32] = ' ';
|
||||
else
|
||||
delay_text[i * 32] = '*';
|
||||
delay_text[i * 32 + 1] = i + '0';
|
||||
memcpy(delay_text + i * 32 + 2, " seconds", 9);
|
||||
|
||||
ments[i + 2].type = MENT_DATA;
|
||||
ments[i + 2].caption = delay_text + i * 32;
|
||||
ments[i + 2].data = &delay_values[i];
|
||||
}
|
||||
|
||||
memset(&ments[i + 2], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Time delay for entering bootloader menu", 0, 0};
|
||||
|
||||
u32 *temp_bootwait = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_bootwait != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.bootwait = *(u32 *)temp_bootwait;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(delay_values);
|
||||
free(delay_text);
|
||||
|
||||
if (temp_bootwait == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_customlogo()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 5);
|
||||
u32 *cb_values = (u32 *)malloc(sizeof(u32) * 2);
|
||||
|
||||
for (u32 j = 0; j < 2; j++)
|
||||
{
|
||||
cb_values[j] = j;
|
||||
ments[j + 2].type = MENT_DATA;
|
||||
ments[j + 2].data = &cb_values[j];
|
||||
}
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
if (h_cfg.customlogo)
|
||||
{
|
||||
ments[2].caption = " Disable";
|
||||
ments[3].caption = "*Enable";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ments[2].caption = "*Disable";
|
||||
ments[3].caption = " Enable";
|
||||
}
|
||||
|
||||
memset(&ments[4], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Custom bootlogo", 0, 0};
|
||||
|
||||
u32 *temp_customlogo = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_customlogo != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.customlogo = *(u32 *)temp_customlogo;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(cb_values);
|
||||
|
||||
if (temp_customlogo == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_verification()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 6);
|
||||
u32 *vr_values = (u32 *)malloc(sizeof(u32) * 3);
|
||||
char *vr_text = (char *)malloc(64 * 3);
|
||||
|
||||
for (u32 j = 0; j < 3; j++)
|
||||
{
|
||||
vr_values[j] = j;
|
||||
ments[j + 2].type = MENT_DATA;
|
||||
ments[j + 2].data = &vr_values[j];
|
||||
}
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
memcpy(vr_text, " Disable (Fastest)", 19);
|
||||
memcpy(vr_text + 64, " Sparse (Fast - Not reliable)", 32);
|
||||
memcpy(vr_text + 128, " Full (Slow - 100% reliable)", 32);
|
||||
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (h_cfg.verification != i)
|
||||
{
|
||||
vr_text[64 * i] = ' ';
|
||||
ments[2 + i].caption = vr_text + (i * 64);
|
||||
}
|
||||
else
|
||||
{
|
||||
vr_text[64 * i] = '*';
|
||||
ments[2 + i].caption = vr_text + (i * 64);
|
||||
}
|
||||
}
|
||||
|
||||
memset(&ments[5], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Backup & Restore verification", 0, 0};
|
||||
|
||||
u32 *temp_verification = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_verification != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.verification = *(u32 *)temp_verification;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(vr_values);
|
||||
free(vr_text);
|
||||
|
||||
if (temp_verification == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_backlight()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
u32 bri_entries = 11;
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (bri_entries + 3));
|
||||
u32 *bri_values = (u32 *)malloc(sizeof(u32) * bri_entries);
|
||||
char *bri_text = (char *)malloc(8 * bri_entries);
|
||||
|
||||
for (u32 j = 1; j < bri_entries; j++)
|
||||
bri_values[j] = j * 10;
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
u32 i = 0;
|
||||
for (i = 1; i < bri_entries; i++)
|
||||
{
|
||||
if ((h_cfg.backlight / 20) != i)
|
||||
bri_text[i * 32] = ' ';
|
||||
else
|
||||
bri_text[i * 32] = '*';
|
||||
|
||||
if (i < 10)
|
||||
{
|
||||
bri_text[i * 32 + 1] = i + '0';
|
||||
memcpy(bri_text + i * 32 + 2, "0%", 3);
|
||||
}
|
||||
|
||||
else
|
||||
memcpy(bri_text + i * 32 + 1, "100%", 5);
|
||||
|
||||
ments[i + 1].type = MENT_DATA;
|
||||
ments[i + 1].caption = bri_text + i * 32;
|
||||
ments[i + 1].data = &bri_values[i];
|
||||
}
|
||||
|
||||
memset(&ments[i + 1], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Backlight brightness", 0, 0};
|
||||
|
||||
u32 *temp_backlight = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_backlight != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.backlight = (*(u32 *)temp_backlight) * 2;
|
||||
//Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(bri_values);
|
||||
free(bri_text);
|
||||
|
||||
if (temp_backlight == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_auto_hos_poweroff()
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 5);
|
||||
u32 *hp_values = (u32 *)malloc(sizeof(u32) * 2);
|
||||
|
||||
for (u32 j = 0; j < 2; j++)
|
||||
{
|
||||
hp_values[j] = j;
|
||||
ments[j + 2].type = MENT_DATA;
|
||||
ments[j + 2].data = &hp_values[j];
|
||||
}
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
if (h_cfg.autohosoff)
|
||||
{
|
||||
ments[2].caption = " Disable";
|
||||
ments[3].caption = "*Enable";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ments[2].caption = "*Disable";
|
||||
ments[3].caption = " Enable";
|
||||
}
|
||||
|
||||
memset(&ments[4], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Power off if woke up from HOS", 0, 0};
|
||||
|
||||
u32 *temp_autohosoff = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||
if (temp_autohosoff != NULL)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
|
||||
h_cfg.autohosoff = *(u32 *)temp_autohosoff;
|
||||
// Save choice to ini file.
|
||||
if (!create_config_entry())
|
||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts(&gfx_con, "\nPress any key...");
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(hp_values);
|
||||
|
||||
if (temp_autohosoff == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* 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 _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
typedef struct _hekate_config
|
||||
{
|
||||
// Non-volatile config.
|
||||
u32 autoboot;
|
||||
u32 autoboot_list;
|
||||
u32 bootwait;
|
||||
u32 customlogo;
|
||||
u32 verification;
|
||||
u32 backlight;
|
||||
u32 autohosoff;
|
||||
u32 errors;
|
||||
// Global temporary config.
|
||||
int se_keygen_done;
|
||||
u32 sbar_time_keeping;
|
||||
} hekate_config;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ERR_LIBSYS_LP0 = (1 << 0),
|
||||
} hsysmodule_t;
|
||||
|
||||
void set_default_configuration();
|
||||
int create_config_entry();
|
||||
void config_autoboot();
|
||||
void config_bootdelay();
|
||||
void config_customlogo();
|
||||
void config_verification();
|
||||
void config_backlight();
|
||||
void config_auto_hos_poweroff();
|
||||
|
||||
#endif /* _CONFIG_H_ */
|
||||
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ini.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../utils/dirlist.h"
|
||||
|
||||
static char *_strdup(char *str)
|
||||
{
|
||||
char *res = (char *)malloc(strlen(str) + 1);
|
||||
strcpy(res, str);
|
||||
return res;
|
||||
}
|
||||
|
||||
int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||
{
|
||||
u32 lblen;
|
||||
u32 pathlen = strlen(ini_path);
|
||||
u32 k = 0;
|
||||
char lbuf[512];
|
||||
char *filelist = NULL;
|
||||
FIL fp;
|
||||
ini_sec_t *csec = NULL;
|
||||
|
||||
char *filename = (char *)malloc(256);
|
||||
|
||||
memcpy(filename, ini_path, pathlen + 1);
|
||||
|
||||
if (is_dir)
|
||||
{
|
||||
filelist = dirlist(filename, "*.ini");
|
||||
if (!filelist)
|
||||
{
|
||||
free(filename);
|
||||
return 0;
|
||||
}
|
||||
memcpy(filename + pathlen, "/", 2);
|
||||
pathlen++;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (is_dir)
|
||||
{
|
||||
if (filelist[k * 256])
|
||||
{
|
||||
memcpy(filename + pathlen, &filelist[k * 256], strlen(&filelist[k * 256]) + 1);
|
||||
k++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (f_open(&fp, filename, FA_READ) != FR_OK)
|
||||
{
|
||||
free(filelist);
|
||||
free(filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
// Fetch one line.
|
||||
lbuf[0] = 0;
|
||||
f_gets(lbuf, 512, &fp);
|
||||
lblen = strlen(lbuf);
|
||||
|
||||
// Remove trailing newline.
|
||||
if (lbuf[lblen - 1] == '\n')
|
||||
lbuf[lblen - 1] = 0;
|
||||
|
||||
if (lblen > 2 && lbuf[0] == '[') // Create new section.
|
||||
{
|
||||
if (csec)
|
||||
{
|
||||
list_append(dst, &csec->link);
|
||||
csec = NULL;
|
||||
}
|
||||
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != ']'; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||
csec->name = _strdup(&lbuf[1]);
|
||||
csec->type = INI_CHOICE;
|
||||
list_init(&csec->kvs);
|
||||
}
|
||||
else if (lblen > 2 && lbuf[0] == '{') //Create new caption.
|
||||
{
|
||||
if (csec)
|
||||
{
|
||||
list_append(dst, &csec->link);
|
||||
csec = NULL;
|
||||
}
|
||||
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != '}'; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||
csec->name = _strdup(&lbuf[1]);
|
||||
csec->type = INI_CAPTION;
|
||||
csec->color = 0xFF0AB9E6;
|
||||
}
|
||||
else if (lblen > 2 && lbuf[0] == '#') //Create empty lines and comments.
|
||||
{
|
||||
if (csec)
|
||||
{
|
||||
list_append(dst, &csec->link);
|
||||
csec = NULL;
|
||||
}
|
||||
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != '\n'; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||
csec->name = _strdup(&lbuf[1]);
|
||||
csec->type = INI_COMMENT;
|
||||
}
|
||||
else if (lblen < 2)
|
||||
{
|
||||
if (csec)
|
||||
{
|
||||
list_append(dst, &csec->link);
|
||||
csec = NULL;
|
||||
}
|
||||
|
||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||
csec->name = NULL;
|
||||
csec->type = INI_NEWLINE;
|
||||
}
|
||||
else if (csec && csec->type == INI_CHOICE) //Extract key/value.
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != '='; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
ini_kv_t *kv = (ini_kv_t *)malloc(sizeof(ini_kv_t));
|
||||
kv->key = _strdup(&lbuf[0]);
|
||||
kv->val = _strdup(&lbuf[i + 1]);
|
||||
list_append(&csec->kvs, &kv->link);
|
||||
}
|
||||
} while (!f_eof(&fp));
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
if (csec)
|
||||
list_append(dst, &csec->link);
|
||||
|
||||
} while (is_dir);
|
||||
|
||||
free(filename);
|
||||
free(filelist);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ini_free(link_t *dst)
|
||||
{
|
||||
if (!dst->prev || !dst->next)
|
||||
return;
|
||||
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, dst, link)
|
||||
{
|
||||
if (ini_sec->type == INI_CHOICE)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
list_init(dst);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
cfg = NULL;
|
||||
}
|
||||
|
||||
char *ini_check_payload_section(ini_sec_t *cfg)
|
||||
{
|
||||
char *path = NULL;
|
||||
|
||||
if (cfg == NULL)
|
||||
return NULL;
|
||||
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link)
|
||||
{
|
||||
if (!strcmp("payload", kv->key))
|
||||
{
|
||||
if (!path)
|
||||
path = _strdup(kv->val);
|
||||
}
|
||||
}
|
||||
|
||||
if (path)
|
||||
return path;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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 _INI_H_
|
||||
#define _INI_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "../utils/list.h"
|
||||
|
||||
#define INI_CHOICE 3
|
||||
#define INI_CAPTION 5
|
||||
#define INI_CHGLINE 6
|
||||
#define INI_NEWLINE 0xFE
|
||||
#define INI_COMMENT 0xFF
|
||||
|
||||
typedef struct _ini_kv_t
|
||||
{
|
||||
char *key;
|
||||
char *val;
|
||||
link_t link;
|
||||
} ini_kv_t;
|
||||
|
||||
typedef struct _ini_sec_t
|
||||
{
|
||||
char *name;
|
||||
link_t kvs;
|
||||
link_t link;
|
||||
u32 type;
|
||||
u32 color;
|
||||
} ini_sec_t;
|
||||
|
||||
int ini_parse(link_t *dst, char *ini_path, bool is_dir);
|
||||
void ini_free(link_t *dst);
|
||||
ini_sec_t *ini_clone_section(ini_sec_t *cfg);
|
||||
void ini_free_section(ini_sec_t *cfg);
|
||||
char *ini_check_payload_section(ini_sec_t *cfg);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "di.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../soc/i2c.h"
|
||||
#include "../soc/pmc.h"
|
||||
#include "../power/max77620.h"
|
||||
#include "../soc/gpio.h"
|
||||
#include "../soc/pinmux.h"
|
||||
#include "../soc/clock.h"
|
||||
|
||||
#include "di.inl"
|
||||
|
||||
static u32 _display_ver = 0;
|
||||
|
||||
static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
|
||||
{
|
||||
u32 end = get_tmr_us() + timeout;
|
||||
while (get_tmr_us() < end && DSI(off) & mask)
|
||||
;
|
||||
usleep(5);
|
||||
}
|
||||
|
||||
void display_init()
|
||||
{
|
||||
// Power on.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO0_CFG, 0xD0); // Configure to 1.2V.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7, 0x09);
|
||||
|
||||
// Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x1010000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x1010000;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = 0x18000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x20000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIP_CAL) = 0xA;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = 0x80000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 0xA;
|
||||
|
||||
// DPD idle.
|
||||
PMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000;
|
||||
PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000;
|
||||
|
||||
// Config pins.
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE;
|
||||
|
||||
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.
|
||||
|
||||
usleep(10000);
|
||||
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // Backlight -5V enable.
|
||||
|
||||
usleep(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.
|
||||
|
||||
// Config display interface and display.
|
||||
MIPI_CAL(0x60) = 0;
|
||||
|
||||
exec_cfg((u32 *)CLOCK_BASE, _display_config_1, 4);
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_2, 94);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_3, 61);
|
||||
|
||||
usleep(10000);
|
||||
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH); // Backlight Reset enable.
|
||||
|
||||
usleep(60000);
|
||||
|
||||
DSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204;
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x337;
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x406;
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;
|
||||
_display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
|
||||
|
||||
usleep(5000);
|
||||
|
||||
_display_ver = DSI(_DSIREG(DSI_RD_DATA));
|
||||
if (_display_ver == 0x10)
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_4, 43);
|
||||
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x1105;
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
|
||||
usleep(180000);
|
||||
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x2905;
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
|
||||
usleep(20000);
|
||||
|
||||
exec_cfg((u32 *)CLOCK_BASE, _display_config_6, 3);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_5, 21);
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_7, 10);
|
||||
|
||||
usleep(10000);
|
||||
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_8, 6);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_9, 4);
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_10, 16);
|
||||
|
||||
usleep(10000);
|
||||
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_11, 113);
|
||||
}
|
||||
|
||||
void display_backlight_pwm_init()
|
||||
{
|
||||
clock_enable_pwm();
|
||||
|
||||
PWM(PWM_CONTROLLER_PWM_CSR) = (1 << 31); // Enable PWM
|
||||
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1; // PWM clock source.
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.
|
||||
|
||||
}
|
||||
|
||||
void display_backlight(bool enable)
|
||||
{
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); // Backlight PWM GPIO.
|
||||
}
|
||||
|
||||
void display_backlight_brightness(u32 brightness, u32 step_delay)
|
||||
{
|
||||
u32 old_value = (PWM(PWM_CONTROLLER_PWM_CSR) >> 16) & 0xFF;
|
||||
if (brightness == old_value)
|
||||
return;
|
||||
|
||||
if (brightness > 255)
|
||||
brightness = 255;
|
||||
|
||||
if (old_value < brightness)
|
||||
{
|
||||
for (u32 i = old_value; i < brightness + 1; i++)
|
||||
{
|
||||
PWM(PWM_CONTROLLER_PWM_CSR) = (1 << 31) | (i << 16); // Enable PWM
|
||||
usleep(step_delay);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = old_value; i > brightness; i--)
|
||||
{
|
||||
PWM(PWM_CONTROLLER_PWM_CSR) = (1 << 31) | (i << 16); // Enable PWM
|
||||
usleep(step_delay);
|
||||
}
|
||||
}
|
||||
if (!brightness)
|
||||
PWM(PWM_CONTROLLER_PWM_CSR) = 0;
|
||||
}
|
||||
|
||||
void display_end()
|
||||
{
|
||||
display_backlight_brightness(0, 1000);
|
||||
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 1;
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x2805;
|
||||
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX;
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_12, 17);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_13, 16);
|
||||
|
||||
usleep(10000);
|
||||
|
||||
if (_display_ver == 0x10)
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_14, 22);
|
||||
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x1005;
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
|
||||
usleep(50000);
|
||||
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); //Backlight Reset disable.
|
||||
|
||||
usleep(10000);
|
||||
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); //Backlight -5V disable.
|
||||
|
||||
usleep(10000);
|
||||
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); //Backlight +5V disable.
|
||||
|
||||
usleep(10000);
|
||||
|
||||
// Disable clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x1010000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = 0x1010000;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = 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;
|
||||
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.
|
||||
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_TRISTATE) | PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1;
|
||||
}
|
||||
|
||||
void display_color_screen(u32 color)
|
||||
{
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8);
|
||||
|
||||
// Configure display to show single color.
|
||||
DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;
|
||||
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;
|
||||
|
||||
usleep(35000);
|
||||
|
||||
display_backlight(true);
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer()
|
||||
{
|
||||
// Sanitize framebuffer area.
|
||||
memset((u32 *)0xC0000000, 0, 0x3C0000);
|
||||
// This configures the framebuffer @ 0xC0000000 with a resolution of 1280x720 (line stride 768).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32);
|
||||
|
||||
usleep(35000);
|
||||
|
||||
return (u32 *)0xC0000000;
|
||||
}
|
||||
@@ -1,365 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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 _DI_H_
|
||||
#define _DI_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
/*! Display registers. */
|
||||
#define _DIREG(reg) ((reg) * 4)
|
||||
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
|
||||
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
|
||||
#define SYNCPT_CNTRL_NO_STALL (1 << 8)
|
||||
#define SYNCPT_CNTRL_SOFT_RESET (1 << 0)
|
||||
|
||||
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
|
||||
#define SYNCPT_VSYNC_ENABLE (1 << 8)
|
||||
|
||||
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
|
||||
|
||||
#define DC_CMD_DISPLAY_COMMAND 0x32
|
||||
#define DISP_CTRL_MODE_STOP (0 << 5)
|
||||
#define DISP_CTRL_MODE_C_DISPLAY (1 << 5)
|
||||
#define DISP_CTRL_MODE_NC_DISPLAY (2 << 5)
|
||||
#define DISP_CTRL_MODE_MASK (3 << 5)
|
||||
|
||||
#define DC_CMD_DISPLAY_POWER_CONTROL 0x36
|
||||
#define PW0_ENABLE (1 << 0)
|
||||
#define PW1_ENABLE (1 << 2)
|
||||
#define PW2_ENABLE (1 << 4)
|
||||
#define PW3_ENABLE (1 << 6)
|
||||
#define PW4_ENABLE (1 << 8)
|
||||
#define PM0_ENABLE (1 << 16)
|
||||
#define PM1_ENABLE (1 << 18)
|
||||
|
||||
#define DC_CMD_INT_MASK 0x38
|
||||
#define DC_CMD_INT_ENABLE 0x39
|
||||
|
||||
#define DC_CMD_STATE_ACCESS 0x40
|
||||
#define READ_MUX (1 << 0)
|
||||
#define WRITE_MUX (1 << 2)
|
||||
|
||||
#define DC_CMD_STATE_CONTROL 0x41
|
||||
#define GENERAL_ACT_REQ (1 << 0)
|
||||
#define WIN_A_ACT_REQ (1 << 1)
|
||||
#define WIN_B_ACT_REQ (1 << 2)
|
||||
#define WIN_C_ACT_REQ (1 << 3)
|
||||
#define CURSOR_ACT_REQ (1 << 7)
|
||||
#define GENERAL_UPDATE (1 << 8)
|
||||
#define WIN_A_UPDATE (1 << 9)
|
||||
#define WIN_B_UPDATE (1 << 10)
|
||||
#define WIN_C_UPDATE (1 << 11)
|
||||
#define CURSOR_UPDATE (1 << 15)
|
||||
#define NC_HOST_TRIG (1 << 24)
|
||||
|
||||
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
|
||||
#define WINDOW_A_SELECT (1 << 4)
|
||||
#define WINDOW_B_SELECT (1 << 5)
|
||||
#define WINDOW_C_SELECT (1 << 6)
|
||||
|
||||
#define DC_CMD_REG_ACT_CONTROL 0x043
|
||||
|
||||
#define DC_COM_CRC_CONTROL 0x300
|
||||
#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
|
||||
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
|
||||
|
||||
#define DC_COM_DSC_TOP_CTL 0x33E
|
||||
|
||||
#define DC_DISP_DISP_WIN_OPTIONS 0x402
|
||||
#define HDMI_ENABLE (1 << 30)
|
||||
#define DSI_ENABLE (1 << 29)
|
||||
#define SOR1_TIMING_CYA (1 << 27)
|
||||
#define SOR1_ENABLE (1 << 26)
|
||||
#define SOR_ENABLE (1 << 25)
|
||||
#define CURSOR_ENABLE (1 << 16)
|
||||
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
|
||||
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
|
||||
#define DC_DISP_REF_TO_SYNC 0x406
|
||||
#define DC_DISP_SYNC_WIDTH 0x407
|
||||
#define DC_DISP_BACK_PORCH 0x408
|
||||
#define DC_DISP_ACTIVE 0x409
|
||||
#define DC_DISP_FRONT_PORCH 0x40A
|
||||
|
||||
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
|
||||
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD3 (3 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD4 (4 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD6 (5 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD8 (6 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD9 (7 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD12 (8 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD16 (9 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD18 (10 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD24 (11 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD13 (12 << 8)
|
||||
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
|
||||
|
||||
#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F
|
||||
#define DISP_DATA_FORMAT_DF1P1C (0 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P2C24B (1 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P2C18B (2 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P2C16B (3 << 0)
|
||||
#define DISP_DATA_FORMAT_DF2S (4 << 0)
|
||||
#define DISP_DATA_FORMAT_DF3S (5 << 0)
|
||||
#define DISP_DATA_FORMAT_DFSPI (6 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P3C24B (7 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P3C18B (8 << 0)
|
||||
#define DISP_ALIGNMENT_MSB (0 << 8)
|
||||
#define DISP_ALIGNMENT_LSB (1 << 8)
|
||||
#define DISP_ORDER_RED_BLUE (0 << 9)
|
||||
#define DISP_ORDER_BLUE_RED (1 << 9)
|
||||
|
||||
#define DC_DISP_DISP_COLOR_CONTROL 0x430
|
||||
#define DITHER_CONTROL_MASK (3 << 8)
|
||||
#define DITHER_CONTROL_DISABLE (0 << 8)
|
||||
#define DITHER_CONTROL_ORDERED (2 << 8)
|
||||
#define DITHER_CONTROL_ERRDIFF (3 << 8)
|
||||
#define BASE_COLOR_SIZE_MASK (0xf << 0)
|
||||
#define BASE_COLOR_SIZE_666 (0 << 0)
|
||||
#define BASE_COLOR_SIZE_111 (1 << 0)
|
||||
#define BASE_COLOR_SIZE_222 (2 << 0)
|
||||
#define BASE_COLOR_SIZE_333 (3 << 0)
|
||||
#define BASE_COLOR_SIZE_444 (4 << 0)
|
||||
#define BASE_COLOR_SIZE_555 (5 << 0)
|
||||
#define BASE_COLOR_SIZE_565 (6 << 0)
|
||||
#define BASE_COLOR_SIZE_332 (7 << 0)
|
||||
#define BASE_COLOR_SIZE_888 (8 << 0)
|
||||
|
||||
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
|
||||
#define SC1_H_QUALIFIER_NONE (1 << 16)
|
||||
#define SC0_H_QUALIFIER_NONE (1 << 0)
|
||||
|
||||
#define DC_DISP_DATA_ENABLE_OPTIONS 0x432
|
||||
#define DE_SELECT_ACTIVE_BLANK (0 << 0)
|
||||
#define DE_SELECT_ACTIVE (1 << 0)
|
||||
#define DE_SELECT_ACTIVE_IS (2 << 0)
|
||||
#define DE_CONTROL_ONECLK (0 << 2)
|
||||
#define DE_CONTROL_NORMAL (1 << 2)
|
||||
#define DE_CONTROL_EARLY_EXT (2 << 2)
|
||||
#define DE_CONTROL_EARLY (3 << 2)
|
||||
#define DE_CONTROL_ACTIVE_BLANK (4 << 2)
|
||||
|
||||
#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480
|
||||
#define DC_DISP_SD_BL_PARAMETERS 0x4D7
|
||||
#define DC_DISP_SD_BL_CONTROL 0x4DC
|
||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||
|
||||
#define DC_WIN_CSC_YOF 0x611
|
||||
#define DC_WIN_CSC_KYRGB 0x612
|
||||
#define DC_WIN_CSC_KUR 0x613
|
||||
#define DC_WIN_CSC_KVR 0x614
|
||||
#define DC_WIN_CSC_KUG 0x615
|
||||
#define DC_WIN_CSC_KVG 0x616
|
||||
#define DC_WIN_CSC_KUB 0x617
|
||||
#define DC_WIN_CSC_KVB 0x618
|
||||
#define DC_WIN_AD_WIN_OPTIONS 0xB80
|
||||
#define DC_WIN_BD_WIN_OPTIONS 0xD80
|
||||
#define DC_WIN_CD_WIN_OPTIONS 0xF80
|
||||
|
||||
// The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).
|
||||
#define DC_WIN_WIN_OPTIONS 0x700
|
||||
#define H_DIRECTION (1 << 0)
|
||||
#define V_DIRECTION (1 << 2)
|
||||
#define SCAN_COLUMN (1 << 4)
|
||||
#define COLOR_EXPAND (1 << 6)
|
||||
#define CSC_ENABLE (1 << 18)
|
||||
#define WIN_ENABLE (1 << 30)
|
||||
|
||||
#define DC_WIN_COLOR_DEPTH 0x703
|
||||
#define WIN_COLOR_DEPTH_P1 0x0
|
||||
#define WIN_COLOR_DEPTH_P2 0x1
|
||||
#define WIN_COLOR_DEPTH_P4 0x2
|
||||
#define WIN_COLOR_DEPTH_P8 0x3
|
||||
#define WIN_COLOR_DEPTH_B4G4R4A4 0x4
|
||||
#define WIN_COLOR_DEPTH_B5G5R5A 0x5
|
||||
#define WIN_COLOR_DEPTH_B5G6R5 0x6
|
||||
#define WIN_COLOR_DEPTH_AB5G5R5 0x7
|
||||
#define WIN_COLOR_DEPTH_B8G8R8A8 0xC
|
||||
#define WIN_COLOR_DEPTH_R8G8B8A8 0xD
|
||||
#define WIN_COLOR_DEPTH_B6x2G6x2R6x2A8 0xE
|
||||
#define WIN_COLOR_DEPTH_R6x2G6x2B6x2A8 0xF
|
||||
#define WIN_COLOR_DEPTH_YCbCr422 0x10
|
||||
#define WIN_COLOR_DEPTH_YUV422 0x11
|
||||
#define WIN_COLOR_DEPTH_YCbCr420P 0x12
|
||||
#define WIN_COLOR_DEPTH_YUV420P 0x13
|
||||
#define WIN_COLOR_DEPTH_YCbCr422P 0x14
|
||||
#define WIN_COLOR_DEPTH_YUV422P 0x15
|
||||
#define WIN_COLOR_DEPTH_YCbCr422R 0x16
|
||||
#define WIN_COLOR_DEPTH_YUV422R 0x17
|
||||
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
|
||||
#define WIN_COLOR_DEPTH_YUV422RA 0x19
|
||||
|
||||
#define DC_WIN_BUFFER_CONTROL 0x702
|
||||
#define DC_WIN_POSITION 0x704
|
||||
|
||||
#define DC_WIN_SIZE 0x705
|
||||
#define H_SIZE(x) (((x) & 0x1fff) << 0)
|
||||
#define V_SIZE(x) (((x) & 0x1fff) << 16)
|
||||
|
||||
#define DC_WIN_PRESCALED_SIZE 0x706
|
||||
#define H_PRESCALED_SIZE(x) (((x) & 0x7fff) << 0)
|
||||
#define V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)
|
||||
|
||||
#define DC_WIN_H_INITIAL_DDA 0x707
|
||||
#define DC_WIN_V_INITIAL_DDA 0x708
|
||||
|
||||
#define DC_WIN_DDA_INC 0x709
|
||||
#define H_DDA_INC(x) (((x) & 0xffff) << 0)
|
||||
#define V_DDA_INC(x) (((x) & 0xffff) << 16)
|
||||
|
||||
#define DC_WIN_LINE_STRIDE 0x70A
|
||||
#define LINE_STRIDE(x) (x)
|
||||
#define UV_LINE_STRIDE(x) (((x) & 0xffff) << 16)
|
||||
#define DC_WIN_DV_CONTROL 0x70E
|
||||
|
||||
// The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER).
|
||||
#define DC_WINBUF_START_ADDR 0x800
|
||||
#define DC_WINBUF_ADDR_H_OFFSET 0x806
|
||||
#define DC_WINBUF_ADDR_V_OFFSET 0x808
|
||||
#define DC_WINBUF_SURFACE_KIND 0x80B
|
||||
|
||||
/*! Display serial interface registers. */
|
||||
#define _DSIREG(reg) ((reg) * 4)
|
||||
|
||||
#define DSI_RD_DATA 0x9
|
||||
#define DSI_WR_DATA 0xA
|
||||
|
||||
#define DSI_POWER_CONTROL 0xB
|
||||
#define DSI_POWER_CONTROL_ENABLE 1
|
||||
|
||||
#define DSI_INT_ENABLE 0xC
|
||||
#define DSI_INT_STATUS 0xD
|
||||
#define DSI_INT_MASK 0xE
|
||||
|
||||
#define DSI_HOST_CONTROL 0xF
|
||||
#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21)
|
||||
#define DSI_HOST_CONTROL_CRC_RESET (1 << 20)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
|
||||
#define DSI_HOST_CONTROL_RAW (1 << 6)
|
||||
#define DSI_HOST_CONTROL_HS (1 << 5)
|
||||
#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4)
|
||||
#define DSI_HOST_CONTROL_IMM_BTA (1 << 3)
|
||||
#define DSI_HOST_CONTROL_PKT_BTA (1 << 2)
|
||||
#define DSI_HOST_CONTROL_CS (1 << 1)
|
||||
#define DSI_HOST_CONTROL_ECC (1 << 0)
|
||||
|
||||
#define DSI_CONTROL 0x10
|
||||
#define DSI_CONTROL_HS_CLK_CTRL (1 << 20)
|
||||
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
|
||||
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
|
||||
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
|
||||
#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
|
||||
#define DSI_CONTROL_DCS_ENABLE (1 << 3)
|
||||
#define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2)
|
||||
#define DSI_CONTROL_VIDEO_ENABLE (1 << 1)
|
||||
#define DSI_CONTROL_HOST_ENABLE (1 << 0)
|
||||
|
||||
#define DSI_SOL_DELAY 0x11
|
||||
#define DSI_MAX_THRESHOLD 0x12
|
||||
|
||||
#define DSI_TRIGGER 0x13
|
||||
#define DSI_TRIGGER_HOST (1 << 1)
|
||||
#define DSI_TRIGGER_VIDEO (1 << 0)
|
||||
|
||||
#define DSI_TX_CRC 0x14
|
||||
#define DSI_STATUS 0x15
|
||||
#define DSI_INIT_SEQ_CONTROL 0x1A
|
||||
#define DSI_INIT_SEQ_DATA_0 0x1B
|
||||
#define DSI_INIT_SEQ_DATA_1 0x1C
|
||||
#define DSI_INIT_SEQ_DATA_2 0x1D
|
||||
#define DSI_INIT_SEQ_DATA_3 0x1E
|
||||
#define DSI_PKT_SEQ_0_LO 0x23
|
||||
#define DSI_PKT_SEQ_0_HI 0x24
|
||||
#define DSI_PKT_SEQ_1_LO 0x25
|
||||
#define DSI_PKT_SEQ_1_HI 0x26
|
||||
#define DSI_PKT_SEQ_2_LO 0x27
|
||||
#define DSI_PKT_SEQ_2_HI 0x28
|
||||
#define DSI_PKT_SEQ_3_LO 0x29
|
||||
#define DSI_PKT_SEQ_3_HI 0x2A
|
||||
#define DSI_PKT_SEQ_4_LO 0x2B
|
||||
#define DSI_PKT_SEQ_4_HI 0x2C
|
||||
#define DSI_PKT_SEQ_5_LO 0x2D
|
||||
#define DSI_PKT_SEQ_5_HI 0x2E
|
||||
#define DSI_DCS_CMDS 0x33
|
||||
#define DSI_PKT_LEN_0_1 0x34
|
||||
#define DSI_PKT_LEN_2_3 0x35
|
||||
#define DSI_PKT_LEN_4_5 0x36
|
||||
#define DSI_PKT_LEN_6_7 0x37
|
||||
#define DSI_PHY_TIMING_0 0x3C
|
||||
#define DSI_PHY_TIMING_1 0x3D
|
||||
#define DSI_PHY_TIMING_2 0x3E
|
||||
#define DSI_BTA_TIMING 0x3F
|
||||
|
||||
#define DSI_TIMEOUT_0 0x44
|
||||
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
|
||||
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
|
||||
|
||||
#define DSI_TIMEOUT_1 0x45
|
||||
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
|
||||
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
|
||||
|
||||
#define DSI_TO_TALLY 0x46
|
||||
|
||||
#define DSI_PAD_CONTROL_0 0x4B
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
|
||||
|
||||
#define DSI_PAD_CONTROL_CD 0x4c
|
||||
#define DSI_VIDEO_MODE_CONTROL 0x4E
|
||||
|
||||
#define DSI_PAD_CONTROL_1 0x4F
|
||||
#define DSI_PAD_CONTROL_2 0x50
|
||||
|
||||
#define DSI_PAD_CONTROL_3 0x51
|
||||
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
|
||||
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
|
||||
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
|
||||
#define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0)
|
||||
|
||||
#define DSI_PAD_CONTROL_4 0x52
|
||||
|
||||
#define DSI_INIT_SEQ_DATA_15 0x5F
|
||||
|
||||
/*! Display backlight related PWM registers. */
|
||||
#define PWM_CONTROLLER_PWM_CSR 0x00
|
||||
|
||||
void display_init();
|
||||
void display_backlight_pwm_init();
|
||||
void display_end();
|
||||
|
||||
/*! Show one single color on the display. */
|
||||
void display_color_screen(u32 color);
|
||||
|
||||
/*! Switches screen backlight ON/OFF. */
|
||||
void display_backlight(bool enable);
|
||||
void display_backlight_brightness(u32 brightness, u32 step_delay);
|
||||
|
||||
/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
|
||||
u32 *display_init_framebuffer();
|
||||
|
||||
#endif
|
||||
@@ -1,564 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
//Clock config.
|
||||
static const cfg_op_t _display_config_1[4] = {
|
||||
{0x4E, 0x40000000}, //CLK_RST_CONTROLLER_CLK_SOURCE_DISP1
|
||||
{0x34, 0x4830A001}, //CLK_RST_CONTROLLER_PLLD_BASE
|
||||
{0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
|
||||
{0x37, 0x2D0AAA} //CLK_RST_CONTROLLER_PLLD_MISC
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t _display_config_2[94] = {
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_REG_ACT_CONTROL, 0x54},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_DISP_DC_MCCIF_FIFOCTRL, 0},
|
||||
{DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},
|
||||
{DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},
|
||||
{DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},
|
||||
{DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | 0x9}, // 9: SYNCPT
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{0x4E4, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_COMMAND, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}
|
||||
};
|
||||
|
||||
//DSI Init config.
|
||||
static const cfg_op_t _display_config_3[61] = {
|
||||
{DSI_WR_DATA, 0},
|
||||
{DSI_INT_ENABLE, 0},
|
||||
{DSI_INT_STATUS, 0},
|
||||
{DSI_INT_MASK, 0},
|
||||
{DSI_INIT_SEQ_DATA_0, 0},
|
||||
{DSI_INIT_SEQ_DATA_1, 0},
|
||||
{DSI_INIT_SEQ_DATA_2, 0},
|
||||
{DSI_INIT_SEQ_DATA_3, 0},
|
||||
{DSI_INIT_SEQ_DATA_15, 0},
|
||||
{DSI_DCS_CMDS, 0},
|
||||
{DSI_PKT_SEQ_0_LO, 0},
|
||||
{DSI_PKT_SEQ_1_LO, 0},
|
||||
{DSI_PKT_SEQ_2_LO, 0},
|
||||
{DSI_PKT_SEQ_3_LO, 0},
|
||||
{DSI_PKT_SEQ_4_LO, 0},
|
||||
{DSI_PKT_SEQ_5_LO, 0},
|
||||
{DSI_PKT_SEQ_0_HI, 0},
|
||||
{DSI_PKT_SEQ_1_HI, 0},
|
||||
{DSI_PKT_SEQ_2_HI, 0},
|
||||
{DSI_PKT_SEQ_3_HI, 0},
|
||||
{DSI_PKT_SEQ_4_HI, 0},
|
||||
{DSI_PKT_SEQ_5_HI, 0},
|
||||
{DSI_CONTROL, 0},
|
||||
{DSI_PAD_CONTROL_CD, 0},
|
||||
{DSI_SOL_DELAY, 0x18},
|
||||
{DSI_MAX_THRESHOLD, 0x1E0},
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_INIT_SEQ_CONTROL, 0},
|
||||
{DSI_PKT_LEN_0_1, 0},
|
||||
{DSI_PKT_LEN_2_3, 0},
|
||||
{DSI_PKT_LEN_4_5, 0},
|
||||
{DSI_PKT_LEN_6_7, 0},
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30109},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
{DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Enable
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30118},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_MAX_THRESHOLD, 0x40},
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_TX_CRC, 0},
|
||||
{DSI_INIT_SEQ_CONTROL, 0}
|
||||
};
|
||||
|
||||
//DSI config (if ver == 0x10).
|
||||
static const cfg_op_t _display_config_4[43] = {
|
||||
{DSI_WR_DATA, 0x439},
|
||||
{DSI_WR_DATA, 0x9483FFB9},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xBD15},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x1939},
|
||||
{DSI_WR_DATA, 0xAAAAAAD8},
|
||||
{DSI_WR_DATA, 0xAAAAAAEB},
|
||||
{DSI_WR_DATA, 0xAAEBAAAA},
|
||||
{DSI_WR_DATA, 0xAAAAAAAA},
|
||||
{DSI_WR_DATA, 0xAAAAAAEB},
|
||||
{DSI_WR_DATA, 0xAAEBAAAA},
|
||||
{DSI_WR_DATA, 0xAA},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x1BD15},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2739},
|
||||
{DSI_WR_DATA, 0xFFFFFFD8},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFF},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2BD15},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xF39},
|
||||
{DSI_WR_DATA, 0xFFFFFFD8},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFF},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xBD15},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x6D915},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x439},
|
||||
{DSI_WR_DATA, 0xB9},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_5[21] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30172},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
{DSI_PKT_SEQ_0_LO, 0x40000208},
|
||||
{DSI_PKT_SEQ_2_LO, 0x40000308},
|
||||
{DSI_PKT_SEQ_4_LO, 0x40000308},
|
||||
{DSI_PKT_SEQ_1_LO, 0x40000308},
|
||||
{DSI_PKT_SEQ_3_LO, 0x3F3B2B08},
|
||||
{DSI_PKT_SEQ_3_HI, 0x2CC},
|
||||
{DSI_PKT_SEQ_5_LO, 0x3F3B2B08},
|
||||
{DSI_PKT_SEQ_5_HI, 0x2CC},
|
||||
{DSI_PKT_LEN_0_1, 0xCE0000},
|
||||
{DSI_PKT_LEN_2_3, 0x87001A2},
|
||||
{DSI_PKT_LEN_4_5, 0x190},
|
||||
{DSI_PKT_LEN_6_7, 0x190},
|
||||
{DSI_HOST_CONTROL, 0},
|
||||
};
|
||||
|
||||
//Clock config.
|
||||
static const cfg_op_t _display_config_6[3] = {
|
||||
{0x34, 0x4810C001}, //CLK_RST_CONTROLLER_PLLD_BASE
|
||||
{0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
|
||||
{0x37, 0x2DFC00} //CLK_RST_CONTROLLER_PLLD_MISC
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_7[10] = {
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_CONTROL, 0},
|
||||
{DSI_SOL_DELAY, 6},
|
||||
{DSI_MAX_THRESHOLD, 0x1E0},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL| DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_config_8[6] = {
|
||||
{0x18, 0},
|
||||
{2, 0xF3F10000},
|
||||
{0x16, 0},
|
||||
{0x18, 0},
|
||||
{0x18, 0x10010},
|
||||
{0x17, 0x300}
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_9[4] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
|
||||
{DSI_PAD_CONTROL_4, 0}
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_config_10[16] = {
|
||||
{0xE, 0x200200},
|
||||
{0xF, 0x200200},
|
||||
{0x19, 0x200002},
|
||||
{0x1A, 0x200002},
|
||||
{5, 0},
|
||||
{6, 0},
|
||||
{7, 0},
|
||||
{8, 0},
|
||||
{9, 0},
|
||||
{0xA, 0},
|
||||
{0x10, 0},
|
||||
{0x11, 0},
|
||||
{0x1A, 0},
|
||||
{0x1C, 0},
|
||||
{0x1D, 0},
|
||||
{0, 0x2A000001}
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t _display_config_11[113] = {
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{0x4E4, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_COMMAND, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
/* Set Display timings */
|
||||
{DC_DISP_DISP_TIMING_OPTIONS, 0},
|
||||
{DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1.
|
||||
{DC_DISP_SYNC_WIDTH, 0x10048},
|
||||
{DC_DISP_BACK_PORCH, 0x90048},
|
||||
{DC_DISP_ACTIVE, 0x50002D0},
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
|
||||
/* End of Display timings */
|
||||
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
||||
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_DISP_DISP_CLOCK_CONTROL, 0},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)},
|
||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0}
|
||||
};
|
||||
|
||||
////Display A config.
|
||||
static const cfg_op_t _display_config_12[17] = {
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088},
|
||||
{DC_CMD_INT_MASK, 0},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_INT_ENABLE, 0},
|
||||
{DC_CMD_CONT_SYNCPT_VSYNC, 0},
|
||||
{DC_CMD_DISPLAY_COMMAND, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_POWER_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_13[16] = {
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30118},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_MAX_THRESHOLD, 0x40},
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_TX_CRC, 0},
|
||||
{DSI_INIT_SEQ_CONTROL, 0}
|
||||
};
|
||||
|
||||
//DSI config (if ver == 0x10).
|
||||
static const cfg_op_t _display_config_14[22] = {
|
||||
{DSI_WR_DATA, 0x439},
|
||||
{DSI_WR_DATA, 0x9483FFB9},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2139},
|
||||
{DSI_WR_DATA, 0x191919D5},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xB39},
|
||||
{DSI_WR_DATA, 0x4F0F41B1},
|
||||
{DSI_WR_DATA, 0xF179A433},
|
||||
{DSI_WR_DATA, 0x2D81},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x439},
|
||||
{DSI_WR_DATA, 0xB9},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t cfg_display_one_color[8] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} //DISPLAY_CTRL_MODE: continuous display.
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t cfg_display_framebuffer[32] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, //T_A8R8G8B8 //NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)}, //Pre-scaled size: 1280x2880 bytes.
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)},
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, //Window size: 1280 vertical lines x 720 horizontal pixels.
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, 0},
|
||||
{DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.
|
||||
{DC_WINBUF_START_ADDR, 0xC0000000}, //Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, //Enable window AD.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.
|
||||
};
|
||||
@@ -1,524 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "gfx.h"
|
||||
|
||||
static const u8 _gfx_font[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 032 ( )
|
||||
0x00, 0x30, 0x30, 0x18, 0x18, 0x00, 0x0C, 0x00, // Char 033 (!)
|
||||
0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, // Char 034 (")
|
||||
0x00, 0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66, // Char 035 (#)
|
||||
0x00, 0x18, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x18, // Char 036 ($)
|
||||
0x00, 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, // Char 037 (%)
|
||||
0x00, 0x3C, 0x66, 0x3C, 0x1C, 0xE6, 0x66, 0xFC, // Char 038 (&)
|
||||
0x00, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, // Char 039 (')
|
||||
0x00, 0x30, 0x18, 0x0C, 0x0C, 0x18, 0x30, 0x00, // Char 040 (()
|
||||
0x00, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x00, // Char 041 ())
|
||||
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, // Char 042 (*)
|
||||
0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, // Char 043 (+)
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C, 0x00, // Char 044 (,)
|
||||
0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, // Char 045 (-)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, // Char 046 (.)
|
||||
0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, // Char 047 (/)
|
||||
0x00, 0x3C, 0x66, 0x76, 0x6E, 0x66, 0x3C, 0x00, // Char 048 (0)
|
||||
0x00, 0x18, 0x1C, 0x18, 0x18, 0x18, 0x7E, 0x00, // Char 049 (1)
|
||||
0x00, 0x3C, 0x62, 0x30, 0x0C, 0x06, 0x7E, 0x00, // Char 050 (2)
|
||||
0x00, 0x3C, 0x62, 0x38, 0x60, 0x66, 0x3C, 0x00, // Char 051 (3)
|
||||
0x00, 0x6C, 0x6C, 0x66, 0xFE, 0x60, 0x60, 0x00, // Char 052 (4)
|
||||
0x00, 0x7E, 0x06, 0x7E, 0x60, 0x66, 0x3C, 0x00, // Char 053 (5)
|
||||
0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00, // Char 054 (6)
|
||||
0x00, 0x7E, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00, // Char 055 (7)
|
||||
0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, // Char 056 (8)
|
||||
0x00, 0x3C, 0x66, 0x7C, 0x60, 0x66, 0x3C, 0x00, // Char 057 (9)
|
||||
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, // Char 058 (:)
|
||||
0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x00, // Char 059 (;)
|
||||
0x00, 0x70, 0x1C, 0x06, 0x06, 0x1C, 0x70, 0x00, // Char 060 (<)
|
||||
0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00, // Char 061 (=)
|
||||
0x00, 0x0E, 0x38, 0x60, 0x60, 0x38, 0x0E, 0x00, // Char 062 (>)
|
||||
0x00, 0x3C, 0x66, 0x30, 0x18, 0x00, 0x18, 0x00, // Char 063 (?)
|
||||
0x00, 0x3C, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3C, // Char 064 (@)
|
||||
0x00, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, // Char 065 (A)
|
||||
0x00, 0x3E, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00, // Char 066 (B)
|
||||
0x00, 0x3C, 0x66, 0x06, 0x06, 0x66, 0x3C, 0x00, // Char 067 (C)
|
||||
0x00, 0x1E, 0x36, 0x66, 0x66, 0x36, 0x1E, 0x00, // Char 068 (D)
|
||||
0x00, 0x7E, 0x06, 0x1E, 0x06, 0x06, 0x7E, 0x00, // Char 069 (E)
|
||||
0x00, 0x3E, 0x06, 0x1E, 0x06, 0x06, 0x06, 0x00, // Char 070 (F)
|
||||
0x00, 0x3C, 0x66, 0x06, 0x76, 0x66, 0x3C, 0x00, // Char 071 (G)
|
||||
0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, // Char 072 (H)
|
||||
0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 073 (I)
|
||||
0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, // Char 074 (J)
|
||||
0x00, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x00, // Char 075 (K)
|
||||
0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00, // Char 076 (L)
|
||||
0x00, 0x46, 0x6E, 0x7E, 0x56, 0x46, 0x46, 0x00, // Char 077 (M)
|
||||
0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00, // Char 078 (N)
|
||||
0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 079 (O)
|
||||
0x00, 0x3E, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00, // Char 080 (P)
|
||||
0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x70, 0x00, // Char 081 (Q)
|
||||
0x00, 0x3E, 0x66, 0x3E, 0x1E, 0x36, 0x66, 0x00, // Char 082 (R)
|
||||
0x00, 0x3C, 0x66, 0x0C, 0x30, 0x66, 0x3C, 0x00, // Char 083 (S)
|
||||
0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, // Char 084 (T)
|
||||
0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 085 (U)
|
||||
0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, // Char 086 (V)
|
||||
0x00, 0x46, 0x46, 0x56, 0x7E, 0x6E, 0x46, 0x00, // Char 087 (W)
|
||||
0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, // Char 088 (X)
|
||||
0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, // Char 089 (Y)
|
||||
0x00, 0x7E, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00, // Char 090 (Z)
|
||||
0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, // Char 091 ([)
|
||||
0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, // Char 092 (\)
|
||||
0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, // Char 093 (])
|
||||
0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, // Char 094 (^)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, // Char 095 (_)
|
||||
0x00, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, // Char 096 (`)
|
||||
0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00, // Char 097 (a)
|
||||
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00, // Char 098 (b)
|
||||
0x00, 0x00, 0x3C, 0x06, 0x06, 0x06, 0x3C, 0x00, // Char 099 (c)
|
||||
0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, // Char 100 (d)
|
||||
0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00, // Char 101 (e)
|
||||
0x00, 0x38, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00, // Char 102 (f)
|
||||
0x00, 0x00, 0x7C, 0x66, 0x7C, 0x40, 0x3C, 0x00, // Char 103 (g)
|
||||
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x00, // Char 104 (h)
|
||||
0x00, 0x18, 0x00, 0x1C, 0x18, 0x18, 0x3C, 0x00, // Char 105 (i)
|
||||
0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1E, 0x00, // Char 106 (j)
|
||||
0x00, 0x06, 0x06, 0x36, 0x1E, 0x36, 0x66, 0x00, // Char 107 (k)
|
||||
0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 108 (l)
|
||||
0x00, 0x00, 0x66, 0xFE, 0xFE, 0xD6, 0xC6, 0x00, // Char 109 (m)
|
||||
0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00, // Char 110 (n)
|
||||
0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 111 (o)
|
||||
0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x00, // Char 112 (p)
|
||||
0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00, // Char 113 (q)
|
||||
0x00, 0x00, 0x3E, 0x66, 0x06, 0x06, 0x06, 0x00, // Char 114 (r)
|
||||
0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00, // Char 115 (s)
|
||||
0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x70, 0x00, // Char 116 (t)
|
||||
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00, // Char 117 (u)
|
||||
0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, // Char 118 (v)
|
||||
0x00, 0x00, 0xC6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00, // Char 119 (w)
|
||||
0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, // Char 120 (x)
|
||||
0x00, 0x00, 0x66, 0x66, 0x7C, 0x60, 0x3C, 0x00, // Char 121 (y)
|
||||
0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00, // Char 122 (z)
|
||||
0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08, 0x18, // Char 123 ({)
|
||||
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // Char 124 (|)
|
||||
0x00, 0x0C, 0x08, 0x08, 0x10, 0x08, 0x08, 0x0C, // Char 125 (})
|
||||
0x00, 0x00, 0x00, 0x4C, 0x32, 0x00, 0x00, 0x00 // Char 126 (~)
|
||||
};
|
||||
|
||||
void gfx_init_ctxt(gfx_ctxt_t *ctxt, u32 *fb, u32 width, u32 height, u32 stride)
|
||||
{
|
||||
ctxt->fb = fb;
|
||||
ctxt->width = width;
|
||||
ctxt->height = height;
|
||||
ctxt->stride = stride;
|
||||
}
|
||||
|
||||
void gfx_clear_grey(gfx_ctxt_t *ctxt, u8 color)
|
||||
{
|
||||
memset(ctxt->fb, color, 0x3C0000);
|
||||
}
|
||||
|
||||
void gfx_clear_color(gfx_ctxt_t *ctxt, u32 color)
|
||||
{
|
||||
for (u32 i = 0; i < ctxt->height * ctxt->stride; i++)
|
||||
ctxt->fb[i] = color;
|
||||
}
|
||||
|
||||
void gfx_clear_partial_grey(gfx_ctxt_t *ctxt, u8 color, u32 pos_x, u32 height)
|
||||
{
|
||||
memset(ctxt->fb + pos_x * ctxt->stride, color, height * 4 * ctxt->stride);
|
||||
}
|
||||
|
||||
void gfx_con_init(gfx_con_t *con, gfx_ctxt_t *ctxt)
|
||||
{
|
||||
con->gfx_ctxt = ctxt;
|
||||
con->fntsz = 16;
|
||||
con->x = 0;
|
||||
con->y = 0;
|
||||
con->savedx = 0;
|
||||
con->savedy = 0;
|
||||
con->fgcol = 0xFFCCCCCC;
|
||||
con->fillbg = 0;
|
||||
con->bgcol = 0xFF1B1B1B;
|
||||
con->mute = 0;
|
||||
}
|
||||
|
||||
void gfx_con_setcol(gfx_con_t *con, u32 fgcol, int fillbg, u32 bgcol)
|
||||
{
|
||||
con->fgcol = fgcol;
|
||||
con->fillbg = fillbg;
|
||||
con->bgcol = bgcol;
|
||||
}
|
||||
|
||||
void gfx_con_getpos(gfx_con_t *con, u32 *x, u32 *y)
|
||||
{
|
||||
*x = con->x;
|
||||
*y = con->y;
|
||||
}
|
||||
|
||||
void gfx_con_setpos(gfx_con_t *con, u32 x, u32 y)
|
||||
{
|
||||
con->x = x;
|
||||
con->y = y;
|
||||
}
|
||||
|
||||
void gfx_putc(gfx_con_t *con, char c)
|
||||
{
|
||||
// Duplicate code for performance reasons.
|
||||
switch (con->fntsz)
|
||||
{
|
||||
case 16:
|
||||
if (c >= 32 && c <= 126)
|
||||
{
|
||||
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 < 16; i+=2)
|
||||
{
|
||||
u8 v = *cbuf++;
|
||||
for (u32 k = 0; k < 2; k++)
|
||||
{
|
||||
for (u32 j = 0; j < 8; j++)
|
||||
{
|
||||
if (v & 1)
|
||||
{
|
||||
*fb = con->fgcol;
|
||||
fb++;
|
||||
*fb = con->fgcol;
|
||||
}
|
||||
else if (con->fillbg)
|
||||
{
|
||||
*fb = con->bgcol;
|
||||
fb++;
|
||||
*fb = con->bgcol;
|
||||
}
|
||||
else
|
||||
fb++;
|
||||
v >>= 1;
|
||||
fb++;
|
||||
}
|
||||
fb += con->gfx_ctxt->stride - 16;
|
||||
v = *cbuf;
|
||||
}
|
||||
}
|
||||
con->x += 16;
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
con->x = 0;
|
||||
con->y +=16;
|
||||
if (con->y > con->gfx_ctxt->height - 16)
|
||||
con->y = 0;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
default:
|
||||
if (c >= 32 && c <= 126)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
u8 v = *cbuf++;
|
||||
for (u32 j = 0; j < 8; j++)
|
||||
{
|
||||
if (v & 1)
|
||||
*fb = con->fgcol;
|
||||
else if (con->fillbg)
|
||||
*fb = con->bgcol;
|
||||
v >>= 1;
|
||||
fb++;
|
||||
}
|
||||
fb += con->gfx_ctxt->stride - 8;
|
||||
}
|
||||
con->x += 8;
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
con->x = 0;
|
||||
con->y += 8;
|
||||
if (con->y > con->gfx_ctxt->height - 8)
|
||||
con->y = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void gfx_puts(gfx_con_t *con, const char *s)
|
||||
{
|
||||
if (!s || con->mute)
|
||||
return;
|
||||
|
||||
for (; *s; s++)
|
||||
gfx_putc(con, *s);
|
||||
}
|
||||
|
||||
static void _gfx_putn(gfx_con_t *con, u32 v, int base, char fill, int fcnt)
|
||||
{
|
||||
char buf[65];
|
||||
static const char digits[] = "0123456789ABCDEFghijklmnopqrstuvwxyz";
|
||||
char *p;
|
||||
int c = fcnt;
|
||||
|
||||
if (base > 36)
|
||||
return;
|
||||
|
||||
p = buf + 64;
|
||||
*p = 0;
|
||||
do
|
||||
{
|
||||
c--;
|
||||
*--p = digits[v % base];
|
||||
v /= base;
|
||||
} while (v);
|
||||
|
||||
if (fill != 0)
|
||||
{
|
||||
while (c > 0)
|
||||
{
|
||||
*--p = fill;
|
||||
c--;
|
||||
}
|
||||
}
|
||||
|
||||
gfx_puts(con, p);
|
||||
}
|
||||
|
||||
void gfx_put_small_sep(gfx_con_t *con)
|
||||
{
|
||||
u8 prevFontSize = con->fntsz;
|
||||
con->fntsz = 8;
|
||||
gfx_putc(con, '\n');
|
||||
con->fntsz = prevFontSize;
|
||||
}
|
||||
|
||||
void gfx_put_big_sep(gfx_con_t *con)
|
||||
{
|
||||
u8 prevFontSize = con->fntsz;
|
||||
con->fntsz = 16;
|
||||
gfx_putc(con, '\n');
|
||||
con->fntsz = prevFontSize;
|
||||
}
|
||||
|
||||
void gfx_printf(gfx_con_t *con, const char *fmt, ...)
|
||||
{
|
||||
if (con->mute)
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
int fill, fcnt;
|
||||
|
||||
va_start(ap, fmt);
|
||||
while(*fmt)
|
||||
{
|
||||
if(*fmt == '%')
|
||||
{
|
||||
fmt++;
|
||||
fill = 0;
|
||||
fcnt = 0;
|
||||
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
|
||||
{
|
||||
fcnt = *fmt;
|
||||
fmt++;
|
||||
if (*fmt >= '0' && *fmt <= '9')
|
||||
{
|
||||
fill = fcnt;
|
||||
fcnt = *fmt - '0';
|
||||
fmt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fill = ' ';
|
||||
fcnt -= '0';
|
||||
}
|
||||
}
|
||||
switch(*fmt)
|
||||
{
|
||||
case 'c':
|
||||
gfx_putc(con, va_arg(ap, u32));
|
||||
break;
|
||||
case 's':
|
||||
gfx_puts(con, va_arg(ap, char *));
|
||||
break;
|
||||
case 'd':
|
||||
_gfx_putn(con, va_arg(ap, u32), 10, fill, fcnt);
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
case 'x':
|
||||
case 'X':
|
||||
_gfx_putn(con, va_arg(ap, u32), 16, fill, fcnt);
|
||||
break;
|
||||
case 'k':
|
||||
con->fgcol = va_arg(ap, u32);
|
||||
break;
|
||||
case 'K':
|
||||
con->bgcol = va_arg(ap, u32);
|
||||
con->fillbg = 1;
|
||||
break;
|
||||
case '%':
|
||||
gfx_putc(con, '%');
|
||||
break;
|
||||
case '\0':
|
||||
goto out;
|
||||
default:
|
||||
gfx_putc(con, '%');
|
||||
gfx_putc(con, *fmt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
gfx_putc(con, *fmt);
|
||||
fmt++;
|
||||
}
|
||||
|
||||
out:
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void gfx_hexdump(gfx_con_t *con, u32 base, const u8 *buf, u32 len)
|
||||
{
|
||||
if (con->mute)
|
||||
return;
|
||||
|
||||
u8 prevFontSize = con->fntsz;
|
||||
con->fntsz = 8;
|
||||
for(u32 i = 0; i < len; i++)
|
||||
{
|
||||
if(i % 0x10 == 0)
|
||||
{
|
||||
if(i != 0)
|
||||
{
|
||||
gfx_puts(con, "| ");
|
||||
for(u32 j = 0; j < 0x10; j++)
|
||||
{
|
||||
u8 c = buf[i - 0x10 + j];
|
||||
if(c >= 32 && c <= 126)
|
||||
gfx_putc(con, c);
|
||||
else
|
||||
gfx_putc(con, '.');
|
||||
}
|
||||
gfx_putc(con, '\n');
|
||||
}
|
||||
gfx_printf(con, "%08x: ", base + i);
|
||||
}
|
||||
gfx_printf(con, "%02x ", buf[i]);
|
||||
if (i == len - 1)
|
||||
{
|
||||
int ln = len % 0x10 != 0;
|
||||
u32 k = 0x10 - 1;
|
||||
if (ln)
|
||||
{
|
||||
k = (len & 0xF) - 1;
|
||||
for (u32 j = 0; j < 0x10 - k; j++)
|
||||
gfx_puts(con, " ");
|
||||
}
|
||||
gfx_puts(con, "| ");
|
||||
for(u32 j = 0; j < (ln ? k : k + 1); j++)
|
||||
{
|
||||
u8 c = buf[i - k + j];
|
||||
if(c >= 32 && c <= 126)
|
||||
gfx_putc(con, c);
|
||||
else
|
||||
gfx_putc(con, '.');
|
||||
}
|
||||
gfx_putc(con, '\n');
|
||||
}
|
||||
}
|
||||
gfx_putc(con, '\n');
|
||||
con->fntsz = prevFontSize;
|
||||
}
|
||||
|
||||
static int abs(int x)
|
||||
{
|
||||
if (x < 0)
|
||||
return -x;
|
||||
return x;
|
||||
}
|
||||
|
||||
void gfx_set_pixel(gfx_ctxt_t *ctxt, u32 x, u32 y, u32 color)
|
||||
{
|
||||
ctxt->fb[x + y * ctxt->stride] = 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 err = (dx > dy ? dx : -dy) / 2, e2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
gfx_set_pixel(ctxt, x0, y0, color);
|
||||
if (x0 == x1 && y0 == y1)
|
||||
break;
|
||||
e2 = err;
|
||||
if (e2 >-dx)
|
||||
{
|
||||
err -= dy;
|
||||
x0 += sx;
|
||||
}
|
||||
if (e2 < dy)
|
||||
{
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_set_rect_grey(gfx_ctxt_t *ctxt, const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)
|
||||
{
|
||||
u32 pos = 0;
|
||||
for (u32 y = pos_y; y < (pos_y + size_y); y++)
|
||||
{
|
||||
for (u32 x = pos_x; x < (pos_x + size_x); x++)
|
||||
{
|
||||
memset(&ctxt->fb[x + y*ctxt->stride], buf[pos], 4);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void gfx_set_rect_rgb(gfx_ctxt_t *ctxt, const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)
|
||||
{
|
||||
u32 pos = 0;
|
||||
for (u32 y = pos_y; y < (pos_y + size_y); y++)
|
||||
{
|
||||
for (u32 x = pos_x; x < (pos_x + size_x); x++)
|
||||
{
|
||||
ctxt->fb[x + y*ctxt->stride] = buf[pos + 2] | (buf[pos + 1] << 8) | (buf[pos] << 16);
|
||||
pos+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_set_rect_argb(gfx_ctxt_t *ctxt, const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)
|
||||
{
|
||||
u32 *ptr = (u32 *)buf;
|
||||
for (u32 y = pos_y; y < (pos_y + size_y); y++)
|
||||
for (u32 x = pos_x; x < (pos_x + size_x); x++)
|
||||
ctxt->fb[x + y * ctxt->stride] = *ptr++;
|
||||
}
|
||||
|
||||
void gfx_render_bmp_argb(gfx_ctxt_t *ctxt, const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)
|
||||
{
|
||||
for (u32 y = pos_y; y < (pos_y + size_y); y++)
|
||||
{
|
||||
for (u32 x = pos_x; x < (pos_x + size_x); x++)
|
||||
ctxt->fb[x + y * ctxt->stride] = buf[(size_y + pos_y - 1 - y ) * size_x + x - pos_x];
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (C) 2018 M4xw
|
||||
*
|
||||
* 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 _GFX_H_
|
||||
#define _GFX_H_
|
||||
|
||||
#include "../../common/common_gfx.h"
|
||||
|
||||
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_partial_grey(gfx_ctxt_t *ctxt, u8 color, u32 pos_x, u32 height);
|
||||
void gfx_clear_color(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_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, ...);
|
||||
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_put_small_sep(gfx_con_t *con);
|
||||
void gfx_put_big_sep(gfx_con_t *con);
|
||||
void gfx_set_rect_grey(gfx_ctxt_t *ctxt, const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||
void gfx_set_rect_rgb(gfx_ctxt_t *ctxt, const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||
void gfx_set_rect_argb(gfx_ctxt_t *ctxt, const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||
void gfx_render_bmp_argb(gfx_ctxt_t *ctxt, const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||
|
||||
#endif
|
||||
@@ -1,931 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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 _HEKATE_LOGOS_H_
|
||||
#define _HEKATE_LOGOS_H_
|
||||
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
// 119 x 57 @24bpp RGB RAW positioned at 577 x 1199
|
||||
#define SZ_MENU_LOGO 20349
|
||||
#define SZ_MENU_LOGO_BLZ 7592
|
||||
static unsigned char Kc_MENU_LOGO_blz[SZ_MENU_LOGO_BLZ] = {
|
||||
0x01, 0x10, 0x80, 0x2D, 0xF0, 0x99, 0x30, 0x84, 0xB0, 0x1C, 0x6C, 0x60, 0x51, 0xF0, 0x59, 0x31,
|
||||
0x03, 0x30, 0xF7, 0x0F, 0xF0, 0x0F, 0xF0, 0x42, 0xF0, 0xFE, 0xF4, 0x15, 0x6C, 0xCF, 0x30, 0xCC,
|
||||
0x20, 0x1D, 0x7F, 0x1F, 0x52, 0x6D, 0xD8, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0xC9, 0xF0, 0xBE, 0xF2, 0x2A, 0x00, 0x75, 0x1F,
|
||||
0x5D, 0x10, 0x36, 0x7F, 0x84, 0x10, 0x7E, 0x00, 0x85, 0x0B, 0x72, 0x00, 0x6C, 0x00, 0x54, 0x40,
|
||||
0x1A, 0x42, 0x8F, 0xBF, 0x21, 0xCF, 0x1F, 0x33, 0x00, 0x03, 0x20, 0x0F, 0xF0, 0x09, 0x90, 0x03,
|
||||
0x30, 0x00, 0x00, 0xFE, 0x33, 0x20, 0x9E, 0x01, 0x2D, 0x19, 0xF0, 0x10, 0x20, 0x49, 0x02, 0x30,
|
||||
0x60, 0xD3, 0x08, 0x81, 0x23, 0x19, 0x1B, 0x2B, 0x19, 0x1B, 0x33, 0x01, 0x18, 0x1B, 0x38, 0x18,
|
||||
0x2B, 0x05, 0x1B, 0x36, 0x18, 0x10, 0xF6, 0x00, 0xDC, 0x1E, 0x20, 0xE1, 0x30, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFB, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xD8, 0xF0,
|
||||
0x3A, 0xFE, 0xAE, 0x00, 0x43, 0x2B, 0xFF, 0x2F, 0x19, 0x1B, 0x4A, 0x15, 0x1C, 0x6A, 0x11, 0x00,
|
||||
0x1D, 0x8A, 0x0E, 0x1E, 0xAD, 0x09, 0x1E, 0xB7, 0x00, 0x81, 0x00, 0x07, 0x1E, 0xA6, 0x0A, 0x1E,
|
||||
0x87, 0x0F, 0x01, 0x1E, 0x60, 0x13, 0x1D, 0x3E, 0x17, 0xEC, 0x51, 0x51, 0x40, 0xC0, 0xB3, 0x01,
|
||||
0x1C, 0x6D, 0x12, 0x1D, 0x96, 0x09, 0x80, 0x0F, 0xF0, 0xC1, 0x09, 0x90, 0x03, 0x30, 0x00, 0x00,
|
||||
0x97, 0x0C, 0x94, 0x15, 0x80, 0x10, 0x27, 0x1E, 0x37, 0x17, 0x54, 0xA9, 0x1E, 0x8F, 0x1D, 0x1C,
|
||||
0x37, 0x28, 0x17, 0x1C, 0x57, 0x13, 0x1C, 0x73, 0x11, 0x1D, 0x00, 0xA8, 0x09, 0xB3, 0x08, 0x1E,
|
||||
0xB5, 0x08, 0x1E, 0xB1, 0x01, 0x09, 0x1E, 0x9F, 0x0C, 0x1E, 0x74, 0x10, 0x1D, 0x00, 0x53, 0x13,
|
||||
0x1C, 0x31, 0x18, 0xD0, 0x02, 0x35, 0xF4, 0x0F, 0xF0, 0xE0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xDA, 0xF0, 0x35, 0xFD, 0xFF, 0x62, 0x04, 0xA6, 0x18, 0x7D,
|
||||
0x10, 0x1D, 0xC6, 0x06, 0x1E, 0x03, 0xF4, 0x01, 0x2A, 0xF0, 0x20, 0xF1, 0x01, 0x20, 0xC1, 0x04,
|
||||
0x07, 0x1E, 0xEC, 0x01, 0x2A, 0x1A, 0x08, 0x0D, 0xD8, 0x49, 0x40, 0x64, 0xC7, 0x52, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x30, 0xF0, 0x1B, 0x00, 0x59, 0x13, 0xEC, 0x27, 0x9F, 0x17, 0x57, 0x30, 0x18, 0x1B,
|
||||
0x51, 0x15, 0x1C, 0x98, 0x01, 0x0B, 0x1D, 0xBA, 0x03, 0xFB, 0xD8, 0xF0, 0x00, 0x20, 0xE5, 0x14,
|
||||
0x03, 0x1F, 0xA4, 0x0B, 0x1E, 0x4B, 0x16, 0x1C, 0x00, 0xAE, 0x03, 0x1D, 0x65, 0x81, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFD, 0x0F, 0xF0, 0x0F, 0xF0, 0xDF, 0xF0, 0xE7,
|
||||
0xF9, 0x2D, 0x18, 0x1B, 0x4E, 0x0F, 0x15, 0x1C, 0xA8, 0x09, 0x1E, 0xF7, 0x23, 0x14, 0x30, 0xF0,
|
||||
0xC0, 0x0E, 0xA4, 0x99, 0x0C, 0x1E, 0x35, 0x93, 0x18, 0x62, 0x11, 0x47, 0x61, 0xE3, 0x0A, 0x4E,
|
||||
0x50, 0x0F, 0xF0, 0x36, 0xF0, 0x62, 0xF1, 0x5F, 0x13, 0x1C, 0x1F, 0x36, 0x07, 0x19, 0xB5, 0x15,
|
||||
0x1A, 0x07, 0x1B, 0x69, 0x11, 0x1C, 0x0D, 0xD0, 0xC1, 0x42, 0xD5, 0xF0, 0x9A, 0xA5, 0x6D, 0x11,
|
||||
0x1D, 0x26, 0x0E, 0xDE, 0x00, 0x9C, 0x00, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xE7, 0xF0, 0xA4, 0xF7, 0xE6, 0x11, 0x09, 0x19, 0xBE, 0x08,
|
||||
0x36, 0xA0, 0x9F, 0x2A, 0xF0, 0xE7, 0xAC, 0x0B, 0x1F, 0x2D, 0x19, 0x48, 0x10, 0x3A, 0x43, 0x17,
|
||||
0x1C, 0xC3, 0x36, 0xB3, 0x0F, 0xF0, 0x2D, 0xF0, 0xD3, 0x95, 0xE2, 0x02, 0xF8, 0x11, 0x1D, 0x5B,
|
||||
0x12, 0x31, 0x18, 0x1C, 0x72, 0x11, 0x04, 0x2C, 0xA1, 0x0C, 0xC0, 0xC0, 0xC0, 0xF4, 0x01, 0x20,
|
||||
0x6C, 0x11, 0x07, 0xFA, 0x18, 0x1C, 0x62, 0xC1, 0x36, 0xF0, 0x0F, 0xF0, 0x23, 0xF0, 0x45, 0xF0,
|
||||
0x35, 0xF1, 0xFD, 0x0F, 0xF0, 0x13, 0xF1, 0x11, 0xF1, 0x99, 0x03, 0xE5, 0x25, 0x3C, 0x00, 0x1E,
|
||||
0xC0, 0xCF, 0x7F, 0x06, 0x1E, 0x99, 0x0B, 0x1E, 0x81, 0x0F, 0x1E, 0x00, 0x38, 0x04, 0xA1, 0x0B,
|
||||
0x1E, 0xDA, 0x56, 0x27, 0x60, 0x90, 0x7C, 0x61, 0x10, 0x1D, 0x23, 0xCE, 0x21, 0xC3, 0x06, 0xA8,
|
||||
0x27, 0x50, 0x1B, 0x30, 0xD8, 0xA7, 0x0A, 0x1E, 0xAA, 0x09, 0x1E, 0xE5, 0x03, 0x00, 0x20, 0xBE,
|
||||
0x95, 0xB1, 0x09, 0x1F, 0x03, 0x00, 0xA4, 0x03, 0x30, 0xA2, 0x0A, 0x1E, 0x00, 0x00, 0x47, 0x04,
|
||||
0x95, 0x0D, 0x1E, 0x36, 0x0C, 0x18, 0x1B, 0x16, 0xCF, 0x23, 0x5F, 0x13, 0x1D, 0xD7, 0x08, 0x33,
|
||||
0x19, 0xC1, 0xA2, 0x2B, 0x02, 0x8D, 0x0E, 0x1E, 0x7E, 0x10, 0x07, 0x1E, 0x8C, 0x0E, 0x1E, 0xB8,
|
||||
0x08, 0x1E, 0xED, 0x00, 0x81, 0x23, 0x3E, 0x9D, 0x45, 0x16, 0xCC, 0xF6, 0x1B, 0x3C, 0x90, 0x36,
|
||||
0x60, 0xD3, 0x65, 0xF1, 0x2A, 0xF0, 0x33, 0xC0, 0xB1, 0xC9, 0x29, 0xF1, 0x96, 0x99, 0x15, 0x9C,
|
||||
0x34, 0x75, 0xFF, 0xB9, 0x21, 0x2C, 0x19, 0x1B, 0x77, 0xD5, 0x0F, 0x77, 0x87, 0x64, 0x0E, 0xE1,
|
||||
0x89, 0x0D, 0x1E, 0x14, 0x07, 0x1E, 0x81, 0x20, 0x1E, 0x66, 0x1F, 0xA8, 0x5C, 0x14, 0xAA, 0x0A,
|
||||
0x1E, 0xFE, 0x5D, 0x80, 0xDA, 0x9D, 0x22, 0xA1, 0x21, 0x1A, 0xC3, 0x3F, 0x27, 0xA0, 0x25, 0x19,
|
||||
0x1B, 0x41, 0x0C, 0x17, 0x1C, 0xCD, 0x54, 0x80, 0x86, 0x01, 0xF9, 0x00, 0x3E, 0x07, 0x1E, 0x78,
|
||||
0x03, 0x20, 0x20, 0x9C, 0x3F, 0xDB, 0x19, 0x36, 0x49, 0x40, 0x17, 0x1C, 0x1D, 0xAD, 0x0A, 0xDB,
|
||||
0xA0, 0xDB, 0x04, 0x69, 0x16, 0x06, 0x00, 0x1D, 0x64, 0xEE, 0x0E, 0xE5, 0x1E, 0xFB, 0x0A, 0x1B,
|
||||
0x61, 0x13, 0x1D, 0xD2, 0x07, 0xDE, 0xB0, 0x7B, 0x03, 0x24, 0x1A, 0x1C, 0x19, 0x93, 0xE9, 0x77,
|
||||
0x01, 0xC3, 0x36, 0x00, 0xC8, 0x31, 0x30, 0x00, 0x36, 0xC0, 0x33, 0xF0, 0x1B, 0x40, 0x82, 0x22,
|
||||
0xA6, 0x02, 0xFF, 0x00, 0x00, 0x33, 0x90, 0xD3, 0x32, 0x2C, 0xF1, 0xB9, 0x6A, 0xB5, 0x32, 0x03,
|
||||
0x00, 0x4D, 0x01, 0xFF, 0xA0, 0x02, 0x32, 0x01, 0xF9, 0x00, 0x04, 0x12, 0xC1, 0x25, 0x48, 0x16,
|
||||
0x1C, 0x1F, 0xBC, 0x08, 0x8C, 0xA1, 0x97, 0x0D, 0x1E, 0x16, 0x54, 0xC0, 0x84, 0x27, 0x3F, 0x17,
|
||||
0x1C, 0xC5, 0x06, 0x1F, 0x62, 0x91, 0x7B, 0x41, 0x0F, 0x1D, 0x1C, 0x0C, 0x20, 0x18, 0x27, 0x80,
|
||||
0x17, 0xBC, 0x21, 0xA8, 0x3D, 0x62, 0xE1, 0x42, 0x16, 0xBE, 0x15, 0x17, 0x06, 0x50, 0x19, 0x52,
|
||||
0x83, 0x81, 0x2A, 0xDB, 0x10, 0x6D, 0x12, 0x07, 0x75, 0x01, 0x1F, 0x54, 0x1D, 0x14, 0x1C, 0x11,
|
||||
0x1C, 0x5F, 0x41, 0x29, 0x41, 0xD6, 0x2B, 0x66, 0x70, 0x13, 0x1D, 0xED, 0x43, 0x72, 0x20, 0xE0,
|
||||
0x03, 0x1F, 0x08, 0x43, 0xFF, 0x03, 0x13, 0x52, 0xB2, 0x38, 0x7D, 0x01, 0x30, 0x30, 0x30, 0x1E,
|
||||
0xE7, 0x09, 0x72, 0x00, 0x59, 0x59, 0x59, 0xA4, 0x01, 0x45, 0x45, 0x23, 0x45, 0x28, 0x0B, 0x39,
|
||||
0x00, 0x69, 0x00, 0x36, 0x90, 0x7B, 0xF9, 0xA9, 0x02, 0x5C, 0x01, 0xFE, 0xF4, 0x02, 0x00, 0x00,
|
||||
0x1E, 0x0F, 0xF5, 0x0A, 0x73, 0x05, 0x44, 0x01, 0xA3, 0x02, 0x1A, 0xC7, 0xFF, 0xC5, 0x3A, 0x00,
|
||||
0x00, 0xBC, 0x0A, 0x44, 0x01, 0xE7, 0x00, 0x3A, 0x05, 0xE7, 0x00, 0xD0, 0x0E, 0xFF, 0x46, 0x46,
|
||||
0x46, 0x9A, 0x02, 0xD2, 0x00, 0x1B, 0x00, 0x28, 0x19, 0x38, 0x1B, 0x67, 0x12, 0x1D, 0xEF, 0x02,
|
||||
0xF3, 0xA6, 0x3B, 0x40, 0x18, 0x1C, 0x12, 0x51, 0x3F, 0x65, 0x61, 0xB2, 0x38, 0x19, 0x1B, 0x38,
|
||||
0x85, 0x0F, 0x57, 0xA0, 0xAC, 0x09, 0x1E, 0x19, 0x1C, 0x04, 0x19, 0x2B, 0x2A, 0x90, 0x9D, 0x22,
|
||||
0x3E, 0x62, 0xE1, 0x43, 0x16, 0x8F, 0x11, 0x97, 0x56, 0x14, 0xB4, 0x66, 0x86, 0x5D, 0x3E, 0x04,
|
||||
0x9D, 0x0B, 0xF3, 0xA6, 0xA5, 0x4F, 0x0A, 0x1E, 0x3D, 0x6B, 0x1A, 0x9D, 0x65, 0xA8, 0x23, 0x35,
|
||||
0x18, 0x34, 0x1C, 0xBD, 0x08, 0x1F, 0x13, 0x92, 0x61, 0x13, 0xFA, 0x12, 0x90, 0x19, 0x5B, 0x2E,
|
||||
0x26, 0x04, 0x47, 0x04, 0x52, 0x52, 0x52, 0xA3, 0x0E, 0xA3, 0xA3, 0x85, 0x08, 0xA7, 0x01, 0x36,
|
||||
0x00, 0x39, 0x00, 0x65, 0x01, 0x1B, 0x03, 0xFC, 0x55, 0x55, 0x55, 0x48, 0x00, 0x65, 0x01, 0x4C,
|
||||
0xF3, 0x89, 0x01, 0x28, 0x78, 0x28, 0x28, 0xA3, 0x02, 0x18, 0x0F, 0x49, 0x05, 0xD2, 0x06, 0x20,
|
||||
0x01, 0xD7, 0x0D, 0xFC, 0x45, 0x0C, 0x7D, 0x01, 0x30, 0x00, 0xB2, 0x02, 0xCA, 0x12, 0x84, 0x86,
|
||||
0x62, 0x01, 0x69, 0x7F, 0x69, 0x69, 0x87, 0x09, 0xB9, 0x0A, 0x35, 0x35, 0x35, 0x6D, 0x0C, 0x6D,
|
||||
0x6D, 0xBC, 0xBC, 0xBC, 0xCF, 0x03, 0x06, 0x0F, 0x4D, 0x01, 0xE0, 0x54, 0x54, 0x54, 0xC1, 0x02,
|
||||
0xEF, 0x1D, 0x19, 0x1B, 0x8D, 0x18, 0x0E, 0xB1, 0x90, 0x21, 0x9A, 0x0C, 0x1E, 0x14, 0x2D, 0x00,
|
||||
0x82, 0xEF, 0xFD, 0x11, 0x2D, 0x50, 0x15, 0x1C, 0xEF, 0x02, 0x27, 0x7F, 0x83, 0xC3, 0x08, 0x20,
|
||||
0x6F, 0x00, 0x17, 0xE8, 0x35, 0x62, 0xF1, 0x62, 0xF1, 0xE8, 0xEF, 0xFD, 0x8A, 0x2C, 0x3E, 0x17,
|
||||
0x1C, 0xC4, 0x35, 0x81, 0xF1, 0x0E, 0xC3, 0x57, 0x14, 0x9E, 0x3A, 0xAB, 0xF3, 0x46, 0x12, 0x92,
|
||||
0x0D, 0x1D, 0x1C, 0x61, 0x95, 0x92, 0x0E, 0xD6, 0x0B, 0x1A, 0x1A, 0xC4, 0x02, 0x28, 0x49, 0x28,
|
||||
0xB2, 0x08, 0xBC, 0x01, 0x55, 0x0B, 0x5F, 0x07, 0x9A, 0x9A, 0x9A, 0x1E, 0x03, 0x00, 0x75, 0x75,
|
||||
0x75, 0xCC, 0x09, 0x5D, 0x00, 0xD4, 0xD4, 0x31, 0xD4, 0xEF, 0xEF, 0xEF, 0x84, 0x84, 0x84, 0x3B,
|
||||
0x04, 0x80, 0x88, 0x05, 0x24, 0x63, 0x8A, 0x39, 0xE5, 0x02, 0xD4, 0x0D, 0xA1, 0xA1, 0xA1, 0x1F,
|
||||
0xF2, 0xF2, 0xF2, 0xCA, 0xCA, 0xCA, 0xA6, 0x05, 0x00, 0x00, 0xC0, 0x78, 0x78, 0x78, 0x98, 0x98,
|
||||
0x98, 0xE0, 0x0A, 0x70, 0x02, 0xC0, 0x37, 0x05, 0x3B, 0x01, 0x23, 0x04, 0x62, 0x31, 0x57, 0x09,
|
||||
0xC3, 0x03, 0x68, 0x01, 0x87, 0x09, 0xFF, 0x4C, 0x4C, 0x4C, 0x97, 0x97, 0x97, 0x88, 0x02, 0x4F,
|
||||
0x08, 0xC0, 0x87, 0x87, 0x87, 0x20, 0x01, 0xCC, 0x03, 0x2C, 0x01, 0xEA, 0x00, 0xA4, 0x01, 0xF8,
|
||||
0x3B, 0x17, 0x1C, 0xB4, 0x81, 0x8F, 0xE6, 0x0D, 0x74, 0x11, 0x30, 0x1D, 0x16, 0x11, 0x3D, 0x84,
|
||||
0xF0, 0x3A, 0x05, 0x19, 0x1C, 0x88, 0x1C, 0x0F, 0x1D, 0xAD, 0x0A, 0x1E, 0xA9, 0x0B, 0x7E, 0x10,
|
||||
0x80, 0x82, 0x10, 0x1D, 0xE0, 0x01, 0x16, 0x03, 0x30, 0x62, 0xF1, 0x62, 0xF1, 0xE8, 0x25, 0xFB,
|
||||
0xA5, 0x23, 0x5A, 0x13, 0x1C, 0xDF, 0xA5, 0x83, 0xD7, 0x43, 0x04, 0x1F, 0x38, 0x17, 0x25, 0x2B,
|
||||
0x43, 0xF2, 0x62, 0x21, 0x4F, 0x70, 0x15, 0x1C, 0xA1, 0x0C, 0x1E, 0xAE, 0x0A, 0x1E, 0x00, 0xA8,
|
||||
0x0B, 0x1E, 0xA5, 0x0B, 0x1E, 0x61, 0x14, 0x00, 0x08, 0x11, 0x22, 0x23, 0x23, 0x33, 0x33, 0x33,
|
||||
0xCA, 0x05, 0x81, 0xBC, 0x01, 0x7C, 0x08, 0x29, 0x07, 0x72, 0x30, 0x95, 0x01, 0xDE, 0x36, 0x50,
|
||||
0x07, 0x99, 0x7F, 0x99, 0x99, 0xFA, 0xFA, 0xFA, 0x34, 0x0B, 0x09, 0x00, 0xE8, 0x32, 0xE0, 0x2C,
|
||||
0x37, 0x29, 0x04, 0x79, 0x05, 0xB6, 0xB6, 0xB6, 0x12, 0x0F, 0x76, 0x47, 0x76, 0x76, 0xA0, 0x02,
|
||||
0x3D, 0x38, 0xA6, 0x32, 0x6F, 0x09, 0xDF, 0x02, 0x8A, 0x39, 0xFC, 0x35, 0x01, 0x46, 0x00, 0x21,
|
||||
0x30, 0x2C, 0x2C, 0x2C, 0x62, 0x01, 0x43, 0x08, 0xC7, 0xA9, 0xA9, 0xA9, 0x73, 0x02, 0x70, 0x70,
|
||||
0x70, 0x0C, 0x00, 0x88, 0x23, 0x01, 0xD3, 0x0E, 0xE1, 0x00, 0xE7, 0x00, 0x31, 0x02, 0x5B, 0x38,
|
||||
0xC9, 0x57, 0x80, 0xBF, 0xF2, 0x02, 0x5A, 0x0F, 0x1C, 0x1C, 0x4E, 0xC8, 0xF4, 0xE5, 0x38, 0x44,
|
||||
0x17, 0xF4, 0x81, 0x10, 0x24, 0xD3, 0x28, 0x1E, 0x2D, 0x70, 0x62, 0xF1, 0x62, 0xF1, 0xC7, 0xF2,
|
||||
0xF5, 0x72, 0x1F, 0x71, 0x11, 0x1D, 0xF2, 0xC0, 0x89, 0xC2, 0x06, 0x21, 0x1F, 0x32, 0x5B, 0x28,
|
||||
0x62, 0xF1, 0x47, 0x1A, 0xD7, 0x27, 0x23, 0x1C, 0x2B, 0xBC, 0x27, 0xCE, 0x07, 0x35, 0x0A, 0xFF,
|
||||
0x06, 0x1C, 0x1C, 0x91, 0x08, 0x63, 0x4E, 0x63, 0x63, 0xF4, 0xF4, 0xF4, 0x9B, 0x01, 0x2B, 0x0B,
|
||||
0x83, 0x01, 0xE0, 0x29, 0x94, 0x4B, 0x30, 0x0B, 0x04, 0xB0, 0xB0, 0xB0, 0x04, 0x0B, 0xAC, 0x05,
|
||||
0xC7, 0x65, 0x01, 0x1E, 0x30, 0x29, 0x04, 0x33, 0x00, 0x96, 0x96, 0x96, 0xF6, 0x0F, 0xF6, 0xF6,
|
||||
0x61, 0x61, 0x61, 0xC4, 0x02, 0x36, 0x60, 0x33, 0x60, 0xE0, 0x6E, 0x01, 0xA4, 0xA4, 0xA4, 0xF7,
|
||||
0xF7, 0xF7, 0x38, 0x01, 0x81, 0x1B, 0x00, 0xBA, 0x39, 0x97, 0x02, 0x2B, 0x08, 0x00, 0x00, 0xB2,
|
||||
0x02, 0x9C, 0x06, 0x4F, 0x02, 0xFF, 0xDE, 0x06, 0x5C, 0x61, 0xF6, 0x66, 0x49, 0x15, 0x47, 0xAA,
|
||||
0xE2, 0x03, 0x27, 0x14, 0x0D, 0xB8, 0x55, 0x87, 0xF0, 0x1E, 0x30, 0x81, 0x80, 0x19, 0x1C, 0x5C,
|
||||
0xB0, 0x9F, 0x62, 0xF1, 0x62, 0xF1, 0x43, 0xE5, 0x27, 0x1A, 0x7B, 0x0F, 0x1E, 0xF9, 0x27, 0x62,
|
||||
0x81, 0xAC, 0x0A, 0x1E, 0x2A, 0x91, 0xA5, 0xE1, 0xF0, 0x03, 0x30, 0xE1, 0x00, 0x00, 0x3B, 0x11,
|
||||
0x18, 0x62, 0x51, 0xB2, 0xB2, 0xB2, 0xCC, 0x0B, 0xCC, 0xCC, 0xC6, 0x09, 0x6F, 0x00, 0x0C, 0x30,
|
||||
0xEF, 0xCD, 0x9E, 0x01, 0xB6, 0x01, 0xFC, 0xE7, 0xE7, 0xE7, 0xCD, 0x05, 0x2C, 0x04, 0xB0, 0x31,
|
||||
0x0B, 0x04, 0x53, 0x78, 0x53, 0x53, 0x29, 0x04, 0x8A, 0x8A, 0x8A, 0x5A, 0x9F, 0x23, 0x61, 0xC4,
|
||||
0x60, 0x3F, 0xE2, 0x02, 0xD8, 0xD8, 0xD8, 0xB9, 0xB9, 0xB9, 0x03, 0x35, 0x04, 0x29, 0x01, 0x55,
|
||||
0x02, 0x62, 0x01, 0x03, 0x00, 0x62, 0x01, 0xDE, 0x06, 0x3E, 0x01, 0xFF, 0xEB, 0x6E, 0x62, 0xC1,
|
||||
0x4B, 0x62, 0xB1, 0xDB, 0x05, 0x1F, 0x2E, 0x0B, 0x19, 0x1E, 0x10, 0x62, 0xF1, 0x81, 0xF0, 0x60,
|
||||
0xF0, 0x62, 0xF1, 0x62, 0xF1, 0x62, 0xF1, 0xFE, 0xC7, 0xF2, 0xA2, 0x0C, 0x62, 0xE1, 0xA2, 0xF3,
|
||||
0x23, 0x31, 0x32, 0x8A, 0x2F, 0x79, 0x2F, 0x2F, 0xAF, 0xAF, 0xAF, 0x72, 0x0F, 0x0E, 0x0E, 0x20,
|
||||
0x0E, 0x75, 0x60, 0xE9, 0xCD, 0x86, 0x01, 0x4B, 0x4B, 0x4B, 0xD9, 0x0E, 0xD9, 0xD9, 0x91, 0x05,
|
||||
0x62, 0x01, 0x50, 0x31, 0xFF, 0x03, 0x9B, 0x9B, 0x3C, 0x9B, 0xD6, 0xD6, 0xD6, 0x72, 0x0F, 0xBD,
|
||||
0x39, 0x29, 0xC1, 0x73, 0x32, 0xF0, 0x02, 0x01, 0x54, 0x0C, 0xE5, 0xE5, 0xE5, 0x44, 0x44, 0x44,
|
||||
0x03, 0x62, 0x31, 0x31, 0x31, 0x31, 0xAB, 0xAB, 0xAB, 0x43, 0x05, 0x81, 0x15, 0x0C, 0x03, 0x00,
|
||||
0x15, 0x3C, 0x62, 0xF1, 0xD6, 0x0B, 0xE1, 0x62, 0x81, 0x8B, 0x0E, 0xDF, 0x2F, 0x62, 0x01, 0x62,
|
||||
0xF1, 0x0F, 0xF0, 0x63, 0xF0, 0x62, 0xF1, 0x62, 0xF1, 0x62, 0xF1, 0xFE, 0x90, 0x1C, 0x1C, 0x8A,
|
||||
0x62, 0xB1, 0xA4, 0x62, 0x51, 0x62, 0xF1, 0x9C, 0xF0, 0xE9, 0x49, 0x6E, 0x98, 0x01, 0x5A, 0x00,
|
||||
0x71, 0x01, 0x65, 0x01, 0xBB, 0x32, 0x2C, 0xC7, 0xD2, 0x39, 0xFF, 0x40, 0x40, 0x40, 0xD3, 0xD3,
|
||||
0xD3, 0xF6, 0x06, 0x12, 0x40, 0x12, 0x12, 0x62, 0x01, 0x12, 0x00, 0x97, 0x05, 0xD5, 0xD5, 0xD5,
|
||||
0x1C, 0x94, 0x94, 0x94, 0x7E, 0x3C, 0x0F, 0x00, 0x8E, 0xC5, 0x00, 0x00, 0x34, 0x08, 0xF8, 0x0F,
|
||||
0x00, 0x64, 0x64, 0x64, 0xED, 0x03, 0x6B, 0x6B, 0x6B, 0x11, 0x77, 0x31, 0x2D, 0x2D, 0x2D, 0xAA,
|
||||
0xAA, 0xAA, 0x50, 0x01, 0x81, 0x3B, 0x3B, 0x3B, 0xEF, 0x27, 0x2B, 0xE0, 0x88, 0x28, 0x4A, 0x15,
|
||||
0x38, 0x1C, 0xE0, 0x62, 0xB1, 0xD5, 0x0F, 0x86, 0xF4, 0x1B, 0x0F, 0xF0, 0x63, 0xF0, 0xDC, 0x62,
|
||||
0xF1, 0x62, 0xF1, 0x62, 0xF1, 0xC1, 0x15, 0x1C, 0x89, 0x0E, 0x0D, 0xA5, 0x8F, 0xA3, 0x0B, 0x1E,
|
||||
0x26, 0x1A, 0x9F, 0xD6, 0x0F, 0xF0, 0x90, 0xF0, 0xE0, 0x00, 0x00, 0x8F, 0x01, 0x17, 0x3A, 0x62,
|
||||
0x04, 0xB8, 0x02, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x7A, 0x01, 0x4A, 0x01, 0xA9, 0x02,
|
||||
0x49, 0x49, 0x49, 0xF6, 0x06, 0xC5, 0x0D, 0xC7, 0x2C, 0x34, 0xC3, 0x09, 0x44, 0x01, 0xA3, 0x02,
|
||||
0x66, 0x0F, 0x32, 0x32, 0x32, 0x1F, 0x38, 0x38, 0x38, 0x06, 0x60, 0x03, 0x30, 0x00, 0x00, 0xEF,
|
||||
0x0A, 0xAD, 0x0D, 0xF8, 0xD0, 0x02, 0x56, 0x56, 0x56, 0xDB, 0xDB, 0xDB, 0x84, 0x0C, 0x81, 0x12,
|
||||
0x00, 0x62, 0x61, 0x2C, 0x01, 0x62, 0x41, 0x62, 0xF1, 0xE5, 0x28, 0x47, 0x15, 0x3F, 0x1C, 0xD8,
|
||||
0xF9, 0x76, 0xBB, 0x1B, 0x33, 0x20, 0x00, 0x24, 0x60, 0x5E, 0xF5, 0xEC, 0x84, 0x80, 0x3B, 0xE1,
|
||||
0x62, 0xF1, 0x62, 0xF1, 0x62, 0xF1, 0xF9, 0x16, 0x80, 0x0F, 0x3F, 0x1D, 0xFD, 0x62, 0x81, 0xA6,
|
||||
0xB1, 0x1C, 0x62, 0xE1, 0x01, 0xE5, 0x1F, 0x12, 0xF4, 0x51, 0x36, 0x59, 0x87, 0x03, 0x03, 0xFC,
|
||||
0x09, 0xCC, 0x0C, 0x87, 0x0C, 0x13, 0x0B, 0x5D, 0x7F, 0x5D, 0x5D, 0x66, 0x66, 0x66, 0x00, 0x00,
|
||||
0x00, 0x00, 0x68, 0x60, 0x68, 0x68, 0x6C, 0x6C, 0x6C, 0x64, 0x0B, 0x39, 0x0F, 0xAC, 0x02, 0xE0,
|
||||
0x62, 0x31, 0xC7, 0x02, 0x72, 0x72, 0x72, 0xEE, 0xEE, 0xEE, 0x03, 0xE1, 0x06, 0xC2, 0xC2, 0xC2,
|
||||
0x00, 0x00, 0x09, 0x90, 0x03, 0x30, 0x00, 0x00, 0xF1, 0xC4, 0xC4, 0xC4, 0xC6, 0xC6, 0xC6, 0x51,
|
||||
0x0C, 0xF3, 0x40, 0xF3, 0xF3, 0xFC, 0x03, 0xE1, 0x33, 0x62, 0xD1, 0x62, 0xF1, 0xBA, 0x20, 0x69,
|
||||
0x00, 0xFC, 0xCC, 0x57, 0x80, 0xEB, 0x03, 0x20, 0x4F, 0x08, 0x2F, 0x84, 0x81, 0xF0, 0xE2, 0x09,
|
||||
0x10, 0x21, 0x84, 0x50, 0x1F, 0x1A, 0x1B, 0x1D, 0x5A, 0x90, 0x85, 0x62, 0xF1, 0x62, 0xF1, 0x94,
|
||||
0xC5, 0x70, 0x22, 0x74, 0x10, 0x1D, 0xF5, 0x0F, 0x43, 0x82, 0xB8, 0x08, 0x1E, 0x2F, 0x18, 0x1C,
|
||||
0x89, 0x8D, 0x81, 0x63, 0xFC, 0x71, 0x21, 0x54, 0x46, 0xFA, 0x6E, 0x5F, 0x11, 0x14, 0x07, 0x3C,
|
||||
0x3C, 0x3F, 0x3C, 0x6B, 0x01, 0xA5, 0x0C, 0xDA, 0xDA, 0xDA, 0x77, 0x01, 0x00, 0x00, 0xC6, 0x03,
|
||||
0x30, 0x22, 0x3E, 0xC0, 0x0C, 0x5B, 0x08, 0xEF, 0x0D, 0xC7, 0x32, 0x46, 0x08, 0x5E, 0x05, 0xFF,
|
||||
0xE4, 0x06, 0xB1, 0xB1, 0xB1, 0xA5, 0xA5, 0xA5, 0xA6, 0x01, 0xA6, 0xA6, 0x00, 0x00, 0x09, 0x90,
|
||||
0x03, 0x30, 0x00, 0x00, 0x12, 0x00, 0xE3, 0x0A, 0xFC, 0x95, 0x95, 0x95, 0xCC, 0x03, 0xC0, 0x69,
|
||||
0x62, 0xF1, 0x2D, 0xF0, 0x3C, 0x78, 0x18, 0x1C, 0xC3, 0x07, 0x57, 0x70, 0x9B, 0x07, 0x6A, 0x12,
|
||||
0x30, 0x1D, 0x9F, 0x3F, 0x1B, 0x20, 0xFA, 0x64, 0x25, 0x3D, 0x18, 0x87, 0x00, 0x9A, 0x81, 0x10,
|
||||
0x41, 0x16, 0x1C, 0x2D, 0x18, 0x1B, 0x23, 0x01, 0x59, 0x60, 0x62, 0xF1, 0x62, 0xF1, 0x2C, 0xF4,
|
||||
0xA8, 0x23, 0x67, 0x11, 0x1D, 0x1F, 0xEE, 0x20, 0x87, 0xCD, 0x05, 0x1F, 0x3A, 0x18, 0x1C, 0x02,
|
||||
0xDE, 0x10, 0xAD, 0xF0, 0xAD, 0x07, 0x1A, 0xAB, 0x00, 0x61, 0x15, 0x4E, 0x15, 0x37, 0x1C, 0xD2,
|
||||
0x00, 0x38, 0x18, 0x1C, 0x27, 0x19, 0xE9, 0x14, 0x82, 0x50, 0x04, 0x2D, 0x2E, 0x2E, 0x12, 0x00,
|
||||
0x6C, 0x00, 0xF9, 0xF9, 0x31, 0xF9, 0xD5, 0x0C, 0x18, 0x00, 0x64, 0x0B, 0x09, 0x00, 0x03, 0x00,
|
||||
0x58, 0x58, 0x3E, 0x58, 0xBD, 0x09, 0x5B, 0x5B, 0x5B, 0x6E, 0x6E, 0x6E, 0x02, 0xDD, 0xDD, 0xDD,
|
||||
0xBA, 0x09, 0xC7, 0x32, 0x2E, 0x08, 0x7F, 0x7F, 0x38, 0x7F, 0xDC, 0xDC, 0xDC, 0x07, 0x0E, 0x1E,
|
||||
0x1E, 0x1E, 0x10, 0x1B, 0x00, 0x00, 0x00, 0x09, 0x90, 0x03, 0x30, 0x00, 0x00, 0xDE, 0x06, 0xFF,
|
||||
0x03, 0x15, 0x00, 0xFF, 0x8E, 0x35, 0x62, 0x11, 0x62, 0xF1, 0x50, 0xFA, 0x83, 0x17, 0x1B, 0xDD,
|
||||
0xC4, 0xAF, 0x0B, 0xDF, 0x18, 0x84, 0x20, 0x1A, 0xD7, 0xED, 0x24, 0x1A, 0x1B, 0x4B, 0x0A, 0x15,
|
||||
0x1C, 0xC4, 0x07, 0x1E, 0xEA, 0x87, 0x20, 0xF0, 0x40, 0x02, 0x1F, 0xB3, 0x09, 0x1E, 0x2C, 0x1A,
|
||||
0x1B, 0x00, 0x15, 0x62, 0x81, 0x62, 0xF1, 0x62, 0xF1, 0x62, 0xF1, 0x4A, 0x16, 0x1C, 0x1E, 0xD5,
|
||||
0xF4, 0x82, 0xE8, 0x02, 0x20, 0x48, 0xFD, 0x07, 0x7D, 0x0D, 0xC2, 0x7B, 0xF3, 0xB0, 0x27, 0x79,
|
||||
0x0F, 0x1D, 0xE0, 0x04, 0x1F, 0x03, 0xE8, 0x02, 0x1F, 0x54, 0x06, 0xB4, 0x09, 0x85, 0x0E, 0x1C,
|
||||
0x18, 0x1E, 0x1E, 0x1D, 0x29, 0x2A, 0x2A, 0x5B, 0x5C, 0x00, 0x5C, 0x98, 0x01, 0x31, 0x0B, 0x8B,
|
||||
0x05, 0x24, 0x00, 0xD5, 0x0C, 0xAF, 0x38, 0x00, 0x00, 0xFE, 0x65, 0x01, 0x50, 0x01, 0x6B, 0x04,
|
||||
0x7B, 0x0C, 0xC3, 0x09, 0x62, 0x31, 0x0F, 0x00, 0x3A, 0x08, 0xFF, 0x71, 0x71, 0x71, 0xE4, 0x09,
|
||||
0x59, 0x59, 0x59, 0x62, 0x01, 0x88, 0x1A, 0x04, 0x00, 0x00, 0x09, 0x90, 0x20, 0x91, 0xC7, 0xF2,
|
||||
0x62, 0xF1, 0xC7, 0xF2, 0xB6, 0x07, 0xFF, 0x7A, 0x10, 0x1D, 0xFE, 0x79, 0x88, 0xB4, 0x08, 0x1E,
|
||||
0x10, 0x27, 0x19, 0x26, 0xBD, 0x75, 0x5C, 0x2F, 0x19, 0x1B, 0x72, 0x0C, 0x11, 0x1D, 0xF7, 0xAD,
|
||||
0x74, 0x21, 0xBE, 0x08, 0x1F, 0x08, 0x1E, 0x1B, 0x4F, 0x58, 0x62, 0xF1, 0x62, 0xF1, 0x35, 0xF1,
|
||||
0xE0, 0x27, 0x30, 0x7C, 0x19, 0x1C, 0xB7, 0x08, 0x2A, 0xA0, 0x69, 0x06, 0x20, 0x1A, 0x30, 0x09,
|
||||
0x20, 0xEE, 0xBB, 0x1E, 0x8C, 0x1A, 0x1C, 0xB2, 0x09, 0x7E, 0xA3, 0x8B, 0x7F, 0x0E, 0x1B, 0x20,
|
||||
0x23, 0x22, 0x3F, 0x41, 0x00, 0x41, 0xC1, 0xC1, 0xC1, 0xE4, 0xE4, 0xE4, 0x92, 0x01, 0x80, 0x0F,
|
||||
0x0F, 0x0F, 0x50, 0x07, 0x33, 0x00, 0x03, 0x30, 0x53, 0x31, 0xDC, 0x35, 0xF8, 0x3F, 0x3F, 0x3F,
|
||||
0xD2, 0xD2, 0xD2, 0x92, 0x92, 0x00, 0x92, 0x62, 0x31, 0x67, 0x05, 0x62, 0x62, 0x62, 0x8E, 0x02,
|
||||
0x8A, 0x09, 0xC6, 0x60, 0x3C, 0x0C, 0xC0, 0xA7, 0xFD, 0x62, 0x71, 0x62, 0xF1, 0xE9, 0xF1, 0x07,
|
||||
0x22, 0x50, 0x7F, 0x15, 0x1D, 0x4A, 0x04, 0xBC, 0x94, 0x64, 0x12, 0x1D, 0x1D, 0x0C, 0x8D, 0xBC,
|
||||
0x19, 0xD8, 0x26, 0x40, 0x16, 0x1C, 0xAD, 0x08, 0x05, 0x38, 0xA1, 0x95, 0x0C, 0x1E, 0x16, 0x2A,
|
||||
0x90, 0x62, 0xF1, 0x62, 0xF1, 0xE1, 0x4B, 0xF9, 0x1C, 0x1B, 0x26, 0xCA, 0x02, 0x0F, 0x1D, 0xFC,
|
||||
0x11, 0xDE, 0x80, 0xC8, 0x06, 0x1F, 0x3A, 0x17, 0x1B, 0x1E, 0x01, 0x1A, 0x1B, 0x19, 0x00, 0xBC,
|
||||
0x2B, 0x19, 0x1B, 0x5C, 0x08, 0x13, 0x1C, 0xD6, 0x19, 0x82, 0xF2, 0x01, 0x1F, 0x46, 0x08, 0x14,
|
||||
0x62, 0x11, 0x5B, 0x5D, 0x5D, 0x03, 0x03, 0x7A, 0x7A, 0x22, 0x7A, 0x89, 0x01, 0x00, 0x00, 0x0F,
|
||||
0x00, 0x4C, 0xFB, 0x53, 0x04, 0xB5, 0x05, 0xD1, 0x7E, 0xD1, 0xD1, 0x91, 0x05, 0x05, 0x0A, 0x3B,
|
||||
0x01, 0xCA, 0x02, 0x43, 0x43, 0x3C, 0x43, 0xD4, 0xD4, 0xD4, 0x9C, 0x9C, 0x9C, 0x38, 0x34, 0x80,
|
||||
0x36, 0xC0, 0x37, 0xFB, 0x62, 0xC1, 0x62, 0xF1, 0x86, 0xF7, 0x2D, 0x19, 0x1B, 0x1F, 0x9A, 0x0C,
|
||||
0x84, 0xA0, 0xD2, 0x05, 0x1F, 0x58, 0x14, 0x04, 0x1D, 0x28, 0x03, 0x10, 0x84, 0x00, 0x79, 0x05,
|
||||
0xC5, 0x11, 0x3D, 0x17, 0x3C, 0x1B, 0x7B, 0x0F, 0x1D, 0xEA, 0x5F, 0x81, 0xF2, 0x02, 0x20, 0x20,
|
||||
0x55, 0x15, 0x1C, 0x18, 0x2A, 0x90, 0x62, 0xF1, 0x62, 0xF1, 0xE0, 0x97, 0xF2, 0x2E, 0x28, 0x42,
|
||||
0x16, 0x1C, 0xD4, 0x05, 0x24, 0xA0, 0x83, 0xA5, 0x0B, 0x1E, 0x39, 0x18, 0xAE, 0x16, 0x20, 0xF1,
|
||||
0x08, 0xA0, 0x1A, 0x1B, 0x25, 0x1A, 0x1B, 0x2E, 0x19, 0x1C, 0x00, 0x4C, 0x15, 0x1C, 0xA6, 0xA3,
|
||||
0xB2, 0xBD, 0x07, 0x1E, 0x10, 0x2D, 0x16, 0x1A, 0x23, 0x28, 0x27, 0x79, 0x7A, 0x00, 0x7A, 0x62,
|
||||
0x01, 0x1E, 0x00, 0x15, 0x00, 0x1D, 0x37, 0xA8, 0xF9, 0xC1, 0x02, 0x5E, 0x7E, 0x5E, 0x5E, 0xED,
|
||||
0xED, 0xED, 0x8F, 0x8F, 0x8F, 0x00, 0x62, 0x01, 0xDB, 0x09, 0x36, 0x00, 0x44, 0x04, 0x38, 0x04,
|
||||
0x8B, 0x02, 0x46, 0x46, 0x3F, 0x46, 0x7E, 0x69, 0xA8, 0xF9, 0xBB, 0x32, 0xF6, 0x36, 0x62, 0x71,
|
||||
0x62, 0xF1, 0x81, 0xF0, 0xFE, 0x51, 0x20, 0x4D, 0x15, 0x1C, 0xD9, 0x05, 0xCD, 0xA2, 0xF2, 0x01,
|
||||
0xC1, 0x84, 0x0E, 0x1E, 0x8A, 0x00, 0x53, 0x15, 0x1C, 0x58, 0x08, 0x14, 0x1C, 0x78, 0x00, 0x9A,
|
||||
0x0B, 0x1E, 0xE6, 0x02, 0x04, 0x84, 0xA0, 0xBB, 0x05, 0x23, 0x1A, 0x6E, 0xF7, 0x1B, 0xC7, 0xF2,
|
||||
0x62, 0xF1, 0xD3, 0xDE, 0xF0, 0x29, 0x1A, 0x1B, 0x7E, 0x10, 0x1D, 0x24, 0x90, 0x81, 0xFE, 0x00,
|
||||
0x20, 0xB5, 0x08, 0x1E, 0x6F, 0x10, 0x00, 0x1D, 0x57, 0x14, 0x1C, 0x52, 0x15, 0x1C, 0x90, 0x03,
|
||||
0x80, 0x7D, 0x0F, 0x1D, 0xB6, 0x09, 0x5C, 0xD1, 0x69, 0x10, 0x20, 0x1C, 0x11, 0x1A, 0x19, 0x24,
|
||||
0x26, 0x26, 0x6D, 0x00, 0x6E, 0x6E, 0xE6, 0xE6, 0xE6, 0x89, 0x04, 0x63, 0x00, 0x24, 0x00, 0xE0,
|
||||
0x3C, 0x60, 0x88, 0x68, 0x89, 0x01, 0x39, 0x39, 0x39, 0x53, 0x04, 0xA3, 0x02, 0xC7, 0x87, 0x87,
|
||||
0x87, 0x62, 0x91, 0x50, 0x50, 0x50, 0xEB, 0x08, 0xEB, 0xEB, 0x26, 0x01, 0x18, 0x60, 0x7B, 0x99,
|
||||
0x5B, 0x35, 0x3E, 0x01, 0x7B, 0x3F, 0xFC, 0x93, 0x36, 0x62, 0x91, 0x62, 0xF1, 0x35, 0xF4, 0x23,
|
||||
0x1B, 0x1B, 0x6C, 0x0F, 0x12, 0x1D, 0xF6, 0x18, 0xB0, 0xFC, 0x00, 0x20, 0xE4, 0x08, 0x03, 0x1F,
|
||||
0xD7, 0x04, 0x1F, 0xDA, 0x04, 0x1F, 0x00, 0xED, 0x84, 0xE0, 0xD8, 0x05, 0x1F, 0x80, 0x01, 0xEE,
|
||||
0x44, 0xC7, 0xF2, 0xE2, 0xD9, 0x05, 0x62, 0xE1, 0x44, 0x62, 0xB1, 0xDE, 0xF0, 0x32, 0x18, 0x1C,
|
||||
0x1B, 0xA5, 0x0A, 0x65, 0xD1, 0xF4, 0xAE, 0x23, 0xD6, 0x04, 0x1F, 0x14, 0xDC, 0x04, 0x1F, 0xF8,
|
||||
0x01, 0xC6, 0xD0, 0xA1, 0x0B, 0x20, 0x1E, 0x21, 0x4A, 0x07, 0x1A, 0x19, 0x1B, 0x00, 0xE2, 0x05,
|
||||
0xEA, 0x64, 0xEA, 0xEA, 0x9E, 0x01, 0x26, 0x26, 0x26, 0x23, 0x04, 0x00, 0x00, 0xC4, 0xEE, 0x62,
|
||||
0x3C, 0x00, 0x44, 0x01, 0x2C, 0x04, 0x83, 0x83, 0x83, 0x9E, 0x01, 0x8F, 0xF4, 0xF4, 0xF4, 0x61,
|
||||
0x0E, 0xCA, 0x02, 0x12, 0x33, 0x2D, 0x00, 0x38, 0x01, 0xF8, 0x89, 0x89, 0x89, 0xFE, 0xFE, 0xFE,
|
||||
0x97, 0x02, 0x29, 0x01, 0xC0, 0xA0, 0x05, 0x1E, 0x00, 0xD5, 0x63, 0x44, 0x01, 0x12, 0x00, 0x41,
|
||||
0x01, 0x81, 0x81, 0x3F, 0x81, 0x7C, 0x7C, 0x7C, 0x5E, 0x02, 0x62, 0xA1, 0x62, 0xF1, 0x65, 0xF1,
|
||||
0xF0, 0x84, 0x20, 0x4D, 0x04, 0x77, 0x10, 0x1D, 0xEE, 0x02, 0x1F, 0x03, 0x0F, 0xF0, 0x6F, 0xF0,
|
||||
0xDB, 0x04, 0x1F, 0x49, 0x17, 0x1C, 0x03, 0x16, 0x5F, 0x31, 0x62, 0xF1, 0x7F, 0x22, 0x3F, 0x17,
|
||||
0x1C, 0xCF, 0x0E, 0x06, 0x1F, 0x33, 0x60, 0xEE, 0x02, 0x20, 0x43, 0x16, 0x04, 0x62, 0x81, 0xD4,
|
||||
0xF0, 0x2C, 0x21, 0x36, 0x18, 0x1C, 0xA9, 0x09, 0x07, 0x1E, 0x00, 0x00, 0x0F, 0xF0, 0xD2, 0xF0,
|
||||
0xA8, 0x0B, 0x1E, 0x28, 0x0E, 0x19, 0x1B, 0x18, 0x39, 0x23, 0x8A, 0x0E, 0x89, 0x01, 0x91, 0x91,
|
||||
0x38, 0x91, 0xFF, 0xFF, 0xFF, 0x68, 0x01, 0x36, 0x36, 0x36, 0x10, 0x06, 0x00, 0x3F, 0x00, 0x24,
|
||||
0x24, 0x24, 0x3C, 0x00, 0x37, 0x37, 0x23, 0x37, 0x57, 0x57, 0x57, 0x47, 0x01, 0xE5, 0xE5, 0xE5,
|
||||
0x10, 0x90, 0x90, 0x90, 0xCE, 0xCE, 0xCE, 0x7A, 0x01, 0x4B, 0x00, 0xC0, 0x85, 0x65, 0x8B, 0x0B,
|
||||
0x65, 0x01, 0x9F, 0x9F, 0x9F, 0xFB, 0xFB, 0x07, 0xFB, 0x99, 0x99, 0x99, 0x45, 0x45, 0x45, 0xA9,
|
||||
0x02, 0x80, 0x6D, 0x0B, 0xEE, 0x02, 0x76, 0x02, 0x0B, 0x01, 0x51, 0x51, 0x51, 0xA1, 0x0F, 0xA1,
|
||||
0xA1, 0xE7, 0xE7, 0xE7, 0x6D, 0x6D, 0x6D, 0x00, 0x19, 0x0E, 0x74, 0x01, 0x32, 0x01, 0x2A, 0x2A,
|
||||
0x2A, 0x47, 0x01, 0xC5, 0x47, 0xC5, 0xC5, 0xFF, 0x03, 0xF9, 0x03, 0x62, 0xA1, 0x65, 0xF1, 0xEC,
|
||||
0x21, 0x22, 0x7C, 0x1A, 0x1B, 0x5D, 0x13, 0x1C, 0xC7, 0x07, 0x1F, 0x00, 0xFD, 0x84, 0x50, 0x81,
|
||||
0xF0, 0xF8, 0x01, 0x20, 0xAB, 0x0A, 0x06, 0x1E, 0x3C, 0x17, 0x92, 0x04, 0x5F, 0x51, 0xAA, 0xF4,
|
||||
0x36, 0x20, 0x33, 0x78, 0x18, 0x1C, 0xC9, 0x06, 0x3C, 0x00, 0x22, 0x39, 0x20, 0x21, 0x50, 0xEC,
|
||||
0x02, 0x21, 0x3B, 0x17, 0x1C, 0x1A, 0x71, 0x64, 0x80, 0xD4, 0xF0, 0xE1, 0x10, 0xA3, 0x12, 0x30,
|
||||
0x18, 0x1B, 0x87, 0x0F, 0x07, 0x1E, 0xE1, 0x04, 0x1F, 0x0F, 0x60, 0x03, 0x30, 0x00, 0x00, 0x03,
|
||||
0x00, 0xF0, 0xFF, 0x00, 0x21, 0xFF, 0x00, 0x20, 0xE3, 0x03, 0x00, 0x1F, 0x05, 0x01, 0x27, 0x1A,
|
||||
0x1C, 0x17, 0x37, 0x22, 0x1A, 0x42, 0xA4, 0x51, 0x31, 0x31, 0x31, 0x23, 0x0D, 0xFC, 0xFC, 0xFC,
|
||||
0x11, 0xCC, 0xCC, 0xCC, 0x8A, 0x8A, 0x8A, 0x76, 0x76, 0x00, 0x76, 0x78, 0x78, 0x78, 0x85, 0x85,
|
||||
0x85, 0xB5, 0x00, 0xB5, 0xB5, 0x56, 0x01, 0xD6, 0xD6, 0xD6, 0x9D, 0x0B, 0x2B, 0x44, 0x2B, 0x2B,
|
||||
0x53, 0x01, 0xD0, 0xD0, 0xD0, 0x2C, 0x2C, 0x04, 0x2C, 0x15, 0x15, 0x15, 0x48, 0x60, 0x2D, 0x00,
|
||||
0x36, 0x00, 0x93, 0x70, 0x93, 0x93, 0xEC, 0xEC, 0xEC, 0x6B, 0x01, 0x9D, 0x9D, 0x20, 0x9D, 0x2F,
|
||||
0x01, 0x74, 0x74, 0x74, 0x7E, 0x7E, 0x7E, 0x02, 0xA7, 0xA7, 0xA7, 0xE0, 0xE0, 0xE0, 0xE3, 0xE3,
|
||||
0x00, 0xE3, 0x65, 0x65, 0x65, 0x12, 0x12, 0x12, 0x00, 0x00, 0x80, 0x62, 0x31, 0x32, 0x01, 0xAF,
|
||||
0xAF, 0xAF, 0xD7, 0xD7, 0xD7, 0x03, 0x2E, 0x2E, 0x2E, 0xC9, 0x13, 0x5F, 0xF1, 0x48, 0xF0, 0x84,
|
||||
0x20, 0x2E, 0x78, 0x1A, 0x1B, 0x6D, 0x11, 0x1D, 0xA9, 0x0A, 0x1E, 0x00, 0xCF, 0x07, 0x1F, 0xEA,
|
||||
0x02, 0x84, 0x10, 0xEF, 0x01, 0x20, 0x20, 0xDD, 0x04, 0x1F, 0xC3, 0x08, 0x1F, 0x9A, 0x00, 0x0C,
|
||||
0x1E, 0x59, 0x14, 0x1D, 0x9B, 0x01, 0x18, 0x36, 0xE0, 0xA0, 0xA1, 0xF1, 0x24, 0x1B, 0x1B, 0x7F,
|
||||
0x0F, 0x1D, 0xB7, 0x01, 0x08, 0x1E, 0xAC, 0x0A, 0x1E, 0xAE, 0x0A, 0x1E, 0x00, 0x94, 0x0D, 0x1E,
|
||||
0x2B, 0x1A, 0x1C, 0xE7, 0xD3, 0x02, 0xF4, 0xC0, 0x68, 0x21, 0xBA, 0x0E, 0x3E, 0x17, 0x1B, 0x89,
|
||||
0x0D, 0x1E, 0x03, 0xB7, 0x09, 0x1E, 0xDB, 0x05, 0x1F, 0xF0, 0x01, 0x00, 0x20, 0xEF, 0x02, 0x20,
|
||||
0xE9, 0x03, 0x20, 0xD7, 0x00, 0x05, 0x1F, 0xB4, 0x09, 0x1E, 0x85, 0x0F, 0x1E, 0x00, 0x3C, 0x18,
|
||||
0x1B, 0x16, 0x99, 0xE3, 0x86, 0x31, 0x27, 0x27, 0x30, 0x27, 0x6F, 0x6F, 0x6F, 0xC0, 0xC0, 0xC0,
|
||||
0xE1, 0x00, 0xE1, 0xE1, 0x3C, 0x00, 0x00, 0x00, 0xDE, 0xDE, 0xDE, 0xB8, 0x0C, 0xB8, 0xB8, 0x7B,
|
||||
0x7B, 0x7B, 0x33, 0x33, 0x33, 0x00, 0x5F, 0x31, 0x5F, 0x5F, 0x5F, 0x85, 0x0B, 0x29, 0x29, 0x29,
|
||||
0x11, 0x2D, 0x00, 0x26, 0xC1, 0x29, 0x01, 0x6D, 0x0B, 0xA3, 0xA3, 0xA3, 0xD8, 0x0F, 0xD8, 0xD8,
|
||||
0xE2, 0xE2, 0xE2, 0x00, 0x00, 0xDF, 0xDF, 0x20, 0xDF, 0xC8, 0xC8, 0xC8, 0x8D, 0x8D, 0x8D, 0x3D,
|
||||
0x00, 0x3D, 0x3D, 0x5F, 0x31, 0x38, 0x61, 0x20, 0x01, 0x63, 0x63, 0x63, 0x1C, 0x77, 0x77, 0x77,
|
||||
0x25, 0x25, 0x25, 0x4A, 0x11, 0x46, 0xF0, 0xC0, 0x84, 0xF0, 0x81, 0x30, 0x1A, 0x1B, 0x18, 0x78,
|
||||
0x20, 0x35, 0x18, 0x23, 0x1B, 0x4F, 0x15, 0x1D, 0x81, 0x00, 0x52, 0x14, 0x1D, 0x10, 0x41, 0x17,
|
||||
0x1C, 0x28, 0x1A, 0x1B, 0x11, 0x5C, 0x21, 0x80, 0x0F, 0xF0, 0x25, 0xF0, 0x30, 0x1C, 0x1A, 0x1B,
|
||||
0x17, 0xA7, 0x01, 0x11, 0x11, 0xC7, 0x23, 0x11, 0x0F, 0x1D, 0x1B, 0x1E, 0x01, 0x10, 0x4A, 0xF0,
|
||||
0xDE, 0xF0, 0xE1, 0x18, 0x10, 0xAD, 0x00, 0x16, 0xEB, 0x0B, 0x1B, 0x1B, 0x40, 0x17, 0x0B, 0x1C,
|
||||
0x53, 0x13, 0x1D, 0x53, 0x14, 0x1D, 0x4C, 0x00, 0x15, 0x1D, 0x3A, 0x18, 0x1B, 0x4D, 0x00, 0x0F,
|
||||
0x5C, 0x01, 0xA0, 0x03, 0x20, 0xD8, 0xF0, 0xE8, 0x38, 0x15, 0x00, 0x18, 0x00, 0x42, 0x42, 0x42,
|
||||
0x1F, 0x53, 0x53, 0x53, 0x4E, 0x4E, 0x4E, 0x3E, 0x3E, 0x00, 0x3E, 0x18, 0x00, 0x9A, 0x0B, 0x1E,
|
||||
0x00, 0x0C, 0x00, 0x48, 0x00, 0x47, 0x01, 0x0A, 0x7E, 0x0A, 0x0A, 0x12, 0x30, 0x65, 0xC1, 0x33,
|
||||
0x00, 0x18, 0x00, 0x1D, 0x01, 0x34, 0x7C, 0x34, 0x34, 0x4D, 0x4D, 0x4D, 0x54, 0x54, 0x54, 0x00,
|
||||
0x48, 0x48, 0x48, 0x22, 0x22, 0x22, 0x11, 0x11, 0x00, 0x11, 0x1D, 0x01, 0xCA, 0x05, 0x29, 0x91,
|
||||
0x20, 0x20, 0x20, 0xFF, 0x00, 0x8E, 0x0D, 0x0D, 0x0D, 0x76, 0x08, 0x07, 0x70, 0x42, 0xF0, 0x48,
|
||||
0xF0, 0x4E, 0x50, 0xF8, 0x16, 0x87, 0x50, 0x12, 0x84, 0x20, 0x16, 0x1C, 0x36, 0xC0, 0x2F, 0xF0,
|
||||
0xCA, 0x39, 0xF0, 0x00, 0x00, 0x4B, 0x50, 0x23, 0x61, 0x42, 0xF0, 0x78, 0xF0, 0x18, 0x50, 0x18,
|
||||
0x7F, 0x09, 0x00, 0x1B, 0x1B, 0x12, 0x00, 0x00, 0x1C, 0x1B, 0x13, 0x11, 0x1C, 0x1B, 0x14, 0x1C,
|
||||
0x1B, 0x18, 0xCF, 0x20, 0x19, 0x40, 0x05, 0x50, 0x39, 0xF0, 0x03, 0x00, 0x39, 0x30, 0x3F, 0x60,
|
||||
0x3C, 0xC0, 0x50, 0xC1, 0x2D, 0xF0, 0xFF, 0x3B, 0x07, 0x0F, 0x00, 0x17, 0x17, 0x17, 0x03, 0x00,
|
||||
0x08, 0x0A, 0x0B, 0x0A, 0xE3, 0x18, 0x18, 0x18, 0x15, 0x30, 0x15, 0xF0, 0x05, 0x71, 0x0F, 0xF0,
|
||||
0x33, 0xF0, 0xF8, 0x81, 0xF0, 0x81, 0xF0, 0x0F, 0xF0, 0x21, 0xF0, 0x36, 0xF0, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x27, 0xF0, 0xFF, 0x09, 0x80, 0x47, 0x06, 0x03, 0x30, 0x00, 0x00, 0x35, 0xC0, 0x27, 0xF0,
|
||||
0x3F, 0xF0, 0x3C, 0xF0, 0xFF, 0x30, 0xF0, 0xB3, 0xF1, 0xFA, 0xF2, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x7A, 0xF1, 0x5B, 0xF8, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x1A, 0xF7, 0x5B, 0xF8, 0x5C, 0xFD, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x1D, 0xF7, 0xFF, 0x79, 0xFB, 0x6D,
|
||||
0x9B, 0x62, 0x01, 0x00, 0x00, 0xC1, 0x02, 0x03, 0x30, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x09, 0x90, 0xFF,
|
||||
0x03, 0x30, 0x00, 0x00, 0x8B, 0x3B, 0xFB, 0x3D, 0x62, 0x01, 0x81, 0x0C, 0x6A, 0x6A, 0x3F, 0x6A,
|
||||
0x42, 0x0F, 0x03, 0x30, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFE, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x09, 0x90, 0x03, 0x30, 0x00, 0x00, 0x88, 0x0B,
|
||||
0xFF, 0x03, 0x0C, 0x4F, 0x4F, 0x4F, 0x6D, 0x0B, 0x8F, 0x0A, 0x05, 0x0A, 0xC6, 0x0F, 0xF1, 0xA8,
|
||||
0xA8, 0xA8, 0x03, 0x30, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xF8, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x09, 0x90, 0x03, 0x30, 0x00, 0x00, 0xFF, 0x9C,
|
||||
0x9C, 0x9C, 0xA9, 0xA9, 0xA9, 0xCE, 0x0D, 0x09, 0x00, 0xC0, 0x62, 0x01, 0xB2, 0x08, 0x6B, 0x0A,
|
||||
0xF4, 0x0B, 0x03, 0x30, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x09, 0x90, 0x03, 0x30, 0xFF, 0x00, 0x00, 0x03,
|
||||
0x00, 0x0C, 0x0C, 0x0C, 0xBE, 0x08, 0xF1, 0x08, 0x86, 0xC4, 0xE3, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0C,
|
||||
0xC0, 0xEA, 0xF6, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF,
|
||||
0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0,
|
||||
0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x36, 0xF0,
|
||||
0xFD, 0xC2, 0xFF, 0x76, 0xC2, 0x24, 0xF0, 0x1B, 0xF0, 0x12, 0xF0, 0xAE, 0xF0, 0x24, 0xF0, 0x66,
|
||||
0xF0, 0x66, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x21, 0xF0, 0x9B, 0xF1, 0x1B, 0xF0,
|
||||
0x02, 0xF1, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0x39, 0xF0, 0xD4, 0x67, 0x7B, 0x30, 0x15,
|
||||
0x90, 0x7F, 0x62, 0x39, 0xC0, 0xFF, 0x30, 0xF0, 0xB2, 0x6B, 0x7D, 0x61, 0x90, 0xF0, 0x27, 0xF0,
|
||||
0x27, 0xF0, 0xB8, 0x6E, 0x1E, 0xF0, 0xFF, 0x65, 0xF4, 0x0F, 0xF0, 0x0F, 0xF0, 0x18, 0xF0, 0x1B,
|
||||
0xF0, 0x12, 0xF0, 0xA2, 0x90, 0x1E, 0xF0, 0xFF, 0x5D, 0x90, 0x02, 0xF1, 0xDB, 0xF0, 0xF7, 0x32,
|
||||
0x00, 0x00, 0x21, 0x03, 0xEE, 0x32, 0x78, 0x00, 0xFF, 0x51, 0x30, 0xB7, 0x03, 0x40, 0x05, 0xF3,
|
||||
0x03, 0xF2, 0x01, 0x76, 0x02, 0x39, 0x00, 0xD6, 0x32, 0xFF, 0x45, 0x90, 0x42, 0xCF, 0x18, 0x00,
|
||||
0x35, 0x01, 0x9F, 0x00, 0x60, 0x90, 0x2C, 0x01, 0x27, 0x00, 0xFF, 0x90, 0x00, 0xCF, 0x30, 0x97,
|
||||
0xFB, 0x82, 0x62, 0x00, 0x06, 0xE7, 0x00, 0x0F, 0xF0, 0x1E, 0xF0, 0xFF, 0x84, 0x3C, 0x4F, 0xCB,
|
||||
0x65, 0xF1, 0x56, 0xF1, 0xDE, 0x36, 0xD6, 0x02, 0xC8, 0x0A, 0xA7, 0x01, 0xFF, 0x03, 0x30, 0x08,
|
||||
0x61, 0x8A, 0x39, 0x83, 0x01, 0xD9, 0x02, 0x4F, 0x02, 0x14, 0xC1, 0x38, 0xC1, 0xFF, 0xD2, 0xC3,
|
||||
0x72, 0x60, 0x8D, 0x60, 0x7E, 0x60, 0x2D, 0x00, 0x81, 0x00, 0x1A, 0x04, 0x4D, 0x04, 0xFF, 0x30,
|
||||
0x00, 0x81, 0x06, 0xDD, 0x04, 0x74, 0x01, 0x0B, 0x04, 0xF6, 0x00, 0x2A, 0x03, 0x6F, 0x03, 0xFF,
|
||||
0xCC, 0x03, 0xF0, 0x00, 0xA8, 0x03, 0x7D, 0x01, 0xC4, 0x02, 0x45, 0x60, 0x06, 0xCC, 0xD4, 0x01,
|
||||
0xFF, 0xD8, 0x00, 0xC1, 0x02, 0x15, 0x03, 0x62, 0x91, 0x4D, 0x01, 0x6A, 0x02, 0x3D, 0x35, 0x0C,
|
||||
0x00, 0xFF, 0x2A, 0xF3, 0x22, 0x6E, 0x76, 0x02, 0x4E, 0x03, 0x6A, 0x05, 0x66, 0x30, 0x03, 0xC3,
|
||||
0x6F, 0x99, 0xFF, 0xC5, 0x01, 0x01, 0x32, 0xE2, 0xC2, 0x62, 0xF1, 0x62, 0xF1, 0x1B, 0x33, 0xD1,
|
||||
0x01, 0x33, 0x00, 0xFF, 0xD9, 0x02, 0x03, 0x30, 0x03, 0x30, 0x62, 0x31, 0x7B, 0x0C, 0x2E, 0x02,
|
||||
0x28, 0x02, 0x62, 0x01, 0xFF, 0x5F, 0x9A, 0x33, 0x30, 0xB1, 0x00, 0x9C, 0x00, 0x12, 0x00, 0x2A,
|
||||
0x00, 0x45, 0x00, 0xED, 0x30, 0xFF, 0x08, 0x31, 0x12, 0x00, 0xBA, 0x00, 0x48, 0x00, 0x39, 0x00,
|
||||
0xD8, 0x60, 0x3C, 0x00, 0x33, 0x00, 0xFF, 0x09, 0x00, 0x61, 0x02, 0x59, 0x01, 0x09, 0x00, 0x6C,
|
||||
0x00, 0x70, 0x05, 0x54, 0x00, 0x7E, 0x00, 0xFF, 0xB9, 0x04, 0x1D, 0x01, 0x81, 0x00, 0x09, 0x00,
|
||||
0x49, 0x02, 0x3C, 0x00, 0x20, 0x04, 0x7B, 0x30, 0xFF, 0x12, 0x00, 0x08, 0x01, 0x5A, 0x39, 0x7B,
|
||||
0x30, 0xB1, 0x00, 0x0B, 0x01, 0x23, 0x01, 0xF7, 0x05, 0xFF, 0x6E, 0x04, 0x2C, 0xC4, 0xA1, 0x01,
|
||||
0x37, 0x02, 0x57, 0x00, 0x7E, 0x06, 0x5D, 0x60, 0x1E, 0x00, 0xFF, 0xF9, 0x00, 0x45, 0x00, 0x4A,
|
||||
0x3A, 0x6F, 0x36, 0xC7, 0x02, 0x22, 0x3B, 0x30, 0x00, 0x09, 0x33, 0xFF, 0x5D, 0x00, 0x4E, 0x00,
|
||||
0xB6, 0x01, 0x36, 0x39, 0x4B, 0x00, 0xA6, 0x02, 0xB4, 0x03, 0x3C, 0x00, 0xFF, 0x38, 0x01, 0x0C,
|
||||
0x00, 0x17, 0x01, 0xB4, 0x06, 0x3C, 0x00, 0xEA, 0x03, 0x1E, 0x30, 0xC0, 0xF9, 0xFF, 0x4C, 0xC8,
|
||||
0x08, 0x01, 0x19, 0x02, 0x36, 0x06, 0x02, 0x01, 0x84, 0x00, 0xF9, 0x03, 0x50, 0x01, 0xFF, 0xDE,
|
||||
0x00, 0x35, 0x31, 0x37, 0x05, 0x18, 0x00, 0xF6, 0x66, 0x9C, 0x60, 0x32, 0x07, 0xA6, 0x05, 0xFF,
|
||||
0x1B, 0x00, 0x09, 0x03, 0x62, 0x07, 0xB7, 0x03, 0x12, 0x00, 0x55, 0x02, 0xCF, 0x00, 0x90, 0x00,
|
||||
0xFF, 0x12, 0x00, 0x68, 0x01, 0x81, 0x00, 0xCD, 0x02, 0x70, 0x70, 0x70, 0x4E, 0x00, 0x8F, 0x36,
|
||||
0x00, 0x0F, 0x00, 0x50, 0x50, 0x50, 0x74, 0x01, 0xAE, 0x00, 0x38, 0x01, 0xE3, 0xC8, 0x01, 0x6E,
|
||||
0x04, 0xED, 0x00, 0x3F, 0x00, 0x27, 0x00, 0x5F, 0x01, 0x38, 0x01, 0xB1, 0x7F, 0xB1, 0xB1, 0xA8,
|
||||
0x00, 0xEA, 0x03, 0x48, 0x00, 0x8C, 0x01, 0x12, 0x00, 0x8D, 0x30, 0xFC, 0x31, 0x02, 0x40, 0x05,
|
||||
0x6E, 0x04, 0x21, 0x06, 0xF2, 0x01, 0xB9, 0x04, 0x64, 0x02, 0x43, 0x02, 0xFF, 0x75, 0x00, 0xAA,
|
||||
0xAA, 0xAA, 0x5C, 0x01, 0x62, 0x61, 0xBF, 0x31, 0x03, 0x00, 0xF1, 0xA2, 0x03, 0x21, 0x00, 0x40,
|
||||
0x02, 0x9F, 0x00, 0xD4, 0x01, 0xC5, 0x01, 0x5B, 0x02, 0x18, 0x00, 0xFF, 0x72, 0x06, 0xF9, 0x00,
|
||||
0x22, 0x02, 0x21, 0x00, 0x40, 0x32, 0x0D, 0x02, 0x86, 0x01, 0x58, 0x02, 0xFF, 0xA7, 0x07, 0xDB,
|
||||
0x00, 0x06, 0x00, 0x60, 0x00, 0xB3, 0x01, 0xF0, 0x03, 0x21, 0x00, 0x1B, 0x00, 0xFF, 0xF4, 0x02,
|
||||
0xBD, 0xBD, 0xBD, 0x16, 0x02, 0xAA, 0x34, 0xC0, 0x00, 0x39, 0x00, 0xF1, 0xA4, 0x01, 0x23, 0x01,
|
||||
0x97, 0x02, 0x00, 0x00, 0x0F, 0x60, 0xE1, 0x30, 0x44, 0x3A, 0xE7, 0x96, 0xFF, 0x9C, 0x00, 0xAE,
|
||||
0x00, 0x3D, 0x05, 0x03, 0x03, 0x95, 0x04, 0x7C, 0x7C, 0x7C, 0x1F, 0x92, 0x01, 0x8D, 0x00, 0xCA,
|
||||
0x02, 0x12, 0x00, 0x5D, 0x00, 0x62, 0x31, 0x91, 0x95, 0xA3, 0x02, 0xFF, 0xCE, 0x01, 0x3C, 0x00,
|
||||
0xCF, 0x00, 0x21, 0x03, 0xAF, 0xAF, 0xAF, 0x68, 0x01, 0x8F, 0xA5, 0x00, 0xF8, 0x01, 0x6D, 0x6D,
|
||||
0x6D, 0x3F, 0x00, 0x37, 0x02, 0x7B, 0x00, 0xE3, 0x51, 0x00, 0x51, 0x03, 0x1E, 0x06, 0xA4, 0x01,
|
||||
0xB7, 0x00, 0x1D, 0x01, 0xBE, 0x02, 0x66, 0x7F, 0x66, 0x66, 0x66, 0x00, 0xEF, 0x01, 0x5D, 0x00,
|
||||
0xD2, 0x00, 0xC7, 0x02, 0x09, 0x00, 0xFC, 0x62, 0x01, 0xC3, 0x00, 0xE2, 0x02, 0x5B, 0x05, 0x05,
|
||||
0x01, 0x1B, 0x00, 0xBB, 0x02, 0x0F, 0x00, 0xFF, 0x5A, 0x00, 0x08, 0x01, 0x90, 0x00, 0xD5, 0x00,
|
||||
0xE9, 0x01, 0x52, 0x02, 0x30, 0x03, 0x1B, 0x00, 0xFF, 0x7C, 0x02, 0x6B, 0x01, 0x30, 0x03, 0x00,
|
||||
0x03, 0xBA, 0xBA, 0xBA, 0x5D, 0x00, 0x8F, 0x62, 0x91, 0x9F, 0x03, 0xB2, 0x02, 0x0F, 0x00, 0x5A,
|
||||
0x00, 0x30, 0x00, 0xA2, 0x00, 0x7B, 0x30, 0xFF, 0x8A, 0x8A, 0x8A, 0xEA, 0x00, 0x51, 0x03, 0xD7,
|
||||
0x01, 0x68, 0x01, 0x0F, 0x00, 0xF8, 0x73, 0x02, 0x38, 0x01, 0x9F, 0x00, 0x8F, 0x01, 0x6F, 0x03,
|
||||
0x7E, 0x00, 0x72, 0x00, 0x5D, 0x03, 0xFF, 0x00, 0x00, 0xFC, 0x03, 0x7E, 0x03, 0x17, 0x04, 0xDE,
|
||||
0x00, 0xC9, 0x00, 0x26, 0x01, 0x55, 0x7F, 0x55, 0x55, 0x15, 0x00, 0x8E, 0x05, 0x06, 0x00, 0xE9,
|
||||
0x01, 0x3C, 0x00, 0xDB, 0x00, 0xFC, 0xEA, 0x03, 0xB4, 0x00, 0x0C, 0x00, 0x3D, 0x38, 0x90, 0x00,
|
||||
0x5C, 0x01, 0xC7, 0x38, 0x91, 0x95, 0xFF, 0x3A, 0x02, 0xC3, 0x03, 0x62, 0x01, 0xBE, 0x02, 0xB4,
|
||||
0xB4, 0xB4, 0x7B, 0x00, 0x8F, 0x0E, 0x01, 0xCA, 0x02, 0xFE, 0x04, 0x12, 0x00, 0xF0, 0x00, 0x62,
|
||||
0x01, 0x62, 0xF1, 0xBA, 0x00, 0xFF, 0x8F, 0x01, 0x09, 0x09, 0x09, 0x5D, 0x00, 0x27, 0x00, 0x02,
|
||||
0x04, 0x77, 0x01, 0xF1, 0xA0, 0x35, 0x69, 0x00, 0x60, 0x00, 0x83, 0x01, 0x38, 0x01, 0x0F, 0x00,
|
||||
0x52, 0x52, 0x3F, 0x52, 0x75, 0x03, 0x69, 0x00, 0xBC, 0x01, 0x28, 0x05, 0x6A, 0x02, 0x12, 0x00,
|
||||
0xE0, 0x01, 0xFE, 0xC0, 0x00, 0x66, 0x00, 0x30, 0x00, 0x27, 0x00, 0xDE, 0x00, 0xBA, 0x00, 0x8F,
|
||||
0x01, 0x7D, 0x7F, 0x7D, 0x7D, 0x4D, 0x01, 0xD7, 0x01, 0xC7, 0x32, 0x62, 0x01, 0x41, 0x04, 0x99,
|
||||
0x00, 0xFC, 0xE4, 0x03, 0x72, 0x00, 0x52, 0x02, 0x9E, 0x01, 0x94, 0x02, 0x9C, 0x00, 0x33, 0x00,
|
||||
0x03, 0x7F, 0x03, 0x03, 0xFF, 0x03, 0x63, 0x00, 0x2A, 0x00, 0x62, 0xC1, 0xB1, 0x03, 0xC3, 0x30,
|
||||
0xFC, 0x2C, 0x04, 0x12, 0x00, 0x62, 0x01, 0x63, 0x00, 0xA7, 0xA7, 0xA7, 0xB6, 0x04, 0x8F, 0x77,
|
||||
0x01, 0xAD, 0x04, 0x9A, 0x9A, 0x9A, 0xFD, 0x05, 0x62, 0x01, 0xAD, 0x63, 0xAD, 0xAD, 0xD1, 0x01,
|
||||
0xA8, 0x00, 0xA4, 0x04, 0x0D, 0x35, 0x02, 0x01, 0x53, 0x7C, 0x53, 0x53, 0xBD, 0x03, 0x60, 0x00,
|
||||
0xF3, 0x00, 0xC7, 0x32, 0xDE, 0x00, 0x47, 0x01, 0xFC, 0x62, 0x31, 0xA6, 0xA6, 0xA6, 0xD3, 0x35,
|
||||
0x04, 0x02, 0xA4, 0xA4, 0x31, 0xA4, 0xE0, 0x01, 0x45, 0x00, 0x3F, 0x36, 0x54, 0x00, 0xC6, 0x00,
|
||||
0x51, 0x00, 0xA6, 0x02, 0xFE, 0xA8, 0x36, 0xC7, 0x62, 0xCF, 0x00, 0x62, 0x31, 0x72, 0x03, 0x0C,
|
||||
0x00, 0xB1, 0x00, 0x8C, 0x01, 0xFF, 0xFF, 0x00, 0x19, 0x02, 0x53, 0x01, 0x5D, 0x00, 0x62, 0xF1,
|
||||
0x2A, 0x03, 0x4D, 0x01, 0xED, 0x00, 0xFF, 0x4B, 0x4B, 0x4B, 0xCC, 0x00, 0x32, 0x04, 0x84, 0x00,
|
||||
0xC7, 0x02, 0xCB, 0x01, 0xF8, 0x3C, 0x00, 0xC1, 0x02, 0x12, 0x00, 0x15, 0x00, 0x27, 0x00, 0x45,
|
||||
0x45, 0x45, 0x1F, 0x04, 0x02, 0xE0, 0x04, 0x62, 0x01, 0x1E, 0x00, 0x48, 0x00, 0x1E, 0x00, 0xCF,
|
||||
0x03, 0xED, 0x00, 0xFF, 0xCB, 0x01, 0x3E, 0x3E, 0x3E, 0x02, 0x01, 0xC6, 0x00, 0x31, 0x02, 0x09,
|
||||
0x00, 0xF1, 0x62, 0x61, 0x84, 0x00, 0x81, 0x81, 0x81, 0xA1, 0x01, 0x54, 0x54, 0x23, 0x54, 0x3C,
|
||||
0x00, 0xCB, 0x01, 0x00, 0x00, 0xD9, 0x02, 0x08, 0x01, 0x7A, 0x04, 0x5D, 0x00, 0xFE, 0x25, 0x02,
|
||||
0xC8, 0x01, 0x20, 0x01, 0x2D, 0x03, 0x78, 0x00, 0x56, 0x01, 0x93, 0x30, 0x87, 0x00, 0xFF, 0x5E,
|
||||
0x02, 0x62, 0x01, 0x7B, 0x00, 0xAE, 0x00, 0x5D, 0x5D, 0x5D, 0xFE, 0x01, 0x8F, 0xCF, 0x00, 0x1A,
|
||||
0x01, 0x38, 0x01, 0x00, 0x00, 0x45, 0x30, 0xDB, 0x03, 0xF9, 0x00, 0x03, 0x03, 0xFF, 0xE2, 0x02,
|
||||
0xD1, 0x01, 0x20, 0x01, 0x39, 0x30, 0x7D, 0x01, 0x84, 0x84, 0x84, 0x1F, 0x40, 0x02, 0x6F, 0x6F,
|
||||
0x6F, 0x29, 0x01, 0x30, 0x00, 0x0D, 0x02, 0xE3, 0x01, 0xF1, 0x09, 0x00, 0x68, 0x01, 0x72, 0x00,
|
||||
0x4E, 0x00, 0x62, 0x01, 0xB1, 0x03, 0x72, 0x72, 0x3F, 0x72, 0xE1, 0x03, 0xA6, 0x02, 0x2A, 0x03,
|
||||
0xA5, 0x00, 0x5C, 0x31, 0x02, 0x01, 0x00, 0x00, 0xFE, 0x5B, 0x5B, 0x5B, 0x2A, 0x00, 0x51, 0x00,
|
||||
0x62, 0x61, 0x81, 0x00, 0x62, 0x31, 0xF8, 0xD7, 0x01, 0xA2, 0xA2, 0xA2, 0xD7, 0x31, 0x21, 0x00,
|
||||
0x48, 0x00, 0xE4, 0x00, 0xF1, 0xF7, 0x02, 0x5D, 0x00, 0x41, 0x41, 0x41, 0x72, 0x00, 0x09, 0x66,
|
||||
0xA2, 0x00, 0xE3, 0x89, 0x89, 0x89, 0x44, 0x44, 0x44, 0x87, 0x00, 0x3F, 0x03, 0xC0, 0x49, 0x02,
|
||||
0x62, 0x01, 0x12, 0x00, 0xB7, 0x03, 0x46, 0x02, 0x1E, 0x1E, 0x1E, 0x1F, 0x5F, 0x5F, 0x5F, 0x94,
|
||||
0x94, 0x94, 0x29, 0x29, 0x00, 0x29, 0x48, 0x00, 0x27, 0x00, 0x92, 0x92, 0x92, 0x48, 0x00, 0x72,
|
||||
0x00, 0xC6, 0x97, 0x97, 0x97, 0xE7, 0x30, 0x66, 0x03, 0x20, 0x01, 0x86, 0x01, 0x24, 0x00, 0xF8,
|
||||
0x30, 0x00, 0x36, 0x36, 0x36, 0xC3, 0x00, 0x09, 0x00, 0x80, 0x80, 0x31, 0x80, 0xB5, 0x02, 0xE1,
|
||||
0x00, 0x0A, 0x02, 0x82, 0x82, 0x82, 0xED, 0x00, 0x8E, 0x4E, 0x03, 0x45, 0x00, 0x3F, 0x3F, 0x3F,
|
||||
0x35, 0x01, 0x00, 0x00, 0x45, 0x00, 0xE3, 0x87, 0x00, 0xCF, 0x00, 0x4D, 0x01, 0x96, 0x00, 0x94,
|
||||
0x02, 0xA1, 0xA1, 0xA1, 0x1F, 0x57, 0x00, 0x63, 0x00, 0x62, 0x61, 0x61, 0x02, 0x42, 0x00, 0x93,
|
||||
0x00, 0x9D, 0x02, 0xE7, 0x00, 0xFF, 0x9C, 0x9C, 0x9C, 0xB5, 0x02, 0x49, 0x49, 0x49, 0x39, 0x00,
|
||||
0x88, 0x75, 0x00, 0x57, 0x00, 0x56, 0x01, 0x73, 0x02, 0x45, 0x00, 0x03, 0x03, 0x62, 0x01, 0x84,
|
||||
0x00, 0xFF, 0x6E, 0x01, 0xD0, 0x02, 0x98, 0x01, 0x6C, 0x6C, 0x6C, 0x96, 0x96, 0x07, 0x96, 0x21,
|
||||
0x00, 0x9F, 0x00, 0xCE, 0x01, 0x97, 0x02, 0x0A, 0x0A, 0x0A, 0x1E, 0x43, 0x43, 0x43, 0x9C, 0x00,
|
||||
0xCA, 0x02, 0x21, 0x00, 0x79, 0x02, 0xAA, 0x01, 0xF8, 0x3C, 0x00, 0x1F, 0x02, 0x15, 0x03, 0x47,
|
||||
0x01, 0x65, 0x61, 0x69, 0x33, 0xAE, 0x00, 0x4E, 0x03, 0xFF, 0x73, 0x32, 0x62, 0x61, 0xDA, 0x01,
|
||||
0x3C, 0x00, 0x2A, 0x00, 0x12, 0x00, 0xA5, 0xA5, 0x3F, 0xA5, 0x27, 0x00, 0x1B, 0x00, 0x7E, 0x00,
|
||||
0x8A, 0x00, 0x2C, 0x2C, 0x2C, 0x1E, 0x62, 0x01, 0x88, 0x88, 0x88, 0x62, 0x01, 0xB1, 0x00, 0x20,
|
||||
0x31, 0x6E, 0x01, 0xF1, 0x2B, 0x02, 0x3F, 0x00, 0xD2, 0x00, 0x72, 0x00, 0x47, 0x47, 0x47, 0x2A,
|
||||
0x00, 0x8F, 0x28, 0x02, 0x48, 0x00, 0x63, 0x63, 0x63, 0x7F, 0x7F, 0x7F, 0x03, 0x7B, 0x30, 0x8E,
|
||||
0x8E, 0x8E, 0x78, 0x00, 0x71, 0x71, 0x71, 0x11, 0xA5, 0x00, 0xBC, 0x01, 0x0B, 0x0B, 0x0B, 0xFF,
|
||||
0x00, 0x93, 0x93, 0x23, 0x93, 0x8B, 0x8B, 0x8B, 0x69, 0x69, 0x69, 0xC3, 0x03, 0x80, 0x06, 0x00,
|
||||
0x3B, 0x01, 0xB9, 0x01, 0x8D, 0x8D, 0x8D, 0x51, 0x00, 0xA0, 0x02, 0xC7, 0x36, 0x00, 0x1B, 0x00,
|
||||
0x05, 0x01, 0xD1, 0x01, 0x58, 0x58, 0x58, 0x87, 0x0F, 0x87, 0x87, 0x0C, 0x03, 0x8D, 0x00, 0x68,
|
||||
0x01, 0x8D, 0x00, 0x45, 0x30, 0x54, 0x00, 0xFC, 0x12, 0x00, 0x4D, 0x4D, 0x4D, 0x27, 0x00, 0x3F,
|
||||
0x00, 0x57, 0x00, 0xC1, 0x71, 0xC1, 0xC1, 0xB6, 0x01, 0x30, 0x00, 0x00, 0x00, 0x90, 0x30, 0x53,
|
||||
0x01, 0x90, 0x7C, 0x90, 0x90, 0x93, 0x00, 0xB6, 0x01, 0x56, 0x56, 0x56, 0xF2, 0x01, 0x8C, 0x60,
|
||||
0x00, 0xB4, 0x00, 0x4E, 0x00, 0x98, 0x98, 0x98, 0x1D, 0x01, 0x85, 0x47, 0x85, 0x85, 0xCC, 0x00,
|
||||
0x0C, 0x0C, 0x0C, 0x75, 0x75, 0x04, 0x75, 0x91, 0x91, 0x91, 0x1B, 0x00, 0x57, 0x57, 0x57, 0x10,
|
||||
0x9F, 0x9F, 0x9F, 0x34, 0x34, 0x34, 0x46, 0x46, 0x00, 0x46, 0x9B, 0x9B, 0x9B, 0xA8, 0x00, 0xBA,
|
||||
0x00, 0xB8, 0xB8, 0x30, 0xB8, 0x62, 0x62, 0x62, 0x07, 0x07, 0x07, 0x29, 0x01, 0x80, 0x99, 0x99,
|
||||
0x99, 0x86, 0x86, 0x86, 0x36, 0x00, 0x78, 0x00, 0xC0, 0x79, 0x79, 0x79, 0x9D, 0x9D, 0x9D, 0x68,
|
||||
0x68, 0x00, 0x68, 0x83, 0x83, 0x83, 0x5C, 0x5C, 0x5C, 0x13, 0x32, 0x80, 0x0C, 0x90, 0x35, 0xF4,
|
||||
0x30, 0x30, 0x30, 0x8F, 0x8F, 0x8F, 0x03, 0x14, 0x01, 0x36, 0x00, 0xAC, 0xAC, 0xAC, 0x95, 0x95,
|
||||
0x95, 0x03, 0x6B, 0x6B, 0x6B, 0xA0, 0xA0, 0xA0, 0x5C, 0x01, 0x46, 0x02, 0xC0, 0x15, 0x00, 0x8C,
|
||||
0x8C, 0x8C, 0xE1, 0x00, 0x71, 0x01, 0x3C, 0x63, 0x22, 0x71, 0x22, 0x22, 0x48, 0x00, 0x26, 0x26,
|
||||
0x26, 0x60, 0x00, 0xF6, 0x03, 0xC4, 0x54, 0x00, 0x35, 0x01, 0x18, 0x00, 0x60, 0x00, 0x35, 0x35,
|
||||
0x35, 0x41, 0x31, 0x8F, 0x2D, 0x2D, 0x2D, 0x6A, 0x6A, 0x6A, 0x7E, 0x7E, 0x00, 0x7E, 0x12, 0x00,
|
||||
0xCC, 0x33, 0x8D, 0x00, 0x32, 0x32, 0x32, 0x02, 0x01, 0x8E, 0x6E, 0x6E, 0x6E, 0x4F, 0x4F, 0x4F,
|
||||
0x12, 0x00, 0x36, 0x00, 0xC0, 0x02, 0x31, 0x51, 0x60, 0x37, 0x37, 0x37, 0x2F, 0x01, 0x45, 0x30,
|
||||
0x38, 0x63, 0x38, 0x38, 0x6F, 0x00, 0x24, 0x00, 0x24, 0x24, 0x24, 0x5A, 0x0C, 0x5A, 0x5A, 0x78,
|
||||
0x78, 0x78, 0x67, 0x67, 0x67, 0x00, 0x2E, 0x2E, 0x2E, 0x08, 0x01, 0x3E, 0x01, 0x06, 0x00, 0x7A,
|
||||
0x7A, 0x38, 0x7A, 0x5E, 0x5E, 0x5E, 0x4C, 0x4C, 0x4C, 0x78, 0x03, 0x80, 0x1E, 0x00, 0x78, 0x60,
|
||||
0x96, 0x00, 0xFB, 0x01, 0x57, 0x00, 0x45, 0x00, 0x15, 0x00, 0x40, 0x7F, 0x40, 0x40, 0x5D, 0x00,
|
||||
0xB4, 0x00, 0x28, 0x28, 0x28, 0x4B, 0x03, 0x8C, 0x36, 0x00, 0x84, 0x00, 0x2B, 0x2B, 0x2B, 0xC3,
|
||||
0x00, 0x33, 0x33, 0x23, 0x33, 0x3C, 0x3C, 0x3C, 0x1B, 0x00, 0x99, 0x00, 0x42, 0x42, 0x30, 0x42,
|
||||
0x2F, 0x2F, 0x2F, 0x30, 0x00, 0x4E, 0x4E, 0x4E, 0x10, 0x7B, 0x7B, 0x7B, 0x1B, 0x00, 0x48, 0x48,
|
||||
0x48, 0x1E, 0x00, 0x88, 0x1E, 0x33, 0x4A, 0x4A, 0x4A, 0x77, 0x77, 0x77, 0x3F, 0x00, 0x81, 0xEA,
|
||||
0x00, 0x4E, 0x00, 0x59, 0x59, 0x59, 0x76, 0x76, 0x76, 0x03, 0x65, 0x65, 0x65, 0x31, 0x31, 0x31,
|
||||
0x3C, 0x00, 0x0C, 0xC0, 0xC0, 0x53, 0xF1, 0x21, 0x21, 0x21, 0x1B, 0x00, 0x1F, 0x1F, 0x1F, 0x11,
|
||||
0x3D, 0x3D, 0x3D, 0xA3, 0xA3, 0xA3, 0x73, 0x73, 0x00, 0x73, 0x74, 0x74, 0x74, 0x61, 0x61, 0x61,
|
||||
0x20, 0x00, 0x20, 0x20, 0x21, 0x00, 0x23, 0x23, 0x23, 0x39, 0x39, 0x04, 0x39, 0x25, 0x25, 0x25,
|
||||
0x09, 0x00, 0x89, 0x91, 0x09, 0x00, 0x5A, 0x00, 0xF0, 0x09, 0x00, 0x21, 0x00, 0x09, 0x00, 0x27,
|
||||
0x30, 0x60, 0x00, 0x27, 0x00, 0x00, 0x00, 0x12, 0x30, 0xFF, 0x99, 0x30, 0x23, 0x91, 0x3C, 0x00,
|
||||
0xCC, 0x33, 0x0E, 0x0E, 0x0E, 0x12, 0x00, 0x8F, 0x02, 0xC1, 0x15, 0x30, 0x7B, 0x00, 0x45, 0x30,
|
||||
0x09, 0x00, 0x27, 0x00, 0x8D, 0xC0, 0x39, 0x00, 0xFF, 0x4E, 0x30, 0x33, 0x00, 0x14, 0x31, 0x57,
|
||||
0x00, 0x30, 0x00, 0x78, 0xC0, 0xAE, 0x60, 0x2A, 0x00, 0xFF, 0x0F, 0x0F, 0x0F, 0x5A, 0x00, 0x39,
|
||||
0x30, 0x03, 0x00, 0x06, 0x00, 0x13, 0x78, 0x13, 0x13, 0x1E, 0x00, 0x3C, 0x30, 0x06, 0x00, 0x1B,
|
||||
0x00, 0x7B, 0x00, 0x5D, 0x30, 0xFC, 0xB4, 0x00, 0x09, 0x00, 0x18, 0x30, 0x1E, 0x03, 0x06, 0x00,
|
||||
0x09, 0x30, 0xB3, 0x01, 0x03, 0x00, 0xFF, 0x09, 0x00, 0x12, 0x00, 0x48, 0x00, 0x12, 0x12, 0x12,
|
||||
0x1D, 0x1D, 0x07, 0x1D, 0x00, 0x00, 0x39, 0x00, 0x3C, 0x00, 0x0F, 0xF0, 0x36, 0xF0, 0x10, 0x10,
|
||||
0x3E, 0x10, 0x17, 0x17, 0x17, 0x3A, 0x3A, 0x3A, 0xAE, 0x00, 0xAE, 0xAE, 0x3B, 0x3B, 0x3B, 0x0F,
|
||||
0x00, 0x14, 0x14, 0x20, 0x14, 0x16, 0x16, 0x16, 0x09, 0x00, 0x39, 0x00, 0x11, 0x11, 0x30, 0x11,
|
||||
0x36, 0x00, 0xB2, 0xF2, 0x3C, 0xF0, 0x90, 0xF0, 0x90, 0xF0, 0x36, 0x30, 0x7B, 0x90, 0xFE, 0x0F,
|
||||
0xF0, 0x2A, 0xF0, 0x0F, 0xF0, 0x57, 0xF0, 0x0F, 0xF0, 0x18, 0xF0, 0x27, 0x00, 0x21, 0x00, 0xFF,
|
||||
0x45, 0xF0, 0x12, 0xF0, 0x60, 0x60, 0x0C, 0xC0, 0x30, 0x60, 0x18, 0x18, 0x18, 0x1F, 0x2A, 0x00,
|
||||
0x03, 0x30, 0x0F, 0xF0, 0x24, 0xF0, 0x00, 0x00, 0x1A, 0x1A, 0x1A, 0x1F, 0x27, 0x27, 0x27, 0x60,
|
||||
0x60, 0x60, 0x2A, 0x2A, 0x00, 0x2A, 0x15, 0x15, 0x15, 0x5C, 0x01, 0x00, 0x00, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0,
|
||||
0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F,
|
||||
0xF0, 0x0F, 0xF0, 0xFF, 0x18, 0xF0, 0x0D, 0x0D, 0x0D, 0x19, 0x19, 0x19, 0x1C, 0x01, 0x1C, 0x1C,
|
||||
0x06, 0x60, 0x03, 0x30, 0x00, 0x00, 0x1B, 0x1B, 0x1B, 0x1C, 0xFF, 0xFF, 0xA8, 0x1D, 0x00, 0x00,
|
||||
0x0E, 0x00, 0x00, 0x00, 0xD5, 0x31, 0x00, 0x00
|
||||
};
|
||||
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
// 68 x 192 @8bpp Grayscale RAW.
|
||||
#define X_BOOTLOGO 68
|
||||
#define Y_BOOTLOGO 192
|
||||
#define SZ_BOOTLOGO 13056
|
||||
#define SZ_BOOTLOGO_BLZ 6704
|
||||
static u8 BOOTLOGO_BLZ[SZ_BOOTLOGO_BLZ] = {
|
||||
0x0F, 0xF0, 0x80, 0x1B, 0x1B, 0x77, 0xF0, 0x6A, 0x08, 0x41, 0x80, 0x0F, 0x4D, 0x21, 0x40, 0x29,
|
||||
0xF0, 0xFC, 0x34, 0xED, 0x34, 0x10, 0x23, 0x26, 0x27, 0x23, 0x76, 0x30, 0x0F, 0xF0, 0xC3, 0xC9,
|
||||
0xF0, 0x3F, 0x7F, 0xC6, 0x53, 0x80, 0x2E, 0x33, 0xDB, 0x2D, 0xBA, 0x20, 0x8F, 0x1C, 0xE7, 0x76,
|
||||
0x23, 0xF8, 0x0E, 0x40, 0xF0, 0x54, 0x9C, 0x1E, 0x21, 0x3A, 0x1F, 0xBD, 0x71, 0x20, 0x2F, 0x3D,
|
||||
0xDB, 0x35, 0xFE, 0x00, 0x82, 0x19, 0xB1, 0x9E, 0x83, 0x5D, 0x22, 0x85, 0x1C, 0x93, 0xB1, 0x44,
|
||||
0x3F, 0xD2, 0x29, 0x63, 0x26, 0x39, 0x88, 0x33, 0x45, 0xDA, 0x38, 0x08, 0x9E, 0x50, 0x32, 0x56,
|
||||
0x78, 0x75, 0x27, 0x1D, 0x1D, 0x99, 0xE6, 0xE8, 0xC3, 0x28, 0x33, 0xD0, 0x2B, 0x21, 0xC9, 0xB0,
|
||||
0x49, 0xB9, 0x1C, 0x60, 0x30, 0x4F, 0xA1, 0x6D, 0x3A, 0x36, 0x37, 0x36, 0x00, 0x34, 0x2B, 0x79,
|
||||
0x3C, 0x51, 0xF1, 0x2E, 0x3C, 0xD2, 0x32, 0x0C, 0x26, 0x19, 0xC6, 0x9F, 0x70, 0x95, 0x21, 0x8D,
|
||||
0xBB, 0xBC, 0xBA, 0x0E, 0xBB, 0xBB, 0xBA, 0xBC, 0xBB, 0xF4, 0x10, 0x4E, 0xF1, 0xC9, 0x10, 0xE0,
|
||||
0xD2, 0x36, 0xC9, 0x90, 0x11, 0x1E, 0x19, 0xA0, 0x1C, 0x27, 0x3F, 0x1C, 0x52, 0x54, 0x51, 0x51,
|
||||
0x50, 0x51, 0x4D, 0x3A, 0x00, 0x24, 0xE0, 0x87, 0x38, 0x60, 0xC9, 0x10, 0x0D, 0xB1, 0x34, 0x59,
|
||||
0xDA, 0xB1, 0x13, 0xDE, 0x93, 0x25, 0x28, 0x27, 0x88, 0x2D, 0xEB, 0x9A, 0x6A, 0x46, 0x1F, 0xC9,
|
||||
0x70, 0xB9, 0x81, 0xF4, 0x71, 0x4C, 0x29, 0x02, 0x30, 0x2A, 0x1F, 0x73, 0x02, 0x7C, 0x22, 0xC7,
|
||||
0x90, 0xD4, 0xB0, 0x24, 0xD4, 0x37, 0x25, 0x85, 0xB0, 0x27, 0x6B, 0xA4, 0xA3, 0x08, 0x0C, 0x47,
|
||||
0x91, 0xAC, 0xBB, 0x2C, 0x27, 0x72, 0x01, 0x54, 0x22, 0x6F, 0x60, 0xF7, 0xBC, 0x6C, 0x14, 0x25,
|
||||
0x7D, 0x88, 0x48, 0x5C, 0xDA, 0x3B, 0x7D, 0xA8, 0x84, 0x08, 0x48, 0xAB, 0x8A, 0x6A, 0x0C, 0xA7,
|
||||
0x32, 0x2B, 0x56, 0xA8, 0x2B, 0x02, 0x20, 0x2C, 0xF2, 0xC0, 0x6C, 0x14, 0x34, 0x14, 0x05, 0x99,
|
||||
0x09, 0xB5, 0x30, 0x7C, 0x8C, 0x45, 0x0F, 0x50, 0xA5, 0x30, 0x27, 0x42, 0x91, 0xAD, 0x1B, 0x1E,
|
||||
0xFE, 0xC0, 0xB0, 0x04, 0x6C, 0x04, 0x2C, 0x79, 0x22, 0x95, 0x21, 0x0A, 0x65, 0x1A, 0xE9, 0x22,
|
||||
0xB7, 0x8A, 0x69, 0x33, 0x45, 0xA4, 0x2E, 0x24, 0xF5, 0x27, 0x80, 0x1C, 0x1F, 0x23, 0x24, 0x25,
|
||||
0x26, 0x51, 0x11, 0x26, 0x40, 0x25, 0x4C, 0x01, 0x99, 0x07, 0x25, 0x25, 0x2C, 0x3A, 0x4A, 0x06,
|
||||
0xD3, 0xC4, 0x33, 0x60, 0x45, 0x48, 0x79, 0x2C, 0xA4, 0x23, 0xED, 0x5F, 0x75, 0x76, 0x89, 0x37,
|
||||
0x46, 0xA4, 0x32, 0x2B, 0x47, 0xAA, 0x00, 0x42, 0x1E, 0x1D, 0x20, 0x29, 0x2F, 0x0A, 0x10, 0x38,
|
||||
0x40, 0x01, 0x10, 0x37, 0x01, 0x00, 0x36, 0x37, 0x37, 0x37, 0x3B, 0x05, 0x47, 0x50, 0xD2, 0xFC,
|
||||
0x1F, 0xB5, 0xB3, 0x1C, 0xFA, 0xB3, 0xA5, 0x58, 0x8C, 0x64, 0xA7, 0x4C, 0x5B, 0x9F, 0x89, 0x2B,
|
||||
0x00, 0x1D, 0x1D, 0x24, 0x2F, 0xD1, 0x01, 0x10, 0xD2, 0x01, 0x10, 0xA0, 0xD2, 0xD3, 0xD3, 0xD3,
|
||||
0xD4, 0xD4, 0xD4, 0xD2, 0x00, 0xD2, 0xD4, 0xD4, 0xED, 0x34, 0xE0, 0x72, 0x20, 0xF5, 0x27, 0xA0,
|
||||
0x6E, 0x5B, 0x71, 0x50, 0x56, 0x90, 0xB6, 0xBA, 0xBA, 0xB0, 0x03, 0x86, 0x36, 0x25, 0x0B, 0x21,
|
||||
0x2B, 0x38, 0x3F, 0x02, 0x10, 0x84, 0x42, 0x02, 0x10, 0x40, 0x00, 0x00, 0x41, 0x41, 0x41, 0x43,
|
||||
0x0A, 0x46, 0x45, 0x3B, 0x2D, 0x20, 0xBD, 0xCC, 0x68, 0xD8, 0x30, 0x60, 0x41, 0x4F, 0x54, 0x4F,
|
||||
0x43, 0x33, 0x24, 0x16, 0x04, 0x80, 0x1E, 0x24, 0x2C, 0x2F, 0x30, 0x31, 0x0A, 0x00, 0x32, 0x40,
|
||||
0x32, 0x31, 0x31, 0x30, 0x31, 0x32, 0x31, 0x30, 0x00, 0x30, 0x31, 0x31, 0x32, 0x2F, 0x2B, 0xD4,
|
||||
0x75, 0xBD, 0x5C, 0xC0, 0x61, 0xA9, 0x7F, 0x00, 0x9C, 0x05, 0x29, 0x24, 0x1F, 0x1D, 0xC1, 0x29,
|
||||
0x87, 0x20, 0x22, 0x21, 0x22, 0x26, 0x15, 0x0B, 0x22, 0x21, 0x20, 0x20, 0x21, 0x20, 0x21, 0x20,
|
||||
0x4F, 0x1E, 0x1F, 0x1E, 0x20, 0x1E, 0x1D, 0x85, 0x90, 0x39, 0xB8, 0x1D, 0x23, 0x2B, 0x30, 0x0C,
|
||||
0x2E, 0x2F, 0x2F, 0x2F, 0x2F, 0x30, 0x2D, 0x2F, 0x00, 0x2C, 0x35, 0x26, 0x1C, 0x1D, 0x1E, 0x24,
|
||||
0x29, 0x2C, 0x02, 0x31, 0x31, 0x2D, 0x28, 0x25, 0x1E, 0x1E, 0x4D, 0x53, 0x80, 0x09, 0xF5, 0x41,
|
||||
0xA0, 0xA4, 0xA6, 0xA5, 0xA6, 0xA7, 0x39, 0x18, 0x83, 0xA7, 0xA5, 0xA2, 0x25, 0xAF, 0x28, 0x29,
|
||||
0x32, 0x3A, 0x10, 0x7D, 0xA0, 0xAB, 0xA0, 0x6E, 0x35, 0x2A, 0x21, 0x00, 0x9D, 0xFB, 0x1B, 0xCD,
|
||||
0x5D, 0x1C, 0x96, 0x6F, 0x72, 0x76, 0x7E, 0x0D, 0xA5, 0x8D, 0x74, 0x72, 0x73, 0x7A, 0x9D, 0x8C,
|
||||
0x00, 0x2B, 0x1F, 0x10, 0x2B, 0x3A, 0x8B, 0xDD, 0xC1, 0xA3, 0x02, 0x82, 0xAD, 0xC2, 0xE4, 0x6C,
|
||||
0x2D, 0x22, 0x1D, 0x00, 0xC4, 0x32, 0x35, 0xFC, 0x9D, 0x8A, 0x1D, 0x24, 0x2E, 0x36, 0x42, 0x07,
|
||||
0x74, 0x8F, 0x41, 0x35, 0x33, 0x35, 0x40, 0x51, 0x00, 0x9E, 0x30, 0x1D, 0x1B, 0x1F, 0x29, 0x3A,
|
||||
0x98, 0x00, 0xDC, 0x59, 0x43, 0x3F, 0x3F, 0x43, 0x49, 0x77, 0x00, 0xD2, 0x6C, 0x06, 0x29, 0x5D,
|
||||
0xF6, 0x2D, 0x13, 0x25, 0x88, 0x1D, 0x1E, 0x3C, 0x23, 0x37, 0x8A, 0x68, 0x2B, 0x12, 0x27, 0x3F,
|
||||
0x8A, 0x10, 0x61, 0x1F, 0x1C, 0x24, 0x34, 0x64, 0xDC, 0x58, 0x00, 0x3B, 0x2F, 0x2C, 0x2A, 0x30,
|
||||
0x38, 0x45, 0x69, 0x00, 0xDB, 0x33, 0x24, 0xBC, 0x79, 0xBD, 0x9C, 0xE1, 0xDA, 0x21, 0x36, 0x38,
|
||||
0x84, 0x62, 0x09, 0x19, 0x1C, 0x28, 0x43, 0x98, 0x59, 0x02, 0x20, 0x1E, 0x2A, 0x3B, 0xB7, 0x8C,
|
||||
0x3A, 0x29, 0x00, 0x21, 0x1E, 0x1F, 0x21, 0x28, 0x37, 0x45, 0xB6, 0x00, 0x88, 0x2C, 0x20, 0xC2,
|
||||
0xF5, 0x21, 0x7D, 0x28, 0x31, 0x50, 0xA5, 0x42, 0xE8, 0x54, 0xB0, 0x7B, 0x37, 0x33, 0x37, 0x4D,
|
||||
0x8D, 0x00, 0xA4, 0x30, 0x1E, 0x1E, 0x2F, 0x3F, 0xD2, 0x3F, 0x00, 0x2E, 0x1F, 0x86, 0x36, 0x3B,
|
||||
0x7F, 0xAA, 0x30, 0x8E, 0x56, 0x84, 0x58, 0x76, 0xD9, 0x41, 0x05, 0xC6, 0x38, 0x61, 0xA1, 0xBB,
|
||||
0xAB, 0x07, 0xAB, 0xB5, 0x92, 0x47, 0x24, 0x41, 0x20, 0x3A, 0x27, 0x20, 0x1D, 0x2A, 0x30, 0x36,
|
||||
0x44, 0xD2, 0x33, 0x3A, 0x95, 0x1A, 0x42, 0xA1, 0x76, 0x85, 0xC0, 0xFD, 0x0B, 0x34, 0x44, 0x4A,
|
||||
0x48, 0x47, 0x07, 0x45, 0x38, 0x15, 0x03, 0x20, 0x30, 0x41, 0x10, 0xCD, 0x43, 0x32, 0x64, 0x42,
|
||||
0xD2, 0xBD, 0x00, 0x84, 0x60, 0x7D, 0x30, 0x35, 0x1C, 0xAD, 0x3B, 0x7B, 0xC8, 0xFC, 0x25, 0x25,
|
||||
0x25, 0x25, 0xA2, 0x16, 0xC9, 0x20, 0x37, 0x8D, 0x3B, 0xB0, 0xBD, 0x00, 0x41, 0x20, 0x1C, 0xE5,
|
||||
0xF6, 0x3D, 0x14, 0x61, 0xD2, 0x3A, 0x08, 0x29, 0x7B, 0x28, 0x60, 0x02, 0x1E, 0xE4, 0x0B, 0x40,
|
||||
0xD2, 0x7A, 0x5F, 0x1F, 0x4A, 0x32, 0x41, 0xD2, 0x38, 0x25, 0x46, 0x50, 0xD9, 0x81, 0x2D, 0x23,
|
||||
0xE0, 0x0C, 0xD8, 0x44, 0x80, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x01, 0x93, 0x24, 0x71, 0x08, 0x09,
|
||||
0x70, 0x20, 0x35, 0x00, 0x36, 0x7E, 0x85, 0xAC, 0x1C, 0x3D, 0xA4, 0x95, 0x51, 0x87, 0x4D, 0x4A,
|
||||
0xAB, 0x96, 0x95, 0x0E, 0xB2, 0x92, 0x90, 0xAB, 0x7A, 0x28, 0x1B, 0x1F, 0x00, 0x31, 0x41, 0xD3,
|
||||
0x39, 0x2A, 0xA3, 0x01, 0x06, 0x00, 0x24, 0x60, 0x36, 0x45, 0xD4, 0x3B, 0x29, 0x1F, 0x86, 0x01,
|
||||
0x1E, 0x40, 0x1F, 0x1D, 0x1C, 0x8D, 0xD9, 0xF6, 0xB7, 0x2F, 0x7C, 0x8D, 0x18, 0x4E, 0x5A, 0xA8,
|
||||
0x4D, 0x47, 0x5B, 0x97, 0x2B, 0x00, 0x1C, 0x20, 0x31, 0x45, 0xD3, 0x42, 0x35, 0x2B, 0x00, 0x0D,
|
||||
0x21, 0x30, 0x3F, 0x4E, 0xD4, 0x44, 0x35, 0x2B, 0x01, 0x2B, 0x2C, 0x2C, 0x2B, 0x27, 0x79, 0x01,
|
||||
0x1C, 0x7B, 0x54, 0xA0, 0x89, 0x3D, 0x7D, 0xC8, 0x8B, 0x69, 0x34, 0x47, 0xA4, 0x37, 0x03, 0x2B,
|
||||
0x41, 0x8F, 0x56, 0x1F, 0x1F, 0x31, 0x43, 0x00, 0xDD, 0x83, 0x7E, 0x00, 0x00, 0x06, 0x00, 0x7D,
|
||||
0x81, 0x89, 0x18, 0xDD, 0x84, 0x7D, 0x7A, 0x79, 0x7A, 0x79, 0x7A, 0x00, 0x77, 0x73, 0x24, 0x1E,
|
||||
0xB7, 0x36, 0x25, 0x6B, 0x17, 0x57, 0x56, 0x35, 0xF0, 0x35, 0x7C, 0x79, 0x32, 0x40, 0x98, 0x5A,
|
||||
0x27, 0x00, 0x3C, 0x8A, 0x62, 0x21, 0x1F, 0x2B, 0x3D, 0xAE, 0x00, 0xAE, 0x01, 0x10, 0xAB, 0xAB,
|
||||
0xAB, 0xAB, 0xAD, 0xB0, 0x02, 0xB2, 0xAF, 0x00, 0x00, 0xAC, 0xAB, 0xAB, 0xA9, 0xA6, 0x04, 0x25,
|
||||
0x1F, 0x7D, 0x98, 0xD1, 0x29, 0x77, 0x9C, 0x2C, 0x52, 0xB0, 0x1C, 0x6F, 0x3C, 0x70, 0x9D, 0x44,
|
||||
0x56, 0xAB, 0x40, 0x00, 0x1E, 0x1E, 0x24, 0x31, 0x39, 0x3F, 0x09, 0x10, 0x06, 0x10, 0xC0, 0x40,
|
||||
0x41, 0x43, 0x41, 0x3D, 0x3C, 0x3C, 0x3C, 0x00, 0x3C, 0x3B, 0x36, 0x2E, 0x24, 0x1E, 0x49, 0xA9,
|
||||
0x29, 0x47, 0xC0, 0x41, 0x8D, 0x65, 0x9C, 0x33, 0x43, 0x95, 0xBB, 0xB7, 0x01, 0x7A, 0x2B, 0x62,
|
||||
0x0E, 0x22, 0x28, 0x2C, 0x2B, 0x29, 0x04, 0x01, 0x00, 0x07, 0x00, 0x2B, 0x2E, 0x2E, 0x2C, 0x2D,
|
||||
0xC2, 0x00, 0x83, 0x2B, 0x2B, 0x28, 0x24, 0x1F, 0x1C, 0xE9, 0xC2, 0x49, 0x50, 0xC0, 0xA5, 0x52,
|
||||
0x32, 0x2F, 0x25, 0x2E, 0x41, 0x4B, 0x44, 0x01, 0x30, 0x40, 0x10, 0xD4, 0x08, 0x08, 0x10, 0x20,
|
||||
0x05, 0x10, 0x1F, 0x47, 0x09, 0xAE, 0x1F, 0x20, 0x1E, 0x1E, 0x1E, 0x20, 0x1E, 0xFC, 0x55, 0x80,
|
||||
0x1A, 0x41, 0x10, 0x09, 0x35, 0x3B, 0xC4, 0x83, 0x04, 0x28, 0x28, 0x26, 0x1E, 0xD9, 0x64, 0x1A,
|
||||
0x28, 0xB3, 0x3D, 0xF4, 0x69, 0x0B, 0xAE, 0xC1, 0x1E, 0x26, 0x3D, 0x32, 0x51, 0x66, 0x63, 0x3F,
|
||||
0x27, 0x20, 0x24, 0x26, 0x80, 0x25, 0x28, 0x05, 0x10, 0x01, 0x00, 0x2C, 0x2A, 0x29, 0xDA, 0x2E,
|
||||
0x8C, 0xD5, 0x0E, 0x27, 0x22, 0x1E, 0xA1, 0xC6, 0x28, 0xC3, 0x92, 0x98, 0x14, 0xD1, 0x5F, 0xA5,
|
||||
0xAC, 0xA5, 0xA5, 0xB0, 0x95, 0x3B, 0x00, 0x7D, 0x08, 0x21, 0x2B, 0x37, 0x3C, 0x40, 0x3F, 0x09,
|
||||
0x00, 0x81, 0x3F, 0x41, 0x40, 0x40, 0x40, 0x40, 0x42, 0x3F, 0x00, 0x40, 0x40, 0x3F, 0x40, 0x3E,
|
||||
0x38, 0x31, 0x26, 0x00, 0x1E, 0xC2, 0x4D, 0xD9, 0x41, 0x7D, 0xC8, 0x26, 0x49, 0xAB, 0x73, 0x0E,
|
||||
0x4A, 0x47, 0x49, 0x51, 0x87, 0x9C, 0x0E, 0x09, 0x25, 0x40, 0x36, 0x00, 0x00, 0x07, 0x60, 0xF4,
|
||||
0x00, 0x00, 0x00, 0x00, 0xF5, 0xF5, 0x36, 0xF5, 0x34, 0x84, 0x22, 0x35, 0x29, 0xA7, 0xF7, 0x33,
|
||||
0x7C, 0x8C, 0x32, 0x39, 0x27, 0x26, 0x27, 0x35, 0x4B, 0x9F, 0x4B, 0x00, 0x1E, 0x1D, 0x26, 0x30,
|
||||
0x40, 0x4A, 0x5F, 0x0E, 0x50, 0x40, 0x02, 0x20, 0x52, 0x0E, 0x4C, 0x2E, 0x4D, 0x45, 0x39, 0x27,
|
||||
0x41, 0x70, 0x87, 0x22, 0x59, 0x0A, 0x39, 0x7D, 0xA8, 0x1A, 0x20, 0x36, 0x8A, 0x0A, 0x68, 0x27,
|
||||
0x1C, 0x6F, 0x0C, 0x7D, 0x08, 0x1F, 0x1C, 0x20, 0x18, 0x29, 0x32, 0x35, 0x39, 0x38, 0x6B, 0x0C,
|
||||
0xAD, 0x1F, 0x39, 0x60, 0x39, 0x39, 0xA4, 0x1F, 0x38, 0x38, 0x33, 0x2A, 0x24, 0x04, 0x1E, 0xE9,
|
||||
0x82, 0xD5, 0xF5, 0x34, 0x7E, 0x81, 0x2A, 0x35, 0x02, 0x86, 0x27, 0x42, 0x9D, 0x4D, 0x20, 0x6B,
|
||||
0x02, 0x20, 0x21, 0x20, 0x22, 0x21, 0x69, 0x1C, 0x23, 0xAA, 0x1F, 0x21, 0x23, 0x31, 0x01, 0x94,
|
||||
0x21, 0x23, 0x21, 0x1E, 0x1E, 0x1B, 0x05, 0xC9, 0x7D, 0xB8, 0xC0, 0x2D, 0x51, 0xAA, 0x68, 0x33,
|
||||
0x2F, 0x33, 0x40, 0x00, 0x85, 0x9E, 0x2E, 0x09, 0x90, 0x78, 0xF0, 0x1A, 0x69, 0xEB, 0x99, 0x7A,
|
||||
0xD8, 0x38, 0x6A, 0xA6, 0xAB, 0xA6, 0xA6, 0xAF, 0x98, 0x00, 0x47, 0x24, 0x00, 0x00, 0x60, 0xF1,
|
||||
0x81, 0xF4, 0x85, 0x10, 0x29, 0xC1, 0x25, 0x7C, 0x37, 0x47, 0x60, 0x73, 0x71, 0x53, 0x39, 0x25,
|
||||
0x00, 0x09, 0x80, 0x34, 0xDC, 0x51, 0xE1, 0x68, 0x40, 0xEF, 0x78, 0x27, 0x2E, 0x31, 0x1F, 0x2E,
|
||||
0x29, 0x72, 0xC3, 0x81, 0x70, 0xE9, 0xD2, 0x71, 0x23, 0x3E, 0x98, 0x22, 0x7C, 0x23, 0x23, 0x23,
|
||||
0x22, 0x25, 0x25, 0x24, 0x24, 0x00, 0x23, 0x23, 0x20, 0x1B, 0x1A, 0x0C, 0x30, 0xB9, 0x01, 0x0E,
|
||||
0x70, 0xE0, 0x1A, 0x34, 0x66, 0xC9, 0xE0, 0x1C, 0x38, 0x42, 0x63, 0x67, 0x66, 0x16, 0x67, 0x68,
|
||||
0x67, 0x66, 0x68, 0x68, 0x68, 0x65, 0x00, 0x5E, 0xC5, 0xE4, 0x19, 0x35, 0xA0, 0x0D, 0x61, 0x41,
|
||||
0x10, 0xD2, 0x42, 0xB0, 0x11, 0xFA, 0x36, 0xAE, 0x1F, 0x97, 0x01, 0xA8, 0x1F, 0xA9, 0x1F, 0xAD,
|
||||
0xFA, 0xC9, 0xF0, 0xC5, 0x04, 0xFE, 0x41, 0x80, 0x79, 0x0C, 0x40, 0x46, 0x46, 0x46, 0x97, 0x11,
|
||||
0x46, 0x43, 0x46, 0x41, 0x33, 0x80, 0xA4, 0x1A, 0xCD, 0x04, 0x1C, 0x1D, 0x28, 0x5D, 0x41, 0xE9,
|
||||
0xF2, 0xC2, 0x92, 0x22, 0x9B, 0x01, 0x25, 0x00, 0x00, 0x26, 0x57, 0x26, 0x4C, 0x3E, 0x1C, 0x29,
|
||||
0x80, 0x24, 0x21, 0x20, 0x1B, 0x0A, 0x09, 0x5C, 0x89, 0x5C, 0x0D, 0x71, 0xCF, 0xA9, 0x23, 0xBD,
|
||||
0x33, 0x1F, 0x25, 0x2F, 0x33, 0x1E, 0xBD, 0x95, 0x23, 0x2B, 0x90, 0x63, 0xC6, 0x01, 0x84, 0x61,
|
||||
0xF2, 0x51, 0x11, 0x36, 0x82, 0x19, 0x28, 0x07, 0x32, 0x85, 0x60, 0x17, 0x25, 0x23, 0x21, 0x21,
|
||||
0x24, 0x34, 0x85, 0x5E, 0x00, 0x20, 0x59, 0x40, 0x1A, 0x92, 0x1B, 0x29, 0x33, 0xA7, 0x77, 0x0A,
|
||||
0x27, 0x2F, 0x30, 0x19, 0xD1, 0x99, 0x22, 0x2D, 0x23, 0xE7, 0x13, 0xAA, 0x6F, 0xEA, 0x59, 0x71,
|
||||
0x9E, 0x88, 0x6A, 0x67, 0x67, 0x68, 0x00, 0x6A, 0x71, 0xAB, 0x56, 0xC7, 0x90, 0x1E, 0x2A, 0x3A,
|
||||
0x10, 0x41, 0x00, 0x82, 0x91, 0xF6, 0x56, 0x49, 0x29, 0x18, 0x30, 0x74, 0x4F, 0x90, 0xAA, 0x3F,
|
||||
0xB1, 0xAD, 0xA7, 0x13, 0x0E, 0xA8, 0xA5, 0x74, 0x2D, 0x08, 0x1D, 0xBF, 0x81, 0x20, 0x2B, 0x3C,
|
||||
0xAB, 0x79, 0x2A, 0x02, 0x1E, 0x37, 0xDA, 0x8D, 0x49, 0xD1, 0x39, 0x0C, 0x11, 0x9F, 0x10, 0x3E,
|
||||
0x56, 0x3E, 0x92, 0x77, 0x4B, 0x46, 0x46, 0x45, 0x45, 0x3E, 0x00, 0x2E, 0x21, 0xE0, 0x10, 0xA2,
|
||||
0x7C, 0x3D, 0x41, 0x00, 0xD9, 0x39, 0xEC, 0xC1, 0xEC, 0x19, 0x06, 0x69, 0x5B, 0x86, 0x39, 0x25,
|
||||
0x34, 0x51, 0x3F, 0x29, 0x07, 0x26, 0x24, 0x24, 0x25, 0x23, 0xDB, 0xB1, 0x1F, 0x2B, 0x20, 0x39,
|
||||
0xAB, 0x7A, 0x2B, 0x1F, 0x28, 0x61, 0xF9, 0x93, 0xDA, 0x60, 0x95, 0x21, 0xAA, 0x9B, 0x22, 0x23,
|
||||
0x21, 0x25, 0x27, 0x25, 0x03, 0x07, 0x03, 0x86, 0xB0, 0x28, 0x36, 0xA9, 0x77, 0x28, 0x1E, 0x03,
|
||||
0x1B, 0x1C, 0x33, 0x82, 0x19, 0xC9, 0x80, 0x1A, 0xA5, 0xB2, 0x2D, 0x54, 0x45, 0x78, 0x89, 0x88,
|
||||
0x6C, 0x2E, 0x22, 0x86, 0xA0, 0x80, 0x1C, 0x24, 0x2D, 0x56, 0x41, 0x22, 0x07, 0x00, 0x6E, 0x4B,
|
||||
0xC0, 0x9D, 0x8A, 0x2D, 0x13, 0xE4, 0xA0, 0xFD, 0x0B, 0x7B, 0xB0, 0xA5, 0x32, 0x0F, 0xA0, 0xCF,
|
||||
0xB9, 0x0C, 0x26, 0x22, 0xEF, 0x26, 0x75, 0xA0, 0x55, 0x1E, 0x51, 0xD1, 0xBA, 0x0C, 0xF9, 0xA5,
|
||||
0x22, 0x3F, 0x4B, 0x6B, 0xA3, 0x29, 0xFF, 0xC7, 0x1F, 0x41, 0x30, 0x47, 0x21, 0xD1, 0xA9, 0x7F,
|
||||
0x2E, 0x50, 0xA5, 0x02, 0x32, 0xA5, 0x02, 0x30, 0x5F, 0xA5, 0x02, 0x1D, 0x4C, 0xE0, 0x1A, 0x9A,
|
||||
0x64, 0x69, 0xCB, 0x41, 0xB0, 0x37, 0x75, 0x89, 0x67, 0x40, 0x12, 0x24, 0x3E, 0x8B, 0x62, 0x21,
|
||||
0x04, 0x99, 0x67, 0x7C, 0xE0, 0x1E, 0x52, 0x19, 0x6D, 0x37, 0x28, 0xFA, 0xB0, 0x33, 0x57, 0x75,
|
||||
0x8F, 0x2D, 0x1F, 0xA5, 0x32, 0x33, 0x66, 0x40, 0xF0, 0xD1, 0xA9, 0xF0, 0xDC, 0x81, 0x24, 0x9A,
|
||||
0x8A, 0x2A, 0x44, 0xA4, 0x89, 0x46, 0x06, 0x37, 0x39, 0x58, 0xA5, 0x02, 0xC7, 0x00, 0x39, 0xF7,
|
||||
0x41, 0xF0, 0xF9, 0x33, 0xF8, 0xD1, 0xB6, 0xA5, 0x12, 0xBA, 0xAC, 0x7D, 0x34, 0x21, 0x03, 0x30,
|
||||
0x83, 0x3A, 0xF0, 0xE5, 0xF6, 0x0D, 0x71, 0x7C, 0x44, 0x31, 0x40, 0x4B, 0x50, 0x0F, 0x4D, 0x42,
|
||||
0x30, 0x32, 0x3C, 0x1B, 0x3B, 0xF0, 0xC1, 0xCB, 0x35, 0x68, 0x47, 0xDA, 0x39, 0x27, 0x21, 0xD6,
|
||||
0x21, 0x28, 0x32, 0x10, 0x33, 0x31, 0x28, 0x20, 0x57, 0x87, 0xFE, 0x8A, 0x0A, 0x1B, 0x19, 0x38,
|
||||
0xB5, 0x93, 0xDA, 0x7D, 0x38, 0x11, 0x9A, 0x2C, 0x46, 0x7A, 0x88, 0x0D, 0x88, 0x6D, 0x2E, 0x21,
|
||||
0x1C, 0xDD, 0x29, 0x26, 0x22, 0x20, 0x44, 0x05, 0x1C, 0x9E, 0x88, 0x27, 0x2D, 0x2D, 0x29, 0x68,
|
||||
0x09, 0x85, 0xA1, 0x76, 0x48, 0xC9, 0x00, 0x9C, 0xB5, 0x21, 0x30, 0x7C, 0xAF, 0x0D, 0x95, 0x8E,
|
||||
0x8E, 0x9A, 0xAF, 0x56, 0xD1, 0x09, 0x26, 0x40, 0x32, 0x40, 0x41, 0x38, 0x28, 0x1F, 0x62, 0x28,
|
||||
0x34, 0x08, 0xC0, 0x4A, 0x0E, 0x1E, 0x28, 0x38, 0x86, 0x85, 0x81, 0x2B, 0x01, 0x80, 0x44, 0x1C,
|
||||
0xB5, 0x53, 0x0E, 0x61, 0x32, 0x3C, 0x57, 0xAB, 0x56, 0x1D, 0x3E, 0x3E, 0x3E, 0x4B, 0x6C, 0xA3,
|
||||
0x2A, 0xB5, 0x03, 0x80, 0x4B, 0x81, 0x14, 0x24, 0x84, 0x09, 0x29, 0x30, 0x33, 0x2E, 0x0A, 0x27,
|
||||
0x46, 0x04, 0x20, 0x31, 0x52, 0x2E, 0x00, 0x3B, 0xD1, 0x49, 0xA2, 0x1C, 0x1A, 0x91, 0x45, 0x9E,
|
||||
0xBA, 0x32, 0x84, 0x7C, 0x33, 0x0C, 0x22, 0x23, 0x24, 0x2F, 0x48, 0x98, 0x56, 0x1E, 0x00, 0x21,
|
||||
0x39, 0x81, 0x24, 0xF0, 0x03, 0x29, 0x3A, 0xA0, 0xB6, 0x0C, 0xB4, 0x5D, 0xC5, 0x01, 0x21, 0x3B,
|
||||
0x65, 0x2E, 0x00, 0x48, 0x44, 0x55, 0x8E, 0x85, 0x20, 0xD1, 0xA4, 0x20, 0x38, 0x8A, 0x67, 0x25,
|
||||
0x07, 0xBA, 0x00, 0x24, 0x3F, 0x8B, 0x62, 0x20, 0x21, 0x3F, 0x01, 0xF5, 0x27, 0x85, 0x00, 0x2F,
|
||||
0x4F, 0x8E, 0x09, 0x85, 0x2A, 0x1E, 0x13, 0x19, 0x22, 0x3E, 0x6F, 0x6E, 0x24, 0x1C, 0x61, 0xB2,
|
||||
0x8B, 0xA4, 0xD0, 0x1F, 0x33, 0x75, 0x8E, 0x2E, 0x1E, 0x1D, 0x1E, 0x00, 0x2B, 0x47, 0xAB, 0x41,
|
||||
0x1E, 0xD9, 0x31, 0x4F, 0x2A, 0x20, 0x1C, 0x20, 0x35, 0x5F, 0x41, 0x00, 0x8C, 0x30, 0x20, 0x10,
|
||||
0x1B, 0x22, 0x41, 0x40, 0xB5, 0xC3, 0x0E, 0x71, 0x8E, 0x25, 0x44, 0xA5, 0x3C, 0x89, 0x45, 0x37,
|
||||
0x39, 0x59, 0x9E, 0x8A, 0x2B, 0x00, 0x1B, 0x23, 0x41, 0x10, 0x10, 0x4E, 0x41, 0x00, 0x37, 0x85,
|
||||
0x10, 0xA8, 0x8E, 0x32, 0x20, 0xD2, 0x16, 0xB6, 0x20, 0x39, 0xC8, 0xA5, 0x22, 0x5D, 0x83, 0xF8,
|
||||
0x55, 0x8E, 0xB1, 0xBC, 0xBC, 0xAD, 0x7E, 0x36, 0x00, 0xD5, 0x05, 0x85, 0x30, 0x29, 0x85, 0x50,
|
||||
0x32, 0x1F, 0x1B, 0x23, 0x0B, 0x3A, 0x25, 0x50, 0x95, 0x81, 0x45, 0xBD, 0x1A, 0xC0, 0x20, 0x23,
|
||||
0x2F, 0x2D, 0x40, 0x4B, 0x4E, 0x4C, 0x41, 0x30, 0x23, 0x1C, 0x00, 0x10, 0x40, 0x50, 0x2B, 0x48,
|
||||
0x02, 0x65, 0x41, 0x20, 0x8E, 0x16, 0xA2, 0x23, 0xE9, 0xB1, 0xA7, 0xDC, 0x7D, 0x48, 0xC0, 0x96,
|
||||
0x24, 0x27, 0x29, 0x27, 0x0D, 0x25, 0x1F, 0x1D, 0x19, 0x16, 0xB5, 0x43, 0x1F, 0x39, 0x66, 0x18,
|
||||
0x41, 0x00, 0x90, 0x33, 0x1F, 0xA2, 0x63, 0x1A, 0xA1, 0x86, 0xE9, 0x62, 0xD1, 0xF3, 0x47, 0x22,
|
||||
0x24, 0x25, 0x1F, 0x1E, 0x22, 0x2C, 0x01, 0x31, 0x2C, 0x26, 0x5A, 0x1A, 0xC9, 0x20, 0x53, 0x30,
|
||||
0x22, 0x18, 0x27, 0x3F, 0x6B, 0xBA, 0x08, 0x93, 0x39, 0x26, 0x21, 0x08, 0x28, 0x46, 0x73, 0xC9,
|
||||
0xA0, 0x1C, 0xD5, 0x05, 0x99, 0x0E, 0xB7, 0x54, 0xE8, 0x49, 0x28, 0x34, 0x78, 0x89, 0x6D, 0x34,
|
||||
0x46, 0x8F, 0x01, 0xB0, 0xAB, 0x86, 0x29, 0x1D, 0x1B, 0xB5, 0x33, 0x69, 0x40, 0x49, 0x3C, 0x41,
|
||||
0x55, 0x76, 0x11, 0x0A, 0x9E, 0x52, 0x20, 0x3F, 0x3C, 0x43, 0x5B, 0x7D, 0x85, 0x40, 0x1C, 0xD9,
|
||||
0x81, 0xA0, 0x29, 0x2E, 0x83, 0x22, 0x3B, 0xA5, 0x9C, 0x8F, 0xA0, 0x02, 0x9A, 0x93, 0x87, 0x5A,
|
||||
0x66, 0xA1, 0x86, 0x24, 0x00, 0x81, 0x44, 0xC4, 0xC1, 0x07, 0x00, 0x14, 0x1A, 0xD5, 0xC2, 0xBF,
|
||||
0x19, 0xBE, 0xBF, 0xC3, 0xC5, 0x2E, 0x00, 0x50, 0x41, 0x60, 0x1A, 0x50, 0xD1, 0x79, 0x72, 0x43,
|
||||
0x2D, 0x6C, 0x99, 0x47, 0x43, 0x54, 0x03, 0x9E, 0xA1, 0x3E, 0x30, 0x3D, 0x5C, 0xAA, 0x2C, 0x00,
|
||||
0x1D, 0x02, 0x6F, 0x41, 0xF0, 0xFF, 0x4E, 0x22, 0xD1, 0xD9, 0xA5, 0x83, 0x8A, 0x75, 0x69, 0x2E,
|
||||
0x28, 0x3C, 0x74, 0x8A, 0x2D, 0x1E, 0x00, 0x2A, 0x48, 0xA3, 0x41, 0x00, 0x3E, 0xD9, 0x11, 0xFF,
|
||||
0x3D, 0xF0, 0xA8, 0x4C, 0x2A, 0x59, 0xAA, 0x39, 0x45, 0x8D, 0x23, 0x39, 0x8A, 0x14, 0x63, 0x24,
|
||||
0x20, 0x32, 0x6C, 0x87, 0x27, 0x1A, 0x00, 0x24, 0x43, 0xA5, 0x2F, 0x51, 0x01, 0x61, 0xE9, 0xF2,
|
||||
0xFF, 0x50, 0x3E, 0x21, 0xD5, 0xB5, 0x3D, 0x84, 0x22, 0x3A, 0x89, 0x66, 0x28, 0x07, 0x26, 0x34,
|
||||
0x6D, 0x89, 0x2E, 0x21, 0x2B, 0x48, 0x00, 0xA5, 0x31, 0xE1, 0x0A, 0x4A, 0x96, 0xA0, 0x00, 0x00,
|
||||
0xA2, 0x44, 0xA3, 0xA1, 0x01, 0x10, 0xA2, 0xA2, 0xA2, 0xA2, 0xA3, 0x04, 0xA2, 0xA2, 0xA0, 0x9A,
|
||||
0x8B, 0x37, 0xAD, 0x9B, 0x35, 0x0C, 0xC0, 0x29, 0x9B, 0x61, 0xD5, 0x04, 0x8C, 0x84, 0x66, 0x64,
|
||||
0x6D, 0x06, 0x8A, 0x9A, 0x68, 0x63, 0x68, 0x72, 0xAB, 0x2E, 0x00, 0x1B, 0x1F, 0x29, 0x08, 0x53,
|
||||
0x55, 0x50, 0x4E, 0x4D, 0x04, 0x4C, 0x01, 0x10, 0x00, 0x00, 0x4D, 0x4D, 0x4D, 0x4C, 0x4D, 0x06,
|
||||
0x4A, 0x43, 0x37, 0x29, 0x20, 0x69, 0xCB, 0x31, 0x80, 0x31, 0x60, 0x6C, 0x8C, 0x8A, 0x8A, 0x8C,
|
||||
0x90, 0x8F, 0x8B, 0x00, 0x8A, 0x8B, 0x8D, 0x89, 0xF6, 0x0F, 0x27, 0x3A, 0x4A, 0x10, 0x4F, 0x47,
|
||||
0x38, 0x2E, 0x01, 0x10, 0x9D, 0x01, 0x28, 0x29, 0x30, 0x29, 0x28, 0x2A, 0x29, 0x2A, 0x29, 0x27,
|
||||
0x23, 0x00, 0x1F, 0xA1, 0xB6, 0x3A, 0x09, 0x95, 0x25, 0x32, 0x39, 0x3A, 0x0A, 0x3B, 0x39, 0x3C,
|
||||
0x3D, 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x31, 0x21, 0xA1, 0x06, 0x4D, 0x41, 0x00, 0x38, 0x26, 0x1D,
|
||||
0x14, 0x1D, 0x02, 0x00, 0xB4, 0x04, 0x1C, 0x1C, 0x1D, 0x1E, 0x1D, 0x06, 0x1C, 0x1D, 0xB6, 0x01,
|
||||
0xF5, 0xC7, 0x81, 0xA4, 0x4C, 0x03, 0x01, 0x10, 0x22, 0x7C, 0x40, 0x03, 0x20, 0x75, 0x01, 0x3A,
|
||||
0x89, 0x1D, 0x44, 0x1F, 0x50, 0x18, 0xF0, 0xD5, 0x95, 0x51, 0x0D, 0x91, 0x85, 0xD0, 0x3F, 0x6D,
|
||||
0x71, 0x13, 0x2A, 0xF8, 0x95, 0xA7, 0xA8, 0x00, 0x54, 0x20, 0x01, 0x9D, 0x51, 0x71, 0x21, 0xF0,
|
||||
0xA9, 0x5F, 0x4E, 0xC0, 0x1C, 0x7F, 0xAD, 0xBE, 0xB5, 0x33, 0x19, 0x94, 0x50, 0x1C, 0xA0, 0xD9,
|
||||
0x11, 0x6F, 0x78, 0x4F, 0xBB, 0xD1, 0xF7, 0xB1, 0xB7, 0x04, 0x3E, 0x74, 0x97, 0x1A, 0x1E, 0x30,
|
||||
0x85, 0x40, 0x5B, 0x6F, 0x38, 0x2A, 0x2B, 0x03, 0x30, 0x2A, 0x2B, 0x29, 0x2A, 0x08, 0x2A, 0x2A,
|
||||
0x28, 0x29, 0x24, 0x20, 0x1C, 0x71, 0x93, 0x80, 0xE5, 0xF6, 0x7D, 0x8A, 0x21, 0x3F, 0x73, 0x5A,
|
||||
0x4F, 0x4F, 0x50, 0x07, 0x4F, 0x01, 0x00, 0x4E, 0x4F, 0x4F, 0x4E, 0x50, 0x50, 0x02, 0x4F, 0x4D,
|
||||
0x46, 0x38, 0x28, 0x20, 0x51, 0x41, 0x1C, 0x40, 0x71, 0x73, 0x1C, 0x3E, 0x31, 0x0B, 0x04, 0x20,
|
||||
0x1D, 0xAB, 0x57, 0x24, 0x4D, 0x68, 0x5E, 0xFF, 0x3D, 0xF0, 0x3A, 0x24, 0x1B, 0x55, 0x9E, 0x3B,
|
||||
0x45, 0xD9, 0xA1, 0x7C, 0x6C, 0x2B, 0x20, 0x7D, 0x23, 0x30, 0x53, 0x21, 0x49, 0x09, 0x21, 0x11,
|
||||
0x0E, 0x40, 0xF0, 0xA5, 0x12, 0xE8, 0x71, 0x1F, 0x34, 0x3D, 0x21, 0x3F, 0x7F, 0x41, 0xDE, 0x1E,
|
||||
0xAB, 0x9E, 0x40, 0x24, 0x1C, 0x07, 0x1E, 0x27, 0x3B, 0x85, 0xAF, 0x6E, 0x95, 0x01, 0x24, 0x2E,
|
||||
0xC0, 0xFF, 0x21, 0xFB, 0x47, 0x89, 0x2D, 0x85, 0x80, 0x01, 0x10, 0x19, 0xFB, 0x53, 0xBA, 0x4E,
|
||||
0x8E, 0xB4, 0x6F, 0x30, 0x33, 0x57, 0xA5, 0x00, 0xA0, 0x50, 0x2F, 0x21, 0x85, 0x40, 0x03, 0x30,
|
||||
0x03, 0x30, 0x00, 0x00, 0xF0, 0x63, 0x0F, 0xDF, 0x3D, 0x25, 0xD9, 0x91, 0xDC, 0x3B, 0x28, 0x11,
|
||||
0x2C, 0x84, 0x1D, 0x24, 0x30, 0x45, 0x65, 0xA7, 0xA1, 0x01, 0x8B, 0xB1, 0x78, 0x3E, 0x2A, 0x78,
|
||||
0x07, 0x22, 0x89, 0x2D, 0xA0, 0x7D, 0x6E, 0x05, 0x30, 0x66, 0x01, 0x00, 0x65, 0x66, 0x66, 0x14,
|
||||
0x66, 0x63, 0x59, 0x46, 0x30, 0x1F, 0x1C, 0xD9, 0xA1, 0x80, 0xED, 0x5F, 0x19, 0xCB, 0x4D, 0x4A,
|
||||
0x76, 0xB6, 0xBB, 0x88, 0x05, 0x43, 0x5B, 0x23, 0xCD, 0x3D, 0x64, 0x44, 0x3A, 0x39, 0x06, 0x00,
|
||||
0x86, 0x00, 0x00, 0x39, 0x38, 0x3A, 0x39, 0x38, 0x38, 0x38, 0x01, 0x32, 0x2B, 0x22, 0xC8, 0x20,
|
||||
0x19, 0x6D, 0x77, 0x1C, 0xE5, 0x95, 0xA8, 0x27, 0x3B, 0x88, 0xB2, 0x8F, 0x79, 0xAC, 0x9F, 0x00,
|
||||
0x41, 0x1A, 0x16, 0x23, 0xD0, 0x2C, 0x52, 0x2F, 0x20, 0x20, 0x0A, 0x1F, 0x1F, 0x20, 0x22, 0x21,
|
||||
0x0C, 0x06, 0x1F, 0x21, 0x20, 0x1F, 0x20, 0x20, 0x20, 0x36, 0x01, 0x5D, 0x96, 0x95, 0xB1, 0x20,
|
||||
0x70, 0x2F, 0x55, 0xA5, 0xA0, 0x5D, 0x3F, 0x3F, 0x51, 0x00, 0x8F, 0xB6, 0x6F, 0x2B, 0x1E, 0x58,
|
||||
0x5D, 0x2B, 0x31, 0xD5, 0xA0, 0xB7, 0x22, 0xD6, 0x24, 0x19, 0x6D, 0xE7, 0x1E, 0x2A, 0x72, 0xB0,
|
||||
0x0B, 0x77, 0x3E, 0x2B, 0x23, 0x24, 0x30, 0x47, 0x6F, 0x00, 0xAB, 0x9B, 0x24, 0xD0, 0x0C, 0x04,
|
||||
0x1C, 0x4D, 0xE3, 0x08, 0x14, 0x9C, 0xD8, 0x21, 0x23, 0x20, 0x1E, 0x61, 0x92, 0x46, 0xDC, 0x39,
|
||||
0x10, 0x27, 0x95, 0x95, 0x6F, 0x4D, 0x32, 0x9F, 0x1A, 0x1F, 0x2A, 0x22, 0x3B, 0x4A, 0x86, 0x26,
|
||||
0x8D, 0x09, 0xA5, 0x12, 0x46, 0xEB, 0x80, 0xB0, 0x1C, 0x1E, 0x26, 0x2E, 0x36, 0x3A, 0x48, 0x29,
|
||||
0x00, 0x1E, 0xC1, 0xB8, 0x4E, 0x46, 0x07, 0x30, 0x27, 0x26, 0x2E, 0x36, 0x1D, 0x4E, 0x23, 0x2B,
|
||||
0x2B, 0x20, 0x50, 0x06, 0x4F, 0xBF, 0xC0, 0x10, 0xB9, 0x38, 0x10, 0x30, 0x1A, 0x19, 0x1C, 0x1E,
|
||||
0x23, 0x04, 0x2A, 0xED, 0x03, 0x87, 0xC3, 0xF7, 0x36, 0xD1, 0x89, 0x34, 0x42, 0x41, 0xB0, 0x04,
|
||||
0x08, 0x01, 0x71, 0x57, 0x15, 0x27, 0x37, 0x47, 0x48, 0x0F, 0x3E, 0x2B, 0x20, 0x11, 0x3E, 0x10,
|
||||
0x26, 0x2F, 0x3A, 0x49, 0x0C, 0x69, 0xAC, 0x1B, 0x17, 0x43, 0xD8, 0x70, 0x0D, 0x31, 0xAC, 0x9F,
|
||||
0x29, 0x74, 0x2D, 0xB1, 0x0B, 0x2E, 0x2E, 0x4D, 0x35, 0x2C, 0x18, 0x2A, 0x2B, 0x32, 0x28, 0xE0,
|
||||
0x12, 0x1E, 0x20, 0x24, 0x2B, 0x36, 0x45, 0x02, 0x55, 0xA1, 0xD2, 0x3F, 0x30, 0x49, 0x27, 0xD1,
|
||||
0xF9, 0x1B, 0x48, 0xF0, 0x5F, 0x78, 0xA4, 0xA5, 0xA6, 0xA4, 0xA4, 0xA5, 0x01, 0xA5, 0xA6, 0xA6,
|
||||
0xA5, 0xA2, 0x19, 0x00, 0x1D, 0xB8, 0x00, 0xA0, 0x1C, 0x1C, 0x11, 0x05, 0x28, 0x32, 0x3D, 0x4E,
|
||||
0x7B, 0x04, 0xC9, 0x10, 0x52, 0xFF, 0x42, 0x3D, 0x84, 0xB5, 0x53, 0x19, 0x49, 0x45, 0xB2, 0x28,
|
||||
0x54, 0x6F, 0x72, 0x72, 0x72, 0x72, 0x73, 0x00, 0x79, 0x82, 0x9B, 0xBB, 0x8B, 0x99, 0x58, 0x21,
|
||||
0x26, 0x20, 0x2F, 0x38, 0x4A, 0x68, 0xAD, 0xE1, 0x5C, 0x52, 0xDD, 0x40, 0xB1, 0x63, 0xD8, 0x0A,
|
||||
0x1B, 0x19, 0x69, 0x9B, 0xF9, 0x97, 0x29, 0x64, 0x31, 0x71, 0x07, 0x38, 0x44, 0x62, 0xA5, 0xAD,
|
||||
0x6E, 0x02, 0x37, 0x20, 0x69, 0x19, 0x1F, 0x24, 0x2B, 0x35, 0x42, 0x04, 0x54, 0x96, 0xD2, 0xA8,
|
||||
0x52, 0xF8, 0xB4, 0x7D, 0x5E, 0x08, 0x4B, 0x37, 0x27, 0x20, 0xD0, 0x6C, 0x21, 0xD1, 0x29, 0xDE,
|
||||
0x01, 0xD0, 0x19, 0x17, 0x6A, 0x23, 0x09, 0x28, 0x39, 0x78, 0xB6, 0x8F, 0x06, 0x45, 0x2F, 0x82,
|
||||
0x10, 0x1E, 0x24, 0x30, 0x3C, 0x4C, 0x04, 0x79, 0xC0, 0xF4, 0x12, 0xD7, 0x25, 0x85, 0x00, 0x6A,
|
||||
0x49, 0x35, 0x1C, 0x2B, 0x22, 0x20, 0xA9, 0x9F, 0x48, 0xE9, 0xE2, 0x20, 0x2C, 0x28, 0x4D, 0x9F,
|
||||
0xAC, 0x67, 0x38, 0x25, 0x1E, 0x08, 0x2A, 0x80, 0x37, 0x50, 0xAB, 0x6C, 0x52, 0xF1, 0xCD, 0x9B,
|
||||
0x0D, 0x01, 0x88, 0xE3, 0x4F, 0x2F, 0x1F, 0x80, 0x28, 0x19, 0xF6, 0xBE, 0x62, 0x26, 0x70, 0x37,
|
||||
0x76, 0xB6, 0x8E, 0x41, 0x2E, 0x22, 0xB9, 0x40, 0x80, 0x51, 0x10, 0x51, 0xD3, 0x94, 0x6A, 0x63,
|
||||
0x74, 0xA4, 0x02, 0x41, 0x00, 0x48, 0x55, 0x20, 0x09, 0xD5, 0xF0, 0x9F, 0x2C, 0x4E, 0xA1, 0x1D,
|
||||
0xA7, 0x63, 0x3D, 0x2C, 0x25, 0x22, 0x21, 0x21, 0x00, 0x37, 0x03, 0x21, 0x3A, 0x64, 0xCF, 0x20,
|
||||
0xD6, 0xAC, 0x7A, 0x11, 0x63, 0x4E, 0x40, 0x3F, 0x5A, 0xA3, 0x41, 0x20, 0xEB, 0x8F, 0xC0, 0x61,
|
||||
0x22, 0x05, 0x09, 0x27, 0x19, 0x81, 0x2B, 0x6F, 0xB6, 0xA5, 0x0B, 0x7D, 0x72, 0x6A, 0x68, 0x68,
|
||||
0x67, 0x68, 0x65, 0x00, 0x5D, 0x22, 0xB5, 0x23, 0x98, 0x25, 0xB5, 0x7D, 0x59, 0x42, 0x0C, 0x36,
|
||||
0x37, 0x53, 0xA2, 0x85, 0x00, 0x45, 0xBA, 0x33, 0xA1, 0xA6, 0xD0, 0xE9, 0x92, 0x1E, 0x2F, 0x82,
|
||||
0xAA, 0xAB, 0xA8, 0xA7, 0x01, 0xA7, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA2, 0x24, 0x00, 0x74, 0x04,
|
||||
0x5D, 0xD1, 0x50, 0xDA, 0xA8, 0x60, 0x4D, 0x63, 0x05, 0x41, 0x00, 0xE1, 0x22, 0x02, 0xB8, 0xB2,
|
||||
0x2D, 0x23, 0xA4, 0x86, 0x27, 0x39, 0x3D, 0x4A, 0x4A, 0x47, 0x46, 0x45, 0x46, 0x46, 0x46, 0x00,
|
||||
0x46, 0x42, 0x35, 0x23, 0x79, 0x0C, 0x44, 0x65, 0x99, 0x10, 0xD5, 0xD1, 0x40, 0xF8, 0xD2, 0xAC,
|
||||
0xA5, 0xFF, 0xFF, 0x02, 0xE2, 0x9A, 0x71, 0x21, 0x5F, 0x59, 0x8A, 0x98, 0x30, 0x25, 0x02, 0x10,
|
||||
0x26, 0x5E, 0x24, 0x26, 0x25, 0x24, 0xB1, 0x12, 0x21, 0x2D, 0x3F, 0x10, 0x53, 0x65, 0x74, 0xB5,
|
||||
0x69, 0x0F, 0x3B, 0x64, 0x5A, 0x39, 0x30, 0x29, 0x21, 0x3B, 0x44, 0x1B, 0x95, 0xF1, 0x89, 0xC5,
|
||||
0xD0, 0x30, 0x25, 0x74, 0x2D, 0x39, 0x48, 0x59, 0x6C, 0x8F, 0xC5, 0xF1, 0x00, 0x44, 0x40, 0xF8,
|
||||
0xCB, 0x83, 0x49, 0x39, 0x2B, 0xB3, 0x83, 0x81, 0x21, 0x33, 0xBD, 0x3C, 0xC7, 0xF0, 0x5E, 0x91,
|
||||
0x29, 0x32, 0x40, 0x1C, 0x4F, 0x61, 0x72, 0xA4, 0xD6, 0x66, 0x12, 0x63, 0x22, 0xC3, 0x60, 0x74,
|
||||
0x2E, 0x2C, 0x03, 0x35, 0xFC, 0x8C, 0x45, 0x42, 0x80, 0xB4, 0x84, 0x26, 0x7C, 0x2B, 0x37, 0x43,
|
||||
0x55, 0x67, 0x82, 0xB5, 0xE3, 0x00, 0x69, 0x53, 0x3C, 0xF8, 0x70, 0x21, 0x3D, 0x44, 0x69, 0x9B,
|
||||
0x64, 0x7D, 0x28, 0x94, 0xF5, 0x21, 0x27, 0x2F, 0x3B, 0x49, 0x5B, 0x6E, 0x8E, 0x00, 0xCD, 0xF2,
|
||||
0x1B, 0x22, 0x46, 0x85, 0x50, 0x2D, 0x13, 0xF9, 0xE3, 0x30, 0xD4, 0xF4, 0x88, 0x62, 0x20, 0x22,
|
||||
0x2A, 0x33, 0x40, 0x50, 0x62, 0x01, 0x74, 0xAC, 0xD5, 0x0D, 0x21, 0xC9, 0x80, 0x95, 0xC1, 0x25,
|
||||
0x37, 0x25, 0x78, 0x29, 0x28, 0x29, 0x28, 0x27, 0x00, 0x13, 0x1F, 0x21, 0x20, 0x21, 0x20, 0x1D,
|
||||
0xD7, 0x5B, 0x1E, 0x1E, 0x25, 0x2D, 0x08, 0x37, 0x45, 0x57, 0x6C, 0x86, 0xB5, 0xE7, 0x45, 0x00,
|
||||
0x82, 0x22, 0x45, 0x9D, 0x24, 0xCB, 0x51, 0x82, 0x88, 0x76, 0x0C, 0x86, 0x47, 0x82, 0x23, 0x94,
|
||||
0x06, 0x2F, 0x6C, 0x2E, 0x25, 0x2F, 0x82, 0x84, 0x1E, 0x21, 0x2A, 0x38, 0x4F, 0x6B, 0x7F, 0xCE,
|
||||
0x00, 0x3F, 0x25, 0x9B, 0xA1, 0x16, 0x0D, 0x72, 0x3D, 0x24, 0x56, 0xAF, 0x93, 0x1E, 0x76, 0x6B,
|
||||
0x6B, 0x6A, 0x69, 0x60, 0x24, 0x01, 0x0E, 0x80, 0x43, 0xF6, 0x87, 0x3B, 0x28, 0x1E, 0x1D, 0x97,
|
||||
0x40, 0x80, 0xC5, 0x10, 0x39, 0x55, 0x9E, 0xF1, 0xB5, 0x93, 0x22, 0x59, 0xFA, 0xA1, 0x1F, 0x32,
|
||||
0x84, 0x80, 0x42, 0x34, 0xC9, 0x10, 0x25, 0x40, 0xB4, 0x06, 0x38, 0x1C, 0x05, 0xA8, 0x42, 0x2B,
|
||||
0x21, 0x3E, 0x56, 0x85, 0x22, 0x2B, 0x3E, 0x5A, 0xC2, 0x41, 0x20, 0xF1, 0x7B, 0x59, 0x6A, 0xE0,
|
||||
0x76, 0x8D, 0x8A, 0x68, 0x2A, 0x39, 0x02, 0x20, 0x1E, 0x1C, 0x11, 0x2D, 0x03, 0x3C, 0x69, 0x0F,
|
||||
0x00, 0xCD, 0x46, 0x2E, 0xC8, 0x3F, 0x89, 0x1E, 0x25, 0x32, 0x49, 0x7F, 0x4A, 0x21, 0x49, 0x29,
|
||||
0x20, 0xA5, 0xC2, 0x81, 0xA4, 0x1F, 0x30, 0x6B, 0x88, 0x2D, 0x1E, 0x03, 0xBD, 0x5D, 0x3A, 0xD8,
|
||||
0x14, 0xFF, 0xE0, 0x5C, 0x30, 0x23, 0x05, 0x1D, 0x47, 0x02, 0x28, 0x3A, 0x55, 0xB9, 0x82, 0x20,
|
||||
0xF1, 0x42, 0x40, 0x25, 0xF9, 0xA3, 0x3B, 0x25, 0xCB, 0x28, 0x45, 0x9A, 0x14, 0x83, 0x43, 0x2F,
|
||||
0x2E, 0x2F, 0x2D, 0x26, 0x1D, 0x02, 0x80, 0x33, 0x59, 0x90, 0x20, 0xE9, 0x6E, 0x34, 0x26, 0x1F,
|
||||
0x04, 0x22, 0x2F, 0x44, 0x70, 0xDB, 0x82, 0x20, 0xCB, 0x65, 0x20, 0x35, 0x21, 0x85, 0xB0, 0x28,
|
||||
0x62, 0xB2, 0x27, 0x47, 0x9A, 0x14, 0xBC, 0xA6, 0xA5, 0xA4, 0xA4, 0xA3, 0xA0, 0x24, 0x00, 0xCC,
|
||||
0x00, 0x42, 0x68, 0xB4, 0x09, 0x20, 0x82, 0x3D, 0x34, 0x11, 0x3A, 0x51, 0x9A, 0x37, 0x20, 0xF8,
|
||||
0xA9, 0x57, 0x3A, 0x08, 0x27, 0x1E, 0xA5, 0x82, 0x15, 0xBA, 0xEF, 0x2B, 0x75, 0xA2, 0x55, 0x1C,
|
||||
0x47, 0x43, 0x43, 0x42, 0x3E, 0x32, 0x22, 0xCE, 0x01, 0x80, 0x2C, 0x45, 0x67, 0x9B, 0x57, 0x11,
|
||||
0xFF, 0xAB, 0x59, 0x10, 0x72, 0xCC, 0x7F, 0x20, 0xDC, 0x78, 0x4C, 0x34, 0xAE, 0x40, 0x84, 0xE9,
|
||||
0xF2, 0xDB, 0x3B, 0x1F, 0x36, 0x8B, 0x6C, 0x30, 0x26, 0x03, 0x26, 0x24, 0x24, 0x24, 0x22, 0x17,
|
||||
0x10, 0x22, 0x2B, 0x20, 0x3F, 0x5F, 0x8F, 0xEA, 0x03, 0x10, 0xD4, 0xE9, 0x3C, 0x10, 0x90, 0xF9,
|
||||
0xBB, 0x5D, 0x41, 0x2E, 0xC7, 0x9A, 0x19, 0x22, 0x20, 0xE9, 0x12, 0x85, 0x10, 0x76, 0x9D, 0x79,
|
||||
0x6F, 0xEF, 0x8C, 0x77, 0x03, 0x3B, 0x67, 0x59, 0x83, 0xDD, 0x4B, 0x51, 0xE3, 0x86, 0x50, 0x37,
|
||||
0x08, 0x29, 0xF4, 0x4D, 0x1C, 0x6E, 0x33, 0x22, 0x19, 0x06, 0x25, 0x4B, 0xB2, 0x67, 0xEA, 0x2E,
|
||||
0x51, 0x98, 0x47, 0x31, 0x2F, 0x2F, 0x30, 0x00, 0x2D, 0x26, 0x28, 0x3A, 0x1F, 0x27, 0x37, 0x52,
|
||||
0x74, 0x04, 0xCD, 0x06, 0x31, 0xC4, 0x66, 0x45, 0xEA, 0x06, 0xFD, 0xC2, 0x19, 0x26, 0xE2, 0x71,
|
||||
0xB3, 0x2C, 0x6E, 0xA3, 0xB6, 0xA6, 0xA6, 0xA4, 0x01, 0xA6, 0xA4, 0xA1, 0xAE, 0x02, 0x5D, 0x09,
|
||||
0x20, 0x21, 0x28, 0x18, 0x35, 0x50, 0x70, 0xB5, 0xC1, 0x10, 0xEA, 0x83, 0x51, 0x10, 0x34, 0x26,
|
||||
0xC0, 0x0C, 0x57, 0x03, 0x79, 0x8B, 0xF5, 0x37, 0x61, 0x53, 0x1A, 0x7C, 0xC1, 0x01, 0x1D, 0x28,
|
||||
0x55, 0x73, 0x77, 0x74, 0x71, 0x01, 0x71, 0x73, 0x71, 0x65, 0x24, 0x1B, 0x1C, 0x1F, 0x00, 0x26,
|
||||
0x2C, 0x30, 0x33, 0x35, 0x39, 0x47, 0x5E, 0x00, 0x7B, 0x9C, 0x42, 0x20, 0x69, 0x41, 0x36, 0x24,
|
||||
0x00, 0x2F, 0x44, 0x27, 0x68, 0x10, 0x49, 0x99, 0x6D, 0xC7, 0x1F, 0x26, 0x32, 0x34, 0x0E, 0x33,
|
||||
0x3C, 0x04, 0x32, 0xB1, 0x01, 0x1E, 0x29, 0x39, 0x86, 0x0A, 0x8E, 0x90, 0x90, 0x90, 0x94, 0x9A,
|
||||
0xA3, 0xA4, 0x00, 0xAD, 0xC4, 0x04, 0xFF, 0xEA, 0x98, 0x92, 0x8F, 0x91, 0x02, 0x8F, 0x8A, 0x80,
|
||||
0x2B, 0x1F, 0xCE, 0x00, 0xE9, 0xF2, 0x3A, 0x84, 0xE0, 0x25, 0x27, 0x2A, 0x28, 0x25, 0x62, 0x0B,
|
||||
0xB1, 0x07, 0x51, 0x60, 0x41, 0xF0, 0xFF, 0xC6, 0x21, 0x97, 0x20, 0x15, 0x5A, 0xE5, 0x56, 0xCC,
|
||||
0x7A, 0x2B, 0x7D, 0x45, 0x79, 0x89, 0x87, 0x6E, 0x2C, 0x75, 0x0C, 0x21, 0x40, 0x39, 0x63, 0x01,
|
||||
0x10, 0x3D, 0xF0, 0x44, 0x28, 0x69, 0xBB, 0x28, 0x4C, 0x35, 0xC9, 0x31, 0x7B, 0xB1, 0x94, 0x8E,
|
||||
0x8E, 0x9A, 0x01, 0xB0, 0x56, 0xA8, 0x01, 0x39, 0x62, 0x01, 0x10, 0x39, 0xF4, 0x45, 0x64, 0x27,
|
||||
0x1B, 0xA1, 0x76, 0x46, 0xDB, 0x59, 0x1A, 0x2B, 0x93, 0x28, 0x64, 0x57, 0xAB, 0x56, 0x40, 0x3D,
|
||||
0x3F, 0x4B, 0x6C, 0x00, 0xA3, 0x2A, 0x1D, 0x20, 0x30, 0x4E, 0xC1, 0x05, 0x10, 0x80, 0xC5, 0xC5,
|
||||
0xC5, 0xC5, 0xC4, 0xC5, 0xC6, 0x00, 0x00, 0x80, 0xC5, 0xC6, 0xC5, 0xC4, 0xC4, 0xC2, 0xB9, 0x39,
|
||||
0x00, 0x0D, 0x91, 0x4D, 0x15, 0x50, 0x85, 0x56, 0x1A, 0x83, 0x7C, 0x33, 0x24, 0x0F, 0x25, 0x24,
|
||||
0x2F, 0x48, 0x98, 0x56, 0x1E, 0x1E, 0x00, 0x29, 0x38, 0x4B, 0x59, 0x5B, 0x59, 0x01, 0x00, 0x03,
|
||||
0x00, 0xC0, 0x5A, 0x5B, 0x59, 0x5A, 0x5A, 0x5B, 0x5B, 0x5B, 0x00, 0x5C, 0x5D, 0x53, 0x41, 0x2D,
|
||||
0x1F, 0x1B, 0x1A, 0x00, 0x91, 0xB5, 0x6A, 0xA8, 0x37, 0x8A, 0x66, 0x24, 0x33, 0x00, 0x24, 0x43,
|
||||
0x40, 0x8C, 0x62, 0x4B, 0x00, 0x30, 0x3D, 0x41, 0x3F, 0x08, 0x39, 0x33, 0x30, 0x30, 0x31, 0x32,
|
||||
0x31, 0x32, 0x00, 0x30, 0x32, 0x30, 0x32, 0x32, 0x31, 0x38, 0x40, 0x00, 0x48, 0x46, 0x38, 0x29,
|
||||
0x1F, 0x99, 0x80, 0x51, 0x51, 0x8E, 0x86, 0xE0, 0x74, 0x8F, 0x2E, 0x1E, 0x1D, 0x1E, 0x2B, 0x47,
|
||||
0x00, 0xAB, 0x41, 0x20, 0x1F, 0x29, 0x3A, 0x87, 0x87, 0x00, 0x81, 0x2F, 0x24, 0xE1, 0x07, 0x24,
|
||||
0x26, 0x27, 0x26, 0x08, 0x22, 0x8C, 0x02, 0x21, 0x2E, 0x41, 0xB7, 0xB8, 0xB3, 0x02, 0x32, 0x22,
|
||||
0x9B, 0x50, 0x0D, 0x31, 0x29, 0x8E, 0x20, 0x18, 0x52, 0x1D, 0x6C, 0x2B, 0x45, 0xA5, 0x89, 0x45,
|
||||
0x37, 0x3B, 0x59, 0x00, 0x9E, 0x8A, 0x2B, 0x1B, 0x8E, 0x00, 0x10, 0x00, 0x3B, 0x26, 0x30, 0x05,
|
||||
0x02, 0x2B, 0x36, 0x39, 0x35, 0x28, 0x1F, 0x2E, 0x12, 0x81, 0x59, 0x2E, 0x00, 0x3F, 0x24, 0x5D,
|
||||
0x86, 0x45, 0x51, 0x51, 0x81, 0x81, 0xD2, 0x55, 0x8D, 0xB0, 0xBC, 0xBC, 0xAC, 0x7D, 0xE5, 0x06,
|
||||
0x80, 0x22, 0xC1, 0x28, 0x48, 0x28, 0x1B, 0x1E, 0x28, 0x3F, 0x02, 0xC0, 0xDE, 0xDD, 0x70, 0x27,
|
||||
0x85, 0x00, 0x3B, 0x68, 0x20, 0x2E, 0x00, 0x49, 0x58, 0x19, 0x1A, 0x84, 0x43, 0xD9, 0x21, 0x42,
|
||||
0xBA, 0x9D, 0x05, 0xF5, 0x4B, 0x4F, 0x4D, 0x42, 0x31, 0x24, 0x4A, 0x09, 0x3E, 0x40, 0x20, 0x11,
|
||||
0x4D, 0x28, 0x1C, 0x1E, 0x31, 0x53, 0x41, 0x00, 0x81, 0x87, 0x2E, 0x51, 0x01, 0x3E, 0x6E, 0xB6,
|
||||
0x10, 0x50, 0x10, 0x1A, 0x64, 0x71, 0x43, 0x48, 0xB5, 0x13, 0x81, 0xA4, 0xE9, 0x06, 0x24, 0x25,
|
||||
0x45, 0x17, 0x9D, 0x1F, 0x1E, 0x1D, 0x23, 0x3F, 0x10, 0x20, 0x2A, 0x1C, 0x20, 0x20, 0x36, 0x61,
|
||||
0x41, 0x00, 0x8F, 0x30, 0x1F, 0x1B, 0x08, 0x21, 0x82, 0x21, 0x4F, 0x2B, 0x1C, 0x1A, 0xD5, 0xF5,
|
||||
0x1B, 0x42, 0x1D, 0x62, 0x5D, 0x41, 0x9B, 0x01, 0x19, 0x1E, 0x27, 0x5D, 0x09, 0x4F, 0x1E, 0x21,
|
||||
0x41, 0x10, 0x30, 0x19, 0x06, 0xC9, 0x20, 0x34, 0x70, 0xC6, 0x01, 0x3F, 0x72, 0x30, 0xA5, 0x82,
|
||||
0xC5, 0x04, 0x28, 0xCE, 0x40, 0x4B, 0x39, 0xDD, 0x2E, 0x41, 0x8B, 0x69, 0x34, 0x2F, 0x2F, 0x2F,
|
||||
0x00, 0x34, 0x41, 0x8F, 0x5F, 0x20, 0x98, 0x30, 0x4E, 0x29, 0x20, 0x1B, 0x20, 0xD5, 0x35, 0x33,
|
||||
0x1F, 0x1B, 0x23, 0x2E, 0x20, 0x84, 0x50, 0x2A, 0x1D, 0x72, 0x6D, 0xA7, 0xFE, 0x27, 0x90, 0xA8,
|
||||
0xB2, 0x1C, 0xAC, 0xA5, 0xA5, 0xA5, 0xA5, 0xA7, 0xA7, 0xAB, 0x00, 0x3D, 0x1F, 0x22, 0x54, 0x40,
|
||||
0xAC, 0x03, 0x67, 0x91, 0x45, 0x21, 0x58, 0x2E, 0x50, 0x41, 0xB0, 0xC7, 0x84, 0x1E, 0x2E, 0x63,
|
||||
0x7C, 0xA0, 0x07, 0x8F, 0x75, 0x73, 0x73, 0x73, 0x72, 0x70, 0x3E, 0x00, 0x27, 0x1B, 0x23, 0x40,
|
||||
0x6F, 0x10, 0x20, 0x09, 0x05, 0x65, 0x60, 0xC5, 0x14, 0x31, 0x1E, 0xB6, 0x10, 0x41, 0x20, 0x19,
|
||||
0x1B, 0x95, 0x91, 0x99, 0xF9, 0x03, 0xEA, 0x72, 0x22, 0x2F, 0x43, 0x7C, 0x61, 0x37, 0x03, 0x32,
|
||||
0x33, 0x33, 0x31, 0x2D, 0x24, 0x1E, 0xC9, 0x40, 0x80, 0x57, 0x34, 0x25, 0x2B, 0x41, 0x6D, 0x41,
|
||||
0x00, 0x94, 0x40, 0x3D, 0x28, 0x27, 0x2E, 0x49, 0x73, 0x85, 0x20, 0x64, 0x71, 0xC0, 0x29, 0x27,
|
||||
0xCC, 0x60, 0xA0, 0x25, 0x29, 0x2D, 0x28, 0x20, 0x1E, 0x07, 0x1E, 0x1F, 0x1E, 0x16, 0x04, 0x85,
|
||||
0x00, 0x71, 0x10, 0x00, 0x6D, 0x58, 0x53, 0x44, 0x4A, 0x5D, 0x7A, 0x4A, 0x00, 0xA0, 0x58, 0x20,
|
||||
0x48, 0x45, 0x4B, 0x63, 0x7C, 0x85, 0x20, 0x38, 0x58, 0x95, 0x31, 0xE0, 0x29, 0x83, 0x64, 0x70,
|
||||
0x53, 0x23, 0x78, 0x03, 0x28, 0x12, 0x16, 0x21, 0x56, 0x40, 0x70, 0x10, 0x00, 0x07, 0x00, 0xE1,
|
||||
0xE3, 0xE3, 0xF8, 0x0C, 0xFF, 0xFF, 0xEB, 0xE3, 0xCC, 0x15, 0xE3, 0x41, 0x10, 0x2A, 0x50, 0x65,
|
||||
0x51, 0x0D, 0x11, 0x71, 0x03, 0x29, 0xB4, 0x1E, 0x2C, 0x4E, 0x81, 0x0F, 0x26, 0x2D, 0x5D, 0x96,
|
||||
0x8E, 0x3B, 0x1F, 0x1B, 0x00, 0x22, 0x40, 0x6F, 0x01, 0x10, 0x3D, 0xF0, 0x4F, 0x29, 0x54, 0x30,
|
||||
0x98, 0x1A, 0x85, 0x20, 0xDA, 0x95, 0x11, 0x19, 0x82, 0x70, 0x1E, 0x26, 0x2A, 0x4B, 0xAE, 0x78,
|
||||
0x2F, 0x4C, 0xAF, 0x84, 0x88, 0x00, 0xA3, 0x28, 0x1C, 0x21, 0x3E, 0x6A, 0x01, 0x10, 0x3D, 0xF0,
|
||||
0xC0, 0x4B, 0x1C, 0x51, 0x1C, 0x98, 0x00, 0xB5, 0x93, 0x1A, 0xFA, 0x23, 0x30, 0x5A, 0x7D, 0x85,
|
||||
0x38, 0x37, 0x7C, 0x8D, 0x49, 0x4E, 0x00, 0x98, 0x54, 0x1E, 0x1F, 0x36, 0xD5, 0x55, 0x4D, 0xF5,
|
||||
0x19, 0x60, 0xA5, 0x62, 0xD9, 0x11, 0x58, 0xA7, 0x20, 0x36, 0x89, 0x68, 0x2F, 0x07, 0x3F, 0x9F,
|
||||
0x5F, 0x2F, 0x40, 0x8B, 0x62, 0x20, 0x00, 0x20, 0x2B, 0x43, 0x5D, 0x6B, 0x04, 0x00, 0xDA, 0x35,
|
||||
0xD0, 0x15, 0xE0, 0x86, 0x06, 0x71, 0x6E, 0xD5, 0x05, 0xC5, 0x84, 0x33, 0x48, 0xDC, 0x19, 0xF9,
|
||||
0x53, 0x1A, 0xB2, 0x54, 0x7C, 0x79, 0x3C, 0x56, 0xB0, 0x05, 0x37, 0x2B, 0x43, 0x97, 0x4D, 0x21,
|
||||
0x1C, 0x21, 0x00, 0x2A, 0x36, 0x3C, 0x09, 0x30, 0x41, 0x3F, 0xD2, 0x75, 0x3A, 0x48, 0x31, 0x85,
|
||||
0xB0, 0x95, 0x01, 0x00, 0x97, 0x1C, 0x1E, 0x2B, 0x50, 0x0E, 0xAB, 0x8E, 0xA1, 0x8A, 0x31, 0x43,
|
||||
0x86, 0xA4, 0x00, 0x2E, 0x1D, 0xE7, 0x04, 0x27, 0x29, 0x2D, 0x02, 0x03, 0x10, 0x2A, 0x64, 0x00,
|
||||
0x00, 0x2A, 0x28, 0x10, 0x12, 0x28, 0x28, 0x22, 0x9D, 0x42, 0x89, 0xE9, 0x72, 0x1C, 0x86, 0xA6,
|
||||
0x23, 0x36, 0x55, 0x86, 0x7D, 0x05, 0x37, 0x2D, 0x5B, 0x97, 0x47, 0x6D, 0x01, 0x21, 0x29, 0x20,
|
||||
0x35, 0x3A, 0x3C, 0x3D, 0x3A, 0x3B, 0x3C, 0x3D, 0x00, 0x3C, 0x3B, 0x03, 0x10, 0x3C, 0x3C, 0x3C,
|
||||
0x3C, 0x3B, 0x04, 0x3B, 0x37, 0x2E, 0x4D, 0x95, 0x34, 0x45, 0xC5, 0x04, 0x0E, 0x31, 0xC8, 0x43,
|
||||
0x50, 0x1E, 0x22, 0x2E, 0x33, 0x2E, 0x24, 0x22, 0x01, 0x2E, 0x31, 0x27, 0x1E, 0x1B, 0x20, 0x2B,
|
||||
0x40, 0x00, 0xB7, 0xBB, 0x02, 0x20, 0x03, 0x30, 0x00, 0x00, 0xBE, 0xBE, 0xBE, 0x1C, 0xBD, 0xBA,
|
||||
0xB3, 0x31, 0x22, 0xC9, 0x80, 0x41, 0x10, 0x1C, 0x60, 0x1C, 0xFA, 0xB5, 0x1F, 0x21, 0x1E, 0x10,
|
||||
0x15, 0xAE, 0x13, 0x34, 0x62, 0x57, 0x01, 0x10, 0x3D, 0xF0, 0x3E, 0x25, 0x1B, 0x1C, 0x51, 0x81,
|
||||
0x86, 0x39, 0x29, 0x95, 0xB1, 0x21, 0x2B, 0x35, 0x36, 0x36, 0x04, 0x36, 0x35, 0x34, 0x31, 0x29,
|
||||
0x20, 0x6A, 0x02, 0x65, 0x40, 0x01, 0x10, 0x3D, 0xF0, 0x48, 0x27, 0x09, 0x44, 0x1D, 0x52, 0x1E,
|
||||
0xB2, 0x2B, 0x73, 0x88, 0xBA, 0xBB, 0xBA, 0xBC, 0xBA, 0xBA, 0xBC, 0x00, 0xA1, 0x24, 0x1B, 0x22,
|
||||
0x38, 0x5F, 0x01, 0x10, 0x29, 0xF3, 0xC0, 0x43, 0x0C, 0x20, 0xD9, 0x71, 0x27, 0x3D, 0xA1, 0x1D,
|
||||
0x29, 0x3D, 0x16, 0x4B, 0x51, 0x51, 0x51, 0x53, 0x5A, 0x7B, 0x92, 0x00, 0x2B, 0x1B, 0x20, 0x30,
|
||||
0x49, 0x96, 0x9E, 0xA2, 0x00, 0xA2, 0xA2, 0xA2, 0xA2, 0xA5, 0xA5, 0xEA, 0xFF, 0x00, 0xFF, 0xBE,
|
||||
0xA4, 0xA3, 0xA2, 0xA2, 0xA1, 0xA3, 0x00, 0xA0, 0x9A, 0x8A, 0x37, 0x24, 0xF9, 0x72, 0x35, 0x46,
|
||||
0x20, 0xDB, 0x3B, 0x29, 0x1B, 0x1C, 0xF8, 0x80, 0x1D, 0x1F, 0x20, 0x22, 0x27, 0x27, 0x27, 0x28,
|
||||
0x2A, 0x34, 0x4A, 0x00, 0x97, 0x4A, 0x1E, 0x1E, 0x24, 0x31, 0x40, 0x49, 0x00, 0x0B, 0x00, 0x4D,
|
||||
0x51, 0x63, 0x7C, 0x41, 0x00, 0xA2, 0x60, 0x21, 0x50, 0x4C, 0x4D, 0x4D, 0x4D, 0x4C, 0x43, 0x37,
|
||||
0x00, 0x28, 0x82, 0x70, 0x21, 0x33, 0x46, 0xA5, 0x02, 0x7D, 0xC1, 0xE9, 0x42, 0xE2, 0x3E, 0x8A,
|
||||
0x62, 0x1F, 0x1B, 0x1D, 0x21, 0x26, 0x00, 0x27, 0x28, 0x29, 0x29, 0x2A, 0x2F, 0x45, 0x6E, 0x00,
|
||||
0x41, 0x00, 0x96, 0x40, 0x2D, 0x2A, 0x29, 0x2A, 0x29, 0x01, 0x28, 0x20, 0x04, 0x1D, 0x41, 0xB0,
|
||||
0x27, 0x1F, 0x14, 0x3D, 0x81, 0x24, 0x6A, 0x26, 0x29, 0x27, 0x29, 0x2B, 0x33, 0x4A, 0xA5, 0x00,
|
||||
0x4D, 0x1E, 0x16, 0x24, 0x1E, 0x1E, 0x1C, 0x1E, 0x23, 0x04, 0x3A, 0x69, 0x41, 0x10, 0x35, 0x20,
|
||||
0x1D, 0x1D, 0x1D, 0x04, 0x1D, 0x1D, 0xF1, 0x10, 0x2D, 0x83, 0xC9, 0xE0, 0x1D, 0x24, 0x60, 0x1C,
|
||||
0x86, 0x87, 0x87, 0x88, 0x89, 0x98, 0xAF, 0x8A, 0x00, 0x2E, 0xF4, 0x73, 0x20, 0x3A, 0xC9, 0x40,
|
||||
0x1C, 0x5F, 0xE3, 0x22, 0x52, 0x41, 0x10, 0x27, 0x2D, 0xA0, 0x1E, 0x24, 0x4E, 0x67, 0x6A, 0x05,
|
||||
0x6A, 0x6B, 0x6D, 0x6F, 0x59, 0x34, 0x22, 0xD1, 0x83, 0x80, 0x39, 0x85, 0x20, 0x32, 0x20, 0x18,
|
||||
0x60, 0x1D, 0xA2, 0x3B, 0x28, 0x32, 0x0B, 0xA3, 0x1C, 0x20, 0x27, 0x2D, 0x2F, 0x2E, 0x2E, 0x01,
|
||||
0x31, 0x2E, 0x28, 0x21, 0x42, 0x83, 0x21, 0x3A, 0x41, 0x10, 0x90, 0x91, 0x33, 0x20, 0xA7, 0x83,
|
||||
0x19, 0x85, 0x40, 0x41, 0x60, 0x19, 0x82, 0xE8, 0x20, 0x1F, 0x20, 0x1E, 0x1F, 0x21, 0x1F, 0x1C,
|
||||
0x00, 0x45, 0x93, 0x20, 0x38, 0x66, 0x85, 0x00, 0x90, 0x33, 0x26, 0x62, 0x91, 0xD9, 0x80, 0x95,
|
||||
0x01, 0x3A, 0x85, 0x20, 0x1C, 0x81, 0x41, 0x20, 0x27, 0x2B, 0x32, 0x56, 0x35, 0x1D, 0x1D, 0x24,
|
||||
0x49, 0x4A, 0x00, 0x28, 0x20, 0x1B, 0x1D, 0x12, 0x23, 0x26, 0x26, 0x26, 0x08, 0x26, 0x27, 0x2A,
|
||||
0x3F, 0x6C, 0xE2, 0xFF, 0xFF, 0x00, 0x94, 0x3E, 0x28, 0x25, 0x26, 0x27, 0x27, 0x26, 0x00, 0x24,
|
||||
0x21, 0x1E, 0xE8, 0x10, 0x1C, 0xD9, 0x71, 0x1D, 0x22, 0x1C, 0x68, 0x3A, 0x32, 0x1E, 0x2D, 0x61,
|
||||
0xB1, 0xA8, 0x51, 0x1E, 0x01, 0x1D, 0x2B, 0x77, 0xAF, 0xA3, 0x3D, 0x20, 0x1B, 0x00, 0x1D, 0x22,
|
||||
0x2E, 0x3A, 0x41, 0x45, 0x45, 0x45, 0x00, 0x46, 0x48, 0x5C, 0x79, 0xE3, 0xFF, 0xFF, 0xA1, 0x00,
|
||||
0x5A, 0x49, 0x45, 0x44, 0x45, 0x45, 0x43, 0x3E, 0x00, 0x33, 0x26, 0x20, 0x1B, 0x1C, 0x0D, 0x61,
|
||||
0xC9, 0x00, 0x41, 0x80, 0xE0, 0x1C, 0x26, 0x4D, 0xB1, 0x71, 0x3D, 0x27, 0x1C, 0x00, 0x1D, 0x26,
|
||||
0x39, 0x4E, 0x81, 0x9B, 0x27, 0x1B, 0x00, 0x1F, 0x2E, 0x47, 0xDE, 0xE0, 0xE2, 0xE2, 0x07, 0x10,
|
||||
0x80, 0xE3, 0xF7, 0xFF, 0xFF, 0xEA, 0xE3, 0xE2, 0xE2, 0x00, 0xE2, 0xE3, 0xE2, 0xE1, 0xE0, 0xDD,
|
||||
0x34, 0x21, 0x00, 0x41, 0x90, 0xDA, 0x41, 0x90, 0x20, 0x2F, 0x7E, 0x8B, 0x38, 0x05, 0x25, 0x1E,
|
||||
0x49, 0x12, 0x32, 0x4B, 0x9D, 0x3D, 0x1D, 0x04, 0x1F, 0x37, 0x5D, 0x03, 0x30, 0x85, 0xF0, 0x1E,
|
||||
0x72, 0x35, 0x85, 0x00, 0xB8, 0x28, 0xC9, 0x70, 0x22, 0x37, 0x8B, 0x68, 0x27, 0xDE, 0x31, 0x82,
|
||||
0x26, 0x3F, 0x8A, 0x61, 0x21, 0x21, 0x3B, 0x66, 0x00, 0x01, 0x10, 0x3D, 0xF0, 0x47, 0x28, 0x92,
|
||||
0x61, 0xC9, 0x00, 0xDA, 0x3B, 0x33, 0x27, 0x1C, 0xF3, 0x61, 0x21, 0x38, 0x8B, 0x71, 0x25, 0x04,
|
||||
0x76, 0x30, 0x24, 0x3C, 0x91, 0x62, 0x21, 0x1F, 0x35, 0x01, 0x5B, 0x07, 0x70, 0x03, 0x30, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0x41, 0x0E, 0x25, 0xD9, 0x60, 0x21, 0x34, 0x47, 0xDB, 0x39, 0x27, 0x02,
|
||||
0xA6, 0x71, 0x1F, 0x31, 0x65, 0xA4, 0x32, 0x20, 0x55, 0x11, 0x81, 0x20, 0x2E, 0x55, 0xAA, 0x34,
|
||||
0x1E, 0x1E, 0x2C, 0x00, 0x42, 0x5C, 0x6A, 0x01, 0x00, 0x71, 0x6F, 0x03, 0x10, 0x70, 0x48, 0x00,
|
||||
0x00, 0x70, 0x70, 0x6F, 0x6F, 0x6D, 0x63, 0x4C, 0x01, 0x32, 0xAC, 0x20, 0x1C, 0x41, 0x30, 0x48,
|
||||
0xDB, 0x3A, 0x26, 0x0A, 0x32, 0x50, 0xFD, 0x10, 0x42, 0x92, 0x9D, 0x52, 0x33, 0x2F, 0x03, 0x2F,
|
||||
0x32, 0x3A, 0x6C, 0xAB, 0x72, 0x29, 0x1D, 0x00, 0x1B, 0x21, 0x2B, 0x36, 0x3D, 0x40, 0x3F, 0x05,
|
||||
0x40, 0x80, 0x41, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x3F, 0x39, 0x02, 0x30, 0x24, 0x40, 0x70,
|
||||
0x21, 0x35, 0x47, 0xDC, 0x3A, 0x04, 0x29, 0x65, 0x80, 0x20, 0x2D, 0x46, 0x81, 0xB0, 0xB0, 0x02,
|
||||
0xA4, 0xA5, 0xA6, 0xB6, 0xA6, 0x6B, 0x32, 0x20, 0x00, 0x1B, 0x1B, 0x1D, 0x20, 0x20, 0x21, 0x22,
|
||||
0x0B, 0x10, 0x80, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x23, 0x22, 0x00, 0x21, 0x23, 0x23, 0x21,
|
||||
0x22, 0x21, 0x1E, 0x1E, 0x00, 0x25, 0x70, 0x20, 0x32, 0x45, 0xDA, 0x37, 0x27, 0x62, 0x30, 0x81,
|
||||
0x8A, 0x30, 0x1F, 0x2B, 0x3C, 0x4A, 0x59, 0x71, 0x71, 0x01, 0x70, 0x4B, 0x3E, 0x2E, 0x21, 0x0A,
|
||||
0x90, 0x1A, 0x04, 0x40, 0xA0, 0x6E, 0xF0, 0x21, 0x2E, 0x3B, 0xDC, 0x32, 0x24, 0x1B, 0x40, 0x81,
|
||||
0x1A, 0x0C, 0x20, 0x1E, 0x23, 0x27, 0x2D, 0x32, 0x30, 0x02, 0x2E, 0x28, 0x24, 0x1E, 0x55, 0xC0,
|
||||
0x19, 0x7A, 0x20, 0x19, 0x50, 0x45, 0xA0, 0x1C, 0x37, 0x00, 0x1E, 0x27, 0x2D, 0x30, 0x29, 0x05,
|
||||
0x1F, 0x12, 0xC0, 0x73, 0x00, 0x1E, 0x1F, 0x2C, 0x80, 0x22, 0xF0, 0x53, 0xB0, 0xE6, 0x1F, 0x24,
|
||||
0x24, 0x21, 0x1D, 0x1C, 0xF0, 0x1C, 0x1B, 0x80, 0xA0, 0x19, 0x02, 0x20, 0x1D, 0xF0, 0x0A, 0x60,
|
||||
0x1C, 0x1C, 0x1C, 0x1D, 0x0E, 0x1C, 0x0A, 0xA0, 0x1B, 0x03, 0x30, 0x00, 0x00, 0x1B, 0x1B, 0x1B,
|
||||
0x1A, 0xFF, 0xFF, 0xFF, 0x30, 0x1A, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xD0, 0x18, 0x00, 0x00
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,225 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "tui.h"
|
||||
#include "../utils/btn.h"
|
||||
#include "../config/config.h"
|
||||
#include "../power/max17050.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../config/config.h"
|
||||
#include "di.h"
|
||||
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
extern u8 *Kc_MENU_LOGO;
|
||||
#define X_MENU_LOGO 119
|
||||
#define Y_MENU_LOGO 57
|
||||
#define X_POS_MENU_LOGO 577
|
||||
#define Y_POS_MENU_LOGO 1179
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
extern hekate_config h_cfg;
|
||||
|
||||
void tui_sbar(gfx_con_t *con, bool force_update)
|
||||
{
|
||||
u32 cx, cy;
|
||||
|
||||
u32 timePassed = get_tmr_s() - h_cfg.sbar_time_keeping;
|
||||
if (!force_update)
|
||||
if (timePassed < 5)
|
||||
return;
|
||||
|
||||
u8 prevFontSize = con->fntsz;
|
||||
con->fntsz = 16;
|
||||
h_cfg.sbar_time_keeping = get_tmr_s();
|
||||
|
||||
u32 battPercent = 0;
|
||||
int battVoltCurr = 0;
|
||||
|
||||
gfx_con_getpos(con, &cx, &cy);
|
||||
gfx_con_setpos(con, 0, 1260);
|
||||
|
||||
max17050_get_property(MAX17050_RepSOC, (int *)&battPercent);
|
||||
max17050_get_property(MAX17050_VCELL, &battVoltCurr);
|
||||
|
||||
gfx_clear_partial_grey(con->gfx_ctxt, 0x30, 1256, 24);
|
||||
gfx_printf(con, "%K%k Battery: %d.%d%% (%d mV) - Charge:", 0xFF303030, 0xFF888888,
|
||||
(battPercent >> 8) & 0xFF, (battPercent & 0xFF) / 26, battVoltCurr);
|
||||
|
||||
max17050_get_property(MAX17050_AvgCurrent, &battVoltCurr);
|
||||
|
||||
if (battVoltCurr >= 0)
|
||||
gfx_printf(con, " %k+%d mA%k%K\n",
|
||||
0xFF008800, battVoltCurr / 1000, 0xFFCCCCCC, 0xFF1B1B1B);
|
||||
else
|
||||
gfx_printf(con, " %k-%d mA%k%K\n",
|
||||
0xFF880000, (~battVoltCurr) / 1000, 0xFFCCCCCC, 0xFF1B1B1B);
|
||||
con->fntsz = prevFontSize;
|
||||
gfx_con_setpos(con, cx, cy);
|
||||
}
|
||||
|
||||
void tui_pbar(gfx_con_t *con, int x, int y, u32 val, u32 fgcol, u32 bgcol)
|
||||
{
|
||||
u32 cx, cy;
|
||||
if (val > 200)
|
||||
val = 200;
|
||||
|
||||
gfx_con_getpos(con, &cx, &cy);
|
||||
|
||||
gfx_con_setpos(con, x, y);
|
||||
|
||||
gfx_printf(con, "%k[%3d%%]%k", fgcol, val, 0xFFCCCCCC);
|
||||
|
||||
x += 7 * con->fntsz;
|
||||
|
||||
for (int i = 0; i < (con->fntsz >> 3) * 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);
|
||||
}
|
||||
|
||||
gfx_con_setpos(con, cx, cy);
|
||||
|
||||
// Update status bar.
|
||||
tui_sbar(con, false);
|
||||
}
|
||||
|
||||
void *tui_do_menu(gfx_con_t *con, menu_t *menu)
|
||||
{
|
||||
int idx = 0, prev_idx = 0, cnt = 0x7FFFFFFF;
|
||||
|
||||
gfx_clear_partial_grey(con->gfx_ctxt, 0x1B, 0, 1256);
|
||||
tui_sbar(con, true);
|
||||
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
gfx_set_rect_rgb(con->gfx_ctxt, Kc_MENU_LOGO,
|
||||
X_MENU_LOGO, Y_MENU_LOGO, X_POS_MENU_LOGO, Y_POS_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
|
||||
while (true)
|
||||
{
|
||||
gfx_con_setcol(con, 0xFFCCCCCC, 1, 0xFF1B1B1B);
|
||||
gfx_con_setpos(con, menu->x, menu->y);
|
||||
gfx_printf(con, "[%s]\n\n", menu->caption);
|
||||
|
||||
// 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))
|
||||
{
|
||||
idx++;
|
||||
if (idx > (cnt - 1))
|
||||
{
|
||||
idx = 0;
|
||||
prev_idx = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
idx--;
|
||||
if (idx < 0)
|
||||
{
|
||||
idx = cnt - 1;
|
||||
prev_idx = cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev_idx = idx;
|
||||
|
||||
// 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)
|
||||
gfx_printf(con, "%k %s", menu->ents[cnt].color, menu->ents[cnt].caption);
|
||||
else if (menu->ents[cnt].type != MENT_CHGLINE)
|
||||
gfx_printf(con, " %s", menu->ents[cnt].caption);
|
||||
if(menu->ents[cnt].type == MENT_MENU)
|
||||
gfx_printf(con, "%k...", 0xFF0099EE);
|
||||
gfx_printf(con, " \n");
|
||||
}
|
||||
gfx_con_setcol(con, 0xFFCCCCCC, 1, 0xFF1B1B1B);
|
||||
gfx_putc(con, '\n');
|
||||
|
||||
// Print help and battery status.
|
||||
gfx_con_setpos(con, 0, 1127);
|
||||
if (h_cfg.errors)
|
||||
{
|
||||
gfx_printf(con, "%k Warning: %k", 0xFF800000, 0xFF555555);
|
||||
if (h_cfg.errors & ERR_LIBSYS_LP0)
|
||||
gfx_printf(con, "Sleep mode library is missing!\n");
|
||||
}
|
||||
gfx_con_setpos(con, 0, 1191);
|
||||
gfx_printf(con, "%k VOL: Move up/down\n PWR: Select option%k", 0xFF555555, 0xFFCCCCCC);
|
||||
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
|
||||
// Wait for user command.
|
||||
u32 btn = btn_wait();
|
||||
|
||||
if (btn & BTN_VOL_DOWN && idx < (cnt - 1))
|
||||
idx++;
|
||||
else if (btn & BTN_VOL_DOWN && idx == (cnt - 1))
|
||||
{
|
||||
idx = 0;
|
||||
prev_idx = -1;
|
||||
}
|
||||
if (btn & BTN_VOL_UP && idx > 0)
|
||||
idx--;
|
||||
else if (btn & BTN_VOL_UP && idx == 0)
|
||||
{
|
||||
idx = cnt - 1;
|
||||
prev_idx = cnt;
|
||||
}
|
||||
if (btn & BTN_POWER)
|
||||
{
|
||||
ment_t *ent = &menu->ents[idx];
|
||||
switch (ent->type)
|
||||
{
|
||||
case MENT_HANDLER:
|
||||
ent->handler(ent->data);
|
||||
break;
|
||||
case MENT_MENU:
|
||||
return tui_do_menu(con, ent->menu);
|
||||
break;
|
||||
case MENT_DATA:
|
||||
return ent->data;
|
||||
break;
|
||||
case MENT_BACK:
|
||||
return NULL;
|
||||
break;
|
||||
case MENT_HDLR_RE:
|
||||
ent->handler(ent->data);
|
||||
return NULL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
con->fntsz = 16;
|
||||
gfx_clear_partial_grey(con->gfx_ctxt, 0x1B, 0, 1256);
|
||||
#ifdef MENU_LOGO_ENABLE
|
||||
gfx_set_rect_rgb(con->gfx_ctxt, Kc_MENU_LOGO,
|
||||
X_MENU_LOGO, Y_MENU_LOGO, X_POS_MENU_LOGO, Y_POS_MENU_LOGO);
|
||||
#endif //MENU_LOGO_ENABLE
|
||||
}
|
||||
tui_sbar(con, false);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,774 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018 Ced2911
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "hos.h"
|
||||
#include "../storage/sdmmc.h"
|
||||
#include "../storage/nx_emmc.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../sec/se.h"
|
||||
#include "../sec/se_t210.h"
|
||||
#include "../soc/pmc.h"
|
||||
#include "../soc/cluster.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../sec/tsec.h"
|
||||
#include "../utils/util.h"
|
||||
#include "pkg1.h"
|
||||
#include "pkg2.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "../gfx/di.h"
|
||||
#include "../config/config.h"
|
||||
#include "../mem/mc.h"
|
||||
#include "../soc/fuse.h"
|
||||
#include "../utils/dirlist.h"
|
||||
|
||||
#include "../gfx/gfx.h"
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
extern hekate_config h_cfg;
|
||||
|
||||
extern void sd_unmount();
|
||||
|
||||
//#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
|
||||
typedef struct _launch_ctxt_t
|
||||
{
|
||||
void *keyblob;
|
||||
|
||||
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;
|
||||
char* kip1_patches;
|
||||
|
||||
bool svcperm;
|
||||
bool debugmode;
|
||||
bool atmosphere;
|
||||
} 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_600 5
|
||||
#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_600
|
||||
|
||||
// Exosphère magic "XBC0".
|
||||
#define MAGIC_EXOSPHERE 0x30434258
|
||||
|
||||
static const u8 keyblob_keyseeds[][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
|
||||
{ 0x2D, 0x1F, 0x48, 0x80, 0xED, 0xEC, 0xED, 0x3E, 0x3C, 0xF2, 0x48, 0xB5, 0x65, 0x7D, 0xF7, 0xBE }, //4.0.0
|
||||
{ 0xBB, 0x5A, 0x01, 0xF9, 0x88, 0xAF, 0xF5, 0xFC, 0x6C, 0xFF, 0x07, 0x9E, 0x13, 0x3C, 0x39, 0x80 }, //5.0.0
|
||||
{ 0xD8, 0xCC, 0xE1, 0x26, 0x6A, 0x35, 0x3F, 0xCC, 0x20, 0xF3, 0x2D, 0x3B, 0x51, 0x7D, 0xE9, 0xC0 } //6.0.0
|
||||
};
|
||||
|
||||
static const u8 cmac_keyseed[0x10] =
|
||||
{ 0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5 };
|
||||
|
||||
static const u8 master_keyseed_retail[0x10] =
|
||||
{ 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C };
|
||||
|
||||
static const u8 console_keyseed[0x10] =
|
||||
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
|
||||
|
||||
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] =
|
||||
{ 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66 };
|
||||
|
||||
static const u8 console_keyseed_4xx_5xx[0x10] =
|
||||
{ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
|
||||
|
||||
|
||||
static void _se_lock()
|
||||
{
|
||||
for (u32 i = 0; i < 16; i++)
|
||||
se_key_acc_ctrl(i, 0x15);
|
||||
|
||||
for (u32 i = 0; i < 2; i++)
|
||||
se_rsa_acc_ctrl(i, 1);
|
||||
|
||||
SE(0x4) = 0; // Make this reg secure only.
|
||||
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) = 0; // Make all key access regs secure only.
|
||||
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) = 0; // Make all RSA access regs secure only.
|
||||
SE(SE_SECURITY_0) &= 0xFFFFFFFB; // Make access lock regs secure only.
|
||||
memset((void *)IPATCH_BASE, 0, 13);
|
||||
SB(SB_CSR) = 0x10; // Protected IROM enable.
|
||||
|
||||
// This is useful for documenting the bits in the SE config registers, so we can keep it around.
|
||||
/*gfx_printf(&gfx_con, "SE(SE_SECURITY_0) = %08X\n", SE(SE_SECURITY_0));
|
||||
gfx_printf(&gfx_con, "SE(0x4) = %08X\n", SE(0x4));
|
||||
gfx_printf(&gfx_con, "SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) = %08X\n", SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET));
|
||||
gfx_printf(&gfx_con, "SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) = %08X\n", SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET));
|
||||
for(u32 i = 0; i < 16; i++)
|
||||
gfx_printf(&gfx_con, "%02X ", SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + i * 4) & 0xFF);
|
||||
gfx_putc(&gfx_con, '\n');
|
||||
for(u32 i = 0; i < 2; i++)
|
||||
gfx_printf(&gfx_con, "%02X ", SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + i * 4) & 0xFF);
|
||||
gfx_putc(&gfx_con, '\n');
|
||||
gfx_hexdump(&gfx_con, SE_BASE, (void *)SE_BASE, 0x400);*/
|
||||
}
|
||||
|
||||
void _pmc_scratch_lock(u32 kb)
|
||||
{
|
||||
switch (kb)
|
||||
{
|
||||
case KB_FIRMWARE_VERSION_100_200:
|
||||
case KB_FIRMWARE_VERSION_300:
|
||||
case KB_FIRMWARE_VERSION_301:
|
||||
PMC(APBDEV_PMC_SEC_DISABLE) = 0x7FFFF3;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) = 0xFFFFFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE3) = 0xFFAFFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE4) = 0xFFFFFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE6) = 0xFFFFFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE7) = 0xFFFFFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE8) = 0xFFAAFFFF;
|
||||
break;
|
||||
case KB_FIRMWARE_VERSION_400:
|
||||
case KB_FIRMWARE_VERSION_500:
|
||||
case KB_FIRMWARE_VERSION_600:
|
||||
default:
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE4) |= 0x3F3FFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE6) |= 0xF3FFC00F;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE7) |= 0x3FFFFF;
|
||||
PMC(APBDEV_PMC_SEC_DISABLE8) |= 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// Get TSEC key.
|
||||
if (tsec_query(tmp, 1, tsec_fw) < 0)
|
||||
return 0;
|
||||
|
||||
se_aes_key_set(13, 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);
|
||||
|
||||
// Clear SBK.
|
||||
se_aes_key_clear(14);
|
||||
|
||||
//TODO: verify keyblob CMAC.
|
||||
//se_aes_unwrap_key(11, 13, cmac_keyseed);
|
||||
//se_aes_cmac(tmp, 0x10, 11, keyblob + 0x10, 0xA0);
|
||||
//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);
|
||||
|
||||
// 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_block_ecb(12, 0, tmp, master_keyseed_retail);
|
||||
|
||||
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);
|
||||
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);
|
||||
break;
|
||||
case KB_FIRMWARE_VERSION_500:
|
||||
case KB_FIRMWARE_VERSION_600:
|
||||
default:
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
// Package2 key.
|
||||
se_key_acc_ctrl(8, 0x15);
|
||||
se_aes_unwrap_key(8, 12, key8_keyseed);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
|
||||
{
|
||||
int res = 0;
|
||||
sdmmc_storage_t storage;
|
||||
sdmmc_t sdmmc;
|
||||
|
||||
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4);
|
||||
|
||||
// Read package1.
|
||||
ctxt->pkg1 = (u8 *)malloc(0x40000);
|
||||
sdmmc_storage_set_mmc_partition(&storage, 1);
|
||||
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, ctxt->pkg1);
|
||||
ctxt->pkg1_id = pkg1_identify(ctxt->pkg1);
|
||||
if (!ctxt->pkg1_id)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%kUnknown package1,\nVersion (= '%s').%k\n", 0xFFFF0000, (char *)ctxt->pkg1 + 0x10, 0xFFCCCCCC);
|
||||
goto out;
|
||||
}
|
||||
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 *)calloc(NX_EMMC_BLOCKSIZE, 1);
|
||||
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
sdmmc_storage_end(&storage);
|
||||
return res;
|
||||
}
|
||||
|
||||
static u8 *_read_emmc_pkg2(launch_ctxt_t *ctxt)
|
||||
{
|
||||
u8 *bctBuf = NULL;
|
||||
sdmmc_storage_t storage;
|
||||
sdmmc_t sdmmc;
|
||||
|
||||
if (!sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4))
|
||||
return NULL;
|
||||
sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||
|
||||
// Parse eMMC GPT.
|
||||
LIST_INIT(gpt);
|
||||
nx_emmc_gpt_parse(&gpt, &storage);
|
||||
DPRINTF("Parsed GPT\n");
|
||||
// Find package2 partition.
|
||||
emmc_part_t *pkg2_part = nx_emmc_part_find(&gpt, "BCPKG2-1-Normal-Main");
|
||||
if (!pkg2_part)
|
||||
goto out;
|
||||
|
||||
// Read in package2 header and get package2 real size.
|
||||
//TODO: implement memalign for DMA buffers.
|
||||
static const u32 BCT_SIZE = 0x4000;
|
||||
bctBuf = (u8 *)malloc(BCT_SIZE);
|
||||
nx_emmc_part_read(&storage, pkg2_part, BCT_SIZE / NX_EMMC_BLOCKSIZE, 1, bctBuf);
|
||||
u32 *hdr = (u32 *)(bctBuf + 0x100);
|
||||
u32 pkg2_size = hdr[0] ^ hdr[2] ^ hdr[3];
|
||||
DPRINTF("pkg2 size on emmc is %08X\n", pkg2_size);
|
||||
|
||||
// Read in Boot Config.
|
||||
memset(bctBuf, 0, BCT_SIZE);
|
||||
nx_emmc_part_read(&storage, pkg2_part, 0, BCT_SIZE / NX_EMMC_BLOCKSIZE, bctBuf);
|
||||
|
||||
// Read in package2.
|
||||
u32 pkg2_size_aligned = ALIGN(pkg2_size, NX_EMMC_BLOCKSIZE);
|
||||
DPRINTF("pkg2 size aligned is %08X\n", pkg2_size_aligned);
|
||||
ctxt->pkg2 = malloc(pkg2_size_aligned);
|
||||
ctxt->pkg2_size = pkg2_size;
|
||||
nx_emmc_part_read(&storage, pkg2_part, BCT_SIZE / NX_EMMC_BLOCKSIZE,
|
||||
pkg2_size_aligned / NX_EMMC_BLOCKSIZE, ctxt->pkg2);
|
||||
out:;
|
||||
nx_emmc_gpt_free(&gpt);
|
||||
sdmmc_storage_end(&storage);
|
||||
return bctBuf;
|
||||
}
|
||||
|
||||
static int _config_warmboot(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
FIL fp;
|
||||
if (f_open(&fp, value, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
ctxt->warmboot_size = f_size(&fp);
|
||||
ctxt->warmboot = malloc(ctxt->warmboot_size);
|
||||
f_read(&fp, ctxt->warmboot, ctxt->warmboot_size, NULL);
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_secmon(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
FIL fp;
|
||||
if (f_open(&fp, value, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
ctxt->secmon_size = f_size(&fp);
|
||||
ctxt->secmon = malloc(ctxt->secmon_size);
|
||||
f_read(&fp, ctxt->secmon, ctxt->secmon_size, NULL);
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_kernel(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
FIL fp;
|
||||
if (f_open(&fp, value, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
ctxt->kernel_size = f_size(&fp);
|
||||
ctxt->kernel = malloc(ctxt->kernel_size);
|
||||
f_read(&fp, ctxt->kernel, ctxt->kernel_size, NULL);
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
FIL fp;
|
||||
|
||||
if (!memcmp(value + strlen(value) - 1, "*", 1))
|
||||
{
|
||||
char *dir = (char *)malloc(256);
|
||||
memcpy(dir, value, strlen(value) + 1);
|
||||
|
||||
u32 dirlen = 0;
|
||||
dir[strlen(dir) - 2] = 0;
|
||||
char *filelist = dirlist(dir, "*.kip*");
|
||||
|
||||
memcpy(dir + strlen(dir), "/", 2);
|
||||
dirlen = strlen(dir);
|
||||
|
||||
u32 i = 0;
|
||||
if (filelist)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (!filelist[i * 256])
|
||||
break;
|
||||
|
||||
memcpy(dir + dirlen, &filelist[i * 256], strlen(&filelist[i * 256]) + 1);
|
||||
if (f_open(&fp, dir, FA_READ))
|
||||
{
|
||||
free(dir);
|
||||
free(filelist);
|
||||
|
||||
return 0;
|
||||
}
|
||||
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||
mkip1->kip1 = malloc(f_size(&fp));
|
||||
f_read(&fp, mkip1->kip1, f_size(&fp), NULL);
|
||||
DPRINTF("Loaded kip1 from SD (size %08X)\n", f_size(&fp));
|
||||
f_close(&fp);
|
||||
list_append(&ctxt->kip1_list, &mkip1->link);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
free(dir);
|
||||
free(filelist);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (f_open(&fp, value, FA_READ))
|
||||
return 0;
|
||||
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||
mkip1->kip1 = malloc(f_size(&fp));
|
||||
f_read(&fp, mkip1->kip1, f_size(&fp), NULL);
|
||||
DPRINTF("Loaded kip1 from SD (size %08X)\n", f_size(&fp));
|
||||
f_close(&fp);
|
||||
list_append(&ctxt->kip1_list, &mkip1->link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_svcperm(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (*value == '1')
|
||||
{
|
||||
DPRINTF("Disabled SVC verification\n");
|
||||
ctxt->svcperm = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_debugmode(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (*value == '1')
|
||||
{
|
||||
DPRINTF("Enabled Debug mode\n");
|
||||
ctxt->debugmode = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_atmosphere(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (*value == '1')
|
||||
{
|
||||
DPRINTF("Enabled atmosphere patching\n");
|
||||
ctxt->atmosphere = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_kip1patch(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return 0;
|
||||
|
||||
int valueLen = strlen(value);
|
||||
if (!valueLen)
|
||||
return 0;
|
||||
|
||||
if (ctxt->kip1_patches == NULL)
|
||||
{
|
||||
ctxt->kip1_patches = malloc(valueLen + 1);
|
||||
memcpy(ctxt->kip1_patches, value, valueLen);
|
||||
ctxt->kip1_patches[valueLen] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *oldAlloc = ctxt->kip1_patches;
|
||||
int oldSize = strlen(oldAlloc);
|
||||
ctxt->kip1_patches = malloc(oldSize + 1 + valueLen + 1);
|
||||
memcpy(ctxt->kip1_patches, oldAlloc, oldSize);
|
||||
free(oldAlloc);
|
||||
oldAlloc = NULL;
|
||||
ctxt->kip1_patches[oldSize++] = ',';
|
||||
memcpy(&ctxt->kip1_patches[oldSize], value, valueLen);
|
||||
ctxt->kip1_patches[oldSize + valueLen] = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef struct _cfg_handler_t
|
||||
{
|
||||
const char *key;
|
||||
int (*handler)(launch_ctxt_t *ctxt, const char *value);
|
||||
} cfg_handler_t;
|
||||
|
||||
static const cfg_handler_t _config_handlers[] = {
|
||||
{ "warmboot", _config_warmboot },
|
||||
{ "secmon", _config_secmon },
|
||||
{ "kernel", _config_kernel },
|
||||
{ "kip1", _config_kip1 },
|
||||
{ "kip1patch", _config_kip1patch },
|
||||
{ "fullsvcperm", _config_svcperm },
|
||||
{ "debugmode", _config_debugmode },
|
||||
{ "atmosphere", _config_atmosphere },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
static int _config(launch_ctxt_t *ctxt, ini_sec_t *cfg)
|
||||
{
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link)
|
||||
{
|
||||
for(u32 i = 0; _config_handlers[i].key; i++)
|
||||
{
|
||||
if (!strcmp(_config_handlers[i].key, kv->key))
|
||||
if (!_config_handlers[i].handler(ctxt, kv->val))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _free_launch_components(launch_ctxt_t *ctxt)
|
||||
{
|
||||
free(ctxt->keyblob);
|
||||
free(ctxt->pkg1);
|
||||
free(ctxt->pkg2);
|
||||
free(ctxt->warmboot);
|
||||
free(ctxt->secmon);
|
||||
free(ctxt->kernel);
|
||||
free(ctxt->kip1_patches);
|
||||
}
|
||||
|
||||
int hos_launch(ini_sec_t *cfg)
|
||||
{
|
||||
int bootStateDramPkg2 = 0;
|
||||
int bootStatePkg2Continue = 0;
|
||||
int exoFwNumber = 0;
|
||||
launch_ctxt_t ctxt;
|
||||
|
||||
memset(&ctxt, 0, sizeof(launch_ctxt_t));
|
||||
list_init(&ctxt.kip1_list);
|
||||
|
||||
if (!gfx_con.mute)
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
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.
|
||||
if (!_read_emmc_pkg1(&ctxt))
|
||||
return 0;
|
||||
|
||||
gfx_printf(&gfx_con, "Loaded package1 and keyblob\n");
|
||||
|
||||
// Generate keys.
|
||||
if (!h_cfg.se_keygen_done)
|
||||
{
|
||||
keygen(ctxt.keyblob, ctxt.pkg1_id->kb, (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off);
|
||||
h_cfg.se_keygen_done = 1;
|
||||
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);
|
||||
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;
|
||||
|
||||
// Replace 'SecureMonitor' if requested.
|
||||
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.
|
||||
patch_t *secmon_patchset = ctxt.pkg1_id->secmon_patchset;
|
||||
gfx_printf(&gfx_con, "%kPatching Security Monitor%k\n", 0xFFFFBA00, 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.
|
||||
u8 *bootConfigBuf = _read_emmc_pkg2(&ctxt);
|
||||
if (!bootConfigBuf)
|
||||
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 || ctxt.atmosphere)
|
||||
{
|
||||
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.
|
||||
kernel_patch_t *kernel_patchset = ctxt.pkg2_kernel_id->kernel_patchset;
|
||||
if (kernel_patchset != NULL)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%kPatching kernel%k\n", 0xFFFFBA00, 0xFFCCCCCC);
|
||||
u32 *temp;
|
||||
for (u32 i = 0; kernel_patchset[i].id != 0xFFFFFFFF; i++)
|
||||
{
|
||||
if ((ctxt.svcperm && kernel_patchset[i].id == SVC_VERIFY_DS)
|
||||
|| (ctxt.debugmode && kernel_patchset[i].id == DEBUG_MODE_EN)
|
||||
|| (ctxt.atmosphere && kernel_patchset[i].id == ATM_GEN_PATCH))
|
||||
*(vu32 *)(ctxt.kernel + kernel_patchset[i].off) = kernel_patchset[i].val;
|
||||
else if (ctxt.atmosphere && kernel_patchset[i].id == ATM_ARR_PATCH)
|
||||
{
|
||||
temp = (u32 *)kernel_patchset[i].ptr;
|
||||
for (u32 j = 0; j < kernel_patchset[i].val; j++)
|
||||
*(vu32 *)(ctxt.kernel + kernel_patchset[i].off + (j << 2)) = temp[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge extra KIP1s into loaded ones.
|
||||
gfx_printf(&gfx_con, "%kPatching kernel initial processes%k\n", 0xFFFFBA00, 0xFFCCCCCC);
|
||||
LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
|
||||
pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1);
|
||||
|
||||
// Patch kip1s in memory if needed.
|
||||
const char* unappliedPatch = pkg2_patch_kips(&kip1_info, ctxt.kip1_patches);
|
||||
if (unappliedPatch != NULL)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%kREQUESTED PATCH '%s' NOT APPLIED!%k\n", 0xFFFF0000, unappliedPatch, 0xFFCCCCCC);
|
||||
sd_unmount(); // Just exiting is not enough until pkg2_patch_kips stops modifying the string passed into it.
|
||||
while(1) {} // MUST stop here, because if user requests 'nogc' but it's not applied, their GC controller gets updated!
|
||||
}
|
||||
|
||||
// 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.
|
||||
sd_unmount();
|
||||
|
||||
gfx_printf(&gfx_con, "\n%kBooting...%k\n", 0xFF96FF00, 0xFFCCCCCC);
|
||||
|
||||
se_aes_key_clear(8);
|
||||
se_aes_key_clear(11);
|
||||
|
||||
// Final per firmware configuration.
|
||||
switch (ctxt.pkg1_id->kb)
|
||||
{
|
||||
case KB_FIRMWARE_VERSION_100_200:
|
||||
if (!exoFwNumber)
|
||||
{
|
||||
if (!strcmp(ctxt.pkg1_id->id, "20161121183008"))
|
||||
exoFwNumber = 1;
|
||||
else
|
||||
exoFwNumber = 2;
|
||||
}
|
||||
case KB_FIRMWARE_VERSION_300:
|
||||
case KB_FIRMWARE_VERSION_301:
|
||||
if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_300)
|
||||
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0xE3; // Warmboot 3.0.0 PA address id.
|
||||
else if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_301)
|
||||
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0x104; // Warmboot 3.0.1/.2 PA address id.
|
||||
se_key_acc_ctrl(12, 0xFF);
|
||||
se_key_acc_ctrl(13, 0xFF);
|
||||
bootStateDramPkg2 = 2;
|
||||
bootStatePkg2Continue = 3;
|
||||
if (!exoFwNumber)
|
||||
exoFwNumber = 3;
|
||||
break;
|
||||
case KB_FIRMWARE_VERSION_400:
|
||||
if (!exoFwNumber)
|
||||
exoFwNumber = 4;
|
||||
case KB_FIRMWARE_VERSION_500:
|
||||
if (!exoFwNumber)
|
||||
exoFwNumber = 5;
|
||||
case KB_FIRMWARE_VERSION_600:
|
||||
default:
|
||||
se_key_acc_ctrl(12, 0xFF);
|
||||
se_key_acc_ctrl(15, 0xFF);
|
||||
bootStateDramPkg2 = 2;
|
||||
bootStatePkg2Continue = 4;
|
||||
if (!exoFwNumber)
|
||||
exoFwNumber = 6;
|
||||
break;
|
||||
}
|
||||
|
||||
// Free allocated memory.
|
||||
ini_free_section(cfg);
|
||||
_free_launch_components(&ctxt);
|
||||
|
||||
// Clear BCT area for retail units and copy it over if dev unit.
|
||||
if (ctxt.pkg1_id->kb < KB_FIRMWARE_VERSION_600)
|
||||
{
|
||||
memset((void *)0x4003D000, 0, 0x3000);
|
||||
if ((fuse_read_odm(4) & 3) == 3)
|
||||
memcpy((void *)0x4003D000, bootConfigBuf, 0x1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset((void *)0x4003F000, 0, 0x1000);
|
||||
if ((fuse_read_odm(4) & 3) == 3)
|
||||
memcpy((void *)0x4003F800, bootConfigBuf, 0x800);
|
||||
}
|
||||
free(bootConfigBuf);
|
||||
|
||||
// Config Exosphère if booting Atmosphère.
|
||||
if (ctxt.atmosphere)
|
||||
{
|
||||
vu32 *mb_exo_magic = (vu32 *)0x40002E40;
|
||||
vu32 *mb_exo_fw_no = (vu32 *)0x40002E44;
|
||||
|
||||
*mb_exo_magic = MAGIC_EXOSPHERE;
|
||||
*mb_exo_fw_no = exoFwNumber;
|
||||
}
|
||||
|
||||
// Finalize MC carveout and lock SE before starting 'SecureMonitor'.
|
||||
mc_config_carveout_finalize();
|
||||
_se_lock();
|
||||
|
||||
//TODO: pkg1.1 locks PMC scratches, we can do that too at some point. For <4.0.0 after secmon?
|
||||
//_pmc_scratch_lock(ctxt.pkg1_id->kb);
|
||||
|
||||
// < 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_out = 0;
|
||||
|
||||
// Disable display. This must be executed before secmon to provide support for all fw versions.
|
||||
display_end();
|
||||
|
||||
// Wait for secmon to get ready.
|
||||
cluster_boot_cpu0(ctxt.pkg1_id->secmon_base);
|
||||
while (!*mb_out)
|
||||
usleep(1); // This only works when in IRAM or with a trained DRAM.
|
||||
|
||||
// Signal pkg2 ready and continue boot.
|
||||
*mb_in = bootStatePkg2Continue;
|
||||
|
||||
// Halt ourselves in waitevent state and resume if there's JTAG activity.
|
||||
while (1)
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = 0x50000000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,26 +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 _HOS_H_
|
||||
#define _HOS_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "../config/ini.h"
|
||||
|
||||
int hos_launch(ini_sec_t *cfg);
|
||||
int keygen(u8 *keyblob, u32 kb, void *tsec_fw);
|
||||
|
||||
#endif
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "pkg1.h"
|
||||
#include "../utils/aarch64_util.h"
|
||||
#include "../sec/se.h"
|
||||
|
||||
#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)) },
|
||||
//Patch package2 decryption and signature/hash checks.
|
||||
{ 0x9F0 + 0xADC, _NOP() }, //Header signature.
|
||||
{ 0x9F0 + 0xB8C, _NOP() }, //Version.
|
||||
{ 0x9F0 + 0xBB0, _NOP() } //Sections SHA2.
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_secmon_2_patchset,
|
||||
// Patch package2 decryption and signature/hash checks.
|
||||
{ 0xAC8 + 0xAAC, _NOP() }, //Header signature.
|
||||
{ 0xAC8 + 0xB3C, _NOP() }, //Version.
|
||||
{ 0xAC8 + 0xB58, _NOP() } //Sections SHA2.
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_secmon_3_patchset,
|
||||
// Patch package2 decryption and signature/hash checks.
|
||||
{ 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.
|
||||
);
|
||||
|
||||
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.
|
||||
);
|
||||
|
||||
PATCHSET_DEF(_secmon_6_patchset,
|
||||
// Patch package2 decryption and signature/hash checks.
|
||||
{ 0xDC8 + 0x820, _NOP() }, //package2 structure.
|
||||
{ 0xDC8 + 0x82C, _NOP() }, //Version.
|
||||
{ 0xDC8 + 0xE90, _NOP() }, //Header signature.
|
||||
{ 0xDC8 + 0x112C, _NOP() } //Sections SHA2.
|
||||
);
|
||||
|
||||
/*
|
||||
* package1.1 header: <wb, ldr, sm>
|
||||
* package1.1 layout:
|
||||
* 1.0: {sm, ldr, wb} { 2, 1, 0 }
|
||||
* 2.0: {wb, ldr, sm} { 0, 1, 2 }
|
||||
* 3.0: {wb, ldr, sm} { 0, 1, 2 }
|
||||
* 3.1: {wb, ldr, sm} { 0, 1, 2 }
|
||||
* 4.0: {ldr, sm, wb} { 1, 2, 0 }
|
||||
* 5.0: {ldr, sm, wb} { 1, 2, 0 }
|
||||
* 6.0: {ldr, sm, wb} { 1, 2, 0 }
|
||||
*/
|
||||
|
||||
static const pkg1_id_t _pkg1_ids[] = {
|
||||
{ "20161121183008", 0, 0x1900, 0x3FE0, { 2, 1, 0 }, SM_100_ADR, 0x8000D000, true, _secmon_1_patchset }, //1.0.0 (Patched relocator)
|
||||
{ "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_2_patchset }, //2.0.0 - 2.3.0
|
||||
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset }, //3.0.0
|
||||
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset }, //3.0.1 - 3.0.2
|
||||
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_4_patchset }, //4.0.0 - 4.1.0
|
||||
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_5_patchset }, //5.0.0 - 5.1.0
|
||||
{ "20180802162753", 5, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_6_patchset }, //6.0.0 - 6.0.0
|
||||
{ NULL } //End.
|
||||
};
|
||||
|
||||
|
||||
const pkg1_id_t *pkg1_identify(u8 *pkg1)
|
||||
{
|
||||
for (u32 i = 0; _pkg1_ids[i].id; i++)
|
||||
if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 12))
|
||||
return &_pkg1_ids[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1)
|
||||
{
|
||||
// Decrypt package1.
|
||||
u8 *pkg11 = pkg1 + id->pkg11_off;
|
||||
u32 pkg11_size = *(u32 *)pkg11;
|
||||
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)
|
||||
{
|
||||
pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + id->pkg11_off + 0x20);
|
||||
|
||||
u32 sec_size[3] = { hdr->wb_size, hdr->ldr_size, hdr->sm_size };
|
||||
//u32 sec_off[3] = { hdr->wb_off, hdr->ldr_off, hdr->sm_off };
|
||||
|
||||
u8 *pdata = (u8 *)hdr + sizeof(pk11_hdr_t);
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
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]];
|
||||
}
|
||||
}
|
||||
@@ -1,63 +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 _PKG1_H_
|
||||
#define _PKG1_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
typedef struct _patch_t
|
||||
{
|
||||
u32 off;
|
||||
u32 val;
|
||||
} patch_t;
|
||||
|
||||
#define PATCHSET_DEF(name, ...) \
|
||||
patch_t name[] = { \
|
||||
__VA_ARGS__, \
|
||||
{ 0xFFFFFFFF, 0xFFFFFFFF } \
|
||||
}
|
||||
|
||||
typedef struct _pkg1_id_t
|
||||
{
|
||||
const char *id;
|
||||
u32 kb;
|
||||
u32 tsec_off;
|
||||
u32 pkg11_off;
|
||||
u32 sec_map[3];
|
||||
u32 secmon_base;
|
||||
u32 warmboot_base;
|
||||
bool set_warmboot;
|
||||
patch_t *secmon_patchset;
|
||||
} pkg1_id_t;
|
||||
|
||||
typedef struct _pk11_hdr_t
|
||||
{
|
||||
u32 magic;
|
||||
u32 wb_size;
|
||||
u32 wb_off;
|
||||
u32 pad;
|
||||
u32 ldr_size;
|
||||
u32 ldr_off;
|
||||
u32 sm_size;
|
||||
u32 sm_off;
|
||||
} 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);
|
||||
|
||||
#endif
|
||||
@@ -1,902 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018 Atmosphère-NX
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "pkg2.h"
|
||||
#include "../utils/aarch64_util.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../sec/se.h"
|
||||
#include "../libs/compr/blz.h"
|
||||
|
||||
#include "../gfx/gfx.h"
|
||||
|
||||
extern gfx_con_t gfx_con;
|
||||
|
||||
/*#include "util.h"
|
||||
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
|
||||
#define DEBUG_PRINTING*/
|
||||
#define DPRINTF(...)
|
||||
|
||||
//TODO: Replace hardcoded AArch64 instructions with instruction macros.
|
||||
//TODO: Reduce hardcoded values without searching kernel for patterns?
|
||||
// The process ID send/receive kernel patches were taken from Atmosphère's kernel patches.
|
||||
// They should only be used when running Atmosphère.
|
||||
#define FREE_CODE_OFF_1ST_100 0x4797C
|
||||
#define FREE_CODE_OFF_1ST_200 0x6486C
|
||||
#define FREE_CODE_OFF_1ST_300 0x494A4
|
||||
#define FREE_CODE_OFF_1ST_302 0x494BC
|
||||
#define FREE_CODE_OFF_1ST_400 0x52890
|
||||
#define FREE_CODE_OFF_1ST_500 0x5C020
|
||||
#define FREE_CODE_OFF_1ST_600 0x5EE00
|
||||
|
||||
#define ID_SND_OFF_100 0x23CC0
|
||||
#define ID_SND_OFF_200 0x3F134
|
||||
#define ID_SND_OFF_300 0x26080
|
||||
#define ID_SND_OFF_302 0x26080
|
||||
#define ID_SND_OFF_400 0x2AF64
|
||||
#define ID_SND_OFF_500 0x2AD34
|
||||
#define ID_SND_OFF_600 0x2BB8C
|
||||
|
||||
#define ID_RCV_OFF_100 0x219F0
|
||||
#define ID_RCV_OFF_200 0x3D1A8
|
||||
#define ID_RCV_OFF_300 0x240F0
|
||||
#define ID_RCV_OFF_302 0x240F0
|
||||
#define ID_RCV_OFF_400 0x28F6C
|
||||
#define ID_RCV_OFF_500 0x28DAC
|
||||
#define ID_RCV_OFF_600 0x29B6C
|
||||
|
||||
static u32 PRC_ID_SND_100[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A0E03EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
|
||||
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9412948, 0xA8C12FEA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_100 (FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100) + 4)
|
||||
static u32 PRC_ID_RCV_100[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A1C03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
|
||||
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9412968, 0xA8C12FEA
|
||||
};
|
||||
|
||||
static u32 PRC_ID_SND_200[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
|
||||
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9413148, 0xA8C12FEA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_200 (FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200) + 4)
|
||||
static u32 PRC_ID_RCV_200[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
|
||||
0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9413168, 0xA8C12FEA
|
||||
};
|
||||
|
||||
static u32 PRC_ID_SND_300[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
|
||||
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9415548, 0xA8C12FEA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_300 (FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300) + 4)
|
||||
static u32 PRC_ID_RCV_300[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
|
||||
0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415568, 0xA8C12FEA
|
||||
};
|
||||
|
||||
static u32 PRC_ID_SND_302[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
|
||||
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9415548, 0xA8C12FEA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_302 (FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_302) + 4)
|
||||
static u32 PRC_ID_RCV_302[] =
|
||||
{
|
||||
0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
|
||||
0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415568, 0xA8C12FEA
|
||||
};
|
||||
|
||||
static u32 PRC_ID_SND_400[] =
|
||||
{
|
||||
0x2A1703EA, 0xD37EF54A, 0xF86A6B8A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9,
|
||||
0xEB09015F, 0x54000060, 0xF94053EA, 0xF9415948, 0xF94053EA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_400 (FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400) + 4)
|
||||
static u32 PRC_ID_RCV_400[] =
|
||||
{
|
||||
0xF9403BED, 0x2A0E03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
|
||||
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B28, 0xD503201F
|
||||
};
|
||||
|
||||
static u32 PRC_ID_SND_500[] =
|
||||
{
|
||||
0x2A1703EA, 0xD37EF54A, 0xF86A6B6A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9,
|
||||
0xEB09015F, 0x54000060, 0xF94043EA, 0xF9415948, 0xF94043EA
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_500 (FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500) + 4)
|
||||
static u32 PRC_ID_RCV_500[] =
|
||||
{
|
||||
0xF9403BED, 0x2A1503EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
|
||||
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B08, 0xF9406FEA
|
||||
};
|
||||
|
||||
static u32 PRC_ID_SND_600[] =
|
||||
{
|
||||
0xA9BF2FEA, 0xF94037EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
|
||||
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
|
||||
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
|
||||
};
|
||||
#define FREE_CODE_OFF_2ND_600 (FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600) + 4)
|
||||
static u32 PRC_ID_RCV_600[] =
|
||||
{
|
||||
0xA9BF2FEA, 0xF94043EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
|
||||
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
|
||||
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
|
||||
};
|
||||
|
||||
// Include kernel patches here, so we can utilize pkg1 id
|
||||
KERNEL_PATCHSET_DEF(_kernel_1_patchset,
|
||||
{ SVC_VERIFY_DS, 0x3764C, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x44074, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_100, _B(ID_SND_OFF_100, FREE_CODE_OFF_1ST_100), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_100, sizeof(PRC_ID_SND_100) >> 2, PRC_ID_SND_100}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100), ID_SND_OFF_100 + 4), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_100, _B(ID_RCV_OFF_100, FREE_CODE_OFF_2ND_100), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_100, sizeof(PRC_ID_RCV_100) >> 2, PRC_ID_RCV_100}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_100 + sizeof(PRC_ID_RCV_100), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_2ND_100 + sizeof(PRC_ID_RCV_100), ID_RCV_OFF_100 + 4), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_2_patchset,
|
||||
{ SVC_VERIFY_DS, 0x54834, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x6086C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_200, _B(ID_SND_OFF_200, FREE_CODE_OFF_1ST_200), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_200, sizeof(PRC_ID_SND_200) >> 2, PRC_ID_SND_200}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200), ID_SND_OFF_200 + 4), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_200, _B(ID_RCV_OFF_200, FREE_CODE_OFF_2ND_200), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_200, sizeof(PRC_ID_RCV_200) >> 2, PRC_ID_RCV_200}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_200 + sizeof(PRC_ID_RCV_200), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_2ND_200 + sizeof(PRC_ID_RCV_200), ID_RCV_OFF_200 + 4), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_3_patchset,
|
||||
{ SVC_VERIFY_DS, 0x3BD24, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x483FC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_300, _B(ID_SND_OFF_300, FREE_CODE_OFF_1ST_300), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_300, sizeof(PRC_ID_SND_300) >> 2, PRC_ID_SND_300}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300), ID_SND_OFF_300 + 4), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_300, _B(ID_RCV_OFF_300, FREE_CODE_OFF_2ND_300), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_300, sizeof(PRC_ID_RCV_300) >> 2, PRC_ID_RCV_300}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_300 + sizeof(PRC_ID_RCV_300), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_2ND_300 + sizeof(PRC_ID_RCV_300), ID_RCV_OFF_300 + 4), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_302_patchset,
|
||||
{ SVC_VERIFY_DS, 0x3BD24, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x48414, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_302, _B(ID_SND_OFF_302, FREE_CODE_OFF_1ST_302), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_302, sizeof(PRC_ID_SND_302) >> 2, PRC_ID_SND_302}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_302), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_302), ID_SND_OFF_302 + 4), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_302, _B(ID_RCV_OFF_302, FREE_CODE_OFF_2ND_302), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_302, sizeof(PRC_ID_RCV_302) >> 2, PRC_ID_RCV_302}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_302), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_2ND_302 + sizeof(PRC_ID_RCV_302), ID_RCV_OFF_302 + 4), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_4_patchset,
|
||||
{ SVC_VERIFY_DS, 0x41EB4, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x4EBFC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_400, _B(ID_SND_OFF_400, FREE_CODE_OFF_1ST_400), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_400, sizeof(PRC_ID_SND_400) >> 2, PRC_ID_SND_400}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400), // Branch back and skip 2 instructions.
|
||||
_B(FREE_CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400), ID_SND_OFF_400 + 8), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_400, _B(ID_RCV_OFF_400, FREE_CODE_OFF_2ND_400), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_400, sizeof(PRC_ID_RCV_400) >> 2, PRC_ID_RCV_400}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_400 + sizeof(PRC_ID_RCV_400), // Branch back and skip 1 instruction.
|
||||
_B(FREE_CODE_OFF_2ND_400 + sizeof(PRC_ID_RCV_400), ID_RCV_OFF_400 + 4), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_5_patchset,
|
||||
{ SVC_VERIFY_DS, 0x45E6C, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x5513C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_500, _B(ID_SND_OFF_500, FREE_CODE_OFF_1ST_500), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_500, sizeof(PRC_ID_SND_500) >> 2, PRC_ID_SND_500}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), // Branch back and skip 2 instructions.
|
||||
_B(FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), ID_SND_OFF_500 + 8), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_500, _B(ID_RCV_OFF_500, FREE_CODE_OFF_2ND_500), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_500, sizeof(PRC_ID_RCV_500) >> 2, PRC_ID_RCV_500}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_500 + sizeof(PRC_ID_RCV_500), // Branch back and skip 2 instructions.
|
||||
_B(FREE_CODE_OFF_2ND_500 + sizeof(PRC_ID_RCV_500), ID_RCV_OFF_500 + 8), NULL}
|
||||
);
|
||||
|
||||
KERNEL_PATCHSET_DEF(_kernel_6_patchset,
|
||||
{ SVC_VERIFY_DS, 0x47EA0, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x57548, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_600, _B(ID_SND_OFF_600, FREE_CODE_OFF_1ST_600), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_600, sizeof(PRC_ID_SND_600) >> 2, PRC_ID_SND_600}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), // Branch back and skip 4 instructions.
|
||||
_B(FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), ID_SND_OFF_600 + 0x10), NULL},
|
||||
{ ATM_GEN_PATCH, ID_RCV_OFF_600, _B(ID_RCV_OFF_600, FREE_CODE_OFF_2ND_600), NULL}, // Receive process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_600, sizeof(PRC_ID_RCV_600) >> 2, PRC_ID_RCV_600}, // Receive process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_600 + sizeof(PRC_ID_RCV_600), // Branch back and skip 4 instructions.
|
||||
_B(FREE_CODE_OFF_2ND_600 + sizeof(PRC_ID_RCV_600), ID_RCV_OFF_600 + 0x10), NULL}
|
||||
);
|
||||
|
||||
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
|
||||
{ 0x64ce1a44, _kernel_6_patchset }, //6.0.0
|
||||
{ 0, 0 } //End.
|
||||
};
|
||||
|
||||
enum kip_offset_section
|
||||
{
|
||||
KIP_TEXT = 0,
|
||||
KIP_RODATA = 1,
|
||||
KIP_DATA = 2,
|
||||
KIP_BSS = 3,
|
||||
KIP_UNKSEC1 = 4,
|
||||
KIP_UNKSEC2 = 5
|
||||
};
|
||||
|
||||
#define KIP_PATCH_SECTION_SHIFT (29)
|
||||
#define KIP_PATCH_SECTION_MASK (7 << KIP_PATCH_SECTION_SHIFT)
|
||||
#define KIP_PATCH_OFFSET_MASK (~KIP_PATCH_SECTION_MASK)
|
||||
#define GET_KIP_PATCH_SECTION(x) ((x >> KIP_PATCH_SECTION_SHIFT) & 7)
|
||||
#define GET_KIP_PATCH_OFFSET(x) (x & KIP_PATCH_OFFSET_MASK)
|
||||
#define KPS(x) ((u32)(x) << KIP_PATCH_SECTION_SHIFT)
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_100[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x194A0, 4, "\xBA\x09\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x3A79C, 4, "\xE0\x06\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_100[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_100 },
|
||||
{ "nogc", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_200[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x15DF4, 4, "\xBC\x0A\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x3F720, 4, "\x00\x06\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_200[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_200 },
|
||||
{ "nogc", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_210[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x15F64, 4, "\xDF\x0A\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x3FAF8, 4, "\x00\x06\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_210[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_210 },
|
||||
{ "nogc", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_300[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x18E24, 4, "\x52\x0C\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x49EC8, 4, "\x40\x04\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_300[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_300 },
|
||||
{ "nogc", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_30x[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x18E90, 4, "\x52\x0C\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x49F34, 4, "\xE0\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_30x[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_30x },
|
||||
{ "nogc", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_4xx[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x1C4FC, 4, "\x3C\x2F\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x57934, 4, "\xE0\x02\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_40x[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0xA3458, 4, "\x14\x40\x80\x72", "\x14\x80\x80\x72" },
|
||||
{ KPS(KIP_TEXT) | 0xAAB44, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_40x[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_4xx },
|
||||
{ "nogc", _fs_nogc_40x },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_410[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0xA34BC, 4, "\x14\x40\x80\x72", "\x14\x80\x80\x72" },
|
||||
{ KPS(KIP_TEXT) | 0xAABA8, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_410[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_4xx },
|
||||
{ "nogc", _fs_nogc_410 },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_50x[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x22DDC, 4, "\x7D\x3E\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x7D490, 4, "\x40\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_50x[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0xCF3C4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0xD73A0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_50x[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_50x },
|
||||
{ "nogc", _fs_nogc_50x },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_510[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x22E0C, 4, "\x85\x3E\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0x7D860, 4, "\x40\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_510[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0xCF794, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ KPS(KIP_TEXT) | 0xD7770, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_510[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_510 },
|
||||
{ "nogc", _fs_nogc_510 },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_600[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x712A8, 4, "\x8E\x3E\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0xEB08C, 4, "\xC0\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nosigchk_600_exfat[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x7C9A8, 4, "\x8E\x3E\x00\x94", "\xE0\x03\x1F\x2A" },
|
||||
{ KPS(KIP_TEXT) | 0xF678C, 4, "\xC0\x03\x00\x36", "\x1F\x20\x03\xD5" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_600[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x12CC20, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x1538F4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patch_t _fs_nogc_600_exfat[] =
|
||||
{
|
||||
{ KPS(KIP_TEXT) | 0x138320, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
|
||||
{ KPS(KIP_TEXT) | 0x15EFF4, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_600[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_600 },
|
||||
{ "nogc", _fs_nogc_600 },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_patchset_t _fs_patches_600_exfat[] =
|
||||
{
|
||||
{ "nosigchk", _fs_nosigchk_600_exfat },
|
||||
{ "nogc", _fs_nogc_600_exfat },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static kip1_id_t _kip_ids[] =
|
||||
{
|
||||
{ "FS", "\xde\x9f\xdd\xa4\x08\x5d\xd5\xfe\x68\xdc\xb2\x0b\x41\x09\x5b\xb4", _fs_patches_100 }, // FS 1.0.0
|
||||
{ "FS", "\xfc\x3e\x80\x99\x1d\xca\x17\x96\x4a\x12\x1f\x04\xb6\x1b\x17\x5e", _fs_patches_100 }, // FS 1.0.0 exfat
|
||||
{ "FS", "\xcd\x7b\xbe\x18\xd6\x13\x0b\x28\xf6\x2f\x19\xfa\x79\x45\x53\x5b", _fs_patches_200 }, // FS 2.0.0
|
||||
{ "FS", "\xe7\x66\x92\xdf\xaa\x04\x20\xe9\xfd\xd6\x8e\x43\x63\x16\x18\x18", _fs_patches_200 }, // FS 2.0.0 exfat
|
||||
{ "FS", "\x0d\x70\x05\x62\x7b\x07\x76\x7c\x0b\x96\x3f\x9a\xff\xdd\xe5\x66", _fs_patches_210 }, // FS 2.1.0
|
||||
{ "FS", "\xdb\xd8\x5f\xca\xcc\x19\x3d\xa8\x30\x51\xc6\x64\xe6\x45\x2d\x32", _fs_patches_210 }, // FS 2.1.0 exfat
|
||||
{ "FS", "\xa8\x6d\xa5\xe8\x7e\xf1\x09\x7b\x23\xda\xb5\xb4\xdb\xba\xef\xe7", _fs_patches_300 }, // FS 3.0.0
|
||||
{ "FS", "\x98\x1c\x57\xe7\xf0\x2f\x70\xf7\xbc\xde\x75\x31\x81\xd9\x01\xa6", _fs_patches_300 }, // FS 3.0.0 exfat
|
||||
{ "FS", "\x57\x39\x7c\x06\x3f\x10\xb6\x31\x3f\x4d\x83\x76\x53\xcc\xc3\x71", _fs_patches_30x }, // FS 3.0.1
|
||||
{ "FS", "\x07\x30\x99\xd7\xc6\xad\x7d\x89\x83\xbc\x7a\xdd\x93\x2b\xe3\xd1", _fs_patches_30x }, // FS 3.0.1 exfat
|
||||
{ "FS", "\x06\xe9\x07\x19\x59\x5a\x01\x0c\x62\x46\xff\x70\x94\x6f\x10\xfb", _fs_patches_40x }, // FS 4.0.1
|
||||
{ "FS", "\x54\x9b\x0f\x8d\x6f\x72\xc4\xe9\xf3\xfd\x1f\x19\xea\xce\x4a\x5a", _fs_patches_40x }, // FS 4.0.1 exfat
|
||||
{ "FS", "\x80\x96\xaf\x7c\x6a\x35\xaa\x82\x71\xf3\x91\x69\x95\x41\x3b\x0b", _fs_patches_410 }, // FS 4.1.0
|
||||
{ "FS", "\x02\xd5\xab\xaa\xfd\x20\xc8\xb0\x63\x3a\xa0\xdb\xae\xe0\x37\x7e", _fs_patches_410 }, // FS 4.1.0 exfat
|
||||
{ "FS", "\xa6\xf2\x7a\xd9\xac\x7c\x73\xad\x41\x9b\x63\xb2\x3e\x78\x5a\x0c", _fs_patches_50x }, // FS 5.0.0
|
||||
{ "FS", "\xce\x3e\xcb\xa2\xf2\xf0\x62\xf5\x75\xf8\xf3\x60\x84\x2b\x32\xb4", _fs_patches_50x }, // FS 5.0.0 exfat
|
||||
{ "FS", "\x76\xf8\x74\x02\xc9\x38\x7c\x0f\x0a\x2f\xab\x1b\x45\xce\xbb\x93", _fs_patches_510 }, // FS 5.1.0
|
||||
{ "FS", "\x10\xb2\xd8\x16\x05\x48\x85\x99\xdf\x22\x42\xcb\x6b\xac\x2d\xf1", _fs_patches_510 }, // FS 5.1.0 exfat
|
||||
{ "FS", "\x1b\x82\xcb\x22\x18\x67\xcb\x52\xc4\x4a\x86\x9e\xa9\x1a\x1a\xdd", _fs_patches_600 }, // FS 6.0.0-4.0
|
||||
{ "FS", "\x96\x6a\xdd\x3d\x20\xb6\x27\x13\x2c\x5a\x8d\xa4\x9a\xc9\xd8\xdd", _fs_patches_600_exfat }, // FS 6.0.0-4.0 exfat
|
||||
{ "FS", "\x3a\x57\x4d\x43\x61\x86\x19\x1d\x17\x88\xeb\x2c\x0f\x07\x6b\x11", _fs_patches_600 }, // FS 6.0.0-5.0
|
||||
{ "FS", "\x33\x05\x53\xf6\xb5\xfb\x55\xc4\xc2\xd7\xb7\x36\x24\x02\x76\xb3", _fs_patches_600_exfat } // FS 6.0.0-5.0 exfat
|
||||
};
|
||||
|
||||
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);
|
||||
for (u32 j = 0; j < KIP1_NUM_SECTIONS; j++)
|
||||
size += kip1->sections[j].size_comp;
|
||||
return size;
|
||||
}
|
||||
|
||||
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2)
|
||||
{
|
||||
u8 *ptr = pkg2->data + pkg2->sec_size[PKG2_SEC_KERNEL];
|
||||
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)ptr;
|
||||
ptr += sizeof(pkg2_ini1_t);
|
||||
|
||||
for (u32 i = 0; i < ini1->num_procs; i++)
|
||||
{
|
||||
pkg2_kip1_t *kip1 = (pkg2_kip1_t *)ptr;
|
||||
pkg2_kip1_info_t *ki = (pkg2_kip1_info_t *)malloc(sizeof(pkg2_kip1_info_t));
|
||||
ki->kip1 = kip1;
|
||||
ki->size = _pkg2_calc_kip1_size(kip1);
|
||||
list_append(info, &ki->link);
|
||||
ptr += ki->size;
|
||||
DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size);
|
||||
}
|
||||
}
|
||||
|
||||
int pkg2_has_kip(link_t *info, u64 tid)
|
||||
{
|
||||
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
|
||||
if(ki->kip1->tid == tid)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1)
|
||||
{
|
||||
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
|
||||
if (ki->kip1->tid == tid)
|
||||
{
|
||||
ki->kip1 = kip1;
|
||||
ki->size = _pkg2_calc_kip1_size(kip1);
|
||||
DPRINTF("replaced kip (new size %08X)\n", ki->size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1)
|
||||
{
|
||||
pkg2_kip1_info_t *ki = (pkg2_kip1_info_t *)malloc(sizeof(pkg2_kip1_info_t));
|
||||
ki->kip1 = kip1;
|
||||
ki->size = _pkg2_calc_kip1_size(kip1);
|
||||
DPRINTF("added kip (size %08X)\n", ki->size);
|
||||
list_append(info, &ki->link);
|
||||
}
|
||||
|
||||
void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1)
|
||||
{
|
||||
if (pkg2_has_kip(info, kip1->tid))
|
||||
pkg2_replace_kip(info, kip1->tid, kip1);
|
||||
else
|
||||
pkg2_add_kip(info, kip1);
|
||||
}
|
||||
|
||||
int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp)
|
||||
{
|
||||
u32 compClearMask = ~sectsToDecomp;
|
||||
if ((ki->kip1->flags & compClearMask) == ki->kip1->flags)
|
||||
return 0; // Already decompressed, nothing to do.
|
||||
|
||||
pkg2_kip1_t hdr;
|
||||
memcpy(&hdr, ki->kip1, sizeof(hdr));
|
||||
|
||||
unsigned int newKipSize = sizeof(hdr);
|
||||
for (u32 sectIdx=0; sectIdx<KIP1_NUM_SECTIONS; sectIdx++)
|
||||
{
|
||||
u32 sectCompBit = 1u << sectIdx;
|
||||
// For compressed, cant get actual decompressed size without doing it, so use safe "output size".
|
||||
if (sectIdx < 3 && (sectsToDecomp & sectCompBit) && (hdr.flags & sectCompBit))
|
||||
newKipSize += hdr.sections[sectIdx].size_decomp;
|
||||
else
|
||||
newKipSize += hdr.sections[sectIdx].size_comp;
|
||||
}
|
||||
|
||||
pkg2_kip1_t* newKip = malloc(newKipSize);
|
||||
unsigned char* dstDataPtr = newKip->data;
|
||||
const unsigned char* srcDataPtr = ki->kip1->data;
|
||||
for (u32 sectIdx=0; sectIdx<KIP1_NUM_SECTIONS; sectIdx++)
|
||||
{
|
||||
u32 sectCompBit = 1u << sectIdx;
|
||||
// Easy copy path for uncompressed or ones we dont want to uncompress.
|
||||
if (sectIdx >= 3 || !(sectsToDecomp & sectCompBit) || !(hdr.flags & sectCompBit))
|
||||
{
|
||||
unsigned int dataSize = hdr.sections[sectIdx].size_comp;
|
||||
if (dataSize == 0)
|
||||
continue;
|
||||
|
||||
memcpy(dstDataPtr, srcDataPtr, dataSize);
|
||||
srcDataPtr += dataSize;
|
||||
dstDataPtr += dataSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned int compSize = hdr.sections[sectIdx].size_comp;
|
||||
unsigned int outputSize = hdr.sections[sectIdx].size_decomp;
|
||||
gfx_printf(&gfx_con, "Decomping %s KIP1 sect %d of size %d...\n", (const char*)hdr.name, sectIdx, compSize);
|
||||
if (blz_uncompress_srcdest(srcDataPtr, compSize, dstDataPtr, outputSize) == 0)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%kERROR decomping sect %d of %s KIP!%k\n", 0xFFFF0000, sectIdx, (char*)hdr.name, 0xFFCCCCCC);
|
||||
free(newKip);
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF("Done! Decompressed size is %d!\n", outputSize);
|
||||
}
|
||||
hdr.sections[sectIdx].size_comp = outputSize;
|
||||
srcDataPtr += compSize;
|
||||
dstDataPtr += outputSize;
|
||||
}
|
||||
|
||||
hdr.flags &= compClearMask;
|
||||
memcpy(newKip, &hdr, sizeof(hdr));
|
||||
newKipSize = dstDataPtr-(unsigned char*)(newKip);
|
||||
|
||||
free(ki->kip1);
|
||||
ki->kip1 = newKip;
|
||||
ki->size = newKipSize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* pkg2_patch_kips(link_t *info, char* patchNames)
|
||||
{
|
||||
if (patchNames == NULL || patchNames[0] == 0)
|
||||
return NULL;
|
||||
|
||||
static const u32 MAX_NUM_PATCHES_REQUESTED = sizeof(u32)*8;
|
||||
char* patches[MAX_NUM_PATCHES_REQUESTED];
|
||||
|
||||
u32 numPatches=1;
|
||||
patches[0] = patchNames;
|
||||
{
|
||||
for (char* p = patchNames; *p != 0; p++)
|
||||
{
|
||||
if (*p == ',')
|
||||
{
|
||||
*p = 0;
|
||||
patches[numPatches++] = p+1;
|
||||
if (numPatches >= MAX_NUM_PATCHES_REQUESTED)
|
||||
return "too_many_patches";
|
||||
}
|
||||
else if (*p >= 'A' && *p <= 'Z')
|
||||
*p += 0x20;
|
||||
}
|
||||
}
|
||||
|
||||
u32 patchesApplied = 0; // Bitset over patches.
|
||||
for (u32 i=0; i<numPatches; i++)
|
||||
{
|
||||
// Eliminate leading spaces.
|
||||
for (const char* p=patches[i]; *p!=0; p++)
|
||||
{
|
||||
if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
|
||||
patches[i]++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
int valueLen = strlen(patches[i]);
|
||||
if (valueLen == 0)
|
||||
continue;
|
||||
|
||||
// Eliminate trailing spaces.
|
||||
for (int chIdx=valueLen-1; chIdx>=0; chIdx--)
|
||||
{
|
||||
const char* p = patches[i] + chIdx;
|
||||
if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
|
||||
valueLen = chIdx;
|
||||
else
|
||||
break;
|
||||
}
|
||||
patches[i][valueLen] = 0;
|
||||
|
||||
DPRINTF("Requested patch: '%s'\n", patches[i]);
|
||||
}
|
||||
|
||||
u32 shaBuf[32/sizeof(u32)];
|
||||
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
|
||||
{
|
||||
shaBuf[0] = 0; // sha256 for this kip not yet calculated.
|
||||
for (u32 currKipIdx=0; currKipIdx<(sizeof(_kip_ids)/sizeof(_kip_ids[0])); currKipIdx++)
|
||||
{
|
||||
if (strncmp((const char*)ki->kip1->name, _kip_ids[currKipIdx].name, sizeof(ki->kip1->name)) != 0)
|
||||
continue;
|
||||
|
||||
u32 bitsAffected = 0;
|
||||
kip1_patchset_t* currPatchset = _kip_ids[currKipIdx].patchset;
|
||||
while (currPatchset != NULL && currPatchset->name != NULL)
|
||||
{
|
||||
for (u32 i=0; i<numPatches; i++)
|
||||
{
|
||||
if (strcmp(currPatchset->name, patches[i]) != 0)
|
||||
{
|
||||
bitsAffected = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
currPatchset++;
|
||||
}
|
||||
|
||||
// Dont bother even hashing this KIP if we dont have any patches enabled for it.
|
||||
if (bitsAffected == 0)
|
||||
continue;
|
||||
|
||||
if (shaBuf[0] == 0)
|
||||
{
|
||||
if (!se_calc_sha256(shaBuf, ki->kip1, ki->size))
|
||||
memset(shaBuf, 0, sizeof(shaBuf));
|
||||
}
|
||||
|
||||
if (memcmp(shaBuf, _kip_ids[currKipIdx].hash, sizeof(_kip_ids[0].hash)) != 0)
|
||||
continue;
|
||||
|
||||
// Find out which sections are affected by the enabled patches, to know which to decompress.
|
||||
bitsAffected = 0;
|
||||
currPatchset = _kip_ids[currKipIdx].patchset;
|
||||
while (currPatchset != NULL && currPatchset->name != NULL)
|
||||
{
|
||||
if (currPatchset->patches != NULL)
|
||||
{
|
||||
for (u32 currEnabIdx=0; currEnabIdx<numPatches; currEnabIdx++)
|
||||
{
|
||||
if (strcmp(currPatchset->name, patches[currEnabIdx]))
|
||||
continue;
|
||||
|
||||
for (const kip1_patch_t* currPatch=currPatchset->patches; currPatch != NULL && currPatch->length != 0; currPatch++)
|
||||
bitsAffected |= 1u << GET_KIP_PATCH_SECTION(currPatch->offset);
|
||||
}
|
||||
}
|
||||
currPatchset++;
|
||||
}
|
||||
|
||||
// Got patches to apply to this kip, have to decompress it.
|
||||
#ifdef DEBUG_PRINTING
|
||||
u32 preDecompTime = get_tmr_us();
|
||||
#endif
|
||||
if (pkg2_decompress_kip(ki, bitsAffected))
|
||||
return (const char*)ki->kip1->name; // Failed to decompress.
|
||||
|
||||
#ifdef DEBUG_PRINTING
|
||||
u32 postDecompTime = get_tmr_us();
|
||||
if (!se_calc_sha256(shaBuf, ki->kip1, ki->size))
|
||||
memset(shaBuf, 0, sizeof(shaBuf));
|
||||
|
||||
DPRINTF("%dms %s KIP1 size %d hash %08X\n", (postDecompTime-preDecompTime)/1000, ki->kip1->name, (int)ki->size, __builtin_bswap32(shaBuf[0]));
|
||||
#endif
|
||||
|
||||
currPatchset = _kip_ids[currKipIdx].patchset;
|
||||
while (currPatchset != NULL && currPatchset->name != NULL)
|
||||
{
|
||||
for (u32 currEnabIdx=0; currEnabIdx<numPatches; currEnabIdx++)
|
||||
{
|
||||
if (strcmp(currPatchset->name, patches[currEnabIdx]))
|
||||
continue;
|
||||
|
||||
u32 appliedMask = 1u << currEnabIdx;
|
||||
if (currPatchset->patches == NULL)
|
||||
{
|
||||
gfx_printf(&gfx_con, "Patch '%s' not necessary for %s KIP1\n", currPatchset->name, (const char*)ki->kip1->name);
|
||||
patchesApplied |= appliedMask;
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned char* kipSectData = ki->kip1->data;
|
||||
for (u32 currSectIdx=0; currSectIdx<KIP1_NUM_SECTIONS; currSectIdx++)
|
||||
{
|
||||
if (bitsAffected & (1u << currSectIdx))
|
||||
{
|
||||
gfx_printf(&gfx_con, "Applying patch '%s' on %s KIP1 sect %d\n", currPatchset->name, (const char*)ki->kip1->name, currSectIdx);
|
||||
for (const kip1_patch_t* currPatch=currPatchset->patches;currPatch != NULL && currPatch->length != 0; currPatch++)
|
||||
{
|
||||
if (GET_KIP_PATCH_SECTION(currPatch->offset) != currSectIdx)
|
||||
continue;
|
||||
|
||||
u32 currOffset = GET_KIP_PATCH_OFFSET(currPatch->offset);
|
||||
if (memcmp(&kipSectData[currOffset], currPatch->srcData, currPatch->length) != 0)
|
||||
{
|
||||
gfx_printf(&gfx_con, "%kDATA MISMATCH FOR PATCH AT OFFSET 0x%x!!!%k\n", 0xFFFF0000, currOffset, 0xFFCCCCCC);
|
||||
return currPatchset->name; // MUST stop here as kip is likely corrupt.
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF("Patching %d bytes at offset 0x%x\n", currPatch->length, currOffset);
|
||||
memcpy(&kipSectData[currOffset], currPatch->dstData, currPatch->length);
|
||||
}
|
||||
}
|
||||
}
|
||||
kipSectData += ki->kip1->sections[currSectIdx].size_comp;
|
||||
}
|
||||
|
||||
patchesApplied |= appliedMask;
|
||||
break;
|
||||
}
|
||||
currPatchset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i=0; i<numPatches; i++)
|
||||
{
|
||||
if ((patchesApplied & (1u << i)) == 0)
|
||||
return patches[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pkg2_hdr_t *pkg2_decrypt(void *data)
|
||||
{
|
||||
u8 *pdata = (u8 *)data;
|
||||
|
||||
// Skip signature.
|
||||
pdata += 0x100;
|
||||
|
||||
pkg2_hdr_t *hdr = (pkg2_hdr_t *)pdata;
|
||||
|
||||
// Skip header.
|
||||
pdata += sizeof(pkg2_hdr_t);
|
||||
|
||||
// Decrypt header.
|
||||
se_aes_crypt_ctr(8, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||
//gfx_hexdump(&gfx_con, (u32)hdr, hdr, 0x100);
|
||||
|
||||
if (hdr->magic != PKG2_MAGIC)
|
||||
return NULL;
|
||||
|
||||
for (u32 i = 0; i < 4; i++)
|
||||
{
|
||||
DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]);
|
||||
if (!hdr->sec_size[i])
|
||||
continue;
|
||||
|
||||
se_aes_crypt_ctr(8, pdata, hdr->sec_size[i], pdata, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]);
|
||||
//gfx_hexdump(&gfx_con, (u32)pdata, pdata, 0x100);
|
||||
|
||||
pdata += hdr->sec_size[i];
|
||||
}
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
void pkg2_build_encrypt(void *dst, void *kernel, u32 kernel_size, link_t *kips_info)
|
||||
{
|
||||
u8 *pdst = (u8 *)dst;
|
||||
|
||||
// Signature.
|
||||
memset(pdst, 0, 0x100);
|
||||
pdst += 0x100;
|
||||
|
||||
// Header.
|
||||
pkg2_hdr_t *hdr = (pkg2_hdr_t *)pdst;
|
||||
memset(hdr, 0, sizeof(pkg2_hdr_t));
|
||||
pdst += sizeof(pkg2_hdr_t);
|
||||
hdr->magic = PKG2_MAGIC;
|
||||
hdr->base = 0x10000000;
|
||||
DPRINTF("kernel @ %08X (%08X)\n", (u32)kernel, kernel_size);
|
||||
|
||||
// Kernel.
|
||||
memcpy(pdst, kernel, kernel_size);
|
||||
hdr->sec_size[PKG2_SEC_KERNEL] = kernel_size;
|
||||
hdr->sec_off[PKG2_SEC_KERNEL] = 0x10000000;
|
||||
se_aes_crypt_ctr(8, pdst, kernel_size, pdst, kernel_size, &hdr->sec_ctr[PKG2_SEC_KERNEL * 0x10]);
|
||||
pdst += kernel_size;
|
||||
DPRINTF("kernel encrypted\n");
|
||||
|
||||
// INI1.
|
||||
u32 ini1_size = sizeof(pkg2_ini1_t);
|
||||
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)pdst;
|
||||
memset(ini1, 0, sizeof(pkg2_ini1_t));
|
||||
ini1->magic = INI1_MAGIC;
|
||||
pdst += sizeof(pkg2_ini1_t);
|
||||
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips_info, link)
|
||||
{
|
||||
DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->size);
|
||||
memcpy(pdst, ki->kip1, ki->size);
|
||||
pdst += ki->size;
|
||||
ini1_size += ki->size;
|
||||
ini1->num_procs++;
|
||||
}
|
||||
ini1->size = ini1_size;
|
||||
hdr->sec_size[PKG2_SEC_INI1] = ini1_size;
|
||||
hdr->sec_off[PKG2_SEC_INI1] = 0x14080000;
|
||||
se_aes_crypt_ctr(8, ini1, ini1_size, ini1, ini1_size, &hdr->sec_ctr[PKG2_SEC_INI1 * 0x10]);
|
||||
DPRINTF("INI1 encrypted\n");
|
||||
|
||||
//Encrypt header.
|
||||
*(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
|
||||
se_aes_crypt_ctr(8, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr);
|
||||
memset(hdr->ctr, 0 , 0x10);
|
||||
*(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
|
||||
}
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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 _PKG2_H_
|
||||
#define _PKG2_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "../utils/list.h"
|
||||
|
||||
#define PKG2_MAGIC 0x31324B50
|
||||
#define PKG2_SEC_BASE 0x80000000
|
||||
#define PKG2_SEC_KERNEL 0
|
||||
#define PKG2_SEC_INI1 1
|
||||
|
||||
#define INI1_MAGIC 0x31494E49
|
||||
|
||||
typedef struct _kernel_patch_t
|
||||
{
|
||||
u32 id;
|
||||
u32 off;
|
||||
u32 val;
|
||||
u32 *ptr;
|
||||
} kernel_patch_t;
|
||||
|
||||
#define KERNEL_PATCHSET_DEF(name, ...) \
|
||||
kernel_patch_t name[] = { \
|
||||
__VA_ARGS__, \
|
||||
{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, (u32 *)0xFFFFFFFF} \
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
// Generic instruction patches
|
||||
SVC_VERIFY_DS = 0x10, // 0x0-0xF are RESERVED.
|
||||
DEBUG_MODE_EN,
|
||||
ATM_GEN_PATCH,
|
||||
// >4 bytes patches. Value is a pointer of a u32 array.
|
||||
ATM_ARR_PATCH,
|
||||
};
|
||||
|
||||
typedef struct _pkg2_hdr_t
|
||||
{
|
||||
u8 ctr[0x10];
|
||||
u8 sec_ctr[0x40];
|
||||
u32 magic;
|
||||
u32 base;
|
||||
u32 pad0;
|
||||
u16 version;
|
||||
u16 pad1;
|
||||
u32 sec_size[4];
|
||||
u32 sec_off[4];
|
||||
u8 sec_sha256[0x80];
|
||||
u8 data[];
|
||||
} pkg2_hdr_t;
|
||||
|
||||
typedef struct _pkg2_ini1_t
|
||||
{
|
||||
u32 magic;
|
||||
u32 size;
|
||||
u32 num_procs;
|
||||
u32 pad;
|
||||
} pkg2_ini1_t;
|
||||
|
||||
typedef struct _pkg2_kip1_sec_t
|
||||
{
|
||||
u32 offset;
|
||||
u32 size_decomp;
|
||||
u32 size_comp;
|
||||
u32 attrib;
|
||||
} pkg2_kip1_sec_t;
|
||||
|
||||
#define KIP1_NUM_SECTIONS 6
|
||||
|
||||
typedef struct _pkg2_kip1_t
|
||||
{
|
||||
u32 magic;
|
||||
u8 name[12];
|
||||
u64 tid;
|
||||
u32 proc_cat;
|
||||
u8 main_thrd_prio;
|
||||
u8 def_cpu_core;
|
||||
u8 res;
|
||||
u8 flags;
|
||||
pkg2_kip1_sec_t sections[KIP1_NUM_SECTIONS];
|
||||
u32 caps[0x20];
|
||||
u8 data[];
|
||||
} pkg2_kip1_t;
|
||||
|
||||
typedef struct _pkg2_kip1_info_t
|
||||
{
|
||||
pkg2_kip1_t *kip1;
|
||||
u32 size;
|
||||
link_t link;
|
||||
} pkg2_kip1_info_t;
|
||||
|
||||
typedef struct _pkg2_kernel_id_t
|
||||
{
|
||||
u32 crc32c_id;
|
||||
kernel_patch_t *kernel_patchset;
|
||||
} pkg2_kernel_id_t;
|
||||
|
||||
typedef struct _kip1_patch_t
|
||||
{
|
||||
u32 offset; //section+offset of patch to apply
|
||||
u32 length; //in bytes, 0 means last patch
|
||||
const char* srcData; //that must match
|
||||
const char* dstData; //that it gets replaced by
|
||||
} kip1_patch_t;
|
||||
|
||||
typedef struct _kip1_patchset_t
|
||||
{
|
||||
const char* name; //NULL means end
|
||||
kip1_patch_t* patches; //NULL means not necessary
|
||||
} kip1_patchset_t;
|
||||
|
||||
typedef struct _kip1_id_t
|
||||
{
|
||||
const char* name;
|
||||
u8 hash[16];
|
||||
kip1_patchset_t* patchset;
|
||||
} kip1_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 char* pkg2_patch_kips(link_t *info, char* patchNames);
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 M4xw
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ianos.h"
|
||||
#include "../utils/types.h"
|
||||
#include "../libs/elfload/elfload.h"
|
||||
#include "../../common/common_module.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../gfx/gfx.h"
|
||||
|
||||
#define IRAM_LIB_ADDR 0x4002B000
|
||||
#define DRAM_LIB_ADDR 0xE0000000
|
||||
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
extern heap_t _heap;
|
||||
|
||||
extern void *sd_file_read(char *path);
|
||||
extern bool sd_mount();
|
||||
extern void sd_unmount();
|
||||
|
||||
void *elfBuf = NULL;
|
||||
void *fileBuf = NULL;
|
||||
|
||||
static void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig)
|
||||
{
|
||||
bdkParams_t bdkParameters = (bdkParams_t)malloc(sizeof(struct _bdkParams_t));
|
||||
bdkParameters->gfxCon = &gfx_con;
|
||||
bdkParameters->gfxCtx = &gfx_ctxt;
|
||||
bdkParameters->memcpy = (memcpy_t)&memcpy;
|
||||
bdkParameters->memset = (memset_t)&memset;
|
||||
bdkParameters->sharedHeap = &_heap;
|
||||
|
||||
entrypoint(moduleConfig, bdkParameters);
|
||||
}
|
||||
|
||||
static void *_ianos_alloc_cb(el_ctx *ctx, Elf_Addr phys, Elf_Addr virt, Elf_Addr size)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)phys;
|
||||
(void)size;
|
||||
return (void *)virt;
|
||||
}
|
||||
|
||||
static bool _ianos_read_cb(el_ctx *ctx, void *dest, size_t numberBytes, size_t offset)
|
||||
{
|
||||
(void)ctx;
|
||||
|
||||
memcpy(dest, fileBuf + offset, numberBytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ianos_print_error(int errorno)
|
||||
{
|
||||
switch (errorno)
|
||||
{
|
||||
case 1:
|
||||
gfx_printf(&gfx_con, "Can't find library!\n");
|
||||
break;
|
||||
case 2:
|
||||
gfx_printf(&gfx_con, "Cant init ELF context!\n");
|
||||
break;
|
||||
case 3:
|
||||
gfx_printf(&gfx_con, "Cant alloc memory!\n");
|
||||
break;
|
||||
case 4:
|
||||
gfx_printf(&gfx_con, "Error loading ELF!\n");
|
||||
break;
|
||||
case 5:
|
||||
gfx_printf(&gfx_con, "Error relcating ELF!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Support shared libraries.
|
||||
int ianos_loader(bool sdmount, char *path, elfType_t type, void *moduleConfig)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
if (sdmount)
|
||||
{
|
||||
if (!sd_mount())
|
||||
{
|
||||
res = 0xFFFF;
|
||||
goto elfLoadFinalOut;
|
||||
}
|
||||
}
|
||||
|
||||
fileBuf = sd_file_read(path);
|
||||
|
||||
if (sdmount)
|
||||
sd_unmount();
|
||||
|
||||
if (!fileBuf)
|
||||
{
|
||||
res = 1;
|
||||
goto elfLoadFinalOut;
|
||||
}
|
||||
|
||||
|
||||
el_ctx ctx;
|
||||
ctx.pread = _ianos_read_cb;
|
||||
|
||||
if (el_init(&ctx))
|
||||
{
|
||||
res = 2;
|
||||
goto elfLoadFinalOut;
|
||||
}
|
||||
|
||||
// Set our relocated library's buffer.
|
||||
switch (type & 0xFFFF)
|
||||
{
|
||||
case EXEC_ELF:
|
||||
case AR64_ELF:
|
||||
elfBuf = (void *)DRAM_LIB_ADDR;
|
||||
sd_unmount();
|
||||
break;
|
||||
default:
|
||||
elfBuf = memalign(ctx.align, ctx.memsz);
|
||||
}
|
||||
|
||||
if (!elfBuf)
|
||||
{
|
||||
res = 3;
|
||||
goto elfLoadFinalOut;
|
||||
}
|
||||
|
||||
// Load and relocate library.
|
||||
ctx.base_load_vaddr = ctx.base_load_paddr = (uintptr_t)elfBuf;
|
||||
if (el_load(&ctx, _ianos_alloc_cb))
|
||||
{
|
||||
res = 4;
|
||||
goto elfFreeOut;
|
||||
}
|
||||
|
||||
if (el_relocate(&ctx))
|
||||
{
|
||||
res = 5;
|
||||
goto elfFreeOut;
|
||||
}
|
||||
|
||||
// Launch.
|
||||
uintptr_t epaddr = ctx.ehdr.e_entry + (uintptr_t)elfBuf;
|
||||
moduleEntrypoint_t ep = (moduleEntrypoint_t)epaddr;
|
||||
|
||||
_ianos_call_ep(ep, moduleConfig);
|
||||
|
||||
elfFreeOut:
|
||||
if ((u32)elfBuf >= 0x90000000 && (u32)elfBuf <= DRAM_LIB_ADDR)
|
||||
free(elfBuf);
|
||||
free(fileBuf);
|
||||
elfBuf = NULL;
|
||||
fileBuf = NULL;
|
||||
|
||||
elfLoadFinalOut:
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 M4xw
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* 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 IANOS_H
|
||||
#define IANOS_H
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DRAM_LIB = 0, // DRAM library.
|
||||
EXEC_ELF = 1, // Executable elf that does not return.
|
||||
DR64_LIB = 2, // AARCH64 DRAM library.
|
||||
AR64_ELF = 3, // Executable elf that does not return.
|
||||
KEEP_IN_RAM = (1 << 31) // Shared library mask.
|
||||
} elfType_t;
|
||||
|
||||
int ianos_loader(bool sdmount, char *path, elfType_t type, void* config);
|
||||
|
||||
#endif
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 rajkosto
|
||||
* Copyright (c) 2018 SciresM
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "blz.h"
|
||||
|
||||
const blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter)
|
||||
{
|
||||
if (compDataLen < sizeof(blz_footer))
|
||||
return NULL;
|
||||
|
||||
const blz_footer *srcFooter = (const blz_footer*)&compData[compDataLen - sizeof(blz_footer)];
|
||||
if (outFooter != NULL)
|
||||
memcpy(outFooter, srcFooter, sizeof(blz_footer)); // Must be a memcpy because no umaligned accesses on ARMv4.
|
||||
|
||||
return srcFooter;
|
||||
}
|
||||
|
||||
// From https://github.com/SciresM/hactool/blob/master/kip.c which is exactly how kernel does it, thanks SciresM!
|
||||
int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer)
|
||||
{
|
||||
u32 addl_size = footer->addl_size;
|
||||
u32 header_size = footer->header_size;
|
||||
u32 cmp_and_hdr_size = footer->cmp_and_hdr_size;
|
||||
|
||||
unsigned char* cmp_start = &dataBuf[compSize] - cmp_and_hdr_size;
|
||||
u32 cmp_ofs = cmp_and_hdr_size - header_size;
|
||||
u32 out_ofs = cmp_and_hdr_size + addl_size;
|
||||
|
||||
while (out_ofs)
|
||||
{
|
||||
unsigned char control = cmp_start[--cmp_ofs];
|
||||
for (unsigned int i=0; i<8; i++)
|
||||
{
|
||||
if (control & 0x80)
|
||||
{
|
||||
if (cmp_ofs < 2)
|
||||
return 0; // Out of bounds.
|
||||
|
||||
cmp_ofs -= 2;
|
||||
u16 seg_val = ((unsigned int)(cmp_start[cmp_ofs + 1]) << 8) | cmp_start[cmp_ofs];
|
||||
u32 seg_size = ((seg_val >> 12) & 0xF) + 3;
|
||||
u32 seg_ofs = (seg_val & 0x0FFF) + 3;
|
||||
if (out_ofs < seg_size) // Kernel restricts segment copy to stay in bounds.
|
||||
seg_size = out_ofs;
|
||||
|
||||
out_ofs -= seg_size;
|
||||
|
||||
for (unsigned int j = 0; j < seg_size; j++)
|
||||
cmp_start[out_ofs + j] = cmp_start[out_ofs + j + seg_ofs];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy directly.
|
||||
if (cmp_ofs < 1)
|
||||
return 0; //out of bounds
|
||||
|
||||
cmp_start[--out_ofs] = cmp_start[--cmp_ofs];
|
||||
}
|
||||
control <<= 1;
|
||||
if (out_ofs == 0) // Blz works backwards, so if it reaches byte 0, it's done.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize)
|
||||
{
|
||||
blz_footer footer;
|
||||
const blz_footer *compFooterPtr = blz_get_footer(compData, compDataLen, &footer);
|
||||
if (compFooterPtr == NULL)
|
||||
return 0;
|
||||
|
||||
// Decompression must be done in-place, so need to copy the relevant compressed data first.
|
||||
unsigned int numCompBytes = (const unsigned char*)(compFooterPtr)-compData;
|
||||
memcpy(dstData, compData, numCompBytes);
|
||||
memset(&dstData[numCompBytes], 0, dstSize - numCompBytes);
|
||||
|
||||
return blz_uncompress_inplace(dstData, compDataLen, &footer);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 rajkosto
|
||||
*
|
||||
* 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 _BLZ_H_
|
||||
#define _BLZ_H_
|
||||
|
||||
#include "../../utils/types.h"
|
||||
|
||||
typedef struct _blz_footer
|
||||
{
|
||||
u32 cmp_and_hdr_size;
|
||||
u32 header_size;
|
||||
u32 addl_size;
|
||||
} blz_footer;
|
||||
|
||||
// Returns pointer to footer in compData if present, additionally copies it to outFooter if not NULL.
|
||||
const blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter);
|
||||
// Returns 0 on failure.
|
||||
int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer);
|
||||
// Returns 0 on failure.
|
||||
int blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize);
|
||||
|
||||
#endif
|
||||
@@ -1,589 +0,0 @@
|
||||
/* $OpenBSD: exec_elf.h,v 1.53 2014/01/03 03:00:39 guenther Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995, 1996 Erik Theisen. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* imported sys/exec_elf.h from OpenBSD */
|
||||
|
||||
#ifndef ELF_H
|
||||
#define ELF_H
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t Elf_Byte;
|
||||
|
||||
typedef uint32_t Elf32_Addr; /* Unsigned program address */
|
||||
typedef uint32_t Elf32_Off; /* Unsigned file offset */
|
||||
typedef int32_t Elf32_Sword; /* Signed large integer */
|
||||
typedef uint32_t Elf32_Word; /* Unsigned large integer */
|
||||
typedef uint16_t Elf32_Half; /* Unsigned medium integer */
|
||||
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint64_t Elf64_Off;
|
||||
typedef int32_t Elf64_Shalf;
|
||||
|
||||
#ifdef __alpha__
|
||||
typedef int64_t Elf64_Sword;
|
||||
typedef uint64_t Elf64_Word;
|
||||
#else
|
||||
typedef int32_t Elf64_Sword;
|
||||
typedef uint32_t Elf64_Word;
|
||||
#endif
|
||||
|
||||
typedef int64_t Elf64_Sxword;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
|
||||
typedef uint32_t Elf64_Half;
|
||||
typedef uint16_t Elf64_Quarter;
|
||||
|
||||
/*
|
||||
* e_ident[] identification indexes
|
||||
* See http://www.sco.com/developers/gabi/latest/ch4.eheader.html
|
||||
*/
|
||||
#define EI_MAG0 0 /* file ID */
|
||||
#define EI_MAG1 1 /* file ID */
|
||||
#define EI_MAG2 2 /* file ID */
|
||||
#define EI_MAG3 3 /* file ID */
|
||||
#define EI_CLASS 4 /* file class */
|
||||
#define EI_DATA 5 /* data encoding */
|
||||
#define EI_VERSION 6 /* ELF header version */
|
||||
#define EI_OSABI 7 /* OS/ABI ID */
|
||||
#define EI_ABIVERSION 8 /* ABI version */
|
||||
#define EI_PAD 9 /* start of pad bytes */
|
||||
#define EI_NIDENT 16 /* Size of e_ident[] */
|
||||
|
||||
/* e_ident[] magic number */
|
||||
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
|
||||
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
|
||||
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
|
||||
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
|
||||
#define ELFMAG "\177ELF" /* magic */
|
||||
#define SELFMAG 4 /* size of magic */
|
||||
|
||||
/* e_ident[] file class */
|
||||
#define ELFCLASSNONE 0 /* invalid */
|
||||
#define ELFCLASS32 1 /* 32-bit objs */
|
||||
#define ELFCLASS64 2 /* 64-bit objs */
|
||||
#define ELFCLASSNUM 3 /* number of classes */
|
||||
|
||||
/* e_ident[] data encoding */
|
||||
#define ELFDATANONE 0 /* invalid */
|
||||
#define ELFDATA2LSB 1 /* Little-Endian */
|
||||
#define ELFDATA2MSB 2 /* Big-Endian */
|
||||
#define ELFDATANUM 3 /* number of data encode defines */
|
||||
|
||||
/* e_ident[] Operating System/ABI */
|
||||
#define ELFOSABI_SYSV 0 /* UNIX System V ABI */
|
||||
#define ELFOSABI_HPUX 1 /* HP-UX operating system */
|
||||
#define ELFOSABI_NETBSD 2 /* NetBSD */
|
||||
#define ELFOSABI_LINUX 3 /* GNU/Linux */
|
||||
#define ELFOSABI_HURD 4 /* GNU/Hurd */
|
||||
#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
|
||||
#define ELFOSABI_SOLARIS 6 /* Solaris */
|
||||
#define ELFOSABI_MONTEREY 7 /* Monterey */
|
||||
#define ELFOSABI_IRIX 8 /* IRIX */
|
||||
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
|
||||
#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
|
||||
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
|
||||
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
|
||||
#define ELFOSABI_ARM 97 /* ARM */
|
||||
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
|
||||
|
||||
/* e_ident */
|
||||
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
|
||||
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
|
||||
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
|
||||
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
|
||||
|
||||
/* ELF Header */
|
||||
typedef struct
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT]; /* ELF Identification */
|
||||
Elf32_Half e_type; /* object file type */
|
||||
Elf32_Half e_machine; /* machine */
|
||||
Elf32_Word e_version; /* object file version */
|
||||
Elf32_Addr e_entry; /* virtual entry point */
|
||||
Elf32_Off e_phoff; /* program header table offset */
|
||||
Elf32_Off e_shoff; /* section header table offset */
|
||||
Elf32_Word e_flags; /* processor-specific flags */
|
||||
Elf32_Half e_ehsize; /* ELF header size */
|
||||
Elf32_Half e_phentsize; /* program header entry size */
|
||||
Elf32_Half e_phnum; /* number of program header entries */
|
||||
Elf32_Half e_shentsize; /* section header entry size */
|
||||
Elf32_Half e_shnum; /* number of section header entries */
|
||||
Elf32_Half e_shstrndx; /* section header table's "section
|
||||
header string table" entry offset */
|
||||
} Elf32_Ehdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT]; /* Id bytes */
|
||||
Elf64_Quarter e_type; /* file type */
|
||||
Elf64_Quarter e_machine; /* machine type */
|
||||
Elf64_Half e_version; /* version number */
|
||||
Elf64_Addr e_entry; /* entry point */
|
||||
Elf64_Off e_phoff; /* Program hdr offset */
|
||||
Elf64_Off e_shoff; /* Section hdr offset */
|
||||
Elf64_Half e_flags; /* Processor flags */
|
||||
Elf64_Quarter e_ehsize; /* sizeof ehdr */
|
||||
Elf64_Quarter e_phentsize; /* Program header entry size */
|
||||
Elf64_Quarter e_phnum; /* Number of program headers */
|
||||
Elf64_Quarter e_shentsize; /* Section header entry size */
|
||||
Elf64_Quarter e_shnum; /* Number of section headers */
|
||||
Elf64_Quarter e_shstrndx; /* String table index */
|
||||
} Elf64_Ehdr;
|
||||
|
||||
/* e_type */
|
||||
#define ET_NONE 0 /* No file type */
|
||||
#define ET_REL 1 /* relocatable file */
|
||||
#define ET_EXEC 2 /* executable file */
|
||||
#define ET_DYN 3 /* shared object file */
|
||||
#define ET_CORE 4 /* core file */
|
||||
#define ET_NUM 5 /* number of types */
|
||||
#define ET_LOPROC 0xff00 /* reserved range for processor */
|
||||
#define ET_HIPROC 0xffff /* specific e_type */
|
||||
|
||||
/* e_machine */
|
||||
#define EM_NONE 0 /* No Machine */
|
||||
#define EM_M32 1 /* AT&T WE 32100 */
|
||||
#define EM_SPARC 2 /* SPARC */
|
||||
#define EM_386 3 /* Intel 80386 */
|
||||
#define EM_68K 4 /* Motorola 68000 */
|
||||
#define EM_88K 5 /* Motorola 88000 */
|
||||
#define EM_486 6 /* Intel 80486 - unused? */
|
||||
#define EM_860 7 /* Intel 80860 */
|
||||
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
|
||||
/*
|
||||
* Don't know if EM_MIPS_RS4_BE,
|
||||
* EM_SPARC64, EM_PARISC,
|
||||
* or EM_PPC are ABI compliant
|
||||
*/
|
||||
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
|
||||
#define EM_SPARC64 11 /* SPARC v9 64-bit unofficial */
|
||||
#define EM_PARISC 15 /* HPPA */
|
||||
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
|
||||
#define EM_PPC 20 /* PowerPC */
|
||||
#define EM_ARM 40 /* ARM AArch32 */
|
||||
#define EM_ALPHA 41 /* DEC ALPHA */
|
||||
#define EM_SH 42 /* Hitachi/Renesas Super-H */
|
||||
#define EM_SPARCV9 43 /* SPARC version 9 */
|
||||
#define EM_IA_64 50 /* Intel IA-64 Processor */
|
||||
#define EM_AMD64 62 /* AMD64 architecture */
|
||||
#define EM_VAX 75 /* DEC VAX */
|
||||
#define EM_AARCH64 183 /* ARM AArch64 */
|
||||
|
||||
/* Non-standard */
|
||||
#define EM_ALPHA_EXP 0x9026 /* DEC ALPHA */
|
||||
|
||||
/* Version */
|
||||
#define EV_NONE 0 /* Invalid */
|
||||
#define EV_CURRENT 1 /* Current */
|
||||
#define EV_NUM 2 /* number of versions */
|
||||
|
||||
/* Section Header */
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word sh_name; /* name - index into section header
|
||||
* string table section */
|
||||
Elf32_Word sh_type; /* type */
|
||||
Elf32_Word sh_flags; /* flags */
|
||||
Elf32_Addr sh_addr; /* address */
|
||||
Elf32_Off sh_offset; /* file offset */
|
||||
Elf32_Word sh_size; /* section size */
|
||||
Elf32_Word sh_link; /* section header table index link */
|
||||
Elf32_Word sh_info; /* extra information */
|
||||
Elf32_Word sh_addralign; /* address alignment */
|
||||
Elf32_Word sh_entsize; /* section entry size */
|
||||
} Elf32_Shdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half sh_name; /* section name */
|
||||
Elf64_Half sh_type; /* section type */
|
||||
Elf64_Xword sh_flags; /* section flags */
|
||||
Elf64_Addr sh_addr; /* virtual address */
|
||||
Elf64_Off sh_offset; /* file offset */
|
||||
Elf64_Xword sh_size; /* section size */
|
||||
Elf64_Half sh_link; /* link to another */
|
||||
Elf64_Half sh_info; /* misc info */
|
||||
Elf64_Xword sh_addralign; /* memory alignment */
|
||||
Elf64_Xword sh_entsize; /* table entry size */
|
||||
} Elf64_Shdr;
|
||||
|
||||
/* Special Section Indexes */
|
||||
#define SHN_UNDEF 0 /* undefined */
|
||||
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
|
||||
#define SHN_LOPROC 0xff00 /* reserved range for processor */
|
||||
#define SHN_HIPROC 0xff1f /* specific section indexes */
|
||||
#define SHN_ABS 0xfff1 /* absolute value */
|
||||
#define SHN_COMMON 0xfff2 /* common symbol */
|
||||
#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */
|
||||
|
||||
/* sh_type */
|
||||
#define SHT_NULL 0 /* inactive */
|
||||
#define SHT_PROGBITS 1 /* program defined information */
|
||||
#define SHT_SYMTAB 2 /* symbol table section */
|
||||
#define SHT_STRTAB 3 /* string table section */
|
||||
#define SHT_RELA 4 /* relocation section with addends*/
|
||||
#define SHT_HASH 5 /* symbol hash table section */
|
||||
#define SHT_DYNAMIC 6 /* dynamic section */
|
||||
#define SHT_NOTE 7 /* note section */
|
||||
#define SHT_NOBITS 8 /* no space section */
|
||||
#define SHT_REL 9 /* relation section without addends */
|
||||
#define SHT_SHLIB 10 /* reserved - purpose unknown */
|
||||
#define SHT_DYNSYM 11 /* dynamic symbol table section */
|
||||
#define SHT_NUM 12 /* number of section types */
|
||||
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define SHT_HIPROC 0x7fffffff /* specific section header types */
|
||||
#define SHT_LOUSER 0x80000000 /* reserved range for application */
|
||||
#define SHT_HIUSER 0xffffffff /* specific indexes */
|
||||
|
||||
/* Section names */
|
||||
#define ELF_BSS ".bss" /* uninitialized data */
|
||||
#define ELF_DATA ".data" /* initialized data */
|
||||
#define ELF_DEBUG ".debug" /* debug */
|
||||
#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
|
||||
#define ELF_DYNSTR ".dynstr" /* dynamic string table */
|
||||
#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
|
||||
#define ELF_FINI ".fini" /* termination code */
|
||||
#define ELF_GOT ".got" /* global offset table */
|
||||
#define ELF_HASH ".hash" /* symbol hash table */
|
||||
#define ELF_INIT ".init" /* initialization code */
|
||||
#define ELF_REL_DATA ".rel.data" /* relocation data */
|
||||
#define ELF_REL_FINI ".rel.fini" /* relocation termination code */
|
||||
#define ELF_REL_INIT ".rel.init" /* relocation initialization code */
|
||||
#define ELF_REL_DYN ".rel.dyn" /* relocation dynamic link info */
|
||||
#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
|
||||
#define ELF_REL_TEXT ".rel.text" /* relocation code */
|
||||
#define ELF_RODATA ".rodata" /* read-only data */
|
||||
#define ELF_SHSTRTAB ".shstrtab" /* section header string table */
|
||||
#define ELF_STRTAB ".strtab" /* string table */
|
||||
#define ELF_SYMTAB ".symtab" /* symbol table */
|
||||
#define ELF_TEXT ".text" /* code */
|
||||
|
||||
/* Section Attribute Flags - sh_flags */
|
||||
#define SHF_WRITE 0x1 /* Writable */
|
||||
#define SHF_ALLOC 0x2 /* occupies memory */
|
||||
#define SHF_EXECINSTR 0x4 /* executable */
|
||||
#define SHF_TLS 0x400 /* thread local storage */
|
||||
#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor \
|
||||
* specific section attributes */
|
||||
|
||||
/* Symbol Table Entry */
|
||||
typedef struct elf32_sym
|
||||
{
|
||||
Elf32_Word st_name; /* name - index into string table */
|
||||
Elf32_Addr st_value; /* symbol value */
|
||||
Elf32_Word st_size; /* symbol size */
|
||||
unsigned char st_info; /* type and binding */
|
||||
unsigned char st_other; /* 0 - no defined meaning */
|
||||
Elf32_Half st_shndx; /* section header index */
|
||||
} Elf32_Sym;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half st_name; /* Symbol name index in str table */
|
||||
Elf_Byte st_info; /* type / binding attrs */
|
||||
Elf_Byte st_other; /* unused */
|
||||
Elf64_Quarter st_shndx; /* section index of symbol */
|
||||
Elf64_Xword st_value; /* value of symbol */
|
||||
Elf64_Xword st_size; /* size of symbol */
|
||||
} Elf64_Sym;
|
||||
|
||||
/* Symbol table index */
|
||||
#define STN_UNDEF 0 /* undefined */
|
||||
|
||||
/* Extract symbol info - st_info */
|
||||
#define ELF32_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF32_ST_TYPE(x) (((unsigned int)x) & 0xf)
|
||||
#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t)&0xf))
|
||||
|
||||
#define ELF64_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF64_ST_TYPE(x) (((unsigned int)x) & 0xf)
|
||||
#define ELF64_ST_INFO(b, t) (((b) << 4) + ((t)&0xf))
|
||||
|
||||
/* Symbol Binding - ELF32_ST_BIND - st_info */
|
||||
#define STB_LOCAL 0 /* Local symbol */
|
||||
#define STB_GLOBAL 1 /* Global symbol */
|
||||
#define STB_WEAK 2 /* like global - lower precedence */
|
||||
#define STB_NUM 3 /* number of symbol bindings */
|
||||
#define STB_LOPROC 13 /* reserved range for processor */
|
||||
#define STB_HIPROC 15 /* specific symbol bindings */
|
||||
|
||||
/* Symbol type - ELF32_ST_TYPE - st_info */
|
||||
#define STT_NOTYPE 0 /* not specified */
|
||||
#define STT_OBJECT 1 /* data object */
|
||||
#define STT_FUNC 2 /* function */
|
||||
#define STT_SECTION 3 /* section */
|
||||
#define STT_FILE 4 /* file */
|
||||
#define STT_TLS 6 /* thread local storage */
|
||||
#define STT_LOPROC 13 /* reserved range for processor */
|
||||
#define STT_HIPROC 15 /* specific symbol types */
|
||||
|
||||
/* Relocation entry with implicit addend */
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Addr r_offset; /* offset of relocation */
|
||||
Elf32_Word r_info; /* symbol table index and type */
|
||||
} Elf32_Rel;
|
||||
|
||||
/* Relocation entry with explicit addend */
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Addr r_offset; /* offset of relocation */
|
||||
Elf32_Word r_info; /* symbol table index and type */
|
||||
Elf32_Sword r_addend;
|
||||
} Elf32_Rela;
|
||||
|
||||
/* Extract relocation info - r_info */
|
||||
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||
#define ELF32_R_TYPE(i) ((unsigned char)(i))
|
||||
#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Xword r_offset; /* where to do it */
|
||||
Elf64_Xword r_info; /* index & type of relocation */
|
||||
} Elf64_Rel;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Xword r_offset; /* where to do it */
|
||||
Elf64_Xword r_info; /* index & type of relocation */
|
||||
Elf64_Sxword r_addend; /* adjustment value */
|
||||
} Elf64_Rela;
|
||||
|
||||
#define ELF64_R_SYM(info) ((info) >> 32)
|
||||
#define ELF64_R_TYPE(info) ((info)&0xFFFFFFFF)
|
||||
#define ELF64_R_INFO(s, t) (((s) << 32) + (__uint32_t)(t))
|
||||
|
||||
#if defined(__mips64__) && defined(__MIPSEL__)
|
||||
/*
|
||||
* The 64-bit MIPS ELF ABI uses a slightly different relocation format
|
||||
* than the regular ELF ABI: the r_info field is split into several
|
||||
* pieces (see gnu/usr.bin/binutils/include/elf/mips.h for details).
|
||||
*/
|
||||
#undef ELF64_R_SYM
|
||||
#undef ELF64_R_TYPE
|
||||
#undef ELF64_R_INFO
|
||||
#define ELF64_R_TYPE(info) (swap32((info) >> 32))
|
||||
#define ELF64_R_SYM(info) ((info)&0xFFFFFFFF)
|
||||
#define ELF64_R_INFO(s, t) (((__uint64_t)swap32(t) << 32) + (__uint32_t)(s))
|
||||
#endif /* __mips64__ && __MIPSEL__ */
|
||||
|
||||
/* Program Header */
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word p_type; /* segment type */
|
||||
Elf32_Off p_offset; /* segment offset */
|
||||
Elf32_Addr p_vaddr; /* virtual address of segment */
|
||||
Elf32_Addr p_paddr; /* physical address - ignored? */
|
||||
Elf32_Word p_filesz; /* number of bytes in file for seg. */
|
||||
Elf32_Word p_memsz; /* number of bytes in mem. for seg. */
|
||||
Elf32_Word p_flags; /* flags */
|
||||
Elf32_Word p_align; /* memory alignment */
|
||||
} Elf32_Phdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half p_type; /* entry type */
|
||||
Elf64_Half p_flags; /* flags */
|
||||
Elf64_Off p_offset; /* offset */
|
||||
Elf64_Addr p_vaddr; /* virtual address */
|
||||
Elf64_Addr p_paddr; /* physical address */
|
||||
Elf64_Xword p_filesz; /* file size */
|
||||
Elf64_Xword p_memsz; /* memory size */
|
||||
Elf64_Xword p_align; /* memory & file alignment */
|
||||
} Elf64_Phdr;
|
||||
|
||||
/* Segment types - p_type */
|
||||
#define PT_NULL 0 /* unused */
|
||||
#define PT_LOAD 1 /* loadable segment */
|
||||
#define PT_DYNAMIC 2 /* dynamic linking section */
|
||||
#define PT_INTERP 3 /* the RTLD */
|
||||
#define PT_NOTE 4 /* auxiliary information */
|
||||
#define PT_SHLIB 5 /* reserved - purpose undefined */
|
||||
#define PT_PHDR 6 /* program header */
|
||||
#define PT_TLS 7 /* thread local storage */
|
||||
#define PT_LOOS 0x60000000 /* reserved range for OS */
|
||||
#define PT_HIOS 0x6fffffff /* specific segment types */
|
||||
#define PT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define PT_HIPROC 0x7fffffff /* specific segment types */
|
||||
|
||||
#define PT_OPENBSD_RANDOMIZE 0x65a3dbe6 /* fill with random data */
|
||||
#define PT_GANDR_KERNEL 0x67646b6c /* gdkl */
|
||||
|
||||
/* Segment flags - p_flags */
|
||||
#define PF_X 0x1 /* Executable */
|
||||
#define PF_W 0x2 /* Writable */
|
||||
#define PF_R 0x4 /* Readable */
|
||||
#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */
|
||||
/* specific segment flags */
|
||||
|
||||
/* Dynamic structure */
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Sword d_tag; /* controls meaning of d_val */
|
||||
union {
|
||||
Elf32_Word d_val; /* Multiple meanings - see d_tag */
|
||||
Elf32_Addr d_ptr; /* program virtual address */
|
||||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Xword d_tag; /* controls meaning of d_val */
|
||||
union {
|
||||
Elf64_Addr d_ptr;
|
||||
Elf64_Xword d_val;
|
||||
} d_un;
|
||||
} Elf64_Dyn;
|
||||
|
||||
/* Dynamic Array Tags - d_tag */
|
||||
#define DT_NULL 0 /* marks end of _DYNAMIC array */
|
||||
#define DT_NEEDED 1 /* string table offset of needed lib */
|
||||
#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */
|
||||
#define DT_PLTGOT 3 /* address PLT/GOT */
|
||||
#define DT_HASH 4 /* address of symbol hash table */
|
||||
#define DT_STRTAB 5 /* address of string table */
|
||||
#define DT_SYMTAB 6 /* address of symbol table */
|
||||
#define DT_RELA 7 /* address of relocation table */
|
||||
#define DT_RELASZ 8 /* size of relocation table */
|
||||
#define DT_RELAENT 9 /* size of relocation entry */
|
||||
#define DT_STRSZ 10 /* size of string table */
|
||||
#define DT_SYMENT 11 /* size of symbol table entry */
|
||||
#define DT_INIT 12 /* address of initialization func. */
|
||||
#define DT_FINI 13 /* address of termination function */
|
||||
#define DT_SONAME 14 /* string table offset of shared obj */
|
||||
#define DT_RPATH 15 /* string table offset of library \
|
||||
* search path */
|
||||
#define DT_SYMBOLIC 16 /* start sym search in shared obj. */
|
||||
#define DT_REL 17 /* address of rel. tbl. w addends */
|
||||
#define DT_RELSZ 18 /* size of DT_REL relocation table */
|
||||
#define DT_RELENT 19 /* size of DT_REL relocation entry */
|
||||
#define DT_PLTREL 20 /* PLT referenced relocation entry */
|
||||
#define DT_DEBUG 21 /* bugger */
|
||||
#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */
|
||||
#define DT_JMPREL 23 /* add. of PLT's relocation entries */
|
||||
#define DT_BIND_NOW 24 /* Bind now regardless of env setting */
|
||||
#define DT_LOOS 0x6000000d /* reserved range for OS */
|
||||
#define DT_HIOS 0x6ffff000 /* specific dynamic array tags */
|
||||
#define DT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */
|
||||
|
||||
/* some other useful tags */
|
||||
#define DT_RELACOUNT 0x6ffffff9 /* if present, number of RELATIVE */
|
||||
#define DT_RELCOUNT 0x6ffffffa /* relocs, which must come first */
|
||||
#define DT_FLAGS_1 0x6ffffffb
|
||||
|
||||
/* Dynamic Flags - DT_FLAGS_1 .dynamic entry */
|
||||
#define DF_1_NOW 0x00000001
|
||||
#define DF_1_GLOBAL 0x00000002
|
||||
#define DF_1_GROUP 0x00000004
|
||||
#define DF_1_NODELETE 0x00000008
|
||||
#define DF_1_LOADFLTR 0x00000010
|
||||
#define DF_1_INITFIRST 0x00000020
|
||||
#define DF_1_NOOPEN 0x00000040
|
||||
#define DF_1_ORIGIN 0x00000080
|
||||
#define DF_1_DIRECT 0x00000100
|
||||
#define DF_1_TRANS 0x00000200
|
||||
#define DF_1_INTERPOSE 0x00000400
|
||||
#define DF_1_NODEFLIB 0x00000800
|
||||
#define DF_1_NODUMP 0x00001000
|
||||
#define DF_1_CONLFAT 0x00002000
|
||||
|
||||
/* ld.so: number of low tags that are used saved internally (0 .. DT_NUM-1) */
|
||||
#define DT_NUM (DT_JMPREL + 1)
|
||||
|
||||
/*
|
||||
* Note Definitions
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word namesz;
|
||||
Elf32_Word descsz;
|
||||
Elf32_Word type;
|
||||
} Elf32_Note;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half namesz;
|
||||
Elf64_Half descsz;
|
||||
Elf64_Half type;
|
||||
} Elf64_Note;
|
||||
|
||||
#if defined(ELFSIZE) && (ELFSIZE == 32)
|
||||
#define Elf_Ehdr Elf32_Ehdr
|
||||
#define Elf_Phdr Elf32_Phdr
|
||||
#define Elf_Shdr Elf32_Shdr
|
||||
#define Elf_Sym Elf32_Sym
|
||||
#define Elf_Rel Elf32_Rel
|
||||
#define Elf_RelA Elf32_Rela
|
||||
#define Elf_Dyn Elf32_Dyn
|
||||
#define Elf_Half Elf32_Half
|
||||
#define Elf_Word Elf32_Word
|
||||
#define Elf_Sword Elf32_Sword
|
||||
#define Elf_Addr Elf32_Addr
|
||||
#define Elf_Off Elf32_Off
|
||||
#define Elf_Nhdr Elf32_Nhdr
|
||||
#define Elf_Note Elf32_Note
|
||||
|
||||
#define ELF_R_SYM ELF32_R_SYM
|
||||
#define ELF_R_TYPE ELF32_R_TYPE
|
||||
#define ELF_R_INFO ELF32_R_INFO
|
||||
#define ELFCLASS ELFCLASS32
|
||||
|
||||
#define ELF_ST_BIND ELF32_ST_BIND
|
||||
#define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
#define ELF_ST_INFO ELF32_ST_INFO
|
||||
|
||||
#elif defined(ELFSIZE) && (ELFSIZE == 64)
|
||||
|
||||
#define Elf_Ehdr Elf64_Ehdr
|
||||
#define Elf_Phdr Elf64_Phdr
|
||||
#define Elf_Shdr Elf64_Shdr
|
||||
#define Elf_Sym Elf64_Sym
|
||||
#define Elf_Rel Elf64_Rel
|
||||
#define Elf_RelA Elf64_Rela
|
||||
#define Elf_Dyn Elf64_Dyn
|
||||
#define Elf_Half Elf64_Half
|
||||
#define Elf_Word Elf64_Word
|
||||
#define Elf_Sword Elf64_Sword
|
||||
#define Elf_Addr Elf64_Addr
|
||||
#define Elf_Off Elf64_Off
|
||||
#define Elf_Nhdr Elf64_Nhdr
|
||||
#define Elf_Note Elf64_Note
|
||||
|
||||
#define ELF_R_SYM ELF64_R_SYM
|
||||
#define ELF_R_TYPE ELF64_R_TYPE
|
||||
#define ELF_R_INFO ELF64_R_INFO
|
||||
#define ELFCLASS ELFCLASS64
|
||||
|
||||
#define ELF_ST_BIND ELF64_ST_BIND
|
||||
#define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
#define ELF_ST_INFO ELF64_ST_INFO
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2014, Owen Shepherd
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ELFARCH_H
|
||||
#define ELFARCH_H
|
||||
|
||||
#if defined(__i386__)
|
||||
#define EM_THIS EM_386
|
||||
#define EL_ARCH_USES_REL
|
||||
#elif defined(__amd64__)
|
||||
#define EM_THIS EM_AMD64
|
||||
#define EL_ARCH_USES_RELA
|
||||
#elif defined(__arm__)
|
||||
#define EM_THIS EM_ARM
|
||||
#define EL_ARCH_USES_REL
|
||||
#elif defined(__aarch64__)
|
||||
#define EM_THIS EM_AARCH64
|
||||
#define EL_ARCH_USES_RELA
|
||||
#define EL_ARCH_USES_REL
|
||||
#else
|
||||
#error specify your ELF architecture
|
||||
#endif
|
||||
|
||||
#if defined(__LP64__) || defined(__LLP64__)
|
||||
#define ELFSIZE 64
|
||||
#else
|
||||
#define ELFSIZE 32
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define ELFDATATHIS ELFDATA2LSB
|
||||
#else
|
||||
#define ELFDATATHIS ELFDATA2MSB
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,324 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2018, M4xw
|
||||
* Copyright © 2014, Owen Shepherd
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "elfload.h"
|
||||
|
||||
el_status el_pread(el_ctx *ctx, void *def, size_t nb, size_t offset)
|
||||
{
|
||||
return ctx->pread(ctx, def, nb, offset) ? EL_OK : EL_EIO;
|
||||
}
|
||||
|
||||
#define EL_PHOFF(ctx, num) (((ctx)->ehdr.e_phoff + (num) *(ctx)->ehdr.e_phentsize))
|
||||
el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i)
|
||||
{
|
||||
el_status rv = EL_OK;
|
||||
for (; *i < ctx->ehdr.e_phnum; (*i)++)
|
||||
{
|
||||
if ((rv = el_pread(ctx, phdr, sizeof *phdr, EL_PHOFF(ctx, *i))))
|
||||
return rv;
|
||||
|
||||
if (phdr->p_type == type)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
*i = -1;
|
||||
return rv;
|
||||
}
|
||||
|
||||
#define EL_SHOFF(ctx, num) (((ctx)->ehdr.e_shoff + (num) *(ctx)->ehdr.e_shentsize))
|
||||
el_status el_findshdr(el_ctx *ctx, Elf_Shdr *shdr, uint32_t type, unsigned *i)
|
||||
{
|
||||
el_status rv = EL_OK;
|
||||
|
||||
for (; *i < ctx->ehdr.e_shnum; (*i)++)
|
||||
{
|
||||
if ((rv = el_pread(ctx, shdr, sizeof *shdr, EL_SHOFF(ctx, *i))))
|
||||
|
||||
return rv;
|
||||
|
||||
if (shdr->sh_type == type)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
*i = -1;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
el_status el_init(el_ctx *ctx)
|
||||
{
|
||||
el_status rv = EL_OK;
|
||||
if ((rv = el_pread(ctx, &ctx->ehdr, sizeof ctx->ehdr, 0)))
|
||||
return rv;
|
||||
|
||||
/* validate header */
|
||||
|
||||
if (!IS_ELF(ctx->ehdr))
|
||||
return EL_NOTELF;
|
||||
|
||||
if (ctx->ehdr.e_ident[EI_CLASS] != ELFCLASS)
|
||||
return EL_WRONGBITS;
|
||||
|
||||
if (ctx->ehdr.e_ident[EI_DATA] != ELFDATATHIS)
|
||||
return EL_WRONGENDIAN;
|
||||
|
||||
if (ctx->ehdr.e_ident[EI_VERSION] != EV_CURRENT)
|
||||
return EL_NOTELF;
|
||||
|
||||
if (ctx->ehdr.e_type != ET_EXEC && ctx->ehdr.e_type != ET_DYN)
|
||||
return EL_NOTEXEC;
|
||||
|
||||
if (ctx->ehdr.e_machine != EM_THIS)
|
||||
return EL_WRONGARCH;
|
||||
|
||||
if (ctx->ehdr.e_version != EV_CURRENT)
|
||||
return EL_NOTELF;
|
||||
|
||||
/* load phdrs */
|
||||
Elf_Phdr ph;
|
||||
|
||||
/* iterate through, calculate extents */
|
||||
ctx->base_load_paddr = ctx->base_load_vaddr = 0;
|
||||
ctx->align = 1;
|
||||
ctx->memsz = 0;
|
||||
|
||||
unsigned i = 0;
|
||||
for (;;)
|
||||
{
|
||||
if ((rv = el_findphdr(ctx, &ph, PT_LOAD, &i)))
|
||||
return rv;
|
||||
|
||||
if (i == (unsigned)-1)
|
||||
break;
|
||||
|
||||
Elf_Addr phend = ph.p_vaddr + ph.p_memsz;
|
||||
if (phend > ctx->memsz)
|
||||
ctx->memsz = phend;
|
||||
|
||||
if (ph.p_align > ctx->align)
|
||||
ctx->align = ph.p_align;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
// Program Header
|
||||
if (ctx->ehdr.e_type == ET_DYN)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
if ((rv = el_findphdr(ctx, &ph, PT_DYNAMIC, &i)))
|
||||
return rv;
|
||||
|
||||
if (i == (unsigned)-1)
|
||||
return EL_NODYN;
|
||||
|
||||
ctx->dynoff = ph.p_offset;
|
||||
ctx->dynsize = ph.p_filesz;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->dynoff = 0;
|
||||
ctx->dynsize = 0;
|
||||
}
|
||||
|
||||
// Section String Table
|
||||
if (ctx->ehdr.e_type == ET_DYN)
|
||||
{
|
||||
i = ctx->ehdr.e_shstrndx - 1;
|
||||
|
||||
if ((rv = el_findshdr(ctx, &ctx->shstr, SHT_STRTAB, &i)))
|
||||
return rv;
|
||||
|
||||
// Reset
|
||||
i = 0;
|
||||
|
||||
if ((rv = el_findshdr(ctx, &ctx->symtab, SHT_SYMTAB, &i)))
|
||||
return rv;
|
||||
|
||||
if (i == (unsigned)-1)
|
||||
return EL_NODYN;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
typedef void* (*el_alloc_cb)(
|
||||
el_ctx *ctx,
|
||||
Elf_Addr phys,
|
||||
Elf_Addr virt,
|
||||
Elf_Addr size);
|
||||
*/
|
||||
|
||||
el_status el_load(el_ctx *ctx, el_alloc_cb alloc)
|
||||
{
|
||||
el_status rv = EL_OK;
|
||||
|
||||
/* address deltas */
|
||||
Elf_Addr pdelta = ctx->base_load_paddr;
|
||||
Elf_Addr vdelta = ctx->base_load_vaddr;
|
||||
|
||||
/* iterate paddrs */
|
||||
Elf_Phdr ph;
|
||||
unsigned i = 0;
|
||||
for (;;)
|
||||
{
|
||||
if ((rv = el_findphdr(ctx, &ph, PT_LOAD, &i)))
|
||||
return rv;
|
||||
|
||||
if (i == (unsigned)-1)
|
||||
break;
|
||||
|
||||
Elf_Addr pload = ph.p_paddr + pdelta;
|
||||
Elf_Addr vload = ph.p_vaddr + vdelta;
|
||||
|
||||
/* allocate mem */
|
||||
char *dest = alloc(ctx, pload, vload, ph.p_memsz);
|
||||
if (!dest)
|
||||
return EL_ENOMEM;
|
||||
|
||||
EL_DEBUG("Loading seg fileoff %x, vaddr %x to %p\n",
|
||||
ph.p_offset, ph.p_vaddr, dest);
|
||||
|
||||
/* read loaded portion */
|
||||
if ((rv = el_pread(ctx, dest, ph.p_filesz, ph.p_offset)))
|
||||
return rv;
|
||||
|
||||
/* zero mem-only portion */
|
||||
memset(dest + ph.p_filesz, 0, ph.p_memsz - ph.p_filesz);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t tag)
|
||||
{
|
||||
el_status rv = EL_OK;
|
||||
size_t ndyn = ctx->dynsize / sizeof(Elf_Dyn);
|
||||
|
||||
for (unsigned i = 0; i < ndyn; i++)
|
||||
{
|
||||
if ((rv = el_pread(ctx, dyn, sizeof *dyn, ctx->dynoff + i * sizeof *dyn)))
|
||||
return rv;
|
||||
|
||||
if (dyn->d_tag == tag)
|
||||
return EL_OK;
|
||||
}
|
||||
|
||||
dyn->d_tag = DT_NULL;
|
||||
return EL_OK;
|
||||
}
|
||||
|
||||
el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type)
|
||||
{
|
||||
el_status rv = EL_OK;
|
||||
|
||||
Elf_Dyn rel, relsz, relent;
|
||||
|
||||
if ((rv = el_finddyn(ctx, &rel, type)))
|
||||
return rv;
|
||||
|
||||
if ((rv = el_finddyn(ctx, &relsz, type + 1)))
|
||||
return rv;
|
||||
|
||||
if ((rv = el_finddyn(ctx, &relent, type + 2)))
|
||||
return rv;
|
||||
|
||||
if (rel.d_tag == DT_NULL || relsz.d_tag == DT_NULL || relent.d_tag == DT_NULL)
|
||||
{
|
||||
ri->entrysize = 0;
|
||||
ri->tablesize = 0;
|
||||
ri->tableoff = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ri->tableoff = rel.d_un.d_ptr;
|
||||
ri->tablesize = relsz.d_un.d_val;
|
||||
ri->entrysize = relent.d_un.d_val;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
extern el_status el_applyrel(el_ctx *ctx, Elf_Rel *rel);
|
||||
extern el_status el_applyrela(el_ctx *ctx, Elf_RelA *rela);
|
||||
|
||||
el_status el_relocate(el_ctx *ctx)
|
||||
{
|
||||
el_status rv = EL_OK;
|
||||
|
||||
// not dynamic
|
||||
if (ctx->ehdr.e_type != ET_DYN)
|
||||
return EL_OK;
|
||||
|
||||
char *base = (char *)ctx->base_load_paddr;
|
||||
|
||||
el_relocinfo ri;
|
||||
#ifdef EL_ARCH_USES_REL
|
||||
if ((rv = el_findrelocs(ctx, &ri, DT_REL)))
|
||||
return rv;
|
||||
|
||||
if (ri.entrysize != sizeof(Elf_Rel) && ri.tablesize)
|
||||
{
|
||||
EL_DEBUG("Relocation size %u doesn't match expected %u\n",
|
||||
ri.entrysize, sizeof(Elf_Rel));
|
||||
return EL_BADREL;
|
||||
}
|
||||
|
||||
size_t relcnt = ri.tablesize / sizeof(Elf_Rel);
|
||||
Elf_Rel *reltab = (Elf_Rel *)(base + ri.tableoff);
|
||||
for (size_t i = 0; i < relcnt; i++)
|
||||
{
|
||||
if ((rv = el_applyrel(ctx, &reltab[i])))
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EL_ARCH_USES_RELA
|
||||
if ((rv = el_findrelocs(ctx, &ri, DT_RELA)))
|
||||
return rv;
|
||||
|
||||
if (ri.entrysize != sizeof(Elf_RelA) && ri.tablesize)
|
||||
{
|
||||
EL_DEBUG("Relocation size %u doesn't match expected %u\n",
|
||||
ri.entrysize, sizeof(Elf_RelA));
|
||||
return EL_BADREL;
|
||||
}
|
||||
|
||||
size_t relacnt = ri.tablesize / sizeof(Elf_RelA);
|
||||
Elf_RelA *relatab = (Elf_RelA *)(base + ri.tableoff);
|
||||
for (size_t i = 0; i < relacnt; i++)
|
||||
{
|
||||
if ((rv = el_applyrela(ctx, &relatab[i])))
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(EL_ARCH_USES_REL) && !defined(EL_ARCH_USES_RELA)
|
||||
#error No relocation type defined!
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2018, M4xw
|
||||
* Copyright © 2014, Owen Shepherd
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ELFLOAD_H
|
||||
#define ELFLOAD_H
|
||||
#include <stddef.h>
|
||||
|
||||
#include "elfarch.h"
|
||||
#include "elf.h"
|
||||
|
||||
#include "../../utils/types.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "../../gfx/gfx.h"
|
||||
extern gfx_con_t gfx_con;
|
||||
#define EL_DEBUG(format, ...) \
|
||||
gfx_printf(&gfx_con, format __VA_OPT__(, ) __VA_ARGS__)
|
||||
#else
|
||||
#define EL_DEBUG(...) \
|
||||
do \
|
||||
{ \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EL_OK = 0,
|
||||
|
||||
EL_EIO,
|
||||
EL_ENOMEM,
|
||||
|
||||
EL_NOTELF,
|
||||
EL_WRONGBITS,
|
||||
EL_WRONGENDIAN,
|
||||
EL_WRONGARCH,
|
||||
EL_WRONGOS,
|
||||
EL_NOTEXEC,
|
||||
EL_NODYN,
|
||||
EL_BADREL,
|
||||
|
||||
} el_status;
|
||||
|
||||
typedef struct el_ctx
|
||||
{
|
||||
bool (*pread)(struct el_ctx *ctx, void *dest, size_t nb, size_t offset);
|
||||
|
||||
/* base_load_* -> address we are actually going to load at
|
||||
*/
|
||||
Elf_Addr
|
||||
base_load_paddr,
|
||||
base_load_vaddr;
|
||||
|
||||
/* size in memory of binary */
|
||||
Elf_Addr memsz;
|
||||
|
||||
/* required alignment */
|
||||
Elf_Addr align;
|
||||
|
||||
/* ELF header */
|
||||
Elf_Ehdr ehdr;
|
||||
|
||||
// Section Header Str Table
|
||||
Elf_Shdr shstr;
|
||||
Elf_Shdr symtab;
|
||||
|
||||
/* Offset of dynamic table (0 if not ET_DYN) */
|
||||
Elf_Off dynoff;
|
||||
/* Size of dynamic table (0 if not ET_DYN) */
|
||||
Elf_Addr dynsize;
|
||||
} el_ctx;
|
||||
|
||||
el_status el_pread(el_ctx *ctx, void *def, size_t nb, size_t offset);
|
||||
|
||||
el_status el_init(el_ctx *ctx);
|
||||
typedef void *(*el_alloc_cb)(
|
||||
el_ctx *ctx,
|
||||
Elf_Addr phys,
|
||||
Elf_Addr virt,
|
||||
Elf_Addr size);
|
||||
|
||||
el_status el_load(el_ctx *ctx, el_alloc_cb alloccb);
|
||||
|
||||
/* find the next phdr of type \p type, starting at \p *i.
|
||||
* On success, returns EL_OK with *i set to the phdr number, and the phdr loaded
|
||||
* in *phdr.
|
||||
*
|
||||
* If the end of the phdrs table was reached, *i is set to -1 and the contents
|
||||
* of *phdr are undefined
|
||||
*/
|
||||
el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i);
|
||||
|
||||
/* Relocate the loaded executable */
|
||||
el_status el_relocate(el_ctx *ctx);
|
||||
|
||||
/* find a dynamic table entry
|
||||
* returns the entry on success, dyn->d_tag = DT_NULL on failure
|
||||
*/
|
||||
el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t type);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf_Off tableoff;
|
||||
Elf_Addr tablesize;
|
||||
Elf_Addr entrysize;
|
||||
} el_relocinfo;
|
||||
|
||||
/* find all information regarding relocations of a specific type.
|
||||
*
|
||||
* pass DT_REL or DT_RELA for type
|
||||
* sets ri->entrysize = 0 if not found
|
||||
*/
|
||||
el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type);
|
||||
|
||||
#endif
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2014, Owen Shepherd
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "elfload.h"
|
||||
|
||||
#if defined(__aarch64__)
|
||||
|
||||
#define R_AARCH64_NONE 0
|
||||
#define R_AARCH64_RELATIVE 1027
|
||||
|
||||
el_status el_applyrela(el_ctx *ctx, Elf_RelA *rel)
|
||||
{
|
||||
uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr);
|
||||
uint32_t type = ELF_R_TYPE(rel->r_info);
|
||||
uint32_t sym = ELF_R_SYM(rel->r_info);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case R_AARCH64_NONE:
|
||||
EL_DEBUG("R_AARCH64_NONE\n");
|
||||
break;
|
||||
case R_AARCH64_RELATIVE:
|
||||
if (sym)
|
||||
{
|
||||
EL_DEBUG("R_AARCH64_RELATIVE with symbol ref!\n");
|
||||
return EL_BADREL;
|
||||
}
|
||||
|
||||
EL_DEBUG("Applying R_AARCH64_RELATIVE reloc @%p\n", p);
|
||||
*p = rel->r_addend + ctx->base_load_vaddr;
|
||||
break;
|
||||
|
||||
default:
|
||||
EL_DEBUG("Bad relocation %u\n", type);
|
||||
return EL_BADREL;
|
||||
}
|
||||
|
||||
return EL_OK;
|
||||
}
|
||||
|
||||
el_status el_applyrel(el_ctx *ctx, Elf_Rel *rel)
|
||||
{
|
||||
uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr);
|
||||
uint32_t type = ELF_R_TYPE(rel->r_info);
|
||||
uint32_t sym = ELF_R_SYM(rel->r_info);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case R_AARCH64_NONE:
|
||||
EL_DEBUG("R_AARCH64_NONE\n");
|
||||
break;
|
||||
case R_AARCH64_RELATIVE:
|
||||
if (sym)
|
||||
{
|
||||
EL_DEBUG("R_AARCH64_RELATIVE with symbol ref!\n");
|
||||
return EL_BADREL;
|
||||
}
|
||||
|
||||
EL_DEBUG("Applying R_AARCH64_RELATIVE reloc @%p\n", p);
|
||||
*p += ctx->base_load_vaddr;
|
||||
break;
|
||||
|
||||
default:
|
||||
EL_DEBUG("Bad relocation %u\n", type);
|
||||
return EL_BADREL;
|
||||
}
|
||||
|
||||
return EL_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <m4x@m4xw.net> wrote this file. As long as you retain this notice you can do
|
||||
* whatever you want with this stuff. If we meet some day, and you think this
|
||||
* stuff is worth it, you can buy me a beer in return. M4xw
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "elfload.h"
|
||||
|
||||
#if defined(__arm__)
|
||||
|
||||
// Taken from http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044f/IHI0044F_aaelf.pdf
|
||||
#define R_ARM_NONE 0
|
||||
#define R_ARM_ABS32 2
|
||||
#define R_ARM_JUMP_SLOT 22
|
||||
#define R_ARM_GLOB_DAT 21
|
||||
#define R_ARM_RELATIVE 23
|
||||
|
||||
el_status el_applyrel(el_ctx *ctx, Elf_Rel *rel)
|
||||
{
|
||||
uint32_t sym = ELF_R_SYM(rel->r_info); // Symbol offset
|
||||
uint32_t type = ELF_R_TYPE(rel->r_info); // Relocation Type
|
||||
uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr); // Target Addr
|
||||
|
||||
#if 0 // For later symbol usage
|
||||
Elf32_Sym *elfSym;
|
||||
const char *symbolName;
|
||||
|
||||
// We resolve relocs from the originating elf-image
|
||||
elfSym = (Elf32_Sym *)(ctx->symtab.sh_offset + (char *)buffteg) + sym;
|
||||
int strtab_offset = ctx->shstr.sh_offset;
|
||||
char *strtab = (char *)buffteg + strtab_offset;
|
||||
symbolName = strtab + elfSym->st_name;
|
||||
//EL_DEBUG("Str: %s sz: %x val: %x\n", symbolName, elfSym->st_size, elfSym->st_value);
|
||||
#endif
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case R_ARM_NONE:
|
||||
EL_DEBUG("R_ARM_NONE\n");
|
||||
break;
|
||||
case R_ARM_JUMP_SLOT:
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_GLOB_DAT:
|
||||
// Stubbed for later purpose
|
||||
//*p += elfSym->st_value; // + vaddr from sec
|
||||
//*p |= 0; // 1 if Thumb && STT_FUNC, ignored for now
|
||||
break;
|
||||
case R_ARM_RELATIVE: // Needed for PIE
|
||||
if (sym)
|
||||
{
|
||||
return EL_BADREL;
|
||||
}
|
||||
*p += ctx->base_load_vaddr;
|
||||
break;
|
||||
|
||||
default:
|
||||
return EL_BADREL;
|
||||
}
|
||||
|
||||
return EL_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,39 +0,0 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample Code of OS Dependent Functions for FatFs */
|
||||
/* (C) ChaN, 2017 */
|
||||
/* (C) CTCaer, 2018 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "ff.h"
|
||||
#include "../../mem/heap.h"
|
||||
|
||||
|
||||
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on not enough core) */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Free a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free (nothing to do for null) */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Free the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
3318
bootloader/main.c
3318
bootloader/main.c
File diff suppressed because it is too large
Load Diff
@@ -1,28 +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 _HEAP_H_
|
||||
#define _HEAP_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
void heap_init(u32 base);
|
||||
void *malloc(u32 size);
|
||||
void *calloc(u32 num, u32 size);
|
||||
void free(void *buf);
|
||||
void *memalign(u32 align, u32 size);
|
||||
|
||||
#endif
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef _MC_H_
|
||||
#define _MC_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "../mem/mc_t210.h"
|
||||
|
||||
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock);
|
||||
void mc_config_carveout();
|
||||
void mc_config_carveout_finalize();
|
||||
void mc_enable_ahb_redirect();
|
||||
void mc_disable_ahb_redirect();
|
||||
void mc_enable();
|
||||
|
||||
#endif
|
||||
@@ -1,24 +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 _SDRAM_H_
|
||||
#define _SDRAM_H_
|
||||
|
||||
void sdram_init();
|
||||
const void *sdram_get_params();
|
||||
void sdram_lp0_save_params(const void *params);
|
||||
|
||||
#endif
|
||||
@@ -1,964 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright 2014 Google Inc.
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines the SDRAM parameter structure.
|
||||
*
|
||||
* Note that PLLM is used by EMC. The field names are in camel case to ease
|
||||
* directly converting BCT config files (*.cfg) into C structure.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__
|
||||
#define __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
enum
|
||||
{
|
||||
/* Specifies the memory type to be undefined */
|
||||
NvBootMemoryType_None = 0,
|
||||
|
||||
/* Specifies the memory type to be DDR SDRAM */
|
||||
NvBootMemoryType_Ddr = 0,
|
||||
|
||||
/* Specifies the memory type to be LPDDR SDRAM */
|
||||
NvBootMemoryType_LpDdr = 0,
|
||||
|
||||
/* Specifies the memory type to be DDR2 SDRAM */
|
||||
NvBootMemoryType_Ddr2 = 0,
|
||||
|
||||
/* Specifies the memory type to be LPDDR2 SDRAM */
|
||||
NvBootMemoryType_LpDdr2,
|
||||
|
||||
/* Specifies the memory type to be DDR3 SDRAM */
|
||||
NvBootMemoryType_Ddr3,
|
||||
|
||||
/* Specifies the memory type to be LPDDR4 SDRAM */
|
||||
NvBootMemoryType_LpDdr4,
|
||||
|
||||
NvBootMemoryType_Num,
|
||||
|
||||
/* Specifies an entry in the ram_code table that's not in use */
|
||||
NvBootMemoryType_Unused = 0X7FFFFFF,
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines the SDRAM parameter structure
|
||||
*/
|
||||
struct sdram_params
|
||||
{
|
||||
|
||||
/* Specifies the type of memory device */
|
||||
u32 MemoryType;
|
||||
|
||||
/* MC/EMC clock source configuration */
|
||||
|
||||
/* Specifies the M value for PllM */
|
||||
u32 PllMInputDivider;
|
||||
/* Specifies the N value for PllM */
|
||||
u32 PllMFeedbackDivider;
|
||||
/* Specifies the time to wait for PLLM to lock (in microseconds) */
|
||||
u32 PllMStableTime;
|
||||
/* Specifies misc. control bits */
|
||||
u32 PllMSetupControl;
|
||||
/* Specifies the P value for PLLM */
|
||||
u32 PllMPostDivider;
|
||||
/* Specifies value for Charge Pump Gain Control */
|
||||
u32 PllMKCP;
|
||||
/* Specifies VCO gain */
|
||||
u32 PllMKVCO;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare0;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare1;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare2;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare3;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare4;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare5;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare6;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare7;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare8;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare9;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare10;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare11;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare12;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare13;
|
||||
|
||||
/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
|
||||
u32 EmcClockSource;
|
||||
u32 EmcClockSourceDll;
|
||||
|
||||
/* Defines possible override for PLLLM_MISC2 */
|
||||
u32 ClkRstControllerPllmMisc2Override;
|
||||
/* enables override for PLLLM_MISC2 */
|
||||
u32 ClkRstControllerPllmMisc2OverrideEnable;
|
||||
/* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
|
||||
u32 ClearClk2Mc1;
|
||||
|
||||
/* Auto-calibration of EMC pads */
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_INTERVAL */
|
||||
u32 EmcAutoCalInterval;
|
||||
/*
|
||||
* Specifies the value for EMC_AUTO_CAL_CONFIG
|
||||
* Note: Trigger bits are set by the SDRAM code.
|
||||
*/
|
||||
u32 EmcAutoCalConfig;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
|
||||
u32 EmcAutoCalConfig2;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
|
||||
u32 EmcAutoCalConfig3;
|
||||
|
||||
/* Specifies the values for EMC_AUTO_CAL_CONFIG4-8 */
|
||||
u32 EmcAutoCalConfig4;
|
||||
u32 EmcAutoCalConfig5;
|
||||
u32 EmcAutoCalConfig6;
|
||||
u32 EmcAutoCalConfig7;
|
||||
u32 EmcAutoCalConfig8;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
|
||||
u32 EmcAutoCalVrefSel0;
|
||||
u32 EmcAutoCalVrefSel1;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CHANNEL */
|
||||
u32 EmcAutoCalChannel;
|
||||
|
||||
/* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
|
||||
u32 EmcPmacroAutocalCfg0;
|
||||
u32 EmcPmacroAutocalCfg1;
|
||||
u32 EmcPmacroAutocalCfg2;
|
||||
u32 EmcPmacroRxTerm;
|
||||
u32 EmcPmacroDqTxDrv;
|
||||
u32 EmcPmacroCaTxDrv;
|
||||
u32 EmcPmacroCmdTxDrv;
|
||||
u32 EmcPmacroAutocalCfgCommon;
|
||||
u32 EmcPmacroZctrl;
|
||||
|
||||
/*
|
||||
* Specifies the time for the calibration
|
||||
* to stabilize (in microseconds)
|
||||
*/
|
||||
u32 EmcAutoCalWait;
|
||||
|
||||
u32 EmcXm2CompPadCtrl;
|
||||
u32 EmcXm2CompPadCtrl2;
|
||||
u32 EmcXm2CompPadCtrl3;
|
||||
|
||||
/*
|
||||
* DRAM size information
|
||||
* Specifies the value for EMC_ADR_CFG
|
||||
*/
|
||||
u32 EmcAdrCfg;
|
||||
|
||||
/*
|
||||
* Specifies the time to wait after asserting pin
|
||||
* CKE (in microseconds)
|
||||
*/
|
||||
u32 EmcPinProgramWait;
|
||||
/* Specifies the extra delay before/after pin RESET/CKE command */
|
||||
u32 EmcPinExtraWait;
|
||||
|
||||
u32 EmcPinGpioEn;
|
||||
u32 EmcPinGpio;
|
||||
|
||||
/*
|
||||
* Specifies the extra delay after the first writing
|
||||
* of EMC_TIMING_CONTROL
|
||||
*/
|
||||
u32 EmcTimingControlWait;
|
||||
|
||||
/* Timing parameters required for the SDRAM */
|
||||
|
||||
/* Specifies the value for EMC_RC */
|
||||
u32 EmcRc;
|
||||
/* Specifies the value for EMC_RFC */
|
||||
u32 EmcRfc;
|
||||
/* Specifies the value for EMC_RFC_PB */
|
||||
u32 EmcRfcPb;
|
||||
/* Specifies the value for EMC_RFC_CTRL2 */
|
||||
u32 EmcRefctrl2;
|
||||
/* Specifies the value for EMC_RFC_SLR */
|
||||
u32 EmcRfcSlr;
|
||||
/* Specifies the value for EMC_RAS */
|
||||
u32 EmcRas;
|
||||
/* Specifies the value for EMC_RP */
|
||||
u32 EmcRp;
|
||||
/* Specifies the value for EMC_R2R */
|
||||
u32 EmcR2r;
|
||||
/* Specifies the value for EMC_W2W */
|
||||
u32 EmcW2w;
|
||||
/* Specifies the value for EMC_R2W */
|
||||
u32 EmcR2w;
|
||||
/* Specifies the value for EMC_W2R */
|
||||
u32 EmcW2r;
|
||||
/* Specifies the value for EMC_R2P */
|
||||
u32 EmcR2p;
|
||||
/* Specifies the value for EMC_W2P */
|
||||
u32 EmcW2p;
|
||||
|
||||
u32 EmcTppd;
|
||||
u32 EmcCcdmw;
|
||||
|
||||
/* Specifies the value for EMC_RD_RCD */
|
||||
u32 EmcRdRcd;
|
||||
/* Specifies the value for EMC_WR_RCD */
|
||||
u32 EmcWrRcd;
|
||||
/* Specifies the value for EMC_RRD */
|
||||
u32 EmcRrd;
|
||||
/* Specifies the value for EMC_REXT */
|
||||
u32 EmcRext;
|
||||
/* Specifies the value for EMC_WEXT */
|
||||
u32 EmcWext;
|
||||
/* Specifies the value for EMC_WDV */
|
||||
u32 EmcWdv;
|
||||
|
||||
u32 EmcWdvChk;
|
||||
u32 EmcWsv;
|
||||
u32 EmcWev;
|
||||
|
||||
/* Specifies the value for EMC_WDV_MASK */
|
||||
u32 EmcWdvMask;
|
||||
|
||||
u32 EmcWsDuration;
|
||||
u32 EmcWeDuration;
|
||||
|
||||
/* Specifies the value for EMC_QUSE */
|
||||
u32 EmcQUse;
|
||||
/* Specifies the value for EMC_QUSE_WIDTH */
|
||||
u32 EmcQuseWidth;
|
||||
/* Specifies the value for EMC_IBDLY */
|
||||
u32 EmcIbdly;
|
||||
/* Specifies the value for EMC_OBDLY */
|
||||
u32 EmcObdly;
|
||||
/* Specifies the value for EMC_EINPUT */
|
||||
u32 EmcEInput;
|
||||
/* Specifies the value for EMC_EINPUT_DURATION */
|
||||
u32 EmcEInputDuration;
|
||||
/* Specifies the value for EMC_PUTERM_EXTRA */
|
||||
u32 EmcPutermExtra;
|
||||
/* Specifies the value for EMC_PUTERM_WIDTH */
|
||||
u32 EmcPutermWidth;
|
||||
/* Specifies the value for EMC_PUTERM_ADJ */
|
||||
////u32 EmcPutermAdj;
|
||||
|
||||
/* Specifies the value for EMC_QRST */
|
||||
u32 EmcQRst;
|
||||
/* Specifies the value for EMC_QSAFE */
|
||||
u32 EmcQSafe;
|
||||
/* Specifies the value for EMC_RDV */
|
||||
u32 EmcRdv;
|
||||
/* Specifies the value for EMC_RDV_MASK */
|
||||
u32 EmcRdvMask;
|
||||
/* Specifies the value for EMC_RDV_EARLY */
|
||||
u32 EmcRdvEarly;
|
||||
/* Specifies the value for EMC_RDV_EARLY_MASK */
|
||||
u32 EmcRdvEarlyMask;
|
||||
/* Specifies the value for EMC_QPOP */
|
||||
u32 EmcQpop;
|
||||
|
||||
/* Specifies the value for EMC_REFRESH */
|
||||
u32 EmcRefresh;
|
||||
/* Specifies the value for EMC_BURST_REFRESH_NUM */
|
||||
u32 EmcBurstRefreshNum;
|
||||
/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
|
||||
u32 EmcPreRefreshReqCnt;
|
||||
/* Specifies the value for EMC_PDEX2WR */
|
||||
u32 EmcPdEx2Wr;
|
||||
/* Specifies the value for EMC_PDEX2RD */
|
||||
u32 EmcPdEx2Rd;
|
||||
/* Specifies the value for EMC_PCHG2PDEN */
|
||||
u32 EmcPChg2Pden;
|
||||
/* Specifies the value for EMC_ACT2PDEN */
|
||||
u32 EmcAct2Pden;
|
||||
/* Specifies the value for EMC_AR2PDEN */
|
||||
u32 EmcAr2Pden;
|
||||
/* Specifies the value for EMC_RW2PDEN */
|
||||
u32 EmcRw2Pden;
|
||||
/* Specifies the value for EMC_CKE2PDEN */
|
||||
u32 EmcCke2Pden;
|
||||
/* Specifies the value for EMC_PDEX2CKE */
|
||||
u32 EmcPdex2Cke;
|
||||
/* Specifies the value for EMC_PDEX2MRR */
|
||||
u32 EmcPdex2Mrr;
|
||||
/* Specifies the value for EMC_TXSR */
|
||||
u32 EmcTxsr;
|
||||
/* Specifies the value for EMC_TXSRDLL */
|
||||
u32 EmcTxsrDll;
|
||||
/* Specifies the value for EMC_TCKE */
|
||||
u32 EmcTcke;
|
||||
/* Specifies the value for EMC_TCKESR */
|
||||
u32 EmcTckesr;
|
||||
/* Specifies the value for EMC_TPD */
|
||||
u32 EmcTpd;
|
||||
/* Specifies the value for EMC_TFAW */
|
||||
u32 EmcTfaw;
|
||||
/* Specifies the value for EMC_TRPAB */
|
||||
u32 EmcTrpab;
|
||||
/* Specifies the value for EMC_TCLKSTABLE */
|
||||
u32 EmcTClkStable;
|
||||
/* Specifies the value for EMC_TCLKSTOP */
|
||||
u32 EmcTClkStop;
|
||||
/* Specifies the value for EMC_TREFBW */
|
||||
u32 EmcTRefBw;
|
||||
|
||||
/* FBIO configuration values */
|
||||
|
||||
/* Specifies the value for EMC_FBIO_CFG5 */
|
||||
u32 EmcFbioCfg5;
|
||||
/* Specifies the value for EMC_FBIO_CFG7 */
|
||||
u32 EmcFbioCfg7;
|
||||
/* Specifies the value for EMC_FBIO_CFG8 */
|
||||
u32 EmcFbioCfg8;
|
||||
|
||||
/* Command mapping for CMD brick 0 */
|
||||
u32 EmcCmdMappingCmd0_0;
|
||||
u32 EmcCmdMappingCmd0_1;
|
||||
u32 EmcCmdMappingCmd0_2;
|
||||
u32 EmcCmdMappingCmd1_0;
|
||||
u32 EmcCmdMappingCmd1_1;
|
||||
u32 EmcCmdMappingCmd1_2;
|
||||
u32 EmcCmdMappingCmd2_0;
|
||||
u32 EmcCmdMappingCmd2_1;
|
||||
u32 EmcCmdMappingCmd2_2;
|
||||
u32 EmcCmdMappingCmd3_0;
|
||||
u32 EmcCmdMappingCmd3_1;
|
||||
u32 EmcCmdMappingCmd3_2;
|
||||
u32 EmcCmdMappingByte;
|
||||
|
||||
/* Specifies the value for EMC_FBIO_SPARE */
|
||||
u32 EmcFbioSpare;
|
||||
|
||||
/* Specifies the value for EMC_CFG_RSV */
|
||||
u32 EmcCfgRsv;
|
||||
|
||||
/* MRS command values */
|
||||
|
||||
/* Specifies the value for EMC_MRS */
|
||||
u32 EmcMrs;
|
||||
/* Specifies the MP0 command to initialize mode registers */
|
||||
u32 EmcEmrs;
|
||||
/* Specifies the MP2 command to initialize mode registers */
|
||||
u32 EmcEmrs2;
|
||||
/* Specifies the MP3 command to initialize mode registers */
|
||||
u32 EmcEmrs3;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
|
||||
u32 EmcMrw1;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
|
||||
u32 EmcMrw2;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
|
||||
u32 EmcMrw3;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
|
||||
u32 EmcMrw4;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 3? at cold boot */
|
||||
u32 EmcMrw6;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
|
||||
u32 EmcMrw8;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 11? at cold boot */
|
||||
u32 EmcMrw9;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 12 at cold boot */
|
||||
u32 EmcMrw10;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 14 at cold boot */
|
||||
u32 EmcMrw12;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 14? at cold boot */
|
||||
u32 EmcMrw13;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 22 at cold boot */
|
||||
u32 EmcMrw14;
|
||||
/*
|
||||
* Specifies the programming to extra LPDDR2 Mode Register
|
||||
* at cold boot
|
||||
*/
|
||||
u32 EmcMrwExtra;
|
||||
/*
|
||||
* Specifies the programming to extra LPDDR2 Mode Register
|
||||
* at warm boot
|
||||
*/
|
||||
u32 EmcWarmBootMrwExtra;
|
||||
/*
|
||||
* Specify the enable of extra Mode Register programming at
|
||||
* warm boot
|
||||
*/
|
||||
u32 EmcWarmBootExtraModeRegWriteEnable;
|
||||
/*
|
||||
* Specify the enable of extra Mode Register programming at
|
||||
* cold boot
|
||||
*/
|
||||
u32 EmcExtraModeRegWriteEnable;
|
||||
|
||||
/* Specifies the EMC_MRW reset command value */
|
||||
u32 EmcMrwResetCommand;
|
||||
/* Specifies the EMC Reset wait time (in microseconds) */
|
||||
u32 EmcMrwResetNInitWait;
|
||||
/* Specifies the value for EMC_MRS_WAIT_CNT */
|
||||
u32 EmcMrsWaitCnt;
|
||||
/* Specifies the value for EMC_MRS_WAIT_CNT2 */
|
||||
u32 EmcMrsWaitCnt2;
|
||||
|
||||
/* EMC miscellaneous configurations */
|
||||
|
||||
/* Specifies the value for EMC_CFG */
|
||||
u32 EmcCfg;
|
||||
/* Specifies the value for EMC_CFG_2 */
|
||||
u32 EmcCfg2;
|
||||
/* Specifies the pipe bypass controls */
|
||||
u32 EmcCfgPipe;
|
||||
u32 EmcCfgPipeClk;
|
||||
u32 EmcFdpdCtrlCmdNoRamp;
|
||||
u32 EmcCfgUpdate;
|
||||
|
||||
/* Specifies the value for EMC_DBG */
|
||||
u32 EmcDbg;
|
||||
u32 EmcDbgWriteMux;
|
||||
|
||||
/* Specifies the value for EMC_CMDQ */
|
||||
u32 EmcCmdQ;
|
||||
/* Specifies the value for EMC_MC2EMCQ */
|
||||
u32 EmcMc2EmcQ;
|
||||
/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
|
||||
u32 EmcDynSelfRefControl;
|
||||
|
||||
/* Specifies the value for MEM_INIT_DONE */
|
||||
u32 AhbArbitrationXbarCtrlMemInitDone;
|
||||
|
||||
/* Specifies the value for EMC_CFG_DIG_DLL */
|
||||
u32 EmcCfgDigDll;
|
||||
u32 EmcCfgDigDll_1;
|
||||
/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
|
||||
u32 EmcCfgDigDllPeriod;
|
||||
/* Specifies the value of *DEV_SELECTN of various EMC registers */
|
||||
u32 EmcDevSelect;
|
||||
|
||||
/* Specifies the value for EMC_SEL_DPD_CTRL */
|
||||
u32 EmcSelDpdCtrl;
|
||||
|
||||
/* Pads trimmer delays */
|
||||
u32 EmcFdpdCtrlDq;
|
||||
u32 EmcFdpdCtrlCmd;
|
||||
u32 EmcPmacroIbVrefDq_0;
|
||||
u32 EmcPmacroIbVrefDq_1;
|
||||
u32 EmcPmacroIbVrefDqs_0;
|
||||
u32 EmcPmacroIbVrefDqs_1;
|
||||
u32 EmcPmacroIbRxrt;
|
||||
u32 EmcCfgPipe1;
|
||||
u32 EmcCfgPipe2;
|
||||
|
||||
/* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
|
||||
u32 EmcPmacroQuseDdllRank0_0;
|
||||
u32 EmcPmacroQuseDdllRank0_1;
|
||||
u32 EmcPmacroQuseDdllRank0_2;
|
||||
u32 EmcPmacroQuseDdllRank0_3;
|
||||
u32 EmcPmacroQuseDdllRank0_4;
|
||||
u32 EmcPmacroQuseDdllRank0_5;
|
||||
u32 EmcPmacroQuseDdllRank1_0;
|
||||
u32 EmcPmacroQuseDdllRank1_1;
|
||||
u32 EmcPmacroQuseDdllRank1_2;
|
||||
u32 EmcPmacroQuseDdllRank1_3;
|
||||
u32 EmcPmacroQuseDdllRank1_4;
|
||||
u32 EmcPmacroQuseDdllRank1_5;
|
||||
|
||||
u32 EmcPmacroObDdllLongDqRank0_0;
|
||||
u32 EmcPmacroObDdllLongDqRank0_1;
|
||||
u32 EmcPmacroObDdllLongDqRank0_2;
|
||||
u32 EmcPmacroObDdllLongDqRank0_3;
|
||||
u32 EmcPmacroObDdllLongDqRank0_4;
|
||||
u32 EmcPmacroObDdllLongDqRank0_5;
|
||||
u32 EmcPmacroObDdllLongDqRank1_0;
|
||||
u32 EmcPmacroObDdllLongDqRank1_1;
|
||||
u32 EmcPmacroObDdllLongDqRank1_2;
|
||||
u32 EmcPmacroObDdllLongDqRank1_3;
|
||||
u32 EmcPmacroObDdllLongDqRank1_4;
|
||||
u32 EmcPmacroObDdllLongDqRank1_5;
|
||||
|
||||
u32 EmcPmacroObDdllLongDqsRank0_0;
|
||||
u32 EmcPmacroObDdllLongDqsRank0_1;
|
||||
u32 EmcPmacroObDdllLongDqsRank0_2;
|
||||
u32 EmcPmacroObDdllLongDqsRank0_3;
|
||||
u32 EmcPmacroObDdllLongDqsRank0_4;
|
||||
u32 EmcPmacroObDdllLongDqsRank0_5;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_0;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_1;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_2;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_3;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_4;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_5;
|
||||
|
||||
u32 EmcPmacroIbDdllLongDqsRank0_0;
|
||||
u32 EmcPmacroIbDdllLongDqsRank0_1;
|
||||
u32 EmcPmacroIbDdllLongDqsRank0_2;
|
||||
u32 EmcPmacroIbDdllLongDqsRank0_3;
|
||||
u32 EmcPmacroIbDdllLongDqsRank1_0;
|
||||
u32 EmcPmacroIbDdllLongDqsRank1_1;
|
||||
u32 EmcPmacroIbDdllLongDqsRank1_2;
|
||||
u32 EmcPmacroIbDdllLongDqsRank1_3;
|
||||
|
||||
u32 EmcPmacroDdllLongCmd_0;
|
||||
u32 EmcPmacroDdllLongCmd_1;
|
||||
u32 EmcPmacroDdllLongCmd_2;
|
||||
u32 EmcPmacroDdllLongCmd_3;
|
||||
u32 EmcPmacroDdllLongCmd_4;
|
||||
u32 EmcPmacroDdllShortCmd_0;
|
||||
u32 EmcPmacroDdllShortCmd_1;
|
||||
u32 EmcPmacroDdllShortCmd_2;
|
||||
|
||||
/*
|
||||
* Specifies the delay after asserting CKE pin during a WarmBoot0
|
||||
* sequence (in microseconds)
|
||||
*/
|
||||
u32 WarmBootWait;
|
||||
|
||||
/* Specifies the value for EMC_ODT_WRITE */
|
||||
u32 EmcOdtWrite;
|
||||
|
||||
/* Periodic ZQ calibration */
|
||||
|
||||
/*
|
||||
* Specifies the value for EMC_ZCAL_INTERVAL
|
||||
* Value 0 disables ZQ calibration
|
||||
*/
|
||||
u32 EmcZcalInterval;
|
||||
/* Specifies the value for EMC_ZCAL_WAIT_CNT */
|
||||
u32 EmcZcalWaitCnt;
|
||||
/* Specifies the value for EMC_ZCAL_MRW_CMD */
|
||||
u32 EmcZcalMrwCmd;
|
||||
|
||||
/* DRAM initialization sequence flow control */
|
||||
|
||||
/* Specifies the MRS command value for resetting DLL */
|
||||
u32 EmcMrsResetDll;
|
||||
/* Specifies the command for ZQ initialization of device 0 */
|
||||
u32 EmcZcalInitDev0;
|
||||
/* Specifies the command for ZQ initialization of device 1 */
|
||||
u32 EmcZcalInitDev1;
|
||||
/*
|
||||
* Specifies the wait time after programming a ZQ initialization
|
||||
* command (in microseconds)
|
||||
*/
|
||||
u32 EmcZcalInitWait;
|
||||
/*
|
||||
* Specifies the enable for ZQ calibration at cold boot [bit 0]
|
||||
* and warm boot [bit 1]
|
||||
*/
|
||||
u32 EmcZcalWarmColdBootEnables;
|
||||
|
||||
/*
|
||||
* Specifies the MRW command to LPDDR2 for ZQ calibration
|
||||
* on warmboot
|
||||
*/
|
||||
/* Is issued to both devices separately */
|
||||
u32 EmcMrwLpddr2ZcalWarmBoot;
|
||||
/*
|
||||
* Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
|
||||
* Is issued to both devices separately
|
||||
*/
|
||||
u32 EmcZqCalDdr3WarmBoot;
|
||||
u32 EmcZqCalLpDdr4WarmBoot;
|
||||
/*
|
||||
* Specifies the wait time for ZQ calibration on warmboot
|
||||
* (in microseconds)
|
||||
*/
|
||||
u32 EmcZcalWarmBootWait;
|
||||
/*
|
||||
* Specifies the enable for DRAM Mode Register programming
|
||||
* at warm boot
|
||||
*/
|
||||
u32 EmcMrsWarmBootEnable;
|
||||
/*
|
||||
* Specifies the wait time after sending an MRS DLL reset command
|
||||
* in microseconds)
|
||||
*/
|
||||
u32 EmcMrsResetDllWait;
|
||||
/* Specifies the extra MRS command to initialize mode registers */
|
||||
u32 EmcMrsExtra;
|
||||
/* Specifies the extra MRS command at warm boot */
|
||||
u32 EmcWarmBootMrsExtra;
|
||||
/* Specifies the EMRS command to enable the DDR2 DLL */
|
||||
u32 EmcEmrsDdr2DllEnable;
|
||||
/* Specifies the MRS command to reset the DDR2 DLL */
|
||||
u32 EmcMrsDdr2DllReset;
|
||||
/* Specifies the EMRS command to set OCD calibration */
|
||||
u32 EmcEmrsDdr2OcdCalib;
|
||||
/*
|
||||
* Specifies the wait between initializing DDR and setting OCD
|
||||
* calibration (in microseconds)
|
||||
*/
|
||||
u32 EmcDdr2Wait;
|
||||
/* Specifies the value for EMC_CLKEN_OVERRIDE */
|
||||
u32 EmcClkenOverride;
|
||||
|
||||
/*
|
||||
* Specifies LOG2 of the extra refresh numbers after booting
|
||||
* Program 0 to disable
|
||||
*/
|
||||
u32 EmcExtraRefreshNum;
|
||||
/* Specifies the master override for all EMC clocks */
|
||||
u32 EmcClkenOverrideAllWarmBoot;
|
||||
/* Specifies the master override for all MC clocks */
|
||||
u32 McClkenOverrideAllWarmBoot;
|
||||
/* Specifies digital dll period, choosing between 4 to 64 ms */
|
||||
u32 EmcCfgDigDllPeriodWarmBoot;
|
||||
|
||||
/* Pad controls */
|
||||
|
||||
/* Specifies the value for PMC_VDDP_SEL */
|
||||
u32 PmcVddpSel;
|
||||
/* Specifies the wait time after programming PMC_VDDP_SEL */
|
||||
u32 PmcVddpSelWait;
|
||||
/* Specifies the value for PMC_DDR_PWR */
|
||||
u32 PmcDdrPwr;
|
||||
/* Specifies the value for PMC_DDR_CFG */
|
||||
u32 PmcDdrCfg;
|
||||
/* Specifies the value for PMC_IO_DPD3_REQ */
|
||||
u32 PmcIoDpd3Req;
|
||||
/* Specifies the wait time after programming PMC_IO_DPD3_REQ */
|
||||
u32 PmcIoDpd3ReqWait;
|
||||
u32 PmcIoDpd4ReqWait;
|
||||
|
||||
/* Specifies the value for PMC_REG_SHORT */
|
||||
u32 PmcRegShort;
|
||||
/* Specifies the value for PMC_NO_IOPOWER */
|
||||
u32 PmcNoIoPower;
|
||||
|
||||
u32 PmcDdrCntrlWait;
|
||||
u32 PmcDdrCntrl;
|
||||
|
||||
/* Specifies the value for EMC_ACPD_CONTROL */
|
||||
u32 EmcAcpdControl;
|
||||
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE_CFG */
|
||||
////u32 EmcSwizzleRank0ByteCfg;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
|
||||
u32 EmcSwizzleRank0Byte0;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
|
||||
u32 EmcSwizzleRank0Byte1;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
|
||||
u32 EmcSwizzleRank0Byte2;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
|
||||
u32 EmcSwizzleRank0Byte3;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE_CFG */
|
||||
////u32 EmcSwizzleRank1ByteCfg;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
|
||||
u32 EmcSwizzleRank1Byte0;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
|
||||
u32 EmcSwizzleRank1Byte1;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
|
||||
u32 EmcSwizzleRank1Byte2;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
|
||||
u32 EmcSwizzleRank1Byte3;
|
||||
|
||||
/* Specifies the value for EMC_TXDSRVTTGEN */
|
||||
u32 EmcTxdsrvttgen;
|
||||
|
||||
/* Specifies the value for EMC_DATA_BRLSHFT_0 */
|
||||
u32 EmcDataBrlshft0;
|
||||
u32 EmcDataBrlshft1;
|
||||
|
||||
u32 EmcDqsBrlshft0;
|
||||
u32 EmcDqsBrlshft1;
|
||||
|
||||
u32 EmcCmdBrlshft0;
|
||||
u32 EmcCmdBrlshft1;
|
||||
u32 EmcCmdBrlshft2;
|
||||
u32 EmcCmdBrlshft3;
|
||||
|
||||
u32 EmcQuseBrlshft0;
|
||||
u32 EmcQuseBrlshft1;
|
||||
u32 EmcQuseBrlshft2;
|
||||
u32 EmcQuseBrlshft3;
|
||||
|
||||
u32 EmcDllCfg0;
|
||||
u32 EmcDllCfg1;
|
||||
|
||||
u32 EmcPmcScratch1;
|
||||
u32 EmcPmcScratch2;
|
||||
u32 EmcPmcScratch3;
|
||||
|
||||
u32 EmcPmacroPadCfgCtrl;
|
||||
|
||||
u32 EmcPmacroVttgenCtrl0;
|
||||
u32 EmcPmacroVttgenCtrl1;
|
||||
u32 EmcPmacroVttgenCtrl2;
|
||||
|
||||
u32 EmcPmacroBrickCtrlRfu1;
|
||||
u32 EmcPmacroCmdBrickCtrlFdpd;
|
||||
u32 EmcPmacroBrickCtrlRfu2;
|
||||
u32 EmcPmacroDataBrickCtrlFdpd;
|
||||
u32 EmcPmacroBgBiasCtrl0;
|
||||
u32 EmcPmacroDataPadRxCtrl;
|
||||
u32 EmcPmacroCmdPadRxCtrl;
|
||||
u32 EmcPmacroDataRxTermMode;
|
||||
u32 EmcPmacroCmdRxTermMode;
|
||||
u32 EmcPmacroDataPadTxCtrl;
|
||||
u32 EmcPmacroCommonPadTxCtrl;
|
||||
u32 EmcPmacroCmdPadTxCtrl;
|
||||
u32 EmcCfg3;
|
||||
|
||||
u32 EmcPmacroTxPwrd0;
|
||||
u32 EmcPmacroTxPwrd1;
|
||||
u32 EmcPmacroTxPwrd2;
|
||||
u32 EmcPmacroTxPwrd3;
|
||||
u32 EmcPmacroTxPwrd4;
|
||||
u32 EmcPmacroTxPwrd5;
|
||||
|
||||
u32 EmcConfigSampleDelay;
|
||||
|
||||
u32 EmcPmacroBrickMapping0;
|
||||
u32 EmcPmacroBrickMapping1;
|
||||
u32 EmcPmacroBrickMapping2;
|
||||
|
||||
u32 EmcPmacroTxSelClkSrc0;
|
||||
u32 EmcPmacroTxSelClkSrc1;
|
||||
u32 EmcPmacroTxSelClkSrc2;
|
||||
u32 EmcPmacroTxSelClkSrc3;
|
||||
u32 EmcPmacroTxSelClkSrc4;
|
||||
u32 EmcPmacroTxSelClkSrc5;
|
||||
|
||||
u32 EmcPmacroDdllBypass;
|
||||
|
||||
u32 EmcPmacroDdllPwrd0;
|
||||
u32 EmcPmacroDdllPwrd1;
|
||||
u32 EmcPmacroDdllPwrd2;
|
||||
|
||||
u32 EmcPmacroCmdCtrl0;
|
||||
u32 EmcPmacroCmdCtrl1;
|
||||
u32 EmcPmacroCmdCtrl2;
|
||||
|
||||
/* DRAM size information */
|
||||
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG */
|
||||
u32 McEmemAdrCfg;
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
|
||||
u32 McEmemAdrCfgDev0;
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
|
||||
u32 McEmemAdrCfgDev1;
|
||||
u32 McEmemAdrCfgChannelMask;
|
||||
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLECfg0 */
|
||||
u32 McEmemAdrCfgBankMask0;
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
|
||||
u32 McEmemAdrCfgBankMask1;
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
|
||||
u32 McEmemAdrCfgBankMask2;
|
||||
|
||||
/*
|
||||
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
||||
* size (in KBytes)
|
||||
*/
|
||||
u32 McEmemCfg;
|
||||
|
||||
/* MC arbitration configuration */
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_CFG */
|
||||
u32 McEmemArbCfg;
|
||||
/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
|
||||
u32 McEmemArbOutstandingReq;
|
||||
|
||||
u32 McEmemArbRefpbHpCtrl;
|
||||
u32 McEmemArbRefpbBankCtrl;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
|
||||
u32 McEmemArbTimingRcd;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RP */
|
||||
u32 McEmemArbTimingRp;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RC */
|
||||
u32 McEmemArbTimingRc;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
|
||||
u32 McEmemArbTimingRas;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
|
||||
u32 McEmemArbTimingFaw;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
|
||||
u32 McEmemArbTimingRrd;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
|
||||
u32 McEmemArbTimingRap2Pre;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
|
||||
u32 McEmemArbTimingWap2Pre;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
|
||||
u32 McEmemArbTimingR2R;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
|
||||
u32 McEmemArbTimingW2W;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
|
||||
u32 McEmemArbTimingR2W;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
|
||||
u32 McEmemArbTimingW2R;
|
||||
|
||||
u32 McEmemArbTimingRFCPB;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_DA_TURNS */
|
||||
u32 McEmemArbDaTurns;
|
||||
/* Specifies the value for MC_EMEM_ARB_DA_COVERS */
|
||||
u32 McEmemArbDaCovers;
|
||||
/* Specifies the value for MC_EMEM_ARB_MISC0 */
|
||||
u32 McEmemArbMisc0;
|
||||
/* Specifies the value for MC_EMEM_ARB_MISC1 */
|
||||
u32 McEmemArbMisc1;
|
||||
u32 McEmemArbMisc2;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
|
||||
u32 McEmemArbRing1Throttle;
|
||||
/* Specifies the value for MC_EMEM_ARB_OVERRIDE */
|
||||
u32 McEmemArbOverride;
|
||||
/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
|
||||
u32 McEmemArbOverride1;
|
||||
/* Specifies the value for MC_EMEM_ARB_RSV */
|
||||
u32 McEmemArbRsv;
|
||||
|
||||
u32 McDaCfg0;
|
||||
u32 McEmemArbTimingCcdmw;
|
||||
|
||||
/* Specifies the value for MC_CLKEN_OVERRIDE */
|
||||
u32 McClkenOverride;
|
||||
|
||||
/* Specifies the value for MC_STAT_CONTROL */
|
||||
u32 McStatControl;
|
||||
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_BOM */
|
||||
u32 McVideoProtectBom;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
|
||||
u32 McVideoProtectBomAdrHi;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
|
||||
u32 McVideoProtectSizeMb;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
|
||||
u32 McVideoProtectVprOverride;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
|
||||
u32 McVideoProtectVprOverride1;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
|
||||
u32 McVideoProtectGpuOverride0;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
|
||||
u32 McVideoProtectGpuOverride1;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_BOM */
|
||||
u32 McSecCarveoutBom;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
|
||||
u32 McSecCarveoutAdrHi;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
|
||||
u32 McSecCarveoutSizeMb;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.
|
||||
VIDEO_PROTECT_WRITEAccess */
|
||||
u32 McVideoProtectWriteAccess;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.
|
||||
SEC_CARVEOUT_WRITEAccess */
|
||||
u32 McSecCarveoutProtectWriteAccess;
|
||||
|
||||
/* Write-Protect Regions (WPR) */
|
||||
u32 McGeneralizedCarveout1Bom;
|
||||
u32 McGeneralizedCarveout1BomHi;
|
||||
u32 McGeneralizedCarveout1Size128kb;
|
||||
u32 McGeneralizedCarveout1Access0;
|
||||
u32 McGeneralizedCarveout1Access1;
|
||||
u32 McGeneralizedCarveout1Access2;
|
||||
u32 McGeneralizedCarveout1Access3;
|
||||
u32 McGeneralizedCarveout1Access4;
|
||||
u32 McGeneralizedCarveout1ForceInternalAccess0;
|
||||
u32 McGeneralizedCarveout1ForceInternalAccess1;
|
||||
u32 McGeneralizedCarveout1ForceInternalAccess2;
|
||||
u32 McGeneralizedCarveout1ForceInternalAccess3;
|
||||
u32 McGeneralizedCarveout1ForceInternalAccess4;
|
||||
u32 McGeneralizedCarveout1Cfg0;
|
||||
|
||||
u32 McGeneralizedCarveout2Bom;
|
||||
u32 McGeneralizedCarveout2BomHi;
|
||||
u32 McGeneralizedCarveout2Size128kb;
|
||||
u32 McGeneralizedCarveout2Access0;
|
||||
u32 McGeneralizedCarveout2Access1;
|
||||
u32 McGeneralizedCarveout2Access2;
|
||||
u32 McGeneralizedCarveout2Access3;
|
||||
u32 McGeneralizedCarveout2Access4;
|
||||
u32 McGeneralizedCarveout2ForceInternalAccess0;
|
||||
u32 McGeneralizedCarveout2ForceInternalAccess1;
|
||||
u32 McGeneralizedCarveout2ForceInternalAccess2;
|
||||
u32 McGeneralizedCarveout2ForceInternalAccess3;
|
||||
u32 McGeneralizedCarveout2ForceInternalAccess4;
|
||||
u32 McGeneralizedCarveout2Cfg0;
|
||||
|
||||
u32 McGeneralizedCarveout3Bom;
|
||||
u32 McGeneralizedCarveout3BomHi;
|
||||
u32 McGeneralizedCarveout3Size128kb;
|
||||
u32 McGeneralizedCarveout3Access0;
|
||||
u32 McGeneralizedCarveout3Access1;
|
||||
u32 McGeneralizedCarveout3Access2;
|
||||
u32 McGeneralizedCarveout3Access3;
|
||||
u32 McGeneralizedCarveout3Access4;
|
||||
u32 McGeneralizedCarveout3ForceInternalAccess0;
|
||||
u32 McGeneralizedCarveout3ForceInternalAccess1;
|
||||
u32 McGeneralizedCarveout3ForceInternalAccess2;
|
||||
u32 McGeneralizedCarveout3ForceInternalAccess3;
|
||||
u32 McGeneralizedCarveout3ForceInternalAccess4;
|
||||
u32 McGeneralizedCarveout3Cfg0;
|
||||
|
||||
u32 McGeneralizedCarveout4Bom;
|
||||
u32 McGeneralizedCarveout4BomHi;
|
||||
u32 McGeneralizedCarveout4Size128kb;
|
||||
u32 McGeneralizedCarveout4Access0;
|
||||
u32 McGeneralizedCarveout4Access1;
|
||||
u32 McGeneralizedCarveout4Access2;
|
||||
u32 McGeneralizedCarveout4Access3;
|
||||
u32 McGeneralizedCarveout4Access4;
|
||||
u32 McGeneralizedCarveout4ForceInternalAccess0;
|
||||
u32 McGeneralizedCarveout4ForceInternalAccess1;
|
||||
u32 McGeneralizedCarveout4ForceInternalAccess2;
|
||||
u32 McGeneralizedCarveout4ForceInternalAccess3;
|
||||
u32 McGeneralizedCarveout4ForceInternalAccess4;
|
||||
u32 McGeneralizedCarveout4Cfg0;
|
||||
|
||||
u32 McGeneralizedCarveout5Bom;
|
||||
u32 McGeneralizedCarveout5BomHi;
|
||||
u32 McGeneralizedCarveout5Size128kb;
|
||||
u32 McGeneralizedCarveout5Access0;
|
||||
u32 McGeneralizedCarveout5Access1;
|
||||
u32 McGeneralizedCarveout5Access2;
|
||||
u32 McGeneralizedCarveout5Access3;
|
||||
u32 McGeneralizedCarveout5Access4;
|
||||
u32 McGeneralizedCarveout5ForceInternalAccess0;
|
||||
u32 McGeneralizedCarveout5ForceInternalAccess1;
|
||||
u32 McGeneralizedCarveout5ForceInternalAccess2;
|
||||
u32 McGeneralizedCarveout5ForceInternalAccess3;
|
||||
u32 McGeneralizedCarveout5ForceInternalAccess4;
|
||||
u32 McGeneralizedCarveout5Cfg0;
|
||||
|
||||
/* Specifies enable for CA training */
|
||||
u32 EmcCaTrainingEnable;
|
||||
|
||||
/* Set if bit 6 select is greater than bit 7 select; uses aremc.
|
||||
spec packet SWIZZLE_BIT6_GT_BIT7 */
|
||||
u32 SwizzleRankByteEncode;
|
||||
/* Specifies enable and offset for patched boot ROM write */
|
||||
u32 BootRomPatchControl;
|
||||
/* Specifies data for patched boot ROM write */
|
||||
u32 BootRomPatchData;
|
||||
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_BOM */
|
||||
u32 McMtsCarveoutBom;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
|
||||
u32 McMtsCarveoutAdrHi;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
|
||||
u32 McMtsCarveoutSizeMb;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
|
||||
u32 McMtsCarveoutRegCtrl;
|
||||
|
||||
/* End */
|
||||
};
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__ */
|
||||
@@ -1,162 +0,0 @@
|
||||
/*
|
||||
* Battery charger driver for Nintendo Switch's TI BQ24193
|
||||
*
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "bq24193.h"
|
||||
#include "../soc/i2c.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
switch (prop) {
|
||||
case BQ24193_InputVoltageLimit: // Input voltage limit (mV).
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_InputSource);
|
||||
data = (data & BQ24193_INCONFIG_VINDPM_MASK) >> 3;
|
||||
*value += ((data >> 0) & 1) ? 80 : 0;
|
||||
*value += ((data >> 1) & 1) ? 160 : 0;
|
||||
*value += ((data >> 2) & 1) ? 320 : 0;
|
||||
*value += ((data >> 3) & 1) ? 640 : 0;
|
||||
*value += 3880;
|
||||
break;
|
||||
case BQ24193_InputCurrentLimit: // Input current limit (mA).
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_InputSource);
|
||||
data &= BQ24193_INCONFIG_INLIMIT_MASK;
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
*value = 100;
|
||||
break;
|
||||
case 1:
|
||||
*value = 150;
|
||||
break;
|
||||
case 2:
|
||||
*value = 500;
|
||||
break;
|
||||
case 3:
|
||||
*value = 900;
|
||||
break;
|
||||
case 4:
|
||||
*value = 1200;
|
||||
break;
|
||||
case 5:
|
||||
*value = 1500;
|
||||
break;
|
||||
case 6:
|
||||
*value = 2000;
|
||||
break;
|
||||
case 7:
|
||||
*value = 3000;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BQ24193_SystemMinimumVoltage: // Minimum system voltage limit (mV).
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_PORConfig);
|
||||
*value = (data & BQ24193_PORCONFIG_SYSMIN_MASK) >> 1;
|
||||
*value *= 100;
|
||||
*value += 3000;
|
||||
break;
|
||||
case BQ24193_FastChargeCurrentLimit: // Fast charge current limit (mA).
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgCurr);
|
||||
data = (data & BQ24193_CHRGCURR_ICHG_MASK) >> 2;
|
||||
*value += ((data >> 0) & 1) ? 64 : 0;
|
||||
*value += ((data >> 1) & 1) ? 128 : 0;
|
||||
*value += ((data >> 2) & 1) ? 256 : 0;
|
||||
*value += ((data >> 3) & 1) ? 512 : 0;
|
||||
*value += ((data >> 4) & 1) ? 1024 : 0;
|
||||
*value += ((data >> 5) & 1) ? 2048 : 0;
|
||||
*value += 512;
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgCurr);
|
||||
data &= BQ24193_CHRGCURR_20PCT_MASK;
|
||||
if (data)
|
||||
*value = *value * 20 / 100; // Fast charge current limit is 20%.
|
||||
break;
|
||||
case BQ24193_ChargeVoltageLimit: // Charge voltage limit (mV).
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgVolt);
|
||||
data = (data & BQ24193_CHRGVOLT_VREG) >> 2;
|
||||
*value += ((data >> 0) & 1) ? 16 : 0;
|
||||
*value += ((data >> 1) & 1) ? 32 : 0;
|
||||
*value += ((data >> 2) & 1) ? 64 : 0;
|
||||
*value += ((data >> 3) & 1) ? 128 : 0;
|
||||
*value += ((data >> 4) & 1) ? 256 : 0;
|
||||
*value += ((data >> 5) & 1) ? 512 : 0;
|
||||
*value += 3504;
|
||||
break;
|
||||
case BQ24193_RechargeThreshold: // Recharge voltage threshold less than voltage limit (mV).
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgVolt);
|
||||
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
||||
if (data)
|
||||
*value = 300;
|
||||
else
|
||||
*value = 100;
|
||||
break;
|
||||
case BQ24193_ThermalRegulation: // Thermal regulation threshold (oC).
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_IRCompThermal);
|
||||
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
*value = 60;
|
||||
break;
|
||||
case 1:
|
||||
*value = 80;
|
||||
break;
|
||||
case 2:
|
||||
*value = 100;
|
||||
break;
|
||||
case 3:
|
||||
*value = 120;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BQ24193_ChargeStatus: // 0: Not charging, 1: Pre-charge, 2: Fast charging, 3: Charge termination done
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Status);
|
||||
*value = (data & BQ24193_STATUS_CHRG_MASK) >> 4;
|
||||
break;
|
||||
case BQ24193_TempStatus: // 0: Normal, 2: Warm, 3: Cool, 5: Cold, 6: Hot.
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_FaultReg);
|
||||
*value = data & BQ24193_FAULT_THERM_MASK;
|
||||
break;
|
||||
case BQ24193_DevID: // Dev ID.
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_VendorPart);
|
||||
*value = data & BQ24193_VENDORPART_DEV_MASK;
|
||||
break;
|
||||
case BQ24193_ProductNumber: // Product number.
|
||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_VendorPart);
|
||||
*value = (data & BQ24193_VENDORPART_PN_MASK) >> 3;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bq24193_fake_battery_removal()
|
||||
{
|
||||
u8 value;
|
||||
|
||||
// Disable watchdog to keep BATFET disabled.
|
||||
value = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer);
|
||||
value &= ~BQ24193_CHRGTERM_WATCHDOG_MASK;
|
||||
i2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer, value);
|
||||
|
||||
// Force BATFET to disabled state. This disconnects the battery from the system.
|
||||
value = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc);
|
||||
value |= BQ24193_MISC_BATFET_DI_MASK;
|
||||
i2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc, value);
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Battery charger driver for Nintendo Switch's TI BQ24193
|
||||
*
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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 __BQ24193_H_
|
||||
#define __BQ24193_H_
|
||||
|
||||
#define BQ24193_I2C_ADDR 0x6B
|
||||
|
||||
// REG 0 masks.
|
||||
#define BQ24193_INCONFIG_INLIMIT_MASK (7<<0)
|
||||
#define BQ24193_INCONFIG_VINDPM_MASK 0x78
|
||||
#define BQ24193_INCONFIG_HIZ_EN_MASK (1<<7)
|
||||
|
||||
// REG 1 masks.
|
||||
#define BQ24193_PORCONFIG_BOOST_MASK (1<<0)
|
||||
#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1)
|
||||
#define BQ24193_PORCONFIG_CHGCONFIG_MASK (3<<4)
|
||||
#define BQ24193_PORCONFIG_I2CWATCHDOG_MASK (1<<6)
|
||||
#define BQ24193_PORCONFIG_RESET_MASK (1<<7)
|
||||
|
||||
// REG 2 masks.
|
||||
#define BQ24193_CHRGCURR_20PCT_MASK (1<<0)
|
||||
#define BQ24193_CHRGCURR_ICHG_MASK 0xFC
|
||||
|
||||
// REG 3 masks.
|
||||
#define BQ24193_PRECHRG_ITERM 0x0F
|
||||
#define BQ24193_PRECHRG_IPRECHG 0xF0
|
||||
|
||||
// REG 4 masks.
|
||||
#define BQ24193_CHRGVOLT_VTHRES (1<<0)
|
||||
#define BQ24193_CHRGVOLT_BATTLOW (1<<1)
|
||||
#define BQ24193_CHRGVOLT_VREG 0xFC
|
||||
|
||||
// REG 5 masks.
|
||||
#define BQ24193_CHRGTERM_ISET_MASK (1<<0)
|
||||
#define BQ24193_CHRGTERM_CHGTIMER_MASK (3<<1)
|
||||
#define BQ24193_CHRGTERM_ENTIMER_MASK (1<<3)
|
||||
#define BQ24193_CHRGTERM_WATCHDOG_MASK (3<<4)
|
||||
#define BQ24193_CHRGTERM_TERM_ST_MASK (1<<6)
|
||||
#define BQ24193_CHRGTERM_TERM_EN_MASK (1<<7)
|
||||
|
||||
// REG 6 masks.
|
||||
#define BQ24193_IRTHERMAL_THERM_MASK (3<<0)
|
||||
#define BQ24193_IRTHERMAL_VCLAMP_MASK (7<<2)
|
||||
#define BQ24193_IRTHERMAL_BATTCOMP_MASK (7<<5)
|
||||
|
||||
// REG 7 masks.
|
||||
#define BQ24193_MISC_INT_MASK (3<<0)
|
||||
#define BQ24193_MISC_VSET_MASK (1<<4)
|
||||
#define BQ24193_MISC_BATFET_DI_MASK (1<<5)
|
||||
#define BQ24193_MISC_TMR2X_EN_MASK (1<<6)
|
||||
#define BQ24193_MISC_DPDM_EN_MASK (1<<7)
|
||||
|
||||
// REG 8 masks.
|
||||
#define BQ24193_STATUS_VSYS_MASK (1<<0)
|
||||
#define BQ24193_STATUS_THERM_MASK (1<<1)
|
||||
#define BQ24193_STATUS_PG_MASK (1<<2)
|
||||
#define BQ24193_STATUS_DPM_MASK (1<<3)
|
||||
#define BQ24193_STATUS_CHRG_MASK (3<<4)
|
||||
#define BQ24193_STATUS_VBUS_MASK (3<<6)
|
||||
|
||||
// REG 9 masks.
|
||||
#define BQ24193_FAULT_THERM_MASK (7<<0)
|
||||
#define BQ24193_FAULT_BATT_OVP_MASK (1<<3)
|
||||
#define BQ24193_FAULT_CHARGE_MASK (3<<4)
|
||||
#define BQ24193_FAULT_BOOST_MASK (1<<6)
|
||||
#define BQ24193_FAULT_WATCHDOG_MASK (1<<7)
|
||||
|
||||
// REG A masks.
|
||||
#define BQ24193_VENDORPART_DEV_MASK (3<<0)
|
||||
#define BQ24193_VENDORPART_PN_MASK (7<<3)
|
||||
|
||||
enum BQ24193_reg {
|
||||
BQ24193_InputSource = 0x00,
|
||||
BQ24193_PORConfig = 0x01,
|
||||
BQ24193_ChrgCurr = 0x02,
|
||||
BQ24193_PreChrgTerm = 0x03,
|
||||
BQ24193_ChrgVolt = 0x04,
|
||||
BQ24193_ChrgTermTimer = 0x05,
|
||||
BQ24193_IRCompThermal = 0x06,
|
||||
BQ24193_Misc = 0x07,
|
||||
BQ24193_Status = 0x08,
|
||||
BQ24193_FaultReg = 0x09,
|
||||
BQ24193_VendorPart = 0x0A,
|
||||
};
|
||||
|
||||
enum BQ24193_reg_prop {
|
||||
BQ24193_InputVoltageLimit, // REG 0.
|
||||
BQ24193_InputCurrentLimit, // REG 0.
|
||||
BQ24193_SystemMinimumVoltage, // REG 1.
|
||||
BQ24193_FastChargeCurrentLimit, // REG 2.
|
||||
BQ24193_ChargeVoltageLimit, // REG 4.
|
||||
BQ24193_RechargeThreshold, // REG 4.
|
||||
BQ24193_ThermalRegulation, // REG 6.
|
||||
BQ24193_ChargeStatus, // REG 8.
|
||||
BQ24193_TempStatus, // REG 9.
|
||||
BQ24193_DevID, // REG A.
|
||||
BQ24193_ProductNumber, // REG A.
|
||||
};
|
||||
|
||||
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value);
|
||||
void bq24193_fake_battery_removal();
|
||||
|
||||
#endif /* __BQ24193_H_ */
|
||||
@@ -1,266 +0,0 @@
|
||||
/*
|
||||
* Fuel gauge driver for Nintendo Switch's Maxim 17050
|
||||
*
|
||||
* Copyright (C) 2011 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* This driver is based on max17040_battery.c
|
||||
*/
|
||||
|
||||
#include "max17050.h"
|
||||
#include "../soc/i2c.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
/* Status register bits */
|
||||
#define STATUS_POR_BIT (1 << 1)
|
||||
#define STATUS_BST_BIT (1 << 3)
|
||||
#define STATUS_VMN_BIT (1 << 8)
|
||||
#define STATUS_TMN_BIT (1 << 9)
|
||||
#define STATUS_SMN_BIT (1 << 10)
|
||||
#define STATUS_BI_BIT (1 << 11)
|
||||
#define STATUS_VMX_BIT (1 << 12)
|
||||
#define STATUS_TMX_BIT (1 << 13)
|
||||
#define STATUS_SMX_BIT (1 << 14)
|
||||
#define STATUS_BR_BIT (1 << 15)
|
||||
|
||||
#define VFSOC0_LOCK 0x0000
|
||||
#define VFSOC0_UNLOCK 0x0080
|
||||
|
||||
#define MAX17050_VMAX_TOLERANCE 50 /* 50 mV */
|
||||
|
||||
int max17050_get_property(enum MAX17050_reg reg, int *value)
|
||||
{
|
||||
u16 data;
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case MAX17050_Age: // Age (percent). Based on 100% x (FullCAP Register/DesignCap).
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Age);
|
||||
*value = data >> 8; /* Show MSB. 1% increments */
|
||||
break;
|
||||
case MAX17050_Cycles: // Cycle count.
|
||||
i2c_recv_buf_small((u8 *)value, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Cycles);
|
||||
break;
|
||||
case MAX17050_MinVolt: // Voltage max/min
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MinMaxVolt);
|
||||
*value = (data & 0xff) * 20; /* Voltage MIN. Units of 20mV */
|
||||
break;
|
||||
case MAX17050_MaxVolt: // Voltage max/min
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MinMaxVolt);
|
||||
*value = (data >> 8) * 20; /* Voltage MAX. Units of LSB = 20mV */
|
||||
break;
|
||||
case MAX17050_V_empty: // Voltage min design.
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_V_empty);
|
||||
*value = (data >> 7) * 10; /* Units of LSB = 10mV */
|
||||
break;
|
||||
case MAX17050_VCELL: // Voltage now.
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VCELL);
|
||||
*value = data * 625 / 8 / 1000;
|
||||
break;
|
||||
case MAX17050_AvgVCELL: // Voltage avg.
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgVCELL);
|
||||
*value = data * 625 / 8 / 1000;
|
||||
break;
|
||||
case MAX17050_OCVInternal: // Voltage ocv.
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_OCVInternal);
|
||||
*value = data * 625 / 8 / 1000;
|
||||
break;
|
||||
case MAX17050_RepSOC: // Capacity %.
|
||||
i2c_recv_buf_small((u8 *)value, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepSOC);
|
||||
break;
|
||||
case MAX17050_DesignCap: // Charge full design.
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_DesignCap);
|
||||
data = data * 5 / 10;
|
||||
*value = data;
|
||||
break;
|
||||
case MAX17050_FullCAP: // Charge full.
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FullCAP);
|
||||
data = data * 5 / 10;
|
||||
*value = data;
|
||||
break;
|
||||
case MAX17050_RepCap: // Charge now.
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepCap);
|
||||
data = data * 5 / 10;
|
||||
*value = data;
|
||||
break;
|
||||
case MAX17050_TEMP: // Temp.
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_TEMP);
|
||||
*value = (s16)data;
|
||||
*value = *value * 10 / 256;
|
||||
break;
|
||||
case MAX17050_Current: // Current now.
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Current);
|
||||
*value = (s16)data;
|
||||
*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR;
|
||||
break;
|
||||
case MAX17050_AvgCurrent: // Current avg.
|
||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgCurrent);
|
||||
*value = (s16)data;
|
||||
*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _max17050_write_verify_reg(u8 reg, u16 value)
|
||||
{
|
||||
int retries = 8;
|
||||
int ret;
|
||||
u16 read_value;
|
||||
|
||||
do
|
||||
{
|
||||
ret = i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, reg, (u8 *)&value, 2);
|
||||
i2c_recv_buf_small((u8 *)&read_value, 2, I2C_1, MAXIM17050_I2C_ADDR, reg);
|
||||
if (read_value != value)
|
||||
{
|
||||
ret = -1;
|
||||
retries--;
|
||||
}
|
||||
} while (retries && read_value != value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void _max17050_override_por(u8 reg, u16 value)
|
||||
{
|
||||
if (value)
|
||||
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, reg, (u8 *)&value, 2);
|
||||
}
|
||||
|
||||
static void _max17050_load_new_capacity_params()
|
||||
{
|
||||
u16 fullcap, repSoc, dq_acc, dp_acc;
|
||||
|
||||
fullcap = 0x2476; // 4667mAh design capacity.
|
||||
dq_acc = 0x10bc; // From a healthy fuel gauge.
|
||||
dp_acc = 0x5e09; // =||=
|
||||
repSoc = 0x6400; // 100%.
|
||||
|
||||
_max17050_write_verify_reg(MAX17050_RemCap, fullcap);
|
||||
_max17050_write_verify_reg(MAX17050_RepCap, fullcap);
|
||||
|
||||
_max17050_write_verify_reg(MAX17050_dQacc, dq_acc);
|
||||
_max17050_write_verify_reg(MAX17050_dPacc, dp_acc);
|
||||
|
||||
_max17050_write_verify_reg(MAX17050_FullCAP, fullcap);
|
||||
//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_DesignCap, (u8 *)&fullcap, 2);
|
||||
_max17050_write_verify_reg(MAX17050_FullCAPNom, fullcap);
|
||||
/* Update SOC register with new SOC */
|
||||
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepSOC, (u8 *)&repSoc, 2);
|
||||
}
|
||||
|
||||
static void _max17050_reset_vfsoc0_reg()
|
||||
{
|
||||
u16 lockVal = 0;
|
||||
u16 vfSoc = 0x6440; // >100% for fully charged battery
|
||||
|
||||
lockVal = VFSOC0_UNLOCK;
|
||||
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VFSOC0Enable, (u8 *)&lockVal, 2);
|
||||
|
||||
_max17050_write_verify_reg(MAX17050_VFSOC0, vfSoc);
|
||||
|
||||
lockVal = VFSOC0_LOCK;
|
||||
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VFSOC0Enable, (u8 *)&lockVal, 2);
|
||||
}
|
||||
|
||||
static void _max17050_update_capacity_regs()
|
||||
{
|
||||
u16 value = 0x2476; // Set to 4667mAh design capacity.
|
||||
_max17050_write_verify_reg(MAX17050_FullCAP, value);
|
||||
_max17050_write_verify_reg(MAX17050_FullCAPNom, value);
|
||||
//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_DesignCap, config->design_cap, 2);
|
||||
}
|
||||
|
||||
static void _max17050_write_config_regs()
|
||||
{
|
||||
u16 value = 0;
|
||||
|
||||
value = 0x7254;
|
||||
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_CONFIG, (u8 *)&value, 2);
|
||||
value = 0x2473;
|
||||
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_LearnCFG, (u8 *)&value, 2);
|
||||
//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FilterCFG, (u8 *)&value, 2)
|
||||
//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RelaxCFG, (u8 *)&value, 2)
|
||||
//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FullSOCThr, (u8 *)&value, 2)
|
||||
}
|
||||
|
||||
/*
|
||||
* Block write all the override values coming from platform data.
|
||||
* This function MUST be called before the POR initialization proceedure
|
||||
* specified by maxim.
|
||||
*/
|
||||
static void _max17050_override_por_values()
|
||||
{
|
||||
u16 dq_acc = 0x10bc; // From a healthy fuel gauge.
|
||||
u16 dp_acc = 0x5e09; // =||=
|
||||
|
||||
_max17050_override_por(MAX17050_dQacc, dq_acc);
|
||||
_max17050_override_por(MAX17050_dPacc, dp_acc);
|
||||
|
||||
//_max17050_override_por(MAX17050_RCOMP0, config->rcomp0); //0x58
|
||||
//_max17050_override_por(MAX17050_TempCo, config->tcompc0); //0x1b22
|
||||
|
||||
//u16 k_empty0 = 0x439;
|
||||
//_max17050_override_por(map, MAX17050_K_empty0, k_empty0); // Unknown cell data
|
||||
}
|
||||
|
||||
static void _max17050_set_por_bit(u16 value)
|
||||
{
|
||||
_max17050_write_verify_reg(MAX17050_STATUS, value);
|
||||
}
|
||||
|
||||
int max17050_fix_configuration()
|
||||
{
|
||||
/* Init phase, set the POR bit */
|
||||
_max17050_set_por_bit(STATUS_POR_BIT);
|
||||
|
||||
/* Override POR values */
|
||||
_max17050_override_por_values();
|
||||
/* After Power up, the MAX17050 requires 500ms in order
|
||||
* to perform signal debouncing and initial SOC reporting
|
||||
*/
|
||||
msleep(500);
|
||||
|
||||
/* Initialize configaration */
|
||||
_max17050_write_config_regs();
|
||||
|
||||
/* update capacity params */
|
||||
_max17050_update_capacity_regs();
|
||||
|
||||
/* delay must be atleast 350mS to allow VFSOC
|
||||
* to be calculated from the new configuration
|
||||
*/
|
||||
msleep(350);
|
||||
|
||||
/* reset vfsoc0 reg */
|
||||
_max17050_reset_vfsoc0_reg();
|
||||
|
||||
/* load new capacity params */
|
||||
_max17050_load_new_capacity_params();
|
||||
|
||||
/* Init complete, Clear the POR bit */
|
||||
//_max17050_set_por_bit(0); // Should we? Or let the switch to reconfigure POR?
|
||||
|
||||
// Sets POR, BI, BR.
|
||||
_max17050_set_por_bit(0x8801);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Fuel gauge driver for Nintendo Switch's Maxim 17050
|
||||
* Note that Maxim 8966 and 8997 are mfd and this is its subdevice.
|
||||
*
|
||||
* Copyright (C) 2011 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __MAX17050_H_
|
||||
#define __MAX17050_H_
|
||||
|
||||
#define MAX17050_STATUS_BattAbsent (1 << 3)
|
||||
#define MAX17050_DEFAULT_SNS_RESISTOR 10000
|
||||
|
||||
/* Consider RepCap which is less then 10 units below FullCAP full */
|
||||
#define MAX17050_FULL_THRESHOLD 10
|
||||
|
||||
#define MAX17050_CHARACTERIZATION_DATA_SIZE 48
|
||||
|
||||
#define MAXIM17050_I2C_ADDR 0x36
|
||||
|
||||
enum MAX17050_reg {
|
||||
MAX17050_STATUS = 0x00,
|
||||
MAX17050_VALRT_Th = 0x01,
|
||||
MAX17050_TALRT_Th = 0x02,
|
||||
MAX17050_SALRT_Th = 0x03,
|
||||
MAX17050_AtRate = 0x04,
|
||||
MAX17050_RepCap = 0x05,
|
||||
MAX17050_RepSOC = 0x06,
|
||||
MAX17050_Age = 0x07,
|
||||
MAX17050_TEMP = 0x08,
|
||||
MAX17050_VCELL = 0x09,
|
||||
MAX17050_Current = 0x0A,
|
||||
MAX17050_AvgCurrent = 0x0B,
|
||||
|
||||
MAX17050_SOC = 0x0D,
|
||||
MAX17050_AvSOC = 0x0E,
|
||||
MAX17050_RemCap = 0x0F,
|
||||
MAX17050_FullCAP = 0x10,
|
||||
MAX17050_TTE = 0x11,
|
||||
MAX17050_QRTbl00 = 0x12,
|
||||
MAX17050_FullSOCThr = 0x13,
|
||||
MAX17050_RSLOW = 0x14,
|
||||
|
||||
MAX17050_AvgTA = 0x16,
|
||||
MAX17050_Cycles = 0x17,
|
||||
MAX17050_DesignCap = 0x18,
|
||||
MAX17050_AvgVCELL = 0x19,
|
||||
MAX17050_MinMaxTemp = 0x1A,
|
||||
MAX17050_MinMaxVolt = 0x1B,
|
||||
MAX17050_MinMaxCurr = 0x1C,
|
||||
MAX17050_CONFIG = 0x1D,
|
||||
MAX17050_ICHGTerm = 0x1E,
|
||||
MAX17050_AvCap = 0x1F,
|
||||
MAX17050_ManName = 0x20,
|
||||
MAX17050_DevName = 0x21,
|
||||
MAX17050_QRTbl10 = 0x22,
|
||||
MAX17050_FullCAPNom = 0x23,
|
||||
MAX17050_TempNom = 0x24,
|
||||
MAX17050_TempLim = 0x25,
|
||||
MAX17050_TempHot = 0x26,
|
||||
MAX17050_AIN = 0x27,
|
||||
MAX17050_LearnCFG = 0x28,
|
||||
MAX17050_FilterCFG = 0x29,
|
||||
MAX17050_RelaxCFG = 0x2A,
|
||||
MAX17050_MiscCFG = 0x2B,
|
||||
MAX17050_TGAIN = 0x2C,
|
||||
MAX17050_TOFF = 0x2D,
|
||||
MAX17050_CGAIN = 0x2E,
|
||||
MAX17050_COFF = 0x2F,
|
||||
|
||||
MAX17050_QRTbl20 = 0x32,
|
||||
MAX17050_SOC_empty = 0x33,
|
||||
MAX17050_T_empty = 0x34,
|
||||
MAX17050_FullCAP0 = 0x35,
|
||||
MAX17050_LAvg_empty = 0x36,
|
||||
MAX17050_FCTC = 0x37,
|
||||
MAX17050_RCOMP0 = 0x38,
|
||||
MAX17050_TempCo = 0x39,
|
||||
MAX17050_V_empty = 0x3A,
|
||||
MAX17050_K_empty0 = 0x3B,
|
||||
MAX17050_TaskPeriod = 0x3C,
|
||||
MAX17050_FSTAT = 0x3D,
|
||||
|
||||
MAX17050_SHDNTIMER = 0x3F,
|
||||
MAX17050_QRTbl30 = 0x42,
|
||||
MAX17050_dQacc = 0x45,
|
||||
MAX17050_dPacc = 0x46,
|
||||
|
||||
MAX17050_VFSOC0 = 0x48,
|
||||
|
||||
MAX17050_QH = 0x4D,
|
||||
MAX17050_QL = 0x4E,
|
||||
|
||||
MAX17050_MinVolt = 0x50, // Custom ID. Not to be sent to i2c.
|
||||
MAX17050_MaxVolt = 0x51, // Custom ID. Not to be sent to i2c.
|
||||
|
||||
MAX17050_VFSOC0Enable = 0x60,
|
||||
|
||||
MAX17050_MODELChrTbl = 0x80,
|
||||
|
||||
MAX17050_OCV = 0xEE,
|
||||
|
||||
MAX17050_OCVInternal = 0xFB,
|
||||
|
||||
MAX17050_VFSOC = 0xFF,
|
||||
};
|
||||
|
||||
int max17050_get_property(enum MAX17050_reg reg, int *value);
|
||||
int max17050_fix_configuration();
|
||||
|
||||
#endif /* __MAX17050_H_ */
|
||||
@@ -1,114 +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 _MAX7762X_H_
|
||||
#define _MAX7762X_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
/*
|
||||
* Switch Power domains (max77620):
|
||||
* Name | Usage | uV step | uV min | uV default | uV max | Init
|
||||
*-------+---------------+---------+--------+------------+---------+------------------
|
||||
* sd0 | core | 12500 | 600000 | 625000 | 1400000 | 1.125V (pkg1.1)
|
||||
* sd1 | SDRAM | 12500 | 600000 | 1125000 | 1125000 | 1.1V (pkg1.1)
|
||||
* sd2 | ldo{0-1, 7-8} | 12500 | 600000 | 1325000 | 1350000 | 1.325V (pcv)
|
||||
* sd3 | 1.8V general | 12500 | 600000 | 1800000 | 1800000 |
|
||||
* ldo0 | Display Panel | 25000 | 800000 | 1200000 | 1200000 | 1.2V (pkg1.1)
|
||||
* ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
|
||||
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
|
||||
* ldo3 | | 50000 | 800000 | 3100000 | 3100000 |
|
||||
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 |
|
||||
* ldo5 | | 50000 | 800000 | 1800000 | 1800000 |
|
||||
* ldo6 | | 50000 | 800000 | 2900000 | 2900000 |
|
||||
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 |
|
||||
* ldo8 | XUSB, DC | 50000 | 800000 | 1050000 | 1050000 |
|
||||
*/
|
||||
|
||||
/*
|
||||
* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode
|
||||
* MAX77620_REG_GPIOx: 0x9 sets output and enable
|
||||
*/
|
||||
|
||||
/*! MAX77620 partitions. */
|
||||
#define REGULATOR_SD0 0
|
||||
#define REGULATOR_SD1 1
|
||||
#define REGULATOR_SD2 2
|
||||
#define REGULATOR_SD3 3
|
||||
#define REGULATOR_LDO0 4
|
||||
#define REGULATOR_LDO1 5
|
||||
#define REGULATOR_LDO2 6
|
||||
#define REGULATOR_LDO3 7
|
||||
#define REGULATOR_LDO4 8
|
||||
#define REGULATOR_LDO5 9
|
||||
#define REGULATOR_LDO6 10
|
||||
#define REGULATOR_LDO7 11
|
||||
#define REGULATOR_LDO8 12
|
||||
#define REGULATOR_MAX 12
|
||||
|
||||
#define MAX77621_CPU_I2C_ADDR 0x1B
|
||||
#define MAX77621_GPU_I2C_ADDR 0x1C
|
||||
|
||||
#define MAX77621_VOUT_REG 0
|
||||
#define MAX77621_VOUT_DVC_REG 1
|
||||
#define MAX77621_CONTROL1_REG 2
|
||||
#define MAX77621_CONTROL2_REG 3
|
||||
|
||||
/* MAX77621_VOUT */
|
||||
#define MAX77621_VOUT_ENABLE (1 << 7)
|
||||
#define MAX77621_VOUT_MASK 0x7F
|
||||
|
||||
/* MAX77621_VOUT_DVC_DVS */
|
||||
#define MAX77621_DVS_VOUT_MASK 0x7F
|
||||
|
||||
/* MAX77621_CONTROL1 */
|
||||
#define MAX77621_SNS_ENABLE (1 << 7)
|
||||
#define MAX77621_FPWM_EN_M (1 << 6)
|
||||
#define MAX77621_NFSR_ENABLE (1 << 5)
|
||||
#define MAX77621_AD_ENABLE (1 << 4)
|
||||
#define MAX77621_BIAS_ENABLE (1 << 3)
|
||||
#define MAX77621_FREQSHIFT_9PER (1 << 2)
|
||||
|
||||
#define MAX77621_RAMP_12mV_PER_US 0x0
|
||||
#define MAX77621_RAMP_25mV_PER_US 0x1
|
||||
#define MAX77621_RAMP_50mV_PER_US 0x2
|
||||
#define MAX77621_RAMP_200mV_PER_US 0x3
|
||||
#define MAX77621_RAMP_MASK 0x3
|
||||
|
||||
/* MAX77621_CONTROL2 */
|
||||
#define MAX77621_WDTMR_ENABLE (1 << 6)
|
||||
#define MAX77621_DISCH_ENBABLE (1 << 5)
|
||||
#define MAX77621_FT_ENABLE (1 << 4)
|
||||
#define MAX77621_T_JUNCTION_120 (1 << 7)
|
||||
|
||||
#define MAX77621_CKKADV_TRIP_DISABLE 0xC
|
||||
#define MAX77621_CKKADV_TRIP_75mV_PER_US 0x0
|
||||
#define MAX77621_CKKADV_TRIP_150mV_PER_US 0x4
|
||||
#define MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS 0x8
|
||||
|
||||
#define MAX77621_INDUCTOR_MIN_30_PER 0x0
|
||||
#define MAX77621_INDUCTOR_NOMINAL 0x1
|
||||
#define MAX77621_INDUCTOR_PLUS_30_PER 0x2
|
||||
#define MAX77621_INDUCTOR_PLUS_60_PER 0x3
|
||||
|
||||
int max77620_regulator_get_status(u32 id);
|
||||
int max77620_regulator_config_fps(u32 id);
|
||||
int max77620_regulator_set_voltage(u32 id, u32 mv);
|
||||
int max77620_regulator_enable(u32 id, int enable);
|
||||
void max77620_config_default();
|
||||
void max77620_low_battery_monitor_config();
|
||||
|
||||
#endif
|
||||
@@ -1,34 +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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: the placement of the relocator is a bit fragile atm, maybe we
|
||||
* should include it in start.S and copy it to some known good
|
||||
* place in IRAM instead. Basically we want it as far back atm
|
||||
* as it might be overwritten during relocation.
|
||||
*/
|
||||
|
||||
.section .text.reloc
|
||||
.arm
|
||||
|
||||
.globl _reloc_ipl
|
||||
.type _reloc_ipl, %function
|
||||
_reloc_ipl:
|
||||
LDMIA R0!, {R4-R7}
|
||||
STMIA R1!, {R4-R7}
|
||||
SUBS R2, #0x10
|
||||
BNE _reloc_ipl
|
||||
BX R3
|
||||
@@ -1,165 +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 _CLOCK_H_
|
||||
#define _CLOCK_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
/*! Clock registers. */
|
||||
#define CLK_RST_CONTROLLER_RST_SOURCE 0x0
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_L 0x4
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_H 0x8
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_U 0xC
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_L 0x10
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_H 0x14
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_U 0x18
|
||||
#define CLK_RST_CONTROLLER_CCLK_BURST_POLICY 0x20
|
||||
#define CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER 0x24
|
||||
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY 0x28
|
||||
#define CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER 0x2C
|
||||
#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30
|
||||
#define CLK_RST_CONTROLLER_MISC_CLK_ENB 0x48
|
||||
#define CLK_RST_CONTROLLER_OSC_CTRL 0x50
|
||||
#define CLK_RST_CONTROLLER_PLLC_BASE 0x80
|
||||
#define CLK_RST_CONTROLLER_PLLC_MISC 0x88
|
||||
#define CLK_RST_CONTROLLER_PLLM_BASE 0x90
|
||||
#define CLK_RST_CONTROLLER_PLLM_MISC1 0x98
|
||||
#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9C
|
||||
#define CLK_RST_CONTROLLER_PLLP_BASE 0xA0
|
||||
#define CLK_RST_CONTROLLER_PLLD_BASE 0xD0
|
||||
#define CLK_RST_CONTROLLER_PLLX_BASE 0xE0
|
||||
#define CLK_RST_CONTROLLER_PLLX_MISC 0xE4
|
||||
#define CLK_RST_CONTROLLER_PLLE_BASE 0xE8
|
||||
#define CLK_RST_CONTROLLER_PLLE_MISC 0xEC
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA 0xF8
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB 0xFC
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_PWM 0x110
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C1 0x124
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C5 0x128
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_VI 0x148
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1 0x150
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2 0x154
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4 0x164
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA 0x178
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB 0x17C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X 0x180
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC 0x1A0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C3 0x1B8
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 0x1BC
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_CSITE 0x1D4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_TSEC 0x1F4
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X 0x280
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_X_CLR 0x288
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_X 0x28C
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_X_SET 0x290
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_X_CLR 0x294
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_Y 0x298
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_Y_SET 0x29C
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_Y_CLR 0x2A0
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_Y 0x2A4
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2A8
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2AC
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_L_SET 0x300
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_L_CLR 0x304
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_H_CLR 0x30C
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_U_SET 0x310
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_U_CLR 0x314
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_L_SET 0x320
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_L_CLR 0x324
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_H_CLR 0x32C
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_U_SET 0x330
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_U_CLR 0x334
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_V 0x358
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_W 0x35C
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_V 0x360
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_W 0x364
|
||||
#define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2 0x388
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC 0x3A0
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3A4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_V_SET 0x440
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_W_SET 0x448
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_W_CLR 0x44C
|
||||
#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET 0x450
|
||||
#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR 0x454
|
||||
#define CLK_RST_CONTROLLER_UTMIP_PLL_CFG2 0x488
|
||||
#define CLK_RST_CONTROLLER_PLLE_AUX 0x48C
|
||||
#define CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S0 0x4A0
|
||||
#define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE 0x554
|
||||
#define CLK_RST_CONTROLLER_SPARE_REG0 0x55C
|
||||
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP 0x620
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIP_CAL 0x66C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0
|
||||
#define CLK_RST_CONTROLLER_SE_SUPER_CLK_DIVIDER 0x704
|
||||
|
||||
/*! Generic clock descriptor. */
|
||||
typedef struct _clock_t
|
||||
{
|
||||
u32 reset;
|
||||
u32 enable;
|
||||
u32 source;
|
||||
u8 index;
|
||||
u8 clk_src;
|
||||
u8 clk_div;
|
||||
} clock_t;
|
||||
|
||||
/*! Generic clock enable/disable. */
|
||||
void clock_enable(const clock_t *clk);
|
||||
void clock_disable(const clock_t *clk);
|
||||
|
||||
/*! Clock control for specific hardware portions. */
|
||||
void clock_enable_fuse(bool enable);
|
||||
void clock_enable_uart(u32 idx);
|
||||
void clock_enable_i2c(u32 idx);
|
||||
void clock_disable_i2c(u32 idx);
|
||||
void clock_enable_se();
|
||||
void clock_enable_unk2();
|
||||
void clock_enable_host1x();
|
||||
void clock_disable_host1x();
|
||||
void clock_enable_tsec();
|
||||
void clock_disable_tsec();
|
||||
void clock_enable_sor_safe();
|
||||
void clock_disable_sor_safe();
|
||||
void clock_enable_sor0();
|
||||
void clock_disable_sor0();
|
||||
void clock_enable_sor1();
|
||||
void clock_disable_sor1();
|
||||
void clock_enable_kfuse();
|
||||
void clock_disable_kfuse();
|
||||
void clock_enable_cl_dvfs();
|
||||
void clock_disable_cl_dvfs();
|
||||
void clock_enable_coresight();
|
||||
void clock_disable_coresight();
|
||||
void clock_enable_pwm();
|
||||
void clock_disable_pwm();
|
||||
void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val);
|
||||
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type);
|
||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
||||
void clock_sdmmc_enable(u32 id, u32 val);
|
||||
void clock_sdmmc_disable(u32 id);
|
||||
|
||||
#endif
|
||||
@@ -1,130 +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/>.
|
||||
*/
|
||||
|
||||
#include "../soc/cluster.h"
|
||||
#include "../soc/i2c.h"
|
||||
#include "../soc/clock.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../soc/pmc.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../power/max77620.h"
|
||||
#include "../power/max7762x.h"
|
||||
|
||||
void _cluster_enable_power()
|
||||
{
|
||||
u8 tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO, tmp & 0xDF);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, MAX77620_CNFG_GPIO_DRV_PUSHPULL | MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH);
|
||||
|
||||
// Enable cores power.
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL1_REG,
|
||||
MAX77621_AD_ENABLE | MAX77621_NFSR_ENABLE | MAX77621_SNS_ENABLE); // 1-3.x: MAX77621_NFSR_ENABLE
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL2_REG,
|
||||
MAX77621_T_JUNCTION_120 | MAX77621_WDTMR_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US| MAX77621_INDUCTOR_NOMINAL); // 1-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_ENABLE | 0x37);
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVC_REG, MAX77621_VOUT_ENABLE | 0x37);
|
||||
}
|
||||
|
||||
int _cluster_pmc_enable_partition(u32 part, u32 toggle, bool enable)
|
||||
{
|
||||
// Check if the partition has already been turned on.
|
||||
if (enable && PMC(APBDEV_PMC_PWRGATE_STATUS) & part)
|
||||
return 1;
|
||||
|
||||
u32 i = 5001;
|
||||
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)
|
||||
{
|
||||
usleep(1);
|
||||
i--;
|
||||
if (i < 1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
PMC(APBDEV_PMC_PWRGATE_TOGGLE) = toggle | (enable ? 0x100 : 0);
|
||||
|
||||
i = 5001;
|
||||
while (i > 0)
|
||||
{
|
||||
if (PMC(APBDEV_PMC_PWRGATE_STATUS) & part)
|
||||
break;
|
||||
usleep(1);
|
||||
i--;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cluster_boot_cpu0(u32 entry)
|
||||
{
|
||||
// Set ACTIVE_CLUSER to FAST.
|
||||
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE;
|
||||
|
||||
_cluster_enable_power();
|
||||
|
||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000))
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7;
|
||||
usleep(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_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;
|
||||
|
||||
// Configure initial CPU clock frequency and enable clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888;
|
||||
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = 1;
|
||||
|
||||
clock_enable_coresight();
|
||||
|
||||
// CAR2PMC_CPU_ACK_WIDTH should be set to 0.
|
||||
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;
|
||||
|
||||
// Enable CPU rail.
|
||||
_cluster_pmc_enable_partition(1, 0, true);
|
||||
// Enable cluster 0 non-CPU.
|
||||
_cluster_pmc_enable_partition(0x8000, 15, true);
|
||||
// Enable CE0.
|
||||
_cluster_pmc_enable_partition(0x4000, 14, true);
|
||||
|
||||
// Request and wait for RAM repair.
|
||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1;
|
||||
while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & 2))
|
||||
;
|
||||
|
||||
EXCP_VEC(0x100) = 0;
|
||||
|
||||
// Set reset vector.
|
||||
SB(SB_AA64_RESET_LOW) = entry | 1;
|
||||
SB(SB_AA64_RESET_HIGH) = 0;
|
||||
// Non-secure reset vector write disable.
|
||||
SB(SB_CSR) = 2;
|
||||
(void)SB(SB_CSR);
|
||||
|
||||
// Clear MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7;
|
||||
// Clear NONCPU reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
|
||||
// Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x411F000F;
|
||||
}
|
||||
@@ -1,37 +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 _CLUSTER_H_
|
||||
#define _CLUSTER_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
/*! Flow controller registers. */
|
||||
#define LOW_CTLR_HALT_CPU0_EVENTS 0x0
|
||||
#define LOW_CTLR_HALT_CPU1_EVENTS 0x14
|
||||
#define LOW_CTLR_HALT_CPU2_EVENTS 0x1C
|
||||
#define LOW_CTLR_HALT_CPU3_EVENTS 0x24
|
||||
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
|
||||
#define FLOW_CTLR_CPU0_CSR 0x8
|
||||
#define FLOW_CTLR_CPU1_CSR 0x18
|
||||
#define FLOW_CTLR_CPU2_CSR 0x20
|
||||
#define FLOW_CTLR_CPU3_CSR 0x28
|
||||
#define FLOW_CTLR_RAM_REPAIR 0x40
|
||||
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98
|
||||
|
||||
void cluster_boot_cpu0(u32 entry);
|
||||
|
||||
#endif
|
||||
@@ -1,325 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../soc/fuse.h"
|
||||
#include "../soc/t210.h"
|
||||
|
||||
#define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))
|
||||
|
||||
static const u32 evp_thunk_template[] = {
|
||||
0xe92d0007, // STMFD SP!, {R0-R2}
|
||||
0xe1a0200e, // MOV R2, LR
|
||||
0xe2422002, // SUB R2, R2, #2
|
||||
0xe5922000, // LDR R2, [R2]
|
||||
0xe20220ff, // AND R2, R2, #0xFF
|
||||
0xe1a02082, // MOV R2, R2,LSL#1
|
||||
0xe59f001c, // LDR R0, =evp_thunk_template
|
||||
0xe59f101c, // LDR R1, =thunk_end
|
||||
0xe0411000, // SUB R1, R1, R0
|
||||
0xe59f0018, // LDR R0, =iram_evp_thunks
|
||||
0xe0800001, // ADD R0, R0, R1
|
||||
0xe0822000, // ADD R2, R2, R0
|
||||
0xe3822001, // ORR R2, R2, #1
|
||||
0xe8bd0003, // LDMFD SP!, {R0,R1}
|
||||
0xe12fff12, // BX R2
|
||||
0x001007b0, // off_1007EC DCD evp_thunk_template
|
||||
0x001007f8, // off_1007F0 DCD thunk_end
|
||||
0x40004c30, // off_1007F4 DCD iram_evp_thunks
|
||||
// thunk_end is here
|
||||
};
|
||||
static const u32 evp_thunk_template_len = sizeof(evp_thunk_template);
|
||||
|
||||
// treated as 12bit values
|
||||
static const u32 hash_vals[] = {1, 2, 4, 8, 0, 3, 5, 6, 7, 9, 10, 11};
|
||||
|
||||
void fuse_disable_program()
|
||||
{
|
||||
FUSE(FUSE_DISABLEREGPROGRAM) = 1;
|
||||
}
|
||||
|
||||
u32 fuse_read_odm(u32 idx)
|
||||
{
|
||||
return FUSE(FUSE_RESERVED_ODMX(idx));
|
||||
}
|
||||
|
||||
void fuse_wait_idle()
|
||||
{
|
||||
u32 ctrl;
|
||||
do
|
||||
{
|
||||
ctrl = FUSE(FUSE_CTRL);
|
||||
} while (((ctrl >> 16) & 0x1f) != 4);
|
||||
}
|
||||
|
||||
u32 parity32_even(u32 *words, u32 count)
|
||||
{
|
||||
u32 acc = words[0];
|
||||
for (u32 i = 1; i < count; i++)
|
||||
{
|
||||
acc ^= words[i];
|
||||
}
|
||||
u32 lo = ((acc & 0xffff) ^ (acc >> 16)) & 0xff;
|
||||
u32 hi = ((acc & 0xffff) ^ (acc >> 16)) >> 8;
|
||||
u32 x = hi ^ lo;
|
||||
lo = ((x & 0xf) ^ (x >> 4)) & 3;
|
||||
hi = ((x & 0xf) ^ (x >> 4)) >> 2;
|
||||
x = hi ^ lo;
|
||||
|
||||
return (x & 1) ^ (x >> 1);
|
||||
}
|
||||
|
||||
int patch_hash_one(u32 *word)
|
||||
{
|
||||
u32 bits20_31 = *word & 0xfff00000;
|
||||
u32 parity_bit = parity32_even(&bits20_31, 1);
|
||||
u32 hash = 0;
|
||||
for (u32 i = 0; i < 12; i++)
|
||||
{
|
||||
if (*word & (1 << (20 + i)))
|
||||
{
|
||||
hash ^= hash_vals[i];
|
||||
}
|
||||
}
|
||||
if (hash == 0)
|
||||
{
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*word ^= 1 << 24;
|
||||
return 1;
|
||||
}
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
for (u32 i = 0; i < ARRAYSIZE(hash_vals); i++)
|
||||
{
|
||||
if (hash_vals[i] == hash)
|
||||
{
|
||||
*word ^= 1 << (20 + i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
int patch_hash_multi(u32 *words, u32 count)
|
||||
{
|
||||
u32 parity_bit = parity32_even(words, count);
|
||||
u32 bits0_14 = words[0] & 0x7fff;
|
||||
u32 bit15 = words[0] & 0x8000;
|
||||
u32 bits16_19 = words[0] & 0xf0000;
|
||||
|
||||
u32 hash = 0;
|
||||
words[0] = bits16_19;
|
||||
for (u32 i = 0; i < count; i++)
|
||||
{
|
||||
u32 w = words[i];
|
||||
if (w)
|
||||
{
|
||||
for (u32 bitpos = 0; bitpos < 32; bitpos++)
|
||||
{
|
||||
if ((w >> bitpos) & 1)
|
||||
{
|
||||
hash ^= 0x4000 + i * 32 + bitpos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
hash ^= bits0_14;
|
||||
// stupid but this is what original code does.
|
||||
// equivalent to original words[0] &= 0xfff00000
|
||||
words[0] = bits16_19 ^ bit15 ^ bits0_14;
|
||||
|
||||
if (hash == 0)
|
||||
{
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
words[0] ^= 0x8000;
|
||||
return 1;
|
||||
}
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
u32 bitcount = hash - 0x4000;
|
||||
if (bitcount < 16 || bitcount >= count * 32)
|
||||
{
|
||||
u32 num_set = 0;
|
||||
for (u32 bitpos = 0; bitpos < 15; bitpos++)
|
||||
{
|
||||
if ((hash >> bitpos) & 1)
|
||||
{
|
||||
num_set++;
|
||||
}
|
||||
}
|
||||
if (num_set != 1)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
words[0] ^= hash;
|
||||
return 1;
|
||||
}
|
||||
words[bitcount / 32] ^= 1 << (hash & 0x1f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
|
||||
{
|
||||
u32 words[80];
|
||||
u32 word_count;
|
||||
u32 word_addr;
|
||||
u32 word0 = 0;
|
||||
u32 total_read = 0;
|
||||
|
||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||
word_count &= 0x7f;
|
||||
word_addr = 191;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
total_read += word_count;
|
||||
if (total_read >= ARRAYSIZE(words))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < word_count; i++)
|
||||
{
|
||||
FUSE(FUSE_ADDR) = word_addr--;
|
||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;
|
||||
fuse_wait_idle();
|
||||
words[i] = FUSE(FUSE_RDATA);
|
||||
}
|
||||
|
||||
word0 = words[0];
|
||||
if (patch_hash_multi(words, word_count) >= 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
u32 ipatch_count = (words[0] >> 16) & 0xf;
|
||||
if (ipatch_count)
|
||||
{
|
||||
for (u32 i = 0; i < ipatch_count; i++)
|
||||
{
|
||||
u32 word = words[i];
|
||||
u32 addr = (word >> 16) * 2;
|
||||
u32 data = word & 0xffff;
|
||||
|
||||
ipatch(addr, data);
|
||||
}
|
||||
}
|
||||
words[0] = word0;
|
||||
if ((word0 >> 25) == 0)
|
||||
break;
|
||||
if (patch_hash_one(&word0) >= 2)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
word_count = word0 >> 25;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
||||
{
|
||||
u32 words[80];
|
||||
u32 word_count;
|
||||
u32 word_addr;
|
||||
u32 word0 = 0;
|
||||
u32 total_read = 0;
|
||||
int evp_thunk_written = 0;
|
||||
void *evp_thunk_dst_addr = 0;
|
||||
|
||||
memset(iram_evp_thunks, 0, *iram_evp_thunks_len);
|
||||
|
||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||
word_count &= 0x7f;
|
||||
word_addr = 191;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
total_read += word_count;
|
||||
if (total_read >= ARRAYSIZE(words))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < word_count; i++)
|
||||
{
|
||||
FUSE(FUSE_ADDR) = word_addr--;
|
||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;
|
||||
fuse_wait_idle();
|
||||
words[i] = FUSE(FUSE_RDATA);
|
||||
}
|
||||
|
||||
word0 = words[0];
|
||||
if (patch_hash_multi(words, word_count) >= 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
u32 ipatch_count = (words[0] >> 16) & 0xf;
|
||||
u32 insn_count = word_count - ipatch_count - 1;
|
||||
if (insn_count)
|
||||
{
|
||||
if (!evp_thunk_written)
|
||||
{
|
||||
evp_thunk_dst_addr = (void *)iram_evp_thunks;
|
||||
|
||||
memcpy(evp_thunk_dst_addr, (void *)evp_thunk_template, evp_thunk_template_len);
|
||||
evp_thunk_dst_addr += evp_thunk_template_len;
|
||||
evp_thunk_written = 1;
|
||||
*iram_evp_thunks_len = evp_thunk_template_len;
|
||||
|
||||
//write32(TEGRA_EXCEPTION_VECTORS_BASE + 0x208, iram_evp_thunks);
|
||||
}
|
||||
|
||||
u32 thunk_patch_len = insn_count * sizeof(u32);
|
||||
memcpy(evp_thunk_dst_addr, &words[ipatch_count + 1], thunk_patch_len);
|
||||
evp_thunk_dst_addr += thunk_patch_len;
|
||||
*iram_evp_thunks_len += thunk_patch_len;
|
||||
}
|
||||
words[0] = word0;
|
||||
if ((word0 >> 25) == 0)
|
||||
break;
|
||||
if (patch_hash_one(&word0) >= 2)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
word_count = word0 >> 25;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void read_raw_ipatch_fuses(u32 *words)
|
||||
{
|
||||
for (u32 i = 0; i < 0x100; i++)
|
||||
{
|
||||
FUSE(FUSE_ADDR) = i;
|
||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;
|
||||
fuse_wait_idle();
|
||||
words[i] = FUSE(FUSE_RDATA);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* 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 _FUSE_H_
|
||||
#define _FUSE_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
/*! Fuse registers. */
|
||||
#define FUSE_CTRL 0x0
|
||||
#define FUSE_ADDR 0x4
|
||||
#define FUSE_RDATA 0x8
|
||||
#define FUSE_WDATA 0xC
|
||||
#define FUSE_TIME_RD1 0x10
|
||||
#define FUSE_TIME_RD2 0x14
|
||||
#define FUSE_TIME_PGM1 0x18
|
||||
#define FUSE_TIME_PGM2 0x1C
|
||||
#define FUSE_PRIV2INTFC 0x20
|
||||
#define FUSE_FUSEBYPASS 0x24
|
||||
#define FUSE_PRIVATEKEYDISABLE 0x28
|
||||
#define FUSE_DISABLEREGPROGRAM 0x2C
|
||||
#define FUSE_WRITE_ACCESS_SW 0x30
|
||||
#define FUSE_PWR_GOOD_SW 0x34
|
||||
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19c
|
||||
|
||||
/*! Fuse commands. */
|
||||
#define FUSE_READ 0x1
|
||||
#define FUSE_WRITE 0x2
|
||||
#define FUSE_SENSE 0x3
|
||||
#define FUSE_CMD_MASK 0x3
|
||||
|
||||
/*! Fuse cache registers. */
|
||||
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
|
||||
|
||||
void fuse_disable_program();
|
||||
u32 fuse_read_odm(u32 idx);
|
||||
void fuse_wait_idle();
|
||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
||||
void read_raw_ipatch_fuses(u32 *words);
|
||||
|
||||
#endif
|
||||
@@ -1,143 +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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "i2c.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
static u32 i2c_addrs[] = {
|
||||
0x7000C000, 0x7000C400, 0x7000C500,
|
||||
0x7000C700, 0x7000D000, 0x7000D100
|
||||
};
|
||||
|
||||
static void _i2c_wait(vu32 *base)
|
||||
{
|
||||
base[I2C_CONFIG_LOAD] = 0x25;
|
||||
for (u32 i = 0; i < 20; i++)
|
||||
{
|
||||
usleep(1);
|
||||
if (!(base[I2C_CONFIG_LOAD] & 1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
|
||||
{
|
||||
if (size > 4)
|
||||
return 0;
|
||||
|
||||
u32 tmp = 0;
|
||||
memcpy(&tmp, buf, size);
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
||||
base[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).
|
||||
base[I2C_CMD_DATA1] = tmp; //Set value.
|
||||
base[I2C_CNFG] = (2 * size - 2) | 0x2800; //Set size and send mode.
|
||||
_i2c_wait(base); //Kick transaction.
|
||||
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
|
||||
while (base[I2C_STATUS] & 0x100)
|
||||
;
|
||||
|
||||
if (base[I2C_STATUS] << 28)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
|
||||
{
|
||||
if (size > 8)
|
||||
return 0;
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
||||
base[I2C_CMD_ADDR0] = (x << 1) | 1; // Set x (recv mode).
|
||||
base[I2C_CNFG] = (size - 1) << 1 | 0x2840; // Set size and recv mode.
|
||||
_i2c_wait(base); // Kick transaction.
|
||||
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
|
||||
while (base[I2C_STATUS] & 0x100)
|
||||
;
|
||||
|
||||
if (base[I2C_STATUS] << 28)
|
||||
return 0;
|
||||
|
||||
u32 tmp = base[I2C_CMD_DATA1]; // Get LS value.
|
||||
if (size > 4)
|
||||
{
|
||||
memcpy(buf, &tmp, 4);
|
||||
tmp = base[I2C_CMD_DATA2]; // Get MS value.
|
||||
memcpy(buf + 4, &tmp, size - 4);
|
||||
}
|
||||
else
|
||||
memcpy(buf, &tmp, size);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void i2c_init(u32 idx)
|
||||
{
|
||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
||||
|
||||
base[I2C_CLK_DIVISOR_REGISTER] = 0x50001;
|
||||
base[I2C_BUS_CLEAR_CONFIG] = 0x90003;
|
||||
_i2c_wait(base);
|
||||
|
||||
for (u32 i = 0; i < 10; i++)
|
||||
{
|
||||
usleep(20000);
|
||||
if (base[INTERRUPT_STATUS_REGISTER] & 0x800)
|
||||
break;
|
||||
}
|
||||
|
||||
(vu32)base[I2C_BUS_CLEAR_STATUS];
|
||||
base[INTERRUPT_STATUS_REGISTER] = base[INTERRUPT_STATUS_REGISTER];
|
||||
}
|
||||
|
||||
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
|
||||
{
|
||||
u8 tmp[4];
|
||||
|
||||
if (size > 3)
|
||||
return 0;
|
||||
|
||||
tmp[0] = y;
|
||||
memcpy(tmp + 1, buf, size);
|
||||
|
||||
return _i2c_send_pkt(idx, x, tmp, size + 1);
|
||||
}
|
||||
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
|
||||
{
|
||||
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);
|
||||
if (res)
|
||||
res = _i2c_recv_pkt(idx, buf, size, x);
|
||||
return res;
|
||||
}
|
||||
|
||||
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)
|
||||
{
|
||||
return i2c_send_buf_small(idx, x, y, &b, 1);
|
||||
}
|
||||
|
||||
u8 i2c_recv_byte(u32 idx, u32 x, u32 y)
|
||||
{
|
||||
u8 tmp = 0;
|
||||
i2c_recv_buf_small(&tmp, 1, idx, x, y);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -1,46 +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 _I2C_H_
|
||||
#define _I2C_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
#define I2C_1 0
|
||||
#define I2C_2 1
|
||||
#define I2C_3 2
|
||||
#define I2C_4 3
|
||||
#define I2C_5 4
|
||||
#define I2C_6 5
|
||||
|
||||
#define I2C_CNFG 0x00
|
||||
#define I2C_CMD_ADDR0 0x01
|
||||
#define I2C_CMD_DATA1 0x03
|
||||
#define I2C_CMD_DATA2 0x04
|
||||
#define I2C_STATUS 0x07
|
||||
#define INTERRUPT_STATUS_REGISTER 0x1A
|
||||
#define I2C_CLK_DIVISOR_REGISTER 0x1B
|
||||
#define I2C_BUS_CLEAR_CONFIG 0x21
|
||||
#define I2C_BUS_CLEAR_STATUS 0x22
|
||||
#define I2C_CONFIG_LOAD 0x23
|
||||
|
||||
void i2c_init(u32 idx);
|
||||
int 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);
|
||||
u8 i2c_recv_byte(u32 idx, u32 x, u32 y);
|
||||
|
||||
#endif
|
||||
@@ -1,42 +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/>.
|
||||
*/
|
||||
|
||||
#include "../soc/kfuse.h"
|
||||
#include "../soc/clock.h"
|
||||
#include "../soc/t210.h"
|
||||
|
||||
int kfuse_read(u32 *buf)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
clock_enable_kfuse();
|
||||
|
||||
while (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_DONE))
|
||||
;
|
||||
|
||||
if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS))
|
||||
goto out;
|
||||
|
||||
KFUSE(KFUSE_KEYADDR) = KFUSE_KEYADDR_AUTOINC;
|
||||
for (int i = 0; i < KFUSE_NUM_WORDS; i++)
|
||||
buf[i] = KFUSE(KFUSE_KEYS);
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
clock_disable_kfuse();
|
||||
return res;
|
||||
}
|
||||
@@ -1,41 +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 _KFUSE_H_
|
||||
#define _KFUSE_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
#define KFUSE_STATE_SOFTRESET (1 << 31)
|
||||
#define KFUSE_STATE_STOP (1 << 25)
|
||||
#define KFUSE_STATE_RESTART (1 << 24)
|
||||
#define KFUSE_STATE_CRCPASS (1 << 17)
|
||||
#define KFUSE_STATE_DONE (1 << 16)
|
||||
#define KFUSE_STATE_ERRBLOCK_MASK 0x3F00
|
||||
#define KFUSE_STATE_ERRBLOCK_SHIFT 8
|
||||
#define KFUSE_STATE_CURBLOCK_MASK 0x3F
|
||||
|
||||
#define KFUSE_KEYADDR_AUTOINC (1<<16)
|
||||
|
||||
#define KFUSE_STATE 0x80
|
||||
#define KFUSE_KEYADDR 0x88
|
||||
#define KFUSE_KEYS 0x8C
|
||||
|
||||
#define KFUSE_NUM_WORDS 144
|
||||
|
||||
int kfuse_read(u32 *buf);
|
||||
|
||||
#endif
|
||||
@@ -1,32 +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/>.
|
||||
*/
|
||||
|
||||
#include "../soc/pinmux.h"
|
||||
#include "../soc/t210.h"
|
||||
|
||||
void pinmux_config_uart(u32 idx)
|
||||
{
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_RTS(idx)) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN;
|
||||
}
|
||||
|
||||
void pinmux_config_i2c(u32 idx)
|
||||
{
|
||||
PINMUX_AUX(PINMUX_AUX_X_I2C_SCL(idx)) = PINMUX_INPUT_ENABLE;
|
||||
PINMUX_AUX(PINMUX_AUX_X_I2C_SDA(idx)) = PINMUX_INPUT_ENABLE;
|
||||
}
|
||||
@@ -1,89 +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 _PINMUX_H_
|
||||
#define _PINMUX_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
/*! APB MISC registers. */
|
||||
#define APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL 0x8D4
|
||||
#define APB_MISC_GP_SDMMC3_CLK_LPBK_CONTROL 0x8D8
|
||||
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
|
||||
#define APB_MISC_GP_VGPIO_GPIO_MUX_SEL 0xB74
|
||||
|
||||
/*! Pinmux registers. */
|
||||
#define PINMUX_AUX_SDMMC1_CLK 0x00
|
||||
#define PINMUX_AUX_SDMMC1_CMD 0x04
|
||||
#define PINMUX_AUX_SDMMC1_DAT3 0x08
|
||||
#define PINMUX_AUX_SDMMC1_DAT2 0x0C
|
||||
#define PINMUX_AUX_SDMMC1_DAT1 0x10
|
||||
#define PINMUX_AUX_SDMMC1_DAT0 0x14
|
||||
#define PINMUX_AUX_SDMMC3_CLK 0x1C
|
||||
#define PINMUX_AUX_SDMMC3_CMD 0x20
|
||||
#define PINMUX_AUX_SDMMC3_DAT0 0x24
|
||||
#define PINMUX_AUX_SDMMC3_DAT1 0x28
|
||||
#define PINMUX_AUX_SDMMC3_DAT2 0x2C
|
||||
#define PINMUX_AUX_SDMMC3_DAT3 0x30
|
||||
#define PINMUX_AUX_DMIC3_CLK 0xB4
|
||||
#define PINMUX_AUX_UART2_TX 0xF4
|
||||
#define PINMUX_AUX_UART3_TX 0x104
|
||||
#define PINMUX_AUX_WIFI_EN 0x1B4
|
||||
#define PINMUX_AUX_WIFI_RST 0x1B8
|
||||
#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
|
||||
/*! 0:UART-A, 1:UART-B, 3:UART-C, 3:UART-D */
|
||||
#define PINMUX_AUX_UARTX_TX(x) (0xE4 + 0x10 * (x))
|
||||
#define PINMUX_AUX_UARTX_RX(x) (0xE8 + 0x10 * (x))
|
||||
#define PINMUX_AUX_UARTX_RTS(x) (0xEC + 0x10 * (x))
|
||||
#define PINMUX_AUX_UARTX_CTS(x) (0xF0 + 0x10 * (x))
|
||||
/*! 0:GEN1, 1:GEN2, 2:GEN3, 3:CAM, 4:PWR */
|
||||
#define PINMUX_AUX_X_I2C_SCL(x) (0xBC + 8 * (x))
|
||||
#define PINMUX_AUX_X_I2C_SDA(x) (0xC0 + 8 * (x))
|
||||
|
||||
#define PINMUX_FUNC_MASK (3 << 0)
|
||||
|
||||
#define PINMUX_PULL_MASK (3 << 2)
|
||||
#define PINMUX_PULL_NONE (0 << 2)
|
||||
#define PINMUX_PULL_DOWN (1 << 2)
|
||||
#define PINMUX_PULL_UP (2 << 2)
|
||||
|
||||
#define PINMUX_TRISTATE (1 << 4)
|
||||
#define PINMUX_PARKED (1 << 5)
|
||||
#define PINMUX_INPUT_ENABLE (1 << 6)
|
||||
#define PINMUX_LOCK (1 << 7)
|
||||
#define PINMUX_LPDR (1 << 8)
|
||||
#define PINMUX_HSM (1 << 9)
|
||||
|
||||
#define PINMUX_IO_HV (1 << 10)
|
||||
#define PINMUX_OPEN_DRAIN (1 << 11)
|
||||
#define PINMUX_SCHMT (1 << 12)
|
||||
|
||||
#define PINMUX_DRIVE_1X (0 << 13)
|
||||
#define PINMUX_DRIVE_2X (1 << 13)
|
||||
#define PINMUX_DRIVE_3X (2 << 13)
|
||||
#define PINMUX_DRIVE_4X (3 << 13)
|
||||
|
||||
void pinmux_config_uart(u32 idx);
|
||||
void pinmux_config_i2c(u32 idx);
|
||||
|
||||
#endif
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
*
|
||||
* 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 _PMC_H_
|
||||
#define _PMC_H_
|
||||
|
||||
/*! PMC registers. */
|
||||
#define APBDEV_PMC_SEC_DISABLE 0x4
|
||||
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
|
||||
#define APBDEV_PMC_PWRGATE_STATUS 0x38
|
||||
#define APBDEV_PMC_NO_IOPOWER 0x44
|
||||
#define APBDEV_PMC_SCRATCH0 0x50
|
||||
#define APBDEV_PMC_SCRATCH1 0x54
|
||||
#define APBDEV_PMC_SCRATCH20 0xA0
|
||||
#define APBDEV_PMC_PWR_DET_VAL 0xE4
|
||||
#define APBDEV_PMC_DDR_PWR 0xE8
|
||||
#define APBDEV_PMC_CRYPTO_OP 0xF4
|
||||
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
|
||||
#define APBDEV_PMC_RST_STATUS 0x1B4
|
||||
#define APBDEV_PMC_IO_DPD_REQ 0x1B8
|
||||
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
|
||||
#define APBDEV_PMC_VDDP_SEL 0x1CC
|
||||
#define APBDEV_PMC_SCRATCH49 0x244
|
||||
#define APBDEV_PMC_TSC_MULT 0x2B4
|
||||
#define APBDEV_PMC_SEC_DISABLE2 0x2C4
|
||||
#define APBDEV_PMC_WEAK_BIAS 0x2C8
|
||||
#define APBDEV_PMC_REG_SHORT 0x2CC
|
||||
#define APBDEV_PMC_SEC_DISABLE3 0x2D8
|
||||
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
|
||||
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
|
||||
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
|
||||
#define APBDEV_PMC_CNTRL2 0x440
|
||||
#define APBDEV_PMC_IO_DPD4_REQ 0x464
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC
|
||||
#define APBDEV_PMC_DDR_CNTRL 0x4E4
|
||||
#define APBDEV_PMC_SEC_DISABLE4 0x5B0
|
||||
#define APBDEV_PMC_SEC_DISABLE5 0x5B4
|
||||
#define APBDEV_PMC_SEC_DISABLE6 0x5B8
|
||||
#define APBDEV_PMC_SEC_DISABLE7 0x5BC
|
||||
#define APBDEV_PMC_SEC_DISABLE8 0x5C0
|
||||
#define APBDEV_PMC_SCRATCH188 0x810
|
||||
#define APBDEV_PMC_SCRATCH190 0x818
|
||||
#define APBDEV_PMC_SCRATCH200 0x840
|
||||
|
||||
#endif
|
||||
@@ -1,564 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA210_PMC_H_
|
||||
#define _TEGRA210_PMC_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
struct tegra_pmc_regs
|
||||
{
|
||||
u32 cntrl;
|
||||
u32 sec_disable;
|
||||
u32 pmc_swrst;
|
||||
u32 wake_mask;
|
||||
u32 wake_lvl;
|
||||
u32 wake_status;
|
||||
u32 sw_wake_status;
|
||||
u32 dpd_pads_oride;
|
||||
u32 dpd_sample;
|
||||
u32 dpd_enable;
|
||||
u32 pwrgate_timer_off;
|
||||
u32 clamp_status;
|
||||
u32 pwrgate_toggle;
|
||||
u32 remove_clamping_cmd;
|
||||
u32 pwrgate_status;
|
||||
u32 pwrgood_timer;
|
||||
u32 blink_timer;
|
||||
u32 no_iopower;
|
||||
u32 pwr_det;
|
||||
u32 pwr_det_latch;
|
||||
u32 scratch0;
|
||||
u32 scratch1;
|
||||
u32 scratch2;
|
||||
u32 scratch3;
|
||||
u32 scratch4;
|
||||
u32 scratch5;
|
||||
u32 scratch6;
|
||||
u32 scratch7;
|
||||
u32 scratch8;
|
||||
u32 scratch9;
|
||||
u32 scratch10;
|
||||
u32 scratch11;
|
||||
u32 scratch12;
|
||||
u32 scratch13;
|
||||
u32 scratch14;
|
||||
u32 scratch15;
|
||||
u32 scratch16;
|
||||
u32 scratch17;
|
||||
u32 scratch18;
|
||||
u32 scratch19;
|
||||
u32 odmdata;
|
||||
u32 scratch21;
|
||||
u32 scratch22;
|
||||
u32 scratch23;
|
||||
u32 secure_scratch0;
|
||||
u32 secure_scratch1;
|
||||
u32 secure_scratch2;
|
||||
u32 secure_scratch3;
|
||||
u32 secure_scratch4;
|
||||
u32 secure_scratch5;
|
||||
u32 cpupwrgood_timer;
|
||||
u32 cpupwroff_timer;
|
||||
u32 pg_mask;
|
||||
u32 pg_mask_1;
|
||||
u32 auto_wake_lvl;
|
||||
u32 auto_wake_lvl_mask;
|
||||
u32 wake_delay;
|
||||
u32 pwr_det_val;
|
||||
u32 ddr_pwr;
|
||||
u32 usb_debounce_del;
|
||||
u32 usb_a0;
|
||||
u32 crypto_op;
|
||||
u32 pllp_wb0_override;
|
||||
u32 scratch24;
|
||||
u32 scratch25;
|
||||
u32 scratch26;
|
||||
u32 scratch27;
|
||||
u32 scratch28;
|
||||
u32 scratch29;
|
||||
u32 scratch30;
|
||||
u32 scratch31;
|
||||
u32 scratch32;
|
||||
u32 scratch33;
|
||||
u32 scratch34;
|
||||
u32 scratch35;
|
||||
u32 scratch36;
|
||||
u32 scratch37;
|
||||
u32 scratch38;
|
||||
u32 scratch39;
|
||||
u32 scratch40;
|
||||
u32 scratch41;
|
||||
u32 scratch42;
|
||||
u32 bondout_mirror[3];
|
||||
u32 sys_33v_en;
|
||||
u32 bondout_mirror_access;
|
||||
u32 gate;
|
||||
u32 wake2_mask;
|
||||
u32 wake2_lvl;
|
||||
u32 wake2_status;
|
||||
u32 sw_wake2_status;
|
||||
u32 auto_wake2_lvl_mask;
|
||||
u32 pg_mask_2;
|
||||
u32 pg_mask_ce1;
|
||||
u32 pg_mask_ce2;
|
||||
u32 pg_mask_ce3;
|
||||
u32 pwrgate_timer_ce[7];
|
||||
u32 pcx_edpd_cntrl;
|
||||
u32 osc_edpd_over;
|
||||
u32 clk_out_cntrl;
|
||||
u32 sata_pwrgt;
|
||||
u32 sensor_ctrl;
|
||||
u32 rst_status;
|
||||
u32 io_dpd_req;
|
||||
u32 io_dpd_status;
|
||||
u32 io_dpd2_req;
|
||||
u32 io_dpd2_status;
|
||||
u32 sel_dpd_tim;
|
||||
u32 vddp_sel;
|
||||
u32 ddr_cfg;
|
||||
u32 e_no_vttgen;
|
||||
u8 _rsv0[4];
|
||||
u32 pllm_wb0_override_freq;
|
||||
u32 test_pwrgate;
|
||||
u32 pwrgate_timer_mult;
|
||||
u32 dis_sel_dpd;
|
||||
u32 utmip_uhsic_triggers;
|
||||
u32 utmip_uhsic_saved_state;
|
||||
u32 utmip_pad_cfg;
|
||||
u32 utmip_term_pad_cfg;
|
||||
u32 utmip_uhsic_sleep_cfg;
|
||||
u32 utmip_uhsic_sleepwalk_cfg;
|
||||
u32 utmip_sleepwalk_p[3];
|
||||
u32 uhsic_sleepwalk_p0;
|
||||
u32 utmip_uhsic_status;
|
||||
u32 utmip_uhsic_fake;
|
||||
u32 bondout_mirror3[5 - 3];
|
||||
u32 secure_scratch6;
|
||||
u32 secure_scratch7;
|
||||
u32 scratch43;
|
||||
u32 scratch44;
|
||||
u32 scratch45;
|
||||
u32 scratch46;
|
||||
u32 scratch47;
|
||||
u32 scratch48;
|
||||
u32 scratch49;
|
||||
u32 scratch50;
|
||||
u32 scratch51;
|
||||
u32 scratch52;
|
||||
u32 scratch53;
|
||||
u32 scratch54;
|
||||
u32 scratch55;
|
||||
u32 scratch0_eco;
|
||||
u32 por_dpd_ctrl;
|
||||
u32 scratch2_eco;
|
||||
u32 utmip_uhsic_line_wakeup;
|
||||
u32 utmip_bias_master_cntrl;
|
||||
u32 utmip_master_config;
|
||||
u32 td_pwrgate_inter_part_timer;
|
||||
u32 utmip_uhsic2_triggers;
|
||||
u32 utmip_uhsic2_saved_state;
|
||||
u32 utmip_uhsic2_sleep_cfg;
|
||||
u32 utmip_uhsic2_sleepwalk_cfg;
|
||||
u32 uhsic2_sleepwalk_p1;
|
||||
u32 utmip_uhsic2_status;
|
||||
u32 utmip_uhsic2_fake;
|
||||
u32 utmip_uhsic2_line_wakeup;
|
||||
u32 utmip_master2_config;
|
||||
u32 utmip_uhsic_rpd_cfg;
|
||||
u32 pg_mask_ce0;
|
||||
u32 pg_mask3[5 - 3];
|
||||
u32 pllm_wb0_override2;
|
||||
u32 tsc_mult;
|
||||
u32 cpu_vsense_override;
|
||||
u32 glb_amap_cfg;
|
||||
u32 sticky_bits;
|
||||
u32 sec_disable2;
|
||||
u32 weak_bias;
|
||||
u32 reg_short;
|
||||
u32 pg_mask_andor;
|
||||
u8 _rsv1[0x2c];
|
||||
u32 secure_scratch8; /* offset 0x300 */
|
||||
u32 secure_scratch9;
|
||||
u32 secure_scratch10;
|
||||
u32 secure_scratch11;
|
||||
u32 secure_scratch12;
|
||||
u32 secure_scratch13;
|
||||
u32 secure_scratch14;
|
||||
u32 secure_scratch15;
|
||||
u32 secure_scratch16;
|
||||
u32 secure_scratch17;
|
||||
u32 secure_scratch18;
|
||||
u32 secure_scratch19;
|
||||
u32 secure_scratch20;
|
||||
u32 secure_scratch21;
|
||||
u32 secure_scratch22;
|
||||
u32 secure_scratch23;
|
||||
u32 secure_scratch24;
|
||||
u32 secure_scratch25;
|
||||
u32 secure_scratch26;
|
||||
u32 secure_scratch27;
|
||||
u32 secure_scratch28;
|
||||
u32 secure_scratch29;
|
||||
u32 secure_scratch30;
|
||||
u32 secure_scratch31;
|
||||
u32 secure_scratch32;
|
||||
u32 secure_scratch33;
|
||||
u32 secure_scratch34;
|
||||
u32 secure_scratch35;
|
||||
u32 secure_scratch36;
|
||||
u32 secure_scratch37;
|
||||
u32 secure_scratch38;
|
||||
u32 secure_scratch39;
|
||||
u32 secure_scratch40;
|
||||
u32 secure_scratch41;
|
||||
u32 secure_scratch42;
|
||||
u32 secure_scratch43;
|
||||
u32 secure_scratch44;
|
||||
u32 secure_scratch45;
|
||||
u32 secure_scratch46;
|
||||
u32 secure_scratch47;
|
||||
u32 secure_scratch48;
|
||||
u32 secure_scratch49;
|
||||
u32 secure_scratch50;
|
||||
u32 secure_scratch51;
|
||||
u32 secure_scratch52;
|
||||
u32 secure_scratch53;
|
||||
u32 secure_scratch54;
|
||||
u32 secure_scratch55;
|
||||
u32 secure_scratch56;
|
||||
u32 secure_scratch57;
|
||||
u32 secure_scratch58;
|
||||
u32 secure_scratch59;
|
||||
u32 secure_scratch60;
|
||||
u32 secure_scratch61;
|
||||
u32 secure_scratch62;
|
||||
u32 secure_scratch63;
|
||||
u32 secure_scratch64;
|
||||
u32 secure_scratch65;
|
||||
u32 secure_scratch66;
|
||||
u32 secure_scratch67;
|
||||
u32 secure_scratch68;
|
||||
u32 secure_scratch69;
|
||||
u32 secure_scratch70;
|
||||
u32 secure_scratch71;
|
||||
u32 secure_scratch72;
|
||||
u32 secure_scratch73;
|
||||
u32 secure_scratch74;
|
||||
u32 secure_scratch75;
|
||||
u32 secure_scratch76;
|
||||
u32 secure_scratch77;
|
||||
u32 secure_scratch78;
|
||||
u32 secure_scratch79;
|
||||
u32 _rsv0x420[8];
|
||||
u32 cntrl2; /* 0x440 */
|
||||
u32 _rsv0x444[2];
|
||||
u32 event_counter; /* 0x44C */
|
||||
u32 fuse_control;
|
||||
u32 scratch1_eco;
|
||||
u32 _rsv0x458[1];
|
||||
u32 io_dpd3_req; /* 0x45C */
|
||||
u32 io_dpd3_status;
|
||||
u32 io_dpd4_req;
|
||||
u32 io_dpd4_status;
|
||||
u32 _rsv0x46C[30];
|
||||
u32 ddr_cntrl; /* 0x4E4 */
|
||||
u32 _rsv0x4E8[70];
|
||||
u32 scratch56; /* 0x600 */
|
||||
u32 scratch57;
|
||||
u32 scratch58;
|
||||
u32 scratch59;
|
||||
u32 scratch60;
|
||||
u32 scratch61;
|
||||
u32 scratch62;
|
||||
u32 scratch63;
|
||||
u32 scratch64;
|
||||
u32 scratch65;
|
||||
u32 scratch66;
|
||||
u32 scratch67;
|
||||
u32 scratch68;
|
||||
u32 scratch69;
|
||||
u32 scratch70;
|
||||
u32 scratch71;
|
||||
u32 scratch72;
|
||||
u32 scratch73;
|
||||
u32 scratch74;
|
||||
u32 scratch75;
|
||||
u32 scratch76;
|
||||
u32 scratch77;
|
||||
u32 scratch78;
|
||||
u32 scratch79;
|
||||
u32 scratch80;
|
||||
u32 scratch81;
|
||||
u32 scratch82;
|
||||
u32 scratch83;
|
||||
u32 scratch84;
|
||||
u32 scratch85;
|
||||
u32 scratch86;
|
||||
u32 scratch87;
|
||||
u32 scratch88;
|
||||
u32 scratch89;
|
||||
u32 scratch90;
|
||||
u32 scratch91;
|
||||
u32 scratch92;
|
||||
u32 scratch93;
|
||||
u32 scratch94;
|
||||
u32 scratch95;
|
||||
u32 scratch96;
|
||||
u32 scratch97;
|
||||
u32 scratch98;
|
||||
u32 scratch99;
|
||||
u32 scratch100;
|
||||
u32 scratch101;
|
||||
u32 scratch102;
|
||||
u32 scratch103;
|
||||
u32 scratch104;
|
||||
u32 scratch105;
|
||||
u32 scratch106;
|
||||
u32 scratch107;
|
||||
u32 scratch108;
|
||||
u32 scratch109;
|
||||
u32 scratch110;
|
||||
u32 scratch111;
|
||||
u32 scratch112;
|
||||
u32 scratch113;
|
||||
u32 scratch114;
|
||||
u32 scratch115;
|
||||
u32 scratch116;
|
||||
u32 scratch117;
|
||||
u32 scratch118;
|
||||
u32 scratch119;
|
||||
u32 scratch120; /* 0x700 */
|
||||
u32 scratch121;
|
||||
u32 scratch122;
|
||||
u32 scratch123;
|
||||
u32 scratch124;
|
||||
u32 scratch125;
|
||||
u32 scratch126;
|
||||
u32 scratch127;
|
||||
u32 scratch128;
|
||||
u32 scratch129;
|
||||
u32 scratch130;
|
||||
u32 scratch131;
|
||||
u32 scratch132;
|
||||
u32 scratch133;
|
||||
u32 scratch134;
|
||||
u32 scratch135;
|
||||
u32 scratch136;
|
||||
u32 scratch137;
|
||||
u32 scratch138;
|
||||
u32 scratch139;
|
||||
u32 scratch140;
|
||||
u32 scratch141;
|
||||
u32 scratch142;
|
||||
u32 scratch143;
|
||||
u32 scratch144;
|
||||
u32 scratch145;
|
||||
u32 scratch146;
|
||||
u32 scratch147;
|
||||
u32 scratch148;
|
||||
u32 scratch149;
|
||||
u32 scratch150;
|
||||
u32 scratch151;
|
||||
u32 scratch152;
|
||||
u32 scratch153;
|
||||
u32 scratch154;
|
||||
u32 scratch155;
|
||||
u32 scratch156;
|
||||
u32 scratch157;
|
||||
u32 scratch158;
|
||||
u32 scratch159;
|
||||
u32 scratch160;
|
||||
u32 scratch161;
|
||||
u32 scratch162;
|
||||
u32 scratch163;
|
||||
u32 scratch164;
|
||||
u32 scratch165;
|
||||
u32 scratch166;
|
||||
u32 scratch167;
|
||||
u32 scratch168;
|
||||
u32 scratch169;
|
||||
u32 scratch170;
|
||||
u32 scratch171;
|
||||
u32 scratch172;
|
||||
u32 scratch173;
|
||||
u32 scratch174;
|
||||
u32 scratch175;
|
||||
u32 scratch176;
|
||||
u32 scratch177;
|
||||
u32 scratch178;
|
||||
u32 scratch179;
|
||||
u32 scratch180;
|
||||
u32 scratch181;
|
||||
u32 scratch182;
|
||||
u32 scratch183;
|
||||
u32 scratch184;
|
||||
u32 scratch185;
|
||||
u32 scratch186;
|
||||
u32 scratch187;
|
||||
u32 scratch188;
|
||||
u32 scratch189;
|
||||
u32 scratch190;
|
||||
u32 scratch191;
|
||||
u32 scratch192;
|
||||
u32 scratch193;
|
||||
u32 scratch194;
|
||||
u32 scratch195;
|
||||
u32 scratch196;
|
||||
u32 scratch197;
|
||||
u32 scratch198;
|
||||
u32 scratch199;
|
||||
u32 scratch200;
|
||||
u32 scratch201;
|
||||
u32 scratch202;
|
||||
u32 scratch203;
|
||||
u32 scratch204;
|
||||
u32 scratch205;
|
||||
u32 scratch206;
|
||||
u32 scratch207;
|
||||
u32 scratch208;
|
||||
u32 scratch209;
|
||||
u32 scratch210;
|
||||
u32 scratch211;
|
||||
u32 scratch212;
|
||||
u32 scratch213;
|
||||
u32 scratch214;
|
||||
u32 scratch215;
|
||||
u32 scratch216;
|
||||
u32 scratch217;
|
||||
u32 scratch218;
|
||||
u32 scratch219;
|
||||
u32 scratch220;
|
||||
u32 scratch221;
|
||||
u32 scratch222;
|
||||
u32 scratch223;
|
||||
u32 scratch224;
|
||||
u32 scratch225;
|
||||
u32 scratch226;
|
||||
u32 scratch227;
|
||||
u32 scratch228;
|
||||
u32 scratch229;
|
||||
u32 scratch230;
|
||||
u32 scratch231;
|
||||
u32 scratch232;
|
||||
u32 scratch233;
|
||||
u32 scratch234;
|
||||
u32 scratch235;
|
||||
u32 scratch236;
|
||||
u32 scratch237;
|
||||
u32 scratch238;
|
||||
u32 scratch239;
|
||||
u32 scratch240;
|
||||
u32 scratch241;
|
||||
u32 scratch242;
|
||||
u32 scratch243;
|
||||
u32 scratch244;
|
||||
u32 scratch245;
|
||||
u32 scratch246;
|
||||
u32 scratch247;
|
||||
u32 scratch248;
|
||||
u32 scratch249;
|
||||
u32 scratch250;
|
||||
u32 scratch251;
|
||||
u32 scratch252;
|
||||
u32 scratch253;
|
||||
u32 scratch254;
|
||||
u32 scratch255;
|
||||
u32 scratch256;
|
||||
u32 scratch257;
|
||||
u32 scratch258;
|
||||
u32 scratch259;
|
||||
u32 scratch260;
|
||||
u32 scratch261;
|
||||
u32 scratch262;
|
||||
u32 scratch263;
|
||||
u32 scratch264;
|
||||
u32 scratch265;
|
||||
u32 scratch266;
|
||||
u32 scratch267;
|
||||
u32 scratch268;
|
||||
u32 scratch269;
|
||||
u32 scratch270;
|
||||
u32 scratch271;
|
||||
u32 scratch272;
|
||||
u32 scratch273;
|
||||
u32 scratch274;
|
||||
u32 scratch275;
|
||||
u32 scratch276;
|
||||
u32 scratch277;
|
||||
u32 scratch278;
|
||||
u32 scratch279;
|
||||
u32 scratch280;
|
||||
u32 scratch281;
|
||||
u32 scratch282;
|
||||
u32 scratch283;
|
||||
u32 scratch284;
|
||||
u32 scratch285;
|
||||
u32 scratch286;
|
||||
u32 scratch287;
|
||||
u32 scratch288;
|
||||
u32 scratch289;
|
||||
u32 scratch290;
|
||||
u32 scratch291;
|
||||
u32 scratch292;
|
||||
u32 scratch293;
|
||||
u32 scratch294;
|
||||
u32 scratch295;
|
||||
u32 scratch296;
|
||||
u32 scratch297;
|
||||
u32 scratch298;
|
||||
u32 scratch299; /* 0x9CC */
|
||||
u32 _rsv0x9D0[50];
|
||||
u32 secure_scratch80; /* 0xa98 */
|
||||
u32 secure_scratch81;
|
||||
u32 secure_scratch82;
|
||||
u32 secure_scratch83;
|
||||
u32 secure_scratch84;
|
||||
u32 secure_scratch85;
|
||||
u32 secure_scratch86;
|
||||
u32 secure_scratch87;
|
||||
u32 secure_scratch88;
|
||||
u32 secure_scratch89;
|
||||
u32 secure_scratch90;
|
||||
u32 secure_scratch91;
|
||||
u32 secure_scratch92;
|
||||
u32 secure_scratch93;
|
||||
u32 secure_scratch94;
|
||||
u32 secure_scratch95;
|
||||
u32 secure_scratch96;
|
||||
u32 secure_scratch97;
|
||||
u32 secure_scratch98;
|
||||
u32 secure_scratch99;
|
||||
u32 secure_scratch100;
|
||||
u32 secure_scratch101;
|
||||
u32 secure_scratch102;
|
||||
u32 secure_scratch103;
|
||||
u32 secure_scratch104;
|
||||
u32 secure_scratch105;
|
||||
u32 secure_scratch106;
|
||||
u32 secure_scratch107;
|
||||
u32 secure_scratch108;
|
||||
u32 secure_scratch109;
|
||||
u32 secure_scratch110;
|
||||
u32 secure_scratch111;
|
||||
u32 secure_scratch112;
|
||||
u32 secure_scratch113;
|
||||
u32 secure_scratch114;
|
||||
u32 secure_scratch115;
|
||||
u32 secure_scratch116;
|
||||
u32 secure_scratch117;
|
||||
u32 secure_scratch118;
|
||||
u32 secure_scratch119;
|
||||
};
|
||||
|
||||
#endif /* _TEGRA210_PMC_H_ */
|
||||
@@ -1,121 +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 _T210_H_
|
||||
#define _T210_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
#define BOOTROM_BASE 0x100000
|
||||
#define HOST1X_BASE 0x50000000
|
||||
#define BPMP_CACHE_BASE 0x50040000
|
||||
#define DISPLAY_A_BASE 0x54200000
|
||||
#define DSI_BASE 0x54300000
|
||||
#define VIC_BASE 0x54340000
|
||||
#define TSEC_BASE 0x54500000
|
||||
#define SOR1_BASE 0x54580000
|
||||
#define TMR_BASE 0x60005000
|
||||
#define CLOCK_BASE 0x60006000
|
||||
#define FLOW_CTLR_BASE 0x60007000
|
||||
#define SYSREG_BASE 0x6000C000
|
||||
#define SB_BASE (SYSREG_BASE + 0x200)
|
||||
#define GPIO_BASE 0x6000D000
|
||||
#define GPIO_1_BASE (GPIO_BASE)
|
||||
#define GPIO_2_BASE (GPIO_BASE + 0x100)
|
||||
#define GPIO_3_BASE (GPIO_BASE + 0x200)
|
||||
#define GPIO_4_BASE (GPIO_BASE + 0x300)
|
||||
#define GPIO_5_BASE (GPIO_BASE + 0x400)
|
||||
#define GPIO_6_BASE (GPIO_BASE + 0x500)
|
||||
#define GPIO_7_BASE (GPIO_BASE + 0x600)
|
||||
#define GPIO_8_BASE (GPIO_BASE + 0x700)
|
||||
#define EXCP_VEC_BASE 0x6000F000
|
||||
#define IPATCH_BASE 0x6001DC00
|
||||
#define APB_MISC_BASE 0x70000000
|
||||
#define PINMUX_AUX_BASE 0x70003000
|
||||
#define UART_BASE 0x70006000
|
||||
#define PWM_BASE 0x7000A000
|
||||
#define RTC_BASE 0x7000E000
|
||||
#define PMC_BASE 0x7000E400
|
||||
#define SYSCTR0_BASE 0x700F0000
|
||||
#define FUSE_BASE 0x7000F800
|
||||
#define KFUSE_BASE 0x7000FC00
|
||||
#define SE_BASE 0x70012000
|
||||
#define MC_BASE 0x70019000
|
||||
#define EMC_BASE 0x7001B000
|
||||
#define MIPI_CAL_BASE 0x700E3000
|
||||
#define I2S_BASE 0x702D1000
|
||||
#define CL_DVFS_BASE 0x70110000
|
||||
|
||||
#define _REG(base, off) *(vu32 *)((base) + (off))
|
||||
|
||||
#define HOST1X(off) _REG(HOST1X_BASE, off)
|
||||
#define BPMP_CACHE_CTRL(off) _REG(BPMP_CACHE_BASE, off)
|
||||
#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off)
|
||||
#define DSI(off) _REG(DSI_BASE, off)
|
||||
#define VIC(off) _REG(VIC_BASE, off)
|
||||
#define TSEC(off) _REG(TSEC_BASE, off)
|
||||
#define SOR1(off) _REG(SOR1_BASE, off)
|
||||
#define TMR(off) _REG(TMR_BASE, off)
|
||||
#define CLOCK(off) _REG(CLOCK_BASE, off)
|
||||
#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off)
|
||||
#define SYSREG(off) _REG(SYSREG_BASE, off)
|
||||
#define SB(off) _REG(SB_BASE, off)
|
||||
#define GPIO(off) _REG(GPIO_BASE, off)
|
||||
#define GPIO_1(off) _REG(GPIO_1_BASE, off)
|
||||
#define GPIO_2(off) _REG(GPIO_2_BASE, off)
|
||||
#define GPIO_3(off) _REG(GPIO_3_BASE, off)
|
||||
#define GPIO_4(off) _REG(GPIO_4_BASE, off)
|
||||
#define GPIO_5(off) _REG(GPIO_5_BASE, off)
|
||||
#define GPIO_6(off) _REG(GPIO_6_BASE, off)
|
||||
#define GPIO_7(off) _REG(GPIO_7_BASE, off)
|
||||
#define GPIO_8(off) _REG(GPIO_8_BASE, off)
|
||||
#define EXCP_VEC(off) _REG(EXCP_VEC_BASE, off)
|
||||
#define APB_MISC(off) _REG(APB_MISC_BASE, off)
|
||||
#define PINMUX_AUX(off) _REG(PINMUX_AUX_BASE, off)
|
||||
#define PWM(off) _REG(PWM_BASE, off)
|
||||
#define RTC(off) _REG(RTC_BASE, off)
|
||||
#define PMC(off) _REG(PMC_BASE, off)
|
||||
#define SYSCTR0(off) _REG(SYSCTR0_BASE, off)
|
||||
#define FUSE(off) _REG(FUSE_BASE, off)
|
||||
#define KFUSE(off) _REG(KFUSE_BASE, off)
|
||||
#define SE(off) _REG(SE_BASE, off)
|
||||
#define MC(off) _REG(MC_BASE, off)
|
||||
#define EMC(off) _REG(EMC_BASE, off)
|
||||
#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off)
|
||||
#define I2S(off) _REG(I2S_BASE, off)
|
||||
#define CL_DVFS(off) _REG(CL_DVFS_BASE, off)
|
||||
#define TEST_REG(off) _REG(0x0, off)
|
||||
|
||||
/*! Misc registers. */
|
||||
#define APB_MISC_PP_STRAPPING_OPT_A 0x08
|
||||
#define APB_MISC_PP_PINMUX_GLOBAL 0x40
|
||||
#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34
|
||||
#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64
|
||||
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68
|
||||
|
||||
/*! System registers. */
|
||||
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
|
||||
#define AHB_AHB_SPARE_REG 0x110
|
||||
|
||||
/*! Secure boot registers. */
|
||||
#define SB_CSR 0x0
|
||||
#define SB_AA64_RESET_LOW 0x30
|
||||
#define SB_AA64_RESET_HIGH 0x34
|
||||
|
||||
/*! SYSCTR0 registers. */
|
||||
#define SYSCTR0_CNTFID0 0x20
|
||||
|
||||
#endif
|
||||
@@ -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) 0x14000000 | ((((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
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "btn.h"
|
||||
#include "../soc/i2c.h"
|
||||
#include "../soc/gpio.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "util.h"
|
||||
#include "../power/max77620.h"
|
||||
|
||||
u32 btn_read()
|
||||
{
|
||||
u32 res = 0;
|
||||
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_7))
|
||||
res |= BTN_VOL_DOWN;
|
||||
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))
|
||||
res |= BTN_VOL_UP;
|
||||
if (i2c_recv_byte(4, MAX77620_I2C_ADDR, 0x15) & 0x4)
|
||||
res |= BTN_POWER;
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 btn_wait()
|
||||
{
|
||||
u32 res = 0, btn = btn_read();
|
||||
bool pwr = false;
|
||||
|
||||
//Power button down, raise a filter.
|
||||
if (btn & BTN_POWER)
|
||||
{
|
||||
pwr = true;
|
||||
btn &= ~BTN_POWER;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
res = btn_read();
|
||||
//Power button up, remove filter.
|
||||
if (!(res & BTN_POWER) && pwr)
|
||||
pwr = false;
|
||||
else if (pwr) //Power button still down.
|
||||
res &= ~BTN_POWER;
|
||||
} while (btn == res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 btn_wait_timeout(u32 time_ms, u32 mask)
|
||||
{
|
||||
u32 timeout = get_tmr_ms() + time_ms;
|
||||
u32 res = btn_read() & mask;
|
||||
|
||||
do
|
||||
{
|
||||
if (!(res & mask))
|
||||
res = btn_read() & mask;
|
||||
} while (get_tmr_ms() < timeout);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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 _BTN_H_
|
||||
#define _BTN_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define BTN_POWER 0x1
|
||||
#define BTN_VOL_DOWN 0x2
|
||||
#define BTN_VOL_UP 0x4
|
||||
|
||||
u32 btn_read();
|
||||
u32 btn_wait();
|
||||
u32 btn_wait_timeout(u32 time_ms, u32 mask);
|
||||
|
||||
#endif
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../utils/types.h"
|
||||
|
||||
char *dirlist(const char *directory, const char *pattern)
|
||||
{
|
||||
u8 max_entries = 61;
|
||||
|
||||
int res = 0;
|
||||
u32 i = 0, j = 0, k = 0;
|
||||
DIR dir;
|
||||
static FILINFO fno;
|
||||
|
||||
char *dir_entries = (char *)calloc(max_entries, 256);
|
||||
char *temp = (char *)calloc(1, 256);
|
||||
|
||||
if (!pattern && !f_opendir(&dir, directory))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
res = f_readdir(&dir, &fno);
|
||||
if (res || !fno.fname[0])
|
||||
break;
|
||||
if (!(fno.fattrib & AM_DIR))
|
||||
{
|
||||
memcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);
|
||||
k++;
|
||||
if (k > (max_entries - 1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
f_closedir(&dir);
|
||||
}
|
||||
else if (pattern && !f_findfirst(&dir, &fno, directory, pattern) && fno.fname[0])
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!(fno.fattrib & AM_DIR))
|
||||
{
|
||||
memcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);
|
||||
k++;
|
||||
if (k > (max_entries - 1))
|
||||
break;
|
||||
}
|
||||
res = f_findnext(&dir, &fno);
|
||||
} while (fno.fname[0] && !res);
|
||||
f_closedir(&dir);
|
||||
}
|
||||
|
||||
if (!k)
|
||||
{
|
||||
free(temp);
|
||||
free(dir_entries);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < k - 1 ; i++)
|
||||
{
|
||||
for (j = i + 1; j < k; j++)
|
||||
{
|
||||
if (strcmp(&dir_entries[i * 256], &dir_entries[j * 256]) > 0)
|
||||
{
|
||||
memcpy(temp, &dir_entries[i * 256], strlen(&dir_entries[i * 256]) + 1);
|
||||
memcpy(&dir_entries[i * 256], &dir_entries[j * 256], strlen(&dir_entries[j * 256]) + 1);
|
||||
memcpy(&dir_entries[j * 256], temp, strlen(temp) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(temp);
|
||||
|
||||
return dir_entries;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
char *dirlist(const char *directory, const char *pattern);
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "util.h"
|
||||
#include "../soc/t210.h"
|
||||
|
||||
u32 get_tmr_s()
|
||||
{
|
||||
return RTC(0x8); //RTC_SECONDS
|
||||
}
|
||||
|
||||
u32 get_tmr_ms()
|
||||
{
|
||||
// The registers must be read with the following order:
|
||||
// -> RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC)
|
||||
return (RTC(0x10) | (RTC(0xC)<< 10));
|
||||
}
|
||||
|
||||
u32 get_tmr_us()
|
||||
{
|
||||
return TMR(0x10); //TIMERUS_CNTR_1US
|
||||
}
|
||||
|
||||
void msleep(u32 milliseconds)
|
||||
{
|
||||
u32 start = RTC(0x10) | (RTC(0xC)<< 10);
|
||||
while (((RTC(0x10) | (RTC(0xC)<< 10)) - start) <= milliseconds)
|
||||
;
|
||||
}
|
||||
|
||||
void usleep(u32 microseconds)
|
||||
{
|
||||
u32 start = TMR(0x10);
|
||||
while ((TMR(0x10) - start) <= microseconds)
|
||||
;
|
||||
}
|
||||
|
||||
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops)
|
||||
{
|
||||
for(u32 i = 0; i < num_ops; i++)
|
||||
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;
|
||||
}
|
||||
|
||||
u32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len)
|
||||
{
|
||||
u32 len32 = len / 4;
|
||||
|
||||
if (!(len32 % 32))
|
||||
{
|
||||
while (len32)
|
||||
{
|
||||
len32 -= 32;
|
||||
if(buf1[len32] != buf2[len32])
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (len32)
|
||||
{
|
||||
len32 -= 32;
|
||||
if(buf1[len32] != buf2[len32])
|
||||
return 1;
|
||||
if (len32 < 32)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* 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 _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define byte_swap_32(num) ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
|
||||
((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000)
|
||||
|
||||
typedef struct _cfg_op_t
|
||||
{
|
||||
u32 off;
|
||||
u32 val;
|
||||
} cfg_op_t;
|
||||
|
||||
u32 get_tmr_us();
|
||||
u32 get_tmr_ms();
|
||||
u32 get_tmr_s();
|
||||
void usleep(u32 ticks);
|
||||
void msleep(u32 milliseconds);
|
||||
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
|
||||
u32 crc32c(const void *buf, u32 len);
|
||||
|
||||
/* This is a faster implementation of memcmp that checks two u32 values */
|
||||
/* every 128 Bytes block. Intented only for Backup and Restore */
|
||||
u32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len);
|
||||
|
||||
#endif
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Common Gfx Header
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (C) 2018 M4xw
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
//TODO: Move it to BDK
|
||||
#include "../bootloader/utils/types.h"
|
||||
|
||||
typedef struct _gfx_ctxt_t
|
||||
{
|
||||
u32 *fb;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 stride;
|
||||
} gfx_ctxt_t;
|
||||
|
||||
typedef struct _gfx_con_t
|
||||
{
|
||||
gfx_ctxt_t *gfx_ctxt;
|
||||
u32 fntsz;
|
||||
u32 x;
|
||||
u32 y;
|
||||
u32 savedx;
|
||||
u32 savedy;
|
||||
u32 fgcol;
|
||||
int fillbg;
|
||||
u32 bgcol;
|
||||
bool mute;
|
||||
} gfx_con_t;
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 M4xw
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
//TODO: Move it to BDK
|
||||
#include "../bootloader/utils/types.h"
|
||||
|
||||
typedef struct _hnode
|
||||
{
|
||||
int used;
|
||||
u32 size;
|
||||
struct _hnode *prev;
|
||||
struct _hnode *next;
|
||||
} hnode_t;
|
||||
|
||||
typedef struct _heap
|
||||
{
|
||||
u32 start;
|
||||
hnode_t *first;
|
||||
} heap_t;
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Common Module Header
|
||||
* Copyright (C) 2018 M4xw
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
//TODO: Move it to BDK
|
||||
#include "common_gfx.h"
|
||||
#include "common_heap.h"
|
||||
|
||||
// Module Callback
|
||||
typedef void (*cbMainModule_t)(const char *s);
|
||||
typedef void (*memcpy_t)(void *, void *, size_t);
|
||||
typedef void (*memset_t)(void *, int, size_t);
|
||||
|
||||
typedef struct _bdkParams_t
|
||||
{
|
||||
gfx_con_t *gfxCon;
|
||||
gfx_ctxt_t *gfxCtx;
|
||||
heap_t *sharedHeap;
|
||||
memcpy_t memcpy;
|
||||
memset_t memset;
|
||||
} *bdkParams_t;
|
||||
|
||||
// Module Entrypoint
|
||||
typedef void (*moduleEntrypoint_t)(void *, bdkParams_t);
|
||||
42
ipl/btn.c
Executable file
42
ipl/btn.c
Executable file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "btn.h"
|
||||
#include "i2c.h"
|
||||
#include "gpio.h"
|
||||
#include "t210.h"
|
||||
|
||||
u32 btn_read()
|
||||
{
|
||||
u32 res = 0;
|
||||
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_7))
|
||||
res |= BTN_VOL_DOWN;
|
||||
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))
|
||||
res |= BTN_VOL_UP;
|
||||
if (i2c_recv_byte(4, 0x3C, 0x15) & 0x4)
|
||||
res |= BTN_POWER;
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 btn_wait()
|
||||
{
|
||||
u32 res = 0, btn = btn_read();
|
||||
do
|
||||
{
|
||||
res = btn_read();
|
||||
} while (btn == res);
|
||||
return res;
|
||||
}
|
||||
29
ipl/btn.h
Executable file
29
ipl/btn.h
Executable file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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 _BTN_H_
|
||||
#define _BTN_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define BTN_POWER 0x1
|
||||
#define BTN_VOL_DOWN 0x2
|
||||
#define BTN_VOL_UP 0x4
|
||||
|
||||
u32 btn_read();
|
||||
u32 btn_wait();
|
||||
|
||||
#endif
|
||||
188
bootloader/soc/clock.c → ipl/clock.c
Normal file → Executable file
188
bootloader/soc/clock.c → ipl/clock.c
Normal file → Executable file
@@ -1,82 +1,79 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "../soc/clock.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../storage/sdmmc.h"
|
||||
#include "clock.h"
|
||||
#include "t210.h"
|
||||
#include "util.h"
|
||||
#include "sdmmc.h"
|
||||
|
||||
static const clock_t _clock_uart[] = {
|
||||
/* UART A */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, 6, 0, 0 },
|
||||
/* UART B */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, 7, 0, 0 },
|
||||
/* UART C */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, 0x17, 0, 0 },
|
||||
static const clock_t _clock_uart[] = {
|
||||
/* UART A */ { 4, 0x10, 0x178, 6, 0, 0 },
|
||||
/* UART B */ { 4, 0x10, 0x17C, 7, 0, 0 },
|
||||
/* UART C */ { 8, 0x14, 0x1A0, 0x17, 0, 0 },
|
||||
/* UART D */ { 0 },
|
||||
/* UART E */ { 0 }
|
||||
};
|
||||
|
||||
static const clock_t _clock_i2c[] = {
|
||||
/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 0xC, 6, 0 },
|
||||
/* I2C1 */ { 4, 0x10, 0x124, 0xC, 6, 0 },
|
||||
/* I2C2 */ { 0 },
|
||||
/* I2C3 */ { 0 },
|
||||
/* I2C4 */ { 0 },
|
||||
/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 0xF, 6, 0 },
|
||||
/* I2C5 */ { 8, 0x14, 0x128, 0xF, 6, 0 },
|
||||
/* I2C6 */ { 0 }
|
||||
};
|
||||
|
||||
static clock_t _clock_se = { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, 0x1F, 0, 0 };
|
||||
static clock_t _clock_unk2 = { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_RST_SOURCE, 0x1E, 0, 0 };
|
||||
static clock_t _clock_se = { 0x358, 0x360, 0x42C, 0x1F, 0, 0 };
|
||||
|
||||
static clock_t _clock_host1x = { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, 0x1C, 4, 3 };
|
||||
static clock_t _clock_tsec = { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, 0x13, 0, 2 };
|
||||
static clock_t _clock_sor_safe = { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_RST_SOURCE, 0x1E, 0, 0 };
|
||||
static clock_t _clock_sor0 = { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_RST_SOURCE, 0x16, 0, 0 };
|
||||
static clock_t _clock_sor1 = { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, 0x17, 0, 2 };
|
||||
static clock_t _clock_kfuse = { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_RST_SOURCE, 8, 0, 0 };
|
||||
static clock_t _clock_host1x = { 4, 0x10, 0x180, 0x1C, 4, 3 };
|
||||
static clock_t _clock_tsec = { 0xC, 0x18, 0x1F4, 0x13, 0, 2 };
|
||||
static clock_t _clock_sor_safe = { 0x2A4, 0x298, 0, 0x1E, 0, 0 };
|
||||
static clock_t _clock_sor0 = { 0x28C, 0x280, 0, 0x16, 0, 0 };
|
||||
static clock_t _clock_sor1 = { 0x28C, 0x280, 0x410, 0x17, 0, 2 };
|
||||
static clock_t _clock_kfuse = { 8, 0x14, 0, 8, 0, 0 };
|
||||
|
||||
static clock_t _clock_cl_dvfs = { CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_RST_CONTROLLER_RST_SOURCE, 0x1B, 0, 0 };
|
||||
static clock_t _clock_coresight = { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, 9, 0, 4};
|
||||
|
||||
static clock_t _clock_pwm = { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, 0x11, 6, 4};
|
||||
static clock_t _clock_cl_dvfs = { 0x35C, 0x364, 0, 0x1B, 0, 0 };
|
||||
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);
|
||||
// Disable.
|
||||
//Put clock into reset.
|
||||
CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index);
|
||||
//Disable.
|
||||
CLOCK(clk->enable) &= ~(1 << clk->index);
|
||||
// Configure clock source if required.
|
||||
//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);
|
||||
// Take clock off reset.
|
||||
//Enable.
|
||||
CLOCK(clk->enable) = CLOCK(clk->enable) & ~(1 << clk->index) | (1 << clk->index);
|
||||
//Take clock off reset.
|
||||
CLOCK(clk->reset) &= ~(1 << clk->index);
|
||||
}
|
||||
|
||||
void clock_disable(const clock_t *clk)
|
||||
{
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index);
|
||||
// Disable.
|
||||
//Put clock into reset.
|
||||
CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index);
|
||||
//Disable.
|
||||
CLOCK(clk->enable) &= ~(1 << clk->index);
|
||||
}
|
||||
|
||||
void clock_enable_fuse(bool enable)
|
||||
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)
|
||||
@@ -89,21 +86,11 @@ void clock_enable_i2c(u32 idx)
|
||||
clock_enable(&_clock_i2c[idx]);
|
||||
}
|
||||
|
||||
void clock_disable_i2c(u32 idx)
|
||||
{
|
||||
clock_disable(&_clock_i2c[idx]);
|
||||
}
|
||||
|
||||
void clock_enable_se()
|
||||
{
|
||||
clock_enable(&_clock_se);
|
||||
}
|
||||
|
||||
void clock_enable_unk2()
|
||||
{
|
||||
clock_enable(&_clock_unk2);
|
||||
}
|
||||
|
||||
void clock_enable_host1x()
|
||||
{
|
||||
clock_enable(&_clock_host1x);
|
||||
@@ -157,12 +144,12 @@ 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;
|
||||
usleep(10);
|
||||
CLOCK(0x14) = CLOCK(0x14) & 0xFFFFFEFF | 0x100;
|
||||
sleep(10);
|
||||
CLOCK(0x8) &= 0xFFFFFEFF;
|
||||
usleep(20);
|
||||
sleep(20);
|
||||
}
|
||||
|
||||
void clock_disable_kfuse()
|
||||
@@ -175,60 +162,40 @@ void clock_enable_cl_dvfs()
|
||||
clock_enable(&_clock_cl_dvfs);
|
||||
}
|
||||
|
||||
void clock_disable_cl_dvfs()
|
||||
{
|
||||
clock_disable(&_clock_cl_dvfs);
|
||||
}
|
||||
|
||||
void clock_enable_coresight()
|
||||
{
|
||||
clock_enable(&_clock_coresight);
|
||||
}
|
||||
|
||||
void clock_disable_coresight()
|
||||
{
|
||||
clock_disable(&_clock_coresight);
|
||||
}
|
||||
#define L_SWR_SDMMC1_RST (1<<14)
|
||||
#define L_SWR_SDMMC2_RST (1<<9)
|
||||
#define L_SWR_SDMMC4_RST (1<<15)
|
||||
#define U_SWR_SDMMC3_RST (1<<5)
|
||||
|
||||
void clock_enable_pwm()
|
||||
{
|
||||
clock_enable(&_clock_pwm);
|
||||
}
|
||||
#define L_CLK_ENB_SDMMC1 (1<<14)
|
||||
#define L_CLK_ENB_SDMMC2 (1<<9)
|
||||
#define L_CLK_ENB_SDMMC4 (1<<15)
|
||||
#define U_CLK_ENB_SDMMC3 (1<<5)
|
||||
|
||||
void clock_disable_pwm()
|
||||
{
|
||||
clock_disable(&_clock_pwm);
|
||||
}
|
||||
#define L_SET_SDMMC1_RST (1<<14)
|
||||
#define L_SET_SDMMC2_RST (1<<9)
|
||||
#define L_SET_SDMMC4_RST (1<<15)
|
||||
#define U_SET_SDMMC3_RST (1<<5)
|
||||
|
||||
#define L_SWR_SDMMC1_RST (1 << 14)
|
||||
#define L_SWR_SDMMC2_RST (1 << 9)
|
||||
#define L_SWR_SDMMC4_RST (1 << 15)
|
||||
#define U_SWR_SDMMC3_RST (1 << 5)
|
||||
#define L_CLR_SDMMC1_RST (1<<14)
|
||||
#define L_CLR_SDMMC2_RST (1<<9)
|
||||
#define L_CLR_SDMMC4_RST (1<<15)
|
||||
#define U_CLR_SDMMC3_RST (1<<5)
|
||||
|
||||
#define L_CLK_ENB_SDMMC1 (1 << 14)
|
||||
#define L_CLK_ENB_SDMMC2 (1 << 9)
|
||||
#define L_CLK_ENB_SDMMC4 (1 << 15)
|
||||
#define U_CLK_ENB_SDMMC3 (1 << 5)
|
||||
#define L_SET_CLK_ENB_SDMMC1 (1<<14)
|
||||
#define L_SET_CLK_ENB_SDMMC2 (1<<9)
|
||||
#define L_SET_CLK_ENB_SDMMC4 (1<<15)
|
||||
#define U_SET_CLK_ENB_SDMMC3 (1<<5)
|
||||
|
||||
#define L_SET_SDMMC1_RST (1 << 14)
|
||||
#define L_SET_SDMMC2_RST (1 << 9)
|
||||
#define L_SET_SDMMC4_RST (1 << 15)
|
||||
#define U_SET_SDMMC3_RST (1 << 5)
|
||||
|
||||
#define L_CLR_SDMMC1_RST (1 << 14)
|
||||
#define L_CLR_SDMMC2_RST (1 << 9)
|
||||
#define L_CLR_SDMMC4_RST (1 << 15)
|
||||
#define U_CLR_SDMMC3_RST (1 << 5)
|
||||
|
||||
#define L_SET_CLK_ENB_SDMMC1 (1 << 14)
|
||||
#define L_SET_CLK_ENB_SDMMC2 (1 << 9)
|
||||
#define L_SET_CLK_ENB_SDMMC4 (1 << 15)
|
||||
#define U_SET_CLK_ENB_SDMMC3 (1 << 5)
|
||||
|
||||
#define L_CLR_CLK_ENB_SDMMC1 (1 << 14)
|
||||
#define L_CLR_CLK_ENB_SDMMC2 (1 << 9)
|
||||
#define L_CLR_CLK_ENB_SDMMC4 (1 << 15)
|
||||
#define U_CLR_CLK_ENB_SDMMC3 (1 << 5)
|
||||
#define L_CLR_CLK_ENB_SDMMC1 (1<<14)
|
||||
#define L_CLR_CLK_ENB_SDMMC2 (1<<9)
|
||||
#define L_CLR_CLK_ENB_SDMMC4 (1<<15)
|
||||
#define U_CLR_CLK_ENB_SDMMC3 (1<<5)
|
||||
|
||||
static int _clock_sdmmc_is_reset(u32 id)
|
||||
{
|
||||
@@ -292,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)
|
||||
{
|
||||
@@ -307,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)
|
||||
{
|
||||
@@ -364,8 +331,7 @@ static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)
|
||||
divisor = 2;
|
||||
break;
|
||||
default:
|
||||
*pout = 24728;
|
||||
divisor = 31;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_clock_sdmmc_table[2 * id] = val;
|
||||
@@ -470,7 +436,7 @@ void clock_sdmmc_enable(u32 id, u32 val)
|
||||
_clock_sdmmc_config_clock_source_inner(&div, id, val);
|
||||
_clock_sdmmc_set_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
usleep((100000 + div - 1) / div);
|
||||
sleep((100000 + div - 1) / div);
|
||||
_clock_sdmmc_clear_reset(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
}
|
||||
108
ipl/clock.h
Executable file
108
ipl/clock.h
Executable file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 _CLOCK_H_
|
||||
#define _CLOCK_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*! Clock registers. */
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_L 0x4
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_U 0xC
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_L 0x10
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_H 0x14
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_U 0x18
|
||||
#define CLK_RST_CONTROLLER_CCLK_BURST_POLICY 0x20
|
||||
#define CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER 0x24
|
||||
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY 0x28
|
||||
#define CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER 0x2C
|
||||
#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30
|
||||
#define CLK_RST_CONTROLLER_MISC_CLK_ENB 0x48
|
||||
#define CLK_RST_CONTROLLER_OSC_CTRL 0x50
|
||||
#define CLK_RST_CONTROLLER_PLLX_BASE 0xE0
|
||||
#define CLK_RST_CONTROLLER_PLLX_MISC 0xE4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1 0x150
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2 0x154
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4 0x164
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 0x1BC
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19C
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X 0x280
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_Y 0x298
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_Y_SET 0x29C
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_L_SET 0x300
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_L_CLR 0x304
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_U_SET 0x310
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_U_CLR 0x314
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_L_SET 0x320
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_L_CLR 0x324
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_U_SET 0x330
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_U_CLR 0x334
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_V 0x358
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_V 0x360
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_W 0x364
|
||||
#define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2 0x388
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_V_SET 0x440
|
||||
#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR 0x454
|
||||
#define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518
|
||||
#define CLK_RST_CONTROLLER_SPARE_REG0 0x55C
|
||||
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694
|
||||
|
||||
/*! Generic clock descriptor. */
|
||||
typedef struct _clock_t
|
||||
{
|
||||
u32 reset;
|
||||
u32 enable;
|
||||
u32 source;
|
||||
u8 index;
|
||||
u8 clk_src;
|
||||
u8 clk_div;
|
||||
} clock_t;
|
||||
|
||||
/*! Generic clock enable/disable. */
|
||||
void clock_enable(const clock_t *clk);
|
||||
void clock_disable(const clock_t *clk);
|
||||
|
||||
/*! Clock control for specific hardware portions. */
|
||||
void clock_enable_fuse(u32 enable);
|
||||
void clock_enable_uart(u32 idx);
|
||||
void clock_enable_i2c(u32 idx);
|
||||
void clock_enable_se();
|
||||
void clock_enable_host1x();
|
||||
void clock_disable_host1x();
|
||||
void clock_enable_tsec();
|
||||
void clock_disable_tsec();
|
||||
void clock_enable_sor_safe();
|
||||
void clock_disable_sor_safe();
|
||||
void clock_enable_sor0();
|
||||
void clock_disable_sor0();
|
||||
void clock_enable_sor1();
|
||||
void clock_disable_sor1();
|
||||
void clock_enable_kfuse();
|
||||
void clock_disable_kfuse();
|
||||
void clock_enable_cl_dvfs();
|
||||
void clock_enable_coresight();
|
||||
void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val);
|
||||
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type);
|
||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
||||
void clock_sdmmc_enable(u32 id, u32 val);
|
||||
void clock_sdmmc_disable(u32 id);
|
||||
|
||||
#endif
|
||||
127
ipl/cluster.c
Executable file
127
ipl/cluster.c
Executable file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "cluster.h"
|
||||
#include "i2c.h"
|
||||
#include "clock.h"
|
||||
#include "util.h"
|
||||
#include "pmc.h"
|
||||
#include "t210.h"
|
||||
#include "max77620.h"
|
||||
|
||||
void _cluster_enable_power()
|
||||
{
|
||||
u8 tmp = i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_AME_GPIO);
|
||||
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_AME_GPIO, tmp & 0xDF);
|
||||
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_GPIO5, 0x09);
|
||||
|
||||
//Enable cores power.
|
||||
i2c_send_byte(I2C_5, 0x1B, 0x2, 0x20);
|
||||
i2c_send_byte(I2C_5, 0x1B, 0x3, 0x8D);
|
||||
i2c_send_byte(I2C_5, 0x1B, 0x0, 0xB7);
|
||||
i2c_send_byte(I2C_5, 0x1B, 0x1, 0xB7);
|
||||
}
|
||||
|
||||
int _cluster_pmc_enable_partition(u32 part, u32 toggle)
|
||||
{
|
||||
//Check if the partition has already been turned on.
|
||||
if (PMC(APBDEV_PMC_PWRGATE_STATUS) & part)
|
||||
return 1;
|
||||
|
||||
u32 i = 5001;
|
||||
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)
|
||||
{
|
||||
sleep(1);
|
||||
i--;
|
||||
if (i < 1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
PMC(APBDEV_PMC_PWRGATE_TOGGLE) = toggle | 0x100;
|
||||
|
||||
i = 5001;
|
||||
while (i > 0)
|
||||
{
|
||||
if (PMC(APBDEV_PMC_PWRGATE_STATUS) & part)
|
||||
break;
|
||||
sleep(1);
|
||||
i--;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cluster_boot_cpu0(u32 entry)
|
||||
{
|
||||
//Set ACTIVE_CLUSER to FAST.
|
||||
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE;
|
||||
|
||||
_cluster_enable_power();
|
||||
|
||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000))
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7;
|
||||
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_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;
|
||||
|
||||
//Configure initial CPU clock frequency and enable clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888;
|
||||
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = 1;
|
||||
|
||||
clock_enable_coresight();
|
||||
|
||||
//CAR2PMC_CPU_ACK_WIDTH should be set to 0.
|
||||
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) = CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) & 0xFFFFF000;
|
||||
|
||||
//Enable CPU rail.
|
||||
_cluster_pmc_enable_partition(1, 0);
|
||||
//Enable cluster 0 non-CPU.
|
||||
_cluster_pmc_enable_partition(0x8000, 15);
|
||||
//Enable CE0.
|
||||
_cluster_pmc_enable_partition(0x4000, 14);
|
||||
|
||||
//Request and wait for RAM repair.
|
||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1;
|
||||
while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & 2))
|
||||
;
|
||||
|
||||
EXCP_VEC(0x100) = 0;
|
||||
|
||||
//Set reset vector.
|
||||
SB(SB_AA64_RESET_LOW) = entry | 1;
|
||||
SB(SB_AA64_RESET_HIGH) = 0;
|
||||
//Non-secure reset vector write disable.
|
||||
SB(SB_CSR) = 2;
|
||||
(void)SB(SB_CSR);
|
||||
|
||||
//Clear MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7;
|
||||
//Clear NONCPU reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
|
||||
//Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x411F000F;
|
||||
}
|
||||
28
ipl/cluster.h
Executable file
28
ipl/cluster.h
Executable file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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 _CLUSTER_H_
|
||||
#define _CLUSTER_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*! Flow controller registers. */
|
||||
#define FLOW_CTLR_RAM_REPAIR 0x40
|
||||
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98
|
||||
|
||||
void cluster_boot_cpu0(u32 entry);
|
||||
|
||||
#endif
|
||||
2258
ipl/ctc_logo.h
Normal file
2258
ipl/ctc_logo.h
Normal file
File diff suppressed because it is too large
Load Diff
213
ipl/di.c
Executable file
213
ipl/di.c
Executable file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "di.h"
|
||||
#include "t210.h"
|
||||
#include "util.h"
|
||||
#include "i2c.h"
|
||||
#include "pmc.h"
|
||||
#include "max77620.h"
|
||||
|
||||
#include "di.inl"
|
||||
|
||||
static u32 _display_ver = 0;
|
||||
|
||||
static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
|
||||
{
|
||||
u32 end = TMR(0x10) + timeout;
|
||||
while (TMR(0x10) < end && DSI(off) & mask)
|
||||
;
|
||||
sleep(5);
|
||||
}
|
||||
|
||||
void display_init()
|
||||
{
|
||||
//Power on.
|
||||
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_LDO0_CFG, 0xD0); //Configure to 1.2V.
|
||||
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_GPIO7, 0x09);
|
||||
|
||||
//Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks.
|
||||
CLOCK(0x30C) = 0x1010000;
|
||||
CLOCK(0x328) = 0x1010000;
|
||||
CLOCK(0x304) = 0x18000000;
|
||||
CLOCK(0x320) = 0x18000000;
|
||||
CLOCK(0x284) = 0x20000;
|
||||
CLOCK(0x66C) = 0xA;
|
||||
CLOCK(0x448) = 0x80000;
|
||||
CLOCK(0x620) = 0xA;
|
||||
|
||||
//DPD idle.
|
||||
PMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000;
|
||||
PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000;
|
||||
|
||||
//Config pins.
|
||||
PINMUX_AUX(0x1D0) &= 0xFFFFFFEF;
|
||||
PINMUX_AUX(0x1D4) &= 0xFFFFFFEF;
|
||||
PINMUX_AUX(0x1FC) &= 0xFFFFFFEF;
|
||||
PINMUX_AUX(0x200) &= 0xFFFFFFEF;
|
||||
PINMUX_AUX(0x204) &= 0xFFFFFFEF;
|
||||
|
||||
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_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;
|
||||
|
||||
exec_cfg((u32 *)CLOCK_BASE, _display_config_1, 4);
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_2, 94);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_3, 60);
|
||||
|
||||
sleep(10000);
|
||||
|
||||
GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFB | 0x4;
|
||||
|
||||
sleep(60000);
|
||||
|
||||
DSI(_DSIREG(DSI_DSI_BTA_TIMING)) = 0x50204;
|
||||
DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x337;
|
||||
DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;
|
||||
_display_dsi_wait(250000, _DSIREG(DSI_DSI_TRIGGER), 3);
|
||||
|
||||
DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x406;
|
||||
DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;
|
||||
_display_dsi_wait(250000, _DSIREG(DSI_DSI_TRIGGER), 3);
|
||||
|
||||
DSI(_DSIREG(DSI_HOST_DSI_CONTROL)) = 0x200B;
|
||||
_display_dsi_wait(150000, _DSIREG(DSI_HOST_DSI_CONTROL), 8);
|
||||
|
||||
sleep(5000);
|
||||
|
||||
_display_ver = DSI(_DSIREG(DSI_DSI_RD_DATA));
|
||||
if (_display_ver == 0x10)
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_4, 43);
|
||||
|
||||
DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x1105;
|
||||
DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;
|
||||
|
||||
sleep(180000);
|
||||
|
||||
DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x2905;
|
||||
DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;
|
||||
|
||||
sleep(20000);
|
||||
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_5, 21);
|
||||
exec_cfg((u32 *)CLOCK_BASE, _display_config_6, 3);
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_7, 10);
|
||||
|
||||
sleep(10000);
|
||||
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_8, 6);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_9, 4);
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_10, 16);
|
||||
|
||||
sleep(10000);
|
||||
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_11, 113);
|
||||
}
|
||||
|
||||
void display_end()
|
||||
{
|
||||
GPIO_6(0x24) &= 0xFFFFFFFE;
|
||||
DSI(_DSIREG(DSI_DSI_VID_MODE_CONTROL)) = 1;
|
||||
DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x2805;
|
||||
|
||||
u32 end = HOST1X(0x30A4) + 5;
|
||||
while (HOST1X(0x30A4) < end)
|
||||
;
|
||||
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = 5;
|
||||
DSI(_DSIREG(DSI_DSI_VID_MODE_CONTROL)) = 0;
|
||||
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_12, 17);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_13, 16);
|
||||
|
||||
sleep(10000);
|
||||
|
||||
if (_display_ver == 0x10)
|
||||
exec_cfg((u32 *)DSI_BASE, _display_config_14, 22);
|
||||
|
||||
DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x1005;
|
||||
DSI(_DSIREG(DSI_DSI_TRIGGER)) = 2;
|
||||
|
||||
sleep(50000);
|
||||
|
||||
GPIO_6(0x24) &= 0xFFFFFFFB;
|
||||
|
||||
sleep(10000);
|
||||
|
||||
GPIO_3(0x20) &= 0xFFFFFFFD;
|
||||
|
||||
sleep(10000);
|
||||
|
||||
GPIO_3(0x20) = (GPIO_3(0x20) >> 1) << 1;
|
||||
|
||||
sleep(10000);
|
||||
|
||||
//Disable clocks.
|
||||
CLOCK(0x308) = 0x1010000;
|
||||
CLOCK(0x32C) = 0x1010000;
|
||||
CLOCK(0x300) = 0x18000000;
|
||||
CLOCK(0x324) = 0x18000000;
|
||||
|
||||
DSI(_DSIREG(DSI_PAD_CONTROL)) = 0x10F010F;
|
||||
DSI(_DSIREG(DSI_DSI_POWER_CONTROL)) = 0;
|
||||
|
||||
GPIO_6(0x04) &= 0xFFFFFFFE;
|
||||
|
||||
PINMUX_AUX(0x1FC) = PINMUX_AUX(0x1FC) & 0xFFFFFFEF | 0x10;
|
||||
PINMUX_AUX(0x1FC) = (PINMUX_AUX(0x1FC) >> 2) << 2 | 1;
|
||||
}
|
||||
|
||||
void display_color_screen(u32 color)
|
||||
{
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8);
|
||||
|
||||
//Configure display to show single color.
|
||||
DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;
|
||||
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 | 1;
|
||||
|
||||
sleep(35000);
|
||||
|
||||
GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFE | 1;
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer(u32 *fb)
|
||||
{
|
||||
//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);
|
||||
|
||||
GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFE | 1;
|
||||
|
||||
return (u32 *)0xC0000000;
|
||||
}
|
||||
72
ipl/di.h
Executable file
72
ipl/di.h
Executable file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 _DI_H_
|
||||
#define _DI_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*! Display registers. */
|
||||
#define _DIREG(reg) ((reg) * 4)
|
||||
#define DC_CMD_DISPLAY_COMMAND 0x32
|
||||
#define DC_CMD_STATE_ACCESS 0x40
|
||||
#define DC_CMD_STATE_CONTROL 0x41
|
||||
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
|
||||
#define DC_DISP_DISP_WIN_OPTIONS 0x402
|
||||
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
|
||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||
#define DC_WIN_AD_WIN_OPTIONS 0xB80
|
||||
#define DC_WIN_BD_WIN_OPTIONS 0xD80
|
||||
#define DC_WIN_CD_WIN_OPTIONS 0xF80
|
||||
|
||||
//The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).
|
||||
#define DC_X_WIN_XD_WIN_OPTIONS 0x700
|
||||
#define DC_X_WIN_XD_COLOR_DEPTH 0x703
|
||||
#define DC_X_WIN_XD_POSITION 0x704
|
||||
#define DC_X_WIN_XD_SIZE 0x705
|
||||
#define DC_X_WIN_XD_PRESCALED_SIZE 0x706
|
||||
#define DC_X_WIN_XD_H_INITIAL_DDA 0x707
|
||||
#define DC_X_WIN_XD_V_INITIAL_DDA 0x708
|
||||
#define DC_X_WIN_XD_DDA_INCREMENT 0x709
|
||||
#define DC_X_WIN_XD_LINE_STRIDE 0x70A
|
||||
|
||||
//The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER).
|
||||
#define DC_X_WINBUF_XD_START_ADDR 0x800
|
||||
#define DC_X_WINBUF_XD_ADDR_H_OFFSET 0x806
|
||||
#define DC_X_WINBUF_XD_ADDR_V_OFFSET 0x808
|
||||
#define DC_X_WINBUF_XD_SURFACE_KIND 0x80B
|
||||
|
||||
/*! Display serial interface registers. */
|
||||
#define _DSIREG(reg) ((reg) * 4)
|
||||
#define DSI_DSI_RD_DATA 0x9
|
||||
#define DSI_DSI_WR_DATA 0xA
|
||||
#define DSI_DSI_POWER_CONTROL 0xB
|
||||
#define DSI_HOST_DSI_CONTROL 0xF
|
||||
#define DSI_DSI_TRIGGER 0x13
|
||||
#define DSI_DSI_BTA_TIMING 0x3F
|
||||
#define DSI_PAD_CONTROL 0x4B
|
||||
#define DSI_DSI_VID_MODE_CONTROL 0x4E
|
||||
|
||||
void display_init();
|
||||
void display_end();
|
||||
|
||||
/*! Show one single color on the display. */
|
||||
void display_color_screen(u32 color);
|
||||
|
||||
/*! Init display in full 1280x720 resolution (32bpp, line stride 768, framebuffer size = 1280*768*4 bytes). */
|
||||
u32 *display_init_framebuffer();
|
||||
|
||||
#endif
|
||||
548
ipl/di.inl
Executable file
548
ipl/di.inl
Executable file
@@ -0,0 +1,548 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
//Clock config.
|
||||
static const cfg_op_t _display_config_1[4] = {
|
||||
{0x4E, 0x40000000}, //CLK_RST_CONTROLLER_CLK_SOURCE_DISP1
|
||||
{0x34, 0x4830A001}, //CLK_RST_CONTROLLER_PLLD_BASE
|
||||
{0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
|
||||
{0x37, 0x2D0AAA} //CLK_RST_CONTROLLER_PLLD_MISC
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t _display_config_2[94] = {
|
||||
{0x40, 0},
|
||||
{DC_CMD_STATE_CONTROL, 0x100},
|
||||
{DC_CMD_STATE_CONTROL, 1},
|
||||
{0x43, 0x54},
|
||||
{DC_CMD_STATE_CONTROL, 0x100},
|
||||
{DC_CMD_STATE_CONTROL, 1},
|
||||
{0x42, 0x10},
|
||||
{0x42, 0x20},
|
||||
{0x42, 0x40},
|
||||
{0x480, 0},
|
||||
{0x403, 0},
|
||||
{0x404, 0},
|
||||
{0x36, 0x50155},
|
||||
{1, 0x100},
|
||||
{0x28, 0x109},
|
||||
{DC_CMD_STATE_CONTROL, 0xF00},
|
||||
{DC_CMD_STATE_CONTROL, 0xF},
|
||||
{0x40, 0},
|
||||
{0x42, 0x10},
|
||||
{0x700, 0},
|
||||
{0x42, 0x10},
|
||||
{0x70E, 0},
|
||||
{0x700, 0},
|
||||
{0x42, 0x10},
|
||||
{0x42, 0x10},
|
||||
{0x611, 0xF0},
|
||||
{0x612, 0x12A},
|
||||
{0x613, 0},
|
||||
{0x614, 0x198},
|
||||
{0x615, 0x39B},
|
||||
{0x616, 0x32F},
|
||||
{0x617, 0x204},
|
||||
{0x618, 0},
|
||||
{0x42, 0x20},
|
||||
{0x700, 0},
|
||||
{0x42, 0x20},
|
||||
{0x70E, 0},
|
||||
{0x700, 0},
|
||||
{0x42, 0x20},
|
||||
{0x42, 0x20},
|
||||
{0x611, 0xF0},
|
||||
{0x612, 0x12A},
|
||||
{0x613, 0},
|
||||
{0x614, 0x198},
|
||||
{0x615, 0x39B},
|
||||
{0x616, 0x32F},
|
||||
{0x617, 0x204},
|
||||
{0x618, 0},
|
||||
{0x42, 0x40},
|
||||
{0x700, 0},
|
||||
{0x42, 0x40},
|
||||
{0x70E, 0},
|
||||
{0x700, 0},
|
||||
{0x42, 0x40},
|
||||
{0x42, 0x40},
|
||||
{0x611, 0xF0},
|
||||
{0x612, 0x12A},
|
||||
{0x613, 0},
|
||||
{0x614, 0x198},
|
||||
{0x615, 0x39B},
|
||||
{0x616, 0x32F},
|
||||
{0x617, 0x204},
|
||||
{0x618, 0},
|
||||
{0x42, 0x10},
|
||||
{0x700, 0},
|
||||
{0x42, 0x20},
|
||||
{0x700, 0},
|
||||
{0x42, 0x40},
|
||||
{0x700, 0},
|
||||
{0x430, 8},
|
||||
{0x42F, 0},
|
||||
{0x307, 0x1000000},
|
||||
{0x309, 0},
|
||||
{0x4E4, 0},
|
||||
{0x300, 0},
|
||||
{DC_CMD_STATE_CONTROL, 0xF00},
|
||||
{DC_CMD_STATE_CONTROL, 0xF},
|
||||
{0x42, 0x10},
|
||||
{0x716, 0x10000FF},
|
||||
{0x42, 0x20},
|
||||
{0x716, 0x10000FF},
|
||||
{0x42, 0x40},
|
||||
{0x716, 0x10000FF},
|
||||
{0x31, 0},
|
||||
{0x42, 0x10},
|
||||
{0x700, 0},
|
||||
{0x42, 0x20},
|
||||
{0x700, 0},
|
||||
{0x42, 0x40},
|
||||
{0x700, 0},
|
||||
{0x402, 0},
|
||||
{0x32, 0},
|
||||
{DC_CMD_STATE_CONTROL, 0xF00},
|
||||
{DC_CMD_STATE_CONTROL, 0xF}
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_3[60] = {
|
||||
{0xA, 0},
|
||||
{0xC, 0},
|
||||
{0xD, 0},
|
||||
{0xE, 0},
|
||||
{0x1B, 0},
|
||||
{0x1C, 0},
|
||||
{0x1D, 0},
|
||||
{0x1E, 0},
|
||||
{0x33, 0},
|
||||
{0x23, 0},
|
||||
{0x25, 0},
|
||||
{0x27, 0},
|
||||
{0x29, 0},
|
||||
{0x2B, 0},
|
||||
{0x2D, 0},
|
||||
{0x24, 0},
|
||||
{0x26, 0},
|
||||
{0x28, 0},
|
||||
{0x2A, 0},
|
||||
{0x2C, 0},
|
||||
{0x2E, 0},
|
||||
{0x10, 0},
|
||||
{0x4C, 0},
|
||||
{0x11, 0x18},
|
||||
{0x12, 0x1E0},
|
||||
{0x13, 0},
|
||||
{0x1A, 0},
|
||||
{0x34, 0},
|
||||
{0x35, 0},
|
||||
{0x36, 0},
|
||||
{0x37, 0},
|
||||
{0x4F, 0},
|
||||
{0x3C, 0x6070601},
|
||||
{0x3D, 0x40A0E05},
|
||||
{0x3E, 0x30109},
|
||||
{0x3F, 0x190A14},
|
||||
{0x44, 0x2000FFFF},
|
||||
{0x45, 0x7652000},
|
||||
{0x46, 0},
|
||||
{0x4B, 0},
|
||||
{DSI_DSI_POWER_CONTROL, 1},
|
||||
{DSI_DSI_POWER_CONTROL, 1},
|
||||
{DSI_DSI_POWER_CONTROL, 0},
|
||||
{DSI_DSI_POWER_CONTROL, 0},
|
||||
{0x4F, 0},
|
||||
{0x3C, 0x6070601},
|
||||
{0x3D, 0x40A0E05},
|
||||
{0x3E, 0x30118},
|
||||
{0x3F, 0x190A14},
|
||||
{0x44, 0x2000FFFF},
|
||||
{0x45, 0x13432000},
|
||||
{0x46, 0},
|
||||
{0xF, 0x102003},
|
||||
{0x10, 0x31},
|
||||
{DSI_DSI_POWER_CONTROL, 1},
|
||||
{DSI_DSI_POWER_CONTROL, 1},
|
||||
{0x12, 0x40},
|
||||
{0x13, 0},
|
||||
{0x14, 0},
|
||||
{0x1A, 0}
|
||||
};
|
||||
|
||||
//DSI config (if ver == 0x10).
|
||||
static const cfg_op_t _display_config_4[43] = {
|
||||
{DSI_DSI_WR_DATA, 0x439},
|
||||
{DSI_DSI_WR_DATA, 0x9483FFB9},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0xBD15},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0x1939},
|
||||
{DSI_DSI_WR_DATA, 0xAAAAAAD8},
|
||||
{DSI_DSI_WR_DATA, 0xAAAAAAEB},
|
||||
{DSI_DSI_WR_DATA, 0xAAEBAAAA},
|
||||
{DSI_DSI_WR_DATA, 0xAAAAAAAA},
|
||||
{DSI_DSI_WR_DATA, 0xAAAAAAEB},
|
||||
{DSI_DSI_WR_DATA, 0xAAEBAAAA},
|
||||
{DSI_DSI_WR_DATA, 0xAA},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0x1BD15},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0x2739},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFD8},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFF},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0x2BD15},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0xF39},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFD8},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_DSI_WR_DATA, 0xFFFFFF},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0xBD15},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0x6D915},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0x439},
|
||||
{DSI_DSI_WR_DATA, 0xB9},
|
||||
{DSI_DSI_TRIGGER, 2}
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_5[21] = {
|
||||
{0x4F, 0},
|
||||
{0x3C, 0x6070601},
|
||||
{0x3D, 0x40A0E05},
|
||||
{0x3E, 0x30172},
|
||||
{0x3F, 0x190A14},
|
||||
{0x44, 0x20000A40},
|
||||
{0x45, 0x5A2F2000},
|
||||
{0x46, 0},
|
||||
{0x23, 0x40000208},
|
||||
{0x27, 0x40000308},
|
||||
{0x2B, 0x40000308},
|
||||
{0x25, 0x40000308},
|
||||
{0x29, 0x3F3B2B08},
|
||||
{0x2A, 0x2CC},
|
||||
{0x2D, 0x3F3B2B08},
|
||||
{0x2E, 0x2CC},
|
||||
{0x34, 0xCE0000},
|
||||
{0x35, 0x87001A2},
|
||||
{0x36, 0x190},
|
||||
{0x37, 0x190},
|
||||
{0xF, 0},
|
||||
};
|
||||
|
||||
//Clock config.
|
||||
static const cfg_op_t _display_config_6[3] = {
|
||||
{0x34, 0x4810C001}, //CLK_RST_CONTROLLER_PLLD_BASE
|
||||
{0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
|
||||
{0x37, 0x2DFC00} //CLK_RST_CONTROLLER_PLLD_MISC
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_7[10] = {
|
||||
{0x13, 0},
|
||||
{0x10, 0},
|
||||
{0x11, 6},
|
||||
{0x12, 0x1E0},
|
||||
{DSI_DSI_POWER_CONTROL, 1},
|
||||
{0x10, 0x103032},
|
||||
{0xF, 0x33},
|
||||
{0x10, 0x103032},
|
||||
{0xF, 3},
|
||||
{0xF, 0x23}
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_config_8[6] = {
|
||||
{0x18, 0},
|
||||
{2, 0xF3F10000},
|
||||
{0x16, 1},
|
||||
{0x18, 0},
|
||||
{0x18, 0x10010},
|
||||
{0x17, 0x300}
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_9[4] = {
|
||||
{0x4F, 0},
|
||||
{0x50, 0},
|
||||
{0x51, 0x3333},
|
||||
{0x52, 0}
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_config_10[16] = {
|
||||
{0xE, 0x200200},
|
||||
{0xF, 0x200200},
|
||||
{0x19, 0x200002},
|
||||
{0x1A, 0x200002},
|
||||
{5, 0},
|
||||
{6, 0},
|
||||
{7, 0},
|
||||
{8, 0},
|
||||
{9, 0},
|
||||
{0xA, 0},
|
||||
{0x10, 0},
|
||||
{0x11, 0},
|
||||
{0x1A, 0},
|
||||
{0x1C, 0},
|
||||
{0x1D, 0},
|
||||
{0, 0x2A000001}
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t _display_config_11[113] = {
|
||||
{0x40, 0},
|
||||
{0x42, 0x10},
|
||||
{0x700, 0},
|
||||
{0x42, 0x10},
|
||||
{0x70E, 0},
|
||||
{0x700, 0},
|
||||
{0x42, 0x10},
|
||||
{0x42, 0x10},
|
||||
{0x611, 0xF0},
|
||||
{0x612, 0x12A},
|
||||
{0x613, 0},
|
||||
{0x614, 0x198},
|
||||
{0x615, 0x39B},
|
||||
{0x616, 0x32F},
|
||||
{0x617, 0x204},
|
||||
{0x618, 0},
|
||||
{0x42, 0x20},
|
||||
{0x700, 0},
|
||||
{0x42, 0x20},
|
||||
{0x70E, 0},
|
||||
{0x700, 0},
|
||||
{0x42, 0x20},
|
||||
{0x42, 0x20},
|
||||
{0x611, 0xF0},
|
||||
{0x612, 0x12A},
|
||||
{0x613, 0},
|
||||
{0x614, 0x198},
|
||||
{0x615, 0x39B},
|
||||
{0x616, 0x32F},
|
||||
{0x617, 0x204},
|
||||
{0x618, 0},
|
||||
{0x42, 0x40},
|
||||
{0x700, 0},
|
||||
{0x42, 0x40},
|
||||
{0x70E, 0},
|
||||
{0x700, 0},
|
||||
{0x42, 0x40},
|
||||
{0x42, 0x40},
|
||||
{0x611, 0xF0},
|
||||
{0x612, 0x12A},
|
||||
{0x613, 0},
|
||||
{0x614, 0x198},
|
||||
{0x615, 0x39B},
|
||||
{0x616, 0x32F},
|
||||
{0x617, 0x204},
|
||||
{0x618, 0},
|
||||
{0x42, 0x10},
|
||||
{0x700, 0},
|
||||
{0x42, 0x20},
|
||||
{0x700, 0},
|
||||
{0x42, 0x40},
|
||||
{0x700, 0},
|
||||
{0x430, 8},
|
||||
{0x42F, 0},
|
||||
{0x307, 0x1000000},
|
||||
{0x309, 0},
|
||||
{0x4E4, 0},
|
||||
{0x300, 0},
|
||||
{DC_CMD_STATE_CONTROL, 0xF00},
|
||||
{DC_CMD_STATE_CONTROL, 0xF},
|
||||
{0x42, 0x10},
|
||||
{0x716, 0x10000FF},
|
||||
{0x42, 0x20},
|
||||
{0x716, 0x10000FF},
|
||||
{0x42, 0x40},
|
||||
{0x716, 0x10000FF},
|
||||
{0x31, 0},
|
||||
{0x42, 0x10},
|
||||
{0x700, 0},
|
||||
{0x42, 0x20},
|
||||
{0x700, 0},
|
||||
{0x42, 0x40},
|
||||
{0x700, 0},
|
||||
{0x402, 0},
|
||||
{0x32, 0},
|
||||
{DC_CMD_STATE_CONTROL, 0xF00},
|
||||
{DC_CMD_STATE_CONTROL, 0xF},
|
||||
{0x40, 0},
|
||||
{0x405, 0},
|
||||
{0x406, 0x10000},
|
||||
{0x407, 0x10048},
|
||||
{0x408, 0x90048},
|
||||
{0x409, 0x50002D0},
|
||||
{0x40A, 0xA0088},
|
||||
{0x431, 0x10001},
|
||||
{0x303, 0},
|
||||
{0x432, 5},
|
||||
{0x42F, 0},
|
||||
{0x42E, 0},
|
||||
{0x31, 0},
|
||||
{0x42, 0x10},
|
||||
{0x700, 0},
|
||||
{0x42, 0x20},
|
||||
{0x700, 0},
|
||||
{0x42, 0x40},
|
||||
{0x700, 0},
|
||||
{0x402, 0},
|
||||
{0x32, 0x20},
|
||||
{DC_CMD_STATE_CONTROL, 0x100},
|
||||
{DC_CMD_STATE_CONTROL, 1},
|
||||
{0x40, 5},
|
||||
{0x40A, 0xA0088},
|
||||
{0x40, 0},
|
||||
{DC_CMD_STATE_CONTROL, 0x100},
|
||||
{DC_CMD_STATE_CONTROL, 1},
|
||||
{0, 0x301},
|
||||
{0, 0x301},
|
||||
{DC_CMD_STATE_CONTROL, 0x100},
|
||||
{DC_CMD_STATE_CONTROL, 1},
|
||||
{0x40, 0},
|
||||
{0x42E, 4},
|
||||
{0x430, 8},
|
||||
{0x31, 0}
|
||||
};
|
||||
|
||||
////Display A config.
|
||||
static const cfg_op_t _display_config_12[17] = {
|
||||
{0x40A, 0xA0088},
|
||||
{0x38, 0},
|
||||
{0x40, 0},
|
||||
{0x39, 0},
|
||||
{0x28, 0},
|
||||
{0x32, 0},
|
||||
{DC_CMD_STATE_CONTROL, 0x100},
|
||||
{DC_CMD_STATE_CONTROL, 1},
|
||||
{DC_CMD_STATE_CONTROL, 0x100},
|
||||
{DC_CMD_STATE_CONTROL, 1},
|
||||
{0, 0x301},
|
||||
{0, 0x301},
|
||||
{DC_CMD_STATE_CONTROL, 0x100},
|
||||
{DC_CMD_STATE_CONTROL, 1},
|
||||
{0x36, 0},
|
||||
{DC_CMD_STATE_CONTROL, 0x100},
|
||||
{DC_CMD_STATE_CONTROL, 1}
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_13[16] = {
|
||||
{DSI_DSI_POWER_CONTROL, 0},
|
||||
{0x4F, 0},
|
||||
{0x3C, 0x6070601},
|
||||
{0x3D, 0x40A0E05},
|
||||
{0x3E, 0x30109},
|
||||
{0x3F, 0x190A14},
|
||||
{0x44, 0x2000FFFF},
|
||||
{0x45, 0x7652000},
|
||||
{0x46, 0},
|
||||
{0xF, 0x102003},
|
||||
{0x10, 0x31},
|
||||
{DSI_DSI_POWER_CONTROL, 1},
|
||||
{0x12, 0x40},
|
||||
{0x13, 0},
|
||||
{0x14, 0},
|
||||
{0x1A, 0}
|
||||
};
|
||||
|
||||
//DSI config (if ver == 0x10).
|
||||
static const cfg_op_t _display_config_14[22] = {
|
||||
{DSI_DSI_WR_DATA, 0x439},
|
||||
{DSI_DSI_WR_DATA, 0x9483FFB9},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0x2139},
|
||||
{DSI_DSI_WR_DATA, 0x191919D5},
|
||||
{DSI_DSI_WR_DATA, 0x19191919},
|
||||
{DSI_DSI_WR_DATA, 0x19191919},
|
||||
{DSI_DSI_WR_DATA, 0x19191919},
|
||||
{DSI_DSI_WR_DATA, 0x19191919},
|
||||
{DSI_DSI_WR_DATA, 0x19191919},
|
||||
{DSI_DSI_WR_DATA, 0x19191919},
|
||||
{DSI_DSI_WR_DATA, 0x19191919},
|
||||
{DSI_DSI_WR_DATA, 0x19},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0xB39},
|
||||
{DSI_DSI_WR_DATA, 0x4F0F41B1},
|
||||
{DSI_DSI_WR_DATA, 0xF179A433},
|
||||
{DSI_DSI_WR_DATA, 0x2D81},
|
||||
{DSI_DSI_TRIGGER, 2},
|
||||
{DSI_DSI_WR_DATA, 0x439},
|
||||
{DSI_DSI_WR_DATA, 0xB9},
|
||||
{DSI_DSI_TRIGGER, 2}
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t cfg_display_one_color[8] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, 0x10}, //Enable window A.
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, 0x20}, //Enable window B.
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, 0x40}, //Enable window C.
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE
|
||||
{DC_CMD_DISPLAY_COMMAND, 0x20} //DISPLAY_CTRL_MODE: continuous display.
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t cfg_display_framebuffer[32] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, 0x40}, //Enable window C.
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, 0x20}, //Enable window B.
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, 0x10}, //Enable window A.
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE
|
||||
{DC_X_WIN_XD_COLOR_DEPTH, 0xD}, //T_A8B8G8R8
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0},
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0},
|
||||
{DC_X_WIN_XD_POSITION, 0}, //(0,0)
|
||||
{DC_X_WIN_XD_H_INITIAL_DDA, 0},
|
||||
{DC_X_WIN_XD_V_INITIAL_DDA, 0},
|
||||
{DC_X_WIN_XD_PRESCALED_SIZE, 0x5000B40}, //Pre-scaled size: 1280x2880 bytes (= 0x500 vertical lines x 0xB40 bytes).
|
||||
{DC_X_WIN_XD_DDA_INCREMENT, 0x10001000},
|
||||
{DC_X_WIN_XD_SIZE, 0x50002D0}, //Window size: 1280x720 (= 0x500 vertical lines x 0x2D0 horizontal pixels).
|
||||
{DC_X_WIN_XD_LINE_STRIDE, 0x6000C00}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{0x702, 0},
|
||||
{DC_X_WINBUF_XD_SURFACE_KIND, 0}, //Regular surface.
|
||||
{DC_X_WINBUF_XD_START_ADDR, 0xC0000000}, //Framebuffer address.
|
||||
{DC_X_WINBUF_XD_ADDR_H_OFFSET, 0},
|
||||
{DC_X_WINBUF_XD_ADDR_V_OFFSET, 0},
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE
|
||||
{DC_X_WIN_XD_WIN_OPTIONS, 0x40000000}, //Enable window AD.
|
||||
{DC_CMD_DISPLAY_COMMAND, 0x20}, //DISPLAY_CTRL_MODE: continuous display.
|
||||
{DC_CMD_STATE_CONTROL, 0x300}, //General update; window A update.
|
||||
{DC_CMD_STATE_CONTROL, 3} //General activation request; window A activation request.
|
||||
};
|
||||
2
bootloader/libs/fatfs/diskio.c → ipl/diskio.c
Normal file → Executable file
2
bootloader/libs/fatfs/diskio.c → ipl/diskio.c
Normal file → Executable file
@@ -9,7 +9,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "../../storage/sdmmc.h"
|
||||
#include "sdmmc.h"
|
||||
|
||||
extern sdmmc_storage_t sd_storage;
|
||||
|
||||
2
bootloader/libs/fatfs/diskio.h → ipl/diskio.h
Normal file → Executable file
2
bootloader/libs/fatfs/diskio.h → ipl/diskio.h
Normal file → Executable file
@@ -9,7 +9,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../utils/types.h"
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
38
bootloader/mem/emc.h → ipl/emc.h
Normal file → Executable file
38
bootloader/mem/emc.h → ipl/emc.h
Normal file → Executable file
@@ -1,23 +1,23 @@
|
||||
/*
|
||||
* arch/arm/mach-tegra/tegra21_emc.h
|
||||
*
|
||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
* arch/arm/mach-tegra/tegra21_emc.h
|
||||
*
|
||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _EMC_H_
|
||||
#define _EMC_H_
|
||||
941
bootloader/libs/fatfs/ff.c → ipl/ff.c
Normal file → Executable file
941
bootloader/libs/fatfs/ff.c → ipl/ff.c
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
20
bootloader/libs/fatfs/ff.h → ipl/ff.h
Normal file → Executable file
20
bootloader/libs/fatfs/ff.h → ipl/ff.h
Normal file → Executable file
@@ -1,8 +1,8 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.13b /
|
||||
/ FatFs - Generic FAT Filesystem module R0.13a /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2018, ChaN, all right reserved.
|
||||
/ Copyright (C) 2017, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
@@ -20,13 +20,13 @@
|
||||
|
||||
|
||||
#ifndef FF_DEFINED
|
||||
#define FF_DEFINED 63463 /* Revision ID */
|
||||
#define FF_DEFINED 89352 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../utils/types.h" /* Basic integer types */
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
@@ -45,12 +45,6 @@ typedef struct {
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#endif
|
||||
|
||||
#if FF_STR_VOLUME_ID
|
||||
#ifndef FF_VOLUME_STRS
|
||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
@@ -66,11 +60,7 @@ typedef WCHAR TCHAR;
|
||||
typedef char TCHAR;
|
||||
#define _T(x) u8 ## x
|
||||
#define _TEXT(x) u8 ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
|
||||
typedef DWORD TCHAR;
|
||||
#define _T(x) U ## x
|
||||
#define _TEXT(x) U ## x
|
||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
|
||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 2)
|
||||
#error Wrong FF_LFN_UNICODE setting
|
||||
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||
typedef char TCHAR;
|
||||
30
bootloader/libs/fatfs/ffconf.h → ipl/ffconf.h
Normal file → Executable file
30
bootloader/libs/fatfs/ffconf.h → ipl/ffconf.h
Normal file → Executable file
@@ -2,7 +2,7 @@
|
||||
/ FatFs - Configuration file
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 63463 /* Revision ID */
|
||||
#define FFCONF_DEF 89352 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
@@ -33,7 +33,7 @@
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 1
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#define FF_USE_LFN 3
|
||||
#define FF_USE_LFN 1
|
||||
#define FF_MAX_LFN 255
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
@@ -123,7 +123,6 @@
|
||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
||||
/
|
||||
/ Also behavior of string I/O functions will be affected by this option.
|
||||
/ When LFN is not enabled, this option has no effect. */
|
||||
@@ -169,16 +168,11 @@
|
||||
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "sd"
|
||||
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
|
||||
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
|
||||
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
|
||||
/ not defined, a user defined volume string table needs to be defined as:
|
||||
/
|
||||
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
|
||||
*/
|
||||
/* FF_STR_VOLUME_ID switches string support for volume ID.
|
||||
/ When FF_STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the drive ID strings for each
|
||||
/ logical drives. Number of items must be equal to FF_VOLUMES. Valid characters for
|
||||
/ the drive ID strings are: A-Z and 0-9. */
|
||||
|
||||
|
||||
#define FF_MULTI_PARTITION 0
|
||||
@@ -232,7 +226,7 @@
|
||||
|
||||
#define FF_FS_EXFAT 1
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ To enable exFAT, also LFN needs to be enabled.
|
||||
/ When enable exFAT, also LFN needs to be enabled.
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
@@ -240,9 +234,9 @@
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2018
|
||||
/* The option FF_FS_NORTC switches timestamp function. If the system does not have
|
||||
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
|
||||
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||
187
bootloader/libs/fatfs/ffunicode.c → ipl/ffunicode.c
Normal file → Executable file
187
bootloader/libs/fatfs/ffunicode.c → ipl/ffunicode.c
Normal file → Executable file
@@ -27,7 +27,7 @@
|
||||
|
||||
#if FF_USE_LFN /* This module is blanked when non-LFN configuration */
|
||||
|
||||
#if FF_DEFINED != 63463 /* Revision ID */
|
||||
#if FF_DEFINED != 89352 /* Revision ID */
|
||||
#error Wrong include file (ff.h).
|
||||
#endif
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@@ -52,7 +53,8 @@ static const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */
|
||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||
@@ -64,7 +66,8 @@ static const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */
|
||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||
@@ -76,7 +79,8 @@ static const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
@@ -88,7 +92,8 @@ static const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */
|
||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||
@@ -100,7 +105,8 @@ static const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@@ -112,7 +118,8 @@ static const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||
@@ -124,7 +131,8 @@ static const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table */
|
||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||
@@ -136,7 +144,8 @@ static const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table *
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@@ -148,7 +157,8 @@ static const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
|
||||
0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@@ -160,7 +170,8 @@ static const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@@ -172,7 +183,8 @@ static const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@@ -184,7 +196,8 @@ static const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
|
||||
0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
|
||||
0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
|
||||
@@ -196,7 +209,8 @@ static const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */
|
||||
0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
|
||||
0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
|
||||
0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
|
||||
@@ -208,7 +222,8 @@ static const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
|
||||
@@ -220,7 +235,8 @@ static const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
@@ -232,7 +248,8 @@ static const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */
|
||||
static
|
||||
const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */
|
||||
0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
|
||||
0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
|
||||
0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
|
||||
@@ -266,7 +283,7 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
c = (WCHAR)uni;
|
||||
|
||||
} else { /* Non-ASCII */
|
||||
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */
|
||||
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it a valid code? */
|
||||
for (c = 0; c < 0x80 && uni != p[c]; c++) ;
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
@@ -313,28 +330,30 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0, uc;
|
||||
UINT i = 0, n, li, hi;
|
||||
UINT i, n, li, hi;
|
||||
|
||||
|
||||
if (uni < 0x80) { /* ASCII? */
|
||||
c = (WCHAR)uni;
|
||||
|
||||
} else { /* Non-ASCII */
|
||||
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */
|
||||
uc = (WCHAR)uni;
|
||||
p = CVTBL(uni2oem, FF_CODE_PAGE);
|
||||
hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1;
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
i = li + (hi - li) / 2;
|
||||
if (uc == p[i * 2]) break;
|
||||
if (uc > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
if (uni < 0x10000) { /* Is it in BMP? */
|
||||
if (cp == FF_CODE_PAGE) { /* Is it a valid code? */
|
||||
uc = (WCHAR)uni;
|
||||
p = CVTBL(uni2oem, FF_CODE_PAGE);
|
||||
hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1;
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
i = li + (hi - li) / 2;
|
||||
if (uc == p[i * 2]) break;
|
||||
if (uc > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
}
|
||||
}
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,14 +368,14 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0;
|
||||
UINT i = 0, n, li, hi;
|
||||
UINT i, n, li, hi;
|
||||
|
||||
|
||||
if (oem < 0x80) { /* ASCII? */
|
||||
c = oem;
|
||||
|
||||
} else { /* Extended char */
|
||||
if (cp == FF_CODE_PAGE) { /* Is it valid code page? */
|
||||
if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */
|
||||
p = CVTBL(oem2uni, FF_CODE_PAGE);
|
||||
hi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1;
|
||||
li = 0;
|
||||
@@ -386,7 +405,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
#if FF_CODE_PAGE == 0
|
||||
|
||||
static const WORD cp_code[] = { 437, 720, 737, 771, 775, 850, 852, 855, 857, 860, 861, 862, 863, 864, 865, 866, 869, 0};
|
||||
static const WCHAR* const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0};
|
||||
static const WCHAR *const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0};
|
||||
|
||||
|
||||
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
@@ -407,20 +426,20 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
uc = (WCHAR)uni;
|
||||
p = 0;
|
||||
if (cp < 900) { /* SBCS */
|
||||
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get conversion table */
|
||||
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */
|
||||
p = cp_table[i];
|
||||
if (p) { /* Is it valid code page ? */
|
||||
if (p) { /* Is it a valid CP ? */
|
||||
for (c = 0; c < 0x80 && uc != p[c]; c++) ; /* Find OEM code in the table */
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
} else { /* DBCS */
|
||||
switch (cp) { /* Get conversion table */
|
||||
switch (cp) {
|
||||
case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break;
|
||||
case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break;
|
||||
case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break;
|
||||
case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break;
|
||||
}
|
||||
if (p) { /* Is it valid code page? */
|
||||
if (p) { /* Is it a valid code page? */
|
||||
li = 0;
|
||||
for (n = 16; n; n--) { /* Find OEM code */
|
||||
i = li + (hi - li) / 2;
|
||||
@@ -499,90 +518,50 @@ DWORD ff_wtoupper ( /* Returns up-converted code point */
|
||||
DWORD uni /* Unicode code point to be up-converted */
|
||||
)
|
||||
{
|
||||
const WORD *p;
|
||||
WORD uc, bc, nc, cmd;
|
||||
static const WORD cvt1[] = { /* Compressed up conversion table for U+0000 - U+0FFF */
|
||||
/* Compressed upper conversion table */
|
||||
static const WORD cvt1[] = { /* U+0000 - U+0FFF */
|
||||
/* Basic Latin */
|
||||
0x0061,0x031A,
|
||||
/* Latin-1 Supplement */
|
||||
0x00E0,0x0317,
|
||||
0x00F8,0x0307,
|
||||
0x00FF,0x0001,0x0178,
|
||||
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
|
||||
/* Latin Extended-A */
|
||||
0x0100,0x0130,
|
||||
0x0132,0x0106,
|
||||
0x0139,0x0110,
|
||||
0x014A,0x012E,
|
||||
0x0179,0x0106,
|
||||
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
|
||||
/* Latin Extended-B */
|
||||
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
|
||||
0x01CD,0x0110,
|
||||
0x01DD,0x0001,0x018E,
|
||||
0x01DE,0x0112,
|
||||
0x01F3,0x0003,0x01F1,0x01F4,0x01F4,
|
||||
0x01F8,0x0128,
|
||||
0x0222,0x0112,
|
||||
0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241,
|
||||
0x0246,0x010A,
|
||||
0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128,
|
||||
0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A,
|
||||
/* IPA Extensions */
|
||||
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
|
||||
/* Greek, Coptic */
|
||||
0x037B,0x0003,0x03FD,0x03FE,0x03FF,
|
||||
0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A,
|
||||
0x03B1,0x0311,
|
||||
0x03C2,0x0002,0x03A3,0x03A3,
|
||||
0x03C4,0x0308,
|
||||
0x03CC,0x0003,0x038C,0x038E,0x038F,
|
||||
0x03D8,0x0118,
|
||||
0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311,
|
||||
0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118,
|
||||
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
|
||||
/* Cyrillic */
|
||||
0x0430,0x0320,
|
||||
0x0450,0x0710,
|
||||
0x0460,0x0122,
|
||||
0x048A,0x0136,
|
||||
0x04C1,0x010E,
|
||||
0x04CF,0x0001,0x04C0,
|
||||
0x04D0,0x0144,
|
||||
0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144,
|
||||
/* Armenian */
|
||||
0x0561,0x0426,
|
||||
|
||||
0x0000 /* EOT */
|
||||
0x0000
|
||||
};
|
||||
static const WORD cvt2[] = { /* Compressed up conversion table for U+1000 - U+FFFF */
|
||||
static const WORD cvt2[] = { /* U+1000 - U+FFFF */
|
||||
/* Phonetic Extensions */
|
||||
0x1D7D,0x0001,0x2C63,
|
||||
/* Latin Extended Additional */
|
||||
0x1E00,0x0196,
|
||||
0x1EA0,0x015A,
|
||||
0x1E00,0x0196, 0x1EA0,0x015A,
|
||||
/* Greek Extended */
|
||||
0x1F00,0x0608,
|
||||
0x1F10,0x0606,
|
||||
0x1F20,0x0608,
|
||||
0x1F30,0x0608,
|
||||
0x1F40,0x0606,
|
||||
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F,
|
||||
0x1F60,0x0608,
|
||||
0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606,
|
||||
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608,
|
||||
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
|
||||
0x1F80,0x0608,
|
||||
0x1F90,0x0608,
|
||||
0x1FA0,0x0608,
|
||||
0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
|
||||
0x1FCC,0x0001,0x1FC3,
|
||||
0x1FD0,0x0602,
|
||||
0x1FE0,0x0602,
|
||||
0x1FE5,0x0001,0x1FEC,
|
||||
0x1FF3,0x0001,0x1FFC,
|
||||
0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
|
||||
0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF3,0x0001,0x1FFC,
|
||||
/* Letterlike Symbols */
|
||||
0x214E,0x0001,0x2132,
|
||||
/* Number forms */
|
||||
0x2170,0x0210,
|
||||
0x2184,0x0001,0x2183,
|
||||
0x2170,0x0210, 0x2184,0x0001,0x2183,
|
||||
/* Enclosed Alphanumerics */
|
||||
0x24D0,0x051A,
|
||||
0x2C30,0x042F,
|
||||
0x24D0,0x051A, 0x2C30,0x042F,
|
||||
/* Latin Extended-C */
|
||||
0x2C60,0x0102,
|
||||
0x2C67,0x0106, 0x2C75,0x0102,
|
||||
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
|
||||
/* Coptic */
|
||||
0x2C80,0x0164,
|
||||
/* Georgian Supplement */
|
||||
@@ -590,16 +569,18 @@ DWORD ff_wtoupper ( /* Returns up-converted code point */
|
||||
/* Full-width */
|
||||
0xFF41,0x031A,
|
||||
|
||||
0x0000 /* EOT */
|
||||
0x0000
|
||||
};
|
||||
const WORD *p;
|
||||
WORD uc, bc, nc, cmd;
|
||||
|
||||
|
||||
if (uni < 0x10000) { /* Is it in BMP? */
|
||||
uc = (WORD)uni;
|
||||
p = uc < 0x1000 ? cvt1 : cvt2;
|
||||
for (;;) {
|
||||
bc = *p++; /* Get the block base */
|
||||
if (bc == 0 || uc < bc) break; /* Not matched? */
|
||||
bc = *p++; /* Get block base */
|
||||
if (!bc || uc < bc) break;
|
||||
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
|
||||
if (uc < bc + nc) { /* In the block? */
|
||||
switch (cmd) {
|
||||
@@ -615,7 +596,7 @@ DWORD ff_wtoupper ( /* Returns up-converted code point */
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cmd == 0) p += nc; /* Skip table if needed */
|
||||
if (!cmd) p += nc;
|
||||
}
|
||||
uni = uc;
|
||||
}
|
||||
28
ipl/fuse.c
Executable file
28
ipl/fuse.c
Executable file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "fuse.h"
|
||||
#include "t210.h"
|
||||
|
||||
void fuse_disable_program()
|
||||
{
|
||||
FUSE(FUSE_DISABLEREGPROGRAM) = 1;
|
||||
}
|
||||
|
||||
u32 fuse_read_odm(u32 idx)
|
||||
{
|
||||
return FUSE(FUSE_RESERVED_ODMX(idx));
|
||||
}
|
||||
44
ipl/fuse.h
Executable file
44
ipl/fuse.h
Executable file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 _FUSE_H_
|
||||
#define _FUSE_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*! Fuse registers. */
|
||||
#define FUSE_CTRL 0x0
|
||||
#define FUSE_ADDR 0x4
|
||||
#define FUSE_RDATA 0x8
|
||||
#define FUSE_WDATA 0xC
|
||||
#define FUSE_TIME_RD1 0x10
|
||||
#define FUSE_TIME_RD2 0x14
|
||||
#define FUSE_TIME_PGM1 0x18
|
||||
#define FUSE_TIME_PGM2 0x1C
|
||||
#define FUSE_PRIV2INTFC 0x20
|
||||
#define FUSE_FUSEBYPASS 0x24
|
||||
#define FUSE_PRIVATEKEYDISABLE 0x28
|
||||
#define FUSE_DISABLEREGPROGRAM 0x2C
|
||||
#define FUSE_WRITE_ACCESS_SW 0x30
|
||||
#define FUSE_PWR_GOOD_SW 0x34
|
||||
|
||||
/*! Fuse cache registers. */
|
||||
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
|
||||
|
||||
void fuse_disable_program();
|
||||
u32 fuse_read_odm(u32 idx);
|
||||
|
||||
#endif
|
||||
323
ipl/gfx.c
Executable file
323
ipl/gfx.c
Executable file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "gfx.h"
|
||||
|
||||
static const u8 _gfx_font[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x18, 0x18, 0x00, 0x0C, 0x00,
|
||||
0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66,
|
||||
0x00, 0x18, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x18, 0x10, 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62,
|
||||
0x00, 0x3C, 0x66, 0x3C, 0x1C, 0xE6, 0x66, 0xFC, 0x00, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x18, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x00,
|
||||
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00,
|
||||
0x00, 0x3C, 0x66, 0x76, 0x6E, 0x66, 0x3C, 0x00, 0x00, 0x18, 0x1C, 0x18, 0x18, 0x18, 0x7E, 0x00,
|
||||
0x00, 0x3C, 0x62, 0x30, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x62, 0x38, 0x60, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x6C, 0x6C, 0x66, 0xFE, 0x60, 0x60, 0x00, 0x00, 0x7E, 0x06, 0x7E, 0x60, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x7E, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00,
|
||||
0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x3C, 0x66, 0x7C, 0x60, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x00,
|
||||
0x00, 0x70, 0x1C, 0x06, 0x06, 0x1C, 0x70, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0E, 0x38, 0x60, 0x60, 0x38, 0x0E, 0x00, 0x00, 0x3C, 0x66, 0x30, 0x18, 0x00, 0x18, 0x00,
|
||||
0x00, 0x3C, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3C, 0x00, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
|
||||
0x00, 0x3E, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x06, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x1E, 0x36, 0x66, 0x66, 0x36, 0x1E, 0x00, 0x00, 0x7E, 0x06, 0x1E, 0x06, 0x06, 0x7E, 0x00,
|
||||
0x00, 0x3E, 0x06, 0x1E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x76, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
|
||||
0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x00,
|
||||
0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00, 0x00, 0x46, 0x6E, 0x7E, 0x56, 0x46, 0x46, 0x00,
|
||||
0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x3E, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x70, 0x00,
|
||||
0x00, 0x3E, 0x66, 0x3E, 0x1E, 0x36, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x0C, 0x30, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x46, 0x46, 0x56, 0x7E, 0x6E, 0x46, 0x00,
|
||||
0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00,
|
||||
0x00, 0x7E, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C,
|
||||
0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C,
|
||||
0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
|
||||
0x00, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00,
|
||||
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00, 0x3C, 0x06, 0x06, 0x06, 0x3C, 0x00,
|
||||
0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00,
|
||||
0x00, 0x38, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x7C, 0x40, 0x3C, 0x00,
|
||||
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x18, 0x00, 0x1C, 0x18, 0x18, 0x3C, 0x00,
|
||||
0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1E, 0x00, 0x00, 0x06, 0x06, 0x36, 0x1E, 0x36, 0x66, 0x00,
|
||||
0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x66, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x66, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00,
|
||||
0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00,
|
||||
0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x7C, 0x60, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08,
|
||||
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x0C, 0x08, 0x08, 0x10, 0x08, 0x08,
|
||||
0x00, 0x00, 0x00, 0x4c, 0x32, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
void gfx_init_ctxt(gfx_ctxt_t *ctxt, u32 *fb, u32 width, u32 height, u32 stride)
|
||||
{
|
||||
ctxt->fb = fb;
|
||||
ctxt->width = width;
|
||||
ctxt->height = height;
|
||||
ctxt->stride = stride;
|
||||
}
|
||||
|
||||
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_init(gfx_con_t *con, gfx_ctxt_t *ctxt)
|
||||
{
|
||||
con->gfx_ctxt = ctxt;
|
||||
con->x = 0;
|
||||
con->y = 0;
|
||||
con->fgcol = 0xFFFFFFFF;
|
||||
con->fillbg = 0;
|
||||
con->bgcol = 0xFF1B1B1B;
|
||||
}
|
||||
|
||||
void gfx_con_setcol(gfx_con_t *con, u32 fgcol, int fillbg, u32 bgcol)
|
||||
{
|
||||
con->fgcol = fgcol;
|
||||
con->fillbg = fillbg;
|
||||
con->bgcol = bgcol;
|
||||
}
|
||||
|
||||
void gfx_con_getpos(gfx_con_t *con, u32 *x, u32 *y)
|
||||
{
|
||||
*x = con->x;
|
||||
*y = con->y;
|
||||
}
|
||||
|
||||
void gfx_con_setpos(gfx_con_t *con, u32 x, u32 y)
|
||||
{
|
||||
con->x = x;
|
||||
con->y = y;
|
||||
}
|
||||
|
||||
void gfx_putc(gfx_con_t *con, char c)
|
||||
{
|
||||
if (c >= 32 && c <= 126)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
u8 v = *cbuf++;
|
||||
for (u32 j = 0; j < 8; j++)
|
||||
{
|
||||
if (v & 1)
|
||||
*fb = con->fgcol;
|
||||
else if (con->fillbg)
|
||||
*fb = con->bgcol;
|
||||
v >>= 1;
|
||||
fb++;
|
||||
}
|
||||
fb += con->gfx_ctxt->stride - 8;
|
||||
}
|
||||
con->x += 8;
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
con->x = 0;
|
||||
con->y += 8;
|
||||
if (con->y > con->gfx_ctxt->height - 8)
|
||||
con->y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_puts(gfx_con_t *con, const char *s)
|
||||
{
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
for (; *s; s++)
|
||||
gfx_putc(con, *s);
|
||||
}
|
||||
|
||||
static void _gfx_putn(gfx_con_t *con, u32 v, int base, char fill, int fcnt)
|
||||
{
|
||||
char buf[65];
|
||||
static const char digits[] = "0123456789ABCDEFghijklmnopqrstuvwxyz";
|
||||
char *p;
|
||||
int c = fcnt;
|
||||
|
||||
if (base > 36)
|
||||
return;
|
||||
|
||||
p = buf + 64;
|
||||
*p = 0;
|
||||
do
|
||||
{
|
||||
c--;
|
||||
*--p = digits[v % base];
|
||||
v /= base;
|
||||
} while (v);
|
||||
|
||||
if (fill != 0)
|
||||
{
|
||||
while (c > 0)
|
||||
{
|
||||
*--p = fill;
|
||||
c--;
|
||||
}
|
||||
}
|
||||
|
||||
gfx_puts(con, p);
|
||||
}
|
||||
|
||||
void gfx_printf(gfx_con_t *con, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int fill, fcnt;
|
||||
|
||||
va_start(ap, fmt);
|
||||
while(*fmt)
|
||||
{
|
||||
if(*fmt == '%')
|
||||
{
|
||||
fmt++;
|
||||
fill = 0;
|
||||
fcnt = 0;
|
||||
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
|
||||
{
|
||||
fcnt = *fmt;
|
||||
fmt++;
|
||||
if (*fmt >= '0' && *fmt <= '9')
|
||||
{
|
||||
fill = fcnt;
|
||||
fcnt = *fmt - '0';
|
||||
fmt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fill = ' ';
|
||||
fcnt -= '0';
|
||||
}
|
||||
}
|
||||
switch(*fmt)
|
||||
{
|
||||
case 'c':
|
||||
gfx_putc(con, va_arg(ap, u32));
|
||||
break;
|
||||
case 's':
|
||||
gfx_puts(con, va_arg(ap, char *));
|
||||
break;
|
||||
case 'd':
|
||||
_gfx_putn(con, va_arg(ap, u32), 10, fill, fcnt);
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
_gfx_putn(con, va_arg(ap, u32), 16, fill, fcnt);
|
||||
break;
|
||||
case 'k':
|
||||
con->fgcol = va_arg(ap, u32);
|
||||
break;
|
||||
case 'K':
|
||||
con->bgcol = va_arg(ap, u32);
|
||||
con->fillbg = fcnt;
|
||||
break;
|
||||
case '%':
|
||||
gfx_putc(con, '%');
|
||||
break;
|
||||
case '\0':
|
||||
goto out;
|
||||
default:
|
||||
gfx_putc(con, '%');
|
||||
gfx_putc(con, *fmt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
gfx_putc(con, *fmt);
|
||||
fmt++;
|
||||
}
|
||||
|
||||
out:
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void gfx_hexdump(gfx_con_t *con, u32 base, const u8 *buf, u32 len)
|
||||
{
|
||||
for(u32 i = 0; i < len; i++)
|
||||
{
|
||||
if(i % 0x10 == 0)
|
||||
{
|
||||
if(i != 0)
|
||||
{
|
||||
gfx_puts(con, "| ");
|
||||
for(u32 j = 0; j < 0x10; j++)
|
||||
{
|
||||
u8 c = buf[i - 0x10 + j];
|
||||
if(c >= 32 && c < 128)
|
||||
gfx_putc(con, c);
|
||||
else
|
||||
gfx_putc(con, '.');
|
||||
}
|
||||
gfx_putc(con, '\n');
|
||||
}
|
||||
gfx_printf(con, "%08x: ", base + i);
|
||||
}
|
||||
gfx_printf(con, "%02x ", buf[i]);
|
||||
}
|
||||
gfx_putc(con, '\n');
|
||||
}
|
||||
|
||||
static int abs(int x)
|
||||
{
|
||||
if (x < 0)
|
||||
return -x;
|
||||
return x;
|
||||
}
|
||||
|
||||
void gfx_set_pixel(gfx_ctxt_t *ctxt, u32 x, u32 y, u32 color)
|
||||
{
|
||||
ctxt->fb[x + y * ctxt->stride] = 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 err = (dx > dy ? dx : -dy) / 2, e2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
gfx_set_pixel(ctxt, x0, y0, color);
|
||||
if (x0 == x1 && y0 == y1)
|
||||
break;
|
||||
e2 = err;
|
||||
if (e2 >-dx) { err -= dy; x0 += sx; }
|
||||
if (e2 < dy) { err += dx; y0 += sy; }
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_set_logo(gfx_ctxt_t *ctxt, u16 pos_x, u16 pos_y,
|
||||
const u16 size_x, const u16 size_y, const u8 *buf)
|
||||
{
|
||||
u32 pos = 0;
|
||||
for (u32 y = pos_y; y < pos_y + size_y; y++)
|
||||
{
|
||||
for (u32 x = pos_x; x < pos_x + size_x; x++)
|
||||
{
|
||||
ctxt->fb[x + y*ctxt->stride] = (0xFF << 24) | buf[pos] | (buf[pos + 1] << 8) | (buf[pos + 2] << 16);
|
||||
pos+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
ipl/gfx.h
Executable file
55
ipl/gfx.h
Executable file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 _GFX_H_
|
||||
#define _GFX_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct _gfx_ctxt_t
|
||||
{
|
||||
u32 *fb;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 stride;
|
||||
} gfx_ctxt_t;
|
||||
|
||||
typedef struct _gfx_con_t
|
||||
{
|
||||
gfx_ctxt_t *gfx_ctxt;
|
||||
u32 x;
|
||||
u32 y;
|
||||
u32 fgcol;
|
||||
int fillbg;
|
||||
u32 bgcol;
|
||||
} gfx_con_t;
|
||||
|
||||
void gfx_init_ctxt(gfx_ctxt_t *ctxt, u32 *fb, u32 width, u32 height, u32 stride);
|
||||
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_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, ...);
|
||||
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_set_logo(gfx_ctxt_t *ctxt, u16 pos_x, u16 pos_y, const u16 size_x, const u16 size_y, const u8 *buf);
|
||||
|
||||
#endif
|
||||
34
bootloader/soc/gpio.c → ipl/gpio.c
Normal file → Executable file
34
bootloader/soc/gpio.c → ipl/gpio.c
Normal file → Executable file
@@ -1,21 +1,21 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "../soc/gpio.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "gpio.h"
|
||||
#include "t210.h"
|
||||
|
||||
static const u16 _gpio_cnf[31] = {
|
||||
0x000, 0x004, 0x008, 0x00C,
|
||||
@@ -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;
|
||||
}
|
||||
30
bootloader/soc/gpio.h → ipl/gpio.h
Normal file → Executable file
30
bootloader/soc/gpio.h → ipl/gpio.h
Normal file → Executable file
@@ -1,23 +1,23 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
* 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 _GPIO_H_
|
||||
#define _GPIO_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "types.h"
|
||||
|
||||
#define GPIO_MODE_SPIO 0
|
||||
#define GPIO_MODE_GPIO 1
|
||||
64
bootloader/mem/heap.c → ipl/heap.c
Normal file → Executable file
64
bootloader/mem/heap.c → ipl/heap.c
Normal file → Executable file
@@ -1,23 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 M4xw
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "heap.h"
|
||||
#include "../../common/common_heap.h"
|
||||
|
||||
typedef struct _hnode
|
||||
{
|
||||
int used;
|
||||
u32 size;
|
||||
struct _hnode *prev;
|
||||
struct _hnode *next;
|
||||
} hnode_t;
|
||||
|
||||
typedef struct _heap
|
||||
{
|
||||
u32 start;
|
||||
hnode_t *first;
|
||||
} heap_t;
|
||||
|
||||
static void _heap_create(heap_t *heap, u32 start)
|
||||
{
|
||||
@@ -25,12 +37,12 @@ static void _heap_create(heap_t *heap, u32 start)
|
||||
heap->first = NULL;
|
||||
}
|
||||
|
||||
static u32 _heap_alloc(heap_t *heap, u32 size, u32 alignment)
|
||||
static u32 _heap_alloc(heap_t *heap, u32 size)
|
||||
{
|
||||
hnode_t *node, *new;
|
||||
int search = 1;
|
||||
|
||||
size = ALIGN(size, alignment);
|
||||
size = ALIGN(size, 0x10);
|
||||
|
||||
if (!heap->first)
|
||||
{
|
||||
@@ -85,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);
|
||||
@@ -93,12 +104,11 @@ static void _heap_free(heap_t *heap, u32 addr)
|
||||
if (node->next)
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
heap_t _heap;
|
||||
static heap_t _heap;
|
||||
|
||||
void heap_init(u32 base)
|
||||
{
|
||||
@@ -107,23 +117,17 @@ void heap_init(u32 base)
|
||||
|
||||
void *malloc(u32 size)
|
||||
{
|
||||
return (void *)_heap_alloc(&_heap, size, 0x10);
|
||||
}
|
||||
|
||||
void *memalign(u32 align, u32 size)
|
||||
{
|
||||
return (void *)_heap_alloc(&_heap, size, align);
|
||||
return (void *)_heap_alloc(&_heap, size);
|
||||
}
|
||||
|
||||
void *calloc(u32 num, u32 size)
|
||||
{
|
||||
void *res = (void *)_heap_alloc(&_heap, num * size, 0x10);
|
||||
void *res = (void *)_heap_alloc(&_heap, num * size);
|
||||
memset(res, 0, num * size);
|
||||
return res;
|
||||
}
|
||||
|
||||
void free(void *buf)
|
||||
{
|
||||
if ((buf != NULL) || ((u32)buf > (_heap.start - 1)))
|
||||
_heap_free(&_heap, (u32)buf);
|
||||
_heap_free(&_heap, (u32)buf);
|
||||
}
|
||||
27
ipl/heap.h
Executable file
27
ipl/heap.h
Executable file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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 _HEAP_H_
|
||||
#define _HEAP_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void heap_init(u32 base);
|
||||
void *malloc(u32 size);
|
||||
void *calloc(u32 num, u32 size);
|
||||
void free(void *buf);
|
||||
|
||||
#endif
|
||||
505
ipl/hos.c
Executable file
505
ipl/hos.c
Executable file
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "hos.h"
|
||||
#include "sdmmc.h"
|
||||
#include "nx_emmc.h"
|
||||
#include "t210.h"
|
||||
#include "se.h"
|
||||
#include "se_t210.h"
|
||||
#include "pmc.h"
|
||||
#include "cluster.h"
|
||||
#include "heap.h"
|
||||
#include "tsec.h"
|
||||
#include "pkg2.h"
|
||||
#include "nx_emmc.h"
|
||||
#include "util.h"
|
||||
#include "pkg1.h"
|
||||
#include "pkg2.h"
|
||||
#include "ff.h"
|
||||
|
||||
#include "gfx.h"
|
||||
extern gfx_ctxt_t gfx_ctxt;
|
||||
extern gfx_con_t gfx_con;
|
||||
#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
|
||||
//#define DPRINTF(...)
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
#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
|
||||
{ 0x2D, 0x1F, 0x48, 0x80, 0xED, 0xEC, 0xED, 0x3E, 0x3C, 0xF2, 0x48, 0xB5, 0x65, 0x7D, 0xF7, 0xBE }, //4.0.0
|
||||
{ 0xBB, 0x5A, 0x01, 0xF9, 0x88, 0xAF, 0xF5, 0xFC, 0x6C, 0xFF, 0x07, 0x9E, 0x13, 0x3C, 0x39, 0x80 } //5.0.0
|
||||
};
|
||||
|
||||
static const u8 cmac_keyseed[0x10] =
|
||||
{ 0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5 };
|
||||
|
||||
static const u8 master_keyseed_retail[0x10] =
|
||||
{ 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C };
|
||||
|
||||
static const u8 console_keyseed[0x10] =
|
||||
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
|
||||
|
||||
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[0x10] =
|
||||
{ 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66 };
|
||||
|
||||
static const u8 console_keyseed_4xx[0x10] =
|
||||
{ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
|
||||
|
||||
|
||||
static void _se_lock()
|
||||
{
|
||||
for (u32 i = 0; i < 16; i++)
|
||||
se_key_acc_ctrl(i, 0x15);
|
||||
|
||||
for (u32 i = 0; i < 2; i++)
|
||||
se_rsa_acc_ctrl(i, 1);
|
||||
|
||||
SE(0x4) = 0; //Make this reg secure only.
|
||||
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) = 0; //Make all key access regs secure only.
|
||||
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) = 0; //Make all rsa access regs secure only.
|
||||
SE(SE_SECURITY_0) &= 0xFFFFFFFB; //Make access lock regs secure only.
|
||||
|
||||
//This is useful for documenting the bits in the SE config registers, so we can keep it around.
|
||||
/*gfx_printf(&gfx_con, "SE(SE_SECURITY_0) = %08X\n", SE(SE_SECURITY_0));
|
||||
gfx_printf(&gfx_con, "SE(0x4) = %08X\n", SE(0x4));
|
||||
gfx_printf(&gfx_con, "SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) = %08X\n", SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET));
|
||||
gfx_printf(&gfx_con, "SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) = %08X\n", SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET));
|
||||
for(u32 i = 0; i < 16; i++)
|
||||
gfx_printf(&gfx_con, "%02X ", SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + i * 4) & 0xFF);
|
||||
gfx_putc(&gfx_con, '\n');
|
||||
for(u32 i = 0; i < 2; i++)
|
||||
gfx_printf(&gfx_con, "%02X ", SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + i * 4) & 0xFF);
|
||||
gfx_putc(&gfx_con, '\n');
|
||||
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];
|
||||
|
||||
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(0x0D, tmp, 0x10);
|
||||
|
||||
//Derive keyblob keys from TSEC+SBK.
|
||||
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(0x0E);
|
||||
|
||||
//TODO: verify keyblob CMAC.
|
||||
//se_aes_unwrap_key(11, 13, cmac_keyseed);
|
||||
//se_aes_cmac(tmp, 0x10, 11, keyblob + 0x10, 0xA0);
|
||||
//if (!memcmp(keyblob, tmp, 0x10))
|
||||
// return 0;
|
||||
|
||||
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(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(0x0C, 0, tmp, master_keyseed_retail);
|
||||
|
||||
switch (kb) {
|
||||
case KB_FIRMWARE_VERSION_100_200:
|
||||
case KB_FIRMWARE_VERSION_300:
|
||||
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(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:
|
||||
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(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;
|
||||
} 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;
|
||||
sdmmc_storage_t storage;
|
||||
sdmmc_t sdmmc;
|
||||
|
||||
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4);
|
||||
|
||||
//Read package1.
|
||||
ctxt->pkg1 = (u8 *)malloc(0x40000);
|
||||
sdmmc_storage_set_mmc_partition(&storage, 1);
|
||||
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, ctxt->pkg1);
|
||||
ctxt->pkg1_id = pkg1_identify(ctxt->pkg1);
|
||||
if (!ctxt->pkg1_id)
|
||||
{
|
||||
DPRINTF("%kCould not identify package 1 version (= '%s').%k\n", 0xFF0000FF, (char *)ctxt->pkg1 + 0x10, 0xFFFFFFFF);
|
||||
goto out;
|
||||
}
|
||||
DPRINTF("Identified package1 ('%s'), keyblob version %d\n", (char *)(ctxt->pkg1 + 0x10), ctxt->pkg1_id->kb);
|
||||
|
||||
//Read the correct keyblob.
|
||||
ctxt->keyblob = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
|
||||
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
sdmmc_storage_end(&storage);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _read_emmc_pkg2(launch_ctxt_t *ctxt)
|
||||
{
|
||||
int res = 0;
|
||||
sdmmc_storage_t storage;
|
||||
sdmmc_t sdmmc;
|
||||
|
||||
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4);
|
||||
sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||
|
||||
//Parse eMMC GPT.
|
||||
LIST_INIT(gpt);
|
||||
nx_emmc_gpt_parse(&gpt, &storage);
|
||||
DPRINTF("parsed GPT\n");
|
||||
//Find package2 partition.
|
||||
emmc_part_t *pkg2_part = nx_emmc_part_find(&gpt, "BCPKG2-1-Normal-Main");
|
||||
if (!pkg2_part)
|
||||
goto out;
|
||||
|
||||
//Read in package2 header and get package2 real size.
|
||||
//TODO: implement memalign for DMA buffers.
|
||||
u8 *tmp = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
|
||||
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE, 1, tmp);
|
||||
u32 *hdr = (u32 *)(tmp + 0x100);
|
||||
u32 pkg2_size = hdr[0] ^ hdr[2] ^ hdr[3];
|
||||
free(tmp);
|
||||
DPRINTF("pkg2 size on emmc is %08X\n", pkg2_size);
|
||||
//Read in package2.
|
||||
u32 pkg2_size_aligned = ALIGN(pkg2_size, NX_EMMC_BLOCKSIZE);
|
||||
DPRINTF("pkg2 size aligned is %08X\n", pkg2_size_aligned);
|
||||
ctxt->pkg2 = malloc(pkg2_size_aligned);
|
||||
ctxt->pkg2_size = pkg2_size;
|
||||
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE,
|
||||
pkg2_size_aligned / NX_EMMC_BLOCKSIZE, ctxt->pkg2);
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
nx_emmc_gpt_free(&gpt);
|
||||
sdmmc_storage_end(&storage);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _config_warmboot(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
FIL fp;
|
||||
if (f_open(&fp, value, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
ctxt->warmboot_size = f_size(&fp);
|
||||
ctxt->warmboot = malloc(ctxt->warmboot_size);
|
||||
f_read(&fp, ctxt->warmboot, ctxt->warmboot_size, NULL);
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_secmon(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
FIL fp;
|
||||
if (f_open(&fp, value, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
ctxt->secmon_size = f_size(&fp);
|
||||
ctxt->secmon = malloc(ctxt->secmon_size);
|
||||
f_read(&fp, ctxt->secmon, ctxt->secmon_size, NULL);
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_kernel(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
FIL fp;
|
||||
if (f_open(&fp, value, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
ctxt->kernel_size = f_size(&fp);
|
||||
ctxt->kernel = malloc(ctxt->kernel_size);
|
||||
f_read(&fp, ctxt->kernel, ctxt->kernel_size, NULL);
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
FIL fp;
|
||||
if (f_open(&fp, value, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||
mkip1->kip1 = malloc(f_size(&fp));
|
||||
f_read(&fp, mkip1->kip1, f_size(&fp), NULL);
|
||||
DPRINTF("loaded kip from SD (size %08X)\n", f_size(&fp));
|
||||
f_close(&fp);
|
||||
list_append(&ctxt->kip1_list, &mkip1->link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef struct _cfg_handler_t
|
||||
{
|
||||
const char *key;
|
||||
int (*handler)(launch_ctxt_t *ctxt, const char *value);
|
||||
} cfg_handler_t;
|
||||
|
||||
static const cfg_handler_t _config_handlers[] = {
|
||||
{ "warmboot", _config_warmboot },
|
||||
{ "secmon", _config_secmon },
|
||||
{ "kernel", _config_kernel },
|
||||
{ "kip1", _config_kip1 },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
static int _config(launch_ctxt_t *ctxt, ini_sec_t *cfg)
|
||||
{
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link)
|
||||
for(u32 i = 0; _config_handlers[i].key; i++)
|
||||
if (!strcmp(_config_handlers[i].key, kv->key) &&
|
||||
!_config_handlers[i].handler(ctxt, kv->val))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int hos_launch(ini_sec_t *cfg)
|
||||
{
|
||||
launch_ctxt_t ctxt;
|
||||
memset(&ctxt, 0, sizeof(launch_ctxt_t));
|
||||
list_init(&ctxt.kip1_list);
|
||||
|
||||
if (cfg && !_config(&ctxt, cfg))
|
||||
return 0;
|
||||
|
||||
//Read package1 and the correct keyblob.
|
||||
if (!_read_emmc_pkg1(&ctxt))
|
||||
return 0;
|
||||
|
||||
//XXX: remove this once we support 3+.
|
||||
//if (ctxt.pkg1_id->kb > 0)
|
||||
// return 0;
|
||||
|
||||
DPRINTF("loaded pkg1 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 *)0x8000D000, (void *)ctxt.pkg1_id->secmon_base, ctxt.pkg1_id, ctxt.pkg1);
|
||||
//gfx_hexdump(&gfx_con, 0x8000D000, (void *)0x8000D000, 0x100);
|
||||
//gfx_hexdump(&gfx_con, ctxt.pkg1_id->secmon_base, (void *)ctxt.pkg1_id->secmon_base, 0x100);
|
||||
DPRINTF("decrypted and unpacked pkg1\n");
|
||||
}
|
||||
//Replace 'warmboot.bin' if requested.
|
||||
if (ctxt.warmboot)
|
||||
memcpy((void *)0x8000D000, ctxt.warmboot, ctxt.warmboot_size);
|
||||
//Set warmboot address in PMC.
|
||||
PMC(APBDEV_PMC_SCRATCH1) = 0x8000D000;
|
||||
//Replace 'SecureMonitor' if requested.
|
||||
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.
|
||||
patch_t *secmon_patchset = ctxt.pkg1_id->secmon_patchset;
|
||||
|
||||
if (secmon_patchset != NULL) {
|
||||
for (u32 i = 0; secmon_patchset[i].off != 0xFFFFFFFF; i++)
|
||||
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
|
||||
|
||||
DPRINTF("loaded warmboot.bin and secmon\n");
|
||||
|
||||
//Read package2.
|
||||
if (!_read_emmc_pkg2(&ctxt))
|
||||
return 0;
|
||||
|
||||
DPRINTF("read pkg2\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);
|
||||
|
||||
DPRINTF("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];
|
||||
}
|
||||
|
||||
//Merge extra KIP1s into loaded ones.
|
||||
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);
|
||||
DPRINTF("rebuilt pkg2\n");
|
||||
} else {
|
||||
//Read package2.
|
||||
if (!_read_emmc_pkg2(&ctxt))
|
||||
return 0;
|
||||
|
||||
DPRINTF("read pkg2\n");
|
||||
memcpy((void *)0xA9800000, ctxt.pkg2, ctxt.pkg2_size);
|
||||
}
|
||||
}
|
||||
|
||||
se_aes_key_clear(8);
|
||||
se_aes_key_clear(11);
|
||||
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
case KB_FIRMWARE_VERSION_400:
|
||||
case KB_FIRMWARE_VERSION_500:
|
||||
se_key_acc_ctrl(12, 0xFF);
|
||||
se_key_acc_ctrl(15, 0xFF);
|
||||
break;
|
||||
}
|
||||
|
||||
//Clear 'BootConfig'.
|
||||
memset((void *)0x4003D000, 0, 0x3000);
|
||||
|
||||
//pkg2_decrypt((void *)0xA9800000);
|
||||
//sleep(10000);
|
||||
//btn_wait();
|
||||
//return 0;
|
||||
|
||||
//Lock SE before starting 'SecureMonitor'.
|
||||
_se_lock();
|
||||
|
||||
vu32 *mb_in = (vu32 *)0x40002EF8;
|
||||
vu32 *mb_out = (vu32 *)0x40002EFC;
|
||||
|
||||
*mb_in = 0;
|
||||
*mb_out = 0;
|
||||
|
||||
//Wait for secmon to get ready.
|
||||
cluster_boot_cpu0(ctxt.pkg1_id->secmon_base);
|
||||
while (!*mb_out)
|
||||
sleep(1);
|
||||
|
||||
//Signal 'BootConfig'.
|
||||
*mb_in = 1;
|
||||
sleep(100);
|
||||
|
||||
//Signal package2 available.
|
||||
*mb_in = 2;
|
||||
sleep(100);
|
||||
*mb_in = 3;
|
||||
sleep(100);
|
||||
|
||||
/*PMC(0x4) = 0x7FFFF3;
|
||||
PMC(0x2C4) = 0xFFFFFFFF;
|
||||
PMC(0x2D8) = 0xFFAFFFFF;
|
||||
PMC(0x5B0) = 0xFFFFFFFF;
|
||||
PMC(0x5B4) = 0xFFFFFFFF;
|
||||
PMC(0x5B8) = 0xFFFFFFFF;
|
||||
PMC(0x5BC) = 0xFFFFFFFF;
|
||||
PMC(0x5C0) = 0xFFAAFFFF;*/
|
||||
|
||||
//TODO: Cleanup.
|
||||
//display_end();
|
||||
|
||||
//Signal to continue boot.
|
||||
*mb_in = 4;
|
||||
sleep(100);
|
||||
|
||||
//Halt ourselves in waitevent state.
|
||||
while (1)
|
||||
FLOW_CTLR(0x4) = 0x50000000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
26
ipl/hos.h
Executable file
26
ipl/hos.h
Executable file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 _HOS_H_
|
||||
#define _HOS_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "ini.h"
|
||||
|
||||
int hos_launch(ini_sec_t *cfg);
|
||||
int keygen(u8 *keyblob, u32 kb, void *tsec_fw);
|
||||
|
||||
#endif
|
||||
132
ipl/i2c.c
Executable file
132
ipl/i2c.c
Executable file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "i2c.h"
|
||||
#include "util.h"
|
||||
|
||||
static u32 i2c_addrs[] = { 0x7000C000, 0x7000C400, 0x7000C500, 0x7000C700, 0x7000D000, 0x7000D100 };
|
||||
|
||||
static void _i2c_wait(vu32 *base)
|
||||
{
|
||||
base[0x23] = 0x25;
|
||||
for (u32 i = 0; i < 20; i++)
|
||||
{
|
||||
sleep(1);
|
||||
if (!(base[0x23] & 1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
|
||||
{
|
||||
if (size > 4)
|
||||
return 0;
|
||||
|
||||
u32 tmp = 0;
|
||||
memcpy(&tmp, buf, size);
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
||||
base[1] = x << 1; //Set x (send mode).
|
||||
base[3] = tmp; //Set value.
|
||||
base[0] = (2 * size - 2) | 0x2800; //Set size and send mode.
|
||||
_i2c_wait(base); //Kick transaction.
|
||||
|
||||
base[0] = base[0] & 0xFFFFFDFF | 0x200;
|
||||
while (base[7] & 0x100)
|
||||
;
|
||||
|
||||
if (base[7] << 28)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
|
||||
{
|
||||
if (size > 4)
|
||||
return 0;
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
||||
base[1] = (x << 1) | 1; //Set x (recv mode).
|
||||
base[0] = (2 * size - 2) | 0x2840; //Set size and recv mode.
|
||||
_i2c_wait(base); //Kick transaction.
|
||||
|
||||
base[0] = base[0] & 0xFFFFFDFF | 0x200;
|
||||
while (base[7] & 0x100)
|
||||
;
|
||||
|
||||
if (base[7] << 28)
|
||||
return 0;
|
||||
|
||||
u32 tmp = base[3]; //Get value.
|
||||
memcpy(buf, &tmp, size);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void i2c_init(u32 idx)
|
||||
{
|
||||
vu32 *base = (vu32 *)i2c_addrs[idx];
|
||||
|
||||
base[0x1B] = 0x50001;
|
||||
base[0x21] = 0x90003;
|
||||
_i2c_wait(base);
|
||||
|
||||
for (u32 i = 0; i < 10; i++)
|
||||
{
|
||||
sleep(20000);
|
||||
if (base[0x1A] & 0x800)
|
||||
break;
|
||||
}
|
||||
|
||||
vu32 dummy = base[0x22];
|
||||
base[0x1A] = base[0x1A];
|
||||
}
|
||||
|
||||
u32 i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
|
||||
{
|
||||
u8 tmp[4];
|
||||
|
||||
if (size > 3)
|
||||
return 0;
|
||||
|
||||
tmp[0] = y;
|
||||
memcpy(tmp + 1, buf, size);
|
||||
|
||||
_i2c_send_pkt(idx, x, tmp, size + 1);
|
||||
}
|
||||
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
|
||||
{
|
||||
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);
|
||||
if (res)
|
||||
res = _i2c_recv_pkt(idx, buf, size, x);
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)
|
||||
{
|
||||
i2c_send_buf_small(idx, x, y, &b, 1);
|
||||
}
|
||||
|
||||
u8 i2c_recv_byte(u32 idx, u32 x, u32 y)
|
||||
{
|
||||
u8 tmp;
|
||||
i2c_recv_buf_small(&tmp, 1, idx, x, y);
|
||||
return tmp;
|
||||
}
|
||||
35
ipl/i2c.h
Executable file
35
ipl/i2c.h
Executable file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 _I2C_H_
|
||||
#define _I2C_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define I2C_1 0
|
||||
#define I2C_2 1
|
||||
#define I2C_3 2
|
||||
#define I2C_4 3
|
||||
#define I2C_5 4
|
||||
#define I2C_6 5
|
||||
|
||||
void i2c_init(u32 idx);
|
||||
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);
|
||||
u32 i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
|
||||
u8 i2c_recv_byte(u32 idx, u32 x, u32 y);
|
||||
|
||||
#endif
|
||||
93
ipl/ini.c
Executable file
93
ipl/ini.c
Executable file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ini.h"
|
||||
#include "ff.h"
|
||||
#include "heap.h"
|
||||
|
||||
|
||||
static char *_strdup(char *str)
|
||||
{
|
||||
char *res = malloc(strlen(str) + 1);
|
||||
strcpy(res, str);
|
||||
return res;
|
||||
}
|
||||
|
||||
int ini_parse(link_t *dst, char *ini_path)
|
||||
{
|
||||
u32 lblen;
|
||||
char lbuf[512];
|
||||
FIL fp;
|
||||
ini_sec_t *csec = NULL;
|
||||
|
||||
if (f_open(&fp, ini_path, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
|
||||
do
|
||||
{
|
||||
//Fetch one line.
|
||||
lbuf[0] = 0;
|
||||
f_gets(lbuf, 512, &fp);
|
||||
lblen = strlen(lbuf);
|
||||
|
||||
//Skip empty lines and comments.
|
||||
if (lblen <= 1 || lbuf[0] == '#')
|
||||
continue;
|
||||
|
||||
//Remove trailing newline.
|
||||
if (lbuf[lblen - 1] == '\n')
|
||||
lbuf[lblen - 1] = 0;
|
||||
|
||||
if (lblen > 2 && lbuf[0] == '[') //Create new section.
|
||||
{
|
||||
if (csec)
|
||||
{
|
||||
list_append(dst, &csec->link);
|
||||
csec = NULL;
|
||||
}
|
||||
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != ']'; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||
csec->name = _strdup(&lbuf[1]);
|
||||
list_init(&csec->kvs);
|
||||
}
|
||||
else if (csec) //Extract key/value.
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != '='; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
ini_kv_t *kv = (ini_kv_t *)malloc(sizeof(ini_kv_t));
|
||||
kv->key = _strdup(&lbuf[0]);
|
||||
kv->val = _strdup(&lbuf[i + 1]);
|
||||
list_append(&csec->kvs, &kv->link);
|
||||
}
|
||||
} while (!f_eof(&fp));
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
if (csec)
|
||||
list_append(dst, &csec->link);
|
||||
|
||||
return 1;
|
||||
}
|
||||
39
ipl/ini.h
Executable file
39
ipl/ini.h
Executable file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 _INI_H_
|
||||
#define _INI_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "list.h"
|
||||
|
||||
typedef struct _ini_kv_t
|
||||
{
|
||||
char *key;
|
||||
char *val;
|
||||
link_t link;
|
||||
} ini_kv_t;
|
||||
|
||||
typedef struct _ini_sec_t
|
||||
{
|
||||
char *name;
|
||||
link_t kvs;
|
||||
link_t link;
|
||||
} ini_sec_t;
|
||||
|
||||
int ini_parse(link_t *dst, char *ini_path);
|
||||
|
||||
#endif
|
||||
38
ipl/integer.h
Executable file
38
ipl/integer.h
Executable file
@@ -0,0 +1,38 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef FF_INTEGER
|
||||
#define FF_INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types MUST be 16-bit or 32-bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* This type MUST be 8-bit */
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types MUST be 16-bit */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types MUST be 32-bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
||||
typedef unsigned long long QWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user