Exemplo n.º 1
0
void kill_thread(struct thread *thread)
{
    irq_state_t irq;
    struct thread_block *block;

    if (thread == current())
	__exit_thread();

    irq = irq_save();

    /*
     * Muck with the stack so that the next time the thread is run then
     * we end up going to __exit_thread.
     */
    thread->esp->eip = __exit_thread;
    thread->prio = INT_MIN;

    block = thread->blocked;
    if (block) {
	struct semaphore *sem = block->semaphore;
	/* Remove us from the queue and increase the count */
	block->list.next->prev = block->list.prev;
	block->list.prev->next = block->list.next;
	sem->count++;

	thread->blocked = NULL;
	block->timed_out = true; /* Fake an immediate timeout */
    }

    __schedule();

    irq_restore(irq);
}
Exemplo n.º 2
0
void
gpio_out_toggle(struct gpio_out g)
{
    irqstatus_t flag = irq_save();
    gpio_out_toggle_noirq(g);
    irq_restore(flag);
}
Exemplo n.º 3
0
void
command_debug_write16(uint32_t *args)
{
    uint16_t *ptr = (void*)(size_t)args[0];
    irqstatus_t flag = irq_save();
    *ptr = args[1];
    irq_restore(flag);
}
Exemplo n.º 4
0
// Cancel a sample that may have been started with gpio_adc_sample()
void
gpio_adc_cancel_sample(struct gpio_adc g)
{
    irqstatus_t flag = irq_save();
    if ((ADC->ADC_CHSR & 0xffff) == g.bit)
        gpio_adc_read(g);
    irq_restore(flag);
}
Exemplo n.º 5
0
void
command_debug_read16(uint32_t *args)
{
    uint16_t *ptr = (void*)(size_t)args[0];
    irqstatus_t flag = irq_save();
    uint16_t v = *ptr;
    irq_restore(flag);
    sendf("debug_result val=%hu", v);
}
Exemplo n.º 6
0
void up(semaphore_t *s)
{
	unsigned long flags;
	
	irq_save(flags);
	atomic_dec(&s->count);
	wake_up(&s->wait);
	irq_restore(flags);
}
Exemplo n.º 7
0
void down(semaphore_t *s)
{
	unsigned long flags;

	irq_save(flags);
	atomic_inc(&s->count);
	if (atomic_read(&s->count) != 1) {
		wait(&s->wait);
	}
	irq_restore(flags);
}
Exemplo n.º 8
0
// Cancel a sample that may have been started with gpio_adc_sample()
void
gpio_adc_cancel_sample(struct gpio_adc g)
{
    uint32_t chan = adc_status.chan;
    if (chan != g.chan)
        return;
    irqstatus_t flag = irq_save();
    LPC_ADC->ADCR = adc_status.adcr;
    adc_status.chan = chan | ADC_DONE;
    adc_status.pos = ARRAY_SIZE(adc_status.samples);
    (&LPC_ADC->ADDR0)[chan & 0xff];
    irq_restore(flag);
}
Exemplo n.º 9
0
void create_kernel_thread(void)
{
    irq_state_t irq_state = irq_save();

    thread_t *thread = (thread_t *)kmalloc(sizeof(thread_t));
    if (!thread) {
        return;
    }
    memset(thread, 0, sizeof(thread_t));

    thread->id = request_thread_id();
    thread->process = 0;
    thread->page_dir = current_directory;

    ++num_threads;

    schedule_thread(thread);

    irq_restore(irq_state);
}
Exemplo n.º 10
0
struct gpio_out
gpio_out_setup(uint8_t pin, uint8_t val)
{
    if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs))
        goto fail;
    Pio *regs = digital_regs[GPIO2PORT(pin)];
    uint32_t bit = GPIO2BIT(pin);
    irqstatus_t flag = irq_save();
    if (val)
        regs->PIO_SODR = bit;
    else
        regs->PIO_CODR = bit;
    regs->PIO_OER = bit;
    regs->PIO_OWER = bit;
    regs->PIO_PER = bit;
    irq_restore(flag);
    return (struct gpio_out){ .regs=regs, .bit=bit };
fail:
    shutdown("Not an output pin");
}
Exemplo n.º 11
0
struct gpio_in
gpio_in_setup(uint8_t pin, int8_t pull_up)
{
    if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs))
        goto fail;
    uint32_t port = GPIO2PORT(pin);
    Pio *regs = digital_regs[port];
    uint32_t bit = GPIO2BIT(pin);
    irqstatus_t flag = irq_save();
    PMC->PMC_PCER0 = 1 << (ID_PIOA + port);
    if (pull_up)
        regs->PIO_PUER = bit;
    else
        regs->PIO_PUDR = bit;
    regs->PIO_ODR = bit;
    regs->PIO_PER = bit;
    irq_restore(flag);
    return (struct gpio_in){ .regs=regs, .bit=bit };
fail:
    shutdown("Not an input pin");
}
Exemplo n.º 12
0
/* all clocks in the 1.8 V domain are stopped,
 * the PLL, the HSI and the HSE RC oscillators are disabled.
 * SRAM and register contents are preserved.
 * all I/O pins keep the same state as in the Run mode.
 * ADC, DAC, WDG, RTC, LSI_RC, and LSE_OSC can consume power. */
void __enter_stop_mode()
{
	unsigned int irqflag;

	irq_save(irqflag);
	local_irq_disable();

	PWRCLK_ENABLE();
	SCB_SCR |= 4; /* Set SLEEPDEEP bit */
	/* Clear PDDS bit in Power Control register (PWR_CR) */
	PWR_CR |= 1; /* configure LPDS bit in PWR_CR */

	stop_scheduler();
	dsb();
	__wfi();
	clock_init();
	run_scheduler();

	SCB_SCR &= ~4;
	PWR_CR &= ~1;
	PWRCLK_DISABLE();

	irq_restore(irqflag);

	/* wakeup latency:
	 * HSI RC wakeup time + regulator wakeup time from Low-power mode */

	/* Note from reference manual:
	 * If the application needs to disable the external clock before
	 * entering Stop mode, the HSEON bit must first be disabled and the
	 * system clock switched to HSI. Otherwise, if the HSEON bit remains
	 * enabled and the external clock (external oscillator) is removed when
	 * entering Stop mode, the clock security system (CSS) feature must be
	 * enabled to detect any external oscillator failure and avoid a
	 * malfunction behavior when entering stop mode. */
	//BITBAND(&RCC_CR, CSSON, ON);
}
Exemplo n.º 13
0
uint32_t create_thread(process_t *process, entry_t entry, void *args, uint32_t priority, int user, int vm86)
{
    /* create thread */
    thread_t *thread = (thread_t *)kmalloc(sizeof(thread_t));
    if (!thread) {
        return 0;
    }
    memset(thread, 0, sizeof(thread_t));

    /* setup the stack(s) */
    thread->kstack = (uintptr_t)kmalloc(STACK_SIZE);
    /*
    if (user) {
        uint32_t *stack = (uint32_t *)thread->kstack;
        (void)stack;
        DBPRINT("+++ thread->kstack: %x\n", thread->kstack);
        for (int i = -15; i < 15; ++i) {
            DBPRINT("%x -> stack[%d] = %x\n", thread->kstack + i, i, stack[i]);
        }
    }
    */
    
    if (!thread->kstack) {
        return 0;
    }
    if (user) {
        thread->ustack = (uintptr_t)kmalloc(STACK_SIZE);
        if (!thread->ustack) {
            return 0;
        }
    }

    uint32_t *kstack = (uint32_t *)stack_top(thread->kstack);
    uint32_t data_segment = user ? 0x20+3 : 0x10;
    uint32_t code_segment = user ? 0x18+3 : 0x08;

    /* bit 2 always set - bit 9 = interruption flag (IF) - bits 12/13 = privilege level 
     * bit 17 = virtua-8086 mode (VM) */
    uint32_t eflags = (user ? 0x3202 : 0x0202) | (vm86 ? 1 << 17 : 0 << 17);

    if (user) {
        uint32_t *ustack = (uint32_t *)stack_top(thread->ustack);

        PUSH(ustack, (uintptr_t)args);      /* args */
        PUSH(ustack, 0xdeadcaca);           /* return address - thread should be finished
                                             * with a system call, not by jumping to this address */
        PUSH(kstack, 0x23);                 /* ss */
        PUSH(kstack, (uintptr_t)ustack);    /* esp */
    } else {
        PUSH(kstack, (uintptr_t)args);      /* args */
        PUSH(kstack, (uintptr_t)&thread_exit); /* return address */
    }
    PUSH(kstack, eflags);                   /* eflags */
    PUSH(kstack, code_segment);             /* cs */
    PUSH(kstack, (uintptr_t)entry);         /* eip */
    PUSH(kstack, 0);                        /* error code */
    PUSH(kstack, 0);                        /* interrupt number */
    PUSH(kstack, 0);                        /* eax */
    PUSH(kstack, 0);                        /* ebx */
    PUSH(kstack, 0);                        /* ecx */
    PUSH(kstack, 0);                        /* edx */
    PUSH(kstack, 0);                        /* esi */
    PUSH(kstack, 0);                        /* edi */
    PUSH(kstack, 0);                        /* ebp */
    PUSH(kstack, data_segment);             /* ds */
    PUSH(kstack, data_segment);             /* es */
    PUSH(kstack, data_segment);             /* fs */
    PUSH(kstack, data_segment);             /* gs */

    thread->esp = (uintptr_t)kstack;
    thread->ss = data_segment;
    thread->id = request_thread_id();
    thread->process = process;
    /* thread's priority can't exceed its parent's priority */
    thread->priority = min(priority, process->priority); 
    thread->page_dir = process ? process->page_dir : kernel_directory;
    thread->runtime = 0;

    irq_state_t irq_state = irq_save();

    ++num_threads;

    /* register this thread */
    schedule_thread(thread);

    irq_restore(irq_state);

    return thread->id;
}