Squash commits for public release
This commit is contained in:
39
utils/compilers/DevTreeCompiler/ABI/Structs.py
Normal file
39
utils/compilers/DevTreeCompiler/ABI/Structs.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from construct import *
|
||||
|
||||
DEVTREE_HEADER_SIGNATURE = "odtr3"
|
||||
|
||||
DEVTREE_HEADER = Struct(
|
||||
"signature" / PaddedString(8, "ascii"),
|
||||
"revision" / Int32ul,
|
||||
"flags" / Int32ul,
|
||||
"entries_count" / Int32ul,
|
||||
"name_list_offset" / Int32ul
|
||||
)
|
||||
|
||||
DEVTREE_ENTRY_FLAGS_MMIO = (1 << 0)
|
||||
DEVTREE_ENTRY_TYPE_IO = 0
|
||||
DEVTREE_ENTRY_TYPE_FB = 1
|
||||
DEVTREE_ENTRY_TYPE_UART = 2
|
||||
DEVTREE_ENTRY_TYPE_RAM = 3
|
||||
DEVTREE_ENTRY_TYPE_STORAGE = 4
|
||||
DEVTREE_ENTRY_TYPE_BUS_CONTROLLER = 5
|
||||
DEVTREE_ENTRY_TYPE_RTC = 6
|
||||
|
||||
# Currently flags maps to irq_flags_t in the kernel.
|
||||
# Later we might need to enhance irq_flags_from_devtree() to use as translator.
|
||||
DEVTREE_IRQ_FLAGS_EDGE_TRIGGER = (1 << 0)
|
||||
|
||||
DEVTREE_ENTRY = Struct(
|
||||
"type" / Int32ul,
|
||||
"flags" / Int32ul,
|
||||
"region_base" / Int64ul,
|
||||
"region_size" / Int64ul,
|
||||
"irq_lane" / Int32ul,
|
||||
"irq_flags" / Int32ul,
|
||||
"irq_priority" / Int32ul,
|
||||
"rel_name_offset" / Int32ul,
|
||||
"aux1" / Int64ul,
|
||||
"aux2" / Int64ul,
|
||||
"aux3" / Int64ul,
|
||||
"aux4" / Int64ul,
|
||||
)
|
||||
47
utils/compilers/DevTreeCompiler/ABI/Translation.py
Normal file
47
utils/compilers/DevTreeCompiler/ABI/Translation.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from ABI.Structs import *
|
||||
|
||||
|
||||
class Translator():
|
||||
|
||||
@staticmethod
|
||||
def entry_flag_translator(s):
|
||||
translation = {
|
||||
"MMIO": DEVTREE_ENTRY_FLAGS_MMIO,
|
||||
}
|
||||
return translation.get(s, 0)
|
||||
|
||||
@staticmethod
|
||||
def irq_flag_translator(s):
|
||||
translation = {
|
||||
"EDGE_TRIGGER": DEVTREE_IRQ_FLAGS_EDGE_TRIGGER,
|
||||
}
|
||||
return translation.get(s, 0)
|
||||
|
||||
@staticmethod
|
||||
def entry_type(s):
|
||||
translation = {
|
||||
"IO": DEVTREE_ENTRY_TYPE_IO,
|
||||
"FB": DEVTREE_ENTRY_TYPE_FB,
|
||||
"UART": DEVTREE_ENTRY_TYPE_UART,
|
||||
"RAM": DEVTREE_ENTRY_TYPE_RAM,
|
||||
"STORAGE": DEVTREE_ENTRY_TYPE_STORAGE,
|
||||
"BUS_CONTROLLER": DEVTREE_ENTRY_TYPE_BUS_CONTROLLER,
|
||||
"RTC": DEVTREE_ENTRY_TYPE_RTC
|
||||
}
|
||||
return translation.get(s, DEVTREE_ENTRY_TYPE_IO)
|
||||
|
||||
@staticmethod
|
||||
def number(s):
|
||||
return int(s, base=0)
|
||||
|
||||
@staticmethod
|
||||
def flags(s, flagcb):
|
||||
flags = 0x0
|
||||
ents = s.split(" ")
|
||||
|
||||
for ent in ents:
|
||||
t = flagcb(s)
|
||||
if t != None:
|
||||
flags |= t
|
||||
|
||||
return flags
|
||||
24
utils/compilers/DevTreeCompiler/DevTreeCompiler.py
Normal file
24
utils/compilers/DevTreeCompiler/DevTreeCompiler.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from Parser.Parser import Parser
|
||||
from Generator.IRManager import IRManager
|
||||
from Generator.BinWriter import BinWriter
|
||||
from Generator.CWriter import CWriter
|
||||
from Generator.Compiler import Compiler
|
||||
import argparse
|
||||
|
||||
class DevTreeCompiler():
|
||||
|
||||
@staticmethod
|
||||
def compile(input_f, output_f):
|
||||
parser = Parser(input_f)
|
||||
irmng = IRManager(parser)
|
||||
compiler = Compiler(irmng)
|
||||
binw = BinWriter(output_f)
|
||||
binw.write(compiler.compile())
|
||||
|
||||
@staticmethod
|
||||
def to_c_arr(input_f):
|
||||
parser = Parser(input_f)
|
||||
irmng = IRManager(parser)
|
||||
compiler = Compiler(irmng)
|
||||
binw = CWriter()
|
||||
binw.write(compiler.compile())
|
||||
8
utils/compilers/DevTreeCompiler/Generator/BinWriter.py
Normal file
8
utils/compilers/DevTreeCompiler/Generator/BinWriter.py
Normal file
@@ -0,0 +1,8 @@
|
||||
class BinWriter():
|
||||
def __init__(self, output_file):
|
||||
self.output_file = output_file
|
||||
|
||||
def write(self, data):
|
||||
binfile = open(self.output_file, "wb")
|
||||
binfile.write(bytes(data))
|
||||
binfile.close()
|
||||
9
utils/compilers/DevTreeCompiler/Generator/CWriter.py
Normal file
9
utils/compilers/DevTreeCompiler/Generator/CWriter.py
Normal file
@@ -0,0 +1,9 @@
|
||||
class CWriter():
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def write(self, data):
|
||||
print("static uint8_t _devtree_raw[] = {")
|
||||
for byte in bytearray(data):
|
||||
print(hex(byte), end = ",")
|
||||
print("0x0};")
|
||||
110
utils/compilers/DevTreeCompiler/Generator/Compiler.py
Normal file
110
utils/compilers/DevTreeCompiler/Generator/Compiler.py
Normal file
@@ -0,0 +1,110 @@
|
||||
from Generator.IRManager import IRManager
|
||||
from ABI.Structs import *
|
||||
from ABI.Translation import *
|
||||
|
||||
|
||||
class Compiler():
|
||||
__debug = False
|
||||
|
||||
def __init__(self, irmng):
|
||||
self.irmng = irmng
|
||||
|
||||
self.res_binarr = bytearray()
|
||||
self.header_binarr = bytearray()
|
||||
self.devs_binarr = bytearray()
|
||||
self.names_binarr = bytearray()
|
||||
|
||||
def build_header(self):
|
||||
count_of_devs = len(self.irmng.device_list())
|
||||
|
||||
result = {
|
||||
"signature": DEVTREE_HEADER_SIGNATURE,
|
||||
"revision": 1,
|
||||
"flags": 0,
|
||||
"entries_count": count_of_devs,
|
||||
"name_list_offset": DEVTREE_HEADER.sizeof() + len(self.devs_binarr),
|
||||
}
|
||||
|
||||
self.header_binarr = DEVTREE_HEADER.build(result)
|
||||
|
||||
def build_dev(self, dev):
|
||||
result = {
|
||||
"type": 0,
|
||||
"flags": 0,
|
||||
"region_base": 0,
|
||||
"region_size": 0,
|
||||
"irq_lane": 0,
|
||||
"irq_flags": 0,
|
||||
"irq_priority": 0,
|
||||
"rel_name_offset": len(self.names_binarr),
|
||||
"aux1": 0,
|
||||
"aux2": 0,
|
||||
"aux3": 0,
|
||||
"aux4": 0,
|
||||
}
|
||||
|
||||
if "type" in dev:
|
||||
result["type"] = Translator.entry_type(dev["type"])
|
||||
|
||||
if "flags" in dev:
|
||||
result["flags"] = Translator.flags(
|
||||
dev["flags"], Translator.entry_flag_translator)
|
||||
|
||||
if "mem" in dev:
|
||||
devmem = dev["mem"]
|
||||
if "base" in devmem:
|
||||
result["region_base"] = Translator.number(devmem["base"])
|
||||
if "size" in devmem:
|
||||
result["region_size"] = Translator.number(devmem["size"])
|
||||
|
||||
if "irq" in dev:
|
||||
devint = dev["irq"]
|
||||
if "lane" in devint:
|
||||
result["irq_lane"] = Translator.number(devint["lane"])
|
||||
if "flags" in devint:
|
||||
result["irq_flags"] = Translator.flags(
|
||||
devint["flags"], Translator.irq_flag_translator)
|
||||
if "priority" in devint:
|
||||
result["irq_priority"] = Translator.number(devint["priority"])
|
||||
|
||||
if "aux1" in dev:
|
||||
result["aux1"] = Translator.number(dev["aux1"])
|
||||
if "aux2" in dev:
|
||||
result["aux2"] = Translator.number(dev["aux2"])
|
||||
if "aux3" in dev:
|
||||
result["aux3"] = Translator.number(dev["aux3"])
|
||||
if "aux4" in dev:
|
||||
result["aux4"] = Translator.number(dev["aux4"])
|
||||
|
||||
self.devs_binarr += DEVTREE_ENTRY.build(result)
|
||||
self.names_binarr += bytearray((map(ord,
|
||||
dev["name"]))) + bytearray([0])
|
||||
|
||||
def build_dev_list(self):
|
||||
self.devs_binarr = bytearray()
|
||||
self.names_binarr = bytearray()
|
||||
for dev in self.irmng.device_list():
|
||||
self.build_dev(dev)
|
||||
|
||||
def build_binarr(self):
|
||||
self.res_binarr = bytearray()
|
||||
self.header_binarr = bytearray()
|
||||
self.devs_binarr = bytearray()
|
||||
self.names_binarr = bytearray()
|
||||
|
||||
self.build_dev_list()
|
||||
self.build_header()
|
||||
|
||||
self.res_binarr = self.header_binarr + self.devs_binarr + self.names_binarr
|
||||
|
||||
if self.__debug:
|
||||
print("Header", self.header_binarr)
|
||||
print("Devs", self.devs_binarr)
|
||||
print("Names", self.names_binarr)
|
||||
print("Res", self.res_binarr)
|
||||
|
||||
def compile(self):
|
||||
if len(self.res_binarr) == 0:
|
||||
self.build_binarr()
|
||||
|
||||
return self.res_binarr
|
||||
12
utils/compilers/DevTreeCompiler/Generator/IRManager.py
Normal file
12
utils/compilers/DevTreeCompiler/Generator/IRManager.py
Normal file
@@ -0,0 +1,12 @@
|
||||
class IRManager():
|
||||
def __init__(self, parser):
|
||||
self.parser = parser
|
||||
|
||||
def platform_name(self):
|
||||
return self.parser.data()["name"]
|
||||
|
||||
def device_count(self):
|
||||
return len(self.parser.data()["devices"])
|
||||
|
||||
def device_list(self):
|
||||
return self.parser.data()["devices"]
|
||||
20
utils/compilers/DevTreeCompiler/Parser/Parser.py
Normal file
20
utils/compilers/DevTreeCompiler/Parser/Parser.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import json
|
||||
|
||||
class Parser():
|
||||
def __init__(self, input_file):
|
||||
self.decoded_data = None
|
||||
self.input_file = input_file
|
||||
|
||||
def data(self):
|
||||
if self.decoded_data is None:
|
||||
f = open(self.input_file)
|
||||
self.decoded_data = json.load(f)
|
||||
f.close()
|
||||
|
||||
return self.decoded_data
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
18
utils/compilers/DevTreeCompiler/__main__.py
Normal file
18
utils/compilers/DevTreeCompiler/__main__.py
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from DevTreeCompiler import DevTreeCompiler
|
||||
import argparse
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('i', type=str, help='Input file')
|
||||
parser.add_argument('o', type=str, help='Output file')
|
||||
parser.add_argument('--dumpc', action='store_true',
|
||||
help='Dumping C array')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.dumpc:
|
||||
DevTreeCompiler.to_c_arr(args.i)
|
||||
else:
|
||||
DevTreeCompiler.compile(args.i, args.o)
|
||||
Reference in New Issue
Block a user