static void set_current_ctx_sw(struct per_cpu_info *pcpui, struct sw_trapframe *sw_tf) { if (irq_is_enabled()) warn("Turn off IRQs until cur_ctx is set!"); assert(!pcpui->cur_ctx); pcpui->actual_ctx.type = ROS_SW_CTX; pcpui->actual_ctx.tf.sw_tf = *sw_tf; pcpui->cur_ctx = &pcpui->actual_ctx; }
void z_isr_install(unsigned int irq, void (*routine)(void *), void *param) { unsigned int table_idx = irq - CONFIG_GEN_IRQ_START_VECTOR; __ASSERT(!irq_is_enabled(irq), "IRQ %d is enabled", irq); /* If dynamic IRQs are enabled, then the _sw_isr_table is in RAM and * can be modified */ _sw_isr_table[table_idx].arg = param; _sw_isr_table[table_idx].isr = routine; }
static int entropy_nrf5_get_entropy_isr(struct device *dev, u8_t *buf, u16_t len, u32_t flags) { u16_t cnt = len; /* Check if this API is called on correct driver instance. */ __ASSERT_NO_MSG(&entropy_nrf5_data == DEV_DATA(dev)); if (likely((flags & ENTROPY_BUSYWAIT) == 0)) { return rng_pool_get((struct rng_pool *)(entropy_nrf5_data.isr), buf, len); } if (len) { unsigned int key; int irq_enabled; key = irq_lock(); irq_enabled = irq_is_enabled(RNG_IRQn); irq_disable(RNG_IRQn); irq_unlock(key); nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); nrf_rng_task_trigger(NRF_RNG_TASK_START); do { int byte; while (!nrf_rng_event_get(NRF_RNG_EVENT_VALRDY)) { __WFE(); __SEV(); __WFE(); } byte = random_byte_get(); NVIC_ClearPendingIRQ(RNG_IRQn); if (byte < 0) { continue; } buf[--len] = byte; } while (len); if (irq_enabled) { irq_enable(RNG_IRQn); } } return cnt; }
/* it's actually okay to set the state to the existing state. originally, it * was a bug in the state tracking, but it is possible, at least on x86, to have * a halted core (state IDLE) get woken up by an IRQ that does not trigger the * IRQ handling state. for example, there is the I_POKE_CORE ipi. smp_idle * will just sleep again, and reset the state from IDLE to IDLE. */ void __set_cpu_state(struct per_cpu_info *pcpui, int state) { uint64_t now_ticks; assert(!irq_is_enabled()); /* TODO: could put in an option to enable/disable state tracking. */ now_ticks = read_tsc(); pcpui->state_ticks[pcpui->cpu_state] += now_ticks - pcpui->last_tick_cnt; /* TODO: if the state was user, we could account for the vcore's time, * similar to the total_ticks in struct vcore. the difference is that the * total_ticks tracks the vcore's virtual time, while this tracks user time. * something like vcore->user_ticks. */ pcpui->cpu_state = state; pcpui->last_tick_cnt = now_ticks; }
int32_t frontend_syscall(pid_t pid, int32_t syscall_num, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, int32_t* errno) { #ifndef CONFIG_APPSERVER warn("No appserver support, requested syscall %d for proc %d", syscall_num, pid); if(errno) *errno = ENOSYS; return -1; #endif #ifdef CONFIG_X86 if (!irq_is_enabled()) warn("IRQ is disabled in frontend_syscall %d for proc %d\n", syscall_num, pid); #endif static spinlock_t lock = SPINLOCK_INITIALIZER; int32_t ret; // only one frontend request at a time. // interrupts could try to do frontend requests, // which would deadlock, so disable them spin_lock(&lock); // write syscall into magic memory magic_mem[7] = 0; magic_mem[1] = syscall_num; magic_mem[2] = arg0; magic_mem[3] = arg1; magic_mem[4] = arg2; magic_mem[5] = arg3; magic_mem[6] = pid; magic_mem[0] = 0x80; // wait for front-end response while(magic_mem[7] == 0) ; ret = magic_mem[1]; if(errno) *errno = magic_mem[2]; spin_unlock(&lock); return ret; }