Ejemplo n.º 1
0
/** Enable PIO for specified I/O range.
 *
 * @param pio_addr I/O start address.
 * @param size     Size of the I/O region.
 * @param virt     Virtual address for application's
 *                 PIO operations. Can be NULL for PMIO.
 *
 * @return EOK on success.
 * @return Negative error code on failure.
 *
 */
int pio_enable(void *pio_addr, size_t size, void **virt)
{
#ifdef IO_SPACE_BOUNDARY
	if (pio_addr < IO_SPACE_BOUNDARY) {
		if (virt)
			*virt = pio_addr;
		return iospace_enable(task_get_id(), pio_addr, size);
	}
#else
	(void) iospace_enable;
#endif
	if (!virt)
		return EINVAL;

	void *phys_frame =
	    (void *) ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE);
	size_t offset = pio_addr - phys_frame;
	size_t pages = SIZE2PAGES(offset + size);
	
	void *virt_page;
	int rc = physmem_map(phys_frame, pages,
	    AS_AREA_READ | AS_AREA_WRITE, &virt_page);
	if (rc != EOK)
		return rc;
	
	*virt = virt_page + offset;
	return EOK;
}
Ejemplo n.º 2
0
/** Get time of day
 *
 * The time variables are memory mapped (read-only) from kernel which
 * updates them periodically.
 *
 * As it is impossible to read 2 values atomically, we use a trick:
 * First we read the seconds, then we read the microseconds, then we
 * read the seconds again. If a second elapsed in the meantime, set
 * the microseconds to zero.
 *
 * This assures that the values returned by two subsequent calls
 * to gettimeofday() are monotonous.
 *
 */
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
	if (ktime == NULL) {
		uintptr_t faddr;
		int rc = sysinfo_get_value("clock.faddr", &faddr);
		if (rc != EOK) {
			errno = rc;
			return -1;
		}
		
		void *addr;
		rc = physmem_map((void *) faddr, 1,
		    AS_AREA_READ | AS_AREA_CACHEABLE, &addr);
		if (rc != EOK) {
			as_area_destroy(addr);
			errno = rc;
			return -1;
		}
		
		ktime = addr;
	}
	
	if (tz) {
		tz->tz_minuteswest = 0;
		tz->tz_dsttime = DST_NONE;
	}
	
	sysarg_t s2 = ktime->seconds2;
	
	read_barrier();
	tv->tv_usec = ktime->useconds;
	
	read_barrier();
	sysarg_t s1 = ktime->seconds1;
	
	if (s1 != s2) {
		tv->tv_sec = max(s1, s2);
		tv->tv_usec = 0;
	} else
		tv->tv_sec = s1;
	
	return 0;
}