Example #1
0
static void apic_send_ipi(unsigned int target_cpu_id, u32 orig_icr_hi,
			  u32 icr_lo)
{
	if (!cell_owns_cpu(this_cell(), target_cpu_id)) {
		printk("WARNING: CPU %d specified IPI destination outside "
		       "cell boundaries, ICR.hi=%x\n",
		       this_cpu_id(), orig_icr_hi);
		return;
	}

	switch (icr_lo & APIC_ICR_DLVR_MASK) {
	case APIC_ICR_DLVR_NMI:
		/* TODO: must be sent via hypervisor */
		printk("Ignoring NMI IPI\n");
		break;
	case APIC_ICR_DLVR_INIT:
		x86_send_init_sipi(target_cpu_id, X86_INIT, -1);
		break;
	case APIC_ICR_DLVR_SIPI:
		x86_send_init_sipi(target_cpu_id, X86_SIPI,
				   icr_lo & APIC_ICR_VECTOR_MASK);
		break;
	default:
		apic_ops.send_ipi(per_cpu(target_cpu_id)->apic_id, icr_lo);
	}
}
Example #2
0
int i8042_access_handler(u16 port, bool dir_in, unsigned int size)
{
	union registers *guest_regs = &this_cpu_data()->guest_regs;
	const struct jailhouse_cell_desc *config = this_cell()->config;
	const u8 *pio_bitmap = jailhouse_cell_pio_bitmap(config);
	u8 val;

	if (port == I8042_CMD_REG &&
	    config->pio_bitmap_size >= (I8042_CMD_REG + 7) / 8 &&
	    !(pio_bitmap[I8042_CMD_REG / 8] & (1 << (I8042_CMD_REG % 8)))) {
		if (size != 1)
			goto invalid_access;
		if (dir_in) {
			guest_regs->rax &= ~BYTE_MASK(1);
			guest_regs->rax |= inb(I8042_CMD_REG);
		} else {
			val = (u8)guest_regs->rax;
			if (val == I8042_CMD_WRITE_CTRL_PORT ||
			    (val & I8042_CMD_PULSE_CTRL_PORT) ==
			    I8042_CMD_PULSE_CTRL_PORT)
				goto invalid_access;
			outb(val, I8042_CMD_REG);
		}
		return 1;
	}
	return 0;

invalid_access:
	panic_printk("FATAL: Invalid write to i8042 controller port\n");
	return -1;
}
Example #3
0
/**
 * Dispatch MMIO access of a cell CPU.
 * @param mmio		MMIO access description. @a mmio->value will receive the
 * 			result of a successful read access. All @a mmio fields
 * 			may have been modified on return.
 *
 * @return MMIO_HANDLED on success, MMIO_UNHANDLED if no region is registered
 * for the access address and size, or MMIO_ERROR if an access error was
 * detected.
 *
 * @see mmio_region_register
 * @see mmio_region_unregister
 */
enum mmio_result mmio_handle_access(struct mmio_access *mmio)
{
	struct mmio_region_handler handler;
	unsigned long region_base;

	if (find_region(this_cell(), mmio->address, mmio->size, &region_base,
			&handler) < 0)
		return MMIO_UNHANDLED;

	mmio->address -= region_base;
	return handler.function(handler.arg, mmio);
}
Example #4
0
/**
 * Dispatch MMIO access of a cell CPU.
 * @param mmio		MMIO access description. @a mmio->value will receive the
 * 			result of a successful read access. All @a mmio fields
 * 			may have been modified on return.
 *
 * @return MMIO_HANDLED on success, MMIO_UNHANDLED if no region is registered
 * for the access address and size, or MMIO_ERROR if an access error was
 * detected.
 *
 * @see mmio_region_register
 * @see mmio_region_unregister
 */
enum mmio_result mmio_handle_access(struct mmio_access *mmio)
{
	struct cell *cell = this_cell();
	int index = find_region(cell, mmio->address, mmio->size);
	mmio_handler handler;

	if (index < 0)
		return MMIO_UNHANDLED;

	handler = cell->mmio_handlers[index].handler;
	mmio->address -= cell->mmio_locations[index].start;
	return handler(cell->mmio_handlers[index].arg, mmio);
}
Example #5
0
bool worksheet::compare(const worksheet &other, bool reference) const
{
    if (reference)
    {
        return d_ == other.d_;
    }

    if (d_->parent_ != other.d_->parent_) return false;

    for (auto &row : d_->cell_map_)
    {
        if (other.d_->cell_map_.find(row.first) == other.d_->cell_map_.end())
        {
            return false;
        }

        for (auto &cell : row.second)
        {
            if (other.d_->cell_map_[row.first].find(cell.first) == other.d_->cell_map_[row.first].end())
            {
                return false;
            }

            xlnt::cell this_cell(&cell.second);
            xlnt::cell other_cell(&other.d_->cell_map_[row.first][cell.first]);

            if (this_cell.data_type() != other_cell.data_type())
            {
                return false;
            }

            if (this_cell.data_type() == xlnt::cell::type::number
                && std::fabs(this_cell.value<double>() - other_cell.value<double>()) > 0.0)
            {
                return false;
            }
        }
    }

    // todo: missing some comparisons

    if (d_->auto_filter_ == other.d_->auto_filter_ && d_->views_ == other.d_->views_
        && d_->merged_cells_ == other.d_->merged_cells_)
    {
        return true;
    }

    return false;
}