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

Commit 65559100 authored by Max Filippov's avatar Max Filippov
Browse files

xtensa: add HIGHMEM support



Introduce fixmap area just below the vmalloc region. Use it for atomic
mapping of high memory pages.
High memory on cores with cache aliasing is not supported and is still
to be implemented. Fail build for such configurations for now.

Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
parent 04c6b3e2
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -190,6 +190,24 @@ config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX


	  If in doubt, say Y.
	  If in doubt, say Y.


config HIGHMEM
	bool "High Memory Support"
	help
	  Linux can use the full amount of RAM in the system by
	  default. However, the default MMUv2 setup only maps the
	  lowermost 128 MB of memory linearly to the areas starting
	  at 0xd0000000 (cached) and 0xd8000000 (uncached).
	  When there are more than 128 MB memory in the system not
	  all of it can be "permanently mapped" by the kernel.
	  The physical memory that's not permanently mapped is called
	  "high memory".

	  If you are compiling a kernel which will never run on a
	  machine with more than 128 MB total physical RAM, answer
	  N here.

	  If unsure, say Y.

endmenu
endmenu


config XTENSA_CALIBRATE_CCOUNT
config XTENSA_CALIBRATE_CCOUNT
+58 −0
Original line number Original line 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
 *
 * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
 */

#ifndef _ASM_FIXMAP_H
#define _ASM_FIXMAP_H

#include <asm/pgtable.h>
#ifdef CONFIG_HIGHMEM
#include <linux/threads.h>
#include <asm/kmap_types.h>
#endif

/*
 * 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 the consistent memory region 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
 * higher than 1) use fixmap_set(idx,phys) to associate
 * physical memory with fixmap indices.
 */
enum fixed_addresses {
#ifdef CONFIG_HIGHMEM
	/* reserved pte's for temporary kernel mappings */
	FIX_KMAP_BEGIN,
	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
#endif
	__end_of_fixed_addresses
};

#define FIXADDR_TOP     (VMALLOC_START - PAGE_SIZE)
#define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START	((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK)

#include <asm-generic/fixmap.h>

#define kmap_get_fixmap_pte(vaddr) \
	pte_offset_kernel( \
		pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), \
		(vaddr) \
	)

#endif
+44 −1
Original line number Original line Diff line number Diff line
@@ -6,11 +6,54 @@
 * this archive for more details.
 * this archive for more details.
 *
 *
 * Copyright (C) 2003 - 2005 Tensilica Inc.
 * Copyright (C) 2003 - 2005 Tensilica Inc.
 * Copyright (C) 2014 Cadence Design Systems Inc.
 */
 */


#ifndef _XTENSA_HIGHMEM_H
#ifndef _XTENSA_HIGHMEM_H
#define _XTENSA_HIGHMEM_H
#define _XTENSA_HIGHMEM_H


extern void flush_cache_kmaps(void);
#include <asm/cacheflush.h>
#include <asm/fixmap.h>
#include <asm/kmap_types.h>
#include <asm/pgtable.h>

#define PKMAP_BASE		(FIXADDR_START - PMD_SIZE)
#define LAST_PKMAP		PTRS_PER_PTE
#define LAST_PKMAP_MASK		(LAST_PKMAP - 1)
#define PKMAP_NR(virt)		(((virt) - PKMAP_BASE) >> PAGE_SHIFT)
#define PKMAP_ADDR(nr)		(PKMAP_BASE + ((nr) << PAGE_SHIFT))

#define kmap_prot		PAGE_KERNEL

extern pte_t *pkmap_page_table;

void *kmap_high(struct page *page);
void kunmap_high(struct page *page);

static inline void *kmap(struct page *page)
{
	BUG_ON(in_interrupt());
	if (!PageHighMem(page))
		return page_address(page);
	return kmap_high(page);
}

static inline void kunmap(struct page *page)
{
	BUG_ON(in_interrupt());
	if (!PageHighMem(page))
		return;
	kunmap_high(page);
}

static inline void flush_cache_kmaps(void)
{
	flush_cache_all();
}

void *kmap_atomic(struct page *page);
void __kunmap_atomic(void *kvaddr);

void kmap_init(void);


#endif
#endif
+4 −0
Original line number Original line Diff line number Diff line
@@ -310,6 +310,10 @@ set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval)
	update_pte(ptep, pteval);
	update_pte(ptep, pteval);
}
}


static inline void set_pte(pte_t *ptep, pte_t pteval)
{
	update_pte(ptep, pteval);
}


static inline void
static inline void
set_pmd(pmd_t *pmdp, pmd_t pmdval)
set_pmd(pmd_t *pmdp, pmd_t pmdval)
+1 −0
Original line number Original line Diff line number Diff line
@@ -4,3 +4,4 @@


obj-y			:= init.o cache.o misc.o
obj-y			:= init.o cache.o misc.o
obj-$(CONFIG_MMU)	+= fault.o mmu.o tlb.o
obj-$(CONFIG_MMU)	+= fault.o mmu.o tlb.o
obj-$(CONFIG_HIGHMEM)	+= highmem.o
Loading