I have to use Neon co-processor of Ti Sitara am335x processor. To enable neon, I have to enable the 30th bit of FPEXC(floating point exceptional register). For that I need to get into the privilaged/system mode.
Some of them suggested to attain this by sending interrupts. How to do that for cortex A8? Could anyone explain me?
Thanks.
You can use interrupts or svc to get into privileged mode, but then your OS code will be running and you would have no control. How do you then propose to enable neon by accessing fpexc?
Your best bet will be recompile your OS with floating point / neon enabled. This will enable the vfp/neon unit at bootup. Also when vfp/neon is enabled ,the task switcher will need to save restore the fpu registers along with general purpose registers.
Related
After a long trip fixing my LEGACY BIOS bootloader to run on QEMU with HAXM enabled, the bootloader successfully do its job and jumps to the kernel, the first thing the kernel does is to enable CPU features. However, when HAXM is enabled, the kernel detects AVX support but xsetbv triggers a vCPU Shutdown. I figured out that XSAVE and OSXSAVE are disabled in CPUID,EAX=1. I tried to check for them by creating a windows program and they seem to be both enabled on the host CPU.
The goal of enabling HAXM was mainly to test and use AVX, PCID, AES, TSC_DEADLINE support and lot of other features present on my CPU, rather than just rebooting my PC each time which takes minutes!
How to enable OSXSAVE, XSAVE on an HAXM host? How to use AVX and other CPU features?
Enabling these extensions on real hardware (the host CPU) seems to work normally.
I am working on a project where I have a router with ARMv7 processor (Cortex A15) and OpenWRT OS. I have a shell on the router and can load kernel modules with insmod.
My goal is to write a kernel module in C which changes the HVBAR register and then executes the hvc instruction to get the processor in the hyp mode.
This is a scientific project where I want to check if I can place my own hypervisor on a running system. But before I start to write my own hypervisor I want to check if and how I can bring the processor in the hyp mode.
According to this picture take from armv7-a manual B.9.3.4 the system must be in insecure mode, not in user mode and the SCR.HCE bit must be set to 1.
My question is how I can prepare the processor with a C kernel module and inline assembly and then execute the hvc instruction. I want to do this with a kernel module because then I start in PL1. This pseudocode describes what I want to achieve:
call smc // to get in monitor mode
set SRC.HCE to 1 // to enable hvc instruction
set SRC.NS to 1 // to set the system to not secure
call hvc #0 // call the hvc instruction to produce a hypervisor exception
The easiest way to elevate privilege is to start off in the needed privilege mode already: You've a root shell. Is the boot chain verified? Could you replace bootloader or kernel, so your code naturally runs in PL2 (HYP) mode? If so, that's probably the easiest way to do it.
If you can't replace the relevant part of the boot chain, the details of writing the rootkit depend a lot on information about your system left out: In which mode is Linux started? Is KVM support enabled and active? Was PL2 initialized? Was it locked? Is there "secure" firmware you can exploit?
The objective is always the same: have HVBAR point at some code you can control and do a hvc. Depending on your environment, solutions may range from spraying as much RAM as possible with your code and hope (perhaps after some reboots) an uninitialized HVBAR would point at an instruction you control to inhibiting KVM from running and accessing the early hypervisor stub to install yourself instead.
Enumerating such exploits is a bit out of scope for a StackOverflow answer; this is rather dissertation material. Indeed, there's a doctoral thesis exactly on this topic:
Strengthening system security on the ARMv7 processor architecture with hypervisor-based security mechanisms
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?
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...
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
I am struggling with which cortex to choose.
Currently I have a design guy that will give me an M0 with memory for initial development but I want to use M0+ eventually.
Assuming I give up the optional features of the M0+ (MPU and MTB), can I transfer the M0 code to the M0+ without any changes?
I mean, is it the same libraries? same build commands? Linker?
What differences should I consider? I know they have the same ISA so I figured it shouldn't be a problem.
Thanks.
If you just consider M0 versus M0+ and not the system peripherals, all code compiled for Cortex-M0 should work on a Cortex-M0+ platform. They use the same instruction set and programmer model.
The main differences are about MPU and MTB, but also the fact that Cortex-M0 has no User-mode support (All code runs in privileged, ie CONTROL.nPRIV cannot be 1).
I am trying to add multiprocessor support for an embedded operating system (DNA-OS) on the Zynq platform in the ZedBoard.
The OS is actually flawlessly functional with CPU_0 alone. The OS architecture requires the implementation of a cpu_send_ipi function in order to activate multiprocessing support: Basically, this function would interrupt a processor and give him a new thread to process.
I looked for an IPI register in the ug585 (Technical Reference Manual for Zynq) but couldn't find any.
I tried digging further in the Cortex-A9 spec for an IPI register, and found out that software generated interrupts could be used as IPI.
After adding software interrupt support to my OS, the problem is that CPU_0 can interrupt itself, but cannot interrupt CPU_1 !
PS: for my OS to handle SGIs, I used the register spec from the ug585 in page 1486:
So is there any other special configuration to permit CPUs to interrupt each others? or any other way to implement IPI ?
Regards,
Your reference documentation is a form of the GIC (global interrupt controller). The Cortex-A9 MP cores include an integrated GIC controller. Each CPU includes an Interrupt interface. As well, there is a system wide distributor. In order to receive the IPI (also known as SGI or software generate interrupt), you need to enable the CPU interface to receive the SGI interrupts on the 2nd CPU. This entails several steps,
Configuring the GIC interrupt interface registers on CPU2.
Setting the CP15 vector table for CPU2.
Enabling the CPSR I-bit on CPU2
Possibly setting up some banked PPI distributor registers. note1
Note1: While most distributor registers are system global, some are banked per CPU as well. For instance, see section 3.3.8. PPI Status Register in the Cortex-A9 MPcore TRM. I don't see any from a cursory investigation, but I would not rule it out.
Testing that an unused SPI (shared peripheral interrupt) works by handling the vector on CPU2 by setting the GIC distributor GICD_ISPEND register on the CPU1. This should verify that you have steps 2 and 3 covered. You may also need to set the type to ensure that they are interrupts and not FIQ; especially if you have security support. You need to use the GICD_ITARGETSR register to include CPU2.
GIC reference list
ARM Generic GIC document - registration needed, GICv1 (ignore GICv2 info).
ARM Cortex-A9 MPcore TRM - chapter 3, for specific info.
PL390 TRM - it is not spelled out anywhere, but I think this is the integrated GIC. It maybe worth looking at if you use more esoteric features.
Especially useful in the Appendix B of the Generic GIC manual. For some reason, ARM likes to keep changing the register names in each and every document they publish.