Esempio n. 1
0
/*
 * Shortcut for reading a register
 */
static
inline
uint32_t
emu_rreg(struct emu_softc *sc, uint32_t reg)
{
	return bus_read_register(sc->e_busdata, sc->e_buspos, reg);
}
Esempio n. 2
0
/*
 * Setup routine called by autoconf.c when an lhd is found.
 */
int
config_lhd(struct lhd_softc *lh, int lhdno)
{
	char name[32];

	/* Figure out what our name is. */
	snprintf(name, sizeof(name), "lhd%d", lhdno);

	/* Get a pointer to the on-chip buffer. */
	lh->lh_buf = bus_map_area(lh->lh_busdata, lh->lh_buspos, LHD_BUFFER);

	/* Create the semaphores. */
	lh->lh_clear = sem_create("lhd-clear", 1);
	if (lh->lh_clear == NULL) {
		return ENOMEM;
	}
	lh->lh_done = sem_create("lhd-done", 0);
	if (lh->lh_done == NULL) {
		sem_destroy(lh->lh_clear);
		lh->lh_clear = NULL;
		return ENOMEM;
	}

	/* Set up the VFS device structure. */
	lh->lh_dev.d_ops = &lhd_devops;
	lh->lh_dev.d_blocks = bus_read_register(lh->lh_busdata, lh->lh_buspos,
						LHD_REG_NSECT);
	lh->lh_dev.d_blocksize = LHD_SECTSIZE;
	lh->lh_dev.d_data = lh;

	/* Add the VFS device structure to the VFS device list. */
	return vfs_adddev(name, &lh->lh_dev, 1);
}
Esempio n. 3
0
static
void
lser_spin_until_write(struct lser_softc *sc)
{
	u_int32_t val;
	assert(curspl>0);
	do {
		val = bus_read_register(sc->ls_busdata, sc->ls_buspos,
					LSER_REG_WIRQ);
	}
	while ((val & LSER_IRQ_ACTIVE)==0);
}
Esempio n. 4
0
/*
 * The timer device also has a realtime clock on it.
 * This function gets called if the rtclock device is attached
 * to this timer.
 */
void
ltimer_gettime(void *vlt, time_t *secs, uint32_t *nsecs)
{
	struct ltimer_softc *lt = vlt;
	uint32_t secs1, secs2;
	int spl;

	/*
	 * Read the seconds twice, on either side of the nanoseconds. 
	 * If nsecs is small, use the *later* value of seconds, in case
	 * the nanoseconds turned over between the time we got the earlier
	 * value and the time we got nsecs.
	 *
	 * Note that the clock in the ltimer device is accurate down
	 * to a single processor cycle, so this might actually matter
	 * now and then.
	 *
	 * Do it with interrupts off on the current processor to avoid
	 * getting garbage if we get an interrupt among the register
	 * reads.
	 */

	spl = splhigh();

	secs1 = bus_read_register(lt->lt_bus, lt->lt_buspos,
				  LT_REG_SEC);
	*nsecs = bus_read_register(lt->lt_bus, lt->lt_buspos,
				   LT_REG_NSEC);
	secs2 = bus_read_register(lt->lt_bus, lt->lt_buspos,
				  LT_REG_SEC);

	splx(spl);

	if (*nsecs < 5000000) {
		*secs = secs2;
	}
	else {
		*secs = secs1;
	}
}
Esempio n. 5
0
void
lser_irq(void *vsc)
{
	struct lser_softc *sc = vsc;
	uint32_t x;
	bool clear_to_write = false;
	bool got_a_read = false;
	uint32_t ch = 0;

	spinlock_acquire(&sc->ls_lock);

	x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_WIRQ);
	if (x & LSER_IRQ_ACTIVE) {
		x = LSER_IRQ_ENABLE;
		sc->ls_wbusy = 0;
		clear_to_write = true;
		bus_write_register(sc->ls_busdata, sc->ls_buspos,
				   LSER_REG_WIRQ, x);
	}

	x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_RIRQ);
	if (x & LSER_IRQ_ACTIVE) {
		x = LSER_IRQ_ENABLE;
		ch = bus_read_register(sc->ls_busdata, sc->ls_buspos,
				       LSER_REG_CHAR);
		got_a_read = true;
		bus_write_register(sc->ls_busdata, sc->ls_buspos,
				   LSER_REG_RIRQ, x);
	}

	spinlock_release(&sc->ls_lock);

	if (clear_to_write && sc->ls_start != NULL) {
		sc->ls_start(sc->ls_devdata);
	}
	if (got_a_read && sc->ls_input != NULL) {
		sc->ls_input(sc->ls_devdata, ch);
	}
}
Esempio n. 6
0
int
config_lser(struct lser_softc *sc, int lserno)
{
	uint32_t x;

	(void)lserno;

	/*
	 * Enable interrupting.
	 */

	spinlock_init(&sc->ls_lock);
	sc->ls_wbusy = false;

	x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_RIRQ);
	bus_write_register(sc->ls_busdata, sc->ls_buspos,
			   LSER_REG_RIRQ, x | LSER_IRQ_ENABLE);
	x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_WIRQ);
	bus_write_register(sc->ls_busdata, sc->ls_buspos,
			   LSER_REG_WIRQ, x | LSER_IRQ_ENABLE);

	return 0;
}
Esempio n. 7
0
static
void
lser_poll_until_write(struct lser_softc *sc)
{
	uint32_t val;

	KASSERT(spinlock_do_i_hold(&sc->ls_lock));

	do {
		val = bus_read_register(sc->ls_busdata, sc->ls_buspos,
					LSER_REG_WIRQ);
	}
	while ((val & LSER_IRQ_ACTIVE) == 0);
}
Esempio n. 8
0
void
lser_irq(void *vsc)
{
	struct lser_softc *sc = vsc;
	u_int32_t x;
	int clear_to_write=0;
	int got_a_read=0;
	u_int32_t ch = 0;

	assert(curspl>0);

	x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_WIRQ);
	if (x & LSER_IRQ_ACTIVE) {
		x = LSER_IRQ_ENABLE;
		sc->ls_wbusy = 0;
		clear_to_write = 1;
		bus_write_register(sc->ls_busdata, sc->ls_buspos,
				   LSER_REG_WIRQ, x);
	}

	x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_RIRQ);
	if (x & LSER_IRQ_ACTIVE) {
		x = LSER_IRQ_ENABLE;
		ch = bus_read_register(sc->ls_busdata, sc->ls_buspos,
				       LSER_REG_CHAR);
		got_a_read = 1;
		bus_write_register(sc->ls_busdata, sc->ls_buspos, 
				   LSER_REG_RIRQ, x);
	}

	if (clear_to_write && sc->ls_start != NULL) {
		sc->ls_start(sc->ls_devdata);
	}
	if (got_a_read && sc->ls_input != NULL) {
		sc->ls_input(sc->ls_devdata, ch);
	}
}
Esempio n. 9
0
/*
 * Interrupt handler.
 */
void
ltimer_irq(void *vlt)
{
	struct ltimer_softc *lt = vlt;
	uint32_t val;

	val = bus_read_register(lt->lt_bus, lt->lt_buspos, LT_REG_IRQ);
	if (val) {
		/*
		 * Only call hardclock if we're responsible for hardclock.
		 * (Any additional timer devices are unused.)
		 */
		if (lt->lt_hardclock) {
			hardclock();
		}
		/*
		 * Likewise for timerclock.
		 */
		if (lt->lt_timerclock) {
			timerclock();
		}
	}
}
Esempio n. 10
0
/*
 * Shortcut for reading a register.
 */
static
inline
uint32_t lhd_rdreg(struct lhd_softc *lh, uint32_t reg)
{
	return bus_read_register(lh->lh_busdata, lh->lh_buspos, reg);
}