diff options
Diffstat (limited to 'arch/tile/kernel')
59 files changed, 0 insertions, 27540 deletions
diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile deleted file mode 100644 index 3e43d78731a8..000000000000 --- a/arch/tile/kernel/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for the Linux/TILE kernel. -# - -extra-y := vmlinux.lds head_$(BITS).o -obj-y := backtrace.o entry.o hvglue.o irq.o messaging.o \ - pci-dma.o proc.o process.o ptrace.o reboot.o \ - setup.o signal.o single_step.o stack.o sys.o \ - sysfs.o time.o traps.o unaligned.o vdso.o \ - intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o - -ifdef CONFIG_FUNCTION_TRACER -CFLAGS_REMOVE_ftrace.o = -pg -CFLAGS_REMOVE_early_printk.o = -pg -endif - -obj-$(CONFIG_HARDWALL) += hardwall.o -obj-$(CONFIG_COMPAT) += compat.o compat_signal.o -obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o -obj-$(CONFIG_MODULES) += module.o -obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel_$(BITS).o -ifdef CONFIG_TILEGX -obj-$(CONFIG_PCI) += pci_gx.o -else -obj-$(CONFIG_PCI) += pci.o -endif -obj-$(CONFIG_PERF_EVENTS) += perf_event.o -obj-$(CONFIG_USE_PMC) += pmc.o -obj-$(CONFIG_TILE_USB) += usb.o -obj-$(CONFIG_TILE_HVGLUE_TRACE) += hvglue_trace.o -obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o mcount_64.o -obj-$(CONFIG_KPROBES) += kprobes.o -obj-$(CONFIG_KGDB) += kgdb.o -obj-$(CONFIG_JUMP_LABEL) += jump_label.o - -obj-y += vdso/ diff --git a/arch/tile/kernel/asm-offsets.c b/arch/tile/kernel/asm-offsets.c deleted file mode 100644 index 375e7c321eef..000000000000 --- a/arch/tile/kernel/asm-offsets.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2010 Tilera Corporation. All Rights Reserved. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for - * more details. - * - * Generates definitions from c-type structures used by assembly sources. - */ - -/* Check for compatible compiler early in the build. */ -#ifdef CONFIG_TILEGX -# ifndef __tilegx__ -# error Can only build TILE-Gx configurations with tilegx compiler -# endif -# ifndef __LP64__ -# error Must not specify -m32 when building the TILE-Gx kernel -# endif -#else -# ifdef __tilegx__ -# error Can not build TILEPro configurations with tilegx compiler -# endif -#endif - -#include <linux/kbuild.h> -#include <linux/thread_info.h> -#include <linux/sched.h> -#include <linux/hardirq.h> -#include <linux/ptrace.h> -#include <hv/hypervisor.h> - -void foo(void) -{ - DEFINE(SINGLESTEP_STATE_BUFFER_OFFSET, - offsetof(struct single_step_state, buffer)); - DEFINE(SINGLESTEP_STATE_FLAGS_OFFSET, - offsetof(struct single_step_state, flags)); - DEFINE(SINGLESTEP_STATE_ORIG_PC_OFFSET, - offsetof(struct single_step_state, orig_pc)); - DEFINE(SINGLESTEP_STATE_NEXT_PC_OFFSET, - offsetof(struct single_step_state, next_pc)); - DEFINE(SINGLESTEP_STATE_BRANCH_NEXT_PC_OFFSET, - offsetof(struct single_step_state, branch_next_pc)); - DEFINE(SINGLESTEP_STATE_UPDATE_VALUE_OFFSET, - offsetof(struct single_step_state, update_value)); - - DEFINE(THREAD_INFO_TASK_OFFSET, - offsetof(struct thread_info, task)); - DEFINE(THREAD_INFO_FLAGS_OFFSET, - offsetof(struct thread_info, flags)); - DEFINE(THREAD_INFO_STATUS_OFFSET, - offsetof(struct thread_info, status)); - DEFINE(THREAD_INFO_HOMECACHE_CPU_OFFSET, - offsetof(struct thread_info, homecache_cpu)); - DEFINE(THREAD_INFO_PREEMPT_COUNT_OFFSET, - offsetof(struct thread_info, preempt_count)); - DEFINE(THREAD_INFO_STEP_STATE_OFFSET, - offsetof(struct thread_info, step_state)); -#ifdef __tilegx__ - DEFINE(THREAD_INFO_UNALIGN_JIT_BASE_OFFSET, - offsetof(struct thread_info, unalign_jit_base)); - DEFINE(THREAD_INFO_UNALIGN_JIT_TMP_OFFSET, - offsetof(struct thread_info, unalign_jit_tmp)); -#endif - - DEFINE(TASK_STRUCT_THREAD_KSP_OFFSET, - offsetof(struct task_struct, thread.ksp)); - DEFINE(TASK_STRUCT_THREAD_PC_OFFSET, - offsetof(struct task_struct, thread.pc)); - - DEFINE(HV_TOPOLOGY_WIDTH_OFFSET, - offsetof(HV_Topology, width)); - DEFINE(HV_TOPOLOGY_HEIGHT_OFFSET, - offsetof(HV_Topology, height)); - - DEFINE(IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET, - offsetof(irq_cpustat_t, irq_syscall_count)); -} diff --git a/arch/tile/kernel/backtrace.c b/arch/tile/kernel/backtrace.c deleted file mode 100644 index f8b74ca83b92..000000000000 --- a/arch/tile/kernel/backtrace.c +++ /dev/null @@ -1,683 +0,0 @@ -/* - * Copyright 2011 Tilera Corporation. All Rights Reserved. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for - * more details. - */ - -#include <linux/kernel.h> -#include <linux/string.h> -#include <asm/byteorder.h> -#include <asm/backtrace.h> -#include <asm/tile-desc.h> -#include <arch/abi.h> - -#ifdef __tilegx__ -#define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE -#define tile_decoded_instruction tilegx_decoded_instruction -#define tile_mnemonic tilegx_mnemonic -#define parse_insn_tile parse_insn_tilegx -#define TILE_OPC_IRET TILEGX_OPC_IRET -#define TILE_OPC_ADDI TILEGX_OPC_ADDI -#define TILE_OPC_ADDLI TILEGX_OPC_ADDLI -#define TILE_OPC_INFO TILEGX_OPC_INFO -#define TILE_OPC_INFOL TILEGX_OPC_INFOL -#define TILE_OPC_JRP TILEGX_OPC_JRP -#define TILE_OPC_MOVE TILEGX_OPC_MOVE -#define OPCODE_STORE TILEGX_OPC_ST -typedef long long bt_int_reg_t; -#else -#define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEPRO_MAX_INSTRUCTIONS_PER_BUNDLE -#define tile_decoded_instruction tilepro_decoded_instruction -#define tile_mnemonic tilepro_mnemonic -#define parse_insn_tile parse_insn_tilepro -#define TILE_OPC_IRET TILEPRO_OPC_IRET -#define TILE_OPC_ADDI TILEPRO_OPC_ADDI -#define TILE_OPC_ADDLI TILEPRO_OPC_ADDLI -#define TILE_OPC_INFO TILEPRO_OPC_INFO -#define TILE_OPC_INFOL TILEPRO_OPC_INFOL -#define TILE_OPC_JRP TILEPRO_OPC_JRP -#define TILE_OPC_MOVE TILEPRO_OPC_MOVE -#define OPCODE_STORE TILEPRO_OPC_SW -typedef int bt_int_reg_t; -#endif - -/* A decoded bundle used for backtracer analysis. */ -struct BacktraceBundle { - tile_bundle_bits bits; - int num_insns; - struct tile_decoded_instruction - insns[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]; -}; - - -/* Locates an instruction inside the given bundle that - * has the specified mnemonic, and whose first 'num_operands_to_match' - * operands exactly match those in 'operand_values'. - */ -static const struct tile_decoded_instruction *find_matching_insn( - const struct BacktraceBundle *bundle, - tile_mnemonic mnemonic, - const int *operand_values, - int num_operands_to_match) -{ - int i, j; - bool match; - - for (i = 0; i < bundle->num_insns; i++) { - const struct tile_decoded_instruction *insn = - &bundle->insns[i]; - - if (insn->opcode->mnemonic != mnemonic) - continue; - - match = true; - for (j = 0; j < num_operands_to_match; j++) { - if (operand_values[j] != insn->operand_values[j]) { - match = false; - break; - } - } - - if (match) - return insn; - } - - return NULL; -} - -/* Does this bundle contain an 'iret' instruction? */ -static inline bool bt_has_iret(const struct BacktraceBundle *bundle) -{ - return find_matching_insn(bundle, TILE_OPC_IRET, NULL, 0) != NULL; -} - -/* Does this bundle contain an 'addi sp, sp, OFFSET' or - * 'addli sp, sp, OFFSET' instruction, and if so, what is OFFSET? - */ -static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust) -{ - static const int vals[2] = { TREG_SP, TREG_SP }; - - const struct tile_decoded_instruction *insn = - find_matching_insn(bundle, TILE_OPC_ADDI, vals, 2); - if (insn == NULL) - insn = find_matching_insn(bundle, TILE_OPC_ADDLI, vals, 2); -#ifdef __tilegx__ - if (insn == NULL) - insn = find_matching_insn(bundle, TILEGX_OPC_ADDXLI, vals, 2); - if (insn == NULL) - insn = find_matching_insn(bundle, TILEGX_OPC_ADDXI, vals, 2); -#endif - if (insn == NULL) - return false; - - *adjust = insn->operand_values[2]; - return true; -} - -/* Does this bundle contain any 'info OP' or 'infol OP' - * instruction, and if so, what are their OP? Note that OP is interpreted - * as an unsigned value by this code since that's what the caller wants. - * Returns the number of info ops found. - */ -static int bt_get_info_ops(const struct BacktraceBundle *bundle, - int operands[MAX_INFO_OPS_PER_BUNDLE]) -{ - int num_ops = 0; - int i; - - for (i = 0; i < bundle->num_insns; i++) { - const struct tile_decoded_instruction *insn = - &bundle->insns[i]; - - if (insn->opcode->mnemonic == TILE_OPC_INFO || - insn->opcode->mnemonic == TILE_OPC_INFOL) { - operands[num_ops++] = insn->operand_values[0]; - } - } - - return num_ops; -} - -/* Does this bundle contain a jrp instruction, and if so, to which - * register is it jumping? - */ -static bool bt_has_jrp(const struct BacktraceBundle *bundle, int *target_reg) -{ - const struct tile_decoded_instruction *insn = - find_matching_insn(bundle, TILE_OPC_JRP, NULL, 0); - if (insn == NULL) - return false; - - *target_reg = insn->operand_values[0]; - return true; -} - -/* Does this bundle modify the specified register in any way? */ -static bool bt_modifies_reg(const struct BacktraceBundle *bundle, int reg) -{ - int i, j; - for (i = 0; i < bundle->num_insns; i++) { - const struct tile_decoded_instruction *insn = - &bundle->insns[i]; - - if (insn->opcode->implicitly_written_register == reg) - return true; - - for (j = 0; j < insn->opcode->num_operands; j++) - if (insn->operands[j]->is_dest_reg && - insn->operand_values[j] == reg) - return true; - } - - return false; -} - -/* Does this bundle modify sp? */ -static inline bool bt_modifies_sp(const struct BacktraceBundle *bundle) -{ - return bt_modifies_reg(bundle, TREG_SP); -} - -/* Does this bundle modify lr? */ -static inline bool bt_modifies_lr(const struct BacktraceBundle *bundle) -{ - return bt_modifies_reg(bundle, TREG_LR); -} - -/* Does this bundle contain the instruction 'move fp, sp'? */ -static inline bool bt_has_move_r52_sp(const struct BacktraceBundle *bundle) -{ - static const int vals[2] = { 52, TREG_SP }; - return find_matching_insn(bundle, TILE_OPC_MOVE, vals, 2) != NULL; -} - -/* Does this bundle contain a store of lr to sp? */ -static inline bool bt_has_sw_sp_lr(const struct BacktraceBundle *bundle) -{ - static const int vals[2] = { TREG_SP, TREG_LR }; - return find_matching_insn(bundle, OPCODE_STORE, vals, 2) != NULL; -} - -#ifdef __tilegx__ -/* Track moveli values placed into registers. */ -static inline void bt_update_moveli(const struct BacktraceBundle *bundle, - int moveli_args[]) -{ - int i; - for (i = 0; i < bundle->num_insns; i++) { - const struct tile_decoded_instruction *insn = - &bundle->insns[i]; - - if (insn->opcode->mnemonic == TILEGX_OPC_MOVELI) { - int reg = insn->operand_values[0]; - moveli_args[reg] = insn->operand_values[1]; - } - } -} - -/* Does this bundle contain an 'add sp, sp, reg' instruction - * from a register that we saw a moveli into, and if so, what - * is the value in the register? - */ -static bool bt_has_add_sp(const struct BacktraceBundle *bundle, int *adjust, - int moveli_args[]) -{ - static const int vals[2] = { TREG_SP, TREG_SP }; - - const struct tile_decoded_instruction *insn = - find_matching_insn(bundle, TILEGX_OPC_ADDX, vals, 2); - if (insn) { - int reg = insn->operand_values[2]; - if (moveli_args[reg]) { - *adjust = moveli_args[reg]; - return true; - } - } - return false; -} -#endif - -/* Locates the caller's PC and SP for a program starting at the - * given address. - */ -static void find_caller_pc_and_caller_sp(CallerLocation *location, - const unsigned long start_pc, - BacktraceMemoryReader read_memory_func, - void *read_memory_func_extra) -{ - /* Have we explicitly decided what the sp is, - * rather than just the default? - */ - bool sp_determined = false; - - /* Has any bundle seen so far modified lr? */ - bool lr_modified = false; - - /* Have we seen a move from sp to fp? */ - bool sp_moved_to_r52 = false; - - /* Have we seen a terminating bundle? */ - bool seen_terminating_bundle = false; - - /* Cut down on round-trip reading overhead by reading several - * bundles at a time. - */ - tile_bundle_bits prefetched_bundles[32]; - int num_bundles_prefetched = 0; - int next_bundle = 0; - unsigned long pc; - -#ifdef __tilegx__ - /* Naively try to track moveli values to support addx for -m32. */ - int moveli_args[TILEGX_NUM_REGISTERS] = { 0 }; -#endif - - /* Default to assuming that the caller's sp is the current sp. - * This is necessary to handle the case where we start backtracing - * right at the end of the epilog. - */ - location->sp_location = SP_LOC_OFFSET; - location->sp_offset = 0; - - /* Default to having no idea where the caller PC is. */ - location->pc_location = PC_LOC_UNKNOWN; - - /* Don't even try if the PC is not aligned. */ - if (start_pc % TILE_BUNDLE_ALIGNMENT_IN_BYTES != 0) - return; - - for (pc = start_pc;; pc += sizeof(tile_bundle_bits)) { - - struct BacktraceBundle bundle; - int num_info_ops, info_operands[MAX_INFO_OPS_PER_BUNDLE]; - int one_ago, jrp_reg; - bool has_jrp; - - if (next_bundle >= num_bundles_prefetched) { - /* Prefetch some bytes, but don't cross a page - * boundary since that might cause a read failure we - * don't care about if we only need the first few - * bytes. Note: we don't care what the actual page - * size is; using the minimum possible page size will - * prevent any problems. - */ - unsigned int bytes_to_prefetch = 4096 - (pc & 4095); - if (bytes_to_prefetch > sizeof prefetched_bundles) - bytes_to_prefetch = sizeof prefetched_bundles; - - if (!read_memory_func(prefetched_bundles, pc, - bytes_to_prefetch, - read_memory_func_extra)) { - if (pc == start_pc) { - /* The program probably called a bad - * address, such as a NULL pointer. - * So treat this as if we are at the - * start of the function prolog so the - * backtrace will show how we got here. - */ - location->pc_location = PC_LOC_IN_LR; - return; - } - - /* Unreadable address. Give up. */ - break; - } - - next_bundle = 0; - num_bundles_prefetched = - bytes_to_prefetch / sizeof(tile_bundle_bits); - } - - /* - * Decode the next bundle. - * TILE always stores instruction bundles in little-endian - * mode, even when the chip is running in big-endian mode. - */ - bundle.bits = le64_to_cpu(prefetched_bundles[next_bundle++]); - bundle.num_insns = - parse_insn_tile(bundle.bits, pc, bundle.insns); - num_info_ops = bt_get_info_ops(&bundle, info_operands); - - /* First look at any one_ago info ops if they are interesting, - * since they should shadow any non-one-ago info ops. - */ - for (one_ago = (pc != start_pc) ? 1 : 0; - one_ago >= 0; one_ago--) { - int i; - for (i = 0; i < num_info_ops; i++) { - int info_operand = info_operands[i]; - if (info_operand < CALLER_UNKNOWN_BASE) { - /* Weird; reserved value, ignore it. */ - continue; - } - - /* Skip info ops which are not in the - * "one_ago" mode we want right now. - */ - if (((info_operand & ONE_BUNDLE_AGO_FLAG) != 0) - != (one_ago != 0)) - continue; - - /* Clear the flag to make later checking - * easier. */ - info_operand &= ~ONE_BUNDLE_AGO_FLAG; - - /* Default to looking at PC_IN_LR_FLAG. */ - if (info_operand & PC_IN_LR_FLAG) - location->pc_location = - PC_LOC_IN_LR; - else - location->pc_location = - PC_LOC_ON_STACK; - - switch (info_operand) { - case CALLER_UNKNOWN_BASE: - location->pc_location = PC_LOC_UNKNOWN; - location->sp_location = SP_LOC_UNKNOWN; - return; - - case CALLER_SP_IN_R52_BASE: - case CALLER_SP_IN_R52_BASE | PC_IN_LR_FLAG: - location->sp_location = SP_LOC_IN_R52; - return; - - default: - { - const unsigned int val = info_operand - - CALLER_SP_OFFSET_BASE; - const unsigned int sp_offset = - (val >> NUM_INFO_OP_FLAGS) * 8; - if (sp_offset < 32768) { - /* This is a properly encoded - * SP offset. */ - location->sp_location = - SP_LOC_OFFSET; - location->sp_offset = - sp_offset; - return; - } else { |