Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41938761 authored by Michal Simek's avatar Michal Simek
Browse files

microblaze: Introduce fixmap



Fixmap will be used for highmem support.

Signed-off-by: default avatarMichal Simek <monstr@monstr.eu>
parent 83a92529
Loading
Loading
Loading
Loading
+101 −0
Original line number Diff line number Diff line
/*
 * fixmap.h: compile-time virtual memory allocation
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 1998 Ingo Molnar
 *
 * Copyright 2008 Freescale Semiconductor Inc.
 *   Port to powerpc added by Kumar Gala
 *
 * Copyright 2011 Michal Simek <monstr@monstr.eu>
 * Copyright 2011 PetaLogix Qld Pty Ltd
 *   Port to Microblaze
 */

#ifndef _ASM_FIXMAP_H
#define _ASM_FIXMAP_H

#ifndef __ASSEMBLY__
#include <linux/kernel.h>
#include <asm/page.h>

#define FIXADDR_TOP	((unsigned long)(-PAGE_SIZE))

/*
 * Here we define all the compile-time 'special' virtual
 * addresses. The point is to have a constant address at
 * compile time, but to set the physical address only
 * in the boot process. We allocate these special addresses
 * from the end of virtual memory (0xfffff000) backwards.
 * Also this lets us do fail-safe vmalloc(), we
 * can guarantee that these special addresses and
 * vmalloc()-ed addresses never overlap.
 *
 * these 'compile-time allocated' memory buffers are
 * fixed-size 4k pages. (or larger if used with an increment
 * highger than 1) use fixmap_set(idx,phys) to associate
 * physical memory with fixmap indices.
 *
 * TLB entries of such buffers will not be flushed across
 * task switches.
 */
enum fixed_addresses {
	FIX_HOLE,
	__end_of_fixed_addresses
};

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

#define set_fixmap(idx, phys) \
		__set_fixmap(idx, phys, PAGE_KERNEL)
/*
 * Some hardware wants to get fixmapped without caching.
 */
#define set_fixmap_nocache(idx, phys) \
		__set_fixmap(idx, phys, PAGE_KERNEL_CI)

#define clear_fixmap(idx) \
		__set_fixmap(idx, 0, __pgprot(0))

#define __FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START		(FIXADDR_TOP - __FIXADDR_SIZE)

#define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x)	((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)

extern void __this_fixmap_does_not_exist(void);

/*
 * 'index to address' translation. If anyone tries to use the idx
 * directly without tranlation, we catch the bug with a NULL-deference
 * kernel oops. Illegal ranges of incoming indices are caught too.
 */
static __always_inline unsigned long fix_to_virt(const unsigned int idx)
{
	/*
	 * this branch gets completely eliminated after inlining,
	 * except when someone tries to use fixaddr indices in an
	 * illegal way. (such as mixing up address types or using
	 * out-of-range indices).
	 *
	 * If it doesn't get removed, the linker will complain
	 * loudly with a reasonably clear error message..
	 */
	if (idx >= __end_of_fixed_addresses)
		__this_fixmap_does_not_exist();

	return __fix_to_virt(idx);
}

static inline unsigned long virt_to_fix(const unsigned long vaddr)
{
	BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
	return __virt_to_fix(vaddr);
}

#endif /* !__ASSEMBLY__ */
#endif
+11 −6
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <asm/pgalloc.h>
#include <asm/sections.h>
#include <asm/tlb.h>
#include <asm/fixmap.h>

/* Use for MMU and noMMU because of PCI generic code */
int mem_init_done;
@@ -54,6 +55,13 @@ unsigned long lowmem_size;
static void __init paging_init(void)
{
	unsigned long zones_size[MAX_NR_ZONES];
#ifdef CONFIG_MMU
	int idx;

	/* Setup fixmaps */
	for (idx = 0; idx < __end_of_fixed_addresses; idx++)
		clear_fixmap(idx);
#endif

	/* Clean every zones */
	memset(zones_size, 0, sizeof(zones_size));
@@ -316,12 +324,9 @@ asmlinkage void __init mmu_init(void)
	/* Map in all of RAM starting at CONFIG_KERNEL_START */
	mapin_ram();

#ifdef CONFIG_HIGHMEM_START_BOOL
	ioremap_base = CONFIG_HIGHMEM_START;
#else
	ioremap_base = 0xfe000000UL;	/* for now, could be 0xfffff000 */
#endif /* CONFIG_HIGHMEM_START_BOOL */
	ioremap_bot = ioremap_base;
	/* Extend vmalloc and ioremap area as big as possible */
	ioremap_base = ioremap_bot = FIXADDR_START;

	/* Initialize the context management stuff */
	mmu_context_init();

+11 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include <linux/io.h>
#include <asm/mmu.h>
#include <asm/sections.h>
#include <asm/fixmap.h>

#define flush_HPTE(X, va, pg)	_tlbie(va)

@@ -249,3 +250,13 @@ __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
	}
	return pte;
}

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

	if (idx >= __end_of_fixed_addresses)
		BUG();

	map_page(address, phys, pgprot_val(flags));
}