[PATCH 15/17] RISC-V: Paging and MMU
This patch contains code to manage the RISC-V MMU, including definitions of the page tables and the page walking code. Signed-off-by: Palmer Dabbelt--- arch/riscv/include/asm/mmu_context.h | 69 ++ arch/riscv/include/asm/page.h | 134 +++ arch/riscv/include/asm/pgalloc.h | 124 ++ arch/riscv/include/asm/pgtable-32.h | 25 ++ arch/riscv/include/asm/pgtable-64.h | 84 +++ arch/riscv/include/asm/pgtable-bits.h | 48 arch/riscv/include/asm/pgtable.h | 430 ++ arch/riscv/mm/fault.c | 282 ++ 8 files changed, 1196 insertions(+) create mode 100644 arch/riscv/include/asm/mmu_context.h create mode 100644 arch/riscv/include/asm/page.h create mode 100644 arch/riscv/include/asm/pgalloc.h create mode 100644 arch/riscv/include/asm/pgtable-32.h create mode 100644 arch/riscv/include/asm/pgtable-64.h create mode 100644 arch/riscv/include/asm/pgtable-bits.h create mode 100644 arch/riscv/include/asm/pgtable.h create mode 100644 arch/riscv/mm/fault.c diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h new file mode 100644 index ..de1fc1631fc4 --- /dev/null +++ b/arch/riscv/include/asm/mmu_context.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2012 Regents of the University of California + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _ASM_RISCV_MMU_CONTEXT_H +#define _ASM_RISCV_MMU_CONTEXT_H + +#include + +#include +#include +#include + +static inline void enter_lazy_tlb(struct mm_struct *mm, + struct task_struct *task) +{ +} + +/* Initialize context-related info for a new mm_struct */ +static inline int init_new_context(struct task_struct *task, + struct mm_struct *mm) +{ + return 0; +} + +static inline void destroy_context(struct mm_struct *mm) +{ +} + +static inline pgd_t *current_pgdir(void) +{ + return pfn_to_virt(csr_read(sptbr) & SPTBR_PPN); +} + +static inline void set_pgdir(pgd_t *pgd) +{ + csr_write(sptbr, virt_to_pfn(pgd) | SPTBR_MODE); +} + +static inline void switch_mm(struct mm_struct *prev, + struct mm_struct *next, struct task_struct *task) +{ + if (likely(prev != next)) { + set_pgdir(next->pgd); + local_flush_tlb_all(); + } +} + +static inline void activate_mm(struct mm_struct *prev, + struct mm_struct *next) +{ + switch_mm(prev, next, NULL); +} + +static inline void deactivate_mm(struct task_struct *task, + struct mm_struct *mm) +{ +} + +#endif /* _ASM_RISCV_MMU_CONTEXT_H */ diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h new file mode 100644 index ..5bbbff2d5a60 --- /dev/null +++ b/arch/riscv/include/asm/page.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2009 Chen Liqin + * Copyright (C) 2012 Regents of the University of California + * Copyright (C) 2017 SiFive + * Copyright (C) 2017 XiaojingZhu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _ASM_RISCV_PAGE_H +#define _ASM_RISCV_PAGE_H + +#include +#include + +#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. + * When not using MMU this corresponds to the first free page in + * physical memory (aligned on a page boundary). + */ +#ifdef CONFIG_64BIT +#define PAGE_OFFSET_AC(0x8000, UL) +#else +#define PAGE_OFFSET_AC(0xc000, UL) +#endif + +#define KERN_VIRT_SIZE (-PAGE_OFFSET) + +#ifndef __ASSEMBLY__ + +#define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) +#define PAGE_DOWN(addr)((addr)&(~((PAGE_SIZE)-1))) + +/* align addr on a size boundary - adjust address up/down if needed */ +#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1))) +#define _ALIGN_DOWN(addr, size)((addr)&(~((size)-1))) + +/* align addr on a size boundary - adjust address up if needed */ +#define _ALIGN(addr, size)
[PATCH 15/17] RISC-V: Paging and MMU
This patch contains code to manage the RISC-V MMU, including definitions of the page tables and the page walking code. Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/mmu_context.h | 69 ++ arch/riscv/include/asm/page.h | 134 +++ arch/riscv/include/asm/pgalloc.h | 124 ++ arch/riscv/include/asm/pgtable-32.h | 25 ++ arch/riscv/include/asm/pgtable-64.h | 84 +++ arch/riscv/include/asm/pgtable-bits.h | 48 arch/riscv/include/asm/pgtable.h | 430 ++ arch/riscv/mm/fault.c | 282 ++ 8 files changed, 1196 insertions(+) create mode 100644 arch/riscv/include/asm/mmu_context.h create mode 100644 arch/riscv/include/asm/page.h create mode 100644 arch/riscv/include/asm/pgalloc.h create mode 100644 arch/riscv/include/asm/pgtable-32.h create mode 100644 arch/riscv/include/asm/pgtable-64.h create mode 100644 arch/riscv/include/asm/pgtable-bits.h create mode 100644 arch/riscv/include/asm/pgtable.h create mode 100644 arch/riscv/mm/fault.c diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h new file mode 100644 index ..de1fc1631fc4 --- /dev/null +++ b/arch/riscv/include/asm/mmu_context.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2012 Regents of the University of California + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _ASM_RISCV_MMU_CONTEXT_H +#define _ASM_RISCV_MMU_CONTEXT_H + +#include + +#include +#include +#include + +static inline void enter_lazy_tlb(struct mm_struct *mm, + struct task_struct *task) +{ +} + +/* Initialize context-related info for a new mm_struct */ +static inline int init_new_context(struct task_struct *task, + struct mm_struct *mm) +{ + return 0; +} + +static inline void destroy_context(struct mm_struct *mm) +{ +} + +static inline pgd_t *current_pgdir(void) +{ + return pfn_to_virt(csr_read(sptbr) & SPTBR_PPN); +} + +static inline void set_pgdir(pgd_t *pgd) +{ + csr_write(sptbr, virt_to_pfn(pgd) | SPTBR_MODE); +} + +static inline void switch_mm(struct mm_struct *prev, + struct mm_struct *next, struct task_struct *task) +{ + if (likely(prev != next)) { + set_pgdir(next->pgd); + local_flush_tlb_all(); + } +} + +static inline void activate_mm(struct mm_struct *prev, + struct mm_struct *next) +{ + switch_mm(prev, next, NULL); +} + +static inline void deactivate_mm(struct task_struct *task, + struct mm_struct *mm) +{ +} + +#endif /* _ASM_RISCV_MMU_CONTEXT_H */ diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h new file mode 100644 index ..5bbbff2d5a60 --- /dev/null +++ b/arch/riscv/include/asm/page.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2009 Chen Liqin + * Copyright (C) 2012 Regents of the University of California + * Copyright (C) 2017 SiFive + * Copyright (C) 2017 XiaojingZhu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _ASM_RISCV_PAGE_H +#define _ASM_RISCV_PAGE_H + +#include +#include + +#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. + * When not using MMU this corresponds to the first free page in + * physical memory (aligned on a page boundary). + */ +#ifdef CONFIG_64BIT +#define PAGE_OFFSET_AC(0x8000, UL) +#else +#define PAGE_OFFSET_AC(0xc000, UL) +#endif + +#define KERN_VIRT_SIZE (-PAGE_OFFSET) + +#ifndef __ASSEMBLY__ + +#define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) +#define PAGE_DOWN(addr)((addr)&(~((PAGE_SIZE)-1))) + +/* align addr on a size boundary - adjust address up/down if needed */ +#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1))) +#define _ALIGN_DOWN(addr, size)((addr)&(~((size)-1))) + +/* align addr on a size boundary - adjust address up if needed */ +#define _ALIGN(addr, size) _ALIGN_UP(addr, size) + +#define clear_page(pgaddr)
[PATCH 15/17] RISC-V: Paging and MMU
This patch contains code to manage the RISC-V MMU, including definitions of the page tables and the page walking code. Signed-off-by: Palmer Dabbelt--- arch/riscv/include/asm/mmu_context.h | 69 ++ arch/riscv/include/asm/page.h | 134 +++ arch/riscv/include/asm/pgalloc.h | 124 ++ arch/riscv/include/asm/pgtable-32.h | 25 ++ arch/riscv/include/asm/pgtable-64.h | 84 +++ arch/riscv/include/asm/pgtable-bits.h | 48 arch/riscv/include/asm/pgtable.h | 430 ++ arch/riscv/mm/fault.c | 282 ++ 8 files changed, 1196 insertions(+) create mode 100644 arch/riscv/include/asm/mmu_context.h create mode 100644 arch/riscv/include/asm/page.h create mode 100644 arch/riscv/include/asm/pgalloc.h create mode 100644 arch/riscv/include/asm/pgtable-32.h create mode 100644 arch/riscv/include/asm/pgtable-64.h create mode 100644 arch/riscv/include/asm/pgtable-bits.h create mode 100644 arch/riscv/include/asm/pgtable.h create mode 100644 arch/riscv/mm/fault.c diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h new file mode 100644 index ..de1fc1631fc4 --- /dev/null +++ b/arch/riscv/include/asm/mmu_context.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2012 Regents of the University of California + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _ASM_RISCV_MMU_CONTEXT_H +#define _ASM_RISCV_MMU_CONTEXT_H + +#include + +#include +#include +#include + +static inline void enter_lazy_tlb(struct mm_struct *mm, + struct task_struct *task) +{ +} + +/* Initialize context-related info for a new mm_struct */ +static inline int init_new_context(struct task_struct *task, + struct mm_struct *mm) +{ + return 0; +} + +static inline void destroy_context(struct mm_struct *mm) +{ +} + +static inline pgd_t *current_pgdir(void) +{ + return pfn_to_virt(csr_read(sptbr) & SPTBR_PPN); +} + +static inline void set_pgdir(pgd_t *pgd) +{ + csr_write(sptbr, virt_to_pfn(pgd) | SPTBR_MODE); +} + +static inline void switch_mm(struct mm_struct *prev, + struct mm_struct *next, struct task_struct *task) +{ + if (likely(prev != next)) { + set_pgdir(next->pgd); + local_flush_tlb_all(); + } +} + +static inline void activate_mm(struct mm_struct *prev, + struct mm_struct *next) +{ + switch_mm(prev, next, NULL); +} + +static inline void deactivate_mm(struct task_struct *task, + struct mm_struct *mm) +{ +} + +#endif /* _ASM_RISCV_MMU_CONTEXT_H */ diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h new file mode 100644 index ..5bbbff2d5a60 --- /dev/null +++ b/arch/riscv/include/asm/page.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2009 Chen Liqin + * Copyright (C) 2012 Regents of the University of California + * Copyright (C) 2017 SiFive + * Copyright (C) 2017 XiaojingZhu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _ASM_RISCV_PAGE_H +#define _ASM_RISCV_PAGE_H + +#include +#include + +#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. + * When not using MMU this corresponds to the first free page in + * physical memory (aligned on a page boundary). + */ +#ifdef CONFIG_64BIT +#define PAGE_OFFSET_AC(0x8000, UL) +#else +#define PAGE_OFFSET_AC(0xc000, UL) +#endif + +#define KERN_VIRT_SIZE (-PAGE_OFFSET) + +#ifndef __ASSEMBLY__ + +#define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) +#define PAGE_DOWN(addr)((addr)&(~((PAGE_SIZE)-1))) + +/* align addr on a size boundary - adjust address up/down if needed */ +#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1))) +#define _ALIGN_DOWN(addr, size)((addr)&(~((size)-1))) + +/* align addr on a size boundary - adjust address up if needed */ +#define _ALIGN(addr, size)
[PATCH 15/17] RISC-V: Paging and MMU
This patch contains code to manage the RISC-V MMU, including definitions of the page tables and the page walking code. Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/mmu_context.h | 69 ++ arch/riscv/include/asm/page.h | 134 +++ arch/riscv/include/asm/pgalloc.h | 124 ++ arch/riscv/include/asm/pgtable-32.h | 25 ++ arch/riscv/include/asm/pgtable-64.h | 84 +++ arch/riscv/include/asm/pgtable-bits.h | 48 arch/riscv/include/asm/pgtable.h | 430 ++ arch/riscv/mm/fault.c | 282 ++ 8 files changed, 1196 insertions(+) create mode 100644 arch/riscv/include/asm/mmu_context.h create mode 100644 arch/riscv/include/asm/page.h create mode 100644 arch/riscv/include/asm/pgalloc.h create mode 100644 arch/riscv/include/asm/pgtable-32.h create mode 100644 arch/riscv/include/asm/pgtable-64.h create mode 100644 arch/riscv/include/asm/pgtable-bits.h create mode 100644 arch/riscv/include/asm/pgtable.h create mode 100644 arch/riscv/mm/fault.c diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h new file mode 100644 index ..de1fc1631fc4 --- /dev/null +++ b/arch/riscv/include/asm/mmu_context.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2012 Regents of the University of California + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _ASM_RISCV_MMU_CONTEXT_H +#define _ASM_RISCV_MMU_CONTEXT_H + +#include + +#include +#include +#include + +static inline void enter_lazy_tlb(struct mm_struct *mm, + struct task_struct *task) +{ +} + +/* Initialize context-related info for a new mm_struct */ +static inline int init_new_context(struct task_struct *task, + struct mm_struct *mm) +{ + return 0; +} + +static inline void destroy_context(struct mm_struct *mm) +{ +} + +static inline pgd_t *current_pgdir(void) +{ + return pfn_to_virt(csr_read(sptbr) & SPTBR_PPN); +} + +static inline void set_pgdir(pgd_t *pgd) +{ + csr_write(sptbr, virt_to_pfn(pgd) | SPTBR_MODE); +} + +static inline void switch_mm(struct mm_struct *prev, + struct mm_struct *next, struct task_struct *task) +{ + if (likely(prev != next)) { + set_pgdir(next->pgd); + local_flush_tlb_all(); + } +} + +static inline void activate_mm(struct mm_struct *prev, + struct mm_struct *next) +{ + switch_mm(prev, next, NULL); +} + +static inline void deactivate_mm(struct task_struct *task, + struct mm_struct *mm) +{ +} + +#endif /* _ASM_RISCV_MMU_CONTEXT_H */ diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h new file mode 100644 index ..5bbbff2d5a60 --- /dev/null +++ b/arch/riscv/include/asm/page.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2009 Chen Liqin + * Copyright (C) 2012 Regents of the University of California + * Copyright (C) 2017 SiFive + * Copyright (C) 2017 XiaojingZhu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _ASM_RISCV_PAGE_H +#define _ASM_RISCV_PAGE_H + +#include +#include + +#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. + * When not using MMU this corresponds to the first free page in + * physical memory (aligned on a page boundary). + */ +#ifdef CONFIG_64BIT +#define PAGE_OFFSET_AC(0x8000, UL) +#else +#define PAGE_OFFSET_AC(0xc000, UL) +#endif + +#define KERN_VIRT_SIZE (-PAGE_OFFSET) + +#ifndef __ASSEMBLY__ + +#define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) +#define PAGE_DOWN(addr)((addr)&(~((PAGE_SIZE)-1))) + +/* align addr on a size boundary - adjust address up/down if needed */ +#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1))) +#define _ALIGN_DOWN(addr, size)((addr)&(~((size)-1))) + +/* align addr on a size boundary - adjust address up if needed */ +#define _ALIGN(addr, size) _ALIGN_UP(addr, size) + +#define clear_page(pgaddr)