5853 lines
163 KiB
C
5853 lines
163 KiB
C
/*
|
|
* Copyright 2008, Freescale Semiconductor, Inc
|
|
* Andy Fleming
|
|
*
|
|
* Based vaguely on the Linux code
|
|
*
|
|
* See file CREDITS for list of people who contributed to this
|
|
* project.
|
|
*
|
|
* 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
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <common.h>
|
|
#include <command.h>
|
|
#include <mmc.h>
|
|
#include <part.h>
|
|
#include <malloc.h>
|
|
#include <linux/list.h>
|
|
#include <div64.h>
|
|
|
|
#include "mmc_def.h"
|
|
#include <sys_config.h>
|
|
#include <asm/arch/clock.h>
|
|
|
|
#include "mmc_test.h"
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
/* Set block count limit because of 16 bit register limit on some hardware*/
|
|
#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
|
|
#define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535
|
|
#endif
|
|
|
|
extern int sunxi_mmc_exit(int sdc_no);
|
|
//static struct list_head mmc_devices;
|
|
//static int cur_dev_num = -1;
|
|
static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst);
|
|
static ulong mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src);
|
|
|
|
int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd);
|
|
static int mmc_decode_ext_csd(struct mmc *mmc,struct mmc_ext_csd *dec_ext_csd, u8 *ext_csd);
|
|
int mmc_do_switch(struct mmc *mmc, u8 set, u8 index, u8 value, u32 timeout);
|
|
|
|
LIST_HEAD(mmc_devices);
|
|
|
|
static const unsigned int tacc_exp[] = {
|
|
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
|
|
};
|
|
|
|
static const unsigned int tacc_mant[] = {
|
|
0, 10, 12, 13, 15, 20, 25, 30,
|
|
35, 40, 45, 50, 55, 60, 70, 80,
|
|
};
|
|
|
|
int __board_mmc_getcd(u8 *cd, struct mmc *mmc) {
|
|
return -1;
|
|
}
|
|
|
|
int board_mmc_getcd(u8 *cd, struct mmc *mmc)__attribute__((weak,
|
|
alias("__board_mmc_getcd")));
|
|
|
|
int mmc_update_phase(struct mmc *mmc)
|
|
{
|
|
return mmc->update_phase(mmc);
|
|
}
|
|
|
|
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
|
{
|
|
#ifdef CONFIG_MMC_TRACE
|
|
int ret;
|
|
int i;
|
|
u8 *ptr;
|
|
|
|
MMCDBG("CMD_SEND:%d\n", cmd->cmdidx);
|
|
MMCDBG("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
|
|
MMCDBG("\t\tFLAG\t\t\t %d\n", cmd->flags);
|
|
ret = mmc->send_cmd(mmc, cmd, data);
|
|
switch (cmd->resp_type) {
|
|
case MMC_RSP_NONE:
|
|
MMCDBG("\t\tMMC_RSP_NONE\n");
|
|
break;
|
|
case MMC_RSP_R1:
|
|
MMCDBG("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
|
|
cmd->response[0]);
|
|
break;
|
|
case MMC_RSP_R1b:
|
|
MMCDBG("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
|
|
cmd->response[0]);
|
|
break;
|
|
case MMC_RSP_R2:
|
|
MMCDBG("\t\tMMC_RSP_R2\t\t 0x%08X \n",
|
|
cmd->response[0]);
|
|
MMCDBG("\t\t \t\t 0x%08X \n",
|
|
cmd->response[1]);
|
|
MMCDBG("\t\t \t\t 0x%08X \n",
|
|
cmd->response[2]);
|
|
MMCDBG("\t\t \t\t 0x%08X \n",
|
|
cmd->response[3]);
|
|
MMCMSG("\n");
|
|
MMCDBG("\t\t\t\t\tDUMPING DATA\n");
|
|
for (i = 0; i < 4; i++) {
|
|
int j;
|
|
MMCMSG("\t\t\t\t\t%03d - ", i*4);
|
|
ptr = (u8 *)(&cmd->response[i]);
|
|
ptr += 3;
|
|
for (j = 0; j < 4; j++)
|
|
MMCMSG("%02X ", *ptr--);
|
|
MMCMSG("\n");
|
|
}
|
|
break;
|
|
case MMC_RSP_R3:
|
|
MMCDBG("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
|
|
cmd->response[0]);
|
|
break;
|
|
default:
|
|
MMCDBG("\t\tERROR MMC rsp not supported\n");
|
|
break;
|
|
}
|
|
return ret;
|
|
#else
|
|
return mmc->send_cmd(mmc, cmd, data);
|
|
#endif
|
|
}
|
|
|
|
int mmc_send_status(struct mmc *mmc, int timeout)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
int err;
|
|
#ifdef CONFIG_MMC_TRACE
|
|
int status;
|
|
#endif
|
|
|
|
#if defined(CONFIG_ARCH_SUN9IW1P1)
|
|
if(gd->securemode == SUNXI_SECURE_MODE_NO_SECUREOS)
|
|
return 0;
|
|
#endif
|
|
|
|
cmd.cmdidx = MMC_CMD_SEND_STATUS;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
if (!mmc_host_is_spi(mmc))
|
|
cmd.cmdarg = mmc->rca << 16;
|
|
cmd.flags = 0;
|
|
|
|
do {
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
if (err){
|
|
MMCINFO("Send status failed\n");
|
|
return err;
|
|
}
|
|
else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
|
|
break;
|
|
|
|
udelay(1000);
|
|
|
|
if (cmd.response[0] & MMC_STATUS_MASK) {
|
|
MMCINFO("Status Error: 0x%08X\n", cmd.response[0]);
|
|
return COMM_ERR;
|
|
}
|
|
} while (timeout--);
|
|
|
|
#ifdef CONFIG_MMC_TRACE
|
|
status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
|
|
status = status;//avoid warning
|
|
MMCDBG("CURR STATE:%d\n", status);
|
|
#endif
|
|
if (timeout < 0) {
|
|
MMCINFO("Timeout waiting card ready\n");
|
|
return TIMEOUT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int mmc_set_blocklen(struct mmc *mmc, int len)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
|
|
/*ddr mode not send blocklenth*/
|
|
if(mmc->io_mode == MMC_MODE_DDR_52MHz ){
|
|
return 0;
|
|
}
|
|
cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.cmdarg = len;
|
|
cmd.flags = 0;
|
|
|
|
return mmc_send_cmd(mmc, &cmd, NULL);
|
|
}
|
|
|
|
int mmc_set_erase_start_addr(struct mmc *mmc, unsigned int address)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
int err = 0;
|
|
int timeout = 300; //ms
|
|
|
|
cmd.cmdidx = MMC_CMD_ERASE_GROUP_START;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.flags = 0;
|
|
|
|
if (mmc->high_capacity)
|
|
cmd.cmdarg = address;
|
|
else
|
|
cmd.cmdarg = address * mmc->write_bl_len;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
if (err) {
|
|
MMCINFO("%s: send erase start addr failed\n", __FUNCTION__);
|
|
goto ERR_RET;
|
|
}
|
|
|
|
err = mmc_send_status(mmc, timeout); //ms
|
|
|
|
ERR_RET:
|
|
return err;
|
|
}
|
|
|
|
int mmc_set_erase_end_addr(struct mmc *mmc, unsigned int address)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
int err = 0;
|
|
int timeout = 300; //ms
|
|
|
|
cmd.cmdidx = MMC_CMD_ERASE_GROUP_END;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.flags = 0;
|
|
|
|
if (mmc->high_capacity)
|
|
cmd.cmdarg = address;
|
|
else
|
|
cmd.cmdarg = address * mmc->write_bl_len;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
if (err) {
|
|
MMCINFO("%s: send erase end addr failed\n", __FUNCTION__);
|
|
goto ERR_RET;
|
|
}
|
|
|
|
err = mmc_send_status(mmc, timeout); //ms
|
|
|
|
ERR_RET:
|
|
return err;
|
|
}
|
|
|
|
int mmc_launch_erase(struct mmc *mmc, unsigned int erase_arg)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
|
|
cmd.cmdidx = MMC_CMD_ERASE;
|
|
cmd.resp_type = MMC_RSP_R1b;
|
|
cmd.cmdarg = erase_arg;
|
|
cmd.flags = 0;
|
|
|
|
return mmc_send_cmd(mmc, &cmd, NULL);
|
|
}
|
|
|
|
unsigned int mmc_sd_erase_timeout(struct mmc *mmc, unsigned int erase_arg,
|
|
unsigned int qty)
|
|
{
|
|
return 0xffffff;
|
|
}
|
|
|
|
/* calculate erase timeout based on CSD and current card clock frequency */
|
|
unsigned int mmc_mmc_def_erase_timeout(struct mmc *mmc)
|
|
{
|
|
unsigned int erase_timeout = 0;
|
|
unsigned int r2w_factor = (mmc->csd[3]>>26)&0x7; //28:26
|
|
unsigned int tacc_clks = ((mmc->csd[0]>>8)&0xFF)*100; //111:104
|
|
unsigned int e = (mmc->csd[3]>>16)&0x7;
|
|
unsigned int m = (mmc->csd[3]>>19)&0xF;
|
|
unsigned int tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
|
|
unsigned int mult = 10 << r2w_factor;
|
|
|
|
unsigned int timeout_clks = tacc_clks * mult;
|
|
unsigned int timeout_us;
|
|
|
|
|
|
/* Avoid overflow: e.g. tacc_ns=80000000 mult=1280 */
|
|
if (tacc_ns < 1000000)
|
|
timeout_us = (tacc_ns * mult) / 1000;
|
|
else
|
|
timeout_us = (tacc_ns / 1000) * mult;
|
|
|
|
/*
|
|
* ios.clock is only a target. The real clock rate might be
|
|
* less but not that much less, so fudge it by multiplying by 2.
|
|
*/
|
|
timeout_clks <<= 1;
|
|
timeout_us += (timeout_clks * 1000) / (mmc->clock / 1000);
|
|
|
|
erase_timeout = timeout_us / 1000;
|
|
|
|
/*
|
|
* Theoretically, the calculation could underflow so round up
|
|
* to 1ms in that case.
|
|
*/
|
|
if (!erase_timeout)
|
|
erase_timeout = 1;
|
|
|
|
return erase_timeout;
|
|
}
|
|
|
|
unsigned int mmc_mmc_update_timeout(struct mmc *mmc)
|
|
{
|
|
int ret = 0;
|
|
char ext_csd[512];
|
|
struct mmc_ext_csd mmc_ext_csd;
|
|
|
|
MMCDBG("+++%s\n", __FUNCTION__);
|
|
|
|
ret = mmc_send_ext_csd(mmc, ext_csd);
|
|
if (ret) {
|
|
MMCINFO("send ext_csd failed\n");
|
|
goto ERR_RET;
|
|
}
|
|
|
|
ret = mmc_decode_ext_csd(mmc, &mmc_ext_csd, (unsigned char *)ext_csd);
|
|
if (ret) {
|
|
MMCINFO("decode ext_csd failed\n");
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if (mmc_ext_csd.rev >= 4)
|
|
{
|
|
if (mmc_ext_csd.erase_group_def && mmc_ext_csd.hc_erase_timeout)
|
|
mmc->erase_timeout = mmc_ext_csd.hc_erase_timeout;
|
|
else
|
|
mmc->erase_timeout = mmc_mmc_def_erase_timeout(mmc);
|
|
|
|
mmc->trim_discard_timeout = mmc_ext_csd.trim_timeout;
|
|
mmc->secure_erase_timeout = mmc->erase_timeout * mmc_ext_csd.sec_erase_mult;
|
|
mmc->secure_trim_timeout = mmc->erase_timeout * mmc_ext_csd.sec_trim_mult;
|
|
}
|
|
else
|
|
{
|
|
if (mmc_ext_csd.rev == 3) {
|
|
if (mmc_ext_csd.erase_group_def && mmc_ext_csd.hc_erase_timeout)
|
|
mmc->erase_timeout = mmc_ext_csd.hc_erase_timeout;
|
|
else
|
|
mmc->erase_timeout = mmc_mmc_def_erase_timeout(mmc);
|
|
} else {
|
|
mmc->erase_timeout = mmc_mmc_def_erase_timeout(mmc);
|
|
}
|
|
|
|
mmc->trim_discard_timeout = 0x0;
|
|
mmc->secure_erase_timeout = 0x0;
|
|
mmc->secure_trim_timeout = 0x0;
|
|
}
|
|
|
|
ERR_RET:
|
|
MMCDBG("---%s %d\n", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
|
|
unsigned int mmc_mmc_erase_timeout(struct mmc *mmc, unsigned int arg,
|
|
unsigned int qty)
|
|
{
|
|
unsigned int erase_timeout = 0;
|
|
|
|
if (arg == MMC_DISCARD_ARG || arg == MMC_TRIM_ARG) {
|
|
if (!mmc->trim_discard_timeout) {
|
|
MMCINFO("invalid trim_discard_timeout is %d\n", mmc->trim_discard_timeout);
|
|
goto ERR_RET;
|
|
}
|
|
erase_timeout = mmc->trim_discard_timeout;
|
|
} else if (arg == MMC_ERASE_ARG) {
|
|
if (!mmc->erase_timeout) {
|
|
MMCINFO("invalid erase_timeout is %d\n", mmc->erase_timeout);
|
|
goto ERR_RET;
|
|
}
|
|
erase_timeout = mmc->erase_timeout;
|
|
} else if (arg == MMC_SECURE_ERASE_ARG) {
|
|
if (!mmc->secure_erase_timeout) {
|
|
MMCINFO("invalid secure_erase_timeout is %d\n", mmc->secure_erase_timeout);
|
|
goto ERR_RET;
|
|
}
|
|
erase_timeout = mmc->secure_erase_timeout;
|
|
} else if (arg == MMC_SECURE_TRIM1_ARG || arg == MMC_SECURE_TRIM2_ARG) {
|
|
if (!mmc->secure_trim_timeout) {
|
|
MMCINFO("invalid secure_trim_timeout is %d\n", mmc->secure_trim_timeout);
|
|
goto ERR_RET;
|
|
}
|
|
erase_timeout = mmc->secure_trim_timeout;
|
|
} else {
|
|
MMCINFO("Unknown erase argument 0x%x\n", arg);
|
|
goto ERR_RET;
|
|
}
|
|
|
|
erase_timeout *= qty;
|
|
|
|
return erase_timeout;
|
|
|
|
ERR_RET:
|
|
return 0;
|
|
}
|
|
|
|
unsigned int mmc_erase_timeout(struct mmc *mmc, unsigned int erase_arg,
|
|
unsigned int qty)
|
|
{
|
|
if (IS_SD(mmc))
|
|
return mmc_sd_erase_timeout(mmc, erase_arg, qty);
|
|
else {
|
|
return mmc_mmc_erase_timeout(mmc, erase_arg, qty);
|
|
}
|
|
}
|
|
|
|
int mmc_do_erase(struct mmc *mmc, unsigned int from,
|
|
unsigned int to, unsigned int erase_arg)
|
|
{
|
|
int err = 0;
|
|
unsigned int timeout = 0;
|
|
unsigned int qty = 0;
|
|
|
|
MMCDBG("+++%s\n", __FUNCTION__);
|
|
|
|
mmc_mmc_update_timeout(mmc);
|
|
|
|
err = mmc_set_erase_start_addr(mmc, from);
|
|
if (err) {
|
|
MMCINFO("set erase start addr failed\n");
|
|
goto ERR_RET;
|
|
}
|
|
|
|
err = mmc_set_erase_end_addr(mmc, to);
|
|
if (err) {
|
|
MMCINFO("set erase end addr failed\n");
|
|
goto ERR_RET;
|
|
}
|
|
|
|
err = mmc_launch_erase(mmc, erase_arg);
|
|
if (err) {
|
|
MMCINFO("launch erase failed\n");
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if (IS_SD(mmc)) {
|
|
qty = to - from + 1;
|
|
} else {
|
|
qty = (to - from)/mmc->erase_grp_size + 1;
|
|
}
|
|
timeout = mmc_erase_timeout(mmc, erase_arg, qty);
|
|
if (!timeout) {
|
|
MMCINFO("calculate timeout failed\n");
|
|
err = -1;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
err = mmc_send_status(mmc, timeout); //ms
|
|
|
|
ERR_RET:
|
|
|
|
MMCDBG("---%s %d\n", __FUNCTION__, err);
|
|
return err;
|
|
}
|
|
|
|
int mmc_erase_group_aligned(struct mmc *mmc, unsigned int from,
|
|
unsigned int nr)
|
|
{
|
|
if (!mmc->erase_grp_size)
|
|
return 0;
|
|
if (from % mmc->erase_grp_size || nr % mmc->erase_grp_size)
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
void mmc_align_erase_group(struct mmc *mmc, unsigned int from,
|
|
unsigned int nr, unsigned int *align_from, unsigned int *align_nr)
|
|
{
|
|
unsigned int rem, start, cnt;
|
|
|
|
MMCDBG("---start erase addr adjust... \n");
|
|
MMCDBG("--1-- from: %d, nr: %d, erase_group: %d\n", from, nr, mmc->erase_grp_size);
|
|
start = from;
|
|
cnt = nr;
|
|
|
|
rem = start % mmc->erase_grp_size;
|
|
if (rem) {
|
|
rem = mmc->erase_grp_size - rem;
|
|
start += rem;
|
|
if (cnt > rem)
|
|
cnt -= rem;
|
|
else {
|
|
MMCINFO("after adjust start addr, no more space need to erase!!\n");
|
|
goto RET;
|
|
}
|
|
}
|
|
rem = cnt % mmc->erase_grp_size;
|
|
if (rem)
|
|
cnt -= rem;
|
|
|
|
if (cnt == 0) {
|
|
MMCINFO("after adjust nr, no more space need to erase!!\n");
|
|
}
|
|
|
|
RET:
|
|
MMCDBG("--2-- from: %d, nr: %d, erase_group: %d\n", start, cnt, mmc->erase_grp_size);
|
|
*align_from = start;
|
|
*align_nr = cnt;
|
|
return ;
|
|
}
|
|
|
|
int mmc_erase(struct mmc *mmc, unsigned int from,
|
|
unsigned int nr, unsigned int erase_arg)
|
|
{
|
|
int ret;
|
|
|
|
MMCDBG("+++%s\n", __FUNCTION__);
|
|
|
|
if (nr == 0) {
|
|
ret = 0;
|
|
MMCINFO("No space need to be erased !\n");
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if (!IS_SD(mmc))
|
|
{
|
|
if ((erase_arg != MMC_ERASE_ARG)
|
|
&& (erase_arg != MMC_SECURE_ERASE_ARG)
|
|
&& (erase_arg != MMC_TRIM_ARG)
|
|
&& (erase_arg != MMC_DISCARD_ARG)
|
|
&& (erase_arg != MMC_SECURE_TRIM1_ARG)) {
|
|
ret = -1;
|
|
MMCINFO("Unknown erase type!\n");
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if ((erase_arg == MMC_ERASE_ARG)
|
|
||(erase_arg == MMC_SECURE_ERASE_ARG)) {
|
|
ret = mmc_erase_group_aligned(mmc, from, nr);
|
|
if (!ret) {
|
|
ret = -1;
|
|
MMCINFO("Erase addr is not erase group alignment!\n");
|
|
goto ERR_RET;
|
|
}
|
|
}
|
|
|
|
MMCINFO("erase from: %d, to: %d, cnt: %d, erase_group: %d\n",
|
|
from, from+nr-1, nr, mmc->erase_grp_size);
|
|
ret = mmc_do_erase(mmc, from, from+nr-1, erase_arg);
|
|
if (ret) {
|
|
ret = -1;
|
|
MMCINFO("Do erase failed!\n");
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if (erase_arg == MMC_SECURE_TRIM1_ARG)
|
|
{
|
|
ret = mmc_do_erase(mmc, from, from+nr-1, MMC_SECURE_TRIM2_ARG);
|
|
if (ret) {
|
|
ret = -1;
|
|
MMCINFO("Do secure trim step 2 failed!\n");
|
|
goto ERR_RET;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MMCINFO("Don't support to erase SD card\n");
|
|
ret = -1;
|
|
}
|
|
|
|
ERR_RET:
|
|
|
|
MMCDBG("--%s ret%d\n", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
|
|
#define MMC_SANITIZE_REQ_TIMEOUT 240000
|
|
int mmc_do_sanitize(struct mmc *mmc)
|
|
{
|
|
int ret;
|
|
|
|
MMCINFO("%s: start emmc sanitize...\n", __FUNCTION__);
|
|
ret = mmc_do_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
|
|
EXT_CSD_SANITIZE_START, 1,
|
|
MMC_SANITIZE_REQ_TIMEOUT);
|
|
MMCINFO("%s end emmc sanitzie, ret %d\n", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
|
|
void mmc_add_skip_space(unsigned int *skip_space, int index,
|
|
unsigned int from, unsigned int nr)
|
|
{
|
|
MMCDBG("%s: %d from %d nr %d\n", __FUNCTION__, index, from, nr);
|
|
skip_space[0] |= 0x1<<index;
|
|
skip_space[index*2 + 1] = from;
|
|
skip_space[index*2 + 2] = nr;
|
|
}
|
|
|
|
int mmc_insecure_secure_erase(struct mmc *mmc, unsigned int from,
|
|
unsigned int nr, unsigned int *skip_space, int secure)
|
|
{
|
|
int ret = 0;
|
|
unsigned int align_from = from, align_nr = nr;
|
|
int skip;
|
|
unsigned int last_skip_len;
|
|
unsigned arg;
|
|
|
|
skip = 0;
|
|
last_skip_len = 0;
|
|
skip_space[0] = 0x0;
|
|
|
|
MMCDBG("%d %s: start erase, seucre %d...\n", __LINE__, __FUNCTION__, secure);
|
|
ret = mmc_erase_group_aligned(mmc, from, nr);
|
|
if (!ret) {
|
|
mmc_align_erase_group(mmc, from, nr, &align_from, &align_nr);
|
|
}
|
|
|
|
if (align_nr == 0)
|
|
{
|
|
MMCINFO("after align erase group, no space need to erase, erase failed\n");
|
|
mmc_add_skip_space(skip_space, skip, from, nr);
|
|
ret = -1;
|
|
}
|
|
else
|
|
{
|
|
if (secure)
|
|
arg = MMC_SECURE_ERASE_ARG;
|
|
else
|
|
arg = MMC_ERASE_ARG;
|
|
|
|
ret = mmc_erase(mmc, align_from, align_nr, arg);
|
|
if (ret) {
|
|
MMCINFO("erase failed, range %d - %d \n",
|
|
align_from, (align_from+align_nr));
|
|
mmc_add_skip_space(skip_space, skip, from, nr);
|
|
} else {
|
|
if (align_from - from)
|
|
mmc_add_skip_space(skip_space, skip++, from, (align_from-from));
|
|
|
|
if (skip)
|
|
last_skip_len = skip_space[2];
|
|
else
|
|
last_skip_len = 0;
|
|
if (nr - align_nr - last_skip_len)
|
|
mmc_add_skip_space(skip_space, skip++, (align_from+align_nr), (nr-align_nr-last_skip_len));
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int mmc_do_secure_wipe(struct mmc *mmc, unsigned int from, unsigned int nr,
|
|
unsigned int *skip_space)
|
|
{
|
|
int ret = 0;
|
|
int skip, not_support_wipe = 0;
|
|
|
|
|
|
MMCINFO("+++%s\n", __FUNCTION__);
|
|
|
|
if (nr == 0) {
|
|
MMCINFO("%s: on space need to erase, nr %d\n", __FUNCTION__, nr);
|
|
return 0;
|
|
}
|
|
|
|
if (IS_SD(mmc)) {
|
|
MMCINFO("%s: no mmc, do nothing\n", __FUNCTION__);
|
|
ret = -2;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
skip = 0;
|
|
skip_space[0] = 0x0;
|
|
|
|
if (mmc->version <= MMC_VERSION_4_41) //ver 4.41 or older
|
|
{
|
|
if (mmc->secure_feature & EXT_CSD_SEC_ER_EN)
|
|
{
|
|
//support secure purge operation
|
|
if (mmc->secure_feature & EXT_CSD_SEC_GB_CL_EN) {
|
|
//support trim
|
|
MMCDBG("%d %s: start secure trim...\n", __LINE__, __FUNCTION__);
|
|
ret = mmc_erase(mmc, from, nr, MMC_SECURE_TRIM1_ARG);
|
|
if (ret) {
|
|
MMCINFO("secure trim failed, range %d - %d \n",
|
|
from, (from+nr));
|
|
mmc_add_skip_space(skip_space, skip, from, nr);
|
|
}
|
|
} else {
|
|
ret = mmc_insecure_secure_erase(mmc, from, nr, skip_space, 1);
|
|
}
|
|
}
|
|
else if (mmc->secure_feature & EXT_CSD_SEC_GB_CL_EN)
|
|
{
|
|
//support insecure trim operation
|
|
MMCDBG("%d %s: start trim...\n", __LINE__, __FUNCTION__);
|
|
ret = mmc_erase(mmc, from, nr, MMC_TRIM_ARG);
|
|
if (ret) {
|
|
MMCINFO("trim failed, range %d - %d \n", from, (from+nr));
|
|
mmc_add_skip_space(skip_space, skip, from, nr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//is currently not an acceptable solution. writing of zeroes to the user data partition as a third option
|
|
MMCINFO("no method to wipe data (emmc <= v4.41)!\n ");
|
|
not_support_wipe = 1;
|
|
mmc_add_skip_space(skip_space, skip, from, nr);
|
|
}
|
|
}
|
|
else if (mmc->version <= MMC_VERSION_5_0) //v4.5 or newer
|
|
{
|
|
if (mmc->secure_feature & EXT_CSD_SEC_SANITIZE)
|
|
{
|
|
//support sanitize
|
|
if (mmc->secure_feature & EXT_CSD_SEC_GB_CL_EN) {
|
|
//support trim
|
|
MMCDBG("%d %s: start trim...\n", __LINE__, __FUNCTION__);
|
|
ret = mmc_erase(mmc, from, nr, MMC_TRIM_ARG);
|
|
if (ret) {
|
|
MMCINFO("trim failed, range %d - %d \n", from, (from+nr));
|
|
mmc_add_skip_space(skip_space, skip, from, nr);
|
|
goto ERR_RET;
|
|
}
|
|
} else {
|
|
ret = mmc_insecure_secure_erase(mmc, from, nr, skip_space, 0);
|
|
if (ret) {
|
|
MMCINFO("erase failed, range %d - %d \n", from, (from+nr));
|
|
goto ERR_RET;
|
|
}
|
|
}
|
|
|
|
MMCDBG("%d %s: start sanitize...\n", __LINE__, __FUNCTION__);
|
|
ret = mmc_do_sanitize(mmc);
|
|
if (ret) {
|
|
MMCINFO("do sanitize failed!!\n");
|
|
skip = 0;
|
|
skip_space[0] = 0x0;
|
|
mmc_add_skip_space(skip_space, skip, from, nr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//If the eMMC 4.5 part does not expose the required command set, there is currently not an acceptable solution to sanitize this part for re-use
|
|
not_support_wipe = 1;
|
|
MMCINFO("no method to wipe data for current (emmc >v4.5)!\n ");
|
|
mmc_add_skip_space(skip_space, skip, from, nr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MMCINFO("Unknown mmc version 0x%x\n", mmc->version);
|
|
ret = -3;
|
|
}
|
|
|
|
if (not_support_wipe)
|
|
ret = -2;
|
|
|
|
ERR_RET:
|
|
|
|
MMCINFO("---%s ret %d\n", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
|
|
int mmc_secure_wipe(int dev_num, unsigned int start,
|
|
unsigned int blkcnt, unsigned int *skip_space)
|
|
{
|
|
int ret = 0;
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
|
|
MMCINFO("========start %s\n", __FUNCTION__);
|
|
if (mmc->drv_wipe_feature & DRV_PARA_DISABLE_SECURE_WIPE) {
|
|
MMCINFO("driver do not support secure wipe operation\n");
|
|
return -1;
|
|
}
|
|
|
|
ret = mmc_do_secure_wipe(mmc, start, blkcnt, skip_space);
|
|
if (ret == -1) {
|
|
MMCINFO("erase failed!!!!!!\n");
|
|
} else if ((ret == -2) || (ret == -3)) {
|
|
MMCINFO("do not erase!!!!!!\n");
|
|
ret = -1;
|
|
} else if (skip_space[0]){
|
|
MMCINFO("skip some space when align erase group, need to write zeros.\n");
|
|
ret = 1;
|
|
} else {
|
|
MMCINFO("erase ok\n");
|
|
ret = 0;
|
|
}
|
|
|
|
MMCINFO("========end %s %d\n", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
|
|
int mmc_mmc_erase(int dev_num, unsigned int start,
|
|
unsigned int blkcnt, unsigned int *skip_space)
|
|
{
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
int i, ret1, ret = 0;
|
|
|
|
MMCDBG("start %s ...\n", __FUNCTION__);
|
|
if (IS_SD(mmc)) {
|
|
MMCINFO("%s: sd card don't support erase\n", __FUNCTION__);
|
|
ret = -1;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if (mmc->drv_erase_feature & DRV_PARA_DISABLE_EMMC_ERASE) {
|
|
MMCINFO("%s: driver don't support erase\n", __FUNCTION__);
|
|
ret = -1;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if (blkcnt == 0) {
|
|
MMCINFO("%s: no space need to erase, from:%d nr:%d\n",
|
|
__FUNCTION__, start, blkcnt);
|
|
ret = 0;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if ((start+blkcnt) > mmc->block_dev.lba) {
|
|
MMCINFO("%s: input lenght error!!!\n", __FUNCTION__);
|
|
blkcnt = mmc->block_dev.lba - start;
|
|
MMCINFO("%s: after clip, from: %d, nr: %d\n",
|
|
__FUNCTION__, start, blkcnt);
|
|
}
|
|
|
|
ret = mmc_insecure_secure_erase(mmc, start, blkcnt, skip_space, 0);
|
|
if (ret) {
|
|
MMCINFO("%s: erase emmc fail!\n", __FUNCTION__);
|
|
}
|
|
|
|
if (skip_space[0]) {
|
|
ret = 1;
|
|
|
|
MMCINFO("%s: some sectors in emmc are ignored!\n", __FUNCTION__);
|
|
for (i=0; i<2; i++)
|
|
if (skip_space[0] & (1<<i))
|
|
MMCINFO("--%d: from%d nr%d \n", i,
|
|
(int)skip_space[i*2+1], (int)skip_space[i*2+2]);
|
|
}
|
|
|
|
if ((mmc->drv_erase_feature & DRV_PARA_ENABLE_EMMC_SANITIZE_WHEN_ERASE)
|
|
&& (mmc->secure_feature & EXT_CSD_SEC_SANITIZE))
|
|
{
|
|
ret1 = mmc_do_sanitize(mmc);
|
|
if (ret1) {
|
|
MMCINFO("%s: emmc sanitize fail. ignore this error and continue...\n", __FUNCTION__);
|
|
}
|
|
}
|
|
|
|
ERR_RET:
|
|
MMCDBG("end %s %d\n", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
|
|
int mmc_mmc_sanitize(int dev_num)
|
|
{
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
int ret = 0;
|
|
|
|
MMCDBG("start %s ...\n", __FUNCTION__);
|
|
if (IS_SD(mmc)) {
|
|
MMCINFO("%s: sd card don't support erase\n", __FUNCTION__);
|
|
ret = -1;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if (!(mmc->secure_feature & EXT_CSD_SEC_SANITIZE)) {
|
|
MMCINFO("%s: driver don't support sanitize\n", __FUNCTION__);
|
|
ret = -1;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
ret = mmc_do_sanitize(mmc);
|
|
if (ret) {
|
|
ret = -1;
|
|
MMCINFO("%s: sanitize fail!\n", __FUNCTION__);
|
|
}
|
|
|
|
ERR_RET:
|
|
MMCDBG("end %s %d\n", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
|
|
int mmc_mmc_trim(int dev_num, unsigned int start, unsigned int blkcnt)
|
|
{
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
int ret = 0;
|
|
|
|
MMCDBG("start %s ...\n", __FUNCTION__);
|
|
if (IS_SD(mmc)) {
|
|
MMCINFO("%s: sd card don't support trim\n", __FUNCTION__);
|
|
ret = -1;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if (blkcnt == 0) {
|
|
MMCINFO("%s: no space need to erase, from:%d nr:%d\n",
|
|
__FUNCTION__, start, blkcnt);
|
|
ret = 0;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if ((start+blkcnt) > mmc->block_dev.lba) {
|
|
MMCINFO("%s: input lenght error!!!\n", __FUNCTION__);
|
|
blkcnt = mmc->block_dev.lba - start;
|
|
MMCINFO("%s: after clip, from: %d, nr: %d\n",
|
|
__FUNCTION__, start, blkcnt);
|
|
}
|
|
|
|
if (mmc->secure_feature & EXT_CSD_SEC_GB_CL_EN)
|
|
{
|
|
ret = mmc_erase(mmc, start, blkcnt, MMC_TRIM_ARG);
|
|
if (ret) {
|
|
MMCINFO("trim failed, range %d - %d\n", start, (start+blkcnt));
|
|
}
|
|
} else {
|
|
MMCINFO("%s: don't support trim!\n", __FUNCTION__);
|
|
ret = -1;
|
|
}
|
|
|
|
ERR_RET:
|
|
MMCDBG("end %s %d\n", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
|
|
int mmc_mmc_discard(int dev_num, unsigned int start, unsigned int blkcnt)
|
|
{
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
int ret = 0;
|
|
|
|
MMCDBG("start %s ...\n", __FUNCTION__);
|
|
if (IS_SD(mmc)) {
|
|
MMCINFO("%s: sd card don't support discard\n", __FUNCTION__);
|
|
ret = -1;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if (blkcnt == 0) {
|
|
MMCINFO("%s: no space need to erase, from:%d nr:%d\n",
|
|
__FUNCTION__, start, blkcnt);
|
|
ret = 0;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if ((start+blkcnt) > mmc->block_dev.lba) {
|
|
MMCINFO("%s: input lenght error!!!\n", __FUNCTION__);
|
|
blkcnt = mmc->block_dev.lba - start;
|
|
MMCINFO("%s: after clip, from: %d, nr: %d\n",
|
|
__FUNCTION__, start, blkcnt);
|
|
}
|
|
|
|
/* eMMC v4.5 or later */
|
|
if (mmc->version >= MMC_VERSION_4_5)
|
|
{
|
|
ret = mmc_erase(mmc, start, blkcnt, MMC_DISCARD_ARG);
|
|
if (ret) {
|
|
MMCINFO("trim failed, range %d - %d\n", start, (start+blkcnt));
|
|
}
|
|
} else {
|
|
MMCINFO("%s: don't support discard!\n", __FUNCTION__);
|
|
ret = -1;
|
|
}
|
|
|
|
ERR_RET:
|
|
MMCDBG("end %s %d\n", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
|
|
int mmc_mmc_secure_erase(int dev_num, unsigned int start,
|
|
unsigned int blkcnt, unsigned int *skip_space)
|
|
{
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
int i, ret = 0;
|
|
|
|
MMCDBG("start %s ...\n", __FUNCTION__);
|
|
if (IS_SD(mmc)) {
|
|
MMCINFO("%s: sd card don't support secure erase!\n", __FUNCTION__);
|
|
ret = -1;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if (blkcnt == 0) {
|
|
MMCINFO("%s: no space need to erase, from:%d nr:%d\n",
|
|
__FUNCTION__, start, blkcnt);
|
|
ret = 0;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if ((start+blkcnt) > mmc->block_dev.lba) {
|
|
MMCINFO("%s: input lenght error!!!\n", __FUNCTION__);
|
|
blkcnt = mmc->block_dev.lba - start;
|
|
MMCINFO("%s: after clip, from: %d, nr: %d\n",
|
|
__FUNCTION__, start, blkcnt);
|
|
}
|
|
|
|
if (!(mmc->secure_feature & EXT_CSD_SEC_ER_EN)) {
|
|
MMCINFO("%s: don't support secure erase!\n", __FUNCTION__);
|
|
ret = -1;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
ret = mmc_insecure_secure_erase(mmc, start, blkcnt, skip_space,1);
|
|
if (ret) {
|
|
MMCINFO("%s: erase emmc fail!\n", __FUNCTION__);
|
|
}
|
|
|
|
if (skip_space[0]) {
|
|
MMCDBG("%s: some sectors in emmc are ignored!\n\n", __FUNCTION__);
|
|
for (i=0; i<2; i++)
|
|
if (skip_space[0] & (1<<i))
|
|
MMCDBG("--%d: from%d nr%d \n",
|
|
skip_space[i*2+1], skip_space[i*2+2]);
|
|
}
|
|
|
|
ERR_RET:
|
|
MMCDBG("end %s %d\n", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
|
|
int mmc_mmc_secure_trim(int dev_num, unsigned int start, unsigned int blkcnt)
|
|
{
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
int ret = 0;
|
|
|
|
MMCDBG("start %s ...\n", __FUNCTION__);
|
|
if (IS_SD(mmc)) {
|
|
MMCINFO("%s: sd card don't support secure trim!\n", __FUNCTION__);
|
|
ret = -1;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if (blkcnt == 0) {
|
|
MMCINFO("%s: no space need to erase, from:%d nr:%d\n",
|
|
__FUNCTION__, start, blkcnt);
|
|
ret = 0;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
if ((start+blkcnt) > mmc->block_dev.lba) {
|
|
MMCINFO("%s: input lenght error!!!\n", __FUNCTION__);
|
|
blkcnt = mmc->block_dev.lba - start;
|
|
MMCINFO("%s: after clip, from: %d, nr: %d\n",
|
|
__FUNCTION__, start, blkcnt);
|
|
}
|
|
|
|
if ((mmc->secure_feature & EXT_CSD_SEC_ER_EN)
|
|
&& (mmc->secure_feature & EXT_CSD_SEC_GB_CL_EN))
|
|
{
|
|
ret = mmc_erase(mmc, start, blkcnt, MMC_SECURE_TRIM1_ARG);
|
|
if (ret) {
|
|
MMCINFO("secure trim failed, range %d - %d\n", start, (start+blkcnt));
|
|
}
|
|
} else {
|
|
MMCINFO("%s: don't support secure trim!\n", __FUNCTION__);
|
|
ret = -1;
|
|
}
|
|
|
|
ERR_RET:
|
|
MMCDBG("end %s %d\n", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
|
|
#if 0
|
|
/* only clear first 128KB of boot part 0 to zeros */
|
|
int mmc_mmc_clear_boot_part1(int dev_num)
|
|
{
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
int err = 0;
|
|
void *src, *dst;
|
|
unsigned int blkcnt = 128 * 1024 * 2; //128KB
|
|
|
|
if (!(mmc->boot_support))
|
|
{
|
|
MMCINFO("Card doesn't support boot part\n");
|
|
return 0;
|
|
}
|
|
|
|
src = malloc(blkcnt * mmc->write_bl_len);
|
|
if (src == NULL) {
|
|
MMCINFO("%s: malloc mem failed\n", __FUNCTION__);
|
|
return -1;
|
|
}
|
|
memset(src, 0, blkcnt * mmc->write_bl_len);
|
|
|
|
dst = malloc(blkcnt * mmc->write_bl_len);
|
|
if (dst == NULL){
|
|
MMCINFO("%s: malloc mem failed\n", __FUNCTION__);
|
|
goto ERR_RET1;
|
|
}
|
|
|
|
err = mmc_switch_boot_bus_cond(dev_num,
|
|
MMC_SWITCH_BOOT_SDR_NORMAL,
|
|
MMC_SWITCH_BOOT_RST_BUS_COND,
|
|
MMC_SWITCH_BOOT_BUS_SDRx4_DDRx4);
|
|
if (err) {
|
|
MMCINFO("mmc switch boot bus condition failed\n");
|
|
goto ERR_RET;
|
|
}
|
|
MMCDBG("mmc switch boot bus condition succeed\n");
|
|
|
|
err = mmc_switch_boot_part(dev_num,
|
|
MMC_SWITCH_PART_BOOT_ACK_ENB,
|
|
MMC_SWITCH_PART_BOOT_PART_1);
|
|
if (err) {
|
|
MMCINFO("mmc switch boot part failed\n");
|
|
err = -1;
|
|
goto ERR_RET;
|
|
}
|
|
MMCDBG("mmc switch boot part succeed\n");
|
|
|
|
|
|
//switch to boot partition 1
|
|
if (mmc_switch_part(dev_num, MMC_SWITCH_PART_BOOT_PART_1)) {
|
|
MMCINFO("switch to boot1 partition failed\n");
|
|
err = -1;
|
|
goto ERR_RET;
|
|
}
|
|
|
|
mmc_bwrite(dev_num, 0, blkcnt, src);
|
|
mmc_bread(dev_num, 0, blkcnt, dst);
|
|
if (memcmp(src, dst, blkcnt*mmc->write_bl_len))
|
|
err = -1;
|
|
|
|
//switch back to user partiton 1
|
|
if (mmc_switch_part(dev_num, 0)) {
|
|
MMCINFO("switch to boot1 partition failed\n");
|
|
err = -1;
|
|
}
|
|
|
|
ERR_RET:
|
|
free(dst);
|
|
|
|
ERR_RET1:
|
|
free(src);
|
|
|
|
return err;
|
|
}
|
|
|
|
static unsigned long
|
|
mmc_berase_mass_pro(int dev_num)
|
|
{
|
|
int i, ret = 0, boot_ret;
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
unsigned long tmp_skip_space[1+2*2] = {0};
|
|
|
|
if (!IS_SD(mmc))
|
|
{
|
|
//erase boot part
|
|
boot_ret = mmc_mmc_clear_boot_part1(dev_num);
|
|
if (boot_ret) {
|
|
MMCINFO("%s: erase boot part 1 fail\n", __FUNCTION__);
|
|
}
|
|
|
|
//erase user part
|
|
ret = _mmc_insecure_secure_erase(mmc, 0, mmc->block_dev.lba, tmp_skip_space, 0);
|
|
if (ret) {
|
|
MMCINFO("%s: erase emmc user part fail!\n", __FUNCTION__);
|
|
}
|
|
|
|
if (tmp_skip_space[0]) {
|
|
MMCINFO("%s: some sectors in emmc part are ignored!\n\n", __FUNCTION__);
|
|
for (i=0; i<2; i++)
|
|
if (tmp_skip_space[0] & (1<<i))
|
|
MMCINFO("--%d: from%d nr%d \n",
|
|
tmp_skip_space[i*2+1], tmp_skip_space[i*2+2]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MMCINFO("%s: don't support SD card\n", __FUNCTION__);
|
|
ret = -1;
|
|
}
|
|
|
|
return (ret | boot_ret);
|
|
}
|
|
#endif
|
|
|
|
int mmc_send_manual_stop(struct mmc *mmc)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
int ret = 0;
|
|
cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
|
|
cmd.cmdarg = 0;
|
|
cmd.resp_type = MMC_RSP_R1b;
|
|
cmd.flags = MMC_CMD_MANUAL;//let bsp send cmd12
|
|
ret = mmc_send_cmd(mmc, &cmd, NULL);
|
|
if (ret) {
|
|
MMCINFO("mmc fail to send manual stop cmd\n");
|
|
return ret;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct mmc *find_mmc_device(int dev_num)
|
|
{
|
|
struct mmc *m;
|
|
struct list_head *entry;
|
|
|
|
list_for_each(entry, &mmc_devices) {
|
|
m = list_entry(entry, struct mmc, link);
|
|
|
|
if (m->block_dev.dev == dev_num)
|
|
return m;
|
|
}
|
|
|
|
MMCINFO("MMC Device %d not found\n", dev_num);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
|
|
//{
|
|
// struct mmc_cmd cmd;
|
|
// ulong end;
|
|
// int err, start_cmd, end_cmd;
|
|
//
|
|
// if (mmc->high_capacity)
|
|
// end = start + blkcnt - 1;
|
|
// else {
|
|
// end = (start + blkcnt - 1) * mmc->write_bl_len;
|
|
// start *= mmc->write_bl_len;
|
|
// }
|
|
//
|
|
// if (IS_SD(mmc)) {
|
|
// start_cmd = SD_CMD_ERASE_WR_BLK_START;
|
|
// end_cmd = SD_CMD_ERASE_WR_BLK_END;
|
|
// } else {
|
|
// start_cmd = MMC_CMD_ERASE_GROUP_START;
|
|
// end_cmd = MMC_CMD_ERASE_GROUP_END;
|
|
// }
|
|
//
|
|
// cmd.cmdidx = start_cmd;
|
|
// cmd.cmdarg = start;
|
|
// cmd.resp_type = MMC_RSP_R1;
|
|
// cmd.flags = 0;
|
|
//
|
|
// err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
// if (err)
|
|
// goto err_out;
|
|
//
|
|
// cmd.cmdidx = end_cmd;
|
|
// cmd.cmdarg = end;
|
|
//
|
|
// err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
// if (err)
|
|
// goto err_out;
|
|
//
|
|
// cmd.cmdidx = MMC_CMD_ERASE;
|
|
// cmd.cmdarg = SECURE_ERASE;
|
|
// cmd.resp_type = MMC_RSP_R1b;
|
|
//
|
|
// err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
// if (err)
|
|
// goto err_out;
|
|
//
|
|
// return 0;
|
|
//
|
|
//err_out:
|
|
// puts("mmc erase failed\n");
|
|
// return err;
|
|
//}
|
|
|
|
|
|
static unsigned long
|
|
mmc_berase(int dev_num, unsigned long start, lbaint_t blkcnt)
|
|
{
|
|
int err = 0;
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
// unsigned blk = 0, blk_r = 0;
|
|
void* src = malloc(blkcnt * mmc->write_bl_len);
|
|
if(src == NULL){
|
|
printf("erase malloc failed\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!mmc){
|
|
MMCINFO("Can not find mmc dev\n");
|
|
free(src);
|
|
return -1;
|
|
}
|
|
|
|
memset(src, 0, mmc->write_bl_len*blkcnt);
|
|
MMCINFO("erase blk %ld ~ %ld\n", start, start + blkcnt - 1);
|
|
err = mmc_bwrite(dev_num, start, blkcnt, src);
|
|
//mmcinfo("erase flag%d",err);
|
|
if(!err){
|
|
MMCINFO("erase failed\n");
|
|
}
|
|
|
|
free(src);
|
|
return err;
|
|
/*
|
|
if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
|
|
mmcdbg("\n\nCaution! Your devices Erase group is 0x%x\n"
|
|
"The erase range would be change to 0x%x~0x%x\n\n",
|
|
mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
|
|
((start + blkcnt + mmc->erase_grp_size)
|
|
& ~(mmc->erase_grp_size - 1)) - 1);
|
|
|
|
while (blk < blkcnt) {
|
|
blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
|
|
mmc->erase_grp_size : (blkcnt - blk);
|
|
err = mmc_erase_t(mmc, start + blk, blk_r);
|
|
if (err)
|
|
break;
|
|
|
|
blk += blk_r;
|
|
}
|
|
return blk;
|
|
*/
|
|
}
|
|
|
|
#if defined(CONFIG_ARCH_SUN8IW5P1) || defined(CONFIG_ARCH_SUN8IW6P1) || defined(CONFIG_ARCH_SUN8IW8P1)||(defined CONFIG_ARCH_SUN8IW7P1)
|
|
/*
|
|
* 1. 18=3*6, each phase config try 3 times; don't try tx phase 2.
|
|
* 2. {1,1} is the best phase config to compile most of emmc
|
|
* 3. if retry ok, keep current phase and exit. use this new phase config for following operation.
|
|
* if retry fail, set phase to defaul value.
|
|
*/
|
|
#define MAX_RETRY_CNT 18
|
|
static int mmc_retry_request(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
|
{
|
|
//char sunxi_phase[9][2]={{1,1},{0,0},{1,0},{0,1},{1,2},{0,2},{2,0},{2,1},{2,2}};
|
|
char sunxi_phase[9][2]={{1,1},{0,0},{1,0},{0,1},{1,2},{0,2}};
|
|
//char sunxi_phase[9][2]={{0,1}, {1,1},{0,0},{1,0}, {1,2},{0,2}};
|
|
int retry_cnt;
|
|
int ret, err = 0;
|
|
u32 timeout = 1000;
|
|
|
|
if (!mmc->set_phase) {
|
|
return -1;
|
|
}
|
|
|
|
/* send manual stop */
|
|
mmc_send_manual_stop(mmc);
|
|
/* Waiting for the ready status */
|
|
mmc_send_status(mmc, timeout);
|
|
|
|
retry_cnt = 0;
|
|
do
|
|
{
|
|
/* set phase */
|
|
ret = mmc->set_phase(mmc, sunxi_phase[retry_cnt/3][0], sunxi_phase[retry_cnt/3][1]);
|
|
if (ret) {
|
|
MMCINFO("set phase fail, retry fail\n");
|
|
err = -1;
|
|
break;
|
|
}
|
|
|
|
/* retry */
|
|
err = mmc->send_cmd(mmc, cmd, data);
|
|
if (!err) {
|
|
/* if retry ok, keep current phase and exit. */
|
|
MMCINFO("retry ok! retry cnt %d\n", retry_cnt);
|
|
break;
|
|
} else {
|
|
/* send manual stop */
|
|
mmc_send_manual_stop(mmc);
|
|
/* Waiting for the ready status */
|
|
mmc_send_status(mmc, timeout);
|
|
}
|
|
|
|
retry_cnt++;
|
|
} while (retry_cnt < MAX_RETRY_CNT);
|
|
|
|
/* reset to default phase if retry fail */
|
|
if (err)
|
|
{
|
|
mmc->set_phase(mmc, sunxi_phase[0][0], sunxi_phase[0][1]);
|
|
if (ret) {
|
|
MMCINFO("retry fail, set phase to default fail\n");
|
|
}
|
|
}
|
|
|
|
return err;
|
|
}
|
|
#endif
|
|
|
|
static ulong
|
|
mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
struct mmc_data data;
|
|
int timeout = 1000;
|
|
|
|
if ((start + blkcnt) > mmc->block_dev.lba) {
|
|
MMCINFO("MMC: block number 0x%lx exceeds max(0x%lx)\n",
|
|
start + blkcnt, mmc->block_dev.lba);
|
|
return 0;
|
|
}
|
|
|
|
if (blkcnt > 1)
|
|
cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
|
|
else
|
|
cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
|
|
|
|
if (mmc->high_capacity)
|
|
cmd.cmdarg = start;
|
|
else
|
|
cmd.cmdarg = start * mmc->write_bl_len;
|
|
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.flags = 0;
|
|
|
|
data.src = src;
|
|
data.blocks = blkcnt;
|
|
data.blocksize = mmc->write_bl_len;
|
|
data.flags = MMC_DATA_WRITE;
|
|
|
|
if (mmc_send_cmd(mmc, &cmd, &data)) {
|
|
MMCINFO("mmc write failed\n");
|
|
|
|
#if defined(CONFIG_ARCH_SUN8IW5P1) || \
|
|
defined(CONFIG_ARCH_SUN8IW6P1) || \
|
|
defined (CONFIG_ARCH_SUN8IW8P1)|| \
|
|
(defined CONFIG_ARCH_SUN8IW7P1)
|
|
|
|
MMCINFO("mmc write: start retry....\n");
|
|
if (mmc_retry_request(mmc, &cmd, &data)) {
|
|
MMCINFO("mmc write: retry fail\n");
|
|
return 0;
|
|
} else {
|
|
MMCINFO("mmc write: retry ok\n");
|
|
}
|
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
}
|
|
|
|
/* SPI multiblock writes terminate using a special
|
|
* token, not a STOP_TRANSMISSION request.
|
|
*/
|
|
if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
|
|
cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
|
|
cmd.cmdarg = 0;
|
|
cmd.resp_type = MMC_RSP_R1b;
|
|
cmd.flags = 0;
|
|
if (mmc_send_cmd(mmc, &cmd, NULL)) {
|
|
MMCINFO("mmc fail to send stop cmd\n");
|
|
return 0;
|
|
}
|
|
}
|
|
/* Waiting for the ready status */
|
|
mmc_send_status(mmc, timeout);
|
|
|
|
return blkcnt;
|
|
}
|
|
|
|
static ulong
|
|
mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
|
|
{
|
|
lbaint_t cur, blocks_todo = blkcnt;
|
|
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
|
|
if (blkcnt == 0){
|
|
MMCINFO("blkcnt should not be 0\n");
|
|
return 0;
|
|
}
|
|
if (!mmc){
|
|
MMCINFO("Can not found device\n");
|
|
return 0;
|
|
}
|
|
|
|
if (mmc_set_blocklen(mmc, mmc->write_bl_len)){
|
|
MMCINFO("set block len failed\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
do {
|
|
cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo;
|
|
if(mmc_write_blocks(mmc, start, cur, src) != cur){
|
|
MMCINFO("write block failed\n");
|
|
return 0;
|
|
}
|
|
blocks_todo -= cur;
|
|
start += cur;
|
|
// src += cur * mmc->write_bl_len;
|
|
src = (char*)src + cur * mmc->write_bl_len;
|
|
} while (blocks_todo > 0);
|
|
|
|
return blkcnt;
|
|
}
|
|
|
|
|
|
static ulong
|
|
mmc_bwrite_mass_pro(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
|
|
{
|
|
lbaint_t blocks_do = 0;
|
|
ulong start_todo = start;
|
|
|
|
signed int err = 0;
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
#ifdef USE_EMMC_BOOT_PART
|
|
MMCINFO("mmc start mass pro boot part...\n");
|
|
do{
|
|
if((start != BOOT0_SDMMC_START_ADDR)) {
|
|
MMCINFO("boot0 start address %d\n", start);
|
|
break;
|
|
}
|
|
|
|
if (!(mmc->boot_support)) //!(mmc->part_support & PART_SUPPORT)
|
|
{
|
|
MMCINFO("Card doesn't support boot part\n");
|
|
break;
|
|
}
|
|
|
|
|
|
err = mmc_switch_boot_bus_cond(dev_num, MMC_SWITCH_BOOT_SDR_NORMAL, MMC_SWITCH_BOOT_RST_BUS_COND, MMC_SWITCH_BOOT_BUS_SDRx4_DDRx4);
|
|
if (err) {
|
|
MMCINFO("mmc switch boot bus condition failed\n");
|
|
return err;
|
|
}
|
|
MMCDBG("mmc switch boot bus condition succeed\n");
|
|
|
|
err = mmc_switch_boot_part(dev_num, MMC_SWITCH_PART_BOOT_ACK_ENB, MMC_SWITCH_PART_BOOT_PART_1);
|
|
if (err) {
|
|
MMCINFO("mmc switch boot part failed\n");
|
|
return err;
|
|
}
|
|
MMCDBG("mmc switch boot part succeed\n");
|
|
|
|
}while(0);
|
|
#else
|
|
do{
|
|
if((start != BOOT0_SDMMC_START_ADDR)) {
|
|
MMCINFO("boot0 start address %d\n", start);
|
|
break;
|
|
}
|
|
|
|
if (!(mmc->boot_support)) //!(mmc->part_support & PART_SUPPORT)
|
|
{
|
|
MMCINFO("Card doesn't support boot part\n");
|
|
break;
|
|
}
|
|
|
|
err = mmc_switch_boot_part(dev_num, 0, MMC_SWITCH_PART_BOOT_PART_NONE); //disable boot mode
|
|
if (err) {
|
|
MMCINFO("mmc disable boot mode failed\n");
|
|
return err;
|
|
}
|
|
MMCDBG("mmc disable boot mode succeed\n");
|
|
}while(0);
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef USE_EMMC_BOOT_PART
|
|
|
|
//write boot0.bin to boot partition
|
|
if ( (mmc->boot_support) && (start == BOOT0_SDMMC_START_ADDR) )//(mmc->part_support & PART_SUPPORT)
|
|
{
|
|
if (mmc_switch_part(dev_num, MMC_SWITCH_PART_BOOT_PART_1)) {
|
|
MMCINFO("switch to boot1 partition failed\n");
|
|
return 0;
|
|
}
|
|
//In eMMC boot partition,boot0.bin start from 0 sector,so we must change start form 16 to 0;
|
|
start_todo= 0;
|
|
}
|
|
#endif
|
|
|
|
blocks_do = mmc_bwrite(dev_num, start_todo, blkcnt, src);
|
|
//check boot0
|
|
if(start == BOOT0_SDMMC_START_ADDR){
|
|
u32 rblk = 0;
|
|
s32 err = 0;
|
|
void *dst = malloc(blkcnt * mmc->write_bl_len);
|
|
MMCDBG("try to check boot0\n");
|
|
if(dst == NULL){
|
|
MMCINFO("malloc mem failed\n");
|
|
return 0;
|
|
}
|
|
rblk = mmc_bread(dev_num, start_todo, blkcnt, dst);
|
|
if(rblk){
|
|
if(memcmp(src,dst,blkcnt * mmc->write_bl_len)){
|
|
err = -1;
|
|
}
|
|
}else{
|
|
err = -1;
|
|
}
|
|
free(dst);
|
|
if(err){
|
|
MMCINFO("check boot0 failded\n");
|
|
return 0;
|
|
}
|
|
MMCDBG("check boot0 ok\n");
|
|
|
|
}
|
|
|
|
#ifdef USE_EMMC_BOOT_PART
|
|
//
|
|
if ((mmc->boot_support) && (start == BOOT0_SDMMC_START_ADDR) )//(mmc->part_support & PART_SUPPORT)
|
|
{
|
|
//switch back to user partiton
|
|
if (mmc_switch_part(dev_num, 0)) {
|
|
MMCINFO("switch to boot1 partition failed\n");
|
|
return 0;
|
|
}
|
|
#ifdef USE_EMMC_USER_WHEN_USE_BOOT_PART//use eMMC boot and user part at the same time
|
|
MMCINFO("mmc start write user part after write boot part...\n");
|
|
blocks_do = mmc_bwrite(dev_num, start, blkcnt, src);
|
|
//check boot0
|
|
{
|
|
u32 rblk = 0;
|
|
s32 err = 0;
|
|
void *dst = malloc(blkcnt * mmc->write_bl_len);
|
|
MMCDBG("try to check boot0 in user part when use eMMC boot and user part at the same time\n");
|
|
if(dst == NULL){
|
|
MMCINFO("malloc mem failed\n");
|
|
return 0;
|
|
}
|
|
rblk = mmc_bread(dev_num, start, blkcnt, dst);
|
|
if(rblk){
|
|
if(memcmp(src,dst,blkcnt * mmc->write_bl_len)){
|
|
err = -1;
|
|
}
|
|
}else{
|
|
err = -1;
|
|
}
|
|
free(dst);
|
|
if(err){
|
|
MMCINFO("check boot0 in user part failded when use eMMC boot and user part at the same time\n");
|
|
return 0;
|
|
}
|
|
MMCDBG("check boot0 in user part ok when use eMMC boot and user part at the same time\n");
|
|
}
|
|
|
|
|
|
#endif
|
|
}
|
|
#endif
|
|
return blocks_do;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
struct mmc_data data;
|
|
int timeout = 1000;
|
|
|
|
if (blkcnt > 1)
|
|
cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
|
|
else
|
|
cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
|
|
if (mmc->high_capacity)
|
|
cmd.cmdarg = start;
|
|
else
|
|
cmd.cmdarg = start * mmc->read_bl_len;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.flags = 0;
|
|
|
|
data.dest = dst;
|
|
data.blocks = blkcnt;
|
|
data.blocksize = mmc->read_bl_len;
|
|
data.flags = MMC_DATA_READ;
|
|
|
|
if (mmc_send_cmd(mmc, &cmd, &data)) {
|
|
MMCINFO(" read block failed\n");
|
|
|
|
#if defined(CONFIG_ARCH_SUN8IW5P1) || \
|
|
defined(CONFIG_ARCH_SUN8IW6P1) || \
|
|
defined (CONFIG_ARCH_SUN8IW8P1)|| \
|
|
(defined CONFIG_ARCH_SUN8IW7P1)
|
|
|
|
MMCINFO("mmc read: start retry....\n");
|
|
if (mmc_retry_request(mmc, &cmd, &data)) {
|
|
MMCINFO("mmc read: retry fail\n");
|
|
return 0;
|
|
} else {
|
|
MMCINFO("mmc read: retry ok\n");
|
|
}
|
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
}
|
|
|
|
if (blkcnt > 1) {
|
|
cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
|
|
cmd.cmdarg = 0;
|
|
cmd.resp_type = MMC_RSP_R1b;
|
|
cmd.flags = 0;
|
|
if (mmc_send_cmd(mmc, &cmd, NULL)) {
|
|
MMCINFO("mmc fail to send stop cmd\n");
|
|
return 0;
|
|
}
|
|
|
|
/* Waiting for the ready status */
|
|
mmc_send_status(mmc, timeout);
|
|
}
|
|
|
|
return blkcnt;
|
|
}
|
|
|
|
static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
|
|
{
|
|
lbaint_t cur, blocks_todo = blkcnt;
|
|
|
|
if (blkcnt == 0){
|
|
MMCINFO("blkcnt should not be 0\n");
|
|
return 0;
|
|
}
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
if (!mmc){
|
|
MMCINFO("Can not find mmc dev\n");
|
|
return 0;
|
|
}
|
|
if ((start + blkcnt) > mmc->block_dev.lba) {
|
|
MMCINFO("MMC: block number 0x%lx exceeds max(0x%lx)\n",
|
|
start + blkcnt, mmc->block_dev.lba);
|
|
return 0;
|
|
}
|
|
|
|
|
|
if (mmc_set_blocklen(mmc, mmc->read_bl_len)){
|
|
MMCINFO("Set block len failed\n");
|
|
return 0;
|
|
}
|
|
|
|
do {
|
|
cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo;
|
|
if(mmc_read_blocks(mmc, dst, start, cur) != cur){
|
|
MMCINFO("block read failed\n");
|
|
return 0;
|
|
}
|
|
blocks_todo -= cur;
|
|
start += cur;
|
|
// dst += cur * mmc->read_bl_len;
|
|
dst = (char*)dst + cur * mmc->read_bl_len;
|
|
} while (blocks_todo > 0);
|
|
|
|
return blkcnt;
|
|
}
|
|
|
|
static ulong mmc_bread_mass_pro(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
|
|
{
|
|
lbaint_t blocks_do = 0;
|
|
ulong start_todo = start;
|
|
|
|
#ifdef USE_EMMC_BOOT_PART
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
//write boot0.bin to boot partition
|
|
if ((mmc->boot_support) && (start == BOOT0_SDMMC_START_ADDR) )//(mmc->part_support & PART_SUPPORT)
|
|
{
|
|
if (mmc_switch_part(dev_num, MMC_SWITCH_PART_BOOT_PART_1))
|
|
{
|
|
MMCINFO("switch to boot1 partition failed\n");
|
|
return 0;
|
|
}
|
|
//In eMMC boot partition,boot0.bin start from 0 sector,so we must change start form 16 to 0;
|
|
start_todo= 0;
|
|
}
|
|
#endif
|
|
|
|
blocks_do = mmc_bread(dev_num, start_todo, blkcnt, dst);
|
|
|
|
#ifdef USE_EMMC_BOOT_PART
|
|
//
|
|
if ( (mmc->boot_support) && (start == BOOT0_SDMMC_START_ADDR) )//(mmc->part_support & PART_SUPPORT)
|
|
{
|
|
//switch back to user partiton
|
|
if (mmc_switch_part(dev_num, 0)) {
|
|
MMCINFO("switch to boot1 partition failed\n");
|
|
return 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return blocks_do;
|
|
}
|
|
|
|
#ifdef CONFIG_SUNXI_SECURE_STORAGE
|
|
|
|
static int check_secure_area(ulong start, lbaint_t blkcnt)
|
|
{
|
|
u32 sta_add = start;
|
|
u32 end_add = start + blkcnt -1;
|
|
u32 se_sta_add = SDMMC_SECURE_STORAGE_START_ADD;
|
|
u32 se_end_add = SDMMC_SECURE_STORAGE_START_ADD+(SDMMC_ITEM_SIZE*2*MAX_SECURE_STORAGE_MAX_ITEM)-1;
|
|
if(blkcnt<=(SDMMC_ITEM_SIZE*2*MAX_SECURE_STORAGE_MAX_ITEM)){
|
|
if(((sta_add >= se_sta_add)&&(sta_add <= se_end_add))
|
|
||((end_add >= se_sta_add)&&(end_add <= se_end_add))){
|
|
return 1;
|
|
}
|
|
}else{
|
|
if(((se_sta_add >= sta_add)&&(se_sta_add <= end_add))
|
|
||((se_end_add >= sta_add)&&(se_end_add <= end_add))){
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static ulong
|
|
mmc_bwrite_mass_pro_secure(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
|
|
{
|
|
if(check_secure_area(start,blkcnt)){
|
|
MMCINFO("Should not w/r secure area in fun %s,line,%d in start %d,end %d\n",\
|
|
__FUNCTION__,__LINE__ ,start,start + blkcnt-1);
|
|
return -1;
|
|
}
|
|
|
|
return mmc_bwrite_mass_pro(dev_num, start, blkcnt, src);
|
|
}
|
|
|
|
static ulong mmc_bread_mass_pro_secure(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
|
|
{
|
|
if(check_secure_area(start,blkcnt)){
|
|
MMCINFO("Should not w/r secure area in fun %s,line,%d in start %d,end %d\n",\
|
|
__FUNCTION__,__LINE__ ,start,start + blkcnt-1);
|
|
return -1;
|
|
}
|
|
|
|
return mmc_bread_mass_pro(dev_num, start, blkcnt, dst);
|
|
}
|
|
|
|
static unsigned long
|
|
mmc_berase_secure(int dev_num, unsigned long start, lbaint_t blkcnt)
|
|
{
|
|
if(check_secure_area(start,blkcnt)){
|
|
MMCINFO("Should not w/r secure area in fun %s,line,%d in start %d,end %d\n",\
|
|
__FUNCTION__,__LINE__ ,start,start + blkcnt-1);
|
|
return -1;
|
|
}
|
|
|
|
return mmc_berase(dev_num, start, blkcnt);
|
|
}
|
|
|
|
int mmc_secure_wipe_secure(int dev_num, unsigned int start, unsigned int blkcnt, unsigned int *skip_space)
|
|
{
|
|
if(check_secure_area(start,blkcnt)){
|
|
MMCINFO("Should not w/r secure area in fun %s,line,%d in start %d,end %d\n",\
|
|
__FUNCTION__,__LINE__ ,start,start + blkcnt-1);
|
|
return -1;
|
|
}
|
|
|
|
return mmc_secure_wipe(dev_num, start, blkcnt, skip_space);
|
|
}
|
|
|
|
static ulong mmc_bread_secure(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
|
|
{
|
|
if(check_secure_area(start,blkcnt)){
|
|
MMCINFO("Should not w/r secure area in fun %s,line,%d in start %d,end %d\n",\
|
|
__FUNCTION__,__LINE__ ,start,start + blkcnt-1);
|
|
return -1;
|
|
}
|
|
|
|
return mmc_bread(dev_num, start, blkcnt, dst);
|
|
}
|
|
|
|
int mmc_mmc_erase_secure(int dev_num, unsigned int start, unsigned int blkcnt, unsigned int *skip_space)
|
|
{
|
|
if(check_secure_area(start,blkcnt)){
|
|
MMCINFO("Should not w/r secure area in fun %s,line,%d in start %d,end %d\n",\
|
|
__FUNCTION__,__LINE__ ,start,start + blkcnt-1);
|
|
return -1;
|
|
}
|
|
return mmc_mmc_erase(dev_num, start, blkcnt, skip_space);
|
|
}
|
|
|
|
int mmc_mmc_trim_secure(int dev_num, unsigned int start, unsigned int blkcnt)
|
|
{
|
|
if(check_secure_area(start,blkcnt)){
|
|
MMCINFO("Should not w/r secure area in fun %s,line,%d in start %d,end %d\n",\
|
|
__FUNCTION__,__LINE__ ,start,start + blkcnt-1);
|
|
return -1;
|
|
}
|
|
return mmc_mmc_trim(dev_num, start, blkcnt);
|
|
}
|
|
|
|
int mmc_mmc_discard_secure(int dev_num, unsigned int start, unsigned int blkcnt)
|
|
{
|
|
if(check_secure_area(start,blkcnt)){
|
|
MMCINFO("Should not w/r secure area in fun %s,line,%d in start %d,end %d\n",\
|
|
__FUNCTION__,__LINE__ ,start,start + blkcnt-1);
|
|
return -1;
|
|
}
|
|
return mmc_mmc_discard(dev_num, start, blkcnt);
|
|
}
|
|
|
|
int mmc_mmc_sanitize_secure(int dev_num)
|
|
{
|
|
return mmc_mmc_sanitize(dev_num);
|
|
}
|
|
int mmc_mmc_secure_erase_secure(int dev_num, unsigned int start, unsigned int blkcnt, unsigned int *skip_space)
|
|
{
|
|
if(check_secure_area(start,blkcnt)){
|
|
MMCINFO("Should not w/r secure area in fun %s,line,%d in start %d,end %d\n",\
|
|
__FUNCTION__,__LINE__ ,start,start + blkcnt-1);
|
|
return -1;
|
|
}
|
|
return mmc_mmc_secure_erase(dev_num, start, blkcnt, skip_space);
|
|
}
|
|
int mmc_mmc_secure_trim_secure(int dev_num, unsigned int start, unsigned int blkcnt)
|
|
{
|
|
if(check_secure_area(start,blkcnt)){
|
|
MMCINFO("Should not w/r secure area in fun %s,line,%d in start %d,end %d\n",\
|
|
__FUNCTION__,__LINE__ ,start,start + blkcnt-1);
|
|
return -1;
|
|
}
|
|
return mmc_mmc_secure_trim(dev_num, start, blkcnt);
|
|
}
|
|
|
|
static ulong
|
|
mmc_bwrite_secure(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
|
|
{
|
|
if(check_secure_area(start,blkcnt)){
|
|
MMCINFO("Should not w/r secure area in fun %s,line,%d in start %d,end %d\n",\
|
|
__FUNCTION__,__LINE__ ,start,start + blkcnt-1);
|
|
return -1;
|
|
}
|
|
|
|
return mmc_bwrite(dev_num, start, blkcnt, src);
|
|
}
|
|
|
|
|
|
static int get_sdmmc_secure_storage_max_item(void){
|
|
return MAX_SECURE_STORAGE_MAX_ITEM;
|
|
}
|
|
|
|
|
|
static int sdmmc_secure_storage_write(s32 dev_num,u32 item,u8 *buf , lbaint_t blkcnt)
|
|
{
|
|
s32 ret = 0;
|
|
|
|
if(buf == NULL){
|
|
MMCINFO("intput buf is NULL %d\n");
|
|
return -1;
|
|
}
|
|
|
|
if(item > MAX_SECURE_STORAGE_MAX_ITEM){
|
|
MMCINFO("item exceed %d\n",MAX_SECURE_STORAGE_MAX_ITEM);
|
|
return -1;
|
|
}
|
|
|
|
if(blkcnt > SDMMC_ITEM_SIZE){
|
|
MMCINFO("block count exceed %d\n",SDMMC_ITEM_SIZE);
|
|
return -1;
|
|
}
|
|
//first backups
|
|
ret = mmc_bwrite(dev_num,SDMMC_SECURE_STORAGE_START_ADD+SDMMC_ITEM_SIZE*2*item,blkcnt,buf);
|
|
if(ret != blkcnt){
|
|
MMCINFO("Write first backup failed\n");
|
|
return -1;
|
|
}
|
|
//second backups
|
|
ret = mmc_bwrite(dev_num,SDMMC_SECURE_STORAGE_START_ADD+SDMMC_ITEM_SIZE*2*item+SDMMC_ITEM_SIZE,blkcnt,buf);
|
|
if(ret != blkcnt){
|
|
MMCINFO("Write second backup failed\n");
|
|
return -1;
|
|
}
|
|
return blkcnt;
|
|
}
|
|
|
|
|
|
static int sdmmc_secure_storage_read(s32 dev_num,u32 item,u8 *buf , lbaint_t blkcnt)
|
|
{
|
|
s32 ret = 0;
|
|
s32 *fst_bak = (s32 *)buf;
|
|
|
|
if(buf == NULL){
|
|
MMCINFO("intput buf is NULL %d\n");
|
|
ret = -1;
|
|
goto out;
|
|
|
|
}
|
|
|
|
if(item > MAX_SECURE_STORAGE_MAX_ITEM){
|
|
MMCINFO("item exceed %d\n",MAX_SECURE_STORAGE_MAX_ITEM);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
if(blkcnt > SDMMC_ITEM_SIZE){
|
|
MMCINFO("block count exceed %d\n",SDMMC_ITEM_SIZE);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
//first backups
|
|
ret = mmc_bread(dev_num,SDMMC_SECURE_STORAGE_START_ADD+SDMMC_ITEM_SIZE*2*item,blkcnt,fst_bak);
|
|
if(ret != blkcnt){
|
|
MMCINFO("read first backup failed in fun %s line %d\n",__FUNCTION__,__LINE__);
|
|
ret = -1;
|
|
}
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static int sdmmc_secure_storage_read_backup(s32 dev_num,u32 item,u8 *buf , lbaint_t blkcnt)
|
|
{
|
|
s32 ret = 0;
|
|
s32 *sec_bak = (s32 *)buf;
|
|
|
|
if(buf == NULL){
|
|
MMCINFO("intput buf is NULL %d\n");
|
|
ret = -1;
|
|
goto out;
|
|
|
|
}
|
|
|
|
if(item > MAX_SECURE_STORAGE_MAX_ITEM){
|
|
MMCINFO("item exceed %d\n",MAX_SECURE_STORAGE_MAX_ITEM);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
if(blkcnt > SDMMC_ITEM_SIZE){
|
|
MMCINFO("block count exceed %d\n",SDMMC_ITEM_SIZE);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
//second backups
|
|
ret = mmc_bread(dev_num,SDMMC_SECURE_STORAGE_START_ADD+SDMMC_ITEM_SIZE*2*item+SDMMC_ITEM_SIZE,blkcnt,sec_bak);
|
|
if(ret != blkcnt){
|
|
MMCINFO("read second backup failed fun %s line %d\n",__FUNCTION__,__LINE__);
|
|
ret = -1;
|
|
}
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
int mmc_go_idle(struct mmc* mmc)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
int err;
|
|
|
|
udelay(1000);
|
|
|
|
cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
|
|
cmd.cmdarg = 0;
|
|
cmd.resp_type = MMC_RSP_NONE;
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("go idle failed\n");
|
|
return err;
|
|
}
|
|
|
|
udelay(2000);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
sd_send_op_cond(struct mmc *mmc)
|
|
{
|
|
int timeout = 1000;
|
|
int err;
|
|
struct mmc_cmd cmd;
|
|
|
|
do {
|
|
cmd.cmdidx = MMC_CMD_APP_CMD;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.cmdarg = 0;
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("send app cmd failed\n");
|
|
return err;
|
|
}
|
|
|
|
cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
|
|
cmd.resp_type = MMC_RSP_R3;
|
|
|
|
/*
|
|
* Most cards do not answer if some reserved bits
|
|
* in the ocr are set. However, Some controller
|
|
* can set bit 7 (reserved for low voltages), but
|
|
* how to manage low voltages SD card is not yet
|
|
* specified.
|
|
*/
|
|
cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
|
|
(mmc->voltages & 0xff8000);
|
|
|
|
if (mmc->version == SD_VERSION_2)
|
|
cmd.cmdarg |= OCR_HCS;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("send cmd41 failed\n");
|
|
return err;
|
|
}
|
|
|
|
udelay(1000);
|
|
} while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
|
|
|
|
if (timeout < 0){
|
|
MMCINFO("wait card init failed\n");
|
|
return UNUSABLE_ERR;
|
|
}
|
|
|
|
if (mmc->version != SD_VERSION_2)
|
|
mmc->version = SD_VERSION_1_0;
|
|
|
|
if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
|
|
cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
|
|
cmd.resp_type = MMC_RSP_R3;
|
|
cmd.cmdarg = 0;
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("spi read ocr failed\n");
|
|
return err;
|
|
}
|
|
}
|
|
|
|
mmc->ocr = cmd.response[0];
|
|
|
|
mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
|
|
mmc->rca = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int mmc_send_op_cond(struct mmc *mmc)
|
|
{
|
|
int timeout = 10000;
|
|
struct mmc_cmd cmd;
|
|
int err;
|
|
|
|
/* Some cards seem to need this */
|
|
mmc_go_idle(mmc);
|
|
|
|
/* Asking to the card its capabilities */
|
|
cmd.cmdidx = MMC_CMD_SEND_OP_COND;
|
|
cmd.resp_type = MMC_RSP_R3;
|
|
cmd.cmdarg = 0x40ff8000;//foresee
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("mmc send op cond failed\n");
|
|
return err;
|
|
}
|
|
|
|
udelay(1000);
|
|
|
|
do {
|
|
cmd.cmdidx = MMC_CMD_SEND_OP_COND;
|
|
cmd.resp_type = MMC_RSP_R3;
|
|
cmd.cmdarg = (mmc_host_is_spi(mmc) ? 0 :
|
|
(mmc->voltages &
|
|
(cmd.response[0] & OCR_VOLTAGE_MASK)) |
|
|
(cmd.response[0] & OCR_ACCESS_MODE));
|
|
|
|
if (mmc->host_caps & MMC_MODE_HC)
|
|
cmd.cmdarg |= OCR_HCS;
|
|
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("mmc send op cond failed\n");
|
|
return err;
|
|
}
|
|
|
|
udelay(1000);
|
|
} while (!(cmd.response[0] & OCR_BUSY) && timeout--);
|
|
|
|
if (timeout < 0){
|
|
MMCINFO("wait for mmc init failed\n");
|
|
return UNUSABLE_ERR;
|
|
}
|
|
|
|
if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
|
|
cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
|
|
cmd.resp_type = MMC_RSP_R3;
|
|
cmd.cmdarg = 0;
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("spi read ocr failed\n");
|
|
return err;
|
|
}
|
|
}
|
|
|
|
mmc->version = MMC_VERSION_UNKNOWN;
|
|
mmc->ocr = cmd.response[0];
|
|
|
|
mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
|
|
mmc->rca = 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
struct mmc_data data;
|
|
int err;
|
|
|
|
/* Get the Card Status Register */
|
|
cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.cmdarg = 0;
|
|
cmd.flags = 0;
|
|
|
|
data.dest = ext_csd;
|
|
data.blocks = 1;
|
|
data.blocksize = 512;
|
|
data.flags = MMC_DATA_READ;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, &data);
|
|
if(err)
|
|
MMCINFO("mmc send ext csd failed\n");
|
|
|
|
return err;
|
|
}
|
|
|
|
/* decode ext_csd */
|
|
static int mmc_decode_ext_csd(struct mmc *mmc,
|
|
struct mmc_ext_csd *dec_ext_csd, u8 *ext_csd)
|
|
{
|
|
int err = 0;
|
|
|
|
if ((!ext_csd) || !(dec_ext_csd))
|
|
return 0;
|
|
|
|
/* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */
|
|
dec_ext_csd->raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE];
|
|
|
|
|
|
dec_ext_csd->rev = ext_csd[EXT_CSD_REV];
|
|
if (dec_ext_csd->rev > 8) {
|
|
MMCINFO("unrecognised EXT_CSD revision %d, maybe ver5.2 or later version!\n", dec_ext_csd->rev);
|
|
//err = -1;
|
|
//goto out;
|
|
}
|
|
|
|
dec_ext_csd->raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0];
|
|
dec_ext_csd->raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1];
|
|
dec_ext_csd->raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2];
|
|
dec_ext_csd->raw_sectors[3] = ext_csd[EXT_CSD_SEC_CNT + 3];
|
|
if (dec_ext_csd->rev >= 2) {
|
|
dec_ext_csd->sectors =
|
|
ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
|
|
ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
|
|
ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
|
|
ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
|
|
}
|
|
|
|
dec_ext_csd->raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
|
|
|
|
dec_ext_csd->raw_erase_timeout_mult =
|
|
ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
|
|
dec_ext_csd->raw_hc_erase_grp_size =
|
|
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
|
|
if (dec_ext_csd->rev >= 3) {
|
|
dec_ext_csd->erase_group_def =
|
|
ext_csd[EXT_CSD_ERASE_GROUP_DEF];
|
|
dec_ext_csd->hc_erase_timeout = 300 *
|
|
ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
|
|
dec_ext_csd->hc_erase_size =
|
|
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10;
|
|
}
|
|
|
|
dec_ext_csd->raw_hc_erase_gap_size =
|
|
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
|
|
dec_ext_csd->raw_sec_trim_mult =
|
|
ext_csd[EXT_CSD_SEC_TRIM_MULT];
|
|
dec_ext_csd->raw_sec_erase_mult =
|
|
ext_csd[EXT_CSD_SEC_ERASE_MULT];
|
|
dec_ext_csd->raw_sec_feature_support =
|
|
ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
|
|
dec_ext_csd->raw_trim_mult =
|
|
ext_csd[EXT_CSD_TRIM_MULT];
|
|
|
|
if (dec_ext_csd->rev >= 4) {
|
|
dec_ext_csd->sec_trim_mult =
|
|
ext_csd[EXT_CSD_SEC_TRIM_MULT];
|
|
dec_ext_csd->sec_erase_mult =
|
|
ext_csd[EXT_CSD_SEC_ERASE_MULT];
|
|
dec_ext_csd->sec_feature_support =
|
|
ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
|
|
dec_ext_csd->trim_timeout = 300 *
|
|
ext_csd[EXT_CSD_TRIM_MULT];
|
|
}
|
|
|
|
dec_ext_csd->raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
|
|
|
|
/* eMMC v4.5 or later */
|
|
if (dec_ext_csd->rev >= 6) {
|
|
dec_ext_csd->generic_cmd6_time = 10 *
|
|
ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
|
|
dec_ext_csd->power_off_longtime = 10 *
|
|
ext_csd[EXT_CSD_POWER_OFF_LONG_TIME];
|
|
|
|
} else {
|
|
dec_ext_csd->data_sector_size = 512;
|
|
}
|
|
|
|
//out:
|
|
return err;
|
|
}
|
|
|
|
int mmc_do_switch(struct mmc *mmc, u8 set, u8 index, u8 value, u32 timeout)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
int ret;
|
|
|
|
cmd.cmdidx = MMC_CMD_SWITCH;
|
|
cmd.resp_type = MMC_RSP_R1b;
|
|
cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
|
|
(index << 16) |
|
|
(value << 8);
|
|
cmd.flags = 0;
|
|
|
|
ret = mmc_send_cmd(mmc, &cmd, NULL);
|
|
if(ret){
|
|
MMCINFO("mmc switch failed\n");
|
|
}
|
|
|
|
ret = mmc_update_phase(mmc);
|
|
if (ret)
|
|
{
|
|
MMCINFO("update clock failed after send switch cmd\n");
|
|
return ret;
|
|
}
|
|
|
|
/* Waiting for the ready status */
|
|
mmc_send_status(mmc, timeout);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
|
|
{
|
|
int timeout = 1000;
|
|
return mmc_do_switch(mmc, set, index, value, timeout);
|
|
}
|
|
|
|
static int mmc_en_emmc_hw_rst(struct mmc *mmc)
|
|
{
|
|
char ext_csd[512] = {0};
|
|
int err;
|
|
|
|
err = mmc_send_ext_csd(mmc, ext_csd);
|
|
if (err) {
|
|
MMCINFO("mmc get extcsd fail -0\n");
|
|
return err;
|
|
}
|
|
|
|
if (ext_csd[162] & 0x1) {
|
|
MMCINFO("hw rst already enabled\n");
|
|
goto OUT;
|
|
}
|
|
|
|
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, \
|
|
EXT_CSD_RST_N_FUNCTION, EXT_CSD_RST_N_ENABLE);
|
|
if (err) {
|
|
MMCINFO("mmc enable hw rst fail\n");
|
|
return err;
|
|
}
|
|
|
|
err = mmc_send_ext_csd(mmc, ext_csd);
|
|
if (err) {
|
|
MMCINFO("mmc get extcsd fail -1\n");
|
|
return err;
|
|
}
|
|
|
|
if (!(ext_csd[162] & 0x1)) {
|
|
MMCINFO("en hw rst fail, 0x%x\n", ext_csd[162]);
|
|
return -1;
|
|
} else {
|
|
MMCINFO("en hw rst ok, 0x%x\n", ext_csd[162]);
|
|
}
|
|
|
|
OUT:
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int mmc_chk_emmc_hw_rst(struct mmc *mmc)
|
|
{
|
|
char ext_csd[512] = {0};
|
|
int err;
|
|
|
|
err = mmc_send_ext_csd(mmc, ext_csd);
|
|
if (err) {
|
|
MMCINFO("mmc get extcsd fail -0\n");
|
|
return err;
|
|
}
|
|
|
|
if (ext_csd[162] & 0x1)
|
|
MMCINFO("Warining:hw rst already enabled!!!!!\n");
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int mmc_change_freq(struct mmc *mmc)
|
|
{
|
|
char ext_csd[512];
|
|
char cardtype;
|
|
int err;
|
|
int retry = 5;
|
|
|
|
mmc->card_caps = 0;
|
|
|
|
if (mmc_host_is_spi(mmc))
|
|
return 0;
|
|
|
|
/* Only version 4 supports high-speed */
|
|
if (mmc->version < MMC_VERSION_4)
|
|
return 0;
|
|
//here we assume eMMC support 8 bit
|
|
mmc->card_caps |= MMC_MODE_4BIT|MMC_MODE_8BIT;
|
|
|
|
err = mmc_send_ext_csd(mmc, ext_csd);
|
|
|
|
if (err){
|
|
MMCINFO("mmc get ext csd failed\n");
|
|
return err;
|
|
}
|
|
|
|
cardtype = ext_csd[196] & 0xf;
|
|
|
|
//retry for Toshiba emmc;for the first time Toshiba emmc change to HS
|
|
//it will return response crc err,so retry
|
|
do{
|
|
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
|
|
if(!err){
|
|
break;
|
|
}
|
|
MMCINFO("retry mmc switch(cmd6)\n");
|
|
}while(retry--);
|
|
|
|
if (err){
|
|
MMCINFO("mmc change to hs failed\n");
|
|
return err;
|
|
}
|
|
|
|
err = mmc_update_phase(mmc);
|
|
if (err)
|
|
{
|
|
MMCINFO("update clock failed\n");
|
|
return err;
|
|
}
|
|
|
|
/* Now check to see that it worked */
|
|
err = mmc_send_ext_csd(mmc, ext_csd);
|
|
|
|
if (err){
|
|
MMCINFO("send ext csd faild\n");
|
|
return err;
|
|
}
|
|
|
|
/* No high-speed support */
|
|
if (!ext_csd[185])
|
|
return 0;
|
|
|
|
/* High Speed is set, there are two types: 52MHz and 26MHz */
|
|
if (cardtype & MMC_HS_52MHZ)
|
|
mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
|
|
else
|
|
mmc->card_caps |= MMC_MODE_HS;
|
|
|
|
if (cardtype & MMC_DDR_52MHZ){
|
|
mmc->card_caps |= MMC_MODE_DDR_52MHz;
|
|
MMCDBG("get ddr OK!\n");
|
|
}else{
|
|
MMCINFO("get ddr fail!\n");
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int mmc_switch_boot_bus_cond(int dev_num, u32 boot_mode, u32 rst_bus_cond, u32 bus_width)
|
|
{
|
|
char ext_csd[512]={0};
|
|
unsigned char boot_bus_cond = 0;
|
|
int ret = 0;
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
if (!mmc){
|
|
MMCINFO("can not find mmc device\n");
|
|
return -1;
|
|
}
|
|
|
|
|
|
boot_bus_cond = (mmc->boot_bus_cond &
|
|
(~MMC_SWITCH_BOOT_MODE_MASK) & (~MMC_SWITCH_BOOT_RST_BUS_COND_MASK) & (~MMC_SWITCH_BOOT_BUS_WIDTH_MASK))
|
|
| ((boot_mode << 3) & MMC_SWITCH_BOOT_MODE_MASK)
|
|
| ((rst_bus_cond << 2) & MMC_SWITCH_BOOT_RST_BUS_COND_MASK)
|
|
| ((bus_width) & MMC_SWITCH_BOOT_BUS_WIDTH_MASK);
|
|
|
|
ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_COND,boot_bus_cond);
|
|
if(ret){
|
|
MMCINFO("switch bus cond failed\n");
|
|
return -1;
|
|
}
|
|
ret = mmc_send_ext_csd(mmc, ext_csd);
|
|
if(ret){
|
|
MMCINFO("send ext csd failed\n");
|
|
return -1;
|
|
}
|
|
MMCDBG("boot bus cond:0x%x\n",ext_csd[EXT_CSD_BOOT_BUS_COND]);
|
|
if(boot_bus_cond!=ext_csd[EXT_CSD_BOOT_BUS_COND]) {
|
|
MMCINFO("Set boot bus cond failed,now bus con is 0x%x\n",ext_csd[EXT_CSD_BOOT_BUS_COND]);
|
|
return -1;
|
|
}
|
|
mmc->boot_bus_cond = boot_bus_cond;
|
|
return ret;
|
|
}
|
|
|
|
int mmc_switch_boot_part(int dev_num, u32 boot_ack, u32 boot_part)
|
|
{
|
|
char ext_csd[512]={0};
|
|
unsigned char part_config = 0;
|
|
int ret = 0;
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
if (!mmc){
|
|
MMCINFO("can not find mmc device\n");
|
|
return -1;
|
|
}
|
|
|
|
|
|
part_config = (mmc->part_config & (~MMC_SWITCH_PART_BOOT_PART_MASK) & (~MMC_SWITCH_PART_BOOT_ACK_MASK))
|
|
| ((boot_part << 3) & MMC_SWITCH_PART_BOOT_PART_MASK) | (boot_ack << 6);
|
|
ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,part_config);
|
|
|
|
if(ret){
|
|
MMCINFO("switch boot partd failed\n");
|
|
return -1;
|
|
}
|
|
ret = mmc_send_ext_csd(mmc, ext_csd);
|
|
if(ret){
|
|
MMCINFO("send ext csd failed\n");
|
|
return -1;
|
|
}
|
|
|
|
MMCDBG("part conf:0x%x\n",ext_csd[EXT_CSD_PART_CONF]);
|
|
if(part_config!=ext_csd[EXT_CSD_PART_CONF]) {
|
|
MMCINFO("switch boot part failed,now part conf is 0x%x\n",ext_csd[EXT_CSD_PART_CONF]);
|
|
return -1;
|
|
}
|
|
mmc->part_config = part_config;
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
int mmc_switch_part(int dev_num, unsigned int part_num)
|
|
{
|
|
char ext_csd[512]={0};
|
|
unsigned char part_config = 0;
|
|
int ret = 0;
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
|
|
MMCDBG("Try to switch part \n");
|
|
if (!mmc){
|
|
MMCINFO("can not find mmc device\n");
|
|
return -1;
|
|
}
|
|
|
|
|
|
part_config = (mmc->part_config & ~PART_ACCESS_MASK)
|
|
| (part_num & PART_ACCESS_MASK);
|
|
ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,part_config);
|
|
if(ret){
|
|
MMCINFO("mmc switch part failed\n");
|
|
return -1;
|
|
}
|
|
ret = mmc_send_ext_csd(mmc, ext_csd);
|
|
if(ret){
|
|
MMCINFO("send ext csd failed\n");
|
|
return -1;
|
|
}
|
|
MMCDBG("part conf:0x%x\n",ext_csd[EXT_CSD_PART_CONF]);
|
|
if(part_config!=ext_csd[EXT_CSD_PART_CONF]) {
|
|
MMCINFO("switch boot part failed,now bus con is 0x%x\n",ext_csd[EXT_CSD_PART_CONF]);
|
|
return -1;
|
|
}
|
|
mmc->part_config = part_config;
|
|
|
|
MMCDBG("switch part succeed\n");
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
int mmc_select_hwpart(int dev_num, int hwpart)
|
|
{
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
int ret;
|
|
|
|
if (!mmc)
|
|
return -1;
|
|
|
|
if (mmc->part_num == hwpart)
|
|
return 0;
|
|
|
|
if (mmc->part_config == MMCPART_NOAVAILABLE) {
|
|
printf("Card doesn't support part_switch\n");
|
|
return -1;
|
|
}
|
|
|
|
ret = mmc_switch_part(dev_num, hwpart);
|
|
if (ret)
|
|
return ret;
|
|
|
|
mmc->part_num = hwpart;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
struct mmc_data data;
|
|
|
|
/* Switch the frequency */
|
|
cmd.cmdidx = SD_CMD_SWITCH_FUNC;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.cmdarg = (mode << 31) | 0xffffff;
|
|
cmd.cmdarg &= ~(0xf << (group * 4));
|
|
cmd.cmdarg |= value << (group * 4);
|
|
cmd.flags = 0;
|
|
|
|
data.dest = (char *)resp;
|
|
data.blocksize = 64;
|
|
data.blocks = 1;
|
|
data.flags = MMC_DATA_READ;
|
|
|
|
return mmc_send_cmd(mmc, &cmd, &data);
|
|
}
|
|
|
|
|
|
int sd_change_freq(struct mmc *mmc)
|
|
{
|
|
int err;
|
|
struct mmc_cmd cmd;
|
|
uint scr[2];
|
|
uint switch_status[16];
|
|
struct mmc_data data;
|
|
int timeout;
|
|
|
|
mmc->card_caps = 0;
|
|
|
|
if (mmc_host_is_spi(mmc))
|
|
return 0;
|
|
|
|
/* Read the SCR to find out if this card supports higher speeds */
|
|
cmd.cmdidx = MMC_CMD_APP_CMD;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.cmdarg = mmc->rca << 16;
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("Send app cmd failed\n");
|
|
return err;
|
|
}
|
|
|
|
cmd.cmdidx = SD_CMD_APP_SEND_SCR;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.cmdarg = 0;
|
|
cmd.flags = 0;
|
|
|
|
timeout = 3;
|
|
|
|
retry_scr:
|
|
data.dest = (char *)&scr;
|
|
data.blocksize = 8;
|
|
data.blocks = 1;
|
|
data.flags = MMC_DATA_READ;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, &data);
|
|
|
|
if (err) {
|
|
if (timeout--)
|
|
goto retry_scr;
|
|
|
|
MMCINFO("Send scr failed\n");
|
|
return err;
|
|
}
|
|
|
|
mmc->scr[0] = __be32_to_cpu(scr[0]);
|
|
mmc->scr[1] = __be32_to_cpu(scr[1]);
|
|
|
|
switch ((mmc->scr[0] >> 24) & 0xf) {
|
|
case 0:
|
|
mmc->version = SD_VERSION_1_0;
|
|
break;
|
|
case 1:
|
|
mmc->version = SD_VERSION_1_10;
|
|
break;
|
|
case 2:
|
|
mmc->version = SD_VERSION_2;
|
|
break;
|
|
default:
|
|
mmc->version = SD_VERSION_1_0;
|
|
break;
|
|
}
|
|
|
|
if (mmc->scr[0] & SD_DATA_4BIT)
|
|
mmc->card_caps |= MMC_MODE_4BIT;
|
|
|
|
/* Version 1.0 doesn't support switching */
|
|
if (mmc->version == SD_VERSION_1_0)
|
|
return 0;
|
|
|
|
timeout = 4;
|
|
while (timeout--) {
|
|
err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
|
|
(u8 *)&switch_status);
|
|
|
|
if (err){
|
|
MMCINFO("Check high speed status faild\n");
|
|
return err;
|
|
}
|
|
|
|
/* The high-speed function is busy. Try again */
|
|
if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
|
|
break;
|
|
}
|
|
|
|
/* If high-speed isn't supported, we return */
|
|
if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
|
|
return 0;
|
|
|
|
err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)&switch_status);
|
|
|
|
if (err){
|
|
MMCINFO("switch to high speed failed\n");
|
|
return err;
|
|
}
|
|
|
|
err = mmc_update_phase(mmc);
|
|
if (err)
|
|
{
|
|
MMCINFO("update clock failed\n");
|
|
return err;
|
|
}
|
|
|
|
if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
|
|
mmc->card_caps |= MMC_MODE_HS;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* frequency bases */
|
|
/* divided by 10 to be nice to platforms without floating point */
|
|
static const int fbase[] = {
|
|
10000,
|
|
100000,
|
|
1000000,
|
|
10000000,
|
|
};
|
|
|
|
/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
|
|
* to platforms without floating point.
|
|
*/
|
|
static const int multipliers[] = {
|
|
0, /* reserved */
|
|
10,
|
|
12,
|
|
13,
|
|
15,
|
|
20,
|
|
25,
|
|
30,
|
|
35,
|
|
40,
|
|
45,
|
|
50,
|
|
55,
|
|
60,
|
|
70,
|
|
80,
|
|
};
|
|
|
|
void mmc_set_ios(struct mmc *mmc)
|
|
{
|
|
mmc->set_ios(mmc);
|
|
}
|
|
|
|
|
|
|
|
void mmc_set_clock(struct mmc *mmc, uint clock)
|
|
{
|
|
if (clock > mmc->f_max)
|
|
clock = mmc->f_max;
|
|
|
|
if (clock < mmc->f_min)
|
|
clock = mmc->f_min;
|
|
|
|
mmc->clock = clock;
|
|
|
|
mmc_set_ios(mmc);
|
|
}
|
|
|
|
void mmc_set_bus_width(struct mmc *mmc, uint width)
|
|
{
|
|
mmc->bus_width = width;
|
|
|
|
mmc_set_ios(mmc);
|
|
}
|
|
|
|
int mmc_startup(struct mmc *mmc)
|
|
{
|
|
int err;
|
|
uint mult, freq;
|
|
u64 cmult, csize, capacity;
|
|
struct mmc_cmd cmd;
|
|
char ext_csd[512];
|
|
int timeout = 1000;
|
|
|
|
#ifdef CONFIG_MMC_SPI_CRC_ON
|
|
if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
|
|
cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.cmdarg = 1;
|
|
cmd.flags = 0;
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("Spi crc on off failed\n");
|
|
return err;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* Put the Card in Identify Mode */
|
|
cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
|
|
MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
|
|
cmd.resp_type = MMC_RSP_R2;
|
|
cmd.cmdarg = 0;
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("Put the Card in Identify Mode failed\n");
|
|
return err;
|
|
}
|
|
|
|
memcpy(mmc->cid, cmd.response, 16);
|
|
|
|
/*
|
|
* For MMC cards, set the Relative Address.
|
|
* For SD cards, get the Relatvie Address.
|
|
* This also puts the cards into Standby State
|
|
*/
|
|
if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
|
|
cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
|
|
cmd.cmdarg = mmc->rca << 16;
|
|
cmd.resp_type = MMC_RSP_R6;
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("send rca failed\n");
|
|
return err;
|
|
}
|
|
|
|
if (IS_SD(mmc))
|
|
mmc->rca = (cmd.response[0] >> 16) & 0xffff;
|
|
}
|
|
|
|
/* Get the Card-Specific Data */
|
|
cmd.cmdidx = MMC_CMD_SEND_CSD;
|
|
cmd.resp_type = MMC_RSP_R2;
|
|
cmd.cmdarg = mmc->rca << 16;
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
/* Waiting for the ready status */
|
|
mmc_send_status(mmc, timeout);
|
|
|
|
if (err){
|
|
MMCINFO("get csd failed\n");
|
|
return err;
|
|
}
|
|
|
|
mmc->csd[0] = cmd.response[0];
|
|
mmc->csd[1] = cmd.response[1];
|
|
mmc->csd[2] = cmd.response[2];
|
|
mmc->csd[3] = cmd.response[3];
|
|
|
|
if (mmc->version == MMC_VERSION_UNKNOWN) {
|
|
int version = (cmd.response[0] >> 26) & 0xf;
|
|
|
|
switch (version) {
|
|
case 0:
|
|
mmc->version = MMC_VERSION_1_2;
|
|
break;
|
|
case 1:
|
|
mmc->version = MMC_VERSION_1_4;
|
|
break;
|
|
case 2:
|
|
mmc->version = MMC_VERSION_2_2;
|
|
break;
|
|
case 3:
|
|
mmc->version = MMC_VERSION_3;
|
|
break;
|
|
case 4:
|
|
mmc->version = MMC_VERSION_4;
|
|
break;
|
|
default:
|
|
mmc->version = MMC_VERSION_1_2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* divide frequency by 10, since the mults are 10x bigger */
|
|
freq = fbase[(cmd.response[0] & 0x7)];
|
|
mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
|
|
|
|
mmc->tran_speed = freq * mult;
|
|
|
|
mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
|
|
|
|
if (IS_SD(mmc))
|
|
mmc->write_bl_len = mmc->read_bl_len;
|
|
else
|
|
mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
|
|
|
|
if (mmc->high_capacity) {
|
|
csize = (mmc->csd[1] & 0x3f) << 16
|
|
| (mmc->csd[2] & 0xffff0000) >> 16;
|
|
cmult = 8;
|
|
} else {
|
|
csize = (mmc->csd[1] & 0x3ff) << 2
|
|
| (mmc->csd[2] & 0xc0000000) >> 30;
|
|
cmult = (mmc->csd[2] & 0x00038000) >> 15;
|
|
}
|
|
|
|
mmc->capacity = (csize + 1) << (cmult + 2);
|
|
mmc->capacity *= mmc->read_bl_len;
|
|
|
|
if (mmc->read_bl_len > 512)
|
|
mmc->read_bl_len = 512;
|
|
|
|
if (mmc->write_bl_len > 512)
|
|
mmc->write_bl_len = 512;
|
|
|
|
/* Select the card, and put it into Transfer Mode */
|
|
if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
|
|
cmd.cmdidx = MMC_CMD_SELECT_CARD;
|
|
cmd.resp_type = MMC_RSP_R1b;
|
|
cmd.cmdarg = mmc->rca << 16;
|
|
cmd.flags = 0;
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("Select the card failed\n");
|
|
return err;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* For SD, its erase group is always one sector
|
|
*/
|
|
mmc->erase_grp_size = 1;
|
|
mmc->part_config = MMCPART_NOAVAILABLE;
|
|
if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
|
|
/* check ext_csd version and capacity */
|
|
err = mmc_send_ext_csd(mmc, ext_csd);
|
|
|
|
if(!err){
|
|
/* update mmc version */
|
|
switch (ext_csd[192]) {
|
|
case 0:
|
|
mmc->version = MMC_VERSION_4;
|
|
break;
|
|
case 1:
|
|
mmc->version = MMC_VERSION_4_1;
|
|
break;
|
|
case 2:
|
|
mmc->version = MMC_VERSION_4_2;
|
|
break;
|
|
case 3:
|
|
mmc->version = MMC_VERSION_4_3;
|
|
break;
|
|
case 5:
|
|
mmc->version = MMC_VERSION_4_41;
|
|
break;
|
|
case 6:
|
|
mmc->version = MMC_VERSION_4_5;
|
|
break;
|
|
case 7:
|
|
mmc->version = MMC_VERSION_5_0;
|
|
break;
|
|
case 8:
|
|
mmc->version = MMC_VERSION_5_1;
|
|
break;
|
|
default:
|
|
if (ext_csd[EXT_CSD_REV] > 8)
|
|
mmc->version = MMC_VERSION_NEW_VER;
|
|
else
|
|
MMCINFO("Invalid ext_csd revision %d\n", ext_csd[192]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if (!err & (ext_csd[192] >= 2)) {
|
|
/*
|
|
* According to the JEDEC Standard, the value of
|
|
* ext_csd's capacity is valid if the value is more
|
|
* than 2GB
|
|
*/
|
|
capacity = ext_csd[212] << 0 | ext_csd[213] << 8 |
|
|
ext_csd[214] << 16 | ext_csd[215] << 24;
|
|
capacity *= 512;
|
|
if ((capacity >> 20) > 2 * 1024)
|
|
mmc->capacity = capacity;
|
|
}
|
|
|
|
/*
|
|
* Get timeout value
|
|
*/
|
|
mmc_mmc_update_timeout(mmc);
|
|
|
|
/*
|
|
* Check whether GROUP_DEF is set, if yes, read out
|
|
* group size from ext_csd directly, or calculate
|
|
* the group size from the csd value.
|
|
*
|
|
* WJQ, 20141022
|
|
* take write block as the unit of erase group
|
|
*/
|
|
{
|
|
int erase_gsz, erase_gmul;
|
|
int def_erase_grp_size, hc_erase_gpr_size;
|
|
int hc_erase_timeout;
|
|
|
|
erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
|
|
erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
|
|
def_erase_grp_size = (erase_gsz + 1) * (erase_gmul + 1);
|
|
|
|
hc_erase_gpr_size = ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 512 * 1024;
|
|
hc_erase_gpr_size = hc_erase_gpr_size / mmc->write_bl_len;
|
|
|
|
hc_erase_timeout = 300 * ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
|
|
|
|
if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] && hc_erase_gpr_size && hc_erase_timeout)
|
|
mmc->erase_grp_size = hc_erase_gpr_size;
|
|
else
|
|
mmc->erase_grp_size = def_erase_grp_size;
|
|
}
|
|
|
|
mmc->secure_feature = ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
|
|
mmc->secure_removal_type = ext_csd[EXT_CSD_SECURE_REMOAL_TYPE];
|
|
|
|
/* store the partition info of emmc */
|
|
if (ext_csd[226])//ext_csd[160] & PART_SUPPORT
|
|
{
|
|
mmc->boot_support = 1;//lwj
|
|
mmc->part_support = ext_csd[160];
|
|
mmc->part_config = ext_csd[179];
|
|
mmc->boot1_lba = 128000*ext_csd[226]/512;
|
|
mmc->boot2_lba = 128000*ext_csd[226]/512;
|
|
mmc->boot_bus_cond = ext_csd[177];
|
|
|
|
MMCDBG("PART_SUPPORT mmc->boot1_lba = %d\n",mmc->boot1_lba);
|
|
}
|
|
else
|
|
{
|
|
MMCDBG("not PART_SUPPORT ext_csd[226] = %d\n",ext_csd[226]);
|
|
}
|
|
}
|
|
|
|
|
|
mmc_set_clock(mmc,25000000);
|
|
|
|
if (IS_SD(mmc))
|
|
err = sd_change_freq(mmc);
|
|
else
|
|
err = mmc_change_freq(mmc);
|
|
|
|
if (err){
|
|
MMCINFO("Change speed mode failed\n");
|
|
return err;
|
|
}
|
|
|
|
/* for re-update sample phase */
|
|
err = mmc_update_phase(mmc);
|
|
if (err)
|
|
{
|
|
MMCINFO("update clock failed\n");
|
|
return err;
|
|
}
|
|
|
|
/* Restrict card's capabilities by what the host can do */
|
|
mmc->card_caps &= mmc->host_caps;
|
|
|
|
if (IS_SD(mmc)) {
|
|
if (mmc->card_caps & MMC_MODE_4BIT) {
|
|
cmd.cmdidx = MMC_CMD_APP_CMD;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.cmdarg = mmc->rca << 16;
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
if (err){
|
|
MMCINFO("send app cmd failed\n");
|
|
return err;
|
|
}
|
|
|
|
cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
|
|
cmd.resp_type = MMC_RSP_R1;
|
|
cmd.cmdarg = 2;
|
|
cmd.flags = 0;
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
if (err){
|
|
MMCINFO("sd set bus width failed\n");
|
|
return err;
|
|
}
|
|
|
|
mmc_set_bus_width(mmc, 4);
|
|
}
|
|
|
|
if (mmc->card_caps & MMC_MODE_HS)
|
|
mmc_set_clock(mmc, 50000000);
|
|
else
|
|
mmc_set_clock(mmc, 25000000);
|
|
} else {
|
|
if (mmc->card_caps & MMC_MODE_8BIT) {
|
|
|
|
if( (mmc->card_caps & MMC_MODE_DDR_52MHz) ){
|
|
MMCINFO("ddr8 \n");
|
|
/* Set the card to use 8 bit ddr*/
|
|
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
|
|
EXT_CSD_BUS_WIDTH,
|
|
EXT_CSD_BUS_DDR_8);
|
|
if (err){
|
|
MMCINFO("mmc switch bus width failed\n");
|
|
return err;
|
|
}
|
|
mmc_set_bus_width(mmc, 8);
|
|
}else{
|
|
/* Set the card to use 8 bit*/
|
|
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
|
|
EXT_CSD_BUS_WIDTH,
|
|
EXT_CSD_BUS_WIDTH_8);
|
|
|
|
if (err){
|
|
MMCINFO("mmc switch bus width8 failed\n");
|
|
return err;
|
|
}
|
|
mmc_set_bus_width(mmc, 8);
|
|
}
|
|
|
|
}else if (mmc->card_caps & MMC_MODE_4BIT) {
|
|
if ( (mmc->card_caps & MMC_MODE_DDR_52MHz) ){
|
|
MMCINFO("ddr4 \n");
|
|
/* Set the card to use 4 bit ddr*/
|
|
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
|
|
EXT_CSD_BUS_WIDTH,
|
|
EXT_CSD_BUS_DDR_4);
|
|
if (err){
|
|
MMCINFO("mmc switch bus width failed\n");
|
|
return err;
|
|
}
|
|
mmc_set_bus_width(mmc, 4);
|
|
}else{
|
|
/* Set the card to use 4 bit*/
|
|
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
|
|
EXT_CSD_BUS_WIDTH,
|
|
EXT_CSD_BUS_WIDTH_4);
|
|
if (err){
|
|
MMCINFO("mmc switch bus width failed\n");
|
|
return err;
|
|
}
|
|
mmc_set_bus_width(mmc, 4);
|
|
}
|
|
}
|
|
|
|
if( (mmc->card_caps & MMC_MODE_DDR_52MHz) ){
|
|
mmc->io_mode = MMC_MODE_DDR_52MHz;
|
|
MMCDBG("mmc mmc->io_mode = %x\n",mmc->io_mode);
|
|
mmc_set_clock(mmc, 50000000);
|
|
}else if (mmc->card_caps & MMC_MODE_HS) {
|
|
if (mmc->card_caps & MMC_MODE_HS_52MHz)
|
|
mmc_set_clock(mmc, 52000000);
|
|
else
|
|
mmc_set_clock(mmc, 26000000);
|
|
} else{
|
|
mmc_set_clock(mmc, 20000000);
|
|
}
|
|
}
|
|
|
|
/* fill in device description */
|
|
mmc->block_dev.lun = 0;
|
|
mmc->block_dev.type = 0;
|
|
mmc->block_dev.blksz = mmc->read_bl_len;
|
|
mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
|
|
if (IS_SD(mmc)){
|
|
sprintf(mmc->block_dev.vendor, "MID %06x PSN %08x",
|
|
mmc->cid[0] >> 24, (mmc->cid[2] << 8) | (mmc->cid[3] >> 24));
|
|
sprintf(mmc->block_dev.product, "PNM %c%c%c%c%c", mmc->cid[0] & 0xff,
|
|
(mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
|
|
(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
|
|
sprintf(mmc->block_dev.revision, "PRV %d.%d", mmc->cid[2] >> 28,
|
|
(mmc->cid[2] >> 24) & 0xf);
|
|
} else {
|
|
sprintf(mmc->block_dev.vendor, "MID %06x PSN %04x%04x",
|
|
mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
|
|
(mmc->cid[3] >> 16) & 0xffff);
|
|
sprintf(mmc->block_dev.product, "PNM %c%c%c%c%c%c", mmc->cid[0] & 0xff,
|
|
(mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
|
|
(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
|
|
(mmc->cid[2] >> 24) & 0xff);
|
|
sprintf(mmc->block_dev.revision, "PRV %d.%d", (mmc->cid[2] >> 20) & 0xf,
|
|
(mmc->cid[2] >> 16) & 0xf);
|
|
}
|
|
|
|
MMCDBG("%s\n", mmc->block_dev.vendor);
|
|
MMCDBG("%s -- 0x%02x-%02x-%02x-%02x-%02x-%02x\n", mmc->block_dev.product,
|
|
mmc->cid[0] & 0xff, (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
|
|
(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
|
|
MMCDBG("%s\n", mmc->block_dev.revision);
|
|
|
|
if (IS_SD(mmc)){
|
|
MMCDBG("MDT m-%d y-%d\n", ((mmc->cid[3] >> 8) & 0xF), (((mmc->cid[3] >> 12) & 0xFF) + 2000));
|
|
} else {
|
|
if (ext_csd[192] > 4) {
|
|
MMCDBG("MDT m-%d y-%d\n", ((mmc->cid[3] >> 12) & 0xF),
|
|
(((mmc->cid[3] >> 8) & 0xF) < 13) ? (((mmc->cid[3] >> 8) & 0xF) + 2013) : (((mmc->cid[3] >> 8) & 0xF) + 1997));
|
|
} else {
|
|
MMCDBG("MDT m-%d y-%d\n", ((mmc->cid[3] >> 12) & 0xF), (((mmc->cid[3] >> 8) & 0xF) + 1997));
|
|
}
|
|
}
|
|
|
|
MMCINFO("CID 0x%x 0x%x 0x%x 0x%x\n",mmc->cid[0],mmc->cid[1],mmc->cid[2],mmc->cid[3]);
|
|
|
|
/*printf("---------------ext_csd[192] = %d--------------\n", ext_csd[192]);*/
|
|
if(!IS_SD(mmc)){
|
|
switch(mmc->version)
|
|
{
|
|
case MMC_VERSION_1_2:
|
|
MMCINFO("MMC ver 1.2\n");
|
|
break;
|
|
case MMC_VERSION_1_4:
|
|
MMCINFO("MMC ver 1.4\n");
|
|
break;
|
|
case MMC_VERSION_2_2:
|
|
MMCINFO("MMC ver 2.2\n");
|
|
break;
|
|
case MMC_VERSION_3:
|
|
MMCINFO("MMC ver 3.0\n");
|
|
break;
|
|
case MMC_VERSION_4:
|
|
MMCINFO("MMC ver 4.0\n");
|
|
break;
|
|
case MMC_VERSION_4_1:
|
|
MMCINFO("MMC ver 4.1\n");
|
|
break;
|
|
case MMC_VERSION_4_2:
|
|
MMCINFO("MMC ver 4.2\n");
|
|
break;
|
|
case MMC_VERSION_4_3:
|
|
MMCINFO("MMC ver 4.3\n");
|
|
break;
|
|
case MMC_VERSION_4_41:
|
|
MMCINFO("MMC ver 4.41\n");
|
|
break;
|
|
case MMC_VERSION_4_5:
|
|
MMCINFO("MMC ver 4.5\n");
|
|
break;
|
|
case MMC_VERSION_5_0:
|
|
MMCINFO("MMC ver 5.0\n");
|
|
break;
|
|
case MMC_VERSION_5_1:
|
|
MMCINFO("MMC v5.1\n");
|
|
break;
|
|
case MMC_VERSION_NEW_VER:
|
|
MMCINFO("MMC v5.2 or later version\n");
|
|
break;
|
|
default:
|
|
MMCINFO("Unknow MMC ver\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
mmc->clock_after_init = mmc->clock;/*back up clock after mmc init*/
|
|
if (!IS_SD(mmc)) {
|
|
if (mmc->drv_hwrst_feature & DRV_PARA_ENABLE_EMMC_HWRST) {
|
|
err = mmc_en_emmc_hw_rst(mmc);
|
|
if (err)
|
|
return err;
|
|
} else {
|
|
err = mmc_chk_emmc_hw_rst(mmc);
|
|
if (err)
|
|
return err;
|
|
}
|
|
}
|
|
|
|
MMCINFO("mmc clk %d\n", mmc->clock);
|
|
//MMCINFO("---mmc bus_width %d---\n", mmc->bus_width);
|
|
MMCINFO("SD/MMC Card: %dbit, capacity: %ldMB\n",(mmc->card_caps & MMC_MODE_8BIT)?8:(mmc->card_caps & MMC_MODE_4BIT ? 4 : 1), mmc->block_dev.lba>>11);
|
|
MMCINFO("boot0 capacity: %dKB,boot1 capacity: %dKB\n"
|
|
,mmc->boot1_lba*512/1024,mmc->boot2_lba*512/1024);
|
|
MMCINFO("***SD/MMC %d init OK!!!***\n", mmc->control_num);
|
|
//init_part(&mmc->block_dev);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int mmc_send_if_cond(struct mmc *mmc)
|
|
{
|
|
struct mmc_cmd cmd;
|
|
int err;
|
|
|
|
cmd.cmdidx = SD_CMD_SEND_IF_COND;
|
|
/* We set the bit if the host supports voltages between 2.7 and 3.6 V */
|
|
cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa;
|
|
cmd.resp_type = MMC_RSP_R7;
|
|
cmd.flags = 0;
|
|
|
|
err = mmc_send_cmd(mmc, &cmd, NULL);
|
|
|
|
if (err){
|
|
MMCINFO("mmc send if cond failed\n");
|
|
return err;
|
|
}
|
|
|
|
if ((cmd.response[0] & 0xff) != 0xaa)
|
|
return UNUSABLE_ERR;
|
|
else
|
|
mmc->version = SD_VERSION_2;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int mmc_register(struct mmc *mmc)
|
|
{
|
|
/* Setup the universal parts of the block interface just once */
|
|
mmc->block_dev.if_type = IF_TYPE_MMC;
|
|
//mmc->block_dev.dev = cur_dev_num++;
|
|
mmc->block_dev.dev = mmc->control_num;
|
|
mmc->block_dev.removable = 1;
|
|
//#if 0
|
|
#ifndef CONFIG_SUNXI_SECURE_STORAGE
|
|
mmc->block_dev.block_read = mmc_bread;
|
|
mmc->block_dev.block_write = mmc_bwrite;
|
|
mmc->block_dev.block_erase = mmc_berase;
|
|
mmc->block_dev.block_secure_wipe = mmc_secure_wipe;
|
|
mmc->block_dev.block_read_mass_pro = mmc_bread_mass_pro;
|
|
mmc->block_dev.block_write_mass_pro = mmc_bwrite_mass_pro;
|
|
//mmc->block_dev.block_erase_mass_pro = mmc_berase_mass_pro;
|
|
mmc->block_dev.block_read_secure = NULL;
|
|
mmc->block_dev.block_write_secure = NULL;
|
|
mmc->block_dev.block_get_item_secure= NULL;
|
|
|
|
mmc->block_dev.block_mmc_erase = mmc_mmc_erase;
|
|
mmc->block_dev.block_mmc_trim = mmc_mmc_trim;
|
|
mmc->block_dev.block_mmc_discard = mmc_mmc_discard;
|
|
mmc->block_dev.block_mmc_sanitize = mmc_mmc_sanitize;
|
|
mmc->block_dev.block_mmc_secure_erase = mmc_mmc_secure_erase;
|
|
mmc->block_dev.block_mmc_secure_trim = mmc_mmc_secure_trim;
|
|
#else
|
|
mmc->block_dev.block_read = mmc_bread_secure;
|
|
mmc->block_dev.block_write = mmc_bwrite_secure;
|
|
mmc->block_dev.block_erase = mmc_berase_secure;
|
|
mmc->block_dev.block_secure_wipe = mmc_secure_wipe_secure;
|
|
mmc->block_dev.block_read_mass_pro = mmc_bread_mass_pro_secure;
|
|
mmc->block_dev.block_write_mass_pro = mmc_bwrite_mass_pro_secure;
|
|
mmc->block_dev.block_read_secure = sdmmc_secure_storage_read;
|
|
mmc->block_dev.block_read_secure_backup = sdmmc_secure_storage_read_backup;
|
|
mmc->block_dev.block_write_secure = sdmmc_secure_storage_write;
|
|
mmc->block_dev.block_get_item_secure= get_sdmmc_secure_storage_max_item;
|
|
|
|
mmc->block_dev.block_mmc_erase = mmc_mmc_erase_secure;
|
|
mmc->block_dev.block_mmc_trim = mmc_mmc_trim_secure;
|
|
mmc->block_dev.block_mmc_discard = mmc_mmc_discard_secure;
|
|
mmc->block_dev.block_mmc_sanitize = mmc_mmc_sanitize_secure;
|
|
mmc->block_dev.block_mmc_secure_erase = mmc_mmc_secure_erase_secure;
|
|
mmc->block_dev.block_mmc_secure_trim = mmc_mmc_secure_trim_secure;
|
|
#endif
|
|
|
|
if (!mmc->b_max)
|
|
mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
|
|
|
|
INIT_LIST_HEAD (&mmc->link);
|
|
|
|
list_add_tail (&mmc->link, &mmc_devices);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int mmc_unregister(int sdc_no)
|
|
{
|
|
return 0;
|
|
}
|
|
#ifdef CONFIG_PARTITIONS
|
|
block_dev_desc_t *mmc_get_dev(int dev)
|
|
{
|
|
struct mmc *mmc = find_mmc_device(dev);
|
|
|
|
return mmc ? &mmc->block_dev : NULL;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
int sunxi_need_retry(struct mmc *mmc)
|
|
{
|
|
if(mmc->decide_retry && mmc->update_sdly){
|
|
uint sdly = 0;
|
|
int ret = 0;
|
|
ret = mmc->decide_retry(mmc,&sdly,0);
|
|
if(ret){
|
|
MMCINFO("need retry next dly %d,clk %d\n",sdly,mmc->clock);
|
|
mmc->update_sdly(mmc,sdly);
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
*/
|
|
int sunxi_need_rty(struct mmc *mmc)
|
|
{
|
|
if(mmc->decide_retry ){
|
|
int ret = 0;
|
|
u32 err_no = 0;
|
|
err_no = mmc->get_detail_errno(mmc);
|
|
ret = mmc->decide_retry(mmc,err_no,0);
|
|
if(!ret){
|
|
MMCINFO("need retry next clk %d\n",mmc->clock);
|
|
return 0;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const char tuning_blk_4b[TUNING_LEN*512] = {
|
|
/*hs200/uhs*/
|
|
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
|
|
0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
|
|
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
|
|
0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
|
|
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
|
|
0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
|
|
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
|
|
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
|
|
|
|
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
|
|
0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
|
|
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
|
|
0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
|
|
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
|
|
0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
|
|
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
|
|
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
|
|
|
|
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
|
|
0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
|
|
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
|
|
0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
|
|
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
|
|
0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
|
|
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
|
|
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
|
|
|
|
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
|
|
0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
|
|
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
|
|
0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
|
|
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
|
|
0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
|
|
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
|
|
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
|
|
|
|
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
|
|
0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
|
|
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
|
|
0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
|
|
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
|
|
0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
|
|
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
|
|
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
|
|
|
|
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
|
|
0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
|
|
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
|
|
0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
|
|
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
|
|
0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
|
|
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
|
|
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
|
|
|
|
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
|
|
0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
|
|
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
|
|
0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
|
|
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
|
|
0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
|
|
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
|
|
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
|
|
|
|
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
|
|
0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
|
|
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
|
|
0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
|
|
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
|
|
0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
|
|
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
|
|
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
|
|
|
|
/*0xf*/
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
/*0x1e*/
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
|
|
|
|
/*0x5a*/
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
|
|
|
|
/*wifi*/
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
/*0xf1*/
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
|
|
|
|
|
|
/*0xd2(change form 0xe1/0x1e)*/
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
|
|
|
|
/*0xb4(change form 0xe1/0x1e)*/
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
|
|
|
|
/*0x78(change form 0xe1/0x1e)*/
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
|
|
|
|
/*rand*/
|
|
0xe4, 0x4f, 0x76, 0xbb, 0xf0, 0xb7, 0xe0, 0xdb,
|
|
0xb9, 0x1f, 0x9f, 0xfb, 0x7e, 0x9b, 0x03, 0x7d,
|
|
0x2e, 0x32, 0x8f, 0x29, 0x7a, 0x9b, 0xab, 0x16,
|
|
0x2f, 0x44, 0x99, 0xce, 0xc3, 0x99, 0xaa, 0xad,
|
|
0x2d, 0x82, 0xb2, 0x8a, 0xfa, 0x2d, 0xb9, 0x9a,
|
|
0x9e, 0x0f, 0xf3, 0x90, 0x08, 0x25, 0xf3, 0x09,
|
|
0x79, 0x80, 0x1b, 0x28, 0x95, 0x00, 0x57, 0x7d,
|
|
0xbb, 0x60, 0x0b, 0x2c, 0x92, 0x72, 0x49, 0x4b,
|
|
0xe4, 0xac, 0x48, 0x8b, 0xb0, 0xe4, 0x11, 0x1b,
|
|
0x7a, 0x58, 0x7c, 0xc9, 0xe6, 0xf1, 0x5b, 0x6b,
|
|
0x85, 0xc9, 0xf5, 0x7d, 0xef, 0xea, 0xb6, 0x0b,
|
|
0x12, 0x59, 0x24, 0xd2, 0xc9, 0x53, 0x15, 0xa2,
|
|
0xb1, 0xd6, 0x1f, 0x06, 0x38, 0x63, 0x51, 0x27,
|
|
0xf6, 0x03, 0x20, 0xee, 0x41, 0x88, 0xa4, 0x69,
|
|
0xfb, 0x15, 0x05, 0x70, 0xaf, 0xe0, 0x30, 0x88,
|
|
0xdc, 0x37, 0xce, 0x07, 0x91, 0xc1, 0x76, 0x79,
|
|
0x3a, 0x07, 0x21, 0x43, 0xba, 0x32, 0xdf, 0x86,
|
|
0xba, 0x16, 0xc9, 0x46, 0x40, 0x70, 0x37, 0xcc,
|
|
0x83, 0x6c, 0x33, 0x48, 0xfe, 0x6b, 0x2d, 0xbb,
|
|
0xc3, 0x02, 0xf0, 0x14, 0x12, 0x46, 0xd4, 0x99,
|
|
0x2a, 0x47, 0x35, 0x89, 0x5f, 0xda, 0x25, 0x00,
|
|
0x6d, 0x9c, 0x5e, 0x1a, 0x0c, 0x33, 0x7a, 0x5b,
|
|
0xc4, 0xd7, 0x67, 0x4f, 0x03, 0x12, 0x15, 0x6d,
|
|
0x6d, 0xc3, 0x71, 0x41, 0x73, 0x69, 0x97, 0xcb,
|
|
0x27, 0x9e, 0x43, 0x22, 0x4e, 0xe2, 0x89, 0x5c,
|
|
0xb7, 0x9a, 0xc7, 0xb2, 0xcc, 0x58, 0xd7, 0xe0,
|
|
0x67, 0x5d, 0x89, 0xcb, 0xe7, 0x5d, 0x50, 0x66,
|
|
0x82, 0x82, 0x3b, 0xd6, 0xdd, 0xb3, 0x27, 0xd5,
|
|
0xd9, 0x15, 0x34, 0x54, 0xb0, 0xd2, 0x75, 0x64,
|
|
0x42, 0x1a, 0xec, 0x56, 0xa9, 0x68, 0xb5, 0x21,
|
|
0x13, 0x07, 0x81, 0x05, 0xd1, 0xd4, 0x46, 0x6e,
|
|
0xab, 0x45, 0x35, 0x1b, 0x77, 0xaa, 0xed, 0x7f,
|
|
0xea, 0xb3, 0xee, 0x68, 0xad, 0x33, 0x50, 0xde,
|
|
0xb3, 0x23, 0xb5, 0x4e, 0xcb, 0xea, 0x7c, 0xe8,
|
|
0x71, 0xdc, 0x37, 0x45, 0xea, 0x00, 0x5f, 0x4d,
|
|
0x90, 0x16, 0x47, 0x58, 0x6a, 0xd8, 0x4f, 0x93,
|
|
0xff, 0x81, 0x5a, 0xa6, 0x6c, 0x8c, 0x82, 0x93,
|
|
0xb5, 0xbe, 0x0a, 0xe1, 0x59, 0x66, 0x93, 0xfb,
|
|
0x29, 0xe4, 0x93, 0xd3, 0x59, 0x68, 0x04, 0xca,
|
|
0xd8, 0xfc, 0x59, 0xd4, 0xdd, 0xc5, 0xb6, 0xd7,
|
|
0xc3, 0x85, 0x60, 0x55, 0x16, 0x65, 0x73, 0x4b,
|
|
0xee, 0xf2, 0xd3, 0x59, 0x7b, 0x65, 0x64, 0x22,
|
|
0xe2, 0x27, 0x7e, 0xf6, 0x47, 0x94, 0x9b, 0xaf,
|
|
0x2b, 0x00, 0x53, 0xd8, 0xf9, 0xf7, 0x8b, 0x15,
|
|
0xdb, 0xc9, 0xe9, 0xbe, 0xd2, 0x46, 0x8b, 0xce,
|
|
0x06, 0xc7, 0xf8, 0xfc, 0x5b, 0x6e, 0x56, 0x27,
|
|
0x44, 0xae, 0xde, 0xf7, 0xdc, 0x0d, 0x8e, 0xc2,
|
|
0x33, 0x28, 0x1d, 0xac, 0xe5, 0xf8, 0x34, 0x13,
|
|
0xf2, 0x55, 0xdb, 0x2a, 0xc9, 0xb8, 0x32, 0xe3,
|
|
0xa6, 0x45, 0x61, 0x13, 0x1e, 0x09, 0xd1, 0xd1,
|
|
0xf9, 0x80, 0x9d, 0x1e, 0x3f, 0x5a, 0x43, 0xcc,
|
|
0x95, 0x7e, 0xa0, 0x98, 0xca, 0x50, 0x1b, 0x9a,
|
|
0xae, 0x2f, 0x20, 0xdf, 0x23, 0x42, 0xd0, 0x54,
|
|
0x76, 0x75, 0xf6, 0xe5, 0xef, 0xbe, 0x3d, 0xe7,
|
|
0xa6, 0xa5, 0xa1, 0xb3, 0x99, 0x03, 0x24, 0x94,
|
|
0xfc, 0x0a, 0xc2, 0xe4, 0xd0, 0x85, 0xa6, 0x71,
|
|
0xb7, 0x61, 0x9e, 0x26, 0x07, 0x6d, 0xcd, 0xe7,
|
|
0x1d, 0x5e, 0xa0, 0xbc, 0xf4, 0x16, 0x03, 0x32,
|
|
0xf6, 0x26, 0xd4, 0xfe, 0x11, 0x91, 0x97, 0xe4,
|
|
0x0e, 0xd3, 0x6c, 0xd7, 0x1e, 0x21, 0x3f, 0x62,
|
|
0xb6, 0xf3, 0x3f, 0x46, 0x9d, 0xc0, 0x91, 0x65,
|
|
0x44, 0x08, 0x45, 0xde, 0x55, 0x98, 0x89, 0x7a,
|
|
0x8e, 0x0a, 0x1c, 0x47, 0xd0, 0x8b, 0x06, 0x82,
|
|
0x73, 0xe1, 0x87, 0xba, 0xdd, 0xac, 0x4d, 0x33,
|
|
|
|
|
|
};
|
|
|
|
static const char tuning_blk_8b[TUNING_LEN*512] = {
|
|
/*hs200/uhs*/
|
|
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
|
|
0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
|
|
0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
|
|
0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
|
|
0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
|
|
0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
|
|
0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
|
|
0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
|
|
0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
|
|
0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
|
|
0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
|
|
0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
|
|
0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
|
|
0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
|
|
0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
|
|
0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
|
|
|
|
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
|
|
0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
|
|
0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
|
|
0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
|
|
0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
|
|
0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
|
|
0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
|
|
0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
|
|
0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
|
|
0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
|
|
0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
|
|
0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
|
|
0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
|
|
0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
|
|
0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
|
|
0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
|
|
|
|
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
|
|
0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
|
|
0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
|
|
0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
|
|
0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
|
|
0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
|
|
0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
|
|
0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
|
|
0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
|
|
0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
|
|
0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
|
|
0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
|
|
0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
|
|
0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
|
|
0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
|
|
0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
|
|
|
|
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
|
|
0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
|
|
0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
|
|
0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
|
|
0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
|
|
0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
|
|
0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
|
|
0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
|
|
0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
|
|
0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
|
|
0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
|
|
0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
|
|
0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
|
|
0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
|
|
0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
|
|
0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
|
|
|
|
/*0xf*/
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
|
|
|
|
/*0x1e*/
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE,
|
|
|
|
/*0x5a*/
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
|
|
|
/*wifi*/
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x18,
|
|
0xc5, 0x00, 0x10, 0x18, 0x01, 0x12, 0xf8, 0x4b,
|
|
0x11, 0x42, 0x00, 0x19, 0x03, 0x01, 0x00, 0x00,
|
|
0x05, 0x10, 0x00, 0x18, 0xc5, 0x10, 0x10, 0x18,
|
|
0x30, 0x43, 0x04, 0x16, 0x00, 0x90, 0x10, 0x18,
|
|
0x01, 0x00, 0xf8, 0x4b, 0x11, 0x42, 0x00, 0x27,
|
|
|
|
/*0xf1*/
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01,
|
|
|
|
/*0xd2(change form 0xe1/0x1e)*/
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02,
|
|
|
|
/*0xb4(change form 0xe1/0x1e)*/
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04,
|
|
|
|
|
|
/*0x78(change form 0xe1/0x1e)*/
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80, 0x7F, 0x80,
|
|
|
|
/*rand*/
|
|
0xe4, 0x4f, 0x76, 0xbb, 0xf0, 0xb7, 0xe0, 0xdb,
|
|
0xb9, 0x1f, 0x9f, 0xfb, 0x7e, 0x9b, 0x03, 0x7d,
|
|
0x2e, 0x32, 0x8f, 0x29, 0x7a, 0x9b, 0xab, 0x16,
|
|
0x2f, 0x44, 0x99, 0xce, 0xc3, 0x99, 0xaa, 0xad,
|
|
0x2d, 0x82, 0xb2, 0x8a, 0xfa, 0x2d, 0xb9, 0x9a,
|
|
0x9e, 0x0f, 0xf3, 0x90, 0x08, 0x25, 0xf3, 0x09,
|
|
0x79, 0x80, 0x1b, 0x28, 0x95, 0x00, 0x57, 0x7d,
|
|
0xbb, 0x60, 0x0b, 0x2c, 0x92, 0x72, 0x49, 0x4b,
|
|
0xe4, 0xac, 0x48, 0x8b, 0xb0, 0xe4, 0x11, 0x1b,
|
|
0x7a, 0x58, 0x7c, 0xc9, 0xe6, 0xf1, 0x5b, 0x6b,
|
|
0x85, 0xc9, 0xf5, 0x7d, 0xef, 0xea, 0xb6, 0x0b,
|
|
0x12, 0x59, 0x24, 0xd2, 0xc9, 0x53, 0x15, 0xa2,
|
|
0xb1, 0xd6, 0x1f, 0x06, 0x38, 0x63, 0x51, 0x27,
|
|
0xf6, 0x03, 0x20, 0xee, 0x41, 0x88, 0xa4, 0x69,
|
|
0xfb, 0x15, 0x05, 0x70, 0xaf, 0xe0, 0x30, 0x88,
|
|
0xdc, 0x37, 0xce, 0x07, 0x91, 0xc1, 0x76, 0x79,
|
|
0x3a, 0x07, 0x21, 0x43, 0xba, 0x32, 0xdf, 0x86,
|
|
0xba, 0x16, 0xc9, 0x46, 0x40, 0x70, 0x37, 0xcc,
|
|
0x83, 0x6c, 0x33, 0x48, 0xfe, 0x6b, 0x2d, 0xbb,
|
|
0xc3, 0x02, 0xf0, 0x14, 0x12, 0x46, 0xd4, 0x99,
|
|
0x2a, 0x47, 0x35, 0x89, 0x5f, 0xda, 0x25, 0x00,
|
|
0x6d, 0x9c, 0x5e, 0x1a, 0x0c, 0x33, 0x7a, 0x5b,
|
|
0xc4, 0xd7, 0x67, 0x4f, 0x03, 0x12, 0x15, 0x6d,
|
|
0x6d, 0xc3, 0x71, 0x41, 0x73, 0x69, 0x97, 0xcb,
|
|
0x27, 0x9e, 0x43, 0x22, 0x4e, 0xe2, 0x89, 0x5c,
|
|
0xb7, 0x9a, 0xc7, 0xb2, 0xcc, 0x58, 0xd7, 0xe0,
|
|
0x67, 0x5d, 0x89, 0xcb, 0xe7, 0x5d, 0x50, 0x66,
|
|
0x82, 0x82, 0x3b, 0xd6, 0xdd, 0xb3, 0x27, 0xd5,
|
|
0xd9, 0x15, 0x34, 0x54, 0xb0, 0xd2, 0x75, 0x64,
|
|
0x42, 0x1a, 0xec, 0x56, 0xa9, 0x68, 0xb5, 0x21,
|
|
0x13, 0x07, 0x81, 0x05, 0xd1, 0xd4, 0x46, 0x6e,
|
|
0xab, 0x45, 0x35, 0x1b, 0x77, 0xaa, 0xed, 0x7f,
|
|
0xea, 0xb3, 0xee, 0x68, 0xad, 0x33, 0x50, 0xde,
|
|
0xb3, 0x23, 0xb5, 0x4e, 0xcb, 0xea, 0x7c, 0xe8,
|
|
0x71, 0xdc, 0x37, 0x45, 0xea, 0x00, 0x5f, 0x4d,
|
|
0x90, 0x16, 0x47, 0x58, 0x6a, 0xd8, 0x4f, 0x93,
|
|
0xff, 0x81, 0x5a, 0xa6, 0x6c, 0x8c, 0x82, 0x93,
|
|
0xb5, 0xbe, 0x0a, 0xe1, 0x59, 0x66, 0x93, 0xfb,
|
|
0x29, 0xe4, 0x93, 0xd3, 0x59, 0x68, 0x04, 0xca,
|
|
0xd8, 0xfc, 0x59, 0xd4, 0xdd, 0xc5, 0xb6, 0xd7,
|
|
0xc3, 0x85, 0x60, 0x55, 0x16, 0x65, 0x73, 0x4b,
|
|
0xee, 0xf2, 0xd3, 0x59, 0x7b, 0x65, 0x64, 0x22,
|
|
0xe2, 0x27, 0x7e, 0xf6, 0x47, 0x94, 0x9b, 0xaf,
|
|
0x2b, 0x00, 0x53, 0xd8, 0xf9, 0xf7, 0x8b, 0x15,
|
|
0xdb, 0xc9, 0xe9, 0xbe, 0xd2, 0x46, 0x8b, 0xce,
|
|
0x06, 0xc7, 0xf8, 0xfc, 0x5b, 0x6e, 0x56, 0x27,
|
|
0x44, 0xae, 0xde, 0xf7, 0xdc, 0x0d, 0x8e, 0xc2,
|
|
0x33, 0x28, 0x1d, 0xac, 0xe5, 0xf8, 0x34, 0x13,
|
|
0xf2, 0x55, 0xdb, 0x2a, 0xc9, 0xb8, 0x32, 0xe3,
|
|
0xa6, 0x45, 0x61, 0x13, 0x1e, 0x09, 0xd1, 0xd1,
|
|
0xf9, 0x80, 0x9d, 0x1e, 0x3f, 0x5a, 0x43, 0xcc,
|
|
0x95, 0x7e, 0xa0, 0x98, 0xca, 0x50, 0x1b, 0x9a,
|
|
0xae, 0x2f, 0x20, 0xdf, 0x23, 0x42, 0xd0, 0x54,
|
|
0x76, 0x75, 0xf6, 0xe5, 0xef, 0xbe, 0x3d, 0xe7,
|
|
0xa6, 0xa5, 0xa1, 0xb3, 0x99, 0x03, 0x24, 0x94,
|
|
0xfc, 0x0a, 0xc2, 0xe4, 0xd0, 0x85, 0xa6, 0x71,
|
|
0xb7, 0x61, 0x9e, 0x26, 0x07, 0x6d, 0xcd, 0xe7,
|
|
0x1d, 0x5e, 0xa0, 0xbc, 0xf4, 0x16, 0x03, 0x32,
|
|
0xf6, 0x26, 0xd4, 0xfe, 0x11, 0x91, 0x97, 0xe4,
|
|
0x0e, 0xd3, 0x6c, 0xd7, 0x1e, 0x21, 0x3f, 0x62,
|
|
0xb6, 0xf3, 0x3f, 0x46, 0x9d, 0xc0, 0x91, 0x65,
|
|
0x44, 0x08, 0x45, 0xde, 0x55, 0x98, 0x89, 0x7a,
|
|
0x8e, 0x0a, 0x1c, 0x47, 0xd0, 0x8b, 0x06, 0x82,
|
|
0x73, 0xe1, 0x87, 0xba, 0xdd, 0xac, 0x4d, 0x33,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
#define isascii(c) (((unsigned char)(c))<=0x7f)
|
|
#define isprint(c) ((((unsigned char)(c))>=32 && ((unsigned char)(c))<=126) \
|
|
|| (((unsigned char)(c))>=160 && ((unsigned char)(c))<=255))
|
|
|
|
|
|
#define DBG_DUMP_BUF_LEN (128)
|
|
#define MAX_DUMP_PER_LINE (16)
|
|
#define MAX_DUMP_PER_LINE_HALF (MAX_DUMP_PER_LINE >> 1)
|
|
void hexdump(char *prompt, char *buf, int len)
|
|
{
|
|
int i, j;
|
|
int head = 0;
|
|
|
|
printf("Dump (%s): len %d\n", prompt, len);
|
|
for (i = 0; i < len;) {
|
|
if (i % MAX_DUMP_PER_LINE == 0) {
|
|
printf("%08x ", i);
|
|
head = i;
|
|
}
|
|
printf("%02x ", buf[i]&0xff);
|
|
if (i % MAX_DUMP_PER_LINE == MAX_DUMP_PER_LINE_HALF-1)
|
|
printf(" ");
|
|
if (i % MAX_DUMP_PER_LINE == MAX_DUMP_PER_LINE-1
|
|
|| i==len-1) {
|
|
for (j=i-head+1; j<MAX_DUMP_PER_LINE; j++)
|
|
printf(" ");
|
|
printf(" |");
|
|
for (j=head; j<=i; j++) {
|
|
if (isascii(buf[j]) && isprint(buf[j]))
|
|
printf("%c", buf[j]);
|
|
else
|
|
printf(".");
|
|
}
|
|
printf("|\n");
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
|
|
s16 aw_rand(s32 *seed)
|
|
{
|
|
s32 RandMax = 0x7fff;
|
|
s32 tmp;
|
|
|
|
tmp = (*seed) * 0x000343FD;
|
|
tmp+= 0x00269EC3;
|
|
*seed = tmp;
|
|
tmp >>= 16;
|
|
tmp &= RandMax;
|
|
return (s16)tmp;
|
|
}
|
|
|
|
|
|
void print_rand(void)
|
|
{
|
|
int i =0;
|
|
int seed = 0x55aa;
|
|
char rand[512]={0};
|
|
for(i=0;i<512;i++){
|
|
rand[i]=aw_rand(&seed);
|
|
}
|
|
hexdump("rand data", (void*)rand, 512);
|
|
}
|
|
*/
|
|
|
|
|
|
static int write_tuning_try_freq(struct mmc *mmc,u32 clk)
|
|
{
|
|
int ret = 0;
|
|
const char *std_pattern = NULL;
|
|
char *rcv_pattern = malloc(TUNING_LEN*512);
|
|
u32 err_no = 0;
|
|
if(rcv_pattern == NULL){
|
|
return -1;
|
|
}
|
|
if(mmc->bus_width == 4){
|
|
std_pattern = tuning_blk_4b;
|
|
}else if(mmc->bus_width == 8){
|
|
std_pattern = tuning_blk_8b;
|
|
}else if(mmc->bus_width == 1){
|
|
MMCINFO("Not support 1 bit tuning now\n");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
|
|
do{
|
|
mmc_set_clock(mmc, clk);
|
|
ret = mmc_bwrite(mmc->control_num,
|
|
TUNING_ADD,
|
|
TUNING_LEN,
|
|
std_pattern);
|
|
MMCDBG("Write pattern ret = %d\n",ret);
|
|
if(ret != TUNING_LEN){//failed
|
|
MMCINFO(" write failed\n");
|
|
err_no = mmc->get_detail_errno(mmc);
|
|
//if write failed and block len>1,send stop for next try
|
|
//no care if it is successed
|
|
if(TUNING_LEN>1){
|
|
MMCINFO(" Send stop\n");
|
|
mmc_send_manual_stop(mmc);
|
|
}
|
|
}else{//ok
|
|
MMCINFO(" write ok\n");
|
|
//read pattern and compare with the pattern show sent
|
|
ret = mmc_bread(mmc->control_num,
|
|
TUNING_ADD,
|
|
TUNING_LEN,
|
|
rcv_pattern);
|
|
if(ret != TUNING_LEN){
|
|
MMCINFO(" read failed\n");
|
|
err_no = mmc->get_detail_errno(mmc);
|
|
//if read failedand block len>1,send stop for next try
|
|
//no care if it is successed
|
|
if(TUNING_LEN>1){
|
|
MMCINFO(" Send stop\n");
|
|
mmc_send_manual_stop(mmc);
|
|
}
|
|
}else{
|
|
ret = memcmp(std_pattern, rcv_pattern, TUNING_LEN*512);
|
|
if(ret){
|
|
MMCINFO(" pattern compare fail\n");
|
|
err_no = 0xffffffff;//force retry
|
|
}else{
|
|
MMCINFO(" Pattern compare ok\n");
|
|
MMCINFO(" Write tuning pattern ok\n");
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
}while(!mmc->decide_retry(mmc,err_no,0));
|
|
MMCINFO(" Write tuning pattern failded\n");
|
|
ret = -1;
|
|
|
|
out:
|
|
free(rcv_pattern);
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sunxi_write_tuning(struct mmc *mmc)
|
|
{
|
|
u32 freqs[] = { 400000, 25*1000*1000, 50*1000*1000};
|
|
int i = 0;
|
|
int ret = -1;
|
|
int clk_bak = mmc->clock;
|
|
|
|
if(mmc->decide_retry==NULL){
|
|
MMCINFO("NO support tuning\n");
|
|
return 0;
|
|
}
|
|
|
|
//reset rety count
|
|
mmc->decide_retry(mmc,0,1);
|
|
for(i=0;i<sizeof(freqs)/sizeof(freqs[0]);i++){
|
|
ret = write_tuning_try_freq(mmc,freqs[i]);
|
|
if(!ret){
|
|
//recover the clock before wiite patten
|
|
mmc_set_clock(mmc, clk_bak);
|
|
return ret;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
static ulong sunxi_read_tuning(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
|
|
{
|
|
lbaint_t cur, blocks_todo = blkcnt;
|
|
|
|
if (blkcnt == 0){
|
|
MMCINFO("blkcnt should not be 0\n");
|
|
return 0;
|
|
}
|
|
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
if (!mmc){
|
|
MMCINFO("Can not find mmc dev\n");
|
|
return 0;
|
|
}
|
|
|
|
if ((start + blkcnt) > mmc->block_dev.lba) {
|
|
MMCINFO("MMC: block number 0x%lx exceeds max(0x%lx)\n",
|
|
start + blkcnt, mmc->block_dev.lba);
|
|
return 0;
|
|
}
|
|
|
|
if (mmc_set_blocklen(mmc, mmc->read_bl_len)){
|
|
MMCINFO("Set block len failed\n");
|
|
return 0;
|
|
}
|
|
|
|
do {
|
|
cur =1;//force to read 1 block a time
|
|
if(mmc_read_blocks(mmc, dst, start, cur) != cur){
|
|
MMCINFO("block read failed\n");
|
|
return 0;
|
|
}
|
|
blocks_todo -= cur;
|
|
start += cur;
|
|
dst = (char*)dst + cur * mmc->read_bl_len;
|
|
} while (blocks_todo > 0);
|
|
|
|
return blkcnt;
|
|
}
|
|
|
|
|
|
|
|
|
|
static int sunxi_get_sdly_win(struct mmc *mmc,int start_in,
|
|
int end_in,int *start_out,
|
|
int *end_out,s8 *sdly,
|
|
const char *std_pat,
|
|
int repeat_times)
|
|
{
|
|
int i = 0;
|
|
int j = 0;
|
|
int ret = 0;
|
|
char *rcv_pat = malloc(TUNING_LEN*512);
|
|
|
|
if(rcv_pat == NULL){
|
|
MMCINFO(" malloc mem failed\n");
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
|
|
if((start_in>end_in)
|
|
||(start_out==NULL)
|
|
||(end_out==NULL)
|
|
||(std_pat==NULL)){
|
|
MMCINFO("Input parameter error\n");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
/*
|
|
tick_printf("[mmc]:*************************Try delay win[");
|
|
for(i=start_in;i<=end_in;i++){
|
|
printf("%d",sdly[i]);
|
|
}
|
|
printf("]*************************\n");
|
|
*/
|
|
|
|
|
|
/**********find start point************/
|
|
for(i=start_in;i<=end_in;i++){
|
|
//read pattern and compare with the pattern show sent
|
|
mmc->update_sdly(mmc,sdly[i]);//update sdly
|
|
mmc_set_clock(mmc, mmc->clock);//make sdly efficiency
|
|
for(j=0;j<repeat_times;j++){
|
|
ret = sunxi_read_tuning(mmc->control_num,
|
|
TUNING_ADD,
|
|
TUNING_LEN,
|
|
rcv_pat);
|
|
if(ret != TUNING_LEN){
|
|
MMCINFO(" read failed\n");
|
|
//if read failedand block len>1,send stop for next try
|
|
//no care if it is successed
|
|
//if(TUNING_LEN>1){
|
|
// MMCINFO(" Send stop\n");
|
|
// mmc_send_manual_stop(mmc);
|
|
//}
|
|
break;
|
|
}
|
|
ret = memcmp(std_pat, rcv_pat, TUNING_LEN*512);
|
|
if(ret){
|
|
MMCINFO(" pattern compare fail\n");
|
|
break;
|
|
}
|
|
|
|
MMCDBG(" Pattern compare ok in sample ponit %d\n",sdly[i]);
|
|
}
|
|
if(j>=repeat_times){
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(i>end_in){
|
|
//MMCINFO("Can not find sample point between %d-%d\n",sdly[start_in],sdly[end_in]);
|
|
tick_printf("[mmc]:Can not find sample point between [");
|
|
for(i=start_in;i<=end_in;i++){
|
|
printf("%d",sdly[i]);
|
|
}
|
|
printf("]\n");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
*start_out = i;
|
|
|
|
/**********find end point************/
|
|
for(i++;i<=end_in;i++){
|
|
//read pattern and compare with the pattern show sent
|
|
mmc->update_sdly(mmc,sdly[i]);//update sdly
|
|
mmc_set_clock(mmc, mmc->clock);//make sdly efficiency
|
|
for(j=0;j<repeat_times;j++){
|
|
ret = sunxi_read_tuning(mmc->control_num,
|
|
TUNING_ADD,
|
|
TUNING_LEN,
|
|
rcv_pat);
|
|
if(ret != TUNING_LEN){
|
|
MMCINFO(" read failed\n");
|
|
//if read failedand block len>1,send stop for next try
|
|
//no care if it is successed
|
|
//if(TUNING_LEN>1){
|
|
// MMCINFO(" Send stop\n");
|
|
// mmc_send_manual_stop(mmc);
|
|
//}
|
|
break;
|
|
}
|
|
|
|
ret = memcmp(std_pat, rcv_pat, TUNING_LEN*512);
|
|
if(ret){
|
|
MMCINFO(" pattern compare fail\n");
|
|
break;
|
|
}
|
|
MMCDBG(" Pattern compare ok in sample ponit %d\n",sdly[i]);
|
|
}
|
|
if(j<repeat_times){
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if(i>end_in){
|
|
*end_out = end_in;
|
|
}else{
|
|
*end_out = i-1;
|
|
}
|
|
|
|
tick_printf("[mmc]:*************************delay win[");
|
|
for(i=*start_out;i<=*end_out;i++){
|
|
printf("%d",sdly[i]);
|
|
}
|
|
printf("]*************************\n");
|
|
ret = 0;
|
|
|
|
out:
|
|
free(rcv_pat);
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void calc_real_dly(u32 pll_clk,u32 clk,s8 *real_delay)
|
|
{
|
|
int i = 0;
|
|
char sple_dly_real[8] ={1,2,3,4,5,6,7,0};
|
|
u32 delay0 = 0;
|
|
char sple_win_str[9] = {0};
|
|
|
|
/**********calc readlly delay 0**************/
|
|
/*calc really delay 0*/
|
|
|
|
delay0 = pll_clk/clk/2;
|
|
MMCDBG("delay0: %d, sclk %d,card clk %d\n",delay0,pll_clk,clk);
|
|
for(i=0;i<7;i++){
|
|
if(delay0<= sple_dly_real[i]){
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(i<7){
|
|
memmove(sple_dly_real+i+1,sple_dly_real+i,7-i);
|
|
sple_dly_real[i] = 0;
|
|
}
|
|
|
|
for(i = 0;i<=7;i++){
|
|
sprintf(sple_win_str+i,"%d",sple_dly_real[i]);
|
|
}
|
|
MMCINFO("real sample win [%s]\n",sple_win_str);
|
|
memcpy(real_delay,sple_dly_real,8);
|
|
/**********calc readlly delay 0 end**************/
|
|
}
|
|
|
|
|
|
|
|
static int sunxi_exe_tuning(struct mmc *mmc)
|
|
{
|
|
int ret = 0;
|
|
int i = 0;
|
|
const char *std_pat = NULL;
|
|
s8 sple_dly_real[8] ={1,2,3,4,5,6,7,0};
|
|
|
|
s32 sple_start0 = 0;
|
|
s32 sple_end0 = 0;
|
|
u32 win0 = 0;
|
|
|
|
s32 sple_start1 = 0;
|
|
s32 sple_end1 = 0;
|
|
u32 win1 = 0;
|
|
//u32 f_max_bak = 0;
|
|
|
|
|
|
u32 tuning_freqs[] = {52*1000*1000,26*1000*1000};
|
|
s32 tuning_times = 0;
|
|
int suit_sdly = 0;
|
|
|
|
//decide tuning freq and times
|
|
if (IS_SD(mmc)) {
|
|
if (mmc->card_caps & MMC_MODE_HS){
|
|
tuning_freqs[1]= 25000000;
|
|
tuning_freqs[0]= 50000000;
|
|
tuning_times = 2;
|
|
}else{
|
|
tuning_freqs[0]= 25000000;
|
|
tuning_times = 1;
|
|
}
|
|
} else {
|
|
if (mmc->card_caps & MMC_MODE_HS) {
|
|
if (mmc->card_caps & MMC_MODE_HS_52MHz){
|
|
tuning_freqs[1]= 26000000;
|
|
tuning_freqs[0]= 52000000;
|
|
tuning_times = 2;
|
|
}else{
|
|
tuning_freqs[0]= 26000000;
|
|
tuning_times = 1;
|
|
}
|
|
} else{
|
|
tuning_freqs[0]= 20000000;
|
|
tuning_times = 1;
|
|
}
|
|
}
|
|
|
|
if(mmc->update_sdly==NULL){
|
|
MMCINFO("update_sdly not implement\n");
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
if(mmc->bus_width == 4){
|
|
std_pat = tuning_blk_4b;
|
|
}else if(mmc->bus_width == 8){
|
|
std_pat = tuning_blk_8b;
|
|
}else if(mmc->bus_width == 1){
|
|
MMCINFO("Not support 1 bit tuning now\n");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
//f_max_bak = mmc->f_max;
|
|
//mmc->f_max = 100*1000*1000;
|
|
|
|
//for(i=0;i<sizeof(tuning_freqs)/sizeof(tuning_freqs[0]);i++){
|
|
for(i=0;i<tuning_times;i++){
|
|
MMCDBG("**************************Start tuning in freq %d**************************\n",tuning_freqs[i]);
|
|
mmc_set_clock(mmc, tuning_freqs[i]);
|
|
calc_real_dly(mmc->pll_clock,mmc->clock,sple_dly_real);
|
|
ret = sunxi_get_sdly_win(mmc,0,7,&sple_start0,&sple_end0,sple_dly_real,std_pat,REPEAT_TIMES);
|
|
if(ret){
|
|
MMCDBG("Can not find sample point in win0\n");
|
|
MMCINFO("**************Failed to find sample point in freq %d(%d)**************\n",tuning_freqs[i],mmc->clock);
|
|
win0 = 0;
|
|
//continue;
|
|
//if we can not find sample point, we assume that there is something wrong not related to sample point
|
|
ret = -1;
|
|
goto out;
|
|
}else{
|
|
MMCDBG("find sample point in win0\n");
|
|
if(sple_end0==sple_start0){
|
|
win0 = 1;
|
|
}else{
|
|
win0 = sple_end0-sple_start0+1;
|
|
}
|
|
}
|
|
|
|
ret = sunxi_get_sdly_win(mmc,sple_end0+2,7,&sple_start1,&sple_end1,sple_dly_real,std_pat,REPEAT_TIMES);
|
|
if(ret){
|
|
MMCDBG("Can not find sample point in win1\n");
|
|
win1 =0;
|
|
}else{
|
|
MMCDBG("find sample point in win1\n");
|
|
if(sple_end1==sple_start1){
|
|
win1 = 1;
|
|
}else{
|
|
win1 = sple_end1-sple_start1+1;
|
|
}
|
|
}
|
|
|
|
if(win0>win1){
|
|
suit_sdly = sple_start0+(win0)/2;
|
|
}else{
|
|
suit_sdly = sple_start1+(win1)/2;
|
|
}
|
|
|
|
MMCINFO("!!!!!!!!!!!!Find suitable sample point %d in freq %d(%d)!!!!!!!!!!!!\n",sple_dly_real[suit_sdly],tuning_freqs[i],mmc->clock);
|
|
|
|
if(tuning_freqs[i]<=26000000){
|
|
mmc->sdly_tuning.sdly_25M = sple_dly_real[suit_sdly];
|
|
}else if(tuning_freqs[i]<=52000000){
|
|
mmc->sdly_tuning.sdly_50M = sple_dly_real[suit_sdly];
|
|
}else{
|
|
MMCINFO("The freq is over 52M,not be dealt with now\n");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
mmc->update_sdly(mmc,sple_dly_real[suit_sdly]);//update sdly
|
|
}
|
|
|
|
// mmc->f_max = f_max_bak;
|
|
// mmc_set_clock(mmc, mmc->clock_after_init);//recover clock when init ok
|
|
//set clock for burn fireware
|
|
mmc_set_clock(mmc, tuning_freqs[0]);
|
|
MMCINFO("---------------mmc clock %d-----------\n", mmc->clock);
|
|
ret = 0;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int mmc_write_info(int dev_num,void *buffer,u32 buffer_size)
|
|
{
|
|
struct mmc *mmc = find_mmc_device(dev_num);
|
|
int work_mode = uboot_spare_head.boot_data.work_mode;
|
|
if(mmc==NULL){
|
|
MMCINFO("Can not find mmc\n");
|
|
return -1;
|
|
}
|
|
|
|
if(mmc->sample_mode ==AUTO_SAMPLE_MODE
|
|
&& work_mode!= WORK_MODE_BOOT){
|
|
|
|
if(sizeof(struct tuning_sdly)>buffer_size){
|
|
MMCINFO("size of tuning_sdly over %d\n",buffer_size);
|
|
return -1;
|
|
}
|
|
|
|
memcpy(buffer,(void *)&mmc->sdly_tuning,sizeof(sizeof(struct tuning_sdly)));
|
|
MMCINFO("write mmc info ok\n");
|
|
return 0;
|
|
}
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mmc_init_product(struct mmc *mmc)
|
|
{
|
|
int err;
|
|
|
|
//while((*(volatile unsigned int *)0) != 1);
|
|
if (mmc->has_init){
|
|
MMCINFO("Has init\n");
|
|
return 0;
|
|
}
|
|
|
|
retry:
|
|
|
|
err = mmc->init(mmc);
|
|
|
|
if (err){
|
|
MMCINFO("mmc->init error\n");
|
|
return err;
|
|
}
|
|
mmc_set_bus_width(mmc, 1);
|
|
mmc_set_clock(mmc, 1);
|
|
|
|
/* Reset the Card */
|
|
err = mmc_go_idle(mmc);
|
|
|
|
if (err){
|
|
MMCINFO("mmc go idle error\n");
|
|
return err;
|
|
}
|
|
/* The internal partition reset to user partition(0) at every CMD0*/
|
|
mmc->part_num = 0;
|
|
|
|
MMCINFO("************Try SD card %d************\n",mmc->control_num);
|
|
/* Test for SD version 2 */
|
|
err = mmc_send_if_cond(mmc);
|
|
if(err && !sunxi_need_rty(mmc)){
|
|
goto retry;
|
|
}
|
|
|
|
/* Now try to get the SD card's operating condition */
|
|
err = sd_send_op_cond(mmc);
|
|
if(err && !sunxi_need_rty(mmc)){
|
|
goto retry;
|
|
}
|
|
|
|
/* If the command timed out, we check for an MMC card */
|
|
if (err == -1){
|
|
if(!sunxi_need_rty(mmc)){
|
|
goto retry;
|
|
}
|
|
MMCINFO("*Try MMC card %d*\n",mmc->control_num);
|
|
err = mmc_send_op_cond(mmc);
|
|
if(err && !sunxi_need_rty(mmc)){
|
|
goto retry;
|
|
}
|
|
|
|
if (err) {
|
|
MMCINFO("Card did not respond to voltage select!\n");
|
|
MMCINFO("*SD/MMC %d init error!*\n",mmc->control_num);
|
|
return UNUSABLE_ERR;
|
|
}
|
|
}
|
|
|
|
err = mmc_startup(mmc);
|
|
if (err){
|
|
MMCINFO("*SD/MMC %d init error!*\n",mmc->control_num);
|
|
mmc->has_init = 0;
|
|
}
|
|
else{
|
|
mmc->has_init = 1;
|
|
//MMCINFO("************SD/MMC %d init OK!!!************\n",mmc->control_num);
|
|
}
|
|
|
|
if(err && !sunxi_need_rty(mmc)){
|
|
goto retry;
|
|
}
|
|
|
|
err = sunxi_write_tuning(mmc);
|
|
if(err){
|
|
MMCINFO("Write pattern failed\n");
|
|
return err;
|
|
}
|
|
|
|
err = sunxi_exe_tuning(mmc);
|
|
if(err){
|
|
return err;
|
|
}
|
|
|
|
|
|
init_part(&mmc->block_dev);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
static int mmc_init_boot(struct mmc *mmc)
|
|
{
|
|
int err;
|
|
int work_mode = uboot_spare_head.boot_data.work_mode;
|
|
|
|
if (mmc->has_init){
|
|
MMCINFO("Has init\n");
|
|
return 0;
|
|
}
|
|
|
|
err = mmc->init(mmc);
|
|
|
|
if (err){
|
|
MMCINFO("mmc->init error\n");
|
|
return err;
|
|
}
|
|
mmc_set_bus_width(mmc, 1);
|
|
mmc_set_clock(mmc, 1);
|
|
|
|
/* Reset the Card */
|
|
err = mmc_go_idle(mmc);
|
|
|
|
if (err){
|
|
MMCINFO("mmc go idle error\n");
|
|
return err;
|
|
}
|
|
/* The internal partition reset to user partition(0) at every CMD0*/
|
|
mmc->part_num = 0;
|
|
|
|
MMCINFO("*Try SD card %d*\n",mmc->control_num);
|
|
/* Test for SD version 2 */
|
|
err = mmc_send_if_cond(mmc);
|
|
|
|
/* Now try to get the SD card's operating condition */
|
|
err = sd_send_op_cond(mmc);
|
|
|
|
/* If the command timed out, we check for an MMC card */
|
|
if (err == -1){
|
|
MMCINFO("*Try MMC card %d*\n",mmc->control_num);
|
|
err = mmc_send_op_cond(mmc);
|
|
if (err) {
|
|
MMCINFO("Card did not respond to voltage select!\n");
|
|
MMCINFO("***SD/MMC %d init error!!!***\n",mmc->control_num);
|
|
return UNUSABLE_ERR;
|
|
}
|
|
}
|
|
|
|
err = mmc_startup(mmc);
|
|
if (err){
|
|
MMCINFO("*SD/MMC %d init error!!*\n",mmc->control_num);
|
|
mmc->has_init = 0;
|
|
}
|
|
else{
|
|
mmc->has_init = 1;
|
|
//MMCINFO("************SD/MMC %d init OK!!!************\n",mmc->control_num);
|
|
}
|
|
|
|
|
|
if((mmc->sample_mode == AUTO_SAMPLE_MODE)
|
|
&&(work_mode == WORK_MODE_BOOT)){
|
|
u32 suit_sdly = 0;
|
|
struct tuning_sdly *sdly= (struct tuning_sdly *)uboot_spare_head.boot_data.sdcard_spare_data;
|
|
|
|
//MMCINFO("****************sdly:%d*************************\n",sdly->sdly_50M);
|
|
suit_sdly = sdly->sdly_50M;
|
|
if(script_parser_patch("mmc2_para","sdc_sdly_50M",&suit_sdly,1) == SCRIPT_PARSER_OK){
|
|
int rval = 0;
|
|
script_parser_fetch("mmc2_para","sdc_sdly_50M", &rval, 1);
|
|
MMCINFO("set kernel %s %d ok\n","sdc_sdly_50M",rval);
|
|
}else{
|
|
MMCINFO("set kernel %s failed\n","sdc_sdly_50M");
|
|
}
|
|
|
|
suit_sdly = sdly->sdly_25M;
|
|
if(script_parser_patch("mmc2_para","sdc_sdly_25M",&suit_sdly,1) == SCRIPT_PARSER_OK){
|
|
int rval = 0;
|
|
script_parser_fetch("mmc2_para","sdc_sdly_25M", &rval, 1);
|
|
MMCINFO("set kernel %s %d ok\n","sdc_sdly_25M",rval);
|
|
}else{
|
|
MMCINFO("set kernel %s failed\n","sdc_sdly_25M");
|
|
}
|
|
|
|
}
|
|
init_part(&mmc->block_dev);
|
|
return err;
|
|
}
|
|
|
|
int mmc_init(struct mmc *mmc)
|
|
{
|
|
int work_mode = uboot_spare_head.boot_data.work_mode;
|
|
int ret = 0;
|
|
|
|
#if defined(CONFIG_ARCH_SUN9IW1P1)
|
|
if(gd->securemode == SUNXI_SECURE_MODE_NO_SECUREOS)
|
|
{
|
|
mmc->block_dev.lun = 0x0;
|
|
mmc->block_dev.type = 0x0;
|
|
mmc->block_dev.blksz = 0x200;
|
|
//use max lba/capacity becauese we can not get capacity from sd,because we can not get rca.
|
|
//for eMMC,we can get capacity,but for compatible to sd,we use max too
|
|
mmc->block_dev.lba = 0xffffffff;
|
|
mmc->capacity = 0xffffffff;
|
|
//mmc->block_dev.part_type = 0x2;
|
|
//assume high capacity for we do not init card here
|
|
mmc->high_capacity = 1;
|
|
//mmc->b_max = (0x20<<4);//(0x10000>>5);
|
|
//mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
|
|
mmc->read_bl_len = 0x200;
|
|
mmc->write_bl_len = 0x200;
|
|
//mmc->erase_grp_size = 0x1;
|
|
mmc->part_config = MMCPART_NOAVAILABLE;
|
|
mmc->has_init = 1;
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
//while((*(volatile unsigned int *)0) != 1);
|
|
if((mmc->sample_mode == AUTO_SAMPLE_MODE)
|
|
&&(work_mode != WORK_MODE_BOOT)){
|
|
return mmc_init_product(mmc);
|
|
}
|
|
ret = mmc_init_boot(mmc);
|
|
|
|
if (mmc->drv_wipe_feature & DRV_PARA_DISABLE_EMMC_SANITIZE)
|
|
mmc->secure_feature &= (~EXT_CSD_SEC_SANITIZE);
|
|
else if (mmc->drv_wipe_feature & DRV_PARA_DISABLE_EMMC_SECURE_PURGE)
|
|
mmc->secure_feature &= (~EXT_CSD_SEC_ER_EN);
|
|
else if (mmc->drv_wipe_feature & DRV_PARA_DISABLE_EMMC_TRIM)
|
|
mmc->secure_feature &= (~EXT_CSD_SEC_GB_CL_EN);
|
|
|
|
//MMCINFO("========================================\n");
|
|
//MMCINFO("mmc->block_dev.lba: %d Sectors\n", mmc->block_dev.lba);
|
|
//MMCINFO("wr_blk_len: 0x%x Byte\n", mmc->write_bl_len);
|
|
MMCINFO("erase_grp_size:0x%xWrBlk * 0x%x = 0x%x Byte\n",
|
|
mmc->erase_grp_size, mmc->write_bl_len, mmc->erase_grp_size*mmc->write_bl_len);
|
|
//MMCINFO("erase_to: %d ms\n", mmc->erase_timeout);
|
|
//MMCINFO("trim_discard_to: %d ms\n", mmc->trim_discard_timeout);
|
|
//MMCINFO("secure_tirm_to: %d ms\n", mmc->secure_erase_timeout);
|
|
//MMCINFO("secure_erase_to: %d ms\n", mmc->secure_trim_timeout);
|
|
|
|
MMCDBG("support sanitze: %d\n",\
|
|
mmc->secure_feature & EXT_CSD_SEC_SANITIZE);
|
|
MMCDBG("support trim: %d\n", \
|
|
mmc->secure_feature & EXT_CSD_SEC_GB_CL_EN);
|
|
MMCDBG("support secure purge op: %d\n", \
|
|
mmc->secure_feature & EXT_CSD_SEC_ER_EN);
|
|
MMCDBG("secure removal type: 0x%x\n", \
|
|
mmc->secure_removal_type);
|
|
|
|
MMCINFO("secure_feature 0x%x\n", mmc->secure_feature);
|
|
MMCINFO("secure_removal_type 0x%x\n", mmc->secure_removal_type);
|
|
|
|
//MMCINFO("========================================\n\n");
|
|
|
|
|
|
#ifdef MMC_INTERNAL_TEST
|
|
if (((mmc->mmc_test&MMC_ITEST_WHEN_BOOT) && (work_mode == WORK_MODE_BOOT))
|
|
|| ((mmc->mmc_test&MMC_ITEST_WHEN_PRODUCT) && (work_mode != WORK_MODE_BOOT)) )
|
|
{
|
|
if (mmc->mmc_test & MMC_ITEST_RWC) {
|
|
ret = mmc_t_rwc(mmc, 1024*1024*2, 10);
|
|
if (ret) {
|
|
MMCINFO("%s: mmc_t_rwc fail\n", __FUNCTION__);
|
|
}
|
|
}
|
|
|
|
if (mmc->mmc_test & MMC_ITEST_MEMCPY) {
|
|
ret = mmc_t_memcpy();
|
|
if (ret) {
|
|
MMCINFO("%s: mmc_t_memcpy fail\n", __FUNCTION__);
|
|
}
|
|
}
|
|
|
|
if (mmc->mmc_test & MMC_ITEST_SEQ_W_SPD) {
|
|
/* from 1GB, len: 64MB, each: 64KB */
|
|
ret = mmc_t_seq_write_speed_test(mmc, 1024*1024*2, 64*1024*2, 128);
|
|
if (ret) {
|
|
MMCINFO("%s: mmc_t_write_speed_test fail\n", __FUNCTION__);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* CPU and board-specific MMC initializations. Aliased function
|
|
* signals caller to move on
|
|
*/
|
|
static int __def_mmc_init(bd_t *bis)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
|
|
int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
|
|
|
|
void print_mmc_devices(char separator)
|
|
{
|
|
struct mmc *m;
|
|
struct list_head *entry;
|
|
|
|
list_for_each(entry, &mmc_devices) {
|
|
m = list_entry(entry, struct mmc, link);
|
|
|
|
MMCINFO("%s: %d", m->name, m->block_dev.dev);
|
|
|
|
if (entry->next != &mmc_devices)
|
|
printf("%c ", separator);
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
int get_mmc_num(void)
|
|
{
|
|
//return cur_dev_num;
|
|
return board_mmc_get_num();
|
|
}
|
|
|
|
int mmc_initialize(bd_t *bis)
|
|
{
|
|
// INIT_LIST_HEAD (&mmc_devices);
|
|
|
|
if (board_mmc_init(bis) < 0)
|
|
cpu_mmc_init(bis);
|
|
|
|
print_mmc_devices(',');
|
|
|
|
return 0;
|
|
}
|
|
|
|
int mmc_exit(void)
|
|
{
|
|
int err;
|
|
int sdc_no = 2;
|
|
struct mmc *mmc = find_mmc_device(sdc_no);
|
|
if(mmc == NULL){
|
|
MMCINFO(" mmc %s not find,so not exit\n",sdc_no);
|
|
return -1;
|
|
}
|
|
|
|
MMCINFO("mmc exit start\n");
|
|
|
|
#if defined(CONFIG_ARCH_SUN9IW1P1)
|
|
if(gd->securemode == SUNXI_SECURE_MODE_NO_SECUREOS)
|
|
{
|
|
MMCINFO("mmc not exit\n");
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
err = mmc->init(mmc);
|
|
|
|
if (err){
|
|
MMCINFO("mmc->init error\n");
|
|
MMCINFO("mmc %d exit failed\n",mmc->control_num);
|
|
return err;
|
|
}
|
|
mmc_set_bus_width(mmc, 1);
|
|
mmc_set_clock(mmc, 1);
|
|
|
|
/* Reset the Card */
|
|
err = mmc_go_idle(mmc);
|
|
|
|
if (err){
|
|
MMCINFO("mmc go idle error\n");
|
|
MMCINFO("mmc %d exit failed\n",mmc->control_num);
|
|
return err;
|
|
}
|
|
/* The internal partition reset to user partition(0) at every CMD0*/
|
|
mmc->part_num = 0;
|
|
|
|
//MMCINFO("************Try SD card %d************\n",mmc->control_num);
|
|
/* Test for SD version 2 */
|
|
err = mmc_send_if_cond(mmc);
|
|
|
|
/* Now try to get the SD card's operating condition */
|
|
err = sd_send_op_cond(mmc);
|
|
|
|
/* If the command timed out, we check for an MMC card */
|
|
if (err == -1){
|
|
//MMCINFO("************Try MMC card %d************\n",mmc->control_num);
|
|
err = mmc_send_op_cond(mmc);
|
|
|
|
if (err) {
|
|
MMCINFO("Card did not respond to voltage select!\n");
|
|
MMCINFO("mmc %d exit failed\n",mmc->control_num);
|
|
return UNUSABLE_ERR;
|
|
}
|
|
}
|
|
|
|
/*
|
|
err = mmc_startup(mmc);
|
|
if (err){
|
|
MMCINFO("************SD/MMC %d init error!!!************\n",mmc->control_num);
|
|
mmc->has_init = 0;
|
|
}
|
|
else{
|
|
mmc->has_init = 1;
|
|
//MMCINFO("************SD/MMC %d init OK!!!************\n",mmc->control_num);
|
|
}
|
|
*/
|
|
|
|
sunxi_mmc_exit(sdc_no);
|
|
|
|
MMCINFO("mmc %d exit ok\n",mmc->control_num);
|
|
return err;
|
|
}
|