mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-06 07:04:54 +00:00
dfu: Add ChipID quirks for various XMEGA parts
This also adds an *almost* throw-away python script to import the chip-ids from the default conf file from the avrdude project. I've imported it here in case we have to start caring about different page sizes or application offsets.
This commit is contained in:
parent
8517464eac
commit
21852821c5
178
plugins/dfu/contrib/parse-avrdude-conf.py
Executable file
178
plugins/dfu/contrib/parse-avrdude-conf.py
Executable file
@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env python3
|
||||
""" This parses avrdude.conf and generates quirks for fwupd """
|
||||
|
||||
# pylint: disable=wrong-import-position,pointless-string-statement
|
||||
|
||||
"""
|
||||
Licensed under the GNU General Public License Version 2
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
from difflib import SequenceMatcher
|
||||
|
||||
# finds a part using the ID
|
||||
def _find_part_by_id(parts, part_id):
|
||||
for part in parts:
|
||||
if 'id' not in part:
|
||||
continue
|
||||
if part['id'] == part_id:
|
||||
return part
|
||||
return None
|
||||
|
||||
# finds a memory layout for a part, climbing up the tree to the parent if reqd.
|
||||
def _find_mem_layout(parts, part):
|
||||
if 'memory-application' in part:
|
||||
memory_flash = part['memory-application']
|
||||
if memory_flash:
|
||||
return memory_flash
|
||||
|
||||
#look at the parent
|
||||
if 'parent' in part:
|
||||
parent = _find_part_by_id(parts, part['parent'])
|
||||
if parent:
|
||||
return _find_mem_layout(parts, parent)
|
||||
print('no parent ', part['parent'], 'found for', part['id'])
|
||||
return None
|
||||
|
||||
# parses the weird syntax of avrdude.conf and makes lots of nested dictionaries
|
||||
def _parse_parts(fn_source):
|
||||
print("reading", fn_source)
|
||||
|
||||
part = None
|
||||
memory_id = None
|
||||
parts = []
|
||||
|
||||
for line in open(fn_source).readlines():
|
||||
|
||||
# try to clean up crazy syntax
|
||||
line = line.replace('\n', '')
|
||||
if line.endswith(';'):
|
||||
line = line[:-1]
|
||||
|
||||
# ignore blank lines
|
||||
line = line.rstrip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
# count how many spaces deep this is
|
||||
lvl = 0
|
||||
for char in line:
|
||||
if char != ' ':
|
||||
break
|
||||
lvl = lvl + 1
|
||||
|
||||
# ignore comments
|
||||
line = line.strip()
|
||||
if line[0] == '#':
|
||||
continue
|
||||
|
||||
# level 0 of hell
|
||||
if lvl == 0:
|
||||
if line.startswith('part'):
|
||||
memory_id = None
|
||||
part = {}
|
||||
parts.append(part)
|
||||
if line.startswith('part parent '):
|
||||
part['parent'] = line[13:].replace('"', '')
|
||||
continue
|
||||
|
||||
# level 4 of hell
|
||||
if lvl == 4:
|
||||
if line.startswith('memory'):
|
||||
memory_id = 'memory-' + line[7:].replace('"', '')
|
||||
part[memory_id] = {}
|
||||
continue
|
||||
split = line.split('=')
|
||||
if len(split) != 2:
|
||||
print('ignoring', line)
|
||||
continue
|
||||
part[split[0].strip()] = split[1].strip().replace('"', '')
|
||||
continue
|
||||
|
||||
# level 8 of hell
|
||||
if lvl == 8:
|
||||
if memory_id:
|
||||
split = line.split('=')
|
||||
if len(split) != 2:
|
||||
continue
|
||||
memory = part[memory_id]
|
||||
memory[split[0].strip()] = split[1].strip()
|
||||
continue
|
||||
return parts
|
||||
|
||||
def _get_longest_substring(s1, s2):
|
||||
match = SequenceMatcher(None, s1, s2).find_longest_match(0, len(s1), 0, len(s2))
|
||||
return s2[match.b: match.b + match.size]
|
||||
|
||||
# writes important data to the quirks file
|
||||
def _write_quirks(parts, fn_destination):
|
||||
outp = []
|
||||
|
||||
results = {}
|
||||
|
||||
for part in parts:
|
||||
|
||||
# ignore meta parts with deprecated names
|
||||
if 'desc' not in part:
|
||||
continue
|
||||
if 'signature' not in part:
|
||||
continue
|
||||
|
||||
# find the layout
|
||||
mem_part = _find_mem_layout(parts, part)
|
||||
if not mem_part:
|
||||
print("no memory layout for", part['desc'])
|
||||
continue
|
||||
if not 'size' in mem_part:
|
||||
print("no memory size for", part['desc'])
|
||||
continue
|
||||
if mem_part['size'].startswith('0x'):
|
||||
size = int(mem_part['size'], 16)
|
||||
else:
|
||||
size = int(mem_part['size'], 10)
|
||||
|
||||
# output the line for the quirk
|
||||
chip_id = '0x' + part['signature'].replace('0x', '').replace(' ', '')
|
||||
mem_layout = '@Flash/0x0/1*%.0iKg' % int(size / 1024)
|
||||
|
||||
# merge duplicate quirks
|
||||
if chip_id in results:
|
||||
result = results[chip_id]
|
||||
result['desc'] = _get_longest_substring(result['desc'], part['desc'])
|
||||
else:
|
||||
result = {}
|
||||
result['desc'] = part['desc']
|
||||
result['size'] = size
|
||||
result['mem_layout'] = mem_layout
|
||||
results[chip_id] = result
|
||||
|
||||
for chip_id in results:
|
||||
result = results[chip_id]
|
||||
outp.append('# ' + result['desc'] + ' size:0x%x' % result['size'] + '\n')
|
||||
outp.append(chip_id + '=' + result['mem_layout'] + '\n\n')
|
||||
|
||||
# write file
|
||||
print("writing", fn_destination)
|
||||
open(fn_destination, 'w').writelines(outp)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 3:
|
||||
print("USAGE: %s avrdude.conf tmp.quirk" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
all_parts = _parse_parts(sys.argv[1])
|
||||
_write_quirks(all_parts, sys.argv[2])
|
@ -78,3 +78,111 @@ USB\VID_0B0E&PID_2456=0B0E0971
|
||||
|
||||
# AT32UC3A3 is BL @0x2000, Size: 0x40000
|
||||
0x58200204=@Flash/0x2000/1*248Kg
|
||||
|
||||
# ATxmega16A4 size:0x4000
|
||||
0x1e9441=@Flash/0x0/1*16Kg
|
||||
|
||||
# ATxmega16C4 size:0x4000
|
||||
0x1e9544=@Flash/0x0/1*16Kg
|
||||
|
||||
# ATxmega16D4 size:0x4000
|
||||
0x1e9442=@Flash/0x0/1*16Kg
|
||||
|
||||
# ATxmega32A4 size:0x8000
|
||||
0x1e9541=@Flash/0x0/1*32Kg
|
||||
|
||||
# ATxmega32C4 size:0x8000
|
||||
0x1e9443=@Flash/0x0/1*32Kg
|
||||
|
||||
# ATxmega32D4 size:0x8000
|
||||
0x1e9542=@Flash/0x0/1*32Kg
|
||||
|
||||
# ATxmega64A4 size:0x10000
|
||||
0x1e9646=@Flash/0x0/1*64Kg
|
||||
|
||||
# ATxmega64C3 size:0x10000
|
||||
0x1e9649=@Flash/0x0/1*64Kg
|
||||
|
||||
# ATxmega64D3 size:0x10000
|
||||
0x1e964a=@Flash/0x0/1*64Kg
|
||||
|
||||
# ATxmega64D4 size:0x10000
|
||||
0x1e9647=@Flash/0x0/1*64Kg
|
||||
|
||||
# ATxmega64A1 size:0x10000
|
||||
0x1e964e=@Flash/0x0/1*64Kg
|
||||
|
||||
# ATxmega64A3 size:0x10000
|
||||
0x1e9642=@Flash/0x0/1*64Kg
|
||||
|
||||
# ATxmega64B1 size:0x10000
|
||||
0x1e9652=@Flash/0x0/1*64Kg
|
||||
|
||||
# ATxmega64B3 size:0x10000
|
||||
0x1e9651=@Flash/0x0/1*64Kg
|
||||
|
||||
# ATxmega128C3 size:0x20000
|
||||
0x1e9752=@Flash/0x0/1*128Kg
|
||||
|
||||
# ATxmega128D3 size:0x20000
|
||||
0x1e9748=@Flash/0x0/1*128Kg
|
||||
|
||||
# ATxmega128D4 size:0x20000
|
||||
0x1e9747=@Flash/0x0/1*128Kg
|
||||
|
||||
# ATxmega128A1 size:0x20000
|
||||
0x1e974c=@Flash/0x0/1*128Kg
|
||||
|
||||
# ATxmega128A1revD size:0x20000
|
||||
0x1e9741=@Flash/0x0/1*128Kg
|
||||
|
||||
# ATxmega128A3 size:0x20000
|
||||
0x1e9742=@Flash/0x0/1*128Kg
|
||||
|
||||
# ATxmega128A4 size:0x20000
|
||||
0x1e9746=@Flash/0x0/1*128Kg
|
||||
|
||||
# ATxmega128B1 size:0x20000
|
||||
0x1e974d=@Flash/0x0/1*128Kg
|
||||
|
||||
# ATxmega128B3 size:0x20000
|
||||
0x1e974b=@Flash/0x0/1*128Kg
|
||||
|
||||
# ATxmega192C3 size:0x30000
|
||||
0x1e9751=@Flash/0x0/1*192Kg
|
||||
|
||||
# ATxmega192D3 size:0x30000
|
||||
0x1e9749=@Flash/0x0/1*192Kg
|
||||
|
||||
# ATxmega192A1 size:0x30000
|
||||
0x1e974e=@Flash/0x0/1*192Kg
|
||||
|
||||
# ATxmega192A3 size:0x30000
|
||||
0x1e9744=@Flash/0x0/1*192Kg
|
||||
|
||||
# ATxmega256 size:0x40000
|
||||
0x1e9846=@Flash/0x0/1*256Kg
|
||||
|
||||
# ATxmega256D3 size:0x40000
|
||||
0x1e9844=@Flash/0x0/1*256Kg
|
||||
|
||||
# ATxmega256A3 size:0x40000
|
||||
0x1e9842=@Flash/0x0/1*256Kg
|
||||
|
||||
# ATxmega256A3B size:0x40000
|
||||
0x1e9843=@Flash/0x0/1*256Kg
|
||||
|
||||
# ATxmega384C3 size:0x60000
|
||||
0x1e9845=@Flash/0x0/1*384Kg
|
||||
|
||||
# ATxmega384D3 size:0x60000
|
||||
0x1e9847=@Flash/0x0/1*384Kg
|
||||
|
||||
# ATxmega8E5 size:0x2000
|
||||
0x1e9341=@Flash/0x0/1*8Kg
|
||||
|
||||
# ATxmega16E5 size:0x4000
|
||||
0x1e9445=@Flash/0x0/1*16Kg
|
||||
|
||||
# ATxmega32E5 size:0x8000
|
||||
0x1e954c=@Flash/0x0/1*32Kg
|
||||
|
Loading…
Reference in New Issue
Block a user