Commit 6ba045f9 authored by Jayachandran C's avatar Jayachandran C Committed by Ralf Baechle

MIPS: Move generated code to .text for microMIPS

Prepare of a next patch which will call tlbmiss_handler_setup_pgd on
microMIPS. MicroMIPS complains if the called code s not in the .text
section. To fix this we generate code into space reserved in
arch/mips/mm/tlb-funcs.S

While there, move the rest of the generated functions (handle_tlbl,
handle_tlbs, handle_tlbm) to the same file.
Signed-off-by: default avatarJayachandran C <jchandra@broadcom.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/5542/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 1990e542
...@@ -28,11 +28,7 @@ ...@@ -28,11 +28,7 @@
#define TLBMISS_HANDLER_SETUP_PGD(pgd) \ #define TLBMISS_HANDLER_SETUP_PGD(pgd) \
do { \ do { \
void (*tlbmiss_handler_setup_pgd)(unsigned long); \ extern void tlbmiss_handler_setup_pgd(unsigned long); \
extern u32 tlbmiss_handler_setup_pgd_array[16]; \
\
tlbmiss_handler_setup_pgd = \
(__typeof__(tlbmiss_handler_setup_pgd)) tlbmiss_handler_setup_pgd_array; \
tlbmiss_handler_setup_pgd((unsigned long)(pgd)); \ tlbmiss_handler_setup_pgd((unsigned long)(pgd)); \
} while (0) } while (0)
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
obj-y += cache.o dma-default.o extable.o fault.o \ obj-y += cache.o dma-default.o extable.o fault.o \
gup.o init.o mmap.o page.o page-funcs.o \ gup.o init.o mmap.o page.o page-funcs.o \
tlbex.o tlbex-fault.o uasm-mips.o tlbex.o tlbex-fault.o tlb-funcs.o uasm-mips.o
obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
obj-$(CONFIG_64BIT) += pgtable-64.o obj-$(CONFIG_64BIT) += pgtable-64.o
......
/*
* 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.
*
* Micro-assembler generated tlb handler functions.
*
* Copyright (C) 2013 Broadcom Corporation.
*
* Based on mm/page-funcs.c
* Copyright (C) 2012 MIPS Technologies, Inc.
* Copyright (C) 2012 Ralf Baechle <ralf@linux-mips.org>
*/
#include <asm/asm.h>
#include <asm/regdef.h>
#define FASTPATH_SIZE 128
LEAF(tlbmiss_handler_setup_pgd)
.space 16 * 4
END(tlbmiss_handler_setup_pgd)
EXPORT(tlbmiss_handler_setup_pgd_end)
LEAF(handle_tlbm)
.space FASTPATH_SIZE * 4
END(handle_tlbm)
EXPORT(handle_tlbm_end)
LEAF(handle_tlbs)
.space FASTPATH_SIZE * 4
END(handle_tlbs)
EXPORT(handle_tlbs_end)
LEAF(handle_tlbl)
.space FASTPATH_SIZE * 4
END(handle_tlbl)
EXPORT(handle_tlbl_end)
...@@ -1455,27 +1455,25 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) ...@@ -1455,27 +1455,25 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
dump_handler("r4000_tlb_refill", (u32 *)ebase, 64); dump_handler("r4000_tlb_refill", (u32 *)ebase, 64);
} }
/* extern u32 handle_tlbl[], handle_tlbl_end[];
* 128 instructions for the fastpath handler is generous and should extern u32 handle_tlbs[], handle_tlbs_end[];
* never be exceeded. extern u32 handle_tlbm[], handle_tlbm_end[];
*/
#define FASTPATH_SIZE 128
u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned;
u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
u32 tlbmiss_handler_setup_pgd_array[16] __cacheline_aligned; extern u32 tlbmiss_handler_setup_pgd[], tlbmiss_handler_setup_pgd_end[];
static void __cpuinit build_r4000_setup_pgd(void) static void __cpuinit build_r4000_setup_pgd(void)
{ {
const int a0 = 4; const int a0 = 4;
const int a1 = 5; const int a1 = 5;
u32 *p = tlbmiss_handler_setup_pgd_array; u32 *p = tlbmiss_handler_setup_pgd_array;
const int tlbmiss_handler_setup_pgd_size =
tlbmiss_handler_setup_pgd_end - tlbmiss_handler_setup_pgd;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
memset(tlbmiss_handler_setup_pgd_array, 0, sizeof(tlbmiss_handler_setup_pgd_array)); memset(tlbmiss_handler_setup_pgd, 0, tlbmiss_handler_setup_pgd_size *
sizeof(tlbmiss_handler_setup_pgd[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -1503,15 +1501,15 @@ static void __cpuinit build_r4000_setup_pgd(void) ...@@ -1503,15 +1501,15 @@ static void __cpuinit build_r4000_setup_pgd(void)
uasm_i_jr(&p, 31); uasm_i_jr(&p, 31);
UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg); UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg);
} }
if (p - tlbmiss_handler_setup_pgd_array > ARRAY_SIZE(tlbmiss_handler_setup_pgd_array)) if (p >= tlbmiss_handler_setup_pgd_end)
panic("tlbmiss_handler_setup_pgd_array space exceeded"); panic("tlbmiss_handler_setup_pgd space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote tlbmiss_handler_setup_pgd_array (%u instructions).\n", pr_debug("Wrote tlbmiss_handler_setup_pgd (%u instructions).\n",
(unsigned int)(p - tlbmiss_handler_setup_pgd_array)); (unsigned int)(p - tlbmiss_handler_setup_pgd));
dump_handler("tlbmiss_handler", dump_handler("tlbmiss_handler", tlbmiss_handler_setup_pgd,
tlbmiss_handler_setup_pgd_array, tlbmiss_handler_setup_pgd_size);
ARRAY_SIZE(tlbmiss_handler_setup_pgd_array));
} }
#endif #endif
...@@ -1756,10 +1754,11 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte, ...@@ -1756,10 +1754,11 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
static void __cpuinit build_r3000_tlb_load_handler(void) static void __cpuinit build_r3000_tlb_load_handler(void)
{ {
u32 *p = handle_tlbl; u32 *p = handle_tlbl;
const int handle_tlbl_size = handle_tlbl_end - handle_tlbl;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
memset(handle_tlbl, 0, sizeof(handle_tlbl)); memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -1773,23 +1772,24 @@ static void __cpuinit build_r3000_tlb_load_handler(void) ...@@ -1773,23 +1772,24 @@ static void __cpuinit build_r3000_tlb_load_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbl) > FASTPATH_SIZE) if (p >= handle_tlbl_end)
panic("TLB load handler fastpath space exceeded"); panic("TLB load handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB load handler fastpath (%u instructions).\n", pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbl)); (unsigned int)(p - handle_tlbl));
dump_handler("r3000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl)); dump_handler("r3000_tlb_load", handle_tlbl, handle_tlbl_size);
} }
static void __cpuinit build_r3000_tlb_store_handler(void) static void __cpuinit build_r3000_tlb_store_handler(void)
{ {
u32 *p = handle_tlbs; u32 *p = handle_tlbs;
const int handle_tlbs_size = handle_tlbs_end - handle_tlbs;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
memset(handle_tlbs, 0, sizeof(handle_tlbs)); memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -1803,23 +1803,24 @@ static void __cpuinit build_r3000_tlb_store_handler(void) ...@@ -1803,23 +1803,24 @@ static void __cpuinit build_r3000_tlb_store_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbs) > FASTPATH_SIZE) if (p >= handle_tlbs)
panic("TLB store handler fastpath space exceeded"); panic("TLB store handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB store handler fastpath (%u instructions).\n", pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbs)); (unsigned int)(p - handle_tlbs));
dump_handler("r3000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs)); dump_handler("r3000_tlb_store", handle_tlbs, handle_tlbs_size);
} }
static void __cpuinit build_r3000_tlb_modify_handler(void) static void __cpuinit build_r3000_tlb_modify_handler(void)
{ {
u32 *p = handle_tlbm; u32 *p = handle_tlbm;
const int handle_tlbm_size = handle_tlbm_end - handle_tlbm;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
memset(handle_tlbm, 0, sizeof(handle_tlbm)); memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -1833,14 +1834,14 @@ static void __cpuinit build_r3000_tlb_modify_handler(void) ...@@ -1833,14 +1834,14 @@ static void __cpuinit build_r3000_tlb_modify_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbm) > FASTPATH_SIZE) if (p >= handle_tlbm_end)
panic("TLB modify handler fastpath space exceeded"); panic("TLB modify handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n", pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbm)); (unsigned int)(p - handle_tlbm));
dump_handler("r3000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm)); dump_handler("r3000_tlb_modify", handle_tlbm, handle_tlbm_size);
} }
#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */ #endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
...@@ -1904,11 +1905,12 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l, ...@@ -1904,11 +1905,12 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l,
static void __cpuinit build_r4000_tlb_load_handler(void) static void __cpuinit build_r4000_tlb_load_handler(void)
{ {
u32 *p = handle_tlbl; u32 *p = handle_tlbl;
const int handle_tlbl_size = handle_tlbl_end - handle_tlbl;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
struct work_registers wr; struct work_registers wr;
memset(handle_tlbl, 0, sizeof(handle_tlbl)); memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -2047,24 +2049,25 @@ static void __cpuinit build_r4000_tlb_load_handler(void) ...@@ -2047,24 +2049,25 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbl) > FASTPATH_SIZE) if (p >= handle_tlbl_end)
panic("TLB load handler fastpath space exceeded"); panic("TLB load handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB load handler fastpath (%u instructions).\n", pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbl)); (unsigned int)(p - handle_tlbl));
dump_handler("r4000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl)); dump_handler("r4000_tlb_load", handle_tlbl, handle_tlbl_size);
} }
static void __cpuinit build_r4000_tlb_store_handler(void) static void __cpuinit build_r4000_tlb_store_handler(void)
{ {
u32 *p = handle_tlbs; u32 *p = handle_tlbs;
const int handle_tlbs_size = handle_tlbs_end - handle_tlbs;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
struct work_registers wr; struct work_registers wr;
memset(handle_tlbs, 0, sizeof(handle_tlbs)); memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -2101,24 +2104,25 @@ static void __cpuinit build_r4000_tlb_store_handler(void) ...@@ -2101,24 +2104,25 @@ static void __cpuinit build_r4000_tlb_store_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbs) > FASTPATH_SIZE) if (p >= handle_tlbs_end)
panic("TLB store handler fastpath space exceeded"); panic("TLB store handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB store handler fastpath (%u instructions).\n", pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbs)); (unsigned int)(p - handle_tlbs));
dump_handler("r4000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs)); dump_handler("r4000_tlb_store", handle_tlbs, handle_tlbs_size);
} }
static void __cpuinit build_r4000_tlb_modify_handler(void) static void __cpuinit build_r4000_tlb_modify_handler(void)
{ {
u32 *p = handle_tlbm; u32 *p = handle_tlbm;
const int handle_tlbm_size = handle_tlbm_end - handle_tlbm;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
struct work_registers wr; struct work_registers wr;
memset(handle_tlbm, 0, sizeof(handle_tlbm)); memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -2156,14 +2160,14 @@ static void __cpuinit build_r4000_tlb_modify_handler(void) ...@@ -2156,14 +2160,14 @@ static void __cpuinit build_r4000_tlb_modify_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbm) > FASTPATH_SIZE) if (p >= handle_tlbm_end)
panic("TLB modify handler fastpath space exceeded"); panic("TLB modify handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n", pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbm)); (unsigned int)(p - handle_tlbm));
dump_handler("r4000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm)); dump_handler("r4000_tlb_modify", handle_tlbm, handle_tlbm_size);
} }
void __cpuinit build_tlb_refill_handler(void) void __cpuinit build_tlb_refill_handler(void)
...@@ -2235,13 +2239,13 @@ void __cpuinit build_tlb_refill_handler(void) ...@@ -2235,13 +2239,13 @@ void __cpuinit build_tlb_refill_handler(void)
void __cpuinit flush_tlb_handlers(void) void __cpuinit flush_tlb_handlers(void)
{ {
local_flush_icache_range((unsigned long)handle_tlbl, local_flush_icache_range((unsigned long)handle_tlbl,
(unsigned long)handle_tlbl + sizeof(handle_tlbl)); (unsigned long)handle_tlbl_end);
local_flush_icache_range((unsigned long)handle_tlbs, local_flush_icache_range((unsigned long)handle_tlbs,
(unsigned long)handle_tlbs + sizeof(handle_tlbs)); (unsigned long)handle_tlbs_end);
local_flush_icache_range((unsigned long)handle_tlbm, local_flush_icache_range((unsigned long)handle_tlbm,
(unsigned long)handle_tlbm + sizeof(handle_tlbm)); (unsigned long)handle_tlbm_end);
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd_array, local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd,
(unsigned long)tlbmiss_handler_setup_pgd_array + sizeof(handle_tlbm)); (unsigned long)tlbmiss_handler_setup_pgd_end);
#endif #endif
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment