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); }
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++; }
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); }
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); }
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); }
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); }