diff --git a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c index 3e7bd270e72639dfc2f82c957c590746be578ba9..27e16844ac1468844e082c022f6ba119151bfe07 100644 --- a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c +++ b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c @@ -55,17 +55,19 @@ void MemManage_Handler() // Acknowledge du registre CFSR SCB->CFSR = 0xFFFF; - // Instructions assembleur foncionnelles // __asm volatile( -// "mrs r0, psp\n" -// "ldr r1, =user_starting_address\n" // recup le pointeur vers l'adresse de retour souhaitée -// "ldr r1, [r1]\n" // deref le pointeur pour recup l'adresse de retour +// "mrs r0, psp\n" // Charger la valeur du pointeur de pile du processus (PSP) dans r0 +// "ldr r1, =user_starting_address\n" // Charger l'adresse de user_starting_address dans r1 +// // Cette adresse est actuellement stockée comme une valeur immédiate +// "ldr r1, [r1]\n" // Dé-référencer le pointeur pour obtenir la véritable adresse de retour +// // Maintenant, r1 contient l'adresse souhaitée de retour // ); -// Instruction assembleur : Crée un hardfault + +// Instruction assembleur, erreur : crée un hardfault // __asm volatile( -// "str r1, [r0, #24]\n" +// "str r1, [r0, #24]\n" // Stocker la valeur de r1 à l'adresse PSP + 24 (espace réservé pour le registre PC) // ); } @@ -84,10 +86,10 @@ void test_user_mode() int n; for (n=0; n<3; n++); // OK -// LPC_GPIO2->FIOPIN=0xaa; // not OK (read only) + LPC_GPIO2->FIOPIN=0xaa; // not OK (read only) a=LPC_GPIO2->FIOPIN; // OK a=*p_sram2; // OK (unprivileged read only) -// *p_sram2=5; // not OK (privileged only for writing) + *p_sram2=5; // not OK (privileged only for writing) n=LPC_TIM0->TC; // not OK (privileged access only) } struct __FILE { int handle; /* Add whatever you need here */ }; diff --git a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c index 0905fd257988326730be5fcce818ccd6b6596447..af382e021eec6a9d2055395093cd50b449daf72e 100644 --- a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c +++ b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c @@ -17,9 +17,30 @@ "<8 characters hexadecimal address>=<8 characters hexadecimal value> for writing\n"); bool is_supervisor_mode=false; +extern uint32_t * error_adresses; +extern uint32_t * error_codes; +extern uint32_t error_count; + +extern void switch_to_user_mode(); + void SVC_Handler() { - // to be filled for exercise 4 + // Si le mode superviseur est actif + if (is_supervisor_mode) + { + // Passe en mode utilisateur + switch_to_user_mode(); + } + else + { + // Active le mode superviseur en écrivant 0 dans le registre controle + __asm volatile( + "mov r0, #0\n" + "msr control, r0\n" + ); + } + + is_supervisor_mode = !is_supervisor_mode; } @@ -34,41 +55,59 @@ void exec_user_read_write() fflush(stdin); fscanf(stdin, "%s",str); - for (i=0; i<strlen(str); i++) + // Si l'utilisateur entre la commande switch + if (strcmp(str, "switch") == 0) + { + __asm volatile("svc 0\n"); + } + // Si l'utilisateur entre la commande status + else if (strcmp(str, "status") == 0) { - if (str[i] == ',') + PRINT("Error list (total : %d) :\n", error_count); + for (int i = 0; i < error_count; i++) { - if (i==0 || ++coma_nb>1) + PRINT("%d) Error address : %d | Code : %d\n", i, error_adresses[i], error_codes[i]); + } + } + // Si l'utilisateur entre n'importe quelle autre commande + else + { + for (i=0; i<strlen(str); i++) { - PRINT_SYNTAX_ERROR(); - return; + if (str[i] == ',') + { + if (i==0 || ++coma_nb>1) + { + PRINT_SYNTAX_ERROR(); + return; + } + str[i]=0; + value_idx=i+1; + } else if (!isxdigit(str[i])) + { + PRINT_SYNTAX_ERROR(); + return; + } } - str[i]=0; - value_idx=i+1; - } else if (!isxdigit(str[i])) + if ((coma_nb&(i<2)) || i>17) { PRINT_SYNTAX_ERROR(); + PRINT("(Bad length!)"); return; } - } - if ((coma_nb&(i<2)) || i>17) - { - PRINT_SYNTAX_ERROR(); - PRINT("(Bad length!)"); - return; - } - sscanf(str, "%x", &addr); - if (!coma_nb) // if read - { - PRINT("reading address: 0x%08x\n", addr); - PRINT("value read: 0x%08x\n", *(unsigned *)addr); - } - else // write - { - sscanf(str+value_idx, "%x", &value); - PRINT("writing address: 0x%08x with 0x%08x\n", addr, value); - *(unsigned *)addr=value; + sscanf(str, "%x", &addr); + if (!coma_nb) // if read + { + PRINT("reading address: 0x%08x\n", addr); + PRINT("value read: 0x%08x\n", *(unsigned *)addr); + } + else // write + { + sscanf(str+value_idx, "%x", &value); + PRINT("writing address: 0x%08x with 0x%08x\n", addr, value); + *(unsigned *)addr=value; + } } }