diff --git a/src/init_proc.c b/src/init_proc.c index 18d033c..ac3b690 100644 --- a/src/init_proc.c +++ b/src/init_proc.c @@ -1,5 +1,10 @@ +/** + * + * @file init_proc.c + * @brief Modulo con le funzioni per la creazione dei processi utente di test. + * + */ #include "init_proc.h" -#include "kernel.h" #include "pandos_const.h" #include "pandos_types.h" #include "syscalls.h" @@ -9,19 +14,30 @@ #include #include +/* Tag per le utility di log */ #define LOG "IP" -void test(){ log(LOG, "test"); } -void test1(){ log(LOG, "test1"); } - +/** + * @brief Gestore delle eccezioni riguardanti il tlb del livello supporto. + * */ extern void tlb_exc_handler(void); +/** + * @brief Gestore delle eccezioni del livello supporto. + * */ extern void support_exec_handler(void); +/* TODO */ static int semaforo_a_cazzo = 0; +/** + * @brief Inizializza una tabella delle pagine privata + * @param tbl la tabella da inizializzare + * @param asid l'ASID del processo proprietario della tabella + * */ static void init_page_table(pteEntry_t *tbl, const int asid); + inline void instantiator_proc(void) { state_t tp_states[UPROCMAX]; @@ -30,48 +46,45 @@ inline void instantiator_proc(void) init_supp_structures(); - for (i = 0; i < 1 /*UPROCMAX*/; i++) { + for (i = 1; i <= 1 /*UPROCMAX*/; i++) { logi(LOG, "creating uproc", i); /* Create state_t and support_t structures for test processes */ /* state */ - tp_states[i].pc_epc = UPROCSTARTADDR; - tp_states[i].reg_t9 = UPROCSTARTADDR; - tp_states[i].reg_sp = USERSTACKTOP; + tp_states[i - 1].pc_epc = UPROCSTARTADDR; + tp_states[i - 1].reg_t9 = UPROCSTARTADDR; + tp_states[i - 1].reg_sp = USERSTACKTOP; /* Timer enabled, interrupts enabled and usermode */ - tp_states[i].status = STATUS_TE | STATUS_IEc | STATUS_IEp | STATUS_KUc; - for (int j = 0; j < 8; j ++) { + tp_states[i - 1].status = STATUS_TE | STATUS_IEc | STATUS_KUc | STATUS_IM_MASK ; + /*for (int j = 0; j < 8; j ++) { tp_states[i].status |= STATUS_IM_BIT(j); - } - tp_states[i].entry_hi = 0 & (i << ENTRYHI_ASID_BIT); + }*/ + tp_states[i - 1].entry_hi = 0 & (i << ENTRYHI_ASID_BIT); /* support */ - tp_supps[i].sup_asid = i; - init_page_table(tp_supps[i].sup_privatePgTbl, i); + tp_supps[i - 1].sup_asid = i; + init_page_table(tp_supps[i - 1].sup_privatePgTbl, i); context_t context[2]; - context[0].pc = (memaddr)test; - context[1].pc = (memaddr)test1; + context[0].pc = (memaddr)tlb_exc_handler; + context[1].pc = (memaddr)support_exec_handler; /* Timer enabled, interupts on and kernel mode */ context[0].status = STATUS_TE | STATUS_IM_MASK | STATUS_KUc | STATUS_IEc; context[1].status = STATUS_TE | STATUS_IM_MASK | STATUS_KUc | STATUS_IEc; - for (int j = 0; j < 8; j ++) { - context[i].status |= STATUS_IM_BIT(j); - } /* Set stack ptr to the end of the stack minus 1 */ context[0].stackPtr = (memaddr)&tp_supps[i].sup_stackTLB[500 - 1]; context[1].stackPtr = (memaddr)&tp_supps[i].sup_stackGen[500 - 1]; - memcpy(tp_supps[i].sup_exceptContext, context, sizeof(context_t)); + memcpy(tp_supps[i - 1].sup_exceptContext, context, sizeof(context_t)); - SYSCALL(CREATEPROCESS, (unsigned int)&tp_states[i], PROCESS_PRIO_HIGH, - (unsigned int)&tp_supps[i]); - logi(LOG, "created uproc ", i); + SYSCALL(CREATEPROCESS, (unsigned int)&tp_states[i - 1], PROCESS_PRIO_HIGH, + (unsigned int)&tp_supps[i - 1]); + logi(LOG, "created uproc ", i ); } - for (i = 0; i < UPROCMAX; i++) + for (i = 0; i < 1/*UPROCMAX*/; i++) SYSCALL(PASSEREN, (unsigned int)&semaforo_a_cazzo, 0, 0); } diff --git a/src/init_proc.h b/src/init_proc.h index 22bb2b9..2a0d161 100644 --- a/src/init_proc.h +++ b/src/init_proc.h @@ -1,6 +1,15 @@ +/** + * + * @file init_proc.h + * @brief Modulo con le funzioni per la creazione dei processi utente di test. + * + */ #ifndef INIT_PROC_H #define INIT_PROC_H +/** + * @brief Crea, inizializza e lancia gli 8 processi utente di test. + */ extern void instantiator_proc(void); #endif diff --git a/src/kernel.c b/src/kernel.c index 13d2197..be1ad23 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -42,6 +42,11 @@ inline static void init_passup_vector(void); * */ inline static void exception_handler(void); +/** + * @brief Gestore delle eccezioni del tipo TLB-refill + * */ +inline static void uTLB_RefillHandler(void); + /** * @brief Inizializzazione del sistema operativo. Inizializza le strutture dati * necessarie, crea il processo di init e lascia il controllo allo scheduler. @@ -101,6 +106,7 @@ void exception_handler(void) cause = CAUSE_GET_EXCCODE(getCAUSE()); + if (cause != 8 && cause != 0) LOGi("ex", cause); if (act_proc != NULL) { @@ -165,8 +171,7 @@ void exception_handler(void) scheduler_next(); } -/* TLB-Refill Handler */ -inline void uTLB_RefillHandler(void) +void uTLB_RefillHandler(void) { state_t *exc_state; unsigned int pg_n; diff --git a/src/kernel.h b/src/kernel.h index 738c9d0..5817284 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -16,9 +16,4 @@ enum eh_act { CONTINUE = 2 /* Continuare con l'esecuzione del processo corrente */ }; -/** - * @brief Gestore del refil del TLB. - * */ -extern void uTLB_RefillHandler(void); - #endif diff --git a/src/scheduler.c b/src/scheduler.c index 0c1da57..840769e 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -173,6 +173,11 @@ inline pcb_t *dequeue_proc(const unsigned int priority) } inline void load_proc(pcb_t *pcb) +{ + load_with_state(pcb, &pcb->p_s); +} + +inline void load_with_state(pcb_t *pcb, state_t *state) { if (pcb == NULL) { LOG("Attempt to load NULL pcb"); @@ -196,4 +201,5 @@ inline void load_proc(pcb_t *pcb) /* Lo carico */ LDST(&act_proc->p_s); + } diff --git a/src/scheduler.h b/src/scheduler.h index 798c4fd..65ab151 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -71,4 +71,5 @@ extern pcb_t *dequeue_proc(const unsigned int priority); * */ extern void load_proc(pcb_t *pcb); +extern void load_with_state(pcb_t *pcb, state_t *state); #endif diff --git a/src/vm_support.c b/src/vm_support.c index f9348b0..c1618e0 100644 --- a/src/vm_support.c +++ b/src/vm_support.c @@ -1,3 +1,8 @@ +/** + * @file vm_support.c + * @brief Implementazione delle funzioni necessarie per la gestione della + * memoria virtuale. + * */ #include "vm_support.h" #include "listx.h" #include "pandos_const.h" @@ -10,35 +15,77 @@ #include #include +/** + * @brief Dimensione della Swap Pool + * */ #define SWAP_POOL_SIZE 2 * UPROCMAX + +/** + * @brief Indirizzo di inizio della Swap Pool + * */ #define SWAP_POOL_BEGIN 0x20020000 -#define CALC_NEW_PFN(entryLO, pfn) (pfn ) | (entryLO & 2047) +/** + * @brief Macro per l'aggiornamento del campo PFN di un entry lo + * */ +#define CALC_NEW_PFN(entryLO, pfn) pfn | (entryLO & 2047) +/* Macro per il log */ #define LOG(s) log("VM", s) #define LOGi(s, i) logi("VM", s, i) +/** + * @struct swppl_entry_t + * @brief Rappresenta una entry della swap table. + * @var asid Indica l'ASID del processo propretario della pagina salvata + * nella entry + * @var vpn Indica il numero della pagina salvata nella entry + * @ pg_tbl_entry Puntatore alla entry dentro la tabella delle pagine privata + * del processo + * */ typedef struct { int asid; int vpn; pteEntry_t *pg_tbl_entry; } swppl_entry_t; -int swp_pl_sem; - +/** + * @var Array con le entry della swap pool + * */ static swppl_entry_t swppl_tbl[SWAP_POOL_SIZE]; +/* + * @var Semaforo mutex per la swap pool + * */ +int swp_pl_sem; + /* * @var Putatore al frame da scegliere quando si esegue l'algoritmo di * rimpiazzamento * */ static size_tt frm_ch_ptr = 0; -static int chose_frame(void); +/** + * @brief Implementa l'algoritmo di rimpiazzamento per i frame nella swap pool + * @return Il numero del frame da rimpiazzare + * */ +static inline int chose_frame(void); -static void toggle_int(int on); +/** + * @brief Utility per abilitare/disabilitare gli interrupt. Usata per poter + * eseguire istruzioni in modo 'atomico'. + * @param on Un intero booleano - 1 se si vogliono abilitare gli interrupt, 0 + * se si vogliono disabilitare. + * */ +static inline void toggle_int(int on); -static int update_tlb(unsigned int entryHi, unsigned int entryLo); +/** + * @brief Aggiorna il TLB con le entryHI e entryLO passate. Esegue prima una + * probe per controllare e' gia' presente un'entry con entryHi corrispondente + * e successivamente una TLBWRI per aggiornarne i valori. + * @return 1 se ha successo, 0 altrimenti + * */ +static inline int update_tlb(unsigned int entryHi, unsigned int entryLo); inline void init_supp_structures(void) { @@ -52,15 +99,8 @@ inline void init_supp_structures(void) swppl_tbl[i].asid = -1; } -// TODO -static unsigned int debugV; -static unsigned int debugV2; -static unsigned int debugV3; -static unsigned int debugV4; - inline void tlb_exc_handler(void) { - LOG("Qua arriva"); support_t *act_proc_sup = (support_t *)SYSCALL(GETSUPPORTPTR, 0, 0, 0); if (act_proc_sup == NULL) { LOG("Error on getsupport"); @@ -107,7 +147,7 @@ inline void tlb_exc_handler(void) toggle_int(TRUE); /* Prendo i registri del device */ - dtpreg_t *dev_reg = (dtpreg_t *)DEV_REG_ADDR(FLASHINT, act_proc_sup->sup_asid); + dtpreg_t *dev_reg = (dtpreg_t *)DEV_REG_ADDR(FLASHINT, act_proc_sup->sup_asid - 1); /* Metto in data0 il pfn che voglio scrivere */ dev_reg->data0 = ENTRYLO_GET_PFN(proc_pgtbl_entry->pte_entryLO); @@ -125,7 +165,7 @@ inline void tlb_exc_handler(void) /* Prendo il device register del dispositivo flash associato al processo */ dtpreg_t *dev_reg = - (dtpreg_t *)DEV_REG_ADDR(FLASHINT, act_proc_sup->sup_asid); + (dtpreg_t *)DEV_REG_ADDR(FLASHINT, act_proc_sup->sup_asid - 1); /* Scrivi il contenuto di data0 sul frame della swap pool scelto */ unsigned int sp_addr = (unsigned int)SWAP_POOL_BEGIN + (chosen_frame * PAGESIZE); @@ -166,13 +206,11 @@ inline void tlb_exc_handler(void) /* V nel semaforo della swap table per rilasciare la mutua esclusione */ SYSCALL(VERHOGEN, (unsigned int)&swp_pl_sem, 0, 0); - /* SUPER-TODO capire come fare un ldst in modo safe per non mandare a - * puttane lo scheduler */ LDST(&act_proc_sup->sup_exceptState[0]); } } -inline int update_tlb(unsigned int entryHi, unsigned int entryLo) +int update_tlb(unsigned int entryHi, unsigned int entryLo) { #define P_BIT 0x40000000 unsigned int index; @@ -191,12 +229,12 @@ inline int update_tlb(unsigned int entryHi, unsigned int entryLo) return 1; } -inline int chose_frame(void) { +int chose_frame(void) { frm_ch_ptr %= SWAP_POOL_SIZE; return frm_ch_ptr++; } -inline void toggle_int(int on) { +void toggle_int(int on) { if (on) { setSTATUS(getSTATUS() | 1); } else { diff --git a/src/vm_support.h b/src/vm_support.h index 39016f0..7d9ae3a 100644 --- a/src/vm_support.h +++ b/src/vm_support.h @@ -1,10 +1,24 @@ +/** + * @file vm_support.h + * @brief Modulo contenente le funzioni per la gestione della memoria virtuale + * */ #ifndef VM_SUPPORT #define VM_SUPPORT +/** + * @var Semaforo mutex per la Swap Pool + * */ extern int swp_pl_sem; +/** + * @brief Inizializza tutte le strutture dati necessarie per la gestione + * della memoria virtuale. + * */ extern void init_supp_structures(void); +/** + * @brief Gestore delle eccezioni del TLB. The pager + * */ extern void tlb_exc_handler(void); #endif