Modes des CPU ARMv7
Avec l’évolution des systèmes d’exploitation (OS), la nécessité de pouvoir disposer de différents niveaux de privilèges a émergé. En effet, afin d’augmenter la robustesse et la fiabilité des logiciels, il est devenu indispensable de pouvoir contrôler l’accès aux ressources du processeur ainsi que d’isoler le code du noyau de l’OS des applications utilisateur.
Concept
Les processeurs connaissent deux espaces de fonctionnement principaux, l’espace système ou noyau (kernel space), et l’espace application ou utilisateur (user space). Ces deux espaces correspondent à deux niveaux de privilèges, le niveau privilégié et respectivement le niveau non privilégié. L’espace système fonctionne au niveau privilégié, tandis que l’espace application travaille au niveau non privilégié.
Idéalement et avec le support de la MMU/MPU, seul le code du noyau travaille au niveau privilégié. Cela lui accorde un accès illimité à l’ensemble des composants matériels du processeur (CPU, mémoires et contrôleurs de périphériques d’entrées/sorties). Lors du démarrage du système ou après un reset, le processeur entre toujours dans l’espace système afin d’obtenir tous les privilèges et de pouvoir ainsi procéder à l’ensemble des initialisations nécessaires au fonctionnement du système. Si des interruptions ou des exceptions surviennent, le processeur bascule automatiquement dans l’espace système afin d’acquérir le niveau privilégié lui permettant d’accéder aux ressources matérielles et effectuer les traitements adéquats.
Les applications utilisateur, généralement considérées comme des programmes moins fiables que le code du noyau, s’exécutent dans un espace restreint au niveau non privilégié. Si une application a besoin d’accéder à des informations ou des ressources matérielles, elle devra impérativement passer par le noyau avec des appels système (une interruption logicielle). Les appels système ont un certain coût en temps d’exécution, lequel peut dégrader les performances du système et nuire au bon fonctionnement de certains logiciels. Dans de tels cas, il est usuel de déplacer le code du logiciel d’application dans le code du noyau. Il en va généralement ainsi pour les pilotes de périphériques, ceci d’autant plus qu’ils requièrent l’accès aux registres de contrôleurs de périphériques d’entrées/sorties.
Sur les CPU ARMv7, ces deux espaces se décomposent en différents modes de fonctionnement. Leur déclinaison dépend du profil du processeur (A, R ou M), ainsi que des fonctionnalités choisies par le fabricant du µP ou du µC.
Profil M
Les processeurs du profil M sont spécialement conçus pour simplifier le développement de systèmes à basse consommation et de leurs applications. Ces processeurs ne peuvent exécuter que du code Thumb ou Thumb-2.
Modes du processeur
Les processeurs du profil M supportent deux modes, le mode Thread
et le mode
Handler
. Pour exécuter le code principal de l’application ou tâches de fond
(tasks ou threads), le processeur se trouve dans le mode Thread
. Par
contre, à la levée d’une exception ou d’une interruption, le processeur bascule
automatiquement dans le mode Handler
avant de retourner dans le mode Thread
à la fin du traitement de l’événement.
Ces processeurs supportent également deux niveaux de privilèges, le niveau
privilégié et le niveau non privilégié. Lorsque le processeur entre dans le mode
Handler
, il obtient automatiquement le niveau privilégié. Dans le mode
Thread
, l’application peut choisir entre le niveau privilégié et niveau non
privilégié. Avec le niveau privilégié, le processeur donne accès à toutes ses
ressources, tandis qu’avec le niveau non privilégié, en conjonction avec la MPU,
il interdit l’accès à certaines zones de la mémoire et certaines opérations ne
sont plus disponibles.
Lors du démarrage du processeur ou après un reset, le processeur entre
toujours dans le mode Thread
avec le niveau privilégié.
Banque de registres
Les processeurs du profil M n’ont qu’une banque de registres pour les deux modes
du processeur. Seul le pointeur de pile, le registre R13, existe en deux copies,
le MSP
(Main Stack Pointer) et le PSP
(Process Stack Pointer).
Le MSP
ou SP_main
est le pointeur de pile par défaut après le reset du
processeur. Le MSP
est le SP utilisé pour le traitement des événements en mode
Handler
. Le PSP
ou SP_process
est un pointeur de pile à disposition des
codes exécutés en mode Thread
, ceci indépendamment du niveau de privilèges.
L’usage du PSP
devient très intéressant pour des applications multi-tâches
(applications mettant en oeuvre un RTOS). Il permet en effet de limiter la
taille de la pile de chacune des tâches à leurs besoins, indépendamment les unes
des autres.
Les modes Thread
et Handler
utilisent le même registre R14 (LR). Sa
duplication n’est pas nécessaire, car lors de la levée d’une interruption ou
d’une exception, le processeur sauve automatiquement son contenu sur la pile. La
sauvegarde effectuée, il poursuit le traitement de l’événement et l’utilisera
finalement pour retourner au programme interrompu et continuer son exécution,
une fois le traitement de l’événement terminé.
Les registres R0 à R12 sont à usage universel. Cependant, avec le jeu d’instructions Thumb codé sur 16-bit, beaucoup d’instructions ne peuvent utiliser que les registres R0 à R7, les registres bas. Cette limitation tombe avec le jeu d’instructions Thumb-2 codé sur 32 bits.
Les registres spéciaux servent à la gestion de l’état du programme (registre
xPSR
), des masques d’interruptions (registres PRIMASK
, FAULTMASK
et
BASEPRI
) ainsi qu’au contrôle des modes du processeur (registre CONTROL
).
Registre d’état du programme
Le registre d’état du programme PSR se décline en trois sous-registres.
Le registre APSR (Application Program Status Register) contient les fanions de conditions résultant d’opérations effectuées par le processeur.
Le registre IPSR (Interrupt Program Status Register) fournit le numéro
(bits [8:0]) de l’exception ou de l’interruption en cours de traitement dans le
mode Handler
. Le processeur modifie ce registre à l’entrée et à la sortie de
la routine de traitement. Si le processeur se trouve dans le mode Thread
, la
valeur est toujours 0.
Le registre EPSR (Execution Program Status Register) contient les fanions de conditions ainsi que le bit T (bit [24]) le champ superpose indiquant ICI / IT (bits[26:24,15:10]) l’état d’exécution du processeur.
-
Le bit T indique au processeur le jeu d’instructions à exécuter. Il doit impérativement être à mis à 1 pour exécuter du code Thumb/Thumb-2. Lors de branchements indirects, le bit 0 de l’adresse indique au processeur le jeu d’instructions à utiliser, 0 pour ARM et 1 pour Thumb/Thumb-2. Il est dès lors impératif que ce bit soit toujours à 1.
-
Le champ ICI (Interrupt Continue load/store Instruction) fournit une information sur la liste des registres en suspens pour les instructions de transfert multiple, lorsque l’exécution de l’une de ces instructions est stoppée pour traiter une exception ou une interruption. Cette fonctionnalité est une option au choix des fabricants.
-
Le champ IT (IT Instruction) décrit le comportement de l’exécution de l’instruction Thumb
IT
(If-Then).
Les instructions mrs
et msr
donnent un accès en lecture, respectivement en
écriture, à ces registres.
Registres de gestion des masques d’interruptions
Les processeurs du profil M implémentent trois registres spéciaux, le registre
PRIMASK
, le registre FAULTMASK
et le registre BASEPRI
, pour gérer les
interruptions au niveau du CPU.
Le registre PRIMASK, avec le PM
mis à 1, bloque la levée de toutes les
exceptions et interruptions dont le niveau de priorité peut être configuré. Ce
registre correspond à un bit de désactivation globale des interruptions sur
d’autres processeurs. Le bit PM
mis à 0 autorise la levée d’interruptions.
L’instruction “cpsid i
” met le bit à 1 tandis que l’instruction “cpsie i
” le
remet à 0.
Le registre FAULTMASK, avec le FM
mis à 1, bloque, en plus des exceptions
et interruptions pouvant être configurées et les exceptions HardFault
. Le bit
FM
mis à 0 autorise la levée d’interruptions. L’instruction “cpsid f
” met le
bit à 1 tandis que l’instruction “cpsie f
” le remet à 0.
Le registre BASEPRI, avec le champ BASEPRI
(bits [7:0]), définit le niveau
de priorité minimal d’une exception ou d’une interruption, afin que celle-ci
puisse lever une exception. Si la valeur du registre est 0, le filtre n’a aucun
effet. Les instructions msr
et mrs
donnent accès à son contenu.
Registre de contrôle des modes du processeur
La gestion des modes du processeur s’effectue via le registre de contrôle des
modes du processeur, le registre CONTROL
.
-
Le bit mPRIV (bit[0]) définit le niveau de privilège pour l’exécution du code dans le mode
Thread
. Avec un bit mis à 0, le code s’exécute au niveau privilégié. Si le bit est 1, le code s’exécute au niveau non privilégié. -
Le bit SPSEL (bit[1]) définit le pointeur de pile à utiliser pour l’exécution du code en mode
Thread
. Avec un bit mis à 0, le processeur utilise leMSP
. Si le bit est 1, le processeur utilise lePSP
. Si le processeur se trouve dans le modeHandler
, le processeur ne considère pas ce bit et utilise toujours leMSP
. -
Le bit FPCA (bit[2]) indique si l’extension à virgule flottante (FP) est active. Un 0 indique que l’extension FP est inactive. Un 1 indique q’elle est active.
Les instructions msr
et mrs
donnent accès à son contenu. Lors d’une
écriture, le code doit encore utiliser l’instruction isb
afin de garantir
l’effet de l’opération avant l’exécution de la prochaine instruction.