linux kernel - How Can I put ARM processor in different modes using C program? -


i going through different mode of arm processor. want check processor state(ex: register values) while in different mode.

so can me find out sample code put processor in different mode ?

for example found code undefined mode: asm volatile (".short 0xffff\n");

if wish test modes user space, difficult question. there maybe no way go fiq mode, if there no fiq peripheral in system. system may not using monitor mode @ all, etc. abort mode, can use invalid pointer, or use mmap. however, answer mode switches user space book (or impossible) without assistance kernel. creating test module /proc or /sys file , using techniques below implement kernel code straight forward method.

you should aware not mode switch transitions allowed. instance, may never switch user mode other mode except through exception mechanisms. issue each arm mode has banked registers. 1 of these important sp (or stack pointer) , lr (or link register) that fundamental 'c' code.

it more safe use macro of in-line assembler bound test snippets, use function calls. test code must not call external routines. can difficult using floating point, etc may result in compiler inserting hidden sub-routine calls. should inspect generated assembler , provide comments others.

 /* current mode restoration. */  static inline unsigned int get_cpsr(void)  {      unsigned int rval;      asm (" mrs %0, cpsr\n" : "=r" (rval));      return rval;  } 

you can put in header file. compiler inline code so, msr instruction placed within routine.

to change mode use define like,

 /* change mode */  #define change_mode(mode) asm("cps %0" : : "i"(mode)) 

tangr's has correct mode defines,

#define mode_usr        0x10   /* never use one, there no way back! */ #define mode_fiq        0x11   /* banked r8-r14 */ #define mode_irq        0x12 #define mode_svc        0x13 #define mode_mon        0x16 #define mode_abt        0x17 #define mode_und        0x1b #define mode_sys        0x1f   /* same user... */ 

you need restore previous mode,

#define restore_mode(mode) \      mode &= 0x1f; \      asm(" msr cpsr, %0\n" : : "r"(mode) : "cc") 

put follows,

  void test_abort(void)   {      unsigned int old_mode = get_cpsr() & 0x1f;      change_mode(mode_abt);      /* test code here... must not call functions. */      restore_mode(old_mode);   } 

this answers question directly. however, due of difficulties, easier write assembler achieve test. believe trying leverage existing linux code test modes. not arm-linux design goal , without modifying source, difficult achieve , highly system specific if is.


Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -