Пример #1
0
int
__check_dram(paddr_t start, paddr_t end)
{
	u_int8_t *page;
	int i, x;

	_DPRINTF(" checking...");
	for (; start < end; start += NBPG) {
		page = (u_int8_t *)SH3_PHYS_TO_P2SEG (start);
		x = random();
		for (i = 0; i < NBPG; i += 4)
			*(volatile int *)(page + i) = (x ^ i);
		for (i = 0; i < NBPG; i += 4)
			if (*(volatile int *)(page + i) != (x ^ i))
				goto bad;
		x = random();
		for (i = 0; i < NBPG; i += 4)
			*(volatile int *)(page + i) = (x ^ i);
		for (i = 0; i < NBPG; i += 4)
			if (*(volatile int *)(page + i) != (x ^ i))
				goto bad;
	}
	_DPRINTF("success.\n");
	return (0);
 bad:
	_DPRINTF("failed.\n");
	return (1);
}
Пример #2
0
void
__find_dram_shadow(paddr_t start, paddr_t end)
{
	vaddr_t page, startaddr, endaddr;
	int x;

	_DPRINTF("search D-RAM from 0x%08lx for 0x%08lx\n", start, end);
	startaddr = SH3_PHYS_TO_P2SEG(start);
	endaddr = SH3_PHYS_TO_P2SEG(end);

	page = startaddr;

	x = random();
	*(volatile int *)(page + 0) = x;
	*(volatile int *)(page + 4) = ~x;

	if (*(volatile int *)(page + 0) != x ||
	    *(volatile int *)(page + 4) != ~x)
		return;

	for (page += NBPG; page < endaddr; page += NBPG) {
		if (*(volatile int *)(page + 0) == x &&
		    *(volatile int *)(page + 4) == ~x) {
			goto memend_found;
		}
	}

	page -= NBPG;
	*(volatile int *)(page + 0) = x;
	*(volatile int *)(page + 4) = ~x;

	if (*(volatile int *)(page + 0) != x ||
	    *(volatile int *)(page + 4) != ~x)
		return; /* no memory in this bank */

 memend_found:
	KASSERT(mem_cluster_cnt < VM_PHYSSEG_MAX);

	mem_clusters[mem_cluster_cnt].start = start;
	mem_clusters[mem_cluster_cnt].size = page - startaddr;

	/* skip kernel area */
	if (mem_cluster_cnt == 1)
		mem_clusters[1].size -= mem_clusters[0].size;

	mem_cluster_cnt++;
}
Пример #3
0
int
_bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
    size_t size, caddr_t *kvap, int flags)
{
	vaddr_t va;
	bus_addr_t addr;
	int curseg;
	const struct kmem_dyn_mode *kd;

	DPRINTF(("bus_dmamem_map: t = %p, segs = %p, nsegs = %d, size = %d, kvap = %p, flags = %x\n", t, segs, nsegs, size, kvap, flags));

        /*
	 * If we're only mapping 1 segment, use P2SEG, to avoid
	 * TLB thrashing.
	 */
	if (nsegs == 1) {
		if (flags & BUS_DMA_COHERENT) {
			*kvap = (caddr_t)SH3_PHYS_TO_P2SEG(segs[0].ds_addr);
		} else {
			*kvap = (caddr_t)SH3_PHYS_TO_P1SEG(segs[0].ds_addr);
		}
		DPRINTF(("bus_dmamem_map: addr = 0x%08lx, kva = %p\n", segs[0].ds_addr, *kvap));
		return 0;
	}

	/* Always round the size. */
	size = round_page(size);
	kd = flags & BUS_DMA_NOWAIT ? &kd_trylock : &kd_waitok;
	va = (vaddr_t)km_alloc(size, &kv_any, &kp_none, kd);
	if (va == 0)
		return (ENOMEM);

	*kvap = (caddr_t)va;
	for (curseg = 0; curseg < nsegs; curseg++) {
		DPRINTF(("bus_dmamem_map: segs[%d]: ds_addr = 0x%08lx, ds_len = %ld\n", curseg, segs[curseg].ds_addr, segs[curseg].ds_len));
		for (addr = segs[curseg].ds_addr;
		     addr < segs[curseg].ds_addr + segs[curseg].ds_len;
		     addr += PAGE_SIZE, va += PAGE_SIZE, size -= PAGE_SIZE) {
			if (size == 0)
				panic("_bus_dmamem_map: size botch");
			pmap_kenter_pa(va, addr,
			    PROT_READ | PROT_WRITE);
		}
	}
	pmap_update(pmap_kernel());

	return (0);
}
Пример #4
0
int
obio_iomem_map(void *v, bus_addr_t bpa, bus_size_t size,
    int flags, bus_space_handle_t *bshp)
{
	bus_addr_t addr = SH3_PHYS_TO_P2SEG(bpa);
	int error;

	KASSERT((bpa & SH3_PHYS_MASK) == bpa);

	if (bpa < 0x14000000 || bpa >= 0x1c000000) {
		/* CS0,1,2,3,4,7 */
		*bshp = (bus_space_handle_t)addr;
		return (0);
	}

	/* CS5,6 */
	error = obio_iomem_add_mapping(addr, size, (int)(u_long)v, bshp);

	return (error);
}
Пример #5
0
int
_bus_dmamap_load_paddr(bus_dma_tag_t t, bus_dmamap_t map,
    paddr_t paddr, vaddr_t vaddr, bus_size_t size)
{
	bus_dma_segment_t * const segs = map->dm_segs;
	bus_addr_t bmask = ~(map->_dm_boundary - 1);

	int first = map->dm_mapsize == 0;
	int nseg = map->dm_nsegs;
	paddr_t lastaddr = SH3_P2SEG_TO_PHYS(segs[nseg].ds_addr);

	map->dm_mapsize += size;

	do {
		bus_size_t sgsize = size;

		/* Make sure we don't cross any boundaries. */
		if (map->_dm_boundary > 0) {
			bus_addr_t baddr; /* next boundary address */

			baddr = (paddr + map->_dm_boundary) & bmask;
			if (sgsize > (baddr - paddr))
				sgsize = (baddr - paddr);
		}

		/*
		 * Insert chunk into a segment, coalescing with
		 * previous segment if possible.
		 */
		if (first) {
			/* first segment */
			segs[nseg].ds_addr = SH3_PHYS_TO_P2SEG(paddr);
			segs[nseg].ds_len = sgsize;
			segs[nseg]._ds_vaddr = vaddr;
			first = 0;
		} else if ((paddr == lastaddr)
		 && (segs[nseg].ds_len + sgsize <= map->_dm_maxsegsz)
		 && (map->_dm_boundary == 0 ||
		     (segs[nseg].ds_addr & bmask) == (paddr & bmask))) {
			/* coalesce */
			segs[nseg].ds_len += sgsize;
		} else {
			if (++nseg >= map->_dm_segcnt)
				return (EFBIG);

			/* new segment */
			segs[nseg].ds_addr = SH3_PHYS_TO_P2SEG(paddr);
			segs[nseg].ds_len = sgsize;
			segs[nseg]._ds_vaddr = vaddr;
		}

		lastaddr = paddr + sgsize;
		paddr += sgsize;
		vaddr += sgsize;
		size -= sgsize;
	} while (size > 0);

	map->dm_nsegs = nseg;

	return (0);
}
Пример #6
0
void
dumpsys()
{
	cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
	daddr64_t blkno;
	int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
	u_int page = 0;
	paddr_t dumppa;
	u_int seg;
	int rc;
	extern int msgbufmapped;

	/* Don't record dump messages in msgbuf. */
	msgbufmapped = 0;

	/* Make sure dump settings are valid. */
	if (dumpdev == NODEV)
		return;
	if (dumpsize == 0) {
		dumpconf();
		if (dumpsize == 0)
			return;
	}
	if (dumplo <= 0) {
		printf("\ndump to dev 0x%x not possible, not enough space\n",
		    dumpdev);
		return;
	}

	dump = bdevsw[major(dumpdev)].d_dump;
	blkno = dumplo;

	printf("\ndumping to dev 0x%x offset %ld\n", dumpdev, dumplo);

#ifdef UVM_SWAP_ENCRYPT
	uvm_swap_finicrypt_all();
#endif

	printf("dump ");

	/* Write dump header */
	rc = cpu_dump(dump, &blkno);
	if (rc != 0)
		goto bad;

	for (seg = 0; seg < h->kcore_nsegs; seg++) {
		u_int pagesleft;

		pagesleft = atop(h->kcore_segs[seg].size);
		dumppa = (paddr_t)h->kcore_segs[seg].start;

		while (pagesleft != 0) {
			u_int npages;

#define	NPGMB	atop(1024 * 1024)
			if (page != 0 && (page % NPGMB) == 0)
				printf("%u ", page / NPGMB);

			/* do not dump more than 1MB at once */
			npages = min(pagesleft, NPGMB);
#undef NPGMB
			npages = min(npages, dumpsize);

			rc = (*dump)(dumpdev, blkno,
			    (caddr_t)SH3_PHYS_TO_P2SEG(dumppa), ptoa(npages));
			if (rc != 0)
				goto bad;

			pagesleft -= npages;
			dumppa += ptoa(npages);
			page += npages;
			dumpsize -= npages;
			if (dumpsize == 0)
				goto bad;	/* if truncated dump */
			blkno += ctod(npages);
		}
	}
bad:
	switch (rc) {
	case 0:
		printf("succeeded\n");
		break;
	case ENXIO:
		printf("device bad\n");
		break;
	case EFAULT:
		printf("device not ready\n");
		break;
	case EINVAL:
		printf("area improper\n");
		break;
	case EIO:
		printf("I/O error\n");
		break;
	case EINTR:
		printf("aborted\n");
		break;
	default:
		printf("error %d\n", rc);
		break;
	}

	/* make sure console can output our last message */
	delay(1 * 1000 * 1000);
}