uint64_t AllocatePage(uint64_t size, bool Below4Gb) { if(!DidInit) return AllocateFromReserved(size); auto mut = AutoMutex(mtx); OpsSinceLastCoalesce++; size_t trycount = 0; auto len = PageList->size(); begin: if(PageList->size() == 0) { HALT("Out of physical pages"); } Pair* p = PageList->front(); if(Below4Gb && p->BaseAddr >= 0xFFFFFFFF) { trycount++; PageList->erase(PageList->begin()); PageList->push_back(p); goto begin; } else if(p->LengthInPages > size) { p->LengthInPages -= size; uint64_t raddr = p->BaseAddr; p->BaseAddr += (size * 0x1000); return raddr; } else if(p->LengthInPages == size) { auto raddr = p->BaseAddr; PageList->erase(PageList->begin()); delete p; return raddr; } else { if(trycount < len) { auto fr = PageList->front(); PageList->erase(PageList->begin()); PageList->push_back(fr); trycount++; goto begin; // dirty } else { Log(1, "tried allocating %d pages, failed", size); HALT("Out of physical pages"); return 0; } } }
/* * The scheduler must be called within a critical section since it * changes global state, and since dispatch() needs to be called * within a critical section. Disable_count for current_running is * checked to see that it's != 0. The scheduler also handles saving * the current interrupt controller mask (which is later restored in * setup_current_running()). */ void scheduler(void) { unsigned long long t; /* * Save hardware interrupt mask in the pcb struct. The mask * will be restored in setup_current_running() */ current_running->int_controller_mask = ((uint16_t)inb(0x21)) | (((uint16_t)inb(0xa1)) << 8); ASSERT(current_running->disable_count != 0); do { switch (current_running->status) { case SLEEPING: t = get_timer(); if (current_running->wakeup_time < t) current_running->status = RUNNING; /* FALLTHROUGH */ case RUNNING: /* pick the next job to run */ current_running = current_running->next; break; case BLOCKED: /* if no more jobs, halt */ if (current_running->next == current_running) { HALT("No more jobs."); } current_running = current_running->next; /* Remove the job from the ready queue */ remove_job(current_running->previous); break; case EXITED: /* if no more jobs, loop forever */ if (current_running->next == current_running) { HALT("No more jobs."); } current_running = current_running->next; /* * Remove pcb from the ready queue and insert * it into the free_pcb queue */ free_pcb(current_running->previous); break; default: HALT("Invalid job status."); break; } } while (current_running->status != RUNNING); /* .. and run it */ dispatch(); }
/** * Define the Reset handler. * It initializes the bss and data sections of the RAM */ void __attribute__((naked)) reset() { uint32_t *src, *dst; // Loop over the data section to copy initialized code from _etext src = &_etext; dst = &_sdata; while (dst < &_edata) { *dst++ = *src++; } // loop over the bss and clear dst = &_sbss; while (dst < &_ebss) { *dst++ = 0; } /* Call CTORS of static objects */ #ifdef __cplusplus __libc_init_array(); #endif // call the main function main(); log_error("\n\n***** End of main *****"); HALT(); }
//---------------------------------------------------------------------- // hyperapp nested (extended) page fault handler // used to implement approved execution //---------------------------------------------------------------------- u32 emhf_app_handleintercept_hwpgtblviolation(VCPU *vcpu, struct regs *r, u64 gpa, u64 gva, u64 violationcode){ (void)r; #if defined(__LDN_TV_INTEGRATION__) { extern u32 tv_app_handleintercept_hwpgtblviolation(VCPU *vcpu, struct regs *r, u64 gpa, u64 gva, u64 violationcode); u32 status; status = tv_app_handleintercept_hwpgtblviolation(vcpu, r, gpa, gva, violationcode); //if(!status) // return APP_SUCCESS; //TV returns zero in case it handled the pf //if so we don't perform the lockdown logic on this pf return status; } #endif //__LDN_TV_INTEGRATION__ #if defined(__LDN_APPROVEDEXEC__) if(currentenvironment == LDN_ENV_TRUSTED_SIGNATURE) return( approvedexec_handleevent(vcpu, r, gpa, gva, violationcode) ); #endif //__LDN_APPROVEDEXEC__ //we never handle nested (extended) page faults in the untrusted //environment printf("\nCPU(0x%02x): Unhandled HW page-fault!", vcpu->id); printf("\nCPU(0x%02x): gva=0x%08x, gpa=0x%08x, errorcode=0x%08x", vcpu->id, (u32)gva, (u32)gpa, (u32)violationcode); printf("\nCPU(0x%02x): current gpa protection is: 0x%08x", emhf_memprot_getprot(vcpu, gpa)); printf("\nCPU(0x%02x): Halting!"); HALT(); return APP_ERROR; //we never get here }
void PushWork(int i,int j) { register TaskElement *te = gMem->tasks + LocalTaskStack[LocalStackTop--]; int a; if (LocalStackTop < 0) { printf("!!!!!!!FAILURE IN LOCAL STACK TOP!!!\n\n\n"); HALT(-1); } te->left=i; te->right=j; GETLOCK(&gMem->TaskStackLock); ANNOUNCE("\t\t\tI have got the lock -- ", whoami); a=gMem->TaskStackTop++; te->next=gMem->TaskStack; gMem->TaskStack=te; FREELOCK(&gMem->TaskStackLock); ANNOUNCE("\t\t\tI have released the lock -- ",whoami); ANNOUNCE("\t\t\tMy TaskStackTop was -- ",a); if(LocalStackTop < 0) { printf("Local TaskStackTop negative!\n"); } }
//=============================================================================== void PowerOff_Process(void) { if(System.PowerProcess == 0) { return; } System.PowerProcess--; switch(System.PowerProcess) //System.PowerProcess=8000/10 { case (7900/10): setAmpReset(OFF); break; case (5000/10): break; case (4500/10): System.PowerProcess = (2500/10); TxKeyToBE(F_POWEROFF); break; case (200/10): MICOM_STROBE_PORT = OFF; MICOM_DATAOUT_PORT = OFF; o_BE_Reset = OFF; break; case (50/10): System.PowerOnOffDispReqF = 0; VfdSleep(); PowerOff_Port_Config(); Port_Config(); HALT(); Sys_Init_Status(); break; default: break; } }
static void zop_ED_0x76(void) { /* 0xED 0x76 : SLP */ HALT(); /* really, not sure what SLP does, since it's opcode 0xED 0x76, we try to execute 0x76 as it would be normal HALT opcode. The difference maybe only the "depth" CPU is powered down, so for the emulation it does not make too much different - I think - LGB */ T_WAIT_UNTIL(4); }
void CommandTable::Add(CommandInfo * info, CommandReturnType retnType, UInt32 parentPluginOpcodeBase) { UInt32 backCommandID = m_baseID + m_commands.size(); // opcode of the next command to add info->opcode = m_curID; if(m_curID == backCommandID) { // adding at the end? m_commands.push_back(*info); } else if(m_curID < backCommandID) { // adding to existing data? ASSERT(m_curID >= m_baseID); m_commands[m_curID - m_baseID] = *info; } else { HALT("CommandTable::Add: adding past the end"); } m_curID++; CommandMetadata * metadata = &m_metadata[info->opcode]; metadata->parentPlugin = parentPluginOpcodeBase; metadata->returnType = retnType; }
Base* Title::update( Parent* parent ){ Base* next = this; //入力取得 if ( Pad::isTriggered( Pad::U ) ){ --mCursorPosistion; if ( mCursorPosistion < 0 ){ //マイナスは最大値にループ mCursorPosistion = 1; } }else if ( Pad::isTriggered( Pad::D ) ){ ++mCursorPosistion; if ( mCursorPosistion > 1 ){ //1を越えたら0にループ mCursorPosistion = 0; } }else if ( Pad::isTriggered( Pad::A ) ){ next = new Game::Parent( parent->mode() ); if ( mCursorPosistion == 0 ){ parent->setMode( Parent::MODE_1P ); }else if ( mCursorPosistion == 1 ){ parent->setMode( Parent::MODE_2P ); }else{ HALT( "arienai" ); } } //描画 mImage->draw(); //字を出す Framework f = Framework::instance(); f.drawDebugString( 0, 0, "[タイトル] : バクダンビト" ); f.drawDebugString( 1, 2, "ヒトリ デ アソブ" ); f.drawDebugString( 1, 3, "フタリ デ コロシアウ" ); //カーソルを書く f.drawDebugString( 0, mCursorPosistion + 2, ">" ); return next; }
void c_codegen_entry() { outputFile = fopen ( outfile, "w"); ORIG(); JSR("MAIN", "", NULL); HALT(); }
void tdma_release () { if (xSemaphoreGive(tdma_mutex) != pdPASS) { log_error("Failed to release the TDMA semaphore"); HALT(); } }
void Mesh::read(std::istream& is, const char* fileExtension) { bool loaded=false; if(!strcmp(fileExtension, "obj")) { readObjFile(is); loaded=true; } if(!strcmp(fileExtension, "off")) { readOffFile(is); loaded=true; } if(!strcmp(fileExtension, "ply")) { readPlyFile(is); loaded=true; } if(!strcmp(fileExtension, "tri")) { readTriFile(is); loaded=true; } if(!strcmp(fileExtension, "stl")) { readStlFile(is); loaded=true; } if(!loaded) HALT("can't read fileExtension '" <<fileExtension <<"'"); }
/** * This function stops the MCU and will never return. * It is called in any error case. */ extern void vscp_bl_adapter_halt(void) { /* Move interrupt vectors to application section */ VSCP_BL_ADAPTER_ISR_VECTOR_TO_APP(); HALT(); return; }
/** * Define the default empty handler */ void debug_handler(const char *name) { log_error("\n\n**********************\n" "*** Unhandled ISR ****\n" "*** %s ****\n" "**********************\n", name); HALT(); }
// Sets clkCPU/PER system clock and clkPER4 hi-res // - the standard 32 MHz with 128 MHz hi-res = setClockExternal16MHzHiRes(8, 1) // - overclocking 68 MHz with 272 MHz hi-res = setClockExternal16MHzHiRes(17, 1) <- not stable, but some chips might work for testing purposes void setClockExternal16MHzHiRes(uint8_t multiplier, uint16_t divider) { uint8_t pll = 0; if (1 <= multiplier && multiplier <= 31 ) { pll = multiplier; } else HALT(); uint8_t prescaler = 0; switch (divider) { case 1 : prescaler = 0b00000; break; case 2 : prescaler = 0b00001; break; case 4 : prescaler = 0b00011; break; case 8 : prescaler = 0b00101; break; case 16 : prescaler = 0b00111; break; case 32 : prescaler = 0b01001; break; case 64 : prescaler = 0b01011; break; case 128 : prescaler = 0b01101; break; case 256 : prescaler = 0b01111; break; case 512 : prescaler = 0b10001; break; default : HALT(); break; } OSC.XOSCCTRL = 0b11 << 6 | 0b1011; // Enable 16MHz XTAL with 16K CLK start-up time OSC.CTRL |= 0b01000; // Enable External Oscillator while((OSC.STATUS & 0b01000) == 0) { } // Wait External Oscillator to stabilize OSC.PLLCTRL = 0b11 << 6 | pll; // Select External clock source with 1x..31x PLL OSC.CTRL |= 0b10000; // Enable PLL while((OSC.STATUS & 0b10000) == 0) { } // Wait PLL to stabilize uint8_t psctrl = prescaler << 2 | 0b11; // clkPER4 /2 = clkPER2 /2 = clkPER/CPU, protected by CCP! CCP = 0xD8; // Unlock Configuration Change Protection CLK.PSCTRL = psctrl; if (CLK.PSCTRL != psctrl) HALT(); // Error! uint8_t ctrl = 0b100; // Select PLL to System Clock CCP = 0xD8; // Unlock Configuration Change Protection CLK.CTRL = ctrl; if (CLK.CTRL != ctrl) HALT(); // Error! }
void scheduler() { //Due possibili casi: // -Esiste un processo in esecuzione -> context switch // -Non c'è un processo -> ne carico uno if(currentProcess!=NULL){ //current process è quello che deve essere eseguito timer+=getTODLO()-last_access; last_access=getTODLO(); //#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -> sta su uARMconst //#define SCHED_TIME_SLICE 5000 //#define SCHED_PSEUDO_CLOCK 100000 setTIMER(MIN(SCHED_TIME_SLICE, SCHED_PSEUDO_CLOCK-timer)); LDST(&(currentProcess->s_t)); } else{ //Anche qui due casi possibili, controlliamo se la readyQueue è vuota if(clist_empty(readyQueue)){ //processCount = 0 -> HALT -> non ci sono processi if(processCount == 0) HALT(); //processCount>0 e SBC==0-> qualcosa è andato storto -> deadlock if(processCount>0 && softBlockCount == 0) PANIC(); //caso "normale" -> aspettiamo che un processo necessiti di essere allocato if(processCount>0 && softBlockCount > 0) WAIT(); //qualsiasi altro stato PANIC(); } else{ //semplicemente carico il primo processo in memoria //scherzavo, non è semplice currentProcess = removeProcQ(readyQueue); if(currentProcess == NULL) PANIC(); //qualcosa è andato storto //imposta i timer e altre cose brutte scheduler(); } } }
void HandleIPv6Packet(Devices::NIC::GenericNIC* interface, void* packet, uint64_t length, IPv6Address source, IPv6Address destip) { UNUSED(interface); UNUSED(packet); UNUSED(length); UNUSED(source); UNUSED(destip); HALT("UDP over IPv6 not implemented."); }
void kipc_post_process(IPC* ipc, KPROCESS* sender) { KPROCESS* receiver = (KPROCESS*)ipc->process; int index = -1; bool wake = false; IPC* cur; CHECK_HANDLE(receiver, sizeof(KPROCESS)); CHECK_MAGIC(receiver, MAGIC_PROCESS); if (ipc->cmd & HAL_IO_FLAG) { KIO* kio = (KIO*)(((IO*)ipc->param2)->kio); CHECK_HANDLE(kio, sizeof(KIO)); CHECK_MAGIC(kio, MAGIC_KIO); if (!kio_send(kio, receiver)) return; } disable_interrupts(); if ((wake = ((receiver->kipc.wait_process == sender || receiver->kipc.wait_process == (KPROCESS*)ANY_HANDLE) && (receiver->kipc.cmd == ipc->cmd || receiver->kipc.cmd == ANY_CMD) && ((receiver->kipc.param1 == ipc->param1) || (receiver->kipc.param1 == ANY_HANDLE)))) == true) { receiver->kipc.wait_process = (KPROCESS*)INVALID_HANDLE; } if (!rb_is_full(&receiver->process->ipcs)) index = rb_put(&receiver->process->ipcs); enable_interrupts(); if (index >= 0) { cur = KIPC_ITEM(receiver, index); cur->cmd = ipc->cmd; cur->param1 = ipc->param1; cur->param2 = ipc->param2; cur->param3 = ipc->param3; cur->process = (HANDLE)sender; //already waiting? Wakeup him if (wake) kprocess_wakeup(receiver); } else { kprocess_error(sender, ERROR_OVERFLOW); #if (KERNEL_IPC_DEBUG) printk("Error: receiver %s IPC overflow!\n", kprocess_name(receiver)); if (sender == (KPROCESS*)KERNEL_HANDLE) printk("Sender: kernel\n"); else printk("Sender: %s\n", kprocess_name((KPROCESS*)sender)); printk("cmd: %#X, p1: %#X, p2: %#X, p3: %#X\n", ipc->cmd, ipc->param1, ipc->param2, ipc->param3); #if (KERNEL_DEVELOPER_MODE) HALT(); #endif #endif } }
void Title::update( Parent* parent ){ //取得输入 if(isRequestEnd){ Framework f = Framework::instance(); f.requestEnd(); if (f.isEndRequested()){ Sequence::Parent::destroy(); } } if ( Pad::isTriggered( Pad::U ) ){ --mCursorPosition; if ( mCursorPosition < 0 ){ mCursorPosition = 1; } SoundManager::instance()->playSe( SoundManager::SE_CURSOR_MOVE ); }else if ( Pad::isTriggered( Pad::D ) ){ ++mCursorPosition; if ( mCursorPosition > 1 ){ mCursorPosition = 0; } SoundManager::instance()->playSe( SoundManager::SE_CURSOR_MOVE ); }else if ( Pad::isTriggered( Pad::MAGIC ) ){ parent->moveTo( Parent::NEXT_GAME ); if ( mCursorPosition == 0 ){ parent->setMode( Parent::MODE_S1 ); }else if ( mCursorPosition == 1 ){ pAS=AppStatus::instance(); Title::pAS->setIsRequestEnd(true); pAS=0; parent->setMode(Parent::MODE_S1); }else{ HALT( "arienai" ); } SoundManager::instance()->playSe( SoundManager::SE_SELECTION ); } mImage->drawUI();//REDRAW Framework f = Framework::instance(); f.drawDebugString( 0, 0, "Boomer" ); f.drawDebugString( 1, 2, "Play Game" ); f.drawDebugString( 1, 3, "End Game" ); f.drawDebugString( 0, mCursorPosition + 2, ">" ); }
void schedule() { /* azioni da compiere quando non c'e' nessun thread pronto ad eseguire */ if (emptyThreadQ(&readyQueue) && currentThread == NULL) { prova(); if (threadCount == 1)/* se c'e' solo il SSI -> normal system shutdown */ HALT(); /* chiamo la HALT ROM routine */ else if (threadCount > 0 && softBlockCount == 0) {/* deadlock */ PANIC(); /* chiamo la PANIC ROM routine */ } else if (threadCount > 0 && softBlockCount > 0) { /* in attesa di un interrupt -> wait state */ /* se ci sono thread in attesa dello pseudo tick, * carico il valore dello pseudo clock nel registro della cpu.*/ if (!emptyThreadQ(&waitForPseudoClockQueue)) { SET_IT(SCHED_PSEUDO_CLOCK); } /* impostiamo lo stato del processore con gli interrupt abilitati*/ setSTATUS(getSTATUS() | STATUS_IEc | STATUS_INT_UNMASKED); for (;;); } } else { /* Se non c'è nessun Thread in esecuzione ma c'e n'è almeno uno nella readyQueue allora carico un thread*/ if (currentThread == NULL) { currentThread = removeThread(&readyQueue); currentThread->elapsedTime = 0; currentThread->startTime = GET_TODLOW; SET_IT(SCHED_TIME_SLICE); /* Altrimenti se è passato il SCHED_TIME_SLICE rimuovo il thread corrente dall'esecuzione*/ } else if (currentThread->elapsedTime >= SCHED_TIME_SLICE) { //in questo modo do priorità all'SSI if (currentThread != tcb_SSI) { insertThread(&readyQueue, currentThread); /*Carico un nuovo thread*/ currentThread = removeThread(&readyQueue); } currentThread->elapsedTime = 0; currentThread->startTime = GET_TODLOW; /* Se e' scattato lo pseudo clock non settiamo il timer a 5 ms * dato che scattera' subito l'interrupt dello pseudo clock */ if (!isPseudoClock) SET_IT(SCHED_TIME_SLICE); } /* carico lo stato del thread nel processore dalla sua tcb */ LDST(&(currentThread->t_state)); } }
/* * funzione principale */ void schedule(void) { tcb_t *SSI_t, *tmp_q; unsigned int execKill; /* esami tutta la ready queue, spostando tutti i thread contrassegnati to_kill * nella killable_queue. Inizia la scansione da capo ad ogni thread spostato */ if (!emptyThreadQ(ready_queue)){ tmp_q = ready_queue; do{ execKill = FALSE; if(tmp_q->to_kill == TRUE){ tmp_q = outThreadQ(&ready_queue, tmp_q); insertBackThreadQ(&killable_queue, tmp_q); execKill = TRUE; } tmp_q = tmp_q->t_prev; if (execKill == TRUE) tmp_q = ready_queue; if (emptyThreadQ(ready_queue)) execKill = FALSE; } while(((tmp_q != ready_queue) && (!emptyThreadQ(ready_queue))) || execKill == TRUE); } /* termina tutti i thread, svuotando contestualmente killable_queue */ if (!emptyThreadQ(killable_queue)){ tmp_q = killable_queue; do{ outThreadQ(&killable_queue, tmp_q); force_terminate(tmp_q->tid); tmp_q = tmp_q->t_prev; } while(!emptyThreadQ(killable_queue)); } if (emptyThreadQ(ready_queue)) { if (thread_count == 1) HALT(); /* dovrebbe bastare questo tipo di controllo */ SSI_t = resolveTid(SSI_TID); if (thread_count > 0 && softb_count == 0) PANIC(); /* anche la SSI non puo' eseguire perche' e' in recv */ if (thread_count > 0 && softb_count > 0 && SSI_t->status == W4_ANYTID) { all_blocked = TRUE; /* tutti i thread sospesi */ last_time_slice = TOD_SNAPSHOT; SET_IT(pseudo_count); /* settaggio interval timer con il valore di pseudo clock */ ENABLE_INTERRUPT; for (;;); /* aspetta una interrupt */ } } upThread(); /* dispatch di un nuovo thread */ }
void __attribute__((noreturn)) panic(const char *fmt, ...) { char __panic_buffer[1024]; va_list args; interrupts_disable(); kputs("\nPANIC: "); va_start(args, fmt); vsprintf(__panic_buffer, fmt, args); va_end(args); kputs(__panic_buffer); HALT(); }
bool IAutoEvent::Wait(UInt32 timeout) { switch(WaitForSingleObject(theEvent, timeout)) { case WAIT_ABANDONED: HALT("IAutoEvent::Wait: got abandoned event"); return false; case WAIT_OBJECT_0: return true; default: case WAIT_TIMEOUT: gLog.FormattedMessage("IAutoEvent::Wait: timeout"); return false; } }
/******************************************************************************** 函数功能:睡眠前切换只sub时钟,关闭主时钟振荡,进入halt模式 入口: 返回: 无 ********************************************************************************/ void Goto_Sleep_PUCK(void) { if(Switch_Main_Osc(HALT_MODE)) { Clear_CPU_Dog(); //睡前喂狗 while(1) //对RTC闹铃和全失压的处理------PUCK { //CG_SelectPowerSaveMode(PSHALT); //STOP(); HALT(); //.......................................... Clear_CPU_Dog(); if((Resume_Src.Src_Flag&(IRAD_RESUME|KEY_RESUME))) //不是全失压或者RTC闹铃,退出睡眠 break; } } //醒来了,根据唤醒源马上切换高速晶振-----------PUCK Switch_Main_Osc(RUN_MODE); Clear_CPU_Dog(); }
Parent::Parent( GrandParent::Mode mode ) : mState( 0 ), mStageID( 0 ), mLife( INITIALI_LIFE_NUMBER ), mNextSequence( NEXT_NONE ), mChild( 0 ){ /*if ( mode == GrandParent::MODE_S1 ){ mStageID = 1; }else{ mStageID = 0; }*/ switch(mode){ case GrandParent::MODE_S1: mStageID = 0; break; case GrandParent::MODE_S2: mStageID = 1; break; case GrandParent::MODE_S3: mStageID = 2; break; case GrandParent::MODE_S4: mStageID = 3; break; case GrandParent::MODE_S5: mStageID = 4; break; case GrandParent::MODE_NONE: HALT("Stage wrong"); break; default: break; } //最初Ready mChild = new Ready(); }
void Parent::update( GrandParent* parent ){ if ( mClear ){ mClear->update( this ); }else if ( mLoading ){ mLoading->update( this ); }else if ( mMenu ){ mMenu->update( this ); }else if ( mPlay ){ mPlay->update( this ); }else{ HALT( "bakana!" ); //ありえない } //遷移判定 switch ( mNext ){ case SEQ_STAGE_SELECT: parent->moveTo( GrandParent::SEQ_STAGE_SELECT ); //丸投げ break; case SEQ_TITLE: parent->moveTo( GrandParent::SEQ_TITLE ); //丸投げ break; case SEQ_PLAY: SAFE_DELETE( mLoading ); SAFE_DELETE( mMenu ); mPlay = new Game::Play(); break; case SEQ_CLEAR: SAFE_DELETE( mPlay ); mClear = new Game::Clear(); break; case SEQ_MENU: SAFE_DELETE( mPlay ); mMenu = new Game::Menu(); break; } mNext = SEQ_NONE; //これを忘れるとひどいことに }
//---init SVM------------------------------------------------------------------- static void _svm_initSVM(VCPU *vcpu){ u32 eax, edx, ecx, ebx; u64 hsave_pa; //check if CPU supports SVM extensions cpuid(0x80000001, &eax, &ebx, &ecx, &edx); if( !(ecx & (1<<ECX_SVM)) ){ printf("\nCPU(0x%02x): no SVM extensions. HALT!", vcpu->id); HALT(); } //check if SVM extensions are disabled by the BIOS rdmsr(VM_CR_MSR, &eax, &edx); if( eax & (1<<VM_CR_SVME_DISABLE) ){ printf("\nCPU(0x%02x): SVM extensions disabled in the BIOS. HALT!", vcpu->id); HALT(); } // check for nested paging support and number of ASIDs cpuid(0x8000000A, &eax, &ebx, &ecx, &edx); if(!(edx & 0x1)){ printf("\nCPU(0x%02x): No support for Nested Paging, HALTING!", vcpu->id); HALT(); } printf("\nCPU(0x%02x): Nested paging support present", vcpu->id); if( (ebx-1) < 2 ){ printf("\nCPU(0x%02x): Total number of ASID is too low, HALTING!", vcpu->id); HALT(); } printf("\nCPU(0x%02x): Total ASID is valid", vcpu->id); // enable SVM and debugging support (if required) rdmsr((u32)VM_CR_MSR, &eax, &edx); eax &= (~(1<<VM_CR_DPD)); wrmsr((u32)VM_CR_MSR, eax, edx); printf("\nCPU(0x%02x): HDT debugging enabled", vcpu->id); rdmsr((u32)MSR_EFER, &eax, &edx); eax |= (1<<EFER_SVME); wrmsr((u32)MSR_EFER, eax, edx); printf("\nCPU(0x%02x): SVM extensions enabled", vcpu->id); // Initialize the HSA //printf("\nHSAVE area=0x%08X", vcpu->hsave_vaddr_ptr); hsave_pa = hva2spa((void*)vcpu->hsave_vaddr_ptr); //printf("\nHSAVE physaddr=0x%08x", hsave_pa); eax = (u32)hsave_pa; edx = (u32)(hsave_pa >> 32); wrmsr((u32)VM_HSAVE_PA, eax, edx); printf("\nCPU(0x%02x): SVM HSAVE initialized", vcpu->id); // enable NX protections rdmsr(MSR_EFER, &eax, &edx); eax |= (1 << EFER_NXE); wrmsr(MSR_EFER, eax, edx); printf("\nCPU(0x%02x): NX protection enabled", vcpu->id); return; }
//--------------- //--entry point-- //--------------- int main(int argc, char* argv[]) { initLog(); log("Interpreter pokrenut"); if(argc != 2) WRONG_ARGUMENT_COUNT(); if(!loadExecutableFile(argv[1])) FILE_CAN_NOT_BE_LOADED(); log("Izvrsni fajl ucitan"); for(;;) { logCPUInfo(); logMemory(IP, 20); logStackTrace(); ubyte opcode = read_next_ubyte(); log("opcode = 0x%02hx", opcode); // Testiramo prvi bit instrukcije if(opcode & 0x80) { // prvi bit 1 // odredjujemo dest i src ubyte dst = read_next_ubyte(), src; src = dst & 0x0F; dst >>= 4; //if(src == 0xf && dst == 0xf) // ADRESSING_ERROR(); switch(opcode) { case 0x80: // JMP if(dst != 0x00) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); IP = read_next_word() + (src == 0xf ? 0 : REGS[src]); break; case 0x81: // JZ if(dst != 0x00) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); { word c = read_next_word(); if(TEST_FLAG_Z()) IP += c + (src == 0xf ? 0 : REGS[src]); } break; case 0x82: // JGT if(dst != 0x00) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); { word c = read_next_word(); if(!TEST_FLAG_O() && !TEST_FLAG_Z()) IP += c + (src == 0xf ? 0 : REGS[src]); } break; case 0x83: // MOV if(src == 0x0f || dst == 0x0f) ADRESSING_ERROR(); REGS[dst] = REGS[src]; SET_OR_CLEAR_FLAG_N(REGS[dst] < 0); SET_OR_CLEAR_FLAG_Z(REGS[dst] == 0); break; case 0x84: // LDR if(dst == 0x0f) ADRESSING_ERROR(); REGS[dst] = read_word(read_next_word() + (src == 0xf ? 0 : REGS[src])); SET_OR_CLEAR_FLAG_N(REGS[dst] < 0); SET_OR_CLEAR_FLAG_Z(REGS[dst] == 0); break; case 0x85: // STR if(src == 0x0f) ADRESSING_ERROR(); write_word(read_next_word() + (dst == 0xf ? 0 : REGS[dst]), REGS[src]); break; case 0x86: // IN if(src != 0x00 || dst == 0x0f) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); scanf("%d", ®S[dst]); SET_OR_CLEAR_FLAG_N(REGS[dst] < 0); SET_OR_CLEAR_FLAG_Z(REGS[dst] == 0); break; case 0x87: // OUT if(dst != 0x00 || src == 0x0f) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); printf("%d\n", REGS[src]); break; case 0x88: // CLC if(dst != 0x00 || src != 0x00) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); CLEAR_FLAG_C(); break; case 0x89: // STC if(dst != 0x00 || src != 0x00) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); SET_FLAG_C(); break; case 0x8A: // NC if(dst != 0x00 || src != 0x00) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); if(TEST_FLAG_C()) { CLEAR_FLAG_C(); } else { SET_FLAG_C(); } break; case 0x8B: // MOVF if(src != 0x00 || dst == 0x0f) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); REGS[dst] = PSW; break; case 0x8C: // MOVTSP if(dst != 0x00 || src == 0x0f) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); SP = REGS[src]; break; case 0x8D: // MOVFSP if(src != 0x00 || dst == 0x0f) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); REGS[dst] = SP; break; case 0x8E: // CALL if(dst != 0x00) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); { word c = read_next_word(); push(IP); IP = c + (src == 0xf ? 0 : REGS[src]); } break; case 0x8F: // RET if(dst != 0x00 || src != 0x00) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); IP = pop(); break; case 0x90: // HLT if(dst != 0x00 || src != 0x00) // polje koje se ne koristi mora biti 0 ADRESSING_ERROR(); HALT(); break; default: WRONG_OP_CODE(); } } else { // prvi bit 0
// Execute one instruction cycle // void one_instruction_cycle(CPU *cpu) { // If the CPU isn't running, say so and return. // If the pc is out of range, complain and stop running the CPU. // if ((*cpu).running==0){ printf("The CPU is not running. \n"); return; } // Get instruction and increment pc // int instr_loc = (*cpu).pc; // Instruction's location (pc before increment) (*cpu).ir = (*cpu).mem[(*cpu).pc]; (*cpu).pc++; // Making sure the instruction is if ((*cpu).reg_R<0 || (*cpu).reg_R>NREG || (*cpu).addr_MM<0 || (*cpu).addr_MM>100 ) { printf("Error. The register or memory address given in the instruction is out of bounds.\n"); return; } //Decode opcode into opcode, reg_r, addr_MM, and instruction sign (*cpu).opcode = abs((*cpu).mem[instr_loc] / 1000); (*cpu).reg_R = abs((*cpu).mem[instr_loc] / 100) % 10; (*cpu).addr_MM = abs((*cpu).mem[instr_loc] % 100); // In case first instruction stored in memory is a zero, we need to give it a sign of 0. if((*cpu).mem[instr_loc] != 0) { (*cpu).instr_sign = (*cpu).mem[instr_loc] / abs((*cpu).mem[instr_loc]); } else{ (*cpu).instr_sign=0; } // Echo instruction printf("At %02d instr %d %d %02d: ", instr_loc, (*cpu).opcode, (*cpu).reg_R, (*cpu).addr_MM); switch ((*cpu).opcode) { case 0: HALT(cpu); break; case 1: LD(cpu); break; case 2: ST(cpu); break; case 3: ADD(cpu); break; case 4: NEG(cpu); break; case 5: LDM(cpu); break; case 6: ADDM(cpu); break; case 7: BR(cpu); break; case 8: BRC(cpu); break; case 9: switch ((*cpu).reg_R) { case 0: GETC(cpu); break; case 1: OUT(cpu); break; case 2: PUTS(cpu); break; case 3: dump_CPU(cpu); break; case 4: dump_memory(cpu); break; case 5: printf("Ignored"); break; case 6: printf("Ignored"); break; case 7: printf("Ignored"); break; case 8: printf("Ignored"); break; case 9: printf("Ignored"); break; } break; default: printf("Bad opcode!? %d\n", (*cpu).opcode); } }
void abort(void) { log_error("abort() called"); HALT(); }