diff --git a/swap_disk/.swap_file b/swap_disk/.swap_file
new file mode 100644
index 0000000000000000000000000000000000000000..be5f1ace884f209d3c4bb43ef627b7489e4365d0
Binary files /dev/null and b/swap_disk/.swap_file differ
diff --git a/swap_disk/Makefile b/swap_disk/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9ed04b7622012da3255fd00d99d2e6f2ed827118
--- /dev/null
+++ b/swap_disk/Makefile
@@ -0,0 +1,47 @@
+# $Id: Makefile 102 2009-11-03 13:14:39Z simon_duquennoy $
+##############################################################################
+ROOTDIR = ../x86-64/
+LIBNAME = hardware
+
+CC = gcc
+CFLAGS = -Wall -ansi -pedantic
+LIBDIR = $(ROOTDIR)
+INCDIR = -I$(ROOTDIR)/include
+LIBS = -L$(ROOTDIR)/lib -l$(LIBNAME)
+
+###------------------------------
+### Main targets
+###------------------------------------------------------------
+BINARIES= mmu_manager oracle
+
+all: $(BINARIES)
+
+###------------------------------
+### Main rules
+###------------------------------------------------------------
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $< $(INCDIR)
+
+%: %.o
+ $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+
+Makefile.depends:
+ $(CC) -MM *.c $(INCDIR) > Makefile.depends
+
+include Makefile.depends
+
+
+
+mmu_manager: mmu_manager.o user_process.o matrix.o swap.o
+oracle: oracle.o matrix.o
+
+
+###------------------------------
+### Misc.
+###------------------------------------------------------------
+.PHONY: clean realclean depend
+clean:
+ $(RM) *.o $(BINARIES) Makefile.depends
+realclean: clean
+ $(RM) vdiskA.bin vdiskB.bin
diff --git a/swap_disk/hardware.h b/swap_disk/hardware.h
new file mode 100644
index 0000000000000000000000000000000000000000..14a3726125b5f212d814ee21fc76f1ee2a994784
--- /dev/null
+++ b/swap_disk/hardware.h
@@ -0,0 +1,127 @@
+/* ------------------------------
+ $Id: hardware.h 114 2009-12-01 13:06:43Z simon_duquennoy $
+ ------------------------------------------------------------
+
+ hardware.h
+
+ Interface de la biblioth�que de simulation du mat�riel.
+
+*/
+
+#ifndef _HARDWARE_H_
+#define _HARDWARE_H_
+
+/**
+ * CMD_
+ * commandes ATA-2
+ */
+#define CMD_SEEK 0x02
+#define CMD_READ 0x04
+#define CMD_WRITE 0x06
+#define CMD_FORMAT 0x08
+#define CMD_STATUS 0x12
+#define CMD_DMASET 0x14
+#define CMD_DSKINFO 0x16
+#define CMD_MANUF 0xA2
+#define CMD_DIAG 0xA4
+
+/**
+ * Commandes de la MMU (registre MMU_CMD)
+ */
+#define MMU_PROCESS 0xCC /* Commande d'activation/d�sactivation de la MMU */
+#define MMU_RESET 0xD5 /* Commande de r�initialisation de la MMU */
+
+/**
+ * Physical and virtual memory for MMU
+ */
+extern void *physical_memory;
+extern void *virtual_memory;
+
+/**
+ * prototype des fonctions-interruptions.
+ * une interruption ne recoit aucun param�tre "d'appel",
+ * une interruption ne retourne aucun resultat, mais
+ * sa terminaison restaure le contexte d'ex�cution du programme interrompu.
+ */
+typedef void (*func_irq)(void);
+
+/**
+ * int init_hardware(const char *fileconfig);
+ * initialisation du mat�riel. Pas de "reinitialisation" possible.
+ * l'initialisation d�finit le mat�riel conform�ment aux sp�cifications
+ * fournies par le fichier dont le nom est "fileconfig".
+ * retourne 0 en cas de probl�me lors de l'initialisation.
+ */
+extern int init_hardware(const char *fileconfig);
+
+/**
+ * IRQVECTOR
+ * donne la base d'un tableau de pointeur de fonction du type
+ * func_irq. la fonction IRQVECTOR[n]() est appel�e lorsque
+ * l'interuption de niveau n est d�clanch�e par le mat�riel.
+ */
+#define IRQ_VECOTR_SIZE 256
+extern func_irq *irq_vector; /* n'utilisez pas cette variable */
+#define IRQVECTOR irq_vector /* pr�f�rez ce #define IRQVECTOR */
+
+extern int SYSTICKDURATION; /* microseconde entre les SYSTICK */
+
+/**
+ * MASTERBUFFER et SLAVEBUFFER
+ * Adresses des buffers de donnees des disques maitre et esclave
+ */
+/* n'utilisez pas ces variables*/
+extern unsigned char ** HDA_masterbufferaddress, **HDB_masterbufferaddress;
+/* pr�f�rez ces #define MASTERBUFFER et SLAVEBUFFER */
+#define MASTERBUFFER (*HDA_masterbufferaddress)
+#define SLAVEBUFFER (*HDB_masterbufferaddress)
+
+/**
+ * BASEADDRESS_RAM
+ * variable associ�e � adresse de base de la m�moire globale
+ * de la machine. Cette m�moire est commune � tout les programmes
+ * qui utilisent la librairie sur la m�me machine.
+ *
+ */
+extern unsigned char *baseGlobalMem; /* n'utilisez pas cette variable */
+#define BASEADDRESS_RAM baseGlobalMem /* pr�f�rez ce #define BASEADDRESS_RAM */
+
+/**
+ * int _in(int port);
+ * lecture du contenu du registre mat�riel n� "port".
+ * retourne la valeur lue.
+ */
+int _in(int port);
+
+/**
+ * void _out(int port, int value);
+ * ecriture de la valeur "value" dans le registre mat�riel n� "port".
+ */
+void _out(int port, int value);
+
+/**
+ * void _sleep(int irq_level);
+ * Stoppe l'activit� du microprocesseur jusqu'� l'occurence
+ * une interruption de niveau au moins �gale � "irqLevel".
+ */
+void _sleep(int irq_level);
+
+/**
+ * void _mask(int irqLevel);
+ * - cache au microprocesseur l'occurence d'interruptions
+ * de niveau inf�rieure � irqLevel.
+ * - 16�me bit � 0 : passage en mode prot�g�
+ * - 16�me bit � 1 : passage en mode user
+ *
+ */
+void _mask(int irq_level);
+
+/**
+ * void _int(int irqLevel);
+ * - lance une interruption logicielle de niveau irqLevel
+ *
+ */
+void _int(int irqLevel);
+
+#endif
+
diff --git a/swap_disk/hardware.ini b/swap_disk/hardware.ini
new file mode 100644
index 0000000000000000000000000000000000000000..5e85a850a8ea9004696dfe73ae0226197e8b8121
--- /dev/null
+++ b/swap_disk/hardware.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_LO = 0xCC # Registre contenant l'adresse m�moire ayant provoqu� une faute (32 bits de poids faible)
+MMU_FAULT_ADDR_HI = 0xCD # Registre contenant l'adresse m�moire ayant provoqu� une faute (32 bits de poids fort)
+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/swap_disk/hw_config.h b/swap_disk/hw_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..930a2df501e0fcfedc470a4df84b0feda6cfd313
--- /dev/null
+++ b/swap_disk/hw_config.h
@@ -0,0 +1,34 @@
+/* ------------------------------
+ $Id: hw_config.h 105 2009-11-24 15:22:50Z simon_duquennoy $
+ ------------------------------------------------------------
+
+ Fichier de configuration des acces au materiel
+
+ Philippe Marquet, march 2007
+
+ Code au niveau applicatif la description du materiel qui est fournie
+ par hardware.ini
+
+*/
+
+#ifndef _HW_CONFIG_H_
+#define _HW_CONFIG_H_
+
+#define HARDWARE_INI "hardware.ini"
+
+#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
+
+#define PM_PAGES (1 << 8)
+#define VM_PAGES (1 << 12)
+#define PAGE_SIZE 4096
+#define PM_SIZE (4096 * PM_PAGES)
+#define VM_SIZE (4096 * VM_PAGES)
+
+#endif
+
diff --git a/swap_disk/matrix.c b/swap_disk/matrix.c
new file mode 100644
index 0000000000000000000000000000000000000000..df1eab2221cd0c87569c7625b99b7304d393efa4
--- /dev/null
+++ b/swap_disk/matrix.c
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "matrix.h"
+
+static void log_state(int i, int n) {
+ if(n && i % n == n - 1) {
+ printf(".");
+ fflush(stdout);
+ }
+}
+
+void matrix_init(matrix *m) {
+ int i,j;
+ for(i = 0; i<MATRIX_SIZE; i++) {
+ for(j = 0; j<MATRIX_SIZE; j++) {
+ (*m)[i][j] = rand();
+ }
+ }
+}
+
+void matrix_add(matrix *dest, matrix *m1, matrix *m2) {
+ int i, j;
+ for(i = 0; i<MATRIX_SIZE; i++) {
+ log_state(i, MATRIX_SIZE / 20);
+ for(j = 0; j<MATRIX_SIZE; j++) {
+ (*dest)[i][j] = (*m1)[i][j] + (*m2)[i][j];
+ }
+ }
+ printf(" done\n");
+}
+
+void matrix_mult(matrix *dest, matrix *m1, matrix *m2) {
+ int i, j, k;
+ for(i = 0; i<MATRIX_SIZE; i++) {
+ log_state(i, MATRIX_SIZE / 20);
+ for(j = 0; j<MATRIX_SIZE; j++) {
+ int curr_val = 0;
+ for(k = 0; k<MATRIX_SIZE; k++) {
+ curr_val += (*m1)[i][k] * (*m2)[k][j];
+ }
+ (*dest)[i][j] = curr_val;
+ }
+ }
+ printf(" done\n");
+}
+
+unsigned matrix_checksum(matrix *m) {
+ int i, j;
+ unsigned int checksum = 0;
+ for(i = 0; i<MATRIX_SIZE; i++) {
+ for(j = 0; j<MATRIX_SIZE; j++) {
+ checksum += (*m)[i][j];
+ checksum += checksum >> 16;
+ checksum &= 0x0000ffff;
+ }
+ }
+ return checksum;
+}
+
diff --git a/swap_disk/matrix.h b/swap_disk/matrix.h
new file mode 100644
index 0000000000000000000000000000000000000000..2e0c8bcb8b1d45e22e43998abc13e1e9937c3c01
--- /dev/null
+++ b/swap_disk/matrix.h
@@ -0,0 +1,16 @@
+#ifndef _MATRIX_H_
+#define _MATRIX_H_
+
+#define MATRIX_SIZE 400
+#define MATRIX_ADD 0
+#define MATRIX_MUL 1
+
+typedef unsigned int matrix[MATRIX_SIZE][MATRIX_SIZE];
+
+extern void matrix_init(matrix *m);
+extern void matrix_add(matrix *dest, matrix *m1, matrix *m2);
+extern void matrix_mult(matrix *dest, matrix *m1, matrix *m2);
+extern unsigned matrix_checksum(matrix *m);
+
+#endif
+
diff --git a/swap_disk/mmu_manager.c b/swap_disk/mmu_manager.c
new file mode 100644
index 0000000000000000000000000000000000000000..208ae972ada6d27e893555b702582b47c1d8fcc0
--- /dev/null
+++ b/swap_disk/mmu_manager.c
@@ -0,0 +1,116 @@
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include "hardware.h"
+#include "hw_config.h"
+#include "mmu_manager.h"
+#include "swap.h"
+
+#define PAGE_SWAPPED -2
+#define EMPTY_VM_PAGE -1
+#define EMPTY_PM_PAGE 0
+
+int VM_MAPPING[VM_PAGES] = {EMPTY_PM_PAGE};
+int PM_MAPPING[PM_PAGES] = {EMPTY_VM_PAGE};
+int first_pm_free = 1;
+
+extern void user_process();
+
+void simple_swap_mmu_handler()
+{
+ tlb_entry_t tlb;
+ int ppage = 1;
+ long int vaddr = ((long int)_in(MMU_FAULT_ADDR_HI) << 32) | (_in(MMU_FAULT_ADDR_LO) & 0xFFFFFFFF);
+ long int vpage = (vaddr >> 12) & 0xFFF;
+
+ if (vaddr < ((long int)virtual_memory) || vaddr > ((long int)virtual_memory) + VM_SIZE)
+ {
+ fprintf(stderr, "Adresse virtuelle incorrecte");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Sauvegarder la vpage dans le fichier swap */
+ store_to_swap(vpage, ppage);
+
+ /* Rajouter l'entree dans la tlb */
+ tlb.s.tlb_vpage = vpage;
+ tlb.s.tlb_ppage = ppage;
+ tlb.s.tlb_rwx = 7;
+ tlb.s.tlb_used = 1;
+
+ /* Vider la MMU */
+ _out(MMU_CMD, MMU_RESET);
+ _out(TLB_ADD_ENTRY, tlb.i);
+}
+
+void swap_mmu_handler()
+{
+ tlb_entry_t tlb;
+ long int vaddr = (((long int)_in(MMU_FAULT_ADDR_HI)) << 32) | (((long int)_in(MMU_FAULT_ADDR_LO)) & 0xFFFFFFFF);
+ int vpage = (vaddr >> 12) & 0xFFF;
+
+ if (vaddr < (long int)virtual_memory || vaddr > (long int)virtual_memory + VM_SIZE - 1)
+ {
+ fprintf(stderr, "Adresse virtuelle incorrecten \n");
+ exit(EXIT_FAILURE);
+ }
+
+ int ppage = VM_MAPPING[vpage];
+
+ /*
+ * Si la vpage n'a jamais eu de correspondance ou elle existe dans notre fichier de swap
+ * sinon, on recupere directement sa ppage coorespondante dans nos mapping.
+ */
+ if (ppage == EMPTY_PM_PAGE || ppage == PAGE_SWAPPED)
+ {
+ /* round robin algorithm*/
+ if (!(++first_pm_free % PM_PAGES))
+ first_pm_free = 1;
+ ppage = first_pm_free;
+
+ /* old_vpage: la vpage qui pointait vers la ppage courante */
+ /* S'il n'y a aucune vpage qui pointait vers la ppage courante
+ * nous avons donc affaire à la première correspondance.
+ */
+ int old_vpage = PM_MAPPING[ppage];
+ if (old_vpage != EMPTY_VM_PAGE)
+ {
+ store_to_swap(old_vpage, ppage);
+ VM_MAPPING[old_vpage] = PAGE_SWAPPED; /* On signifie qu'on l'a rajouté dans le swap*/
+ }
+
+ /* Si la vpage courant existe dans notre fichier swap,
+ * On le restore dans ce cas.
+ * */
+ if (VM_MAPPING[vpage] == PAGE_SWAPPED)
+ fetch_from_swap(vpage, ppage);
+
+ VM_MAPPING[vpage] = ppage;
+ PM_MAPPING[ppage] = vpage;
+ }
+
+ tlb.s.tlb_vpage = vpage;
+ tlb.s.tlb_ppage = ppage;
+ tlb.s.tlb_rwx = 7;
+ tlb.s.tlb_used = 1;
+
+ _out(TLB_DEL_ENTRY, tlb.i);
+ _out(TLB_ADD_ENTRY, tlb.i);
+}
+
+void master_process()
+{
+ if (init_hardware(HARDWARE_INI) == 0)
+ fprintf(stderr, "Error in hardware initialization\n");
+ IRQVECTOR[MMU_IRQ] = swap_mmu_handler;
+}
+
+int main(int argc, char **argv)
+{
+ master_process();
+ _mask(0x1001);
+ user_process();
+
+ return 0;
+}
diff --git a/swap_disk/mmu_manager.h b/swap_disk/mmu_manager.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b44faf2d94e63ebde5b5539abf30412bb3e04a6
--- /dev/null
+++ b/swap_disk/mmu_manager.h
@@ -0,0 +1,34 @@
+#if !defined(MI_KERNEL)
+
+#define MI_KERNEL
+
+#define MMU_ENABLE 1
+#define MMU_IRQ 13
+#define MMU_FAULT_ADDR_LO 0xCC
+#define MMU_FAULT_ADDR_HI 0xCD
+#define TLB_ADD_ENTRY 0xCE
+#define MMU_CMD 0x66
+#define HARDWARE_INI "hardware.ini"
+
+struct tlb_entry_s
+{
+ unsigned tlb_RFU : 8;
+ unsigned tlb_vpage : 12;
+ unsigned tlb_ppage : 8;
+ unsigned tlb_rwx : 3;
+ unsigned tlb_used : 1;
+};
+
+union tlb_entry_u
+{
+ int i;
+ struct tlb_entry_s s;
+};
+
+typedef union tlb_entry_u tlb_entry_t;
+
+void simple_swap_mmu_handler();
+void swap_mmu_handler();
+void init_master();
+
+#endif
diff --git a/swap_disk/oracle.c b/swap_disk/oracle.c
new file mode 100644
index 0000000000000000000000000000000000000000..c792098047f6161e77d878f9e113c410ee7fe29b
--- /dev/null
+++ b/swap_disk/oracle.c
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "hw_config.h"
+#include "matrix.h"
+
+int main() {
+ int operation;
+ unsigned timestamp;
+ unsigned prev_checksum;
+ unsigned new_checksum;
+ matrix matrix1;
+ matrix matrix2;
+ matrix matrix3;
+ char line[1024];
+
+ while(!feof(stdin)) {
+ fgets(line, sizeof(line), stdin);
+ }
+
+ if(sscanf(line, "timestamp: 0x%x, operation: %d, checksum: 0x%x", ×tamp, &operation, &prev_checksum) == 0) {
+ fprintf(stderr, "[oracle] Invalid input\n");
+ exit(1);
+ }
+
+ srand(timestamp);
+
+ printf("[Starting oracle]\n");
+
+ printf("timestamp: 0x%04x, ", timestamp);
+ printf("operation: %d, ", operation);
+ printf("checksum: 0x%04x\n", prev_checksum);
+ /* init matrices */
+ printf("initializing matrices\n");
+ matrix_init(&matrix1);
+ matrix_init(&matrix2);
+ switch(operation) {
+ case 0: /* add matrices */
+ printf("adding VM matrices ");fflush(stdout);
+ matrix_add(&matrix3, &matrix1, &matrix2);
+ break;
+ case 1: /* multiply matrices */
+ printf("multiplying matrices ");fflush(stdout);
+ matrix_mult(&matrix3, &matrix1, &matrix2);
+ break;
+ default:
+ break;
+ }
+ new_checksum = matrix_checksum(&matrix3);
+ printf("new checksum: 0x%04x [%s]\n", new_checksum, new_checksum == prev_checksum ? "ok" : "ko");
+
+ return 0;
+}
+
diff --git a/swap_disk/swap.c b/swap_disk/swap.c
new file mode 100644
index 0000000000000000000000000000000000000000..bfe9065043535d7dfc7d5b5dd727b276ec9da5ef
--- /dev/null
+++ b/swap_disk/swap.c
@@ -0,0 +1,44 @@
+/* functions return non null value on error */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include "hardware.h"
+#include "hw_config.h"
+
+static FILE *swap_file = NULL;
+
+static int
+init_swap(void)
+{
+ swap_file = fopen(".swap_file", "w+"); /* w+: create, read, write*/
+ return swap_file == NULL;
+}
+
+int
+store_to_swap(int vpage, int ppage)
+{
+ if (swap_file == NULL)
+ if (init_swap())
+ return -2;
+ if (fseek(swap_file, vpage << 12, SEEK_SET) == -1)
+ return -1;
+ if (fwrite((void*)((ppage << 12) | (uintptr_t)physical_memory),
+ 1, PAGE_SIZE, swap_file) == 0)
+ return -1;
+ return 0;
+}
+
+int
+fetch_from_swap(int vpage, int ppage)
+{
+ if (swap_file == NULL)
+ if (init_swap())
+ return -2;
+ if (fseek(swap_file, vpage << 12, SEEK_SET) == -1)
+ return -1;
+ if (fread((void*)((ppage << 12) | (uintptr_t)physical_memory),
+ 1, PAGE_SIZE, swap_file) == 0)
+ return -1;
+ return 0;
+}
diff --git a/swap_disk/swap.h b/swap_disk/swap.h
new file mode 100644
index 0000000000000000000000000000000000000000..75d5ad5f88b34a6fa191533484f3314e80ab9f16
--- /dev/null
+++ b/swap_disk/swap.h
@@ -0,0 +1,7 @@
+#if !defined(SWAP)
+#define SWAP
+
+int store_to_swap(int, int);
+int fetch_from_swap(int, int);
+
+#endif // SWAP
diff --git a/swap_disk/user_process.c b/swap_disk/user_process.c
new file mode 100644
index 0000000000000000000000000000000000000000..e269ce86a178875f0b6192c2c2070804db91a667
--- /dev/null
+++ b/swap_disk/user_process.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "hw_config.h"
+#include "matrix.h"
+
+extern void *virtual_memory;
+
+#define MATRIX_OP MATRIX_ADD
+/*#define MATRIX_OP MATRIX_MUL*/
+
+void user_process() {
+ unsigned short timestamp = (unsigned)time(NULL);
+ matrix *matrix1 = (matrix*)virtual_memory;
+ matrix *matrix2 = ((matrix*)virtual_memory) + 1;
+ matrix *matrix3 = ((matrix*)virtual_memory) + 2;
+
+ srand(timestamp);
+
+ printf("[Starting user process]\n");
+
+ /* print some informations */
+ printf("matrices size: %dx%d\n", MATRIX_SIZE, MATRIX_SIZE);
+ printf("vm used: %5d pages\n", 3 * sizeof(matrix) / PAGE_SIZE);
+ printf("pm space: %5d pages\n", 1 << 8);
+ printf("vm space: %5d pages\n", 1 << 12);
+ /* init matrices */
+ printf("initializing matrices\n");
+ matrix_init(matrix1);
+ matrix_init(matrix2);
+#if MATRIX_OP == MATRIX_ADD
+ /* add matrices */
+ printf("adding VM matrices ");fflush(stdout);
+ matrix_add(matrix3, matrix1, matrix2);
+#elif MATRIX_OP == MATRIX_MUL
+ /* multiply matrices */
+ printf("multiplying matrices ");fflush(stdout);
+ matrix_mult(matrix3, matrix1, matrix2);
+#endif
+ printf("timestamp: 0x%04x, ", timestamp);
+ printf("operation: %d, ", MATRIX_OP);
+ printf("checksum: 0x%04x\n", matrix_checksum(matrix3));
+}
+
+void show(){
+
+}
\ No newline at end of file