]> git.openfabrics.org - ~emulex/infiniband.git/commitdiff
sh: Rework P2 to only include kernel text.
authorPaul Mundt <lethal@linux-sh.org>
Thu, 21 Jan 2010 06:42:58 +0000 (15:42 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Thu, 21 Jan 2010 06:42:58 +0000 (15:42 +0900)
This effectively neutralizes P2 by getting rid of P1 identity mapping
for all available memory and instead only establishes a single unbuffered
PMB entry (16MB -- the smallest available) that covers the kernel.

As using segmentation for abusing caching attributes in drivers is no
longer supported (and there are no drivers that can be enabled in 32-bit
mode that do this), this provides us with all of the uncached access
needs by the kernel itself.

Drivers and their ilk need to specify their caching attributes when
remapping through page tables, as usual.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/kernel/head_32.S

index ee954d1b8cc68952a3e45a9a43c042b12e325abd..e93320135cda9b6177b53d7b733efc9e00b30d5e 100644 (file)
@@ -86,7 +86,96 @@ ENTRY(_stext)
 #endif
 
 #if defined(CONFIG_PMB) && !defined(CONFIG_PMB_LEGACY)
+/*
+ * Reconfigure the initial PMB mappings setup by the hardware.
+ *
+ * When we boot in 32-bit MMU mode there are 2 PMB entries already
+ * setup for us.
+ *
+ * Entry       VPN        PPN      V   SZ      C       UB      WT
+ * ---------------------------------------------------------------
+ *   0     0x80000000 0x00000000   1  512MB    1       0       1
+ *   1     0xA0000000 0x00000000   1  512MB    0       0       0
+ *
+ * But we reprogram them here because we want complete control over
+ * our address space and the initial mappings may not map PAGE_OFFSET
+ * to __MEMORY_START (or even map all of our RAM).
+ *
+ * Once we've setup cached and uncached mappings we clear the rest of the
+ * PMB entries. This clearing also deals with the fact that PMB entries
+ * can persist across reboots. The PMB could have been left in any state
+ * when the reboot occurred, so to be safe we clear all entries and start
+ * with with a clean slate.
+ *
+ * The uncached mapping is constructed using the smallest possible
+ * mapping with a single unbufferable page. Only the kernel text needs to
+ * be covered via the uncached mapping so that certain functions can be
+ * run uncached.
+ *
+ * Drivers and the like that have previously abused the 1:1 identity
+ * mapping are unsupported in 32-bit mode and must specify their caching
+ * preference when page tables are constructed.
+ *
+ * This frees up the P2 space for more nefarious purposes.
+ *
+ * Register utilization is as follows:
+ *
+ *     r0 = PMB_DATA data field
+ *     r1 = PMB_DATA address field
+ *     r2 = PMB_ADDR data field
+ *     r3 = PMB_ADDR address field
+ *     r4 = PMB_E_SHIFT
+ *     r5 = remaining amount of RAM to map
+ *     r6 = PMB mapping size we're trying to use
+ *     r7 = cached_to_uncached
+ *     r8 = scratch register
+ *     r9 = scratch register
+ *     r10 = number of PMB entries we've setup
+ */
+
+       mov.l   .LMMUCR, r1     /* Flush the TLB */
+       mov.l   @r1, r0
+       or      #MMUCR_TI, r0
+       mov.l   r0, @r1
+
+       mov.l   .LMEMORY_SIZE, r5
+       mov     r5, r7
+
+       mov     #PMB_E_SHIFT, r0
+       mov     #0x1, r4
+       shld    r0, r4
 
+       mov.l   .LFIRST_DATA_ENTRY, r0
+       mov.l   .LPMB_DATA, r1
+       mov.l   .LFIRST_ADDR_ENTRY, r2
+       mov.l   .LPMB_ADDR, r3
+
+       mov     #0, r10
+
+       /*
+        * Uncached mapping
+        */
+       mov     #(PMB_SZ_16M >> 2), r9
+       shll2   r9
+
+       mov     #(PMB_UB >> 8), r8
+       shll8   r8
+
+       or      r0, r8
+       or      r9, r8
+       mov.l   r8, @r1
+       mov     r2, r8
+       add     r7, r8
+       mov.l   r8, @r3
+
+       add     r4, r1
+       add     r4, r3
+       add     #1, r10
+
+/*
+ * Iterate over all of the available sizes from largest to
+ * smallest for constructing the cached mapping.
+ */
 #define __PMB_ITER_BY_SIZE(size)                       \
 .L##size:                                              \
        mov     #(size >> 4), r6;                       \
@@ -113,26 +202,6 @@ ENTRY(_stext)
        /* Increment to the next PMB_ADDR entry */      \
        add     r4, r3;                                 \
        /* Increment number of PMB entries */           \
-       add     #1, r10;                                \
-                                                       \
-       /*                                              \
-        * Uncached mapping                             \
-        */                                             \
-       mov     #(PMB_UB >> 8), r8;                     \
-       shll8   r8;                                     \
-                                                       \
-       or      r0, r8;                                 \
-       or      r9, r8;                                 \
-       mov.l   r8, @r1;                                \
-       mov     r2, r8;                                 \
-       add     r7, r8;                                 \
-       mov.l   r8, @r3;                                \
-                                                       \
-       /* Increment to the next PMB_DATA entry */      \
-       add     r4, r1;                                 \
-       /* Increment to the next PMB_ADDR entry */      \
-       add     r4, r3;                                 \
-       /* Increment number of PMB entries */           \
        add     #1, r10;                                \
                                                        \
        sub     r6, r5;                                 \
@@ -142,68 +211,14 @@ ENTRY(_stext)
        bra     .L##size;                               \
 9999:
 
-       /*
-        * Reconfigure the initial PMB mappings setup by the hardware.
-        *
-        * When we boot in 32-bit MMU mode there are 2 PMB entries already
-        * setup for us.
-        *
-        * Entry       VPN         PPN      V   SZ      C       UB      WT
-        * ---------------------------------------------------------------
-        *   0      0x80000000 0x00000000   1  512MB    1       0       1
-        *   1      0xA0000000 0x00000000   1  512MB    0       0       0
-        *
-        * But we reprogram them here because we want complete control over
-        * our address space and the initial mappings may not map PAGE_OFFSET
-        * to __MEMORY_START (or even map all of our RAM).
-        *
-        * Once we've setup cached and uncached mappings for all of RAM we
-        * clear the rest of the PMB entries.
-        *
-        * This clearing also deals with the fact that PMB entries can persist
-        * across reboots. The PMB could have been left in any state when the
-        * reboot occurred, so to be safe we clear all entries and start with
-        * with a clean slate.
-        */
-
-       mov.l   .LMMUCR, r1     /* Flush the TLB */
-       mov.l   @r1, r0
-       or      #MMUCR_TI, r0
-       mov.l   r0, @r1
-
-       mov.l   .LMEMORY_SIZE, r5
-       mov     r5, r7
-
-       mov     #PMB_E_SHIFT, r0
-       mov     #0x1, r4
-       shld    r0, r4
-
-       mov.l   .LFIRST_DATA_ENTRY, r0
-       mov.l   .LPMB_DATA, r1
-       mov.l   .LFIRST_ADDR_ENTRY, r2
-       mov.l   .LPMB_ADDR, r3
-
-       mov     #0, r10
-
-       /*
-        * r0 = PMB_DATA data field
-        * r1 = PMB_DATA address field
-        * r2 = PMB_ADDR data field
-        * r3 = PMB_ADDR address field
-        * r4 = PMB_E_SHIFT
-        * r5 = remaining amount of RAM to map
-        * r6 = PMB mapping size we're trying to use
-        * r7 = cached_to_uncached
-        * r8 = scratch register
-        * r9 = scratch register
-        * r10 = number of PMB entries we've setup
-        */
        __PMB_ITER_BY_SIZE(512)
        __PMB_ITER_BY_SIZE(128)
        __PMB_ITER_BY_SIZE(64)
        __PMB_ITER_BY_SIZE(16)
 
-       /* Update cached_to_uncached */
+       /*
+        * Now that we can access it, update cached_to_uncached.
+        */
        mov.l   .Lcached_to_uncached, r0
        mov.l   r7, @r0