Changes between Version 6 and Version 7 of Archi-1-TD11
- Timestamp:
- May 19, 2022, 10:55:28 AM (3 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Archi-1-TD11
v6 v7 223 223 1. À l'entrée dans le noyau, `kentry` analyse le champ `XCODE` du registre de `c0_cause` et si c'est `0` alors il saute au code donné ci-après (ce n'est pas exactement le code que vous pouvez voir dans les fichiers sources pour que ce soit plus facile à comprendre). 224 224 {{{#!c 225 cause_irq:225 irq_handler: 226 226 addiu $29, $29, -23*4 // 23 registers to save (18 tmp regs+HI+LO+$31+EPC+SR) 227 227 mfc0 $27, $14 // $27 <- EPC (addr of syscall instruction) 228 228 mfc0 $26, $12 // $26 <- SR (status register) 229 sw $31, 22*4($29) // $31 because, it is lost by jal i rq_handler229 sw $31, 22*4($29) // $31 because, it is lost by jal isrcall 230 230 sw $27, 21*4($29) // save EPC (return address of IRQ) 231 231 sw $26, 20*4($29) // save SR (status register) … … 235 235 [etc. pour les autres sauvegardes des registres temporaires] 236 236 237 jal i rq_handler // call the irq handler fontion écrite en C237 jal isrcall // call the irq handler fonction écrite en C 238 238 239 239 lw $1, 1*4($29) // restore all temporary registers including HI and LO … … 251 251 {{{#!protected ------------------------------------------------------------------------------------ 252 252 '' 253 * On doit sauver les registres temporaires parce que l'IRQ peut interrompre le programme n'importe quand et qu'il faudra revenir à l'application interrompue dans le même état donc sans perte d'information dans les registres. On ne sauve pas les registres persistants parce que ce sera fait dans la fonction `i rq_handler()`, si c'est nécessaire.254 '' 255 }}} 256 1. La fonction `i rq_handler()` a pour mission d'appeler la bonne ISR. Dans le code qui suit (extrait du fichier `kernel/harch.c`), on voit d'abord la déclaration de la structure qui décrit les registres présents dans l'ICU. En fait c'est un tableau de structures parce qu'il y a autant d'instances d'ICU que de processeurs (donné par NCPUS), ici, il y a un seul processeur MIPS, donc NCPUS=1.253 * On doit sauver les registres temporaires parce que l'IRQ peut interrompre le programme n'importe quand et qu'il faudra revenir à l'application interrompue dans le même état donc sans perte d'information dans les registres. On ne sauve pas les registres persistants parce que ce sera fait dans la fonction `isrcall()`, si c'est nécessaire. 254 '' 255 }}} 256 1. La fonction `isrcall()` a pour mission d'appeler la bonne ISR. Dans le code qui suit (extrait du fichier `kernel/harch.c`), on voit d'abord la déclaration de la structure qui décrit les registres présents dans l'ICU. En fait c'est un tableau de structures parce qu'il y a autant d'instances d'ICU que de processeurs (donné par NCPUS), ici, il y a un seul processeur MIPS, donc NCPUS=1. 257 257 {{{#!c 258 258 struct icu_s { … … 274 274 } 275 275 276 void i rq_handler(void) {276 void isrcall (void) { 277 277 int irq = icu_get_highest (cpuid()); 278 278 irq_vector_isr[irq] (irq_vector_dev[irq]); … … 282 282 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`.\\\\ 283 283 Dans quel fichier est défini `__icu_regs_map` ?\\ 284 Que font les fonctions `icu_get_highest()`, `icu_set_mask()` et `i rq_handler()`?\\284 Que font les fonctions `icu_get_highest()`, `icu_set_mask()` et `isrcall()`?\\ 285 285 Comment s'appelle le couple de tableaux `irq_vector_isr[irq]` et `irq_vector_dev[irq]` ?\\ 286 286 Combien ont-il de cases ? … … 290 290 * `icu_get_highest()` lit le registre `ICU_HIGHEST` de l'ICU et rend donc le numéro de l'IRQ la plus prioritaire. 291 291 * `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`. 292 * `i rq_handler()` 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). `irq_handler()` 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[]`.292 * `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[]`. 293 293 * Les deux tableaux constituent le vecteur d'interruption et ils ont autant de cases que l'ICU prend d'IRQ, c.-à-d. 32. 294 294 '' 295 295 }}} 296 1. Si `ICU_HIGHEST` contient 10 (dans le cas de notre plateforme) que doit faire la fonction `i rq_handler()`296 1. Si `ICU_HIGHEST` contient 10 (dans le cas de notre plateforme) que doit faire la fonction `isrcall()` 297 297 {{{#!protected ------------------------------------------------------------------------------------ 298 298 ''