Changes between Version 12 and Version 13 of Archi-1-TD11
- Timestamp:
- Nov 26, 2023, 6:34:16 PM (21 months ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Archi-1-TD11
v12 v13 66 66 67 67 - Une IRQ peut être masquée, c'est-à-dire que le processeur ne va pas interrompre le programme en cours. 68 - Le masquage peut être demandé à plusieurs endroits : dans le composant ICU et dans le processeur lui-même .68 - Le masquage peut être demandé à plusieurs endroits : dans le composant ICU et dans le processeur lui-même (parfois même dans le contrôleur de périphérique). 69 69 - Le masquage est demandé par le noyau, le plus souvent de manière temporaire, quand il doit exécuter un code critique qui ne doit surtout pas être interrompu. 70 70 … … 96 96 2. dans la case n°`i` du tableau `IRQ_VECTOR_DEV[]`, on trouve le numéro de l'instance du périphérique. 97 97 - Cette dernière information est nécessaire dans le cas des contrôleurs de périphérique multi-instances comme le TTY afin de savoir quel jeu de registres la fonction ISR doit utiliser. 98 - En effet, il y a une fonction ISR unique à exécuter quel que soit le numéro du TTY , l'adresse de cette fonction est placée dans les cases `10`, `11`, `12`, et `13` du tableau `IRQ_VECTOR_ISR[]` (si on a 4 TTYs) et dans les cases `10`, `11`, `12`, et `13` du tableau `IRQ_VECTOR_DEV[]`, on a les valeurs `0`, `1`, `2` et `3` qui correspondent bien au numéro d'instance des TTYs.98 - En effet, il y a une fonction ISR unique à exécuter quel que soit le numéro du TTY. Dans cette plateforme, comme il y a 4 TTY, l'adresse de la fonction ISR est placée dans les cases `10`, `11`, `12`, et `13` du tableau `IRQ_VECTOR_ISR[]`. Dans les cases `10`, `11`, `12`, et `13` du tableau `IRQ_VECTOR_DEV[]`, on a les valeurs `0`, `1`, `2` et `3` qui correspondent bien au numéro d'instance des TTYs. 99 99 100 100 == Rappel sur les 3 registres du coprocesseur 0 impliqués … … 191 191 '' 192 192 }}} 193 1. L'écriture dans `ICU_MASK` n'est pas possible, comment modifier ce registre pour mettre à 1 le bit ` 0` ?194 {{{#!protected ------------------------------------------------------------------------------------ 195 '' 196 * Il faut écrire `1` dans le bit ` 0` de `ICU_SET`.197 '' 198 }}} 199 1. Sur une plateforme (autre que celle des TP) sur laquelle on aurait un TTY0 sur l'entrée 5, un TIMER sur l'entrée 2, et un autre TTY1 sur l'entrée 14. Que doit-on faire pour que seuls le TTY1 et le TIMER soient démasqués et que TTY0 soit masqué ? \\Si les 3 IRQ se lèvent au même cycle, quelles seront les valeurs des registres `ICU_STATE`, `ICU_MASK` et `ICU_HIGHEST` ?193 1. L'écriture dans `ICU_MASK` n'est pas possible, comment modifier ce registre pour mettre à 1 le bit `10` ? 194 {{{#!protected ------------------------------------------------------------------------------------ 195 '' 196 * Il faut écrire `1` dans le bit `10` de `ICU_SET`. 197 '' 198 }}} 199 1. Sur une plateforme (autre que celle des TP) sur laquelle on aurait un TTY0 sur l'entrée 5, un TIMER sur l'entrée 2, et un autre TTY1 sur l'entrée 14. Que doit-on faire pour que seuls le TTY1 et le TIMER soient démasqués et que TTY0 soit masqué ? 200 200 {{{#!protected ------------------------------------------------------------------------------------ 201 201 '' 202 202 * on doit écrire `1` dans les bits 2 et 14 du registre `ICU_SET` donc `0b00000000.00000000.01000000.00000100` = `0x00004004` 203 203 * on doit écrire `1` dans le bit 5 du registre `ICU_CLEAR` donc `0b00000000.00000000.00000000.00100000` = `0x00000020` pour être sûr que le bit 5 de `ICU_MASK` soit à 0. (Au reset, tous les bits de `ICU_MASK` sont à 0, mais là on ne sait pas si c'est juste après le reset) 204 '' 205 }}} 206 1. Si on définit dans le code C: 207 {{{#!c 208 struct icu_s { 209 int state; // état des IRQ à l'entrée de l'ICU 210 int mask; // masque des IRQ 211 int set; // registre de mise à 1 des bits du registre mask 212 int clear; // registre de mise à 0 des bits du registre mask 213 int highest; // numéro de l'IRQ active la plus prioritaire 214 int unused[3]; // 3 registres non utilisés 215 }; 216 extern volatile struct icu_s __icu_regs_map; // déclaration de l'existence de cette struct pour gcc 217 }}} 218 Ecrivez la fonction mettant à 1 le bit n°`irq` du registre `ICU_MASK`: `void icu_set_mask (int irq)` 219 {{{#!protected ------------------------------------------------------------------------------------ 220 '' 221 {{{#!c 222 void icu_set_mask (int irq) 223 { 224 __icu_regs_map.set = 1 << irq; // set bit n'irq to 1, do not change the others 225 } 226 }}} 227 '' 228 }}} 229 1. Si les 3 IRQ de la question précédente se lèvent au même cycle, quelles seront les valeurs des registres `ICU_STATE`, `ICU_MASK` et `ICU_HIGHEST` ? 230 {{{#!protected ------------------------------------------------------------------------------------ 231 '' 204 232 * Si les 3 IRQ s'activent alors `ICU_STATE` ← `0x00000000.00000000.01000000.00100100` = `0x00004024`\\ 205 233 on ne sait pas ce qu'il y a dans `ICU_MASK`, sauf pour les bits 2, 5 et 14 mais on sait qu'il ne change pas de valeur et `ICU_HIGHEST ← 2` (le plus petit numéro d'IRQ). … … 230 258 '' 231 259 }}} 232 1. Comment demande-t-on l'acquittement ? 260 1. Comment demande-t-on l'acquittement ? Donnez au moins un exemple. 233 261 {{{#!protected ------------------------------------------------------------------------------------ 234 262 '' … … 259 287 '' 260 288 * C'est l'adresse de retour dans le programme interrompu. Quand le processeur reçoit une IRQ alors qu'il est en train d'exécuter l'instruction `i` à l'adresse `PC` (Program Counter), alors le MIPS termine l'exécution de l'instruction `i`, puis il enregistre `PC+4` (adresse de l'instruction qui suit `i`) dans `c0_EPC` et il saute à l'adresse `0x80000180`. 261 * Question de Karine : et si `i` est un saut (ou l'instruction dans le delayed slot d'un saut pris ?)262 289 '' 263 290 }}} … … 334 361 }}} 335 362 La déclaration `extern volatile struct icu_s __icu_regs_map[NCPUS];` informe le compilateur que le symbole `__icu_regs_map` est défini ailleurs et que c'est un tableau de structures de type `struct icu_s`. Ainsi, le compilateur `gcc` sait comment utiliser la variable `__icu_regs_map`.\\\\ 336 Dans quel fichier est défini `__icu_regs_map` ?\\ 337 Que font les fonctions `icu_get_highest()`, `icu_set_mask()` et `isrcall()`?\\ 338 Comment s'appelle le couple de tableaux `irq_vector_isr[irq]` et `irq_vector_dev[irq]` ?\\ 339 Combien ont-il de cases ? 363 Dans quel fichier est défini `__icu_regs_map` ? 340 364 {{{#!protected ------------------------------------------------------------------------------------ 341 365 '' 342 366 * Ce symbole est défini dans le fichier ldscript du kernel `kernel/kernel.ld` 367 '' 368 }}} 369 Que font les fonctions `icu_get_highest()`, `icu_set_mask()` et `isrcall()`? 370 {{{#!protected ------------------------------------------------------------------------------------ 371 '' 343 372 * `icu_get_highest()` lit le registre `ICU_HIGHEST` de l'ICU et rend donc le numéro de l'IRQ la plus prioritaire. 344 373 * `icu_set_mask()` met 1 dans le bit n°`irq` du registre `ICU_SET` de l'ICU n°`icu` (ici `icu` est à 0 parce qu'il faut une ICU par MIPS et qu'il n"y a qu'un seul MIPS). Cela a pour effet de mettre à `1` dans le bit n°`irq` du registre `ICU_MASK`. 345 374 * `isrcall()` va chercher dans l'ICU le numéro de l'IRQ la plus prioritaire et la copie dans la variable `irq` (cette notion de priorité n'a de sens que dans le cas où au moins deux IRQ sont actives en même temps). `isrcall()` appelle la fonction ISR qui est dans la case n°`irq` du tableau `irq_vector_isr[]` et lui donne en argument le numéro d'instance qui est dans la case n°`irq` du tableau `irq_vector_dev[]`. 375 '' 376 }}} 377 Comment s'appelle le couple de tableaux `irq_vector_isr[irq]` et `irq_vector_dev[irq]` et combien de cases ont-ils ? 378 {{{#!protected ------------------------------------------------------------------------------------ 379 '' 346 380 * Les deux tableaux constituent le vecteur d'interruption et ils ont autant de cases que l'ICU prend d'IRQ, c.-à-d. 32. 347 381 ''