Example #1
0
File: object.c Project: virajs/egui
/*
    总是将孩子节点加在子节点链的最右边

    如果 obj 在对象树中
    那么完成添加工作后一定要更新 root->parent 的 lchild 成员和 rchild 成员
    这是为了保证遍历的正确
*/
si_t object_insert_child(struct object* parent, struct object* child)
{
	struct object* tree = NULL;

	if(NULL == parent)
	{
		return 0;
	}

	/* 父节点有右子节点 */
	if(parent->rchild != NULL)
	{
		parent->rchild->parent = child;

		/* 父节点的右子节点作为自己的左子节点 */
		child->lchild = parent->rchild;
	}

	child->parent = parent;
	parent->rchild = child;

	/* 找到这棵树根节点的父节点 */
	tree = object_get_root(parent)->parent;

	/* child 在对象树中 */
	/* 必须更新 root->parent 节点的 lchild 成员和 rchild 成员 */
	/* 更新最左边节点 */
	tree->lchild = object_tree_l_most_node(tree->parent);
	/* 更新最右边节点 */
	tree->rchild = object_tree_r_most_node(tree->parent);

	return 0;
}
Example #2
0
File: nmi.c Project: dota1923/qemu
void nmi_monitor_handle(int cpu_index, Error **errp)
{
    struct do_nmi_s ns = {
        .cpu_index = cpu_index,
        .err = NULL,
        .handled = false
    };

    nmi_children(object_get_root(), &ns);
    if (ns.handled) {
        error_propagate(errp, ns.err);
    } else {
        error_setg(errp, QERR_UNSUPPORTED);
    }
}

void inject_nmi(void)
{
#if defined(TARGET_I386)
    CPUState *cs;

    CPU_FOREACH(cs) {
        X86CPU *cpu = X86_CPU(cs);

        if (!cpu->apic_state) {
            cpu_interrupt(cs, CPU_INTERRUPT_NMI);
        } else {
            apic_deliver_nmi(cpu->apic_state);
        }
    }
#else
    nmi_monitor_handle(0, NULL);
#endif
}
Example #3
0
static void realize(DeviceState *d, Error **errp)
{
    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
    Object *root_container;
    char link_name[256];
    gchar *child_name;
    Error *err = NULL;

    DPRINTFN("drc realize: %x", drck->get_index(drc));
    /* NOTE: we do this as part of realize/unrealize due to the fact
     * that the guest will communicate with the DRC via RTAS calls
     * referencing the global DRC index. By unlinking the DRC
     * from DRC_CONTAINER_PATH/<drc_index> we effectively make it
     * inaccessible by the guest, since lookups rely on this path
     * existing in the composition tree
     */
    root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
    snprintf(link_name, sizeof(link_name), "%x", drck->get_index(drc));
    child_name = object_get_canonical_path_component(OBJECT(drc));
    DPRINTFN("drc child name: %s", child_name);
    object_property_add_alias(root_container, link_name,
                              drc->owner, child_name, &err);
    if (err) {
        error_report("%s", error_get_pretty(err));
        error_free(err);
        object_unref(OBJECT(drc));
    }
    g_free(child_name);
    DPRINTFN("drc realize complete");
}
static void acpi_get_cpu_info(AcpiCpuInfo *cpu)
{
    Object *root = object_get_root();

    memset(cpu->found_cpus, 0, sizeof cpu->found_cpus);
    object_child_foreach(root, acpi_add_cpu_info, cpu);
}
Example #5
0
PRManagerInfoList *qmp_query_pr_managers(Error **errp)
{
    PRManagerInfoList *head = NULL;
    PRManagerInfoList **prev = &head;
    Object *container = container_get(object_get_root(), PR_MANAGER_PATH);

    object_child_foreach(container, query_one_pr_manager, &prev);
    return head;
}
Example #6
0
IOThreadInfoList *qmp_query_iothreads(Error **errp)
{
    IOThreadInfoList *head = NULL;
    IOThreadInfoList **prev = &head;
    Object *container = container_get(object_get_root(), IOTHREADS_PATH);

    object_child_foreach(container, query_one_iothread, &prev);
    return head;
}
Example #7
0
File: object.c Project: virajs/egui
void object_move_first(struct object* obj)
{
	struct object * tree = NULL, * parent = NULL;
	/* 如果活动窗口不是顶层窗口也不是父窗口的右子节点 */
	/* 将活动窗口变成父窗口的右子节点 */
	if(obj == obj->parent->parent || obj == obj->parent->rchild)
	{
		return 0;
	}
	/* 找到 win_info_ptr 的父窗口 */
	parent = obj->parent;
	while(parent == parent->parent->lchild)
	{
		parent = parent->parent;
	}
	parent = parent->parent;

	/* obj 有左子节点 */
	/* obj 在末端 */
	if(obj->lchild != NULL)
	{
		obj->lchild->parent = obj->parent;
		obj->parent->lchild = obj->lchild;
	}
	/* obj 没有左子节点 */
	/* obj 在中间*/
	else
	{
		obj->parent->lchild = NULL;
	}

	obj->lchild = parent->rchild;
	parent->rchild->parent =obj;

	obj->parent = parent;
	parent->rchild = obj;

	/* 找到这棵树根节点的父节点 */
	tree = object_get_root(parent)->parent;

	/* 必须更新 root->parent 节点的 lchild 成员和 rchild 成员 */
	/* 此时 tree == root->parent */

	/* 更新最左边节点 */
	tree->lchild = object_tree_l_most_node(tree->parent);
	/* 更新最右边节点 */
	tree->rchild = object_tree_r_most_node(tree->parent);
}
Example #8
0
static void unrealize(DeviceState *d, Error **errp)
{
    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
    Object *root_container;
    char name[256];
    Error *err = NULL;

    DPRINTFN("drc unrealize: %x", drck->get_index(drc));
    root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
    snprintf(name, sizeof(name), "%x", drck->get_index(drc));
    object_property_del(root_container, name, &err);
    if (err) {
        error_report_err(err);
        object_unref(OBJECT(drc));
    }
}
Example #9
0
File: object.c Project: virajs/egui
/*
    总是将孩子节点加在子节点链的最左边

    如果 obj 在对象树中
    那么完成添加工作后一定要更新 root->parent 的 lchild 成员和 rchild 成员
    这是为了保证遍历的正确
*/
si_t object_attach_child(struct object * obj, struct object * child)
{
    struct object * tree;

    /* parent 没有子对象 */
    if(obj->rchild == NULL)
    {
        /* 作为上层对象的右子节点 */
        obj->rchild = child;
        child->parent = obj;
    }
    else
    {
        obj = obj->rchild;

        /* 一直往左走 */
        while(obj->lchild != NULL)
        {
            obj = obj->lchild;
        }

        /* 作为同层对象的左子节点 */
        obj->lchild = child;
        child->parent = obj;
    }

    /* 找到这棵树根节点的父节点 */
    /* 没有的话 tree == NULL */
	tree = object_get_root(obj)->parent;

    /* obj 在对象树中 */
    /* 必须更新 root->parent 节点的 lchild 成员和 rchild 成员 */
    /* 此时 tree == root->parent */
    if(tree != NULL)
    {
        /* 更新最左边节点 */
        tree->lchild = object_tree_l_most_node(tree->parent);
        /* 更新最右边节点 */
        tree->rchild = object_tree_r_most_node(tree->parent);
    }

    return 0;
}
Example #10
0
static si_t
handle_window_activate
(union message * msg)
{
	struct object* node;
	si_t n = 0, i = 0;
	node = OBJECT_POINTER(application_widgets_for_each_increament(do_find_window, msg));

	if(node == NULL)
	{
		return 0;
	}

	object_move_first(node);
	if(global_application.focus != NULL)
	{
		dispatch_msg_to_subchilds(node, MESSAGE_TYPE_WINDOW_DEACTIVATE);
	}

	global_application.focus = WINDOW_POINTER(node);
	if(WIDGET_POINTER(node)->callback != NULL)
	{
		WIDGET_POINTER(node)->callback(node, msg);
	}

	dispatch_msg_to_subchilds(node, MESSAGE_TYPE_WIDGET_REPAINT);

	/**
	 * 次序提前
	 **/
	node = object_get_root(node)->parent;
	n = vector_size(&global_application.window_vector);
	for(i = 0; i < n; ++ i)
	{
		if(vector_at(&global_application.window_vector, i) == node)
		{
			vector_move_back(&global_application.window_vector, i);
			break;
		}
	}

	return 0;
}
static si_t handle_minimize_button_release(union message* msg)
{
	struct object* tree = NULL;
	struct object* node = NULL;
	int i = 0, j = 0;
	struct window_info_iterator iter;
	/* 不能最小化或不在活动窗口的最小化按钮内释放 */
	if(global_wm.active_win_info_ptr->minimize_enable != 1
		|| !is_point_in_area(&(msg->mouse.cursor_position), &(global_wm.active_win_info_ptr->minimize_button_area)))
	{
		return 0;
	}

	/**
	 * send minmize msg to every client window(including subwindows)
	 **/
	tree = object_get_root(OBJECT_POINTER(global_wm.active_win_info_ptr))->parent;
	node = tree->lchild;
	while(node != NULL)
	{
		EGUI_PRINT_INFO("send minimized msg to %s", ((struct window_info*)node)->title);
		send_window_minimize_message(&global_wm.active_app_info_ptr->uds, msg, (si_t)node);
		node = object_tree_iterator_increment(tree, node);
	}

	/**
	 * send deactive msg to client
	 **/
	send_window_deactivate_message(&global_wm.active_app_info_ptr->uds, msg, (si_t)global_wm.active_win_info_ptr);
	/** 通知桌面 **/
	if(NULL != global_wm.desktop_app_ptr)
	{
		send_window_deactivate_message(&global_wm.desktop_app_ptr->uds, NULL, (si_t)tree->parent);
	}

	window_info_iterator_clear(&iter);
	/* get next active window and application */
	if(all_app_traversal_decrement(&iter, _do_find_next_active_window, tree->parent))
	{
		global_wm.active_win_info_ptr = iter.win_info_ptr;
		global_wm.active_app_info_ptr = iter.app_info_ptr;
	}
	else
	{
		global_wm.active_win_info_ptr = NULL;
		global_wm.active_app_info_ptr = NULL;
		return 0;
	}

	/**
	 * 获得顶层窗口
	 **/
	node = object_get_root(OBJECT_POINTER(global_wm.active_win_info_ptr));
	/**
	 * move next active window back
	 **/
	i = application_info_get_win_index(global_wm.active_app_info_ptr, (struct window_info*)node);
	j = window_manager_get_app_index(global_wm.active_app_info_ptr);
	vector_move_back(&(global_wm.active_app_info_ptr->window_info_vector), i);
	vector_move_back(&(global_wm.application_info_vector), j);

	/**
	 * send active msg
	 **/
	send_window_activate_message(&global_wm.active_app_info_ptr->uds, msg, (si_t)global_wm.active_win_info_ptr);
	if(NULL != global_wm.desktop_app_ptr)
	{
		send_window_activate_message(&global_wm.desktop_app_ptr->uds, NULL, (si_t)node);
	}

	return 0;
}
/**
 * 通过按下鼠标消息设置那个是活动的
 * 设置活动用户应用程序和活动窗口
 *
 * @param msg 必须是鼠标按下消息
 *
 * @return 0
 **/
static si_t mask_active_by_mouse_down(union message * msg)
{
	struct window_info_iterator iter;
	window_info_iterator_clear(&iter);

	if(!all_app_traversal_decrement(&iter, _do_find_clicked_window, &msg->mouse.cursor_position)) {
        /* Clear useless pointers in tainted iter */
        window_info_iterator_clear(&iter);
    }

	/* 在桌面上按下了鼠标的某个键 */
	if(iter.app_info_ptr == NULL || iter.win_info_ptr == NULL)
	{
		/* 原来有活动窗口 */
		if(global_wm.active_win_info_ptr != NULL)
		{
			/* 发送激死消息给原来的活动窗口 */
			send_window_deactivate_message(&global_wm.active_app_info_ptr->uds, msg, (si_t)global_wm.active_win_info_ptr);
			/** 通知桌面 **/
			if(NULL != global_wm.desktop_app_ptr)
			{
				send_window_deactivate_message(&global_wm.desktop_app_ptr->uds, NULL,
					(si_t)object_get_root(OBJECT_POINTER(global_wm.active_win_info_ptr)));
			}

			/* 改变活动窗口 */
			global_wm.active_win_info_ptr = NULL;
			global_wm.active_app_info_ptr = NULL;
		}
	}
	/* 在窗口上按下了鼠标的某个键 */
	else if(global_wm.active_win_info_ptr != iter.win_info_ptr)
	{
		/* 原来有活动窗口 */
		if(global_wm.active_win_info_ptr != NULL)
		{
			/* 发送激死消息给原来的活动窗口 */
			send_window_deactivate_message(&global_wm.active_app_info_ptr->uds, msg, (si_t)global_wm.active_win_info_ptr);
			/** 通知桌面 **/
			if(NULL != global_wm.desktop_app_ptr)
			{
				send_window_deactivate_message(&global_wm.desktop_app_ptr->uds, NULL,
					(si_t)object_get_root(OBJECT_POINTER(global_wm.active_win_info_ptr)));
			}
		}

		/* 将活动窗口移动到该用户应用程序的窗口向量的尾部 */
		vector_move_back(&(iter.app_info_ptr->window_info_vector), iter.win_index);

		/* 将活动程序移动到用户应用程序向量的尾部 */
		vector_move_back(&(global_wm.application_info_vector), iter.app_index);

		/* 将活动窗口作为父控件的长子控件 */
		object_move_first(OBJECT_POINTER(iter.win_info_ptr));

		/* 改变活动窗口 */
		global_wm.active_win_info_ptr = iter.win_info_ptr;
		global_wm.active_app_info_ptr = iter.app_info_ptr;

		send_window_activate_message(&global_wm.active_app_info_ptr->uds, msg, (si_t)iter.win_info_ptr);
		if(NULL != global_wm.desktop_app_ptr)
		{
			send_window_activate_message(&global_wm.desktop_app_ptr->uds, NULL, (si_t)iter.top_win_info_ptr);
		}
	}

	return 0;
}
Example #13
0
File: object.c Project: virajs/egui
si_t object_delete(struct object* object, void(*destructor)(void*))
{
	if(object->parent->parent == object)
	{
		object_tree_for_each(object, destructor);
	}
	else
	{
		/* 找到这棵树根节点的父节点 */
		struct object* tree = object_get_root(object)->parent;

		/* 是父节点的右子节点 */
		if(object == object->parent->rchild)
		{
			/* object 没有左子节点 */
			/* parent 的下一层对象只有 object */
			if(object->lchild == NULL)
			{
				/* 清除父节点中的指针 */
				object->parent->rchild = NULL;
			}
			/* object 有左子节点 */
			/* parent 的下一层有多个对象 */
			else
			{
				/* 处理 object 同层的对象 */
				object->parent->rchild = object->lchild;
				object->lchild->parent = object->parent;

				/* 清空 object->lchild */
				object->lchild = NULL;
			}
		}
		/* 是父节点的左子节点 */
		/* 此时 parent 的下一层有多个对象 */
		else if(object == object->parent->lchild)
		{
			/* object 没有左子节点 */
			/* object 处于末端 */
			if(object->lchild == NULL)
			{
				/* 清除父节点中的指针 */
				object->parent->lchild = NULL;
			}
			/* object 有左子节点 */
			/* object 处于中间 */
			else
			{
				/* 处理 object 同层的对象 */
				object->parent->lchild = object->lchild;
				object->lchild->parent = object->parent;

				/* 清空 object->lchild */
				object->lchild = NULL;
			}
		}

		object_tree_for_each(object, destructor);

		/* 必须更新 root->parent 节点的 lchild 和 rchild */
		/* 此时 tree == root->parent */
		if(tree != NULL)
		{
			/* 更新最左边节点 */
			tree->lchild = object_tree_l_most_node(tree->parent);
			/* 更新最右边节点 */
			tree->rchild = object_tree_r_most_node(tree->parent);
		}

	}
	return 0;
}
Example #14
0
/* PC hardware initialisation */
static void pc_init1(MemoryRegion *system_memory,
                     MemoryRegion *system_io,
                     ram_addr_t ram_size,
                     const char *boot_device,
                     const char *kernel_filename,
                     const char *kernel_cmdline,
                     const char *initrd_filename,
                     const char *cpu_model,
                     int pci_enabled,
                     int kvmclock_enabled)
{
    int i;
    ram_addr_t below_4g_mem_size, above_4g_mem_size;
    PCIBus *pci_bus;
    ISABus *isa_bus;
    PCII440FXState *i440fx_state;
    int piix3_devfn = -1;
    qemu_irq *cpu_irq;
    qemu_irq *gsi;
    qemu_irq *i8259;
    qemu_irq *smi_irq;
    GSIState *gsi_state;
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    BusState *idebus[MAX_IDE_BUS];
    ISADevice *rtc_state;
    ISADevice *floppy;
    MemoryRegion *ram_memory;
    MemoryRegion *pci_memory;
    MemoryRegion *rom_memory;
    DeviceState *dev;

    pc_cpus_init(cpu_model);

    if (kvmclock_enabled) {
        kvmclock_create();
    }

    if (ram_size >= 0xe0000000 ) {
        above_4g_mem_size = ram_size - 0xe0000000;
        below_4g_mem_size = 0xe0000000;
    } else {
        above_4g_mem_size = 0;
        below_4g_mem_size = ram_size;
    }

    if (pci_enabled) {
        pci_memory = g_new(MemoryRegion, 1);
        memory_region_init(pci_memory, "pci", INT64_MAX);
        rom_memory = pci_memory;
    } else {
        pci_memory = NULL;
        rom_memory = system_memory;
    }

    /* allocate ram and load rom/bios */
    if (!xen_enabled()) {
        pc_memory_init(system_memory,
                       kernel_filename, kernel_cmdline, initrd_filename,
                       below_4g_mem_size, above_4g_mem_size,
                       pci_enabled ? rom_memory : system_memory, &ram_memory);
    }

    gsi_state = g_malloc0(sizeof(*gsi_state));
    if (kvm_irqchip_in_kernel()) {
        kvm_piix3_setup_irq_routing(pci_enabled);
        gsi = qemu_allocate_irqs(kvm_piix3_gsi_handler, gsi_state,
                                 GSI_NUM_PINS);
    } else {
        gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
    }

    if (pci_enabled) {
        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi,
                              system_memory, system_io, ram_size,
                              below_4g_mem_size,
                              0x100000000ULL - below_4g_mem_size,
                              0x100000000ULL + above_4g_mem_size,
                              (sizeof(target_phys_addr_t) == 4
                               ? 0
                               : ((uint64_t)1 << 62)),
                              pci_memory, ram_memory);
    } else {
        pci_bus = NULL;
        i440fx_state = NULL;
        isa_bus = isa_bus_new(NULL, system_io);
        no_hpet = 1;
    }
    isa_bus_irqs(isa_bus, gsi);

    if (kvm_irqchip_in_kernel()) {
        i8259 = kvm_i8259_init(isa_bus);
    } else if (xen_enabled()) {
        i8259 = xen_interrupt_controller_init();
    } else {
        cpu_irq = pc_allocate_cpu_irq();
        i8259 = i8259_init(isa_bus, cpu_irq[0]);
    }

    for (i = 0; i < ISA_NUM_IRQS; i++) {
        gsi_state->i8259_irq[i] = i8259[i];
    }
    if (pci_enabled) {
        ioapic_init(gsi_state);
    }

    pc_register_ferr_irq(gsi[13]);

    dev = pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
    if (dev) {
        object_property_add_child(object_get_root(), "vga", OBJECT(dev), NULL);
    }

    if (xen_enabled()) {
        pci_create_simple(pci_bus, -1, "xen-platform");
    }

    /* init basic PC hardware */
    pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled());

    for(i = 0; i < nb_nics; i++) {
        NICInfo *nd = &nd_table[i];

        if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0))
            pc_init_ne2k_isa(isa_bus, nd);
        else
            pci_nic_init_nofail(nd, "e1000", NULL);
    }

    ide_drive_get(hd, MAX_IDE_BUS);
    if (pci_enabled) {
        PCIDevice *dev;
        if (xen_enabled()) {
            dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1);
        } else {
            dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
        }
        idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
        idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");

        /* FIXME there's some major spaghetti here.  Somehow we create the
         * devices on the PIIX before we actually create it.  We create the
         * PIIX3 deep in the recess of the i440fx creation too and then lose
         * the DeviceState.
         *
         * For now, let's "fix" this by making judicious use of paths.  This
         * is not generally the right way to do this.
         */
        object_property_add_child(object_resolve_path("/i440fx/piix3", NULL),
                                  "rtc", (Object *)rtc_state, NULL);
    } else {
        for(i = 0; i < MAX_IDE_BUS; i++) {
            ISADevice *dev;
            dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i],
                               ide_irq[i],
                               hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
            idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0");
        }
    }

    audio_init(isa_bus, pci_enabled ? pci_bus : NULL);

    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
                 floppy, idebus[0], idebus[1], rtc_state);

    if (pci_enabled && usb_enabled) {
        usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);
    }

    if (pci_enabled && acpi_enabled) {
        i2c_bus *smbus;

        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
        /* TODO: Populate SPD eeprom data.  */
        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
                              gsi[9], *smi_irq,
                              kvm_enabled());
        smbus_eeprom_init(smbus, 8, NULL, 0);
    }

    if (pci_enabled) {
        pc_pci_device_init(pci_bus);
    }
}
Example #15
0
/**
 * spapr_drc_populate_dt
 *
 * @fdt: libfdt device tree
 * @path: path in the DT to generate properties
 * @owner: parent Object/DeviceState for which to generate DRC
 *         descriptions for
 * @drc_type_mask: mask of sPAPRDRConnectorType values corresponding
 *   to the types of DRCs to generate entries for
 *
 * generate OF properties to describe DRC topology/indices to guests
 *
 * as documented in PAPR+ v2.1, 13.5.2
 */
int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
                          uint32_t drc_type_mask)
{
    Object *root_container;
    ObjectProperty *prop;
    ObjectPropertyIterator *iter;
    uint32_t drc_count = 0;
    GArray *drc_indexes, *drc_power_domains;
    GString *drc_names, *drc_types;
    int ret;

    /* the first entry of each properties is a 32-bit integer encoding
     * the number of elements in the array. we won't know this until
     * we complete the iteration through all the matching DRCs, but
     * reserve the space now and set the offsets accordingly so we
     * can fill them in later.
     */
    drc_indexes = g_array_new(false, true, sizeof(uint32_t));
    drc_indexes = g_array_set_size(drc_indexes, 1);
    drc_power_domains = g_array_new(false, true, sizeof(uint32_t));
    drc_power_domains = g_array_set_size(drc_power_domains, 1);
    drc_names = g_string_set_size(g_string_new(NULL), sizeof(uint32_t));
    drc_types = g_string_set_size(g_string_new(NULL), sizeof(uint32_t));

    /* aliases for all DRConnector objects will be rooted in QOM
     * composition tree at DRC_CONTAINER_PATH
     */
    root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);

    iter = object_property_iter_init(root_container);
    while ((prop = object_property_iter_next(iter))) {
        Object *obj;
        sPAPRDRConnector *drc;
        sPAPRDRConnectorClass *drck;
        uint32_t drc_index, drc_power_domain;

        if (!strstart(prop->type, "link<", NULL)) {
            continue;
        }

        obj = object_property_get_link(root_container, prop->name, NULL);
        drc = SPAPR_DR_CONNECTOR(obj);
        drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

        if (owner && (drc->owner != owner)) {
            continue;
        }

        if ((drc->type & drc_type_mask) == 0) {
            continue;
        }

        drc_count++;

        /* ibm,drc-indexes */
        drc_index = cpu_to_be32(drck->get_index(drc));
        g_array_append_val(drc_indexes, drc_index);

        /* ibm,drc-power-domains */
        drc_power_domain = cpu_to_be32(-1);
        g_array_append_val(drc_power_domains, drc_power_domain);

        /* ibm,drc-names */
        drc_names = g_string_append(drc_names, drck->get_name(drc));
        drc_names = g_string_insert_len(drc_names, -1, "\0", 1);

        /* ibm,drc-types */
        drc_types = g_string_append(drc_types,
                                    spapr_drc_get_type_str(drc->type));
        drc_types = g_string_insert_len(drc_types, -1, "\0", 1);
    }
    object_property_iter_free(iter);

    /* now write the drc count into the space we reserved at the
     * beginning of the arrays previously
     */
    *(uint32_t *)drc_indexes->data = cpu_to_be32(drc_count);
    *(uint32_t *)drc_power_domains->data = cpu_to_be32(drc_count);
    *(uint32_t *)drc_names->str = cpu_to_be32(drc_count);
    *(uint32_t *)drc_types->str = cpu_to_be32(drc_count);

    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-indexes",
                      drc_indexes->data,
                      drc_indexes->len * sizeof(uint32_t));
    if (ret) {
        fprintf(stderr, "Couldn't create ibm,drc-indexes property\n");
        goto out;
    }

    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-power-domains",
                      drc_power_domains->data,
                      drc_power_domains->len * sizeof(uint32_t));
    if (ret) {
        fprintf(stderr, "Couldn't finalize ibm,drc-power-domains property\n");
        goto out;
    }

    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-names",
                      drc_names->str, drc_names->len);
    if (ret) {
        fprintf(stderr, "Couldn't finalize ibm,drc-names property\n");
        goto out;
    }

    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-types",
                      drc_types->str, drc_types->len);
    if (ret) {
        fprintf(stderr, "Couldn't finalize ibm,drc-types property\n");
        goto out;
    }

out:
    g_array_free(drc_indexes, true);
    g_array_free(drc_power_domains, true);
    g_string_free(drc_names, true);
    g_string_free(drc_types, true);

    return ret;
}
Example #16
0
File: char.c Project: mdroth/qemu
static Object *get_chardevs_root(void)
{
    return container_get(object_get_root(), "/chardevs");
}
Example #17
0
File: object.c Project: virajs/egui
/*
    如果 obj 有左子节点
    那么这个左子节点并不是 obj 子对象
    所以在析构以 obj 为根的树之前一定要要将 obj->lchild 成员清空

    如果 obj 在对象树中
    那么完成删除工作后一定要更新 root->parent 的 lchild 成员和 rchild 成员
    这是为了保证遍历的正确
*/
si_t object_remove(struct object * obj)
{
    struct object * tree;

    /* obj 有父对象 */
    if(obj->parent != NULL)
    {
        /* 找到这棵树根节点的父节点 */
        /* 没有的话 tree == NULL */
		tree = object_get_root(obj)->parent;

        /* obj 是由父节点右子节点 */
        if(obj == obj->parent->rchild)
        {
            /* obj 没有左子节点 */
            /* parent 的下一层对象只有 obj */
            if(obj->lchild == NULL)
            {
                /* 清除父节点中的指针 */
                obj->parent->rchild = NULL;
            }
            /* obj 有左子节点 */
            /* parent 的下一层有多个对象 */
            else
            {
                /* 处理 obj 同层的对象 */
                obj->parent->rchild = obj->lchild;
                obj->lchild->parent = obj->parent;

                /* 清空 obj->lchild */
                obj->lchild = NULL;
            }
        }
        /* obj 是由父节点左子节点 */
        /* 此时 parent 的下一层有多个对象 */
        else if(obj == obj->parent->lchild)
        {
            /* obj 没有左子节点 */
            /* obj 处于末端 */
            if(obj->lchild == NULL)
            {
                /* 清除父节点中的指针 */
                obj->parent->lchild = NULL;
            }
            /* obj 有左子节点 */
            /* obj 处于中间 */
            else
            {
                /* 处理 obj 同层的对象 */
                obj->parent->lchild = obj->lchild;
                obj->lchild->parent = obj->parent;

                /* 清空 obj->lchild */
                obj->lchild = NULL;
            }
        }

        /* 删除 obj 以及它的所有子对象 */
        object_tree_free(obj);

        /* obj 在对象树中 */
        /* 必须更新 root->parent 节点的 lchild 成员和 rchild 成员 */
        /* 此时 tree == root->parent */
        if(tree != NULL)
        {
            /* 更新最左边节点 */
            tree->lchild = object_tree_l_most_node(tree->parent);
            /* 更新最右边节点 */
            tree->rchild = object_tree_r_most_node(tree->parent);
        }
    }
    /* 没有父对象 */
    else
    {
        /* 清空 obj->lchild */
        obj->lchild = NULL;

        /* 删除 obj 以及它的所有子对象 */
        object_tree_free(obj);
    }

    return 0;
}