コード例 #1
0
ファイル: vm_machdep.c プロジェクト: oza/FreeBSD-7.3-dyntick
/*
 * Functions to map and unmap memory non-cached into KVA the kernel won't try 
 * to allocate. The goal is to provide uncached memory to busdma, to honor
 * BUS_DMA_COHERENT. 
 * We can allocate at most ARM_NOCACHE_KVA_SIZE bytes. 
 * The allocator is rather dummy, each page is represented by a bit in
 * a bitfield, 0 meaning the page is not allocated, 1 meaning it is.
 * As soon as it finds enough contiguous pages to satisfy the request,
 * it returns the address.
 */
void *
arm_remap_nocache(void *addr, vm_size_t size)
{
	int i, j;

	size = round_page(size);
	for (i = 0; i < ARM_NOCACHE_KVA_SIZE / PAGE_SIZE; i++) {
		if (!(arm_nocache_allocated[i / BITS_PER_INT] & (1 << (i % 
		    BITS_PER_INT)))) {
			for (j = i; j < i + (size / (PAGE_SIZE)); j++)
				if (arm_nocache_allocated[j / BITS_PER_INT] &
				    (1 << (j % BITS_PER_INT)))
					break;
			if (j == i + (size / (PAGE_SIZE)))
				break;
		}
	}
	if (i < ARM_NOCACHE_KVA_SIZE / PAGE_SIZE) {
		vm_offset_t tomap = arm_nocache_startaddr + i * PAGE_SIZE;
		void *ret = (void *)tomap;
		vm_paddr_t physaddr = vtophys((vm_offset_t)addr);
		
		for (; tomap < (vm_offset_t)ret + size; tomap += PAGE_SIZE,
		    physaddr += PAGE_SIZE, i++) {
			pmap_kenter_nocache(tomap, physaddr);
			arm_nocache_allocated[i / BITS_PER_INT] |= 1 << (i % 
			    BITS_PER_INT);
		}
		return (ret);
	}

	return (NULL);
}
コード例 #2
0
ファイル: vm_machdep.c プロジェクト: ChaosJohn/freebsd
/*
 * Functions to map and unmap memory non-cached into KVA the kernel won't try
 * to allocate. The goal is to provide uncached memory to busdma, to honor
 * BUS_DMA_COHERENT.
 * We can allocate at most ARM_NOCACHE_KVA_SIZE bytes.
 * The allocator is rather dummy, each page is represented by a bit in
 * a bitfield, 0 meaning the page is not allocated, 1 meaning it is.
 * As soon as it finds enough contiguous pages to satisfy the request,
 * it returns the address.
 */
void *
arm_remap_nocache(void *addr, vm_size_t size)
{
	int i, j;

	size = round_page(size);
	for (i = 0; i < ARM_NOCACHE_KVA_SIZE / PAGE_SIZE; i++) {
		if (!(arm_nocache_allocated[i / BITS_PER_INT] & (1 << (i %
		    BITS_PER_INT)))) {
			for (j = i; j < i + (size / (PAGE_SIZE)); j++)
				if (arm_nocache_allocated[j / BITS_PER_INT] &
				    (1 << (j % BITS_PER_INT)))
					break;
			if (j == i + (size / (PAGE_SIZE)))
				break;
		}
	}
	if (i < ARM_NOCACHE_KVA_SIZE / PAGE_SIZE) {
		vm_offset_t tomap = arm_nocache_startaddr + i * PAGE_SIZE;
		void *ret = (void *)tomap;
		vm_paddr_t physaddr = vtophys((vm_offset_t)addr);
		vm_offset_t vaddr = (vm_offset_t) addr;
		
		vaddr = vaddr & ~PAGE_MASK;
		for (; tomap < (vm_offset_t)ret + size; tomap += PAGE_SIZE,
		    vaddr += PAGE_SIZE, physaddr += PAGE_SIZE, i++) {
			cpu_idcache_wbinv_range(vaddr, PAGE_SIZE);
#ifdef ARM_L2_PIPT
			cpu_l2cache_wbinv_range(physaddr, PAGE_SIZE);
#else
			cpu_l2cache_wbinv_range(vaddr, PAGE_SIZE);
#endif
			pmap_kenter_nocache(tomap, physaddr);
			cpu_tlb_flushID_SE(vaddr);
			arm_nocache_allocated[i / BITS_PER_INT] |= 1 << (i %
			    BITS_PER_INT);
		}
		return (ret);
	}

	return (NULL);
}
コード例 #3
0
void
platform_mp_start_ap(void)
{
	uint32_t reg, *ptr, cpu_num;

	/* Copy boot code to SRAM */
	*((unsigned int*)(0xf1020240)) = 0xffff0101;
	*((unsigned int*)(0xf1008500)) = 0xffff0003;

	pmap_kenter_nocache(0x880f0000, 0xffff0000);
	reg = 0x880f0000;

	for (ptr = (uint32_t *)mptramp; ptr < (uint32_t *)mpentry;
	    ptr++, reg += 4)
		*((uint32_t *)reg) = *ptr;

	if (mp_ncpus > 1) {
		reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0);
		reg &= 0x00ffffff;
		reg |= 0x01000000;
		write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0, reg);
	}
	if (mp_ncpus > 2) {
		reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1);
		reg &= 0xff00ffff;
		reg |= 0x00010000;
		write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg);
	}
	if (mp_ncpus > 3) {
		reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1);
		reg &= 0x00ffffff;
		reg |= 0x01000000;
		write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg);
	}

	reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0);
	reg |= ((0x1 << (mp_ncpus - 1)) - 1) << 21;
	write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);
	reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0);
	reg |= 0x01000000;
	write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);

	DELAY(100);
	reg &= ~(0xf << 21);
	write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);
	DELAY(100);

	bus_space_write_4(fdtbus_bs_tag, MV_BASE, CPU_RESUME_CONTROL, 0);

	for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ )
		bus_space_write_4(fdtbus_bs_tag, CPU_PMU(cpu_num), CPU_PMU_BOOT,
		    pmap_kextract((vm_offset_t)mpentry));

	cpu_idcache_wbinv_all();

	for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ )
		bus_space_write_4(fdtbus_bs_tag, MP, MP_SW_RESET(cpu_num), 0);

	/* XXX: Temporary workaround for hangup after releasing AP's */
	wmb();
	DELAY(10);

	initialize_coherency_fabric();
}