[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/scatter/tools/bch b/src/bsp/scatter/tools/bch
new file mode 100755
index 0000000..4954ae1
--- /dev/null
+++ b/src/bsp/scatter/tools/bch
Binary files differ
diff --git a/src/bsp/scatter/tools/nand-utils/README b/src/bsp/scatter/tools/nand-utils/README
new file mode 100644
index 0000000..16294ea
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/README
@@ -0,0 +1,12 @@
+usage
+
+1. ramdomizer.py:  in_image, out_image, randomizer_type, sec_reseed enable, page size, spare size, sector size, page per block, ppen, vendor
+e.g: python randomizer.py nand_storage_image/TC58TEG5DCJTA00_rand_off_ecc.bin nand_storage_image/random.bin 'SS' 1 16384 1280 1024 256 0 "TSB"
+
+2. gen_storage_image.py: NAND device name(reference nand_device_list.txt), in_image, out_image, rand_en
+e.g: python gen_storage_image.py F59D4G81A-45TG-18V nand_storage_image/GPT_2048_W1_64_FIT.bin nand_storage_image/F59D4G81A-45TG-18V-storage-image.bin 0
+
+3. gen_nand_header.py: NAND device name(reference nand_device_list.txt)
+e.g: python gen_nand_header.py TH58TFG8DDLAB4C
+
+If want to ignore .pyc file, please use python -B xxx.py
diff --git a/src/bsp/scatter/tools/nand-utils/__init__.py b/src/bsp/scatter/tools/nand-utils/__init__.py
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/__init__.py
diff --git a/src/bsp/scatter/tools/nand-utils/ac_calculator/ac_calculator.py b/src/bsp/scatter/tools/nand-utils/ac_calculator/ac_calculator.py
new file mode 100755
index 0000000..4fe91b7
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/ac_calculator/ac_calculator.py
@@ -0,0 +1,493 @@
+#!/usr/bin/env python
+
+import argparse
+import sys
+import struct
+import os
+import math
+import xml.dom.minidom
+
+# max strobe delay cycle
+max_strobe_dly = 3
+
+def calculate_sdr_acccon(ac, rate):
+	# turn clock rate from HZ into KHZ
+	rate /= 1000
+	# calculate tpoecs
+	tpoecs = max(ac["tALH"], ac["tCLH"])
+	tpoecs = int(math.ceil(float(tpoecs) * rate / 1000000))
+	tpoecs &= 0xf
+	# calculate tprecs
+	tprecs = max(ac["tCLS"], ac["tALS"])
+	tprecs = int(math.ceil(float(tprecs) * rate / 1000000))
+	tprecs &= 0x3f
+	# calculate tc2r
+	tc2r = int(math.ceil(float(ac["tCR"]) * rate / 1000000)) - 1
+	tc2r = int(math.ceil(float(tc2r) / 2))
+	tc2r &= 0x3f
+	# calculate tw2r
+	tw2r = int(math.ceil(float(ac["tWHR"]) * rate / 1000000)) - 1
+	tw2r = int(math.ceil(float(tw2r) / 2))
+	tw2r &= 0xf;
+	# calculate twh
+	twh = max(ac["tREH"], ac["tWH"])
+	twh = int(math.ceil(float(twh) * rate / 1000000)) - 1
+	twh &= 0xf
+	# calculate twst
+	twst = 0
+	if (twh + 1) * 1000000 / rate < ac["tWC"]:
+		twst = ac["tWC"] - (twh + 1) * 1000000 / rate
+	twst = max(ac["tWP"], twst)
+	twst = int(math.ceil(float(twst) * rate / 1000000)) - 1
+	twst &= 0xf
+	# calculate trlt
+	trlt = 0
+	if (twh + 1) * 1000000 / rate < ac["tRC"]:
+		trlt = ac["tRC"] - (twh + 1) * 1000000 / rate
+	trlt = max(ac["tRP"], trlt)
+	trlt = int(math.ceil(float(trlt) * rate / 1000000)) - 1
+	trlt &= 0xf
+	# calculate strobe sel
+	tsel = 0
+	if (trlt + 1) * 1000000 / rate < ac["tREA"]:
+		tsel = int(math.ceil(float(ac["tREA"]) * rate / 1000000))
+		tsel -= trlt + 1
+		if tsel > max_strobe_dly:
+			trlt += tsel - max_strobe_dly
+			tsel = max_strobe_dly
+	# get acccon
+	acccon = (tpoecs) << 28 | (tprecs) << 22 | (tc2r) << 16 | (tw2r) << 12 | (twh) << 8 | (twst) << 4 | (trlt)
+
+	return (acccon, tsel)
+
+def check_sdr_acccon_match_spec(ac, rate, acccon):
+	# turn clock rate from HZ into KHZ
+	rate /= 1000
+	# check tWH
+	twh = ((acccon >> 8) & 0xf) + 1
+	if twh * 1000000 / rate < ac["tWH"]:
+		return 1
+	# check tREH
+	if twh * 1000000 / rate < ac["tREH"]:
+		return 1
+	# check tWP
+	twst = ((acccon >> 4) & 0xf) + 1
+	if twst * 1000000 / rate < ac["tWP"]:
+		return 1
+	# check tRP
+	trlt = (acccon & 0xf) + 1
+	if trlt * 1000000 / rate < ac["tRP"]:
+		return 1
+	# check tWC
+	if (twh + twst) * 1000000 / rate < ac["tWC"]:
+		return 1
+	# check tRC
+	if (twh + trlt) * 1000000 / rate < ac["tRC"]:
+		return 1
+	# check more below
+
+	return 0
+
+def calculate_sdr_speed(ac, acccon, array, rate):
+	# turn clock rate from HZ into KHZ
+	rate /= 1000
+
+	twh = ((acccon >> 8) & 0xf) + 1
+	twst = ((acccon >> 4) & 0xf) + 1
+	trlt = (acccon & 0xf) + 1
+	chunk = array["page_size"] + array["spare_size"]
+
+	# read speed
+	tread = (float)(twh + trlt) * 1000000 / rate
+	tread *= chunk
+	tread += ac["tR"]
+	tread /= 1000
+	rspeed = 1000000 / tread
+	rspeed *= array["page_size"] / 1024
+
+	# write speed
+	twrite = (float)(twh + twst) * 1000000 / rate
+	twrite *= chunk
+	twrite += ac["tPROG"]
+	twrite /= 1000
+	wspeed = 1000000 / twrite
+	wspeed *= array["page_size"] / 1024
+
+	# erase speed
+	terase = ac["tBERS"] / 1000
+	espeed = 1000000 / terase
+	espeed *= array["page_size"] * array["page_per_block"] / 1024
+
+	return (rspeed, wspeed, espeed)
+
+def get_array_para(nand):
+	array = {}
+	for node in nand.childNodes:
+		if node.nodeName != "entry":
+			continue
+		artype = node.getAttribute("type")
+		if artype == "name":
+			array["name"] = node.getAttribute("value")
+		elif artype == "page_size":
+			array["page_size"] = eval(node.getAttribute("value"))
+		elif artype == "spare_size":
+			array["spare_size"] = eval(node.getAttribute("value"))
+		elif artype == "page_per_block":
+			array["page_per_block"] = eval(node.getAttribute("value"))
+	print ("NAND: %s, page size: %d, spare size: %d, page per block: %d" %
+		(array["name"], array["page_size"], array["spare_size"], array["page_per_block"]))
+
+	return array
+
+def get_sdr_ac_timing(ac_timing):
+	# get AC timing parameter value
+	ac = {}
+	for node in ac_timing.childNodes:
+		if node.nodeName != "entry":
+			continue
+		actype = node.getAttribute("type")
+		if actype == "tREA":
+			ac["tREA"] = eval(node.getAttribute("value"))
+		elif actype == "tREH":
+			ac["tREH"] = eval(node.getAttribute("value"))
+		elif actype == "tCR":
+			ac["tCR"] = eval(node.getAttribute("value"))
+		elif actype == "tRP":
+			ac["tRP"] = eval(node.getAttribute("value"))
+		elif actype == "tWP":
+			ac["tWP"] = eval(node.getAttribute("value"))
+		elif actype == "tWH":
+			ac["tWH"] = eval(node.getAttribute("value"))
+		elif actype == "tWHR":
+			ac["tWHR"] = eval(node.getAttribute("value"))
+		elif actype == "tCLS":
+			ac["tCLS"] = eval(node.getAttribute("value"))
+		elif actype == "tALS":
+			ac["tALS"] = eval(node.getAttribute("value"))
+		elif actype == "tCLH":
+			ac["tCLH"] = eval(node.getAttribute("value"))
+		elif actype == "tALH":
+			ac["tALH"] = eval(node.getAttribute("value"))
+		elif actype == "tWC":
+			ac["tWC"] = eval(node.getAttribute("value"))
+		elif actype == "tRC":
+			ac["tRC"] = eval(node.getAttribute("value"))
+		elif actype == "tR":
+			ac["tR"] = eval(node.getAttribute("value"))
+		elif actype == "tPROG":
+			ac["tPROG"] = eval(node.getAttribute("value"))
+		elif actype == "tBERS":
+			ac["tBERS"] = eval(node.getAttribute("value"))
+	print ("tR: %d, tPROG: %d, tBERS: %d ns" % (ac["tR"], ac["tPROG"], ac["tBERS"]))
+	return ac
+
+def sdr_calculator(nand, freq):
+	print ("This is SDR mode calculator!!")
+	nand_file = "./sdr/" + nand
+	doc_nand = xml.dom.minidom.parse(nand_file)
+	root_nand = doc_nand.documentElement
+	for nand_node in root_nand.childNodes:
+		if nand_node.nodeName == "ac_timing":
+			ac = get_sdr_ac_timing(nand_node)
+		elif nand_node.nodeName == "array":
+			array = get_array_para(nand_node)
+
+	# get frequency
+	freq_file = "./freq/" + freq
+	root_freq = xml.dom.minidom.parse(freq_file)
+	for frequency in root_freq.childNodes:
+		if frequency.nodeName == "frequency":
+			break
+
+	divider = eval(frequency.getAttribute("divider"))
+
+	# calculate acccon, stobe, performance
+	print ("Read IO speed: %.2f KB/s, Write IO speed: %.2f KB/s" %
+		((1000000000 / float(ac["tRC"]) / 1024), (1000000000 / float(ac["tWC"]) / 1024)))
+	out_format = "{:^12}\t{:^12}\t{:^5}\t{:^12}\t{:^12}\t{:^12}\t"
+	print (out_format.format("freq","acccon","strobe","read(KB/s)","write(KB/s)", "erase(KB/s)"))
+	performance = []
+	for node in frequency.childNodes:
+		if node.nodeName != "entry":
+			continue
+		rate = eval(node.getAttribute("value"))
+		rate /= divider
+		freq_name = node.getAttribute("name")
+		(acccon, strobe) = calculate_sdr_acccon(ac, rate)
+		acccon_match = check_sdr_acccon_match_spec(ac, rate, acccon)
+		if acccon_match > 1:
+			print ("acccon %#x strobe %d not match spec" % (acccon, strobe))
+			raise Exception("not match spec")
+		(rspeed, wspeed, espeed) = calculate_sdr_speed(ac, acccon, array, rate)
+		rate *= divider
+		print (out_format.format(rate, hex(acccon), strobe, format(rspeed, ".2f"), \
+			format(wspeed, ".2f"), espeed))
+		performance.append({"rate":rate, "acccon":hex(acccon), "strobe":strobe, \
+					"rspeed":rspeed, "wspeed":wspeed, "espeed":espeed})
+
+	best_read = best_write = 0
+	for best in performance:
+		if best["rspeed"] > best_read:
+			best_read = best["rspeed"]
+			best_read_idx = performance.index(best)
+		if best["wspeed"] > best_write:
+			best_write = best["wspeed"]
+			best_write_idx = performance.index(best)
+	print ("frequency[%d] has the best read performance [%.2f KB/s]" %
+			(performance[best_read_idx]["rate"], performance[best_read_idx]["rspeed"]))
+	print ("frequency[%d] has the best write performance [%.2f KB/s]" %
+			(performance[best_write_idx]["rate"], performance[best_read_idx]["wspeed"]))
+
+def get_onfi_ac_timing(ac_timing):
+	# get AC timing parameter value
+	ac = {}
+	for node in ac_timing.childNodes:
+		if node.nodeName != "entry":
+			continue
+		actype = node.getAttribute("type")
+		if actype == "tCAD":
+			ac["tCAD"] = eval(node.getAttribute("value"))
+		elif actype == "tWRCK":
+			ac["tWRCK"] = eval(node.getAttribute("value"))
+		elif actype == "tDQSCK":
+			ac["tDQSCK"] = eval(node.getAttribute("value"))
+		elif actype == "tWHR":
+			ac["tWHR"] = eval(node.getAttribute("value"))
+		elif actype == "tWPRE":
+			ac["tWPRE"] = eval(node.getAttribute("value"))
+		elif actype == "tWPST":
+			ac["tWPST"] = eval(node.getAttribute("value"))
+		elif actype == "rate_max":
+			ac["rate_max"] = eval(node.getAttribute("value"))
+		elif actype == "tR":
+			ac["tR"] = eval(node.getAttribute("value"))
+		elif actype == "tPROG":
+			ac["tPROG"] = eval(node.getAttribute("value"))
+		elif actype == "tBERS":
+			ac["tBERS"] = eval(node.getAttribute("value"))
+	print ("tR: %d, tPROG: %d, tBERS: %d ns" % (ac["tR"], ac["tPROG"], ac["tBERS"]))
+
+	ac["tCKWR"] = ac["tDQSCK"]
+
+	return ac
+
+def calculate_onfi_acccon(ac, rate):
+	# turn clock rate from HZ into KHZ
+	rate /= 1000
+	# calculate tWPRE, tWRST, tCKWR
+	ac["tWPRE_real"] = int(math.ceil(float(ac["tWPRE"]) * 1000000 / rate))
+	ac["tWPST_real"] = int(math.ceil(float(ac["tWPST"]) * 1000000 / rate))
+	ac["tCKWR"] = int(math.ceil(math.ceil(float(ac["tDQSCK"]) * rate / 1000000) * 1000000 / rate))
+	# acccon register setting
+	# calculate tprecs
+	tprecs = max(ac["tCAD"], ac["tWRCK"])
+	if ac["tWPRE_real"] > int(math.ceil(1.5 * 1000000 / rate)):
+		tprecs = max(tprecs, ac["tWPRE_real"] - int(math.ceil(1.5 * 1000000 / rate)))
+	tprecs = int(math.ceil(float(tprecs) * rate / 1000000))
+	tprecs &= 0x3f;
+	# calculate tw2r
+	tw2r = int(math.ceil(float(ac["tWHR"]) * rate / 1000000))
+	tw2r = int(math.ceil(float(tw2r - 1) / 2))
+	tw2r &= 0xf
+	acccon = (tprecs) << 22 | (tw2r) << 12
+
+	# acccon1 register setting
+	# calculate trdpst
+	trdpst = int(math.ceil(float(ac["tCKWR"]) * rate / 1000000)) - 1
+	trdpst &= 0x3f
+	# calculate twrpst
+	twrpst = int(math.ceil(float(ac["tWPST_real"]) * rate / 1000000)) - 1
+	twrpst &= 0x3f
+	acccon1 = (trdpst) << 8 | (twrpst)
+
+	return (acccon, acccon1)
+
+def get_toggle_ac_timing(ac_timing):
+	# get AC timing parameter value
+	ac = {}
+	for node in ac_timing.childNodes:
+		if node.nodeName != "entry":
+			continue
+		actype = node.getAttribute("type")
+		if actype == "tCH":
+			ac["tCH"] = eval(node.getAttribute("value"))
+		elif actype == "tCALS":
+			ac["tCALS"] = eval(node.getAttribute("value"))
+		elif actype == "tCALH":
+			ac["tCALH"] = eval(node.getAttribute("value"))
+		elif actype == "tWPRE":
+			ac["tWPRE"] = eval(node.getAttribute("value"))
+		elif actype == "tWPST":
+			ac["tWPST"] = eval(node.getAttribute("value"))
+		elif actype == "tWPSTH":
+			ac["tWPSTH"] = eval(node.getAttribute("value"))
+		elif actype == "tCR":
+			ac["tCR"] = eval(node.getAttribute("value"))
+		elif actype == "tDQSRE":
+			ac["tDQSRE"] = eval(node.getAttribute("value"))
+		elif actype == "tRPSTH":
+			ac["tRPSTH"] = eval(node.getAttribute("value"))
+		elif actype == "tCDQSS":
+			ac["tCDQSS"] = eval(node.getAttribute("value"))
+		elif actype == "tWHR":
+			ac["tWHR"] = eval(node.getAttribute("value"))
+		elif actype == "rate_max":
+			ac["rate_max"] = eval(node.getAttribute("value"))
+		elif actype == "tR":
+			ac["tR"] = eval(node.getAttribute("value"))
+		elif actype == "tPROG":
+			ac["tPROG"] = eval(node.getAttribute("value"))
+		elif actype == "tBERS":
+			ac["tBERS"] = eval(node.getAttribute("value"))
+	print ("tR: %d, tPROG: %d, tBERS: %d ns" % (ac["tR"], ac["tPROG"], ac["tBERS"]))
+
+	return ac
+
+def calculate_toggle_acccon(ac, rate):
+	# turn clock rate from HZ into KHZ
+	rate /= 1000
+	# calculate tRPST
+	ac["tRPST"] = ac["tDQSRE"] + 0.5 * 1000000 / rate
+	# acccon register setting
+	# calculate tpoecs
+	tpoecs = max(max(ac["tCALH"], ac["tWPSTH"]), ac["tRPSTH"])
+	tpoecs = int(math.ceil(float(tpoecs) * rate / 1000000)) - 1
+	tpoecs &= 0xf
+	# calculate tprecs
+	tprecs = max(ac["tCALS"], ac["tCDQSS"])
+	tprecs = int(math.ceil(float(tprecs) * rate / 1000000)) - 1
+	tprecs &= 0x3f
+	# calculate tc2r
+	tc2r = math.ceil(float(ac["tCR"]) * rate / 1000000) - 1
+	tc2r = int(math.ceil(tc2r / 2))
+	tc2r &= 0x3f
+	# calculate tw2r
+	tw2r = math.ceil(float(ac["tWHR"]) * rate / 1000000) - 1
+	tw2r = int(math.ceil(tw2r / 2))
+	tw2r &= 0x3f
+	# calculate twh
+	twh = max(ac["tCH"], ac["tCALH"])
+	twh = int(math.ceil(float(twh) * rate / 1000000)) - 1
+	twh &= 0xf
+	# calculate twst
+	twst = int(math.ceil(float(ac["tCALS"]) * rate / 1000000)) - 1
+	twst &= 0xf
+	trlt = 0
+	acccon = (tpoecs) << 28 | (tprecs) << 22 | (tc2r) << 16 | (tw2r) << 12 | (twh) << 8 | (twst) << 4 | (trlt)
+
+	# acccon1 register setting
+	# calculate trdpre
+	trdpre = int(math.ceil(float(ac["tWPRE"]) * rate / 1000000)) - 1
+	trdpre &= 0x3f
+	# calculate trdpst
+	trdpst = int(math.ceil(float(ac["tRPST"]) * rate / 1000000)) - 1
+	trdpst &= 0x3f
+	# calculate twrpre
+	twrpre = int(math.ceil(float(ac["tWPRE"]) * rate / 1000000)) - 1
+	twrpre &= 0x3f
+	# calculate twrpst
+	twrpst = int(math.ceil(float(ac["tWPST"]) * rate / 1000000)) - 1
+	twrpst &= 0x3f
+	acccon1 = (trdpre << 24) | (twrpre) << 16 | (trdpst) << 8 | (twrpst)
+
+	return (acccon, acccon1)
+
+def calculate_ddr_speed(ac, array, rate):
+	# turn clock rate from HZ into KHZ
+	rate /= 1000
+
+	chunk = array["page_size"] + array["spare_size"]
+
+	# read speed
+	tread = 1000000 / float(rate * 2)
+	tread *= chunk
+	tread += ac["tR"]
+	tread /= 1000
+	rspeed = 1000000 / tread
+	rspeed *= array["page_size"] / 1024
+
+	# write speed
+	twrite = 1000000 / float(rate * 2)
+	twrite *= chunk
+	twrite += ac["tPROG"]
+	twrite /= 1000
+	wspeed = 1000000 / twrite
+	wspeed *= array["page_size"] / 1024
+
+	# erase speed
+	terase = ac["tBERS"] / 1000
+	espeed = 1000000 / terase
+	espeed *= array["page_size"] * array["page_per_block"] / 1024
+
+	return (rspeed, wspeed, espeed)
+
+def ddr_calculator(nand, freq, mode):
+	print ("This is %s mode calculator!!" % mode)
+	nand_file = "./" + mode + "/" + nand
+	doc_nand = xml.dom.minidom.parse(nand_file)
+	root_nand = doc_nand.documentElement
+	for nand_node in root_nand.childNodes:
+		if nand_node.nodeName == "ac_timing":
+			if mode == "ddr_onfi":
+				ac = get_onfi_ac_timing(nand_node)
+			elif mode == "ddr_toggle":
+				ac = get_toggle_ac_timing(nand_node)
+			else:
+				raise Exception("unsupported ddr mode!!")
+		elif nand_node.nodeName == "array":
+			array = get_array_para(nand_node)
+
+	# get frequency
+	freq_file = "./freq/" + freq
+	root_freq = xml.dom.minidom.parse(freq_file)
+	for frequency in root_freq.childNodes:
+		if frequency.nodeName == "frequency":
+			break
+
+	divider = eval(frequency.getAttribute("divider"))
+
+	out_format = "{:^12}\t{:^12}\t{:^12}\t{:^12}\t{:^12}\t{:^12}\t"
+	print (out_format.format("freq","acccon","acccon1","read(KB/s)","write(KB/s)", "erase(KB/s)"))
+	rate_invalid = []
+	for node in frequency.childNodes:
+		if node.nodeName != "entry":
+			continue
+		rate = eval(node.getAttribute("value"))
+		rate /= divider
+		if rate > ac["rate_max"]:
+			rate_invalid.append(rate * divider)
+			continue
+		freq_name = node.getAttribute("name")
+		if mode == "ddr_onfi":
+			(acccon, acccon1) = calculate_onfi_acccon(ac, rate)
+		elif mode == "ddr_toggle":
+			(acccon, acccon1) = calculate_toggle_acccon(ac, rate)
+		else:
+			raise Exception("unsupported ddr mode!!")
+		(rspeed, wspeed, espeed) = calculate_ddr_speed(ac, array, rate)
+		rate *= divider
+		print (out_format.format(rate, hex(acccon), hex(acccon1), format(rspeed, ".2f"), \
+			format(wspeed, ".2f"), espeed))
+
+	for rate in rate_invalid:
+		print ("rate[%d] not supported!" % rate)
+
+def ddr_toggle_calculator(nand, freq):
+	print ("This is Toggle DDR mode calculator!!")
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('mode', help = 'working mode: sdr, ddr_onfi, ddr_toggle')
+	parser.add_argument('nand', help= 'nand AC timing xml file')
+	parser.add_argument('freq', help = 'frequency file')
+	args = parser.parse_args()
+
+	if args.mode == "sdr":
+		sdr_calculator(args.nand, args.freq)
+	elif args.mode == "ddr_onfi" or args.mode == "ddr_toggle":
+		ddr_calculator(args.nand, args.freq, args.mode)
+	else:
+		raise Exception("Working mode not supported!")
+
+if __name__ == "__main__":
+        sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/ac_calculator/ddr_onfi/MT29F64G08CBCGB.xml b/src/bsp/scatter/tools/nand-utils/ac_calculator/ddr_onfi/MT29F64G08CBCGB.xml
new file mode 100644
index 0000000..026a9d8
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/ac_calculator/ddr_onfi/MT29F64G08CBCGB.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<nand>
+	<array>
+		<!--size value must be with "byte" unit-->
+		<entry type="name" value="MT29F64G08CBCGB" descript="nand name"/>
+		<entry type="page_size" value="16384" descript="page size"/>
+		<entry type="spare_size" value="2208" descript="spare size"/>
+		<entry type="page_per_block" value="512" descript="page per block"/>
+	</array>
+	<ac_timing>
+		<!--timing value not highlight must be with "ns" unit-->
+		<entry type="tCAD" value="25" descript="Command, address data delay"/>
+		<entry type="tWPRE" value="1.5" descript="unit tCK, DQS write preamble"/>
+		<entry type="tWPST" value="1.5" descript="unit tCK, DQS write postamble"/>
+		<entry type="tWRCK" value="20" descript="W/R# low to data output cycle"/>
+		<entry type="tDQSCK" value="20" descript="Access window of DQS from CLK"/>
+		<entry type="tCKWR" value="div_round_up(tDQSCK, tCK)" descript="unit tCK, Data output end to W/R# high"/>
+		<entry type="tWHR" value="80" descript="Command cycle to data output"/>
+		<entry type="tR" value="52000" descript="data transfer from cell to data register"/>
+		<entry type="tPROG" value="330000" descript="page program time"/>
+		<entry type="tBERS" value="10000000" descript="block erase time"/>
+		<entry type="rate_max" value="100000000" descript="max frequency supported (HZ)"/>
+	</ac_timing>
+</nand>
diff --git a/src/bsp/scatter/tools/nand-utils/ac_calculator/ddr_toggle/TC58TEG6DDLTA00.xml b/src/bsp/scatter/tools/nand-utils/ac_calculator/ddr_toggle/TC58TEG6DDLTA00.xml
new file mode 100644
index 0000000..f669901
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/ac_calculator/ddr_toggle/TC58TEG6DDLTA00.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<nand>
+	<array>
+		<!--size value must be with "byte" unit-->
+		<entry type="name" value="TC58TEG6DDLTA00" descript="nand name"/>
+		<entry type="page_size" value="16384" descript="page size"/>
+		<entry type="spare_size" value="1280" descript="spare size"/>
+		<entry type="page_per_block" value="256" descript="page per block"/>
+	</array>
+	<ac_timing>
+		<!--timing value not highlight must be with "ns" unit-->
+		<entry type="tCH" value="5" descript="CE# hold time"/>
+		<entry type="tCALS" value="15" descript="CLE/ALE setup time"/>
+		<entry type="tCALH" value="5" descript="CLE/ALE hold time"/>
+		<entry type="tWPRE" value="15" descript="Write preamble"/>
+		<entry type="tWPST" value="6.5" descript="Write postamble"/>
+		<entry type="tWPSTH" value="25" descript="Write postamble hold time"/>
+		<entry type="tCR" value="10" descript="CE# low to RE# low"/>
+		<entry type="tDQSRE" value="25" descript="RE# to DQS and DQ delay"/>
+		<entry type="tRPST" value="tDQSRE+0.5*tRC" descript="Read postamble"/>
+		<entry type="tRPSTH" value="25" descript="Read postamble hold time"/>
+		<entry type="tCDQSS" value="100" descript="DQS setup time for data input mode start"/>
+		<entry type="tWHR" value="120" descript="WE# high to RE# low"/>
+		<entry type="tR" value="50000" descript="data transfer from cell to data register"/>
+		<entry type="tPROG" value="1400000" descript="page program time"/>
+		<entry type="tBERS" value="5000000" descript="block erase time"/>
+		<entry type="rate_max" value="100000000" descript="max frequency supported (HZ)"/>
+	</ac_timing>
+</nand>
diff --git a/src/bsp/scatter/tools/nand-utils/ac_calculator/freq/mt8133.xml b/src/bsp/scatter/tools/nand-utils/ac_calculator/freq/mt8133.xml
new file mode 100644
index 0000000..c791fd2
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/ac_calculator/freq/mt8133.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--divider: 1: clocks below are 1x clock, 2: clocks below are 2x clock-->
+<frequency divider="2">
+	<!--rate unit: HZ-->
+	<entry name="26m" value="26000000"/>
+	<entry name="syspll2_d2" value="182000000"/>
+	<entry name="syspll_d7" value="156000000"/>
+	<entry name="syspll_d3" value="364000000"/>
+	<entry name="syspll2_d4" value="91000000"/>
+	<entry name="msdcpll_d2" value="200000000"/>
+	<entry name="univpll1_d2" value="312000000"/>
+	<entry name="univpll_d5" value="249600000"/>
+</frequency>
diff --git a/src/bsp/scatter/tools/nand-utils/ac_calculator/sdr/W29N08GZSIBA.xml b/src/bsp/scatter/tools/nand-utils/ac_calculator/sdr/W29N08GZSIBA.xml
new file mode 100644
index 0000000..85cf677
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/ac_calculator/sdr/W29N08GZSIBA.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<nand>
+	<array>
+		<!--size value must be with "byte" unit-->
+		<entry type="name" value="W29N08GZSIBA" descript="nand name"/>
+		<entry type="page_size" value="2048" descript="page size"/>
+		<entry type="spare_size" value="64" descript="spare size"/>
+		<entry type="page_per_block" value="64" descript="page per block"/>
+	</array>
+	<ac_timing>
+		<!--timing value must be with "ns" unit-->
+		<entry type="tREA" value="25" descript="RE# access time"/>
+		<entry type="tREH" value="10" descript="RE# high hold time"/>
+		<entry type="tCR" value="0" descript="CE# low to RE# low. If no this para, set 0"/>
+		<entry type="tRP" value="12" descript="RE# pulse width"/>
+		<entry type="tWP" value="12" descript="WE# pulse width"/>
+		<entry type="tWH" value="10" descript="WE# high hold time"/>
+		<entry type="tWHR" value="80" descript="WE# high to RE# low"/>
+		<entry type="tCLS" value="10" descript="CLE setup time"/>
+		<entry type="tALS" value="10" descript="ALE setup time"/>
+		<entry type="tCLH" value="5" descript="CLE hold time"/>
+		<entry type="tALH" value="5" descript="ALE hold time"/>
+		<entry type="tWC" value="35" descript="write cycle time"/>
+		<entry type="tRC" value="35" descript="read cycle time"/>
+		<entry type="tR" value="25000" descript="data transfer from cell to data register"/>
+		<entry type="tPROG" value="250000" descript="page program time"/>
+		<entry type="tBERS" value="2000000" descript="block erase time"/>
+	</ac_timing>
+</nand>
diff --git a/src/bsp/scatter/tools/nand-utils/ecc_bch.py b/src/bsp/scatter/tools/nand-utils/ecc_bch.py
new file mode 100755
index 0000000..6e2c80e
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/ecc_bch.py
@@ -0,0 +1,690 @@
+#!/usr/bin/env python3
+
+import math
+
+M_14_4 = ((0x85,0x5c,0x9a,0x89,0x8a,0x48,0x9b,0x01),
+	  (0x0a,0xb9,0x34,0x13,0x15,0x91,0x36,0x03),
+	  (0x14,0x72,0x69,0x26,0x2a,0x22,0x6d,0x06),
+	  (0x28,0xe4,0xd2,0x4c,0x54,0x44,0xda,0x0c),
+	  (0x50,0xc8,0xa5,0x99,0xa8,0x88,0xb4,0x19),
+	  (0xa0,0x90,0x4b,0x33,0x51,0x11,0x69,0x33),
+	  (0x40,0x21,0x97,0x66,0xa2,0x22,0xd2,0x66),
+	  (0x80,0x42,0x2e,0xcd,0x44,0x45,0xa4,0xcd))
+
+M_14_6 = ((0xf9,0x0f,0x2a,0x86,0x79,0xef,0x10,0x33,0xaf,0x5c,0x12,0x00),
+	  (0xf2,0x1f,0x54,0x0c,0xf3,0xde,0x21,0x66,0x5e,0xb9,0x24,0x00),
+	  (0xe4,0x3f,0xa8,0x18,0xe6,0xbd,0x43,0xcc,0xbc,0x72,0x49,0x00),
+	  (0xc8,0x7f,0x50,0x31,0xcc,0x7b,0x87,0x98,0x79,0xe5,0x92,0x00),
+	  (0x90,0xff,0xa0,0x62,0x98,0xf7,0x0e,0x31,0xf3,0xca,0x25,0x01),
+	  (0x20,0xff,0x41,0xc5,0x30,0xef,0x1d,0x62,0xe6,0x95,0x4b,0x02),
+	  (0x40,0xfe,0x83,0x8a,0x61,0xde,0x3b,0xc4,0xcc,0x2b,0x97,0x04),
+	  (0x80,0xfc,0x07,0x15,0xc3,0xbc,0x77,0x88,0x99,0x57,0x2e,0x09))
+
+M_14_8 = ((0xff,0xbc,0xd3,0xff,0x94,0x43,0x78,0xdc,0x34,0x8f,0x9c,0x67,0x75,0x68,0x01),
+	  (0xfe,0x79,0xa7,0xff,0x29,0x87,0xf0,0xb8,0x69,0x1e,0x39,0xcf,0xea,0xd0,0x02),
+	  (0xfc,0xf3,0x4e,0xff,0x53,0x0e,0xe1,0x71,0xd3,0x3c,0x72,0x9e,0xd5,0xa1,0x05),
+	  (0xf8,0xe7,0x9d,0xfe,0xa7,0x1c,0xc2,0xe3,0xa6,0x79,0xe4,0x3c,0xab,0x43,0x0b),
+	  (0xf0,0xcf,0x3b,0xfd,0x4f,0x39,0x84,0xc7,0x4d,0xf3,0xc8,0x79,0x56,0x87,0x16),
+	  (0xe0,0x9f,0x77,0xfa,0x9f,0x72,0x08,0x8f,0x9b,0xe6,0x91,0xf3,0xac,0x0e,0x2d),
+	  (0xc0,0x3f,0xef,0xf4,0x3f,0xe5,0x10,0x1e,0x37,0xcd,0x23,0xe7,0x59,0x1d,0x5a),
+	  (0x80,0x7f,0xde,0xe9,0x7f,0xca,0x21,0x3c,0x6e,0x9a,0x47,0xce,0xb3,0x3a,0xb4))
+
+M_14_10 = ((0x39,0xb4,0xc5,0x64,0x41,0x71,0xe9,0xdc,0x14,0x76,0x1f,0x20,0xc4,0xdb,0xb7,0xb4,0x92,0x16,0x00),
+	   (0x72,0x68,0x8b,0xc9,0x82,0xe2,0xd2,0xb9,0x29,0xec,0x3e,0x40,0x88,0xb7,0x6f,0x69,0x25,0x2d,0x00),
+	   (0xe4,0xd0,0x16,0x93,0x05,0xc5,0xa5,0x73,0x53,0xd8,0x7d,0x80,0x10,0x6f,0xdf,0xd2,0x4a,0x5a,0x00),
+	   (0xc8,0xa1,0x2d,0x26,0x0b,0x8a,0x4b,0xe7,0xa6,0xb0,0xfb,0x00,0x21,0xde,0xbe,0xa5,0x95,0xb4,0x00),
+	   (0x90,0x43,0x5b,0x4c,0x16,0x14,0x97,0xce,0x4d,0x61,0xf7,0x01,0x42,0xbc,0x7d,0x4b,0x2b,0x69,0x01),
+	   (0x20,0x87,0xb6,0x98,0x2c,0x28,0x2e,0x9d,0x9b,0xc2,0xee,0x03,0x84,0x78,0xfb,0x96,0x56,0xd2,0x02),
+	   (0x40,0x0e,0x6d,0x31,0x59,0x50,0x5c,0x3a,0x37,0x85,0xdd,0x07,0x08,0xf1,0xf6,0x2d,0xad,0xa4,0x05),
+	   (0x80,0x1c,0xda,0x62,0xb2,0xa0,0xb8,0x74,0x6e,0x0a,0xbb,0x0f,0x10,0xe2,0xed,0x5b,0x5a,0x49,0x0b))
+
+M_14_12 = ((0x09,0xba,0x4b,0x25,0xd5,0xac,0x8b,0x18,0x40,0xfa,0x59,0x74,0xbd,0x76,0x3c,0xaf,0x8e,0x99,0x61,0xd4,0x60,0x01),
+	   (0x12,0x74,0x97,0x4a,0xaa,0x59,0x17,0x31,0x80,0xf4,0xb3,0xe8,0x7a,0xed,0x78,0x5e,0x1d,0x33,0xc3,0xa8,0xc1,0x02),
+	   (0x24,0xe8,0x2e,0x95,0x54,0xb3,0x2e,0x62,0x00,0xe9,0x67,0xd1,0xf5,0xda,0xf1,0xbc,0x3a,0x66,0x86,0x51,0x83,0x05),
+	   (0x48,0xd0,0x5d,0x2a,0xa9,0x66,0x5d,0xc4,0x00,0xd2,0xcf,0xa2,0xeb,0xb5,0xe3,0x79,0x75,0xcc,0x0c,0xa3,0x06,0x0b),
+	   (0x90,0xa0,0xbb,0x54,0x52,0xcd,0xba,0x88,0x01,0xa4,0x9f,0x45,0xd7,0x6b,0xc7,0xf3,0xea,0x98,0x19,0x46,0x0d,0x16),
+	   (0x20,0x41,0x77,0xa9,0xa4,0x9a,0x75,0x11,0x03,0x48,0x3f,0x8b,0xae,0xd7,0x8e,0xe7,0xd5,0x31,0x33,0x8c,0x1a,0x2c),
+	   (0x40,0x82,0xee,0x52,0x49,0x35,0xeb,0x22,0x06,0x90,0x7e,0x16,0x5d,0xaf,0x1d,0xcf,0xab,0x63,0x66,0x18,0x35,0x58),
+	   (0x80,0x04,0xdd,0xa5,0x92,0x6a,0xd6,0x45,0x0c,0x20,0xfd,0x2c,0xba,0x5e,0x3b,0x9e,0x57,0xc7,0xcc,0x30,0x6a,0xb0))
+
+M_14_14 = (
+	(0x99,0xb1,0x75,0x12,0xb5,0xb2,0xee,0x98,0xe1,0x46,0x4a,0x20,0xd7,0xc9,0xfd,0x38,0xff,0x67,0xc8,0xff,0xa6,0xe7,0xcb,0xe5,0x13,0x00),
+	(0x32,0x63,0xeb,0x24,0x6a,0x65,0xdd,0x31,0xc3,0x8d,0x94,0x40,0xae,0x93,0xfb,0x71,0xfe,0xcf,0x90,0xff,0x4d,0xcf,0x97,0xcb,0x27,0x00),
+	(0x64,0xc6,0xd6,0x49,0xd4,0xca,0xba,0x63,0x86,0x1b,0x29,0x81,0x5c,0x27,0xf7,0xe3,0xfc,0x9f,0x21,0xff,0x9b,0x9e,0x2f,0x97,0x4f,0x00),
+	(0xc8,0x8c,0xad,0x93,0xa8,0x95,0x75,0xc7,0x0c,0x37,0x52,0x02,0xb9,0x4e,0xee,0xc7,0xf9,0x3f,0x43,0xfe,0x37,0x3d,0x5f,0x2e,0x9f,0x00),
+	(0x90,0x19,0x5b,0x27,0x51,0x2b,0xeb,0x8e,0x19,0x6e,0xa4,0x04,0x72,0x9d,0xdc,0x8f,0xf3,0x7f,0x86,0xfc,0x6f,0x7a,0xbe,0x5c,0x3e,0x01),
+	(0x20,0x33,0xb6,0x4e,0xa2,0x56,0xd6,0x1d,0x33,0xdc,0x48,0x09,0xe4,0x3a,0xb9,0x1f,0xe7,0xff,0x0c,0xf9,0xdf,0xf4,0x7c,0xb9,0x7c,0x02),
+	(0x40,0x66,0x6c,0x9d,0x44,0xad,0xac,0x3b,0x66,0xb8,0x91,0x12,0xc8,0x75,0x72,0x3f,0xce,0xff,0x19,0xf2,0xbf,0xe9,0xf9,0x72,0xf9,0x04),
+	(0x80,0xcc,0xd8,0x3a,0x89,0x5a,0x59,0x77,0xcc,0x70,0x23,0x25,0x90,0xeb,0xe4,0x7e,0x9c,0xff,0x33,0xe4,0x7f,0xd3,0xf3,0xe5,0xf2,0x09))
+
+M_14_16 = (
+	(0x67,0x48,0x60,0x1c,0xa4,0x8a,0x25,0x51,0x86,0x8a,0x12,0x09,0x34,0xe5,0xfd,
+		0xd7,0x8f,0x87,0x57,0x33,0x44,0x2e,0x6f,0x23,0xab,0x82,0xdd,0xe6,0x01),
+	(0xce,0x90,0xc0,0x38,0x48,0x15,0x4b,0xa2,0x0c,0x15,0x25,0x12,0x68,0xca,0xfb,
+		0xaf,0x1f,0x0f,0xaf,0x66,0x88,0x5c,0xde,0x46,0x56,0x05,0xbb,0xcd,0x03),
+	(0x9c,0x21,0x81,0x71,0x90,0x2a,0x96,0x44,0x19,0x2a,0x4a,0x24,0xd0,0x94,0xf7,
+		0x5f,0x3f,0x1e,0x5e,0xcd,0x10,0xb9,0xbc,0x8d,0xac,0x0a,0x76,0x9b,0x07),
+	(0x38,0x43,0x02,0xe3,0x20,0x55,0x2c,0x89,0x32,0x54,0x94,0x48,0xa0,0x29,0xef,
+		0xbf,0x7e,0x3c,0xbc,0x9a,0x21,0x72,0x79,0x1b,0x59,0x15,0xec,0x36,0x0f),
+	(0x70,0x86,0x04,0xc6,0x41,0xaa,0x58,0x12,0x65,0xa8,0x28,0x91,0x40,0x53,0xde,
+		0x7f,0xfd,0x78,0x78,0x35,0x43,0xe4,0xf2,0x36,0xb2,0x2a,0xd8,0x6d,0x1e),
+	(0xe0,0x0c,0x09,0x8c,0x83,0x54,0xb1,0x24,0xca,0x50,0x51,0x22,0x81,0xa6,0xbc,
+		0xff,0xfa,0xf1,0xf0,0x6a,0x86,0xc8,0xe5,0x6d,0x64,0x55,0xb0,0xdb,0x3c),
+	(0xc0,0x19,0x12,0x18,0x07,0xa9,0x62,0x49,0x94,0xa1,0xa2,0x44,0x02,0x4d,0x79,
+		0xff,0xf5,0xe3,0xe1,0xd5,0x0c,0x91,0xcb,0xdb,0xc8,0xaa,0x60,0xb7,0x79),
+	(0x80,0x33,0x24,0x30,0x0e,0x52,0xc5,0x92,0x28,0x43,0x45,0x89,0x04,0x9a,0xf2,
+		0xfe,0xeb,0xc7,0xc3,0xab,0x19,0x22,0x97,0xb7,0x91,0x55,0xc1,0x6e,0xf3))
+
+M_14_18 = (
+	(0x05,0x2c,0x4b,0x17,0x5e,0x12,0x96,0x3a,0x12,0x8e,0x9d,0x4b,0xcb,0x85,0x8d,
+		0xa5,0x7d,0x91,0x59,0x4e,0x86,0xb6,0x5a,0xca,0xc7,0x0c,0x3f,0x1c,0x20,0xd3,0x7e,0x1a,0x00),
+	(0x0a,0x58,0x96,0x2e,0xbc,0x24,0x2c,0x75,0x24,0x1c,0x3b,0x97,0x96,0x0b,0x1b,
+		0x4b,0xfb,0x22,0xb3,0x9c,0x0c,0x6d,0xb5,0x94,0x8f,0x19,0x7e,0x38,0x40,0xa6,0xfd,0x34,0x00),
+	(0x14,0xb0,0x2c,0x5d,0x78,0x49,0x58,0xea,0x48,0x38,0x76,0x2e,0x2d,0x17,0x36,
+		0x96,0xf6,0x45,0x66,0x39,0x19,0xda,0x6a,0x29,0x1f,0x33,0xfc,0x70,0x80,0x4c,0xfb,0x69,0x00),
+	(0x28,0x60,0x59,0xba,0xf0,0x92,0xb0,0xd4,0x91,0x70,0xec,0x5c,0x5a,0x2e,0x6c,
+		0x2c,0xed,0x8b,0xcc,0x72,0x32,0xb4,0xd5,0x52,0x3e,0x66,0xf8,0xe1,0x00,0x99,0xf6,0xd3,0x00),
+	(0x50,0xc0,0xb2,0x74,0xe1,0x25,0x61,0xa9,0x23,0xe1,0xd8,0xb9,0xb4,0x5c,0xd8,
+		0x58,0xda,0x17,0x99,0xe5,0x64,0x68,0xab,0xa5,0x7c,0xcc,0xf0,0xc3,0x01,0x32,0xed,0xa7,0x01),
+	(0xa0,0x80,0x65,0xe9,0xc2,0x4b,0xc2,0x52,0x47,0xc2,0xb1,0x73,0x69,0xb9,0xb0,
+		0xb1,0xb4,0x2f,0x32,0xcb,0xc9,0xd0,0x56,0x4b,0xf9,0x98,0xe1,0x87,0x03,0x64,0xda,0x4f,0x03),
+	(0x40,0x01,0xcb,0xd2,0x85,0x97,0x84,0xa5,0x8e,0x84,0x63,0xe7,0xd2,0x72,0x61,
+		0x63,0x69,0x5f,0x64,0x96,0x93,0xa1,0xad,0x96,0xf2,0x31,0xc3,0x0f,0x07,0xc8,0xb4,0x9f,0x06),
+	(0x80,0x02,0x96,0xa5,0x0b,0x2f,0x09,0x4b,0x1d,0x09,0xc7,0xce,0xa5,0xe5,0xc2,
+		0xc6,0xd2,0xbe,0xc8,0x2c,0x27,0x43,0x5b,0x2d,0xe5,0x63,0x86,0x1f,0x0e,0x90,0x69,0x3f,0x0d))
+M_14_20 = (
+	(0xe1,0xa2,0x8a,0xab,0x20,0x3f,0xfa,0x57,0x9f,0x6b,0xe5,0x09,0x6b,0xb4,0xc2,0x9a,
+		0x1d,0xaa,0xd3,0xde,0xd7,0x84,0x38,0x7a,0x50,0x9b,0x98,0x15,0xf1,0xd5,0xb5,0x2c,0x13,0x87,0x35,0x01),
+	(0xc2,0x45,0x15,0x57,0x41,0x7e,0xf4,0xaf,0x3e,0xd7,0xca,0x13,0xd6,0x68,0x85,0x35,
+		0x3b,0x54,0xa7,0xbd,0xaf,0x09,0x71,0xf4,0xa0,0x36,0x31,0x2b,0xe2,0xab,0x6b,0x59,0x26,0x0e,0x6b,0x02),
+	(0x84,0x8b,0x2a,0xae,0x82,0xfc,0xe8,0x5f,0x7d,0xae,0x95,0x27,0xac,0xd1,0x0a,0x6b,
+		0x76,0xa8,0x4e,0x7b,0x5f,0x13,0xe2,0xe8,0x41,0x6d,0x62,0x56,0xc4,0x57,0xd7,0xb2,0x4c,0x1c,0xd6,0x04),
+	(0x08,0x17,0x55,0x5c,0x05,0xf9,0xd1,0xbf,0xfa,0x5c,0x2b,0x4f,0x58,0xa3,0x15,0xd6,
+		0xec,0x50,0x9d,0xf6,0xbe,0x26,0xc4,0xd1,0x83,0xda,0xc4,0xac,0x88,0xaf,0xae,0x65,0x99,0x38,0xac,0x09),
+	(0x10,0x2e,0xaa,0xb8,0x0a,0xf2,0xa3,0x7f,0xf5,0xb9,0x56,0x9e,0xb0,0x46,0x2b,0xac,
+		0xd9,0xa1,0x3a,0xed,0x7d,0x4d,0x88,0xa3,0x07,0xb5,0x89,0x59,0x11,0x5f,0x5d,0xcb,0x32,0x71,0x58,0x13),
+	(0x20,0x5c,0x54,0x71,0x15,0xe4,0x47,0xff,0xea,0x73,0xad,0x3c,0x61,0x8d,0x56,0x58,
+		0xb3,0x43,0x75,0xda,0xfb,0x9a,0x10,0x47,0x0f,0x6a,0x13,0xb3,0x22,0xbe,0xba,0x96,0x65,0xe2,0xb0,0x26),
+	(0x40,0xb8,0xa8,0xe2,0x2a,0xc8,0x8f,0xfe,0xd5,0xe7,0x5a,0x79,0xc2,0x1a,0xad,0xb0,
+		0x66,0x87,0xea,0xb4,0xf7,0x35,0x21,0x8e,0x1e,0xd4,0x26,0x66,0x45,0x7c,0x75,0x2d,0xcb,0xc4,0x61,0x4d),
+	(0x80,0x70,0x51,0xc5,0x55,0x90,0x1f,0xfd,0xab,0xcf,0xb5,0xf2,0x84,0x35,0x5a,0x61,
+		0xcd,0x0e,0xd5,0x69,0xef,0x6b,0x42,0x1c,0x3d,0xa8,0x4d,0xcc,0x8a,0xf8,0xea,0x5a,0x96,0x89,0xc3,0x9a))
+
+M_14_22 = (
+	(0x33,0xdb,0xdc,0x30,0x9c,0xe3,0xd0,0x5d,0x4f,0xfe,0x2f,0x46,0xe6,0x42,0xf9,0x14,0x3b,0xbf,
+		0x84,0xff,0xc6,0x12,0xc8,0x8e,0x88,0x2d,0x62,0xf7,0xd7,0xdf,0x4a,0xfa,0x92,0x8a,0xd6,0x0c,0xb3,0xc9,0x13,0x00),
+	(0x66,0xb6,0xb9,0x61,0x38,0xc7,0xa1,0xbb,0x9e,0xfc,0x5f,0x8c,0xcc,0x85,0xf2,0x29,0x76,0x7e,
+		0x09,0xff,0x8d,0x25,0x90,0x1d,0x11,0x5b,0xc4,0xee,0xaf,0xbf,0x95,0xf4,0x25,0x15,0xad,0x19,0x66,0x93,0x27,0x00),
+	(0xcc,0x6c,0x73,0xc3,0x70,0x8e,0x43,0x77,0x3d,0xf9,0xbf,0x18,0x99,0x0b,0xe5,0x53,0xec,0xfc,
+		0x12,0xfe,0x1b,0x4b,0x20,0x3b,0x22,0xb6,0x88,0xdd,0x5f,0x7f,0x2b,0xe9,0x4b,0x2a,0x5a,0x33,0xcc,0x26,0x4f,0x00),
+	(0x98,0xd9,0xe6,0x86,0xe1,0x1c,0x87,0xee,0x7a,0xf2,0x7f,0x31,0x32,0x17,0xca,0xa7,0xd8,0xf9,
+		0x25,0xfc,0x37,0x96,0x40,0x76,0x44,0x6c,0x11,0xbb,0xbf,0xfe,0x56,0xd2,0x97,0x54,0xb4,0x66,0x98,0x4d,0x9e,0x00),
+	(0x30,0xb3,0xcd,0x0d,0xc3,0x39,0x0e,0xdd,0xf5,0xe4,0xff,0x62,0x64,0x2e,0x94,0x4f,0xb1,0xf3,
+		0x4b,0xf8,0x6f,0x2c,0x81,0xec,0x88,0xd8,0x22,0x76,0x7f,0xfd,0xad,0xa4,0x2f,0xa9,0x68,0xcd,0x30,0x9b,0x3c,0x01),
+	(0x60,0x66,0x9b,0x1b,0x86,0x73,0x1c,0xba,0xeb,0xc9,0xff,0xc5,0xc8,0x5c,0x28,0x9f,0x62,0xe7,
+		0x97,0xf0,0xdf,0x58,0x02,0xd9,0x11,0xb1,0x45,0xec,0xfe,0xfa,0x5b,0x49,0x5f,0x52,0xd1,0x9a,0x61,0x36,0x79,0x02),
+	(0xc0,0xcc,0x36,0x37,0x0c,0xe7,0x38,0x74,0xd7,0x93,0xff,0x8b,0x91,0xb9,0x50,0x3e,0xc5,0xce,
+		0x2f,0xe1,0xbf,0xb1,0x04,0xb2,0x23,0x62,0x8b,0xd8,0xfd,0xf5,0xb7,0x92,0xbe,0xa4,0xa2,0x35,0xc3,0x6c,0xf2,0x04),
+	(0x80,0x99,0x6d,0x6e,0x18,0xce,0x71,0xe8,0xae,0x27,0xff,0x17,0x23,0x73,0xa1,0x7c,0x8a,0x9d,
+		0x5f,0xc2,0x7f,0x63,0x09,0x64,0x47,0xc4,0x16,0xb1,0xfb,0xeb,0x6f,0x25,0x7d,0x49,0x45,0x6b,0x86,0xd9,0xe4,0x09))
+
+M_14_24 = (
+	(0xe3,0x52,0x0e,0x48,0x62,0x13,0x72,0xa9,0x45,0x49,0x9d,0x16,0x6f,0x37,0x17,0x32,0xfe,0x9c,0xe1,0xe2,
+		0x62,0xc9,0x86,0x96,0x28,0x92,0x8b,0x0b,0x24,0xb4,0x17,0xaa,0xed,0xa0,0x25,0x93,0xb2,0x58,0xad,0x57,0x18,0xee,0x01),
+	(0xc6,0xa5,0x1c,0x90,0xc4,0x26,0xe4,0x52,0x8b,0x92,0x3a,0x2d,0xde,0x6e,0x2e,0x64,0xfc,0x39,0xc3,0xc5,
+		0xc5,0x92,0x0d,0x2d,0x51,0x24,0x17,0x17,0x48,0x68,0x2f,0x54,0xdb,0x41,0x4b,0x26,0x65,0xb1,0x5a,0xaf,0x30,0xdc,0x03),
+	(0x8c,0x4b,0x39,0x20,0x89,0x4d,0xc8,0xa5,0x16,0x25,0x75,0x5a,0xbc,0xdd,0x5c,0xc8,0xf8,0x73,0x86,0x8b,
+		0x8b,0x25,0x1b,0x5a,0xa2,0x48,0x2e,0x2e,0x90,0xd0,0x5e,0xa8,0xb6,0x83,0x96,0x4c,0xca,0x62,0xb5,0x5e,0x61,0xb8,0x07),
+	(0x18,0x97,0x72,0x40,0x12,0x9b,0x90,0x4b,0x2d,0x4a,0xea,0xb4,0x78,0xbb,0xb9,0x90,0xf1,0xe7,0x0c,0x17,
+		0x17,0x4b,0x36,0xb4,0x44,0x91,0x5c,0x5c,0x20,0xa1,0xbd,0x50,0x6d,0x07,0x2d,0x99,0x94,0xc5,0x6a,0xbd,0xc2,0x70,0x0f),
+	(0x30,0x2e,0xe5,0x80,0x24,0x36,0x21,0x97,0x5a,0x94,0xd4,0x69,0xf1,0x76,0x73,0x21,0xe3,0xcf,0x19,0x2e,
+		0x2e,0x96,0x6c,0x68,0x89,0x22,0xb9,0xb8,0x40,0x42,0x7b,0xa1,0xda,0x0e,0x5a,0x32,0x29,0x8b,0xd5,0x7a,0x85,0xe1,0x1e),
+	(0x60,0x5c,0xca,0x01,0x49,0x6c,0x42,0x2e,0xb5,0x28,0xa9,0xd3,0xe2,0xed,0xe6,0x42,0xc6,0x9f,0x33,0x5c,
+		0x5c,0x2c,0xd9,0xd0,0x12,0x45,0x72,0x71,0x81,0x84,0xf6,0x42,0xb5,0x1d,0xb4,0x64,0x52,0x16,0xab,0xf5,0x0a,0xc3,0x3d),
+	(0xc0,0xb8,0x94,0x03,0x92,0xd8,0x84,0x5c,0x6a,0x51,0x52,0xa7,0xc5,0xdb,0xcd,0x85,0x8c,0x3f,0x67,0xb8,
+		0xb8,0x58,0xb2,0xa1,0x25,0x8a,0xe4,0xe2,0x02,0x09,0xed,0x85,0x6a,0x3b,0x68,0xc9,0xa4,0x2c,0x56,0xeb,0x15,0x86,0x7b),
+	(0x80,0x71,0x29,0x07,0x24,0xb1,0x09,0xb9,0xd4,0xa2,0xa4,0x4e,0x8b,0xb7,0x9b,0x0b,0x19,0x7f,0xce,0x70,
+		0x71,0xb1,0x64,0x43,0x4b,0x14,0xc9,0xc5,0x05,0x12,0xda,0x0b,0xd5,0x76,0xd0,0x92,0x49,0x59,0xac,0xd6,0x2b,0x0c,0xf7))
+
+M_14_28 = (
+	(0x71,0x5c,0xcd,0xf7,0x4c,0x41,0x3d,0x9b,0xa0,0x5e,0x93,0x46,0x1b,0x6e,0x2d,0x27,0xe6,0x50,
+		0xd8,0xf6,0x31,0x0c,0x17,0xdc,0xee,0x29,0xf5,0x71,0x0a,0x34,0xb7,0xa8,0x40,0x3a,0xe1,
+		0xc9,0x00,0xfb,0x50,0xd3,0x64,0x27,0x9f,0xe9,0x2f,0x15,0xed,0x99,0x19,0x01),
+	(0xe2,0xb8,0x9a,0xef,0x99,0x82,0x7a,0x36,0x41,0xbd,0x26,0x8d,0x36,0xdc,0x5a,0x4e,0xcc,0xa1,
+		0xb0,0xed,0x63,0x18,0x2e,0xb8,0xdd,0x53,0xea,0xe3,0x14,0x68,0x6e,0x51,0x81,0x74,0xc2,
+		0x93,0x01,0xf6,0xa1,0xa6,0xc9,0x4e,0x3e,0xd3,0x5f,0x2a,0xda,0x33,0x33,0x02),
+	(0xc4,0x71,0x35,0xdf,0x33,0x05,0xf5,0x6c,0x82,0x7a,0x4d,0x1a,0x6d,0xb8,0xb5,0x9c,0x98,0x43,
+		0x61,0xdb,0xc7,0x30,0x5c,0x70,0xbb,0xa7,0xd4,0xc7,0x29,0xd0,0xdc,0xa2,0x02,0xe9,0x84,
+		0x27,0x03,0xec,0x43,0x4d,0x93,0x9d,0x7c,0xa6,0xbf,0x54,0xb4,0x67,0x66,0x04),
+	(0x88,0xe3,0x6a,0xbe,0x67,0x0a,0xea,0xd9,0x04,0xf5,0x9a,0x34,0xda,0x70,0x6b,0x39,0x31,0x87,
+		0xc2,0xb6,0x8f,0x61,0xb8,0xe0,0x76,0x4f,0xa9,0x8f,0x53,0xa0,0xb9,0x45,0x05,0xd2,0x09,
+		0x4f,0x06,0xd8,0x87,0x9a,0x26,0x3b,0xf9,0x4c,0x7f,0xa9,0x68,0xcf,0xcc,0x08),
+	(0x10,0xc7,0xd5,0x7c,0xcf,0x14,0xd4,0xb3,0x09,0xea,0x35,0x69,0xb4,0xe1,0xd6,0x72,0x62,0x0e,
+		0x85,0x6d,0x1f,0xc3,0x70,0xc1,0xed,0x9e,0x52,0x1f,0xa7,0x40,0x73,0x8b,0x0a,0xa4,0x13,
+		0x9e,0x0c,0xb0,0x0f,0x35,0x4d,0x76,0xf2,0x99,0xfe,0x52,0xd1,0x9e,0x99,0x11),
+	(0x20,0x8e,0xab,0xf9,0x9e,0x29,0xa8,0x67,0x13,0xd4,0x6b,0xd2,0x68,0xc3,0xad,0xe5,0xc4,0x1c,
+		0x0a,0xdb,0x3e,0x86,0xe1,0x82,0xdb,0x3d,0xa5,0x3e,0x4e,0x81,0xe6,0x16,0x15,0x48,0x27,
+		0x3c,0x19,0x60,0x1f,0x6a,0x9a,0xec,0xe4,0x33,0xfd,0xa5,0xa2,0x3d,0x33,0x23),
+	(0x40,0x1c,0x57,0xf3,0x3d,0x53,0x50,0xcf,0x26,0xa8,0xd7,0xa4,0xd1,0x86,0x5b,0xcb,0x89,0x39,
+		0x14,0xb6,0x7d,0x0c,0xc3,0x05,0xb7,0x7b,0x4a,0x7d,0x9c,0x02,0xcd,0x2d,0x2a,0x90,0x4e,
+		0x78,0x32,0xc0,0x3e,0xd4,0x34,0xd9,0xc9,0x67,0xfa,0x4b,0x45,0x7b,0x66,0x46),
+	(0x80,0x38,0xae,0xe6,0x7b,0xa6,0xa0,0x9e,0x4d,0x50,0xaf,0x49,0xa3,0x0d,0xb7,0x96,0x13,0x73,
+		0x28,0x6c,0xfb,0x18,0x86,0x0b,0x6e,0xf7,0x94,0xfa,0x38,0x05,0x9a,0x5b,0x54,0x20,0x9d,
+		0xf0,0x64,0x80,0x7d,0xa8,0x69,0xb2,0x93,0xcf,0xf4,0x97,0x8a,0xf6,0xcc,0x8c))
+
+M_14_32 = (
+	(0xe9,0xad,0x1d,0x01,0x8d,0x7a,0xce,0xe3,0x9d,0xea,0x5f,0x5b,0x0b,0xc1,0x33,0x1b,0x1e,0xc4,0xeb,
+		0x8d,0x56,0x0a,0x03,0xb3,0x6c,0x36,0x35,0x60,0xc7,0x66,0xdc,0x33,0x1f,0xb7,0x9a,0x24,0x75,0x5c,0xf9,
+		0x64,0xdb,0x1e,0x71,0x7a,0xfd,0x91,0x36,0x72,0xfd,0xf0,0xa3,0xab,0x90,0xf2,0xf1,0x13,0x01),
+	(0xd2,0x5b,0x3b,0x02,0x1a,0xf5,0x9c,0xc7,0x3b,0xd5,0xbf,0xb6,0x16,0x82,0x67,0x36,0x3c,0x88,0xd7,
+		0x1b,0xad,0x14,0x06,0x66,0xd9,0x6c,0x6a,0xc0,0x8e,0xcd,0xb8,0x67,0x3e,0x6e,0x35,0x49,0xea,0xb8,0xf2,
+		0xc9,0xb6,0x3d,0xe2,0xf4,0xfa,0x23,0x6d,0xe4,0xfa,0xe1,0x47,0x57,0x21,0xe5,0xe3,0x27,0x02),
+	(0xa4,0xb7,0x76,0x04,0x34,0xea,0x39,0x8f,0x77,0xaa,0x7f,0x6d,0x2d,0x04,0xcf,0x6c,0x78,0x10,0xaf,
+		0x37,0x5a,0x29,0x0c,0xcc,0xb2,0xd9,0xd4,0x80,0x1d,0x9b,0x71,0xcf,0x7c,0xdc,0x6a,0x92,0xd4,0x71,0xe5,
+		0x93,0x6d,0x7b,0xc4,0xe9,0xf5,0x47,0xda,0xc8,0xf5,0xc3,0x8f,0xae,0x42,0xca,0xc7,0x4f,0x04),
+	(0x48,0x6f,0xed,0x08,0x68,0xd4,0x73,0x1e,0xef,0x54,0xff,0xda,0x5a,0x08,0x9e,0xd9,0xf0,0x20,0x5e,
+		0x6f,0xb4,0x52,0x18,0x98,0x65,0xb3,0xa9,0x01,0x3b,0x36,0xe3,0x9e,0xf9,0xb8,0xd5,0x24,0xa9,0xe3,0xca,
+		0x27,0xdb,0xf6,0x88,0xd3,0xeb,0x8f,0xb4,0x91,0xeb,0x87,0x1f,0x5d,0x85,0x94,0x8f,0x9f,0x08),
+	(0x90,0xde,0xda,0x11,0xd0,0xa8,0xe7,0x3c,0xde,0xa9,0xfe,0xb5,0xb5,0x10,0x3c,0xb3,0xe1,0x41,0xbc,
+		0xde,0x68,0xa5,0x30,0x30,0xcb,0x66,0x53,0x03,0x76,0x6c,0xc6,0x3d,0xf3,0x71,0xab,0x49,0x52,0xc7,0x95,
+		0x4f,0xb6,0xed,0x11,0xa7,0xd7,0x1f,0x69,0x23,0xd7,0x0f,0x3f,0xba,0x0a,0x29,0x1f,0x3f,0x11),
+	(0x20,0xbd,0xb5,0x23,0xa0,0x51,0xcf,0x79,0xbc,0x53,0xfd,0x6b,0x6b,0x21,0x78,0x66,0xc3,0x83,0x78,
+		0xbd,0xd1,0x4a,0x61,0x60,0x96,0xcd,0xa6,0x06,0xec,0xd8,0x8c,0x7b,0xe6,0xe3,0x56,0x93,0xa4,0x8e,0x2b,
+		0x9f,0x6c,0xdb,0x23,0x4e,0xaf,0x3f,0xd2,0x46,0xae,0x1f,0x7e,0x74,0x15,0x52,0x3e,0x7e,0x22),
+	(0x40,0x7a,0x6b,0x47,0x40,0xa3,0x9e,0xf3,0x78,0xa7,0xfa,0xd7,0xd6,0x42,0xf0,0xcc,0x86,0x07,0xf1,
+		0x7a,0xa3,0x95,0xc2,0xc0,0x2c,0x9b,0x4d,0x0d,0xd8,0xb1,0x19,0xf7,0xcc,0xc7,0xad,0x26,0x49,0x1d,0x57,
+		0x3e,0xd9,0xb6,0x47,0x9c,0x5e,0x7f,0xa4,0x8d,0x5c,0x3f,0xfc,0xe8,0x2a,0xa4,0x7c,0xfc,0x44),
+	(0x80,0xf4,0xd6,0x8e,0x80,0x46,0x3d,0xe7,0xf1,0x4e,0xf5,0xaf,0xad,0x85,0xe0,0x99,0x0d,0x0f,0xe2,
+		0xf5,0x46,0x2b,0x85,0x81,0x59,0x36,0x9b,0x1a,0xb0,0x63,0x33,0xee,0x99,0x8f,0x5b,0x4d,0x92,0x3a,0xae,
+		0x7c,0xb2,0x6d,0x8f,0x38,0xbd,0xfe,0x48,0x1b,0xb9,0x7e,0xf8,0xd1,0x55,0x48,0xf9,0xf8,0x89))
+
+M_14_36 = (
+	(0x0b,0x60,0xbf,0x81,0x57,0x76,0xb3,0x6c,0xaa,0xd3,0xb7,0xc1,0x3b,0xf7,0x8f,0x6c,0xef,0x2a,0x35,0x63,
+		0x0c,0xad,0xc0,0xdb,0x40,0x49,0x27,0x9c,0x40,0x1f,0xfc,0x83,0xe4,0x85,0x3f,0x75,0x0b,0x7f,0x60,0x3c,0x73,
+		0xcd,0x64,0x3c,0x0d,0xd9,0xf2,0x17,0xf0,0x3e,0x1c,0xe4,0x3c,0xe4,0xa1,0x9e,0xba,0x51,0xd5,0xfd,0x09,0x56,0x6c,0x01),
+	(0x16,0xc0,0x7e,0x03,0xaf,0xec,0x66,0xd9,0x54,0xa7,0x6f,0x83,0x77,0xee,0x1f,0xd9,0xde,0x55,0x6a,0xc6,
+		0x18,0x5a,0x81,0xb7,0x81,0x92,0x4e,0x38,0x81,0x3e,0xf8,0x07,0xc9,0x0b,0x7f,0xea,0x16,0xfe,0xc0,0x78,0xe6,
+		0x9a,0xc9,0x78,0x1a,0xb2,0xe5,0x2f,0xe0,0x7d,0x38,0xc8,0x79,0xc8,0x43,0x3d,0x75,0xa3,0xaa,0xfb,0x13,0xac,0xd8,0x02),
+	(0x2c,0x80,0xfd,0x06,0x5e,0xd9,0xcd,0xb2,0xa9,0x4e,0xdf,0x06,0xef,0xdc,0x3f,0xb2,0xbd,0xab,0xd4,0x8c,
+		0x31,0xb4,0x02,0x6f,0x03,0x25,0x9d,0x70,0x02,0x7d,0xf0,0x0f,0x92,0x17,0xfe,0xd4,0x2d,0xfc,0x81,0xf1,0xcc,
+		0x35,0x93,0xf1,0x34,0x64,0xcb,0x5f,0xc0,0xfb,0x70,0x90,0xf3,0x90,0x87,0x7a,0xea,0x46,0x55,0xf7,0x27,0x58,0xb1,0x05),
+	(0x58,0x00,0xfb,0x0d,0xbc,0xb2,0x9b,0x65,0x53,0x9d,0xbe,0x0d,0xde,0xb9,0x7f,0x64,0x7b,0x57,0xa9,0x19,
+		0x63,0x68,0x05,0xde,0x06,0x4a,0x3a,0xe1,0x04,0xfa,0xe0,0x1f,0x24,0x2f,0xfc,0xa9,0x5b,0xf8,0x03,0xe3,0x99,
+		0x6b,0x26,0xe3,0x69,0xc8,0x96,0xbf,0x80,0xf7,0xe1,0x20,0xe7,0x21,0x0f,0xf5,0xd4,0x8d,0xaa,0xee,0x4f,0xb0,0x62,0x0b),
+	(0xb0,0x00,0xf6,0x1b,0x78,0x65,0x37,0xcb,0xa6,0x3a,0x7d,0x1b,0xbc,0x73,0xff,0xc8,0xf6,0xae,0x52,0x33,
+		0xc6,0xd0,0x0a,0xbc,0x0d,0x94,0x74,0xc2,0x09,0xf4,0xc1,0x3f,0x48,0x5e,0xf8,0x53,0xb7,0xf0,0x07,0xc6,0x33,
+		0xd7,0x4c,0xc6,0xd3,0x90,0x2d,0x7f,0x01,0xef,0xc3,0x41,0xce,0x43,0x1e,0xea,0xa9,0x1b,0x55,0xdd,0x9f,0x60,0xc5,0x16),
+	(0x60,0x01,0xec,0x37,0xf0,0xca,0x6e,0x96,0x4d,0x75,0xfa,0x36,0x78,0xe7,0xfe,0x91,0xed,0x5d,0xa5,0x66,
+		0x8c,0xa1,0x15,0x78,0x1b,0x28,0xe9,0x84,0x13,0xe8,0x83,0x7f,0x90,0xbc,0xf0,0xa7,0x6e,0xe1,0x0f,0x8c,0x67,
+		0xae,0x99,0x8c,0xa7,0x21,0x5b,0xfe,0x02,0xde,0x87,0x83,0x9c,0x87,0x3c,0xd4,0x53,0x37,0xaa,0xba,0x3f,0xc1,0x8a,0x2d),
+	(0xc0,0x02,0xd8,0x6f,0xe0,0x95,0xdd,0x2c,0x9b,0xea,0xf4,0x6d,0xf0,0xce,0xfd,0x23,0xdb,0xbb,0x4a,0xcd,
+		0x18,0x43,0x2b,0xf0,0x36,0x50,0xd2,0x09,0x27,0xd0,0x07,0xff,0x20,0x79,0xe1,0x4f,0xdd,0xc2,0x1f,0x18,0xcf,
+		0x5c,0x33,0x19,0x4f,0x43,0xb6,0xfc,0x05,0xbc,0x0f,0x07,0x39,0x0f,0x79,0xa8,0xa7,0x6e,0x54,0x75,0x7f,0x82,0x15,0x5b),
+	(0x80,0x05,0xb0,0xdf,0xc0,0x2b,0xbb,0x59,0x36,0xd5,0xe9,0xdb,0xe0,0x9d,0xfb,0x47,0xb6,0x77,0x95,0x9a,
+		0x31,0x86,0x56,0xe0,0x6d,0xa0,0xa4,0x13,0x4e,0xa0,0x0f,0xfe,0x41,0xf2,0xc2,0x9f,0xba,0x85,0x3f,0x30,0x9e,
+		0xb9,0x66,0x32,0x9e,0x86,0x6c,0xf9,0x0b,0x78,0x1f,0x0e,0x72,0x1e,0xf2,0x50,0x4f,0xdd,0xa8,0xea,0xfe,0x04,0x2b,0xb6))
+
+M_14_40 = (
+	(0x07,0xfc,0x23,0x1b,0x0b,0x76,0x74,0xd3,0x0c,0xf3,0x99,0x16,0x24,0xcd,0x55,0xde,0xf6,0x72,0xe5,0x93,
+		0x5f,0xc9,0xef,0x51,0xee,0x1b,0x7e,0x95,0x33,0x51,0x2b,0x68,0x66,0x93,0x54,0x29,0x02,0x18,0xc4,0x7d,
+		0xef,0xf8,0x99,0xa3,0x34,0x6f,0xf4,0x8b,0x10,0xea,0x8f,0xee,0xf7,0xeb,0x96,0x44,0xf6,0x19,0x65,0x4b,
+		0xc1,0x8d,0xda,0x49,0x0a,0x80,0x72,0xee,0x69,0x07,0x01),
+	(0x0e,0xf8,0x47,0x36,0x16,0xec,0xe8,0xa6,0x19,0xe6,0x33,0x2d,0x48,0x9a,0xab,0xbc,0xed,0xe5,0xca,0x27,
+		0xbf,0x92,0xdf,0xa3,0xdc,0x37,0xfc,0x2a,0x67,0xa2,0x56,0xd0,0xcc,0x26,0xa9,0x52,0x04,0x30,0x88,0xfb,
+		0xde,0xf1,0x33,0x47,0x69,0xde,0xe8,0x17,0x21,0xd4,0x1f,0xdd,0xef,0xd7,0x2d,0x89,0xec,0x33,0xca,0x96,
+		0x82,0x1b,0xb5,0x93,0x14,0x00,0xe5,0xdc,0xd3,0x0e,0x02),
+	(0x1c,0xf0,0x8f,0x6c,0x2c,0xd8,0xd1,0x4d,0x33,0xcc,0x67,0x5a,0x90,0x34,0x57,0x79,0xdb,0xcb,0x95,0x4f,
+		0x7e,0x25,0xbf,0x47,0xb9,0x6f,0xf8,0x55,0xce,0x44,0xad,0xa0,0x99,0x4d,0x52,0xa5,0x08,0x60,0x10,0xf7,
+		0xbd,0xe3,0x67,0x8e,0xd2,0xbc,0xd1,0x2f,0x42,0xa8,0x3f,0xba,0xdf,0xaf,0x5b,0x12,0xd9,0x67,0x94,0x2d,
+		0x05,0x37,0x6a,0x27,0x29,0x00,0xca,0xb9,0xa7,0x1d,0x04),
+	(0x38,0xe0,0x1f,0xd9,0x58,0xb0,0xa3,0x9b,0x66,0x98,0xcf,0xb4,0x20,0x69,0xae,0xf2,0xb6,0x97,0x2b,0x9f,
+		0xfc,0x4a,0x7e,0x8f,0x72,0xdf,0xf0,0xab,0x9c,0x89,0x5a,0x41,0x33,0x9b,0xa4,0x4a,0x11,0xc0,0x20,0xee,
+		0x7b,0xc7,0xcf,0x1c,0xa5,0x79,0xa3,0x5f,0x84,0x50,0x7f,0x74,0xbf,0x5f,0xb7,0x24,0xb2,0xcf,0x28,0x5b,
+		0x0a,0x6e,0xd4,0x4e,0x52,0x00,0x94,0x73,0x4f,0x3b,0x08),
+	(0x70,0xc0,0x3f,0xb2,0xb1,0x60,0x47,0x37,0xcd,0x30,0x9f,0x69,0x41,0xd2,0x5c,0xe5,0x6d,0x2f,0x57,0x3e,
+		0xf9,0x95,0xfc,0x1e,0xe5,0xbe,0xe1,0x57,0x39,0x13,0xb5,0x82,0x66,0x36,0x49,0x95,0x22,0x80,0x41,0xdc,
+		0xf7,0x8e,0x9f,0x39,0x4a,0xf3,0x46,0xbf,0x08,0xa1,0xfe,0xe8,0x7e,0xbf,0x6e,0x49,0x64,0x9f,0x51,0xb6,
+		0x14,0xdc,0xa8,0x9d,0xa4,0x00,0x28,0xe7,0x9e,0x76,0x10),
+	(0xe0,0x80,0x7f,0x64,0x63,0xc1,0x8e,0x6e,0x9a,0x61,0x3e,0xd3,0x82,0xa4,0xb9,0xca,0xdb,0x5e,0xae,0x7c,
+		0xf2,0x2b,0xf9,0x3d,0xca,0x7d,0xc3,0xaf,0x72,0x26,0x6a,0x05,0xcd,0x6c,0x92,0x2a,0x45,0x00,0x83,0xb8,
+		0xef,0x1d,0x3f,0x73,0x94,0xe6,0x8d,0x7e,0x11,0x42,0xfd,0xd1,0xfd,0x7e,0xdd,0x92,0xc8,0x3e,0xa3,0x6c,
+		0x29,0xb8,0x51,0x3b,0x49,0x01,0x50,0xce,0x3d,0xed,0x20),
+	(0xc0,0x01,0xff,0xc8,0xc6,0x82,0x1d,0xdd,0x34,0xc3,0x7c,0xa6,0x05,0x49,0x73,0x95,0xb7,0xbd,0x5c,0xf9,
+		0xe4,0x57,0xf2,0x7b,0x94,0xfb,0x86,0x5f,0xe5,0x4c,0xd4,0x0a,0x9a,0xd9,0x24,0x55,0x8a,0x00,0x06,0x71,
+		0xdf,0x3b,0x7e,0xe6,0x28,0xcd,0x1b,0xfd,0x22,0x84,0xfa,0xa3,0xfb,0xfd,0xba,0x25,0x91,0x7d,0x46,0xd9,
+		0x52,0x70,0xa3,0x76,0x92,0x02,0xa0,0x9c,0x7b,0xda,0x41),
+	(0x80,0x03,0xfe,0x91,0x8d,0x05,0x3b,0xba,0x69,0x86,0xf9,0x4c,0x0b,0x92,0xe6,0x2a,0x6f,0x7b,0xb9,0xf2,
+		0xc9,0xaf,0xe4,0xf7,0x28,0xf7,0x0d,0xbf,0xca,0x99,0xa8,0x15,0x34,0xb3,0x49,0xaa,0x14,0x01,0x0c,0xe2,
+		0xbe,0x77,0xfc,0xcc,0x51,0x9a,0x37,0xfa,0x45,0x08,0xf5,0x47,0xf7,0xfb,0x75,0x4b,0x22,0xfb,0x8c,0xb2,
+		0xa5,0xe0,0x46,0xed,0x24,0x05,0x40,0x39,0xf7,0xb4,0x83))
+
+M_14_44 = (
+	(0x7d,0xa2,0x90,0xd1,0x9e,0x20,0xfb,0xa2,0xfc,0xec,0x54,0xbe,0xe8,0x7c,0xc7,0xcf,0x35,0xe2,0x9e,0x88,
+		0xbb,0x90,0x85,0x87,0xb0,0xce,0x13,0x68,0xe7,0xa1,0xfc,0xd7,0xe0,0x8b,0x65,0x5a,0xad,0xf2,0xfd,0x0c,
+		0x14,0x48,0x8c,0xa1,0x2c,0x93,0xc1,0xac,0x2c,0x90,0x73,0x0e,0xe7,0xcb,0xf9,0x3c,0xef,0xb4,0xd8,0x6e,
+		0x6e,0xed,0x5a,0x44,0xe9,0xde,0x74,0xfc,0xec,0x76,0x29,0xcb,0x9d,0x46,0x3a,0xd9,0x98,0x01),
+	(0xfa,0x44,0x21,0xa3,0x3d,0x41,0xf6,0x45,0xf9,0xd9,0xa9,0x7c,0xd1,0xf9,0x8e,0x9f,0x6b,0xc4,0x3d,0x11,
+		0x77,0x21,0x0b,0x0f,0x61,0x9d,0x27,0xd0,0xce,0x43,0xf9,0xaf,0xc1,0x17,0xcb,0xb4,0x5a,0xe5,0xfb,0x19,
+		0x28,0x90,0x18,0x43,0x59,0x26,0x83,0x59,0x59,0x20,0xe7,0x1c,0xce,0x97,0xf3,0x79,0xde,0x69,0xb1,0xdd,
+		0xdc,0xda,0xb5,0x88,0xd2,0xbd,0xe9,0xf8,0xd9,0xed,0x52,0x96,0x3b,0x8d,0x74,0xb2,0x31,0x03),
+	(0xf4,0x89,0x42,0x46,0x7b,0x82,0xec,0x8b,0xf2,0xb3,0x53,0xf9,0xa2,0xf3,0x1d,0x3f,0xd7,0x88,0x7b,0x22,
+		0xee,0x42,0x16,0x1e,0xc2,0x3a,0x4f,0xa0,0x9d,0x87,0xf2,0x5f,0x83,0x2f,0x96,0x69,0xb5,0xca,0xf7,0x33,
+		0x50,0x20,0x31,0x86,0xb2,0x4c,0x06,0xb3,0xb2,0x40,0xce,0x39,0x9c,0x2f,0xe7,0xf3,0xbc,0xd3,0x62,0xbb,
+		0xb9,0xb5,0x6b,0x11,0xa5,0x7b,0xd3,0xf1,0xb3,0xdb,0xa5,0x2c,0x77,0x1a,0xe9,0x64,0x63,0x06),
+	(0xe8,0x13,0x85,0x8c,0xf6,0x04,0xd9,0x17,0xe5,0x67,0xa7,0xf2,0x45,0xe7,0x3b,0x7e,0xae,0x11,0xf7,0x44,
+		0xdc,0x85,0x2c,0x3c,0x84,0x75,0x9e,0x40,0x3b,0x0f,0xe5,0xbf,0x06,0x5f,0x2c,0xd3,0x6a,0x95,0xef,0x67,
+		0xa0,0x40,0x62,0x0c,0x65,0x99,0x0c,0x66,0x65,0x81,0x9c,0x73,0x38,0x5f,0xce,0xe7,0x79,0xa7,0xc5,0x76,
+		0x73,0x6b,0xd7,0x22,0x4a,0xf7,0xa6,0xe3,0x67,0xb7,0x4b,0x59,0xee,0x34,0xd2,0xc9,0xc6,0x0c),
+	(0xd0,0x27,0x0a,0x19,0xed,0x09,0xb2,0x2f,0xca,0xcf,0x4e,0xe5,0x8b,0xce,0x77,0xfc,0x5c,0x23,0xee,0x89,
+		0xb8,0x0b,0x59,0x78,0x08,0xeb,0x3c,0x81,0x76,0x1e,0xca,0x7f,0x0d,0xbe,0x58,0xa6,0xd5,0x2a,0xdf,0xcf,
+		0x40,0x81,0xc4,0x18,0xca,0x32,0x19,0xcc,0xca,0x02,0x39,0xe7,0x70,0xbe,0x9c,0xcf,0xf3,0x4e,0x8b,0xed,
+		0xe6,0xd6,0xae,0x45,0x94,0xee,0x4d,0xc7,0xcf,0x6e,0x97,0xb2,0xdc,0x69,0xa4,0x93,0x8d,0x19),
+	(0xa0,0x4f,0x14,0x32,0xda,0x13,0x64,0x5f,0x94,0x9f,0x9d,0xca,0x17,0x9d,0xef,0xf8,0xb9,0x46,0xdc,0x13,
+		0x71,0x17,0xb2,0xf0,0x10,0xd6,0x79,0x02,0xed,0x3c,0x94,0xff,0x1a,0x7c,0xb1,0x4c,0xab,0x55,0xbe,0x9f,
+		0x81,0x02,0x89,0x31,0x94,0x65,0x32,0x98,0x95,0x05,0x72,0xce,0xe1,0x7c,0x39,0x9f,0xe7,0x9d,0x16,0xdb,
+		0xcd,0xad,0x5d,0x8b,0x28,0xdd,0x9b,0x8e,0x9f,0xdd,0x2e,0x65,0xb9,0xd3,0x48,0x27,0x1b,0x33),
+	(0x40,0x9f,0x28,0x64,0xb4,0x27,0xc8,0xbe,0x28,0x3f,0x3b,0x95,0x2f,0x3a,0xdf,0xf1,0x73,0x8d,0xb8,0x27,
+		0xe2,0x2e,0x64,0xe1,0x21,0xac,0xf3,0x04,0xda,0x79,0x28,0xff,0x35,0xf8,0x62,0x99,0x56,0xab,0x7c,0x3f,
+		0x03,0x05,0x12,0x63,0x28,0xcb,0x64,0x30,0x2b,0x0b,0xe4,0x9c,0xc3,0xf9,0x72,0x3e,0xcf,0x3b,0x2d,0xb6,
+		0x9b,0x5b,0xbb,0x16,0x51,0xba,0x37,0x1d,0x3f,0xbb,0x5d,0xca,0x72,0xa7,0x91,0x4e,0x36,0x66),
+	(0x80,0x3e,0x51,0xc8,0x68,0x4f,0x90,0x7d,0x51,0x7e,0x76,0x2a,0x5f,0x74,0xbe,0xe3,0xe7,0x1a,0x71,0x4f,
+		0xc4,0x5d,0xc8,0xc2,0x43,0x58,0xe7,0x09,0xb4,0xf3,0x50,0xfe,0x6b,0xf0,0xc5,0x32,0xad,0x56,0xf9,0x7e,
+		0x06,0x0a,0x24,0xc6,0x50,0x96,0xc9,0x60,0x56,0x16,0xc8,0x39,0x87,0xf3,0xe5,0x7c,0x9e,0x77,0x5a,0x6c,
+		0x37,0xb7,0x76,0x2d,0xa2,0x74,0x6f,0x3a,0x7e,0x76,0xbb,0x94,0xe5,0x4e,0x23,0x9d,0x6c,0xcc))
+
+M_14_48 = (
+	(0x35,0x47,0xc2,0xf2,0xec,0xd9,0xb1,0x4c,0x34,0xd1,0x12,0x79,0x34,0xab,0x17,0x76,0x39,0x6a,0x37,0x7b,0x4d,
+		0xfe,0xb6,0x97,0xee,0xe9,0x71,0x1d,0xf6,0x99,0xf7,0x8e,0x9a,0x1f,0x05,0x13,0x6f,0xcc,0xb9,0xce,0xcf,0x60,
+		0xb9,0x66,0x35,0xa2,0xfc,0x8e,0x9a,0x40,0xdc,0x24,0xf6,0x6b,0xd9,0x96,0xfa,0xa1,0xfb,0x5f,0xc1,0xc2,0x6a,
+		0x84,0x88,0x13,0x48,0x43,0xcb,0xcb,0x77,0x63,0xc1,0xfa,0xf9,0x16,0xd4,0x69,0xd8,0x98,0x96,0x38,0x8f,0xae,0x01),
+	(0x6a,0x8e,0x84,0xe5,0xd9,0xb3,0x63,0x99,0x68,0xa2,0x25,0xf2,0x68,0x56,0x2f,0xec,0x72,0xd4,0x6e,0xf6,0x9a,
+		0xfc,0x6d,0x2f,0xdd,0xd3,0xe3,0x3a,0xec,0x33,0xef,0x1d,0x35,0x3f,0x0a,0x26,0xde,0x98,0x73,0x9d,0x9f,0xc1,
+		0x72,0xcd,0x6a,0x44,0xf9,0x1d,0x35,0x81,0xb8,0x49,0xec,0xd7,0xb2,0x2d,0xf5,0x43,0xf7,0xbf,0x82,0x85,0xd5,
+		0x08,0x11,0x27,0x90,0x86,0x96,0x97,0xef,0xc6,0x82,0xf5,0xf3,0x2d,0xa8,0xd3,0xb0,0x31,0x2d,0x71,0x1e,0x5d,0x03),
+	(0xd4,0x1c,0x09,0xcb,0xb3,0x67,0xc7,0x32,0xd1,0x44,0x4b,0xe4,0xd1,0xac,0x5e,0xd8,0xe5,0xa8,0xdd,0xec,0x35,
+		0xf9,0xdb,0x5e,0xba,0xa7,0xc7,0x75,0xd8,0x67,0xde,0x3b,0x6a,0x7e,0x14,0x4c,0xbc,0x31,0xe7,0x3a,0x3f,0x83,
+		0xe5,0x9a,0xd5,0x88,0xf2,0x3b,0x6a,0x02,0x71,0x93,0xd8,0xaf,0x65,0x5b,0xea,0x87,0xee,0x7f,0x05,0x0b,0xab,
+		0x11,0x22,0x4e,0x20,0x0d,0x2d,0x2f,0xdf,0x8d,0x05,0xeb,0xe7,0x5b,0x50,0xa7,0x61,0x63,0x5a,0xe2,0x3c,0xba,0x06),
+	(0xa8,0x39,0x12,0x96,0x67,0xcf,0x8e,0x65,0xa2,0x89,0x96,0xc8,0xa3,0x59,0xbd,0xb0,0xcb,0x51,0xbb,0xd9,0x6b,
+		0xf2,0xb7,0xbd,0x74,0x4f,0x8f,0xeb,0xb0,0xcf,0xbc,0x77,0xd4,0xfc,0x28,0x98,0x78,0x63,0xce,0x75,0x7e,0x06,
+		0xcb,0x35,0xab,0x11,0xe5,0x77,0xd4,0x04,0xe2,0x26,0xb1,0x5f,0xcb,0xb6,0xd4,0x0f,0xdd,0xff,0x0a,0x16,0x56,
+		0x23,0x44,0x9c,0x40,0x1a,0x5a,0x5e,0xbe,0x1b,0x0b,0xd6,0xcf,0xb7,0xa0,0x4e,0xc3,0xc6,0xb4,0xc4,0x79,0x74,0x0d),
+	(0x50,0x73,0x24,0x2c,0xcf,0x9e,0x1d,0xcb,0x44,0x13,0x2d,0x91,0x47,0xb3,0x7a,0x61,0x97,0xa3,0x76,0xb3,0xd7,
+		0xe4,0x6f,0x7b,0xe9,0x9e,0x1e,0xd7,0x61,0x9f,0x79,0xef,0xa8,0xf9,0x51,0x30,0xf1,0xc6,0x9c,0xeb,0xfc,0x0c,
+		0x96,0x6b,0x56,0x23,0xca,0xef,0xa8,0x09,0xc4,0x4d,0x62,0xbf,0x96,0x6d,0xa9,0x1f,0xba,0xff,0x15,0x2c,0xac,
+		0x46,0x88,0x38,0x81,0x34,0xb4,0xbc,0x7c,0x37,0x16,0xac,0x9f,0x6f,0x41,0x9d,0x86,0x8d,0x69,0x89,0xf3,0xe8,0x1a),
+	(0xa0,0xe6,0x48,0x58,0x9e,0x3d,0x3b,0x96,0x89,0x26,0x5a,0x22,0x8f,0x66,0xf5,0xc2,0x2e,0x47,0xed,0x66,0xaf,
+		0xc9,0xdf,0xf6,0xd2,0x3d,0x3d,0xae,0xc3,0x3e,0xf3,0xde,0x51,0xf3,0xa3,0x60,0xe2,0x8d,0x39,0xd7,0xf9,0x19,
+		0x2c,0xd7,0xac,0x46,0x94,0xdf,0x51,0x13,0x88,0x9b,0xc4,0x7e,0x2d,0xdb,0x52,0x3f,0x74,0xff,0x2b,0x58,0x58,
+		0x8d,0x10,0x71,0x02,0x69,0x68,0x79,0xf9,0x6e,0x2c,0x58,0x3f,0xdf,0x82,0x3a,0x0d,0x1b,0xd3,0x12,0xe7,0xd1,0x35),
+	(0x40,0xcd,0x91,0xb0,0x3c,0x7b,0x76,0x2c,0x13,0x4d,0xb4,0x44,0x1e,0xcd,0xea,0x85,0x5d,0x8e,0xda,0xcd,0x5e,
+		0x93,0xbf,0xed,0xa5,0x7b,0x7a,0x5c,0x87,0x7d,0xe6,0xbd,0xa3,0xe6,0x47,0xc1,0xc4,0x1b,0x73,0xae,0xf3,0x33,
+		0x58,0xae,0x59,0x8d,0x28,0xbf,0xa3,0x26,0x10,0x37,0x89,0xfd,0x5a,0xb6,0xa5,0x7e,0xe8,0xfe,0x57,0xb0,0xb0,
+		0x1a,0x21,0xe2,0x04,0xd2,0xd0,0xf2,0xf2,0xdd,0x58,0xb0,0x7e,0xbe,0x05,0x75,0x1a,0x36,0xa6,0x25,0xce,0xa3,0x6b),
+	(0x80,0x9a,0x23,0x61,0x79,0xf6,0xec,0x58,0x26,0x9a,0x68,0x89,0x3c,0x9a,0xd5,0x0b,0xbb,0x1c,0xb5,0x9b,0xbd,
+		0x26,0x7f,0xdb,0x4b,0xf7,0xf4,0xb8,0x0e,0xfb,0xcc,0x7b,0x47,0xcd,0x8f,0x82,0x89,0x37,0xe6,0x5c,0xe7,0x67,
+		0xb0,0x5c,0xb3,0x1a,0x51,0x7e,0x47,0x4d,0x20,0x6e,0x12,0xfb,0xb5,0x6c,0x4b,0xfd,0xd0,0xfd,0xaf,0x60,0x61,
+		0x35,0x42,0xc4,0x09,0xa4,0xa1,0xe5,0xe5,0xbb,0xb1,0x60,0xfd,0x7c,0x0b,0xea,0x34,0x6c,0x4c,0x4b,0x9c,0x47,0xd7))
+
+M_14_52 = (
+	(0x59,0x1e,0x2c,0xdc,0xd7,0x83,0xf5,0xe2,0x0b,0x8f,0x38,0xb3,0x18,0xaf,0x4d,0xc3,0xec,0x44,0x65,0xad,0xbf,
+		0x7a,0xd7,0xd9,0x60,0x25,0x18,0x74,0xa4,0x00,0x48,0xce,0x0d,0xb8,0x77,0x76,0x2a,0x13,0xe3,0x63,0x93,0xd3,
+		0xa4,0x17,0x9b,0x05,0x74,0x05,0x3d,0xad,0xa6,0xe6,0xcc,0x03,0xdf,0x2e,0xce,0xf5,0x32,0xd8,0x6f,0x76,0x16,
+		0x4f,0x9c,0xbf,0x61,0x7e,0x04,0x1f,0x57,0xf6,0x68,0x01,0xff,0x7c,0x10,0xb1,0x7a,0x5e,0xb5,0xdd,0xae,0xef,
+		0xe3,0xf7,0xa7,0x23,0xda,0xec,0xbd,0x01),
+	(0xb2,0x3c,0x58,0xb8,0xaf,0x07,0xeb,0xc5,0x17,0x1e,0x71,0x66,0x31,0x5e,0x9b,0x86,0xd9,0x89,0xca,0x5a,0x7f,
+		0xf5,0xae,0xb3,0xc1,0x4a,0x30,0xe8,0x48,0x01,0x90,0x9c,0x1b,0x70,0xef,0xec,0x54,0x26,0xc6,0xc7,0x26,0xa7,
+		0x49,0x2f,0x36,0x0b,0xe8,0x0a,0x7a,0x5a,0x4d,0xcd,0x99,0x07,0xbe,0x5d,0x9c,0xeb,0x65,0xb0,0xdf,0xec,0x2c,
+		0x9e,0x38,0x7f,0xc3,0xfc,0x08,0x3e,0xae,0xec,0xd1,0x02,0xfe,0xf9,0x20,0x62,0xf5,0xbc,0x6a,0xbb,0x5d,0xdf,
+		0xc7,0xef,0x4f,0x47,0xb4,0xd9,0x7b,0x03),
+	(0x64,0x79,0xb0,0x70,0x5f,0x0f,0xd6,0x8b,0x2f,0x3c,0xe2,0xcc,0x62,0xbc,0x36,0x0d,0xb3,0x13,0x95,0xb5,0xfe,
+		0xea,0x5d,0x67,0x83,0x95,0x60,0xd0,0x91,0x02,0x20,0x39,0x37,0xe0,0xde,0xd9,0xa9,0x4c,0x8c,0x8f,0x4d,0x4e,
+		0x93,0x5e,0x6c,0x16,0xd0,0x15,0xf4,0xb4,0x9a,0x9a,0x33,0x0f,0x7c,0xbb,0x38,0xd7,0xcb,0x60,0xbf,0xd9,0x59,
+		0x3c,0x71,0xfe,0x86,0xf9,0x11,0x7c,0x5c,0xd9,0xa3,0x05,0xfc,0xf3,0x41,0xc4,0xea,0x79,0xd5,0x76,0xbb,0xbe,
+		0x8f,0xdf,0x9f,0x8e,0x68,0xb3,0xf7,0x06),
+	(0xc8,0xf2,0x60,0xe1,0xbe,0x1e,0xac,0x17,0x5f,0x78,0xc4,0x99,0xc5,0x78,0x6d,0x1a,0x66,0x27,0x2a,0x6b,0xfd,
+		0xd5,0xbb,0xce,0x06,0x2b,0xc1,0xa0,0x23,0x05,0x40,0x72,0x6e,0xc0,0xbd,0xb3,0x53,0x99,0x18,0x1f,0x9b,0x9c,
+		0x26,0xbd,0xd8,0x2c,0xa0,0x2b,0xe8,0x69,0x35,0x35,0x67,0x1e,0xf8,0x76,0x71,0xae,0x97,0xc1,0x7e,0xb3,0xb3,
+		0x78,0xe2,0xfc,0x0d,0xf3,0x23,0xf8,0xb8,0xb2,0x47,0x0b,0xf8,0xe7,0x83,0x88,0xd5,0xf3,0xaa,0xed,0x76,0x7d,
+		0x1f,0xbf,0x3f,0x1d,0xd1,0x66,0xef,0x0d),
+	(0x90,0xe5,0xc1,0xc2,0x7d,0x3d,0x58,0x2f,0xbe,0xf0,0x88,0x33,0x8b,0xf1,0xda,0x34,0xcc,0x4e,0x54,0xd6,0xfa,
+		0xab,0x77,0x9d,0x0d,0x56,0x82,0x41,0x47,0x0a,0x80,0xe4,0xdc,0x80,0x7b,0x67,0xa7,0x32,0x31,0x3e,0x36,0x39,
+		0x4d,0x7a,0xb1,0x59,0x40,0x57,0xd0,0xd3,0x6a,0x6a,0xce,0x3c,0xf0,0xed,0xe2,0x5c,0x2f,0x83,0xfd,0x66,0x67,
+		0xf1,0xc4,0xf9,0x1b,0xe6,0x47,0xf0,0x71,0x65,0x8f,0x16,0xf0,0xcf,0x07,0x11,0xab,0xe7,0x55,0xdb,0xed,0xfa,
+		0x3e,0x7e,0x7f,0x3a,0xa2,0xcd,0xde,0x1b),
+	(0x20,0xcb,0x83,0x85,0xfb,0x7a,0xb0,0x5e,0x7c,0xe1,0x11,0x67,0x16,0xe3,0xb5,0x69,0x98,0x9d,0xa8,0xac,0xf5,
+		0x57,0xef,0x3a,0x1b,0xac,0x04,0x83,0x8e,0x14,0x00,0xc9,0xb9,0x01,0xf7,0xce,0x4e,0x65,0x62,0x7c,0x6c,0x72,
+		0x9a,0xf4,0x62,0xb3,0x80,0xae,0xa0,0xa7,0xd5,0xd4,0x9c,0x79,0xe0,0xdb,0xc5,0xb9,0x5e,0x06,0xfb,0xcd,0xce,
+		0xe2,0x89,0xf3,0x37,0xcc,0x8f,0xe0,0xe3,0xca,0x1e,0x2d,0xe0,0x9f,0x0f,0x22,0x56,0xcf,0xab,0xb6,0xdb,0xf5,
+		0x7d,0xfc,0xfe,0x74,0x44,0x9b,0xbd,0x37),
+	(0x40,0x96,0x07,0x0b,0xf7,0xf5,0x60,0xbd,0xf8,0xc2,0x23,0xce,0x2c,0xc6,0x6b,0xd3,0x30,0x3b,0x51,0x59,0xeb,
+		0xaf,0xde,0x75,0x36,0x58,0x09,0x06,0x1d,0x29,0x00,0x92,0x73,0x03,0xee,0x9d,0x9d,0xca,0xc4,0xf8,0xd8,0xe4,
+		0x34,0xe9,0xc5,0x66,0x01,0x5d,0x41,0x4f,0xab,0xa9,0x39,0xf3,0xc0,0xb7,0x8b,0x73,0xbd,0x0c,0xf6,0x9b,0x9d,
+		0xc5,0x13,0xe7,0x6f,0x98,0x1f,0xc1,0xc7,0x95,0x3d,0x5a,0xc0,0x3f,0x1f,0x44,0xac,0x9e,0x57,0x6d,0xb7,0xeb,
+		0xfb,0xf8,0xfd,0xe9,0x88,0x36,0x7b,0x6f),
+	(0x80,0x2c,0x0f,0x16,0xee,0xeb,0xc1,0x7a,0xf1,0x85,0x47,0x9c,0x59,0x8c,0xd7,0xa6,0x61,0x76,0xa2,0xb2,0xd6,
+		0x5f,0xbd,0xeb,0x6c,0xb0,0x12,0x0c,0x3a,0x52,0x00,0x24,0xe7,0x06,0xdc,0x3b,0x3b,0x95,0x89,0xf1,0xb1,0xc9,
+		0x69,0xd2,0x8b,0xcd,0x02,0xba,0x82,0x9e,0x56,0x53,0x73,0xe6,0x81,0x6f,0x17,0xe7,0x7a,0x19,0xec,0x37,0x3b,
+		0x8b,0x27,0xce,0xdf,0x30,0x3f,0x82,0x8f,0x2b,0x7b,0xb4,0x80,0x7f,0x3e,0x88,0x58,0x3d,0xaf,0xda,0x6e,0xd7,
+		0xf7,0xf1,0xfb,0xd3,0x11,0x6d,0xf6,0xde))
+
+M_14_56 = (
+	(0x09,0x0c,0xd9,0xd0,0xcb,0xbe,0x78,0x3e,0x36,0xc1,0x98,0xbd,0x12,0x71,0x0c,0x3f,0x74,0x83,0x2f,0x15,0x56,
+		0xbf,0xd7,0xb9,0x1d,0x07,0x43,0xe8,0x19,0x60,0x3e,0xe4,0x9c,0x9e,0xfd,0xad,0x6e,0x9e,0xda,0x69,0xc9,0x52,
+		0x2d,0xf5,0xe3,0x8e,0xe4,0x45,0x4a,0x34,0x7b,0x2d,0xce,0x27,0x8d,0x97,0x4a,0xa9,0xfc,0xd0,0xe0,0x99,0x90,
+		0xb0,0x8e,0x7a,0xcf,0x2a,0xa1,0x9c,0xcb,0x1f,0x96,0x32,0xa3,0x19,0xd8,0x42,0x67,0x08,0x6e,0xf3,0xb0,0xd1,
+		0x38,0xf3,0x05,0x88,0x34,0x5a,0x46,0x68,0x83,0x7d,0xa2,0xf9,0xf7,0x1d,0x01),
+	(0x12,0x18,0xb2,0xa1,0x97,0x7d,0xf1,0x7c,0x6c,0x82,0x31,0x7b,0x25,0xe2,0x18,0x7e,0xe8,0x06,0x5f,0x2a,0xac,
+		0x7e,0xaf,0x73,0x3b,0x0e,0x86,0xd0,0x33,0xc0,0x7c,0xc8,0x39,0x3d,0xfb,0x5b,0xdd,0x3c,0xb5,0xd3,0x92,0xa5,
+		0x5a,0xea,0xc7,0x1d,0xc9,0x8b,0x94,0x68,0xf6,0x5a,0x9c,0x4f,0x1a,0x2f,0x95,0x52,0xf9,0xa1,0xc1,0x33,0x21,
+		0x61,0x1d,0xf5,0x9e,0x55,0x42,0x39,0x97,0x3f,0x2c,0x65,0x46,0x33,0xb0,0x85,0xce,0x10,0xdc,0xe6,0x61,0xa3,
+		0x71,0xe6,0x0b,0x10,0x69,0xb4,0x8c,0xd0,0x06,0xfb,0x44,0xf3,0xef,0x3b,0x02),
+	(0x24,0x30,0x64,0x43,0x2f,0xfb,0xe2,0xf9,0xd8,0x04,0x63,0xf6,0x4a,0xc4,0x31,0xfc,0xd0,0x0d,0xbe,0x54,0x58,
+		0xfd,0x5e,0xe7,0x76,0x1c,0x0c,0xa1,0x67,0x80,0xf9,0x90,0x73,0x7a,0xf6,0xb7,0xba,0x79,0x6a,0xa7,0x25,0x4b,
+		0xb5,0xd4,0x8f,0x3b,0x92,0x17,0x29,0xd1,0xec,0xb5,0x38,0x9f,0x34,0x5e,0x2a,0xa5,0xf2,0x43,0x83,0x67,0x42,
+		0xc2,0x3a,0xea,0x3d,0xab,0x84,0x72,0x2e,0x7f,0x58,0xca,0x8c,0x66,0x60,0x0b,0x9d,0x21,0xb8,0xcd,0xc3,0x46,
+		0xe3,0xcc,0x17,0x20,0xd2,0x68,0x19,0xa1,0x0d,0xf6,0x89,0xe6,0xdf,0x77,0x04),
+	(0x48,0x60,0xc8,0x86,0x5e,0xf6,0xc5,0xf3,0xb1,0x09,0xc6,0xec,0x95,0x88,0x63,0xf8,0xa1,0x1b,0x7c,0xa9,0xb0,
+		0xfa,0xbd,0xce,0xed,0x38,0x18,0x42,0xcf,0x00,0xf3,0x21,0xe7,0xf4,0xec,0x6f,0x75,0xf3,0xd4,0x4e,0x4b,0x96,
+		0x6a,0xa9,0x1f,0x77,0x24,0x2f,0x52,0xa2,0xd9,0x6b,0x71,0x3e,0x69,0xbc,0x54,0x4a,0xe5,0x87,0x06,0xcf,0x84,
+		0x84,0x75,0xd4,0x7b,0x56,0x09,0xe5,0x5c,0xfe,0xb0,0x94,0x19,0xcd,0xc0,0x16,0x3a,0x43,0x70,0x9b,0x87,0x8d,
+		0xc6,0x99,0x2f,0x40,0xa4,0xd1,0x32,0x42,0x1b,0xec,0x13,0xcd,0xbf,0xef,0x08),
+	(0x90,0xc0,0x90,0x0d,0xbd,0xec,0x8b,0xe7,0x63,0x13,0x8c,0xd9,0x2b,0x11,0xc7,0xf0,0x43,0x37,0xf8,0x52,0x61,
+		0xf5,0x7b,0x9d,0xdb,0x71,0x30,0x84,0x9e,0x01,0xe6,0x43,0xce,0xe9,0xd9,0xdf,0xea,0xe6,0xa9,0x9d,0x96,0x2c,
+		0xd5,0x52,0x3f,0xee,0x48,0x5e,0xa4,0x44,0xb3,0xd7,0xe2,0x7c,0xd2,0x78,0xa9,0x94,0xca,0x0f,0x0d,0x9e,0x09,
+		0x09,0xeb,0xa8,0xf7,0xac,0x12,0xca,0xb9,0xfc,0x61,0x29,0x33,0x9a,0x81,0x2d,0x74,0x86,0xe0,0x36,0x0f,0x1b,
+		0x8d,0x33,0x5f,0x80,0x48,0xa3,0x65,0x84,0x36,0xd8,0x27,0x9a,0x7f,0xdf,0x11),
+	(0x20,0x81,0x21,0x1b,0x7a,0xd9,0x17,0xcf,0xc7,0x26,0x18,0xb3,0x57,0x22,0x8e,0xe1,0x87,0x6e,0xf0,0xa5,0xc2,
+		0xea,0xf7,0x3a,0xb7,0xe3,0x60,0x08,0x3d,0x03,0xcc,0x87,0x9c,0xd3,0xb3,0xbf,0xd5,0xcd,0x53,0x3b,0x2d,0x59,
+		0xaa,0xa5,0x7e,0xdc,0x91,0xbc,0x48,0x89,0x66,0xaf,0xc5,0xf9,0xa4,0xf1,0x52,0x29,0x95,0x1f,0x1a,0x3c,0x13,
+		0x12,0xd6,0x51,0xef,0x59,0x25,0x94,0x73,0xf9,0xc3,0x52,0x66,0x34,0x03,0x5b,0xe8,0x0c,0xc1,0x6d,0x1e,0x36,
+		0x1a,0x67,0xbe,0x00,0x91,0x46,0xcb,0x08,0x6d,0xb0,0x4f,0x34,0xff,0xbe,0x23),
+	(0x40,0x02,0x43,0x36,0xf4,0xb2,0x2f,0x9e,0x8f,0x4d,0x30,0x66,0xaf,0x44,0x1c,0xc3,0x0f,0xdd,0xe0,0x4b,0x85,
+		0xd5,0xef,0x75,0x6e,0xc7,0xc1,0x10,0x7a,0x06,0x98,0x0f,0x39,0xa7,0x67,0x7f,0xab,0x9b,0xa7,0x76,0x5a,0xb2,
+		0x54,0x4b,0xfd,0xb8,0x23,0x79,0x91,0x12,0xcd,0x5e,0x8b,0xf3,0x49,0xe3,0xa5,0x52,0x2a,0x3f,0x34,0x78,0x26,
+		0x24,0xac,0xa3,0xde,0xb3,0x4a,0x28,0xe7,0xf2,0x87,0xa5,0xcc,0x68,0x06,0xb6,0xd0,0x19,0x82,0xdb,0x3c,0x6c,
+		0x34,0xce,0x7c,0x01,0x22,0x8d,0x96,0x11,0xda,0x60,0x9f,0x68,0xfe,0x7d,0x47),
+	(0x80,0x04,0x86,0x6c,0xe8,0x65,0x5f,0x3c,0x1f,0x9b,0x60,0xcc,0x5e,0x89,0x38,0x86,0x1f,0xba,0xc1,0x97,0x0a,
+		0xab,0xdf,0xeb,0xdc,0x8e,0x83,0x21,0xf4,0x0c,0x30,0x1f,0x72,0x4e,0xcf,0xfe,0x56,0x37,0x4f,0xed,0xb4,0x64,
+		0xa9,0x96,0xfa,0x71,0x47,0xf2,0x22,0x25,0x9a,0xbd,0x16,0xe7,0x93,0xc6,0x4b,0xa5,0x54,0x7e,0x68,0xf0,0x4c,
+		0x48,0x58,0x47,0xbd,0x67,0x95,0x50,0xce,0xe5,0x0f,0x4b,0x99,0xd1,0x0c,0x6c,0xa1,0x33,0x04,0xb7,0x79,0xd8,
+		0x68,0x9c,0xf9,0x02,0x44,0x1a,0x2d,0x23,0xb4,0xc1,0x3e,0xd1,0xfc,0xfb,0x8e))
+
+M_14_60 = (
+	(0xb3,0xf4,0x1b,0x06,0x78,0x68,0xf9,0xe5,0xe9,0x1f,0xc1,0xce,0x37,0x6f,0x39,0xbd,0x28,0xc4,0xd3,0x49,0xd6,
+		0x9f,0x34,0x0b,0x67,0xb7,0x6d,0x3c,0xb6,0x8c,0xcc,0xa2,0xfd,0x37,0x17,0xd9,0x85,0x02,0x1e,0x86,0x7d,0xc0,
+		0xcc,0x64,0x92,0xc2,0x66,0x9a,0x36,0x77,0xb1,0xa8,0xa5,0xb9,0x47,0x22,0x75,0xde,0x09,0xe9,0x63,0xd6,0xf5,
+		0x1b,0xd0,0xfd,0xfb,0x8f,0x3a,0xcd,0x4c,0xac,0xaa,0xe6,0xda,0x43,0xf5,0x2d,0xd3,0x1e,0xd8,0x78,0x21,0x8d,
+		0x00,0xdf,0x88,0xd5,0x7b,0xaf,0xb3,0xd6,0x1c,0x80,0x5f,0x7c,0x37,0x9d,0xd7,0xea,0x4c,0x4f,0x8b,0xa1,0xc8,0x01),
+	(0x66,0xe9,0x37,0x0c,0xf0,0xd0,0xf2,0xcb,0xd3,0x3f,0x82,0x9d,0x6f,0xde,0x72,0x7a,0x51,0x88,0xa7,0x93,0xac,
+		0x3f,0x69,0x16,0xce,0x6e,0xdb,0x78,0x6c,0x19,0x99,0x45,0xfb,0x6f,0x2e,0xb2,0x0b,0x05,0x3c,0x0c,0xfb,0x80,
+		0x99,0xc9,0x24,0x85,0xcd,0x34,0x6d,0xee,0x62,0x51,0x4b,0x73,0x8f,0x44,0xea,0xbc,0x13,0xd2,0xc7,0xac,0xeb,
+		0x37,0xa0,0xfb,0xf7,0x1f,0x75,0x9a,0x99,0x58,0x55,0xcd,0xb5,0x87,0xea,0x5b,0xa6,0x3d,0xb0,0xf1,0x42,0x1a,
+		0x01,0xbe,0x11,0xab,0xf7,0x5e,0x67,0xad,0x39,0x00,0xbf,0xf8,0x6e,0x3a,0xaf,0xd5,0x99,0x9e,0x16,0x43,0x91,0x03),
+	(0xcc,0xd2,0x6f,0x18,0xe0,0xa1,0xe5,0x97,0xa7,0x7f,0x04,0x3b,0xdf,0xbc,0xe5,0xf4,0xa2,0x10,0x4f,0x27,0x59,
+		0x7f,0xd2,0x2c,0x9c,0xdd,0xb6,0xf1,0xd8,0x32,0x32,0x8b,0xf6,0xdf,0x5c,0x64,0x17,0x0a,0x78,0x18,0xf6,0x01,
+		0x33,0x93,0x49,0x0a,0x9b,0x69,0xda,0xdc,0xc5,0xa2,0x96,0xe6,0x1e,0x89,0xd4,0x79,0x27,0xa4,0x8f,0x59,0xd7,
+		0x6f,0x40,0xf7,0xef,0x3f,0xea,0x34,0x33,0xb1,0xaa,0x9a,0x6b,0x0f,0xd5,0xb7,0x4c,0x7b,0x60,0xe3,0x85,0x34,
+		0x02,0x7c,0x23,0x56,0xef,0xbd,0xce,0x5a,0x73,0x00,0x7e,0xf1,0xdd,0x74,0x5e,0xab,0x33,0x3d,0x2d,0x86,0x22,0x07),
+	(0x98,0xa5,0xdf,0x30,0xc0,0x43,0xcb,0x2f,0x4f,0xff,0x08,0x76,0xbe,0x79,0xcb,0xe9,0x45,0x21,0x9e,0x4e,0xb2,
+		0xfe,0xa4,0x59,0x38,0xbb,0x6d,0xe3,0xb1,0x65,0x64,0x16,0xed,0xbf,0xb9,0xc8,0x2e,0x14,0xf0,0x30,0xec,0x03,
+		0x66,0x26,0x93,0x14,0x36,0xd3,0xb4,0xb9,0x8b,0x45,0x2d,0xcd,0x3d,0x12,0xa9,0xf3,0x4e,0x48,0x1f,0xb3,0xae,
+		0xdf,0x80,0xee,0xdf,0x7f,0xd4,0x69,0x66,0x62,0x55,0x35,0xd7,0x1e,0xaa,0x6f,0x99,0xf6,0xc0,0xc6,0x0b,0x69,
+		0x04,0xf8,0x46,0xac,0xde,0x7b,0x9d,0xb5,0xe6,0x00,0xfc,0xe2,0xbb,0xe9,0xbc,0x56,0x67,0x7a,0x5a,0x0c,0x45,0x0e),
+	(0x30,0x4b,0xbf,0x61,0x80,0x87,0x96,0x5f,0x9e,0xfe,0x11,0xec,0x7c,0xf3,0x96,0xd3,0x8b,0x42,0x3c,0x9d,0x64,
+		0xfd,0x49,0xb3,0x70,0x76,0xdb,0xc6,0x63,0xcb,0xc8,0x2c,0xda,0x7f,0x73,0x91,0x5d,0x28,0xe0,0x61,0xd8,0x07,
+		0xcc,0x4c,0x26,0x29,0x6c,0xa6,0x69,0x73,0x17,0x8b,0x5a,0x9a,0x7b,0x24,0x52,0xe7,0x9d,0x90,0x3e,0x66,0x5d,
+		0xbf,0x01,0xdd,0xbf,0xff,0xa8,0xd3,0xcc,0xc4,0xaa,0x6a,0xae,0x3d,0x54,0xdf,0x32,0xed,0x81,0x8d,0x17,0xd2,
+		0x08,0xf0,0x8d,0x58,0xbd,0xf7,0x3a,0x6b,0xcd,0x01,0xf8,0xc5,0x77,0xd3,0x79,0xad,0xce,0xf4,0xb4,0x18,0x8a,0x1c),
+	(0x60,0x96,0x7e,0xc3,0x00,0x0f,0x2d,0xbf,0x3c,0xfd,0x23,0xd8,0xf9,0xe6,0x2d,0xa7,0x17,0x85,0x78,0x3a,0xc9,
+		0xfa,0x93,0x66,0xe1,0xec,0xb6,0x8d,0xc7,0x96,0x91,0x59,0xb4,0xff,0xe6,0x22,0xbb,0x50,0xc0,0xc3,0xb0,0x0f,
+		0x98,0x99,0x4c,0x52,0xd8,0x4c,0xd3,0xe6,0x2e,0x16,0xb5,0x34,0xf7,0x48,0xa4,0xce,0x3b,0x21,0x7d,0xcc,0xba,
+		0x7e,0x03,0xba,0x7f,0xff,0x51,0xa7,0x99,0x89,0x55,0xd5,0x5c,0x7b,0xa8,0xbe,0x65,0xda,0x03,0x1b,0x2f,0xa4,
+		0x11,0xe0,0x1b,0xb1,0x7a,0xef,0x75,0xd6,0x9a,0x03,0xf0,0x8b,0xef,0xa6,0xf3,0x5a,0x9d,0xe9,0x69,0x31,0x14,0x39),
+	(0xc0,0x2c,0xfd,0x86,0x01,0x1e,0x5a,0x7e,0x79,0xfa,0x47,0xb0,0xf3,0xcd,0x5b,0x4e,0x2f,0x0a,0xf1,0x74,0x92,
+		0xf5,0x27,0xcd,0xc2,0xd9,0x6d,0x1b,0x8f,0x2d,0x23,0xb3,0x68,0xff,0xcd,0x45,0x76,0xa1,0x80,0x87,0x61,0x1f,
+		0x30,0x33,0x99,0xa4,0xb0,0x99,0xa6,0xcd,0x5d,0x2c,0x6a,0x69,0xee,0x91,0x48,0x9d,0x77,0x42,0xfa,0x98,0x75,
+		0xfd,0x06,0x74,0xff,0xfe,0xa3,0x4e,0x33,0x13,0xab,0xaa,0xb9,0xf6,0x50,0x7d,0xcb,0xb4,0x07,0x36,0x5e,0x48,
+		0x23,0xc0,0x37,0x62,0xf5,0xde,0xeb,0xac,0x35,0x07,0xe0,0x17,0xdf,0x4d,0xe7,0xb5,0x3a,0xd3,0xd3,0x62,0x28,0x72),
+	(0x80,0x59,0xfa,0x0d,0x03,0x3c,0xb4,0xfc,0xf2,0xf4,0x8f,0x60,0xe7,0x9b,0xb7,0x9c,0x5e,0x14,0xe2,0xe9,0x24,
+		0xeb,0x4f,0x9a,0x85,0xb3,0xdb,0x36,0x1e,0x5b,0x46,0x66,0xd1,0xfe,0x9b,0x8b,0xec,0x42,0x01,0x0f,0xc3,0x3e,
+		0x60,0x66,0x32,0x49,0x61,0x33,0x4d,0x9b,0xbb,0x58,0xd4,0xd2,0xdc,0x23,0x91,0x3a,0xef,0x84,0xf4,0x31,0xeb,
+		0xfa,0x0d,0xe8,0xfe,0xfd,0x47,0x9d,0x66,0x26,0x56,0x55,0x73,0xed,0xa1,0xfa,0x96,0x69,0x0f,0x6c,0xbc,0x90,
+		0x46,0x80,0x6f,0xc4,0xea,0xbd,0xd7,0x59,0x6b,0x0e,0xc0,0x2f,0xbe,0x9b,0xce,0x6b,0x75,0xa6,0xa7,0xc5,0x50,0xe4))
+
+M_14_68 = (
+	(0x69,0xca,0x0b,0xcf,0x38,0x48,0x00,0xd2,0xb9,0x9f,0x98,0x8a,0xe6,0x14,0xb2,0x89,0x11,0x91,0xa9,0xb8,0x25,
+		0x5e,0xfa,0xc6,0x5b,0x19,0x78,0xe6,0x47,0x46,0x13,0x3e,0xb8,0x62,0x2f,0xaa,0xcf,0x9c,0x80,0x2a,0xe2,0x8c,
+		0x9a,0x48,0x0a,0xa7,0x09,0xf6,0x7a,0x9f,0x91,0x1e,0xbf,0xa1,0x2f,0xa7,0x4e,0xaf,0x9f,0x83,0xc3,0xbe,0x7c,
+		0x1e,0x71,0x64,0xf0,0x68,0x20,0x66,0x35,0xb6,0xf7,0x82,0x44,0xde,0xf5,0xc3,0x50,0xfe,0xc7,0x51,0xf1,0x06,
+		0xd9,0xad,0xfc,0xd3,0x2c,0x3a,0x57,0x0a,0xf3,0x0d,0xe5,0x2a,0x88,0xbf,0x5c,0xa6,0xa9,0x53,0xeb,0xa7,0x94,
+		0xf2,0x81,0x2a,0xbb,0xaa,0x43,0x4e,0x47,0x40,0xe1,0x5d,0x0f,0x1a,0x02,0x00),
+	(0xd2,0x94,0x17,0x9e,0x71,0x90,0x00,0xa4,0x73,0x3f,0x31,0x15,0xcd,0x29,0x64,0x13,0x23,0x22,0x53,0x71,0x4b,
+		0xbc,0xf4,0x8d,0xb7,0x32,0xf0,0xcc,0x8f,0x8c,0x26,0x7c,0x70,0xc5,0x5e,0x54,0x9f,0x39,0x01,0x55,0xc4,0x19,
+		0x35,0x91,0x14,0x4e,0x13,0xec,0xf5,0x3e,0x23,0x3d,0x7e,0x43,0x5f,0x4e,0x9d,0x5e,0x3f,0x07,0x87,0x7d,0xf9,
+		0x3c,0xe2,0xc8,0xe0,0xd1,0x40,0xcc,0x6a,0x6c,0xef,0x05,0x89,0xbc,0xeb,0x87,0xa1,0xfc,0x8f,0xa3,0xe2,0x0d,
+		0xb2,0x5b,0xf9,0xa7,0x59,0x74,0xae,0x14,0xe6,0x1b,0xca,0x55,0x10,0x7f,0xb9,0x4c,0x53,0xa7,0xd6,0x4f,0x29,
+		0xe5,0x03,0x55,0x76,0x55,0x87,0x9c,0x8e,0x80,0xc2,0xbb,0x1e,0x34,0x04,0x00),
+	(0xa4,0x29,0x2f,0x3c,0xe3,0x20,0x01,0x48,0xe7,0x7e,0x62,0x2a,0x9a,0x53,0xc8,0x26,0x46,0x44,0xa6,0xe2,0x96,
+		0x78,0xe9,0x1b,0x6f,0x65,0xe0,0x99,0x1f,0x19,0x4d,0xf8,0xe0,0x8a,0xbd,0xa8,0x3e,0x73,0x02,0xaa,0x88,0x33,
+		0x6a,0x22,0x29,0x9c,0x26,0xd8,0xeb,0x7d,0x46,0x7a,0xfc,0x86,0xbe,0x9c,0x3a,0xbd,0x7e,0x0e,0x0e,0xfb,0xf2,
+		0x79,0xc4,0x91,0xc1,0xa3,0x81,0x98,0xd5,0xd8,0xde,0x0b,0x12,0x79,0xd7,0x0f,0x43,0xf9,0x1f,0x47,0xc5,0x1b,
+		0x64,0xb7,0xf2,0x4f,0xb3,0xe8,0x5c,0x29,0xcc,0x37,0x94,0xab,0x20,0xfe,0x72,0x99,0xa6,0x4e,0xad,0x9f,0x52,
+		0xca,0x07,0xaa,0xec,0xaa,0x0e,0x39,0x1d,0x01,0x85,0x77,0x3d,0x68,0x08,0x00),
+	(0x48,0x53,0x5e,0x78,0xc6,0x41,0x02,0x90,0xce,0xfd,0xc4,0x54,0x34,0xa7,0x90,0x4d,0x8c,0x88,0x4c,0xc5,0x2d,
+		0xf1,0xd2,0x37,0xde,0xca,0xc0,0x33,0x3f,0x32,0x9a,0xf0,0xc1,0x15,0x7b,0x51,0x7d,0xe6,0x04,0x54,0x11,0x67,
+		0xd4,0x44,0x52,0x38,0x4d,0xb0,0xd7,0xfb,0x8c,0xf4,0xf8,0x0d,0x7d,0x39,0x75,0x7a,0xfd,0x1c,0x1c,0xf6,0xe5,
+		0xf3,0x88,0x23,0x83,0x47,0x03,0x31,0xab,0xb1,0xbd,0x17,0x24,0xf2,0xae,0x1f,0x86,0xf2,0x3f,0x8e,0x8a,0x37,
+		0xc8,0x6e,0xe5,0x9f,0x66,0xd1,0xb9,0x52,0x98,0x6f,0x28,0x57,0x41,0xfc,0xe5,0x32,0x4d,0x9d,0x5a,0x3f,0xa5,
+		0x94,0x0f,0x54,0xd9,0x55,0x1d,0x72,0x3a,0x02,0x0a,0xef,0x7a,0xd0,0x10,0x00),
+	(0x90,0xa6,0xbc,0xf0,0x8c,0x83,0x04,0x20,0x9d,0xfb,0x89,0xa9,0x68,0x4e,0x21,0x9b,0x18,0x11,0x99,0x8a,0x5b,
+		0xe2,0xa5,0x6f,0xbc,0x95,0x81,0x67,0x7e,0x64,0x34,0xe1,0x83,0x2b,0xf6,0xa2,0xfa,0xcc,0x09,0xa8,0x22,0xce,
+		0xa8,0x89,0xa4,0x70,0x9a,0x60,0xaf,0xf7,0x19,0xe9,0xf1,0x1b,0xfa,0x72,0xea,0xf4,0xfa,0x39,0x38,0xec,0xcb,
+		0xe7,0x11,0x47,0x06,0x8f,0x06,0x62,0x56,0x63,0x7b,0x2f,0x48,0xe4,0x5d,0x3f,0x0c,0xe5,0x7f,0x1c,0x15,0x6f,
+		0x90,0xdd,0xca,0x3f,0xcd,0xa2,0x73,0xa5,0x30,0xdf,0x50,0xae,0x82,0xf8,0xcb,0x65,0x9a,0x3a,0xb5,0x7e,0x4a,
+		0x29,0x1f,0xa8,0xb2,0xab,0x3a,0xe4,0x74,0x04,0x14,0xde,0xf5,0xa0,0x21,0x00),
+	(0x20,0x4d,0x79,0xe1,0x19,0x07,0x09,0x40,0x3a,0xf7,0x13,0x53,0xd1,0x9c,0x42,0x36,0x31,0x22,0x32,0x15,0xb7,
+		0xc4,0x4b,0xdf,0x78,0x2b,0x03,0xcf,0xfc,0xc8,0x68,0xc2,0x07,0x57,0xec,0x45,0xf5,0x99,0x13,0x50,0x45,0x9c,
+		0x51,0x13,0x49,0xe1,0x34,0xc1,0x5e,0xef,0x33,0xd2,0xe3,0x37,0xf4,0xe5,0xd4,0xe9,0xf5,0x73,0x70,0xd8,0x97,
+		0xcf,0x23,0x8e,0x0c,0x1e,0x0d,0xc4,0xac,0xc6,0xf6,0x5e,0x90,0xc8,0xbb,0x7e,0x18,0xca,0xff,0x38,0x2a,0xde,
+		0x20,0xbb,0x95,0x7f,0x9a,0x45,0xe7,0x4a,0x61,0xbe,0xa1,0x5c,0x05,0xf1,0x97,0xcb,0x34,0x75,0x6a,0xfd,0x94,
+		0x52,0x3e,0x50,0x65,0x57,0x75,0xc8,0xe9,0x08,0x28,0xbc,0xeb,0x41,0x43,0x00),
+	(0x40,0x9a,0xf2,0xc2,0x33,0x0e,0x12,0x80,0x74,0xee,0x27,0xa6,0xa2,0x39,0x85,0x6c,0x62,0x44,0x64,0x2a,0x6e,
+		0x89,0x97,0xbe,0xf1,0x56,0x06,0x9e,0xf9,0x91,0xd1,0x84,0x0f,0xae,0xd8,0x8b,0xea,0x33,0x27,0xa0,0x8a,0x38,
+		0xa3,0x26,0x92,0xc2,0x69,0x82,0xbd,0xde,0x67,0xa4,0xc7,0x6f,0xe8,0xcb,0xa9,0xd3,0xeb,0xe7,0xe0,0xb0,0x2f,
+		0x9f,0x47,0x1c,0x19,0x3c,0x1a,0x88,0x59,0x8d,0xed,0xbd,0x20,0x91,0x77,0xfd,0x30,0x94,0xff,0x71,0x54,0xbc,
+		0x41,0x76,0x2b,0xff,0x34,0x8b,0xce,0x95,0xc2,0x7c,0x43,0xb9,0x0a,0xe2,0x2f,0x97,0x69,0xea,0xd4,0xfa,0x29,
+		0xa5,0x7c,0xa0,0xca,0xae,0xea,0x90,0xd3,0x11,0x50,0x78,0xd7,0x83,0x86,0x00),
+	(0x80,0x34,0xe5,0x85,0x67,0x1c,0x24,0x00,0xe9,0xdc,0x4f,0x4c,0x45,0x73,0x0a,0xd9,0xc4,0x88,0xc8,0x54,0xdc,
+		0x12,0x2f,0x7d,0xe3,0xad,0x0c,0x3c,0xf3,0x23,0xa3,0x09,0x1f,0x5c,0xb1,0x17,0xd5,0x67,0x4e,0x40,0x15,0x71,
+		0x46,0x4d,0x24,0x85,0xd3,0x04,0x7b,0xbd,0xcf,0x48,0x8f,0xdf,0xd0,0x97,0x53,0xa7,0xd7,0xcf,0xc1,0x61,0x5f,
+		0x3e,0x8f,0x38,0x32,0x78,0x34,0x10,0xb3,0x1a,0xdb,0x7b,0x41,0x22,0xef,0xfa,0x61,0x28,0xff,0xe3,0xa8,0x78,
+		0x83,0xec,0x56,0xfe,0x69,0x16,0x9d,0x2b,0x85,0xf9,0x86,0x72,0x15,0xc4,0x5f,0x2e,0xd3,0xd4,0xa9,0xf5,0x53,
+		0x4a,0xf9,0x40,0x95,0x5d,0xd5,0x21,0xa7,0x23,0xa0,0xf0,0xae,0x07,0x0d,0x01))
+
+M_14_72 = (
+	(0x2d,0xdb,0xaa,0xfd,0x80,0xd2,0xff,0x17,0x22,0xad,0xb3,0x0d,0xbe,0x69,0x1c,0xe6,0xbc,0x6e,0x4a,0x07,0x64,
+		0x01,0xd4,0x0a,0x01,0x7f,0xfc,0x49,0x87,0xdc,0xed,0x3d,0xe7,0x4f,0x48,0x0a,0xef,0x1e,0xbf,0xfd,0x6b,0x2b,
+		0x6c,0x66,0x8c,0x5f,0xd1,0xe9,0x09,0xb3,0x75,0x13,0x80,0x24,0xd6,0xc9,0xcb,0xe7,0x91,0xad,0xc2,0x88,0xbe,
+		0x84,0x25,0x42,0x40,0xd6,0xdc,0x89,0x0f,0xa5,0xeb,0x8b,0x84,0x34,0xd6,0x47,0xc7,0x0c,0xc9,0xe4,0xbb,0xfa,
+		0x00,0xde,0x97,0x72,0x6f,0xf3,0xec,0x8e,0x26,0xf5,0x3a,0x44,0x21,0xea,0xb3,0xb0,0x40,0xab,0x2c,0xfc,0xd7,
+		0x45,0x88,0x90,0x6d,0x4d,0x74,0x2a,0x8a,0xc2,0xbb,0x1d,0x98,0x70,0xcf,0x43,0x63,0x18,0x02,0x6f,0x5c,0x02,0x00),
+	(0x5a,0xb6,0x55,0xfb,0x01,0xa5,0xff,0x2f,0x44,0x5a,0x67,0x1b,0x7c,0xd3,0x38,0xcc,0x79,0xdd,0x94,0x0e,0xc8,
+		0x02,0xa8,0x15,0x02,0xfe,0xf8,0x93,0x0e,0xb9,0xdb,0x7b,0xce,0x9f,0x90,0x14,0xde,0x3d,0x7e,0xfb,0xd7,0x56,
+		0xd8,0xcc,0x18,0xbf,0xa2,0xd3,0x13,0x66,0xeb,0x26,0x00,0x49,0xac,0x93,0x97,0xcf,0x23,0x5b,0x85,0x11,0x7d,
+		0x09,0x4b,0x84,0x80,0xac,0xb9,0x13,0x1f,0x4a,0xd7,0x17,0x09,0x69,0xac,0x8f,0x8e,0x19,0x92,0xc9,0x77,0xf5,
+		0x01,0xbc,0x2f,0xe5,0xde,0xe6,0xd9,0x1d,0x4d,0xea,0x75,0x88,0x42,0xd4,0x67,0x61,0x81,0x56,0x59,0xf8,0xaf,
+		0x8b,0x10,0x21,0xdb,0x9a,0xe8,0x54,0x14,0x85,0x77,0x3b,0x30,0xe1,0x9e,0x87,0xc6,0x30,0x04,0xde,0xb8,0x04,0x00),
+	(0xb4,0x6c,0xab,0xf6,0x03,0x4a,0xff,0x5f,0x88,0xb4,0xce,0x36,0xf8,0xa6,0x71,0x98,0xf3,0xba,0x29,0x1d,0x90,
+		0x05,0x50,0x2b,0x04,0xfc,0xf1,0x27,0x1d,0x72,0xb7,0xf7,0x9c,0x3f,0x21,0x29,0xbc,0x7b,0xfc,0xf6,0xaf,0xad,
+		0xb0,0x99,0x31,0x7e,0x45,0xa7,0x27,0xcc,0xd6,0x4d,0x00,0x92,0x58,0x27,0x2f,0x9f,0x47,0xb6,0x0a,0x23,0xfa,
+		0x12,0x96,0x08,0x01,0x59,0x73,0x27,0x3e,0x94,0xae,0x2f,0x12,0xd2,0x58,0x1f,0x1d,0x33,0x24,0x93,0xef,0xea,
+		0x03,0x78,0x5f,0xca,0xbd,0xcd,0xb3,0x3b,0x9a,0xd4,0xeb,0x10,0x85,0xa8,0xcf,0xc2,0x02,0xad,0xb2,0xf0,0x5f,
+		0x17,0x21,0x42,0xb6,0x35,0xd1,0xa9,0x28,0x0a,0xef,0x76,0x60,0xc2,0x3d,0x0f,0x8d,0x61,0x08,0xbc,0x71,0x09,0x00),
+	(0x68,0xd9,0x56,0xed,0x07,0x94,0xfe,0xbf,0x10,0x69,0x9d,0x6d,0xf0,0x4d,0xe3,0x30,0xe7,0x75,0x53,0x3a,0x20,
+		0x0b,0xa0,0x56,0x08,0xf8,0xe3,0x4f,0x3a,0xe4,0x6e,0xef,0x39,0x7f,0x42,0x52,0x78,0xf7,0xf8,0xed,0x5f,0x5b,
+		0x61,0x33,0x63,0xfc,0x8a,0x4e,0x4f,0x98,0xad,0x9b,0x00,0x24,0xb1,0x4e,0x5e,0x3e,0x8f,0x6c,0x15,0x46,0xf4,
+		0x25,0x2c,0x11,0x02,0xb2,0xe6,0x4e,0x7c,0x28,0x5d,0x5f,0x24,0xa4,0xb1,0x3e,0x3a,0x66,0x48,0x26,0xdf,0xd5,
+		0x07,0xf0,0xbe,0x94,0x7b,0x9b,0x67,0x77,0x34,0xa9,0xd7,0x21,0x0a,0x51,0x9f,0x85,0x05,0x5a,0x65,0xe1,0xbf,
+		0x2e,0x42,0x84,0x6c,0x6b,0xa2,0x53,0x51,0x14,0xde,0xed,0xc0,0x84,0x7b,0x1e,0x1a,0xc3,0x10,0x78,0xe3,0x12,0x00),
+	(0xd0,0xb2,0xad,0xda,0x0f,0x28,0xfd,0x7f,0x21,0xd2,0x3a,0xdb,0xe0,0x9b,0xc6,0x61,0xce,0xeb,0xa6,0x74,0x40,
+		0x16,0x40,0xad,0x10,0xf0,0xc7,0x9f,0x74,0xc8,0xdd,0xde,0x73,0xfe,0x84,0xa4,0xf0,0xee,0xf1,0xdb,0xbf,0xb6,
+		0xc2,0x66,0xc6,0xf8,0x15,0x9d,0x9e,0x30,0x5b,0x37,0x01,0x48,0x62,0x9d,0xbc,0x7c,0x1e,0xd9,0x2a,0x8c,0xe8,
+		0x4b,0x58,0x22,0x04,0x64,0xcd,0x9d,0xf8,0x50,0xba,0xbe,0x48,0x48,0x63,0x7d,0x74,0xcc,0x90,0x4c,0xbe,0xab,
+		0x0f,0xe0,0x7d,0x29,0xf7,0x36,0xcf,0xee,0x68,0x52,0xaf,0x43,0x14,0xa2,0x3e,0x0b,0x0b,0xb4,0xca,0xc2,0x7f,
+		0x5d,0x84,0x08,0xd9,0xd6,0x44,0xa7,0xa2,0x28,0xbc,0xdb,0x81,0x09,0xf7,0x3c,0x34,0x86,0x21,0xf0,0xc6,0x25,0x00),
+	(0xa0,0x65,0x5b,0xb5,0x1f,0x50,0xfa,0xff,0x42,0xa4,0x75,0xb6,0xc1,0x37,0x8d,0xc3,0x9c,0xd7,0x4d,0xe9,0x80,
+		0x2c,0x80,0x5a,0x21,0xe0,0x8f,0x3f,0xe9,0x90,0xbb,0xbd,0xe7,0xfc,0x09,0x49,0xe1,0xdd,0xe3,0xb7,0x7f,0x6d,
+		0x85,0xcd,0x8c,0xf1,0x2b,0x3a,0x3d,0x61,0xb6,0x6e,0x02,0x90,0xc4,0x3a,0x79,0xf9,0x3c,0xb2,0x55,0x18,0xd1,
+		0x97,0xb0,0x44,0x08,0xc8,0x9a,0x3b,0xf1,0xa1,0x74,0x7d,0x91,0x90,0xc6,0xfa,0xe8,0x98,0x21,0x99,0x7c,0x57,
+		0x1f,0xc0,0xfb,0x52,0xee,0x6d,0x9e,0xdd,0xd1,0xa4,0x5e,0x87,0x28,0x44,0x7d,0x16,0x16,0x68,0x95,0x85,0xff,
+		0xba,0x08,0x11,0xb2,0xad,0x89,0x4e,0x45,0x51,0x78,0xb7,0x03,0x13,0xee,0x79,0x68,0x0c,0x43,0xe0,0x8d,0x4b,0x00),
+	(0x40,0xcb,0xb6,0x6a,0x3f,0xa0,0xf4,0xff,0x85,0x48,0xeb,0x6c,0x83,0x6f,0x1a,0x87,0x39,0xaf,0x9b,0xd2,0x01,
+		0x59,0x00,0xb5,0x42,0xc0,0x1f,0x7f,0xd2,0x21,0x77,0x7b,0xcf,0xf9,0x13,0x92,0xc2,0xbb,0xc7,0x6f,0xff,0xda,
+		0x0a,0x9b,0x19,0xe3,0x57,0x74,0x7a,0xc2,0x6c,0xdd,0x04,0x20,0x89,0x75,0xf2,0xf2,0x79,0x64,0xab,0x30,0xa2,
+		0x2f,0x61,0x89,0x10,0x90,0x35,0x77,0xe2,0x43,0xe9,0xfa,0x22,0x21,0x8d,0xf5,0xd1,0x31,0x43,0x32,0xf9,0xae,
+		0x3e,0x80,0xf7,0xa5,0xdc,0xdb,0x3c,0xbb,0xa3,0x49,0xbd,0x0e,0x51,0x88,0xfa,0x2c,0x2c,0xd0,0x2a,0x0b,0xff,
+		0x75,0x11,0x22,0x64,0x5b,0x13,0x9d,0x8a,0xa2,0xf0,0x6e,0x07,0x26,0xdc,0xf3,0xd0,0x18,0x86,0xc0,0x1b,0x97,0x00),
+	(0x80,0x96,0x6d,0xd5,0x7e,0x40,0xe9,0xff,0x0b,0x91,0xd6,0xd9,0x06,0xdf,0x34,0x0e,0x73,0x5e,0x37,0xa5,0x03,
+		0xb2,0x00,0x6a,0x85,0x80,0x3f,0xfe,0xa4,0x43,0xee,0xf6,0x9e,0xf3,0x27,0x24,0x85,0x77,0x8f,0xdf,0xfe,0xb5,
+		0x15,0x36,0x33,0xc6,0xaf,0xe8,0xf4,0x84,0xd9,0xba,0x09,0x40,0x12,0xeb,0xe4,0xe5,0xf3,0xc8,0x56,0x61,0x44,
+		0x5f,0xc2,0x12,0x21,0x20,0x6b,0xee,0xc4,0x87,0xd2,0xf5,0x45,0x42,0x1a,0xeb,0xa3,0x63,0x86,0x64,0xf2,0x5d,
+		0x7d,0x00,0xef,0x4b,0xb9,0xb7,0x79,0x76,0x47,0x93,0x7a,0x1d,0xa2,0x10,0xf5,0x59,0x58,0xa0,0x55,0x16,0xfe,
+		0xeb,0x22,0x44,0xc8,0xb6,0x26,0x3a,0x15,0x45,0xe1,0xdd,0x0e,0x4c,0xb8,0xe7,0xa1,0x31,0x0c,0x81,0x37,0x2e,0x01))
+
+M_14_80 = (
+	(0x15,0x5e,0x86,0xe5,0xe1,0xb8,0x22,0x20,0x32,0xf5,0xca,0x86,0x4b,0x13,0xa3,0x49,0x5c,0x5a,0x83,0x37,0xfa,
+		0x23,0x9e,0xd3,0x30,0x7b,0xae,0xfa,0x43,0x2c,0xfa,0x61,0xf0,0x67,0x71,0xb4,0x6f,0x54,0x73,0x8d,0x2a,0x77,
+		0x78,0x38,0x7e,0x3c,0xe9,0x0b,0x79,0xd7,0x48,0xbf,0x4c,0xd8,0x21,0x77,0x26,0x23,0x51,0x23,0x85,0x89,0x97,
+		0xa9,0xd2,0xe2,0xe1,0x0a,0x9c,0x3e,0xc7,0x51,0xa9,0x6d,0x73,0x88,0x69,0xb6,0xb3,0x1a,0xf1,0xa2,0x62,0xb7,
+		0x4e,0x92,0xc0,0x21,0x31,0x93,0xbd,0xd6,0xe0,0x04,0x47,0x58,0xaf,0x70,0xc1,0x20,0x08,0xc3,0xd4,0x58,0x99,
+		0x77,0x23,0xc5,0xd0,0x2e,0x1e,0x70,0xa7,0xbc,0xfb,0x25,0x3a,0x27,0x96,0x7b,0x44,0x44,0x1e,0xf5,0xb1,0x5e,
+		0x2a,0x8e,0x30,0xe7,0x72,0x04,0x82,0xa4,0x73,0xf7,0xa0,0x9a,0xd7,0x02,0x00),
+	(0x2a,0xbc,0x0c,0xcb,0xc3,0x71,0x45,0x40,0x64,0xea,0x95,0x0d,0x97,0x26,0x46,0x93,0xb8,0xb4,0x06,0x6f,0xf4,
+		0x47,0x3c,0xa7,0x61,0xf6,0x5c,0xf5,0x87,0x58,0xf4,0xc3,0xe0,0xcf,0xe2,0x68,0xdf,0xa8,0xe6,0x1a,0x55,0xee,
+		0xf0,0x70,0xfc,0x78,0xd2,0x17,0xf2,0xae,0x91,0x7e,0x99,0xb0,0x43,0xee,0x4c,0x46,0xa2,0x46,0x0a,0x13,0x2f,
+		0x53,0xa5,0xc5,0xc3,0x15,0x38,0x7d,0x8e,0xa3,0x52,0xdb,0xe6,0x10,0xd3,0x6c,0x67,0x35,0xe2,0x45,0xc5,0x6e,
+		0x9d,0x24,0x81,0x43,0x62,0x26,0x7b,0xad,0xc1,0x09,0x8e,0xb0,0x5e,0xe1,0x82,0x41,0x10,0x86,0xa9,0xb1,0x32,
+		0xef,0x46,0x8a,0xa1,0x5d,0x3c,0xe0,0x4e,0x79,0xf7,0x4b,0x74,0x4e,0x2c,0xf7,0x88,0x88,0x3c,0xea,0x63,0xbd,
+		0x54,0x1c,0x61,0xce,0xe5,0x08,0x04,0x49,0xe7,0xee,0x41,0x35,0xaf,0x05,0x00),
+	(0x54,0x78,0x19,0x96,0x87,0xe3,0x8a,0x80,0xc8,0xd4,0x2b,0x1b,0x2e,0x4d,0x8c,0x26,0x71,0x69,0x0d,0xde,0xe8,
+		0x8f,0x78,0x4e,0xc3,0xec,0xb9,0xea,0x0f,0xb1,0xe8,0x87,0xc1,0x9f,0xc5,0xd1,0xbe,0x51,0xcd,0x35,0xaa,0xdc,
+		0xe1,0xe1,0xf8,0xf1,0xa4,0x2f,0xe4,0x5d,0x23,0xfd,0x32,0x61,0x87,0xdc,0x99,0x8c,0x44,0x8d,0x14,0x26,0x5e,
+		0xa6,0x4a,0x8b,0x87,0x2b,0x70,0xfa,0x1c,0x47,0xa5,0xb6,0xcd,0x21,0xa6,0xd9,0xce,0x6a,0xc4,0x8b,0x8a,0xdd,
+		0x3a,0x49,0x02,0x87,0xc4,0x4c,0xf6,0x5a,0x83,0x13,0x1c,0x61,0xbd,0xc2,0x05,0x83,0x20,0x0c,0x53,0x63,0x65,
+		0xde,0x8d,0x14,0x43,0xbb,0x78,0xc0,0x9d,0xf2,0xee,0x97,0xe8,0x9c,0x58,0xee,0x11,0x11,0x79,0xd4,0xc7,0x7a,
+		0xa9,0x38,0xc2,0x9c,0xcb,0x11,0x08,0x92,0xce,0xdd,0x83,0x6a,0x5e,0x0b,0x00),
+	(0xa8,0xf0,0x32,0x2c,0x0f,0xc7,0x15,0x01,0x91,0xa9,0x57,0x36,0x5c,0x9a,0x18,0x4d,0xe2,0xd2,0x1a,0xbc,0xd1,
+		0x1f,0xf1,0x9c,0x86,0xd9,0x73,0xd5,0x1f,0x62,0xd1,0x0f,0x83,0x3f,0x8b,0xa3,0x7d,0xa3,0x9a,0x6b,0x54,0xb9,
+		0xc3,0xc3,0xf1,0xe3,0x49,0x5f,0xc8,0xbb,0x46,0xfa,0x65,0xc2,0x0e,0xb9,0x33,0x19,0x89,0x1a,0x29,0x4c,0xbc,
+		0x4c,0x95,0x16,0x0f,0x57,0xe0,0xf4,0x39,0x8e,0x4a,0x6d,0x9b,0x43,0x4c,0xb3,0x9d,0xd5,0x88,0x17,0x15,0xbb,
+		0x75,0x92,0x04,0x0e,0x89,0x99,0xec,0xb5,0x06,0x27,0x38,0xc2,0x7a,0x85,0x0b,0x06,0x41,0x18,0xa6,0xc6,0xca,
+		0xbc,0x1b,0x29,0x86,0x76,0xf1,0x80,0x3b,0xe5,0xdd,0x2f,0xd1,0x39,0xb1,0xdc,0x23,0x22,0xf2,0xa8,0x8f,0xf5,
+		0x52,0x71,0x84,0x39,0x97,0x23,0x10,0x24,0x9d,0xbb,0x07,0xd5,0xbc,0x16,0x00),
+	(0x50,0xe1,0x65,0x58,0x1e,0x8e,0x2b,0x02,0x22,0x53,0xaf,0x6c,0xb8,0x34,0x31,0x9a,0xc4,0xa5,0x35,0x78,0xa3,
+		0x3f,0xe2,0x39,0x0d,0xb3,0xe7,0xaa,0x3f,0xc4,0xa2,0x1f,0x06,0x7f,0x16,0x47,0xfb,0x46,0x35,0xd7,0xa8,0x72,
+		0x87,0x87,0xe3,0xc7,0x93,0xbe,0x90,0x77,0x8d,0xf4,0xcb,0x84,0x1d,0x72,0x67,0x32,0x12,0x35,0x52,0x98,0x78,
+		0x99,0x2a,0x2d,0x1e,0xae,0xc0,0xe9,0x73,0x1c,0x95,0xda,0x36,0x87,0x98,0x66,0x3b,0xab,0x11,0x2f,0x2a,0x76,
+		0xeb,0x24,0x09,0x1c,0x12,0x33,0xd9,0x6b,0x0d,0x4e,0x70,0x84,0xf5,0x0a,0x17,0x0c,0x82,0x30,0x4c,0x8d,0x95,
+		0x79,0x37,0x52,0x0c,0xed,0xe2,0x01,0x77,0xca,0xbb,0x5f,0xa2,0x73,0x62,0xb9,0x47,0x44,0xe4,0x51,0x1f,0xeb,
+		0xa5,0xe2,0x08,0x73,0x2e,0x47,0x20,0x48,0x3a,0x77,0x0f,0xaa,0x79,0x2d,0x00),
+	(0xa0,0xc2,0xcb,0xb0,0x3c,0x1c,0x57,0x04,0x44,0xa6,0x5e,0xd9,0x70,0x69,0x62,0x34,0x89,0x4b,0x6b,0xf0,0x46,
+		0x7f,0xc4,0x73,0x1a,0x66,0xcf,0x55,0x7f,0x88,0x45,0x3f,0x0c,0xfe,0x2c,0x8e,0xf6,0x8d,0x6a,0xae,0x51,0xe5,
+		0x0e,0x0f,0xc7,0x8f,0x27,0x7d,0x21,0xef,0x1a,0xe9,0x97,0x09,0x3b,0xe4,0xce,0x64,0x24,0x6a,0xa4,0x30,0xf1,
+		0x32,0x55,0x5a,0x3c,0x5c,0x81,0xd3,0xe7,0x38,0x2a,0xb5,0x6d,0x0e,0x31,0xcd,0x76,0x56,0x23,0x5e,0x54,0xec,
+		0xd6,0x49,0x12,0x38,0x24,0x66,0xb2,0xd7,0x1a,0x9c,0xe0,0x08,0xeb,0x15,0x2e,0x18,0x04,0x61,0x98,0x1a,0x2b,
+		0xf3,0x6e,0xa4,0x18,0xda,0xc5,0x03,0xee,0x94,0x77,0xbf,0x44,0xe7,0xc4,0x72,0x8f,0x88,0xc8,0xa3,0x3e,0xd6,
+		0x4b,0xc5,0x11,0xe6,0x5c,0x8e,0x40,0x90,0x74,0xee,0x1e,0x54,0xf3,0x5a,0x00),
+	(0x40,0x85,0x97,0x61,0x79,0x38,0xae,0x08,0x88,0x4c,0xbd,0xb2,0xe1,0xd2,0xc4,0x68,0x12,0x97,0xd6,0xe0,0x8d,
+		0xfe,0x88,0xe7,0x34,0xcc,0x9e,0xab,0xfe,0x10,0x8b,0x7e,0x18,0xfc,0x59,0x1c,0xed,0x1b,0xd5,0x5c,0xa3,0xca,
+		0x1d,0x1e,0x8e,0x1f,0x4f,0xfa,0x42,0xde,0x35,0xd2,0x2f,0x13,0x76,0xc8,0x9d,0xc9,0x48,0xd4,0x48,0x61,0xe2,
+		0x65,0xaa,0xb4,0x78,0xb8,0x02,0xa7,0xcf,0x71,0x54,0x6a,0xdb,0x1c,0x62,0x9a,0xed,0xac,0x46,0xbc,0xa8,0xd8,
+		0xad,0x93,0x24,0x70,0x48,0xcc,0x64,0xaf,0x35,0x38,0xc1,0x11,0xd6,0x2b,0x5c,0x30,0x08,0xc2,0x30,0x35,0x56,
+		0xe6,0xdd,0x48,0x31,0xb4,0x8b,0x07,0xdc,0x29,0xef,0x7e,0x89,0xce,0x89,0xe5,0x1e,0x11,0x91,0x47,0x7d,0xac,
+		0x97,0x8a,0x23,0xcc,0xb9,0x1c,0x81,0x20,0xe9,0xdc,0x3d,0xa8,0xe6,0xb5,0x00),
+	(0x80,0x0a,0x2f,0xc3,0xf2,0x70,0x5c,0x11,0x10,0x99,0x7a,0x65,0xc3,0xa5,0x89,0xd1,0x24,0x2e,0xad,0xc1,0x1b,
+		0xfd,0x11,0xcf,0x69,0x98,0x3d,0x57,0xfd,0x21,0x16,0xfd,0x30,0xf8,0xb3,0x38,0xda,0x37,0xaa,0xb9,0x46,0x95,
+		0x3b,0x3c,0x1c,0x3f,0x9e,0xf4,0x85,0xbc,0x6b,0xa4,0x5f,0x26,0xec,0x90,0x3b,0x93,0x91,0xa8,0x91,0xc2,0xc4,
+		0xcb,0x54,0x69,0xf1,0x70,0x05,0x4e,0x9f,0xe3,0xa8,0xd4,0xb6,0x39,0xc4,0x34,0xdb,0x59,0x8d,0x78,0x51,0xb1,
+		0x5b,0x27,0x49,0xe0,0x90,0x98,0xc9,0x5e,0x6b,0x70,0x82,0x23,0xac,0x57,0xb8,0x60,0x10,0x84,0x61,0x6a,0xac,
+		0xcc,0xbb,0x91,0x62,0x68,0x17,0x0f,0xb8,0x53,0xde,0xfd,0x12,0x9d,0x13,0xcb,0x3d,0x22,0x22,0x8f,0xfa,0x58,
+		0x2f,0x15,0x47,0x98,0x73,0x39,0x02,0x41,0xd2,0xb9,0x7b,0x50,0xcd,0x6b,0x01))
+
+def bch_enc_14(data, enc_len, level):
+	""" bch ecc encode function, parity bits is 14.
+	data is the source buffer
+	enc_len is the encode length
+	level is the ecc level used """
+
+	#print "bch encode length is %d, " % enc_len,
+	#print "ecc level is %d " % level
+
+	# select proper matrix for the ecc level assigned #
+	parity_byte = int(math.ceil(float(level) * 14 / 8))
+	#temp = 'matrix = M_14_' + str(level)
+	#exec(temp)
+	if str(level) == "4":
+		matrix = M_14_4
+	elif str(level) == "6":
+		matrix = M_14_6
+	elif str(level) == "8":
+		matrix = M_14_8
+	elif str(level) == "10":
+		matrix = M_14_10
+	elif str(level) == "12":
+		matrix = M_14_12
+	elif str(level) == "14":
+		matrix = M_14_14
+	elif str(level) == "16":
+		matrix = M_14_16
+	elif str(level) == "18":
+		matrix = M_14_18
+	elif str(level) == "20":
+		matrix = M_14_20
+	elif str(level) == "22":
+		matrix = M_14_22
+	elif str(level) == "24":
+		matrix = M_14_24
+	elif str(level) == "28":
+		matrix = M_14_28
+	elif str(level) == "32":
+		matrix = M_14_32
+	elif str(level) == "36":
+		matrix = M_14_36
+	elif str(level) == "40":
+		matrix = M_14_40
+	elif str(level) == "44":
+		matrix = M_14_44
+	elif str(level) == "48":
+		matrix = M_14_48
+	elif str(level) == "52":
+		matrix = M_14_52
+	elif str(level) == "56":
+		matrix = M_14_56
+	elif str(level) == "60":
+		matrix = M_14_60
+	elif str(level) == "68":
+		matrix = M_14_68
+	elif str(level) == "72":
+		matrix = M_14_72
+	elif str(level) == "80":
+		matrix = M_14_80
+
+	# fetch raw data #
+	raw = data + (b'\0' * parity_byte)
+	raw = bytearray(raw)
+
+	for i in range(enc_len):
+		for j in range(8):
+			if (raw[i] & (1 << j)) != 0:
+				for k in range(parity_byte + 1):
+					raw[i + k] ^= matrix[j][k]
+	
+	# feedback parity data generated #
+	#raw = raw.decode()#str(raw)
+	parity_data = raw[enc_len:]
+	return parity_data
+
+if __name__ == "__main__":
+	""" this is bch encode function. """
+	print("this is bch encode function.")
\ No newline at end of file
diff --git a/src/bsp/scatter/tools/nand-utils/ecc_bch_13.py b/src/bsp/scatter/tools/nand-utils/ecc_bch_13.py
new file mode 100755
index 0000000..ce7685f
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/ecc_bch_13.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+
+import math
+
+M_13_4 = ((0x45,0x89,0x41,0xb8,0x3a,0xac,0x1a,0x00),
+		(0x8a,0x12,0x83,0x70,0x75,0x58,0x35,0x00),
+		(0x14,0x25,0x06,0xe1,0xea,0xb0,0x6a,0x00),
+		(0x28,0x4a,0x0c,0xc2,0xd5,0x61,0xd5,0x00),
+		(0x50,0x94,0x18,0x84,0xab,0xc3,0xaa,0x01),
+		(0xa0,0x28,0x31,0x08,0x57,0x87,0x55,0x03),
+		(0x40,0x51,0x62,0x10,0xae,0x0e,0xab,0x06),
+		(0x80,0xa2,0xc4,0x20,0x5c,0x1d,0x56,0x0d))
+
+M_13_6 = ((0x7f,0x9e,0x49,0x86,0x93,0x87,0x9d,0xce,0x46,0x5f,0x00),
+		(0xfe,0x3c,0x93,0x0c,0x27,0x0f,0x3b,0x9d,0x8d,0xbe,0x00),
+		(0xfc,0x79,0x26,0x19,0x4e,0x1e,0x76,0x3a,0x1b,0x7d,0x01),
+		(0xf8,0xf3,0x4c,0x32,0x9c,0x3c,0xec,0x74,0x36,0xfa,0x02),
+		(0xf0,0xe7,0x99,0x64,0x38,0x79,0xd8,0xe9,0x6c,0xf4,0x05),
+		(0xe0,0xcf,0x33,0xc9,0x70,0xf2,0xb0,0xd3,0xd9,0xe8,0x0b),
+		(0xc0,0x9f,0x67,0x92,0xe1,0xe4,0x61,0xa7,0xb3,0xd1,0x17),
+		(0x80,0x3f,0xcf,0x24,0xc3,0xc9,0xc3,0x4e,0x67,0xa3,0x2f))
+
+M_13_8 = ((0x51,0x3f,0x51,0x0e,0xbc,0x61,0x90,0xc3,0x05,0x47,0x47,0xbe,0x89,0x01),
+		(0xa2,0x7e,0xa2,0x1c,0x78,0xc3,0x20,0x87,0x0b,0x8e,0x8e,0x7c,0x13,0x03),
+		(0x44,0xfd,0x44,0x39,0xf0,0x86,0x41,0x0e,0x17,0x1c,0x1d,0xf9,0x26,0x06),
+		(0x88,0xfa,0x89,0x72,0xe0,0x0d,0x83,0x1c,0x2e,0x38,0x3a,0xf2,0x4d,0x0c),
+		(0x10,0xf5,0x13,0xe5,0xc0,0x1b,0x06,0x39,0x5c,0x70,0x74,0xe4,0x9b,0x18),
+		(0x20,0xea,0x27,0xca,0x81,0x37,0x0c,0x72,0xb8,0xe0,0xe8,0xc8,0x37,0x31),
+		(0x40,0xd4,0x4f,0x94,0x03,0x6f,0x18,0xe4,0x70,0xc1,0xd1,0x91,0x6f,0x62),
+		(0x80,0xa8,0x9f,0x28,0x07,0xde,0x30,0xc8,0xe1,0x82,0xa3,0x23,0xdf,0xc4))
+
+M_13_10 = ((0xd3,0x92,0x7b,0x58,0x0a,0x9f,0x2c,0x92,0xdb,0x83,0x6a,0x40,0xf5,0x83,0x66,0x9f,0x04,0x00),
+		(0xa6,0x25,0xf7,0xb0,0x14,0x3e,0x59,0x24,0xb7,0x07,0xd5,0x80,0xea,0x07,0xcd,0x3e,0x09,0x00),
+		(0x4c,0x4b,0xee,0x61,0x29,0x7c,0xb2,0x48,0x6e,0x0f,0xaa,0x01,0xd5,0x0f,0x9a,0x7d,0x12,0x00),
+		(0x98,0x96,0xdc,0xc3,0x52,0xf8,0x64,0x91,0xdc,0x1e,0x54,0x03,0xaa,0x1f,0x34,0xfb,0x24,0x00),
+		(0x30,0x2d,0xb9,0x87,0xa5,0xf0,0xc9,0x22,0xb9,0x3d,0xa8,0x06,0x54,0x3f,0x68,0xf6,0x49,0x00),
+		(0x60,0x5a,0x72,0x0f,0x4b,0xe1,0x93,0x45,0x72,0x7b,0x50,0x0d,0xa8,0x7e,0xd0,0xec,0x93,0x00),
+		(0xc0,0xb4,0xe4,0x1e,0x96,0xc2,0x27,0x8b,0xe4,0xf6,0xa0,0x1a,0x50,0xfd,0xa0,0xd9,0x27,0x01),
+		(0x80,0x69,0xc9,0x3d,0x2c,0x85,0x4f,0x16,0xc9,0xed,0x41,0x35,0xa0,0xfa,0x41,0xb3,0x4f,0x02))
+
+M_13_12 = ((0x4f,0xc2,0x99,0xd4,0x10,0xb5,0xd4,0x3c,0xa4,0x2c,0x05,0x4a,0xc6,0xce,0xd6,0x0f,0x09,0xf4,0x40,0x11,0x00),
+		(0x9e,0x84,0x33,0xa9,0x21,0x6a,0xa9,0x79,0x48,0x59,0x0a,0x94,0x8c,0x9d,0xad,0x1f,0x12,0xe8,0x81,0x22,0x00),
+		(0x3c,0x09,0x67,0x52,0x43,0xd4,0x52,0xf3,0x90,0xb2,0x14,0x28,0x19,0x3b,0x5b,0x3f,0x24,0xd0,0x03,0x45,0x00),
+		(0x78,0x12,0xce,0xa4,0x86,0xa8,0xa5,0xe6,0x21,0x65,0x29,0x50,0x32,0x76,0xb6,0x7e,0x48,0xa0,0x07,0x8a,0x00),
+		(0xf0,0x24,0x9c,0x49,0x0d,0x51,0x4b,0xcd,0x43,0xca,0x52,0xa0,0x64,0xec,0x6c,0xfd,0x90,0x40,0x0f,0x14,0x01),
+		(0xe0,0x49,0x38,0x93,0x1a,0xa2,0x96,0x9a,0x87,0x94,0xa5,0x40,0xc9,0xd8,0xd9,0xfa,0x21,0x81,0x1e,0x28,0x02),
+		(0xc0,0x93,0x70,0x26,0x35,0x44,0x2d,0x35,0x0f,0x29,0x4b,0x81,0x92,0xb1,0xb3,0xf5,0x43,0x02,0x3d,0x50,0x04),
+		(0x80,0x27,0xe1,0x4c,0x6a,0x88,0x5a,0x6a,0x1e,0x52,0x96,0x02,0x25,0x63,0x67,0xeb,0x87,0x04,0x7a,0xa0,0x08))
+
+M_13_14 = ((0xeb,0xee,0x73,0xc9,0x34,0x8a,0xc0,0x32,0x03,0x65,0x1f,0x54,0x4b,0xad,0x2b,0xd4,0xe0,0x15,0x23,0xc2,0x08,0x65,0x4a,0x00),
+		(0xd6,0xdd,0xe7,0x92,0x69,0x14,0x81,0x65,0x06,0xca,0x3e,0xa8,0x96,0x5a,0x57,0xa8,0xc1,0x2b,0x46,0x84,0x11,0xca,0x94,0x00),
+		(0xac,0xbb,0xcf,0x25,0xd3,0x28,0x02,0xcb,0x0c,0x94,0x7d,0x50,0x2d,0xb5,0xae,0x50,0x83,0x57,0x8c,0x08,0x23,0x94,0x29,0x01),
+		(0x58,0x77,0x9f,0x4b,0xa6,0x51,0x04,0x96,0x19,0x28,0xfb,0xa0,0x5a,0x6a,0x5d,0xa1,0x06,0xaf,0x18,0x11,0x46,0x28,0x53,0x02),
+		(0xb0,0xee,0x3e,0x97,0x4c,0xa3,0x08,0x2c,0x33,0x50,0xf6,0x41,0xb5,0xd4,0xba,0x42,0x0d,0x5e,0x31,0x22,0x8c,0x50,0xa6,0x04),
+		(0x60,0xdd,0x7d,0x2e,0x99,0x46,0x11,0x58,0x66,0xa0,0xec,0x83,0x6a,0xa9,0x75,0x85,0x1a,0xbc,0x62,0x44,0x18,0xa1,0x4c,0x09),
+		(0xc0,0xba,0xfb,0x5c,0x32,0x8d,0x22,0xb0,0xcc,0x40,0xd9,0x07,0xd5,0x52,0xeb,0x0a,0x35,0x78,0xc5,0x88,0x30,0x42,0x99,0x12),
+		(0x80,0x75,0xf7,0xb9,0x64,0x1a,0x45,0x60,0x99,0x81,0xb2,0x0f,0xaa,0xa5,0xd6,0x15,0x6a,0xf0,0x8a,0x11,0x61,0x84,0x32,0x25))
+
+M_13_16 = ((0xa7,0xfb,0xf8,0x61,0xfb,0x46,0x8d,0x5b,0xbf,0x09,0xfe,0xc1,0xdf,0xab,0x44,0xff,0x81,0xec,0x9b,0x3d,0xca,0x00,0x67,0x17,0x7e,0x17,0x01),
+		(0x4e,0xf7,0xf1,0xc3,0xf6,0x8d,0x1a,0xb7,0x7e,0x13,0xfc,0x83,0xbf,0x57,0x89,0xfe,0x03,0xd9,0x37,0x7b,0x94,0x01,0xce,0x2e,0xfc,0x2e,0x02),
+		(0x9c,0xee,0xe3,0x87,0xed,0x1b,0x35,0x6e,0xfd,0x26,0xf8,0x07,0x7f,0xaf,0x12,0xfd,0x07,0xb2,0x6f,0xf6,0x28,0x03,0x9c,0x5d,0xf8,0x5d,0x04),
+		(0x38,0xdd,0xc7,0x0f,0xdb,0x37,0x6a,0xdc,0xfa,0x4d,0xf0,0x0f,0xfe,0x5e,0x25,0xfa,0x0f,0x64,0xdf,0xec,0x51,0x06,0x38,0xbb,0xf0,0xbb,0x08),
+		(0x70,0xba,0x8f,0x1f,0xb6,0x6f,0xd4,0xb8,0xf5,0x9b,0xe0,0x1f,0xfc,0xbd,0x4a,0xf4,0x1f,0xc8,0xbe,0xd9,0xa3,0x0c,0x70,0x76,0xe1,0x77,0x11),
+		(0xe0,0x74,0x1f,0x3f,0x6c,0xdf,0xa8,0x71,0xeb,0x37,0xc1,0x3f,0xf8,0x7b,0x95,0xe8,0x3f,0x90,0x7d,0xb3,0x47,0x19,0xe0,0xec,0xc2,0xef,0x22),
+		(0xc0,0xe9,0x3e,0x7e,0xd8,0xbe,0x51,0xe3,0xd6,0x6f,0x82,0x7f,0xf0,0xf7,0x2a,0xd1,0x7f,0x20,0xfb,0x66,0x8f,0x32,0xc0,0xd9,0x85,0xdf,0x45),
+		(0x80,0xd3,0x7d,0xfc,0xb0,0x7d,0xa3,0xc6,0xad,0xdf,0x04,0xff,0xe0,0xef,0x55,0xa2,0xff,0x40,0xf6,0xcd,0x1e,0x65,0x80,0xb3,0x0b,0xbf,0x8b))
+
+def bch_enc_13(data, enc_len, level):
+	""" bch ecc encode function, parity bits is 13.
+	data is the source buffer
+	enc_len is the encode length
+	level is the ecc level used """
+
+	#print "bch encode length is %d, " % enc_len,
+	#print "ecc level is %d " % level
+
+	# select proper matrix for the ecc level assigned #
+	parity_byte = int(math.ceil(float(level) * 13 / 8))
+	temp = 'matrix = M_13_' + str(level)
+	exec(temp)
+
+	# fetch raw data #
+	raw = data + ('\0' * parity_byte)
+	raw = bytearray(raw)
+
+	for i in range(enc_len):
+		for j in range(8):
+			if (raw[i] & (1 << j)) != 0:
+				for k in range(parity_byte + 1):
+					raw[i + k] ^= matrix[j][k]
+
+	# feedback parity data generated #
+	raw = str(raw)
+	parity_data = raw[enc_len:]
+	return parity_data
+
+if __name__ == "__main__":
+	""" this is bch encode function. """
+	print "this is bch encode function."
diff --git a/src/bsp/scatter/tools/nand-utils/gen-nand-burn-img.sh b/src/bsp/scatter/tools/nand-utils/gen-nand-burn-img.sh
new file mode 100755
index 0000000..1608eaa
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen-nand-burn-img.sh
@@ -0,0 +1,147 @@
+#! /bin/sh
+
+NAND_HEADER_VERSION=$1
+NAND_CHIP_NAME=$2
+PARTITION_XML=$3
+
+if [ "${NAND_CHIP_NAME}" = "" ]; then
+	echo "ERROR: please input NAND_CHIP_NAME"
+	exit 1
+else
+	echo "NAND: ${NAND_CHIP_NAME}"
+fi
+
+if [ "${NAND_HEADER_VERSION}" = "" ]; then
+	echo "ERROR: please input NAND_HEADER_VERSION"
+	exit 2
+else
+	echo "NAND_HEADER_VERSION: ${NAND_HEADER_VERSION}"
+	if [ "${NAND_HEADER_VERSION}" = "2.0" ]; then
+		RANDOM_EN=0
+	elif [ "${NAND_HEADER_VERSION}" = "1.1" ]; then
+		RANDOM_EN=1
+	fi
+fi
+
+if [ "${PARTITION_XML}" = "" ]; then
+	echo "ERROR: please input PARTITION_XML"
+	exit 3
+else
+	echo "PARTITION_XML: ${PARTITION_XML}"
+fi
+
+OUTPUT_FLD="output"
+IMAGE_FLD="images"
+BURN_SUFFIX="-burn"
+BURN_IMG="${PWD}/${OUTPUT_FLD}/nand-burn.img"
+BURN_LIST_CSV="${PWD}/${OUTPUT_FLD}/partition_table.csv"
+BURN_LIST_DEF="${PWD}/${OUTPUT_FLD}/partition_table.def"
+rm -rf ${PWD}/${OUTPUT_FLD}/*${BURN_SUFFIX}
+rm -rf ${BURN_IMG}
+touch ${BURN_IMG}
+
+rm -rf ${BURN_LIST_CSV}
+touch ${BURN_LIST_CSV}
+rm -rf ${BURN_LIST_DEF}
+touch ${BURN_LIST_DEF}
+
+python ${PWD}/tools/nand-utils/gen_burner_partition_table_def.py ${NAND_CHIP_NAME} \
+	${NAND_HEADER_VERSION} ${BURN_LIST_DEF} 0 0 0 0
+
+LBS=$(grep -o 'lbs="[0-9]*"' ${PARTITION_XML} | grep -o [0-9]*)
+
+MBR_NAND="MBR_NAND"
+MBR_NAND_BRUN="MBR_NAND-burn"
+PART_IDX=0
+
+cat ${PARTITION_XML} | while read line
+do
+	IMAGE_NAME=""
+	LBA_START=""
+	LBA_END=""
+	CHECK=$(echo $line | grep "name")
+	if [ "${CHECK}" != "" ]; then
+		PARTITION=${line#*name=}
+		PARTITION=${PARTITION#*\"}
+		PARTITION=${PARTITION%%\"*}
+	else
+		PARTITION=""
+	fi
+	if [ "${PARTITION}" = "UBOOT" ]; then
+		IMAGE_NAME="lk.img"
+	fi
+	if [ "${PARTITION}" = "TEE1" -o "${PARTITION}" = "TEE2" ]; then
+		IMAGE_NAME="tz.img"
+	fi
+	if [ "${PARTITION}" = "USRDATA" ]; then
+		IMAGE_NAME="userdata.ubi"
+	fi
+	if [ "${PARTITION}" = "BOOTIMG1" -o "${PARTITION}" = "BOOTIMG2" ]; then
+		IMAGE_NAME="boot.img"
+	fi
+	if [ "${PARTITION}" = "ROOTFS1" -o "${PARTITION}" = "ROOTFS2" ]; then
+		IMAGE_NAME="rootfs.ubi"
+	fi
+
+	if [ "${PARTITION}" != "" ]; then
+		echo ${PART_IDX} ${PARTITION}
+		if [ "${IMAGE_NAME}" != "" -a ! -f "${PWD}/${IMAGE_FLD}/${IMAGE_NAME}" ]; then
+			echo "file "${PWD}/${IMAGE_FLD}/${IMAGE_NAME}" not exist!! "
+			IMAGE_NAME=""
+		fi
+		LBA_START=${line#*start=}
+		LBA_START=${LBA_START#*\"}
+		LBA_START=${LBA_START%%\"*}
+		LBA_END=${line#*end=}
+		LBA_END=${LBA_END#*\"}
+		LBA_END=${LBA_END%%\"*}
+		((LBA_NUM=${LBA_END}-${LBA_START}+1))
+		((PART_SIZE=${LBS}*${LBA_NUM}))
+		((PART_START_ADDR=${LBS}*${LBA_START}))
+
+		if [ "${PART_IDX}" = "0" ]; then
+			((MBR_PART_SIZE=${LBS}*${LBA_START}))
+			((MBR_LBA_END=${LBA_START}-1))
+			python ${PWD}/tools/nand-utils/gen_burner_image.pyc ${NAND_CHIP_NAME} \
+				${PWD}/${IMAGE_FLD}/${MBR_NAND} ${PWD}/${OUTPUT_FLD}/${MBR_NAND_BRUN} ${NAND_HEADER_VERSION} ${RANDOM_EN}
+			touch ${PWD}/${IMAGE_FLD}/${MBR_NAND_BRUN}
+			cat ${PWD}/${OUTPUT_FLD}/${MBR_NAND_BRUN} >> ${PWD}/${IMAGE_FLD}/${MBR_NAND_BRUN}
+			python ${PWD}/tools/nand-utils/pad_dummy_data_by_partition.pyc ${NAND_CHIP_NAME} \
+				${PWD}/${IMAGE_FLD}/${MBR_NAND_BRUN} ${MBR_PART_SIZE} ${NAND_HEADER_VERSION}
+			cat ${PWD}/${IMAGE_FLD}/${MBR_NAND_BRUN} > ${BURN_IMG}
+			python ${PWD}/tools/nand-utils/gen_burner_partition_table_def.py ${NAND_CHIP_NAME} \
+				${NAND_HEADER_VERSION} ${BURN_LIST_DEF} ${PWD}/${OUTPUT_FLD}/${MBR_NAND_BRUN} 0 ${MBR_LBA_END} 1
+			python ${PWD}/tools/nand-utils/gen_burner_partition_table_csv.py ${NAND_CHIP_NAME} \
+				${NAND_HEADER_VERSION} ${BURN_LIST_CSV} ${PWD}/${OUTPUT_FLD}/${MBR_NAND_BRUN} 0 ${MBR_LBA_END} "MBR_NAND"
+		fi
+
+	fi
+
+	if [ "${IMAGE_NAME}" != "" ]; then
+		PART_IDX=$((${PART_IDX}+1))
+		if [ ! -f "${PWD}/${IMAGE_FLD}/${IMAGE_NAME}${BURN_SUFFIX}" ]; then
+			python ${PWD}/tools/nand-utils/gen_burner_image.pyc ${NAND_CHIP_NAME} \
+				${PWD}/${IMAGE_FLD}/${IMAGE_NAME} ${PWD}/${OUTPUT_FLD}/${IMAGE_NAME}${BURN_SUFFIX} ${NAND_HEADER_VERSION} ${RANDOM_EN}
+			touch ${PWD}/${IMAGE_FLD}/${IMAGE_NAME}${BURN_SUFFIX}
+			cat ${PWD}/${OUTPUT_FLD}/${IMAGE_NAME}${BURN_SUFFIX} >> ${PWD}/${IMAGE_FLD}/${IMAGE_NAME}${BURN_SUFFIX}
+			python ${PWD}/tools/nand-utils/pad_dummy_data_by_partition.pyc ${NAND_CHIP_NAME} \
+				${PWD}/${IMAGE_FLD}/${IMAGE_NAME}${BURN_SUFFIX} ${PART_SIZE} ${NAND_HEADER_VERSION}
+		fi
+		cat ${PWD}/${IMAGE_FLD}/${IMAGE_NAME}${BURN_SUFFIX} >> ${BURN_IMG}
+		python ${PWD}/tools/nand-utils/gen_burner_partition_table_def.py ${NAND_CHIP_NAME} \
+			${NAND_HEADER_VERSION} ${BURN_LIST_DEF} ${PWD}/${OUTPUT_FLD}/${IMAGE_NAME}${BURN_SUFFIX} ${LBA_START} ${LBA_END} 1
+		python ${PWD}/tools/nand-utils/gen_burner_partition_table_csv.py ${NAND_CHIP_NAME} \
+			${NAND_HEADER_VERSION} ${BURN_LIST_CSV} ${PWD}/${OUTPUT_FLD}/${IMAGE_NAME}${BURN_SUFFIX} ${LBA_START} ${LBA_END} ${PARTITION}
+	elif [ "${PARTITION}" != "" ]; then
+		PART_IDX=$((${PART_IDX}+1))
+		touch ${PWD}/${IMAGE_FLD}/${PARTITION}${BURN_SUFFIX}
+		python ${PWD}/tools/nand-utils/pad_dummy_data_by_partition.pyc ${NAND_CHIP_NAME} \
+			${PWD}/${IMAGE_FLD}/${PARTITION}${BURN_SUFFIX} ${PART_SIZE} ${NAND_HEADER_VERSION}
+		cat ${PWD}/${IMAGE_FLD}/${PARTITION}${BURN_SUFFIX} >> ${BURN_IMG}
+	fi
+done
+
+python ${PWD}/tools/nand-utils/gen_burner_partition_table_def.py ${NAND_CHIP_NAME} \
+	${NAND_HEADER_VERSION} ${BURN_LIST_DEF} 0 0 0 2
+
+rm -f ${PWD}/${IMAGE_FLD}/*${BURN_SUFFIX}
diff --git a/src/bsp/scatter/tools/nand-utils/gen_burner_image.py b/src/bsp/scatter/tools/nand-utils/gen_burner_image.py
new file mode 100644
index 0000000..a6acb1a
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_burner_image.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python
+
+import argparse
+import sys
+import os
+import math
+import shutil
+import pp_tbl
+import gen_nand_header
+import gen_nand_header_v11
+import randomizer
+from pad_ecc_by_sector import pad_ecc
+from randomizer import randomizer
+
+def padding(data, size):
+	return data + '\0' * (size - len(data))
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('in_image', help = 'raw input image')
+	parser.add_argument('out_image', help = 'the output burn image ')
+	parser.add_argument('version', help= 'nand header version')
+	parser.add_argument('rand_en', help = 'if randomizer is enabled')
+	args = parser.parse_args()
+	version = float(args.version)
+	rand_en = int(args.rand_en)
+
+	if version == 2.0:
+		(vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, ppen, ppb) = gen_nand_header.gen_header(args.nand_name)
+		bad_swap = 1
+	elif version == 1.1:
+		(vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, ppen, ppb) = gen_nand_header_v11.gen_header(args.nand_name, 192, args.nand_name + '_header.bin')
+		bad_swap = 0
+
+	ecc_file = args.out_image
+	rand_file = args.out_image
+	if rand_en == 1:
+		ecc_file = args.nand_name + '_ecc.bin'
+	if ppen == 1:
+		paired = raw_input("insert empty paired page ? Y/y or N/n ")
+		if paired in ['Y', 'y']:
+			rand_file = args.nand_name + '_rand.bin'
+			ecc_file = args.nand_name + '_ecc.bin'
+	sector_size = 1024 if page_size > 512 else 512
+	sector_per_page = page_size / sector_size
+	sector_spare_size = spare_size / sector_per_page
+	# input image page size alignment #
+	file_len = os.path.getsize(args.in_image)
+	pages = int(math.ceil(float(file_len) / page_size))
+	in_file = "temp_in.bin"
+	with open(args.in_image, "rb") as f_in:
+		with open(in_file, "wb") as f_temp:
+			f_temp.write(padding(f_in.read(), pages * page_size))
+	pad_ecc(in_file, ecc_file, sector_size, fdm_size, fdmecc_size, ecc_strength, sector_spare_size, page_size, bad_swap)
+
+	if rand_en == 1:
+		randomizer(ecc_file, rand_file, "SS", 1, page_size, spare_size, sector_size, ppb, ppen, vendor)
+
+	# MT8516 force sector spare size from 56, 54, to be 52
+	if version == 1.1:
+		# spare settings must match 8516 BOOT ROM, The sector size default is 1024 bytes.
+		SPARES = [32, 52, 64, 80, 88, 96, 100, 104, 122, 124]
+		sector_spare_size_adjust = sector_spare_size
+
+		for i in range(len(SPARES)):
+			if (sector_spare_size <= SPARES[i]):
+				if sector_spare_size == SPARES[i]:
+					sector_spare_size_adjust = SPARES[i]
+				if (sector_spare_size < SPARES[i]) and (i != 0):
+					sector_spare_size_adjust = SPARES[i - 1]
+				break
+		k = 0
+		pad_data = (sector_spare_size - sector_spare_size_adjust) * sector_per_page
+		adjust_file = rand_file + '_adjust'
+		f_in = open(rand_file, "rb")
+		f_out = open(adjust_file, "wb")
+		for i in range(pages * sector_per_page):
+			f_in.seek(((sector_size + sector_spare_size) * i), 0)
+			sector_data = f_in.read(sector_size + sector_spare_size_adjust)
+			if (i % sector_per_page) == (sector_per_page - 1):
+				sector_data += '\xff' * pad_data
+			if (i) > 0 and (i % sector_per_page) == 0:
+				k = k + 1
+				f_out.seek(((sector_size + sector_spare_size) * i), 0)
+			else:
+				f_out.seek((sector_size + sector_spare_size_adjust) * i + (k * pad_data), 0)
+
+			f_out.write(sector_data)
+
+		f_in.close()
+		f_out.close()
+		shutil.copyfile(adjust_file, rand_file)
+		# remove temp files #
+		os.remove(adjust_file)
+	# insert empty paired page #
+	if ppen == 1 and paired in ['Y', 'y']:
+		if rand_en == 1:
+			pp_file = rand_file
+		else:
+			pp_file = ecc_file
+		if vendor == 'TSB':
+			PP = pp_tbl.TSB_PP
+		else:
+			raise Exception("unsupport %s pp table " % vendor)
+		f_pp = open(pp_file, "rb")
+		f_out = open(args.out_image, "wb")
+
+		if (os.path.getsize(in_file) % page_size) != 0:
+			raise Exception("input image size is not page size aligned")
+		page_number = os.path.getsize(in_file) / page_size
+		block_number = int(math.ceil(float(page_number) / (ppb / 2)))
+		print "page num %d  block num %d" % (page_number, block_number)
+		for i in range(ppb * block_number):
+			if page_number > 0 and (i % ppb) in PP:
+				f_out.write(f_pp.read(page_size + spare_size))
+				page_number -= 1
+			else:
+				f_out.write('\xff' * (page_size + spare_size))
+		f_pp.close()
+		f_out.close()
+		# remove temp files #
+		os.remove(pp_file)
+
+	if rand_en == 1:
+		os.remove(ecc_file)
+
+	# remove temp files #
+	os.remove(args.nand_name + '_header.bin')
+	os.remove(in_file)
+
+if __name__ == "__main__":
+        sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/gen_burner_partition_table_csv.py b/src/bsp/scatter/tools/nand-utils/gen_burner_partition_table_csv.py
new file mode 100755
index 0000000..c2adf29
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_burner_partition_table_csv.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+import argparse
+import csv
+import sys
+import struct
+import os
+import math
+import gen_nand_header
+import gen_nand_header_v11
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('version', help= 'nand header version')
+	parser.add_argument('table_file', help = 'partition table file')
+	parser.add_argument('image', help = 'image file name')
+	parser.add_argument('start_page', help = 'partition start page index')
+	parser.add_argument('end_page', help = 'partition end page index')
+	parser.add_argument('part_name', help = 'partition name')
+	args = parser.parse_args()
+
+	version = float(args.version)
+	start_page = int(args.start_page)
+	end_page = int(args.end_page)
+	if version == 2.0:
+		(vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, ppen, ppb) = gen_nand_header.gen_header(args.nand_name)
+	elif version == 1.1:
+		(vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, ppen, ppb) = gen_nand_header_v11.gen_header(args.nand_name, 192, args.nand_name + '_header.bin')
+
+	file_len = os.path.getsize(args.image)
+	if (file_len % (page_size + spare_size)) != 0:
+		raise Exception("image size is not full page size aligned")
+	block_num = int(math.ceil(float(file_len) / ((page_size + spare_size) * ppb)))
+	if (start_page % ppb) != 0:
+		raise Exception("partition start page is not block align")
+	start_blk = start_page / ppb
+	if ((end_page + 1) % ppb) != 0:
+		raise Exception("partition end page is not block align")
+	end_blk = end_page / ppb
+	line_info = [start_blk, end_blk, block_num, '0xffffffff', args.part_name]
+
+	with open(args.table_file, "ab") as csvf:
+		csvwriter = csv.writer(csvf, delimiter=';')
+		csvwriter.writerow(line_info)
+
+	# remove temp files #
+	os.remove(args.nand_name + '_header.bin')
+
+if __name__ == "__main__":
+        sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/gen_burner_partition_table_def.py b/src/bsp/scatter/tools/nand-utils/gen_burner_partition_table_def.py
new file mode 100755
index 0000000..61c81dd
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_burner_partition_table_def.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+
+import argparse
+import sys
+import struct
+import os
+import math
+import gen_nand_header
+import gen_nand_header_v11
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('version', help= 'nand header version')
+	parser.add_argument('table_file', help = 'partition table file')
+	parser.add_argument('image', help = 'image file name')
+	parser.add_argument('start_page', help = 'partition start page index')
+	parser.add_argument('end_page', help = 'partition end page index')
+	parser.add_argument('pad', help = '0: pad header, 1: no pad, 2: pad tail')
+	args = parser.parse_args()
+	pad = int(args.pad)
+
+	if pad == 0:
+		line_info = "GROUP DEFINE2" + (3 * '\0')
+	elif pad == 2:
+		line_info = 16 * '\xff'
+	elif pad == 1:
+		version = float(args.version)
+		start_page = int(args.start_page)
+		end_page = int(args.end_page)
+		if version == 2.0:
+			(vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, ppen, ppb) = gen_nand_header.gen_header(args.nand_name)
+		elif version == 1.1:
+			(vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, ppen, ppb) = gen_nand_header_v11.gen_header(args.nand_name, 192, args.nand_name + '_header.bin')
+
+		file_len = os.path.getsize(args.image)
+		if (file_len % (page_size + spare_size)) != 0:
+			raise Exception("image size is not full page size aligned")
+		block_num = int(math.ceil(float(file_len) / ((page_size + spare_size) * ppb)))
+		if (start_page % ppb) != 0:
+			raise Exception("partition start page is not block align")
+		start_blk = start_page / ppb
+		if ((end_page + 1) % ppb) != 0:
+			raise Exception("partition end page is not block align")
+		end_blk = end_page / ppb
+
+		data_type = 1
+
+		line_info = struct.pack("I", data_type)
+		line_info += struct.pack("I", start_blk)
+		line_info += struct.pack("I", end_blk)
+		line_info += struct.pack("I", block_num)
+
+		# remove temp files #
+		os.remove(args.nand_name + '_header.bin')
+	else:
+		raise Exception("wrong pad type")
+
+	with open(args.table_file, "ab") as f:
+		f.write(line_info)
+
+if __name__ == "__main__":
+        sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/gen_nand_header.py b/src/bsp/scatter/tools/nand-utils/gen_nand_header.py
new file mode 100755
index 0000000..fa71e74
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_nand_header.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+
+import ecc_bch
+import sys
+import os
+import struct
+import argparse
+import pp_tbl
+
+def gen_header(nand_name):
+	""" device info:
+	name vendor totalsize(MB) pagesize(B) sparesize(B) pageperblock cycle eccstrength
+	interface acccon acccon1 dqsdlymux dqsdlyctrl nfidlyctrl pptableenable lbasize
+	fastclock usedma fdmsize fdmeccsize strobesel
+	"""
+	with open(os.getcwd() + "/tools/nand-utils/nand_device_list.txt", "r") as f:
+		found = 0
+		for l in f:
+			s = l.split()
+			if s[0] == nand_name:
+				found = 1
+				vendor = s[1]
+				total_size = int(s[2])
+				page_size = int(s[3])
+				#page_shift = len(bin(page_size).replace('0b','')) - 1
+				page_shift = 16 if page_size > 512 else 8
+				spare_size = int(s[4])
+				page_per_block = int(s[5])
+				address_cycle = int(s[6])
+				ecc_strength = int(s[7])
+				interface = int(s[8])
+				acccon = eval(s[9])
+				acccon1 = eval(s[10])
+				dqsdlymux = int(s[11])
+				dqsdlyctrl = eval(s[12])
+				nfidlyctrl = eval(s[13])
+				pptableen = int(s[14])
+				lba_size = int(s[15])
+				fast_clk = int(s[16])
+				use_dma = int(s[17])
+				fdm_size = int(s[18])
+				fdmecc_size = int(s[19])
+				strobesel = int(s[20])
+
+				# meaningless, just set pptableen value as BROM test code #
+				if not pptableen:
+					pptableen = 0xffff
+
+				break
+
+		if not found:
+			raise KeyError("not support " + nand_name)
+
+		#print s[0]
+		#print "vendor %s, total size %d(MB) page size %d, page shift %d, spare size %d, page per block %d" \
+		#	% (vendor, total_size, page_size, page_shift, spare_size, page_per_block)
+		#print "address cycle %d, ecc strength %d, interface %d, acccon 0x%x, acccon1 0x%x" \
+		#	% (address_cycle, ecc_strength, interface, acccon, acccon1)
+		#print "dqsdlymux %d, dqsdlyctrl 0x%x, nfidlyctrl 0x%x, pptable enable %d, lba size %d" \
+		#	% (dqsdlymux, dqsdlyctrl, nfidlyctrl, pptableen, lba_size)
+		#print "fast clock enable %d, use dma %d, fdm size %d, fdmecc size %d" \
+		#	% (fast_clk, use_dma, fdm_size, fdmecc_size)
+		#raise KeyError("not support " + nand_name)
+
+	# nand header is total 440B include ecc parity 140B #
+	header_size = 300
+	pptbl_size = 128
+
+	header = "NANDCONFIG!" + '\0'
+	header += struct.pack("I", total_size)
+	header += struct.pack("H", page_size)
+	header += struct.pack("H", address_cycle)
+	header += struct.pack("H", spare_size)
+	header += struct.pack("H", interface)
+	header += struct.pack("I", ecc_strength)
+	header += struct.pack("H", page_per_block)
+	header += struct.pack("H", page_shift)
+	header += struct.pack("H", pptableen)
+	header += struct.pack("H", dqsdlymux)
+	header += struct.pack("I", dqsdlyctrl)
+	header += struct.pack("I", acccon)
+	header += struct.pack("I", acccon1)
+	header += struct.pack("I", nfidlyctrl)
+	header += struct.pack("H", lba_size)
+	header += struct.pack("H", fast_clk)
+	header += struct.pack("H", use_dma)
+	header += struct.pack("H", strobesel)
+	header += struct.pack("H", fdm_size)
+	header += struct.pack("H", fdmecc_size)
+
+	# pad dummy byte #
+	header += '\x5a' * (header_size - len(header) - pptbl_size)
+	if pptableen == 1:
+		# add pptable #
+		if vendor == 'TSB':
+			header += str(bytearray(pp_tbl.TSB_PP))
+		else:
+			raise KeyError(" no %s pptable " % vendor)
+	else:
+		header += '\xff' * pptbl_size
+
+	# calculate header ecc parity #
+	header_size = 300
+	ecc_level = 80
+	ecc = ecc_bch.bch_enc_14(header, header_size, ecc_level)
+	header += ecc
+
+	header_file = nand_name + '_header.bin'
+	with open(header_file, "wb") as f:
+		f.write(header)
+
+	return (vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, pptableen, page_per_block)
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('gpt_image', help = 'pmbr + gpt entry image ')
+	args = parser.parse_args()
+
+	# generate nand device header #
+	gen_header(args.nand_name)
+
+	# pad nand header #
+	with open(args.nand_name + '_header.bin', "rb") as f_h:
+		h_buf = f_h.read()
+	with open(args.gpt_image, "rb+") as f_g:
+		f_g.seek(440, 0)
+		h_buf = h_buf + f_g.read()
+		f_g.seek(0, 0)
+		f_g.write(h_buf)
+
+	os.remove(args.nand_name + '_header.bin')
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/gen_nand_header_mt2731.py b/src/bsp/scatter/tools/nand-utils/gen_nand_header_mt2731.py
new file mode 100755
index 0000000..cea124e
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_nand_header_mt2731.py
@@ -0,0 +1,141 @@
+#// SPDX-License-Identifier: MediaTekProprietary
+#!/usr/bin/env python
+
+import ecc_bch
+import sys
+import os
+import struct
+import argparse
+import pp_tbl
+
+def gen_header(nand_name):
+	""" device info:
+	name vendor totalsize(MB) pagesize(B) sparesize(B) pageperblock cycle eccstrength
+	interface acccon acccon1 dqsdlymux dqsdlyctrl nfidlyctrl pptableenable lbasize
+	fastclock usedma fdmsize fdmeccsize strobesel
+	"""
+	with open(os.getcwd() + "/tools/nand-utils/nand_device_list_mt2731.txt", "r") as f:
+		found = 0
+		for l in f:
+			s = l.split()
+			if s[0] == nand_name:
+				found = 1
+				vendor = s[1]
+				total_size = int(s[2])
+				page_size = int(s[3])
+				#page_shift = len(bin(page_size).replace('0b','')) - 1
+				page_shift = 16 if page_size > 512 else 8
+				spare_size = int(s[4])
+				page_per_block = int(s[5])
+				address_cycle = int(s[6])
+				ecc_strength = int(s[7])
+				interface = int(s[8])
+				acccon = eval(s[9])
+				acccon1 = eval(s[10])
+				dqsdlymux = int(s[11])
+				dqsdlyctrl = eval(s[12])
+				nfidlyctrl = eval(s[13])
+				pptableen = int(s[14])
+				lba_size = int(s[15])
+				fast_clk = int(s[16])
+				use_dma = int(s[17])
+				fdm_size = int(s[18])
+				fdmecc_size = int(s[19])
+				strobesel = int(s[20])
+
+				# meaningless, just set pptableen value as BROM test code #
+				if not pptableen:
+					pptableen = 0xffff
+
+				break
+
+		if not found:
+			raise KeyError("not support " + nand_name)
+
+	#print s[0]
+	#print "vendor %s, total size %d(MB) page size %d, page shift %d, spare size %d, page per block %d" \
+	#	% (vendor, total_size, page_size, page_shift, spare_size, page_per_block)
+	#print "address cycle %d, ecc strength %d, interface %d, acccon 0x%x, acccon1 0x%x" \
+	#	% (address_cycle, ecc_strength, interface, acccon, acccon1)
+	#print "dqsdlymux %d, dqsdlyctrl 0x%x, nfidlyctrl 0x%x, pptable enable %d, lba size %d" \
+	#	% (dqsdlymux, dqsdlyctrl, nfidlyctrl, pptableen, lba_size)
+	#print "fast clock enable %d, use dma %d, fdm size %d, fdmecc size %d" \
+	#	% (fast_clk, use_dma, fdm_size, fdmecc_size)
+	#raise KeyError("not support " + nand_name)
+
+	# nand header is total 440B include ecc parity 140B #
+	header_size = 398
+	pptbl_size = 128
+
+	# the reserved region is for SGPT and BBT
+	reserved_size = page_size * page_per_block * 8 / 1024
+	# As NAND totol size for 2731 BROM is unit as Mega, the reserved size need to be the unit of Mega
+	if (reserved_size % 1024) == 0:
+		total_size = total_size - reserved_size / 1024
+
+	header = "NANDCONFIG!" + '\0'
+	header += struct.pack("I", total_size)
+	header += struct.pack("H", page_size)
+	header += struct.pack("H", address_cycle)
+	header += struct.pack("H", spare_size)
+	header += struct.pack("H", interface)
+	header += struct.pack("I", ecc_strength)
+	header += struct.pack("H", page_per_block)
+	header += struct.pack("H", page_shift)
+	header += struct.pack("H", pptableen)
+	header += struct.pack("H", dqsdlymux)
+	header += struct.pack("I", dqsdlyctrl)
+	header += struct.pack("I", acccon)
+	header += struct.pack("I", acccon1)
+	header += struct.pack("I", nfidlyctrl)
+	header += struct.pack("H", lba_size)
+	header += struct.pack("H", fast_clk)
+	header += struct.pack("H", use_dma)
+	header += struct.pack("H", strobesel)
+	header += struct.pack("H", fdm_size)
+	header += struct.pack("H", fdmecc_size)
+	# pad dummy byte #
+	header += '\x5a' * (header_size - len(header) - pptbl_size)
+	if pptableen == 1:
+		# add pptable #
+		if vendor == 'TSB':
+			header += str(bytearray(pp_tbl.TSB_PP))
+		else:
+			raise KeyError(" no %s pptable " % vendor)
+	else:
+		header += '\xff' * pptbl_size
+
+	# calculate header ecc parity #
+	header_size = 398
+	ecc_level = 24
+	ecc = ecc_bch.bch_enc_14(header, header_size, ecc_level)
+	header += ecc
+
+	header_file = nand_name + '_header.bin'
+	with open(header_file, "wb") as f:
+		f.write(header)
+
+	return (vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, pptableen, page_per_block)
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('gpt_image', help = 'pmbr + gpt entry image ')
+	args = parser.parse_args()
+
+	# generate nand device header #
+	gen_header(args.nand_name)
+
+	# pad nand header #
+	with open(args.nand_name + '_header.bin', "rb") as f_h:
+		h_buf = f_h.read()
+	with open(args.gpt_image, "rb+") as f_g:
+		f_g.seek(440, 0)
+		h_buf = h_buf + f_g.read()
+		f_g.seek(0, 0)
+		f_g.write(h_buf)
+
+	os.remove(args.nand_name + '_header.bin')
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/gen_nand_header_mt2735_hsm.py b/src/bsp/scatter/tools/nand-utils/gen_nand_header_mt2735_hsm.py
new file mode 100755
index 0000000..13932c7
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_nand_header_mt2735_hsm.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+
+import ecc_bch
+import sys
+import os
+import struct
+import argparse
+
+def gen_header(nand_name, header_file):
+	""" device info:
+	name vendor pagesize(B) sparesize(B) pageperblock blocks cycle
+	"""
+	with open(os.getcwd() + "/tools/nand-utils/nand_device_list_mt2735_hsm.txt", "r") as f:
+		found = 0
+		for l in f:
+			s = l.split()
+			if s[0] == nand_name:
+				found = 1
+				vendor = s[1]
+				page_size = int(s[2])
+				spare_size = int(s[3])
+				pages_per_block = int(s[4])
+				blocks = int(s[5])
+				cycle = int(s[6])
+		if not found:
+			raise KeyError("not support " + nand_name)
+
+	# step1: generate nand header info #
+	header = "NANDCFG!"
+	version = 1
+	# dma mode enable, normal speed
+	config = 0x1
+	sector_size = 1024
+	fdm_size = 8
+	fdmecc_size = 1
+	lbs = 0
+	header += struct.pack("IIIIII", version, config, sector_size,\
+					fdm_size, fdmecc_size, lbs)
+	plane_sel_poi = 12
+	# parameter page is enabled
+	parameter_page_en = (1 << 2)
+	if (config & parameter_page_en):
+		nand = struct.pack("IIIII", 0, 0,\
+					0,  0,\
+					plane_sel_poi)
+	else:
+		nand = struct.pack("IIIII", page_size, spare_size,\
+					pages_per_block,  blocks,\
+					plane_sel_poi)
+	header += nand
+	pll = 0
+	# normal speed, acccon do not need to be set, BROM use default 0x30C77FFF
+	acccon = 0
+	# normal speed, strobe_sel do not need to be set
+	strobe_sel = 0
+	acccon1 = 0
+	dqs_delay_mux = 0
+	dqs_delay_ctrl = 0
+	delay_ctrl = 0
+	latch_lat = 0
+	sam_dly = 0
+	driving = 0
+	high_speed = struct.pack("IIIIIIIIII", pll, acccon, strobe_sel,\
+					acccon1, dqs_delay_mux,\
+					dqs_delay_ctrl, delay_ctrl,\
+					latch_lat, sam_dly, driving)
+	header += high_speed
+	bl_start = 0
+	bl_end = 0
+	header += struct.pack("II", bl_start, bl_end)
+	ecc_level = 24
+	header_size = len(header) + ecc_level * 14 / 8
+	print "header_size: %d" % header_size
+
+	ecc = ecc_bch.bch_enc_14(header, len(header), ecc_level)
+	header += ecc
+
+	with open(header_file, "wb") as f:
+		f.write(header)
+
+	return (header_size, sector_size, fdm_size, fdmecc_size, lbs)
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('gpt_image', help = 'pmbr + gpt entry image ')
+	args = parser.parse_args()
+
+	header_file = args.nand_name + '_header.bin'
+	# generate nand device header #
+	gen_header(args.nand_name, header_file)
+
+	# pad nand header #
+	with open(header_file, "rb") as f_h:
+		h_buf = f_h.read()
+	with open(args.gpt_image, "rb+") as f_g:
+		f_g.seek(440, 0)
+		h_buf += '\x00' * (440 - len(h_buf))
+		h_buf = h_buf + f_g.read()
+		f_g.seek(0, 0)
+		f_g.write(h_buf)
+
+	os.remove(header_file)
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/gen_nand_header_v11.py b/src/bsp/scatter/tools/nand-utils/gen_nand_header_v11.py
new file mode 100755
index 0000000..742c17a
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_nand_header_v11.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+
+import ecc_bch
+import sys
+import os
+import struct
+import argparse
+
+def gen_header(nand_name, lk_start_addr, out_image):
+	""" device info:
+	name vendor interface pagesize(B) cycle sparesize(B) pageperblock total_blocks
+	page_shift block_shift ecc_strength
+	"""
+	with open(os.getcwd() + "/tools/nand-utils/nand_device_list_v11.txt", "r") as f:
+		found = 0
+		for l in f:
+			s = l.split()
+			if s[0] == nand_name:
+				found = 1
+				vendor = s[1]
+				interface = eval(s[2])
+				page_size = int(s[3])
+				address_cycle = int(s[4])
+				spare_size = int(s[5])
+				page_per_block = int(s[6])
+				total_blocks = int(s[7])
+				page_shift = int(s[8])
+				block_shift = int(s[9])
+				ecc_strength = int(s[10])
+
+		if not found:
+			raise KeyError("not support " + nand_name)
+
+		#print s[0]
+		#print "vendor %s, page size %d, page shift %d, spare size %d, page per block %d" \
+		#	% (vendor, page_size, page_shift, spare_size, page_per_block)
+		#print "address cycle %d, ecc strength %d, interface %d block_shift %d total_blocks %d" \
+		#	% (address_cycle, ecc_strength, interface, block_shift, total_blocks)
+
+	# step1: generate nand header info #
+	header = "BOOTLOADER!" + '\0'
+	header += "V006"
+	header += "NFIINFO" + '\0'
+	header += struct.pack("H", interface)
+	header += struct.pack("H", page_size)
+	header += struct.pack("H", address_cycle)
+	# pad 0 for nand type, means slc nand#
+	header += struct.pack("H", 0)
+	# pad tlc control #
+	header += '\0' * 12
+	header += struct.pack("H", spare_size)
+	header += struct.pack("H", page_per_block)
+	header += struct.pack("H", total_blocks)
+	header += struct.pack("H", page_shift)
+	header += struct.pack("H", block_shift)
+	# pad arm align data #
+	header += '\0' * 2
+	# pad mlc control #
+	header += '\0' * 20
+	# pad dummy #
+	header += '\0' * (4 + 4 + 28)
+	# calculate header ecc parity #
+	header_size = 112
+	ecc_level = 80
+	ecc = ecc_bch.bch_enc_14(header, header_size, ecc_level)
+	header += ecc
+	# pad 4B dummy #
+	header += '\0' * 4
+	# double nfb header #
+	header += header
+	# pad page size align dummy data #
+	header += '\0' * (page_size - 512)
+
+	# step2: generate brlyt #
+	header += "BRLYT" + ('\0' * 3)
+	brlyt_version = 1
+	header += struct.pack("I", brlyt_version)
+	boot_region_addr = lk_start_addr
+	header += struct.pack("I", boot_region_addr)
+	main_region_addr = boot_region_addr + (4 * page_per_block)
+	header += struct.pack("I", main_region_addr)
+	bl_desc_magic = 0x42424242
+	header += struct.pack("I", bl_desc_magic)
+	bl_desc_dev = 0x2
+	header += struct.pack("H", bl_desc_dev)
+	bl_desc_type = 0x1
+	header += struct.pack("H", bl_desc_type)
+	header += struct.pack("I", boot_region_addr)
+	header += struct.pack("I", main_region_addr)
+	bl_desc_attribute = 1
+	header += struct.pack("I", bl_desc_attribute)
+	# pad 7 descripters #
+	header += '\0' * 7 * 20
+	# pad page size align dummy data #
+	header += '\0' * (page_size - 180)
+
+	# step3: pad dummy data till GPT LBA #
+	# let us have an agreement that GPT alwasy be at LBA 128 for SLC NAND #
+	# should be the same LBA in lk and kernel to find GPT #
+	gpt_lba = 128
+	header += '\0' * page_size * (gpt_lba - 2)
+
+	with open(out_image, "wb") as f:
+		f.write(header)
+
+	#return (vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, pptableen, page_per_block)
+	return (vendor, 8, 8, ecc_strength, spare_size, page_size, 0, page_per_block)
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('lk_start_addr', help = 'lk start address in page unit')
+	parser.add_argument('out_image', help = 'the output header file')
+	args = parser.parse_args()
+	lk_start_addr = int(args.lk_start_addr)
+
+	# generate nand device header #
+	gen_header(args.nand_name, lk_start_addr, args.out_image)
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/gen_nand_header_v12.py b/src/bsp/scatter/tools/nand-utils/gen_nand_header_v12.py
new file mode 100755
index 0000000..8d9b55f
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_nand_header_v12.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+
+import ecc_bch
+import sys
+import os
+import struct
+import argparse
+
+def gen_header(nand_name, out_image):
+	""" device info:
+	name interface pagesize(B) cycle sparesize(B) pageperblock total_blocks ecc_strength
+	"""
+	with open(os.getcwd() + "/tools/nand-utils/nand_device_list_v12.txt", "r") as f:
+		found = 0
+		for l in f:
+			s = l.split()
+			if s[0] == nand_name:
+				found = 1
+				interface = eval(s[1])
+				page_size = int(s[2])
+				address_cycle = int(s[3])
+				spare_size = int(s[4])
+				page_per_block = int(s[5])
+				total_blocks = int(s[6])
+				ecc_strength = int(s[7])
+
+		if not found:
+			raise KeyError("not support " + nand_name)
+
+	# step1: generate nand header info #
+	header = b"BOOTLOADER!" + b'\0'
+	header += b"V006"
+	header += b"NFIINFO" + b'\0'
+	header += struct.pack("H", interface)
+	header += struct.pack("H", page_size)
+	header += struct.pack("H", address_cycle)
+	header += struct.pack("H", spare_size)
+	header += struct.pack("H", page_per_block)
+	header += struct.pack("H", total_blocks)
+	header += b'\0' * 24
+	# defualt not use ahb mode 
+	header += struct.pack("H", 0)
+	header += struct.pack("B", int(ecc_strength))
+	# fdmecc size usually is 1
+	header += struct.pack("B", 1)
+	header += b'\0' * 16
+	# calculate header ecc parity #
+	header_size = 80
+	ecc_level = 24
+	ecc = ecc_bch.bch_enc_14(header, header_size, ecc_level)
+	header += ecc
+	header += b'\0' * 6
+	# double nfb header #
+	header += header
+
+	with open(out_image, "wb+") as f:
+		f.write(header)
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('out_image', help = 'the output header file')
+	args = parser.parse_args()
+
+	# generate nand device header #
+	gen_header(args.nand_name, args.out_image)
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
\ No newline at end of file
diff --git a/src/bsp/scatter/tools/nand-utils/gen_nand_header_v13.py b/src/bsp/scatter/tools/nand-utils/gen_nand_header_v13.py
new file mode 100644
index 0000000..43f3d8a
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_nand_header_v13.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+
+import ecc_bch
+import sys
+import os
+import struct
+import argparse
+
+def gen_header(nand_name, preloader_start_addr, out_image):
+	""" device info:
+	name vendor interface pagesize(B) cycle sparesize(B) pageperblock total_blocks
+	page_shift block_shift ecc_strength
+	"""
+	with open(os.getcwd() + "/tools/nand-utils/nand_device_list_v13.txt", "r") as f:
+		found = 0
+		for l in f:
+			s = l.split()
+			if s[0] == nand_name:
+				found = 1
+				vendor = s[1]
+				interface = eval(s[2])
+				page_size = int(s[3])
+				address_cycle = int(s[4])
+				spare_size = int(s[5])
+				page_per_block = int(s[6])
+				total_blocks = int(s[7])
+				page_shift = int(s[8])
+				block_shift = int(s[9])
+				ecc_strength = int(s[10])
+
+		if not found:
+			raise KeyError("not support " + nand_name)
+
+		#print s[0]
+		#print "vendor %s, page size %d, page shift %d, spare size %d, page per block %d" \
+		#	% (vendor, page_size, page_shift, spare_size, page_per_block)
+		#print "address cycle %d, ecc strength %d, interface %d block_shift %d total_blocks %d" \
+		#	% (address_cycle, ecc_strength, interface, block_shift, total_blocks)
+
+	# step1: generate nand header info #
+	header = "BOOTLOADER!" + '\0'
+	header += "V006"
+	header += "NFIINFO" + '\0'
+        # nfi_info #
+	header += struct.pack("H", interface)
+	header += struct.pack("H", page_size)
+	header += struct.pack("H", address_cycle)
+	header += struct.pack("H", spare_size)
+	header += struct.pack("H", page_per_block)
+	header += struct.pack("H", total_blocks)
+	header += struct.pack("H", page_shift)
+	header += struct.pack("H", block_shift)
+	# pad mlc control #
+	header += '\0' * 20
+	# pad tlc control #
+	header += '\0' * 3
+	header += struct.pack("B", 1) #b_Randomizer_En
+	header += '\0' * 14
+	# pad dummy #
+	header += '\0' * 2
+        # reserved #
+	header += '\0' * 32
+	# calculate header ecc parity #
+	header_size = 112
+        ecc_level = 80
+	ecc = ecc_bch.bch_enc_14(header, header_size, ecc_level)
+	header += ecc
+	# pad 4B dummy #
+	header += '\0' * 4  # pad 4 bytes to align total 256 bytes 
+	# double nfb header #
+	header += header
+	# pad page size align dummy data #
+	header += '\0' * (page_size - 512)  # fill the nand information to whole page, since it occupy one page
+
+	# step2: generate brlyt #
+	header += "BRLYT" + ('\0' * 3)
+	brlyt_version = 1
+	header += struct.pack("I", brlyt_version)
+	boot_region_addr = preloader_start_addr
+	header += struct.pack("I", boot_region_addr)
+	main_region_addr = boot_region_addr + (4 * page_per_block) # avoid if have bad block, so remain 4 blocks. need the same as partition_nand.xml
+	header += struct.pack("I", main_region_addr)
+	bl_desc_magic = 0x42424242
+	header += struct.pack("I", bl_desc_magic)
+	bl_desc_dev = 0x2
+	header += struct.pack("H", bl_desc_dev)
+	bl_desc_type = 0x1
+	header += struct.pack("H", bl_desc_type)
+	header += struct.pack("I", boot_region_addr)
+	header += struct.pack("I", main_region_addr)
+	bl_desc_attribute = 1
+	header += struct.pack("I", bl_desc_attribute)
+	# pad 7 descripters #
+	header += '\0' * 7 * 20
+	# pad page size align dummy data #
+	header += '\0' * (page_size - 180)
+
+	# step3: pad dummy data till GPT LBA #
+	# let us have an agreement that GPT alwasy be at LBA 128 for SLC NAND #
+	# should be the same LBA in lk and kernel to find GPT #
+	gpt_lba = 128
+	header += '\0' * page_size * (gpt_lba - 2)
+
+	with open(out_image, "wb") as f:
+		f.write(header)
+
+	#return (vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, pptableen, page_per_block)
+	return (vendor, 8, 8, ecc_strength, spare_size, page_size, 0, page_per_block)
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('preloader_start_addr', help = 'preloader start address in page unit')
+	parser.add_argument('out_image', help = 'the output header file')
+	args = parser.parse_args()
+	preloader_start_addr = int(args.preloader_start_addr)
+
+	# generate nand device header #
+	gen_header(args.nand_name, preloader_start_addr, args.out_image)
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/gen_nand_header_v14.py b/src/bsp/scatter/tools/nand-utils/gen_nand_header_v14.py
new file mode 100644
index 0000000..2abf043
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_nand_header_v14.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+
+import ecc_bch
+import sys
+import os
+import struct
+import argparse
+
+def gen_header(nand_name, out_image):
+	""" device info:
+	name interface pagesize cycle sparesize pageperblock total_blocks nand_cfg accon fdmecc_size ecc_fdm plane_sel_poi
+	"""
+	with open(os.getcwd() + "/tools/nand-utils/nand_device_list_v14.txt", "r") as f:
+		found = 0
+		for l in f:
+			s = l.split()
+			if s[0] == nand_name:
+				found = 1
+				interface = eval(s[1])
+				page_size = int(s[2])
+				address_cycle = int(s[3])
+				spare_size = int(s[4])
+				page_per_block = int(s[5])
+				total_blocks = int(s[6])
+				nand_cfg = int(s[7], 16)
+				accon = int(s[8])
+				fdmecc_size = int(s[9])
+				ecc_fdm = int(s[10])
+				plane_sel_poi = int(s[11])
+
+		if not found:
+			raise KeyError("not support " + nand_name)
+
+	# step1: generate nand header info #
+	header = "BOOTLOADER!" + '\0'
+	header += "V006"
+	header += struct.pack("H", interface)
+	header += struct.pack("H", page_size)
+	header += struct.pack("H", address_cycle)
+	header += struct.pack("H", spare_size)
+	header += struct.pack("H", page_per_block)
+	header += struct.pack("H", total_blocks)
+	header += struct.pack("I", nand_cfg)
+	header += '\0' * 8
+	header += struct.pack("I", accon)
+	header += '\0' * 8
+
+	bl_start = 1
+	bl_end = 255
+	header += struct.pack("BBHII", fdmecc_size, ecc_fdm, plane_sel_poi, bl_start,\
+			bl_end)
+	#16 dummy bytes
+	header += '\0' * 16
+	# calculate header ecc parity #
+	ecc_level = 24
+	header_size = len(header)
+	ecc = ecc_bch.bch_enc_14(header, header_size, ecc_level)
+	header += ecc
+	header += '\0' * (128 - len(header))
+	# double nfb header #
+	header += header
+
+	with open(out_image, "wb") as f:
+		f.write(header)
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('out_image', help = 'the output header file')
+	args = parser.parse_args()
+
+	# generate nand device header #
+	gen_header(args.nand_name, args.out_image)
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/gen_nand_header_v4.py b/src/bsp/scatter/tools/nand-utils/gen_nand_header_v4.py
new file mode 100644
index 0000000..e6ef349
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_nand_header_v4.py
@@ -0,0 +1,227 @@
+#!/usr/bin/env python3
+
+import ecc_bch
+import sys
+import os
+import struct
+import argparse
+import pp_tbl
+
+def calc_bcc(buf, buf_len):
+	raw = bytearray(buf)
+	bcc = 0
+
+	for i in range(buf_len):
+		bcc ^= raw[i]
+
+	return bcc
+
+def gen_header(nand_name):
+	print ("NAND: %s" % (nand_name))
+	with open(os.getcwd() + "/tools/nand-utils/nand_device_list_v4.txt", "r") as f:
+		found = 0
+		info_valid = 0
+		nfi_valid = 0
+		mag_valid = 0
+		pp_valid = 0
+		for l in f:
+			s = l.split()
+			if s[0] == nand_name:
+				found = 1
+				nfi_start_idx = 0
+				mag_start_idx = 0
+
+				enable_header = int(s[1])
+				if enable_header == 0:
+					break
+				info_valid = int(s[2])
+				nfi_valid = int(s[3])
+				mag_valid = int(s[4])
+				pp_valid = int(s[5])
+				pp_type = s[6]
+				if info_valid == 1:
+					nand_type = int(s[7])
+					io_width = int(s[8])
+					addr_cycle = int(s[9])
+					target_num = int(s[10])
+					lun_num = int(s[11])
+					plane_num = int(s[12])
+					program_order_type = int(s[13])
+					address_table_type = int(s[14])
+					bad_block_type = int(s[15])
+					read_retry_type = int(s[16])
+					interface_type = int(s[17])
+					sdr_timing_type = int(s[18])
+					ddr_timing_type = int(s[19])
+					block_num = int(s[20])
+					block_size = int(s[21])
+					page_size = int(s[22])
+					spare_size = int(s[23])
+					mode_type = int(s[24])
+					slc_pe_cycle = int(s[25])
+					slc_ecc_required = int(s[26])
+					slc_bitflip_thres = int(s[27])
+					xlc_pe_cycle = int(s[28])
+					xlc_ecc_required = int(s[29])
+					xlc_bitflip_thres = int(s[30])
+					nfi_start_idx = 31
+					mag_start_idx = 31
+					if nand_type == 0:
+						nfc_format = 1
+						rand_en = 0
+					else:
+						nfc_format = 0
+						rand_en = 1
+				if nfi_valid == 1:
+					dqs_dly_sel = int(s[nfi_start_idx])
+					dqs_dly_mux = int(s[nfi_start_idx + 1])
+					rd_dqs_ddr_timing = int(s[nfi_start_idx + 2])
+					mag_start_idx = nfi_start_idx + 3
+				if mag_valid == 1:
+					bm_type = int(s[mag_start_idx])
+					dma_en = int(s[mag_start_idx + 1])
+					ddr_en = int(s[mag_start_idx + 2])
+					nfc_format = int(s[mag_start_idx + 3])
+				break #found
+
+		if not found:
+			raise KeyError("not support " + nand_name)
+
+	# nand header is total 440B include ecc parity 140B #
+	header_size = 300
+	info_size = 64
+	setting_size = 16
+	mag_size = 8
+	pptbl_size = 128
+	dummy_size = header_size - 4 - info_size - setting_size - mag_size - pptbl_size - 3
+
+	header = b"NAND"
+
+	# struct nand_info #
+	if info_valid == 0:
+		header += '\x00' * info_size
+		bcc_chip = '\xff'
+	else:
+		info_buf = b"INFO"
+		info_buf += struct.pack("B", nand_type)
+		info_buf += struct.pack("B", io_width)
+		info_buf += struct.pack("B", addr_cycle)
+		info_buf += struct.pack("B", target_num)
+		info_buf += struct.pack("B", lun_num)
+		info_buf += struct.pack("B", plane_num)
+		info_buf += struct.pack("B", program_order_type)
+		info_buf += struct.pack("B", address_table_type)
+		info_buf += struct.pack("B", bad_block_type)
+		info_buf += struct.pack("B", read_retry_type)
+		info_buf += struct.pack("B", interface_type)
+		info_buf += struct.pack("B", sdr_timing_type)
+		info_buf += struct.pack("B", ddr_timing_type)
+		info_buf += b'\xff' * 3
+		info_buf += struct.pack("I", block_num)
+		info_buf += struct.pack("I", block_size)
+		info_buf += struct.pack("I", page_size)
+		info_buf += struct.pack("I", spare_size)
+		info_buf += struct.pack("I", mode_type)
+		info_buf += struct.pack("I", slc_pe_cycle)
+		info_buf += struct.pack("I", slc_ecc_required)
+		info_buf += struct.pack("I", slc_bitflip_thres)
+		info_buf += struct.pack("I", xlc_pe_cycle)
+		info_buf += struct.pack("I", xlc_ecc_required)
+		info_buf += struct.pack("I", xlc_bitflip_thres)
+		header += info_buf
+		bcc_chip = calc_bcc(info_buf, info_size)
+		bcc_chip = struct.pack("B", bcc_chip)
+
+	# struct nfi_setting #
+	if nfi_valid == 0:
+		header += b'\x00' * setting_size
+		bcc_setting = b'\xff'
+	else:
+		setting_buf = "NFIS"
+		setting_buf += struct.pack("I", dqs_dly_sel)
+		setting_buf += struct.pack("I", dqs_dly_mux)
+		setting_buf += struct.pack("I", rd_dqs_ddr_timing)
+		header += setting_buf
+		bcc_setting = calc_bcc(setting_buf, setting_size)
+		bcc_setting = struct.pack("B", bcc_setting)
+
+	# struct nand_manage #
+	if mag_valid == 0:
+		header += b'\x00' * mag_size
+		bcc_mag = b'\xff'
+	else:
+		mag_buf = "MANG"
+		mag_buf += struct.pack("B", bm_type)
+		mag_buf += struct.pack("B", dma_en)
+		mag_buf += struct.pack("B", ddr_en)
+		mag_buf += struct.pack("B", nfc_format)
+		header += mag_buf
+		bcc_mag = calc_bcc(mag_buf, mag_size)
+		bcc_mag = struct.pack("B", bcc_mag)
+
+	# bcc code #
+	header += bcc_chip
+	header += bcc_setting
+	header += bcc_mag
+
+	# pad dummy byte #
+	header += b'\xff' * dummy_size
+
+	if pp_valid == 1:
+		# add pptable #
+		if pp_type == 'TSB':
+			header += str(bytearray(pp_tbl.TSB_PP))
+		else:
+			raise KeyError(" no %s pptable " % vendor)
+	else:
+		header += b'\xff' * pptbl_size
+
+	# calculate header ecc parity #
+	ecc_level = 80
+	ecc = ecc_bch.bch_enc_14(header, header_size, ecc_level)
+	header += ecc
+
+	header_file = nand_name + '_header.bin'
+	with open(header_file, "wb") as f:
+		f.write(header)
+
+	if info_valid == 0:
+		print ("NAND info invalid, return!")
+		return
+
+	# feedback ecc & randomizer generateion info
+	fdm_size = spare_size / (page_size / 1024) - (xlc_ecc_required * 14 + 7) / 8
+	if fdm_size > 8:
+		fdm_size = 8
+	if nfc_format == 0:
+		fdmecc_size = fdm_size
+		bad_swap = 0
+	else:
+		fdmecc_size = 1
+		bad_swap = 1
+	ppb = block_size / page_size
+
+	return (pp_type, fdm_size, fdmecc_size, xlc_ecc_required, spare_size, page_size, pp_valid, ppb, bad_swap, rand_en)
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('gpt_image', help = 'pmbr + gpt entry image ')
+	args = parser.parse_args()
+
+	# generate nand device header #
+	gen_header(args.nand_name)
+
+	# pad nand header #
+	with open(args.nand_name + '_header.bin', "rb") as f_h:
+		h_buf = f_h.read()
+	with open(args.gpt_image, "rb+") as f_g:
+		f_g.seek(440, 0)
+		h_buf = h_buf + f_g.read()
+		f_g.seek(0, 0)
+		f_g.write(h_buf)
+
+	os.remove(args.nand_name + '_header.bin')
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/gen_storage_image.py b/src/bsp/scatter/tools/nand-utils/gen_storage_image.py
new file mode 100644
index 0000000..cd0e2ec
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gen_storage_image.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+
+import argparse
+import sys
+import os
+import math
+import pp_tbl
+from gen_nand_header import gen_header
+from pad_ecc_by_sector import pad_ecc
+from randomizer import randomizer
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('in_image', help = 'raw input image which has GPT')
+	parser.add_argument('out_image', help = 'the output storage image ')
+	parser.add_argument('rand_en', help = 'if randomizer is enabled')
+	args = parser.parse_args()
+
+	rand_en = int(args.rand_en)
+
+	header_file = args.nand_name + '_header.bin'
+	header_size = 440
+
+	with open(args.in_image, "rb") as f_in:
+		f_in.seek(header_size, 0)
+		in_data = f_in.read()
+
+	(vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, ppen, ppb) = gen_header(args.nand_name)
+	with open(header_file, "rb+") as hf:
+		hf_data = hf.read()
+		hf.write(in_data)
+
+	ecc_file = args.out_image
+	rand_file = args.out_image
+	if rand_en == 1:
+		ecc_file = args.nand_name + '_ecc.bin'
+	if ppen == 1:
+		paired = raw_input("insert empty paired page ? Y/y or N/n ")
+		if paired in ['Y', 'y']:
+			if rand_en == 1:
+				rand_file = args.nand_name + '_rand.bin'
+			else:
+				ecc_file = args.nand_name + '_ecc.bin'
+	sector_size = 1024 if page_size > 512 else 512
+	sector_spare_size = spare_size / (page_size / sector_size)
+	pad_ecc(header_file, ecc_file, sector_size, fdm_size, fdmecc_size, ecc_strength, sector_spare_size, page_size, 1)
+
+	if rand_en == 1:
+		randomizer(ecc_file, rand_file, "SS", 1, page_size, spare_size, sector_size, ppb, ppen, vendor)
+
+	# insert empty paired page #
+	if ppen == 1 and paired in ['Y', 'y']:
+		if rand_en == 1:
+			pp_file = rand_file
+		else:
+			pp_file = ecc_file
+		if vendor == 'TSB':
+			PP = pp_tbl.TSB_PP
+		else:
+			raise Exception("unsupport %s pp table " % vendor)
+		f_pp = open(pp_file, "rb")
+		f_out = open(args.out_image, "wb")
+
+		if (os.path.getsize(header_file) % page_size) != 0:
+			raise Exception("input image size is not page size aligned")
+		page_number = os.path.getsize(header_file) / page_size
+		block_number = int(math.ceil(float(page_number) / (ppb / 2)))
+		print "page num %d  block num %d" % (page_number, block_number)
+		for i in range(ppb * block_number):
+			if page_number > 0 and (i % ppb) in PP:
+				f_out.write(f_pp.read(page_size + spare_size))
+				page_number -= 1
+			else:
+				f_out.write('\xff' * (page_size + spare_size))
+		f_pp.close()
+		f_out.close()
+		# remove temp files #
+		os.remove(pp_file)
+
+	if rand_en == 1:
+		os.remove(ecc_file)
+
+	os.remove(header_file)
+
+if __name__ == "__main__":
+        sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/gpt_analyser.py b/src/bsp/scatter/tools/nand-utils/gpt_analyser.py
new file mode 100755
index 0000000..296c04b
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/gpt_analyser.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+#to do:
+#extract pmbr + gpt header + gpt entry
+#add txt file output
+#add picture file output
+
+import sys
+import os
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('in_image', help = 'input image with GPT')
+	args = parser.parse_args()
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/nand_device_list.txt b/src/bsp/scatter/tools/nand-utils/nand_device_list.txt
new file mode 100644
index 0000000..bf40f3c
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/nand_device_list.txt
@@ -0,0 +1,6 @@
+Attention: use SPACE to input next parameter
+name vendor totalsize(MB) pagesize(B) sparesize(B) pageperblock cycle eccstrength interface acccon acccon1 dqsdlymux dqsdlyctrl nfidlyctrl pptableenable lbasize fastclock usedma fdmsize fdmeccsize strobesel
+F59D4G81A-45TG-18V ESMT 512 2048 64 64 5 4 1 0x10400111 0 0 0 0 0 0 0 0 8 1 0
+MT29F4G08ABAEAWP MCN 512 4096 224 64 5 16 1 0x10400111 0 0 0 0 0 0 0 0 8 1 0
+TH58TFG8DDLAB4C TSB 4096 16384 1280 256 5 40 2 0x22005010 0x01010200 0 0 0 1 0 0 0 8 1 0
+MT29F16G08ADBCA MCN 2048 4096 224 64 5 24 1 0x10404011 0 0 0 0 0 0 7 1 8 1 0
diff --git a/src/bsp/scatter/tools/nand-utils/nand_device_list_mt2731.txt b/src/bsp/scatter/tools/nand-utils/nand_device_list_mt2731.txt
new file mode 100644
index 0000000..c343093
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/nand_device_list_mt2731.txt
@@ -0,0 +1,10 @@
+Attention: use SPACE to input next parameter
+name vendor totalsize(MB) pagesize(B) sparesize(B) pageperblock cycle eccstrength interface acccon acccon1 dqsdlymux dqsdlyctrl nfidlyctrl pptableenable lbasize fastclock usedma fdmsize fdmeccsize strobesel
+F59D4G81A-45TG-18V ESMT 512 2048 64 64 5 4 1 0x10400111 0 0 0 0 0 0 0 0 8 1 0
+MT29F4G08ABAEAWP MCN 512 4096 224 64 5 16 1 0x10400111 0 0 0 0 0 0 0 0 8 1 0
+TH58TFG8DDLAB4C TSB 4096 16384 1280 256 5 40 2 0x22005010 0x01010200 0 0 0 1 0 0 0 8 1 0
+MT29F16G08ADBCA MCN 2048 4096 224 64 5 24 1 0x10404011 0 0 0 0 0 0 7 1 8 1 0
+MT29F4G08ABBFAH MCN 512 4096 256 64 5 12 1 0x10400111 0 0 0 0 0 0 0 0 8 1 0
+MT29F4G08ABBDA  MCN 512 2048 64 64 5 4 1 0x10404012 0 0 0 0 0 0 0 0 8 1 0
+MT29F4G08ABBFA  MCN 512 4096 256 64 5 12 1 0x10400111 0 0 0 0 0 0 0 0 8 1 0
+MT29F8G08ADBFA  MCN 1024 4096 256 64 5 12 1 0x10400111 0 0 0 0 0 0 0 0 8 1 0
diff --git a/src/bsp/scatter/tools/nand-utils/nand_device_list_mt2735_hsm.txt b/src/bsp/scatter/tools/nand-utils/nand_device_list_mt2735_hsm.txt
new file mode 100644
index 0000000..0354dce
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/nand_device_list_mt2735_hsm.txt
@@ -0,0 +1,3 @@
+Attention: use SPACE to input next parameter
+name vendor pagesize(B) sparesize(B) pageperblock blocks cycle
+MT29F8G08ABBCAH4  Micron 4096 224 64 4096 5
diff --git a/src/bsp/scatter/tools/nand-utils/nand_device_list_v11.txt b/src/bsp/scatter/tools/nand-utils/nand_device_list_v11.txt
new file mode 100755
index 0000000..c3a966e
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/nand_device_list_v11.txt
@@ -0,0 +1,10 @@
+Attention: use SPACE to input next parameter
+name vendor interface pagesize(B) cycle sparesize(B) pageperblock total_blocks page_shift block_shift ecc_strength
+MX30LF1G18AC MXIC 0x100 2048 5 64 64 1024 16 22 12
+TC58NVG0S3HTA00 TOSHIBA 0x100 2048 5 128 64 1024 16 22 32
+MT29F2G08ABAEA MICRON 0x100 2048 5 64 64 2048 16 22 12
+MT29F2G08ABAGA MICRON 0x100 2048 5 128 64 2048 16 22 32
+MX30LF4G18AC MXIC 0x100 2048 5 64 64 4096 16 22 12
+MT29F4G08ABAEA MICRON 0x100 4096 5 224 64 2048 16 22 24
+TC58NVG2S0HTA00 TOSHIBA 0x100 4096 5 256 64 2048 16 22 32
+TC58NVG3S0HTA00 TOSHIBA 0x100 4096 5 256 64 4096 16 22 32
\ No newline at end of file
diff --git a/src/bsp/scatter/tools/nand-utils/nand_device_list_v12.txt b/src/bsp/scatter/tools/nand-utils/nand_device_list_v12.txt
new file mode 100644
index 0000000..7b24c12
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/nand_device_list_v12.txt
@@ -0,0 +1,6 @@
+Attention: use SPACE to input next parameter
+name interface pagesize(B) cycle sparesize(B) pageperblock total_blocks ecc_strength
+MT29F4G01ABAFDWB 0x100 4096 5 256 64 2048 12
+MX30LF4G18AC 0x100 2048 5 64 64 4096 12
+TC58NVG2S0HTA00 0x100 4096 5 256 64 2048 24
+COMMONSLC 0x100 0 5 0 0 0 0
diff --git a/src/bsp/scatter/tools/nand-utils/nand_device_list_v13.txt b/src/bsp/scatter/tools/nand-utils/nand_device_list_v13.txt
new file mode 100755
index 0000000..b73c660
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/nand_device_list_v13.txt
@@ -0,0 +1,3 @@
+Attention: use SPACE to input next parameter
+name vendor interface pagesize(B) cycle sparesize(B) pageperblock total_blocks page_shift block_shift ecc_strength
+NM1482KSLAXCL-3B TOSHIBA 0x100 4096 5 256 64 2048 16 22 32
diff --git a/src/bsp/scatter/tools/nand-utils/nand_device_list_v14.txt b/src/bsp/scatter/tools/nand-utils/nand_device_list_v14.txt
new file mode 100755
index 0000000..7fda451
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/nand_device_list_v14.txt
@@ -0,0 +1,8 @@
+Attention: use SPACE to input next parameter
+name interface pagesize cycle sparesize pageperblock total_blocks nand_cfg accon fdmecc_size ecc_fdm plane_sel_poi
+pnand_4k_256 0x100 4096 5 256 64 2048 0x0 0 1 24 0
+pnand_2k_64 0x100 2048 5 64 64 2048 0x0 0 1 12 0
+snand_4k_256 0x100 4096 5 256 64 2048 0x0 0 1 8 12
+snand_2k_64 0x100 2048 5 64 64 2048 0x0 0 1 8 12
+COMMONSLC 0x100 4096 5 256 64 2048 0x2 0 1 24 0
+COMMONSPI 0x100 4096 5 256 64 2048 0x2 0 1 8 12
\ No newline at end of file
diff --git a/src/bsp/scatter/tools/nand-utils/nand_device_list_v4.txt b/src/bsp/scatter/tools/nand-utils/nand_device_list_v4.txt
new file mode 100644
index 0000000..036995f
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/nand_device_list_v4.txt
@@ -0,0 +1,16 @@
+#Attention: use SPACE to input next parameter
+#name enable info_valid nfi_valid mag_valid pp_valid pp_type <info> nand_type io_width addr_cycle
+#target_num lun_num plane_num program_order_type address_table_type bad_block_type
+#read_retry_type interface_type sdr_timing_type ddr_timing_type block_num
+#block_size page_size spare_size mode_type slc_pe_cycle slc_ecc_required
+#slc_bitflip_thres xlc_pe_cycle xlc_ecc_required xlc_bitflip_thres </info>
+#<nfi> dqs_dly_sel dqs_dly_mux rd_dqs_ddr_timing </nfi> <mag> bm_type dma_en
+#ddr_en nfc_format </mag>
+NAND_COMMON 0
+W29N08GZSIBA 1 1 0 0 0 NONE 0 0 5 1 1 1 0 0 0 0 0 7 0 8192 131072 2048 64 0 50000 12 8 500000 12 8
+SDTNSIAMA016G 1 1 0 0 0 NONE 2 0 5 1 1 2 1 2 2 12 2 0 0 1446 6291456 16384 1952 1 500 68 46 50000 68 46
+SDTNSGAMA008G 1 1 0 0 0 NONE 1 0 5 1 1 2 0 5 2 5 2 9 4 1074 4194304 16384 1280 1 30000 40 30 3000 40 30
+TC58TEG7THLTA00 1 1 0 0 0 NONE 2 0 5 1 1 2 1 2 0 13 2 0 0 1446 6291456 16384 1952 1 500 68 46 50000 68 46
+TC58TFG7DDLTA0D 1 1 0 0 0 NONE 1 0 5 1 1 2 0 5 0 7 2 9 4 2106 4194304 16384 1280 8 30000 40 30 3000 40 30
+MT29F4G08ABAEAWP 1 1 0 0 0 NONE 0 0 5 1 1 2 0 0 0 0 0 8 0 1024 262144 4096 224 0 50000 24 18 50000 24 18
+TC58TEG6TCKTA00 1 1 0 0 0 NONE 2 0 5 1 1 1 1 3 0 13 2 0 0 2092 4227072 16384 1952 1 30000 60 45 3000 60 45
diff --git a/src/bsp/scatter/tools/nand-utils/pad_dummy_data.py b/src/bsp/scatter/tools/nand-utils/pad_dummy_data.py
new file mode 100755
index 0000000..ccfba4b
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/pad_dummy_data.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+
+import argparse
+import sys
+import os
+
+def padding(data, size):
+	return data + '\xff' * (size - len(data))
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('in_image', help = 'raw input image which has GPT')
+	parser.add_argument('part_size', help = 'partition size')
+	args = parser.parse_args()
+	part_size = int(args.part_size, 16)
+	file_len = os.path.getsize(args.in_image)
+
+	with open(args.in_image, "rb+") as f:
+		f.read()
+		f.write('\xff' * (part_size - file_len))
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/pad_dummy_data.sh b/src/bsp/scatter/tools/nand-utils/pad_dummy_data.sh
new file mode 100755
index 0000000..bea14d4
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/pad_dummy_data.sh
@@ -0,0 +1,11 @@
+#! /bin/sh
+
+python -B pad_dummy_data.py ../build_imags/MBR_NAND_ECC 0x84000
+python -B pad_dummy_data.py ../build_imags/lk_ecc.img 0x84000
+python -B pad_dummy_data.py ../build_imags/boot_ecc.img 0x1080000
+python -B pad_dummy_data.py ../build_imags/tz_ecc.img 0x42000
+
+cat ../build_imags/MBR_NAND_ECC >> ../build_imags/burner.img
+cat ../build_imags/lk_ecc.img >> ../build_imags/burner.img
+cat ../build_imags/boot_ecc.img >> ../build_imags/burner.img
+cat ../build_imags/tz_ecc.img >> ../build_imags/burner.img
diff --git a/src/bsp/scatter/tools/nand-utils/pad_dummy_data_by_partition.py b/src/bsp/scatter/tools/nand-utils/pad_dummy_data_by_partition.py
new file mode 100755
index 0000000..1d11424
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/pad_dummy_data_by_partition.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+
+import argparse
+import sys
+import os
+import math
+import pp_tbl
+import gen_nand_header
+import gen_nand_header_v11
+from pad_ecc_by_sector import pad_ecc
+
+def padding(data, size):
+	return data + '\xff' * (size - len(data))
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('nand_name', help = 'nand device name')
+	parser.add_argument('in_image', help = 'raw input image')
+	parser.add_argument('part_size', help = 'partition size')
+	parser.add_argument('version', help= 'nand header version')
+	args = parser.parse_args()
+	version = float(args.version)
+
+	if version == 2.0:
+		(vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, ppen, ppb) = gen_nand_header.gen_header(args.nand_name)
+	elif version == 1.1:
+		(vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, ppen, ppb) = gen_nand_header_v11.gen_header(args.nand_name, 192, args.nand_name + '_header.bin')
+
+	# input image page size alignment #
+	file_len = os.path.getsize(args.in_image)
+	pages = int(int(args.part_size) / page_size)
+	part_size = pages * (page_size + spare_size)
+	with open(args.in_image, "rb+") as f:
+		f.read()
+		f.seek(0, 2)
+		f.write('\xff' * (part_size - file_len))
+
+	os.remove(args.nand_name + '_header.bin')
+
+if __name__ == "__main__":
+        sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/pad_ecc_by_sector.py b/src/bsp/scatter/tools/nand-utils/pad_ecc_by_sector.py
new file mode 100755
index 0000000..ef91095
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/pad_ecc_by_sector.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+import argparse
+import sys
+import os
+import math
+import ecc_bch
+
+def pad_ecc(in_image, out_image, sector_size, fdm_size, fdmecc_size, ecc_level, spare_size, page_size, bad_swap):
+	# file size check #
+	file_len = os.path.getsize(in_image)
+	if (file_len % sector_size) != 0:
+		raise Exception("input image size is not sector size aligned")
+	sector_num = file_len / sector_size
+
+	# calculate parity byte number #
+	parity_byte = int(math.ceil(float(ecc_level) * 14 / 8))
+
+	# bad block mark control setting #
+	if bad_swap != 0:
+		bad_sec = page_size / (sector_size + spare_size)
+		bad_pos = page_size % (sector_size + spare_size)
+		sec_per_page = page_size / sector_size
+		print "bad sector %d, bad position %d, sector number per page %d " \
+			% (bad_sec, bad_pos, sec_per_page)
+
+	f_in = open(in_image, "rb")
+	f_out = open(out_image, "wb")
+
+	for i in range(sector_num):
+		percent = float(i) / float(sector_num) * 100
+		sys.stdout.writelines("%.1f"%percent)
+		sys.stdout.writelines("%\r")
+		sys.stdout.flush();
+		f_in.seek(sector_size * i, 0)
+		f_out.seek((sector_size + spare_size) * i, 0)
+		sector_data = f_in.read(sector_size)
+		sector_data += '\xff' * fdmecc_size
+		# bad mark swap #
+		if bad_swap != 0:
+			if (i % sec_per_page) == bad_sec:
+				temp_buf = bytearray(sector_data)
+				temp_byte = temp_buf[bad_pos]
+				temp_buf[bad_pos] = temp_buf[sector_size]
+				temp_buf[sector_size] = temp_byte
+				sector_data = str(temp_buf)
+		parity_data = ecc_bch.bch_enc_14(sector_data, sector_size + fdmecc_size, ecc_level)
+		sector_data += '\xff' * (fdm_size - fdmecc_size)
+		sector_data += parity_data
+		sector_data += '\xff' * (spare_size - fdm_size - parity_byte)
+		f_out.write(sector_data)
+
+	f_in.close()
+	f_out.close()
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('in_image', help = 'raw input image')
+	parser.add_argument('out_image', help = 'ecc padded image')
+	parser.add_argument('sector_size', help = 'sector size')
+	parser.add_argument('fdm_size', help = 'FDM size')
+	parser.add_argument('fdmecc_size', help = 'FDM ECC size')
+	parser.add_argument('ecc_level', help = 'ECC level')
+	parser.add_argument('spare_size', help = 'spare size per sector')
+	parser.add_argument('page_size', help = 'page size')
+	parser.add_argument('bad_swap', help = 'whether do bad mark swap')
+	args = parser.parse_args()
+
+	sector_size = int(args.sector_size)
+	fdm_size = int(args.fdm_size)
+	fdmecc_size = int(args.fdmecc_size)
+	ecc_level = int(args.ecc_level)
+	spare_size = int(args.spare_size)
+	page_size = int(args.page_size)
+	parity_byte = int(math.ceil(float(ecc_level) * 14 / 8))
+	bad_swap = int(args.bad_swap)
+
+	print "secsize %d, fdmsz %d, fdmeccsz %d, lel %d, spare %d, parity_byte %d page size %d bad_swap %d" \
+		% (sector_size, fdm_size, fdmecc_size, ecc_level, spare_size, parity_byte, page_size, bad_swap)
+
+	pad_ecc(args.in_image, args.out_image, sector_size, fdm_size, fdmecc_size, ecc_level, spare_size, page_size, bad_swap)
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/pp_tbl.py b/src/bsp/scatter/tools/nand-utils/pp_tbl.py
new file mode 100755
index 0000000..b5a5ecf
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/pp_tbl.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+
+TSB_PP = (
+    0,   1,   3,   5,   7,   9,  11,  13,  15,  17,  19,  21,  23,  25,  27,  29,
+   31,  33,  35,  37,  39,  41,  43,  45,  47,  49,  51,  53,  55,  57,  59,  61,
+   63,  65,  67,  69,  71,  73,  75,  77,  79,  81,  83,  85,  87,  89,  91,  93,
+   95,  97,  99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125,
+  127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157,
+  159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189,
+  191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221,
+  223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253)
+
+if __name__ == "__main__":
+	""" this file is used to define pair page table """
diff --git a/src/bsp/scatter/tools/nand-utils/randomizer.py b/src/bsp/scatter/tools/nand-utils/randomizer.py
new file mode 100755
index 0000000..b3fe76a
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/randomizer.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+
+import sys
+import os
+import argparse
+import pp_tbl
+
+SS_SEED = (
+	0x576A, 0x05E8, 0x629D, 0x45A3, 0x649C, 0x4BF0, 0x2342, 0x272E,
+	0x7358, 0x4FF3, 0x73EC, 0x5F70, 0x7A60, 0x1AD8, 0x3472, 0x3612,
+	0x224F, 0x0454, 0x030E, 0x70A5, 0x7809, 0x2521, 0x484F, 0x5A2D,
+	0x492A, 0x043D, 0x7F61, 0x3969, 0x517A, 0x3B42, 0x769D, 0x0647,
+	0x7E2A, 0x1383, 0x49D9, 0x07B8, 0x2578, 0x4EEC, 0x4423, 0x352F,
+	0x5B22, 0x72B9, 0x367B, 0x24B6, 0x7E8E, 0x2318, 0x6BD0, 0x5519,
+	0x1783, 0x18A7, 0x7B6E, 0x7602, 0x4B7F, 0x3648, 0x2C53, 0x6B99,
+	0x0C23, 0x67CF, 0x7E0E, 0x4D8C, 0x5079, 0x209D, 0x244A, 0x747B,
+	0x350B, 0x0E4D, 0x7004, 0x6AC3, 0x7F3E, 0x21F5, 0x7A15, 0x2379,
+	0x1517, 0x1ABA, 0x4E77, 0x15A1, 0x04FA, 0x2D61, 0x253A, 0x1302,
+	0x1F63, 0x5AB3, 0x049A, 0x5AE8, 0x1CD7, 0x4A00, 0x30C8, 0x3247,
+	0x729C, 0x5034, 0x2B0E, 0x57F2, 0x00E4, 0x575B, 0x6192, 0x38F8,
+	0x2F6A, 0x0C14, 0x45FC, 0x41DF, 0x38DA, 0x7AE1, 0x7322, 0x62DF,
+	0x5E39, 0x0E64, 0x6D85, 0x5951, 0x5937, 0x6281, 0x33A1, 0x6A32,
+	0x3A5A, 0x2BAC, 0x743A, 0x5E74, 0x3B2E, 0x7EC7, 0x4FD2, 0x5D28,
+	0x751F, 0x3EF8, 0x39B1, 0x4E49, 0x746B, 0x6EF6, 0x44BE, 0x6DB7)
+
+def fetch_seed(ran_type, seeds, idx):
+	if ran_type == "SS":
+		seed_page = seeds[idx % len(seeds)]
+		seed_page &= 0x7fff
+		key = seed_page
+		return (key, seed_page)
+	else:
+		pass
+
+def pn_gen(ran_type, src_len, key):
+	pn_buf = []
+	for i in range(src_len):
+		pn_buf.append(0)
+		if ran_type == "SS":
+			for j in range(8):
+				if bool(key & 0x4000) != bool(key & 0x2000):
+					key <<= 1
+					key &= 0x7ffe
+					key += 1
+					pn_buf[i] += 1 << j
+				else:
+					key <<= 1
+					key &= 0x7ffe
+		else:
+			pass
+	return (key, pn_buf)
+
+def randomizer(in_image, out_image, ran_type, sec_reseed, page_size, spare_size, sector_size, page_per_block, ppen, vendor):
+	# check file length #
+	if (os.path.getsize(in_image) % (page_size + spare_size)) != 0:
+		raise Exception("input image size is not page size aligned")
+
+	page_number = os.path.getsize(in_image) / (page_size + spare_size)
+	sec_per_page = page_size / sector_size
+	spare_per_sec = spare_size / sec_per_page
+
+	if ran_type == "SS":
+		seeds = SS_SEED
+	else:
+		raise Exception("not support %s randomizer" % ran_type)
+	if ppen == 1:
+		if vendor == 'TSB':
+			PP = pp_tbl.TSB_PP
+		else:
+			raise Exception("unsupport %s pp table " % vendor)
+
+	f_in = open(in_image, "rb")
+	f_out = open(out_image, "wb")
+
+	for i in range(page_number):
+		percent = float(i) / float(page_number) * 100
+		sys.stdout.writelines("%.1f"%percent)
+		sys.stdout.writelines("%\r")
+		sys.stdout.flush();
+		if ppen == 1:
+			seed_idx = PP[i % (page_per_block / 2)]
+		else:
+			seed_idx = i % page_per_block
+		(key, seed_page) = fetch_seed(ran_type, seeds, seed_idx)
+		for j in range(sec_per_page):
+			if sec_reseed:
+				key = seed_page
+
+			(key, pn_buf) = pn_gen(ran_type, sector_size + spare_per_sec, key)
+
+			in_buf = f_in.read(sector_size + spare_per_sec)
+			if not in_buf:
+				break
+			in_buf = bytearray(in_buf)
+
+			for k in range(sector_size + spare_per_sec):
+				in_buf[k] ^= pn_buf[k]
+
+			in_buf = str(in_buf)
+			f_out.write(in_buf)
+
+	f_in.close()
+	f_out.close()
+
+def main(argv):
+	parser = argparse.ArgumentParser()
+	parser.add_argument('in_image', help = 'input image w/o random ')
+	parser.add_argument('out_image', help = 'output image w/ random ')
+	parser.add_argument('ran_type', default = 'SS', help = 'randomizer algorithm: SS or TSB')
+	parser.add_argument('sec_reseed', default = '1', help = 'whether reseed each sector')
+	parser.add_argument('page_size', help = 'page size')
+	parser.add_argument('spare_size', help = 'page spare size')
+	parser.add_argument('sector_size', help = 'sector size')
+	parser.add_argument('page_per_block', help = 'page per block number')
+	parser.add_argument('ppen', help = 'whether paired page is enabled')
+	parser.add_argument('vendor', help = 'vendor name')
+	args = parser.parse_args()
+
+	randomizer(args.in_image, args.out_image, args.ran_type, int(args.sec_reseed), int(args.page_size), \
+			int(args.spare_size), int(args.sector_size), int(args.page_per_block), int(args.ppen), args.vendor)
+
+if __name__ == "__main__":
+	sys.exit(main(sys.argv))
diff --git a/src/bsp/scatter/tools/nand-utils/start-burn.sh b/src/bsp/scatter/tools/nand-utils/start-burn.sh
new file mode 100755
index 0000000..29af331
--- /dev/null
+++ b/src/bsp/scatter/tools/nand-utils/start-burn.sh
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+source ${PWD}/tools/nand-utils/gen-nand-burn-img.sh 1.1 MX30LF4G18AC ./project/aud8516-slc/partition_nand.xml
diff --git a/src/bsp/scatter/tools/partition_editor.html b/src/bsp/scatter/tools/partition_editor.html
new file mode 100644
index 0000000..0463856
--- /dev/null
+++ b/src/bsp/scatter/tools/partition_editor.html
@@ -0,0 +1,187 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
+<script>
+$(document).ready(function() {
+    let xmldoc = null;
+
+    function check() {
+        $("#out").text("");
+        let hdr = xmldoc.getElementsByTagName("partition")[0];
+        if (hdr == null) {
+            $("#out").text("Error: invlaid partition file\n");
+            return;
+        }
+
+        let entries = xmldoc.getElementsByTagName("entry");
+        for (let i=0; i<entries.length; i++) {
+            if (parseInt(entries[i].getAttribute("end")) >= parseInt(hdr.getAttribute("lba"))) {
+                let error_msg = "Error: end lba of " + entries[i].getAttribute("name") + " (" + entries[i].getAttribute("end") + ") >= total lba (" + hdr.getAttribute("lba") + ")\n\n";
+                $("#out").text(error_msg);
+                return;
+            }
+        }
+    }
+
+    function show() {
+        if (xmldoc == null)
+            return;
+
+        $("#total_size").text((eval($("#total_lba").val()) * eval($("#lbs").val()) / 1024 / 1024) + "MB");
+        $("#start_addr").text((eval($("#start_lba").val()) * eval($("#lbs").val()) / 1024 / 1024) + "MB");
+
+        let text = "";
+        text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + xmldoc.documentElement.outerHTML;
+        text = text.replace(/>\s*</gm, ">\n<");
+        text = text.replace(/^<entry/gm, "\t<entry");
+        text = text.replace(/^\s+\n/gm, "");
+        $("#out").text($("#out").text() + text);
+    }
+
+    function init_editor() {
+        if (xmldoc == null)
+            return;
+
+        let hdr = xmldoc.getElementsByTagName("partition")[0];
+        $("#total_lba").val(hdr.getAttribute("lba"));
+        if (hdr.getAttribute("lbs") != null)
+            $("#lbs").val(hdr.getAttribute("lbs"));
+        else
+            $("#lbs").val(512);
+
+        let entries = xmldoc.getElementsByTagName("entry");
+        $("#start_lba").val(entries[0].getAttribute("start"));
+
+        let text = "";
+        for (let i=0; i<entries.length; i++) {
+            let size = ((entries[i].getAttribute("end") - entries[i].getAttribute("start") + 1)*$("#lbs").val()/1024);
+            text += (entries[i].getAttribute("name") + " " + size + "\n");
+        }
+        $("#entry_editor").val(text);
+    }
+
+    function update_xml() {
+        if (xmldoc == null)
+            return;
+
+        let hdr = xmldoc.getElementsByTagName("partition")[0];
+        hdr.setAttribute("lba", eval($("#total_lba").val()));
+
+        if (eval($("#lbs").val()) == 512)
+            hdr.removeAttribute("lbs");
+        else
+            hdr.setAttribute("lbs", eval($("#lbs").val()));
+
+        let entries = xmldoc.getElementsByTagName("entry");
+        let entry_strs = $("#entry_editor").val().split("\n");
+
+        let entry_cnt = 0;
+        for (let i=0; i<entry_strs.length; i++) {
+            if (entry_strs[i] == "")
+                continue;
+
+            if (entry_cnt >= entries.length) {
+                let newEle = xmldoc.createElement("entry");
+                newEle.setAttribute("type", entries[entry_cnt-1].getAttribute("type"));
+                hdr.appendChild(newEle);
+                entries = xmldoc.getElementsByTagName("entry");
+            }
+
+            entry = entry_strs[i].trim().split(/\s+/);
+            if (entry.length < 2)
+                continue;
+            if (entry_cnt == 0)
+                entries[entry_cnt].setAttribute("start", eval($("#start_lba").val()));
+            else
+                entries[entry_cnt].setAttribute("start", parseInt(entries[entry_cnt-1].getAttribute("end")) + 1);
+            entries[entry_cnt].setAttribute("end", (parseInt(entries[entry_cnt].getAttribute("start")) + eval(entry[1])*1024/eval($("#lbs").val()) - 1));
+            entries[entry_cnt].setAttribute("name",  entry[0]);
+            entry_cnt++;
+        }
+
+        for (; entry_cnt < entries.length;) {
+            hdr.removeChild(entries[entry_cnt]);
+            entries = xmldoc.getElementsByTagName("entry");
+        }
+    }
+
+    $("#partition").change(function() {
+        let reader = new FileReader();
+        reader.onload = function() {
+            let parser = new DOMParser();
+            xmldoc = parser.parseFromString(reader.result, "application/xml");
+            init_editor();
+            check();
+            show();
+        };
+        reader.readAsText($("#partition")[0].files[0]);
+    });
+
+    $(":text,#entry_editor").keyup(function(){
+        update_xml();
+        check();
+        show();
+    });
+
+    $(":text").change(function(){
+        $(":focus").val(eval($(":focus").val()));
+    });
+
+    $("#entry_editor").change(function(){
+        let text = "";
+        let entry_strs = $("#entry_editor").val().split("\n");
+
+        for (let i=0; i<entry_strs.length; i++) {
+            if (entry_strs[i] == "")
+                continue;
+
+            let entry = entry_strs[i].trim().split(/\s+/);
+            if (entry.length < 2)
+                continue;
+
+            text += entry[0] + " " + eval(entry[1]) + "\n";
+        }
+
+        $("#entry_editor").val(text);
+    });
+
+});
+</script>
+</head>
+<body>
+<label>partition file:
+<input type=file id="partition">
+</label>
+<br>
+<hr>
+
+<label>lba size(lbs):
+<input type=text id="lbs">
+</label>
+<br>
+<label>total lba:
+<input type=text id="total_lba">
+</label>
+<label id="total_size">
+</label>
+<br>
+<hr>
+
+<label>start lba of the first partition:
+<input type=text id="start_lba">
+</label>
+<label id="start_addr">
+</label>
+<br>
+<label> name size(KB)
+</label>
+<br>
+<textarea id=entry_editor rows=20>
+</textarea>
+<br>
+<hr>
+
+<pre id="out"></pre>
+</body>
+</html>
diff --git a/src/bsp/scatter/tools/partition_editor.sh b/src/bsp/scatter/tools/partition_editor.sh
new file mode 100644
index 0000000..a01d283
--- /dev/null
+++ b/src/bsp/scatter/tools/partition_editor.sh
@@ -0,0 +1,106 @@
+#!/bin/bash
+
+if [ -z "$1" ]
+then
+	# Show the partition layout if no argument input
+	echo 'Usage:'
+	echo '	Show current Partitions layout:'
+	echo '		sh partition_editor.sh ${XMLFILE}'
+	exit 1
+fi
+
+if [ ! -f "$1" ]
+then
+	echo $1': File not exist!'
+	exit 1
+fi
+
+# Show the partition layout in better interactive mode
+tmpfile=".part.tmp"
+xmlfile=$1
+
+# LBS(size defined in tmp file is KB based)
+lbs_exist=`grep -o "\<lbs\>" ${xmlfile}`
+if [ -z $lbs_exist ]
+then
+	# For eMMC/Nor, only support 1024-aligned by now
+	lbs=1
+else
+	lbs=`awk -F'"' '/lbs=/{print $4}' ${xmlfile}`
+	lbs=$(($lbs/1024))
+fi
+# LBA(Total page number)
+lba_exist=`grep -o "\<lba\>" ${xmlfile}`
+if [ -z $lba_exist ]
+then
+        lba=0
+else
+        lba=`awk -F'"' '/lba=/{print $2}' ${xmlfile}`
+fi
+# reserved some blocks to store BBT
+reserved_exist=`grep -o "\<reserved\>" ${xmlfile}`
+if [ -z $reserved_exist ]
+then
+	reserved=0
+else
+	reserved=`awk -F'"' '/reserved=/{print $6}' ${xmlfile}`
+fi
+
+# Generate temporary file for interactive modifing and editing
+echo '*** You can delete/insert/modify(partname/size) partitions ***' > ${tmpfile}
+echo '*** Partition size must be ERASE_BLOCK_SIZE(define in Nand SPEC) aligned ***' >> ${tmpfile}
+echo '' >> ${tmpfile}
+echo 'Part_name			Size(KB)        Attr' >> ${tmpfile}
+`sed -nr 's/^.+start=\"(\w+)\"\s*end=\"(\w+)\"\s*(attributes=\"(\w+)\"\s*)?name=\"(\w+)\".+$/\5 \1 \2 \4/p' ${xmlfile} |
+	awk -v blk_size=$lbs '{printf "%-15s\t\t%d\t\t%s\n", $1, ($3-$2+1)*blk_size, $4}' >> ${tmpfile}`
+
+# Edit the partition layout via vim
+vim ${tmpfile}
+
+# The new partition layout
+part_name=(`awk '/^\w+\s+[0-9]+/{print $1}' ${tmpfile}`)
+part_size=(`awk '/^\w+\s+[0-9]+/{print $2}' ${tmpfile}`)
+part_attr=(`awk '/^\w+\s+[0-9]+/{if ($3 == "") print "-"; else print $3}' ${tmpfile}`)
+# How many elements in the array
+newcnt=$((${#part_name[@]}-1))
+# Generate the temporary xml file
+xmltmp=".xml.tmp"
+`cp -f ${xmlfile} ${xmltmp}`
+`sed -i '/name=/d' ${xmltmp}`
+# Modify the temporary xml file
+str1='	<entry type="{0FC63DAF-8483-4772-8E79-3D69D8477DE4}" start="'
+str2='" end="'
+strattr='" attributes="'
+str3='" name="'
+str4='" />'
+# first start address
+sa=`awk -F'"' '/name=/{print $4; exit;}' ${xmlfile}`
+# last end address
+lea=`sed -n '/name=/p' ${xmlfile} | sed -n '$p' | awk -F'"' '{print $6}'`
+for ((i=0; i<=$newcnt; i++)) {
+	len=${part_size[i]}
+	if [ $i -eq $newcnt ]
+	then
+		ea=$lea
+		if [ $lba -ne 0 -a $reserved -ne 0 ]
+		then
+			ea=$(($lba-$reserved-1))
+		fi
+	else
+		ea=$(($sa+$len/$lbs-1))
+	fi
+	name=${part_name[i]}
+	attr=${part_attr[i]}
+	if [ "$attr" == "-" ]
+	then
+		`sed -i '/<\/partition>/i \'"$str1$sa$str2$ea$str3$name$str4"'' ${xmltmp}`
+	else
+		`sed -i '/<\/partition>/i \'"$str1$sa$str2$ea$strattr$attr$str3$name$str4"'' ${xmltmp}`
+	fi
+	sa=$(($ea+1))
+}
+# Replace the xml file with the temp xml file, delete useless temporary files
+`cp -f ${xmltmp} ${xmlfile}`
+`rm -f ${xmltmp} ${tmpfile}`
+
+exit 0