-next fails to boot as of today on S3C6410
Nicolas Pitre
nicolas.pitre at linaro.org
Wed Nov 23 19:32:58 EST 2011
On Wed, 23 Nov 2011, Nicolas Pitre wrote:
> On Wed, 23 Nov 2011, Mark Brown wrote:
>
> > On Wed, Nov 23, 2011 at 11:52:10AM -0600, Rob Herring wrote:
> > > On 11/23/2011 08:55 AM, Mark Brown wrote:
> >
> > > > My bisect turned up a second candidate - Nicholas' commit 549158d (ARM:
> > > > move iotable mappings within the vmalloc region). I reverted that and
> > > > subsequent commits depending on it and my system now appears to boot
> > > > fine with -next (with OF turned on to get the ops for the VIC). This
> > > > code is all a bit deep for me so I've no real idea what might be wrong.
> >
> > > The first suspect should be overlapping static mappings in the iotable.
> > > This was allowed before and now is not. Looking at some of the 6410
> > > platforms, I don't see any though. But you didn't mention which platform
> > > you are on. There is a 1KB mapping which is a bit unusual.
> >
> > I'm on Cragganmore 6410 which just calls a bunch of arch-generic stuff
> > (though now I look I do see a comment saying that we're relying on some
> > setup from the bootloader which I get may have been trashed...).
>
> I'm working on a way to get sensible debug messages out.
>
> The problem is that, as soon as we execute this loop in
> devicemaps_init():
>
> for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
> pmd_clear(pmd_off_k(addr));
>
> we lose all means of communication with the outside world until
> mdesc->map_io() and the following TLB/cache flushes are done. It is
> most likely that you are having a problem in the middle of that.
OK, here it is. Please try this patch:
-------- >8
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index acb2c7ec0a..51b4307591 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -939,23 +939,54 @@ void __init arm_mm_memblock_reserve(void)
#endif
}
+#ifdef CONFIG_DEBUG_LL
+
/*
- * Set up the device mappings. Since we clear out the page tables for all
- * mappings above VMALLOC_START, we will remove any debug device mappings.
- * This means you have to be careful how you debug this function, or any
- * called function. This means you can't use any function or debugging
- * method which may touch any device, otherwise the kernel _will_ crash.
+ * The remainder of the page table containing debug mappings will be
+ * cleared and recreated by devicemaps_init(). To allow for debug devices
+ * to remain accessible, we create a temporary copy of the current page table
+ * here and switch to it, and switch back once the final mappings have
+ * been created.
+ */
+
+static pgd_t * __init install_temp_mm(void)
+{
+ pgd_t *temp_pgd = early_alloc(PTRS_PER_PGD * sizeof(pgd_t));
+ pgd_t *init_pgd = pgd_offset_k(0);
+ memcpy(temp_pgd + USER_PTRS_PER_PGD, init_pgd + USER_PTRS_PER_PGD,
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+ clean_dcache_area(temp_pgd, PTRS_PER_PGD * sizeof(pgd_t));
+ cpu_switch_mm(temp_pgd, &init_mm);
+ return temp_pgd;
+}
+
+static void __init clear_temp_mm(pgd_t *temp_pgd)
+{
+ cpu_switch_mm(init_mm.pgd, &init_mm);
+ memblock_free(__pa(temp_pgd), PTRS_PER_PGD * sizeof(pgd_t));
+}
+
+#else
+#define set_temp_mm() (NULL)
+#define clear_temp_mm() do { } while (0)
+#endif
+
+/*
+ * Set up the device mappings.
*/
static void __init devicemaps_init(struct machine_desc *mdesc)
{
struct map_desc map;
unsigned long addr;
+ pgd_t *temp_pgd;
/*
* Allocate the vector page early.
*/
vectors_page = early_alloc(PAGE_SIZE);
+ temp_pgd = install_temp_mm();
+
for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
pmd_clear(pmd_off_k(addr));
@@ -1012,6 +1043,8 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
if (mdesc->map_io)
mdesc->map_io();
+ clear_temp_mm(temp_pgd);
+
/*
* Finally flush the caches and tlb to ensure that we're in a
* consistent state wrt the writebuffer. This also ensures that
-------- >8
Then, if you didn't already do so, you should enable CONFIG_DEBUG_LL
and hack something like this into the printk code:
-------- >8
diff --git a/kernel/printk.c b/kernel/printk.c
index 1455a0d4ee..b543370cfd 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -876,6 +876,11 @@ asmlinkage int vprintk(const char *fmt, va_list args)
printed_len += vscnprintf(printk_buf + printed_len,
sizeof(printk_buf) - printed_len, fmt, args);
+ {
+ extern void printascii(char *);
+ printascii(printk_buf);
+ }
+
p = printk_buf;
/* Read log level and handle special printk prefix */
-------- >8
That should provide you with the ability to figure out what's wrong.
Nicolas
More information about the linux-arm-kernel
mailing list