-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch contains the initialisation of the memory blocks, MMU attributes and the memory map. Signed-off-by: Ley Foon Tan <lftan@altera.com>
- Loading branch information
Ley Foon Tan
committed
Dec 8, 2014
1 parent
771a016
commit 5ccc6af
Showing
5 changed files
with
663 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch> | ||
* Copyright (C) 2004 Microtronix Datacom Ltd. | ||
* | ||
* 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. | ||
*/ | ||
|
||
#ifndef _ASM_NIOS2_MMU_H | ||
#define _ASM_NIOS2_MMU_H | ||
|
||
/* Default "unsigned long" context */ | ||
typedef unsigned long mm_context_t; | ||
|
||
#endif /* _ASM_NIOS2_MMU_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* | ||
* Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> | ||
* Copyright (C) 2004 Microtronix Datacom Ltd. | ||
* | ||
* MMU support based on asm/page.h from mips which is: | ||
* | ||
* Copyright (C) 1994 - 1999, 2000, 03 Ralf Baechle | ||
* Copyright (C) 1999, 2000 Silicon Graphics, Inc. | ||
* | ||
* 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. | ||
*/ | ||
|
||
#ifndef _ASM_NIOS2_PAGE_H | ||
#define _ASM_NIOS2_PAGE_H | ||
|
||
#include <linux/pfn.h> | ||
#include <linux/const.h> | ||
|
||
/* | ||
* PAGE_SHIFT determines the page size | ||
*/ | ||
#define PAGE_SHIFT 12 | ||
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) | ||
#define PAGE_MASK (~(PAGE_SIZE - 1)) | ||
|
||
/* | ||
* PAGE_OFFSET -- the first address of the first page of memory. | ||
*/ | ||
#define PAGE_OFFSET \ | ||
(CONFIG_NIOS2_MEM_BASE + CONFIG_NIOS2_KERNEL_REGION_BASE) | ||
|
||
#ifndef __ASSEMBLY__ | ||
|
||
/* | ||
* This gives the physical RAM offset. | ||
*/ | ||
#define PHYS_OFFSET CONFIG_NIOS2_MEM_BASE | ||
|
||
/* | ||
* It's normally defined only for FLATMEM config but it's | ||
* used in our early mem init code for all memory models. | ||
* So always define it. | ||
*/ | ||
#define ARCH_PFN_OFFSET PFN_UP(PHYS_OFFSET) | ||
|
||
#define clear_page(page) memset((page), 0, PAGE_SIZE) | ||
#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) | ||
|
||
struct page; | ||
|
||
extern void clear_user_page(void *addr, unsigned long vaddr, struct page *page); | ||
extern void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, | ||
struct page *to); | ||
|
||
extern unsigned long shm_align_mask; | ||
|
||
/* | ||
* These are used to make use of C type-checking. | ||
*/ | ||
typedef struct page *pgtable_t; | ||
typedef struct { unsigned long pte; } pte_t; | ||
typedef struct { unsigned long pgd; } pgd_t; | ||
typedef struct { unsigned long pgprot; } pgprot_t; | ||
|
||
#define pte_val(x) ((x).pte) | ||
#define pgd_val(x) ((x).pgd) | ||
#define pgprot_val(x) ((x).pgprot) | ||
|
||
#define __pte(x) ((pte_t) { (x) }) | ||
#define __pgd(x) ((pgd_t) { (x) }) | ||
#define __pgprot(x) ((pgprot_t) { (x) }) | ||
|
||
extern unsigned long memory_start; | ||
extern unsigned long memory_end; | ||
extern unsigned long memory_size; | ||
|
||
extern struct page *mem_map; | ||
|
||
#endif /* !__ASSEMBLY__ */ | ||
|
||
# define __pa(x) \ | ||
((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) | ||
# define __va(x) \ | ||
((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET)) | ||
|
||
#define page_to_virt(page) \ | ||
((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) | ||
|
||
# define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) | ||
# define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && \ | ||
(pfn) < max_mapnr) | ||
|
||
# define virt_to_page(vaddr) pfn_to_page(PFN_DOWN(virt_to_phys(vaddr))) | ||
# define virt_addr_valid(vaddr) pfn_valid(PFN_DOWN(virt_to_phys(vaddr))) | ||
|
||
# define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ | ||
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | ||
|
||
# define UNCAC_ADDR(addr) \ | ||
((void *)((unsigned)(addr) | CONFIG_NIOS2_IO_REGION_BASE)) | ||
# define CAC_ADDR(addr) \ | ||
((void *)(((unsigned)(addr) & ~CONFIG_NIOS2_IO_REGION_BASE) | \ | ||
CONFIG_NIOS2_KERNEL_REGION_BASE)) | ||
|
||
#include <asm-generic/memory_model.h> | ||
|
||
#include <asm-generic/getorder.h> | ||
|
||
#endif /* _ASM_NIOS2_PAGE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
/* | ||
* User space memory access functions for Nios II | ||
* | ||
* Copyright (C) 2010-2011, Tobias Klauser <tklauser@distanz.ch> | ||
* Copyright (C) 2009, Wind River Systems Inc | ||
* Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com | ||
* | ||
* 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. | ||
*/ | ||
|
||
#ifndef _ASM_NIOS2_UACCESS_H | ||
#define _ASM_NIOS2_UACCESS_H | ||
|
||
#include <linux/errno.h> | ||
#include <linux/thread_info.h> | ||
#include <linux/string.h> | ||
|
||
#include <asm/page.h> | ||
|
||
#define VERIFY_READ 0 | ||
#define VERIFY_WRITE 1 | ||
|
||
/* | ||
* The exception table consists of pairs of addresses: the first is the | ||
* address of an instruction that is allowed to fault, and the second is | ||
* the address at which the program should continue. No registers are | ||
* modified, so it is entirely up to the continuation code to figure out | ||
* what to do. | ||
* | ||
* All the routines below use bits of fixup code that are out of line | ||
* with the main instruction path. This means when everything is well, | ||
* we don't even have to jump over them. Further, they do not intrude | ||
* on our cache or tlb entries. | ||
*/ | ||
struct exception_table_entry { | ||
unsigned long insn; | ||
unsigned long fixup; | ||
}; | ||
|
||
extern int fixup_exception(struct pt_regs *regs); | ||
|
||
/* | ||
* Segment stuff | ||
*/ | ||
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) | ||
#define USER_DS MAKE_MM_SEG(0x80000000UL) | ||
#define KERNEL_DS MAKE_MM_SEG(0) | ||
|
||
#define get_ds() (KERNEL_DS) | ||
|
||
#define get_fs() (current_thread_info()->addr_limit) | ||
#define set_fs(seg) (current_thread_info()->addr_limit = (seg)) | ||
|
||
#define segment_eq(a, b) ((a).seg == (b).seg) | ||
|
||
#define __access_ok(addr, len) \ | ||
(((signed long)(((long)get_fs().seg) & \ | ||
((long)(addr) | (((long)(addr)) + (len)) | (len)))) == 0) | ||
|
||
#define access_ok(type, addr, len) \ | ||
likely(__access_ok((unsigned long)(addr), (unsigned long)(len))) | ||
|
||
# define __EX_TABLE_SECTION ".section __ex_table,\"a\"\n" | ||
|
||
/* | ||
* Zero Userspace | ||
*/ | ||
|
||
static inline unsigned long __must_check __clear_user(void __user *to, | ||
unsigned long n) | ||
{ | ||
__asm__ __volatile__ ( | ||
"1: stb zero, 0(%1)\n" | ||
" addi %0, %0, -1\n" | ||
" addi %1, %1, 1\n" | ||
" bne %0, zero, 1b\n" | ||
"2:\n" | ||
__EX_TABLE_SECTION | ||
".word 1b, 2b\n" | ||
".previous\n" | ||
: "=r" (n), "=r" (to) | ||
: "0" (n), "1" (to) | ||
); | ||
|
||
return n; | ||
} | ||
|
||
static inline unsigned long __must_check clear_user(void __user *to, | ||
unsigned long n) | ||
{ | ||
if (!access_ok(VERIFY_WRITE, to, n)) | ||
return n; | ||
return __clear_user(to, n); | ||
} | ||
|
||
extern long __copy_from_user(void *to, const void __user *from, | ||
unsigned long n); | ||
extern long __copy_to_user(void __user *to, const void *from, unsigned long n); | ||
|
||
static inline long copy_from_user(void *to, const void __user *from, | ||
unsigned long n) | ||
{ | ||
if (!access_ok(VERIFY_READ, from, n)) | ||
return n; | ||
return __copy_from_user(to, from, n); | ||
} | ||
|
||
static inline long copy_to_user(void __user *to, const void *from, | ||
unsigned long n) | ||
{ | ||
if (!access_ok(VERIFY_WRITE, to, n)) | ||
return n; | ||
return __copy_to_user(to, from, n); | ||
} | ||
|
||
extern long strncpy_from_user(char *__to, const char __user *__from, | ||
long __len); | ||
extern long strnlen_user(const char __user *s, long n); | ||
|
||
#define __copy_from_user_inatomic __copy_from_user | ||
#define __copy_to_user_inatomic __copy_to_user | ||
|
||
/* Optimized macros */ | ||
#define __get_user_asm(val, insn, addr, err) \ | ||
{ \ | ||
__asm__ __volatile__( \ | ||
" movi %0, %3\n" \ | ||
"1: " insn " %1, 0(%2)\n" \ | ||
" movi %0, 0\n" \ | ||
"2:\n" \ | ||
" .section __ex_table,\"a\"\n" \ | ||
" .word 1b, 2b\n" \ | ||
" .previous" \ | ||
: "=&r" (err), "=r" (val) \ | ||
: "r" (addr), "i" (-EFAULT)); \ | ||
} | ||
|
||
#define __get_user_unknown(val, size, ptr, err) do { \ | ||
err = 0; \ | ||
if (copy_from_user(&(val), ptr, size)) { \ | ||
err = -EFAULT; \ | ||
} \ | ||
} while (0) | ||
|
||
#define __get_user_common(val, size, ptr, err) \ | ||
do { \ | ||
switch (size) { \ | ||
case 1: \ | ||
__get_user_asm(val, "ldbu", ptr, err); \ | ||
break; \ | ||
case 2: \ | ||
__get_user_asm(val, "ldhu", ptr, err); \ | ||
break; \ | ||
case 4: \ | ||
__get_user_asm(val, "ldw", ptr, err); \ | ||
break; \ | ||
default: \ | ||
__get_user_unknown(val, size, ptr, err); \ | ||
break; \ | ||
} \ | ||
} while (0) | ||
|
||
#define __get_user(x, ptr) \ | ||
({ \ | ||
long __gu_err = -EFAULT; \ | ||
const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ | ||
unsigned long __gu_val; \ | ||
__get_user_common(__gu_val, sizeof(*(ptr)), __gu_ptr, __gu_err);\ | ||
(x) = (__typeof__(x))__gu_val; \ | ||
__gu_err; \ | ||
}) | ||
|
||
#define get_user(x, ptr) \ | ||
({ \ | ||
long __gu_err = -EFAULT; \ | ||
const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ | ||
unsigned long __gu_val = 0; \ | ||
if (access_ok(VERIFY_READ, __gu_ptr, sizeof(*__gu_ptr))) \ | ||
__get_user_common(__gu_val, sizeof(*__gu_ptr), \ | ||
__gu_ptr, __gu_err); \ | ||
(x) = (__typeof__(x))__gu_val; \ | ||
__gu_err; \ | ||
}) | ||
|
||
#define __put_user_asm(val, insn, ptr, err) \ | ||
{ \ | ||
__asm__ __volatile__( \ | ||
" movi %0, %3\n" \ | ||
"1: " insn " %1, 0(%2)\n" \ | ||
" movi %0, 0\n" \ | ||
"2:\n" \ | ||
" .section __ex_table,\"a\"\n" \ | ||
" .word 1b, 2b\n" \ | ||
" .previous\n" \ | ||
: "=&r" (err) \ | ||
: "r" (val), "r" (ptr), "i" (-EFAULT)); \ | ||
} | ||
|
||
#define put_user(x, ptr) \ | ||
({ \ | ||
long __pu_err = -EFAULT; \ | ||
__typeof__(*(ptr)) __user *__pu_ptr = (ptr); \ | ||
__typeof__(*(ptr)) __pu_val = (__typeof(*ptr))(x); \ | ||
if (access_ok(VERIFY_WRITE, __pu_ptr, sizeof(*__pu_ptr))) { \ | ||
switch (sizeof(*__pu_ptr)) { \ | ||
case 1: \ | ||
__put_user_asm(__pu_val, "stb", __pu_ptr, __pu_err); \ | ||
break; \ | ||
case 2: \ | ||
__put_user_asm(__pu_val, "sth", __pu_ptr, __pu_err); \ | ||
break; \ | ||
case 4: \ | ||
__put_user_asm(__pu_val, "stw", __pu_ptr, __pu_err); \ | ||
break; \ | ||
default: \ | ||
/* XXX: This looks wrong... */ \ | ||
__pu_err = 0; \ | ||
if (copy_to_user(__pu_ptr, &(__pu_val), \ | ||
sizeof(*__pu_ptr))) \ | ||
__pu_err = -EFAULT; \ | ||
break; \ | ||
} \ | ||
} \ | ||
__pu_err; \ | ||
}) | ||
|
||
#define __put_user(x, ptr) put_user(x, ptr) | ||
|
||
#endif /* _ASM_NIOS2_UACCESS_H */ |
Oops, something went wrong.