2f9ac29eec
This change enables unaligned userspace memory access via a kernel fast path on tilegx. The kernel tracks user PC/instruction pairs per-thread using a direct-mapped cache in userspace. The cache maps those PC/instruction pairs to JIT'ed instruction sequences that load or store using byte-wide load store intructions and then synthesize 2-, 4- or 8-byte load or store results. Once an instruction has been seen to generate an unaligned access once, subsequent hits on that instruction typically require overhead of only around 50 cycles if cache and TLB is hot. We support the prctl() PR_GET_UNALIGN / PR_SET_UNALIGN sys call to enable or disable unaligned fixups on a per-process basis. To do this we pull some of the tilepro unaligned support out of the single_step.c file; tilepro uses instruction disassembly for both single-step and unaligned access support. Since tilegx actually has hardware singlestep support, though, it's cleaner to keep the tilegx unaligned access code in a separate file. While we're at it, properly rename the tilepro-specific types, etc., to have tilepro suffixes instead of generic tile suffixes. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
86 lines
2.2 KiB
C
86 lines
2.2 KiB
C
/*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef _ASM_TILE_TRAPS_H
|
|
#define _ASM_TILE_TRAPS_H
|
|
|
|
#ifndef __ASSEMBLY__
|
|
#include <arch/chip.h>
|
|
|
|
/* mm/fault.c */
|
|
void do_page_fault(struct pt_regs *, int fault_num,
|
|
unsigned long address, unsigned long write);
|
|
#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
|
|
void do_async_page_fault(struct pt_regs *);
|
|
#endif
|
|
|
|
#ifndef __tilegx__
|
|
/*
|
|
* We return this structure in registers to avoid having to write
|
|
* additional save/restore code in the intvec.S caller.
|
|
*/
|
|
struct intvec_state {
|
|
void *handler;
|
|
unsigned long vecnum;
|
|
unsigned long fault_num;
|
|
unsigned long info;
|
|
unsigned long retval;
|
|
};
|
|
struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num,
|
|
unsigned long address,
|
|
unsigned long info);
|
|
#endif
|
|
|
|
/* kernel/traps.c */
|
|
void do_trap(struct pt_regs *, int fault_num, unsigned long reason);
|
|
void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52);
|
|
|
|
/* kernel/time.c */
|
|
void do_timer_interrupt(struct pt_regs *, int fault_num);
|
|
|
|
/* kernel/messaging.c */
|
|
void hv_message_intr(struct pt_regs *, int intnum);
|
|
|
|
/* kernel/irq.c */
|
|
void tile_dev_intr(struct pt_regs *, int intnum);
|
|
|
|
#ifdef CONFIG_HARDWALL
|
|
/* kernel/hardwall.c */
|
|
void do_hardwall_trap(struct pt_regs *, int fault_num);
|
|
#endif
|
|
|
|
/* kernel/ptrace.c */
|
|
void do_breakpoint(struct pt_regs *, int fault_num);
|
|
|
|
|
|
#ifdef __tilegx__
|
|
/* kernel/single_step.c */
|
|
void gx_singlestep_handle(struct pt_regs *, int fault_num);
|
|
|
|
/* kernel/intvec_64.S */
|
|
void fill_ra_stack(void);
|
|
|
|
/* Handle unalign data fixup. */
|
|
extern void do_unaligned(struct pt_regs *regs, int vecnum);
|
|
#endif
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#ifdef __tilegx__
|
|
/* 128 byte JIT per unalign fixup. */
|
|
#define UNALIGN_JIT_SHIFT 7
|
|
#endif
|
|
|
|
#endif /* _ASM_TILE_TRAPS_H */
|