blob: fa71e74bf474ad53a0d2f3b55f2e440352db9cef [file] [log] [blame]
#!/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))