[RFC/PATCH v2] powerpc: add ioremap_early() function for mapping IO regions before MMU_init()
Kumar Gala
galak at kernel.crashing.org
Thu Aug 14 23:00:48 EST 2008
On Aug 12, 2008, at 10:03 PM, Grant Likely wrote:
> +/**
> + * ioremap_early - Allow large persistant IO regions to be mapped
> early.
> + * @addr: physical address of region
> + * @size: size of region
> + *
> + * This routine uses setbat() to set up IO ranges before the MMU is
> + * fully configured.
> + *
> + * This routine can be called really early, before MMU_init() is
> called. It
> + * is useful for setting up early debug output consoles and
> frequently
> + * accessed IO regions, like the internally memory mapped registers
> (IMMR)
> + * in an SoC. Ranges mapped with this function persist even after
> MMU_init()
> + * is called and the MMU is turned on 'for real.'
> + *
> + * The region mapped is large (minimum size of 128k) and virtual
> mapping must
> + * be aligned against this boundary. Therefore, to avoid
> fragmentation all
> + * calls to ioremap_early() are best made before any calls to ioremap
> + * for smaller regions.
> + */
> +void __iomem * __init
> +ioremap_early(phys_addr_t addr, unsigned long size)
> +{
> + unsigned long v, p;
> + int i;
> +
> + /* Be loud and annoying if someone calls this too late.
> + * No need to crash the kernel though */
> + WARN_ON(mem_init_done);
> + if (mem_init_done)
> + return NULL;
> +
> + /* Make sure request is sane */
> + if (size == 0)
> + return NULL;
> +
> + /* If the region is already block mapped, then there is nothing
> + * to do; just return the mapped address */
> + v = p_mapped_by_bats(addr);
> + if (v)
> + return (void __iomem *)v;
> +
> + /* Adjust size to reflect aligned region */
> + p = _ALIGN_DOWN(addr, 128 << 10); /* BATs align on 128k boundaries
> */
> + size = ALIGN(addr - p + size, 128 << 10);
> +
> + /* Allocate the aligned virtual base address. ALIGN_DOWN is used
> + * to ensure no overlaps occur with normal 4k ioremaps. */
> + v = ioremap_bot = _ALIGN_DOWN(ioremap_bot, 128 << 10) - size;
> +
> + /* Set up a BAT for this IO region */
> + i = loadbat(v, p, size, _PAGE_IO);
what happens if we run out of bats?
does this actually build on any non-BAT based ppc32 system?
>
> + if (i < 0)
> + return NULL;
> +
> + return (void __iomem *) (v + (addr - p));
> +}
> +
More information about the Linuxppc-dev
mailing list