def setUp(self): super(TestRedirectionToDeclaration, self).setUp() name = type(self).__name__ private_h = Header("private.h") private_h.add_type(Structure("Private")) public_h = Header("public.h") public_h.add_types([ Type["Private"].gen_forward_declaration(), Function("public_func") ]) private_c = Source("private.c") public_func_impl = Type["public_func"].gen_definition() private_c.add_type(public_func_impl) src = Source(name.lower() + ".c").add_global_variable( # It must internally re-direct pointer from type "Private" # to "Private.declaration", its forward declaration. Pointer(Type["Private"])("handler")) src.add_type(Pointer(public_func_impl, name="cb_ptr")) src_content = """\ /* %s */ #include "public.h" typedef void (*cb_ptr)(void); Private *handler __attribute__((unused)); """ % (name.lower() + ".c") self.files = [(src, src_content)]
def setUp(self): super(TestLabelAndGotoGeneration, self).setUp() name = type(self).__name__ src = Source(name.lower() + ".c") lbl = Label("begin") i = Type["int"]("i") src.add_type( Function(name="main", body=BodyTree()(Declare(i), lbl, OpAssign(i, OpAdd(i, 1)), Goto(lbl)))) src_content = """\ /* {} */ void main(void) {{ int i; begin: i = i + 1; goto begin; }} """.format(src.path) self.files = [(src, src_content)]
def setUp(self): super(TestSeparateCases, self).setUp() src = Source(type(self).__name__.lower() + ".c") i = Type["int"]("i") src.add_type( Function(name="func_a", body=BodyTree()(Declare(OpDeclareAssign(i, 0)), BranchSwitch(i, separate_cases=True)( SwitchCase(1), SwitchCase(2))))) src_content = """\ /* {} */ void func_a(void) {{ int i = 0; switch (i) {{ case 1: break; case 2: break; default: break; }} }} """.format(src.path) self.files = [(src, src_content)]
def setUp(self): super(TestOptimizeInclusions, self).setUp() name = type(self).__name__ src = Source(name.lower() + ".c") ah = Header("a.h") bh = Header("b.h") ch = Header("c.h") ah.add_type(Type("a")) bh.add_type(Type("b")).add_reference(Type["a"]) ch.add_type(Type("c")).add_reference(Type["b"]).add_inclusion(ah) src.add_type(Pointer(Type["c"], "cpointer")) # c.h includes a.h but inclusion of a.h cannot be substituted with c.h # inclusion because it creating reference loop between inclusions of # c.h and b.h. This test checks inclusions optimization correctness and # ordering of chunks. src_content = """\ /* {} */ #include "a.h" #include "b.h" #include "c.h" typedef c *cpointer; """.format(src.path) self.files = [(src, src_content)]
def setUp(self): super(TestForwardDeclarationHeader, self).setUp() name = type(self).__name__ hdr = Header(name.lower() + ".h") src = Source(name.lower() + ".c") a = Structure("A") a.append_field(Pointer(a)("next")) b = Structure("B") b.append_field(Pointer(a)("next")) hdr.add_type(a) hdr_content = """\ /* {path} */ #ifndef INCLUDE_{fname_upper}_H #define INCLUDE_{fname_upper}_H typedef struct A A; struct A {{ A *next; }}; #endif /* INCLUDE_{fname_upper}_H */ """.format(path=hdr.path, fname_upper=name.upper()) src.add_type(b) src_content = """\ /* {} */ #include "{}" typedef struct B {{ A *next; }} B; """.format(src.path, hdr.path) self.files = [(hdr, hdr_content), (src, src_content)]
class QOMDevice(QOMType): __attribute_info__ = OrderedDict([("directory", { "short": _("Directory"), "input": str }), ("block_num", { "short": _("Block driver quantity"), "input": int }), ("char_num", { "short": _("Character driver quantity"), "input": int }), ("timer_num", { "short": _("Timer quantity"), "input": int })]) def __init__(self, name, directory, nic_num=0, timer_num=0, char_num=0, block_num=0, **qom_kw): super(QOMDevice, self).__init__(name, **qom_kw) self.directory = directory self.nic_num = nic_num self.timer_num = timer_num self.char_num = char_num self.block_num = block_num # Define header file header_path = join("hw", directory, self.qtn.for_header_name + ".h") try: self.header = Header.lookup(header_path) except Exception: self.header = Header(header_path) # Define source file source_path = join("hw", directory, self.qtn.for_header_name + ".c") self.source = Source(source_path) def gen_source(self): pass # Block driver def block_name(self, index): if self.block_num == 1: return "blk" else: return "blk_%u" % index def block_prop_name(self, index): pfx = self.qtn.for_macros + "_" if self.block_num == 1: return pfx + "DRIVE" else: return pfx + "DRIVE_%u" % index def block_declare_fields(self): for index in range(self.block_num): f = QOMStateField(Pointer(Type.lookup("BlockBackend")), self.block_name(index), save=False, prop=True) self.add_state_field(f) # override macro name assigned by `add_state_field` f.prop_macro_name = self.block_prop_name(index) # Character driver def char_name(self, index): if self.char_num == 1: return "chr" else: return "chr_%u" % index def char_can_read_name(self, index): return self.qtn.for_id_name + "_" + self.char_name(index) + "_can_read" def char_read_name(self, index): return self.qtn.for_id_name + "_" + self.char_name(index) + "_read" def char_event_name(self, index): return self.qtn.for_id_name + "_" + self.char_name(index) + "_event" def char_declare_fields(self): field_type = (Type.lookup("CharBackend") if get_vp()["v2.8 chardev"] else Pointer(Type.lookup("CharDriverState"))) for index in range(self.char_num): self.add_state_field( QOMStateField(field_type, self.char_name(index), save=False, prop=True)) def char_gen_cb(self, proto_name, handler_name, index, source, state_struct, type_cast_macro): proto = Type.lookup(proto_name) cb = proto.use_as_prototype(handler_name, body = """\ __attribute__((unused))@b%s@b*s@b=@s%s(opaque);%s """ % ( state_struct.name, self.type_cast_macro.name, "\n\n return 0;" \ if proto.ret_type not in [ None, Type.lookup("void") ] else "", ), static = True, used_types = set([state_struct, type_cast_macro]) ) source.add_type(cb) return cb def char_gen_handlers(self, index, source, state_struct, type_cast_macro): ret = [ self.char_gen_cb(proto_name, handler_name, index, source, state_struct, type_cast_macro) for proto_name, handler_name in [( "IOCanReadHandler", self.char_can_read_name(index) ), ("IOReadHandler", self.char_read_name(index) ), ("IOEventHandler", self.char_event_name(index))] ] # Define handler relative order: can read, read, event line_origins(ret) return ret # TIMERS def timer_name(self, index): if self.timer_num == 1: return "timer" else: return "timer_%u" % index def timer_cb_name(self, index): return self.qtn.for_id_name + "_" + self.timer_name(index) + "_cb" def timer_declare_fields(self): for index in range(self.timer_num): self.add_state_field( QOMStateField(Pointer(Type.lookup("QEMUTimer")), self.timer_name(index), save=True)) def timer_gen_cb(self, index, source, state_struct, type_cast_macro): timer_cb = Function( self.timer_cb_name(index), body="""\ __attribute__((unused))@b%s@b*s@b=@s%s(opaque); """ % (state_struct.name, self.type_cast_macro.name), args=[Type.lookup("void").gen_var("opaque", pointer=True)], static=True, used_types=set([state_struct, type_cast_macro])) source.add_type(timer_cb) return timer_cb # 'realize' method generation def gen_realize(self, dev_type_name, code="", s_is_used=False, used_types=[], used_globals=[]): total_used_types = set([self.state_struct, self.type_cast_macro]) total_used_types.update(used_types) total_used_globals = list(used_globals) if self.char_num > 0: if get_vp()["v2.8 chardev"]: helper_name = "qemu_chr_fe_set_handlers" char_name_fmt = "&s->%s" extra_args = ",@sNULL,@strue" else: helper_name = "qemu_chr_add_handlers" char_name_fmt = "s->%s" extra_args = "" total_used_types.add(Type.lookup(helper_name)) code += "\n" s_is_used = True for chrN in range(self.char_num): chr_name = self.char_name(chrN) har_handlers = self.char_gen_handlers(chrN, self.source, self.state_struct, self.type_cast_macro) code += """\ if@b({chr_name})@b{{ {helper_name}(@a{chr_name},@s{helpers},@ss{extra_args}); }} """.format(helper_name=helper_name, chr_name=char_name_fmt % chr_name, helpers=",@s".join([h.name for h in har_handlers]), extra_args=extra_args) total_used_types.update(har_handlers) if self.block_num > 0: code += "\n" s_is_used = True # actually not, but user probably needed functions from same header total_used_types.add(Type.lookup("BlockDevOps")) for blkN in range(self.block_num): blk_name = self.block_name(blkN) code += """\ if@b(s->%s)@b{ /*@sTODO:@sImplement@sinteraction@swith@sblock@sdriver.@c@s*/ } """ % (blk_name) if self.nic_num > 0: code += "\n" s_is_used = True def_mac = Type.lookup("qemu_macaddr_default_if_unset") fmt_info = Type.lookup("qemu_format_nic_info_str") obj_tn = Type.lookup("object_get_typename") obj_cast = Type.lookup("OBJECT") def_cast = Type.lookup("DEVICE") new_nic = Type.lookup("qemu_new_nic") get_queue = Type.lookup("qemu_get_queue") total_used_types.update([ def_mac, fmt_info, obj_tn, obj_cast, def_cast, new_nic, get_queue ]) for nicN in range(self.nic_num): conf_name = self.nic_conf_name(nicN) nic_name = self.nic_name(nicN) info = self.gen_net_client_info(nicN) self.source.add_global_variable(info) total_used_globals.append(info) code += """\ {def_mac}(&s->{conf_name}.macaddr); s->{nic_name}@b=@s{new_nic}(@a&{info},@s&s->{conf_name},@s{obj_tn}\ ({obj_cast}(s)),@s{def_cast}(s)->id,@ss); {fmt_info}(@a{get_queue}(s->{nic_name}),@ss->{conf_name}.macaddr.a); """.format(def_mac=def_mac.name, conf_name=conf_name, nic_name=nic_name, new_nic=new_nic.name, info=info.name, obj_tn=obj_tn.name, obj_cast=obj_cast.name, def_cast=def_cast.name, fmt_info=fmt_info.name, get_queue=get_queue.name) fn = Function(name="%s_realize" % self.qtn.for_id_name, body="""\ {unused}{Struct}@b*s@b=@s{UPPER}(dev); {extra_code}\ """.format(unused="" if s_is_used else "__attribute__((unused))@b", Struct=self.state_struct.name, UPPER=self.type_cast_macro.name, extra_code=code), args=[ Type.lookup(dev_type_name).gen_var("dev", pointer=True), Pointer(Type.lookup("Error")).gen_var("errp", pointer=True) ], static=True, used_types=total_used_types, used_globals=total_used_globals) return fn # NICs def nic_name(self, index): if self.nic_num == 1: return "nic" else: return "nic_%u" % index def nic_conf_name(self, index): return self.nic_name(index) + "_conf" def net_client_info_name(self, index): return self.qtn.for_id_name + "_" + self.nic_name(index) + "_info" def nic_helper_name(self, helper, index): return "%s_%s_%s" % (self.qtn.for_id_name, self.nic_name(index), helper) def nic_declare_field(self, index): self.add_state_field( QOMStateField(Pointer(Type.lookup("NICState")), self.nic_name(index), save=False)) f = QOMStateField(Type.lookup("NICConf"), self.nic_conf_name(index), save=False, prop=True) self.add_state_field(f) # NIC properties have standard names f.prop_macro_name = None def nic_declare_fields(self): for i in range(self.nic_num): self.nic_declare_field(i) def gen_nic_helper(self, helper, cbtn, index): cbt = Type.lookup(cbtn) return cbt.use_as_prototype( self.nic_helper_name(helper, index), body=" return 0;\n" if cbt.ret_type.name != "void" else "", static=True, used_types=[Type.lookup(self.struct_name)]) def gen_net_client_info(self, index): helpers = [] code = {} for helper_name, cbtn in [("link_status_changed", "LinkStatusChanged"), ("can_receive", "NetCanReceive"), ("receive", "NetReceive"), ("cleanup", "NetCleanup")]: helper = self.gen_nic_helper(helper_name, cbtn, index) self.source.add_type(helper) helpers.append(helper) code[helper_name] = helper # Define relative order of helpers: link, can recv, recv, cleanup line_origins(helpers) code["type"] = Type.lookup("NET_CLIENT_DRIVER_NIC") types = set([Type.lookup("NICState")] + list(code.values())) code["size"] = "sizeof(NICState)" init = Initializer(code, used_types=types) return Type.lookup("NetClientInfo").gen_var( self.net_client_info_name(index), initializer=init, static=True)
class MachineType(QOMType): __attribute_info__ = OrderedDict([("directory", { "short": _("Directory"), "input": str })]) def __init__(self, name, directory, devices=[], buses=[], irqs=[], mems=[], irq_hubs=[]): super(MachineType, self).__init__(name) self.desc = "TODO: provide description for " + name self.devices = devices self.buses = buses self.irqs = irqs self.mems = mems self.irq_hubs = irq_hubs # source file model self.source_path = join_path("hw", directory, self.qtn.for_header_name + ".c") def reset_generator(self): self.node_map = {} self.init_used_types = [] self.hub_layouts = {} self.provide_node_names() def use_type(self, t): if t in self.init_used_types: return self.init_used_types.append(t) def use_type_name(self, name): t = Type.lookup(name) self.use_type(t) def provide_name_for_node(self, node, base): """ Returns name of variable for given node. Does generate and remember a new name if required. """ try: return self.node_map[node] except KeyError: if base in self.node_map: name = base + "_%u" % node.id else: # do not use suffix with id for first node with such base name = base self.node_map[name] = node self.node_map[node] = name return name def provide_node_names(self): for nodes in [ self.devices, self.buses, self.irqs, self.irq_hubs, self.mems ]: for n in nodes: self.provide_name_for_node(n, n.var_base) def gen_prop_val(self, prop): if isinstance(prop.prop_val, str) and Type.exists(prop.prop_val): self.use_type_name(prop.prop_val) return prop.prop_val if prop.prop_type == QOMPropertyTypeString: return "\"%s\"" % str(prop.prop_val) elif prop.prop_type == QOMPropertyTypeBoolean: if not isinstance(prop.prop_val, (bool, ) + integer_types): raise IncorrectPropertyValue( "%s is %s, expected bool" % (prop.prop_name, type(prop.prop_val).__name__)) self.use_type_name("bool") return "true" if prop.prop_val else "false" elif prop.prop_type == QOMPropertyTypeInteger: if not isinstance(prop.prop_val, integer_types): raise IncorrectPropertyValue() return "0x%x" % prop.prop_val elif prop.prop_type == QOMPropertyTypeLink: if prop.prop_val is None: self.use_type_name("NULL") return "NULL" else: self.use_type_name("OBJECT") return "OBJECT(%s)" % self.node_map[prop.prop_val] else: raise UnknownPropertyType() def gen_irq_get(self, irq, var_name): dst = irq[0] if isinstance(dst, IRQHub): raise RuntimeError("Cannot get an IRQ from a hub (%u)." " A hub _is_ an IRQ itself." % dst.id) self.use_type_name("DEVICE") if irq[2] is None: self.use_type_name("qdev_get_gpio_in") return """\ {irq_name} = qdev_get_gpio_in(@aDEVICE({dst_name}),@s{dst_index}); """.format( irq_name=var_name, dst_name=self.node_map[dst], dst_index=irq[1], ) else: gpio_name = irq[2] try: gpio_name_type = Type.lookup(gpio_name) except TypeNotRegistered: gpio_name = '"%s"' % gpio_name else: self.use_type(gpio_name_type) irq_get = Type.lookup("qdev_get_gpio_in_named") self.use_type(irq_get) return """\ {irq_name} = {irq_get}(@aDEVICE({dst_name}),@s{gpio_name},@s{dst_index}); """.format( irq_name=var_name, irq_get=irq_get.name, dst_name=self.node_map[dst], gpio_name=gpio_name, dst_index=irq[1], ) def gen_irq_connect(self, irq, var_name): src = irq[0] if isinstance(src, IRQHub): raise RuntimeError("Cannot connect an IRQ to a hub (%u)." " A hub does use each its IRQ by itself." % src.id) if irq[2] is None: self.use_type_name("DEVICE") self.use_type_name("qdev_connect_gpio_out") return """\ qdev_connect_gpio_out(@aDEVICE({src_name}),@s{src_index},@s{irq_name}); """.format(irq_name=var_name, src_name=self.node_map[src], src_index=irq[1]) else: sysbus_name = Type.lookup("SYSBUS_DEVICE_GPIO_IRQ").text if sysbus_name == "\"%s\"" % irq[ 2] or "SYSBUS_DEVICE_GPIO_IRQ" == irq[2]: self.use_type_name("sysbus_connect_irq") self.use_type_name("SYS_BUS_DEVICE") return """\ sysbus_connect_irq(@aSYS_BUS_DEVICE({src_name}),@s{src_index},@s{irq_name}); """.format(irq_name=var_name, src_name=self.node_map[src], src_index=irq[1]) else: self.use_type_name("DEVICE") self.use_type_name("qdev_connect_gpio_out_named") if Type.exists(irq[2]): self.use_type_name(irq[2]) return """\ qdev_connect_gpio_out_named(@aDEVICE({src_name}),@s{gpio_name},@s{src_index},@s{irq_name}); """.format(irq_name=var_name, src_name=self.node_map[src], src_index=irq[1], gpio_name=irq[2] if Type.exists(irq[2]) else "\"%s\"" % irq[2]) def provide_hub_layout(self, hub): try: return self.hub_layouts[hub] except KeyError: hubl = IRQHubLayout(hub, self) self.hub_layouts[hub] = hubl return hubl def generate_source(self): glob_mem = get_vp("explicit global memory registration") self.source = Source(self.source_path) all_nodes = sort_topologically(self.devices + self.buses + self.irqs + self.mems + self.irq_hubs) decl_code = "" def_code = "" self.reset_generator() skip_nl = False for idx, node in enumerate(all_nodes): if not skip_nl: if idx > 0: def_code += "\n" else: skip_nl = False if isinstance(node, DeviceNode): self.use_type_name("qdev_init_nofail") self.use_type_name("BUS") if Type.exists(node.qom_type): self.use_type_name(node.qom_type) dev_name = self.node_map[node] props_code = "" for p in node.properties: self.use_type_name("OBJECT") self.use_type_name(p.prop_type.set_f) if Type.exists(p.prop_name): self.use_type_name(p.prop_name) if isinstance(p.prop_val, str) and Type.exists(p.prop_val): self.use_type_name(p.prop_val) props_code += """ {set_func}(@aOBJECT({dev_name}),@s{value},@s{prop_name},@sNULL);\ """.format(set_func=p.prop_type.set_f, dev_name=dev_name, prop_name=p.prop_name if Type.exists(p.prop_name) else "\"%s\"" % p.prop_name, value=self.gen_prop_val(p)) if isinstance(node, PCIExpressDeviceNode): self.use_type_name("PCIDevice") self.use_type_name("pci_create_multifunction") self.use_type_name("bool") self.use_type_name("DEVICE") decl_code += " PCIDevice *%s;\n" % dev_name def_code += """\ {dev_name} = pci_create_multifunction(@a{bus_name},@sPCI_DEVFN({slot},@s{func}),@s{multifunction},@s{qom_type});{props_code} qdev_init_nofail(DEVICE({dev_name})); """.format(dev_name=dev_name, bus_name=self.node_map[node.parent_bus], qom_type=node.qom_type if Type.exists(node.qom_type) else "\"%s\"" % node.qom_type, props_code=props_code, multifunction="true" if node.multifunction else "false", slot=node.slot, func=node.function) else: self.use_type_name("DeviceState") self.use_type_name("qdev_create") decl_code += " DeviceState *%s;\n" % dev_name if ((node.parent_bus is None) or isinstance(node.parent_bus, SystemBusNode)): bus_name = "NULL" else: bus_name = "BUS(%s)" % self.node_map[node.parent_bus] if Type.exists(node.qom_type): qom_type = node.qom_type else: qom_type = "\"%s\"" % node.qom_type def_code += """\ {dev_name} = qdev_create(@a{bus_name},@s{qom_type});{props_code} qdev_init_nofail({dev_name}); """.format(dev_name=dev_name, bus_name=bus_name, qom_type=qom_type, props_code=props_code) if isinstance(node, SystemBusDeviceNode): for idx, mmio in node.mmio_mappings.items(): if mmio is not None: self.use_type_name("sysbus_mmio_map") self.use_type_name("SYS_BUS_DEVICE") if isinstance(mmio, str) and Type.exists(mmio): self.use_type_name(mmio) mmio_val = str(mmio) else: mmio_val = "0x%x" % mmio def_code += """\ sysbus_mmio_map(@aSYS_BUS_DEVICE({dev_name}),@s{idx},@s{mmio_val}); """.format(dev_name=dev_name, idx=idx, mmio_val=mmio_val) for bus in node.buses: if len(bus.devices) == 0: continue bus_name = self.node_map[bus] try: if isinstance(bus, PCIExpressBusNode): if isinstance(node, SystemBusDeviceNode): bridge_cast = "PCI_HOST_BRIDGE" bus_field = "bus" elif isinstance(node, PCIExpressDeviceNode): bridge_cast = "PCI_BRIDGE" bus_field = "sec_bus" else: raise UnknownBusBridgeType( node.parent_bus, bus) self.use_type_name(bridge_cast) def_code += """\ {bus_name} = {bridge_cast}({bridge_name})->{bus_field}; """.format(bus_name=bus_name, bridge_name=dev_name, bridge_cast=bridge_cast, bus_field=bus_field) else: raise UnknownBusBridgeType(node.parent_bus, bus) except UnknownBusBridgeType: self.use_type_name("qdev_get_child_bus") self.use_type_name("DEVICE") if bus.cast is not None: self.use_type_name(bus.cast) def_code += """\ {bus_name} = {bus_cast}; """.format( bus_name=bus_name, bus_cast=("(%s *) %%s" % bus.c_type) if bus.cast is None else ("%s(%%s)" % bus.cast), ) % """\ qdev_get_child_bus(@aDEVICE({bridge_name}),@s"{bus_child_name}")\ """.format( bridge_name=dev_name, bus_child_name=bus.gen_child_name_for_bus(), ) elif isinstance(node, BusNode): # No definition code will be generated skip_nl = True if isinstance(node, SystemBusNode): continue if len(node.devices) == 0: continue self.use_type_name(node.c_type) bus_name = self.node_map[node] decl_code += " %s *%s;\n" % (node.c_type, bus_name) elif isinstance(node, IRQLine): if node.hub_ended(): # Do not generate a code for IRQ lines that refers an IRQ # hub. The code will be generated during the hub processing. skip_nl = True continue self.use_type_name("qemu_irq") irq_name = self.node_map[node] decl_code += " qemu_irq %s;\n" % irq_name def_code += (self.gen_irq_get(node.dst, irq_name) + self.gen_irq_connect(node.src, irq_name)) elif isinstance(node, MemoryNode): self.use_type_name("MemoryRegion") if isinstance(node.size, str) and Type.exists(node.size): self.use_type_name(node.size) if Type.exists(node.name): self.use_type_name(node.name) mem_name = self.node_map[node] decl_code += " MemoryRegion *%s;\n" % mem_name if isinstance(node, MemorySASNode): self.use_type_name("get_system_memory") def_code += " %s = get_system_memory();\n" % mem_name else: def_code += " %s = g_new(MemoryRegion, 1);\n" % mem_name if isinstance(node, MemoryAliasNode): self.use_type_name("memory_region_init_alias") if Type.exists(node.alias_offset): self.use_type_name(node.alias_offset) def_code += """\ memory_region_init_alias(@a{mem_name},@sNULL,@s{dbg_name},@s{orig},@s{offset},@s{size}); """.format(mem_name=mem_name, dbg_name=node.name if Type.exists(node.name) else "\"%s\"" % node.name, size=node.size, orig=self.node_map[node.alias_to], offset=node.alias_offset) elif (isinstance(node, MemoryRAMNode) or isinstance(node, MemoryROMNode)): self.use_type_name("memory_region_init_ram") if glob_mem: self.use_type_name("vmstate_register_ram_global") def_code += """\ memory_region_init_ram(@a{mem_name},@sNULL,@s{dbg_name},@s{size},@sNULL);{glob} """.format(mem_name=mem_name, dbg_name=node.name if Type.exists(node.name) else "\"%s\"" % node.name, size=node.size, glob=(("\n vmstate_register_ram_global(%s);" % mem_name) if glob_mem else "")) elif not isinstance(node, MemorySASNode): self.use_type_name("memory_region_init") def_code += """\ memory_region_init(@a{mem_name},@sNULL,@s{dbg_name},@s{size}); """.format(mem_name=mem_name, dbg_name=node.name if Type.exists(node.name) else "\"%s\"" % node.name, size=node.size) if node.parent is not None: if (isinstance(node.offset, str) and Type.exists(node.offset)): self.use_type_name(node.offset) if node.may_overlap: self.use_type_name( "memory_region_add_subregion_overlap") if (isinstance(node.priority, str) and Type.exists(node.priority)): self.use_type_name(node.priority) def_code += """\ memory_region_add_subregion_overlap(@a{parent_name},@s{offset},@s{child},@s{priority}); """.format(parent_name=self.node_map[node.parent], offset=node.offset, priority=node.priority, child=mem_name) else: self.use_type_name("memory_region_add_subregion") if (isinstance(node.priority, str) and Type.exists(node.priority)): self.use_type_name(node.priority) def_code += """\ memory_region_add_subregion(@a{parent_name},@s{offset},@s{child}); """.format(parent_name=self.node_map[node.parent], offset=node.offset, child=mem_name) elif isinstance(node, IRQHub): if len(node.irqs) < 1: # Nothing to do for detached IRQ hub skip_nl = True continue self.use_type_name("qemu_irq") hub_in_name = self.node_map[node] decl_code += " qemu_irq %s;\n" % hub_in_name hubl = self.provide_hub_layout(node) code = hubl.gen_irq_get() decl_code += code[0] def_code += code[1] for in_irq in [irq for irq in node.irqs if irq.dst[0] == node]: src = in_irq.src if isinstance(src[0], IRQHub): # A source hub does connects to this hub by itself continue def_code += self.gen_irq_connect(src, hub_in_name) else: raise UnknownMachineNodeType(str(type(node))) # machine initialization function self.instance_init = Function(name="init_%s" % self.qtn.for_id_name, static=True, args=[ Type.lookup("MachineState").gen_var( "machine", pointer=True) ], body=decl_code + "\n" + def_code, used_types=self.init_used_types) self.source.add_type(self.instance_init) get_vp("machine type register template generator")(self) return self.source.generate()