static void prvInterruptYield( int iId ) { uint32_t *pxUpperCSA = NULL; uint32_t xUpperCSA = 0UL; extern volatile uint32_t *pxCurrentTCB; /* Just to remove compiler warnings. */ ( void ) iId; /* Save the context of a task. The upper context is automatically saved when entering a trap or interrupt. Need to save the lower context as well and copy the PCXI CSA ID into pxCurrentTCB->pxTopOfStack. Only Lower Context CSA IDs may be saved to the TCB of a task. Call vTaskSwitchContext to select the next task, note that this changes the value of pxCurrentTCB so that it needs to be reloaded. Call vPortSetMPURegisterSetOne to change the MPU mapping for the task that has just been switched in. Load the context of the task. Need to restore the lower context by loading the CSA from pxCurrentTCB->pxTopOfStack into PCXI (effectively changing the call stack). In the Interrupt handler post-amble, RSLCX will restore the lower context of the task. RFE will restore the upper context of the task, jump to the return address and restore the previous state of interrupts being enabled/disabled. */ _disable(); _dsync(); xUpperCSA = _mfcr( $PCXI ); pxUpperCSA = portCSA_TO_ADDRESS( xUpperCSA ); *pxCurrentTCB = pxUpperCSA[ 0 ]; vTaskSwitchContext(); pxUpperCSA[ 0 ] = *pxCurrentTCB; CPU_SRC0.bits.SETR = 0; _isync(); }
VOID HalpEndSystemInterrupt(KIRQL Irql) /* * FUNCTION: Enable all irqs with higher priority. */ { const USHORT mask[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, }; /* Interrupts should be disable while enabling irqs of both pics */ _disable(); pic_mask_intr.both &= mask[Irql]; WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master)); WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave)); /* restore ints */ _enable(); }
void *install_int21_hook(void) // Rueckgabe: ptr to allocated realmode mem { if ( GetLogDpmiInfo() ) LogLine("- Now installing rm hook\n"); //--- allocatore low memory for the new int21 handler --- rm21ptr = (struct rmcode *) dpmi_real_malloc(2048, &Hook21Sel); if (rm21ptr != NULL) { //--- lock this low memory region --- if (!dpmi_lock_region(rm21ptr, 2048)) { // locking failed? dpmi_real_free(Hook21Sel); return NULL; } OrgRmInt21 = ahf_dpmi_get_rmint(0x21); // get the org int21 vector //--- now patch the raw code of my new handler --- memcpy(rm21ptr, &rm21code, sizeof(rm21code)); *(unsigned long*)(rm21ptr->oldintofs) = OrgRmInt21; *(unsigned long*)(rm21ptr->LammCallAdr) = FP_OFF(RcvGP2Call); //--- now set my new handler --- _disable(); ahf_dpmi_set_rmint(0x21, ((unsigned long)DPMI_real_segment(rm21ptr) << 16) + DPMI_real_offset(rm21ptr)); _enable(); //--- make sure it's getting restored at exit --- atexit( remove_int21_hook ); } return rm21ptr; } // install_int21_hook()
static VOID StratRead( REQP_RWV FAR *rp ) { tick_mask ticks; PVOID virt; _disable(); outp( i8253CtrlZeroOrTwo, i8253CmdReadCtrZero ); ticks.b[0] = inp(i8253CounterZero ); ticks.b[1] = inp(i8253CounterZero ); UpdateTimeStamp( ticks.w ); // Update the running time stamp if( rp->count < sizeof( TIMESTAMP ) ) { rp->count = 0; // Caller's buffer is too small goto Exit; } if( DevPhysToVirt( rp->transaddr, rp->count, &virt ) != 0 ) { rp->count = 0; // DevHlp failed goto Exit; } rp->count = sizeof( TIMESTAMP ); (*(TIMESTAMP FAR*)virt) = ReadDataBuf; Exit: _enable(); rp->header.status |= RPDONE; }
// Returns the number of seconds this key has been down since last call. fix key_down_time(int scancode) { fix time_down, time; if ((scancode<0)|| (scancode>255)) return 0; #ifndef NDEBUG if (keyd_editor_mode && key_get_shift_status() ) return 0; #endif _disable(); if ( !keyd_pressed[scancode] ) { time_down = key_data.TimeKeyHeldDown[scancode]; key_data.TimeKeyHeldDown[scancode] = 0; } else { time = timer_get_fixed_secondsX(); time_down = time - key_data.TimeKeyWentDown[scancode]; key_data.TimeKeyWentDown[scancode] = time; } _enable(); return time_down; }
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts) { ULONG_PTR EFlags; /* Save EFlags and disable interrupts */ EFlags = __readeflags(); _disable(); /* Initialize and mask the PIC */ HalpInitializeLegacyPIC(); /* Initialize the I/O APIC */ ApicInitializeIOApic(); /* Manually reserve some vectors */ HalpVectorToIndex[APIC_CLOCK_VECTOR] = 8; HalpVectorToIndex[APC_VECTOR] = 99; HalpVectorToIndex[DISPATCH_VECTOR] = 99; /* Set interrupt handlers in the IDT */ KeRegisterInterruptHandler(APIC_CLOCK_VECTOR, HalpClockInterrupt); #ifndef _M_AMD64 KeRegisterInterruptHandler(APC_VECTOR, HalpApcInterrupt); KeRegisterInterruptHandler(DISPATCH_VECTOR, HalpDispatchInterrupt); #endif /* Register the vectors for APC and dispatch interrupts */ HalpRegisterVector(IDT_INTERNAL, 0, APC_VECTOR, APC_LEVEL); HalpRegisterVector(IDT_INTERNAL, 0, DISPATCH_VECTOR, DISPATCH_LEVEL); /* Restore interrupt state */ if (EnableInterrupts) EFlags |= EFLAGS_INTERRUPT_MASK; __writeeflags(EFlags); }
KIRQL NTAPI KeGetCurrentIrql (VOID) /* * PURPOSE: Returns the current irq level * RETURNS: The current irq level */ { KIRQL irql; ULONG Flags; Flags = __readeflags(); _disable(); irql = __readfsbyte(FIELD_OFFSET(KPCR, Irql)); if (irql > HIGH_LEVEL) { DPRINT1 ("CurrentIrql %x\n", irql); ASSERT(FALSE); } if (Flags & EFLAGS_INTERRUPT_MASK) { _enable(); } return irql; }
VOID FASTCALL KiEnterV86Mode(IN ULONG_PTR StackFrameUnaligned) { PKTHREAD Thread; PKV8086_STACK_FRAME StackFrame = (PKV8086_STACK_FRAME)(ROUND_UP(StackFrameUnaligned - 4, 16) + 4); PKTRAP_FRAME TrapFrame = &StackFrame->TrapFrame; PKV86_FRAME V86Frame = &StackFrame->V86Frame; PFX_SAVE_AREA NpxFrame = &StackFrame->NpxArea; ASSERT((ULONG_PTR)NpxFrame % 16 == 0); /* Build fake user-mode trap frame */ TrapFrame->SegCs = KGDT_R0_CODE | RPL_MASK; TrapFrame->SegEs = TrapFrame->SegDs = TrapFrame->SegFs = TrapFrame->SegGs = 0; TrapFrame->ErrCode = 0; /* Get the current thread's initial stack */ Thread = KeGetCurrentThread(); V86Frame->ThreadStack = KiGetThreadNpxArea(Thread); /* Save TEB addresses */ V86Frame->ThreadTeb = Thread->Teb; V86Frame->PcrTeb = KeGetPcr()->NtTib.Self; /* Save return EIP */ TrapFrame->Eip = (ULONG_PTR)Ki386BiosCallReturnAddress; /* Save our stack (after the frames) */ TrapFrame->Esi = StackFrameUnaligned; TrapFrame->Edi = (ULONG_PTR)_AddressOfReturnAddress() + 4; /* Sanitize EFlags and enable interrupts */ TrapFrame->EFlags = __readeflags() & 0x60DD7; TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK; /* Fill out the rest of the frame */ TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK; TrapFrame->HardwareEsp = 0x11FFE; TrapFrame->ExceptionList = EXCEPTION_CHAIN_END; TrapFrame->Dr7 = 0; /* Set some debug fields if trap debugging is enabled */ KiFillTrapFrameDebug(TrapFrame); /* Disable interrupts */ _disable(); /* Copy the thread's NPX frame */ RtlCopyMemory(NpxFrame, V86Frame->ThreadStack, sizeof(FX_SAVE_AREA)); /* Clear exception list */ KeGetPcr()->NtTib.ExceptionList = EXCEPTION_CHAIN_END; /* Set new ESP0 */ KeGetPcr()->TSS->Esp0 = (ULONG_PTR)&TrapFrame->V86Es; /* Set new initial stack */ Thread->InitialStack = V86Frame; /* Set VDM TEB */ Thread->Teb = (PTEB)TRAMPOLINE_TEB; KiSetTebBase(KeGetPcr(), (PVOID)TRAMPOLINE_TEB); /* Enable interrupts */ _enable(); /* Start VDM execution */ NtVdmControl(VdmStartExecution, NULL); /* Exit to V86 mode */ KiEoiHelper(TrapFrame); }
VOID FASTCALL KiIdleLoop(VOID) { PKPRCB Prcb = KeGetCurrentPrcb(); PKTHREAD OldThread, NewThread; /* Initialize the idle loop: disable interrupts */ _enable(); YieldProcessor(); YieldProcessor(); _disable(); /* Now loop forever */ while (TRUE) { /* Check for pending timers, pending DPCs, or pending ready threads */ if ((Prcb->DpcData[0].DpcQueueDepth) || (Prcb->TimerRequest) || (Prcb->DeferredReadyListHead.Next)) { /* Quiesce the DPC software interrupt */ HalClearSoftwareInterrupt(DISPATCH_LEVEL); /* Handle it */ KiRetireDpcList(Prcb); } /* Check if a new thread is scheduled for execution */ if (Prcb->NextThread) { /* Enable interupts */ _enable(); /* Capture current thread data */ OldThread = Prcb->CurrentThread; NewThread = Prcb->NextThread; /* Set new thread data */ Prcb->NextThread = NULL; Prcb->CurrentThread = NewThread; /* The thread is now running */ NewThread->State = Running; /* Switch away from the idle thread */ KiSwapContext(APC_LEVEL, OldThread); /* We are back in the idle thread -- disable interrupts again */ _enable(); YieldProcessor(); YieldProcessor(); _disable(); } else { /* Continue staying idle. Note the HAL returns with interrupts on */ Prcb->PowerState.IdleFunction(&Prcb->PowerState); } } }
void _IOFF (void) { // Disable (close) Hardware Interrupts #ifdef Watcom _disable(); #endif }
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { uint32_t *pulUpperCSA = NULL; uint32_t *pulLowerCSA = NULL; /* 16 Address Registers (4 Address registers are global), 16 Data Registers, and 3 System Registers. There are 3 registers that track the CSAs. FCX points to the head of globally free set of CSAs. PCX for the task needs to point to Lower->Upper->NULL arrangement. LCX points to the last free CSA so that corrective action can be taken. Need two CSAs to store the context of a task. The upper context contains D8-D15, A10-A15, PSW and PCXI->NULL. The lower context contains D0-D7, A2-A7, A11 and PCXI->UpperContext. The pxCurrentTCB->pxTopOfStack points to the Lower Context RSLCX matching the initial BISR. The Lower Context points to the Upper Context ready for the return from the interrupt handler. The Real stack pointer for the task is stored in the A10 which is restored with the upper context. */ /* Have to disable interrupts here because the CSAs are going to be manipulated. */ portENTER_CRITICAL(); { /* DSync to ensure that buffering is not a problem. */ _dsync(); /* Consume two free CSAs. */ pulLowerCSA = portCSA_TO_ADDRESS( _mfcr( $FCX ) ); if( NULL != pulLowerCSA ) { /* The Lower Links to the Upper. */ pulUpperCSA = portCSA_TO_ADDRESS( pulLowerCSA[ 0 ] ); } /* Check that we have successfully reserved two CSAs. */ if( ( NULL != pulLowerCSA ) && ( NULL != pulUpperCSA ) ) { /* Remove the two consumed CSAs from the free CSA list. */ _disable(); _dsync(); _mtcr( $FCX, pulUpperCSA[ 0 ] ); _isync(); _enable(); } else { /* Simply trigger a context list depletion trap. */ _svlcx(); } } portEXIT_CRITICAL(); /* Clear the upper CSA. */ memset( pulUpperCSA, 0, portNUM_WORDS_IN_CSA * sizeof( uint32_t ) ); /* Upper Context. */ pulUpperCSA[ 2 ] = ( uint32_t )pxTopOfStack; /* A10; Stack Return aka Stack Pointer */ pulUpperCSA[ 1 ] = portSYSTEM_PROGRAM_STATUS_WORD; /* PSW */ /* Clear the lower CSA. */ memset( pulLowerCSA, 0, portNUM_WORDS_IN_CSA * sizeof( uint32_t ) ); /* Lower Context. */ pulLowerCSA[ 8 ] = ( uint32_t ) pvParameters; /* A4; Address Type Parameter Register */ pulLowerCSA[ 1 ] = ( uint32_t ) pxCode; /* A11; Return Address aka RA */ /* PCXI pointing to the Upper context. */ pulLowerCSA[ 0 ] = ( portINITIAL_PCXI_UPPER_CONTEXT_WORD | ( uint32_t ) portADDRESS_TO_CSA( pulUpperCSA ) ); /* Save the link to the CSA in the top of stack. */ pxTopOfStack = (uint32_t * ) portADDRESS_TO_CSA( pulLowerCSA ); /* DSync to ensure that buffering is not a problem. */ _dsync(); return pxTopOfStack; }
static void prvSystemTickHandler( int iArg ) { uint32_t ulSavedInterruptMask; uint32_t *pxUpperCSA = NULL; uint32_t xUpperCSA = 0UL; extern volatile uint32_t *pxCurrentTCB; int32_t lYieldRequired; /* Just to avoid compiler warnings about unused parameters. */ ( void ) iArg; /* Clear the interrupt source. */ STM_ISRR.reg = 1UL; /* Reload the Compare Match register for X ticks into the future. If critical section or interrupt nesting budgets are exceeded, then it is possible that the calculated next compare match value is in the past. If this occurs (unlikely), it is possible that the resulting time slippage will exceed a single tick period. Any adverse effect of this is time bounded by the fact that only the first n bits of the 56 bit STM timer are being used for a compare match, so another compare match will occur after an overflow in just those n bits (not the entire 56 bits). As an example, if the peripheral clock is 75MHz, and the tick rate is 1KHz, a missed tick could result in the next tick interrupt occurring within a time that is 1.7 times the desired period. The fact that this is greater than a single tick period is an effect of using a timer that cannot be automatically reset, in hardware, by the occurrence of a tick interrupt. Changing the tick source to a timer that has an automatic reset on compare match (such as a GPTA timer) will reduce the maximum possible additional period to exactly 1 times the desired period. */ STM_CMP0.reg += ulCompareMatchValue; /* Kernel API calls require Critical Sections. */ ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the Tick. */ lYieldRequired = xTaskIncrementTick(); } portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask ); if( lYieldRequired != pdFALSE ) { /* Save the context of a task. The upper context is automatically saved when entering a trap or interrupt. Need to save the lower context as well and copy the PCXI CSA ID into pxCurrentTCB->pxTopOfStack. Only Lower Context CSA IDs may be saved to the TCB of a task. Call vTaskSwitchContext to select the next task, note that this changes the value of pxCurrentTCB so that it needs to be reloaded. Call vPortSetMPURegisterSetOne to change the MPU mapping for the task that has just been switched in. Load the context of the task. Need to restore the lower context by loading the CSA from pxCurrentTCB->pxTopOfStack into PCXI (effectively changing the call stack). In the Interrupt handler post-amble, RSLCX will restore the lower context of the task. RFE will restore the upper context of the task, jump to the return address and restore the previous state of interrupts being enabled/disabled. */ _disable(); _dsync(); xUpperCSA = _mfcr( $PCXI ); pxUpperCSA = portCSA_TO_ADDRESS( xUpperCSA ); *pxCurrentTCB = pxUpperCSA[ 0 ]; vTaskSwitchContext(); pxUpperCSA[ 0 ] = *pxCurrentTCB; CPU_SRC0.bits.SETR = 0; _isync(); } }
DECLSPEC_NORETURN VOID __cdecl KiTrap02(VOID) { PKTSS Tss, NmiTss; PKTHREAD Thread; PKPROCESS Process; PKGDTENTRY TssGdt; KTRAP_FRAME TrapFrame; KIRQL OldIrql; // // In some sort of strange recursion case, we might end up here with the IF // flag incorrectly on the interrupt frame -- during a normal NMI this would // normally already be set. // // For sanity's sake, make sure interrupts are disabled for sure. // NMIs will already be since the CPU does it for us. // _disable(); // // Get the current TSS, thread, and process // Tss = PCR->TSS; Thread = ((PKIPCR)PCR)->PrcbData.CurrentThread; Process = Thread->ApcState.Process; // // Save data usually not in the TSS // Tss->CR3 = Process->DirectoryTableBase[0]; Tss->IoMapBase = Process->IopmOffset; Tss->LDT = Process->LdtDescriptor.LimitLow ? KGDT_LDT : 0; // // Now get the base address of the NMI TSS // TssGdt = &((PKIPCR)KeGetPcr())->GDT[KGDT_NMI_TSS / sizeof(KGDTENTRY)]; NmiTss = (PKTSS)(ULONG_PTR)(TssGdt->BaseLow | TssGdt->HighWord.Bytes.BaseMid << 16 | TssGdt->HighWord.Bytes.BaseHi << 24); // // Switch to it and activate it, masking off the nested flag // // Note that in reality, we are already on the NMI tss -- we just need to // update the PCR to reflect this // PCR->TSS = NmiTss; __writeeflags(__readeflags() &~ EFLAGS_NESTED_TASK); TssGdt->HighWord.Bits.Dpl = 0; TssGdt->HighWord.Bits.Pres = 1; TssGdt->HighWord.Bits.Type = I386_TSS; // // Now build the trap frame based on the original TSS // // The CPU does a hardware "Context switch" / task switch of sorts and so it // takes care of saving our context in the normal TSS. // // We just have to go get the values... // RtlZeroMemory(&TrapFrame, sizeof(KTRAP_FRAME)); TrapFrame.HardwareSegSs = Tss->Ss0; TrapFrame.HardwareEsp = Tss->Esp0; TrapFrame.EFlags = Tss->EFlags; TrapFrame.SegCs = Tss->Cs; TrapFrame.Eip = Tss->Eip; TrapFrame.Ebp = Tss->Ebp; TrapFrame.Ebx = Tss->Ebx; TrapFrame.Esi = Tss->Esi; TrapFrame.Edi = Tss->Edi; TrapFrame.SegFs = Tss->Fs; TrapFrame.ExceptionList = PCR->NtTib.ExceptionList; TrapFrame.PreviousPreviousMode = -1; TrapFrame.Eax = Tss->Eax; TrapFrame.Ecx = Tss->Ecx; TrapFrame.Edx = Tss->Edx; TrapFrame.SegDs = Tss->Ds; TrapFrame.SegEs = Tss->Es; TrapFrame.SegGs = Tss->Gs; TrapFrame.DbgEip = Tss->Eip; TrapFrame.DbgEbp = Tss->Ebp; // // Store the trap frame in the KPRCB // KiSaveProcessorState(&TrapFrame, NULL); // // Call any registered NMI handlers and see if they handled it or not // if (!KiHandleNmi()) { // // They did not, so call the platform HAL routine to bugcheck the system // // Make sure the HAL believes it's running at HIGH IRQL... we can't use // the normal APIs here as playing with the IRQL could change the system // state // OldIrql = PCR->Irql; PCR->Irql = HIGH_LEVEL; HalHandleNMI(NULL); PCR->Irql = OldIrql; } // // Although the CPU disabled NMIs, we just did a BIOS Call, which could've // totally changed things. // // We have to make sure we're still in our original NMI -- a nested NMI // will point back to the NMI TSS, and in that case we're hosed. // if (PCR->TSS->Backlink != KGDT_NMI_TSS) { // // Restore original TSS // PCR->TSS = Tss; // // Set it back to busy // TssGdt->HighWord.Bits.Dpl = 0; TssGdt->HighWord.Bits.Pres = 1; TssGdt->HighWord.Bits.Type = I386_ACTIVE_TSS; // // Restore nested flag // __writeeflags(__readeflags() | EFLAGS_NESTED_TASK); // // Handled, return from interrupt // KiIret(); } // // Unhandled: crash the system // KiSystemFatalException(EXCEPTION_NMI, NULL); }
DECLSPEC_NORETURN VOID FASTCALL KiTrap07Handler(IN PKTRAP_FRAME TrapFrame) { PKTHREAD Thread, NpxThread; PFX_SAVE_AREA SaveArea, NpxSaveArea; ULONG Cr0; /* Save trap frame */ KiEnterTrap(TrapFrame); /* Try to handle NPX delay load */ while (TRUE) { /* Get the current thread */ Thread = KeGetCurrentThread(); /* Get the NPX frame */ SaveArea = KiGetThreadNpxArea(Thread); /* Check if emulation is enabled */ if (SaveArea->Cr0NpxState & CR0_EM) { /* Not implemented */ UNIMPLEMENTED; while (TRUE); } /* Save CR0 and check NPX state */ Cr0 = __readcr0(); if (Thread->NpxState != NPX_STATE_LOADED) { /* Update CR0 */ Cr0 &= ~(CR0_MP | CR0_EM | CR0_TS); __writecr0(Cr0); /* Get the NPX thread */ NpxThread = KeGetCurrentPrcb()->NpxThread; if (NpxThread) { /* Get the NPX frame */ NpxSaveArea = KiGetThreadNpxArea(NpxThread); /* Save FPU state */ DPRINT("FIXME: Save FPU state: %p\n", NpxSaveArea); //Ke386SaveFpuState(NpxSaveArea); /* Update NPX state */ Thread->NpxState = NPX_STATE_NOT_LOADED; } /* Load FPU state */ //Ke386LoadFpuState(SaveArea); /* Update NPX state */ Thread->NpxState = NPX_STATE_LOADED; KeGetCurrentPrcb()->NpxThread = Thread; /* Enable interrupts */ _enable(); /* Check if CR0 needs to be reloaded due to context switch */ if (!SaveArea->Cr0NpxState) KiEoiHelper(TrapFrame); /* Otherwise, we need to reload CR0, disable interrupts */ _disable(); /* Reload CR0 */ Cr0 = __readcr0(); Cr0 |= SaveArea->Cr0NpxState; __writecr0(Cr0); /* Now restore interrupts and check for TS */ _enable(); if (Cr0 & CR0_TS) KiEoiHelper(TrapFrame); /* We're still here -- clear TS and try again */ __writecr0(__readcr0() &~ CR0_TS); _disable(); } else { /* This is an actual fault, not a lack of FPU state */ break; } } /* TS should not be set */ if (Cr0 & CR0_TS) { /* * If it's incorrectly set, then maybe the state is actually still valid * but we could've lock track of that due to a BIOS call. * Make sure MP is still set, which should verify the theory. */ if (Cr0 & CR0_MP) { /* Indeed, the state is actually still valid, so clear TS */ __writecr0(__readcr0() &~ CR0_TS); KiEoiHelper(TrapFrame); } /* Otherwise, something strange is going on */ KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 2, Cr0, 0, 0, TrapFrame); } /* It's not a delayed load, so process this trap as an NPX fault */ KiNpxHandler(TrapFrame, Thread, SaveArea); }
VOID NTAPI KiDispatchInterrupt(VOID) { PKIPCR Pcr = (PKIPCR)KeGetPcr(); PKPRCB Prcb = &Pcr->PrcbData; PVOID OldHandler; PKTHREAD NewThread, OldThread; /* Disable interrupts */ _disable(); /* Check for pending timers, pending DPCs, or pending ready threads */ if ((Prcb->DpcData[0].DpcQueueDepth) || (Prcb->TimerRequest) || (Prcb->DeferredReadyListHead.Next)) { /* Switch to safe execution context */ OldHandler = Pcr->NtTib.ExceptionList; Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END; /* Retire DPCs while under the DPC stack */ //KiRetireDpcListInDpcStack(Prcb, Prcb->DpcStack); // FIXME!!! // KiRetireDpcList(Prcb); /* Restore context */ Pcr->NtTib.ExceptionList = OldHandler; } /* Re-enable interrupts */ _enable(); /* Check for quantum end */ if (Prcb->QuantumEnd) { /* Handle quantum end */ Prcb->QuantumEnd = FALSE; KiQuantumEnd(); } else if (Prcb->NextThread) { /* Capture current thread data */ OldThread = Prcb->CurrentThread; NewThread = Prcb->NextThread; /* Set new thread data */ Prcb->NextThread = NULL; Prcb->CurrentThread = NewThread; /* The thread is now running */ NewThread->State = Running; OldThread->WaitReason = WrDispatchInt; /* Make the old thread ready */ KxQueueReadyThread(OldThread, Prcb); /* Swap to the new thread */ KiSwapContext(APC_LEVEL, OldThread); } }
unsigned int InitAudio(unsigned int Rate,unsigned int Latency) { static const int PagePort[8] = { 0x87,0x83,0x81,0x82,-1,0x8B,0x89,0x8A }; int J,TotalBuf; char *P; /* Disable audio if was initialized */ TrashAudio(); /* If turning audio off, drop out */ if(!Rate) return(1); /* If Rate is out of range, fall out */ if((Rate<8192)||(Rate>44100)) return(0); /* Default values */ SBPort = 0x220; SBIRQ = 7; SBDMA = 1; SBIRQBusy = 0; SBWrite = 0; SBRead = 0; /* Get SoundBlaster Port#,IRQ#,DMA# */ if(P=getenv("BLASTER")) while(*P) switch(toupper(*P++)) { case 'A': SBPort=strtol(P,0,16);break; case 'D': SBDMA=strtol(P,0,16);break; case 'I': SBIRQ=strtol(P,0,16);break; } /* IRQ# = 0,1,2,3,4,5,6,7, DMA# = 0,1,2,3 */ if((SBIRQ>7)||(SBDMA>3)) return(0); /* Reset DSP */ outp(SBPort+0x06,0x01); /* Set the reset flag */ delay(100); /* Wait for 100ms */ outp(SBPort+0x06,0x00); /* Clear the reset flag */ /* Wait for READY status */ for(J=100;J&&!(inp(SBPort+0x0E)&0x80);J--); if(!J) return(0); for(J=100;J&&(ReadDSP()!=0xAA);J--); if(!J) return(0); /* Allocate low memory for DMA buffer */ TotalBuf=(Rate*Latency/1000/SND_BUFSIZE)*SND_BUFSIZE; if(TotalBuf<SND_BUFSIZE) TotalBuf=SND_BUFSIZE; SBBuffers=TotalBuf/SND_BUFSIZE; SBSegment=GetSegment(TotalBuf*sizeof(sample)*2/16+4); if(!SBSegment) return(0); J=SBSegment*16; SBBuffer=(unsigned char *)J; if((J>>16)!=((J+TotalBuf-1)>>16)) SBBuffer+=TotalBuf; memset(SBBuffer,0,TotalBuf*sizeof(sample)); /* Interrupts off */ _disable(); /* Save old interrupt vector */ IRQ5Old=(void (interrupt *)())_dos_getvect(SBIRQ+8); /* Install new interrupt vector */ _dos_setvect(SBIRQ+8,IRQ5Handler); /* Enable the SoundBlaster IRQ */ outp(0x21,inp(0x21)&~(1<<SBIRQ)); /* Disable DMA channel */ outp(0x0A,SBDMA|0x04); /* Clear byte pointer flip-flop */ outp(0x0C,0x00); /* Auto-initialized playback mode */ outp(0x0B,SBDMA|0x58); /* Write DMA offset and transfer length */ J=SBDMA<<1; outp(J,(int)SBBuffer&0xFF); outp(J,((int)SBBuffer>>8)&0xFF); outp(J+1,(TotalBuf-1)&0xFF); outp(J+1,((TotalBuf-1)>>8)&0xFF); /* Write DMA page */ outp(PagePort[SBDMA],((int)SBBuffer>>16)&0xFF); /* Enable DMA channel */ outp(0x0A,SBDMA); /* Enable interrupts */ _enable(); /* Set sampling rate */ WriteDSP(0x40); WriteDSP((65536L-(256000000L/Rate))/256); /* Set DMA transfer size */ WriteDSP(0x48); WriteDSP((SND_BUFSIZE-1)&0xFF); WriteDSP((SND_BUFSIZE-1)>>8); /* Run auto-initialized 8bit DMA */ WriteDSP(0x90); /* Speaker enabled */ WriteDSP(0xD1); /* Done */ return(SndRate=Rate); }
VOID NTAPI KeBugCheckWithTf(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4, IN PKTRAP_FRAME TrapFrame) { PKPRCB Prcb = KeGetCurrentPrcb(); CONTEXT Context; ULONG MessageId; CHAR AnsiName[128]; BOOLEAN IsSystem, IsHardError = FALSE, Reboot = FALSE; PCHAR HardErrCaption = NULL, HardErrMessage = NULL; PVOID Pc = NULL, Memory; PVOID DriverBase; PLDR_DATA_TABLE_ENTRY LdrEntry; PULONG_PTR HardErrorParameters; KIRQL OldIrql; #ifdef CONFIG_SMP LONG i = 0; #endif /* Set active bugcheck */ KeBugCheckActive = TRUE; KiBugCheckDriver = NULL; /* Check if this is power failure simulation */ if (BugCheckCode == POWER_FAILURE_SIMULATE) { /* Call the Callbacks and reboot */ KiDoBugCheckCallbacks(); HalReturnToFirmware(HalRebootRoutine); } /* Save the IRQL and set hardware trigger */ Prcb->DebuggerSavedIRQL = KeGetCurrentIrql(); InterlockedIncrement((PLONG)&KiHardwareTrigger); /* Capture the CPU Context */ RtlCaptureContext(&Prcb->ProcessorState.ContextFrame); KiSaveProcessorControlState(&Prcb->ProcessorState); Context = Prcb->ProcessorState.ContextFrame; /* FIXME: Call the Watchdog if it's registered */ /* Check which bugcode this is */ switch (BugCheckCode) { /* These bug checks already have detailed messages, keep them */ case UNEXPECTED_KERNEL_MODE_TRAP: case DRIVER_CORRUPTED_EXPOOL: case ACPI_BIOS_ERROR: case ACPI_BIOS_FATAL_ERROR: case THREAD_STUCK_IN_DEVICE_DRIVER: case DATA_BUS_ERROR: case FAT_FILE_SYSTEM: case NO_MORE_SYSTEM_PTES: case INACCESSIBLE_BOOT_DEVICE: /* Keep the same code */ MessageId = BugCheckCode; break; /* Check if this is a kernel-mode exception */ case KERNEL_MODE_EXCEPTION_NOT_HANDLED: case SYSTEM_THREAD_EXCEPTION_NOT_HANDLED: case KMODE_EXCEPTION_NOT_HANDLED: /* Use the generic text message */ MessageId = KMODE_EXCEPTION_NOT_HANDLED; break; /* File-system errors */ case NTFS_FILE_SYSTEM: /* Use the generic message for FAT */ MessageId = FAT_FILE_SYSTEM; break; /* Check if this is a coruption of the Mm's Pool */ case DRIVER_CORRUPTED_MMPOOL: /* Use generic corruption message */ MessageId = DRIVER_CORRUPTED_EXPOOL; break; /* Check if this is a signature check failure */ case STATUS_SYSTEM_IMAGE_BAD_SIGNATURE: /* Use the generic corruption message */ MessageId = BUGCODE_PSS_MESSAGE_SIGNATURE; break; /* All other codes */ default: /* Use the default bugcheck message */ MessageId = BUGCODE_PSS_MESSAGE; break; } /* Save bugcheck data */ KiBugCheckData[0] = BugCheckCode; KiBugCheckData[1] = BugCheckParameter1; KiBugCheckData[2] = BugCheckParameter2; KiBugCheckData[3] = BugCheckParameter3; KiBugCheckData[4] = BugCheckParameter4; /* Now check what bugcheck this is */ switch (BugCheckCode) { /* Invalid access to R/O memory or Unhandled KM Exception */ case KERNEL_MODE_EXCEPTION_NOT_HANDLED: case ATTEMPTED_WRITE_TO_READONLY_MEMORY: case ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY: /* Check if we have a trap frame */ if (!TrapFrame) { /* Use parameter 3 as a trap frame, if it exists */ if (BugCheckParameter3) TrapFrame = (PVOID)BugCheckParameter3; } /* Check if we got one now and if we need to get the Program Counter */ if ((TrapFrame) && (BugCheckCode != KERNEL_MODE_EXCEPTION_NOT_HANDLED)) { /* Get the Program Counter */ Pc = (PVOID)KeGetTrapFramePc(TrapFrame); } break; /* Wrong IRQL */ case IRQL_NOT_LESS_OR_EQUAL: /* * The NT kernel has 3 special sections: * MISYSPTE, POOLMI and POOLCODE. The bug check code can * determine in which of these sections this bugcode happened * and provide a more detailed analysis. For now, we don't. */ /* Program Counter is in parameter 4 */ Pc = (PVOID)BugCheckParameter4; /* Get the driver base */ DriverBase = KiPcToFileHeader(Pc, &LdrEntry, FALSE, &IsSystem); if (IsSystem) { /* * The error happened inside the kernel or HAL. * Get the memory address that was being referenced. */ Memory = (PVOID)BugCheckParameter1; /* Find to which driver it belongs */ DriverBase = KiPcToFileHeader(Memory, &LdrEntry, TRUE, &IsSystem); if (DriverBase) { /* Get the driver name and update the bug code */ KiBugCheckDriver = &LdrEntry->BaseDllName; KiBugCheckData[0] = DRIVER_PORTION_MUST_BE_NONPAGED; } else { /* Find the driver that unloaded at this address */ KiBugCheckDriver = NULL; // FIXME: ROS can't locate /* Check if the cause was an unloaded driver */ if (KiBugCheckDriver) { /* Update bug check code */ KiBugCheckData[0] = SYSTEM_SCAN_AT_RAISED_IRQL_CAUGHT_IMPROPER_DRIVER_UNLOAD; } } } else { /* Update the bug check code */ KiBugCheckData[0] = DRIVER_IRQL_NOT_LESS_OR_EQUAL; } /* Clear Pc so we don't look it up later */ Pc = NULL; break; /* Hard error */ case FATAL_UNHANDLED_HARD_ERROR: /* Copy bug check data from hard error */ HardErrorParameters = (PULONG_PTR)BugCheckParameter2; KiBugCheckData[0] = BugCheckParameter1; KiBugCheckData[1] = HardErrorParameters[0]; KiBugCheckData[2] = HardErrorParameters[1]; KiBugCheckData[3] = HardErrorParameters[2]; KiBugCheckData[4] = HardErrorParameters[3]; /* Remember that this is hard error and set the caption/message */ IsHardError = TRUE; HardErrCaption = (PCHAR)BugCheckParameter3; HardErrMessage = (PCHAR)BugCheckParameter4; break; /* Page fault */ case PAGE_FAULT_IN_NONPAGED_AREA: /* Assume no driver */ DriverBase = NULL; /* Check if we have a trap frame */ if (!TrapFrame) { /* We don't, use parameter 3 if possible */ if (BugCheckParameter3) TrapFrame = (PVOID)BugCheckParameter3; } /* Check if we have a frame now */ if (TrapFrame) { /* Get the Program Counter */ Pc = (PVOID)KeGetTrapFramePc(TrapFrame); KiBugCheckData[3] = (ULONG_PTR)Pc; /* Find out if was in the kernel or drivers */ DriverBase = KiPcToFileHeader(Pc, &LdrEntry, FALSE, &IsSystem); } else { /* Can't blame a driver, assume system */ IsSystem = TRUE; } /* FIXME: Check for session pool in addition to special pool */ /* Special pool has its own bug check codes */ if (MmIsSpecialPoolAddress((PVOID)BugCheckParameter1)) { if (MmIsSpecialPoolAddressFree((PVOID)BugCheckParameter1)) { KiBugCheckData[0] = IsSystem ? PAGE_FAULT_IN_FREED_SPECIAL_POOL : DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL; } else { KiBugCheckData[0] = IsSystem ? PAGE_FAULT_BEYOND_END_OF_ALLOCATION : DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION; } } else if (!DriverBase) { /* Find the driver that unloaded at this address */ KiBugCheckDriver = NULL; // FIXME: ROS can't locate /* Check if the cause was an unloaded driver */ if (KiBugCheckDriver) { KiBugCheckData[0] = DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS; } } break; /* Check if the driver forgot to unlock pages */ case DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS: /* Program Counter is in parameter 1 */ Pc = (PVOID)BugCheckParameter1; break; /* Check if the driver consumed too many PTEs */ case DRIVER_USED_EXCESSIVE_PTES: /* Loader entry is in parameter 1 */ LdrEntry = (PVOID)BugCheckParameter1; KiBugCheckDriver = &LdrEntry->BaseDllName; break; /* Check if the driver has a stuck thread */ case THREAD_STUCK_IN_DEVICE_DRIVER: /* The name is in Parameter 3 */ KiBugCheckDriver = (PVOID)BugCheckParameter3; break; /* Anything else */ default: break; } /* Do we have a driver name? */ if (KiBugCheckDriver) { /* Convert it to ANSI */ KeBugCheckUnicodeToAnsi(KiBugCheckDriver, AnsiName, sizeof(AnsiName)); } else { /* Do we have a Program Counter? */ if (Pc) { /* Dump image name */ KiDumpParameterImages(AnsiName, (PULONG_PTR)&Pc, 1, KeBugCheckUnicodeToAnsi); } } /* Check if we need to save the context for KD */ #ifdef _WINKD_ if (!KdPitchDebugger) KdDebuggerDataBlock.SavedContext = (ULONG_PTR)&Context; #endif /* Check if a debugger is connected */ if ((BugCheckCode != MANUALLY_INITIATED_CRASH) && (KdDebuggerEnabled)) { /* Crash on the debugger console */ DbgPrint("\n*** Fatal System Error: 0x%08lx\n" " (0x%p,0x%p,0x%p,0x%p)\n\n", KiBugCheckData[0], KiBugCheckData[1], KiBugCheckData[2], KiBugCheckData[3], KiBugCheckData[4]); /* Check if the debugger isn't currently connected */ if (!KdDebuggerNotPresent) { /* Check if we have a driver to blame */ if (KiBugCheckDriver) { /* Dump it */ DbgPrint("Driver at fault: %s.\n", AnsiName); } /* Check if this was a hard error */ if (IsHardError) { /* Print caption and message */ if (HardErrCaption) DbgPrint(HardErrCaption); if (HardErrMessage) DbgPrint(HardErrMessage); } /* Break in the debugger */ KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_FIRST); } else { /* * ROS HACK. * Ok, so debugging is enabled, but KDBG isn't there. * We'll manually dump the stack for the user. */ KeRosDumpStackFrames(NULL, 0); /* ROS HACK 2: Generate something useful for Bugzilla */ KeRosDumpTriageForBugZillaReport(); } } /* Raise IRQL to HIGH_LEVEL */ _disable(); KeRaiseIrql(HIGH_LEVEL, &OldIrql); /* Avoid recursion */ if (!InterlockedDecrement((PLONG)&KeBugCheckCount)) { #ifdef CONFIG_SMP /* Set CPU that is bug checking now */ KeBugCheckOwner = Prcb->Number; /* Freeze the other CPUs */ for (i = 0; i < KeNumberProcessors; i++) { if (i != (LONG)KeGetCurrentProcessorNumber()) { /* Send the IPI and give them one second to catch up */ KiIpiSend(1 << i, IPI_FREEZE); KeStallExecutionProcessor(1000000); } } #endif /* Display the BSOD */ KiDisplayBlueScreen(MessageId, IsHardError, HardErrCaption, HardErrMessage, AnsiName); /* Check if the debugger is disabled but we can enable it */ if (!(KdDebuggerEnabled) && !(KdPitchDebugger)) { /* Enable it */ #ifdef _WINKD_ KdEnableDebuggerWithLock(FALSE); #endif } else { /* Otherwise, print the last line */ InbvDisplayString("\r\n"); } /* Save the context */ Prcb->ProcessorState.ContextFrame = Context; /* FIXME: Support Triage Dump */ /* FIXME: Write the crash dump */ } else { /* Increase recursion count */ KeBugCheckOwnerRecursionCount++; if (KeBugCheckOwnerRecursionCount == 2) { /* Break in the debugger */ KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_SECOND); } else if (KeBugCheckOwnerRecursionCount > 2) { /* Halt execution */ while (TRUE); } } /* Call the Callbacks */ KiDoBugCheckCallbacks(); /* FIXME: Call Watchdog if enabled */ /* Check if we have to reboot */ if (Reboot) { /* Unload symbols */ DbgUnLoadImageSymbols(NULL, (PVOID)MAXULONG_PTR, 0); HalReturnToFirmware(HalRebootRoutine); } /* Attempt to break in the debugger (otherwise halt CPU) */ KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_SECOND); /* Shouldn't get here */ ASSERT(FALSE); while (TRUE); }
static int counter_nrfx_cancel_alarm(struct device *dev, u8_t chan_id) { _disable(dev, chan_id); return 0; }
void main (int argc, char *argv[]) { union REGS r; DPMI_CALLREGS dr; struct SREGS sr; char *lowp; unsigned short __far *alias; void far *fh; WORD orig_rm_seg; WORD orig_rm_off; DWORD orig_pm_off; WORD orig_pm_sel; int c; int doprot = 1; int doreal = 1; while (argc-- > 1) { if (argv[argc][0] != '-') { badarg: printf ("Invalid argument '%s'\n", argv[argc]); printf ("Valid options are:\n"); printf ("\t-p Don't install protected mode handler\n"); printf ("\t-r Don't install real mode handler\n"); printf ("\t-2 Use COM2 instead of COM1 for testing\n"); exit (1); } switch (argv[argc][1]) { case 'p': { doprot = 0; printf ("Not hooking in protected mode\n"); break; } case 'r': { doreal = 0; printf ("Not hooking in real mode\n"); break; } case '2': { com_id = 2; com_int = 0x0B; com_port = 0x2F8; printf ("Using COM2 instead of COM1 for testing\n"); break; } default: goto badarg; } if (argv[argc][2]) goto badarg; } /* Save the starting real-mode and protected-mode handler addresses. */ r.x.eax = 0x0204; /* DPMI get protected mode vector */ r.h.bl = com_int; int386 (0x31, &r, &r); orig_pm_sel = (WORD) r.x.ecx; orig_pm_off = r.x.edx; r.x.eax = 0x0200; /* DPMI get real mode vector */ r.h.bl = com_int; int386 (0x31, &r, &r); orig_rm_seg = (WORD) r.x.ecx; orig_rm_off = (WORD) r.x.edx; /* Patch the code of the real mode handler so it knows which com port is doing the communications. This is done before the handler is copied low, to take advantage of the label "com_port_low" while it's still valid. */ alias = &com_port_low; fh = (void __far *) &com_port; *(alias = MK_FP(FP_SEG(fh), FP_OFF(alias))) = com_port; /* Allocate 128 bytes of DOS memory for the real-mode handler, which must of course be less than 128 bytes long, plus 1029 bytes for the data. Then copy the real-mode handler to DOS memory and initialize the data to zero. */ if (! (lowp = D32DosMemAlloc (128 + 4 + 1024 + 1, &lowmem_seg))) { printf ("Couldn't get low memory!\n"); exit (1); } _fmemcpy ((char __far *) lowp, (void __far *) rmhandler, 128); _fmemset ((char __far *) lowp + 128, 0, 4 + 1024 + 1); fh = (void __far *) pmhandler; /* Install the new handlers. The memory touched by the protected mode handler needs to be locked, in case we are running under VMM or an external DPMI host. */ if (doprot) { r.x.eax = 0x0205; /* DPMI set protected mode vector */ r.x.ebx = (DWORD) com_int; r.x.ecx = (DWORD) FP_SEG(fh); r.x.edx = FP_OFF(fh); int386 (0x31, &r, &r); r.x.eax = 0x0600; /* DPMI lock linear region */ r.x.ebx = ((DWORD) pmhandler) >> 16; r.x.ecx = ((DWORD) pmhandler) & 0xFFFF; r.x.esi = 0; r.x.edi = 256; /* lock 256 bytes */ int386 (0x31, &r, &r); r.x.eax = 0x0600; r.x.ebx = ((DWORD) &com_port) >> 16; r.x.ecx = ((DWORD) &com_port) & 0xFFFF; r.x.esi = 0; r.x.edi = sizeof(WORD); /* lock 2 bytes */ int386 (0x31, &r, &r); } if (doreal) { r.x.eax = 0x0201; /* DPMI set real mode vector */ r.x.ebx = (DWORD) com_int; r.x.ecx = D32RealSeg(lowp); /* CX:DX == real mode &handler */ r.x.edx = D32RealOff(lowp); int386 (0x31, &r, &r); } /* Initialize COM port. */ com_init (); puts ("Move the mouse or transmit data; press ESC to cancel\n"); /* Wait for the ESC key to be pressed. This loop has a good mix of time spent in real mode and protected mode, so the upper left hand corner of your color screen will toggle between 'R' and 'P'. */ while (1) { /* Explicitly go down to real mode to ask if a key is ready. (The kbhit() call is simpler to code, but extra transfers to real mode may be optimized out by the DOS extender.) */ r.x.eax = 0x300; /* DPMI signal real mode interrupt */ r.x.ebx = 0x16; r.x.ecx = 0; fh = (void far *) &dr; _fmemset (fh, 0, sizeof(DPMI_CALLREGS)); dr.eax = 0x0100; sr.ds = 0; sr.es = FP_SEG(fh); r.x.edi = FP_OFF(fh); int386x (0x31, &r, &r, &sr); if (! (dr.flags & 0x40)) /* Test zero flag */ { if (((c = getch ()) & 0xff) == 27) break; putch (c); } /* Here we just check for an overflow, update our count of interrupts, and reset the buffer. You would process the data before flushing the buffer. */ _disable (); if (*(lowp + 128 + 4 + 1024)) /* Overflow? */ break; total_count += *((unsigned long *)(lowp + 128)); *((unsigned long *)(lowp + 128)) = 0; _enable (); } /* Clean up. */ r.x.eax = 0x0201; /* DPMI set real mode vector */ r.x.ebx = (DWORD) com_int; r.x.ecx = (DWORD) orig_rm_seg; /* CX:DX == real mode &handler */ r.x.edx = (DWORD) orig_rm_off; int386 (0x31, &r, &r); r.x.eax = 0x0205; /* DPMI set protected mode vector */ r.x.ebx = (DWORD) com_int; r.x.ecx = (DWORD) orig_pm_sel; r.x.edx = orig_pm_off; int386 (0x31, &r, &r); if (*(lowp + 128 + 4 + 1024)) printf ("\nOverflow! Increase data receive buffer size or check the\nbuffer more often.\n"); else printf ("\n%lu interrupts processed (%lu in protected mode, %lu real mode).\n", total_count, pm_count, total_count - pm_count); }
void sb16_play(WAVE_HDR* wave) { ULONG MappedIrq; KIRQL Dirql; KAFFINITY Affinity; PKINTERRUPT IrqObject; unsigned int newmask; unsigned int i; unsigned int tmp[255]; i=0; dump_wav(wave); do { // tmp[i++]=get_dma_page(0x0fffff); // DPRINT1("0x%x ",tmp[i-1]); } while((tmp[i-1]&0xffff)!=0); // free_page((tmp[0]),i-1); sb16.buffer=((unsigned char*)tmp[i-1]); /* * Because this is used by alomost every subsystem including irqs it * must be atomic. The following code sequence disables interrupts after * saving the previous state of the interrupt flag */ _disable(); memcpy(sb16.buffer,(&wave->data),wave->dLen); MappedIrq = HalGetInterruptVector(Internal,0,0,8+sb16.irq,&Dirql,&Affinity); IoConnectInterrupt(&IrqObject,DMAOutputISR,0,NULL,MappedIrq,Dirql,Dirql,0,FALSE,Affinity,FALSE); // mask=inb(0x21); newmask=((int)1<<sb16.irq); // outb(0x21,(mask&~newmask)); // Restore the interrupt flag _enable(); // disable_dma(sb16.dma8); //outb(0x0a,5); // clear_dma_ff(1); //outb(0xc,0); // set_dma_count(1,wave->dLen); //set_dma_mode(1,DMA_MODE_WRITE); //outb(0xb,0x49); //outb(0x3,(wave->dLen)&0xff); //outb(0x3,((unsigned int)(wave->dLen)>>8)&0xff); //set_dma_addr(sb16.dma8,(unsigned int)sb16.buffer); //outb(0x83,(((unsigned int)(sb16.buffer-IDMAP_BASE)>>16))&0xf); //outb(0x2,((unsigned int)sb16.buffer&0xff)); //outb(0x2,(((unsigned int)(sb16.buffer-IDMAP_BASE)>>8))&0xff); //enable_dma(sb16.dma8); //outb(0xa,1); write_dsp(sb16.base,0x00D1); write_dsp(sb16.base,0x40); write_dsp(sb16.base,((unsigned char)256-(1000000/wave->nSamplesPerSec))); // outb(sb16.base + 4, (int) 0xa); // outb(sb16.base + 5, (int) 0x00); // outb(sb16.base + 4, (int) 4); // outb(sb16.base + 5, (int) 0xFF); // outb(sb16.base + 4, (int) 0x22); // outb(sb16.base + 5, (int) 0xFF); write_dsp(sb16.base,0x14); write_dsp(sb16.base,(wave->dLen&0x00ff)); write_dsp(sb16.base,((wave->dLen)&0xff00)>>8); // write_dsp(sb16.base,0xc0); // write_dsp(sb16.base,0x0); // OldIRQ=HalGetInterruptVector(Internal,0,0,irq+8,&irql,&affinity); // DPRINT1("OldIRQ: 0x%x\n",OldIRQ); // status=IoConnectInterrupt(&IrqObject,playRoutine,0,NULL,OldIRQ,irql,irql,0,FALSE,affinity,FALSE); // if(status!=STATUS_SUCCESS) DPRINT1("Couldn't set irq\n"); // else DPRINT1("IRQ set\n"); }
VOID FASTCALL KiRetireDpcList(IN PKPRCB Prcb) { PKDPC_DATA DpcData; PLIST_ENTRY ListHead, DpcEntry; PKDPC Dpc; PKDEFERRED_ROUTINE DeferredRoutine; PVOID DeferredContext, SystemArgument1, SystemArgument2; ULONG_PTR TimerHand; #ifdef CONFIG_SMP KIRQL OldIrql; #endif /* Get data and list variables before starting anything else */ DpcData = &Prcb->DpcData[DPC_NORMAL]; ListHead = &DpcData->DpcListHead; /* Main outer loop */ do { /* Set us as active */ Prcb->DpcRoutineActive = TRUE; /* Check if this is a timer expiration request */ if (Prcb->TimerRequest) { /* It is, get the timer hand and disable timer request */ TimerHand = Prcb->TimerHand; Prcb->TimerRequest = 0; /* Expire timers with interrups enabled */ _enable(); KiTimerExpiration(NULL, NULL, (PVOID)TimerHand, NULL); _disable(); } /* Loop while we have entries in the queue */ while (DpcData->DpcQueueDepth != 0) { /* Lock the DPC data and get the DPC entry*/ KeAcquireSpinLockAtDpcLevel(&DpcData->DpcLock); DpcEntry = ListHead->Flink; /* Make sure we have an entry */ if (DpcEntry != ListHead) { /* Remove the DPC from the list */ RemoveEntryList(DpcEntry); Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry); /* Clear its DPC data and save its parameters */ Dpc->DpcData = NULL; DeferredRoutine = Dpc->DeferredRoutine; DeferredContext = Dpc->DeferredContext; SystemArgument1 = Dpc->SystemArgument1; SystemArgument2 = Dpc->SystemArgument2; /* Decrease the queue depth */ DpcData->DpcQueueDepth--; /* Clear DPC Time */ Prcb->DebugDpcTime = 0; /* Release the lock */ KeReleaseSpinLockFromDpcLevel(&DpcData->DpcLock); /* Re-enable interrupts */ _enable(); /* Call the DPC */ DeferredRoutine(Dpc, DeferredContext, SystemArgument1, SystemArgument2); ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); /* Disable interrupts and keep looping */ _disable(); } else { /* The queue should be flushed now */ ASSERT(DpcData->DpcQueueDepth == 0); /* Release DPC Lock */ KeReleaseSpinLockFromDpcLevel(&DpcData->DpcLock); } } /* Clear DPC Flags */ Prcb->DpcRoutineActive = FALSE; Prcb->DpcInterruptRequested = FALSE; #ifdef CONFIG_SMP /* Check if we have deferred threads */ if (Prcb->DeferredReadyListHead.Next) { /* Re-enable interrupts and raise to synch */ _enable(); OldIrql = KeRaiseIrqlToSynchLevel(); /* Process deferred threads */ KiProcessDeferredReadyList(Prcb); /* Lower IRQL back and disable interrupts */ KeLowerIrql(OldIrql); _disable(); } #endif } while (DpcData->DpcQueueDepth != 0); }
DECLSPEC_NORETURN VOID FASTCALL KiTrap06Handler(IN PKTRAP_FRAME TrapFrame) { PUCHAR Instruction; ULONG i; KIRQL OldIrql; /* Check for V86 GPF */ if (__builtin_expect(KiV86Trap(TrapFrame), 1)) { /* Enter V86 trap */ KiEnterV86Trap(TrapFrame); /* Must be a VDM process */ if (__builtin_expect(!PsGetCurrentProcess()->VdmObjects, 0)) { /* Enable interrupts */ _enable(); /* Setup illegal instruction fault */ KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION, TrapFrame->Eip, TrapFrame); } /* Go to APC level */ OldIrql = KfRaiseIrql(APC_LEVEL); _enable(); /* Check for BOP */ if (!VdmDispatchBop(TrapFrame)) { /* Should only happen in VDM mode */ UNIMPLEMENTED; while (TRUE); } /* Bring IRQL back */ KfLowerIrql(OldIrql); _disable(); /* Do a quick V86 exit if possible */ KiExitV86Trap(TrapFrame); } /* Save trap frame */ KiEnterTrap(TrapFrame); /* Enable interrupts */ Instruction = (PUCHAR)TrapFrame->Eip; _enable(); /* Check for user trap */ if (KiUserTrap(TrapFrame)) { /* FIXME: Use SEH */ /* Scan next 4 opcodes */ for (i = 0; i < 4; i++) { /* Check for LOCK instruction */ if (Instruction[i] == 0xF0) { /* Send invalid lock sequence exception */ KiDispatchException0Args(STATUS_INVALID_LOCK_SEQUENCE, TrapFrame->Eip, TrapFrame); } } /* FIXME: SEH ends here */ } /* Kernel-mode or user-mode fault (but not LOCK) */ KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION, TrapFrame->Eip, TrapFrame); }
VOID NTAPI KiTimerExpiration(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { ULARGE_INTEGER SystemTime, InterruptTime; LARGE_INTEGER Interval; LONG Limit, Index, i; ULONG Timers, ActiveTimers, DpcCalls; PLIST_ENTRY ListHead, NextEntry; KIRQL OldIrql; PKTIMER Timer; PKDPC TimerDpc; ULONG Period; DPC_QUEUE_ENTRY DpcEntry[MAX_TIMER_DPCS]; PKSPIN_LOCK_QUEUE LockQueue; #ifdef CONFIG_SMP PKPRCB Prcb = KeGetCurrentPrcb(); #endif /* Disable interrupts */ _disable(); /* Query system and interrupt time */ KeQuerySystemTime((PLARGE_INTEGER)&SystemTime); InterruptTime.QuadPart = KeQueryInterruptTime(); Limit = KeTickCount.LowPart; /* Bring interrupts back */ _enable(); /* Get the index of the timer and normalize it */ Index = PtrToLong(SystemArgument1); if ((Limit - Index) >= TIMER_TABLE_SIZE) { /* Normalize it */ Limit = Index + TIMER_TABLE_SIZE - 1; } /* Setup index and actual limit */ Index--; Limit &= (TIMER_TABLE_SIZE - 1); /* Setup accounting data */ DpcCalls = 0; Timers = 24; ActiveTimers = 4; /* Lock the Database and Raise IRQL */ OldIrql = KiAcquireDispatcherLock(); /* Start expiration loop */ do { /* Get the current index */ Index = (Index + 1) & (TIMER_TABLE_SIZE - 1); /* Get list pointers and loop the list */ ListHead = &KiTimerTableListHead[Index].Entry; while (ListHead != ListHead->Flink) { /* Lock the timer and go to the next entry */ LockQueue = KiAcquireTimerLock(Index); NextEntry = ListHead->Flink; /* Get the current timer and check its due time */ Timers--; Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry); if ((NextEntry != ListHead) && (Timer->DueTime.QuadPart <= InterruptTime.QuadPart)) { /* It's expired, remove it */ ActiveTimers--; KiRemoveEntryTimer(Timer); /* Make it non-inserted, unlock it, and signal it */ Timer->Header.Inserted = FALSE; KiReleaseTimerLock(LockQueue); Timer->Header.SignalState = 1; /* Get the DPC and period */ TimerDpc = Timer->Dpc; Period = Timer->Period; /* Check if there's any waiters */ if (!IsListEmpty(&Timer->Header.WaitListHead)) { /* Check the type of event */ if (Timer->Header.Type == TimerNotificationObject) { /* Unwait the thread */ KxUnwaitThread(&Timer->Header, IO_NO_INCREMENT); } else { /* Otherwise unwait the thread and signal the timer */ KxUnwaitThreadForEvent((PKEVENT)Timer, IO_NO_INCREMENT); } } /* Check if we have a period */ if (Period) { /* Calculate the interval and insert the timer */ Interval.QuadPart = Int32x32To64(Period, -10000); while (!KiInsertTreeTimer(Timer, Interval)); } /* Check if we have a DPC */ if (TimerDpc) { #ifdef CONFIG_SMP /* * If the DPC is targeted to another processor, * then insert it into that processor's DPC queue * instead of delivering it now. * If the DPC is a threaded DPC, and the current CPU * has threaded DPCs enabled (KiExecuteDpc is actively parsing DPCs), * then also insert it into the DPC queue for threaded delivery, * instead of doing it here. */ if (((TimerDpc->Number >= MAXIMUM_PROCESSORS) && ((TimerDpc->Number - MAXIMUM_PROCESSORS) != Prcb->Number)) || ((TimerDpc->Type == ThreadedDpcObject) && (Prcb->ThreadDpcEnable))) { /* Queue it */ KeInsertQueueDpc(TimerDpc, UlongToPtr(SystemTime.LowPart), UlongToPtr(SystemTime.HighPart)); } else #endif { /* Setup the DPC Entry */ DpcEntry[DpcCalls].Dpc = TimerDpc; DpcEntry[DpcCalls].Routine = TimerDpc->DeferredRoutine; DpcEntry[DpcCalls].Context = TimerDpc->DeferredContext; DpcCalls++; ASSERT(DpcCalls < MAX_TIMER_DPCS); } } /* Check if we're done processing */ if (!(ActiveTimers) || !(Timers)) { /* Release the dispatcher while doing DPCs */ KiReleaseDispatcherLock(DISPATCH_LEVEL); /* Start looping all DPC Entries */ for (i = 0; DpcCalls; DpcCalls--, i++) { /* Call the DPC */ DpcEntry[i].Routine(DpcEntry[i].Dpc, DpcEntry[i].Context, UlongToPtr(SystemTime.LowPart), UlongToPtr(SystemTime.HighPart)); } /* Reset accounting */ Timers = 24; ActiveTimers = 4; /* Lock the dispatcher database */ KiAcquireDispatcherLock(); } } else { /* Check if the timer list is empty */ if (NextEntry != ListHead) { /* Sanity check */ ASSERT(KiTimerTableListHead[Index].Time.QuadPart <= Timer->DueTime.QuadPart); /* Update the time */ _disable(); KiTimerTableListHead[Index].Time.QuadPart = Timer->DueTime.QuadPart; _enable(); } /* Release the lock */ KiReleaseTimerLock(LockQueue); /* Check if we've scanned all the timers we could */ if (!Timers) { /* Release the dispatcher while doing DPCs */ KiReleaseDispatcherLock(DISPATCH_LEVEL); /* Start looping all DPC Entries */ for (i = 0; DpcCalls; DpcCalls--, i++) { /* Call the DPC */ DpcEntry[i].Routine(DpcEntry[i].Dpc, DpcEntry[i].Context, UlongToPtr(SystemTime.LowPart), UlongToPtr(SystemTime.HighPart)); } /* Reset accounting */ Timers = 24; ActiveTimers = 4; /* Lock the dispatcher database */ KiAcquireDispatcherLock(); } /* Done looping */ break; } } } while (Index != Limit); /* Verify the timer table, on debug builds */ if (KeNumberProcessors == 1) KiCheckTimerTable(InterruptTime); /* Check if we still have DPC entries */ if (DpcCalls) { /* Release the dispatcher while doing DPCs */ KiReleaseDispatcherLock(DISPATCH_LEVEL); /* Start looping all DPC Entries */ for (i = 0; DpcCalls; DpcCalls--, i++) { /* Call the DPC */ DpcEntry[i].Routine(DpcEntry[i].Dpc, DpcEntry[i].Context, UlongToPtr(SystemTime.LowPart), UlongToPtr(SystemTime.HighPart)); } /* Lower IRQL if we need to */ if (OldIrql != DISPATCH_LEVEL) KeLowerIrql(OldIrql); } else { /* Unlock the dispatcher */ KiReleaseDispatcherLock(OldIrql); } }
DECLSPEC_NORETURN VOID FASTCALL KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame) { ULONG i, j, Iopl; BOOLEAN Privileged = FALSE; PUCHAR Instructions; UCHAR Instruction = 0; KIRQL OldIrql; /* Check for V86 GPF */ if (__builtin_expect(KiV86Trap(TrapFrame), 1)) { /* Enter V86 trap */ KiEnterV86Trap(TrapFrame); /* Must be a VDM process */ if (__builtin_expect(!PsGetCurrentProcess()->VdmObjects, 0)) { /* Enable interrupts */ _enable(); /* Setup illegal instruction fault */ KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION, TrapFrame->Eip, TrapFrame); } /* Go to APC level */ OldIrql = KfRaiseIrql(APC_LEVEL); _enable(); /* Handle the V86 opcode */ if (__builtin_expect(Ki386HandleOpcodeV86(TrapFrame) == 0xFF, 0)) { /* Should only happen in VDM mode */ UNIMPLEMENTED; while (TRUE); } /* Bring IRQL back */ KfLowerIrql(OldIrql); _disable(); /* Do a quick V86 exit if possible */ KiExitV86Trap(TrapFrame); } /* Save trap frame */ KiEnterTrap(TrapFrame); /* Check for user-mode GPF */ if (KiUserTrap(TrapFrame)) { /* Should not be VDM */ ASSERT(KiVdmTrap(TrapFrame) == FALSE); /* Enable interrupts and check error code */ _enable(); if (!TrapFrame->ErrCode) { /* FIXME: Use SEH */ Instructions = (PUCHAR)TrapFrame->Eip; /* Scan next 15 bytes */ for (i = 0; i < 15; i++) { /* Skip prefix instructions */ for (j = 0; j < sizeof(KiTrapPrefixTable); j++) { /* Is this a prefix instruction? */ if (Instructions[i] == KiTrapPrefixTable[j]) { /* Stop looking */ break; } } /* Is this NOT any prefix instruction? */ if (j == sizeof(KiTrapPrefixTable)) { /* We can go ahead and handle the fault now */ Instruction = Instructions[i]; break; } } /* If all we found was prefixes, then this instruction is too long */ if (i == 15) { /* Setup illegal instruction fault */ KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION, TrapFrame->Eip, TrapFrame); } /* Check for privileged instructions */ if (Instruction == 0xF4) // HLT { /* HLT is privileged */ Privileged = TRUE; } else if (Instruction == 0x0F) { /* Test if it's any of the privileged two-byte opcodes */ if (((Instructions[i + 1] == 0x00) && // LLDT or LTR (((Instructions[i + 2] & 0x38) == 0x10) || // LLDT (Instructions[i + 2] == 0x18))) || // LTR ((Instructions[i + 1] == 0x01) && // LGDT or LIDT or LMSW (((Instructions[i + 2] & 0x38) == 0x10) || // LGDT (Instructions[i + 2] == 0x18) || // LIDT (Instructions[i + 2] == 0x30))) || // LMSW (Instructions[i + 1] == 0x08) || // INVD (Instructions[i + 1] == 0x09) || // WBINVD (Instructions[i + 1] == 0x35) || // SYSEXIT (Instructions[i + 1] == 0x26) || // MOV DR, XXX (Instructions[i + 1] == 0x06) || // CLTS (Instructions[i + 1] == 0x20) || // MOV CR, XXX (Instructions[i + 1] == 0x24) || // MOV YYY, DR (Instructions[i + 1] == 0x30) || // WRMSR (Instructions[i + 1] == 0x33)) // RDPMC // INVLPG, INVLPGA, SYSRET { /* These are all privileged */ Privileged = TRUE; } } else { /* Get the IOPL and compare with the RPL mask */ Iopl = (TrapFrame->EFlags & EFLAGS_IOPL) >> 12; if ((TrapFrame->SegCs & RPL_MASK) > Iopl) { /* I/O privilege error -- check for known instructions */ if ((Instruction == 0xFA) || (Instruction == 0xFB)) // CLI or STI { /* These are privileged */ Privileged = TRUE; } else { /* Last hope: an IN/OUT instruction */ for (j = 0; j < sizeof(KiTrapIoTable); j++) { /* Is this an I/O instruction? */ if (Instruction == KiTrapIoTable[j]) { /* Then it's privileged */ Privileged = TRUE; break; } } } } } /* So now... was the instruction privileged or not? */ if (Privileged) { /* Whew! We have a privileged instruction, so dispatch the fault */ KiDispatchException0Args(STATUS_PRIVILEGED_INSTRUCTION, TrapFrame->Eip, TrapFrame); } } /* If we got here, send an access violation */ KiDispatchException2Args(STATUS_ACCESS_VIOLATION, TrapFrame->Eip, 0, 0xFFFFFFFF, TrapFrame); }
void DataOStream::disable() { if( !_disable( )) return; _connections.clear(); }
int32_t xPortStartScheduler( void ) { extern void vTrapInstallHandlers( void ); uint32_t ulMFCR = 0UL; uint32_t *pulUpperCSA = NULL; uint32_t *pulLowerCSA = NULL; /* Interrupts at or below configMAX_SYSCALL_INTERRUPT_PRIORITY are disable when this function is called. */ /* Set-up the timer interrupt. */ prvSetupTimerInterrupt(); /* Install the Trap Handlers. */ vTrapInstallHandlers(); /* Install the Syscall Handler for yield calls. */ if( 0 == _install_trap_handler( portSYSCALL_TRAP, prvTrapYield ) ) { /* Failed to install the yield handler, force an assert. */ configASSERT( ( ( volatile void * ) NULL ) ); } /* Enable then install the priority 1 interrupt for pending context switches from an ISR. See mod_SRC in the TriCore manual. */ CPU_SRC0.reg = ( portENABLE_CPU_INTERRUPT ) | ( configKERNEL_YIELD_PRIORITY ); if( 0 == _install_int_handler( configKERNEL_YIELD_PRIORITY, prvInterruptYield, 0 ) ) { /* Failed to install the yield handler, force an assert. */ configASSERT( ( ( volatile void * ) NULL ) ); } _disable(); /* Load the initial SYSCON. */ _mtcr( $SYSCON, portINITIAL_SYSCON ); _isync(); /* ENDINIT has already been applied in the 'cstart.c' code. */ /* Clear the PSW.CDC to enable the use of an RFE without it generating an exception because this code is not genuinely in an exception. */ ulMFCR = _mfcr( $PSW ); ulMFCR &= portRESTORE_PSW_MASK; _dsync(); _mtcr( $PSW, ulMFCR ); _isync(); /* Finally, perform the equivalent of a portRESTORE_CONTEXT() */ pulLowerCSA = portCSA_TO_ADDRESS( ( *pxCurrentTCB ) ); pulUpperCSA = portCSA_TO_ADDRESS( pulLowerCSA[0] ); _dsync(); _mtcr( $PCXI, *pxCurrentTCB ); _isync(); _nop(); _rslcx(); _nop(); /* Return to the first task selected to execute. */ __asm volatile( "rfe" ); /* Will not get here. */ return 0; }
void interrupt far com1_isr(void) { // performs rs232 functions on com1 unsigned intr; unsigned i; //unsigned lsb; //unsigned msb; _enable(); // disable com1 uart interrupts _outp(COM1_MCR, _inp(COM1_MCR) & 0xf7); start_com1_isr: // check contents of COM1_IIR intr = _inp(COM1_IIR); intr = intr & 0x0f; // mask off b7 to b4 if((intr & 0x01) == 0) // if a valid com1 interrupt is pending { // shift IIR value right one bit and test to see which routine is required intr = intr >> 1; // do rs232 input interrupt routine if(intr == 0) { // read the rs232 status register unsigned msr_char = _inp(COM1_MSR); goto start_com1_isr; } // do tx buffer empty interrupt routine if(intr == 1) { // either write to tx FIFO or read int id register again // the idea here is to continue a tx once it has started, // not to start one in the first place // the tx is started by the main() program writing the first // char to the tx buffer, which will send the char out // once the tx fifo has drained, the tbe bit will be // set in the iir, indicating that the tx buffer is ready for more if(com1_tx==0) // no message to tx { _inp(COM1_IIR); goto start_com1_isr; } if(com1_tx==1) // tx remaining message { for(i=0; i<16;i++) // load 16 characters into the tx fifo { if(com1_tx==0) break; else // only if more message needs to be sent { _outp(COM1_TX, tx1_message[tx1_index]); // write the next character tx1_index++; tx1_counter++; if(tx1_index >= tx1_len) // entire message has been sent { tx1_index = 0; com1_tx = 0; tx1_len = 0; goto start_com1_isr; } } } } goto start_com1_isr; } // rx data received interrupt routine (>= 14 bytes in receive buffer) if(intr == 2) { // read rx register // read 12 bytes from the rx register (still at least 2 bytes left) for(i = 0; i < 12; i++) { rx1_message[rx1_index] = _inp(COM1_RX); rx1_index++; if(rx1_index >= sizeof(rx1_message)) rx1_index = 0; } goto start_com1_isr; } // else do serialization error/break routine if(intr == 3) { // read serialization/line status register unsigned lsr_char = _inp(COM1_LSR); goto start_com1_isr; } // do rx character timeout routine: message end if(intr == 6) { // drain rx fifo while((_inp(COM1_LSR) & 0x01) == 1) { rx1_message[rx1_index] = _inp(COM1_RX); rx1_index++; if(rx1_index >= sizeof(rx1_message)) rx1_index = 0; } //if(rx1_index >= 88) // complete frame received if(rx1_index >= 213) // complete frame received // for PD0 format db & jtm 11/16/2007 { // timestamp the adcp message _disable(); time_stamp(&adcp_time); _enable(); //memcpy(adcp_buffer, rx1_message, 88); //_fmemcpy(adcp_buffer, rx1_message, sizeof(adcp_buffer));//for PD0 format db & jtm 11/16/2007 _fmemcpy(adcp_buffer, rx1_message, 213);//for PD0 format db & jtm 11/16/2007 //rx1_index = 0; adcp_new_data = 1; adcp_data_frame = frame; } rx1_index = 0; goto start_com1_isr; } // end rx character timeout routine goto start_com1_isr; } // end if((intr & 0x01) == 0)
void ui_mega_process() { int mx, my, mz; unsigned char k; event_process(); switch( Record ) { case 0: mouse_get_delta( &mx, &my, &mz ); Mouse.new_dx = mx; Mouse.new_dy = my; Mouse.new_buttons = mouse_get_btns(); last_keypress = key_inkey(); if ( Mouse.new_buttons || last_keypress || Mouse.new_dx || Mouse.new_dy ) { last_event = timer_query(); } break; case 1: if (ui_event_counter==0 ) { EventBuffer[ui_event_counter].frame = 0; EventBuffer[ui_event_counter].type = 7; EventBuffer[ui_event_counter].data = ui_number_of_events; ui_event_counter++; } if (ui_event_counter==1 && (RecordFlags & UI_RECORD_MOUSE) ) { Mouse.new_buttons = 0; EventBuffer[ui_event_counter].frame = FrameCount; EventBuffer[ui_event_counter].type = 6; EventBuffer[ui_event_counter].data = ((Mouse.y & 0xFFFF) << 16) | (Mouse.x & 0xFFFF); ui_event_counter++; } mouse_get_delta( &mx, &my, &mz ); MouseDX = mx; MouseDY = my; MouseButtons = mouse_get_btns(); Mouse.new_dx = MouseDX; Mouse.new_dy = MouseDY; if ((MouseDX != 0 || MouseDY != 0) && (RecordFlags & UI_RECORD_MOUSE) ) { if (ui_event_counter < ui_number_of_events-1 ) { EventBuffer[ui_event_counter].frame = FrameCount; EventBuffer[ui_event_counter].type = 1; EventBuffer[ui_event_counter].data = ((MouseDY & 0xFFFF) << 16) | (MouseDX & 0xFFFF); ui_event_counter++; } else { Record = 0; } } if ( (MouseButtons != Mouse.new_buttons) && (RecordFlags & UI_RECORD_MOUSE) ) { Mouse.new_buttons = MouseButtons; if (ui_event_counter < ui_number_of_events-1 ) { EventBuffer[ui_event_counter].frame = FrameCount; EventBuffer[ui_event_counter].type = 2; EventBuffer[ui_event_counter].data = MouseButtons; ui_event_counter++; } else { Record = 0; } } if ( keyd_last_pressed && (RecordFlags & UI_RECORD_KEYS) ) { _disable(); k = keyd_last_pressed; keyd_last_pressed= 0; _enable(); if (ui_event_counter < ui_number_of_events-1 ) { EventBuffer[ui_event_counter].frame = FrameCount; EventBuffer[ui_event_counter].type = 3; EventBuffer[ui_event_counter].data = k; ui_event_counter++; } else { Record = 0; } } if ( keyd_last_released && (RecordFlags & UI_RECORD_KEYS) ) { _disable(); k = keyd_last_released; keyd_last_released= 0; _enable(); if (ui_event_counter < ui_number_of_events-1 ) { EventBuffer[ui_event_counter].frame = FrameCount; EventBuffer[ui_event_counter].type = 4; EventBuffer[ui_event_counter].data = k; ui_event_counter++; } else { Record = 0; } } last_keypress = key_inkey(); if (last_keypress == KEY_F12 ) { ui_number_of_events = ui_event_counter; last_keypress = 0; Record = 0; break; } if ((last_keypress != 0) && (RecordFlags & UI_RECORD_KEYS) ) { if (ui_event_counter < ui_number_of_events-1 ) { EventBuffer[ui_event_counter].frame = FrameCount; EventBuffer[ui_event_counter].type = 5; EventBuffer[ui_event_counter].data = last_keypress; ui_event_counter++; } else { Record = 0; } } FrameCount++; break; case 2: case 3: Mouse.new_dx = 0; Mouse.new_dy = 0; Mouse.new_buttons = 0; last_keypress = 0; if ( keyd_last_pressed ) { _disable(); k = keyd_last_pressed; keyd_last_pressed = 0; _disable(); SavedState[k] = 1; } if ( keyd_last_released ) { _disable(); k = keyd_last_released; keyd_last_released = 0; _disable(); SavedState[k] = 0; } if (key_inkey() == KEY_F12 ) { restore_state(); Record = 0; break; } if (EventBuffer==NULL) { restore_state(); Record = 0; break; } while( (ui_event_counter < ui_number_of_events) && (EventBuffer[ui_event_counter].frame <= FrameCount) ) { switch ( EventBuffer[ui_event_counter].type ) { case 1: // Mouse moved Mouse.new_dx = EventBuffer[ui_event_counter].data & 0xFFFF; Mouse.new_dy = (EventBuffer[ui_event_counter].data >> 16) & 0xFFFF; break; case 2: // Mouse buttons changed Mouse.new_buttons = EventBuffer[ui_event_counter].data; break; case 3: // Key moved down keyd_pressed[ EventBuffer[ui_event_counter].data ] = 1; break; case 4: // Key moved up keyd_pressed[ EventBuffer[ui_event_counter].data ] = 0; break; case 5: // Key pressed last_keypress = EventBuffer[ui_event_counter].data; break; case 6: // Initial Mouse X position Mouse.x = EventBuffer[ui_event_counter].data & 0xFFFF; Mouse.y = (EventBuffer[ui_event_counter].data >> 16) & 0xFFFF; break; case 7: break; } ui_event_counter++; if (ui_event_counter >= ui_number_of_events ) { Record = 0; restore_state(); //( 0, "Done playing %d events.\n", ui_number_of_events ); } } switch (Record) { case 2: { int next_frame; if ( ui_event_counter < ui_number_of_events ) { next_frame = EventBuffer[ui_event_counter].frame; if ( (FrameCount+PlaybackSpeed) < next_frame ) FrameCount = next_frame - PlaybackSpeed; else FrameCount++; } else { FrameCount++; } } break; case 3: if ( ui_event_counter < ui_number_of_events ) FrameCount = EventBuffer[ui_event_counter].frame; else FrameCount++; break; default: FrameCount++; } } ui_mouse_process(); }
static void _read_data(const tsl2561_t *dev, uint16_t *full, uint16_t *ir) { /* Enable the device */ _enable(dev); /* Wait integration time in ms for ADC to complete */ switch (dev->integration) { case TSL2561_INTEGRATIONTIME_13MS: xtimer_usleep(13700); break; case TSL2561_INTEGRATIONTIME_101MS: xtimer_usleep(101000); break; default: /* TSL2561_INTEGRATIONTIME_402MS */ xtimer_usleep(402000); break; } char buffer[2] = { 0 }; /* Read full spectrum channel */ i2c_read_regs(dev->i2c_dev, dev->addr, TSL2561_COMMAND_MODE | TSL2561_COMMAND_WORD | TSL2561_REGISTER_CHAN0, buffer, 2); *full = (buffer[1] << 8) | buffer[0]; memset(buffer, 0, sizeof(buffer)); /* Read infrared spectrum channel */ i2c_read_regs(dev->i2c_dev, dev->addr, TSL2561_COMMAND_MODE | TSL2561_COMMAND_WORD | TSL2561_REGISTER_CHAN1, buffer, 2); *ir = (buffer[1] << 8) | buffer[0]; /* Turn the device off to save power */ _disable(dev); }
unsigned char ftDigital (unsigned short port) { unsigned char result = 0; #ifdef _WIN32 unsigned short status = port+1; int enabled = ftDisable && _disable(); #endif #ifdef SC12 unsigned short status = port; #endif int bit = 8; int data = triggerX|triggerY|loadIn; if (ftLoadOut) data |= loadOut; trace(8, ("digital %03x", port)); trace(32, (" >%02x", data)); _outp(port, data); idle(ftIdle); data |= clock; trace(32, (" >%02x", data)); _outp(port, data); while (bit-- > 0) { idle(ftIdle); result |= ((_inp(status) & busy) != 0) << bit; trace(16, (" <%02x", result)); data = triggerX|triggerY; if (ftLoadOut) data |= loadOut; trace(32, (" >%02x", data)); _outp(port, data); idle(ftIdle); data |= clock; trace(32, (" >%02x", data)); _outp(port, data); } trace(8, (" %02x\n", result)); #ifdef _WIN32 if (enabled) _enable(); #endif return result; }