diff --git a/MMUConfig.h b/MMUConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..b5b8ee52e050bd0b9a64442e51effc56eb4ae1fc --- /dev/null +++ b/MMUConfig.h @@ -0,0 +1,8 @@ +#define MMU_ENABLE 1 +#define MMU_IRQ 13 +#define MMU_CMD 0x66 +#define MMU_FAULT_ADDR 0xCD +#define TLB_ADD_ENTRY 0xCE +#define TLB_DEL_ENTRY 0xDE +#define TLB_SIZE 32 +#define TLB_ENTRIES 0x800 diff --git a/MMUConfig.ini b/MMUConfig.ini new file mode 100644 index 0000000000000000000000000000000000000000..a35ae179c5ca41d974647291bb24bff714b6dfff --- /dev/null +++ b/MMUConfig.ini @@ -0,0 +1,135 @@ +# $Id: hardware.ini 114 2009-12-01 13:06:43Z simon_duquennoy $ +#------------------------------------------------------------ + +# +# Hardware.cfg +# Fichier de configuration du simulateur de mat�riel +# + +# +# Trace de Debug +# +# define DEBUG_SETUP 0x0001 /* trace hardware setup */ +# define DEBUG_IT 0x0010 /* trace interruptions generation */ +# define DEBUG_REG 0x0100 /* trace hardware register access */ +# define DEBUG_WARNING 0x1000 /* trace hardware warning messages */ +DEBUG = 0x0000 + +# +# Configuration des param�tres de base du simulateur +# +SYSTICK = 1000 # delais entre deux ticks du simulateur (en micro-seconde) + +# +# Configuration des mat�riels r�seau +# +# configuration des ports COM (port serie de type RS232) +# > Port Serie n�1 +SL1_ENABLE = 0 # SL1_ENABLE = 0 => simulation lien serie d�sactiv�e +SL1 = "chimay.lifl.fr" # Machine connect� � la sortie du lien serie n�1 +SL1_COM = 1 # destinataire 1 = lien serie "com1", 2 = lien serie "com2" +SL1_NOISE = 500 # bruit de la ligne 0-999 (exprim� en /1000 d'erreur) +SL1_IRQ = 4 # niveau d'interruption de l'UART serie n�1 +SL1_UARTSR = 0x3F8 # registre de status de l'UART serie n�1 +SL1_UARTDATA = 0x3FA # registre d'entr�e sortie de l'UART serie n�1 +SL1_UDPPORT = 1500 # port UDP "r�el" utiliser pour simulation serie n�1 +# > Port Serie n�2 +SL2_ENABLE = 0 # SL2_ENABLE = 0 => simulation lien serie d�sactiv�e +SL2 = "ldx2" # Machine connect� � la sortie du lien serie n�2 +SL2_COM = 2 # destinataire 1 = lien serie "com1", 2 = lien serie "com2" +SL2_NOISE = 0 # bruit de la ligne 0-999 (exprim� en /1000 d'erreur) +SL2_IRQ = 5 # niveau d'interruption de l'UART serie n�2 +SL2_UARTSR = 0x3FC # registre de status de l'UART serie n�2 +SL2_UARTDATA = 0x3FE # registre d'entr�e sortie de l'UART serie n�2 +SL2_UDPPORT = 1501 # port UDP "r�el" utiliser pour simulation serie n�2 +# > Configuration de la carte Ethernet +ENABLE_ETHERNET = 0 # ENABLE_ETHERNET = 0 => simulation ethernet d�sactiv�e +Eth0_Link = 1 # num de cable de connexion de la carte Eth0 +Eth0_DMASR = 0xE800 # registre de status de la carte Ethernet +Eth0_DMABASE = 0xE804 # adresse de base pour le vidage d'un paquet +Eth0_DMASIZE = 0xE808 # adresse limite pour le vidage d'un paquet +Eth0_IRQ = 9 # niveau d'interruption de la carte. +Eth0_MCADR = "225.0.0.1" # adresse multicast utilis�e pour la simulation ethernet +Eth0_UDPPORT = 1502 # port UDP utilis� pour la simulation ethernet + +# +# Configuration des disques durs +# + +# > Disque dur IDE Maitre +ENABLE_HDA = 1 # ENABLE_HD = 0 => simulation du disque d�sactiv�e +HDA_FILENAME = "vdiskA.bin" # nom du fichier de stockage du disque simul� +HDA_CMDREG = 0x3F6 # registre de commande du disque maitre +HDA_DATAREGS = 0x110 # base des registres de donn�es (r,r+1,r+2,...r+7) +HDA_IRQ = 14 # Interruption du disque +HDA_MAXCYLINDER = 16 # Nombre de pistes du disque ma�tre +HDA_MAXSECTOR = 16 # Nombre de secteurs du disque ma�tre +HDA_SECTORSIZE = 32 # Taille (en octet) d'un secteur du disque ma�tre +HDA_STPS = 2 # nombre de SYSTICK pour changer de secteur +HDA_STPC = 1 # nombre de SYSTICK pour changer de piste +HDA_PON_DELAY = 30 # nombre de SYSTICK avant amorce du disque +HDA_POFF_DELAY = 30 # nombre de SYSTICK avant arret du disque + +# > Disque dur IDE Esclave +ENABLE_HDB = 1 # ENABLE_HD = 0 => simulation du disque d�sactiv�e +HDB_FILENAME = "vdiskB.bin" # nom du fichier de stockage du disque simul� +HDB_CMDREG = 0x376 # registre de commande du disque esclave +HDB_DATAREGS = 0x170 # base des registres de donn�es (r,r+1,r+2,...r+7) +HDB_IRQ = 15 # Niveau d'interruption du disque +HDB_MAXCYLINDER = 16 # Nombre de pistes du disque esclave +HDB_MAXSECTOR = 16 # Nombre de secteurs du disque esclave +HDB_SECTORSIZE = 512 # Taille (en octet) d'un secteur du disque esclave +HDB_STPS = 2 # nombre de SYSTICK pour changer de secteur +HDB_STPC = 3 # nombre de SYSTICK pour changer de piste +HDB_PON_DELAY = 30 # nombre de SYSTICK avant amorce du disque +HDB_POFF_DELAY = 30 # nombre de SYSTICK avant arret du disque + +# +# Configuration de l'horologe interne +# +TIMER_CLOCK = 0xF0 # registre de lecture de la date courante (en ms) +TIMER_PARAM = 0xF4 # registre de configuration du TIMER + # bit 7 : RESET general (=1) + # bit 6 : Alarm ON = 1, Alarm OFF = 0 + # bit 5 : Declanche la division Hz du Timer (=1) + # bit 4 \ Si le division Hz du timer est demand� : + # bit 3 / 00: 1 top d'alarme pour 1 tops d'horloge , + # 01: 1 top d'alarme pour 8 tops d'horloge , + # 10: 1 top d'alarme pour 64 tops d'horloge , + # 11: 1 top d'alarme pour 512 tops d'horloge. + # bit 2 - R.F.U. - + # bit 1 \ Lecture d'un �tat interne de l'alarme + # bit 0 / 00: Alarme Courante, + # 01: Division Hz, + # 10: Ticks/Sec + # 11: niveau d'interruption de l'horloge +TIMER_ALARM = 0xF8 # registre de generation d'interruption +TIMER_IRQ = 2 # Niveau d'interruption de l'horologe +TIMER_TICKS = 1 # Nombre de SYSTICKS par tick d'horloge + +# +# Configuration de la MMU +# +MMU_ENABLE = 1 # MMU_ENABLE = 0 => simulation de la MMU d�sactiv�e +MMU_IRQ = 13 # Niveau d'interruption de la MMU +MMU_CMD = 0x66 # Registre de commande de la MMU +MMU_FAULT_ADDR_HI = 0xCD # Registre contenant l'adresse m�moire ayant provoqu� une faute +MMU_FAULT_ADDR_LO = 0xCC +TLB_ADD_ENTRY = 0xCE # Registre de commande d'ajout d'entr�e dans la TLB + # attend une valeur de la forme : + # struct tlb_entry_s { + # unsigned unused: 8; + # unsigned virt_page: 12; + # unsigned phys_page: 8; + # unsigned access_type: 3; + # unsigned is_active: 1; + #}; + # le nouveau mapping est ajout� dans la TLB, + # provoquant �ventuellement l'�crasement d'une ancienne entr�e +TLB_DEL_ENTRY = 0xDE # Registre de commande de suppression d'entr�e dans la TLB + # seul phys_page est lu, et toutes les entr�e + # correspondant � cette page physicique sont supprim�es de la TLB +TLB_SIZE = 32 # Number of entries in the TLB +TLB_ENTRIES = 0x800 # Registre contenant les entr�es de la TLB (32 bits par entr�e) + # Accessible en lecture comme en �criture avec le m�me format que + # celui utilis� par TLB_ADD_ENTRY diff --git a/Makefile b/Makefile index f1c8d50ee6f6b957cec2e113765f2e5366893b2b..9512dbac599f953d7443a73862419a2f822af8ff 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ INC=-I/vagrant/ASE/ordonnancement/x86-64/include LIB=-L/vagrant/ASE/ordonnancement/x86-64/lib -lhardware -all: try_mul pingpong pingpongpang +all: try_mul pingpong pingpongpang mi_kernel display_stack : display_stack.o gcc -o $@ $^ $(LIB) @@ -15,8 +15,11 @@ pingpong : try.o pingpong.o pingpongpang : try.o pingpongpang.o gcc -o $@ $^ $(LIB) +mi_kernel : mi_user.o mi_kernel.o + gcc -o $@ $^ $(LIB) + %.o:%.c gcc $(INC) -c $< clean: - rm -f *.o *.s display_stack try_mul pingpong pingpongpang vdisk?.bin \ No newline at end of file + rm -f *.o *.s display_stack try_mul pingpong pingpongpang vdisk?.bin mi_kernel \ No newline at end of file diff --git a/mi_kernel.c b/mi_kernel.c new file mode 100644 index 0000000000000000000000000000000000000000..f2ff8a1b7892c398ab24152a33e2cd20c0382cf2 --- /dev/null +++ b/mi_kernel.c @@ -0,0 +1,85 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "hardware.h" +#include "mi_kernel.h" +#include "mi_user.h" +#include "MMUConfig.h" +#include "mi_syscall.h" + +int current_process = 0; + +void mmu_handler() +{ + tlb_entry_t tlb; + long int vaddr = ((long int)_in(MMU_FAULT_ADDR_HI) << 32) | (_in(MMU_FAULT_ADDR_LO) & 0xFFFFFFFF); + long int vpage = (vaddr >> 12) & 0xFFF; + long int ppage = ppage_of_vpage(current_process, vpage); + + //printf("%lx, %lx, %lx, %lx, %d\n", vpage, ppage, vaddr, (long int)virtual_memory, current_process); + if (vaddr < ((long int)virtual_memory) || vaddr > ((long int)virtual_memory) + VM_SIZE || ppage == -1) + { + fprintf(stderr, "Echec"); // TODO + exit(EXIT_FAILURE); + } + + tlb.s.tlb_vpage = vpage; + tlb.s.tlb_ppage = ppage; + tlb.s.tlb_rwx = 7; + tlb.s.tlb_used = 1; + + _out(TLB_ADD_ENTRY, tlb.i); + //_out(TLB_ADD_ENTRY, *(int *)(&tlb)); +} + +void switch_to_process0(void) +{ + current_process = 0; + _out(MMU_CMD, MMU_RESET); +} + +void switch_to_process1(void) +{ + current_process = 1; + _out(MMU_CMD, MMU_RESET); +} + +void init() +{ + if (init_hardware("MMUConfig.ini") == 0) + { + fprintf(stderr, "ERROR INITHARDWARE"); + exit(EXIT_FAILURE); + } + IRQVECTOR[16] = switch_to_process0; + IRQVECTOR[17] = switch_to_process1; + IRQVECTOR[MMU_IRQ] = mmu_handler; +} + +int ppage_of_vpage(int process, unsigned vpage) +{ + if (vpage < N) + { + if (process == PROCESS_0) + return 2 * vpage + 2; + if (process == PROCESS_1) + return 2 * vpage + 1; + } + + return -1; +} + +void main_master(void) +{ + init(); + IRQVECTOR[16] = switch_to_process0; + IRQVECTOR[17] = switch_to_process1; +} + +int main(int argc, char **argv) +{ + + main_master(); + _mask(0x1001); // Basculer mode utilisateur + main_user(); +} diff --git a/process.h b/mi_kernel.h similarity index 68% rename from process.h rename to mi_kernel.h index ea0b40b301048d594cdfe10fdcb48bbf5dd1afe7..04dd6044e2728308cb05f8c76744bdba9343b94d 100644 --- a/process.h +++ b/mi_kernel.h @@ -1,14 +1,12 @@ -#if !defined(PROCESS) -#define PROCESS - -#define PROCESS_1 1 -#define PROCESS_0 0 -#define N 127 -#define VM_SIZE 160000 * 8 +#if !defined(MI_KERNEL) +#define MI_KERNEL +#define VM_SIZE 16000000 #define MMU_FAULT_ADDR_LO 0xCC #define MMU_FAULT_ADDR_HI 0xCD -#define TLB_ADD_ENTRY 0xCE + +#define PROCESS_1 1 +#define PROCESS_0 0 struct tlb_entry_s { @@ -27,8 +25,12 @@ union tlb_entry_u typedef union tlb_entry_u tlb_entry_t; -int ppage_of_vpage(int process, unsigned vpage); - void mmu_handler(); -#endif // PROCESS +void switch_to_process0(void); + +void switch_to_process1(void); + +void main_master(void); + +#endif // MI_KERNEL diff --git a/mi_syscall.h b/mi_syscall.h new file mode 100644 index 0000000000000000000000000000000000000000..9972004e458805e8696cc7c356b37fa1ef555137 --- /dev/null +++ b/mi_syscall.h @@ -0,0 +1,11 @@ +#if !defined(MI_SYSCALL) +#define MI_SYSCALL + +#define SYSCALL_SWTCH_0 16 +#define SYSCALL_SWTCH_1 17 + +#define N 127 + +void init(void); + +#endif // MI_SYSCALL diff --git a/mi_user.c b/mi_user.c new file mode 100644 index 0000000000000000000000000000000000000000..1f76de374be75e0965bb25a12c1b105eaa40cceb --- /dev/null +++ b/mi_user.c @@ -0,0 +1,38 @@ +#include <stdio.h> +#include <string.h> +#include "mi_user.h" +#include "mi_syscall.h" +#include "hardware.h" + +int sum(void *ptr) +{ + int i; + int sum = 0; + + for (i = 0; i < PAGE_SIZE * N / 2; i++) + sum += ((char *)ptr)[i]; + return sum; +} + +void main_user(void) +{ + void *ptr; + int res; + + ptr = virtual_memory; + + _int(SYSCALL_SWTCH_0); + memset(ptr, 1, PAGE_SIZE * N / 2); + + _int(SYSCALL_SWTCH_1); + memset(ptr, 3, PAGE_SIZE * N / 2); + + _int(SYSCALL_SWTCH_0); + res = sum(ptr); + + printf("Resultat du processus 0 : %d\n", res); + _int(SYSCALL_SWTCH_1); + + res = sum(ptr); + printf("Resultat processus 1 : %d\n", res); +} \ No newline at end of file diff --git a/mi_user.h b/mi_user.h new file mode 100644 index 0000000000000000000000000000000000000000..a5e8ac542393e1ce8f436eef7e47551cee86d2ba --- /dev/null +++ b/mi_user.h @@ -0,0 +1,12 @@ +#if !defined(MI_USER) +#define MI_USER + +#define PAGE_SIZE 4000 + +int ppage_of_vpage(int process, unsigned vpage); + +int sum(void *ptr); + +void main_user(void); + +#endif // MI_USER diff --git a/process.c b/process.c deleted file mode 100644 index 60ff9e79feb9a88ae4047b6ee568b04938662414..0000000000000000000000000000000000000000 --- a/process.c +++ /dev/null @@ -1,40 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include "hardware.h" -#include "process.h" - -int current_process = NULL; - -int ppage_of_vpage(int process, unsigned vpage) -{ - if (vpage < N) - { - if (process == PROCESS_0) - return 2 * vpage + 2; - if (process == PROCESS_1) - return 2 * vpage + 1; - } - - return -1; -} - -void mmu_handler() -{ - tlb_entry_t tlb; - unsigned int vaddr = ((long int)_in(MMU_FAULT_ADDR_HI) << 32) | (_in(MMU_FAULT_ADDR_LO) & 0xFFFFFFFF); - unsigned int vpage = (vaddr >> 12) & 0xFFF; - unsigned int ppage = ppage_of_vpage(current_process, vpage); - - if (vaddr < virtual_memory || vaddr > virtual_memory + VM_SIZE || vpage == -1) - { - fprintf(stderr, "Echec"); - exit(EXIT_FAILURE); - } - - tlb.s.tlb_vpage = vpage; - tlb.s.tlb_ppage = ppage; - tlb.s.tlb_rwx = 7; - tlb.s.tlb_used = 1; - - _out(TLB_ADD_ENTRY, tlb.i); -} diff --git a/x86-64/lib/libhardware.a b/x86-64/lib/libhardware.a index 7b1a9ec9aef8e1f6016442b01674e62265a07f6a..738b2688a371f209faf966aee457234e0d5b4443 100644 Binary files a/x86-64/lib/libhardware.a and b/x86-64/lib/libhardware.a differ