Example #1
1
//----------------------------------
//
// your solution to this question should look something like this
//
//  if you run userprog3.dlx.obj 2, it should output
//
//	A0
//	B0
//	A1
//	A2
//	A3
//	A4
//	A5
//	A6
//	B1
//	A7
//	A8
//	A9
//	B2
//	A10
//	B3
//	A11
//	B4
//	A12
//	B5
//	A13
//	B6
//	A14
//	B7
//	A15
//	B8
//	A16
//	B9
//	A17
//	B10
//	A18
//	B11
//	A19
//	B12
//	A20
//	B13
//	A21
//	B14
//	A22
//	B15
//	A23
//	B16
//	A24
//	B17
//	A25
//	B18
//	A26
//	B19
//	A27
//	B20
//	A28
//	B21
//	A29
//	B22
//	A0
//	B23
//	A1
//	B24
//	A2
//	B25
//	A3
//	B26
//	A4
//	B27
//	A5
//	B28
//	A6
//	B29
//	A7
//	B0
//	A8
//	B1
//	A9
//	B2
//	A10
//	B3
//	A11
//	B4
//	A12
//	B5
//	A13
//	B6
//	A14
//	B7
//	A15
//	B8
//	A16
//	B9
//	A17
//	B10
//	A18
//	B11
//	A19
//	B12
//	A20
//	B13
//	A21
//	B14
//	A22
//	B15
//	A23
//	B16
//	A24
//	B17
//	A25
//	B18
//	A26
//	B19
//	A27
//	B20
//	A28
//	B21
//	A29
//	B22
//	B23
//	B24
//	B25
//	B26
//	B27
//	B28
//	B29
// make sure you understand the scheduling algorithm works b4 you strart hacking
//
//   You are free to modify this file (and other userprogs) to test your solution
//   We will not use the same files to test your code.
//
//----------------------------------------------------------------------------
main (int argc, char *argv[])
{
  int number, i,j,offset;
  uint32 handle;
  sem_t semaphore;
  char num_str[10], semaphore_str[10];

  Printf("\n\n**** argc = %d\n\n\n", argc);

  switch(argc)
  {
    case 2:
    Printf("timer = %d\n", TimerGet());
      number = dstrtol(argv[1], NULL, 10);
      Printf("Setting number = %d\n", number);

      for(i=0; i<50; i++)
      	Printf("1");

	 Printf("timer = %d\n", TimerGet());


      semaphore = sem_create(1);
      ditoa(semaphore, semaphore_str);	//Convert the semaphore to a string

      Printf("timer = %d\n", TimerGet());

      for(i=0; i<number; i++)
      {
        ditoa(i, num_str);
        process_create(i,0,"userprog4.dlx.obj", num_str,semaphore_str,
  			NULL);
      }
      Printf("timer = %d\n", TimerGet());
      yield();
      break;
    case 3:
      offset = dstrtol(argv[1], NULL, 10);       //Get semaphore
      semaphore = dstrtol(argv[2], NULL, 10);       //Get semaphore
      for(i=0;i<30;i++)
      {
        for(j=0;j<50000;j++);
        Printf("%c%d\n",'A'+offset,i);
      }
      for(i=0;i<30;i++)
      {
        sem_wait(semaphore);
        for(j=0;j<50000;j++);
        Printf("%c%d\n",'A'+offset,i);
        sem_signal(semaphore);
      }

      break;
    default:
      Printf("Usage: ");
      Printf(argv[0]);
      Printf(" number\n");
      Printf("argc = %d\n", argc);
      exit();
  }



}
void FlightSimClass::xmit_big_packet(const void *p1, uint8_t n1, const void *p2, uint8_t n2)
{
	if (!enabled || !usb_configuration) return;

	uint16_t remaining = n1 + n2;
	if (remaining > 255) return;
	
	bool part2 = false;
	uint8_t remainingPart1 = n1;
	const uint8_t *dataPtr = (const uint8_t*)p1;
	bool writeFragmentHeader = false;
	uint8_t fragmentCounter = 1;

	tx_noautoflush =1; // don't mess with my data, I'm working on it!

	if (tx_packet) {
		// If we have a current packet, fill it with whatever fits
		uint8_t partLen = FLIGHTSIM_TX_SIZE - tx_packet->index; 
		if (partLen > n1) partLen=n1;
		// copy first part, containing total packet length
		memcpy(tx_packet->buf + tx_packet->index, dataPtr, partLen);
		remainingPart1 -= partLen;
		tx_packet->index += partLen;
		if (remainingPart1) {
			// there still is data from the first part that
			// will go to the next packet. The boolean variable
			// part2 remains false
			remaining = remainingPart1+n2;
			dataPtr += partLen;
		} else {
			// maybe we have space for some data from the second part
			part2=true;
			partLen = FLIGHTSIM_TX_SIZE - tx_packet->index;
			// there is no need here to check whether partLen is
			// bigger than n2. It's not. If it were, all the data
			// would have fit in a single packet and xmit_big_packet
			// would never have been called...
			remaining = n2;
			if (partLen) {
				memcpy(tx_packet->buf + tx_packet->index, p2, partLen);
				remaining -= partLen;
				tx_packet->index += partLen;
			}
			dataPtr = (const uint8_t*)p2 + partLen;
		}
		// Packet padding should not be necessary, as xmit_big_packet 
		// will only be called for data that doesn't fit in a single
		// packet. So, the previous code should always fill up the
		// first packet. Right?
		for (int i = tx_packet->index; i < FLIGHTSIM_TX_SIZE; i++) {
			tx_packet->buf[i] = 0;
		}

		// queue first packet for sending
		tx_packet->len = FLIGHTSIM_TX_SIZE;
		usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet);
		tx_packet = NULL;
		writeFragmentHeader = true;
	} else {
		remaining = n1+n2;
	}
	
	while (remaining >0) {
		while (1) {
			// get memory for next packet
			if (usb_tx_packet_count(FLIGHTSIM_TX_ENDPOINT) < TX_PACKET_LIMIT) {
				tx_packet = usb_malloc();
				if (tx_packet) {
					break;
				}
			}

			if (!enabled || !usb_configuration) {
				// teensy disconnected
				tx_noautoflush = 0;
				return;
			}
			tx_noautoflush = 0;  // you can pick up my data, if you like
			yield(); 			 // do other things and wait for memory to become free
			tx_noautoflush = 1;  // wait, I'm working on the packet data
		}

		if (writeFragmentHeader) {
			tx_packet->buf[0]=(remaining+3 <= FLIGHTSIM_TX_SIZE) ? (byte) remaining+3 : FLIGHTSIM_TX_SIZE;
			tx_packet->buf[1]=0xff;
			tx_packet->buf[2]=fragmentCounter++;
			tx_packet->index=3;
		}
		if (!part2) {
			// we still need to send the first part
			uint8_t partLen = FLIGHTSIM_TX_SIZE - tx_packet->index; 
			if (partLen > remainingPart1)
				partLen=remainingPart1;
			memcpy(tx_packet->buf + tx_packet->index, dataPtr, partLen);
			dataPtr += partLen;
			remainingPart1 -= partLen;
			tx_packet->index += partLen;
			remaining -= partLen;
			if (!remainingPart1) {
				part2=true;
				dataPtr = (const uint8_t*)p2;
			}
		}

		if (part2) {
			uint8_t partLen = FLIGHTSIM_TX_SIZE - tx_packet->index; 
			if (partLen) {
				if (partLen > remaining)
					partLen=remaining;
				memcpy(tx_packet->buf + tx_packet->index, dataPtr, partLen);
				remaining -= partLen;
				tx_packet->index += partLen;
				dataPtr += partLen;
			}
		} 
		writeFragmentHeader = true;
		
		if (tx_packet->index >= FLIGHTSIM_TX_SIZE) {
			// queue packet for sending
			tx_packet->len = FLIGHTSIM_TX_SIZE;
			usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet);
			tx_packet = NULL;
		}
	}
	tx_noautoflush = 0;  // data is ready to be transmitted on start of USB token
}
Example #3
0
/**
 * usb_sg_wait - synchronously execute scatter/gather request
 * @io: request block handle, as initialized with usb_sg_init().
 * 	some fields become accessible when this call returns.
 * Context: !in_interrupt ()
 *
 * This function blocks until the specified I/O operation completes.  It
 * leverages the grouping of the related I/O requests to get good transfer
 * rates, by queueing the requests.  At higher speeds, such queuing can
 * significantly improve USB throughput.
 *
 * There are three kinds of completion for this function.
 * (1) success, where io->status is zero.  The number of io->bytes
 *     transferred is as requested.
 * (2) error, where io->status is a negative errno value.  The number
 *     of io->bytes transferred before the error is usually less
 *     than requested, and can be nonzero.
 * (3) cancellation, a type of error with status -ECONNRESET that
 *     is initiated by usb_sg_cancel().
 *
 * When this function returns, all memory allocated through usb_sg_init() or
 * this call will have been freed.  The request block parameter may still be
 * passed to usb_sg_cancel(), or it may be freed.  It could also be
 * reinitialized and then reused.
 *
 * Data Transfer Rates:
 *
 * Bulk transfers are valid for full or high speed endpoints.
 * The best full speed data rate is 19 packets of 64 bytes each
 * per frame, or 1216 bytes per millisecond.
 * The best high speed data rate is 13 packets of 512 bytes each
 * per microframe, or 52 KBytes per millisecond.
 *
 * The reason to use interrupt transfers through this API would most likely
 * be to reserve high speed bandwidth, where up to 24 KBytes per millisecond
 * could be transferred.  That capability is less useful for low or full
 * speed interrupt endpoints, which allow at most one packet per millisecond,
 * of at most 8 or 64 bytes (respectively).
 */
void usb_sg_wait (struct usb_sg_request *io)
{
	int		i, entries = io->entries;

	/* queue the urbs.  */
	spin_lock_irq (&io->lock);
	for (i = 0; i < entries && !io->status; i++) {
		int	retval;

		io->urbs [i]->dev = io->dev;
		retval = usb_submit_urb (io->urbs [i], SLAB_ATOMIC);

		/* after we submit, let completions or cancelations fire;
		 * we handshake using io->status.
		 */
		spin_unlock_irq (&io->lock);
		switch (retval) {
			/* maybe we retrying will recover */
		case -ENXIO:	// hc didn't queue this one
		case -EAGAIN:
		case -ENOMEM:
			io->urbs[i]->dev = NULL;
			retval = 0;
			i--;
			yield ();
			break;

			/* no error? continue immediately.
			 *
			 * NOTE: to work better with UHCI (4K I/O buffer may
			 * need 3K of TDs) it may be good to limit how many
			 * URBs are queued at once; N milliseconds?
			 */
		case 0:
			cpu_relax ();
			break;

			/* fail any uncompleted urbs */
		default:
			io->urbs [i]->dev = NULL;
			io->urbs [i]->status = retval;
			dev_dbg (&io->dev->dev, "%s, submit --> %d\n",
				__FUNCTION__, retval);
			usb_sg_cancel (io);
		}
		spin_lock_irq (&io->lock);
		if (retval && (io->status == 0 || io->status == -ECONNRESET))
			io->status = retval;
	}
	io->count -= entries - i;
	if (io->count == 0)
		complete (&io->complete);
	spin_unlock_irq (&io->lock);

	/* OK, yes, this could be packaged as non-blocking.
	 * So could the submit loop above ... but it's easier to
	 * solve neither problem than to solve both!
	 */
	wait_for_completion (&io->complete);

	sg_clean (io);
}
Example #4
0
int infRecursion_cmd(int argc, char **argv) {
    yield();
    infRecursion_cmd(argc, argv);
    return 0;
}
Example #5
0
int mypthread_yield()
{
	yield();
}
Example #6
0
/*
 * This routine is responsible for faulting in user pages.
 * It passes the work off to one of the appropriate routines.
 * It returns true if the fault was successfully handled.
 */
static int handle_page_fault(struct pt_regs *regs,
                             int fault_num,
                             int is_page_fault,
                             unsigned long address,
                             int write)
{
    struct task_struct *tsk;
    struct mm_struct *mm;
    struct vm_area_struct *vma;
    unsigned long stack_offset;
    int fault;
    int si_code;
    int is_kernel_mode;
    pgd_t *pgd;

    /* on TILE, protection faults are always writes */
    if (!is_page_fault)
        write = 1;

    is_kernel_mode = (EX1_PL(regs->ex1) != USER_PL);

    tsk = validate_current();

    /*
     * Check to see if we might be overwriting the stack, and bail
     * out if so.  The page fault code is a relatively likely
     * place to get trapped in an infinite regress, and once we
     * overwrite the whole stack, it becomes very hard to recover.
     */
    stack_offset = stack_pointer & (THREAD_SIZE-1);
    if (stack_offset < THREAD_SIZE / 8) {
        pr_alert("Potential stack overrun: sp %#lx\n",
                 stack_pointer);
        show_regs(regs);
        pr_alert("Killing current process %d/%s\n",
                 tsk->pid, tsk->comm);
        do_group_exit(SIGKILL);
    }

    /*
     * Early on, we need to check for migrating PTE entries;
     * see homecache.c.  If we find a migrating PTE, we wait until
     * the backing page claims to be done migrating, then we procede.
     * For kernel PTEs, we rewrite the PTE and return and retry.
     * Otherwise, we treat the fault like a normal "no PTE" fault,
     * rather than trying to patch up the existing PTE.
     */
    pgd = get_current_pgd();
    if (handle_migrating_pte(pgd, fault_num, address,
                             is_kernel_mode, write))
        return 1;

    si_code = SEGV_MAPERR;

    /*
     * We fault-in kernel-space virtual memory on-demand. The
     * 'reference' page table is init_mm.pgd.
     *
     * NOTE! We MUST NOT take any locks for this case. We may
     * be in an interrupt or a critical region, and should
     * only copy the information from the master page table,
     * nothing more.
     *
     * This verifies that the fault happens in kernel space
     * and that the fault was not a protection fault.
     */
    if (unlikely(address >= TASK_SIZE &&
                 !is_arch_mappable_range(address, 0))) {
        if (is_kernel_mode && is_page_fault &&
                vmalloc_fault(pgd, address) >= 0)
            return 1;
        /*
         * Don't take the mm semaphore here. If we fixup a prefetch
         * fault we could otherwise deadlock.
         */
        mm = NULL;  /* happy compiler */
        vma = NULL;
        goto bad_area_nosemaphore;
    }

    /*
     * If we're trying to touch user-space addresses, we must
     * be either at PL0, or else with interrupts enabled in the
     * kernel, so either way we can re-enable interrupts here.
     */
    local_irq_enable();

    mm = tsk->mm;

    /*
     * If we're in an interrupt, have no user context or are running in an
     * atomic region then we must not take the fault.
     */
    if (in_atomic() || !mm) {
        vma = NULL;  /* happy compiler */
        goto bad_area_nosemaphore;
    }

    /*
     * When running in the kernel we expect faults to occur only to
     * addresses in user space.  All other faults represent errors in the
     * kernel and should generate an OOPS.  Unfortunately, in the case of an
     * erroneous fault occurring in a code path which already holds mmap_sem
     * we will deadlock attempting to validate the fault against the
     * address space.  Luckily the kernel only validly references user
     * space from well defined areas of code, which are listed in the
     * exceptions table.
     *
     * As the vast majority of faults will be valid we will only perform
     * the source reference check when there is a possibility of a deadlock.
     * Attempt to lock the address space, if we cannot we then validate the
     * source.  If this is invalid we can skip the address space check,
     * thus avoiding the deadlock.
     */
    if (!down_read_trylock(&mm->mmap_sem)) {
        if (is_kernel_mode &&
                !search_exception_tables(regs->pc)) {
            vma = NULL;  /* happy compiler */
            goto bad_area_nosemaphore;
        }
        down_read(&mm->mmap_sem);
    }

    vma = find_vma(mm, address);
    if (!vma)
        goto bad_area;
    if (vma->vm_start <= address)
        goto good_area;
    if (!(vma->vm_flags & VM_GROWSDOWN))
        goto bad_area;
    if (regs->sp < PAGE_OFFSET) {
        /*
         * accessing the stack below sp is always a bug.
         */
        if (address < regs->sp)
            goto bad_area;
    }
    if (expand_stack(vma, address))
        goto bad_area;

    /*
     * Ok, we have a good vm_area for this memory access, so
     * we can handle it..
     */
good_area:
    si_code = SEGV_ACCERR;
    if (fault_num == INT_ITLB_MISS) {
        if (!(vma->vm_flags & VM_EXEC))
            goto bad_area;
    } else if (write) {
#ifdef TEST_VERIFY_AREA
        if (!is_page_fault && regs->cs == KERNEL_CS)
            pr_err("WP fault at "REGFMT"\n", regs->eip);
#endif
        if (!(vma->vm_flags & VM_WRITE))
            goto bad_area;
    } else {
        if (!is_page_fault || !(vma->vm_flags & VM_READ))
            goto bad_area;
    }

survive:
    /*
     * If for any reason at all we couldn't handle the fault,
     * make sure we exit gracefully rather than endlessly redo
     * the fault.
     */
    fault = handle_mm_fault(mm, vma, address, write);
    if (unlikely(fault & VM_FAULT_ERROR)) {
        if (fault & VM_FAULT_OOM)
            goto out_of_memory;
        else if (fault & VM_FAULT_SIGBUS)
            goto do_sigbus;
        BUG();
    }
    if (fault & VM_FAULT_MAJOR)
        tsk->maj_flt++;
    else
        tsk->min_flt++;

#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
    /*
     * If this was an asynchronous fault,
     * restart the appropriate engine.
     */
    switch (fault_num) {
#if CHIP_HAS_TILE_DMA()
    case INT_DMATLB_MISS:
    case INT_DMATLB_MISS_DWNCL:
    case INT_DMATLB_ACCESS:
    case INT_DMATLB_ACCESS_DWNCL:
        __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK);
        break;
#endif
#if CHIP_HAS_SN_PROC()
    case INT_SNITLB_MISS:
    case INT_SNITLB_MISS_DWNCL:
        __insn_mtspr(SPR_SNCTL,
                     __insn_mfspr(SPR_SNCTL) &
                     ~SPR_SNCTL__FRZPROC_MASK);
        break;
#endif
    }
#endif

    up_read(&mm->mmap_sem);
    return 1;

    /*
     * Something tried to access memory that isn't in our memory map..
     * Fix it, but check if it's kernel or user first..
     */
bad_area:
    up_read(&mm->mmap_sem);

bad_area_nosemaphore:
    /* User mode accesses just cause a SIGSEGV */
    if (!is_kernel_mode) {
        /*
         * It's possible to have interrupts off here.
         */
        local_irq_enable();

        force_sig_info_fault(SIGSEGV, si_code, address,
                             fault_num, tsk);
        return 0;
    }

no_context:
    /* Are we prepared to handle this kernel fault?  */
    if (fixup_exception(regs))
        return 0;

    /*
     * Oops. The kernel tried to access some bad page. We'll have to
     * terminate things with extreme prejudice.
     */

    bust_spinlocks(1);

    /* FIXME: no lookup_address() yet */
#ifdef SUPPORT_LOOKUP_ADDRESS
    if (fault_num == INT_ITLB_MISS) {
        pte_t *pte = lookup_address(address);

        if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
            pr_crit("kernel tried to execute"
                    " non-executable page - exploit attempt?"
                    " (uid: %d)\n", current->uid);
    }
#endif
    if (address < PAGE_SIZE)
        pr_alert("Unable to handle kernel NULL pointer dereference\n");
    else
        pr_alert("Unable to handle kernel paging request\n");
    pr_alert(" at virtual address "REGFMT", pc "REGFMT"\n",
             address, regs->pc);

    show_regs(regs);

    if (unlikely(tsk->pid < 2)) {
        panic("Kernel page fault running %s!",
              tsk->pid ? "init" : "the idle task");
    }

    /*
     * More FIXME: we should probably copy the i386 here and
     * implement a generic die() routine.  Not today.
     */
#ifdef SUPPORT_DIE
    die("Oops", regs);
#endif
    bust_spinlocks(1);

    do_group_exit(SIGKILL);

    /*
     * We ran out of memory, or some other thing happened to us that made
     * us unable to handle the page fault gracefully.
     */
out_of_memory:
    up_read(&mm->mmap_sem);
    if (is_global_init(tsk)) {
        yield();
        down_read(&mm->mmap_sem);
        goto survive;
    }
    pr_alert("VM: killing process %s\n", tsk->comm);
    if (!is_kernel_mode)
        do_group_exit(SIGKILL);
    goto no_context;

do_sigbus:
    up_read(&mm->mmap_sem);

    /* Kernel mode? Handle exceptions or die */
    if (is_kernel_mode)
        goto no_context;

    force_sig_info_fault(SIGBUS, BUS_ADRERR, address, fault_num, tsk);
    return 0;
}
Example #7
0
/**
 * ubi_io_read - read data from a physical eraseblock.
 * @ubi: UBI device description object
 * @buf: buffer where to store the read data
 * @pnum: physical eraseblock number to read from
 * @offset: offset within the physical eraseblock from where to read
 * @len: how many bytes to read
 *
 * This function reads data from offset @offset of physical eraseblock @pnum
 * and stores the read data in the @buf buffer. The following return codes are
 * possible:
 *
 * o %0 if all the requested data were successfully read;
 * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but
 *   correctable bit-flips were detected; this is harmless but may indicate
 *   that this eraseblock may become bad soon (but do not have to);
 * o %-EBADMSG if the MTD subsystem reported about data integrity problems, for
 *   example it can be an ECC error in case of NAND; this most probably means
 *   that the data is corrupted;
 * o %-EIO if some I/O error occurred;
 * o other negative error codes in case of other errors.
 */
int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
		int len)
{
	int err, retries = 0;
	size_t read;
	loff_t addr;

	dbg_io("read %d bytes from PEB %d:%d", len, pnum, offset);

	ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
	ubi_assert(offset >= 0 && offset + len <= ubi->peb_size);
	ubi_assert(len > 0);

	err = paranoid_check_not_bad(ubi, pnum);
	if (err)
		return err > 0 ? -EINVAL : err;

	addr = (loff_t)pnum * ubi->peb_size + offset;
retry:
	err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
	if (err == -EUCLEAN)	err = 0;	//added by Elvis, for ignore EUCLEAN
	if (err) {
		if (err == -EUCLEAN) {
			/*
			 * -EUCLEAN is reported if there was a bit-flip which
			 * was corrected, so this is harmless.
			 */
			ubi_msg("fixable bit-flip detected at PEB %d", pnum);
			ubi_assert(len == read);
			return UBI_IO_BITFLIPS;
		}

		if (read != len && retries++ < UBI_IO_RETRIES) {
			dbg_io("error %d while reading %d bytes from PEB %d:%d, "
			       "read only %zd bytes, retry",
			       err, len, pnum, offset, read);
			yield();
			goto retry;
		}

		ubi_err("error %d while reading %d bytes from PEB %d:%d, "
			"read %zd bytes", err, len, pnum, offset, read);
		ubi_dbg_dump_stack();

		/*
		 * The driver should never return -EBADMSG if it failed to read
		 * all the requested data. But some buggy drivers might do
		 * this, so we change it to -EIO.
		 */
		if (read != len && err == -EBADMSG) {
			ubi_assert(0);
			printk("%s[%d] not here\n", __func__, __LINE__);
/*			err = -EIO; */
		}
	} else {
		ubi_assert(len == read);

		if (ubi_dbg_is_bitflip()) {
			dbg_msg("bit-flip (emulated)");
			err = UBI_IO_BITFLIPS;
		}
	}

	return err;
}
Example #8
0
/*
 * This routine handles page faults.  It determines the problem, and
 * then passes it off to one of the appropriate routines.
 *
 * error_code:
 *	bit 0 == 0 means no page found, 1 means protection fault
 *	bit 1 == 0 means read, 1 means write
 *
 * If this routine detects a bad access, it returns 1, otherwise it
 * returns 0.
 */
int do_page_fault(struct pt_regs *regs, unsigned long address,
			      unsigned long error_code)
{
	struct mm_struct *mm = current->mm;
	struct vm_area_struct * vma;
	int write, fault;

#ifdef DEBUG
	printk ("do page fault:\nregs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n",
		regs->sr, regs->pc, address, error_code,
		current->mm->pgd);
#endif

	/*
	 * If we're in an interrupt or have no user
	 * context, we must not take the fault..
	 */
	if (in_interrupt() || !mm)
		goto no_context;

	down_read(&mm->mmap_sem);

	vma = find_vma(mm, address);
	if (!vma)
		goto map_err;
	if (vma->vm_flags & VM_IO)
		goto acc_err;
	if (vma->vm_start <= address)
		goto good_area;
	if (!(vma->vm_flags & VM_GROWSDOWN))
		goto map_err;
	if (user_mode(regs)) {
		/* Accessing the stack below usp is always a bug.  The
		   "+ 256" is there due to some instructions doing
		   pre-decrement on the stack and that doesn't show up
		   until later.  */
		if (address + 256 < rdusp())
			goto map_err;
	}
	if (expand_stack(vma, address))
		goto map_err;

/*
 * Ok, we have a good vm_area for this memory access, so
 * we can handle it..
 */
good_area:
#ifdef DEBUG
	printk("do_page_fault: good_area\n");
#endif
	write = 0;
	switch (error_code & 3) {
		default:	/* 3: write, present */
			/* fall through */
		case 2:		/* write, not present */
			if (!(vma->vm_flags & VM_WRITE))
				goto acc_err;
			write++;
			break;
		case 1:		/* read, present */
			goto acc_err;
		case 0:		/* read, not present */
			if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
				goto acc_err;
	}

	/*
	 * If for any reason at all we couldn't handle the fault,
	 * make sure we exit gracefully rather than endlessly redo
	 * the fault.
	 */

 survive:
	fault = handle_mm_fault(mm, vma, address, write);
#ifdef DEBUG
	printk("handle_mm_fault returns %d\n",fault);
#endif
	switch (fault) {
	case VM_FAULT_MINOR:
		current->min_flt++;
		break;
	case VM_FAULT_MAJOR:
		current->maj_flt++;
		break;
	case VM_FAULT_SIGBUS:
		goto bus_err;
	default:
		goto out_of_memory;
	}

	up_read(&mm->mmap_sem);
	return 0;

/*
 * We ran out of memory, or some other thing happened to us that made
 * us unable to handle the page fault gracefully.
 */
out_of_memory:
	up_read(&mm->mmap_sem);
	if (current->pid == 1) {
		yield();
		down_read(&mm->mmap_sem);
		goto survive;
	}

	printk("VM: killing process %s\n", current->comm);
	if (user_mode(regs))
		do_exit(SIGKILL);

no_context:
	current->thread.signo = SIGBUS;
	current->thread.faddr = address;
	return send_fault_sig(regs);

bus_err:
	current->thread.signo = SIGBUS;
	current->thread.code = BUS_ADRERR;
	current->thread.faddr = address;
	goto send_sig;

map_err:
	current->thread.signo = SIGSEGV;
	current->thread.code = SEGV_MAPERR;
	current->thread.faddr = address;
	goto send_sig;

acc_err:
	current->thread.signo = SIGSEGV;
	current->thread.code = SEGV_ACCERR;
	current->thread.faddr = address;

send_sig:
	up_read(&mm->mmap_sem);
	return send_fault_sig(regs);
}
Example #9
0
void imx233_lradc_wait_channel(int channel)
{
    /* wait for completion */
    while(!(HW_LRADC_CTRL1 & HW_LRADC_CTRL1__LRADCx_IRQ(channel)))
        yield();
}
Example #10
0
/**
 * do_sync_erase - synchronously erase a physical eraseblock.
 * @ubi: UBI device description object
 * @pnum: the physical eraseblock number to erase
 *
 * This function synchronously erases physical eraseblock @pnum and returns
 * zero in case of success and a negative error code in case of failure. If
 * %-EIO is returned, the physical eraseblock most probably went bad.
 */
static int do_sync_erase(struct ubi_device *ubi, int pnum)
{
	int err, retries = 0;
	struct erase_info ei;
	wait_queue_head_t wq;

	dbg_io("erase PEB %d", pnum);
	ubi_assert(pnum >= 0 && pnum < ubi->peb_count);

	if (ubi->ro_mode) {
		ubi_err("read-only mode");
		return -EROFS;
	}

retry:
	init_waitqueue_head(&wq);
	memset(&ei, 0, sizeof(struct erase_info));

	ei.mtd      = ubi->mtd;
	ei.addr     = (loff_t)pnum * ubi->peb_size;
	ei.len      = ubi->peb_size;
	ei.callback = erase_callback;
	ei.priv     = (unsigned long)&wq;

	err = mtd_erase(ubi->mtd, &ei);
	atomic_inc(&ubi->ec_count); //MTK
	if (err) {
		if (retries++ < UBI_IO_RETRIES) {
			ubi_warn("error %d while erasing PEB %d, retry",
				 err, pnum);
			yield();
			goto retry;
		}
		ubi_err("cannot erase PEB %d, error %d", pnum, err);
		dump_stack();
		return err;
	}

	err = wait_event_interruptible(wq, ei.state == MTD_ERASE_DONE ||
					   ei.state == MTD_ERASE_FAILED);
	if (err) {
		ubi_err("interrupted PEB %d erasure", pnum);
		return -EINTR;
	}

	if (ei.state == MTD_ERASE_FAILED) {
		if (retries++ < UBI_IO_RETRIES) {
			ubi_warn("error while erasing PEB %d, retry", pnum);
			yield();
			goto retry;
		}
		ubi_err("cannot erase PEB %d", pnum);
		dump_stack();
		return -EIO;
	}

	err = ubi_self_check_all_ff(ubi, pnum, 0, ubi->peb_size);
	if (err)
		return err;

	if (ubi_dbg_is_erase_failure(ubi)) {
		ubi_err("cannot erase PEB %d (emulated)", pnum);
		return -EIO;
	}

	return 0;
}
Example #11
0
void TickerTask::kill(){
	// end this task. clear all data in scheduler table
	clear();
	yield();
};
Example #12
0
/**
 * ubi_io_read - read data from a physical eraseblock.
 * @ubi: UBI device description object
 * @buf: buffer where to store the read data
 * @pnum: physical eraseblock number to read from
 * @offset: offset within the physical eraseblock from where to read
 * @len: how many bytes to read
 *
 * This function reads data from offset @offset of physical eraseblock @pnum
 * and stores the read data in the @buf buffer. The following return codes are
 * possible:
 *
 * o %0 if all the requested data were successfully read;
 * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but
 *   correctable bit-flips were detected; this is harmless but may indicate
 *   that this eraseblock may become bad soon (but do not have to);
 * o %-EBADMSG if the MTD subsystem reported about data integrity problems, for
 *   example it can be an ECC error in case of NAND; this most probably means
 *   that the data is corrupted;
 * o %-EIO if some I/O error occurred;
 * o other negative error codes in case of other errors.
 */
int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
		int len)
{
	int err, retries = 0;
	size_t read;
	loff_t addr;

	dbg_io("read %d bytes from PEB %d:%d", len, pnum, offset);

	ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
	ubi_assert(offset >= 0 && offset + len <= ubi->peb_size);
	ubi_assert(len > 0);

	err = self_check_not_bad(ubi, pnum);
	if (err)
		return err;

	/*
	 * Deliberately corrupt the buffer to improve robustness. Indeed, if we
	 * do not do this, the following may happen:
	 * 1. The buffer contains data from previous operation, e.g., read from
	 *    another PEB previously. The data looks like expected, e.g., if we
	 *    just do not read anything and return - the caller would not
	 *    notice this. E.g., if we are reading a VID header, the buffer may
	 *    contain a valid VID header from another PEB.
	 * 2. The driver is buggy and returns us success or -EBADMSG or
	 *    -EUCLEAN, but it does not actually put any data to the buffer.
	 *
	 * This may confuse UBI or upper layers - they may think the buffer
	 * contains valid data while in fact it is just old data. This is
	 * especially possible because UBI (and UBIFS) relies on CRC, and
	 * treats data as correct even in case of ECC errors if the CRC is
	 * correct.
	 *
	 * Try to prevent this situation by changing the first byte of the
	 * buffer.
	 */
	*((uint8_t *)buf) ^= 0xFF;

	addr = (loff_t)pnum * ubi->peb_size + offset;
retry:
	err = mtd_read(ubi->mtd, addr, len, &read, buf);
	if (err) {
		const char *errstr = mtd_is_eccerr(err) ? " (ECC error)" : "";

		if (mtd_is_bitflip(err)) {
			/*
			 * -EUCLEAN is reported if there was a bit-flip which
			 * was corrected, so this is harmless.
			 *
			 * We do not report about it here unless debugging is
			 * enabled. A corresponding message will be printed
			 * later, when it is has been scrubbed.
			 */
			ubi_msg("fixable bit-flip detected at PEB %d", pnum);
			ubi_assert(len == read);
			return UBI_IO_BITFLIPS;
		}

		if (retries++ < UBI_IO_RETRIES) {
			ubi_warn("error %d%s while reading %d bytes from PEB %d:%d, read only %zd bytes, retry",
				 err, errstr, len, pnum, offset, read);
			yield();
			goto retry;
		}

		ubi_err("error %d%s while reading %d bytes from PEB %d:%d, read %zd bytes",
			err, errstr, len, pnum, offset, read);
		dump_stack();

		/*
		 * The driver should never return -EBADMSG if it failed to read
		 * all the requested data. But some buggy drivers might do
		 * this, so we change it to -EIO.
		 */
		if (read != len && mtd_is_eccerr(err)) {
			ubi_assert(0);
			err = -EIO;
		}
	} else {
		ubi_assert(len == read);

		if (ubi_dbg_is_bitflip(ubi)) {
			dbg_gen("bit-flip (emulated)");
			err = UBI_IO_BITFLIPS;
		}
	}

	return err;
}
Example #13
0
void adcInit(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    AQ_NOTICE("ADC init\n");

    memset((void *)&adcData, 0, sizeof(adcData));

    // energize mag's set/reset circuit
    adcData.magSetReset = digitalInit(GPIOE, GPIO_Pin_10, 1);

    // use auto-zero function of gyros
    adcData.rateAutoZero = digitalInit(GPIOE, GPIO_Pin_8, 0);

    // bring ACC's SELF TEST line low
    adcData.accST = digitalInit(GPIOE, GPIO_Pin_12, 0);

    // bring ACC's SCALE line low (ADXL3X5 requires this line be tied to GND or left floating)
    adcData.accScale = digitalInit(GPIOC, GPIO_Pin_15, 0);

    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3, ENABLE);

    adcData.sample = ADC_SAMPLES - 1;

    // Use STM32F4's Triple Regular Simultaneous Mode capable of ~ 6M samples per second

    DMA_DeInit(ADC_DMA_STREAM);
    DMA_InitStructure.DMA_Channel = ADC_DMA_CHANNEL;
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)adcDMAData.adc123Raw1;
    DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)0x40012308);
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_BufferSize = ADC_CHANNELS * 3 * 2;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(ADC_DMA_STREAM, &DMA_InitStructure);

    DMA_ITConfig(ADC_DMA_STREAM, DMA_IT_HT | DMA_IT_TC, ENABLE);
    DMA_ClearITPendingBit(ADC_DMA_STREAM, ADC_DMA_FLAGS);

    DMA_Cmd(ADC_DMA_STREAM, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = ADC_DMA_IRQ;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    // ADC Common Init
    ADC_CommonStructInit(&ADC_CommonInitStructure);
    ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult;
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
    ADC_CommonInit(&ADC_CommonInitStructure);

    // ADC1 configuration
    ADC_StructInit(&ADC_InitStructure);
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfConversion = 16;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGX, 1, ADC_SAMPLE_TIME);	// magX
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGX, 2, ADC_SAMPLE_TIME);	// magX
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGX, 3, ADC_SAMPLE_TIME);	// magX
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGX, 4, ADC_SAMPLE_TIME);	// magX

    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGY, 5, ADC_SAMPLE_TIME);	// magY
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGY, 6, ADC_SAMPLE_TIME);	// magY
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGY, 7, ADC_SAMPLE_TIME);	// magY
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGY, 8, ADC_SAMPLE_TIME);	// magY

    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGZ, 9, ADC_SAMPLE_TIME);	// magZ
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGZ, 10, ADC_SAMPLE_TIME);	// magZ
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGZ, 11, ADC_SAMPLE_TIME);	// magZ
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_MAGZ, 12, ADC_SAMPLE_TIME);	// magZ

    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_RATEX, 13, ADC_SAMPLE_TIME);	// rateX
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_RATEX, 14, ADC_SAMPLE_TIME);	// rateX
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_RATEX, 15, ADC_SAMPLE_TIME);	// rateX
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_RATEX, 16, ADC_SAMPLE_TIME);	// rateX

    // Enable ADC1 DMA since ADC1 is the Master
    ADC_DMACmd(ADC1, ENABLE);

    // ADC2 configuration
    ADC_StructInit(&ADC_InitStructure);
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfConversion = 16;
    ADC_Init(ADC2, &ADC_InitStructure);

    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_RATEY, 1, ADC_SAMPLE_TIME);	// rateY
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_RATEY, 2, ADC_SAMPLE_TIME);	// rateY
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_RATEY, 3, ADC_SAMPLE_TIME);	// rateY
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_RATEY, 4, ADC_SAMPLE_TIME);	// rateY

    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCX, 5, ADC_SAMPLE_TIME);	// accX
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCX, 6, ADC_SAMPLE_TIME);	// accX
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCX, 7, ADC_SAMPLE_TIME);	// accX
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCX, 8, ADC_SAMPLE_TIME);	// accX

    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCY, 9, ADC_SAMPLE_TIME);	// accY
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCY, 10, ADC_SAMPLE_TIME);	// accY
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCY, 11, ADC_SAMPLE_TIME);	// accY
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCY, 12, ADC_SAMPLE_TIME);	// accY

    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCZ, 13, ADC_SAMPLE_TIME);	// accZ
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCZ, 14, ADC_SAMPLE_TIME);	// accZ
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCZ, 15, ADC_SAMPLE_TIME);	// accZ
    ADC_RegularChannelConfig(ADC2, ADC_CHANNEL_ACCZ, 16, ADC_SAMPLE_TIME);	// accZ

    // ADC3 configuration
    ADC_StructInit(&ADC_InitStructure);
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfConversion = 16;
    ADC_Init(ADC3, &ADC_InitStructure);

    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_RATEZ, 1, ADC_SAMPLE_TIME);	// rateZ
    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_RATEZ, 2, ADC_SAMPLE_TIME);	// rateZ
    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_RATEZ, 3, ADC_SAMPLE_TIME);	// rateZ
    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_RATEZ, 4, ADC_SAMPLE_TIME);	// rateZ

    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_TEMP1, 5, ADC_SAMPLE_TIME);	// temp1
    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_TEMP2, 6, ADC_SAMPLE_TIME);	// temp2

    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES1, 7, ADC_SAMPLE_TIME);	// pressure1
    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES1, 8, ADC_SAMPLE_TIME);	// pressure1
    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES1, 9, ADC_SAMPLE_TIME);	// pressure1
    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES1, 10, ADC_SAMPLE_TIME);	// pressure1

    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_VIN, 11, ADC_SAMPLE_TIME);	// Vin
    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_TEMP3, 12, ADC_SAMPLE_TIME);	// temp3

    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES2, 13, ADC_SAMPLE_TIME);	// pressure2
    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES2, 14, ADC_SAMPLE_TIME);	// pressure2
    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES2, 15, ADC_SAMPLE_TIME);	// pressure2
    ADC_RegularChannelConfig(ADC3, ADC_CHANNEL_PRES2, 16, ADC_SAMPLE_TIME);	// pressure2

    // Enable DMA request after last transfer (Multi-ADC mode)
    ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

    // Enable
    ADC_Cmd(ADC1, ENABLE);
    ADC_Cmd(ADC2, ENABLE);
    ADC_Cmd(ADC3, ENABLE);

    adcData.adcFlag = CoCreateFlag(1, 0);
    adcTaskStack = aqStackInit(ADC_STACK_SIZE, "ADC");

    adcData.adcTask = CoCreateTask(adcTaskCode, (void *)0, ADC_PRIORITY, &adcTaskStack[ADC_STACK_SIZE-1], ADC_STACK_SIZE);

    // Start ADC1 Software Conversion
    ADC_SoftwareStartConv(ADC1);

    yield(100);

    // set initial temperatures
    adcData.temp1 = adcIDGVoltsToTemp(adcData.voltages[ADC_VOLTS_TEMP1]);
    adcData.temp2 = adcIDGVoltsToTemp(adcData.voltages[ADC_VOLTS_TEMP2]);
    adcData.temp3 = adcT1VoltsToTemp(adcData.voltages[ADC_VOLTS_TEMP3]);
    analogData.vIn = adcVsenseToVin(adcData.voltages[ADC_VOLTS_VIN]);

    adcCalibOffsets();
}
Example #14
0
void Console::wait_for_enter_keypress()
{
    while (fgetc(stdin) != '\n')
        yield();
}
Example #15
0
void Client::execute() {
	if ( DEBUG > 1 ) {
		printf( "Executing client...\n" );
	}

	int choice;

	// Infinite execution loop
	while( true ) {
		//printf( "Client %d has %d/%d units in state %d.\n", id, allocated, requested, state );
		yield();

		if ( state == 1 ) { // Normal operation
			if ( crashed ) {
				mutex.lock();
				crashed = false;
				mutex.unlock();

				report( allocated );
				continue;
			}

			if ( allocated ) {
				choice = randint(1,2);
				switch( choice ) {
					case 1:
						use();
						break;
					case 2:
						release();
						break;
				}
			} else  {
				choice = randint(1,2);
				switch( choice ) {
					case 1:
						work();
						break;
					case 2:
						request(randint(1,REQUEST_MAX));
						break;
				}
			}
		} else if ( state == 2 ) { // Requesting units
			if ( crashed ) {
				mutex.lock();
				crashed = false;
				mutex.unlock();

				report( allocated );

				if ( allocated ) {
					mutex.lock();
					state = 3;
					mutex.unlock();
				} else {
					request( requested );
				}
			}
		} else if ( state == 3 ) { // Crash recovery
			if ( crashed ) {
				mutex.lock();
				crashed = false;
				mutex.unlock();

				report( allocated );
			}

			if ( allocated ) {
				release();
			} else {
				request(requested);
			}
		}
	}
}
Example #16
0
static void __init handle_initrd(void)
{
	int error;
	int pid;

	real_root_dev = new_encode_dev(ROOT_DEV);
	create_dev("/dev/root.old", Root_RAM0);
	/* mount initrd on rootfs' /root */
	mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
	sys_mkdir("/old", 0700);
	root_fd = sys_open("/", 0, 0);
	old_fd = sys_open("/old", 0, 0);
	/* move initrd over / and chdir/chroot in initrd root */
	sys_chdir("/root");
	sys_mount(".", "/", NULL, MS_MOVE, NULL);
	sys_chroot(".");

	/*
	 * In case that a resume from disk is carried out by linuxrc or one of
	 * its children, we need to tell the freezer not to wait for us.
	 */
	current->flags |= PF_FREEZER_SKIP;

	pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
	if (pid > 0)
		while (pid != sys_wait4(-1, NULL, 0, NULL))
			yield();

	current->flags &= ~PF_FREEZER_SKIP;

	/* move initrd to rootfs' /old */
	sys_fchdir(old_fd);
	sys_mount("/", ".", NULL, MS_MOVE, NULL);
	/* switch root and cwd back to / of rootfs */
	sys_fchdir(root_fd);
	sys_chroot(".");
	sys_close(old_fd);
	sys_close(root_fd);

	if (new_decode_dev(real_root_dev) == Root_RAM0) {
		sys_chdir("/old");
		return;
	}

	ROOT_DEV = new_decode_dev(real_root_dev);
	mount_root();

	printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
	error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
	if (!error)
		printk("okay\n");
	else {
		int fd = sys_open("/dev/root.old", O_RDWR, 0);
		if (error == -ENOENT)
			printk("/initrd does not exist. Ignored.\n");
		else
			printk("failed\n");
		printk(KERN_NOTICE "Unmounting old root\n");
		sys_umount("/old", MNT_DETACH);
		printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
		if (fd < 0) {
			error = fd;
		} else {
			error = sys_ioctl(fd, BLKFLSBUF, 0);
			sys_close(fd);
		}
		printk(!error ? "okay\n" : "failed\n");
	}
}
Example #17
0
int usb_serial_write(const void *buffer, uint32_t size)
{
#if 1
	uint32_t len;
	uint32_t wait_count;
	const uint8_t *src = (const uint8_t *)buffer;
	uint8_t *dest;

	tx_noautoflush = 1;
	while (size > 0) {
		if (!tx_packet) {
			wait_count = 0;
			while (1) {
				if (!usb_configuration) {
					tx_noautoflush = 0;
					return -1;
				}
				if (usb_tx_packet_count(CDC_TX_ENDPOINT) < TX_PACKET_LIMIT) {
					tx_noautoflush = 1;
					tx_packet = usb_malloc();
					if (tx_packet) break;
					tx_noautoflush = 0;
				}
				if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
					transmit_previous_timeout = 1;
					return -1;
				}
				yield();
			}
		}
		transmit_previous_timeout = 0;
		len = CDC_TX_SIZE - tx_packet->index;
		if (len > size) len = size;
		dest = tx_packet->buf + tx_packet->index;
		tx_packet->index += len;
		size -= len;
		while (len-- > 0) *dest++ = *src++;
		if (tx_packet->index < CDC_TX_SIZE) {
			usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
		} else {
			tx_packet->len = CDC_TX_SIZE;
			usb_cdc_transmit_flush_timer = 0;
			usb_tx(CDC_TX_ENDPOINT, tx_packet);
			tx_packet = NULL;
		}
	}
	tx_noautoflush = 0;
	return 0;
#endif
#if 0
	const uint8_t *p = (const uint8_t *)buffer;
	int r;

	while (size) {
		r = usb_serial_putchar(*p++);
		if (r < 0) return -1;
		size--;
	}
	return 0;
#endif
}
Example #18
0
/*
 * VERY simple elf loader.
 *
 * Make stupid assumptions like linear allocation of segments, in order
 */
void elf_load(void *base, size_t size) {
	elf_file_header_t *f;
	elf_program_header_t *ph;
	void *alloc_to = (void *)0;
	int i;

	f = base;
	if (f->magic != ELF_MAGIC) { kprint("Bad ELF magic found"); return; }
	if (f->type != ELF_TYPE_EXEC && f->type != ELF_TYPE_DYN_EXEC) { 
		kprintf("Unknown ELF executable type (%x)\n", f->type); 
		return;
	}

	for (i=0; i<(f->ph_entry_count); i++) {
		ph = base + f->program_head_offset + (f->ph_entry_size * i);

		if (ph->segment_type == ELF_PROG_SEG_LOAD) {
			int pages_needed = ((ph->mem_size) / PAGE_SIZE) + 1;
			void * pages[pages_needed];
			void *abase = ph->virtual_addr;
			int i;

			/* Show what we are loading if debugging */
			if (ph->flags & ELF_PS_READ) kprint("R");
			if (ph->flags & ELF_PS_WRITE) kprint("W");
			if (ph->flags & ELF_PS_EXEC) kprint("X");
			kprintf("elf:\t0x%x(0x%x), mem 0x%x, dsk 0x%x, aln 0x%x\n",
				ph->phys_addr, ph->virtual_addr, ph->mem_size, 
				ph->file_size, ph->alignment);

			/* Don't double allocate pages, no matter how 
			 * stupid and broken the ELF header is */
			while (abase < alloc_to) {
				pages_needed--;
				abase += PAGE_SIZE;
			}
			alloc_to = abase + (PAGE_SIZE * pages_needed) - 1;
			kgetpages(pages_needed, pages);
			for (i = 0; i < pages_needed; i++) {
		                paging_add_to_dir(kernel_page_dir, abase, pages[i]);
	       		        abase += PAGE_SIZE;
		        }


			kmemcpy(ph->virtual_addr, base+(ph->offset), 
					ph->file_size);

			if (ph->file_size < ph->mem_size) {
				kmemset((ph->virtual_addr)+(ph->file_size),
					0, (ph->mem_size - ph->file_size));
			}
		}
	}
	
	#if 0
	/* 2008-07-15: THIS IS BAD!
	 * tempstack should NOT be used by things outside of inth.S or mem.S!
	 * even that is going to be phased out...
	 *
	 * new_kthread is a much more sane way to be doing this even to bootstrap
	 * usermode...
	 */

	/* Splinter, but give the tempstack, so we have to yield to make
	 * sure that it is freed again before we are called again in this
	 * thread */
	splinter(f->entry, tempstack+PAGE_SIZE);
	yield();
	#endif
	new_kthread(f->entry);
}
Example #19
0
static int try_to_freeze_tasks(int freeze_user_space)
{
    struct task_struct *g, *p;
    unsigned long end_time;
    unsigned int todo;
    struct timeval start, end;
    s64 elapsed_csecs64;
    unsigned int elapsed_csecs;

    do_gettimeofday(&start);

    end_time = jiffies + TIMEOUT;
    do {
        todo = 0;
        read_lock(&tasklist_lock);
        do_each_thread(g, p) {
            if (frozen(p) || !freezeable(p))
                continue;

            if (!freeze_task(p, freeze_user_space))
                continue;

            /*
             * Now that we've done set_freeze_flag, don't
             * perturb a task in TASK_STOPPED or TASK_TRACED.
             * It is "frozen enough".  If the task does wake
             * up, it will immediately call try_to_freeze.
             */
            if (!task_is_stopped_or_traced(p) &&
                !freezer_should_skip(p))
                todo++;
        } while_each_thread(g, p);
        read_unlock(&tasklist_lock);
        yield();            /* Yield is okay here */
        if (time_after(jiffies, end_time))
            break;
    } while (todo);

    do_gettimeofday(&end);
    elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
    do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
    elapsed_csecs = elapsed_csecs64;

    if (todo) {
        /* This does not unfreeze processes that are already frozen
         * (we have slightly ugly calling convention in that respect,
         * and caller must call thaw_processes() if something fails),
         * but it cleans up leftover PF_FREEZE requests.
         */
        printk("\n");
        printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
                "(%d tasks refusing to freeze):\n",
                elapsed_csecs / 100, elapsed_csecs % 100, todo);
        show_state();
        read_lock(&tasklist_lock);
        do_each_thread(g, p) {
            task_lock(p);
            if (freezing(p) && !freezer_should_skip(p))
                printk(KERN_ERR " %s\n", p->comm);
            cancel_freezing(p);
            task_unlock(p);
        } while_each_thread(g, p);
        read_unlock(&tasklist_lock);
    } else {
Example #20
0
void
FawkesMainThread::loop()
{
  if ( ! __thread_manager->timed_threads_exist() ) {
    __multi_logger->log_debug("FawkesMainThread", "No timed threads exist, waiting");
    try {
      __thread_manager->wait_for_timed_threads();
      __multi_logger->log_debug("FawkesMainThread", "Timed threads have been added, "
				"running main loop now");
    } catch (InterruptedException &e) {
      __multi_logger->log_debug("FawkesMainThread", "Waiting for timed threads interrupted");
      return;
    }
  }

  __plugin_manager->lock();

  try {
    if ( __time_wait ) {
      __time_wait->mark_start();
    }
    __loop_start->stamp_systime();
      
    CancelState old_state;
    set_cancel_state(CANCEL_DISABLED, &old_state);

    __mainloop_mutex->lock();

    if (unlikely(__mainloop_thread != NULL)) {
      try {
	if (likely(__mainloop_thread != NULL)) {
	  __mainloop_thread->wakeup(__mainloop_barrier);
	  __mainloop_barrier->wait();
	}
      } catch (Exception &e) {
	__multi_logger->log_warn("FawkesMainThread", e);
      }
    } else {
      safe_wake(BlockedTimingAspect::WAKEUP_HOOK_PRE_LOOP,       __max_thread_time_usec);
      safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_ACQUIRE, __max_thread_time_usec);
      safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_PREPARE, __max_thread_time_usec);
      safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_PROCESS, __max_thread_time_usec);
      safe_wake(BlockedTimingAspect::WAKEUP_HOOK_WORLDSTATE,     __max_thread_time_usec);
      safe_wake(BlockedTimingAspect::WAKEUP_HOOK_THINK,          __max_thread_time_usec);
      safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SKILL,          __max_thread_time_usec);
      safe_wake(BlockedTimingAspect::WAKEUP_HOOK_ACT,            __max_thread_time_usec);
      safe_wake(BlockedTimingAspect::WAKEUP_HOOK_ACT_EXEC,       __max_thread_time_usec);
      safe_wake(BlockedTimingAspect::WAKEUP_HOOK_POST_LOOP,      __max_thread_time_usec);
    }
    __mainloop_mutex->unlock();
    set_cancel_state(old_state);

    test_cancel();

    __thread_manager->try_recover(__recovered_threads);
    if ( ! __recovered_threads.empty() ) {
      // threads have been recovered!
      //__multi_logger->log_error(name(), "Threads recovered %zu", __recovered_threads.size());
      if(__enable_looptime_warnings) {
	if ( __recovered_threads.size() == 1 ) {
	  __multi_logger->log_warn("FawkesMainThread", "The thread %s could be "
				   "recovered and resumes normal operation",
				   __recovered_threads.front().c_str());
	} else {
	  std::string s;
	  for (std::list<std::string>::iterator i = __recovered_threads.begin();
	       i != __recovered_threads.end(); ++i) {
	    s += *i + " ";
	  }
          
	  __multi_logger->log_warn("FawkesMainThread", "The following threads could be "
				   "recovered and resumed normal operation: %s", s.c_str());
	}
      }
      __recovered_threads.clear();
    }

    if (__desired_loop_time_sec > 0) {
      __loop_end->stamp_systime();
      float loop_time = *__loop_end - __loop_start;
      if(__enable_looptime_warnings) {
        // give some extra 10% to eliminate frequent false warnings due to regular
        // time jitter (TimeWait might not be all that precise)
	if (loop_time > 1.1 * __desired_loop_time_sec) {
	  __multi_logger->log_warn("FawkesMainThread", "Loop time exceeded, "
				   "desired: %f sec (%u usec),  actual: %f sec",
				   __desired_loop_time_sec, __desired_loop_time_usec,
				   loop_time);
	}
      }
    }

    __plugin_manager->unlock();

    if ( __time_wait ) {
      __time_wait->wait_systime();
    } else {
      yield();
    }
  } catch (Exception &e) {
    __multi_logger->log_warn("FawkesMainThread",
			     "Exception caught while executing default main "
			     "loop, ignoring.");
    __multi_logger->log_warn("FawkesMainThread", e);
  } catch (std::exception &e) {
    __multi_logger->log_warn("FawkesMainThread",
			     "STL Exception caught while executing default main "
			     "loop, ignoring. (what: %s)", e.what());
  }
  // catch ... is not a good idea, would catch cancellation exception
  // at least needs to be rethrown.
}
Example #21
0
 void run(){
   while(!threadShouldExit()){
     loop();
     yield();
   }
 }
void do_work(s_coro<void>::yield_type & real_yield) {
    for (int i = 0; i < 10; ++ i) {
        std::cout << "zzz" << std::endl;
        yield(real_yield, 10);
    }
}
Example #23
0
ssize_t read_wrap(int fd, void * buf, size_t count) {
//  off_t offset;
  int status;
  int size = sizeof(buf);
  int bytes_read;

  struct aiocb *aiocbp = malloc(sizeof(struct aiocb)); // allocate structure
  if (aiocbp == NULL) {
    do {
      perror("malloc issue");
      exit(EXIT_FAILURE); 
    } while (0);
  }
  aiocbp->aio_fildes = fd;  // set the file
  if (aiocbp->aio_fildes == -1){
    do { 
      perror("opened on file");
      exit(EXIT_FAILURE); 
    } while (0);
  }
  aiocbp->aio_buf = buf;
  //malloc(size); // allocate for the buffer
  if (aiocbp->aio_buf == NULL) {
    do { 
      perror("malloc issue");
      exit(EXIT_FAILURE); 
    } while (0);
  }
  aiocbp->aio_nbytes = size; // number of bytes to read
  aiocbp->aio_reqprio = 0; // no additional priority set 
  aiocbp->aio_offset = SEEK_CUR;  // offset for the file
  aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE; // correct for polling
  
  status = aio_read(aiocbp);  // start the read
  if (status == -1) {
    do { 
      perror("aio_read issue");
      exit(EXIT_FAILURE); 
    } while (0);
  }
  
  while (status == EINPROGRESS) {
    printf("Async request still going.  \n");
    yield();
    status = aio_error(aiocbp);
  }
  switch (status) {
    case 0:
      printf("I/O succeeded\n");
      bytes_read = aio_return(aiocbp);
      //offset = lseek(fd, size, SEEK_CUR); // set the new offset after the read
      //strcpy(buf, aiocbp->aio_buf);
      break;
    case ECANCELED:
      printf("Canceled\n");
      break;
    default:
      do { 
        perror("aio_error");
        exit(EXIT_FAILURE); 
      } while (0);
      break;
  }

  return bytes_read;
}
asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
				unsigned long address)
{
	struct vm_area_struct *vma = NULL;
	struct task_struct *tsk = current;
	struct mm_struct *mm = tsk->mm;
	const int field = sizeof(unsigned long) * 2;
	siginfo_t info;
	int fault;

	info.si_code = SEGV_MAPERR;

	/*
	* We fault-in kernel-space virtual memory on-demand. The
	* 'reference' page table is init_mm.pgd.
	*
	* NOTE! We MUST NOT take any locks for this case. We may
	* be in an interrupt or a critical region, and should
	* only copy the information from the master page table,
	* nothing more.
	*/
	if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
		goto vmalloc_fault;
#ifdef MODULE_START
	if (unlikely(address >= MODULE_START && address < MODULE_END))
		goto vmalloc_fault;
#endif

	/*
	* If we're in an interrupt or have no user
	* context, we must not take the fault..
	*/
	if (in_atomic() || !mm)
		goto bad_area_nosemaphore;

	down_read(&mm->mmap_sem);
	vma = find_vma(mm, address);
	if (!vma)
		goto bad_area;
	if (vma->vm_start <= address)
		goto good_area;
	if (!(vma->vm_flags & VM_GROWSDOWN))
		goto bad_area;
	if (expand_stack(vma, address))
		goto bad_area;
	/*
	* Ok, we have a good vm_area for this memory access, so
	* we can handle it..
	 */
good_area:
	info.si_code = SEGV_ACCERR;

	if (write) {
		if (!(vma->vm_flags & VM_WRITE))
			goto bad_area;
	} else {
		if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
			goto bad_area;
	}

survive:
	/*
	* If for any reason at all we couldn't handle the fault,
	* make sure we exit gracefully rather than endlessly redo
	* the fault.
	*/
	fault = handle_mm_fault(mm, vma, address, write);
	if (unlikely(fault & VM_FAULT_ERROR)) {
		if (fault & VM_FAULT_OOM)
			goto out_of_memory;
		else if (fault & VM_FAULT_SIGBUS)
			goto do_sigbus;
		BUG();
	}
	if (fault & VM_FAULT_MAJOR)
		tsk->maj_flt++;
	else
		tsk->min_flt++;

	up_read(&mm->mmap_sem);
	return;

	/*
	* Something tried to access memory that isn't in our memory map..
	* Fix it, but check if it's kernel or user first..
	 */
bad_area:
	up_read(&mm->mmap_sem);

bad_area_nosemaphore:
	/* User mode accesses just cause a SIGSEGV */
	if (user_mode(regs)) {
		tsk->thread.cp0_badvaddr = address;
		tsk->thread.error_code = write;
		info.si_signo = SIGSEGV;
		info.si_errno = 0;
		/* info.si_code has been set above */
		info.si_addr = (void __user *) address;
		force_sig_info(SIGSEGV, &info, tsk);
		return;
	}

no_context:
	/* Are we prepared to handle this kernel fault? */
	if (fixup_exception(regs)) {
		current->thread.cp0_baduaddr = address;
		return;
	}

	/*
	* Oops. The kernel tried to access some bad page. We'll have to
	* terminate things with extreme prejudice.
	*/
	bust_spinlocks(1);

	printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at "
			"virtual address %0*lx, epc == %0*lx, ra == %0*lx\n",
			0, field, address, field, regs->cp0_epc,
			field, regs->regs[3]);
	die("Oops", regs);

	/*
	* We ran out of memory, or some other thing happened to us that made
	* us unable to handle the page fault gracefully.
	*/
out_of_memory:
	up_read(&mm->mmap_sem);
	if (is_global_init(tsk)) {
		yield();
		down_read(&mm->mmap_sem);
		goto survive;
	}
	printk("VM: killing process %s\n", tsk->comm);
	if (user_mode(regs))
		do_group_exit(SIGKILL);
	goto no_context;

do_sigbus:
	up_read(&mm->mmap_sem);
	/* Kernel mode? Handle exceptions or die */
	if (!user_mode(regs))
		goto no_context;
	else
	/*
	* Send a sigbus, regardless of whether we were in kernel
	* or user mode.
	*/
	tsk->thread.cp0_badvaddr = address;
	info.si_signo = SIGBUS;
	info.si_errno = 0;
	info.si_code = BUS_ADRERR;
	info.si_addr = (void __user *) address;
	force_sig_info(SIGBUS, &info, tsk);
	return;
vmalloc_fault:
	{
		/*
		* Synchronize this task's top level page-table
		* with the 'reference' page table.
		*
		* Do _not_ use "tsk" here. We might be inside
		* an interrupt in the middle of a task switch..
		*/
		int offset = __pgd_offset(address);
		pgd_t *pgd, *pgd_k;
		pud_t *pud, *pud_k;
		pmd_t *pmd, *pmd_k;
		pte_t *pte_k;

		pgd = (pgd_t *) pgd_current + offset;
		pgd_k = init_mm.pgd + offset;

		if (!pgd_present(*pgd_k))
			goto no_context;
		set_pgd(pgd, *pgd_k);

		pud = pud_offset(pgd, address);
		pud_k = pud_offset(pgd_k, address);
		if (!pud_present(*pud_k))
			goto no_context;

		pmd = pmd_offset(pud, address);
		pmd_k = pmd_offset(pud_k, address);
		if (!pmd_present(*pmd_k))
			goto no_context;
		set_pmd(pmd, *pmd_k);

		pte_k = pte_offset_kernel(pmd_k, address);
		if (!pte_present(*pte_k))
			goto no_context;
		return;
	}
}
//PAGEBREAK: 41
void
trap(struct trapframe *tf) {
	if (tf->trapno == T_SYSCALL) {
		if (proc->killed) {
			exit();
		}

		proc->tf = tf;
		syscall();

		if (proc->killed) {
			exit();
		}

		return;
	}

	switch (tf->trapno) {
	case T_IRQ0 + IRQ_TIMER:
		if (cpu->id == 0) {
			acquire(&tickslock);
			ticks++;
			wakeup(&ticks);
			release(&tickslock);
		}

		lapiceoi();
		break;

	case T_IRQ0 + IRQ_IDE:
		ideintr();
		lapiceoi();
		break;

	case T_IRQ0 + IRQ_IDE+1:
		// Bochs generates spurious IDE1 interrupts.
		break;

	case T_IRQ0 + IRQ_KBD:
		kbdintr();
		lapiceoi();
		break;

	case T_IRQ0 + IRQ_COM1:
		uartintr();
		lapiceoi();
		break;

	case T_IRQ0 + 7:
	case T_IRQ0 + IRQ_SPURIOUS:
		cprintf("cpu%d: spurious interrupt at %x:%x\n",
				cpu->id, tf->cs, tf->eip);
		lapiceoi();
		break;

	//PAGEBREAK: 13
	default:
		if (proc == 0 || (tf->cs & 3) == 0) {
			// In kernel, it must be our mistake.
			cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n",
					tf->trapno, cpu->id, tf->eip, rcr2());
			panic("trap");
		}

		// In user space, assume process misbehaved.
		cprintf("pid %d %s: trap %d err %d on cpu %d "
				"eip 0x%x addr 0x%x--kill proc\n",
				proc->pid, proc->name, tf->trapno, tf->err, cpu->id, tf->eip,
				rcr2());
		proc->killed = 1;
	}

	// Force process exit if it has been killed and is in user space.
	// (If it is still executing in the kernel, let it keep running
	// until it gets to the regular system call return.)
	if (proc && proc->killed && (tf->cs & 3) == DPL_USER) {
		exit();
	}

	// Force process to give up CPU on clock tick.
	// If interrupts were on while locks held, would need to check nlock.
	if (proc && proc->state == RUNNING && tf->trapno == T_IRQ0 + IRQ_TIMER) {
		yield();
	}

	// Check if the process has been killed since we yielded
	if (proc && proc->killed && (tf->cs & 3) == DPL_USER) {
		exit();
	}
}
Example #26
0
void rtw_yield_os()
{
#ifdef PLATFORM_LINUX
	yield();
#endif
}
Example #27
0
/*Finally, recall from the first assignment that we need a way 
to prevent the main thread from terminating prematurely 
if there are other threads still running. 
Implement a solution to this problem in scheduler_end. 
(Hint: you may find the is_empty queue function useful).*/
void scheduler_end(){
	while(is_empty(&ready_list) == 0){
		yield();
	}
};
Example #28
0
static int
__ps2_command(int aux, int command, u8 *param)
{
    int ret2;
    int receive = (command >> 8) & 0xf;
    int send = (command >> 12) & 0xf;

    // Disable interrupts and keyboard/mouse.
    u8 ps2ctr = GET_EBDA(ps2ctr);
    u8 newctr = ((ps2ctr | I8042_CTR_AUXDIS | I8042_CTR_KBDDIS)
                 & ~(I8042_CTR_KBDINT|I8042_CTR_AUXINT));
    dprintf(6, "i8042 ctr old=%x new=%x\n", ps2ctr, newctr);
    int ret = i8042_command(I8042_CMD_CTL_WCTR, &newctr);
    if (ret)
        return ret;

    // Flush any interrupts already pending.
    yield();

    // Enable port command is being sent to.
    if (aux)
        newctr &= ~I8042_CTR_AUXDIS;
    else
        newctr &= ~I8042_CTR_KBDDIS;
    ret = i8042_command(I8042_CMD_CTL_WCTR, &newctr);
    if (ret)
        goto fail;

    if (command == ATKBD_CMD_RESET_BAT) {
        // Reset is special wrt timeouts and bytes received.

        // Send command.
        ret = ps2_sendbyte(aux, command, 1000);
        if (ret)
            goto fail;

        // Receive parameters.
        ret = ps2_recvbyte(aux, 0, 4000);
        if (ret < 0)
            goto fail;
        param[0] = ret;
        ret = ps2_recvbyte(aux, 0, 100);
        if (ret < 0)
            // Some devices only respond with one byte on reset.
            ret = 0;
        param[1] = ret;
    } else if (command == ATKBD_CMD_GETID) {
        // Getid is special wrt bytes received.

        // Send command.
        ret = ps2_sendbyte(aux, command, 200);
        if (ret)
            goto fail;

        // Receive parameters.
        ret = ps2_recvbyte(aux, 0, 500);
        if (ret < 0)
            goto fail;
        param[0] = ret;
        if (ret == 0xab || ret == 0xac || ret == 0x2b || ret == 0x5d
            || ret == 0x60 || ret == 0x47) {
            // These ids (keyboards) return two bytes.
            ret = ps2_recvbyte(aux, 0, 500);
            if (ret < 0)
                goto fail;
            param[1] = ret;
        } else {
            param[1] = 0;
        }
    } else {
        // Send command.
        ret = ps2_sendbyte(aux, command, 200);
        if (ret)
            goto fail;

        // Send parameters (if any).
        int i;
        for (i = 0; i < send; i++) {
            ret = ps2_sendbyte(aux, param[i], 200);
            if (ret)
                goto fail;
        }

        // Receive parameters (if any).
        for (i = 0; i < receive; i++) {
            ret = ps2_recvbyte(aux, 0, 500);
            if (ret < 0)
                goto fail;
            param[i] = ret;
        }
    }

    ret = 0;

fail:
    // Restore interrupts and keyboard/mouse.
    ret2 = i8042_command(I8042_CMD_CTL_WCTR, &ps2ctr);
    if (ret2)
        return ret2;

    return ret;
}
Example #29
0
/* Voice thread entrypoint */
static void voice_thread(void)
{
    struct voice_thread_data td;

    voice_data_init(&td);

    /* audio thread will only set this once after it finished the final
     * audio hardware init so this little construct is safe - even
     * cross-core. */
    while (!audio_is_thread_ready())
        sleep(0);

    goto message_wait;

    while (1)
    {
        td.state = TSTATE_DECODE;

        if (!queue_empty(&voice_queue))
        {
        message_wait:
            queue_wait(&voice_queue, &td.ev);

        message_process:
            voice_message(&td);

            /* Branch to initial start point or branch back to previous
             * operation if interrupted by a message */
            switch (td.state)
            {
            case TSTATE_DECODE:        goto voice_decode;
            case TSTATE_BUFFER_INSERT: goto buffer_insert;
            default:                   goto message_wait;
            }
        }

    voice_decode:
        /* Decode the data */
        if (speex_decode_int(td.st, &td.bits, voice_output_buf) < 0)
        {
            /* End of stream or error - get next clip */
            td.vi.size = 0;

            if (td.vi.get_more != NULL)
                td.vi.get_more(&td.vi.start, &td.vi.size);

            if (td.vi.start != NULL && (ssize_t)td.vi.size > 0)
            {
                /* Make bit buffer use our own buffer */
                speex_bits_set_bit_buffer(&td.bits, td.vi.start, td.vi.size);
                /* Don't skip any samples when we're stringing clips together */
                td.lookahead = 0;

                /* Paranoid check - be sure never to somehow get stuck in a
                 * loop without listening to the queue */
                yield();

                if (!queue_empty(&voice_queue))
                    goto message_wait;
                else
                    goto voice_decode;
            }

            /* If all clips are done and not playing, force pcm playback. */
            if (!pcm_is_playing())
                pcmbuf_play_start();

            /* Synthesize a stop request */
            /* NOTE: We have no way to know when the pcm data placed in the
             * buffer is actually consumed and playback has reached the end
             * so until the info is available or inferred somehow, this will
             * not be accurate and the stopped signal will come too soon.
             * ie. You may not hear the "Shutting Down" splash even though
             * it waits for voice to stop. */
            td.ev.id = Q_VOICE_STOP;
            td.ev.data = 0; /* Let PCM drain by itself */
            yield();
            goto message_process;
        }

        yield();

        /* Output the decoded frame */
        td.count = VOICE_FRAME_SIZE - td.lookahead;
        td.src[0] = (const char *)&voice_output_buf[td.lookahead];
        td.src[1] = NULL;
        td.lookahead -= MIN(VOICE_FRAME_SIZE, td.lookahead);

    buffer_insert:
        /* Process the PCM samples in the DSP and send out for mixing */
        td.state = TSTATE_BUFFER_INSERT;

        while (td.count > 0)
        {
            int out_count = dsp_output_count(td.dsp, td.count);
            int inp_count;
            char *dest;

            while (1)
            {
                if (!queue_empty(&voice_queue))
                    goto message_wait;

                if ((dest = pcmbuf_request_voice_buffer(&out_count)) != NULL)
                    break;

                yield();
            }

            /* Get the real input_size for output_size bytes, guarding
             * against resampling buffer overflows. */
            inp_count = dsp_input_count(td.dsp, out_count);

            if (inp_count <= 0)
                break;

            /* Input size has grown, no error, just don't write more than
             * length */
            if (inp_count > td.count)
                inp_count = td.count;

            out_count = dsp_process(td.dsp, dest, td.src, inp_count);

            if (out_count <= 0)
                break;

            pcmbuf_write_voice_complete(out_count);
            td.count -= inp_count;
        }

        yield();
    } /* end while */
} /* voice_thread */
Example #30
0
File: xor.c Project: cilynx/dd-wrt
int
raid_memchk(unsigned int *p1, unsigned int pattern, unsigned int bytes)
{
	int status=0;
	RAID_DMA_STATUS_T 	dma_status;

	if(bytes > (1<<(SRAM_PAR_SIZE+11))){
		printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
	}

	status = ((pattern&0xFFFF)%bytes )/4;
	p1[status] = pattern;

	while(tp.status != COMPLETE){
		DPRINTK("XOR yield\n");
		//schedule();
		yield();
	}
	tp.status = RUNNING;

	// flush the cache to memory before H/W XOR touches them
	consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);

	tp.tx_desc = tp.tx_first_desc;
	if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
		// prepare tx descript
		raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xFFFFFFFF);
		tp.tx_desc->buf_addr = (unsigned int)__pa(p1);		// physical address
    	tp.tx_desc->func_ctrl.bits.raid_ctrl_status = 0;
    	tp.tx_desc->func_ctrl.bits.buffer_size = bytes ;    		/* total frame byte count */
    	tp.tx_desc->flg_status.bits32 = CMD_CHK;		// only support memory FILL command
    	tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
    	tp.tx_desc->func_ctrl.bits.own = DMA;	        		/* set owner bit */
    	tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;
//    	tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xFFFFFFF0)+tx_desc_virtual_base);

	}
	else{
	 	/* no free tx descriptor */
	 	printk("XOR:no free tx descript");
		return -1;
	}

	// change status
	//tp.status = RUNNING;
	status = tp.busy = 1;

	// start tx DMA
	txdma_ctrl.bits.td_start = 1;

	raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
//	raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);

#ifdef SPIN_WAIT
	gemini_xor_isr(2);
#else
	xor_queue_descriptor();
#endif

//	dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS);
//	if (dma_status.bits32 & (1<<15))	{

	if((tp.tx_first_desc->func_ctrl.bits.raid_ctrl_status & 0x2)) {
		status = 1;
//		raid_write_reg(RAID_DMA_STATUS,0x00008000,0x00080000);
	}
	else{
		status = 0;
	}

	tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ;
	tp.status = COMPLETE;
//	tp.rx_desc->func_ctrl.bits.own = DMA;
	return status ;
}