void ldevent_plexon_low(EVENT *evp, int flag) { int scrb_msg0 = 0, scrb_msg1= 0; unsigned eflags; /* * Must be done with interrupts disabled. Critical * sections with interrupt routine, or scheduling of other processes * which might call ldevent(). */ if((eflags= pswget()) & INTR_IF) InterruptDisable(); if(!flag) { i_b->bevent[i_b->evlx]= *evp; if(++i_b->evlx >= EBUFNUM) i_b->evlx= 0; if(i_b->evlx == i_b->evdx) scrb_msg0= SC_EVERR; if(i_b->evlx == i_b->evdump) { /* time to set new dump? */ i_b->evdump += EDUMPINC; if(i_b->evdump >= EBUFNUM) i_b->evdump -= EBUFNUM; /* * If writing to disk, alert scribe. */ if(i_b->i_flags & I_EOUT) scrb_msg1= SC_EDUMP; } } /* * Send ecode to Plexon box. * Don't send negative ecodes, because only lower 15 bits of * code can be sent to Plexon box. Critical section- this must be done * high priority to avoid conflict with other places events are sent * to plexon box. Don't send ecode directly to Plexon box from here- * just buffer it. This lets high priority ecodes have precendence. */ if( (evp->e_code >= 0) ) { i_b->pl_lopri[i_b->pl_lolx]= evp->e_code; if(++i_b->pl_lolx >= PL_MAXCODES) i_b->pl_lolx= 0; if(i_b->pl_lolx == i_b->pl_lodx) rxerr("Plexon lo pri buffer overflow"); /* overflow error */ } if(eflags & INTR_IF) InterruptEnable(); if(scrb_msg0) r_sendmsg(SCRB, scrb_msg0); if(scrb_msg1) r_sendmsg(SCRB, scrb_msg1); }
static const struct sigevent * md_intr(void *d, int id) { struct mdriver_entry *md = d; int r; if(md->intr != _NTO_INTR_SPARE) { InterruptDisable(); r = md->handler(MDRIVER_PROCESS, md->data); InterruptEnable(); if(r != 0) { md->intr = _NTO_INTR_SPARE; SIGEV_THREAD_INIT(&sigev, md_detach, md, &attr); return &sigev; } } return NULL; }
static T_uezError LPC17xx_40xx_SSP_TransferNoBlock( void *aWorkspace, SPI_Request *aRequest, T_spiCompleteCallback aCallback, void *aCallbackWorkspace) { T_LPC17xx_40xx_SSP_Workspace *aW = (T_LPC17xx_40xx_SSP_Workspace *)aWorkspace; T_LPC17xx_40xx_SSP_Registers *p = aW->iReg; // This routine only works with transfer of 8 bits or lower if (aRequest->iBitsPerTransfer > 8) return UEZ_ERROR_INVALID_PARAMETER; // Disable any potential SSP interrupts InterruptDisable(aW->iIRQChannel); aRequest->iNumTransferredOut = 0; aRequest->iNumTransferredIn = 0; // Setup the callback and the parameters aW->iCompleteCallback = aCallback; aW->iCompleteCallbackWorkspace = aCallbackWorkspace; aW->iRequest = aRequest; // Setup SSP for this configuration ISSPConfig(aW, aRequest); // Start SSP ISSPStart(aRequest); // Note we are in the middle of a transaction aW->iIsBusy = ETrue; // Allow receive half full, receive idle, and transmit half empty interrupts p->iIMSC = SSP_RTIM|SSP_RXIM|SSP_TXIM; // Prime the pump and output in an amount of data // On interrupting, we'll feed in the data ISSPOutput(aW); // Now allow processing of the interrupts (which probably just occurred) InterruptEnable(aW->iIRQChannel); return UEZ_ERROR_NONE; }
void fam_pte_asid_release(ADDRESS *adp) { int flush = 0; // Have to do the following atomically, so that an interrupt can't // come in and invalidate the asid on us. InterruptDisable(); if(adp->cpu.asid != PPC_INVALID_ASID) { asid_map[adp->cpu.asid] = NULL; adp->cpu.asid = PPC_INVALID_ASID; flush = 1; } InterruptEnable(); if(flush) { ppc_tlbia(); ppc_isync(); } }
// Function: LPT_IntAEnable() // Enable the interrupt. // Parameters: // hLPT [in] handle to the card as received from LPT_Open. // funcIntHandler [in] The call back function to be called upon interrupt. // Return Value: // TRUE if the interrupt was successfully enabled. FALSE otherwise. BOOL LPT_IntAEnable (LPT_HANDLE hLPT, LPT_IntA_HANDLER funcIntHandler) { DWORD dwStatus; // Check if interrupt is already enabled if (hLPT->IntA.hThread) return FALSE; // Calls WD_IntEnable() and creates an interrupt handler thread hLPT->IntA.funcIntHandler = funcIntHandler; dwStatus = InterruptEnable(&hLPT->IntA.hThread, hLPT->hWD, &hLPT->IntA.Int, LPT_IntAHandler, (PVOID) hLPT); if (dwStatus) { sprintf(LPT_ErrorString, "InterruptEnable() failed with status 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus)); return FALSE; } return TRUE; }
/*---------------------------------------------------------------------------* * Routine: LPC2478_GPDMA_Enable *---------------------------------------------------------------------------* * Description: * Enable GPDMA controller and register interrupt handler. * Inputs: * void *aW -- Particular GPDMA workspace * Outputs: * T_uezError -- Error code *---------------------------------------------------------------------------*/ static void LPC2478_GPDMA_Enable(void *aWorkspace) { (void)aWorkspace; // Increase number of G_opened channels. G_opened++; // Enable peripheral power PCONP |= PCONP_PCGPDMA; // Was registered already? if(EFalse == InterruptIsRegistered(INTERRUPT_CHANNEL_GP_DMA)) { // Enable interrupt. InterruptRegister(INTERRUPT_CHANNEL_GP_DMA, (TISRFPtr)IGPDMA, INTERRUPT_PRIORITY_NORMAL, "GPDMA"); InterruptEnable(INTERRUPT_CHANNEL_GP_DMA); } // Enable GPDMA by writing ENABLE bit. // Always little-endian. DMACConfiguration = DMACConfiguration_E; }
/*---------------------------------------------------------------------------* * Routine: LPC247x_Timer_SetMatchCallback *---------------------------------------------------------------------------* * Description: * Setup a callback routine for this timer on one of the match * registers. The callback is called when a match occurs and an * interrupt occurs. The callback is called from within the ISR. * Inputs: * void *aWorkspace -- Timer workspace * TUInt8 aMatchRegister -- Which match register to set callback * T_Timer_Callback aCallbackFunc -- Function to call, or 0 to clear. * void *aCallbackWorkspace -- Workspace to pass to callback * Outputs: * T_uezError -- UEZ_ERROR_ILLEGAL_PARAMETER if match register is out * of range. *---------------------------------------------------------------------------*/ static T_uezError LPC1756_Timer_SetMatchCallback( void *aWorkspace, TUInt8 aMatchRegister, T_HALTimer_Callback aCallbackFunc, void *aCallbackWorkspace) { T_LPC1756_Timer_Workspace *p = (T_LPC1756_Timer_Workspace *)aWorkspace; TBool any; TUInt8 i; // Determine if legal match register if (aMatchRegister >= 4) return UEZ_ERROR_ILLEGAL_PARAMETER; // Set the callback (which can be 0 as well as an address) p->iCallbacks[aMatchRegister].iCallbackFunc = aCallbackFunc; p->iCallbacks[aMatchRegister].iCallbackWorkspace = aCallbackWorkspace; // Check to see if there are any callbacks any = EFalse; for (i = 0; i < 4; i++) { if (p->iCallbacks[i].iCallbackFunc) { any = ETrue; break; } } // Register or deregister the interrupt if (any) { // Register if not already registered if (!InterruptIsRegistered(p->iInfo->iVector)) InterruptRegister(p->iInfo->iVector, p->iInfo->iISR, INTERRUPT_PRIORITY_HIGH, p->iInfo->iName); InterruptEnable(p->iInfo->iVector); } else { // No one registered anymore, turn off this callback (but leave registered) InterruptDisable(p->iInfo->iVector); } return UEZ_ERROR_NONE; }
/*---------------------------------------------------------------------------* * Routine: ExternalInterrupt_NXP_LPC1756_Enable *---------------------------------------------------------------------------* * Description: * Enable the given external interrupt * Inputs: * TUInt32 aChannel -- EINT channel (0 to 3) * Outputs: * T_uezError -- Error code *---------------------------------------------------------------------------*/ T_uezError ExternalInterrupt_NXP_LPC1756_Enable( void *aWorkspace, TUInt32 aChannel) { TUInt32 irqNum; T_ExternalInterrupt_NXP_LPC1756_Workspace *p = (T_ExternalInterrupt_NXP_LPC1756_Workspace *)aWorkspace; T_eintCallback *p_callback; T_uezError error = UEZ_ERROR_NONE; IGrab(p); // Fake loop while (1) { // Is this a valid channel? if (aChannel >= NUM_EXTERNAL_INTERRUPTS) { error = UEZ_ERROR_OUT_OF_RANGE; break; } // Is this external interrupt available? p_callback = G_eintCallbacks+aChannel; if (!p_callback->iCallbackFunc) { error = UEZ_ERROR_NOT_FOUND; break; } // Disable it irqNum = EINT0_IRQn+aChannel; InterruptEnable(irqNum); // Do not loop break; } IRelease(p); return error; }
void vmm_aspace(PROCESS *actprp, PROCESS **pactprp) { ADDRESS *adp; if((adp = actprp->memory)) { InterruptDisable(); SPINLOCK(&asid_spin); if(adp->cpu.asid > VM_ASID_BOUNDARY) { // later move it out for minimize int disable time alloc_asid(adp); } SPINUNLOCK(&asid_spin); smp_tlb_sync(actprp); // Set the ASID out32(SH_MMR_CCN_PTEH, (in32(SH_MMR_CCN_PTEH) & ~VM_ASID_MASK) | adp->cpu.asid); // Set the page table out32(SH_MMR_CCN_TTB, (uintptr_t)adp->cpu.pgdir); *pactprp = actprp; InterruptEnable(); } }
_X_EXPORT void xf86EnableInterrupts() { InterruptEnable(); return; }
/*---------------------------------------------------------------------------* * Routine: SerialEnable *---------------------------------------------------------------------------* * Description: * Enable serial processing on this port. * Inputs: * T_serialPort aPort -- Serial port to enable * Outputs: * T_uezError -- Error code *---------------------------------------------------------------------------*/ T_uezError LPC1768_Serial_Activate(void *aWorkspace) { T_Serial_LPC1768_Workspace *p = (T_Serial_LPC1768_Workspace *)aWorkspace; InterruptEnable(p->iInfo->iInterruptChannel); return UEZ_ERROR_NONE; }
int hsmci_init (SIM_HBA *hba) { CONFIG_INFO *cfg; SIM_MMC_EXT *ext; hsmci_ext_t *hsmci = NULL; uintptr_t base; ext = (SIM_MMC_EXT *)hba->ext; cfg = (CONFIG_INFO *)&hba->cfg; hba->verbosity = 4; if (!ext->opts) { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: missing board-specific options\n"); goto ARGSERR; } if ((hsmci = calloc(1, sizeof(hsmci_ext_t))) == NULL) { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: alloc memory failed\n"); goto ERR; } cfg->MemLength[0] = 0x1000; cfg->NumMemWindows = 1; cfg->MemBase[0] = cfg->IOPort_Base[0]; base = (uintptr_t)mmap_device_memory(NULL, cfg->MemLength[0], PROT_READ | PROT_WRITE | PROT_NOCACHE, MAP_SHARED, cfg->MemBase[0]); if (base == (uintptr_t)MAP_FAILED) { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: mmap_device_memory failed\n"); goto ERR; } hsmci->clock = 133000000; hsmci->base = base; hsmci->hba = hba; ext->handle = hsmci; ext->clock = hsmci->clock; ext->detect = _hsmci_detect; ext->powerup = _hsmci_powerup; ext->powerdown = _hsmci_powerdown; ext->cfg_bus = _hsmci_cfg_bus; ext->set_clock = _hsmci_clock; ext->set_blksz = _hsmci_block_size; ext->interrupt = _hsmci_interrupt; ext->command = _hsmci_command; ext->setup_dma = _hsmci_setup_dma; ext->dma_done = _hsmci_dma_done; ext->setup_pio = _hsmci_setup_pio; ext->pio_done = _hsmci_pio_done; ext->shutdown = _hsmci_shutdown; /* Parse options */ hsmci->port = -1; hsmci->blksz = BLK_LENGTH; hsmci->slot = 0; /* Hardcode DMAC controller base address according to G45 datasheet * since this driver is specifically for G45 SoC */ hsmci->dbase = DMAC_BASE; if (!ext->opts) goto ARGSERR; if (hsmci_args(hba, ext->opts) == -1) goto ARGSERR; /* * Set Src/Dst Request peripheral identifier SRC_PER/DST_PER * handshaking interface # according to Table 41-1 DMA Channel Definition * According to datasheet Table 35-2, the I/O line of mci0_da0 is pa2. * According to datasheet Table 35-2, the I/O line of mci1_da0 is pa23. */ if (hsmci->port == 0) { hsmci->dintf = 0; hsmci->da0_mask = (1<<2); } else { hsmci->dintf=13; hsmci->da0_mask = (1<<23); } /* Map G45 PIOA for polling busy signal */ pioa_pdsr = (uint32_t *)mmap_device_memory(NULL, 4, PROT_READ | PROT_WRITE | PROT_NOCACHE, MAP_SHARED, PIOA_PDSR); if (pioa_pdsr == (uint32_t *)MAP_FAILED) { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: mmap_device_memory failed\n"); goto ERR; } if ( (uintptr_t) MAP_FAILED == ( hsmci->pio_base = mmap_device_io( AT91SAM9G45_PIO_SIZE, AT91SAM9G45_PIOD_BASE ) ) ) { slogf( _SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: mmap_device_io for PIOD_PDSR failed" ); goto ERR; } /* Configure CD and WP PIO */ InterruptDisable(); #define CFG_PIO(reg) out32( hsmci->pio_base + (reg), AT91SAM9G45_MCI_PIO_BITS ) CFG_PIO( AT91SAM9G45_PIO_PER ); /* Ensable PIO */ CFG_PIO( AT91SAM9G45_PIO_ODR ); /* Disable output */ CFG_PIO( AT91SAM9G45_PIO_IFDR ); /* Disable glitch input filter */ CFG_PIO( AT91SAM9G45_PIO_CODR ); /* Clear output data */ CFG_PIO( AT91SAM9G45_PIO_IDR ); /* Disable interrupt */ CFG_PIO( AT91SAM9G45_PIO_MDDR ); /* Disable multi-driver */ CFG_PIO( AT91SAM9G45_PIO_PUER ); /* Enable pull-up */ CFG_PIO( AT91SAM9G45_PIO_OWDR ); /* Output write disable */ #undef CFG_PIO InterruptEnable(); /* Configure capacity of controller */ ext->hccap |= MMC_HCCAP_BW1 | MMC_HCCAP_BW4 | MMC_HCCAP_DMA | MMC_HCCAP_BW8 | MMC_HCCAP_HS; // Use the flag MMC_HCCAP_NOCD_BUSY to inform the MMCSD stack that this hardware has R1B bug // ext->hccap |= MMC_HCCAP_BW1 | MMC_HCCAP_BW4 | MMC_HCCAP_DMA | MMC_HCCAP_BW8 | MMC_HCCAP_HS | MMC_HCCAP_NOCD_BUSY; /* Disable the controller and soft reset */ WRITE32(MCI_CR, SWRST | PWSDIS); delay (100); WRITE32(MCI_CR, MCIDIS | PWSDIS); /* Disable DMA */ WRITE32(MCI_DMA, (READ32(MCI_DMA) & (~(DMAEN)))); /* Enable the controller */ WRITE32(MCI_CR, MCIEN | PWSDIS); WRITE32(MCI_IDR, 0xffffffff); /* Set Timeout to Max */ WRITE32(MCI_DTOR, 0x7f); /* Use the lowest baudrate */ WRITE32 (MCI_MR, 0xff | WRPROOF| RDPROOF); hsmci->dmac_dev = dmac_init(hsmci); if (hsmci->dmac_dev == NULL) { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: dmafuncs init FAILED\n"); goto ERR; } hsmci->dmac_dev->io_addr = cfg->MemBase[0] + MCI_FIFO; hsmci->dmac_dev->blksz = hsmci->blksz; /* Select slot, set bus to 1 bit */ WRITE32 (MCI_SDCR, hsmci->slot); if (!cfg->Description[0]) strncpy(cfg->Description, "Atmel HSMCI ", sizeof(cfg->Description)); if ( (uintptr_t) MAP_FAILED == ( hsmci->pmc_base = mmap_device_io(PMC_SIZE, PMC_BASE) ) ) { slogf( _SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: mmap_device_io for PMC failed" ); goto ERR; } return (MMC_SUCCESS); ARGSERR: printf("\nImproper board-specific options used. Accepting args: \n"); printf(" port=# The MCI port been used (0 or 1)\n"); printf("NOTE:\n"); printf(" 1. The args are seperated by colon ':'\n"); printf("Example:\n"); printf("at91sam9g45 port 0: devb-mmcsd-at91sam9g45 mmcsd ioport=0xFFF80000,irq=11,bs=port=0\n"); printf("at91sam9g45 port 1: devb-mmcsd-at91sam9g45 mmcsd ioport=0xFFFD0000,irq=29,bs=port=1\n"); ERR: if (hsmci) { munmap_device_memory ((void *)hsmci->base, (uint32_t)cfg->MemLength[0]); if (hsmci->pio_base) munmap_device_io (hsmci->pio_base, AT91SAM9G45_PIO_SIZE); free (hsmci); } if (pioa_pdsr != (uint32_t *)MAP_FAILED) munmap_device_memory ((void *)pioa_pdsr, 4); return (MMC_FAILURE); }
static void kerext_process_shutdown(void *data) { struct kerargs_process_shutdown *args = data; PROCESS *prp = args->prp; THREAD *act = actives[KERNCPU]; SIGTABLE *stp; int tid; int i; int try_again; lock_kernel(); if(prp == NULL) { prp = act->process; } if(prp->memory) { // Make sure no threads reference the aspace before it's removed for(tid = 0; tid < prp->threads.nentries; tid++) { THREAD *thp; if(VECP(thp, &prp->threads, tid)) { thp->aspace_prp = 0; } } try_again = 0; for(i = 0; i < NUM_PROCESSORS; ++i) { PROCESS *prp0; // The code between interrupt disable and enable should be short, // so that other CPUs will not have chance to get a interrupt and // switch aspace during the check InterruptDisable(); if(get_inkernel() & INKERNEL_INTRMASK) { try_again = 1; } prp0 = *((PROCESS* volatile *)&aspaces_prp[i]); if(get_inkernel() & INKERNEL_INTRMASK) { try_again = 1; } InterruptEnable(); if(prp == prp0) { // Switch current address space if(i == KERNCPU) { set_safe_aspace(i); } else { args->tlb_safe_cpu = i; SENDIPI(i, IPI_TLB_SAFE); try_again = 1; } } } if(try_again) { //Another CPU is pointing at this address space. We've sent //an IPI to get it to point at a safe entry (the process manager's), //but we have to wait until it's been processed before we can //destroy this address space. kererr(act, EAGAIN); return; } if(prp->flags & _NTO_PF_VFORKED) { // We're shutting down a vfork'd process. Don't free the // aspace, the parent process is still using it. prp->memory = NULL; } else { memmgr.mdestroy(prp); } if(prp->memory || aspaces_prp[KERNCPU] == prp) { crash(); } SETKSTATUS(act, 0); return; } // Remove all signal tables while((stp = prp->sig_table)) { prp->sig_table = stp->next; object_free(NULL, &sigtable_souls, stp); } // Check for guardian if(prp->guardian && (prp->guardian->flags & (_NTO_PF_LOADING | _NTO_PF_TERMING | _NTO_PF_ZOMBIE)) == 0) { process_swap(prp->guardian); prp->guardian = 0; } if(prp == act->process) { if(!args->exec) { // if we need to, send a sigchld to the parent if (!(prp->flags & _NTO_PF_NOZOMBIE)) { signal_kill_process(prp->parent, SIGCHLD, prp->siginfo.si_code, prp->siginfo.si_value.sival_int, prp->siginfo.si_pid, 0 ); } prp->siginfo.si_signo = SIGCHLD; } actives_prp[KERNCPU] = sysmgr_prp; thread_destroyall(act); } else { SETKSTATUS(act, prp->siginfo.si_status); } }
static int do_send(PROCTBL_P p, u_int msg, int msg_flag) { u_int msgbit; int killRet; #ifdef A_DEBUG dprintf("-smsg: p %d, msg 0%o-", p, s_(msg)); #endif if(p->p_id <= 0) { rxerr("r_sendmsg(): Attempt to send msg to non-existant proc"); return(-1); } if(msg_flag) msgbit= msg; else msgbit= s_(msg); /* * Procs that are stopped can receive only certain messages. */ if(p != COMM && ((p->p_state & P_RUN_ST) == 0) && ((msgbit & (s_(G_KILL)|s_(G_STOP)|s_(G_RUN))) == 0)) { rxerr("r_sendmsg(): Cannot send msg; process is in stop state"); return(-1); } if(inside_clock) { /* * This is the 'int' process, and we are inside the clock * routine. Don't call protect() if it would block! */ InterruptDisable(); if(!p->p_sem) { /* * Just return -2. 'clock()' will try again next * interrupt. */ InterruptEnable(); return(-2); } else protect(&p->p_sem); InterruptEnable(); } else { protect(&p->p_sem); } p->p_msg |= msgbit; /* set message bit */ /* * Signal sending is interlocked so that a signal is sent only * when necessary to wake up the receiving process, OR re-interrupt * a lower priority message currently executing in the receiving * process. */ if( ! (p->p_state & P_NOSIG_ST)) { /* signalling allowed */ /* * If the receiving process is currently not asleep but * processing a message that has allowed re-interrupts, the * re-interrupt mask will specify which messages are permitted * to signal and cause a re-interrupt. */ if(msgbit & ~p->p_rmask) { p->p_state |= P_NOSIG_ST; release_(&p->p_sem); #ifdef A_DEBUG dprintf("-smsg: killing %d-", p->p_id); #endif killRet = kill(p->p_id, S_ALERT); if(killRet == -1) { perror("do_send() kill error"); stufs(p->p_name, &noproc[BLANKS], &noproc[0] + sizeof(noproc)); rxerr(noproc); p->p_state &= ~P_NOSIG_ST; return(-1); } return(0); } } release_(&p->p_sem); return(0); }