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

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to