-1

I have to check whether the ARM processor is in SVC or IRQ mode during kernel bootup. That is, I want to insert some code to check the ARM mode into start_kernel() function before the interrupts are enabled and after the interrupts are enabled.

I know that I need the SPSR or CPSR values(bits) to check the mode in ARM, but how can I write code for that in start_kernel function since the code for reading bits of CPSR/SPSR is in assembly? Where do I put the assembly code to check the ARM mode during bootup time? Is there any way to dump the SPSR/CPSR values?

karthikpj
  • 33
  • 1
  • 8
  • This should be trivial using inline assembly. What compiler are you using? – Cody Gray - on strike Dec 22 '16 at 06:12
  • @cody I have put `asm (" mrs %0, cpsr\n" : "=r" (rval)); printk(KERN_NOTICE "%u", rval);` after some function in start_kernel function, but no output is seen during bootup. – karthikpj Dec 22 '16 at 08:39
  • I am using ARM GNU/Linux tool chain and arm-linux-gnueabi cross compiler. – karthikpj Dec 22 '16 at 12:13
  • You need to go to 'kernel hacking' and turn on POLLED or low-level debug (DEBUG_LL). Then you can alter [*kernel/printk/printk.c* in function `vprintk_emit`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/printk/printk.c?id=2f1d70af28a94988c1e8fba2ae03d4c7e68e690b#n1491) and add a line `printascii(text)` (at 1549 in current mainline). Then you will have more success working through your boot issues. Also need `extern void printascii(char *);` somewhere of course. When interrupts are active you get double console output, then you need tor remove `printascii`. – artless noise Dec 22 '16 at 14:28
  • @artlessnoise I have done this and its not related to my question at all.I want contents of cpsr not some debugging info. – karthikpj Dec 23 '16 at 04:52
  • `but no output is seen during bootup` is caused by printk buffering which will only be output when interrupts are enabled unless you enable DEBUG_LL and use `printascii`. Otherwise, your `asm` seems to be correct. – artless noise Dec 23 '16 at 18:01

2 Answers2

3

I don't dare imagine why this should be a concern, but fortunately there's an easy answer:

It's in SVC mode.

The very first thing* the kernel entrypoint does is to forcibly switch into SVC mode and mask interrupts. To somehow be in the wrong mode by the time you reach C code in start_kernel way later would need the system to be unimaginably horribly broken. The only way I can conceive of that even being possible is if there is some Secure firmware running asynchronously (e.g. off a Secure timer interrupt) which deliberately corrupts the Non-secure state, and that's sufficiently ridiculous to discount.

* OK, the second thing if the kernel is built with KVM support and entered in HYP, but hey...

Notlikethat
  • 20,095
  • 3
  • 40
  • 77
  • Actually I know that it will be in SVC mode but I need to dump the CPSR/SPSR contents after the interrupts are enabled. Can you tell me how to dump those values in any of the startup functions(might be assembly also) because I am booting the kernel on kzma-9 board and I need to see it as kernel message (when I run dmesg). – karthikpj Dec 23 '16 at 03:05
  • I dont need the checking of mode to be in start_kernel function only. It can be in any of startup code. I just want to see the contents of CPSR/SPSR as kernel message. – karthikpj Dec 23 '16 at 03:18
  • 1
    @karthikpj If you want it to appear in dmesg, then it will need to go via regular `printk()`, which basically rules out doing it from assembly. Since `printk()` needs stuff like locks and percpu variables to be ready, calling it too early might well result in a crash - to be safe, I wouldn't put it any earlier than the initial call printing `linux_banner`. Remember to newline-terminate your format string so it doesn't get munged into whatever message follows. – Notlikethat Dec 23 '16 at 12:55
  • Exactly why I describe how to modify `vprintk_emit()` so that early printk messages are seen. Also you can use `printascii()` directly to verify the code point is reached. – artless noise Dec 23 '16 at 18:04
  • @Notlikethat Do you know by any chance where the interrupts are enabled in startup code? Actually I am trying to print address of each function during the kernel boot but after **setup_arch()** call in **start_kernel** function where vector table for interrupts are initialized, addresses are getting printed randomly without stop(infinitely). Can you point me as to where the problem might be? – karthikpj Dec 24 '16 at 05:45
  • [ARM specific IRQ initialization](http://stackoverflow.com/questions/36423059/arm-specific-irq-initialization); you should up vote **the question** if it is useful to you. – artless noise Dec 26 '16 at 15:45
-1

after the boot the ARM processor is in secure SVC mode during this mode you can access CPSR register(first 6 bits) to check in which mode however when the kernel is runing you are in user non-secure mode and in this mode non secure you can't access the the CPSR and SPSR register and also copro 15 register .

The only way is to write a code that generate an exception to switch monitor mode " using SMC assebmbly instruction" to jump to monitor secure mode then in that mode you reset the "NS" bit to switch to non-secure then you generate another exception to switch the SVC mode(SVC instruction assembly call) now you are in supervisor secure mode and you can then access CPSR and SPSR register

dhokar.w
  • 386
  • 3
  • 6