// SPDX-License-Identifier: GPL-2.0-or-later /* ** System Bus Adapter (SBA) I/O MMU manager ** ** (c) Copyright 2000-2004 Grant Grundler <grundler @ parisc-linux x org> ** (c) Copyright 2004 Naresh Kumar Inna <knaresh at india x hp x com> ** (c) Copyright 2000-2004 Hewlett-Packard Company ** ** Portions (c) 1999 Dave S. Miller (from sparc64 I/O MMU code) ** ** ** ** This module initializes the IOC (I/O Controller) found on B1000/C3000/ ** J5000/J7000/N-class/L-class machines and their successors. ** ** FIXME: add DMA hint support programming in both sba and lba modules.
*/
#include <linux/mm.h> #include <linux/string.h> #include <linux/pci.h> #include <linux/dma-map-ops.h> #include <linux/scatterlist.h> #include <linux/iommu-helper.h> /* * The semantics of 64 register access on 32bit systems can't be guaranteed * by the C standard, we hope the _lo_hi() macros defining readq and writeq * here will behave as expected.
*/ #include <linux/io-64-nonatomic-lo-hi.h>
#include <asm/byteorder.h> #include <asm/io.h> #include <asm/dma.h> /* for DMA_CHUNK_SIZE */
#include <asm/hardware.h> /* for register_parisc_driver() stuff */
#include <asm/ropes.h> #include <asm/page.h> /* for PAGE0 */ #include <asm/pdc.h> /* for PDC_MODEL_* */ #include <asm/pdcpat.h> /* for is_pdc_pat() */ #include <asm/parisc-device.h>
#include"iommu.h"
#define MODULE_NAME "SBA"
/* ** The number of debug flags is a clue - this code is fragile. ** Don't even think about messing with it unless you have ** plenty of 710's to sacrifice to the computer gods. :^)
*/ #undef DEBUG_SBA_INIT #undef DEBUG_SBA_RUN #undef DEBUG_SBA_RUN_SG #undef DEBUG_SBA_RESOURCE #undef ASSERT_PDIR_SANITY #undef DEBUG_LARGE_SG_ENTRIES #undef DEBUG_DMB_TRAP
/* NOTE: When CONFIG_64BIT isn't defined, READ_REG64() is two 32-bit reads */
/** * sba_dump_ranges - debugging only - print ranges assigned to this IOA * @hpa: base address of the sba * * Print the MMIO and IO Port address ranges forwarded by an Astro/Ike/RIO * IO Adapter (aka Bus Converter).
*/ staticvoid
sba_dump_ranges(void __iomem *hpa)
{
DBG_INIT("SBA at 0x%p\n", hpa);
DBG_INIT("IOS_DIST_BASE : %Lx\n", READ_REG64(hpa+IOS_DIST_BASE));
DBG_INIT("IOS_DIST_MASK : %Lx\n", READ_REG64(hpa+IOS_DIST_MASK));
DBG_INIT("IOS_DIST_ROUTE : %Lx\n", READ_REG64(hpa+IOS_DIST_ROUTE));
DBG_INIT("\n");
DBG_INIT("IOS_DIRECT_BASE : %Lx\n", READ_REG64(hpa+IOS_DIRECT_BASE));
DBG_INIT("IOS_DIRECT_MASK : %Lx\n", READ_REG64(hpa+IOS_DIRECT_MASK));
DBG_INIT("IOS_DIRECT_ROUTE: %Lx\n", READ_REG64(hpa+IOS_DIRECT_ROUTE));
}
/** * sba_dump_tlb - debugging only - print IOMMU operating parameters * @hpa: base address of the IOMMU * * Print the size/location of the IO MMU PDIR.
*/ staticvoid sba_dump_tlb(void __iomem *hpa)
{
DBG_INIT("IO TLB at 0x%p\n", hpa);
DBG_INIT("IOC_IBASE : 0x%Lx\n", READ_REG64(hpa+IOC_IBASE));
DBG_INIT("IOC_IMASK : 0x%Lx\n", READ_REG64(hpa+IOC_IMASK));
DBG_INIT("IOC_TCNFG : 0x%Lx\n", READ_REG64(hpa+IOC_TCNFG));
DBG_INIT("IOC_PDIR_BASE: 0x%Lx\n", READ_REG64(hpa+IOC_PDIR_BASE));
DBG_INIT("\n");
} #else #define sba_dump_ranges(x) #define sba_dump_tlb(x) #endif/* DEBUG_SBA_INIT */
#ifdef ASSERT_PDIR_SANITY
/** * sba_dump_pdir_entry - debugging only - print one IOMMU PDIR entry * @ioc: IO MMU structure which owns the pdir we are interested in. * @msg: text to print ont the output line. * @pide: pdir index. * * Print one entry of the IO MMU PDIR in human readable form.
*/ staticvoid
sba_dump_pdir_entry(struct ioc *ioc, char *msg, uint pide)
{ /* start printing from lowest pde in rval */
__le64 *ptr = &(ioc->pdir_base[pide & (~0U * BITS_PER_LONG)]); unsignedlong *rptr = (unsignedlong *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsignedlong) - 1)]);
uint rcnt;
printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n",
msg,
rptr, pide & (BITS_PER_LONG - 1), *rptr);
/** * sba_check_pdir - debugging only - consistency checker * @ioc: IO MMU structure which owns the pdir we are interested in. * @msg: text to print ont the output line. * * Verify the resource map and pdir state is consistent
*/ staticint
sba_check_pdir(struct ioc *ioc, char *msg)
{
u32 *rptr_end = (u32 *) &(ioc->res_map[ioc->res_size]);
u32 *rptr = (u32 *) ioc->res_map; /* resource map ptr */
u64 *pptr = ioc->pdir_base; /* pdir ptr */
uint pide = 0;
while (rptr < rptr_end) {
u32 rval = *rptr; int rcnt = 32; /* number of bits we might check */
while (rcnt) { /* Get last byte and highest bit from that */
u32 pde = ((u32) (((char *)pptr)[7])) << 24; if ((rval ^ pde) & 0x80000000)
{ /* ** BUMMER! -- res_map != pdir -- ** Dump rval and matching pdir entries
*/
sba_dump_pdir_entry(ioc, msg, pide); return(1);
}
rcnt--;
rval <<= 1; /* try the next bit */
pptr++;
pide++;
}
rptr++; /* look at next word of res_map */
} /* It'd be nice if we always got here :^) */ return 0;
}
/** * sba_dump_sg - debugging only - print Scatter-Gather list * @ioc: IO MMU structure which owns the pdir we are interested in. * @startsg: head of the SG list * @nents: number of entries in SG list * * print the SG list so we can verify it's correct by hand.
*/ staticvoid
sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
{ while (nents-- > 0) {
printk(KERN_DEBUG " %d : %08lx/%05x %p/%05x\n",
nents,
(unsignedlong) sg_dma_address(startsg),
sg_dma_len(startsg),
sg_virt(startsg), startsg->length);
startsg++;
}
}
#endif/* ASSERT_PDIR_SANITY */
/************************************************************** * * I/O Pdir Resource Management * * Bits set in the resource map are in use. * Each bit can represent a number of pages. * LSbs represent lower addresses (IOVA's). *
***************************************************************/ #define PAGES_PER_RANGE 1 /* could increase this to 4 or 8 if needed */
/* Convert from IOVP to IOVA and vice versa. */
#ifdef ZX1_SUPPORT /* Pluto (aka ZX1) boxes need to set or clear the ibase bits appropriately */ #define SBA_IOVA(ioc,iovp,offset,hint_reg) ((ioc->ibase) | (iovp) | (offset)) #define SBA_IOVP(ioc,iova) ((iova) & (ioc)->iovp_mask) #else /* only support Astro and ancestors. Saves a few cycles in key places */ #define SBA_IOVA(ioc,iovp,offset,hint_reg) ((iovp) | (offset)) #define SBA_IOVP(ioc,iova) (iova) #endif
/** * sba_search_bitmap - find free space in IO PDIR resource bitmap * @ioc: IO MMU structure which owns the pdir we are interested in. * @dev: device to query the bitmap for * @bits_wanted: number of entries we need. * * Find consecutive free bits in resource bitmap. * Each bit represents one entry in the IO Pdir. * Cool perf optimization: search for log2(size) bits at a time.
*/ staticunsignedlong
sba_search_bitmap(struct ioc *ioc, struct device *dev, unsignedlong bits_wanted)
{ unsignedlong *res_ptr = ioc->res_hint; unsignedlong *res_end = (unsignedlong *) &(ioc->res_map[ioc->res_size]); unsignedlong pide = ~0UL, tpide; unsignedlong boundary_size; unsignedlong shift; int ret;
if (bits_wanted > (BITS_PER_LONG/2)) { /* Search word at a time - no mask needed */ for(; res_ptr < res_end; ++res_ptr) {
tpide = ptr_to_pide(ioc, res_ptr, 0);
ret = iommu_is_span_boundary(tpide, bits_wanted,
shift,
boundary_size); if ((*res_ptr == 0) && !ret) {
*res_ptr = RESMAP_MASK(bits_wanted);
pide = tpide; break;
}
} /* point to the next word on next pass */
res_ptr++;
ioc->res_bitshift = 0;
} else { /* ** Search the resource bit map on well-aligned values. ** "o" is the alignment. ** We need the alignment to invalidate I/O TLB using ** SBA HW features in the unmap path.
*/ unsignedlong o = 1 << get_order(bits_wanted << PAGE_SHIFT);
uint bitshiftcnt = ALIGN(ioc->res_bitshift, o); unsignedlong mask;
/** * sba_alloc_range - find free bits and mark them in IO PDIR resource bitmap * @ioc: IO MMU structure which owns the pdir we are interested in. * @dev: device for which pages should be alloced * @size: number of bytes to create a mapping for * * Given a size, find consecutive unmarked and then mark those bits in the * resource bit map.
*/ staticint
sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
{ unsignedint pages_needed = size >> IOVP_SHIFT; #ifdef SBA_COLLECT_STATS unsignedlong cr_start = mfctl(16); #endif unsignedlong pide;
pide = sba_search_bitmap(ioc, dev, pages_needed); if (pide >= (ioc->res_size << 3)) {
pide = sba_search_bitmap(ioc, dev, pages_needed); if (pide >= (ioc->res_size << 3))
panic("%s: I/O MMU @ %p is out of mapping resources\n",
__FILE__, ioc->ioc_hpa);
}
#ifdef ASSERT_PDIR_SANITY /* verify the first enable bit is clear */ if(0x00 != ((u8 *) ioc->pdir_base)[pide*sizeof(u64) + 7]) {
sba_dump_pdir_entry(ioc, "sba_search_bitmap() botched it?", pide);
} #endif
/** * sba_io_pdir_entry - fill in one IO PDIR entry * @pdir_ptr: pointer to IO PDIR entry * @sid: process Space ID - currently only support KERNEL_SPACE * @vba: Virtual CPU address of buffer to map * @hint: DMA hint set to use for this mapping * * SBA Mapping Routine * * Given a virtual address (vba, arg2) and space id, (sid, arg1) * sba_io_pdir_entry() loads the I/O PDIR entry pointed to by * pdir_ptr (arg0). * Using the bass-ackwards HP bit numbering, Each IO Pdir entry * for Astro/Ike looks like: * * * 0 19 51 55 63 * +-+---------------------+----------------------------------+----+--------+ * |V| U | PPN[43:12] | U | VI | * +-+---------------------+----------------------------------+----+--------+ * * Pluto is basically identical, supports fewer physical address bits: * * 0 23 51 55 63 * +-+------------------------+-------------------------------+----+--------+ * |V| U | PPN[39:12] | U | VI | * +-+------------------------+-------------------------------+----+--------+ * * V == Valid Bit (Most Significant Bit is bit 0) * U == Unused * PPN == Physical Page Number * VI == Virtual Index (aka Coherent Index) * * LPA instruction output is put into PPN field. * LCI (Load Coherence Index) instruction provides the "VI" bits. * * We pre-swap the bytes since PCX-W is Big Endian and the * IOMMU uses little endian for the pdir.
*/
asm("lci 0(%1), %0" : "=r" (ci) : "r" (vba));
pa |= (ci >> PAGE_SHIFT) & 0xff; /* move CI (8 bits) into lowest byte */
pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */
*pdir_ptr = cpu_to_le64(pa); /* swap and store into I/O Pdir */
/* * If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit set * (bit #61, big endian), we have to flush and sync every time * IO-PDIR is changed in Ike/Astro.
*/
asm_io_fdc(pdir_ptr);
}
/** * sba_mark_invalid - invalidate one or more IO PDIR entries * @ioc: IO MMU structure which owns the pdir we are interested in. * @iova: IO Virtual Address mapped earlier * @byte_cnt: number of bytes this mapping covers. * * Marking the IO PDIR entry(ies) as Invalid and invalidate * corresponding IO TLB entry. The Ike PCOM (Purge Command Register) * is to purge stale entries in the IO TLB when unmapping entries. * * The PCOM register supports purging of multiple pages, with a minium * of 1 page and a maximum of 2GB. Hardware requires the address be * aligned to the size of the range being purged. The size of the range * must be a power of 2. The "Cool perf optimization" in the * allocation routine helps keep that true.
*/ staticvoid
sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
{
u32 iovp = (u32) SBA_IOVP(ioc,iova);
__le64 *pdir_ptr = &ioc->pdir_base[PDIR_INDEX(iovp)];
#ifdef ASSERT_PDIR_SANITY /* Assert first pdir entry is set. ** ** Even though this is a big-endian machine, the entries ** in the iopdir are little endian. That's why we look at ** the byte at +7 instead of at +0.
*/ if (0x80 != (((u8 *) pdir_ptr)[7])) {
sba_dump_pdir_entry(ioc,"sba_mark_invalid()", PDIR_INDEX(iovp));
} #endif
/* set "size" field for PCOM */
iovp |= get_order(byte_cnt) + PAGE_SHIFT;
do { /* clear I/O Pdir entry "valid" bit first */
((u8 *) pdir_ptr)[7] = 0;
asm_io_fdc(pdir_ptr); if (ioc_needs_fdc) { #if 0
entries_per_cacheline = L1_CACHE_SHIFT - 3; #endif
}
pdir_ptr++;
byte_cnt -= IOVP_SIZE;
} while (byte_cnt > IOVP_SIZE);
} else
iovp |= IOVP_SHIFT; /* set "size" field for PCOM */
/* ** clear I/O PDIR entry "valid" bit. ** We have to R/M/W the cacheline regardless how much of the ** pdir entry that we clobber. ** The rest of the entry would be useful for debugging if we ** could dump core on HPMC.
*/
((u8 *) pdir_ptr)[7] = 0;
asm_io_fdc(pdir_ptr);
/** * sba_dma_supported - PCI driver can query DMA support * @dev: instance of PCI owned by the driver that's asking * @mask: number of address bits this PCI device can handle * * See Documentation/core-api/dma-api-howto.rst
*/ staticint sba_dma_supported( struct device *dev, u64 mask)
{ struct ioc *ioc;
if (dev == NULL) {
printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
BUG(); return(0);
}
ioc = GET_IOC(dev); if (!ioc) return 0;
/* * check if mask is >= than the current max IO Virt Address * The max IO Virt address will *always* < 30 bits.
*/ return((int)(mask >= (ioc->ibase - 1 +
(ioc->pdir_size / sizeof(u64) * IOVP_SIZE) )));
}
/** * sba_map_single - map one buffer and return IOVA for DMA * @dev: instance of PCI owned by the driver that's asking. * @addr: driver buffer to map. * @size: number of bytes to map in driver buffer. * @direction: R/W or both. * * See Documentation/core-api/dma-api-howto.rst
*/ static dma_addr_t
sba_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction)
{ struct ioc *ioc; unsignedlong flags;
dma_addr_t iovp;
dma_addr_t offset;
__le64 *pdir_start; int pide;
ioc = GET_IOC(dev); if (!ioc) return DMA_MAPPING_ERROR;
#if DELAYED_RESOURCE_CNT > 0 /* Delaying when we re-use a IO Pdir entry reduces the number * of MMIO reads needed to flush writes to the PCOM register.
*/
d = &(ioc->saved[ioc->saved_cnt]);
d->iova = iova;
d->size = size; if (++(ioc->saved_cnt) >= DELAYED_RESOURCE_CNT) { int cnt = ioc->saved_cnt; while (cnt--) {
sba_free_range(ioc, d->iova, d->size);
d--;
}
ioc->saved_cnt = 0;
/* XXX REVISIT for 2.5 Linux - need syncdma for zero-copy support. ** For Astro based systems this isn't a big deal WRT performance. ** As long as 2.4 kernels copyin/copyout data from/to userspace, ** we don't need the syncdma. The issue here is I/O MMU cachelines ** are *not* coherent in all cases. May be hwrev dependent. ** Need to investigate more. asm volatile("syncdma");
*/
}
/** * sba_alloc - allocate/map shared mem for DMA * @hwdev: instance of PCI owned by the driver that's asking. * @size: number of bytes mapped in driver buffer. * @dma_handle: IOVA of new buffer. * @gfp: allocation flags * @attrs: attributes * * See Documentation/core-api/dma-api-howto.rst
*/ staticvoid *sba_alloc(struct device *hwdev, size_t size, dma_addr_t *dma_handle,
gfp_t gfp, unsignedlong attrs)
{ void *ret;
if (!hwdev) { /* only support PCI */
*dma_handle = 0; return NULL;
}
ret = (void *) __get_free_pages(gfp, get_order(size));
/** * sba_free - free/unmap shared mem for DMA * @hwdev: instance of PCI owned by the driver that's asking. * @size: number of bytes mapped in driver buffer. * @vaddr: virtual address IOVA of "consistent" buffer. * @dma_handle: IO virtual address of "consistent" buffer. * @attrs: attributes * * See Documentation/core-api/dma-api-howto.rst
*/ staticvoid
sba_free(struct device *hwdev, size_t size, void *vaddr,
dma_addr_t dma_handle, unsignedlong attrs)
{
sba_unmap_page(hwdev, dma_handle, size, 0, 0);
free_pages((unsignedlong) vaddr, get_order(size));
}
/* ** Since 0 is a valid pdir_base index value, can't use that ** to determine if a value is valid or not. Use a flag to indicate ** the SG list entry contains a valid pdir index.
*/ #define PIDE_FLAG 0x80000000UL
#ifdef DEBUG_LARGE_SG_ENTRIES int dump_run_sg = 0; #endif
/** * sba_map_sg - map Scatter/Gather list * @dev: instance of PCI owned by the driver that's asking. * @sglist: array of buffer/length pairs * @nents: number of entries in list * @direction: R/W or both. * @attrs: attributes * * See Documentation/core-api/dma-api-howto.rst
*/ staticint
sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction, unsignedlong attrs)
{ struct ioc *ioc; int filled = 0; unsignedlong flags;
/* Fast path single entry scatterlists. */ if (nents == 1) {
sg_dma_address(sglist) = sba_map_single(dev, sg_virt(sglist),
sglist->length, direction);
sg_dma_len(sglist) = sglist->length; return 1;
}
spin_lock_irqsave(&ioc->res_lock, flags);
#ifdef ASSERT_PDIR_SANITY if (sba_check_pdir(ioc,"Check before sba_map_sg()"))
{
sba_dump_sg(ioc, sglist, nents);
panic("Check before sba_map_sg()");
} #endif
#ifdef SBA_COLLECT_STATS
ioc->msg_calls++; #endif
/* ** First coalesce the chunks and allocate I/O pdir space ** ** If this is one DMA stream, we can properly map using the ** correct virtual address associated with each DMA page. ** w/o this association, we wouldn't have coherent DMA! ** Access to the virtual address is what forces a two pass algorithm.
*/
iommu_coalesce_chunks(ioc, dev, sglist, nents, sba_alloc_range);
/* ** Program the I/O Pdir ** ** map the virtual addresses to the I/O Pdir ** o dma_address will contain the pdir index ** o dma_len will contain the number of bytes to map ** o address contains the virtual address.
*/
filled = iommu_fill_pdir(ioc, sglist, nents, 0, sba_io_pdir_entry);
/* force FDC ops in io_pdir_entry() to be visible to IOMMU */
asm_io_sync();
#ifdef ASSERT_PDIR_SANITY if (sba_check_pdir(ioc,"Check after sba_map_sg()"))
{
sba_dump_sg(ioc, sglist, nents);
panic("Check after sba_map_sg()\n");
} #endif
/************************************************************************** ** ** SBA PAT PDC support ** ** o call pdc_pat_cell_module() ** o store ranges in PCI "resource" structures **
**************************************************************************/
staticvoid
sba_get_pat_resources(struct sba_device *sba_dev)
{ #if 0 /* ** TODO/REVISIT/FIXME: support for directed ranges requires calls to ** PAT PDC to program the SBA/LBA directed range registers...this ** burden may fall on the LBA code since it directly supports the ** PCI subsystem. It's not clear yet. - ggg
*/
PAT_MOD(mod)->mod_info.mod_pages = PAT_GET_MOD_PAGES(temp);
FIXME : ???
PAT_MOD(mod)->mod_info.dvi = PAT_GET_DVI(temp);
Tells where the dvi bits are located in the address.
PAT_MOD(mod)->mod_info.ioc = PAT_GET_IOC(temp);
FIXME : ??? #endif
}
/************************************************************** * * Initialization and claim *
***************************************************************/ #define PIRANHA_ADDR_MASK 0x00160000UL /* bit 17,18,20 */ #define PIRANHA_ADDR_VAL 0x00060000UL /* bit 17,18 on */ staticvoid *
sba_alloc_pdir(unsignedint pdir_size)
{ unsignedlong pdir_base; unsignedlong pdir_order = get_order(pdir_size);
pdir_base = __get_free_pages(GFP_KERNEL, pdir_order); if (NULL == (void *) pdir_base) {
panic("%s() could not allocate I/O Page Table\n",
__func__);
}
/* If this is not PA8700 (PCX-W2) ** OR newer than ver 2.2 ** OR in a system that doesn't need VINDEX bits from SBA, ** ** then we aren't exposed to the HW bug.
*/ if ( ((boot_cpu_data.pdc.cpuid >> 5) & 0x7f) != 0x13
|| (boot_cpu_data.pdc.versions > 0x202)
|| (boot_cpu_data.pdc.capabilities & 0x08L) ) return (void *) pdir_base;
/* * PA8700 (PCX-W2, aka piranha) silent data corruption fix * * An interaction between PA8700 CPU (Ver 2.2 or older) and * Ike/Astro can cause silent data corruption. This is only * a problem if the I/O PDIR is located in memory such that * (little-endian) bits 17 and 18 are on and bit 20 is off. * * Since the max IO Pdir size is 2MB, by cleverly allocating the * right physical address, we can either avoid (IOPDIR <= 1MB) * or minimize (2MB IO Pdir) the problem if we restrict the * IO Pdir to a maximum size of 2MB-128K (1902K). * * Because we always allocate 2^N sized IO pdirs, either of the * "bad" regions will be the last 128K if at all. That's easy * to test for. *
*/ if (pdir_order <= (19-12)) { if (((virt_to_phys(pdir_base)+pdir_size-1) & PIRANHA_ADDR_MASK) == PIRANHA_ADDR_VAL) { /* allocate a new one on 512k alignment */ unsignedlong new_pdir = __get_free_pages(GFP_KERNEL, (19-12)); /* release original */
free_pages(pdir_base, pdir_order);
pdir_base = new_pdir;
/* release excess */ while (pdir_order < (19-12)) {
new_pdir += pdir_size;
free_pages(new_pdir, pdir_order);
pdir_order +=1;
pdir_size <<=1;
}
}
} else { /* ** 1MB or 2MB Pdir ** Needs to be aligned on an "odd" 1MB boundary.
*/ unsignedlong new_pdir = __get_free_pages(GFP_KERNEL, pdir_order+1); /* 2 or 4MB */
/* release original */
free_pages( pdir_base, pdir_order);
/* release first 1MB */
free_pages(new_pdir, 20-12);
pdir_base = new_pdir + 1024*1024;
if (pdir_order > (20-12)) { /* ** 2MB Pdir. ** ** Flag tells init_bitmap() to mark bad 128k as used ** and to reduce the size by 128k.
*/
piranha_bad_128k = 1;
new_pdir += 3*1024*1024; /* release last 1MB */
free_pages(new_pdir, 20-12);
if (IS_QUICKSILVER(lba))
*agp_found = 1; return 0;
} #endif
staticvoid
sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
{
u32 iova_space_mask;
u32 iova_space_size; int iov_order, tcnfg; #ifdef SBA_AGP_SUPPORT int agp_found = 0; #endif /* ** Firmware programs the base and size of a "safe IOVA space" ** (one that doesn't overlap memory or LMMIO space) in the ** IBASE and IMASK registers.
*/
ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE) & ~0x1fffffULL;
iova_space_size = ~(READ_REG(ioc->ioc_hpa + IOC_IMASK) & 0xFFFFFFFFUL) + 1;
if ((ioc->ibase < 0xfed00000UL) && ((ioc->ibase + iova_space_size) > 0xfee00000UL)) {
printk("WARNING: IOV space overlaps local config and interrupt message, truncating\n");
iova_space_size /= 2;
}
/* ** iov_order is always based on a 1GB IOVA space since we want to ** turn on the other half for AGP GART.
*/
iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT));
ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
/* build IMASK for IOC and Elroy */
iova_space_mask = 0xffffffff;
iova_space_mask <<= (iov_order + PAGE_SHIFT);
ioc->imask = iova_space_mask; #ifdef ZX1_SUPPORT
ioc->iovp_mask = ~(iova_space_mask + PAGE_SIZE - 1); #endif
sba_dump_tlb(ioc->ioc_hpa);
setup_ibase_imask(sba, ioc, ioc_num);
WRITE_REG(ioc->imask, ioc->ioc_hpa + IOC_IMASK);
#ifdef CONFIG_64BIT /* ** Setting the upper bits makes checking for bypass addresses ** a little faster later on.
*/
ioc->imask |= 0xFFFFFFFF00000000UL; #endif
/* Set I/O PDIR Page size to system page size */ switch (PAGE_SHIFT) { case 12: tcnfg = 0; break; /* 4K */ case 13: tcnfg = 1; break; /* 8K */ case 14: tcnfg = 2; break; /* 16K */ case 16: tcnfg = 3; break; /* 64K */ default:
panic(__FILE__ "Unsupported system page size %d",
1 << PAGE_SHIFT); break;
}
WRITE_REG(tcnfg, ioc->ioc_hpa + IOC_TCNFG);
/* ** Program the IOC's ibase and enable IOVA translation ** Bit zero == enable bit.
*/
WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa + IOC_IBASE);
/* ** Clear I/O TLB of any possible entries. ** (Yes. This is a bit paranoid...but so what)
*/
WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM);
#ifdef SBA_AGP_SUPPORT
/* ** If an AGP device is present, only use half of the IOV space ** for PCI DMA. Unfortunately we can't know ahead of time ** whether GART support will actually be used, for now we ** can just key on any AGP device found in the system. ** We program the next pdir index after we stop w/ a key for ** the GART code to handshake on.
*/
device_for_each_child(&sba->dev, &agp_found, sba_ioc_find_quicksilver);
if (agp_found && sba_reserve_agpgart) {
printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n",
__func__, (iova_space_size/2) >> 20);
ioc->pdir_size /= 2;
ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE;
} #endif/*SBA_AGP_SUPPORT*/
}
staticvoid
sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
{
u32 iova_space_size, iova_space_mask; unsignedint pdir_size, iov_order, tcnfg;
/* ** Determine IOVA Space size from memory size. ** ** Ideally, PCI drivers would register the maximum number ** of DMA they can have outstanding for each device they ** own. Next best thing would be to guess how much DMA ** can be outstanding based on PCI Class/sub-class. Both ** methods still require some "extra" to support PCI ** Hot-Plug/Removal of PCI cards. (aka PCI OLARD). ** ** While we have 32-bits "IOVA" space, top two 2 bits are used ** for DMA hints - ergo only 30 bits max.
*/
/* ** iova space must be log2() in size. ** thus, pdir/res_map will also be log2(). ** PIRANHA BUG: Exception is when IO Pdir is 2MB (gets reduced)
*/
iov_order = get_order(iova_space_size << PAGE_SHIFT);
/* iova_space_size is now bytes, not pages */
iova_space_size = 1 << (iov_order + PAGE_SHIFT);
DBG_INIT("%s() IOV base %#lx mask %#0lx\n",
__func__, ioc->ibase, ioc->imask);
/* ** FIXME: Hint registers are programmed with default hint ** values during boot, so hints should be sane even if we ** can't reprogram them the way drivers want.
*/
setup_ibase_imask(sba, ioc, ioc_num);
/* ** Program the IOC's ibase and enable IOVA translation
*/
WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa+IOC_IBASE);
WRITE_REG(ioc->imask, ioc->ioc_hpa+IOC_IMASK);
/* Set I/O PDIR Page size to system page size */ switch (PAGE_SHIFT) { case 12: tcnfg = 0; break; /* 4K */ case 13: tcnfg = 1; break; /* 8K */ case 14: tcnfg = 2; break; /* 16K */ case 16: tcnfg = 3; break; /* 64K */ default:
panic(__FILE__ "Unsupported system page size %d",
1 << PAGE_SHIFT); break;
} /* Set I/O PDIR Page size to PAGE_SIZE (4k/16k/...) */
WRITE_REG(tcnfg, ioc->ioc_hpa+IOC_TCNFG);
/* ** Clear I/O TLB of any possible entries. ** (Yes. This is a bit paranoid...but so what)
*/
WRITE_REG(0 | 31, ioc->ioc_hpa+IOC_PCOM);
ioc->ibase = 0; /* used by SBA_IOVA and related macros */
DBG_INIT("%s() DONE\n", __func__);
}
/************************************************************************** ** ** SBA initialization code (HW and SW) ** ** o identify SBA chip itself ** o initialize SBA chip modes (HardFail) ** o initialize SBA chip modes (HardFail) ** o FIXME: initialize DMA hints for reasonable defaults **
**************************************************************************/
staticvoid sba_hw_init(struct sba_device *sba_dev)
{ int i; int num_ioc;
u64 ioc_ctl;
if (!is_pdc_pat()) { /* Shutdown the USB controller on Astro-based workstations. ** Once we reprogram the IOMMU, the next DMA performed by ** USB will HPMC the box. USB is only enabled if a ** keyboard is present and found. ** ** With serial console, j6k v5.0 firmware says: ** mem_kbd hpa 0xfee003f8 sba 0x0 pad 0x0 cl_class 0x7 ** ** FIXME: Using GFX+USB console at power up but direct ** linux to serial console is still broken. ** USB could generate DMA so we must reset USB. ** The proper sequence would be: ** o block console output ** o reset USB device ** o reprogram serial port ** o unblock console output
*/ if (PAGE0->mem_kbd.cl_class == CL_KEYBD) {
pdc_io_reset_devices();
}
/* ** Need to deal with DMA from LAN. ** Maybe use page zero boot device as a handle to talk ** to PDC about which device to shutdown. ** ** Netbooting, j6k v5.0 firmware says: ** mem_boot hpa 0xf4008000 sba 0x0 pad 0x0 cl_class 0x1002 ** ARGH! invalid class.
*/ if ((PAGE0->mem_boot.cl_class != CL_RANDOM)
&& (PAGE0->mem_boot.cl_class != CL_SEQU)) {
pdc_io_reset();
} #endif
staticvoid
sba_common_init(struct sba_device *sba_dev)
{ int i;
/* add this one to the head of the list (order doesn't matter) ** This will be useful for debugging - especially if we get coredumps
*/
sba_dev->next = sba_list;
sba_list = sba_dev;
#ifdef DEBUG_SBA_INIT /* * If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit set * (bit #61, big endian), we have to flush and sync every time * IO-PDIR is changed in Ike/Astro.
*/ if (ioc_needs_fdc) {
printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n");
} else {
printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n");
} #endif
}
min = max = ioc->avg_search[0]; for (i = 0; i < SBA_SEARCH_SAMPLE; i++) {
avg += ioc->avg_search[i]; if (ioc->avg_search[i] > max) max = ioc->avg_search[i]; if (ioc->avg_search[i] < min) min = ioc->avg_search[i];
}
avg /= SBA_SEARCH_SAMPLE;
seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
min, avg, max);
/* ** Determine if sba should claim this chip (return 0) or not (return 1). ** If so, initialize the chip and tell other partners in crime they ** have work to do.
*/ staticint __init sba_driver_callback(struct parisc_device *dev)
{ struct sba_device *sba_dev;
u32 func_class; int i; char *version; void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); struct proc_dir_entry *root __maybe_unused;
/* ** One time initialization to let the world know the SBA was found. ** This is the only routine which is NOT static. ** Must be called exactly once before pci_init().
*/ staticint __init sba_init(void)
{ return register_parisc_driver(&sba_driver);
}
arch_initcall(sba_init);
/** * sba_get_iommu - Assign the iommu pointer for the pci bus controller. * @pci_hba: The parisc device. * * Returns the appropriate IOMMU data for the given parisc PCI controller. * This is cached and used later for PCI DMA Mapping.
*/ void * sba_get_iommu(struct parisc_device *pci_hba)
{ struct parisc_device *sba_dev = parisc_parent(pci_hba); struct sba_device *sba = dev_get_drvdata(&sba_dev->dev); char t = sba_dev->id.hw_type; int iocnum = (pci_hba->hw_path >> 3); /* IOC # */
WARN_ON((t != HPHW_IOA) && (t != HPHW_BCPORT));
return &(sba->ioc[iocnum]);
}
/** * sba_directed_lmmio - return first directed LMMIO range routed to rope * @pci_hba: The parisc device. * @r: resource PCI host controller wants start/end fields assigned. * * For the given parisc PCI controller, determine if any direct ranges * are routed down the corresponding rope.
*/ void sba_directed_lmmio(struct parisc_device *pci_hba, struct resource *r)
{ struct parisc_device *sba_dev = parisc_parent(pci_hba); struct sba_device *sba = dev_get_drvdata(&sba_dev->dev); char t = sba_dev->id.hw_type; int i; int rope = (pci_hba->hw_path & (ROPES_PER_IOC-1)); /* rope # */
BUG_ON((t!=HPHW_IOA) && (t!=HPHW_BCPORT));
r->start = r->end = 0;
/* Astro has 4 directed ranges. Not sure about Ike/Pluto/et al */ for (i=0; i<4; i++) { int base, size; void __iomem *reg = sba->sba_hpa + i*0x18;
base = READ_REG32(reg + LMMIO_DIRECT0_BASE); if ((base & 1) == 0) continue; /* not enabled */
size = READ_REG32(reg + LMMIO_DIRECT0_ROUTE);
if ((size & (ROPES_PER_IOC-1)) != rope) continue; /* directed down different rope */
/** * sba_distributed_lmmio - return portion of distributed LMMIO range * @pci_hba: The parisc device. * @r: resource PCI host controller wants start/end fields assigned. * * For the given parisc PCI controller, return portion of distributed LMMIO * range. The distributed LMMIO is always present and it's just a question * of the base address and size of the range.
*/ void sba_distributed_lmmio(struct parisc_device *pci_hba, struct resource *r )
{ struct parisc_device *sba_dev = parisc_parent(pci_hba); struct sba_device *sba = dev_get_drvdata(&sba_dev->dev); char t = sba_dev->id.hw_type; int base, size; int rope = (pci_hba->hw_path & (ROPES_PER_IOC-1)); /* rope # */
BUG_ON((t!=HPHW_IOA) && (t!=HPHW_BCPORT));
r->start = r->end = 0;
base = READ_REG32(sba->sba_hpa + LMMIO_DIST_BASE); if ((base & 1) == 0) {
BUG(); /* Gah! Distr Range wasn't enabled! */ return;
}
r->start = (base & ~1UL) | PCI_F_EXTEND;
size = (~READ_REG32(sba->sba_hpa + LMMIO_DIST_MASK)) / ROPES_PER_IOC;
r->start += rope * (size + 1); /* adjust base for this rope */
r->end = r->start + size;
r->flags = IORESOURCE_MEM;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.