Skip to content
Snippets Groups Projects
Commit af092e67 authored by valentin's avatar valentin
Browse files

Ajout code exercice 2

parent e88e4794
Branches
No related tags found
No related merge requests found
...@@ -9,17 +9,23 @@ ...@@ -9,17 +9,23 @@
.global switch_to_user_mode .global switch_to_user_mode
.extern user_stack DATA // this adress can be read like: ldr Rx, =user_stack .extern user_stack DATA // this adress can be read like: ldr Rx, =user_stack
switch_to_user_mode: switch_to_user_mode:
// Charge la valeur 3 dans r0 pour configurer le registre CONTROL
mov r0, #3 mov r0, #3
mov r3, USER_STACK_SIZE
lsl r3, #2 // r3 = USER_STACK_SIZE * 4 // Charge l'adresse du tableau user_stack dans r1
ldr r1, =user_stack ldr r1, =user_stack
add r1, r1, r3
// Déplace l'adresse de user_stack dans le registre PSP (Process Stack Pointer)
msr psp, r1 msr psp, r1
msr control, r0
// Configure le registre CONTROL pour passer en mode utilisateur
msr control, r0 // Bits [0:1] pour le mode utilisateur (p.721)
// Instruction de synchronisation entre les pipelines d'instructions
isb isb
// Saut indirect vers l'adresse contenue dans le registre lr (return address)
bx lr bx lr
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "user_cmd.h" #include "user_cmd.h"
#include "uart.h" #include "uart.h"
// Definition du registre MMFAR
#define MMFAR *(unsigned *)0xE000ED34 #define MMFAR *(unsigned *)0xE000ED34
unsigned user_stack[USER_STACK_SIZE]; unsigned user_stack[USER_STACK_SIZE];
...@@ -33,17 +33,34 @@ int *p_sram2=(int *)0x2007c000, a, *p_out_of_mem=(int *)0x80000; ...@@ -33,17 +33,34 @@ int *p_sram2=(int *)0x2007c000, a, *p_out_of_mem=(int *)0x80000;
void switch_to_user_mode(); void switch_to_user_mode();
void asm_test_fault(); void asm_test_fault();
// Tableau global contenant les adresses provoquant une erreur
uint32_t error_adresses[100]; uint32_t error_adresses[100];
uint32_t error_count = 0; uint32_t error_count = 0;
uint32_t error_codes[100]; uint32_t error_codes[100];
void MemManage_Handler() void MemManage_Handler()
{ {
// Sauvegarde de l'adresse de l'erreur
error_adresses[error_count] = MMFAR; error_adresses[error_count] = MMFAR;
// Sauvegarde du code de l'erreur dans le registre CFSR
error_codes[error_count] = SCB->CFSR; error_codes[error_count] = SCB->CFSR;
SCB->CFSR = 0xFFFF;
// Affichage du code d'erreur en binaire sur les LEDs
LPC_GPIO2->FIOPIN = error_count; LPC_GPIO2->FIOPIN = error_count;
// Incrémente l'index de l'erreur
error_count++; error_count++;
// Acknowledge du registre CFSR
SCB->CFSR = 0xFFFF;
__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
"str r1, [r0, #24]\n"
);
} }
...@@ -61,10 +78,10 @@ void test_user_mode() ...@@ -61,10 +78,10 @@ void test_user_mode()
int n; int n;
for (n=0; n<3; n++); // OK 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=LPC_GPIO2->FIOPIN; // OK
a=*p_sram2; // OK (unprivileged read only) 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) n=LPC_TIM0->TC; // not OK (privileged access only)
} }
struct __FILE { int handle; /* Add whatever you need here */ }; struct __FILE { int handle; /* Add whatever you need here */ };
...@@ -76,62 +93,263 @@ unsigned simulated_memory_space[MAX_MEMORY_SIZE]; ...@@ -76,62 +93,263 @@ unsigned simulated_memory_space[MAX_MEMORY_SIZE];
int main(void) int main(void)
{ {
SCB->SHCSR |= (1 << 16);
// MPU configuration here... // MPU configuration here...
// Region 0 (Flash) /*___________________________________________________________________________________________________*/
MPU->RNR = 0; // Region 0 (flash) :
MPU->RBAR = 0x00000000; // Taille : 512 KB (524288 bytes)
MPU->RASR = 0x5 << 24; // Type de mémoire : Non partagée, normal
MPU->RASR = 0x01 << 19; // Type d'accès : Read
MPU->RASR = 9<<1; //car log2(512) = 9
MPU->RASR = 0x1; MPU->RNR = 0; // ID de la region
// Region 1 (SRAM1) // N = Log2(Region size in bytes)
MPU->RNR = 1; MPU->RBAR = (0x00000000);
MPU->RBAR = 0x10000000;
MPU->RASR = 0x3 << 24; // Reset des bits + enable
MPU->RASR = 0x01 << 19; MPU->RASR = (1 << 0); // ENABLE
MPU->RASR = 5<<1; //car log2(32) = 5
MPU->RASR = 0x1; // Définition taille de région (Region size in bytes) = 2^(SIZE+1)
// 524288 = 2^(SIZE+1) --> SIZE = 18
// Region 2 (SRAM1) MPU->RASR |= (18<<1); // SIZE
MPU->RNR = 2;
MPU->RBAR = 0x2007C000; // Active toutes les sub-régions
MPU->RASR = 0x2 << 24; // MPU->RASR &= (255 << 8); // SRD
MPU->RASR = 0x01 << 19;
MPU->RASR = 5<<1; // Mémoire non-partagée
MPU->RASR = 0x1; // Outer and inner noncacheable
// MPU->RASR |= (0 << 16); // B
// MPU->RASR |= (0 << 17); // C
// Region 3 (GPIO) // MPU->RASR |= (0 << 18); // S
MPU->RNR = 3; MPU->RASR |= (0b001 << 19); // TEX
MPU->RBAR = 0x2009C000;
MPU->RASR = 0x2 << 24; // Read-only avec ou sans permissions
MPU->RASR = 0x02 << 19; MPU->RASR |= (0b110 << 24); // AP
MPU->RASR = 4<<1;
MPU->RASR = 0x1; // Désactivation des instructions
// MPU->RASR |= (0b101 << 28); // XN
// Region 4 (périphériques dont timers) /*___________________________________________________________________________________________________*/
MPU->RNR = 4; // Region 1 (SRAM1) :
MPU->RBAR = 0x40000000; // Taille : 32 KB (32768 bytes)
MPU->RASR = 0x1 << 24; // Type de mémoire : Non partagée, normal
MPU->RASR = 0x02 << 19; // Type d'accès : Read / Write
MPU->RASR = 5<<1; MPU->RNR = 1; // ID de la region
MPU->RASR = 0x1;
// Registre RBAR à verifier
// MPU->RBAR = (0 << 4); // RNR modifié manuellement
// Region 5 (UART)
MPU->RNR = 5; // N = Log2(Region size in bytes)
MPU->RBAR = 0x4000C000; MPU->RBAR = (0x10000000);
MPU->RASR = 0x3 << 24;
MPU->RASR = 0x02 << 19; // Reset des bits + enable
MPU->RASR = 9<<1; MPU->RASR = (1 << 0); // ENABLE
MPU->RASR = 0x1;
// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
// 32768 = 2^(SIZE+1) --> SIZlrE = 14
MPU->CTRL |= 0x5; MPU->RASR |= (14<<1); // SIZE
// Active toutes les sub-régions
// MPU->RASR &= (255 << 8); // SRD
// Mémoire non-partagée
// Outer and inner noncacheable
// MPU->RASR |= (0 << 16); // B
// MPU->RASR |= (0 << 17); // C
// MPU->RASR |= (0 << 18); // S
MPU->RASR |= (0b001 << 19); // TEX
// Full access
MPU->RASR |= (0b011 << 24); // AP
// Désactivation des instructions
// MPU->RASR |= (0b101 << 28); // XN
/*___________________________________________________________________________________________________*/
// Region 2 (SRAM2) :
// Taille : 16 KB (16384 bytes)
// Type de mémoire : Non partagée, normal
// Type d'accès : Read / Write en mode privilégié, Read sinon
MPU->RNR = 2; // ID de la region
// Registre RBAR à verifier
// MPU->RBAR = (0 << 4); // RNR modifié manuellement
// N = Log2(Region size in bytes)
MPU->RBAR = (0x2007C000);
// Reset des bits + enable
MPU->RASR = (1 << 0); // ENABLE
// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
// 16384 = 2^(SIZE+1) --> SIZE = 13
MPU->RASR |= (13<<1); // SIZE
// Active toutes les sub-régions
// MPU->RASR &= (255 << 8); // SRD
// Mémoire non-partagée
// Outer and inner noncacheable
// MPU->RASR |= (0 << 16); // B
// MPU->RASR |= (0 << 17); // C
// MPU->RASR |= (0 << 18); // S
MPU->RASR |= (0b001 << 19); // TEX
// Read-write avec permissions, read-only sans permissions
MPU->RASR |= (0b010 << 24); // AP
// Désactivation des instructions
// MPU->RASR |= (0b101 << 28); // XN
/*___________________________________________________________________________________________________*/
// Region 3 (SRAM2) :
// Taille : 16 KB (16384 bytes)
// Type de mémoire : Non partagée, normal
// Type d'accès : Read / Write en mode privilégié, Read sinon
MPU->RNR = 3; // ID de la region
// Registre RBAR à verifier
// MPU->RBAR = (0 << 4); // RNR modifié manuellement
// N = Log2(Region size in bytes)
MPU->RBAR = (0x20080000);
// Reset des bits + enable
MPU->RASR = (1 << 0); // ENABLE
// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
// 16384 = 2^(SIZE+1) --> SIZE = 13
MPU->RASR |= (13<<1); // SIZE
// Active toutes les sub-régions
// MPU->RASR &= (255 << 8); // SRD
// Mémoire non-partagée
// Outer and inner noncacheable
// MPU->RASR |= (0 << 16); // B
// MPU->RASR |= (0 << 17); // C
// MPU->RASR |= (0 << 18); // S
MPU->RASR |= (0b001 << 19); // TEX
// Read-write avec permissions, read-only sans permissions
MPU->RASR |= (0b010 << 24); // AP
// Désactivation des instructions
// MPU->RASR |= (0b101 << 28); // XN
/*___________________________________________________________________________________________________*/
// Region 4 (GPIO) :
// Taille : 16 KB (16384 bytes)
// Type de mémoire : Non partagée, device
// Type d'accès : Read / Write en mode privilégié, Read sinon
MPU->RNR = 4; // ID de la region
// Registre RBAR à verifier
// MPU->RBAR = (0 << 4); // RNR modifié manuellement
// N = Log2(Region size in bytes)
MPU->RBAR = (0x2009C000);
// Reset des bits + enable
MPU->RASR = (1 << 0); // ENABLE
// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
// 16384 = 2^(SIZE+1) --> SIZE = 13
MPU->RASR |= (13<<1); // SIZE
// Active toutes les sub-régions
// MPU->RASR &= (255 << 8); // SRD
// Mémoire non-partagée
// MPU->RASR |= (0 << 16); // B
// MPU->RASR |= (0 << 17); // C
// MPU->RASR |= (0 << 18); // S
MPU->RASR |= (0b010 << 19); // TEX
// Read-write avec permissions, read-only sans permissions
MPU->RASR |= (0b010 << 24); // AP
// Désactivation des instructions
// MPU->RASR |= (0b101 << 28); // XN
/*___________________________________________________________________________________________________*/
// Region 5 (périphériques dont timers) :
// Taille : 32 KB (32768 bytes)
// Type de mémoire : Non partagée, device
// Type d'accès : Read / Write en mode privilégié uniquement
MPU->RNR = 5; // ID de la region
// Registre RBAR à verifier
// MPU->RBAR = (0 << 4); // RNR modifié manuellement
// N = Log2(Region size in bytes)
MPU->RBAR = (0x40000000);
// Reset des bits + enable
MPU->RASR = (1 << 0); // ENABLE
// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
// 32768 = 2^(SIZE+1) --> SIZE = 14
MPU->RASR |= (14<<1); // SIZE
// Active toutes les sub-régions
// MPU->RASR &= (255 << 8); // SRD
// Mémoire non-partagée, device
// MPU->RASR |= (0 << 16); // B
// MPU->RASR |= (0 << 17); // C
// MPU->RASR |= (0 << 18); // S
MPU->RASR |= (0b010 << 19); // TEX
// Read-write avec permissions uniquement
MPU->RASR |= (0b001 << 24); // AP
// Désactivation des instructions
// MPU->RASR |= (0b101 << 28); // XN
/*___________________________________________________________________________________________________*/
// Region 6 (UART) :
// Taille : 16 KB (16384 bytes)
// Type de mémoire : Non partagée, device
// Type d'accès : Read / Write
MPU->RNR = 6; // ID de la region
// Registre RBAR à verifier
// MPU->RBAR = (0 << 4); // RNR modifié manuellement
// N = Log2(Region size in bytes)
MPU->RBAR = (0x4000C000);
// Reset des bits + enable
MPU->RASR = (1 << 0); // ENABLE
// Définition taille de région (Region size in bytes) = 2^(SIZE+1)
// 16384 = 2^(SIZE+1) --> SIZE = 13
MPU->RASR |= (13<<1); // SIZE
// Active toutes les sub-régions
// MPU->RASR &= (255 << 8); // SRD
// Mémoire non-partagée
// MPU->RASR |= (0 << 16); // B
// MPU->RASR |= (0 << 17); // C
// MPU->RASR |= (0 << 18); // S
MPU->RASR |= (0b010 << 19); // TEX
// Full access
MPU->RASR |= (0b011 << 24); // AP
// Désactivation des instructions
// MPU->RASR |= (0b101 << 28); // XN
// Activation de l’exception de gestion d’erreur mémoire MemManage_Handler()
SCB->SHCSR |= (1 << 16); // MEMFAULTENA
MPU->CTRL |= (1<<0); // Enables MPU
LPC_GPIO2->FIODIR = 0xff;
LPC_GPIO2->FIOPIN = 0xf;
// testing memory accesses in supervisor mode: // testing memory accesses in supervisor mode:
// test_supervisor_mode(); // to be removed after checking // test_supervisor_mode(); // to be removed after checking
......
/*
* user_interpreter.c
*
* Created on: 12 nov. 2023
* Author: Vincent
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdarg.h>
#include "uart.h"
#include "user_cmd.h"
#define MAX_INPUT_LENGTH 200 #define PRINT_SYNTAX_ERROR() PRINT("Syntax error! Expected syntax is either <8 characters hexadecimal address> for reading\n or " \
#define MAX_ERRORS 20 "<8 characters hexadecimal address>=<8 characters hexadecimal value> for writing\n");
bool is_supervisor_mode=false;
// Fausse mémoire et compteur d'erreur pour la simulation
unsigned simulated_memory_space[1024] = {0};
unsigned fault_address_buffer[MAX_ERRORS] = {0};
unsigned fault_code_buffer[MAX_ERRORS] = {0};
unsigned fault_count = 0;
bool is_supervisor_mode = false; // false pour le mode utilisateur, true pour le mode superviseur
// Prototypes de fonctions pour la commutation de mode et l'affichage des erreurs
void switch_mode();
void display_status();
unsigned read_memory(unsigned addr);
void write_memory(unsigned addr, unsigned value);
void SVC_Handler() void SVC_Handler()
{ {
...@@ -25,72 +23,53 @@ void SVC_Handler() ...@@ -25,72 +23,53 @@ void SVC_Handler()
} }
// Fonction pour basculer entre les modes utilisateur et superviseur void exec_user_read_write()
void switch_mode() { {
is_supervisor_mode = !is_supervisor_mode; char str[200];
printf("Switched to %s mode.\n", is_supervisor_mode ? "Supervisor" : "User"); int i=0, coma_nb=0, value_idx;
} unsigned addr, value;
// Fonction pour afficher les erreurs d'accès mémoire PRINT("Write an hexadecimal address for reading <addr> or <addr>,<value> for writing (%s):\n", is_supervisor_mode?"Supervisor":"User");
void display_status() {
if (fault_count == 0) {
printf("No access errors recorded.\n");
} else {
printf("Access errors recorded:\n");
for (unsigned i = 0; i < fault_count; ++i) {
printf("Error %u: Address: 0x%08X, Code: 0x%08X\n", i, fault_address_buffer[i], fault_code_buffer[i]);
}
}
}
// Modifiez les fonctions read_memory et write_memory pour inclure la validation de la MPU fflush(stdin);
unsigned read_memory(unsigned addr) { fscanf(stdin, "%s",str);
if (!validate_mpu_address(addr)) {
printf("MPU violation: Read access denied for address 0x%08X.\n", addr); for (i=0; i<strlen(str); i++)
return 0; // Retourne 0 pour indiquer un échec de lecture {
if (str[i] == ',')
{
if (i==0 || ++coma_nb>1)
{
PRINT_SYNTAX_ERROR();
return;
} }
return simulated_memory_space[addr]; // Lecture réussie str[i]=0;
value_idx=i+1;
} else if (!isxdigit(str[i]))
{
PRINT_SYNTAX_ERROR();
return;
} }
void write_memory(unsigned addr, unsigned value) {
if (!validate_mpu_address(addr)) {
printf("MPU violation: Write access denied for address 0x%08X.\n", addr);
return; // Échec de l'écriture, sortie anticipée
} }
simulated_memory_space[addr] = value; // Écriture réussie if ((coma_nb&(i<2)) || i>17)
}void exec_user_read_write() { {
char input[MAX_INPUT_LENGTH]; PRINT_SYNTAX_ERROR();
unsigned addr, value; PRINT("(Bad length!)");
printf("Enter command (%s mode): ", is_supervisor_mode ? "Supervisor" : "User");
if (fgets(input, sizeof(input), stdin) == NULL) {
printf("Error reading input.\n");
return; return;
} }
// Enlever le caractère de nouvelle ligne si présent sscanf(str, "%x", &addr);
input[strcspn(input, "\n")] = '\0'; if (!coma_nb) // if read
{
// Traitement des commandes "switch" et "status" PRINT("reading address: 0x%08x\n", addr);
if (strcmp(input, "switch") == 0) { PRINT("value read: 0x%08x\n", *(unsigned *)addr);
switch_mode();
} else if (strcmp(input, "status") == 0) {
display_status();
} else {
char *comma = strchr(input, ',');
if (comma) {
*comma = '\0'; // Séparer la chaîne en deux parties
addr = strtoul(input, NULL, 16);
value = strtoul(comma + 1, NULL, 16);
write_memory(addr, value);
printf("Written 0x%08X to address 0x%08X\n", value, addr);
} else if (isxdigit(input[0])) {
addr = strtoul(input, NULL, 16);
value = read_memory(addr);
printf("Value at address 0x%08X: 0x%08X\n", addr, value);
} else {
printf("Syntax error! Please check your input format.\n");
} }
else // write
{
sscanf(str+value_idx, "%x", &value);
PRINT("writing address: 0x%08x with 0x%08x\n", addr, value);
*(unsigned *)addr=value;
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment