cregit-Linux how code gets into the kernel

Release 4.14 arch/blackfin/include/asm/entry.h

/*
 * Copyright 2004-2009 Analog Devices Inc.
 *
 * Licensed under the GPL-2 or later.
 */

#ifndef __BFIN_ENTRY_H

#define __BFIN_ENTRY_H

#include <asm/setup.h>
#include <asm/page.h>

#ifdef __ASSEMBLY__


#define	LFLUSH_I_AND_D	0x00000808

#define	LSIGTRAP	5

/*
 * NOTE!  The single-stepping code assumes that all interrupt handlers
 * start by saving SYSCFG on the stack with their first instruction.
 */

/* This one is used for exceptions, emulation, and NMI.  It doesn't push
   RETI and doesn't do cli.  */

#define SAVE_ALL_SYS		save_context_no_interrupts
/* This is used for all normal interrupts.  It saves a minimum of registers
   to the stack, loads the IRQ number, and jumps to common code.  */
#ifdef CONFIG_IPIPE

# define LOAD_IPIPE_IPEND \
	P0.l = lo(IPEND); \
        P0.h = hi(IPEND); \
        R1 = [P0];
#else

# define LOAD_IPIPE_IPEND
#endif

/*
 * Workaround for anomalies 05000283 and 05000315
 */
#if ANOMALY_05000283 || ANOMALY_05000315

# define ANOMALY_283_315_WORKAROUND(preg, dreg)		\
	cc = dreg == dreg;                              \
        preg.h = HI(CHIPID);                            \
        preg.l = LO(CHIPID);                            \
        if cc jump 1f;                                  \
        dreg.l = W[preg];                               \
1:
#else

# define ANOMALY_283_315_WORKAROUND(preg, dreg)
#endif /* ANOMALY_05000283 || ANOMALY_05000315 */

#ifndef CONFIG_EXACT_HWERR
/* As a debugging aid - we save IPEND when DEBUG_KERNEL is on,
 * otherwise it is a waste of cycles.
 */
# ifndef CONFIG_DEBUG_KERNEL

#define INTERRUPT_ENTRY(N)						\
    [--sp] = SYSCFG;                                                        \
    [--sp] = P0;	/*orig_p0*/					\
    [--sp] = R0;	/*orig_r0*/					\
    [--sp] = (R7:0,P5:0);                                               \
    R0 = (N);                                                           \
    LOAD_IPIPE_IPEND                                                    \
    jump __common_int_entry;
# else /* CONFIG_DEBUG_KERNEL */

#define INTERRUPT_ENTRY(N)						\
    [--sp] = SYSCFG;                                                        \
    [--sp] = P0;	/*orig_p0*/					\
    [--sp] = R0;	/*orig_r0*/					\
    [--sp] = (R7:0,P5:0);                                               \
    p0.l = lo(IPEND);                                                   \
    p0.h = hi(IPEND);                                                   \
    r1 = [p0];                                                          \
    R0 = (N);                                                           \
    LOAD_IPIPE_IPEND                                                    \
    jump __common_int_entry;
# endif /* CONFIG_DEBUG_KERNEL */

/* For timer interrupts, we need to save IPEND, since the user_mode
 *macro accesses it to determine where to account time.
 */

#define TIMER_INTERRUPT_ENTRY(N)					\
    [--sp] = SYSCFG;                                                        \
    [--sp] = P0;	/*orig_p0*/					\
    [--sp] = R0;	/*orig_r0*/					\
    [--sp] = (R7:0,P5:0);                                               \
    p0.l = lo(IPEND);                                                   \
    p0.h = hi(IPEND);                                                   \
    r1 = [p0];                                                          \
    R0 = (N);                                                           \
    jump __common_int_entry;
#else /* CONFIG_EXACT_HWERR is defined */

/* if we want hardware error to be exact, we need to do a SSYNC (which forces
 * read/writes to complete to the memory controllers), and check to see that
 * caused a pending HW error condition. If so, we assume it was caused by user
 * space, by setting the same interrupt that we are in (so it goes off again)
 * and context restore, and a RTI (without servicing anything). This should
 * cause the pending HWERR to fire, and when that is done, this interrupt will
 * be re-serviced properly.
 * As you can see by the code - we actually need to do two SSYNCS - one to
 * make sure the read/writes complete, and another to make sure the hardware
 * error is recognized by the core.
 *
 * The extra nop before the SSYNC is to make sure we work around 05000244,
 * since the 283/315 workaround includes a branch to the end
 */

#define INTERRUPT_ENTRY(N)						\
    [--sp] = SYSCFG;                                                        \
    [--sp] = P0;	/*orig_p0*/					\
    [--sp] = R0;	/*orig_r0*/					\
    [--sp] = (R7:0,P5:0);                                               \
    R1 = ASTAT;                                                         \
    ANOMALY_283_315_WORKAROUND(p0, r0)                                  \
    P0.L = LO(ILAT);                                                    \
    P0.H = HI(ILAT);                                                    \
    NOP;                                                                \
    SSYNC;                                                              \
    SSYNC;                                                              \
    R0 = [P0];                                                          \
    CC = BITTST(R0, EVT_IVHW_P);                                        \
    IF CC JUMP 1f;                                                      \
    ASTAT = R1;                                                         \
    p0.l = lo(IPEND);                                                   \
    p0.h = hi(IPEND);                                                   \
    r1 = [p0];                                                          \
    R0 = (N);                                                           \
    LOAD_IPIPE_IPEND                                                    \
    jump __common_int_entry;                                            \
1:  ASTAT = R1;                                                         \
    RAISE N;                                                            \
    (R7:0, P5:0) = [SP++];                                              \
    SP += 0x8;                                                          \
    SYSCFG = [SP++];                                                    \
    CSYNC;                                                              \
    RTI;


#define TIMER_INTERRUPT_ENTRY(N)					\
    [--sp] = SYSCFG;                                                        \
    [--sp] = P0;	/*orig_p0*/					\
    [--sp] = R0;	/*orig_r0*/					\
    [--sp] = (R7:0,P5:0);                                               \
    R1 = ASTAT;                                                         \
    ANOMALY_283_315_WORKAROUND(p0, r0)                                  \
    P0.L = LO(ILAT);                                                    \
    P0.H = HI(ILAT);                                                    \
    NOP;                                                                \
    SSYNC;                                                              \
    SSYNC;                                                              \
    R0 = [P0];                                                          \
    CC = BITTST(R0, EVT_IVHW_P);                                        \
    IF CC JUMP 1f;                                                      \
    ASTAT = R1;                                                         \
    p0.l = lo(IPEND);                                                   \
    p0.h = hi(IPEND);                                                   \
    r1 = [p0];                                                          \
    R0 = (N);                                                           \
    jump __common_int_entry;                                            \
1:  ASTAT = R1;                                                         \
    RAISE N;                                                            \
    (R7:0, P5:0) = [SP++];                                              \
    SP += 0x8;                                                          \
    SYSCFG = [SP++];                                                    \
    CSYNC;                                                              \
    RTI;
#endif	/* CONFIG_EXACT_HWERR */

/* This one pushes RETI without using CLI.  Interrupts are enabled.  */

#define SAVE_CONTEXT_SYSCALL	save_context_syscall

#define SAVE_CONTEXT		save_context_with_interrupts

#define SAVE_CONTEXT_CPLB	save_context_cplb


#define RESTORE_ALL_SYS		restore_context_no_interrupts

#define RESTORE_CONTEXT		restore_context_with_interrupts

#define RESTORE_CONTEXT_CPLB	restore_context_cplb

#endif				/* __ASSEMBLY__ */
#endif				/* __BFIN_ENTRY_H */

Overall Contributors

PersonTokensPropCommitsCommitProp
Robin Getz8947.59%342.86%
Bryan Wu7339.04%114.29%
Yi Li168.56%114.29%
Bernd Schmidt94.81%228.57%
Total187100.00%7100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.