Beispiel #1
0
/*	Mark \a count contigous interrupts starting at \a startVector as in use.
	This will prevent them from being allocated by others. Only use this when
	the reserved range is hardwired to the given vector, otherwise allocate
	vectors using allocate_io_interrupt_vectors() instead.
*/
status_t
reserve_io_interrupt_vectors(long count, long startVector, interrupt_type type)
{
    MutexLocker locker(&sIOInterruptVectorAllocationLock);

    for (long i = 0; i < count; i++) {
        if (sAllocatedIOInterruptVectors[startVector + i]) {
            panic("reserved interrupt vector range %ld-%ld overlaps already "
                  "allocated vector %ld", startVector, startVector + count - 1,
                  startVector + i);
            free_io_interrupt_vectors(i, startVector);
            return B_BUSY;
        }

        sVectors[startVector + i].type = type;
        sVectors[startVector + i].assigned_cpu
            = &sVectorCPUAssignments[startVector + i];
        sVectorCPUAssignments[startVector + i].count = 1;
        sAllocatedIOInterruptVectors[startVector + i] = true;
    }

    dprintf("reserve_io_interrupt_vectors: reserved %ld vectors starting "
            "from %ld\n", count, startVector);
    return B_OK;
}
Beispiel #2
0
status_t
msi_allocate_vectors(uint8 count, uint8 *startVector, uint64 *address,
	uint16 *data)
{
	if (!sMSISupported)
		return B_UNSUPPORTED;

	long vector;
	status_t result = allocate_io_interrupt_vectors(count, &vector);
	if (result != B_OK)
		return result;

	if (vector >= 256) {
		free_io_interrupt_vectors(count, vector);
		return B_NO_MEMORY;
	}

	*startVector = (uint8)vector;
	*address = MSI_ADDRESS_BASE | (sBootCPUAPICId << MSI_DESTINATION_ID_SHIFT)
		| MSI_NO_REDIRECTION | MSI_DESTINATION_MODE_PHYSICAL;
	*data = MSI_TRIGGER_MODE_EDGE | MSI_DELIVERY_MODE_FIXED
		| ((uint16)vector + ARCH_INTERRUPT_BASE);

	dprintf("msi_allocate_vectors: allocated %u vectors starting from %u\n",
		count, *startVector);
	return B_OK;
}
Beispiel #3
0
status_t
msi_allocate_vectors(uint8 count, uint8 *startVector, uint64 *address,
	uint16 *data)
{
	if (!sMSISupported)
		return B_UNSUPPORTED;

	long vector;
	status_t result = allocate_io_interrupt_vectors(count, &vector,
		INTERRUPT_TYPE_IRQ);
	if (result != B_OK)
		return result;

	if (vector >= NUM_IO_VECTORS) {
		free_io_interrupt_vectors(count, vector);
		return B_NO_MEMORY;
	}

	sMSIConfigurations[vector].fAddress = address;
	sMSIConfigurations[vector].fData = data;
	x86_set_irq_source(vector, IRQ_SOURCE_MSI);

	*startVector = (uint8)vector;
	*address = MSI_ADDRESS_BASE | (sBootCPUAPICId << MSI_DESTINATION_ID_SHIFT)
		| MSI_NO_REDIRECTION | MSI_DESTINATION_MODE_PHYSICAL;
	*data = MSI_TRIGGER_MODE_EDGE | MSI_DELIVERY_MODE_FIXED
		| ((uint16)vector + ARCH_INTERRUPT_BASE);

	dprintf("msi_allocate_vectors: allocated %u vectors starting from %u\n",
		count, *startVector);
	return B_OK;
}
Beispiel #4
0
void
msi_free_vectors(uint8 count, uint8 startVector)
{
	if (!sMSISupported) {
		panic("trying to free msi vectors but msi not supported\n");
		return;
	}

	dprintf("msi_free_vectors: freeing %u vectors starting from %u\n", count,
		startVector);

	free_io_interrupt_vectors(count, startVector);
}