Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm
* 'for-linus' of git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm: (207 commits) ARM: 7267/1: Remove BUILD_BUG_ON from asm/bug.h ARM: 7269/1: mach-sa1100: fix sched_clock breakage ARM: 7198/1: arm/imx6: add restart support for imx6q ARM: restart: remove the now empty arch_reset() ARM: restart: remove comments about adding code to arch_reset() ARM: restart: lpc32xx & u300: remove unnecessary printk ARM: restart: plat-samsung: remove plat/reset.h and s5p_reset_hook ARM: restart: w90x900: use new restart hook ARM: restart: Versatile Express: use new restart hook ARM: restart: versatile: use new restart hook ARM: restart: u300: use new restart hook ARM: restart: tegra: use new restart hook ARM: restart: spear: use new restart hook ARM: restart: shark: use new restart hook ARM: restart: sa1100: use new restart hook ARM: 7252/1: restart: S5PV210: use new restart hook ARM: 7251/1: restart: S5PC100: use new restart hook ARM: 7250/1: restart: S5P64X0: use new restart hook ARM: 7266/1: restart: S3C64XX: use new restart hook ARM: 7265/1: restart: S3C24XX: use new restart hook ... Fix up trivial conflict in arch/arm/mm/init.c due to removal of memblock_init() clashing with the movement of the sorting of the meminfo array.
This commit is contained in:
@@ -13,7 +13,7 @@ CFLAGS_REMOVE_return_address.o = -pg
|
||||
|
||||
# Object file lists.
|
||||
|
||||
obj-y := elf.o entry-armv.o entry-common.o irq.o \
|
||||
obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \
|
||||
process.o ptrace.o return_address.o setup.o signal.o \
|
||||
sys_arm.o stacktrace.o time.o traps.o
|
||||
|
||||
|
@@ -36,12 +36,11 @@
|
||||
#ifdef CONFIG_MULTI_IRQ_HANDLER
|
||||
ldr r1, =handle_arch_irq
|
||||
mov r0, sp
|
||||
ldr r1, [r1]
|
||||
adr lr, BSYM(9997f)
|
||||
teq r1, #0
|
||||
movne pc, r1
|
||||
#endif
|
||||
ldr pc, [r1]
|
||||
#else
|
||||
arch_irq_handler_default
|
||||
#endif
|
||||
9997:
|
||||
.endm
|
||||
|
||||
|
@@ -39,8 +39,14 @@
|
||||
#error KERNEL_RAM_VADDR must start at 0xXXXX8000
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
/* LPAE requires an additional page for the PGD */
|
||||
#define PG_DIR_SIZE 0x5000
|
||||
#define PMD_ORDER 3
|
||||
#else
|
||||
#define PG_DIR_SIZE 0x4000
|
||||
#define PMD_ORDER 2
|
||||
#endif
|
||||
|
||||
.globl swapper_pg_dir
|
||||
.equ swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
|
||||
@@ -164,17 +170,36 @@ __create_page_tables:
|
||||
teq r0, r6
|
||||
bne 1b
|
||||
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
/*
|
||||
* Build the PGD table (first level) to point to the PMD table. A PGD
|
||||
* entry is 64-bit wide.
|
||||
*/
|
||||
mov r0, r4
|
||||
add r3, r4, #0x1000 @ first PMD table address
|
||||
orr r3, r3, #3 @ PGD block type
|
||||
mov r6, #4 @ PTRS_PER_PGD
|
||||
mov r7, #1 << (55 - 32) @ L_PGD_SWAPPER
|
||||
1: str r3, [r0], #4 @ set bottom PGD entry bits
|
||||
str r7, [r0], #4 @ set top PGD entry bits
|
||||
add r3, r3, #0x1000 @ next PMD table
|
||||
subs r6, r6, #1
|
||||
bne 1b
|
||||
|
||||
add r4, r4, #0x1000 @ point to the PMD tables
|
||||
#endif
|
||||
|
||||
ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
|
||||
|
||||
/*
|
||||
* Create identity mapping to cater for __enable_mmu.
|
||||
* This identity mapping will be removed by paging_init().
|
||||
*/
|
||||
adr r0, __enable_mmu_loc
|
||||
adr r0, __turn_mmu_on_loc
|
||||
ldmia r0, {r3, r5, r6}
|
||||
sub r0, r0, r3 @ virt->phys offset
|
||||
add r5, r5, r0 @ phys __enable_mmu
|
||||
add r6, r6, r0 @ phys __enable_mmu_end
|
||||
add r5, r5, r0 @ phys __turn_mmu_on
|
||||
add r6, r6, r0 @ phys __turn_mmu_on_end
|
||||
mov r5, r5, lsr #SECTION_SHIFT
|
||||
mov r6, r6, lsr #SECTION_SHIFT
|
||||
|
||||
@@ -219,8 +244,8 @@ __create_page_tables:
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Then map boot params address in r2 or
|
||||
* the first 1MB of ram if boot params address is not specified.
|
||||
* Then map boot params address in r2 or the first 1MB (2MB with LPAE)
|
||||
* of ram if boot params address is not specified.
|
||||
*/
|
||||
mov r0, r2, lsr #SECTION_SHIFT
|
||||
movs r0, r0, lsl #SECTION_SHIFT
|
||||
@@ -251,7 +276,15 @@ __create_page_tables:
|
||||
mov r3, r7, lsr #SECTION_SHIFT
|
||||
ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
|
||||
orr r3, r7, r3, lsl #SECTION_SHIFT
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
mov r7, #1 << (54 - 32) @ XN
|
||||
#else
|
||||
orr r3, r3, #PMD_SECT_XN
|
||||
#endif
|
||||
1: str r3, [r0], #4
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
str r7, [r0], #4
|
||||
#endif
|
||||
add r3, r3, #1 << SECTION_SHIFT
|
||||
cmp r0, r6
|
||||
blo 1b
|
||||
@@ -282,15 +315,18 @@ __create_page_tables:
|
||||
add r0, r4, #0xd8000000 >> (SECTION_SHIFT - PMD_ORDER)
|
||||
str r3, [r0]
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
sub r4, r4, #0x1000 @ point to the PGD table
|
||||
#endif
|
||||
mov pc, lr
|
||||
ENDPROC(__create_page_tables)
|
||||
.ltorg
|
||||
.align
|
||||
__enable_mmu_loc:
|
||||
__turn_mmu_on_loc:
|
||||
.long .
|
||||
.long __enable_mmu
|
||||
.long __enable_mmu_end
|
||||
.long __turn_mmu_on
|
||||
.long __turn_mmu_on_end
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
__CPUINIT
|
||||
@@ -374,12 +410,17 @@ __enable_mmu:
|
||||
#ifdef CONFIG_CPU_ICACHE_DISABLE
|
||||
bic r0, r0, #CR_I
|
||||
#endif
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
mov r5, #0
|
||||
mcrr p15, 0, r4, r5, c2 @ load TTBR0
|
||||
#else
|
||||
mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
|
||||
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
|
||||
domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
|
||||
domain_val(DOMAIN_IO, DOMAIN_CLIENT))
|
||||
mcr p15, 0, r5, c3, c0, 0 @ load domain access register
|
||||
mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
|
||||
#endif
|
||||
b __turn_mmu_on
|
||||
ENDPROC(__enable_mmu)
|
||||
|
||||
@@ -398,15 +439,19 @@ ENDPROC(__enable_mmu)
|
||||
* other registers depend on the function called upon completion
|
||||
*/
|
||||
.align 5
|
||||
__turn_mmu_on:
|
||||
.pushsection .idmap.text, "ax"
|
||||
ENTRY(__turn_mmu_on)
|
||||
mov r0, r0
|
||||
instr_sync
|
||||
mcr p15, 0, r0, c1, c0, 0 @ write control reg
|
||||
mrc p15, 0, r3, c0, c0, 0 @ read id reg
|
||||
instr_sync
|
||||
mov r3, r3
|
||||
mov r3, r13
|
||||
mov pc, r3
|
||||
__enable_mmu_end:
|
||||
__turn_mmu_on_end:
|
||||
ENDPROC(__turn_mmu_on)
|
||||
.popsection
|
||||
|
||||
|
||||
#ifdef CONFIG_SMP_ON_UP
|
||||
|
@@ -1016,10 +1016,10 @@ static int __init arch_hw_breakpoint_init(void)
|
||||
}
|
||||
|
||||
/* Register debug fault handler. */
|
||||
hook_fault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
|
||||
"watchpoint debug exception");
|
||||
hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
|
||||
"breakpoint debug exception");
|
||||
hook_fault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
|
||||
TRAP_HWBKPT, "watchpoint debug exception");
|
||||
hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
|
||||
TRAP_HWBKPT, "breakpoint debug exception");
|
||||
|
||||
/* Register hotplug notifier. */
|
||||
register_cpu_notifier(&dbg_reset_nb);
|
||||
|
@@ -202,6 +202,8 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kprobes.h>
|
||||
|
||||
#include <asm/opcodes.h>
|
||||
|
||||
#include "kprobes.h"
|
||||
#include "kprobes-test.h"
|
||||
|
||||
@@ -1050,65 +1052,9 @@ static int test_instance;
|
||||
|
||||
static unsigned long test_check_cc(int cc, unsigned long cpsr)
|
||||
{
|
||||
unsigned long temp;
|
||||
int ret = arm_check_condition(cc << 28, cpsr);
|
||||
|
||||
switch (cc) {
|
||||
case 0x0: /* eq */
|
||||
return cpsr & PSR_Z_BIT;
|
||||
|
||||
case 0x1: /* ne */
|
||||
return (~cpsr) & PSR_Z_BIT;
|
||||
|
||||
case 0x2: /* cs */
|
||||
return cpsr & PSR_C_BIT;
|
||||
|
||||
case 0x3: /* cc */
|
||||
return (~cpsr) & PSR_C_BIT;
|
||||
|
||||
case 0x4: /* mi */
|
||||
return cpsr & PSR_N_BIT;
|
||||
|
||||
case 0x5: /* pl */
|
||||
return (~cpsr) & PSR_N_BIT;
|
||||
|
||||
case 0x6: /* vs */
|
||||
return cpsr & PSR_V_BIT;
|
||||
|
||||
case 0x7: /* vc */
|
||||
return (~cpsr) & PSR_V_BIT;
|
||||
|
||||
case 0x8: /* hi */
|
||||
cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
|
||||
return cpsr & PSR_C_BIT;
|
||||
|
||||
case 0x9: /* ls */
|
||||
cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
|
||||
return (~cpsr) & PSR_C_BIT;
|
||||
|
||||
case 0xa: /* ge */
|
||||
cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
|
||||
return (~cpsr) & PSR_N_BIT;
|
||||
|
||||
case 0xb: /* lt */
|
||||
cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
|
||||
return cpsr & PSR_N_BIT;
|
||||
|
||||
case 0xc: /* gt */
|
||||
temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
|
||||
temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
|
||||
return (~temp) & PSR_N_BIT;
|
||||
|
||||
case 0xd: /* le */
|
||||
temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
|
||||
temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
|
||||
return temp & PSR_N_BIT;
|
||||
|
||||
case 0xe: /* al */
|
||||
case 0xf: /* unconditional */
|
||||
return true;
|
||||
}
|
||||
BUG();
|
||||
return false;
|
||||
return (ret != ARM_OPCODE_CONDTEST_FAIL);
|
||||
}
|
||||
|
||||
static int is_last_scenario;
|
||||
@@ -1128,7 +1074,9 @@ static unsigned long test_context_cpsr(int scenario)
|
||||
|
||||
if (!test_case_is_thumb) {
|
||||
/* Testing ARM code */
|
||||
probe_should_run = test_check_cc(current_instruction >> 28, cpsr) != 0;
|
||||
int cc = current_instruction >> 28;
|
||||
|
||||
probe_should_run = test_check_cc(cc, cpsr) != 0;
|
||||
if (scenario == 15)
|
||||
is_last_scenario = true;
|
||||
|
||||
|
@@ -12,12 +12,11 @@
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
extern const unsigned char relocate_new_kernel[];
|
||||
extern const unsigned int relocate_new_kernel_size;
|
||||
|
||||
extern void setup_mm_for_reboot(char mode);
|
||||
|
||||
extern unsigned long kexec_start_address;
|
||||
extern unsigned long kexec_indirection_page;
|
||||
extern unsigned long kexec_mach_type;
|
||||
@@ -111,14 +110,6 @@ void machine_kexec(struct kimage *image)
|
||||
|
||||
if (kexec_reinit)
|
||||
kexec_reinit();
|
||||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
|
||||
flush_cache_all();
|
||||
outer_flush_all();
|
||||
outer_disable();
|
||||
cpu_proc_fin();
|
||||
outer_inv_all();
|
||||
flush_cache_all();
|
||||
cpu_reset(reboot_code_buffer_phys);
|
||||
|
||||
soft_restart(reboot_code_buffer_phys);
|
||||
}
|
||||
|
72
arch/arm/kernel/opcodes.c
Normal file
72
arch/arm/kernel/opcodes.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* linux/arch/arm/kernel/opcodes.c
|
||||
*
|
||||
* A32 condition code lookup feature moved from nwfpe/fpopcode.c
|
||||
*
|
||||
* 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/module.h>
|
||||
#include <asm/opcodes.h>
|
||||
|
||||
#define ARM_OPCODE_CONDITION_UNCOND 0xf
|
||||
|
||||
/*
|
||||
* condition code lookup table
|
||||
* index into the table is test code: EQ, NE, ... LT, GT, AL, NV
|
||||
*
|
||||
* bit position in short is condition code: NZCV
|
||||
*/
|
||||
static const unsigned short cc_map[16] = {
|
||||
0xF0F0, /* EQ == Z set */
|
||||
0x0F0F, /* NE */
|
||||
0xCCCC, /* CS == C set */
|
||||
0x3333, /* CC */
|
||||
0xFF00, /* MI == N set */
|
||||
0x00FF, /* PL */
|
||||
0xAAAA, /* VS == V set */
|
||||
0x5555, /* VC */
|
||||
0x0C0C, /* HI == C set && Z clear */
|
||||
0xF3F3, /* LS == C clear || Z set */
|
||||
0xAA55, /* GE == (N==V) */
|
||||
0x55AA, /* LT == (N!=V) */
|
||||
0x0A05, /* GT == (!Z && (N==V)) */
|
||||
0xF5FA, /* LE == (Z || (N!=V)) */
|
||||
0xFFFF, /* AL always */
|
||||
0 /* NV */
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns:
|
||||
* ARM_OPCODE_CONDTEST_FAIL - if condition fails
|
||||
* ARM_OPCODE_CONDTEST_PASS - if condition passes (including AL)
|
||||
* ARM_OPCODE_CONDTEST_UNCOND - if NV condition, or separate unconditional
|
||||
* opcode space from v5 onwards
|
||||
*
|
||||
* Code that tests whether a conditional instruction would pass its condition
|
||||
* check should check that return value == ARM_OPCODE_CONDTEST_PASS.
|
||||
*
|
||||
* Code that tests if a condition means that the instruction would be executed
|
||||
* (regardless of conditional or unconditional) should instead check that the
|
||||
* return value != ARM_OPCODE_CONDTEST_FAIL.
|
||||
*/
|
||||
asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr)
|
||||
{
|
||||
u32 cc_bits = opcode >> 28;
|
||||
u32 psr_cond = psr >> 28;
|
||||
unsigned int ret;
|
||||
|
||||
if (cc_bits != ARM_OPCODE_CONDITION_UNCOND) {
|
||||
if ((cc_map[cc_bits] >> (psr_cond)) & 1)
|
||||
ret = ARM_OPCODE_CONDTEST_PASS;
|
||||
else
|
||||
ret = ARM_OPCODE_CONDTEST_FAIL;
|
||||
} else {
|
||||
ret = ARM_OPCODE_CONDTEST_UNCOND;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arm_check_condition);
|
@@ -59,8 +59,7 @@ armpmu_get_pmu_id(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(armpmu_get_pmu_id);
|
||||
|
||||
int
|
||||
armpmu_get_max_events(void)
|
||||
int perf_num_counters(void)
|
||||
{
|
||||
int max_events = 0;
|
||||
|
||||
@@ -69,12 +68,6 @@ armpmu_get_max_events(void)
|
||||
|
||||
return max_events;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(armpmu_get_max_events);
|
||||
|
||||
int perf_num_counters(void)
|
||||
{
|
||||
return armpmu_get_max_events();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(perf_num_counters);
|
||||
|
||||
#define HW_OP_UNSUPPORTED 0xFFFF
|
||||
@@ -380,6 +373,8 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
|
||||
{
|
||||
int i, irq, irqs;
|
||||
struct platform_device *pmu_device = armpmu->plat_device;
|
||||
struct arm_pmu_platdata *plat =
|
||||
dev_get_platdata(&pmu_device->dev);
|
||||
|
||||
irqs = min(pmu_device->num_resources, num_possible_cpus());
|
||||
|
||||
@@ -387,8 +382,11 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
|
||||
if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
|
||||
continue;
|
||||
irq = platform_get_irq(pmu_device, i);
|
||||
if (irq >= 0)
|
||||
if (irq >= 0) {
|
||||
if (plat && plat->disable_irq)
|
||||
plat->disable_irq(irq);
|
||||
free_irq(irq, armpmu);
|
||||
}
|
||||
}
|
||||
|
||||
release_pmu(armpmu->type);
|
||||
@@ -448,7 +446,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
|
||||
irq);
|
||||
armpmu_release_hardware(armpmu);
|
||||
return err;
|
||||
}
|
||||
} else if (plat && plat->enable_irq)
|
||||
plat->enable_irq(irq);
|
||||
|
||||
cpumask_set_cpu(i, &armpmu->active_irqs);
|
||||
}
|
||||
|
@@ -65,13 +65,15 @@ enum armv6_counters {
|
||||
* accesses/misses in hardware.
|
||||
*/
|
||||
static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV6_PERFCTR_IBUF_STALL,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV6_PERFCTR_LSU_FULL_STALL,
|
||||
};
|
||||
|
||||
static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
@@ -218,13 +220,15 @@ enum armv6mpcore_perf_types {
|
||||
* accesses/misses in hardware.
|
||||
*/
|
||||
static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV6MPCORE_PERFCTR_IBUF_STALL,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV6MPCORE_PERFCTR_LSU_FULL_STALL,
|
||||
};
|
||||
|
||||
static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
|
@@ -28,165 +28,87 @@ static struct arm_pmu armv7pmu;
|
||||
* they are not available.
|
||||
*/
|
||||
enum armv7_perf_types {
|
||||
ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
|
||||
ARMV7_PERFCTR_IFETCH_MISS = 0x01,
|
||||
ARMV7_PERFCTR_ITLB_MISS = 0x02,
|
||||
ARMV7_PERFCTR_DCACHE_REFILL = 0x03, /* L1 */
|
||||
ARMV7_PERFCTR_DCACHE_ACCESS = 0x04, /* L1 */
|
||||
ARMV7_PERFCTR_DTLB_REFILL = 0x05,
|
||||
ARMV7_PERFCTR_DREAD = 0x06,
|
||||
ARMV7_PERFCTR_DWRITE = 0x07,
|
||||
ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
|
||||
ARMV7_PERFCTR_EXC_TAKEN = 0x09,
|
||||
ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
|
||||
ARMV7_PERFCTR_CID_WRITE = 0x0B,
|
||||
/* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
|
||||
ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
|
||||
ARMV7_PERFCTR_L1_ICACHE_REFILL = 0x01,
|
||||
ARMV7_PERFCTR_ITLB_REFILL = 0x02,
|
||||
ARMV7_PERFCTR_L1_DCACHE_REFILL = 0x03,
|
||||
ARMV7_PERFCTR_L1_DCACHE_ACCESS = 0x04,
|
||||
ARMV7_PERFCTR_DTLB_REFILL = 0x05,
|
||||
ARMV7_PERFCTR_MEM_READ = 0x06,
|
||||
ARMV7_PERFCTR_MEM_WRITE = 0x07,
|
||||
ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
|
||||
ARMV7_PERFCTR_EXC_TAKEN = 0x09,
|
||||
ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
|
||||
ARMV7_PERFCTR_CID_WRITE = 0x0B,
|
||||
|
||||
/*
|
||||
* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
|
||||
* It counts:
|
||||
* - all branch instructions,
|
||||
* - all (taken) branch instructions,
|
||||
* - instructions that explicitly write the PC,
|
||||
* - exception generating instructions.
|
||||
*/
|
||||
ARMV7_PERFCTR_PC_WRITE = 0x0C,
|
||||
ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
|
||||
ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
|
||||
ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F,
|
||||
ARMV7_PERFCTR_PC_WRITE = 0x0C,
|
||||
ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
|
||||
ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
|
||||
ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS = 0x0F,
|
||||
ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
|
||||
ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
|
||||
ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12,
|
||||
|
||||
/* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
|
||||
ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
|
||||
ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
|
||||
ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12,
|
||||
ARMV7_PERFCTR_MEM_ACCESS = 0x13,
|
||||
ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14,
|
||||
ARMV7_PERFCTR_L1_DCACHE_WB = 0x15,
|
||||
ARMV7_PERFCTR_L2_DCACHE_ACCESS = 0x16,
|
||||
ARMV7_PERFCTR_L2_DCACHE_REFILL = 0x17,
|
||||
ARMV7_PERFCTR_L2_DCACHE_WB = 0x18,
|
||||
ARMV7_PERFCTR_BUS_ACCESS = 0x19,
|
||||
ARMV7_PERFCTR_MEMORY_ERROR = 0x1A,
|
||||
ARMV7_PERFCTR_INSTR_SPEC = 0x1B,
|
||||
ARMV7_PERFCTR_TTBR_WRITE = 0x1C,
|
||||
ARMV7_PERFCTR_BUS_CYCLES = 0x1D,
|
||||
ARMV7_PERFCTR_MEM_ACCESS = 0x13,
|
||||
ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14,
|
||||
ARMV7_PERFCTR_L1_DCACHE_WB = 0x15,
|
||||
ARMV7_PERFCTR_L2_CACHE_ACCESS = 0x16,
|
||||
ARMV7_PERFCTR_L2_CACHE_REFILL = 0x17,
|
||||
ARMV7_PERFCTR_L2_CACHE_WB = 0x18,
|
||||
ARMV7_PERFCTR_BUS_ACCESS = 0x19,
|
||||
ARMV7_PERFCTR_MEM_ERROR = 0x1A,
|
||||
ARMV7_PERFCTR_INSTR_SPEC = 0x1B,
|
||||
ARMV7_PERFCTR_TTBR_WRITE = 0x1C,
|
||||
ARMV7_PERFCTR_BUS_CYCLES = 0x1D,
|
||||
|
||||
ARMV7_PERFCTR_CPU_CYCLES = 0xFF
|
||||
ARMV7_PERFCTR_CPU_CYCLES = 0xFF
|
||||
};
|
||||
|
||||
/* ARMv7 Cortex-A8 specific event types */
|
||||
enum armv7_a8_perf_types {
|
||||
ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40,
|
||||
ARMV7_PERFCTR_L2_STORE_MERGED = 0x41,
|
||||
ARMV7_PERFCTR_L2_STORE_BUFF = 0x42,
|
||||
ARMV7_PERFCTR_L2_ACCESS = 0x43,
|
||||
ARMV7_PERFCTR_L2_CACH_MISS = 0x44,
|
||||
ARMV7_PERFCTR_AXI_READ_CYCLES = 0x45,
|
||||
ARMV7_PERFCTR_AXI_WRITE_CYCLES = 0x46,
|
||||
ARMV7_PERFCTR_MEMORY_REPLAY = 0x47,
|
||||
ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY = 0x48,
|
||||
ARMV7_PERFCTR_L1_DATA_MISS = 0x49,
|
||||
ARMV7_PERFCTR_L1_INST_MISS = 0x4A,
|
||||
ARMV7_PERFCTR_L1_DATA_COLORING = 0x4B,
|
||||
ARMV7_PERFCTR_L1_NEON_DATA = 0x4C,
|
||||
ARMV7_PERFCTR_L1_NEON_CACH_DATA = 0x4D,
|
||||
ARMV7_PERFCTR_L2_NEON = 0x4E,
|
||||
ARMV7_PERFCTR_L2_NEON_HIT = 0x4F,
|
||||
ARMV7_PERFCTR_L1_INST = 0x50,
|
||||
ARMV7_PERFCTR_PC_RETURN_MIS_PRED = 0x51,
|
||||
ARMV7_PERFCTR_PC_BRANCH_FAILED = 0x52,
|
||||
ARMV7_PERFCTR_PC_BRANCH_TAKEN = 0x53,
|
||||
ARMV7_PERFCTR_PC_BRANCH_EXECUTED = 0x54,
|
||||
ARMV7_PERFCTR_OP_EXECUTED = 0x55,
|
||||
ARMV7_PERFCTR_CYCLES_INST_STALL = 0x56,
|
||||
ARMV7_PERFCTR_CYCLES_INST = 0x57,
|
||||
ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL = 0x58,
|
||||
ARMV7_PERFCTR_CYCLES_NEON_INST_STALL = 0x59,
|
||||
ARMV7_PERFCTR_NEON_CYCLES = 0x5A,
|
||||
|
||||
ARMV7_PERFCTR_PMU0_EVENTS = 0x70,
|
||||
ARMV7_PERFCTR_PMU1_EVENTS = 0x71,
|
||||
ARMV7_PERFCTR_PMU_EVENTS = 0x72,
|
||||
ARMV7_A8_PERFCTR_L2_CACHE_ACCESS = 0x43,
|
||||
ARMV7_A8_PERFCTR_L2_CACHE_REFILL = 0x44,
|
||||
ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS = 0x50,
|
||||
ARMV7_A8_PERFCTR_STALL_ISIDE = 0x56,
|
||||
};
|
||||
|
||||
/* ARMv7 Cortex-A9 specific event types */
|
||||
enum armv7_a9_perf_types {
|
||||
ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC = 0x40,
|
||||
ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC = 0x41,
|
||||
ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC = 0x42,
|
||||
|
||||
ARMV7_PERFCTR_COHERENT_LINE_MISS = 0x50,
|
||||
ARMV7_PERFCTR_COHERENT_LINE_HIT = 0x51,
|
||||
|
||||
ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES = 0x60,
|
||||
ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES = 0x61,
|
||||
ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62,
|
||||
ARMV7_PERFCTR_STREX_EXECUTED_PASSED = 0x63,
|
||||
ARMV7_PERFCTR_STREX_EXECUTED_FAILED = 0x64,
|
||||
ARMV7_PERFCTR_DATA_EVICTION = 0x65,
|
||||
ARMV7_PERFCTR_ISSUE_STAGE_NO_INST = 0x66,
|
||||
ARMV7_PERFCTR_ISSUE_STAGE_EMPTY = 0x67,
|
||||
ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE = 0x68,
|
||||
|
||||
ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E,
|
||||
|
||||
ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST = 0x70,
|
||||
ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71,
|
||||
ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST = 0x72,
|
||||
ARMV7_PERFCTR_FP_EXECUTED_INST = 0x73,
|
||||
ARMV7_PERFCTR_NEON_EXECUTED_INST = 0x74,
|
||||
|
||||
ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80,
|
||||
ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES = 0x81,
|
||||
ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES = 0x82,
|
||||
ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES = 0x83,
|
||||
ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES = 0x84,
|
||||
ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES = 0x85,
|
||||
ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES = 0x86,
|
||||
|
||||
ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES = 0x8A,
|
||||
ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B,
|
||||
|
||||
ARMV7_PERFCTR_ISB_INST = 0x90,
|
||||
ARMV7_PERFCTR_DSB_INST = 0x91,
|
||||
ARMV7_PERFCTR_DMB_INST = 0x92,
|
||||
ARMV7_PERFCTR_EXT_INTERRUPTS = 0x93,
|
||||
|
||||
ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED = 0xA0,
|
||||
ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED = 0xA1,
|
||||
ARMV7_PERFCTR_PLE_FIFO_FLUSH = 0xA2,
|
||||
ARMV7_PERFCTR_PLE_RQST_COMPLETED = 0xA3,
|
||||
ARMV7_PERFCTR_PLE_FIFO_OVERFLOW = 0xA4,
|
||||
ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5
|
||||
ARMV7_A9_PERFCTR_INSTR_CORE_RENAME = 0x68,
|
||||
ARMV7_A9_PERFCTR_STALL_ICACHE = 0x60,
|
||||
ARMV7_A9_PERFCTR_STALL_DISPATCH = 0x66,
|
||||
};
|
||||
|
||||
/* ARMv7 Cortex-A5 specific event types */
|
||||
enum armv7_a5_perf_types {
|
||||
ARMV7_PERFCTR_IRQ_TAKEN = 0x86,
|
||||
ARMV7_PERFCTR_FIQ_TAKEN = 0x87,
|
||||
|
||||
ARMV7_PERFCTR_EXT_MEM_RQST = 0xc0,
|
||||
ARMV7_PERFCTR_NC_EXT_MEM_RQST = 0xc1,
|
||||
ARMV7_PERFCTR_PREFETCH_LINEFILL = 0xc2,
|
||||
ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3,
|
||||
ARMV7_PERFCTR_ENTER_READ_ALLOC = 0xc4,
|
||||
ARMV7_PERFCTR_READ_ALLOC = 0xc5,
|
||||
|
||||
ARMV7_PERFCTR_STALL_SB_FULL = 0xc9,
|
||||
ARMV7_A5_PERFCTR_PREFETCH_LINEFILL = 0xc2,
|
||||
ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3,
|
||||
};
|
||||
|
||||
/* ARMv7 Cortex-A15 specific event types */
|
||||
enum armv7_a15_perf_types {
|
||||
ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS = 0x40,
|
||||
ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS = 0x41,
|
||||
ARMV7_PERFCTR_L1_DCACHE_READ_REFILL = 0x42,
|
||||
ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL = 0x43,
|
||||
ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
|
||||
ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
|
||||
ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ = 0x42,
|
||||
ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE = 0x43,
|
||||
|
||||
ARMV7_PERFCTR_L1_DTLB_READ_REFILL = 0x4C,
|
||||
ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL = 0x4D,
|
||||
ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ = 0x4C,
|
||||
ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE = 0x4D,
|
||||
|
||||
ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS = 0x50,
|
||||
ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS = 0x51,
|
||||
ARMV7_PERFCTR_L2_DCACHE_READ_REFILL = 0x52,
|
||||
ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL = 0x53,
|
||||
ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
|
||||
ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
|
||||
ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ = 0x52,
|
||||
ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE = 0x53,
|
||||
|
||||
ARMV7_PERFCTR_SPEC_PC_WRITE = 0x76,
|
||||
ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -197,13 +119,15 @@ enum armv7_a15_perf_types {
|
||||
* accesses/misses in hardware.
|
||||
*/
|
||||
static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A8_PERFCTR_STALL_ISIDE,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
@@ -217,12 +141,12 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
* combined.
|
||||
*/
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -231,12 +155,12 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
},
|
||||
[C(L1I)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
|
||||
[C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
|
||||
[C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -245,12 +169,12 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
},
|
||||
[C(LL)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
|
||||
[C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
|
||||
[C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -274,11 +198,11 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
[C(ITLB)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -287,14 +211,12 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
},
|
||||
[C(BPU)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -321,14 +243,15 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
* Cortex-A9 HW events mapping
|
||||
*/
|
||||
static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] =
|
||||
ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_DCACHE_ACCESS,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_DCACHE_REFILL,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_A9_PERFCTR_INSTR_CORE_RENAME,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A9_PERFCTR_STALL_ICACHE,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV7_A9_PERFCTR_STALL_DISPATCH,
|
||||
};
|
||||
|
||||
static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
@@ -342,12 +265,12 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
* combined.
|
||||
*/
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -357,11 +280,11 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
[C(L1I)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -399,11 +322,11 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
[C(ITLB)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -412,14 +335,12 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
},
|
||||
[C(BPU)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -446,13 +367,15 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
* Cortex-A5 HW events mapping
|
||||
*/
|
||||
static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
@@ -460,42 +383,34 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
|
||||
[C(L1D)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)]
|
||||
= ARMV7_PERFCTR_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_DCACHE_REFILL,
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)]
|
||||
= ARMV7_PERFCTR_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_DCACHE_REFILL,
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)]
|
||||
= ARMV7_PERFCTR_PREFETCH_LINEFILL,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
|
||||
[C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
|
||||
[C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
|
||||
},
|
||||
},
|
||||
[C(L1I)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
|
||||
},
|
||||
/*
|
||||
* The prefetch counters don't differentiate between the I
|
||||
* side and the D side.
|
||||
*/
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)]
|
||||
= ARMV7_PERFCTR_PREFETCH_LINEFILL,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
|
||||
[C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
|
||||
[C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
|
||||
},
|
||||
},
|
||||
[C(LL)] = {
|
||||
@@ -529,11 +444,11 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
[C(ITLB)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -543,13 +458,11 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
[C(BPU)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -562,13 +475,15 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
* Cortex-A15 HW events mapping
|
||||
*/
|
||||
static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_SPEC_PC_WRITE,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A15_PERFCTR_PC_WRITE_SPEC,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
@@ -576,16 +491,12 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
|
||||
[C(L1D)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)]
|
||||
= ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_L1_DCACHE_READ_REFILL,
|
||||
[C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ,
|
||||
[C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)]
|
||||
= ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL,
|
||||
[C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE,
|
||||
[C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -601,11 +512,11 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
*/
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -614,16 +525,12 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
},
|
||||
[C(LL)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)]
|
||||
= ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_L2_DCACHE_READ_REFILL,
|
||||
[C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ,
|
||||
[C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)]
|
||||
= ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL,
|
||||
[C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE,
|
||||
[C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -633,13 +540,11 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
[C(DTLB)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_L1_DTLB_READ_REFILL,
|
||||
[C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL,
|
||||
[C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -649,11 +554,11 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
[C(ITLB)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
@@ -663,13 +568,11 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
[C(BPU)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
|
||||
[C(RESULT_MISS)]
|
||||
= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
|
@@ -48,13 +48,15 @@ enum xscale_counters {
|
||||
};
|
||||
|
||||
static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = XSCALE_PERFCTR_ICACHE_NO_DELIVER,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
|
@@ -57,7 +57,7 @@ static const char *isa_modes[] = {
|
||||
"ARM" , "Thumb" , "Jazelle", "ThumbEE"
|
||||
};
|
||||
|
||||
extern void setup_mm_for_reboot(char mode);
|
||||
extern void setup_mm_for_reboot(void);
|
||||
|
||||
static volatile int hlt_counter;
|
||||
|
||||
@@ -92,18 +92,24 @@ static int __init hlt_setup(char *__unused)
|
||||
__setup("nohlt", nohlt_setup);
|
||||
__setup("hlt", hlt_setup);
|
||||
|
||||
void arm_machine_restart(char mode, const char *cmd)
|
||||
{
|
||||
/* Disable interrupts first */
|
||||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);
|
||||
typedef void (*phys_reset_t)(unsigned long);
|
||||
|
||||
/*
|
||||
* Tell the mm system that we are going to reboot -
|
||||
* we may need it to insert some 1:1 mappings so that
|
||||
* soft boot works.
|
||||
*/
|
||||
setup_mm_for_reboot(mode);
|
||||
/*
|
||||
* A temporary stack to use for CPU reset. This is static so that we
|
||||
* don't clobber it with the identity mapping. When running with this
|
||||
* stack, any references to the current task *will not work* so you
|
||||
* should really do as little as possible before jumping to your reset
|
||||
* code.
|
||||
*/
|
||||
static u64 soft_restart_stack[16];
|
||||
|
||||
static void __soft_restart(void *addr)
|
||||
{
|
||||
phys_reset_t phys_reset;
|
||||
|
||||
/* Take out a flat memory mapping. */
|
||||
setup_mm_for_reboot();
|
||||
|
||||
/* Clean and invalidate caches */
|
||||
flush_cache_all();
|
||||
@@ -114,18 +120,35 @@ void arm_machine_restart(char mode, const char *cmd)
|
||||
/* Push out any further dirty data, and ensure cache is empty */
|
||||
flush_cache_all();
|
||||
|
||||
/*
|
||||
* Now call the architecture specific reboot code.
|
||||
*/
|
||||
arch_reset(mode, cmd);
|
||||
/* Switch to the identity mapping. */
|
||||
phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
|
||||
phys_reset((unsigned long)addr);
|
||||
|
||||
/*
|
||||
* Whoops - the architecture was unable to reboot.
|
||||
* Tell the user!
|
||||
*/
|
||||
mdelay(1000);
|
||||
printk("Reboot failed -- System halted\n");
|
||||
while (1);
|
||||
/* Should never get here. */
|
||||
BUG();
|
||||
}
|
||||
|
||||
void soft_restart(unsigned long addr)
|
||||
{
|
||||
u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack);
|
||||
|
||||
/* Disable interrupts first */
|
||||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
|
||||
/* Disable the L2 if we're the last man standing. */
|
||||
if (num_online_cpus() == 1)
|
||||
outer_disable();
|
||||
|
||||
/* Change to the new stack and continue with the reset. */
|
||||
call_with_stack(__soft_restart, (void *)addr, (void *)stack);
|
||||
|
||||
/* Should never get here. */
|
||||
BUG();
|
||||
}
|
||||
|
||||
static void null_restart(char mode, const char *cmd)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -134,7 +157,7 @@ void arm_machine_restart(char mode, const char *cmd)
|
||||
void (*pm_power_off)(void);
|
||||
EXPORT_SYMBOL(pm_power_off);
|
||||
|
||||
void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
|
||||
void (*arm_pm_restart)(char str, const char *cmd) = null_restart;
|
||||
EXPORT_SYMBOL_GPL(arm_pm_restart);
|
||||
|
||||
static void do_nothing(void *unused)
|
||||
@@ -255,7 +278,15 @@ void machine_power_off(void)
|
||||
void machine_restart(char *cmd)
|
||||
{
|
||||
machine_shutdown();
|
||||
|
||||
arm_pm_restart(reboot_mode, cmd);
|
||||
|
||||
/* Give a grace period for failure to restart of 1s */
|
||||
mdelay(1000);
|
||||
|
||||
/* Whoops - the platform was unable to reboot. Tell the user! */
|
||||
printk("Reboot failed -- System halted\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
void __show_regs(struct pt_regs *regs)
|
||||
|
@@ -14,61 +14,153 @@
|
||||
|
||||
#include <asm/sched_clock.h>
|
||||
|
||||
struct clock_data {
|
||||
u64 epoch_ns;
|
||||
u32 epoch_cyc;
|
||||
u32 epoch_cyc_copy;
|
||||
u32 mult;
|
||||
u32 shift;
|
||||
};
|
||||
|
||||
static void sched_clock_poll(unsigned long wrap_ticks);
|
||||
static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0);
|
||||
static void (*sched_clock_update_fn)(void);
|
||||
|
||||
static struct clock_data cd = {
|
||||
.mult = NSEC_PER_SEC / HZ,
|
||||
};
|
||||
|
||||
static u32 __read_mostly sched_clock_mask = 0xffffffff;
|
||||
|
||||
static u32 notrace jiffy_sched_clock_read(void)
|
||||
{
|
||||
return (u32)(jiffies - INITIAL_JIFFIES);
|
||||
}
|
||||
|
||||
static u32 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read;
|
||||
|
||||
static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
|
||||
{
|
||||
return (cyc * mult) >> shift;
|
||||
}
|
||||
|
||||
static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask)
|
||||
{
|
||||
u64 epoch_ns;
|
||||
u32 epoch_cyc;
|
||||
|
||||
/*
|
||||
* Load the epoch_cyc and epoch_ns atomically. We do this by
|
||||
* ensuring that we always write epoch_cyc, epoch_ns and
|
||||
* epoch_cyc_copy in strict order, and read them in strict order.
|
||||
* If epoch_cyc and epoch_cyc_copy are not equal, then we're in
|
||||
* the middle of an update, and we should repeat the load.
|
||||
*/
|
||||
do {
|
||||
epoch_cyc = cd.epoch_cyc;
|
||||
smp_rmb();
|
||||
epoch_ns = cd.epoch_ns;
|
||||
smp_rmb();
|
||||
} while (epoch_cyc != cd.epoch_cyc_copy);
|
||||
|
||||
return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, cd.mult, cd.shift);
|
||||
}
|
||||
|
||||
/*
|
||||
* Atomically update the sched_clock epoch.
|
||||
*/
|
||||
static void notrace update_sched_clock(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 cyc;
|
||||
u64 ns;
|
||||
|
||||
cyc = read_sched_clock();
|
||||
ns = cd.epoch_ns +
|
||||
cyc_to_ns((cyc - cd.epoch_cyc) & sched_clock_mask,
|
||||
cd.mult, cd.shift);
|
||||
/*
|
||||
* Write epoch_cyc and epoch_ns in a way that the update is
|
||||
* detectable in cyc_to_fixed_sched_clock().
|
||||
*/
|
||||
raw_local_irq_save(flags);
|
||||
cd.epoch_cyc = cyc;
|
||||
smp_wmb();
|
||||
cd.epoch_ns = ns;
|
||||
smp_wmb();
|
||||
cd.epoch_cyc_copy = cyc;
|
||||
raw_local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static void sched_clock_poll(unsigned long wrap_ticks)
|
||||
{
|
||||
mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks));
|
||||
sched_clock_update_fn();
|
||||
update_sched_clock();
|
||||
}
|
||||
|
||||
void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
|
||||
unsigned int clock_bits, unsigned long rate)
|
||||
void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
|
||||
{
|
||||
unsigned long r, w;
|
||||
u64 res, wrap;
|
||||
char r_unit;
|
||||
|
||||
sched_clock_update_fn = update;
|
||||
BUG_ON(bits > 32);
|
||||
WARN_ON(!irqs_disabled());
|
||||
WARN_ON(read_sched_clock != jiffy_sched_clock_read);
|
||||
read_sched_clock = read;
|
||||
sched_clock_mask = (1 << bits) - 1;
|
||||
|
||||
/* calculate the mult/shift to convert counter ticks to ns. */
|
||||
clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 0);
|
||||
clocks_calc_mult_shift(&cd.mult, &cd.shift, rate, NSEC_PER_SEC, 0);
|
||||
|
||||
r = rate;
|
||||
if (r >= 4000000) {
|
||||
r /= 1000000;
|
||||
r_unit = 'M';
|
||||
} else {
|
||||
} else if (r >= 1000) {
|
||||
r /= 1000;
|
||||
r_unit = 'k';
|
||||
}
|
||||
} else
|
||||
r_unit = ' ';
|
||||
|
||||
/* calculate how many ns until we wrap */
|
||||
wrap = cyc_to_ns((1ULL << clock_bits) - 1, cd->mult, cd->shift);
|
||||
wrap = cyc_to_ns((1ULL << bits) - 1, cd.mult, cd.shift);
|
||||
do_div(wrap, NSEC_PER_MSEC);
|
||||
w = wrap;
|
||||
|
||||
/* calculate the ns resolution of this counter */
|
||||
res = cyc_to_ns(1ULL, cd->mult, cd->shift);
|
||||
res = cyc_to_ns(1ULL, cd.mult, cd.shift);
|
||||
pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lums\n",
|
||||
clock_bits, r, r_unit, res, w);
|
||||
bits, r, r_unit, res, w);
|
||||
|
||||
/*
|
||||
* Start the timer to keep sched_clock() properly updated and
|
||||
* sets the initial epoch.
|
||||
*/
|
||||
sched_clock_timer.data = msecs_to_jiffies(w - (w / 10));
|
||||
update();
|
||||
update_sched_clock();
|
||||
|
||||
/*
|
||||
* Ensure that sched_clock() starts off at 0ns
|
||||
*/
|
||||
cd->epoch_ns = 0;
|
||||
cd.epoch_ns = 0;
|
||||
|
||||
pr_debug("Registered %pF as sched_clock source\n", read);
|
||||
}
|
||||
|
||||
unsigned long long notrace sched_clock(void)
|
||||
{
|
||||
u32 cyc = read_sched_clock();
|
||||
return cyc_to_sched_clock(cyc, sched_clock_mask);
|
||||
}
|
||||
|
||||
void __init sched_clock_postinit(void)
|
||||
{
|
||||
/*
|
||||
* If no sched_clock function has been provided at that point,
|
||||
* make it the final one one.
|
||||
*/
|
||||
if (read_sched_clock == jiffy_sched_clock_read)
|
||||
setup_sched_clock(jiffy_sched_clock_read, 32, HZ);
|
||||
|
||||
sched_clock_poll(sched_clock_timer.data);
|
||||
}
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
#include <asm/unified.h>
|
||||
#include <asm/cpu.h>
|
||||
@@ -891,6 +892,12 @@ static struct machine_desc * __init setup_machine_tags(unsigned int nr)
|
||||
return mdesc;
|
||||
}
|
||||
|
||||
static int __init meminfo_cmp(const void *_a, const void *_b)
|
||||
{
|
||||
const struct membank *a = _a, *b = _b;
|
||||
long cmp = bank_pfn_start(a) - bank_pfn_start(b);
|
||||
return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
void __init setup_arch(char **cmdline_p)
|
||||
{
|
||||
@@ -909,8 +916,8 @@ void __init setup_arch(char **cmdline_p)
|
||||
arm_dma_zone_size = mdesc->dma_zone_size;
|
||||
}
|
||||
#endif
|
||||
if (mdesc->soft_reboot)
|
||||
reboot_setup("s");
|
||||
if (mdesc->restart_mode)
|
||||
reboot_setup(&mdesc->restart_mode);
|
||||
|
||||
init_mm.start_code = (unsigned long) _text;
|
||||
init_mm.end_code = (unsigned long) _etext;
|
||||
@@ -923,12 +930,16 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
parse_early_param();
|
||||
|
||||
sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
|
||||
sanity_check_meminfo();
|
||||
arm_memblock_init(&meminfo, mdesc);
|
||||
|
||||
paging_init(mdesc);
|
||||
request_standard_resources(mdesc);
|
||||
|
||||
if (mdesc->restart)
|
||||
arm_pm_restart = mdesc->restart;
|
||||
|
||||
unflatten_device_tree();
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
@@ -54,14 +54,18 @@ ENDPROC(cpu_suspend_abort)
|
||||
* r0 = control register value
|
||||
*/
|
||||
.align 5
|
||||
.pushsection .idmap.text,"ax"
|
||||
ENTRY(cpu_resume_mmu)
|
||||
ldr r3, =cpu_resume_after_mmu
|
||||
instr_sync
|
||||
mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, I-cache, etc
|
||||
mrc p15, 0, r0, c0, c0, 0 @ read id reg
|
||||
instr_sync
|
||||
mov r0, r0
|
||||
mov r0, r0
|
||||
mov pc, r3 @ jump to virtual address
|
||||
ENDPROC(cpu_resume_mmu)
|
||||
.popsection
|
||||
cpu_resume_after_mmu:
|
||||
bl cpu_init @ restore the und/abt/irq banked regs
|
||||
mov r0, #0 @ return zero on success
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/exception.h>
|
||||
#include <asm/idmap.h>
|
||||
#include <asm/topology.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/pgtable.h>
|
||||
@@ -61,7 +62,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
|
||||
{
|
||||
struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
|
||||
struct task_struct *idle = ci->idle;
|
||||
pgd_t *pgd;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -83,30 +83,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
|
||||
init_idle(idle, cpu);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate initial page tables to allow the new CPU to
|
||||
* enable the MMU safely. This essentially means a set
|
||||
* of our "standard" page tables, with the addition of
|
||||
* a 1:1 mapping for the physical address of the kernel.
|
||||
*/
|
||||
pgd = pgd_alloc(&init_mm);
|
||||
if (!pgd)
|
||||
return -ENOMEM;
|
||||
|
||||
if (PHYS_OFFSET != PAGE_OFFSET) {
|
||||
#ifndef CONFIG_HOTPLUG_CPU
|
||||
identity_mapping_add(pgd, __pa(__init_begin), __pa(__init_end));
|
||||
#endif
|
||||
identity_mapping_add(pgd, __pa(_stext), __pa(_etext));
|
||||
identity_mapping_add(pgd, __pa(_sdata), __pa(_edata));
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to tell the secondary core where to find
|
||||
* its stack and the page tables.
|
||||
*/
|
||||
secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
|
||||
secondary_data.pgdir = virt_to_phys(pgd);
|
||||
secondary_data.pgdir = virt_to_phys(idmap_pgd);
|
||||
secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir);
|
||||
__cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
|
||||
outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
|
||||
@@ -142,16 +124,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
|
||||
secondary_data.stack = NULL;
|
||||
secondary_data.pgdir = 0;
|
||||
|
||||
if (PHYS_OFFSET != PAGE_OFFSET) {
|
||||
#ifndef CONFIG_HOTPLUG_CPU
|
||||
identity_mapping_del(pgd, __pa(__init_begin), __pa(__init_end));
|
||||
#endif
|
||||
identity_mapping_del(pgd, __pa(_stext), __pa(_etext));
|
||||
identity_mapping_del(pgd, __pa(_sdata), __pa(_edata));
|
||||
}
|
||||
|
||||
pgd_free(&init_mm, pgd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -550,6 +522,10 @@ static void ipi_cpu_stop(unsigned int cpu)
|
||||
local_fiq_disable();
|
||||
local_irq_disable();
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
platform_cpu_kill(cpu);
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
cpu_relax();
|
||||
}
|
||||
|
@@ -10,8 +10,11 @@
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/clockchips.h>
|
||||
@@ -25,6 +28,7 @@
|
||||
/* set up by the platform code */
|
||||
void __iomem *twd_base;
|
||||
|
||||
static struct clk *twd_clk;
|
||||
static unsigned long twd_timer_rate;
|
||||
|
||||
static struct clock_event_device __percpu **twd_evt;
|
||||
@@ -89,6 +93,52 @@ void twd_timer_stop(struct clock_event_device *clk)
|
||||
disable_percpu_irq(clk->irq);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
|
||||
/*
|
||||
* Updates clockevent frequency when the cpu frequency changes.
|
||||
* Called on the cpu that is changing frequency with interrupts disabled.
|
||||
*/
|
||||
static void twd_update_frequency(void *data)
|
||||
{
|
||||
twd_timer_rate = clk_get_rate(twd_clk);
|
||||
|
||||
clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
|
||||
}
|
||||
|
||||
static int twd_cpufreq_transition(struct notifier_block *nb,
|
||||
unsigned long state, void *data)
|
||||
{
|
||||
struct cpufreq_freqs *freqs = data;
|
||||
|
||||
/*
|
||||
* The twd clock events must be reprogrammed to account for the new
|
||||
* frequency. The timer is local to a cpu, so cross-call to the
|
||||
* changing cpu.
|
||||
*/
|
||||
if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE)
|
||||
smp_call_function_single(freqs->cpu, twd_update_frequency,
|
||||
NULL, 1);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block twd_cpufreq_nb = {
|
||||
.notifier_call = twd_cpufreq_transition,
|
||||
};
|
||||
|
||||
static int twd_cpufreq_init(void)
|
||||
{
|
||||
if (!IS_ERR(twd_clk))
|
||||
return cpufreq_register_notifier(&twd_cpufreq_nb,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
core_initcall(twd_cpufreq_init);
|
||||
|
||||
#endif
|
||||
|
||||
static void __cpuinit twd_calibrate_rate(void)
|
||||
{
|
||||
unsigned long count;
|
||||
@@ -140,6 +190,35 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static struct clk *twd_get_clock(void)
|
||||
{
|
||||
struct clk *clk;
|
||||
int err;
|
||||
|
||||
clk = clk_get_sys("smp_twd", NULL);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk));
|
||||
return clk;
|
||||
}
|
||||
|
||||
err = clk_prepare(clk);
|
||||
if (err) {
|
||||
pr_err("smp_twd: clock failed to prepare: %d\n", err);
|
||||
clk_put(clk);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
err = clk_enable(clk);
|
||||
if (err) {
|
||||
pr_err("smp_twd: clock failed to enable: %d\n", err);
|
||||
clk_unprepare(clk);
|
||||
clk_put(clk);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the local clock events for a CPU.
|
||||
*/
|
||||
@@ -165,7 +244,13 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
|
||||
}
|
||||
}
|
||||
|
||||
twd_calibrate_rate();
|
||||
if (!twd_clk)
|
||||
twd_clk = twd_get_clock();
|
||||
|
||||
if (!IS_ERR_OR_NULL(twd_clk))
|
||||
twd_timer_rate = clk_get_rate(twd_clk);
|
||||
else
|
||||
twd_calibrate_rate();
|
||||
|
||||
clk->name = "local_timer";
|
||||
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
|
||||
@@ -173,15 +258,11 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
|
||||
clk->rating = 350;
|
||||
clk->set_mode = twd_set_mode;
|
||||
clk->set_next_event = twd_set_next_event;
|
||||
clk->shift = 20;
|
||||
clk->mult = div_sc(twd_timer_rate, NSEC_PER_SEC, clk->shift);
|
||||
clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
|
||||
clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
|
||||
|
||||
this_cpu_clk = __this_cpu_ptr(twd_evt);
|
||||
*this_cpu_clk = clk;
|
||||
|
||||
clockevents_register_device(clk);
|
||||
|
||||
clockevents_config_and_register(clk, twd_timer_rate,
|
||||
0xf, 0xffffffff);
|
||||
enable_percpu_irq(clk->irq, 0);
|
||||
}
|
||||
|
@@ -1,13 +1,12 @@
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/idmap.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/suspend.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
static pgd_t *suspend_pgd;
|
||||
|
||||
extern int __cpu_suspend(unsigned long, int (*)(unsigned long));
|
||||
extern void cpu_resume_mmu(void);
|
||||
|
||||
@@ -21,7 +20,7 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
|
||||
*save_ptr = virt_to_phys(ptr);
|
||||
|
||||
/* This must correspond to the LDM in cpu_resume() assembly */
|
||||
*ptr++ = virt_to_phys(suspend_pgd);
|
||||
*ptr++ = virt_to_phys(idmap_pgd);
|
||||
*ptr++ = sp;
|
||||
*ptr++ = virt_to_phys(cpu_do_resume);
|
||||
|
||||
@@ -42,7 +41,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
|
||||
struct mm_struct *mm = current->active_mm;
|
||||
int ret;
|
||||
|
||||
if (!suspend_pgd)
|
||||
if (!idmap_pgd)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
@@ -59,14 +58,3 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init cpu_suspend_init(void)
|
||||
{
|
||||
suspend_pgd = pgd_alloc(&init_mm);
|
||||
if (suspend_pgd) {
|
||||
unsigned long addr = virt_to_phys(cpu_resume_mmu);
|
||||
identity_mapping_add(suspend_pgd, addr, addr + SECTION_SIZE);
|
||||
}
|
||||
return suspend_pgd ? 0 : -ENOMEM;
|
||||
}
|
||||
core_initcall(cpu_suspend_init);
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/perf_event.h>
|
||||
|
||||
#include <asm/opcodes.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
@@ -185,6 +186,21 @@ static int swp_handler(struct pt_regs *regs, unsigned int instr)
|
||||
|
||||
perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->ARM_pc);
|
||||
|
||||
res = arm_check_condition(instr, regs->ARM_cpsr);
|
||||
switch (res) {
|
||||
case ARM_OPCODE_CONDTEST_PASS:
|
||||
break;
|
||||
case ARM_OPCODE_CONDTEST_FAIL:
|
||||
/* Condition failed - return to next instruction */
|
||||
regs->ARM_pc += 4;
|
||||
return 0;
|
||||
case ARM_OPCODE_CONDTEST_UNCOND:
|
||||
/* If unconditional encoding - not a SWP, undef */
|
||||
return -EFAULT;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (current->pid != previous_pid) {
|
||||
pr_debug("\"%s\" (%ld) uses deprecated SWP{B} instruction\n",
|
||||
current->comm, (unsigned long)current->pid);
|
||||
|
@@ -180,9 +180,9 @@ static int __init setup_tcm_bank(u8 type, u8 bank, u8 banks,
|
||||
*/
|
||||
void __init tcm_init(void)
|
||||
{
|
||||
u32 tcm_status = read_cpuid_tcmstatus();
|
||||
u8 dtcm_banks = (tcm_status >> 16) & 0x03;
|
||||
u8 itcm_banks = (tcm_status & 0x03);
|
||||
u32 tcm_status;
|
||||
u8 dtcm_banks;
|
||||
u8 itcm_banks;
|
||||
size_t dtcm_code_sz = &__edtcm_data - &__sdtcm_data;
|
||||
size_t itcm_code_sz = &__eitcm_text - &__sitcm_text;
|
||||
char *start;
|
||||
@@ -191,6 +191,22 @@ void __init tcm_init(void)
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Prior to ARMv5 there is no TCM, and trying to read the status
|
||||
* register will hang the processor.
|
||||
*/
|
||||
if (cpu_architecture() < CPU_ARCH_ARMv5) {
|
||||
if (dtcm_code_sz || itcm_code_sz)
|
||||
pr_info("CPU TCM: %u bytes of DTCM and %u bytes of "
|
||||
"ITCM code compiled in, but no TCM present "
|
||||
"in pre-v5 CPU\n", dtcm_code_sz, itcm_code_sz);
|
||||
return;
|
||||
}
|
||||
|
||||
tcm_status = read_cpuid_tcmstatus();
|
||||
dtcm_banks = (tcm_status >> 16) & 0x03;
|
||||
itcm_banks = (tcm_status & 0x03);
|
||||
|
||||
/* Values greater than 2 for D/ITCM banks are "reserved" */
|
||||
if (dtcm_banks > 2)
|
||||
dtcm_banks = 0;
|
||||
|
@@ -13,6 +13,12 @@
|
||||
*(.proc.info.init) \
|
||||
VMLINUX_SYMBOL(__proc_info_end) = .;
|
||||
|
||||
#define IDMAP_TEXT \
|
||||
ALIGN_FUNCTION(); \
|
||||
VMLINUX_SYMBOL(__idmap_text_start) = .; \
|
||||
*(.idmap.text) \
|
||||
VMLINUX_SYMBOL(__idmap_text_end) = .;
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
#define ARM_CPU_DISCARD(x)
|
||||
#define ARM_CPU_KEEP(x) x
|
||||
@@ -92,6 +98,7 @@ SECTIONS
|
||||
SCHED_TEXT
|
||||
LOCK_TEXT
|
||||
KPROBES_TEXT
|
||||
IDMAP_TEXT
|
||||
#ifdef CONFIG_MMU
|
||||
*(.fixup)
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user