Пример #1
0
int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
{
	void *v_overflow_buffer;
	unsigned long i, bytes;

	bytes = nslabs << IO_TLB_SHIFT;

	io_tlb_nslabs = nslabs;
	io_tlb_start = __pa(tlb);
	io_tlb_end = io_tlb_start + bytes;

	/*
	 * Get the overflow emergency buffer
	 */
	v_overflow_buffer = alloc_bootmem_low_pages_nopanic(
						PAGE_ALIGN(io_tlb_overflow));
	if (!v_overflow_buffer)
		return -ENOMEM;

	io_tlb_overflow_buffer = __pa(v_overflow_buffer);

	/*
	 * Allocate and initialize the free list array.  This array is used
	 * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
	 * between io_tlb_start and io_tlb_end.
	 */
	io_tlb_list = alloc_bootmem_pages(PAGE_ALIGN(io_tlb_nslabs * sizeof(int)));
	for (i = 0; i < io_tlb_nslabs; i++)
 		io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
	io_tlb_index = 0;
	io_tlb_orig_addr = alloc_bootmem_pages(PAGE_ALIGN(io_tlb_nslabs * sizeof(phys_addr_t)));

	if (verbose)
		swiotlb_print_info();

	return 0;
}
Пример #2
0
void  __init
swiotlb_init(int verbose)
{
    size_t default_size = IO_TLB_DEFAULT_SIZE;
    unsigned char *vstart;
    unsigned long bytes;

    if (!io_tlb_nslabs) {
        io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
        io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
    }

    bytes = io_tlb_nslabs << IO_TLB_SHIFT;

    /* Get IO TLB memory from the low pages */
    vstart = alloc_bootmem_low_pages_nopanic(PAGE_ALIGN(bytes));
    if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose))
        return;

    if (io_tlb_start)
        free_bootmem(io_tlb_start,
                     PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT));
    pr_warn("Cannot allocate SWIOTLB buffer");
    no_iotlb_memory = true;
}

/*
 * Systems with larger DMA zones (those that don't support ISA) can
 * initialize the swiotlb later using the slab allocator if needed.
 * This should be just like above, but with some error catching.
 */