Changes between Version 6 and Version 7 of Archi-1-TD11


Ignore:
Timestamp:
May 19, 2022, 10:55:28 AM (3 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Archi-1-TD11

    v6 v7  
    2232231. À 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).
    224224{{{#!c
    225 cause_irq:
     225irq_handler:
    226226    addiu   $29,    $29,    -23*4       // 23 registers to save (18 tmp regs+HI+LO+$31+EPC+SR)
    227227    mfc0    $27,    $14                 // $27 <- EPC (addr of syscall instruction)
    228228    mfc0    $26,    $12                 // $26 <- SR (status register)
    229     sw      $31,    22*4($29)           // $31 because, it is lost by jal irq_handler
     229    sw      $31,    22*4($29)           // $31 because, it is lost by jal isrcall
    230230    sw      $27,    21*4($29)           // save EPC (return address of IRQ)
    231231    sw      $26,    20*4($29)           // save SR (status register)
     
    235235    [etc. pour les autres sauvegardes des registres temporaires]                             
    236236
    237     jal     irq_handler                 // call the irq handler fontion écrite en C
     237    jal     isrcall                     // call the irq handler fonction écrite en C
    238238
    239239    lw      $1,     1*4($29)            // restore all temporary registers including HI and LO
     
    251251{{{#!protected ------------------------------------------------------------------------------------
    252252''
    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 `irq_handler()`, si c'est nécessaire.
    254 ''
    255 }}}
    256 1. La fonction `irq_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}}}
     2561. 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.
    257257{{{#!c
    258258struct icu_s {
     
    274274}
    275275
    276 void irq_handler (void) {
     276void isrcall (void) {
    277277    int irq = icu_get_highest (cpuid());       
    278278    irq_vector_isr[irq] (irq_vector_dev[irq]);
     
    282282 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`.\\\\
    283283 Dans quel fichier est défini `__icu_regs_map` ?\\
    284  Que font les fonctions `icu_get_highest()`, `icu_set_mask()` et `irq_handler()`?\\
     284 Que font les fonctions `icu_get_highest()`, `icu_set_mask()` et `isrcall()`?\\
    285285 Comment s'appelle le couple de tableaux `irq_vector_isr[irq]` et `irq_vector_dev[irq]` ?\\
    286286 Combien ont-il de cases ?
     
    290290  * `icu_get_highest()` lit le registre `ICU_HIGHEST` de l'ICU et rend donc le numéro de l'IRQ la plus prioritaire.
    291291  * `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   * `irq_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[]`.
    293293  * Les deux tableaux constituent le vecteur d'interruption et ils ont autant de cases que l'ICU prend d'IRQ, c.-à-d. 32.
    294294''
    295295}}}
    296 1. Si `ICU_HIGHEST` contient 10 (dans le cas de notre plateforme) que doit faire la fonction `irq_handler()`
     2961. Si `ICU_HIGHEST` contient 10 (dans le cas de notre plateforme) que doit faire la fonction `isrcall()`
    297297{{{#!protected ------------------------------------------------------------------------------------
    298298''