399 | | 2. Ouvrez le fichier `kernel/kinit.c`. Dans cette fonction, on appelle `archi_init()` avec en paramètre un nombre qui va servir de période d'horloge. Le simulateur de la plateforme sur les machines de la PPTI va environ à 3.5MHz. Combien de secondes demande-t-on dans ce code ? |
| 399 | 1. Dans la version précédente du gestionnaire de syscall, nous avions masqué les IRQ en écrivant `0` dans le registre `c0_status`(registre $12 du coprocesseur 0). Cela avait pour conséquence de mettre tout à 0, entre autre le bit IE. Il faut modifier ça, parce que sinon, lorsque l'utilisateur demandera à lire le clavier avec l'appel système `fgets()`, l'IRQ venant du timer ne sera jamais prise en compte (`TODO1`), ensuite au retour de la fonction qui réalise l'appel système, il faut masquer les IRQ pour ne pas avoir d'interruption pendant la restauration des registres jusqu'au `eret` qui fait sortir du kernel. |
| 400 | {{{#!c |
| 401 | addiu $29, $29, -8*4 // context for $31 + EPC + SR + syscall_code + 4 args |
| 402 | mfc0 $27, $14 // $27 <- EPC (addr of syscall instruction) |
| 403 | mfc0 $26, $12 // $26 <- SR (status register) |
| 404 | addiu $27, $27, 4 // $27 <- EPC+4 (return address) |
| 405 | sw $31, 7*4($29) // save $31 because it will be erased |
| 406 | sw $27, 6*4($29) // save EPC+4 (return address of syscall) |
| 407 | sw $26, 5*4($29) // save SR (status register) |
| 408 | sw $2, 4*4($29) // save syscall code (useful for debug message) |
| 409 | // TODO1: remplacez "mtc0 $0, $12" par 2 autres pour mettre 1 dans les bits c0_sr.HWI0 et c0_sr.IE |
| 410 | // vous pouvez utiliser $26 |
| 411 | mtc0 $0, $12 // SR <- kernel-mode without INT (UM=0 ERL=0 EXL=0 IE=0) |
| 412 | |
| 413 | la $26, syscall_vector // $26 <- table of syscall functions |
| 414 | andi $2, $2, SYSCALL_NR-1// apply syscall mask |
| 415 | sll $2, $2, 2 // compute syscall index (mutiply by 4) |
| 416 | addu $2, $26, $2 // $2 <- & syscall_vector[$2] |
| 417 | lw $2, ($2) // at the end: $2 <- syscall_vector[$2] |
| 418 | jalr $2 // call syscall function |
| 419 | |
| 420 | // TODO2: Il faut mettre 0 dans SR pour masquer les interruptions |
| 421 | lw $26, 5*4($29) // get old SR |
| 422 | lw $27, 6*4($29) // get return address of syscall |
| 423 | lw $31, 7*4($29) // restore $31 (return address of syscall function) |
| 424 | mtc0 $26, $12 // restore SR |
| 425 | mtc0 $27, $14 // restore EPC |
| 426 | addiu $29, $29, 8*4 // restore stack pointer |
| 427 | eret // return : jr EPC with EXL <- 0 |
| 428 | }}} |
| 429 | {{{#!protected ------------------------------------------------------------------------------------ |
| 430 | '' |
| 431 | {{{#!c |
| 432 | // TODO1: remplacez "mtc0 $0, $12" par 2 autres pour mettre 1 dans les bits c0_sr.HWI0 et c0_sr.IE |
| 433 | li $26, 0x401 // next value of SR |
| 434 | mtc0 $26, $12 // SR <- kernel-mode with INT (HWI0=1 UM=0 ERL=0 EXL=0 IE=1) |
| 435 | |
| 436 | // TODO2: Il faut mettre 0 dans SR pour masquer les interruptions |
| 437 | mtc0 $0, $12 // SR <- kernel-mode without INT (UM=0 ERL=0 EXL=0 IE=0) |
| 438 | }}} |
| 439 | '' |
| 440 | }}} |
| 441 | 1. Ouvrez le fichier `kernel/kinit.c`. Dans cette fonction, on appelle `archi_init()` avec en paramètre un nombre qui va servir de période d'horloge. Le simulateur de la plateforme sur les machines de la PPTI va environ à 3.5MHz. Combien de secondes demande-t-on dans ce code ? |