Skip to content

Commit

Permalink
openrisc: Implement fixmap to fix earlycon
Browse files Browse the repository at this point in the history
With commit 53c98e3 ("openrisc: mm: remove unneeded early ioremap
code") it was commented that early ioremap was not used in OpenRISC.  I
acked this but was wrong, earlycon was using it.  Earlycon setup now
fails with the below trace:

    Kernel command line: earlycon
    ------------[ cut here ]------------
    WARNING: CPU: 0 PID: 0 at mm/ioremap.c:23
    generic_ioremap_prot+0x118/0x130
    Modules linked in:
    CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted
    6.11.0-rc5-00001-gce02fd891c38-dirty torvalds#141
    Call trace:
    [<(ptrval)>] dump_stack_lvl+0x7c/0x9c
    [<(ptrval)>] dump_stack+0x1c/0x2c
    [<(ptrval)>] __warn+0xb4/0x108
    [<(ptrval)>] ? generic_ioremap_prot+0x118/0x130
    [<(ptrval)>] warn_slowpath_fmt+0x60/0x98
    [<(ptrval)>] generic_ioremap_prot+0x118/0x130
    [<(ptrval)>] ioremap_prot+0x20/0x30
    [<(ptrval)>] of_setup_earlycon+0xd4/0x2e0
    [<(ptrval)>] early_init_dt_scan_chosen_stdout+0x18c/0x1c8
    [<(ptrval)>] param_setup_earlycon+0x3c/0x60
    [<(ptrval)>] do_early_param+0xb0/0x118
    [<(ptrval)>] parse_args+0x184/0x4b8
    [<(ptrval)>] ? start_kernel+0x0/0x78c
    [<(ptrval)>] parse_early_options+0x40/0x50
    [<(ptrval)>] ? do_early_param+0x0/0x118
    [<(ptrval)>] parse_early_param+0x48/0x68
    [<(ptrval)>] ? start_kernel+0x318/0x78c
    [<(ptrval)>] ? start_kernel+0x0/0x78c
    ---[ end trace 0000000000000000 ]---

To fix this we could either implement early_ioremap again or implement
fixmap.  In this patch we choose the later option of implementing basic
fixmap support.

While fixing this we also remove the old FIX_IOREMAP slots that were
used by early ioremap code.  That code was also removed by commit
53c98e3 ("openrisc: mm: remove unneeded early ioremap code") but
these definitions were not cleaned up.

Fixes: 53c98e3 ("openrisc: mm: remove unneeded early ioremap code")
Signed-off-by: Stafford Horne <shorne@gmail.com>
  • Loading branch information
stffrdhrn committed Oct 15, 2024
1 parent 5be63fc commit 1037d18
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 16 deletions.
3 changes: 3 additions & 0 deletions arch/openrisc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ config STACKTRACE_SUPPORT
config LOCKDEP_SUPPORT
def_bool y

config FIX_EARLYCON_MEM
def_bool y

menu "Processor type and features"

choice
Expand Down
21 changes: 5 additions & 16 deletions arch/openrisc/include/asm/fixmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,18 @@
#include <linux/bug.h>
#include <asm/page.h>

/*
* On OpenRISC we use these special fixed_addresses for doing ioremap
* early in the boot process before memory initialization is complete.
* This is used, in particular, by the early serial console code.
*
* It's not really 'fixmap', per se, but fits loosely into the same
* paradigm.
*/
enum fixed_addresses {
/*
* FIX_IOREMAP entries are useful for mapping physical address
* space before ioremap() is useable, e.g. really early in boot
* before kmalloc() is working.
*/
#define FIX_N_IOREMAPS 32
FIX_IOREMAP_BEGIN,
FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS - 1,
FIX_EARLYCON_MEM_BASE,
__end_of_fixed_addresses
};

#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
/* FIXADDR_BOTTOM might be a better name here... */
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
#define FIXMAP_PAGE_IO PAGE_KERNEL_NOCACHE

extern void __set_fixmap(enum fixed_addresses idx,
phys_addr_t phys, pgprot_t flags);

#include <asm-generic/fixmap.h>

Expand Down
37 changes: 37 additions & 0 deletions arch/openrisc/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,43 @@ void __init mem_init(void)
return;
}

static int __init map_page(unsigned long va, phys_addr_t pa, pgprot_t prot)
{
p4d_t *p4d;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;

p4d = p4d_offset(pgd_offset_k(va), va);
pud = pud_offset(p4d, va);
pmd = pmd_offset(pud, va);
pte = pte_alloc_kernel(pmd, va);

if (pte == NULL)
return -ENOMEM;

if (pgprot_val(prot))
set_pte_at(&init_mm, va, pte, pfn_pte(pa >> PAGE_SHIFT, prot));
else
pte_clear(&init_mm, va, pte);

local_flush_tlb_page(NULL, va);
return 0;
}

void __init __set_fixmap(enum fixed_addresses idx,
phys_addr_t phys, pgprot_t prot)
{
unsigned long address = __fix_to_virt(idx);

if (idx >= __end_of_fixed_addresses) {
BUG();
return;
}

map_page(address, phys, prot);
}

static const pgprot_t protection_map[16] = {
[VM_NONE] = PAGE_NONE,
[VM_READ] = PAGE_READONLY_X,
Expand Down

0 comments on commit 1037d18

Please sign in to comment.