BARON Benjamin
1 Architecture externe du processeur MIPS32 1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Communication avec la mmoire . . . . . . . . . . . . . . . 1.3 Format des instructions . . . . . . . . . . . . . . . . . . . . 1.4 Conventions dutilisation de la pile dexcution . . . . . . . 1.5 Optimisations de GCC . . . . . . . . . . . . . . . . . . . . . 1.6 Organisation gnrale dune chane de compilation GCC
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
3 3 4 5 6 7 8 9 9 10 12 13 13 14 14 16 17 17 19 19 19 20 22 24 24 25 28 30 30 31 35 35 35
2 Bus systme 2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Services oerts par le bus systme . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 A propos des accs mmoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Mmoires caches 3.1 Introduction . . . . . . . . . . . . . . . . . . . 3.2 Comment faire en sorte de minimiser le taux 3.3 Comment exprimer le voisinage ? . . . . . . . 3.4 Comment faire cette partition ? . . . . . . . . 3.5 Le problme des critures . . . . . . . . . . . 3.6 Inuence des caches sur les performances . .
. . . . . . . de MISS ? . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
4 Retour sur EXCEPTIONS / INTERRUPTIONS / TRAPPES 4.1 Appel systme / Trappe . . . . . . . . . . . . . . . . . 4.2 Exception . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Interruptions / communication avec les priphriques 4.4 A propos de lappel au GIET . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
5 Priphriques 5.1 Un priphrique simple : le TIMER . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 Un priphrique BLOCS : IOC (In Out Controller ) . . . . . . . . . . . . . . . . 5.3 Architecture matrielle nale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Fonctionnement multitche 6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Mcanisme de changement de contexte . . . . . . . . . . . . . . . . . . . . . . . . 7 A propos de larchitecture interne des processeurs 7.1 Ralisation monoprogramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Ralisation RISC pipe-line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Chapitre 1
DATA 32 Processeur MIPS 32 Adresse Donnes 0x1001 0000 Instructions 0x0040 0000 0x0000 0000 Mmoire
RESET
3, 4
R/W
Figure 1.1: Schma du processeur MIPS 32 Remarque. Le MIPS est un processeur RISC (Reduced Instruction Set Computer) = CISC (Complex Instruction Set Computer). Les instructions que le processeur manipule comportent 3 registres : 2 registres sources et un registre destination. De ce fait, il faut un mme nombre de cycles pour excuter chaque instruction du jeu dinstruction. Il est donc possible de dbuter une instruction chaque cycle dhorloge (pipeline). Entres / sorties du processeur : ADDRESS sur 32 bits en sortie ; DATA sur 32 bits en entre / sortie ; Read / Write gnralement sur 3 ou 4 bits, en sortie ; IRQ sur 6 bits en entre permet un priphrique de dclencher une interruption ; RESET sur 1 bit en entre permet initialisation (ie. Mettre la machine dans un tat connu). Il existe dirents types de registres. Registres internes visibles du logiciel : 32 registres gnraux sur 32 bits (nots R(i) pour i [0, 31]) ; PC : Program Counter sauvegarde la position de la dernire instruction excute ; HI et LO utiliss pour les oprations arithmtiques + et /.
Registres protgs non accessibles en mode utilisateur, seulement en mode superviseur : SR : Status Register sur 2 bits : Processeur en mode user / root ; Interruptions masques ou non. CR : Cause Register : Interruption matrielle = message dun priphrique un logiciel ; Exception : programme utilisateur fait quelque chose dinterdit programme tu, dnonciation de la cause de lerreur ; Appel systme : appel lOS (eg. Ecriture disque). EPC : Exception Program Counter pour les interruptions matrielles et les exceptions ; BAR : Bad Address Register Erreur dadressage (eg. segmentation fault) ; PROCID : Numro de processeur : identiant du processeur (utile pour les processeurs multi-core) ; CYCLECOUNT : compteur de cycles. Il y a deux modes de fonctionnement du processeur : mode utilisateur ; mode superviseur (mode kernel). Remarque. Le matriel surveille en permanence le logiciel en train de sexcuter. Sil tente daccder une zone protge, le matriel va lever une exception.
Figure 1.2: Communication avec la mmoire Remarque. Lorsque linstruction excute par le processeur cherche lire un mot (ie. un ensemble de 32 bits aligns), ladresse doit tre un multiple de 4 (ie. de la forme 0x00). Dans le cours nous utiliserons la disposition little endian : ladresse la plus petite correspond loctet le plus petit (de poids faible). Ladressage est divis en deux zones : La zone utilisateur (user) ; La zone superviseur (kernel). Remarque. Chaque fois que le logiciel demande au processseur dexcuter une instruction qui accde au segment superviseur, le matriel vrie que le bit de mode du registre STATUS REGISTER (SR) la valeur superviseur.
0xFFFF FFFF BOOT Zone superviseur I/O 0xBFC0 0000 RESERVED 0x9000 0000
0x7FFF FFFF
0x8200 0000 Zone utilisateur 0x8100 0000 0x8000 0000 0x7FFF FFFF .stack 0x2000 0000 0x1FFF FFFF
.data
Zone utilisateur
0x2000 0000 .text 0x1000 0000 0x0040 0000 0x0000 0000 RESERVED Mmoire 0x0000 0000 0x0040 0000 0x003F FFFF
Figure 1.3: Segmentation de la mmoire Segments rservs de la partie superviseur : Code de BOOT : code quexcute la machine lors du dmarrage / reset de la machine. Ce code est situ dans la mmoire ROM (ie. mmoire morte) et constitue le BIOS ; KCODE : code protg du systme dexploitation. Le BIOS lit sur le disque le code du systme dexploitation et le range dans cet espace mmoire (lors du boot de la machine) ; KDATA : donnes globales prives de lOS tables contenant les contextes dexcution des tches en mode multiprocesseur notamment ; UNC : donnes non cachables (ie. les valeurs ne sont pas recopies dans le cache). Ce sont des tampons de communication entre le processeur et les priphriques ; I/O : contrleur des priphriques. Un priphrique peut tre partag par plusieurs utilisateurs dirents. I/O est alors dans la partie superviseur de lespace adressable. Segments rservs de la partie utilisateur : CODE : code du programme utilisateur, ainsi que le code des fonctions permettant un programme utilisateur daccder aux priphriques grce aux appels systmes ; DATA : donnes globales du programme utilisateur ; STACK : pile dexcution du programme. Remarque. Des espaces adressables sont cbls en dur dans le matriel : Le segment BOOT (0xBFC0 0000). Cette adresse cble est commune tous les processeurs ; La sparation mode superviseur (2 Go) / mode utilisateur (2 Go) pour un processeur sans mmoire virtuelle.
Le format I est utilis par les instructions de lecture/criture mmoire (lw et sw), par les instructions utilisant un oprande immdiat (addi, andi. . .), ainsi que par les branchements courte distance (conditionnels) (bne, beq. . .) ; Le format J nest utilis que pour les branchements longue distance (inconditionnels) (jal, j. . .).
31 0 CODOP 6 RS 5 RT 5 RD 5 SH 5 FUNC 6
R I J
CODOP 6
RS 5
RT 5
IMD16 16
CODOP 6
IMD26 26
Figure 1.4: Formats dinstructions du MIPS 32 Dnition (Valeur immdiate). Valeur que linstruction va utiliser comme oprande sans avoir la lire dans un registre ou en mmoire.
na : Arguments de la fonction f -- minimum 4 1 octet $31 x+3 nv : Variables locales x a4 a3 a2 a1 Mmoire na : Arguments de la fonction g -- minimum 4 R(29) dplac R(29) nr : Registres sauvegards
Stack/Pile
On a alors : na = max(nai , 4) o nai reprsente ne nombre darguments des fonctions gi appeles par f ; nv est le nombre de variables locales utilises en C ; nr est le nombre de registres persistants utiliss + $31. Dnition (Registres persistants et registres temporaires). On distingue deux catgories de registres : Les registres persistants : sauvegarder leur tat initial dans la pile avant lexcution dune fonction, puis restaurer ltat initial de ces registres la n de lexcution de la fonction. Registres $16 $23 et $28 $31 ; Les registres temporaires : ne pas sauvegarder dans la pile. Une fonction peut les modier sans en restaurer la valeur initiale. Registres $1 $15 et $24, $25 ; Les registres rservs au systme dexploitation : non utilisables par les applications utilisateur. Registres $0, $26 et $27.
$0 $1 ... $15 $16 ... $23 $24 $25 $26 $27 $28 Registres persistants ... $31 Registres temporaires Registres reservs
Remarque. Utilit de rserver des places dans la pile pour les variables locales (nv) : Ca ne cote pas cher en mmoire : on re-libre la mmoire la n de lexcution de la fonction ; Si il y a des variables locales de tailles importantes (eg. des tableaux), on utilise la mmoire rserve dans la pile pour les stocker temporairement.
Remarque. Si une fonction f a au moins 4 arguments, elle en transmet 4 par registre et rserve leur place dans la pile. Si cette fonction appelle une autre fonction g. De ce fait, f va sauvegarder la valeur des registres $4 $7 leur place approprie dans la pile pour continuer utiliser les valeurs des arguments.
phase optionnelle
gcc
gcc
gcc
.s
.s
.s
as
as
as
.o
.o
.o
ld
chier binaire
.x .o objdump
chier ascii
.s
.x
La compilation spare est possible. Les fonctions dun chier peuvent faire rfrence (via des adresses mmoires) des fonctions issues dautres chiers. Ldition de liens (ld) rsout les adresses : assigner des valeurs binaires aux valeurs symboliques des adresses (labels). Les valeurs non rsolues dans les chiers binaires sont stockes dans des tables de symboles. On remplace alors les adresses non rsolues la n de la chaine de compilation. Les dirents modules logiciels qui vont tre excuts nentrent pas forcment dans la chane de compilation au niveau du chier *.c. On a la possibilit de compiler la fois des chiers *.h/*.c et *.s. Comment contrler cette chane de compilation ? Via ldition de liens principalement : donner au programme dditeur de liens des consignes dexcution : Chaque chier objet (*.o) contient une ou plusieurs section (eg. section .data, .text dans un chier assembleur). On peut guider le linker pour quil regroupe une ou plusieurs section dans un segment (KCODE, KDATA, DATA, CODE. . .) de lespace adressable. Exemple. Regrouper le contenu de la section .text des dirents chiers objets (*.o) dans le segment CODE de lespace adressable. On peut dnir les adresses de base des dirents segments cibles.
Chapitre 2
Bus systme
2.1 Introduction
Le programme sexcutant sur le processeur peut accder dirents services via le bus systme. Ce dernier permet la communication du processeur avec le monde extrieur.
COMMANDES REPONSES
Disque
PROC
Contrleur I/O
BUS SYSTEME
Mmoire RAM
Mmoire ROM
Contrleur TTY
Ecran / Clavier
Figure 2.1: Reprsentation de la machine dans son ensemble Dnition (Transaction). Echange dinformations en utilisant le bus systme. Il sagit dune criture (sw), ou dune lecture (lw) une certaine adresse. Toujours une paire : Une commande ; Une rponse. Remarque. Il existe une rponse mme dans le cas dune commande criture. Le processeur peut commander une criture vers autre chose quune mmoire. Il peut excuter cet ordre sur un priphrique. Dnition (Matre / Initiateur). Composant matriel capable de dmarrer une transaction (ie. envoyer une commande). Dnition (Esclave / Cible). Composant matriel capable de recevoir une commande et dy rpondre.
Remarque. Attention : un mme composant matriel peut tre la fois matre et esclave. Par exemple : le contrleur de disque : Disque Mmoire RAM. Il a besoin dadresser la mmoire pour lire / crire dans celle-ci.
I/O
I/O
GRANT 0
GRANT 1
BCU
Bus Controller Unit
COMMANDES REPONSES
Bus systme
RAM
ROM
TTY
10
Segmentation de lespace adressable (ensemble de 4 milliards dadresses). Un segment est compos dune adresse de base et dune longueur.
0xFFFF FFFF BOOT BOOT TTY I/O 0xBFC0 0000 0x9000 0000 Zone superviseur
TTY
I/O
Dsigne un segment dans l'espace adressable 0x8000 0000 0x7FFF FFFF Dsigne un octet particulier dans le segment dni par les MSB 31 MSB Zone utilisateur
Most Signicant Bit
0 LSB
Less Signicant Bit
RAM
8 bits
14 bits
Figure 2.3: La segmentation de lespace adressable Toutes les adresses sont alignes sur les frontires de mots de 32 bits. Ce sont donc des multiples de 4. Dans le cas du segment de lespace adressable associ au contrleur TTY, lencombrement est de 4 4 octets.
@ + 0x0 @ + 0x4 @ + 0x8 @ + 0xC TTY_WRITE TTY_READ TTY_STATUS TTY_CONFIG sb Valeur du code ASCII du caractre que l'on veut afcher lb Valeur du code ASCII du caractre tap au clavier lb Sur un bit : reg. READ plein, ou reg. WRITE est vide Conguraion du priphrique
Figure 2.4: Le segment associ au contrleur TTY (0x9000 0000) Remarque. Il y a autant de segments TTY dans lespace adressable quil ny a de priphriques TTY. Par exemple, si y a 3 priphriques TTY, il y aura alors 3 segments TTY correspondant 12 registres utiliss (soit un encombrement de 3 12 = 48 octets). Le programme utilisateur doit utiliser des appels systmes pour accder au TTY puisque le segment TTY se trouve dans la zone kernel (superviseur) de lespace adressable. Puisque le contrle des priphriques est exclusivement gr par lOS, il faut imprativement passer par lui au travers dun appel systme (syscall)
Transmission de la rponse
Le bus systme va se charger de transmettre la rponse du priphrique cible vers le priphrique matre qui a initi la transaction.
11
12
Chapitre 3
Mmoires caches
DISK
PROC 0
Contrleur de cache CI CD
PROC 1 IOC
Contrleur de cache CI CD
32
BCU
Bus Controller Unit
COMMANDES REPONSES
Contrleur de RAM
ROM
TTY
RAM
3.1 Introduction
Dnition (Cycle). Priode entre deux fronts montants du signal priodique envoy (eg. un processeur 25 MHz aura un cycle de 1/25 000 000 seconde). Le signal est distribu tous les composants matriels mme rfrence de temps entre tous ces composants. Objectif. Eviter au processeur de passer par le bus et le BCU pour accder la mmoire RAM. Les mmoires caches doivent tre trs rapide pour rpondre aux requtes de lecture. Le temps de cycle du cache doit tre gal au temps de cycle du processeur (ie. le cache doit rpondre en 1 cycle) ; Cependant la capacit stockage du cache est trs faible. Caches de premier niveau : Cache dinstruction (CI) : mmoire spcique contenant des instructions ; Cache de donnes (CD) : mmoire spcique contenant des donnes. Il existe donc deux types de mmoire : La mmoire dynamique DRAM qui a une grande capacit de stockage Laccs celle-ci est lent (au moins 100 fois plus lent que le cycle du processeur). 1 bit 1 transistor
13
Mmoire statique SDRAM : trs rapide (cale sur le cycle du processeur). Il y a cependant une faible capacit de stockage. 1 bit 6 transistors Une mmoire cache contient des copies des informations prsentes dans la mmoire principale : CI : copie dextraits du segment .code de la mmoire DRAM ; CD : copie dextraits du segment .data et .stack de la mmoire principale.
La localit spatiale
Si le processeur met une requte ladresse x, les requtes suivantes ont une forte probabilit de voir des adresses proches de x (eg. PC, PC+4, PC+8, . . .). Les lments concerns sont : Les instructions sont ranges des adresses voisines ; Les tableaux donnes ranges des adresses conscutives.
La localit temporelle
Si le processeur met une requte ladresse x au cycle n, il arrive trs souvent quune autre requte soit eectue le mme adresse x, au cours des cycles suivant le cycle n. Les lments concerns sont : Les programmes contiennent des boucles (cache dinstructions) ; Les programmes contiennent des compteurs (cache de donnes).
14
0xFFFF FFFF
Espace adressable
31
16 octets = 4 mots
Identiant de la ligne de cache (ie. 28 bits) actuellement prsent dans la case correspondante du cache
Rpertoire Une tranche de l'espace dont la longueur est une puissance de 2 de 8 64 octets 1 octet / 8 bits
Donnes
0x0000 0000
Figure 3.2: Caches correspondance directe En cas de MISS, sur une requte ladresse x, le contrleur de cache va ramener dans le cache une ligne complte contenant ladresse x. Utilisation de la localit spatiale. Pour exploiter la localit temporelle, le contrleur de cache conserve dans le cache le plus longtemps possible les informations rcupres dans la mmoire. Stratgie 1 Cache associatif (associative) Nimporte quelle ligne peut tre range dans nimporte quelle case Les huit cases sont quivalentes entre elles. Le processeur cherche savoir si la ligne est dans le cache regarder dans chaque case si elle est prsente (squentiellement) : il y a nb_cases comparaisons. Stratgie 2 Cache correspondance directe (direct mapping) Une ligne de cache ne peut tre range que dans une seule case. Les cases ne sont plus quivalentes entre elles. Toutes les lignes de cache dune mme famille sont en comptition pour la mme case. Retrouver une ligne de cache partir de son adresse est beaucoup plus rapide car on accde directement la seule case possible.
15
Figure 3.3: Cache correspondance directe Si deux lignes voisines sont dans la mme famille, elles seraient en comptition pour la mme case de cache Le principe de localit nest pas respect.
INDEX TAG 31 0 OFFSET
3 bits
4 bits
Figure 3.4: Adresse dans le cache Les champs de ladresse : OFFSET numro de mot dans la case du cache : log2 (taille ligne) ; INDEX numro de la famille numro de case de cache : log2 (taille cache/taille ligne) ; TAG numro identiant une ligne de cache dans la famille : 32 (OFFSET + INDEX).
31 TAG 4 3 2 1 0
INDEX OFFSET
TAG
VALID
INSTRUCTION 1
INSTRUCTION 0
I1 I3 I5 I7
=
AND
I0 I2 I4 I6 MUX
00 01 10 11
HIT
Instruction
16
P0 C0
P1 C1
x
COMMANDES REPONSES
MEMOIRE
Figure 3.6: Ecriture dans la mmoire WRITE-THROUGH Une criture est eectue immdiatement vers la mmoire (avec mise jour de la copie locale. . .si elle existe). WRITE-BACK Une criture est eectue dans le cache local, et la mmoire nest pas mise jour plus tard, que en cas dvincement. Contradictions Quand le processeur fait un sw, cette instruction nest pas bloquante ; Quand le contrleur de cache fait une criture, il attend un acquittement. Le contrleur de cache contient un tampon dcritures postes (le FIFO du cache de donnes Write Buer) Remarque. Lutilit de cette le dattente matrielle est double : Le processeur nest pas bloqu ; On peut esprer fabriquer des rafales dcriture, et donc optimiser lutilisation du bus.
17
Chaque tape require un cycle dhorloge et une instruction va suivre squentiellement chaque tape. Dans une architecture sans pipeline, une nouvelle instruction est rcupre (IF) dans la premire tape seulement une fois que linstruction prcdente ait ni ltape 5 (WB). Dans une architecture avec pipeline, le CPI peut tre amlior en utilisant linstruction level parallelism (ILP). Ainsi, une nouvelle instruction est rcupre (IF) chaque cycle. Dans le cas o il y aurait 5 instructions dans 5 tapes de pipeline direntes (une instruction par tape), une instruction dirente complterait ltape 5 (WB) pour chaque cycle dhorloge. De ce fait, le CPI est gal 1 pour ce processeur. Dnition (IPC Instruction Per Cycle). Le CPI est linverse de lIPC (Instruction Per Cycle) gal au nombre moyen dinstructions excutes par cycle dhorloge. Dnition (IPS Instruction Per Second). Le nombre dinstructions par seconde IPS (Instruction Per Second) est gal : CP I clock_speed o clock_speed est la frquence du processeur considr calcule en Hertz (Hz) ou en cycles par seconde.
CPI = 1
IF I0
DC IF
EX DC IF
MD EX DC IF
WB
CPI = 1
MD EX DC IF
WB MD EX DC IF WB MD EX DC WB MD EX WB MD WB
I1 I2 I3 I4 I5
18
Chapitre 4
4.2 Exception
Excution (par un programme utilisateur) dune instruction illgale : ADEL lecture illgale OVF overow arithmtique ADES criture illgale RI codop indni ! DBE Bus erreur donnes CPU tentative dexcution mfc0 ou mtc0 IBE Bus erreur instruction Le gestionnaire dexceptions doit dterminer le type de lexception et acher un message permettant au programmeur de localiser et de corriger lerreur. Remarque. Les codes du type dexception sont crits par le matriel dans le registre CR Ladresse de linstruction fautive est crite dans EPC BAR adresse fautive SR Mode Kernel (UM = 0) IT (interruption) masques (IE = 0) PC 0x80000180 : point dentre dans le systme.
19
4.3.1
PROC
IRQ-OUT
ICU
IRQ-IN 0 IRQ-IN 2
TTY
IRQ-IN 1
BCU
TIMER
RAM
IOC
Disque
Figure 4.1: Gestion des interruptions (IRQ) Le systme dexploitation gre donc les mcanismes de contrle. Il existe deux types de communications entre le systme dexploitation et les priphriques : Accs en conguration (opration dcriture sur des registres du priphrique) ou accs en consultation (opration de lecture) ; Initiatives venant du priphrique pour signaler des vnements lOS (interruptions). Communication entre deux processus : suivant le modle producteur / consommateur. Ide. Le priphrique et lOS communiquent travers un tampon mmoire partag ou plusieurs. Dans le cas du TTY, il est ncessaire davoir deux tampons : Un tampon DATA (TTY_WRITE) qui contient le caractre tap au clavier 1 octet en mmoire correspondant la taille mmoire dun caractre ASCII ; Un tampon FULL (TTY_STATUS) contenant un boolen (1 bit) qui indique ltat du tampon DATA : Producteur : FULL 1 si tampon DATA rempli ; Consommateur : FULL 0 si tampon DATA lu et vid. Dnition (IRQ Interrupt Request). Une interruption (IRQ) provient dun contrleur / priphrique et arrive dans lICU (Interrupt Controllor Unit). LIRQ demande alors au processeur dexcuter lISR (Interrupt Service Routine) correspondante. Dnition (ISR Interrupt Service Routine). Un priphrique (TTY, Timer, . . .) souhaite eectuer une criture en mmoire, active une interruption qui va forcer le processeur excuter quelques dizaines / centaines dinstructions. Ce code sappelle ISR (Interrupt Service Routine).
20
Activation : il y a une ISR dirente pour chaque priphrique. Instructions de lISR : Ecrit dans le registre de communication et de synchronisation ; Ecrit dans le registre du priphrique permettant dacquitter la requte dinterruption. Dnition (ICU Interrupt Controller Unit). Ce contrleur comporte (dans le cadre du cours) 32 lignes dinterruption en concurrence pour voler des cycles au processeur. Le composant ICU est un concentrateur dinterruptions permettant de multiplexer 32 interruptions IRQ-IN vers une interruption IRQ-OUT.
4.3.2
Organisation gnrale du GIET Lors dun appel systme, dune interruption, dune exception, il y a un branchement ladresse 0x80000180 point dentre du GIET (Gestionnaire dInterruptions, Exceptions et Trappes).
GIET 0x80000180 Dpend du contenu du registre CR (Cause Register) Gestionnaire d'appels systme Gestionnaire d'exceptions Gestionnaire d'interruptions
ISR_IOC
ISR_TIMER
ISR_TTY
Figure 4.2: Organisation du GIET Les interruptions sont vectorises. Dnition (Vecteur dinterruptions). Un tableau en mmoire dont chaque entre est une adresse dune ISR. Cest donc un tableau dadresse o chaque adresse correspond un point dentre dune fonction du GIET. Remarque. Un tableau dadresse table de sauts vecteur dinterruptions Le gestionnaire dinterruptions dtermine lindex (index compris entre 0 et 31) vers lequel il va se brancher. Pour obtenir lindex en question, le gestionnaire dinterruptions interroge le composant ICU en eectuant une lecture dans son registre INDEX. Conit : si plusieurs IRQ-IN sont actives en mme temps, lICU renvoie lindex le plus petit. Remarque. ICU (Interrupt Controller Unit) PIC (Programmable Interrupt Controller) Registres de lICU : ICU_MASK : chaque bit reprsente la gestion dune interruption des 32 interruptions possibles : ICU_MASK[i] = 0 : pas dinterruption sur lentre i (interruption masque) ; ICU_MASK[i] = 1 : interruption autorise sur lentre i. Les interruptions ont par dfaut une priorit croissante (ie. linterruption de lentre 1 sera traite avant celle de lentre 2). ICU_INDEX : numro de linterruption la plus prioritaire active (registre cod sur 5 bit 25 = 32). Rsum sur les services rendus par lICU : 1. OU logique entre toutes les entres IRQ-IN(i) ;
21
ICU_INDEX
4 3 2 1 0 ICU_MASK
0
AND AND
IRQ-OUT
OR
AND
IRQ-IN[31]
Figure 4.3: ICU (Interrupt Controller Unit) 2. Encodeur de priorit ; 3. Masque slectif M[i] des 32 IRQ-IN[i] (ce masque tient sur un mot de 32 bits). Ide. On augmente la complexit du matriel en ayant plusieurs IRQ-OUT. Si on rplique 8 fois le matriel de lICU, on aura les 32 mmes entres IRQ-IN, et 8 sorties IRQ-OUT. On va avoir 8 IR-OUT[j] et on peut donc router chaque IRQ-IN[i] vers nimporte quelle sortie IRQ-OUT[j]. Do PIC : Programmable Interrupt Controller Remarque. LOS doit congurer les registres de masque de lICU et doit initialiser le vecteur dinterruptions (gnralement dans le code de BOOT). Le code des ISR ne fait pas partie de lOS, mais il sexcute en gnral en mode superviseur.
0x8000 0000
Lorsque le processeur se branche la premire instruction du GIET, les interruptions sont automatiquement masques par le matriel : Si la cause du branchement est une exception, il y a alors un traitement prioritaire de lexception et on ne souhaite pas tre interrompu ; Si la cause du branchement est une interruption, il faut pouvoir excuter le code du GIET sans reboucler sur cette adresse. En eet, chaque cycle, le processeur examine le contenu du registre IRQ_INDEX ; Si la cause du branchement est un appel systme, alors le GIET doit dcider lui-mme dtre interrompu ou non.
22
4.4.1
SIM
Hardware interruption masks Software interruption masks User mode = 1 Kernel mode = 0
Figure 4.4: SR (Status Register) Le processeur a le droit daccder aux ressources protges (registres du CP0, et adresses mmoires suprieures 0x7FFFFFFF) si et seulement si le bit UM vaut 0, ou si lun des deux bits ERL et EXL vaut 1 ; Les interruptions sont autorises si et seulement si le bit IE vaut 1, et si les deux bits ERL et EXL valent 00, et si le bit correspondant de IM vaut 1 ; Les trois types dvnements qui dclenchent le branchement au GIET (interruptions, exceptions et appels systme) forcent le bit EXL 1, ce qui masque les interruptions et autorise laccs aux ressources protges ; Lactivation du signal RESET qui force le branchement au Boot-Loader force le bit ERL 1, ce qui masque les interruptions et autorise laccs aux ressources protges ; Linstruction eret force le bit EXL 0. Lors de lactivation du RESET, SR contient donc la valeur 0x0004. Pour excuter un programme utilisateur en mode protg, avec interruptions actives, il doit contenir la valeur 0xFF11. Le code de boot doit crire la valeur 0xFF13 dans SR et ladresse du programme utilisateur dans EPC avant dappeler linstruction eret.
4.4.2
SWI
Figure 4.5: CR (Cause Register) Le registre CR contient trois champs. Les 4 bits du champs XCODE(3 :0) dnissent la cause de lappel au GIET. Les 6 bits du champs IRQ(5 :0) reprsentent ltat des lignes dinterruption externes au moment de lappel au GIET. Les 2 bits SWI(1 :0) reprsentent les requtes dinterruption logicielle.
23
Chapitre 5
Priphriques
Le pilote de priphrique contient deux parties : Un code de conguration : permet au logiciel (OS) de lire / crire dans les registres internes au priphrique. A linitiative de lOS. Ce code se trouve dans le chier drivers.c ; Le(s) code(s) de(s) ISR (Interrupt Service Routine) permettant au priphrique de communiquer avec lOS. A linitiative du priphrique. Ce code se trouve dans le chier isr.s.
TIMER 1
Dcompteur TIMER_VALUE TIMER_MODE TIMER_PERIOD TIMER_RESETIRQ
PROC
CYCLE_COUNT
IRQ
ICU
Interrupt Controller Unit
TIMER 0
Dcompteur
TTY
Contrleur de cache CI CD
32
BCU
Bus Controller Unit
COMMANDES REPONSES
Cache L2 IOC
In Out Controller
DISK
Mmoire
Figure 5.1: Quelques priphriques Les priphriques sont de deux sortes : Priphrique simple : pouvant recevoir des commandes de lecture / critures, mais ne peuvent pas eux-mmes lire ou crire dans lespace adressable (eg. TIMER, ICU, contrleur TTY. . .) ; Priphriques DMA (Direct Memory Access) : a le droit de lire / crire deux-mme dans lespace adressable.
24
Les registres adressables du TIMER : Registre TIMER_VALUE (Base) : compteur de cycles ; Registre TIMER_MODE (Base + 4) : conguration contient un CODOP crit par le logiciel sur 2 bits : incrmenter (1 bit) ; masquer des interruptions (1 bit). Registre TIMER_PERIOD (Base + 8) : Valeur de la priode o lOS lve des interruptions (gnralement gale 100 000 ou 1 000 000) ; Registre RESETIRQ (Base + 12) : acquittement n du traitement de linterruption. Le registre cach DECOMPTEUR du TIMER nest pas adressable. Cest un dcompteur priodique se basant sur la priode dnie par lOS dans le registre TIMER_PERIOD interne au TIMER.
0xFFFF FFFF
Espace adressable
Timer 1
Base + 12 Base + 8 Base + 4 Base TIMER_RESETIRQ TIMER_PERIOD TIMER_MODE TIMER_VALUE
Timer 0
0x8000 0000
0x0000 0000
Le priphrique TIMER peut contenir plusieurs timers : chaque timer individuel contient les 5 registres physiques et Figure 5.2: Les registres adressables des timers correspond 4 registres adressables dans lespace adressable.
4 octet / 32 bits
Figure 5.3: Disque dur Hirarchie de stockage Espace de stockage 32 registres gnraux Caches L1 Cache L2 Mmoire externe (RAM, ROM) Disque Taille 32 4 = 128 octets 4 Ko 4 Mo 2 Go 200 Go Temps daccs < 1 cycle 1 cycle 20 cycles 400 cycles 100 000 1 000 000 cycles
Dnition (Bloc). On appelle bloc un ensemble doctets (varie entre 512 octets et 4096 octets) qui vont tre rangs des adresses conscutives en mmoire.
25
Dnition (Secteur). Lemplacement sur le disque permettant de stocker un bloc sappelle un secteur. La taille typique dun secteur est de 512 octet. Pour dsigner un bloc dans lespace disque, le logiciel utilise un numro de bloc. Pour dsigner un bloc transfrer, il faut deux instructions : Nom de chier chemin / nom ; Un numro de bloc dans un chier. Transfrer un (ou plusieurs) blocs depuis le disque vers la mmoire : Nom de chier : appel systme ioc_read() renvoie un descripteur de chier (FILE *) ; Dsigner le premier bloc et le nombre de blocs transfrer ; Dsigner ladresse de base du tampon mmoire cible. Deux appels systmes du GIET :
int ioc_read(size_t lba, void * buffer, size_t count); int ioc_write(size_t lba, void * buffer, size_t count);
Signication des paramtres : lba : numro du premier bloc sur le disque (Logical Block Address) ; buffer : adresse de base du tampon en mmoire ; count : nombre de blocs. On utilise des appels systmes pour accder au disque : Le systme doit vrier que le programme utilisateur a le droit de lire / crire des donnes sur le disque et donc de pouvoir faire laccs en question ; Le systme doit vrier que ladresse de destination appartient bien lespace de lutilisateur (ie. infrieure 0x8000 0000) ; Le disque dur est un systme mcanique, donc est trs lent. Le systme va optimiser la position de la tte de lecture sur le disque en utilisant une le FIFO des requtes de demande daccs au disque ; Le systme va descheduler (dsordonnancer, mettre en attente) le programme qui demande un accs au disque. Au lieu de lattente active, le systme va mettre le processus en attente ; Si lon veut faire un second transfert la mme adresse, il faut alors invalider les lignes de cache an de pouvoir charger les donnes souhaites avec la fonction _dcache_buf_invalidate. Remarque. Les fonctions ioc_read et ioc_write ne sont pas bloquantes : elles rendent gnralement la main au programme utilisateur bien avant que lIOC ait termin le transfert paralllisme. Entretemps, lIOC aura eectu le transfert demand. La fonction ioc_read() du segment CODE fait appel la fonction _ioc_read() du segment KCODE. La fonction _ioc_read() vrie que le priphrique nest pas dj utilise en testant la valeur du registre IOC_BUSY dans une boucle de polling (scrutation) ioc_completed(). Lorsque lon sort de cette boucle (ie. IOC_BUSY = 0), on peut utiliser le priphrique (IOC_BUSY = 1). LIOC active alors une interruption lorsque le transfert est termin. Remarque. On considrera quil ny a pas de systme de chiers : le disque ne contient qun seul chier qui est le chier de la station de travail LINUX. Dnition (Driver de priphrique). Logiciel permettant de contrler un priphrique. Le contrleur IOC contient au moins 5 registres adressables : Adresse mmoire IOC_BUFFER ; Nombre de blocs transfrer IOC_COUNT ; Adresse logique (numro) du premier bloc IOC_LBA ;
26
Type du transfert eectuer (read / write) IOC_TYPE ; Acquittement de linterruption IOC_BUSY (non cach). Lexcution de lISR associe au contrleur IOC doit informer lOS que le transfert est termin. LISR crit alors dans une case mmoire IOC_BUSY appartenant lOS dans le segment KUNC (donnes non cachables du kernel). Pendant un transfert, il existe deux processus sexcutant en parallle Besoin de synchronisation : Le processus IOC est propritaire de la variable IOC_BUSY lorsquelle vaut 1. LOS ne peut alors pas modier cette variable et doit attendre sil doit lancer un transfert. LOS est propritaire de cette variable lorsquelle vaut 0, et peut alors lancer un transfert.
OS
SET
RESET IOC_BUSY
IOC
Figure 5.4: Synchronisation entre IOC et OS Remarque. Ce mcanisme est un mcanisme de synchronisation par variable SET / RESET. Ce mcanisme est identique celui utilis pour le TTY avec le registre TTY_STATUS. Le contrleur de disque IOC prsent ici ne peut excuter quun seul transfert entre la mmoire et le disque la fois. Pour viter de rendre bloquant (ie. lappel systme entre dans une boucle dattente active ioc_completed o lattente peut tre longue) les appels systmes ioc_read et ioc_write , lOS peut stocker les paramtres de la commande dans une le dattente en mmoire. Pour ce faire, il rserve des paquets de 16 octets dans lespace adressable o chaque paquet reprsente une commande en attente. Objectif. Eviter au processeur de gcher des cycles en faisant de lattente active. Dans les contrleurs IOC les plus rcents, la le dattente des commandes de transfert est une structure de donnes (le de type FIFO) partage entre lOS et lIOC (variable de synchronisation ncessaire).
0xFFFF FFFF
Espace adressable
16 octets = 1 commande
27
PROC
REQ GNT
CYCLE_COUNT
I, T
IRQ
TIMER T
Dcompteur TIMER_VALUE TIMER_MODE TIMER_PERIOD TIMER_RESETIRQ
ICU
IRQ
ICU_MASK ICU_INDEX
TTY
TTY_WRITE TTY_READ TTY_STATUS TTY_CONFIG
ROM
Contrleur de cache CI CD
IRQ
BCU
Bus Controller Unit
32
COMMANDES REPONSES
Cache L2
DMA I, T
Direct Access Memory
DMA_BUFFER_IN DMA_BUFFER_OUT DMA_COUNT
Frame T Buffer
Buffer
IOC
In Out Controller
IOC_BUFFER IOC_COUNT IOC_LBA IOC_TYPE IOC_BUSY
I, T
DISK
Mmoire
5.3.1
Le composant DMA est utilis pour dplacer des donnes, dun tampon mmoire source vers un tampon mmoire destination. Cest un matre sur le bus puisquil est capable de lire et dcrire nimporte quelle adresse dans lespace adressable du systme. Cest galement une cible, puisquil contient un (petit) nombre de registres adressables dans lesquels le systme dexploitation peut crire, pour dnir les caractristiques du transfert eectuer (adresse du tampon source, adresse du tampon destination, nombre doctets transfrer). Une fois congur, ce composant travaille en parallle avec le processeur, et signale la n du transfert en activant une ligne dinterruption spcique. Le composant DMA contient alors 3 registres adressables : Adresse tampon source DMA_BUFFER_IN ; Adresse tampon destination DMA_BUFFER_OUT ; Nombre doctets transfrer DMA_COUNT.
5.3.2
Le composant Block I/O est un contrleur de disque. Il est utilis pour transfrer des donnes entre un tampon mmoire et un chier situ sur un composant de stockage externe tel quun disque magntique. Tous les transferts se font par blocs de 512 octets (appels secteurs dans le cas des disques).
28
Le contrleur de disque est aussi un matre sur le bus puisquil capable de lire et dcrire en mmoire nimporte quelle adresse dans lespace adressable. Cest galement une cible, puisquil contient un (petit) nombre de registres adressables dans lesquels le systme dexploitation peut crire, pour dnir le transfert eectuer (adresse du tampon en mmoire, dsignation du premier bloc dans le chier, nombre de blocs transfrer). Une fois congur, ce composant travaille en parallle avec le processeur, et signale la n du transfert en activant sa propre ligne dinterruption.
5.3.3
Frame Buer
Le composant Frame Buer est un contrleur vido permettant dacher des images sur un cran graphique. Ce composant contient une mmoire vido permettant de stocker une image de dimension prdnie. On sintressera des images en niveaux de gris . Chaque pixel est cod sur un octet. Il y a donc 256 niveaux de gris, et la valeur 0 correspond un pixel noir. Pour avoir des temps dexcution raisonnables, on se limite des images de 128 lignes de 128 pixels. Dans un PC, la capacit de la mmoire vido atteint couramment 4 Moctets (1024 lignes de 1024 bits, chaque pixel tant cod sur 4 octets pour lachage couleur. Cette mmoire vido est parcourue une frquence xe (typiquement 25 fois par seconde) de faon gnrer le signal vido qui est envoy vers le terminal graphique. Cette mmoire vido (ou frame buer ) est gnralement implante dans la partie de lespace adressable rserve au systme dexploitation. Le Frame Buer est un composant cible sur le bus. Il ne possde pas de registres adressables.
/* Fonctions bloquantes */ int fb_sync_write(size_t offset, void* buffer, size_t length); int fb_sync_read(size_t offset, void* buffer, size_t length);
Ces deux fonctions eectuent le transfert de faon purement logicielle : chaque octet du tampon source est charg par le processeur dans un registre interne, puis crit par le processeur dans le tampon destination. Ces fonctions sont bloquantes et ne rendent la main que lorsque le transfert est termin transfert est synchrone. Cette technique est simple, mais elle est lente.
/* Fonctions non bloqantes */ int fb_write(size_t offset, void* buffer, size_t length); int fb_read(size_t offset, void* buffer, size_t length); int fb_completed();
Les deux fonctions fb_write() et fb_read() utilisent le composant matriel DMA pour acclrer le transfert. Le mcanisme est trs similaire celui utilis par le contrleur I/O. Ces deux fonctions sont non bloquantes. Elles congurent le contrleur DMA pour que celui-ci eectue le transfert et rendent immdiatement la main au programme utilisateur. Plus tard, le contrleur DMA active une interruption pour signaler la n du transfert. Comme dans le cas du contrleur I/O, la fonction fb_completed() est une fonction bloquante qui ne rend la main que lorsque le transfert est termin. On utilise des appels systme car il faut invalider les lignes de cache avec la fonction _dcache_buf_invalidate problme si lon veut acher une nouvelle image. De plus, il faut vrier si le programme est en droit de faire lachage (ie. adresse < 0x8000 0000).
29
Chapitre 6
Fonctionnement multitche
6.1 Introduction
Remarque. Multitche = multiprocesseur : Multitche : utilisation de la machine comme si plusieurs programmes sexcutaient en mme temps ; Multiprocesseur : (au niveau du matriel) une machine peut contenir plusieurs processeurs fonctionnant en parallle. Dnition (Paralllisme). On parle de paralllisme mul lorsque lon excute plusieurs programmes utilisateurs simultanment sur un seul processeur. On dcoupe le temps en tranches de dure xe (quantum). Arbitrairement : 1 tanche = 10 ms = 10 millions de cycles (1 cycle = 109 s).
T0
T1
T2
T0
T1
T2
T0
Figure 6.1: Tranches de temps Dans lexemple ci-dessus, chaque tche aura excut 33 tranches. Chaque programme va sexcuter 3 fois moins vite que sil avait t seul. Cest du pseudo-paralllisme par multiplexage temporel. Les vnements priodiques de changement de contexte (le processeur travaille pour la tche T0 et passe la tche T1) sont gnrs par un TIMER TICK. Le terme TICK dsigne au choix : Linterruption qui dclenche un changement de contexte ; La priodicit de lvnement dclencheur dun changement de contexte. Dnition (Contexte). Ensemble des informations qui doivent tre sauvegardes pour permettre une tche sortante de recommencer sexcuter lorsque ce sera son tour de rentrer (ie. devenir une tche entrante). Sauvegarde des registres : Tous les registres gnraux R(i) sauf R(0), R(26) et R(27) (registres rservs au systme) ; EPC (PC sauvegard dans EPC), STATUS REGISTER (SR), CAUSE REGISTER (CR), HI, LO. Remarque. Ce systme de sauvegarde des registres est similaire celui de la sauvegarde du contexte dexcution dune fonction. Chaque tche ayant sa propre pile, il sut de sauvegarder le pointeur de pile R(29).
30
Espace adressable
LOS a besoin de stocker en mmoire les contextes dexcution des N tches en cours dexcution (1 contexte = 32-3+5 = 34 registres de 32 bits). LOS possde donc un tableau de contextes o chaque case de ce tableau a une capacit de 256 octets. LOS a besoin dune case mmoire permettant de stocker le numro du programme utilisateur en cours dexcution.
Tche A n
Contexte de B
Figure 6.2: Changement de contexte Au moment du TICK (ie. le TIMER gnre une IRQ) : Point dentre du GIET (0x8000 0180) ; Le registre CR contient le code dune interruption : branchement la fonction _int_handler ; Le registre ICU_INDEX contient le numro de lentre dinterruption IRQ_IN associe au TIMER ; Excution de lISR associe au TIMER _isr_switch ; Branchement la fonction _ctx_switch ; Remarque. Les tches sont lues suivant lalgorithme Round Robin qui assigne des portions de temps gales pour chaque tche et excute toutes les tches sans priorit, dans un ordre cyclique. Remarque. Dans le GIET, on ne peut pas crer dynamiquement des tches ; la cration de tches est ralise statiquement dans la phase de BOOT. Phase de BOOT : Initialisation des registres (pile, SR) ; Initialisation des priphriques ; Initialisation de la tche principale ; Initialisation des tableaux de contexte des autres tches qui dmarrent au TICK. Dnition (Virtualisation). Donner limpression lutilisateur quil y a plus de ressources que rellement. Le fonctionnement multitche consiste utiliser un seul processeur physique (matriel) comme n processeurs virtuels.
31
Pour permettre plusieurs applications de sexcuter en pseudo-paralllisme, il faut : Partager le processeur (ie. virtualiser le processeur) ; Partager la mmoire. La mmoire virtuelle consiste donner chaque application limpression quelle dispose de la totalit de lespace adressable. Ce mcanisme permet de compiler chaque application comme si elle sexcutait seule sur la machine. Dnition (Adresse logique vs. adresse physique). Les adresses logiques (virtuelles) sont les adresses calcules par le compilateur (lors de ldition de liens) que lon retrouve dans le code binaire (chier excutable). Ce sont les adresses qui sont mises par le processeur. Une adresse physique permet de rfrencer, manipuler de la mmoire physique. Les adresses logiques sont alors traduites en adresses physiques (relles) au moment de sortir du processeur : entre le processeur et le cache dans le MMU (Memory Management Unit).
Programme A
Programme B
PROC
MMU
Memory Management Unit
IRQ
ICU
Interrupt Controller Unit
DATA
Espace physique
DATA
TTY
4 Goctets COMMANDES REPONSES X octets 4 Goctets
CI
CD
32
BCU
Bus Controller Unit
Cache L2 IOC
In Out Controller
DISK
RAM externe
STACK STACK
Figure 6.3: MMU (Memory Management Unit) Le composant matriel MMU est charg de faire la traduction la vole des adresses logiques vers les adresses physiques (ie. chaque instruction o le processeur va lire dans le cache, il faut faire une traduction en 1 cycle de ladresse dinstruction ou de donne). Ce composant matriel utilise des tables de traduction : une table de traduction dirente pour chaque programme. Les tables de traduction sont stockes en mmoire ; elles sont charges lors de la phase de BOOT. Il ny a pas de collisions : lorsque lOS reoit la demande dun programme pour accder aux ressources de la machine, il dtermine les segments physiques (STACK, DATA, CODE) sans collision. Il faut alors : Un systme de tables de traduction ou table de pages (en mmoire) ; Un composant matriel MMU capable dutiliser ces tables. La technique moderne de virtualisation de la mmoire est la pagination. Dnition (Page). Une page est un bloc dadresses conscutives dans lespace adressable (logique ou physique) align et de taille xe : 4Ko. Remarque. Un bloc align : ladresse la plus leve est un multiple de ladresse la plus petite. Il y a dfaut de page lorsquun VPN nest pas associe un PPN dans la table de pages de la MMU. Il y a alors une erreur de traduction dadresse virtuelle. Il y a une leve dexception et lOS doit alors
32
31
12 OFFSET
0 Adresse physique
Table de traduction
Figure 6.4: Lien entre adresse physique et adresse virtuelle eectuer un mapping pour associer un PPN au VPN recherch en trouvant une page de libre. Attention. Un dfaut de page est dirent dun MISS de cache. La plupart des programmes utilisateurs nutilisent dune toute petite partie de leur espace adressable virtuel (ie. 2 Go). De ce fait, la plupart des tables de pages (ou tables de traduction) sont creuses (ie. contiennent majoritairement des 0). En gnral, lOS utilise des pages deux niveaux.
Virtual Page Number (VPN) 10 Adresse virtuelle INDEX 1 10 INDEX 2 12 OFFSET PPN PTPR
FLAGS
FLAGS
1024 entres
Figure 6.5: Pagination deux niveaux LOS ne cre que les tables de pages de 2eniveau qui sont eectivement utilises. La traduction va alors ncessiter deux lectures mmoire au lieu dune. Remarque. Le registre PTPR (Patch Table Pointer Register) contenu dans le co-processeur contient ladresse de base de la table de traduction de premier niveau. On gagne de la mmoire et on ralenti le mcanisme de traduction. Une vraie traduction (eective) cote au moins deux lectures (environ 30 cycles). La solution est de placer dans la MMU un petit cache spcialis : TLB (Translation Look-aside Buer) qui utilise le principe de localit. En eet, puisque les changements de pages sont rares, on en prote pour conserver dans le TLB de la MMU les rsultats des dernires traductions.
33
Dnition (TLB Translation Look-aside Buer). La TLB permet de conserver localement dans la MMU le rsultat de quelques traductions VPN PPN. La TLB est un tableau associatif (ie. un extrait peut tre rang dans nimporte quelle case = cache correspondance directe : une ligne de cache ne peut tre contenue que dans une seule et unique case).
Valid VPN PPN FLAGS
Rpertoire
Donnes
Figure 6.6: TLB (Translation Look-aside Buer) Lors dun MISS TLB, il faut rcuprer la correspondance VPN PPN en eectuant 2 lectures des tables de traduction. La TLB a un taux de MISS denviron 103 . En cas de MISS sur la TLB, il faut aller consulter les tables de pages en mmoire. Remarque. Lors dun changement de contexte, il faut : Mettre jour le registre PTPR ; Purger la TLB. De mme quil y a deux caches spars pour les instructions et donnes (CI et CD), il y a deux TLB pour parallliser les traductions. En eet, sil ny a quun seul cache, pour une lecture de donne, on perd deux cycles : Lecture de linstruction ; Lecture de la donne.
32 bits 32 registres
Tag V
Banc de registres
TLB Data
Tag V
Data
Processeur
MMU
Cache L2
RAM
34
Chapitre 7
35
LICENCE INFORMATIQUE
JeanLou Desbarbieux Franois Dromard Alain Greiner Frdric Ptrot Franck Wajsburt
LICENCE INFORMATIQUE
1/
INTRODUCTION
Ce document dcrit le langage d'assemblage du processeur MIPS R3000, ainsi que diffrentes conventions relatives l'criture des programmes en langage d'assemblage. Un document spar dcrit l'architecture externe du processeur, c'est--dire les registres visibles du logiciel, les rgles d'adressage de la mmoire, le codage des instructions machine, et les mcanismes matriels permettant le traitement des interruptions, des exceptions et des trappes. On prsente ici successivement l'organisation de la mmoire, les principales rgles syntaxiques du langage, les instructions et les macro-instructions, les directives acceptes par l'assembleur, les quelques appels systme disponibles, ainsi que conventions imposes pour les appels de fonctions et la gestion de la pile. Les programmes assembleur source qui respectent les rgles dfinies dans le prsent document peuvent tre assembls par l'assembleur MIPS de l'environnement GNU GCC pour gnrer du code excutable. Ils sont galement accepts par le simulateur du MIPS R3000 utilis en TP qui permet de visualiser le comportement du processeur instruction par instruction.
2/
ORGANISATION DE LA MEMOIRE
Rappelons que le but d'un programme source X crit en langage d'assemblage est de fournir un programme particulier (appel assembleur) les directives ncessaires pour gnrer le code binaire reprsentant les instructions et les donnes qui devront tre charges en mmoire pour permettre au programme X dtre excut par le processeur. Dans l'architecture MIPS R3000, l'espace adressable est divis en deux segments: le segment utilisateur, et le segment noyau. Un programme utilisateur utilise gnralement trois sous-segments (appels sections) dans le segment utilisateur: la section text contient le code excutable en mode utilisateur. Elle est implante conventionnellement l'adresse 0x00400000. Sa taille est fixe et calcule lors de l'assemblage. La principale tche de l'assembleur consiste gnrer le code binaire correspondant au programme source dcrit en langage d'assemblage, qui sera charg en mmoire dans cette section. la section data contient les donnes globales manipules par le programme utilisateur. Elle est implante conventionnellement l'adresse 0x10000000. Sa taille est fixe et calcule lors de l'assemblage. Les valeurs contenues dans cette section peuvent tre initialises grce des directives contenues dans le programme source en langage d'assemblage.
LICENCE INFORMATIQUE
la section stack contient la pile d'excution du programme utilisateur. Sa taille varie au cours de l'excution. Elle est implante conventionnellement l'adresse 0x7FFFF000. La pile s'tend vers les adresses dcroissantes. Trois sections sont galement dfinies dans le segment noyau:
la section ktext contient le code excutable en mode noyau. Elle est implante conventionnellement l'adresse 0x80000000. Sa taille est fixe et calcule lors de l'assemblage. la section kdata contient les donnes globales manipules par le systme d'exploitation en mode noyau. Elle est implante conventionnellement l'adresse 0xC0000000. Sa taille est fixe et calcule lors de l'assemblage. la section kstack contient la pile d'excution du noyau. Sa taille varie au cours de l'excution. Elle est implante conventionnellement l'adresse 0xFFFFF000. Cette pile s'tend vers les adresses dcroissantes.
Segment noyau
.kdata .ktext Reserved .stack 0x7FFFF000 0x7FFFEFFF 0xC0000000 0xBFFFFFFF 0x80000000 0x7FFFFFFF
Segment utilisateur
LICENCE INFORMATIQUE
3/
RGLES SYNTAXIQUES
LICENCE INFORMATIQUE
LICENCE INFORMATIQUE
Sil ny a pas dentier devant la parenthse ouvrante, le dplacement est nul. Pour ce qui concerne les sauts, il nest pas possible dcrire des sauts des adresses constantes, comme par exemple un j 0x400000 ou bnez $3, -12. Il faut ncessairement utiliser des labels.
LICENCE INFORMATIQUE
4/
INSTRUCTIONS
Dans ce qui suit, le registre not $rr est le registre destination, c.--d. qui reoit le rsultat de lopration, les registres nots $ri et $rj sont les registres source qui contiennent les valeurs des oprandes sur lesquelles seffectuent lopration. Notons quun registre source peut tre le registre destination dune mme instruction assembleur. Un oprande immdiat sera not imm, et sa taille sera spcifi dans la Description : de linstruction. Les instructions de saut prennent comme argument une tiquette (ou label), qui est utilise pour calculer ladresse de saut. Toutes les instructions modifient le registre PC (program counter), qui contient ladresse de linstruction suivante excuter. Enfin, le rsultat dune multiplication ou dune division est rang dans deux registres spciaux, HI pour les poids forts, et LO pour les poids faibles. Ceci nous amne introduire quelques notations : + x / mod and or nor xor Mem[ad] <= || Bn X pq Addition entire en complment 2 Soustraction entire en complment 2 Multiplication entire en complment 2 Division entire en complment 2 Reste de la division entire en complment 2 Oprateur et logique bit bit Oprateur ou logique bit bit Oprateur non-ou logique bit bit Oprateur ou-exclusif logique bit bit Contenu de la mmoire ladresse ad Assignation Concatnation entre deux chanes de bits Rplication du bit B n fois dans une chane de bits Slection des bits p q dans une chane de bits X
LICENCE INFORMATIQUE
add
Description : Les contenus des registres $ri et $rj sont ajouts pour former un rsultat sur 32 bits qui est plac dans le registre $rr rr <= ri + rj Exception : gnration d'une exception si dpassement de capacit.
addi
addiu
addu
and
LICENCE INFORMATIQUE
andi
beq
bgez
LICENCE INFORMATIQUE
bgtz
blez
bltz
bltzal
LICENCE INFORMATIQUE
bne
break
div
divu
11
LICENCE INFORMATIQUE
eret
jal
jalr
jr
LICENCE INFORMATIQUE
lb
lbu
lh
lhu
LICENCE INFORMATIQUE
Description : L'adresse de chargement est la somme de la valeur immdiate sur 16 bits, avec extension de signe, et du contenu du registre $ri. Le demi-mot de 16 bits lu cette adresse subit une extension avec des zro et est plac dans le registre $rr. rr <= (0)16 || (Mem}[imm + ri])150 Exceptions : - Adresse non aligne sur une frontire de demi-mot. - Adresse dans le segment noyau alors que le processeur est en mode utilisateur. - Adresse correspondant un segment non dfini
lui
lw
mfc0
LICENCE INFORMATIQUE
mfhi
mflo
mtc0
mthi
mtlo
LICENCE INFORMATIQUE
mult
Multiplication signe
Syntaxe : mult $ri, $rj Description : Le contenu du registre $ri est multipli par le contenu du registre $rj, le contenu des deux registres tant considr comme des nombres en complment deux. Les 32 bits de poids fort du rsultat sont placs dans le registre hi, et les 32 bits de poids faible dans lo. lo <= (ri x rj)310 hi <= (ri x rj)6332 Exception : pas dexception.
multu
Multiplication non-signe
Syntaxe : multu $ri, $rj Description : Le contenu du registre $ri est multipli par le contenu du registre $rj, le contenu des deux registres tant considr comme des nombres non signs. Les 32 bits de poids fort du rsultat sont placs dans le registre hi, et les 32 bits de poids faible dans lo. lo <= ((0 || ri) x (0 || rj))310 hi <= ((0 || ri) x (0 || rj))6332 Exception : pas dexception.
nor
or
ori
LICENCE INFORMATIQUE
Description : La valeur immdiate sur 16 bits subit une extension de zros. Un ou bit--bit est effectu entre cette valeur tendue et le contenu du registre $ri pour former un rsultat plac dans le registre $rr. rr <= ((0)16 || imm) or ri Exception : pas dexception.
sb
sh
sll
17
LICENCE INFORMATIQUE
sllv
slt
slti
sltiu
LICENCE INFORMATIQUE
sltu
sra
srav
srl
19
LICENCE INFORMATIQUE
srlv
sub
subu
sw
20
LICENCE INFORMATIQUE
syscall
xor
xori
21
LICENCE INFORMATIQUE
5/
MACRO-INSTRUCTIONS
Une macro-instruction est une pseudo-instruction qui ne fait pas partie du jeu d'instructions machine, mais qui est accepte par l'assembleur qui la traduit en une squence de plusieurs instructions machine. Les macro-instructions utilisent le registre $1 si elles ont besoin de faire un calcul intermdiaire. Il ne faut donc pas utiliser ce registre dans les programmes.
la
li
22
LICENCE INFORMATIQUE
6/
Les directives ne sont pas des instructions excutables par la machine, mais permettent de donner des ordres au programme d'assemblage. Toutes ces pseudo-instructions commencent par le caractre . ce qui permet de les diffrencier clairement des instructions.
.align n
Description : Cette directive aligne le compteur d'adresse de la section concerne sur une adresse telle que les n bits de poids faible soient zro. Exemple .align 2 .byte 12 .align 2 .byte 24
LICENCE INFORMATIQUE
.byte n, [m]
Description : La valeur de chacune des expressions n,m, est tronque 8 bits, et les valeurs ainsi obtenues sont places des adresses successives de la section active. Exemple table: .byte 1, 2, 4, 8, 16, 32, 64, 32, 16, 8, 4, 2, 1
.half n, [m]
Description : La valeur de chacune des expressions n,m, est tronque 16 bits, et les valeurs ainsi obtenues sont places des adresses successives de la section active. Exemple coordonnes: .half 0 , 1024
.word n, [m]
Description : La valeur de chaque expression est place dans des adresses successives de la section active. Exemple entiers: .word -1, -1000, -100000, 1, 1000, 100000
.space n
Description : Un espace de taille n octets est rserv partir de l'adresse courante de la section active. Exemple nuls: .space 1024 # initialise 1 kilo de mmoire zro 24
LICENCE INFORMATIQUE
7/
Pour raliser certains traitements qui ne peuvent tre excuts que sous le contrle du systme dexploitation (typiquement les entres/sorties consistant lire ou crire un nombre, ou une chane de caractre sur la console), le programme utilisateur doit utiliser un appel systme , grce linstruction syscall. Par convention, le numro de l'appel systme est contenu dans le registre $2, et ses ventuels arguments dans les registres $4 et $5. Lenvironnement de simulation XSPIM ne modlise quun seul priphriques. Les appels systmes ne sont pas rellement excuts par le processeur MIPS, mais sont directement excuts sur la station de travail qui effectue la simulation. Cinq appels systme sont actuellement supports par XSPIM :
LICENCE INFORMATIQUE
On crit la valeur du pointeur dans $4, et la taille du buffer dans $5, et on excute l'appel systme numro 8. read: .space 256 la $4, read ori $5, $0, ori $2, $0, syscall
255 8
# charge le pointeur dans $4 # charge longueur max dans $5 # code de read_string # copie la chane dans le buffer point par $4
26
LICENCE INFORMATIQUE
8/
Rappelons que lon distingue deux catgories de registres (cf section 3.7 page 5). Dune part les registres temporaires quune fonction peut modifier sans en restaurer la valeur initilale, dautre part les registres persistants quune fonction peut utiliser mais quelle doit restaurer dans leur tat initial avant de sortir. Seuls les registres $16 $23 et $28 $31 font partie de la deuxime catgorie et doivent tre restaurs sils ont t modifis. Les registres $1 $15 et $24, $25 sont utilisables sans sauvegarde pralable. Parmi les registres temporaires, nous allons voir que les registres $2 et $3 sont utiliss pour la valeur de retour des fonctions, les registres $4 $7 sont utiliss pour le passage des paramtres. L'excution de fonctions ncessite une pile en mmoire. Cette pile correspond la section stack. L'utilisation de cette pile fait l'objet de conventions qui doivent tre respectes. Les conventions dfinies ci-dessous sont utilises par le compilateur GCC. la pile s'tend vers les adresses dcroissantes ; le pointeur de pile pointe toujours sur la dernire case occupe dans la pile. Ceci signifie que toutes les cases d'adresse infrieure au pointeur de pile sont libres. Le processeur MIPS R3000 ne possde pas d'instructions spcifiques la gestion de la pile. On utilise les instructions lw et sw pour lire et crire dans la pile. Les appels de fonction utilisent un pointeur particulier, appel pointeur de pile. Ce pointeur est stock conventionnellement dans le registre $29. La valeur de retour (entier ou pointeur) d'une fonction est conventionnellement crite dans le registre $2 par la fonction appele. Par ailleurs, l'architecture matrielle du processeur MIPS R3000 impose l'utilisation du registre $31 pour stocker l'adresse de retour lors d'un appel de fonction.
chaque appel de fonction est associe une zone dans la pile constituant le contexte d'excution de la fonction. Dans le cas des fonctions rcursives, une mme fonction peut tre appele plusieurs fois et possdera donc plusieurs contextes d'excution dans la pile. Dans le cas gnral, un contexte d'excution d'une fonction est constitu de trois zones qui sont, dans l'ordre dempilement : La zone des arguments de la fonction Les valeurs des arguments sont crites dans la pile par la fonction appelante et lues dans la pile par la fonction appele. Dans la suite de ce document, on note na le nombre darguments, et on considre que tous les arguments sont reprsents par des mots de 32 bits. Par convention, on place toujours le premier argument de la fonction appele l'adresse la plus petite dans la zone des arguments. Le compilateur gcc fait une optimisation pour rduire le nombre daccs la mmoire. Les quatre premiers arguments dune fonction ne sont pas explicitement crits dans la pile mais sont laisss dans les registres $4, $5, $6 et $7. Attention, la fonction appelante rserve quand mme dans la pile lespace ncessaire pour tous les arguments, mais elle ny crit simplement pas les 4 premiers. Le pointeur de pile $29 pointe sur la case de la pile o le premier argument devrait tre. 27
LICENCE INFORMATIQUE
Les valeurs stockes dans cette zone ne sont en principe lues et crites que par la fonction appele. Elle est utilise pour stocker les variables et structures de donnes locales la fonction. Dans la suite de ce document, on note nv le nombre de mots de 32 bits constituant la zone des variables locales. La zone de sauvegarde des registres La fonction appele est charge de sauvegarder le registre $31, ainsi que les registres persistants quelle utilise de faon pouvoir restaurer leur valeur avant de rendre la main la fonction appelante. Les registres sont placs dans la pile suivant lordre croissant, le registre dindice le plus petit ladresse la plus petite. Ainsi, le registre $31 contenant ladresse de retour est toujours stock ladresse la plus grande de la zone de sauvegarde. Dans la suite de ce document, on note nr le nombre de registres sauvegards en plus du registre $31. Pour les fonctions terminales (qui nappellent pas dautres fonctions) il nest pas ncessaire de sauver $31. Dans la mesure du possible, il est souhaitable de ne pas utiliser de registres persistants afin dviter leur sauvegarde.
A la sortie de la fonction f, il faut excuter la squence suivante : lpilogue restaurer les valeurs des nr registres dont $31. restaurer le pointeur de pile sa valeur initiale $29 <= $29 + 4*(nv + nr + MAX(nai)) sauter ladresse contenue dans $31
Entre le prologue et lpilogue se trouve le corps de la fonction qui effectue les calculs en utilisant les registres ncessaires ainsi que les variables locales stockes dans la pile, et crit la valeur de retour dans le registre $2. Il est prfrable de choisir uniquement des registres temporaires pour les calculs. Nous avons dit qu lentre dune fonction les quatres premiers arguments sont placs dans les registres $4 $7. Si cette fonction appelle dautres fonctions, elle peut avoir besoin dcraser les registre $4 $7. Elle doit alors les crire dans la pile dans les cases qui leur sont rserves.
28
LICENCE INFORMATIQUE
Lors de lappel dune fonction g par la fonction f, il faut : placer les 4 premiers arguments dans les registres $4 $7 et les autres dans la pile au-del de la place rserve pour les 4 premiers. effectuer le branchement la premire instruction de la fonction g en utilisant une instruction DE TYPE jal ou bgezal.
La figure suivante reprsente ltat de la pile aprs lexcution du prologue de la fonction f Adresses hautes de la pile Af(na-1) Af(1) Af(0)
$29 lentre de f
Zone des variables de f Zone de sauvegarde des registres de f Zone des Arguments de g $31 R (nr-2) R(1) R(0) Ag(na-1) Ag(1) Ag(0)
29
LICENCE INFORMATIQUE
8.2)
Exemple
On traite ici lexemple d'une fonction calculant la norme dun vecteur (x,y), en supposant qu'il existe une fonction int isqrt(int x) qui retourne la racine carre d'un nombre entier. Les coordonnes du vecteur sont des variables globales initialises dans le segment data . Ceci correspond au code C ci-dessous : int int x= y= 5; 4;
int main() { printf ( %x , norme(x,y) ); /* raliser par lappel systme n 1*/ exit() ; } int norme (int a, int b) { int somme, val; somme = a * a + b * b; val = isqrt(somme); return val; } Quelques remarques : La fonction main na pas de variables loc ale (nv = 0), nutilise pas de registres persistants (nr = 1) et appelle la fonction norme avec deux arguments (na = 2). Il faut donc rserver 3 cases dans la pile (1 case pour $31 et 2 cases pour les arguments de norme). Attention, la fonction main est ici une fonction spciale qui se termine par un appel systme exit qui met fin dfinitivement lexcution du programme. Il ne sert rien de restaurer ltat des registres ou de la pile. La fonction norme dclare deux variables locales somme et val (nv = 2), utilise deux registres de travail temporaires $8 et $9 (nr = 1) et appelle la fonction isqrt, qui a un argument. Il faudra donc rserver 4 cases dans la pile (2 pour les variables locales, 1 pour $31, 1 pour larguments de isqrt). Les deux fonction isqrt et norme renvoient leurs rsultat dans le registre $2. /* Variables locales */
30
UNIVERSITE PIERRE ET MARIE CURIE Le programme assembleur est le suivant : x: y: .data .word .word .text main : addiu sw la lw la lw jal or ori syscall ori syscall $29, $29 -12 $31, 8($29) $4, x $4, 0($4) $5, y $5, 0($5) norme $4 $2 $0 $2, $0, 1 $2, $0, 10 5 4
LICENCE INFORMATIQUE
# dcrmentation pointeur de pile pour x et y # sauvegarde de $31 # Ecriture 1er parametre # Ecriture 2e paramtre # rcupration rsultat norme dans $4 # code de print_integer dans $2 # affichage rsultat sur la console # code de exit dans $2 # sortie du programme
norme : # prologue nv=2 nr=1 MAX(na) = 1 addiu $29, $29, -16 sw $31, +4($29) # corps de la fonction mult mflo mult mflo addu jal # pilogue lw addiu jr $4, $4 $5, $5 $4, isqrt $31, $29, $31 $4 $5 $4, $5
# dcrmentation pointeur de pile # sauvegarde adresse de retour # calcul a*a # calcul b*b # calcul somme dans $4 (1er argument) # appel de la fonction isqrt (rsultat dans $2) # restaure adresse de retour # incrmentation pointeur de pile # retour la fonction appelante
31
LICENCE INFORMATIQUE
Alain Greiner
MIPS32 Architecture
page - 1
LICENCE INFORMATIQUE
A) INTRODUCTION Ce document prsente une version lgrement simplifie de l'architecture externe du processeur MIPS32 (pour des raisons de simplicit, tous les mcanismes matriels de gestion de la mmoire virtuelle ont t dlibrment supprims). L'architecture externe reprsente ce que doit connatre un programmeur souhaitant programmer en assembleur, ou la personne souhaitant crire un compilateur pour ce processeur: - Les registres visibles du logiciel. - L'adressage de la mmoire. - Le jeu d'instructions. - Les mcanismes de traitement des interruptions, exceptions et trappes. Le processeur MIPS32 est un processeur 32 bits industriel conu dans les annes 80. Son jeu d'instructions est de type RISC. Il existe plusieurs ralisations industrielles de cette architecture (SIEMENS, NEC, LSI LOGIC, SILICON GRAPHICS, etc...) Cette architecture est suffisamment simple pour prsenter les principes de base de l'architecture des processeurs, et suffisamment puissante pour supporter un systme d'exploitation multi-tches tel qu'UNIX, puisquil supporte deux modes de fonctionnement : dans le mode utilisateur, certaines zones de la mmoire et certains registres du processeur rservs au systme dexploitation sont protgs et donc inaccessibles; dans le mode superviseur, toutes les ressources sont accessibles. L'architecture interne dpend des choix de ralisation matrielle. Plusieurs implantations matrielles de cette architecture ont t ralises l'Universit Pierre et Marie Curie dans un but d'enseignement et de recherche : une version microprogramme, simple mais peu performante (4 cycles par instruction), une version pipe-line plus performante (une instruction par cycle), mais plus complexe, une version superscalaire, encore plus performante (2 instructions par cycle) et beaucoup plus complexe. La spcification du langage d'assemblage, des conventions dutilisation des registres, ainsi que des conventions dutilisation de la pile fait l'objet d'un document spar.
MIPS32 Architecture
page - 2
LICENCE INFORMATIQUE
B) REGISTRES VISIBLES DU LOGICIEL Tous les registres visibles du logiciel, c'est dire ceux dont la valeur peut tre lue ou modifie par les instructions, sont des registres 32 bits. Afin de mettre en oeuvre les mcanismes de protection ncessaires pour un systme d'exploitation multi-tches, le processeur possde deux modes de fonctionnement : utilisateur/superviseur. Ces deux modes de fonctionnement imposent d'avoir deux catgories de registres. 1) Registres non protgs Le processeur possde 35 registres manipuls par les instructions standard (c'est dire les instructions qui peuvent s'excuter aussi bien en mode utilisateur qu'en mode superviseur). Ri (0 i 31) 32 registres gnraux Ces registres sont directement adresss par les instructions, et permettent de stocker des rsultats de calculs intermdiaires. Le registre R0 est un registre particulier: - la lecture fournit la valeur constante "0x00000000" - lcriture ne modifie pas son contenu. Le registre R31 est utilis par les instructions d'appel de procdures (instructions BGEZAL, BLTZAL, JAL et JALR) pour sauvegarder l'adresse de retour. Registre compteur de programme (Program Counter) Ce registre contient l'adresse de l'instruction en cours d'excution. Sa valeur est modifie par toutes les instructions.
PC
HI et LO Registres pour la multiplication ou la division Ces deux registres 32 bits sont utiliss pour stocker le rsultat d'une multiplication ou d'une division, qui est un mot de 64 bits. Contrairement d'autres processeurs plus anciens, le processeur MIP32 ne possde pas de registres particuliers pour stocker les "codes conditions". Des instructions de comparaison permettent de calculer un boolen qui est stock dans lun quelconque des registres gnraux. La valeur de ce boolen peut ultrieurement tre teste par les instructions de branchement conditionnel.
MIPS32 Architecture
page - 3
LICENCE INFORMATIQUE
2) Registres protgs L'architecture MIPS32 dfinit 32 registres (numrots de 0 31), qui ne sont accessibles, en lecture comme en criture, que par les instructions privilgies MTC0 et MFC0 (ces instructions ne peuvent tre excutes qu'en mode superviseur). On dit qu'ils appartiennent au "coprocesseur systme" (appl aussi CP0). En pratique, cette version du processeur MIPS32 en dfinit 6. Ils sont utiliss par le systme dexploitation pour la gestion des interruptions , des exceptions, et des appels systmes (voir chapitre E). SR Registre d'tat (Status Register). Il contient en particulier le bit qui dfinit le mode : superviseur ou utilisateur, ainsi que les bits de masquage des interruptions. (Ce registre possde le numro 12) Registre de cause (Cause Register). En cas d'interruption ou d'exception, son contenu dfinit la cause pour laquelle on fait appel au programme de traitement des interruptions et des exceptions. (Ce registre possde le numro 13) Registre d'exception (Exception Program Counter). Il contient l'adresse de retour (PC + 4) en cas d'interruption. Il contient l'adresse de l'instruction fautive en cas d'exception (PC). (Ce registre possde le numro 14) Registre d'adresse illgale (Bad Address Register). En cas d'exception de type "adresse illgale", il contient la valeur de l'adresse mal forme. (Ce registre possde le numro 8)
CR
EPC
BAR
PROCID Registre en lecture seulement contenant le numro du processeur. Cet index cabl est utilis par le systme dexploitation pour grer des architectures multi-cores. (Ce registre possde le numro 15) CYCLECOUNT Registre en lecture seulement contenant le nombre de cycles excuts depuis linitialisation du processeur. (Ce registre possde le numro 16)
MIPS32 Architecture
page - 4
LICENCE INFORMATIQUE
C) ADRESSAGE MMOIRE 1) Adresses octet Toutes les adresses mises par le processeur sont des adresses octets, ce qui signifie que la mmoire est vue comme un tableau d'octets, qui contient aussi bien les donnes que les instructions. Les adresses sont codes sur 32 bits. Les instructions sont codes sur 32 bits. Les changes de donnes avec la mmoire se font par mot (4 octets conscutifs), demimot (2 octets consecutifs), ou par octet. Pour les transferts de mots et de demi-mots, le processeur respecte la convention "little endian". L'adresse d'un mot de donne ou d'une instruction doit tre multiple de 4. L'adresse d'un demi-mot doit tre multiple de 2. (on dit que les adresses doivent tre "alignes"). Le processeur part en exception si une instruction calcule une adresse qui ne respecte pas cette contrainte. 2) Calcul d'adresse Il existe un seul mode dadressage, consistant effectuer la somme entre le contenu d'un registre gnral Ri, dfini dans l'instruction, et d'un dplacement qui est une valeur immdiate signe, sur 16 bits, contenue galement dans l'instruction: adresse = Ri + Dplacement 3) Mmoire virtuelle Pour des raisons de simplicit, cette version du processeur MIPS32 ne possde pas de mmoire virtuelle, c'est dire que le processeur ne contient aucun mcanisme matriel de traduction des adresses logiques en adresses physiques. Les adresses calcules par le logiciel sont donc transmises au systme mmoire sans modifications. On suppose que la mmoire rpond en un cycle. Un signal permet au systme mmoire de "geler" le processeur s'il n'est pas capable de rpondre en un cycle (ce mcanisme peut tre utilis pour grer les MISS du ou des caches). Si une anomalie est dtecte au cours du transfert entre le processeur et la mmoire, le systme mmoire peut le signaler au moyen d'un signal d'erreur, qui dclenche un dpart en exception.
MIPS32 Architecture
page - 5
LICENCE INFORMATIQUE
4) Protection mmoire En labsence de mmoire virtuelle, lespace mmoire est simplement dcoup en 2 segments identifis par le bit de poids fort de ladresse : adr 31 = 0 adr 31 = 1 ==> segment utilisateur ==> segment systme
Quand le processeur est en mode superviseur, les 2 segments sont accessibles. Quand le processeur est en mode utilisateur, seul le segment utilisateur est accessible. Le processeur part en exception si une instruction essaie d'accder la mmoire avec une adresse correspondant au segment systme alors que le processeur est en mode utilisateur.
MIPS32 Architecture
page - 6
LICENCE INFORMATIQUE
D) JEU D'INSTRUCTIONS 1) Gnralits Le processeur possde 57 instructions qui se rpartissent en 4 classes : 33 12 7 5 instructions arithmtiques/logiques entre registres instructions de branchement instructions de lecture/criture mmoire instructions systmes
Toutes les instructions ont une longueur de 32 bits et possdent un des trois formats suivants :
31 25 20 15 10 5 0
RS RS
RT
RT
RD
SH IMD16
FUNC
IMD26
Le format J nest utilis que pour les branchements longue distance (inconditionnels). Le format I est utilis par les instructions de lecture/criture mmoire, par les instructions utilisant un oprande immdiat, ainsi que par les branchements courte distance (conditionnels). Le format R est utilis par les instructions ncessitant 2 registres sources (dsigns par RS et RT) et un registre rsultat dsign par RD.
MIPS32 Architecture
page - 7
LICENCE INFORMATIQUE
2) Codage des instructions Le codage des instructions est principalement dfini par les 6 bits du champs code opration de l'instruction (INS 31:26). Cependant, trois valeurs particulires de ce champ dfinissent en fait une famille d'instructions : il faut alors analyser d'autres bits de l'instruction pour dcoder l'instruction. Ces codes particuliers sont : SPECIAL (valeur "000000"), BCOND (valeur "000001") et COPRO (valeur "010000")
DECODAGE
INS 28 : 26
OPCOD
000
INS 31 : 29
001 BCOND
010
011
100
101
110
111
J SLTI
JAL SLTIU
BEQ ANDI
BNE ORI
BLEZ XORI
BGTZ LUI
ADDI COPRO
ADDIU
LB SB
LH SH
LW SW
LBU
LHU
Ce tableau exprime que l'instruction LHU (par exemple) possde le code opration "100101".
MIPS32 Architecture
page - 8
LICENCE INFORMATIQUE
Lorsque le code opration a la valeur SPECIAL ("000000"), il faut analyser les 6 bits de poids faible de l'instruction (INS 5:0):
OPCOD = SPECIAL
INS 2 : 0
INS 5 : 3
001
010
011
100
101
110
111
SRL
SRA
SLLV
SYSCALL
SRLV BREAK
SRAV
Lorsque le code opration a la valeur BCOND, il faut analyser les bits 20 et 16 de l'instruction. Lorsque le code opration a la valeur COPRO, il faut analyser les bits 25 et 23 de l'instruction. Les trois instructions de cette famille COPRO sont des instructions privilgies.
OPCOD = BCOND INS 16 0
INS 20
1
INS 25
0 0 1
0 1
BLTZ
BGEZ
MFC0 RFE
MTC0
BLTZAL BGEZAL
MIPS32 Architecture
page - 9
LICENCE INFORMATIQUE
3) Jeu d'instructions Le jeu d'instructions est "orient registres". Cela signifie que les instructions arithmtiques et logiques prennent leurs oprandes dans des registres et rangent le rsultat dans un registre. Les seules instructions permettant de lire ou d'crire des donnes en mmoire effectuent un simple transfert entre un registre gnral et la mmoire, sans aucun traitement arithmtique ou logique. La plupart des instructions arithmtiques et logiques se prsentent sous les 2 formes registre-registre et registre-immdiat: ADD ADDI : R(rd) <--: R(rt) <--R(rs) op R(rt) R(rs) op IMD format R format I
Loprande immdiat 16 bits est sign pour les oprations arithmtiques et non sign pour les oprations logiques. Le dplacement est de 16 bits pour les instructions de branchement conditionnelles (Bxxx) et de 26 bits pour les instructions de saut inconditionnelles (Jxxx). De plus les instructions JAL, JALR, BGEZAL, et BLTZAL sauvegardent une adresse de retour dans le registre R31. Ces instructions sont utilises pour les appels de sousprogramme. Toutes les instructions de branchement conditionnel sont relatives au compteur ordinal pour que le code soit translatable. L'adresse de saut est le rsultat d'une addition entre la valeur du compteur ordinal et un dplacement sign. Les instructions MTC0 et MFC0 permettent de transfrer le contenu des registres SR, CR, EPC et BAR vers un registre gnral et inversement. Ces 2 instructions ne peuvent tre excutes quen mode superviseur, de mme que l'instruction ERET qui permet de restaurer l'tat antrieur du registre d'tat avant de sortir du gestionnaire d'exceptions.
MIPS32 Architecture
page - 10
LICENCE INFORMATIQUE
E) EXCEPTIONS / INTERRUPTIONS / APPELS SYSTEME Il existe quatre types d'vnements qui peuvent interrompre l'excution "normale" d'un programme: - les exceptions - les interruptions - les appels systme (instructions SYSCALL et BREAK) - le signal RESET Dans tous ces cas, le principe gnral consiste passer la main une procdure logicielle spcialise (appele Gestionnaire dInterrutions, Exceptions et Trappes) qui s'excute en mode superviseur, qui il faut transmettre les informations minimales lui permettant de traiter le problme. 1) Exceptions Les exceptions sont des vnements "anormaux", le plus souvent lis une erreur de programmation, qui empche l'excution correcte de l'instruction en cours. La dtection d'une exception entrane l'arrt immdiat de l'excution de l'instruction fautive. Ainsi, on assure que l'instruction fautive ne modifie pas la valeur d'un registre visible ou de la mmoire. Les exceptions ne sont videmment pas masquables. Il y a 7 types d'exception dans cette version du processeur MIPS32 : ADEL ADES DBE IBE OVF RI Adresse illgale en lecture : adresse non aligne ou se trouvant dans le segment systme alors que le processeur est en mode utilisateur. Adresse illgale en criture : adresse non aligne ou accs une donne dans le segment systme alors que le processeur est en mode utilisateur. Data bus erreur : le systme mmoire signale une erreur en activant le signal BERR la suite d'un accs de donne. Instruction bus erreur : le systme mmoire signale une erreur en activant le signal BERR l'occasion d'une lecture instruction. Dpassement de capacit : lors de l'excution d'une instruction arithmtique (ADD, ADDI ou SUB), le rsultat ne peut tre reprsent sur 32 bits. Codop illgal : le codop ne correspond aucune instruction connue (il s'agit probablement d'un branchement dans une zone mmoire ne contenant pas du code excutable.
MIPS32 Architecture
page - 11
LICENCE INFORMATIQUE
CPU
Coprocesseur inaccessible : tentative d'excution d'une instruction privilgie (MTC0, MFC0, ERET) alors que le processeur est en mode utilisateur.
Le processeur doit alors passer en mode superviseur, et se brancher au Gestionnaire d'Interruptions, Exceptions et Trappes (GIET), implant conventionnellement l'adresse "0x80000180". Aprs avoir identifi que la cause est une exception (en examinant le contenu du registre CR), le GIET se branche alors au gestionnaire dexception. Toutes les exceptions tant fatales il n'est pas ncessaire de sauvegarder une adresse de retour car il n'y a pas de reprise de l'excution du programme contenant l'instruction fautive. Le processeur doit cependant transmettre au gestionnaire d'exceptions l'adresse de l'instruction fautive et indiquer dans le registre de cause le type d'exception dtecte. Lorsquil dtecte une exception, le matriel doit donc: - sauvegarder l'adresse de l'instruction fautive dans le registre EPC - passer en mode superviseur et masque les interruptions dans SR - sauvegarder ventuellement ladresse fautive dans BAR - crire le type de l'exception dans le registre CR - brancher l'adresse "0x80000180". 2) Interruptions Les requtes d'interruption matrielles sont des vnements asynchrones provenant gnralement de priphriques externes. Elles peuvent tre masques. Le processeur possde 6 lignes d'interruptions externes qui peuvent tre masques globalement ou individuellement. L'activation d'une de ces ligne est une requte d'interruption. Elles sont crites dans le registre CR, et elles sont prises en compte la fin de l'excution de l'instruction en cours si elles ne sont pas masques. Cette requte doit tre maintenue active par le priphrique tant qu'elle n'a pas t prise en compte par le processeur. Le processeur doit alors passer alors en mode superviseur et se brancher au GIET. Aprs avoir identifi que la cause est une interruption (en examinant le contenu du registre CR), le GIET se branche au gestionnaire dinterruption, qui doit appeler la routine dinterruption (ISR) approprie. Comme il faut reprendre l'excution du programme en cours la fin du traitement de l'interruption, il faut sauvegarder une adresse de retour. Lorsquil reoit une requte dinterruption non masque, le matriel doit donc : - sauvegarder l'adresse de retour (PC + 4) dans le registre EPC - passer en mode superviseur et masque les interruptions dans SR - crire qu'il s'agit d'une interruption dans le registre CR - brancher l'adresse "0x80000180".
MIPS32 Architecture Externe - octobre 31, 2009 page - 12
LICENCE INFORMATIQUE
En plus des 6 lignes d'interruption matrielles, le processeur MIPS32 possde un mcanisme d'interruption logicielle: Il existe 2 bits dans le registre de cause CR qui peuvent tre crits par le logiciel au moyen de l'instruction privilgie MTC0. La mise 1 de ces bits dclenche le mme traitement que les requtes d'interruptions externes, s'ils ne sont pas masqus. 3) Appels systme: instructions SYSCALL et BREAK L'instruction SYSCALL permet une tche (utilisateur ou systme) de demander un service au systme d'exploitation, comme par exemple effectuer une entre-sortie. Le code dfinissant le type de service demand au systme, et un ventuel paramtre doivent avoir t pralablement rangs dans des registres gnraux. L'instruction BREAK est utilise plus spcifiquement pour poser un point d'arrt (dans un but de dverminage du logiciel): on remplace brutalement une instruction du programme dverminer par l'instruction BREAK. Dans les deux cas, le processeur passe en mode superviseur et se branche ici encore au GIET. Aprs avoir identifi que la cause est un appel systme (en examinant le contenu du registre CR), le GIET se branche au gestionnaire dappels systme. Lorsquil rencontre une des deux instructions SYSCALL ou BREAK, le matriel effectue les oprations suivantes : - sauvegarder de l'adresse de retour (PC + 4) dans le registre EPC - passer en mode superviseur et masquage des interruptions dans SR - crire la cause du droutement dans le registre CR - brancher l'adresse "0x80000180". 4) Signal RESET Le processeur possde galement une entre RESET dont l'activation, pendant au moins un cycle, entrane le branchement inconditionnel au logiciel boot-loader. Ce logiciel, implant conventionnellement ladresse 0xBFC00000 doit principalement charger le code du systme dexploitation dans la mmoire et initialiser les priphriques. Cette requte est trs semblable une septime ligne d'interruption externe avec les diffrences importantes suivantes : - elle n'est pas masquable. - il n'est pas ncessaire de sauvegarder une adresse de retour. - le gestionnaire de reset est implant l'adresse "0xBFC00000". Dans ce cas, le processeur doit: - passer en mode superviseur et masque les interruptions dans SR - brancher l'adresse "0xBFC00000"
MIPS32 Architecture
page - 13
LICENCE INFORMATIQUE
5) Sortie du GIET ou du bootloader Avant de reprendre l'excution d'un programme qui a effectu un appel systme (instructions SYSCALL ou BREAK) ou qui a t interrompu par une interruption, ou pour sortir du bootloader, il est ncessaire d'excuter l'instruction ERET. Cette instruction modifie le contenu du registre SR, et effectue un branchement ladresse contenue dans le registre EPC. 6) Gestion du registre d'tat SR La figure suivante prsente le contenu des 16 bits de poids faible du registre SR:
IM[7:0] 0 0 0 UM 0 ERL EXL IE
Cette version du processeur MIP32 nutilise que 12 bts du registre SR : IE : Interrupt Enable EXL : Exception Level ERL : Reset Level UM : User Mode IM[7:0] : Masques individuels pour les six ligne dnterruption matrielles (bits IM[7:2]) et pour les 2 interruptions logicielles (bits IM[1:0])
- Le processeur a le droit daccder aux ressources protges (registres du CP0, et adresses mmoires > 0x7FFFFFFF) si et seulement si le bit UM vaut 0, ou si lun des deux bits ERL et EXL vaut 1. - Les interruptions sont autorises si et seulement si le bit IE vaut 1, et si les deux bits ERL et EXL valent 00, et si le bit correspondant de IM vaut 1. - Les trois types dvnements qui dclenchent le branchement au GIET (interruptions, exceptions et appels systme) forcent le bit EXL 1, ce qui masque les interruptions et autorise laccs aux ressources protges. - Lactivation du signal RESET qui force le branchement au Boot-Loader force le bit ERL 1, ce qui masque les interruptions et autorise laccs aux ressources protges. - Linstruction ERET force le bit EXL 0. Lors de lactivation du RESET, SR contient donc la valeur 0x0004. Pour excuter un programme utilisateur en mode protg, avec interruptions actives, il doit contenir la valeur 0xFF11. Le code de boot doit crire la valeur 0xFF13 dans SR et ladresse du programme utilisateur dans EPC avant dappeler linstruction ERET.
MIPS32 Architecture
page - 14
LICENCE INFORMATIQUE
7) Gestion du registre de cause CR Le registre CR contient trois champs. Les 4 bits du champs XCODE(3:0) dfinissent la cause de l'appel au GIET. Les 6 bits du champs IRQ(5:0) reprsentent l'tat des lignes d'interruption externes au moment de l'appel au GIET. Les 2 bits SWI(1:0) reprsentent les requtes d'interruption logicielle. La figure suivante montre le format du registre de cause CR :
15 14 13 12 11 10 9 SWI 8 7 0 6 0 5 4 3 2 1 0 0 0
IRQ
X CODE
Les valeurs possibles du champs XCODE sont les suivantes : 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 INT Interruption Inutilis Inutilis Inutilis Adresse illgale en lecture Adresse illgale en criture Bus erreur sur accs instruction Bus erreur sur accs donne Appel systme (SYSCALL) Point d'arrt (BREAK) Codop illgal Coprocesseur inaccessible Overflow arithmtique Inutilis Inutilis Inutilis
MIPS32 Architecture
page - 15
/********************************************************************************** * File : giet.s * Author : Franck Wajsburt & Alain Greiner & Joel Porquet * Date : 2009 - 2010 ********************************************************************************** * Interruption/Exception/Trap Handler for MIPS32 processor * The base address of the segment containing this code * MUST be 0x80000000, in order to have the entry point * at address 0x80000180 !!! * All messages are printed on the TTY defined by the processor ID. ********************************************************************************** * History : * 15/09/2009 : The GIET entry point has been modified to comply with * the MIPS32 specification : 0x80000180 * 5/10/2009 : The syscall handler has been modified to comply with the * MIPS32 specification : the value stored in EPC register is the * syscall instruction address => it must be incremented by 4 * to obtain the return address. * 15/10/2009 : The Interrupt handler has been modified to comply with the * VCI_ICU specification : The IRQ index is obtained by a read * to (icu_base_address + 16). * 26/10/2009 : The interrupt handler has been modified to support * multi-processors architectures with one ICU per processor. * Finally, the mfc0 instruction uses now the select parameter * to comply with the MIPS32 specification when accessing the * processor_id (mtfc0 $x, $15, 1) * 08/11/2009 : The syscall handler has been extended to support 32 values * for the syscall index, and to enable interrupts when processing * a system call. * Five new syscalls have been introduced to access the frame buffer * Three new syscalls have been introduced to access the block device * The two syscalls associated to the DMA have been removed. * 18/11/2009 : The syscall handler has been modified to save the SR in * the stack before enabling interrupts. * 15/03/2010 : replace the itoa_print assembler function by the itoa_hex() * function defined in the syscalls.c file. * 10/04/2010 : modify the interrupt handler to use the new ICU component * supporting up to 8 output IRQs for 8 processors. * The active IRQ index is obtained as ICU[32*PROC_ID+16]. * 12/09/2010 : The ctx_switch functionhas been included in this file to * simplify the compilation process. * 25/09/2010 : add .end directive to end the _giet function * and modify the sharp comment character into the regular "slash * asterix ... asterix slash" comment syntax * 27/09/2010 : respect stack convention with 4 minimum slots before calling * C functions * 28/09/2010 : Save all the non-persistant registers in the int_handler **********************************************************************************/
.section .giet,"ax",@progbits .align 2 .global _interrupt_vector /* makes interrupt_vector an external symbol */ .extern seg_icu_base .extern seg_tty_base .extern isr_default .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern .extern _procid _proctime _tty_write _tty_read _tty_read_irq _timer_write _timer_read _icu_write _icu_read _gcd_write _gcd_read _locks_read _locks_write _exit _fb_sync_write _fb_sync_read _fb_write _fb_read _fb_completed _ioc_write _ioc_read _ioc_completed _itoa_hex
.ent _giet /**************************************************************** * Cause Table (indexed by the Cause register) ****************************************************************/ tab_causes: .word _int_handler /* 0000 : external interrupt */ .word _cause_ukn /* 0001 : undefined exception */ .word _cause_ukn /* 0010 : undefined exception */ .word _cause_ukn /* 0011 : undefined exception */ .word _cause_adel /* 0100 : illegal address read exception */ .word _cause_ades /* 0101 : illegal address write exception */ .word _cause_ibe /* 0110 : instruction bus error exception */ .word _cause_dbe /* 0111 : data bus error exception */ .word _sys_handler /* 1000 : system call */ .word _cause_bp /* 1001 : breakpoint exception */
/* /* /* /* /* /*
: : : : : :
illegal codop exception */ illegal coprocessor access */ arithmetic overflow exception */ undefined exception */ undefined exception */ undefined exception */
.space 320 /**************************************************************** * Entry point (at address 0x80000180) ****************************************************************/ _giet: mfc0 $27, $13 /* Cause Register analysis */ lui $26, 0x8000 /* $26 <= tab_causes */ andi $27, $27, 0x3c addu $26, $26, $27 lw $26, ($26) jr $26 /* Jump indexed by CR */ .end _giet /***************************************************************** * System Call Handler * A system call is handled as a special function call. * - $2 contains the system call index (< 16). * - $3 is used to store the syscall address * - $4, $5, $6, $7 contain the arguments values. * - The return address (EPC) iand the SR are saved in the stack. * - Interrupts are enabled before branching to the syscall. * - All syscalls must return to the syscall handler. * - $2, $3, $4, $5, $6, $7 as well as $26 & $27 can be modified. * * In case of undefined system call, an error message displays * the value of EPC on the TTY corresponding to the processor, * and the user program is killed. *****************************************************************/ _sys_handler: addiu $29, $29, -24 /* 2 slots for SR&EPC, 4 slots for args passing */ mfc0 $26, $12 /* load SR */ sw $26, 16($29) /* save it in the stack */ mfc0 $27, $14 /* load EPC */ addiu $27, $27, 4 /* increment EPC for return address */ sw $27, 20($29) /* save it in the stack */ andi sll la addu lw $26, $26, $27, $27, $3, $2, 0x1F $26, 2 tab_syscalls $27, $26 0($27) /* /* /* /* /* $26 $26 $27 $27 $3 <= <= <= <= <= syscall index (i < 32) */ index * 4 */ &tab_syscalls[0] */ &tab_syscalls[i] */ syscall address */
li mfc0 and mtc0 jalr mtc0 lw mtc0 lw mtc0 addiu eret _sys_ukn: la li jal la li jal mfc0 la addiu jal la li jal j
$27, $26, $26, $26, $3 $0, $26, $26, $26, $26, $29,
0xFFFFFFED $12 $26, $27 $12 $12 16($29) $12 20($29) $14 $29,
/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /*
Mask for UM & EXL bits */ $26 <= SR */ UM = 0 / EXL = 0 */ interrupt enabled */ jump to the proper syscall */ interrupt disbled */ load SR from stack */ restore SR */ load EPC from stack */ restore EPC */ restore stack pointer */ exit GIET */ undefined system call */ $4 <= message address */ $5 <= message length */ print unknown message */
24
$4, msg_uknsyscall $5, 36 _tty_write $4, msg_epc $5, 8 _tty_write $4, $14 $5, itoa_buffer $5, $5, 2 _itoa_hex $4, itoa_buffer $5, 10 _tty_write _exit
/* $4 <= message address */ /* $5 <= message length */ /* print EPC message */ /* /* /* /* $4 <= EPC */ $5 <= buffer address */ skip the 0x prefix */ fill the buffer */
/* $4 <= buffer address */ /* $5 <= buffer length */ /* print EPC value */ /* end of program */
itoa_buffer: .ascii "0x00000000" .align 2 /***************************************************************** * System Call Table (indexed by syscall index) */ tab_syscalls: .word _procid /* 0x00 */ .word _proctime /* 0x01 */ .word _tty_write /* 0x02 */ .word _tty_read /* 0x03 */ .word _timer_write /* 0x04 */ .word _timer_read /* 0x05 */ .word _gcd_write /* 0x06 */
.word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word
_gcd_read _icu_write _icu_read _tty_read_irq _sys_ukn _locks_write _locks_read _exit _sys_ukn _fb_sync_write _fb_sync_read _fb_write _fb_read _fb_completed _ioc_write _ioc_read _ioc_completed _sys_ukn _sys_ukn _sys_ukn _sys_ukn _sys_ukn _sys_ukn _sys_ukn _sys_ukn
/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /*
0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F
*/ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */
/******************************************************************* * Interrupt Handler * This simple interrupt handler cannot be interrupted. * It uses an external ICU component (Interrupt Controler Unit) * that concentrates up to 32 interrupts lines to a single IRQ * line that can be connected to any of the 6 MIPS IT inputs. * This component returns the highest priority active interrupt index * (smaller indexes have the highest priority). * * In case of a multi-ptocessor architecture, there is one ICU * per processor. The base address of the ICU segment is * computed as : seg_icu_base + 0x00100000 * proc_id * * The interrupt handler reads the ICU_IT_VECTOR register, * using the offset 16. * This component returns the highest priority interrupt index * (smaller indexes have the highest priority). * Any value larger than 31 means "no active interrupt", and * the default ISR (that does nothing) is executed. * The interrupt vector (32 ISR addresses array stored at * _interrupt_vector address) is initialised with the default * ISR address. The actual ISR addresses are supposed to be written * in the interrupt vector array by the boot code.
* All non persistant registers, such as $1 to $15, and $24 to $25, * as well as register $31 and EPC, are saved in the interrupted * program stack, before calling the * Interrupt Service Routine, and can be used by the ISR code. ********************************************************************/ _int_handler: addiu $29, $29, -23*4 /* stack space reservation */ .set noat sw $1, 4*4($29) /* save $1 */ .set at sw $2, 4*5($29) /* save $2 */ sw $3, 4*6($29) /* save $3 */ sw $4, 4*7($29) /* save $4 */ sw $5, 4*8($29) /* save $5 */ sw $6, 4*9($29) /* save $6 */ sw $7, 4*10($29) /* save $7 */ sw $8, 4*11($29) /* save $8 */ sw $9, 4*12($29) /* save $9 */ sw $10, 4*13($29) /* save $10 */ sw $11, 4*14($29) /* save $11 */ sw $12, 4*15($29) /* save $12 */ sw $13, 4*16($29) /* save $13 */ sw $14, 4*17($29) /* save $14 */ sw $15, 4*18($29) /* save $15 */ sw $24, 4*19($29) /* save $24 */ sw $25, 4*20($29) /* save $25 */ sw $31, 4*21($29) /* save $31 */ mfc0 $27, $14 sw $27, 4*22($29) /* save EPC */ mfc0 $27, $15, 1 /* $27 <= proc_id */ andi $27, $27, 0x7 /* at most 8 processors */ sll $27, $27, 20 /* $27 <= proc_id * 0x100000 */ la $26, seg_icu_base /* $26 <= seg_icu_base */ add $26, $26, $27 /* $26 <= seg_icu_base + 0x100000 * proc_id */ lw $26, 16($26) /* $26 <= interrupt_index */ srl $27, $26, 5 bne $27, $0, restore /* do nothing if index > 31 */ sll $26, $26, 2 /* $26 <= interrupt_index * 4 */ la $27, _interrupt_vector addu $26, $26, $27 lw $26, ($26) /* read ISR address */ jalr $26 /* call ISR */ restore: .set noat lw $1, 4*4($29) /* restore $1 */ .set at lw $2, 4*5($29) /* restore $2 */ lw $3, 4*6($29) /* restore $3 */ lw $4, 4*7($29) /* restore $4 */
$5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $24, $25, $31, $27, $29, $27,
4*8($29) 4*9($29) 4*10($29) 4*11($29) 4*12($29) 4*13($29) 4*14($29) 4*15($29) 4*16($29) 4*17($29) 4*18($29) 4*19($29) 4*20($29) 4*21($29) 4*22($29) $29, 23*4 $14
/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /*
restore $5 */ restore $6 */ restore $7 */ restore $8 */ restore $9 */ restore $10 */ restore $11 */ restore $12 */ restore $13 */ restore $14 */ restore $15 */ restore $24 */ restore $25 */ restore $31 */ return address (EPC) */ restore stack pointer */ restore EPC */ exit GIET */
.word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word
isr_default isr_default isr_default isr_default isr_default isr_default isr_default isr_default isr_default isr_default isr_default isr_default isr_default isr_default isr_default isr_default isr_default isr_default
/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /*
ISR ISR ISR ISR ISR ISR ISR ISR ISR ISR ISR ISR ISR ISR ISR ISR ISR ISR
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
*/ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */
/* The default ISR is called when no specific ISR has been installed in the * interrupt vector. It simply displays a message on TTY 0. */ isr_default: addiu $29, $29, -20 sw $31, 16($29) la $4, msg_default addi $5, $0, 36 jal _tty_write lw $31, 16($29) addiu $29, $29, 20 jr $31 /* /* /* /* /* /* /* /* get space in stack */ to save the return address */ $4 <= string address */ $5 <= string length */ print */ restore return address */ free space */ returns to interrupt handler */
/* Interrupt Vector Table (indexed by interrupt index) * 32 words corresponding to 32 ISR addresses */ _interrupt_vector: .word isr_default /* ISR 0 */ .word isr_default /* ISR 1 */ .word isr_default /* ISR 2 */ .word isr_default /* ISR 3 */ .word isr_default /* ISR 4 */ .word isr_default /* ISR 5 */ .word isr_default /* ISR 6 */ .word isr_default /* ISR 7 */ .word isr_default /* ISR 8 */ .word isr_default /* ISR 9 */ .word isr_default /* ISR 10 */ .word isr_default /* ISR 11 */ .word isr_default /* ISR 12 */ .word isr_default /* ISR 13 */
/************************************************************ * Exception Handler * Same code for all fatal exceptions : * Print the exception type and the values of EPC & BAR * on the TTY correspondintg to the processor PROCID, * and the user program is killed. ************************************************************/ _cause_bp: _cause_ukn: _cause_ri: _cause_ovf: _cause_adel: _cause_ades: _cause_ibe: _cause_dbe: _cause_cpu: mfc0 $26, $13 /* $26 <= CR */ andi $26, $26, 0x3C /* $26 <= _cause_index * 4 */ la $27, mess_causes /* mess_cause table base address */ addu $27, $26, $27 /* pointer on the message base address */ lw li jal la li jal mfc0 $4, ($27) $5, 36 _tty_write $4, msg_epc $5, 8 _tty_write $4, $14 /* $4 <= message address */ /* $5 <= message length */ /* print message cause */ /* $4 <= message address */ /* $5 <= message length */ /* print message EPC */ /* $4 <= EPC value */
$5, itoa_buffer $5, $5, 2 _itoa_hex $4, itoa_buffer $5, 10 _tty_write $4, msg_bar $5, 8 _tty_write $4, $8 $5, itoa_buffer $5, $5, 2 _itoa_hex $4, itoa_buffer $5, 10 _tty_write _exit
/* $5 <= buffer address */ /* skip 0x prefix */ /* fill buffer */ /* $4 <= buffer address */ /* $5 <= buffer length */ /* print EPC value */ /* $4 <= mesage address */ /* $5 <= message length */ /* print message BAR */ /* /* /* /* $4 <= BAR value */ $5 <= buffer address */ skip 0x prefix */ fill buffer */
msg_uknsyscall: msg_ukncause: msg_adel: msg_ades: msg_ibe: msg_dbe: msg_bp: msg_ri: msg_ovf: msg_cpu: .align 2
.asciiz .asciiz .asciiz .asciiz .asciiz .asciiz .asciiz .asciiz .asciiz .asciiz
"\n\n !!! Undefined System Call !!! \n" "\n\nException : strange unknown cause\n" "\n\nException : illegal read address \n" "\n\nException : illegal write address\n" "\n\nException : inst bus error \n" "\n\nException : data bus error \n" "\n\nException : breakpoint \n" "\n\nException : reserved instruction \n" "\n\nException : arithmetic overflow \n" "\n\nException : illegal coproc access\n"
/* $4 <= mesage address */ /* $5 <= message length */ /* print BAR value */ /* end program */
/* Exceptions Messages table (indexed by CAUSE) */ mess_causes: .word msg_ukncause .word msg_ukncause .word msg_ukncause .word msg_ukncause .word msg_adel .word msg_ades .word msg_ibe .word msg_dbe .word msg_ukncause .word msg_bp .word msg_ri .word msg_cpu .word msg_ovf .word msg_ukncause .word msg_ukncause .word msg_ukncause /****************************************************************** * All messages * Messages length are fixed : 8 or 36 characters... ******************************************************************/ msg_bar: .asciiz "\nBAR = " msg_epc: .asciiz "\nEPC = " msg_default: .asciiz "\n\n !!! Default ISR !!! \n"
/**************************************************************************** * _ctx_switch * The _ctx_switch function performs a context switch between the * current task and another task. * It can be used in a multi-processor architecture, with the assumption * that the tasks are statically allocated to processors. * The max number of processorsi is 8, and the max number of tasks is 4. * The scheduling policy is very simple : For each processor, the task index * is incremented, modulo the number of tasks allocated to the processor. * * It has no argument, and no return value. * * It uses three global variables: * - _current_task_array : an array of 8 task index: * (index of the task actually running on each processor) * - _task_number_array : an array of 8 numbers: * (the number of tasks allocated to each processor) * - _task_context_array : an array of 32 task contexts: * (at most 8 processors / each processor can run up to 4 tasks) * A task context is an array of 64 words = 256 bytes. * It is indexed by m = (proc_id*4 + task_id) * It contains copies of the processor registers. * As much as possible a register is stored at the index defined by its number * ( for example, $8 is saved in ctx[8]). * The exception are : * $0 is not saved since always 0 * $26, $27 are not saved since not used by the task * * 0*4(ctx) SR 8*4(ctx) $8 16*4(ctx) $16 24*4(ctx) $24 32*4(ctx) EPC * 1*4(ctx) $1 9*4(ctx) $9 17*4(ctx) $17 25*4(ctx) $25 33*4(ctx) CR * 2*4(ctx) $2 10*4(ctx) $10 18*4(ctx) $18 26*4(ctx) LO 34*4(ctx) reserved * 3*4(ctx) $3 11*4(ctx) $11 19*4(ctx) $19 27*4(ctx) HI 35*4(ctx) reserved * 4*4(ctx) $4 12*4(ctx) $12 20*4(ctx) $20 28*4(ctx) $28 36*4(ctx) reserved * 5*4(ctx) $5 13*4(ctx) $13 21*4(ctx) $21 29*4(ctx) $29 37*4(ctx) reserved * 6*4(ctx) $6 14*4(ctx) $14 22*4(ctx) $22 30*4(ctx) $30 38*4(ctx) reserved * 7*4(ctx) $7 15*4(ctx) $15 23*4(ctx) $23 31*4(ctx) $31 39*4(ctx) reserved
10
* * The return address contained in $31 is saved in the _current task context * (in the ctx[31] slot), and the function actually returns to the address contained * in the ctx[31] slot of the new task context. * * Caution : This function is intended to be used with periodic interrupts. * It can be directly called by the OS, but interrupts must be disabled before calling. ****************************************************************************************/ .section .ksave .global _task_context_array /* initialised in reset.s */ .global _current_task_array /* initialised in reset.s */ .global _task_number_array /* initialised in reset.s */ _task_context_array: .space 8192 _current_task_array: .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 _task_number_array: .word 1 .word 1 .word 1 .word 1 .word 1 .word 1 .word 1 .word 1 /* 32 contexts : indexed by (proc_id*4 + task_id) */ /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* 8 words : indexed by the proc_id */ _current_task_array[0] <= 0 */ _current_task_array[1] <= 0 */ _current_task_array[2] <= 0 */ _current_task_array[3] <= 0 */ _current_task_array[4] <= 0 */ _current_task_array[5] <= 0 */ _current_task_array[6] <= 0 */ _current_task_array[7] <= 0 */ 8 words : indexed by the _task_number_array[0] <= _task_number_array[1] <= _task_number_array[2] <= _task_number_array[3] <= _task_number_array[4] <= _task_number_array[5] <= _task_number_array[6] <= _task_number_array[7] <= proc_id */ 1 */ 1 */ 1 */ 1 */ 1 */ 1 */ 1 */ 1 */
mfc0 andi sll la addu lw addi bnez jr do_it: /* save mfc0 andi sll la addu lw sll la addu mfc0 andi sll addu
$15, 1 $26, 0x7 $26, 2 _task_number_array $27, $26 ($27) $27, -1 do_it
/* /* /* /* /* /* /* /*
$26 <= proc_id */ $26 <= 4*proc_id */ $27 <= base address of _task_number_array */ $27 <= _task_number_array + 4*proc_id */ $27 <= task number */ $26 <= _task_number - 1 */ 0 if only one task */ return */
_current task context */ $26, $26, $26, $27, $27, $26, $26, $27, $27, $26, $26, $26, $27, $15, 1 $26, 0x7 $26, 2 _current_task_array $27, $26 ($27) $26, 8 _task_context_array $27, $26 $15, 1 $26, 0x7 $26, 10 $27, $26 $12 0*4($27) 1*4($27) 2*4($27) 3*4($27) 4*4($27) 5*4($27) 6*4($27) 7*4($27) 8*4($27) 9*4($27) 10*4($27) 11*4($27) 12*4($27) 13*4($27) 14*4($27) 15*4($27) 16*4($27) 17*4($27) 18*4($27) 19*4($27) /* /* /* /* /* /* /* /* $26 $26 $27 $27 $26 $26 $27 $27 <= <= <= <= <= <= <= <= proc_id */ 4*proc_id */ base address of _current_task_array */ _current_task_array + 4*proc_id */ current task index */ 256*task_id */ base address of context array */ _task_context_array + 256*task_id */
/* $26 <= proc_id */ /* $26 <= 1024*proc_id */ /* $27 <= taxk_context_array + 256*(proc_id*4 + task_id) */
/*****************************************************************************************/ .section .switch .global _ctx_switch /* makes it an external symbol */ .align 2 _ctx_switch: /* test if more than one task on the processor */
mfc0 $26, sw $26, .set noat sw $1, .set at sw $2, sw $3, sw $4, sw $5, sw $6, sw $7, sw $8, sw $9, sw $10, sw $11, sw $12, sw $13, sw $14, sw $15, sw $16, sw $17, sw $18, sw $19,
/* $26 <= SR */ /* ctx[0] <= SR */ /* ctx[1] <= $1 */ /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* ctx[2] <= $2 */ ctx[3] <= $3 */ ctx[4] <= $4 */ ctx[5] <= $5 */ ctx[6] <= $6 */ ctx[7] <= $7 */ ctx[8] <= $8 */ ctx[9] <= $9 */ ctx[10] <= $10 */ ctx[11] <= $11 */ ctx[12] <= $12 */ ctx[13] <= $13 */ ctx[14] <= $14 */ ctx[15] <= $15 */ ctx[16] <= $16 */ ctx[17] <= $17 */ ctx[18] <= $18 */ ctx[19] <= $19 */
11
12
$20, $21, $22, $23, $24, $25, $26 $26, $26 $26, $28, $29, $30, $31, $26, $26, $26, $26,
20*4($27) 21*4($27) 22*4($27) 23*4($27) 24*4($27) 25*4($27) 26*4($27) 27*4($27) 28*4($27) 29*4($27) 30*4($27) 31*4($27) $14 32*4($27) $13 33*4($27)
/* /* /* /* /* /*
*/ */ */ */ */ */
/* ctx[26] <= LO */ /* /* /* /* /* ctx[27] ctx[28] ctx[29] ctx[30] ctx[31] <= <= <= <= <= H1 */ $28 */ $29 */ $30 */ $31 */
/* select mfc0 andi sll la addu lw la addu lw addiu sub bne add no_wrap: sw
the new task */ $15, 1 $15, 0x7 $15, 2 _current_task_array $17, $16 ($17) _task_number_array $19, $16 ($19) $18, 1 $18, $20 $0, no_wrap $0, $0 ($17) /* /* /* /* /* /* /* /* /* /* $15 <= proc_id */ $16 <= 4*proc_id */ $17 <= base address of _current_task_array */ $17 <= _current_task_array + 4*proc_id */ $18 <= _current task index */ $19 <= base address of _task_number_array */ $19 <= _task_number_array + 4*proc_id */ $20 <= max = number of tasks */ $18 <= new task index */ test modulo max */
$15, $15, $16, $17, $17, $18, $19, $19, $20, $18, $2, $2, $18, $18,
/* restore next task context */ sll la addu sll addu $19, $27, $27, $19, $27, $18, 8 _task_context_array $27, $19 $15, 10 $27, $19 0*4($27) $12 1*4($27) /* /* /* /* /* $19 $27 $27 $19 $27 <= <= <= <= <= 256*task_id */ base address of context array */ _task_context_array + 256*task_id */ 1024*proc_id */ _task_context_array + 256*(proc_id*4 + task_id) */
.set at lw $2, lw $3, lw $4, lw $5, lw $6, lw $7, lw $8, lw $9, lw $10, lw $11, lw $12, lw $13, lw $14, lw $15, lw $16, lw $17, lw $18, lw $19, lw $20, lw $21, lw $22, lw $23, lw $24, lw $25, lw $26, mtlo $26 lw $26, mthi $26 lw $28, lw $29, lw $30, lw $31, lw $26, mtc0 $26, lw $26, mtc0 $26, jr $31
2*4($27) 3*4($27) 4*4($27) 5*4($27) 6*4($27) 7*4($27) 8*4($27) 9*4($27) 10*4($27) 11*4($27) 12*4($27) 13*4($27) 14*4($27) 15*4($27) 16*4($27) 17*4($27) 18*4($27) 19*4($27) 20*4($27) 21*4($27) 22*4($27) 23*4($27) 24*4($27) 25*4($27) 26*4($27) 27*4($27) 28*4($27) 29*4($27) 30*4($27) 31*4($27) 32*4($27) $14 33*4($27) $13
/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /*
restore restore restore restore restore restore restore restore restore restore restore restore restore restore restore restore restore restore restore restore restore restore restore restore
$2 */ $3 */ $4 */ $5 */ $6 */ $7 */ $8 */ $9 */ $10 */ $11 */ $12 */ $13 */ $14 */ $15 */ $16 */ $17 */ $18 */ $19 */ $20 */ $21 */ $22 */ $23 */ $24 */ $25 */
/* restore LO */ /* /* /* /* /* restore restore restore restore restore HI */ $28 */ $29 */ $30 */ $31 */
/* restore SR */ /* restore $1 */
/* Local Variables: tab-width: 4; c-basic-offset: 4; c-file-offsets:((innamespace . 0)(inline-open . 0)); indent-tabs-mode: nil; End: */ /* vim: set filetype=asm expandtab shiftwidth=4 tabstop=4 softtabstop=4: */
13
14
Instructions MIPS
Assembleur A r it h m ti q u e s /l o g i q u e s
Add Sub Addu Subu Addi Addiu Or And Xor Nor Ori Andi Xori Sllv Srlv Srav Sll Srl Sra Lui Slt Sltu Slti Sltiu Mult Multu Div Divu Rd, Rs, Rt Rd, Rs, Rt Rd, Rs, Rt Rd, Rs, Rt Rt, Rs, I Rt, Rs, I Rd, Rs, Rt Rd, Rs, Rt Rd, Rs, Rt Rd, Rs, Rt Rt, Rs, I Rt, Rs, I Rt, Rs, I Rd, Rt, Rs Rd, Rt, Rs Rd, Rt, Rs Rd, Rt, sh Rd, Rt, sh Rd, Rt, sh Rt, I Rd, Rs, Rt Rd, Rs, Rt Rt, Rs, I Rt, Rs, I Rs, Rt Rs, Rt Rs, Rt Rs, Rt Rd Rd Rs Rs Add Substract Add Substract Add Immediate Add Immediate Logical Or Logical And Logical Exclusive-Or Logical Not Or Or Immediate And Immediate Exclusive-Or Immediate Shitf Left Logical Variable Shitf Right Logical Variable Shitf Right Arithmetical Variable Shitf Left Logical Shitf Right Logical Shitf Right Arithmetical Load Upper Immediate Set if Less Than Set if Less Than Unsigned Set if Less Than Immediate Set if Less Than Immediate Multiply Multiply Unsigned Divide Divide Unsigned Move From HI Move From LO Move To HI Move To LO *with sign extension 16 lowers bits of Rt are set to zero Unsigned immediate Unsigned immediate Unsigned immediate 5 lsb of Rs is significant 5 lsb of Rs is significant 5 lsb of Rs is significant *with sign extension
Opration
Overflow detection Overflow detection No Overflow No Overflow Overflow detection No Overflow Rd<-Rs+Rt Rd<-Rs-Rt Rd<-Rs+Rt Rd<-Rs-Rt Rt<-Rs+I Rt<-Rs+I
Effet
For mat
R R R R I I R R R R I I I R R R R R R I R R I I R R R R R R R R
Rd<-Rs or Rt Rd<-Rs and Rt Rd<-Rs xor Rt Rd<-Rs nor Rt Rt<-Rs or I Rt<-Rs and I Rt<-Rs xor I Rd<-Rt<<Rs Rd<-Rt>>Rs Rd<-Rt>>*Rs Rd<-Rt<<sh Rd<-Rt>>sh Rd<-Rt>>*sh Rt<-I"0000" Rd<-1 if Rs<Rt else 0 Rd<-1 if Rs<Rt else 0 Sign extended Immediate Unsigned Immediate LO<-32 low significant bits HI<-32 high significant bits LO<-32 low significant bits HI<-32 high significant bits LO<-Quotient HI<-Remainder LO<-Quotient HI<-Remainder Rt<-1 Rt<-1 Rs*Rt Rs*Rt Rs/Rt Rs/Rt Rd<-HI Rd<-LO HI<-Rs LO<-Rs if Rs<I else 0 if Rs<I else 0
L e c t u r e / c r i t u r e m m o i r e
Lw
Rt, I(Rs)
Load Word
Rt<-M(Rs+I)
Sw
Rt, I(Rs)
Store Word
M(Rs+I)<-Rt
Lh
Rt, I(Rs)
Lhu
Rt, I(Rs)
Sh
Rt, I(Rs)
Sign extended immediate. Two bytes from storage are located into the 2 less significant bytes of Rt. The sign of these 2 bytes is extended on the 2 most significant bytes. Sign extended immediate. Two bytes from storage are located into the 2 less significant bytes of Rt, others bytes are set to zero. Sign extended immediate/. The two less significant bytes of Rt are stored into the storage. Sign extended immediate. One byte from storage is located into the less significant bytes of Rt. The sign of this byte is extended on the 3 most significant bytes. Sign extended immediate. One byte from storage is located into the less significant bytes of Rt, others bytes are set to zero. Sign extended immediate. The less significant byte of Rt is stored into the storage.
Rt<-M(Rs+I)
Rt<-M(Rs+I)
M(Rs+I)<-Rt
Lb
Rt, I(Rs)
Load Byte
Rt<-M(Rs+I)
Lbu
Rt, I(Rs)
Rt<-M(Rs+I)
Sb
Rt, I(Rs)
Store Byte
M(Rs+I)<-Rt
B r a n c h e m e n t s
Beq
Branch if EQual
PC<-PC+4+(I*4) if Rs=Rt PC<-PC+4 if Rs!=Rt PC<-PC+4+(I*4) if Rs!=Rt PC<-PC+4 if Rs=Rt PC<-PC+4+(I*4) if Rs>=0 PC<-PC+4 if Rs<0 PC<-PC+4+(I*4) if Rs>0 PC<-PC+4 if Rs<=0 PC<-PC+4+(I*4) if Rs<=0 PC<-PC+4 if Rs>0 PC<-PC+4+(I*4) if Rs<0 PC<-PC+4 if Rs>=0 PC<-PC+4+(I*4) if Rs>=0 PC<-PC+4 if Rs<0 R31<-PC+4 in both cases PC<-PC+4+(I*4) if Rs<0 PC<-PC+4 if Rs>=0 R31<-PC+4 in both cases PC<-PC 31:28I*4 R31<-PC+4 PC<-PC 31:28I*4 PC<-Rs R31<-PC+4 PC<-Rs Rd<-PC+4 PC<-Rs
Rs, Rt, label Rs, label Rs, label Rs, label Rs, label Rs, label
Branch if Not Equal Branch if Greater or Equal Zero Branch if Greater Than Zero Branch if Less or Equal Zero Branch if Less Than Zero Branch if Greater or Equal Zero And Link Branch if Greater Than Zero And Link Jump Jump and Link Jump Register Jump and Link Register Jump and Link Register
I I I I I I
H I , L O
Bltzal
Rs, label
J J R R R
DECODAGE OPCOD 001 BCOND 010 011 100 101 110 111
000 SPECIAL
J SLTI
JAL SLTIU
BEQ ANDI
BNE ORI
BLEZ XORI
BGTZ LUI
Zone alloue pour les variables locales de g Zone alloue pour la sauvegarde des registres utiliss par g
emplacement par f
ADDI COPRO
ADDIU
LB SB
LH SH
LW SW
LBU
LHU
$29 aprs allocation emplacement pour les arguments dans f / aprs pilogue de g $29 valeur intiale
110 111
OPCOD = SPECIAL
INS 2 : 0
000
001
010
011
100
101
110
111
na nr nv
dsigne le nombre d'arguments de g dsigne le nombre de registres sauvegarder par f dsigne dsigne le nombre de variables locales de g
SRA
SLLV
SYSCALL
SRLV BREAK
SRAV
001 010
011 100
RS RS
RT
RT
RD
SH IMD16
FUNC
IMD26
Code ASCII
Hex 0 1 2 3 4 5 6 7
0
NUL DLE
1
SOH DC1
2
STX DC2
3
ETX DC3
4
EOT DC4
5
ENQ NAK
6
ACK SYN
7
BEL ETB
8
BS CAN
9
HT EM
A
LF SUB
B
VT ESC
C
FF FS
D
CR GS
E
SO RS
F
SI US
SP 0 @ P ` p
! 1 A Q a q
" 2 B R b r
# 3 C S c s
$ 4 D T d t
% 5 E U e u
& 6 F V f v
' 7 G W g w
( 8 H X h x
) 9 I Y i y
* : J Z j z
+ ; K [ k {
, < L \ l |
= M ] m }
. > N ^ n ~
/ ? O _ o
DEL
0 1 2 3 4 5 6 7 8 9 A B C D E F
8 9 A B C D E F
CSTE
P C
(i)
A D
H I
L O
D T
I R
A L U
Y
ADRESSE