Commit 2a21c730 authored by Fuxin Zhang's avatar Fuxin Zhang Committed by Ralf Baechle

[MIPS] define Hit_Invalidate_I to Index_Invalidate_I for loongson2

Signed-off-by: default avatarFuxin Zhang <zhangfx@lemote.com>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent fee578fa
...@@ -894,6 +894,16 @@ choice ...@@ -894,6 +894,16 @@ choice
prompt "CPU type" prompt "CPU type"
default CPU_R4X00 default CPU_R4X00
config CPU_LOONGSON2
bool "Loongson 2"
depends on SYS_HAS_CPU_LOONGSON2
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
help
The Loongson 2E processor implements the MIPS III instruction set
with many extensions.
config CPU_MIPS32_R1 config CPU_MIPS32_R1
bool "MIPS32 Release 1" bool "MIPS32 Release 1"
depends on SYS_HAS_CPU_MIPS32_R1 depends on SYS_HAS_CPU_MIPS32_R1
...@@ -1104,6 +1114,9 @@ config CPU_SB1 ...@@ -1104,6 +1114,9 @@ config CPU_SB1
endchoice endchoice
config SYS_HAS_CPU_LOONGSON2
bool
config SYS_HAS_CPU_MIPS32_R1 config SYS_HAS_CPU_MIPS32_R1
bool bool
...@@ -1438,6 +1451,15 @@ config CPU_HAS_SMARTMIPS ...@@ -1438,6 +1451,15 @@ config CPU_HAS_SMARTMIPS
config CPU_HAS_WB config CPU_HAS_WB
bool bool
config 64BIT_CONTEXT
bool "Save 64bit integer registers"
depends on 32BIT && CPU_LOONGSON2
help
Loongson2 CPU is 64bit , when used in 32BIT mode, its integer
registers can still be accessed as 64bit, mainly for multimedia
instructions. We must have all 64bit save/restored to make sure
those instructions to get correct result.
# #
# Vectored interrupt mode is an R2 feature # Vectored interrupt mode is an R2 feature
# #
......
...@@ -118,6 +118,7 @@ cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap ...@@ -118,6 +118,7 @@ cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap
cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap
cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap
cflags-$(CONFIG_CPU_LOONGSON2) += -march=r4600 -Wa,--trap
cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
-Wa,-mips32 -Wa,--trap -Wa,-mips32 -Wa,--trap
cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
......
...@@ -14,14 +14,15 @@ binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ ...@@ -14,14 +14,15 @@ binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_MODULES) += mips_ksyms.o module.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o
obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o
obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R4000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R4000) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R8000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R8000) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o
...@@ -29,9 +30,9 @@ obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o ...@@ -29,9 +30,9 @@ obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R10000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R10000) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_SB1) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_SB1) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o
......
...@@ -485,6 +485,14 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) ...@@ -485,6 +485,14 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
MIPS_CPU_LLSC; MIPS_CPU_LLSC;
c->tlbsize = 64; c->tlbsize = 64;
break; break;
case PRID_IMP_LOONGSON2:
c->cputype = CPU_LOONGSON2;
c->isa_level = MIPS_CPU_ISA_III;
c->options = R4K_OPTS |
MIPS_CPU_FPU | MIPS_CPU_LLSC |
MIPS_CPU_32FPR;
c->tlbsize = 64;
break;
} }
} }
......
...@@ -83,6 +83,7 @@ static const char *cpu_name[] = { ...@@ -83,6 +83,7 @@ static const char *cpu_name[] = {
[CPU_VR4181A] = "NEC VR4181A", [CPU_VR4181A] = "NEC VR4181A",
[CPU_SR71000] = "Sandcraft SR71000", [CPU_SR71000] = "Sandcraft SR71000",
[CPU_PR4450] = "Philips PR4450", [CPU_PR4450] = "Philips PR4450",
[CPU_LOONGSON2] = "ICT Loongson-2",
}; };
......
...@@ -8,6 +8,7 @@ lib-y += csum_partial.o memcpy.o memcpy-inatomic.o memset.o strlen_user.o \ ...@@ -8,6 +8,7 @@ lib-y += csum_partial.o memcpy.o memcpy-inatomic.o memset.o strlen_user.o \
obj-y += iomap.o obj-y += iomap.o
obj-$(CONFIG_PCI) += iomap-pci.o obj-$(CONFIG_PCI) += iomap-pci.o
obj-$(CONFIG_CPU_LOONGSON2) += dump_tlb.o
obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o
......
...@@ -9,6 +9,7 @@ obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o ...@@ -9,6 +9,7 @@ obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
obj-$(CONFIG_64BIT) += pgtable-64.o obj-$(CONFIG_64BIT) += pgtable-64.o
obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_HIGHMEM) += highmem.o
obj-$(CONFIG_CPU_LOONGSON2) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
......
...@@ -335,6 +335,10 @@ static void r4k_flush_cache_all(void) ...@@ -335,6 +335,10 @@ static void r4k_flush_cache_all(void)
static inline void local_r4k___flush_cache_all(void * args) static inline void local_r4k___flush_cache_all(void * args)
{ {
#if defined(CONFIG_CPU_LOONGSON2)
r4k_blast_scache();
return;
#endif
r4k_blast_dcache(); r4k_blast_dcache();
r4k_blast_icache(); r4k_blast_icache();
...@@ -848,6 +852,24 @@ static void __init probe_pcache(void) ...@@ -848,6 +852,24 @@ static void __init probe_pcache(void)
c->options |= MIPS_CPU_PREFETCH; c->options |= MIPS_CPU_PREFETCH;
break; break;
case CPU_LOONGSON2:
icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
if (prid & 0x3)
c->icache.ways = 4;
else
c->icache.ways = 2;
c->icache.waybit = 0;
dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
if (prid & 0x3)
c->dcache.ways = 4;
else
c->dcache.ways = 2;
c->dcache.waybit = 0;
break;
default: default:
if (!(config & MIPS_CONF_M)) if (!(config & MIPS_CONF_M))
panic("Don't know how to probe P-caches on this cpu."); panic("Don't know how to probe P-caches on this cpu.");
...@@ -963,6 +985,14 @@ static void __init probe_pcache(void) ...@@ -963,6 +985,14 @@ static void __init probe_pcache(void)
break; break;
} }
#ifdef CONFIG_CPU_LOONGSON2
/*
* LOONGSON2 has 4 way icache, but when using indexed cache op,
* one op will act on all 4 ways
*/
c->icache.ways = 1;
#endif
printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n",
icache_size >> 10, icache_size >> 10,
cpu_has_vtag_icache ? "virtually tagged" : "physically tagged", cpu_has_vtag_icache ? "virtually tagged" : "physically tagged",
...@@ -1036,6 +1066,24 @@ static int __init probe_scache(void) ...@@ -1036,6 +1066,24 @@ static int __init probe_scache(void)
return 1; return 1;
} }
#if defined(CONFIG_CPU_LOONGSON2)
static void __init loongson2_sc_init(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
scache_size = 512*1024;
c->scache.linesz = 32;
c->scache.ways = 4;
c->scache.waybit = 0;
c->scache.waysize = scache_size / (c->scache.ways);
c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways);
pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n",
scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
c->options |= MIPS_CPU_INCLUSIVE_CACHES;
}
#endif
extern int r5k_sc_init(void); extern int r5k_sc_init(void);
extern int rm7k_sc_init(void); extern int rm7k_sc_init(void);
extern int mips_sc_init(void); extern int mips_sc_init(void);
...@@ -1085,6 +1133,12 @@ static void __init setup_scache(void) ...@@ -1085,6 +1133,12 @@ static void __init setup_scache(void)
#endif #endif
return; return;
#if defined(CONFIG_CPU_LOONGSON2)
case CPU_LOONGSON2:
loongson2_sc_init();
return;
#endif
default: default:
if (c->isa_level == MIPS_CPU_ISA_M32R1 || if (c->isa_level == MIPS_CPU_ISA_M32R1 ||
c->isa_level == MIPS_CPU_ISA_M32R2 || c->isa_level == MIPS_CPU_ISA_M32R2 ||
......
...@@ -48,6 +48,22 @@ extern void build_tlb_refill_handler(void); ...@@ -48,6 +48,22 @@ extern void build_tlb_refill_handler(void);
#endif /* CONFIG_MIPS_MT_SMTC */ #endif /* CONFIG_MIPS_MT_SMTC */
#if defined(CONFIG_CPU_LOONGSON2)
/*
* LOONGSON2 has a 4 entry itlb which is a subset of dtlb,
* unfortrunately, itlb is not totally transparent to software.
*/
#define FLUSH_ITLB write_c0_diag(4);
#define FLUSH_ITLB_VM(vma) { if ((vma)->vm_flags & VM_EXEC) write_c0_diag(4); }
#else
#define FLUSH_ITLB
#define FLUSH_ITLB_VM(vma)
#endif
void local_flush_tlb_all(void) void local_flush_tlb_all(void)
{ {
unsigned long flags; unsigned long flags;
...@@ -73,6 +89,7 @@ void local_flush_tlb_all(void) ...@@ -73,6 +89,7 @@ void local_flush_tlb_all(void)
} }
tlbw_use_hazard(); tlbw_use_hazard();
write_c0_entryhi(old_ctx); write_c0_entryhi(old_ctx);
FLUSH_ITLB;
EXIT_CRITICAL(flags); EXIT_CRITICAL(flags);
} }
...@@ -136,6 +153,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, ...@@ -136,6 +153,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
} else { } else {
drop_mmu_context(mm, cpu); drop_mmu_context(mm, cpu);
} }
FLUSH_ITLB;
EXIT_CRITICAL(flags); EXIT_CRITICAL(flags);
} }
} }
...@@ -178,6 +196,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) ...@@ -178,6 +196,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
} else { } else {
local_flush_tlb_all(); local_flush_tlb_all();
} }
FLUSH_ITLB;
EXIT_CRITICAL(flags); EXIT_CRITICAL(flags);
} }
...@@ -210,6 +229,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) ...@@ -210,6 +229,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
finish: finish:
write_c0_entryhi(oldpid); write_c0_entryhi(oldpid);
FLUSH_ITLB_VM(vma);
EXIT_CRITICAL(flags); EXIT_CRITICAL(flags);
} }
} }
...@@ -241,7 +261,7 @@ void local_flush_tlb_one(unsigned long page) ...@@ -241,7 +261,7 @@ void local_flush_tlb_one(unsigned long page)
tlbw_use_hazard(); tlbw_use_hazard();
} }
write_c0_entryhi(oldpid); write_c0_entryhi(oldpid);
FLUSH_ITLB;
EXIT_CRITICAL(flags); EXIT_CRITICAL(flags);
} }
...@@ -293,6 +313,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) ...@@ -293,6 +313,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
else else
tlb_write_indexed(); tlb_write_indexed();
tlbw_use_hazard(); tlbw_use_hazard();
FLUSH_ITLB_VM(vma);
EXIT_CRITICAL(flags); EXIT_CRITICAL(flags);
} }
......
...@@ -893,6 +893,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l, ...@@ -893,6 +893,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_4KSC: case CPU_4KSC:
case CPU_20KC: case CPU_20KC:
case CPU_25KF: case CPU_25KF:
case CPU_LOONGSON2:
tlbw(p); tlbw(p);
break; break;
...@@ -1276,7 +1277,8 @@ static void __init build_r4000_tlb_refill_handler(void) ...@@ -1276,7 +1277,8 @@ static void __init build_r4000_tlb_refill_handler(void)
* need three, with the second nop'ed and the third being * need three, with the second nop'ed and the third being
* unused. * unused.
*/ */
#ifdef CONFIG_32BIT /* Loongson2 ebase is different than r4k, we have more space */
#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
if ((p - tlb_handler) > 64) if ((p - tlb_handler) > 64)
panic("TLB refill handler space exceeded"); panic("TLB refill handler space exceeded");
#else #else
...@@ -1289,7 +1291,7 @@ static void __init build_r4000_tlb_refill_handler(void) ...@@ -1289,7 +1291,7 @@ static void __init build_r4000_tlb_refill_handler(void)
/* /*
* Now fold the handler in the TLB refill handler space. * Now fold the handler in the TLB refill handler space.
*/ */
#ifdef CONFIG_32BIT #if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
f = final_handler; f = final_handler;
/* Simplest case, just copy the handler. */ /* Simplest case, just copy the handler. */
copy_handler(relocs, labels, tlb_handler, p, f); copy_handler(relocs, labels, tlb_handler, p, f);
...@@ -1336,7 +1338,7 @@ static void __init build_r4000_tlb_refill_handler(void) ...@@ -1336,7 +1338,7 @@ static void __init build_r4000_tlb_refill_handler(void)
final_len); final_len);
f = final_handler; f = final_handler;
#ifdef CONFIG_64BIT #if defined(CONFIG_64BIT) && !defined(CONFIG_CPU_LOONGSON2)
if (final_len > 32) if (final_len > 32)
final_len = 64; final_len = 64;
else else
......
...@@ -20,7 +20,11 @@ ...@@ -20,7 +20,11 @@
#define Index_Load_Tag_D 0x05 #define Index_Load_Tag_D 0x05
#define Index_Store_Tag_I 0x08 #define Index_Store_Tag_I 0x08
#define Index_Store_Tag_D 0x09 #define Index_Store_Tag_D 0x09
#if defined(CONFIG_CPU_LOONGSON2)
#define Hit_Invalidate_I 0x00
#else
#define Hit_Invalidate_I 0x10 #define Hit_Invalidate_I 0x10
#endif
#define Hit_Invalidate_D 0x11 #define Hit_Invalidate_D 0x11
#define Hit_Writeback_Inv_D 0x15 #define Hit_Writeback_Inv_D 0x15
......
...@@ -89,6 +89,8 @@ ...@@ -89,6 +89,8 @@
#define PRID_IMP_34K 0x9500 #define PRID_IMP_34K 0x9500
#define PRID_IMP_24KE 0x9600 #define PRID_IMP_24KE 0x9600
#define PRID_IMP_74K 0x9700 #define PRID_IMP_74K 0x9700
#define PRID_IMP_LOONGSON1 0x4200
#define PRID_IMP_LOONGSON2 0x6300
/* /*
* These are the PRID's for when 23:16 == PRID_COMP_SIBYTE * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
...@@ -211,7 +213,10 @@ ...@@ -211,7 +213,10 @@
#define CPU_SB1A 62 #define CPU_SB1A 62
#define CPU_74K 63 #define CPU_74K 63
#define CPU_R14000 64 #define CPU_R14000 64
#define CPU_LAST 64 #define CPU_LOONGSON1 65
#define CPU_LOONGSON2 66
#define CPU_LAST 66
/* /*
* ISA Level encodings * ISA Level encodings
......
...@@ -112,6 +112,8 @@ search_module_dbetables(unsigned long addr) ...@@ -112,6 +112,8 @@ search_module_dbetables(unsigned long addr)
#define MODULE_PROC_FAMILY "RM9000 " #define MODULE_PROC_FAMILY "RM9000 "
#elif defined CONFIG_CPU_SB1 #elif defined CONFIG_CPU_SB1
#define MODULE_PROC_FAMILY "SB1 " #define MODULE_PROC_FAMILY "SB1 "
#elif defined CONFIG_CPU_LOONGSON2
#define MODULE_PROC_FAMILY "LOONGSON2 "
#else #else
#error MODULE_PROC_FAMILY undefined for your processor configuration #error MODULE_PROC_FAMILY undefined for your processor configuration
#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