def gen_flash_images(self): work_dir = self.config.get_str('gapy/work_dir') # Go through all the specified flashes to generate image and stimuli if needed for flash_path in self.config.get_py('runner/flash_devices'): traces.info('Building stimuli for flash ' + flash_path) flash_config = self.config.get(flash_path) if flash_config is None: raise errors.InputError('Invalid flash device: ' + flash_path) if flash_config.get('content/partitions') is not None: for name, partition in flash_config.get('content/partitions').get_items().items(): type_name = partition.get_str('type') if type_name is not None: if type_name == 'readfs': gen_readfs.main(config=self.config, partition_config=partition) elif type_name == 'lfs': gen_lfs.main(config=self.config, partition_config=partition) elif type_name == 'hostfs': work_dir = self.config.get_str('gapy/work_dir') for file in partition.get('files').get_dict(): shutil.copy(file, work_dir) else: raise errors.InputError('Invalid partition type: ' + type_name) if flash_config.get('content/image') is not None: gen_flash_image.main(config=self.config, flash_config=flash_config)
def runnerOperation(args, config=None, runnerConfig=None): traces.info('Board runner') bootTCL = os.path.join(common.openocdDir, 'tcl/jtag_boot.tcl') oocd = openocd.OpenOCD(cable=args.cable, chip=args.chip, scriptsTCL=[bootTCL]) oocd.run(['gap8_jtag_load_binary_and_start %s elf' % (args.binary)])
def gen(self, traces, filename): traces.info(' Generating to file: ' + filename) with open(filename, 'w') as file: for id in range(0, self.nb_regs): value = self.efuses_list[id].get() traces.info(' Writing register (index: %d, value: 0x%x)' % (id, value)) file.write('{0:032b}\n'.format(value))
def appendPartitionTable(self, partitionTable): self.partitionTable = partitionTable # Check if a boot loader has been added previously, if not, generating empty boot loader if len(self.image) == 0: traces.info("Warning: Empty boot loader partition. GAP will not be able to boot from flash.") self.ssbl = binary.SSBL(flashType = self.flashType) self.image += self.ssbl.dump() self.image += self.partitionTable.to_binary()
def operationFunc(args, config=None): traces.info('Gapy flash image tool') flashTCL = os.path.join(common.openocdDir, 'tcl/flash_image.tcl') bootTCL = os.path.join(common.openocdDir, 'tcl/jtag_boot.tcl') oocd = openocd.OpenOCD(cable=args.cable, chip=args.chip, scriptsTCL=[flashTCL, bootTCL]) oocd.run([ 'gap_flash_raw %s %d %s' % (args.image.name, len(args.image.read()), common.openocdDir), 'exit' ])
def run(self, openocdCommand=[]): command = self.prg + ' -c "' for scr in self.scripts: command += 'script %s; ' % scr for cmd in openocdCommand: command += '%s; ' % cmd command += '"' traces.info(command) rc = os.system(command) if rc != 0: traces.critical('OpenOCD return with an error: %d' % rc) exit(-1)
def operationFunc(args, config=None): traces.info('Gapy ELF2Bin converter.') for elf in args.elf: traces.info("Convertting %s:" % elf.name) binApp = binary.App(elf=elf) baseName = os.path.basename(elf.name) if baseName[-4:] == '.elf': baseName = baseName[:-4] outName = os.path.join(os.path.dirname(elf.name), baseName + ".bin") with open(outName, 'wb') as outFile: outFile.write(binApp.dump())
def operationFunc(args, config=None): if (len(args.comp) == 0 or (len(args.comp) == 1 and len(args.comp[0]) == 0)) and len( args.compDir) == 0 and len(args.compDirRec) == 0: return traces.info('Generating ReadFS image') # Concatenate input listsd compList = [] for l in args.comp: compList += l compDirList = [] for l in args.compDir: compDirList += l compDirRecList = [] for l in args.compDirRec: compDirRecList += l # # Build ReadFS image # readFS = ReadFS() for comp in compList: is_enabled = True readFS.appendComponent( Comp(os.path.dirname(comp), os.path.basename(comp), args.incDirInName)) for compDir in compDirList: for comp in getCompsFromDir(compDir, incDirInName=args.incDirInName): readFS.appendComponent(comp) is_enabled = True for compDir in compDirRecList: for comp in getCompsFromDir(compDir, rec=True, incDirInName=args.incDirInName): readFS.appendComponent(comp) is_enabled = True readFS.generate(args.output) if config is not None: config.set('enabled', True)
def __append(self, buffer, padToOffset = None): if self.encrypt == True: traces.info("encrypt with key: %s Iv: %s" % (self.aesKey, self.aesIv)) cmd = 'aes_encode %s %s' % (self.aesKey, self.aesIv) crc = self.get_crc(buffer) buffer += struct.pack('I', crc) p = subprocess.Popen(cmd, shell = True, stdout = subprocess.PIPE, stdin = subprocess.PIPE) out, err = p.communicate(buffer) if p.returncode != 0: raise Exception( 'Error when executing aes_encore to encrypt binary, probably this tool is not available') buffer = out if padToOffset != None: self.bin.padToOffset(padToOffset) self.bin += buffer
def gen_efuse_stim(self, filename): traces.info('Creating efuse stimuli') nb_regs = 128 efuses = [0] * nb_regs info2 = 0 # RTL platform | flash boot | no encryption | no wait xtal efuses[0] = 2 | (2 << 3) | (0 << 4) | (0 << 5) | (0 << 6) | (0 << 7) efuses[37] = 1 << 0 # Boot on UDMA hyper #efuses[39] = 0x2 # Boot on UDMA SPIM1 interface (first single spi) # Do not check bootmode pads by default to boot from what is specified in efuses info2 = (1 << 8) | (1 << 9) efuses[1] = info2 traces.info(' Generating to file: ' + filename) with open(filename, 'w') as file: for efuseId in range (0, 128): value = efuses[efuseId] traces.info(' Writing register (index: %d, value: 0x%x)' % (efuseId, value)) file.write('{0:032b}\n'.format(value))
def operationFunc(args, config=None): traces.info("gen_partition tools") input = args.input.read() if isBinaryPartitionTable(input): traces.info("Parsing binary partition file input: %s..." % args.input.name) table = PartitionTable.from_binary(input) else: traces.info("Parsing CSV input file: %s..." % args.input.name) try: input = input.decode() except UnicodeDecodeError: raise InputError( '"%s" input file must be a CSV text file or partition table binary.' % args.input.name) table = PartitionTable.from_csv(input, args.partitionTableOffset, args.blockSize, args.md5Sum) if not args.no_verify: traces.info("Verifying table...") table.verify(partitionTableOffset=args.partitionTableOffset, flashSectorSize=args.blockSize, flashSize=args.flashSize) # Make sure that the output directory is created output_dir = os.path.abspath(os.path.dirname(args.output)) if not os.path.exists(output_dir): try: os.makedirs(output_dir) except OSError as exc: if exc.errno != errno.EEXIST: raise if isBinaryPartitionTable(input): output = table.to_csv() with sys.stdout if args.output == '-' else open(args.output, 'w') as f: f.write(output) else: output = table.to_binary() try: stdout_binary = sys.stdout.buffer # Python 3 except AttributeError: stdout_binary = sys.stdout with stdout_binary if args.output == '-' else open(args.output, 'wb') as f: f.write(output)
def operationFunc(args): traces.verbose = args.verbose traces.info('Generating ReadFS image') # Concatenate input listsd compList = [] for l in args.comp: compList += l compDirList = [] for l in args.compDir: compDirList += l compDirRecList = [] for l in args.compDirRec: compDirRecList += l # # Build ReadFS image # readFS = ReadFS() for comp in compList: readFS.appendComponent( Comp(os.path.dirname(comp), os.path.basename(comp), args.incDirInName)) for compDir in compDirList: for comp in getCompsFromDir(compDir, incDirInName=args.incDirInName): readFS.appendComponent(comp) for compDir in compDirRecList: for comp in getCompsFromDir(compDir, rec=True, incDirInName=args.incDirInName): readFS.appendComponent(comp) readFS.generate(args.output)
def gen_efuse_stim(self, filename): traces.info('Creating efuse stimuli') nb_regs = 128 efuses = [0] * nb_regs chip = self.config.get_str('**/chip') if chip == 'gap8_revc': if self.get_boot_mode() == 'flash': efuses[0] = 2 | (2 << 3) | (0 << 4) | (0 << 5) | (0 << 6) | ( 0 << 7) if self.get_boot_flash_type() == 'spi': # SPI flash type efuses[37] = (0 << 0) else: # Hyperflash type efuses[37] = (1 << 0) elif chip == 'gap_rev1': if self.get_boot_mode() == 'flash': efuses[0] = 2 | (2 << 3) | (0 << 4) | (0 << 5) | (0 << 6) | ( 0 << 7) if self.get_boot_flash_type() == 'spi': # SPI flash type efuses[37] = (0 << 0) else: # Hyperflash type efuses[37] = (1 << 0) else: # RTL platform | flash boot | no encryption | no wait xtal efuses[0] = 0x2A values = [0] * nb_regs * 8 for efuseId in range(0, nb_regs): value = efuses[efuseId] traces.info(' Writing register (index: %d, value: 0x%x)' % (efuseId, value)) for index in range(0, 8): if (value >> index) & 1 == 1: values[efuseId + index * 128] = 1 traces.info(' Generating to file: ' + filename) with open(filename, 'w') as file: for value in values: file.write('%d ' % (value))
def __dumpHeader(self): traces.info("Generating boot loader header:") traces.info(" Nb areas: %d" % len(self.segments)) # First compute areas flash information flashOffset = 0 flashOffset += 4 + 4 + 4 + 4 + 16 * 4 * len(self.segments) crcOffset = flashOffset flashOffset += 4 flashOffset = align(flashOffset, self.blockSize) if self.encrypt: for segment in self.segments: segment.size += 4 index = 0 for segment in self.segments: segment.nbBlocks = int( (segment.size + self.blockSize - 1) / self.blockSize) segment.offset = flashOffset flashOffset += segment.nbBlocks * self.blockSize traces.info( " Area %d: offset: 0x%x, base: 0x%x, size: 0x%x, nbBlocks: %d" % (index, segment.offset, segment.base, segment.size, segment.nbBlocks)) index += 1 flashOffset = align(flashOffset, 8) self.partitionTableOffset = flashOffset # Then write the header containing memory areas declaration header = BlockBuffer(blockSize=self.blockSize) header.appendInt(self.partitionTableOffset) header.appendInt(len(self.segments)) header.appendInt(self.entry) # Legacy bootAddr ROM field, it is no longer used header.appendInt(0x1c000000) for area in self.segments: header.appendInt(area.offset) header.appendInt(area.base) header.appendInt(area.size) header.appendInt(area.nbBlocks) header.padToOffset(crcOffset) crc = self.get_crc(header) header.appendInt(crc) self.__append(header)
def operationFunc(args, config=None): if config.get_str('root_dir') is None: return traces.info('Generating LittleFS image') cmd = 'mklfs -b 262144 -r 4 -p 4 -s 10485760 -c %s -i %s' % (config.get_str('root_dir'), args.output) traces.info('Generating LittleFS images with command:') traces.info(' ' + cmd) stdout = None if traces.verbose else subprocess.PIPE if subprocess.run(shlex.split(cmd), stdout=stdout).returncode != 0: raise errors.InputError('Failed to generate LittleFS image') if config is not None: config.set('enabled', True)
def gen_efuse_stim(self, filename): traces.info('Creating efuse stimuli') nb_regs = 128 efuses = [0] * nb_regs # RTL platform | flash boot | no encryption | no wait xtal efuses[0] = 2 | (2 << 3) | (0 << 4) | (0 << 5) | (0 << 6) | (0 << 7) efuses[37] = 1 << 0 # Boot on UDMA HYPER traces.info(' Generating to file: ' + filename) with open(filename, 'w') as file: for efuseId in range (0, 128): value = efuses[efuseId] traces.info(' Writing register (index: %d, value: 0x%x)' % (efuseId, value)) file.write('{0:032b}\n'.format(value))
def __dumpHeader(self): traces.info("Generating app header:") traces.info(" Nb areas: %d" % len(self.segments)) # First compute areas flash information flashOffset = 0 flashOffset += 4 + 4 + 4 + 4 + 16 * 4 * len(self.segments) flashOffset = align(flashOffset, 8) if self.encrypt: for segment in self.segments: segment.size += 4 index = 0 for segment in self.segments: segment.offset = flashOffset flashOffset += segment.size flashOffset = align(flashOffset, 8) traces.info(" Area %d: offset: 0x%x, base: 0x%x, size: 0x%x" % ( index, segment.offset, segment.base, segment.size)) index += 1 flashOffset = align(flashOffset, 8) # Then write the header containing memory areas declaration header = BlockBuffer(blockSize = 8) header.appendInt(len(self.segments)) header.appendInt(self.entry) for area in self.segments: header.appendInt(area.offset) header.appendInt(area.base) header.appendInt(area.size) crc = self.get_crc(header) self.__append(struct.pack('4s', App.MAGIC)) self.__append(struct.pack('16s', crc)) self.__append(header)
def operationFunc(args, flash_config=None): traces.info('Build flash image') flashImage = FlashImage(sectorSize = args.blockSize, flashType = args.flashType) # # Bootloader # endOfSSBLOffset = flashImage.appendBootloader(elf = args.boot_loader) traces.info("Partition boot loader size: 0x%X" % endOfSSBLOffset) # # Partition table # traces.info("\nGenerating partition table:") # Check if the partition table is lower than free space in current SSBL flash sector if (endOfSSBLOffset + partition.MAX_PARTITION_TABLE_SIZE) > binary.align(endOfSSBLOffset, args.blockSize): partitionTableOffset = binary.align(endOfSSBLOffset, args.blockSize) traces.info( "No free space to store partition table at the end of the SSBL partition, adding padding untill the next sector 0x%X" % partitionTableOffset) flashImage.image.padToOffset(partitionTableOffset) else: partitionTableOffset = endOfSSBLOffset traces.info("Partition table offset: 0x%X" % partitionTableOffset) if flash_config and flash_config.get('content/partitions') is not None: traces.info('Partition table was provided from configuration file.') config_partitions = {} table = gen_partition.PartitionTable(md5Sum = True) offset = partitionTableOffset + partition.MAX_PARTITION_TABLE_SIZE for name, partition_config in flash_config.get('content/partitions').get_items().items(): if partition_config.get_bool('enabled'): path = partition_config.get_str('image') type_name = partition_config.get_str('type') size = os.path.getsize(path) traces.info("Creating partition (name: %s, type: %s, path: %s, offset: 0x%x, size: 0x%x" % (name, type_name, path, offset, size)) part = partition.PartitionDefinition( name = name, type = partition.DATA_TYPE, subtype = partition.SUBTYPES[partition.DATA_TYPE][type_name], size = size, offset = binary.align(offset, args.blockSize), path = path) table.append(part) offset = part.offset + part.size else: if args.partitionTable: traces.infoWithoutNewLine('Open partition table: ') tableInput = args.partitionTable.read() if gen_partition.isBinaryPartitionTable(tableInput): # Binary format traces.info('Binary table format') table = gen_partition.PartitionTable.from_binary(tableInput) else: # CSV Format traces.info('CSV table format') try: tableInput = tableInput.decode() except UnicodeDecodeError: raise InputError( '"%s" input file must be a CSV text file or partition table binary.' % args.partitionTable.name) traces.info('Parsing CSV input...') table = gen_partition.PartitionTable.from_csv(tableInput, partitionTableOffset = partitionTableOffset, sectorSize = args.blockSize, md5Sum = True) else: # Auto partitioning traces.info('Partition table was not provided, generating generic table.') table = gen_partition.PartitionTable(md5Sum = True) offset = partitionTableOffset + partition.MAX_PARTITION_TABLE_SIZE if "readfs" in args.partition.keys(): traces.info("Creating ReadFS partition") readFSSize = os.path.getsize(args.partition['readfs'].name) traces.info("ReadFS image size: 0x%X" % readFSSize) readFSPartition = partition.PartitionDefinition( name = 'readfs', type = partition.DATA_TYPE, subtype = partition.READFS_SUBTYPE, size = readFSSize, offset = binary.align(offset, args.blockSize)) table.append(readFSPartition) offset = readFSPartition.offset + readFSPartition.size # # LittleFS partition # lfsOffset = binary.align(offset, args.blockSize) if "lfs" in args.partition.keys(): # LittleFS image from CLI traces.info("Creating LittleFS partition") lfsSize = os.path.getsize(args.partition['lfs'].name) traces.info("LittleFS image size: 0x%X" % lfsSize) else: # No LittleFS image, use of remaining free space lfsSize = args.flashSize - lfsOffset traces.info("Creating an empty LittleFS partition, using the rest of the flash space: 0x%X" % lfsSize) lfsPartition = partition.PartitionDefinition( name = 'lfs', type = partition.DATA_TYPE, subtype = partition.LFS_SUBTYPE, size = lfsSize, offset = binary.align(offset, args.blockSize)) table.append(lfsPartition) offset = lfsPartition.offset + lfsPartition.size traces.info('Verifying table...') traces.info(table.to_csv(simple_formatting = False)) table.verify(partitionTableOffset = partitionTableOffset, flashSectorSize = args.blockSize, flashSize = args.flashSize) flashImage.appendPartitionTable(table) # # Writting partition images # traces.info("Dumping partition image::") if flash_config and flash_config.get('content/partitions') is not None: for p in table: if p.path: flashImage.image.padToOffset(p.offset) with open(p.path, 'rb') as p_file: flashImage.image += p_file.read() else: for p in sorted(table, key = lambda x: x.offset): if p.name in args.partition.keys(): traces.info("%s partition [%s]" % (p.name, args.partition[p.name].name)) flashImage.image.padToOffset(p.offset) flashImage.image += args.partition[p.name].read() else: traces.info("%s partition [None]" % p.name) # add padding to finish on 4 bytes align flashImage.image.padToOffset(binary.align(flashImage.getCurrentSize(), 4)) # # Write output # traces.info("\nWritting output image to %s, size %uKB." % (args.output, flashImage.getCurrentSize() / 1024)) flashImage.writeRAWImage(args.output) if args.flashStimuliFormat is not None: file_name = args.flashStimuliFile traces.info("\nWritting output stimuli to %s" %( file_name)) flashImage.writeStimuli(file_name)
def generate(self, outputPath): # Compute the header size headerSize = 12 # Header size and number of components for comp in self.compList: headerSize += 12 # Partition address, size and path length headerSize += len(comp.name) + 1 # Path offset = headerSize # Now set the flash address for each component if len(self.compList) > 0: traces.info('Adding component') traces.info('') traces.info( 'Name Size Partition offset') else: traces.info("*** Warning: No component was specified! ***") for comp in self.compList: comp.partitionAddr = (offset + 3) & ~3 traces.info('%-30s 0x%-15x 0x%x' % (comp.name, comp.size, comp.partitionAddr)) offset = comp.partitionAddr + comp.size # # Now create the raw image as a byte array # # First header size self.appendLongInt(headerSize) # Number of components self.appendInt(len(self.compList)) # Then for each component for comp in self.compList: # The partition address self.appendInt(comp.partitionAddr) # Binary size self.appendInt(comp.size) # The path length self.appendInt(len(comp.name) + 1) # And the path self += comp.name.encode('utf-8') self.appendByte(0) # Then dump all components for comp in self.compList: with open(comp.path, 'rb') as file: self.padToOffset(comp.partitionAddr) self += file.read() # # Write output # traces.newLine() traces.info("Write ReadFS image -> %s" % outputPath) traces.info("Total size: 0x%x bytes" % len(self)) try: os.makedirs(os.path.realpath(os.path.dirname(outputPath))) except FileExistsError: pass with open(outputPath, 'wb') as file: file.write(self)
def gen_efuse_stim(self, filename): traces.info('Creating efuse stimuli') efuse_map = efuse.Efuse_map() if self.config.get_bool('**/runner/efuses/enabled'): # Set all padfun to 1 by default except for JTAG pads to reflect edfault HW values for i in range(0, 96): #self.set_padfun(efuses, i, 1) self.set_padfun( efuse_map, i, 0) # TODO temporary put to 0 to not break all tests self.set_padfun(efuse_map, 81, 0) self.set_padfun(efuse_map, 82, 0) self.set_padfun(efuse_map, 83, 0) self.set_padfun(efuse_map, 84, 0) self.set_padfun(efuse_map, 85, 0) efuse_map.get_efuse('info_1').get_field('platform').set( 2) # RTL platform efuse_map.get_efuse('info_1').get_field('icache_enabled').set(1) # By default, only activate fast clock and fed other blocks like timer at 24Mhz/16 fast_osc_freq_div = 24576062.0 / 16 efuse_map.get_efuse('info_1').get_field('osc_ctrl_setup').set(1) efuse_map.get_efuse('info_1').get_field('osc_ctrl').set(1) efuse_map.get_efuse('info_1').get_field( 'fast_clk_div_pow2_setup').set(1) efuse_map.get_efuse('fast_clk_div_pow2').set(4 | (1 << 3)) efuse_map.get_efuse('info_2').get_field('wake_osc_ctrl_setup').set( 1) efuse_map.get_efuse('info_2').get_field('wake_osc_ctrl').set(1) efuse_map.get_efuse('info_2').get_field( 'wake_fast_clk_div_pow2_setup').set(1) efuse_map.get_efuse('wake_fast_clk_div_pow2').set(4 | (1 << 3)) # Activate oscillator stability wait loop efuse_map.get_efuse('info_1').get_field('wait_xtal').set(1) efuse_map.get_efuse('wait_xtal_period').set( 500 ) # Xtal is monitored in open loop at max 50MHz and we want to monitor every 10us efuse_map.get_efuse('wait_xtal_delta').set(10) # Delta is 1% efuse_map.get_efuse('wait_xtal_min').set( 5) # Stop as soon as 5 stable periods are found efuse_map.get_efuse('wait_xtal_max').set(50000) # Also put right values in fixed wait loop in case a test wants to activate it cycles = int(2000 * fast_osc_freq_div / 1000000) efuse_map.get_efuse('fll_wait_cycles').set(cycles) # 100us efuse_map.get_efuse('fll_wake_wait_cycles').set(cycles) # 100us # No wait for ref clock efuse_map.get_efuse('info_2').get_field('ref_clk_wait').set(1) efuse_map.get_efuse('ref_clk_wait_cycles').set(0) efuse_map.get_efuse('info_2').get_field( 'ref_clk_wait_deep_sleep').set(1) efuse_map.get_efuse('ref_clk_wait_cycles_deep_sleep').set(0) efuse_map.get_efuse('info_1').get_field('timer_source').set(2) # Enable JTAG efuse_map.get_efuse('info_1').get_field('feature_disable_set').set( 1) efuse_map.get_efuse('feature_disable').set(0) boot_mode = self.config.get_str('**/runner/boot/mode') if boot_mode == 'flash': device = self.config.get( self.config.get_str('**/runner/boot/device')) device_type = device.get_str('datasheet/type') # Do not check bootmode pads by default to boot from what is specified in efuses pads_nocheck = 0 if self.config.get_bool( '**/runner/boot/jtag_force') else 1 efuse_map.get_efuse('info_2').get_field( 'bootmode0_nocheck').set(pads_nocheck) efuse_map.get_efuse('info_2').get_field( 'bootmode1_nocheck').set(pads_nocheck) if device_type == 'hyper': # Boot on UDMA hyper efuse_map.get_efuse('info_3').get_field( 'flash_cs_setup').set(1) efuse_map.get_efuse('info_3').get_field('flash_cs').set(1) efuse_map.get_efuse('info_3').get_field( 'flash_itf_setup').set(1) efuse_map.get_efuse('info_3').get_field('flash_itf').set(0) efuse_map.get_efuse('info_1').get_field('bootmode').set(1) efuse_map.get_efuse('info_2').get_field( 'clkdiv_setup').set(1) efuse_map.get_efuse('info_2').get_field('clkdiv').set(0) # Pads for hyper 0 self.set_padfun(efuse_map, 0, 0) self.set_padfun(efuse_map, 1, 0) self.set_padfun(efuse_map, 2, 0) self.set_padfun(efuse_map, 3, 0) self.set_padfun(efuse_map, 4, 0) self.set_padfun(efuse_map, 5, 0) self.set_padfun(efuse_map, 6, 0) self.set_padfun(efuse_map, 7, 0) self.set_padfun(efuse_map, 8, 0) self.set_padfun(efuse_map, 9, 0) self.set_padfun(efuse_map, 10, 0) self.set_padfun(efuse_map, 11, 0) self.set_padfun(efuse_map, 12, 0) elif device_type == 'spi': # Boot on UDMA spi efuse_map.get_efuse('info_1').get_field('bootmode').set(2) efuse_map.get_efuse('info_2').get_field( 'clkdiv_setup').set(1) efuse_map.get_efuse('info_2').get_field('clkdiv').set(0) # Flash is on CS 0 ITF 1 (CS is inverted in efuse) efuse_map.get_efuse('info_3').get_field( 'flash_cs_setup').set(1) efuse_map.get_efuse('info_3').get_field('flash_cs').set(1) efuse_map.get_efuse('info_3').get_field( 'flash_itf_setup').set(1) efuse_map.get_efuse('info_3').get_field('flash_itf').set(1) # SPI wait time after configuring control register, should take 200ns but RTL model take 10us to update it efuse_map.get_efuse('info_2').get_field( 'spi_conf_wait').set(1) efuse_map.get_efuse('spi_conf_wait_cycles').set( math.ceil(0.00001 * fast_osc_freq_div)) # SPI status register value efuse_map.get_efuse('info_2').get_field( 'flash_status_set').set(2) efuse_map.get_efuse('flash_status').set( 0x1b880200 ) # Activate octospi mode and DTR and unprotect all sectors # SPI flash latency efuse_map.get_efuse('info_2').get_field( 'flash_latency_set').set(1) efuse_map.get_efuse('info_2').get_field( 'flash_latency_value').set(22) # Flash commands efuse_map.get_efuse('info_2').get_field( 'flash_commands_set').set(1) efuse_map.get_efuse('flash_commands').set((0x06 << 0) | (0x71 << 8) | (0x0B << 16) | (0xAB << 24)) elif device_type == 'mram': # Boot on MRAM efuse_map.get_efuse('info_1').get_field('bootmode').set(3) efuse_map.get_efuse('info_1').get_field( 'mram_reset_wait').set(1) efuse_map.get_efuse('info_2').get_field( 'wake_mram_reset_wait').set(1) efuse_map.get_efuse('mram_reset_wait_cycles').set( math.ceil(0.000003 * fast_osc_freq_div)) efuse_map.get_efuse('wake_mram_reset_wait_cycles').set( math.ceil(0.000003 * fast_osc_freq_div)) efuse_map.get_efuse('info_2').get_field( 'clkdiv_setup').set(1) efuse_map.get_efuse('info_2').get_field('clkdiv').set(5) efuse_map.get_efuse('info_3').get_field('flash_wait').set( 1) efuse_map.get_efuse('flash_wait').set( math.ceil(0.00002 * fast_osc_freq_div)) elif boot_mode == 'jtag': efuse_map.get_efuse('info_2').get_field( 'bootmode0_nocheck').set(0) efuse_map.get_efuse('info_2').get_field( 'bootmode1_nocheck').set(0) efuse_map.get_efuse('info_1').get_field('bootmode').set(0) elif boot_mode == 'spislave': # Do not check bootmode pads by default to boot from what is specified in efuses efuse_map.get_efuse('info_2').get_field( 'bootmode0_nocheck').set(1) efuse_map.get_efuse('info_2').get_field( 'bootmode1_nocheck').set(1) efuse_map.get_efuse('info_1').get_field('bootmode').set(4) # Lock FLL soc and periph efuse_map.get_efuse('info_1').get_field('fll_global_setup').set(1) efuse_map.get_efuse('info_1').get_field('fll_dco0_setup').set(1) # FLL DRR (DCO min | DCO max) efuse_map.get_efuse('fll_drr').set((0 << 0) | (0x1ff << 16)) # Pre-lock FLL CCR1 (CLK0 DIV | CLK1 DIV) efuse_map.get_efuse('fll_ccr1_pre_lock').set((0 << 0) | (0 << 8)) # Post-lock FLL CCR1 (CLK0 DIV | CLK1 DIV) efuse_map.get_efuse('fll_ccr1_post_lock').set((0 << 0) | (3 << 8)) # FLL CCR2 (CLK0 SEL | CLK1 SEL | CLK2_SEL | CLK3_SEL | CKG0) efuse_map.get_efuse('fll_ccr2').set((0x1 << 0) | (0x1 << 4) | (0x1 << 8) | (0x2 << 12) | (1 << 16)) # DCO0 CR1 (DCO EN | CLOSE LOOP | LOOP GAIN | LOCK TOL | ITG | ASSERT CYCLES) efuse_map.get_efuse('fll_f0cr1').set((1 << 0) | (1 << 1) | (4 << 4) | (10 << 8) | (24 << 16) | (6 << 26)) # DCO0 CR2 (MFI | DCO CODE) efuse_map.get_efuse('fll_f0cr2').set((166 << 0) | (0x1A << 16)) # FLL DRR (DCO min | DCO max) efuse_map.get_efuse('wakeup_fll_drr').set((0 << 0) | (0x1ff << 16)) # Pre-lock FLL CCR1 (CLK0 DIV | CLK1 DIV) efuse_map.get_efuse('wakeup_fll_ccr1_pre_lock').set((0 << 0) | (0 << 8)) # Post-lock FLL CCR1 (CLK0 DIV | CLK1 DIV) efuse_map.get_efuse('wakeup_fll_ccr1_post_lock').set((0 << 0) | (1 << 8)) # FLL CCR2 (CLK0 SEL | CLK1 SEL | CLK2_SEL | CLK3_SEL | CKG0) efuse_map.get_efuse('wakeup_fll_ccr2').set((0x1 << 0) | (0x1 << 4) | (0x1 << 8) | (0x2 << 12) | (1 << 16)) # DCO0 CR1 (DCO EN | CLOSE LOOP | LOOP GAIN | LOCK TOL | ITG | ASSERT CYCLES) efuse_map.get_efuse('wakeup_fll_f0cr1').set((1 << 0) | (1 << 1) | (4 << 4) | (10 << 8) | (24 << 16) | (6 << 26)) # DCO0 CR2 (MFI | DCO CODE) efuse_map.get_efuse('wakeup_fll_f0cr2').set((166 << 0) | (0x1A << 16)) efuse_map.apply_from_config(self.config) efuse_map.gen(traces, filename)
def conf(self): boot_mode = self.config.get_str("runner/boot/mode") if boot_mode is None: raise errors.InputError('The boot mode has to be specified') binary = self.config.get_str('runner/boot-loader') # If we boot from flash, store the boot binary information in the specified flash if boot_mode == 'flash': flash_config = self.get_boot_flash() flash_config.set('content/boot-loader', binary) work_dir = self.config.get_str('gapy/work_dir') # Go through all the specified flashes to generate image and stimuli if needed for flash_path in self.config.get_py('runner/flash_devices'): traces.info('Building stimuli for flash ' + flash_path) flash_config = self.config.get(flash_path) if flash_config is None: raise errors.InputError('Invalid flash device: ' + flash_path) gen_image = False flash_image = self.args.force # The flash can contain the boot binary and several partitions for FS if flash_config.get('content/boot-loader') is not None: gen_image = True if flash_config.get('content/partitions') is not None: for name, partition in flash_config.get( 'content/partitions').get_items().items(): gen_image = True type_name = partition.get_str('type') if type_name is None: raise errors.InputError('No partition type found') if type_name not in ['hostfs'] and ( (partition.get('files') is not None and len(partition.get('files').get_dict()) != 0) or (partition.get_str('root_dir'))): flash_image = True img_path = os.path.join( work_dir, flash_path.replace('/', '.') + '.' + name + '.img') partition.set('image', img_path) if gen_image: img_path = os.path.join(work_dir, flash_path.replace('/', '.') + '.img') flash_config.set('content/image', img_path) flash_config.set('content/flash', flash_image) stim_format = flash_config.get_str("models/%s/stimuli/format" % self.args.platform) if stim_format is not None: file_name = flash_config.get_str("models/%s/stimuli/file" % self.args.platform) if file_name is None: file_name = flash_path.replace('/', '.') + '.' + stim_format file_path = os.path.join(work_dir, file_name) flash_config.set("content/stimuli/format", stim_format) flash_config.set("content/stimuli/file", file_path)
def gen_stimuli(self): traces.info('Building stimuli') # Generate the flash image for every flash self.gen_flash_images()
def __dumpSegment(self): traces.info("Generating boot loader data") for area in self.segments: self.__append(area.data, padToOffset = area.offset)
def __dumpHeader(self): traces.info("Generating boot loader header:") traces.info(" Nb areas: %d, entry point 0x%X" % (len(self.segments), self.entry)) # First compute areas flash information flashOffset = 0 if os.environ.get('TARGET_CHIP') == 'GAP9_V2': # flash_header_t is 13*int + 1024 bytes AC, 128 for KC if os.environ.get('GAP9_OLD_ROM') is not None: flashOffset += 4*16 + 16 * 4 * len(self.segments) else: flashOffset += 4*13 + 1024 + 128*2 + 16 * 4 * len(self.segments) else: flashOffset += 4 + 4 + 4 + 4 + 16 * 4 * len(self.segments) crcOffset = flashOffset flashOffset += 4 flashOffset = align(flashOffset, self.blockSize) if self.encrypt: for segment in self.segments: segment.size += 4 xip_flash_base = 0 xip_flash_size = 0 xip_page_size_cmd = 0 # Page size: 0=512B, 1=1KiB, 2=2KiB, ..., 7 = 64KiB xip_page_size = 512 << xip_page_size_cmd index = 0 for segment in self.segments: if segment.base >= 0x20000000: flashOffset = (flashOffset + xip_page_size - 1) & ~(xip_page_size - 1) xip_flash_base = flashOffset xip_flash_size = segment.size segment.nbBlocks = int((segment.size + self.blockSize - 1) / self.blockSize) segment.offset = flashOffset flashOffset += segment.nbBlocks * self.blockSize traces.info(" Area %d: offset: 0x%x, base: 0x%x, size: 0x%x, nbBlocks: %d" % ( index, segment.offset, segment.base, segment.size, segment.nbBlocks)) index += 1 flashOffset = align(flashOffset, 8) self.partitionTableOffset = flashOffset # Then write the header containing memory areas declaration header = BlockBuffer(blockSize = self.blockSize) header.appendInt(self.partitionTableOffset) header.appendInt(len(self.segments)) header.appendInt(self.entry) # Legacy bootAddr ROM field, it is no longer used header.appendInt(0x1c000000) xip_dev = self.xip_dev xip_vaddr = 0x20000000 xip_l2_addr = 0x1c190000 - 16*xip_page_size xip_l2_nb_pages = 16 flash_nb_pages = int((xip_flash_size + xip_page_size-1) / xip_page_size) if os.environ.get('TARGET_CHIP') == 'GAP9_V2': # XIP config header.appendInt(xip_dev) # Device header.appendInt(xip_vaddr) # Virtual address header.appendInt(xip_page_size_cmd) # Page size: 1=1Kbyte header.appendInt(xip_flash_base) # Flash base header.appendInt(flash_nb_pages) # Flash nb pages header.appendInt(xip_l2_addr) # L2 address header.appendInt(xip_l2_nb_pages) # L2 nb pages header.appendInt(0) # kc_length header.appendInt(0) # key_length if os.environ.get('GAP9_OLD_ROM') is not None: header.appendInt(0) # secure boot header.appendInt(0) # for now else: for i in range(1024): header.appendByte(0) # AC for i in range(256): header.appendByte(0) # KC * 2 for area in self.segments: header.appendInt(area.offset) header.appendInt(area.base) header.appendInt(area.size) header.appendInt(area.nbBlocks) header.padToOffset(crcOffset) crc = self.get_crc(header) header.appendInt(crc) self.__append(header)