Beispiel #1
0
    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)]
Beispiel #2
0
    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)]
Beispiel #3
0
    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)]
Beispiel #4
0
    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)]
Beispiel #5
0
    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)]
Beispiel #6
0
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)
Beispiel #7
0
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()