Exemplo n.º 1
0
int
mptable_build(struct vmctx *ctx, int ncpu)
{
	mpcth_t			mpch;
	bus_entry_ptr		mpeb;
	io_apic_entry_ptr	mpei;
	bproc_entry_ptr		mpep;
	mpfps_t			mpfp;
	int_entry_ptr		mpie;
	char 			*curraddr;
	char 			*startaddr;

	startaddr = paddr_guest2host(ctx, MPTABLE_BASE, MPTABLE_MAX_LENGTH);
	if (startaddr == NULL) {
		printf("mptable requires mapped mem\n");
		return (ENOMEM);
	}

	curraddr = startaddr;
	mpfp = (mpfps_t)curraddr;
	mpt_build_mpfp(mpfp, MPTABLE_BASE);
	curraddr += sizeof(*mpfp);

	mpch = (mpcth_t)curraddr;
	mpt_build_mpch(mpch);
	curraddr += sizeof(*mpch);

	mpep = (bproc_entry_ptr)curraddr;
	mpt_build_proc_entries(mpep, ncpu);
	curraddr += sizeof(*mpep) * ncpu;
	mpch->entry_count += ncpu;

	mpeb = (bus_entry_ptr) curraddr;
	mpt_build_bus_entries(mpeb);
	curraddr += sizeof(*mpeb) * MPE_NUM_BUSES;
	mpch->entry_count += MPE_NUM_BUSES;

	mpei = (io_apic_entry_ptr)curraddr;
	mpt_build_ioapic_entries(mpei, ncpu + 1);
	curraddr += sizeof(*mpei);
	mpch->entry_count++;

	mpie = (int_entry_ptr) curraddr;
	mpt_build_ioint_entries(mpie, MPEII_MAX_IRQ, ncpu + 1);
	curraddr += sizeof(*mpie) * MPEII_MAX_IRQ;
	mpch->entry_count += MPEII_MAX_IRQ;

	if (oem_tbl_start) {
		mpch->oem_table_pointer = curraddr - startaddr + MPTABLE_BASE;
		mpch->oem_table_size = oem_tbl_size;
		memcpy(curraddr, oem_tbl_start, oem_tbl_size);
	}

	mpch->base_table_length = curraddr - (char *)mpch;
	mpch->checksum = mpt_compute_checksum(mpch, mpch->base_table_length);

	return (0);
}
Exemplo n.º 2
0
int
mptable_build(struct vmctx *ctx, int ncpu)
{
	mpcth_t			mpch;
	bus_entry_ptr		mpeb;
	io_apic_entry_ptr	mpei;
	proc_entry_ptr		mpep;
	mpfps_t			mpfp;
	int_entry_ptr		mpie;
	int			ioints, bus;
	char			*curraddr;
	char			*startaddr;

	startaddr = paddr_guest2host(ctx, MPTABLE_BASE, MPTABLE_MAX_LENGTH);
	if (startaddr == NULL) {
		fprintf(stderr, "mptable requires mapped mem\n");
		return -1;
	}

	/*
	 * There is no way to advertise multiple PCI hierarchies via MPtable
	 * so require that there is no PCI hierarchy with a non-zero bus
	 * number.
	 */
	for (bus = 1; bus <= PCI_BUSMAX; bus++) {
		if (pci_bus_configured(bus)) {
			fprintf(stderr, "MPtable is incompatible with "
			    "multiple PCI hierarchies.\r\n");
			fprintf(stderr, "MPtable generation can be disabled "
			    "by passing the -Y option to acrn-dm.\r\n");
			return -1;
		}
	}

	curraddr = startaddr;
	mpfp = (mpfps_t)curraddr;
	mpt_build_mpfp(mpfp, MPTABLE_BASE);
	curraddr += sizeof(*mpfp);

	mpch = (mpcth_t)curraddr;
	mpt_build_mpch(mpch);
	curraddr += sizeof(*mpch);

	mpep = (proc_entry_ptr)curraddr;
	mpt_build_proc_entries(mpep, ncpu);
	curraddr += sizeof(*mpep) * ncpu;
	mpch->entry_count += ncpu;

	mpeb = (bus_entry_ptr) curraddr;
	mpt_build_bus_entries(mpeb);
	curraddr += sizeof(*mpeb) * MPE_NUM_BUSES;
	mpch->entry_count += MPE_NUM_BUSES;

	/* Don't generate io_apic entry for VM with lapic pt */
	if (!lapic_pt) {
		mpei = (io_apic_entry_ptr)curraddr;
		mpt_build_ioapic_entries(mpei, 0);
		curraddr += sizeof(*mpei);
		mpch->entry_count++;

		mpie = (int_entry_ptr) curraddr;
		ioints = mpt_count_ioint_entries();
		mpt_build_ioint_entries(mpie, 0);
		curraddr += sizeof(*mpie) * ioints;
		mpch->entry_count += ioints;
	}

	mpie = (int_entry_ptr)curraddr;
	mpt_build_localint_entries(mpie);
	curraddr += sizeof(*mpie) * MPEII_NUM_LOCAL_IRQ;
	mpch->entry_count += MPEII_NUM_LOCAL_IRQ;

	if (oem_tbl_start) {
		mpch->oem_table_pointer = curraddr - startaddr + MPTABLE_BASE;
		mpch->oem_table_size = oem_tbl_size;
		memcpy(curraddr, oem_tbl_start, oem_tbl_size);
	}

	mpch->base_table_length = curraddr - (char *)mpch;
	mpch->checksum = mpt_compute_checksum(mpch, mpch->base_table_length);

	return 0;
}