Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus: (26 commits) MIPS: Malta: enable Cirrus FB console MIPS: add CONFIG_VIRTUALIZATION for virtio support MIPS: Implement __read_mostly MIPS: ath79: add common WMAC device for AR913X based boards MIPS: ath79: Add initial support for the Atheros AP81 reference board MIPS: ath79: add common SPI controller device SPI: Add SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs MIPS: ath79: add common GPIO buttons device MIPS: ath79: add common watchdog device MIPS: ath79: add common GPIO LEDs device MIPS: ath79: add initial support for the Atheros PB44 reference board MIPS: ath79: utilize the MIPS multi-machine support MIPS: ath79: add GPIOLIB support MIPS: Add initial support for the Atheros AR71XX/AR724X/AR931X SoCs MIPS: jump label: Add MIPS support. MIPS: Use WARN() in uasm for better diagnostics. MIPS: Optimize TLB handlers for Octeon CPUs MIPS: Add LDX and LWX instructions to uasm. MIPS: Use BBIT instructions in TLB handlers MIPS: Declare uasm bbit0 and bbit1 functions. ...
This commit is contained in:
@ -95,6 +95,7 @@ obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o
|
||||
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o
|
||||
obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
|
||||
|
||||
obj-$(CONFIG_OF) += prom.o
|
||||
|
||||
@ -106,4 +107,6 @@ obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/
|
||||
|
||||
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
|
||||
|
||||
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
||||
|
||||
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
|
||||
|
@ -739,6 +739,8 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
|
||||
&& cpu_has_tlb)
|
||||
c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
|
||||
|
||||
c->kscratch_mask = (config4 >> 16) & 0xff;
|
||||
|
||||
return config4 & MIPS_CONF_M;
|
||||
}
|
||||
|
||||
|
54
arch/mips/kernel/jump_label.c
Normal file
54
arch/mips/kernel/jump_label.c
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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) 2010 Cavium Networks, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/cpu.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/inst.h>
|
||||
|
||||
#ifdef HAVE_JUMP_LABEL
|
||||
|
||||
#define J_RANGE_MASK ((1ul << 28) - 1)
|
||||
|
||||
void arch_jump_label_transform(struct jump_entry *e,
|
||||
enum jump_label_type type)
|
||||
{
|
||||
union mips_instruction insn;
|
||||
union mips_instruction *insn_p =
|
||||
(union mips_instruction *)(unsigned long)e->code;
|
||||
|
||||
/* Jump only works within a 256MB aligned region. */
|
||||
BUG_ON((e->target & ~J_RANGE_MASK) != (e->code & ~J_RANGE_MASK));
|
||||
|
||||
/* Target must have 4 byte alignment. */
|
||||
BUG_ON((e->target & 3) != 0);
|
||||
|
||||
if (type == JUMP_LABEL_ENABLE) {
|
||||
insn.j_format.opcode = j_op;
|
||||
insn.j_format.target = (e->target & J_RANGE_MASK) >> 2;
|
||||
} else {
|
||||
insn.word = 0; /* nop */
|
||||
}
|
||||
|
||||
get_online_cpus();
|
||||
mutex_lock(&text_mutex);
|
||||
*insn_p = insn;
|
||||
|
||||
flush_icache_range((unsigned long)insn_p,
|
||||
(unsigned long)insn_p + sizeof(*insn_p));
|
||||
|
||||
mutex_unlock(&text_mutex);
|
||||
put_online_cpus();
|
||||
}
|
||||
|
||||
#endif /* HAVE_JUMP_LABEL */
|
86
arch/mips/kernel/mips_machine.c
Normal file
86
arch/mips/kernel/mips_machine.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#include <linux/mm.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/mips_machine.h>
|
||||
|
||||
static struct mips_machine *mips_machine __initdata;
|
||||
static char *mips_machine_name = "Unknown";
|
||||
|
||||
#define for_each_machine(mach) \
|
||||
for ((mach) = (struct mips_machine *)&__mips_machines_start; \
|
||||
(mach) && \
|
||||
(unsigned long)(mach) < (unsigned long)&__mips_machines_end; \
|
||||
(mach)++)
|
||||
|
||||
__init void mips_set_machine_name(const char *name)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (name == NULL)
|
||||
return;
|
||||
|
||||
p = kstrdup(name, GFP_KERNEL);
|
||||
if (!p)
|
||||
pr_err("MIPS: no memory for machine_name\n");
|
||||
|
||||
mips_machine_name = p;
|
||||
}
|
||||
|
||||
char *mips_get_machine_name(void)
|
||||
{
|
||||
return mips_machine_name;
|
||||
}
|
||||
|
||||
__init int mips_machtype_setup(char *id)
|
||||
{
|
||||
struct mips_machine *mach;
|
||||
|
||||
for_each_machine(mach) {
|
||||
if (mach->mach_id == NULL)
|
||||
continue;
|
||||
|
||||
if (strcmp(mach->mach_id, id) == 0) {
|
||||
mips_machtype = mach->mach_type;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
pr_err("MIPS: no machine found for id '%s', supported machines:\n", id);
|
||||
pr_err("%-24s %s\n", "id", "name");
|
||||
for_each_machine(mach)
|
||||
pr_err("%-24s %s\n", mach->mach_id, mach->mach_name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("machtype=", mips_machtype_setup);
|
||||
|
||||
__init void mips_machine_setup(void)
|
||||
{
|
||||
struct mips_machine *mach;
|
||||
|
||||
for_each_machine(mach) {
|
||||
if (mips_machtype == mach->mach_type) {
|
||||
mips_machine = mach;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mips_machine)
|
||||
return;
|
||||
|
||||
mips_set_machine_name(mips_machine->mach_name);
|
||||
pr_info("MIPS: machine is %s\n", mips_machine_name);
|
||||
|
||||
if (mips_machine->mach_setup)
|
||||
mips_machine->mach_setup();
|
||||
}
|
@ -30,6 +30,8 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/jump_label.h>
|
||||
|
||||
#include <asm/pgtable.h> /* MODULE_START */
|
||||
|
||||
struct mips_hi16 {
|
||||
@ -382,6 +384,9 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||
const Elf_Shdr *s;
|
||||
char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
|
||||
|
||||
/* Make jump label nops. */
|
||||
jump_label_apply_nops(me);
|
||||
|
||||
INIT_LIST_HEAD(&me->arch.dbe_list);
|
||||
for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
|
||||
if (strcmp("__dbe_table", secstrings + s->sh_name) != 0)
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <asm/cpu-features.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mips_machine.h>
|
||||
|
||||
unsigned int vced_count, vcei_count;
|
||||
|
||||
@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
/*
|
||||
* For the first processor also print the system type
|
||||
*/
|
||||
if (n == 0)
|
||||
if (n == 0) {
|
||||
seq_printf(m, "system type\t\t: %s\n", get_system_type());
|
||||
if (mips_get_machine_name())
|
||||
seq_printf(m, "machine\t\t\t: %s\n",
|
||||
mips_get_machine_name());
|
||||
}
|
||||
|
||||
seq_printf(m, "processor\t\t: %ld\n", n);
|
||||
sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
|
||||
@ -69,6 +74,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
);
|
||||
seq_printf(m, "shadow register sets\t: %d\n",
|
||||
cpu_data[n].srsets);
|
||||
seq_printf(m, "kscratch registers\t: %d\n",
|
||||
hweight8(cpu_data[n].kscratch_mask));
|
||||
seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
|
||||
|
||||
sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
|
||||
|
@ -70,7 +70,7 @@ static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
|
||||
* mips_io_port_base is the begin of the address space to which x86 style
|
||||
* I/O ports are mapped.
|
||||
*/
|
||||
const unsigned long mips_io_port_base __read_mostly = -1;
|
||||
const unsigned long mips_io_port_base = -1;
|
||||
EXPORT_SYMBOL(mips_io_port_base);
|
||||
|
||||
static struct resource code_resource = { .name = "Kernel code", };
|
||||
|
@ -1592,7 +1592,6 @@ void __cpuinit per_cpu_trap_init(void)
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
|
||||
TLBMISS_HANDLER_SETUP();
|
||||
|
||||
atomic_inc(&init_mm.mm_count);
|
||||
current->active_mm = &init_mm;
|
||||
@ -1614,6 +1613,7 @@ void __cpuinit per_cpu_trap_init(void)
|
||||
write_c0_wired(0);
|
||||
}
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
TLBMISS_HANDLER_SETUP();
|
||||
}
|
||||
|
||||
/* Install CPU exception handler */
|
||||
|
@ -98,6 +98,13 @@ SECTIONS
|
||||
INIT_TEXT_SECTION(PAGE_SIZE)
|
||||
INIT_DATA_SECTION(16)
|
||||
|
||||
. = ALIGN(4);
|
||||
.mips.machines.init : AT(ADDR(.mips.machines.init) - LOAD_OFFSET) {
|
||||
__mips_machines_start = .;
|
||||
*(.mips.machines.init)
|
||||
__mips_machines_end = .;
|
||||
}
|
||||
|
||||
/* .exit.text is discarded at runtime, not link time, to deal with
|
||||
* references from .rodata
|
||||
*/
|
||||
|
Reference in New Issue
Block a user