linux/arch/tile/include/asm/processor.h
<<
>>
Prefs
   1/*
   2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
   3 *
   4 *   This program is free software; you can redistribute it and/or
   5 *   modify it under the terms of the GNU General Public License
   6 *   as published by the Free Software Foundation, version 2.
   7 *
   8 *   This program is distributed in the hope that it will be useful, but
   9 *   WITHOUT ANY WARRANTY; without even the implied warranty of
  10 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11 *   NON INFRINGEMENT.  See the GNU General Public License for
  12 *   more details.
  13 */
  14
  15#ifndef _ASM_TILE_PROCESSOR_H
  16#define _ASM_TILE_PROCESSOR_H
  17
  18#include <arch/chip.h>
  19
  20#ifndef __ASSEMBLY__
  21
  22/*
  23 * NOTE: we don't include <linux/ptrace.h> or <linux/percpu.h> as one
  24 * normally would, due to #include dependencies.
  25 */
  26#include <linux/types.h>
  27#include <asm/ptrace.h>
  28#include <asm/percpu.h>
  29
  30#include <arch/spr_def.h>
  31
  32struct task_struct;
  33struct thread_struct;
  34
  35typedef struct {
  36        unsigned long seg;
  37} mm_segment_t;
  38
  39/*
  40 * Default implementation of macro that returns current
  41 * instruction pointer ("program counter").
  42 */
  43void *current_text_addr(void);
  44
  45#if CHIP_HAS_TILE_DMA()
  46/* Capture the state of a suspended DMA. */
  47struct tile_dma_state {
  48        int enabled;
  49        unsigned long src;
  50        unsigned long dest;
  51        unsigned long strides;
  52        unsigned long chunk_size;
  53        unsigned long src_chunk;
  54        unsigned long dest_chunk;
  55        unsigned long byte;
  56        unsigned long status;
  57};
  58
  59/*
  60 * A mask of the DMA status register for selecting only the 'running'
  61 * and 'done' bits.
  62 */
  63#define DMA_STATUS_MASK \
  64  (SPR_DMA_STATUS__RUNNING_MASK | SPR_DMA_STATUS__DONE_MASK)
  65#endif
  66
  67/*
  68 * Track asynchronous TLB events (faults and access violations)
  69 * that occur while we are in kernel mode from DMA or the SN processor.
  70 */
  71struct async_tlb {
  72        short fault_num;         /* original fault number; 0 if none */
  73        char is_fault;           /* was it a fault (vs an access violation) */
  74        char is_write;           /* for fault: was it caused by a write? */
  75        unsigned long address;   /* what address faulted? */
  76};
  77
  78#ifdef CONFIG_HARDWALL
  79struct hardwall_info;
  80struct hardwall_task {
  81        /* Which hardwall is this task tied to? (or NULL if none) */
  82        struct hardwall_info *info;
  83        /* Chains this task into the list at info->task_head. */
  84        struct list_head list;
  85};
  86#ifdef __tilepro__
  87#define HARDWALL_TYPES 1   /* udn */
  88#else
  89#define HARDWALL_TYPES 3   /* udn, idn, and ipi */
  90#endif
  91#endif
  92
  93struct thread_struct {
  94        /* kernel stack pointer */
  95        unsigned long  ksp;
  96        /* kernel PC */
  97        unsigned long  pc;
  98        /* starting user stack pointer (for page migration) */
  99        unsigned long  usp0;
 100        /* pid of process that created this one */
 101        pid_t creator_pid;
 102#if CHIP_HAS_TILE_DMA()
 103        /* DMA info for suspended threads (byte == 0 means no DMA state) */
 104        struct tile_dma_state tile_dma_state;
 105#endif
 106        /* User EX_CONTEXT registers */
 107        unsigned long ex_context[2];
 108        /* User SYSTEM_SAVE registers */
 109        unsigned long system_save[4];
 110        /* User interrupt mask */
 111        unsigned long long interrupt_mask;
 112        /* User interrupt-control 0 state */
 113        unsigned long intctrl_0;
 114        /* Is this task currently doing a backtrace? */
 115        bool in_backtrace;
 116        /* Any other miscellaneous processor state bits */
 117        unsigned long proc_status;
 118#if !CHIP_HAS_FIXED_INTVEC_BASE()
 119        /* Interrupt base for PL0 interrupts */
 120        unsigned long interrupt_vector_base;
 121#endif
 122        /* Tile cache retry fifo high-water mark */
 123        unsigned long tile_rtf_hwm;
 124#if CHIP_HAS_DSTREAM_PF()
 125        /* Data stream prefetch control */
 126        unsigned long dstream_pf;
 127#endif
 128#ifdef CONFIG_HARDWALL
 129        /* Hardwall information for various resources. */
 130        struct hardwall_task hardwall[HARDWALL_TYPES];
 131#endif
 132#if CHIP_HAS_TILE_DMA()
 133        /* Async DMA TLB fault information */
 134        struct async_tlb dma_async_tlb;
 135#endif
 136};
 137
 138#endif /* !__ASSEMBLY__ */
 139
 140/*
 141 * Start with "sp" this many bytes below the top of the kernel stack.
 142 * This allows us to be cache-aware when handling the initial save
 143 * of the pt_regs value to the stack.
 144 */
 145#define STACK_TOP_DELTA 64
 146
 147/*
 148 * When entering the kernel via a fault, start with the top of the
 149 * pt_regs structure this many bytes below the top of the page.
 150 * This aligns the pt_regs structure optimally for cache-line access.
 151 */
 152#ifdef __tilegx__
 153#define KSTK_PTREGS_GAP  48
 154#else
 155#define KSTK_PTREGS_GAP  56
 156#endif
 157
 158#ifndef __ASSEMBLY__
 159
 160#ifdef __tilegx__
 161#define TASK_SIZE_MAX           (_AC(1, UL) << (MAX_VA_WIDTH - 1))
 162#else
 163#define TASK_SIZE_MAX           PAGE_OFFSET
 164#endif
 165
 166/* TASK_SIZE and related variables are always checked in "current" context. */
 167#ifdef CONFIG_COMPAT
 168#define COMPAT_TASK_SIZE        (1UL << 31)
 169#define TASK_SIZE               ((current_thread_info()->status & TS_COMPAT) ?\
 170                                 COMPAT_TASK_SIZE : TASK_SIZE_MAX)
 171#else
 172#define TASK_SIZE               TASK_SIZE_MAX
 173#endif
 174
 175#define VDSO_BASE       ((unsigned long)current->active_mm->context.vdso_base)
 176#define VDSO_SYM(x)     (VDSO_BASE + (unsigned long)(x))
 177
 178#define STACK_TOP               TASK_SIZE
 179
 180/* STACK_TOP_MAX is used temporarily in execve and should not check COMPAT. */
 181#define STACK_TOP_MAX           TASK_SIZE_MAX
 182
 183/*
 184 * This decides where the kernel will search for a free chunk of vm
 185 * space during mmap's, if it is using bottom-up mapping.
 186 */
 187#define TASK_UNMAPPED_BASE      (PAGE_ALIGN(TASK_SIZE / 3))
 188
 189#define HAVE_ARCH_PICK_MMAP_LAYOUT
 190
 191#define INIT_THREAD {                                                   \
 192        .ksp = (unsigned long)init_stack + THREAD_SIZE - STACK_TOP_DELTA, \
 193        .interrupt_mask = -1ULL                                         \
 194}
 195
 196/* Kernel stack top for the task that first boots on this cpu. */
 197DECLARE_PER_CPU(unsigned long, boot_sp);
 198
 199/* PC to boot from on this cpu. */
 200DECLARE_PER_CPU(unsigned long, boot_pc);
 201
 202/* Do necessary setup to start up a newly executed thread. */
 203static inline void start_thread(struct pt_regs *regs,
 204                                unsigned long pc, unsigned long usp)
 205{
 206        regs->pc = pc;
 207        regs->sp = usp;
 208        single_step_execve();
 209}
 210
 211/* Free all resources held by a thread. */
 212static inline void release_thread(struct task_struct *dead_task)
 213{
 214        /* Nothing for now */
 215}
 216
 217extern int do_work_pending(struct pt_regs *regs, u32 flags);
 218
 219
 220/*
 221 * Return saved (kernel) PC of a blocked thread.
 222 * Only used in a printk() in kernel/sched/core.c, so don't work too hard.
 223 */
 224#define thread_saved_pc(t)   ((t)->thread.pc)
 225
 226unsigned long get_wchan(struct task_struct *p);
 227
 228/* Return initial ksp value for given task. */
 229#define task_ksp0(task) \
 230        ((unsigned long)(task)->stack + THREAD_SIZE - STACK_TOP_DELTA)
 231
 232/* Return some info about the user process TASK. */
 233#define task_pt_regs(task) \
 234        ((struct pt_regs *)(task_ksp0(task) - KSTK_PTREGS_GAP) - 1)
 235#define current_pt_regs()                                   \
 236        ((struct pt_regs *)((stack_pointer | (THREAD_SIZE - 1)) - \
 237                            STACK_TOP_DELTA - (KSTK_PTREGS_GAP - 1)) - 1)
 238#define task_sp(task)   (task_pt_regs(task)->sp)
 239#define task_pc(task)   (task_pt_regs(task)->pc)
 240/* Aliases for pc and sp (used in fs/proc/array.c) */
 241#define KSTK_EIP(task)  task_pc(task)
 242#define KSTK_ESP(task)  task_sp(task)
 243
 244/* Fine-grained unaligned JIT support */
 245#define GET_UNALIGN_CTL(tsk, adr)       get_unalign_ctl((tsk), (adr))
 246#define SET_UNALIGN_CTL(tsk, val)       set_unalign_ctl((tsk), (val))
 247
 248extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr);
 249extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val);
 250
 251/* Standard format for printing registers and other word-size data. */
 252#ifdef __tilegx__
 253# define REGFMT "0x%016lx"
 254#else
 255# define REGFMT "0x%08lx"
 256#endif
 257
 258/*
 259 * Do some slow action (e.g. read a slow SPR).
 260 * Note that this must also have compiler-barrier semantics since
 261 * it may be used in a busy loop reading memory.
 262 */
 263static inline void cpu_relax(void)
 264{
 265        __insn_mfspr(SPR_PASS);
 266        barrier();
 267}
 268
 269/* Info on this processor (see fs/proc/cpuinfo.c) */
 270struct seq_operations;
 271extern const struct seq_operations cpuinfo_op;
 272
 273/* Provide information about the chip model. */
 274extern char chip_model[64];
 275
 276/* Data on which physical memory controller corresponds to which NUMA node. */
 277extern int node_controller[];
 278
 279/* Does the heap allocator return hash-for-home pages by default? */
 280extern int hash_default;
 281
 282/* Should kernel stack pages be hash-for-home? */
 283extern int kstack_hash;
 284
 285/* Does MAP_ANONYMOUS return hash-for-home pages by default? */
 286#define uheap_hash hash_default
 287
 288
 289/* Are we using huge pages in the TLB for kernel data? */
 290extern int kdata_huge;
 291
 292/* Support standard Linux prefetching. */
 293#define ARCH_HAS_PREFETCH
 294#define prefetch(x) __builtin_prefetch(x)
 295#define PREFETCH_STRIDE CHIP_L2_LINE_SIZE()
 296
 297/* Bring a value into the L1D, faulting the TLB if necessary. */
 298#ifdef __tilegx__
 299#define prefetch_L1(x) __insn_prefetch_l1_fault((void *)(x))
 300#else
 301#define prefetch_L1(x) __insn_prefetch_L1((void *)(x))
 302#endif
 303
 304#else /* __ASSEMBLY__ */
 305
 306/* Do some slow action (e.g. read a slow SPR). */
 307#define CPU_RELAX       mfspr zero, SPR_PASS
 308
 309#endif /* !__ASSEMBLY__ */
 310
 311/* Assembly code assumes that the PL is in the low bits. */
 312#if SPR_EX_CONTEXT_1_1__PL_SHIFT != 0
 313# error Fix assembly assumptions about PL
 314#endif
 315
 316/* We sometimes use these macros for EX_CONTEXT_0_1 as well. */
 317#if SPR_EX_CONTEXT_1_1__PL_SHIFT != SPR_EX_CONTEXT_0_1__PL_SHIFT || \
 318    SPR_EX_CONTEXT_1_1__PL_RMASK != SPR_EX_CONTEXT_0_1__PL_RMASK || \
 319    SPR_EX_CONTEXT_1_1__ICS_SHIFT != SPR_EX_CONTEXT_0_1__ICS_SHIFT || \
 320    SPR_EX_CONTEXT_1_1__ICS_RMASK != SPR_EX_CONTEXT_0_1__ICS_RMASK
 321# error Fix assumptions that EX1 macros work for both PL0 and PL1
 322#endif
 323
 324/* Allow pulling apart and recombining the PL and ICS bits in EX_CONTEXT. */
 325#define EX1_PL(ex1) \
 326  (((ex1) >> SPR_EX_CONTEXT_1_1__PL_SHIFT) & SPR_EX_CONTEXT_1_1__PL_RMASK)
 327#define EX1_ICS(ex1) \
 328  (((ex1) >> SPR_EX_CONTEXT_1_1__ICS_SHIFT) & SPR_EX_CONTEXT_1_1__ICS_RMASK)
 329#define PL_ICS_EX1(pl, ics) \
 330  (((pl) << SPR_EX_CONTEXT_1_1__PL_SHIFT) | \
 331   ((ics) << SPR_EX_CONTEXT_1_1__ICS_SHIFT))
 332
 333/*
 334 * Provide symbolic constants for PLs.
 335 */
 336#define USER_PL 0
 337#if CONFIG_KERNEL_PL == 2
 338#define GUEST_PL 1
 339#endif
 340#define KERNEL_PL CONFIG_KERNEL_PL
 341
 342/* SYSTEM_SAVE_K_0 holds the current cpu number ORed with ksp0. */
 343#ifdef __tilegx__
 344#define CPU_SHIFT 48
 345#if CHIP_VA_WIDTH() > CPU_SHIFT
 346# error Too many VA bits!
 347#endif
 348#define MAX_CPU_ID ((1 << (64 - CPU_SHIFT)) - 1)
 349#define raw_smp_processor_id() \
 350        ((int)(__insn_mfspr(SPR_SYSTEM_SAVE_K_0) >> CPU_SHIFT))
 351#define get_current_ksp0() \
 352        ((unsigned long)(((long)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) << \
 353                          (64 - CPU_SHIFT)) >> (64 - CPU_SHIFT)))
 354#define next_current_ksp0(task) ({ \
 355        unsigned long __ksp0 = task_ksp0(task) & ((1UL << CPU_SHIFT) - 1); \
 356        unsigned long __cpu = (long)raw_smp_processor_id() << CPU_SHIFT; \
 357        __ksp0 | __cpu; \
 358})
 359#else
 360#define LOG2_NR_CPU_IDS 6
 361#define MAX_CPU_ID ((1 << LOG2_NR_CPU_IDS) - 1)
 362#define raw_smp_processor_id() \
 363        ((int)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & MAX_CPU_ID)
 364#define get_current_ksp0() \
 365        (__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & ~MAX_CPU_ID)
 366#define next_current_ksp0(task) ({ \
 367        unsigned long __ksp0 = task_ksp0(task); \
 368        int __cpu = raw_smp_processor_id(); \
 369        BUG_ON(__ksp0 & MAX_CPU_ID); \
 370        __ksp0 | __cpu; \
 371})
 372#endif
 373#if CONFIG_NR_CPUS > (MAX_CPU_ID + 1)
 374# error Too many cpus!
 375#endif
 376
 377#endif /* _ASM_TILE_PROCESSOR_H */
 378