예제 #1
0
static uint16_t
nandsim_read_word(device_t dev)
{
	struct nandsim_softc *sc;
	struct nandsim_chip *chip;
	uint16_t *data_ptr;
	uint16_t ret = 0xffff;
	uint8_t  *byte_ret = (uint8_t *)&ret;

	sc = device_get_softc(dev);
	chip = sc->active_chip;

	if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) {
		if (chip->data.index < chip->data.size - 1) {
			data_ptr =
			    (uint16_t *)&(chip->data.data_ptr[chip->data.index]);
			ret = *data_ptr;
			chip->data.index += 2;
			byte_corrupt(chip, byte_ret);
			byte_corrupt(chip, byte_ret + 1);
		}
		nandsim_log(chip, NANDSIM_LOG_DATA, "read %04x\n", ret);
	}

	return (ret);
}
예제 #2
0
static void
nandsim_loop(void *arg)
{
	struct nandsim_chip *chip = (struct nandsim_chip *)arg;
	struct nandsim_ev *ev;

	nand_debug(NDBG_SIM,"Start main loop for chip%d [%8p]", chip->chip_num,
	    chip);
	for(;;) {
		NANDSIM_CHIP_LOCK(chip);
		if (!(chip->flags & NANDSIM_CHIP_ACTIVE)) {
			chip->flags |= NANDSIM_CHIP_ACTIVE;
			wakeup(chip->nandsim_td);
		}

		if (STAILQ_EMPTY(&chip->nandsim_events)) {
			nand_debug(NDBG_SIM,"Chip%d [%8p] going sleep",
			    chip->chip_num, chip);
			msleep(chip, &chip->ns_lock, PRIBIO, "nandev", 0);
		}

		ev = STAILQ_FIRST(&chip->nandsim_events);
		STAILQ_REMOVE_HEAD(&chip->nandsim_events, links);
		NANDSIM_CHIP_UNLOCK(chip);
		if (ev->type == NANDSIM_EV_EXIT) {
			NANDSIM_CHIP_LOCK(chip);
			destroy_event(ev);
			wakeup(ev);
			while (!STAILQ_EMPTY(&chip->nandsim_events)) {
				ev = STAILQ_FIRST(&chip->nandsim_events);
				STAILQ_REMOVE_HEAD(&chip->nandsim_events,
				    links);
				destroy_event(ev);
				wakeup(ev);
			}
			NANDSIM_CHIP_UNLOCK(chip);
			nandsim_log(chip, NANDSIM_LOG_SM, "destroyed\n");
			mtx_destroy(&chip->ns_lock);
			nandsim_blk_state_destroy(chip);
			nandsim_swap_destroy(chip->swap);
			free(chip, M_NANDSIM);
			nandsim_proc = NULL;

			kthread_exit();
		}

		if (!(chip->flags & NANDSIM_CHIP_FROZEN)) {
			nand_debug(NDBG_SIM,"Chip [%x] get event [%x]",
			    chip->chip_num, ev->type);
			chip->ev_handler(chip, ev->type, ev->data);
		}

		wakeup(ev);
		destroy_event(ev);
	}

}
예제 #3
0
static void
nandsim_write_byte(device_t dev, uint8_t byte)
{
	struct nandsim_softc *sc;
	struct nandsim_chip *chip;

	sc = device_get_softc(dev);
	chip = sc->active_chip;

	if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN) &&
	    (chip->data.index < chip->data.size)) {
		byte_corrupt(chip, &byte);
		chip->data.data_ptr[chip->data.index] &= byte;
		chip->data.index++;
		nandsim_log(chip, NANDSIM_LOG_DATA, "write %02x\n", byte);
	}
}
예제 #4
0
static int
nandsim_select_cs(device_t dev, uint8_t cs)
{
	struct nandsim_softc *sc;

	sc = device_get_softc(dev);

	if (cs >= MAX_CS_NUM)
		return (EINVAL);

	sc->active_chip = sc->chips[cs];

	if (sc->active_chip)
		nandsim_log(sc->active_chip, NANDSIM_LOG_EV,
		    "Select cs %d\n", cs);

	return (0);
}
예제 #5
0
static int
nandsim_send_command(device_t dev, uint8_t command)
{
	struct nandsim_softc *sc;
	struct nandsim_chip *chip;
	struct nandsim_ev *ev;

	sc = device_get_softc(dev);
	chip = sc->active_chip;

	if (chip == NULL)
		return (0);

	nandsim_log(chip, NANDSIM_LOG_EV, "Send command %x\n", command);

	switch (command) {
	case NAND_CMD_READ_ID:
	case NAND_CMD_READ_PARAMETER:
		sc->address_type = ADDR_ID;
		break;
	case NAND_CMD_ERASE:
		sc->address_type = ADDR_ROW;
		break;
	case NAND_CMD_READ:
	case NAND_CMD_PROG:
		sc->address_type = ADDR_ROWCOL;
		break;
	default:
		sc->address_type = ADDR_NONE;
		break;
	}

	if (command == NAND_CMD_STATUS)
		chip->flags |= NANDSIM_CHIP_GET_STATUS;
	else {
		ev = create_event(chip, NANDSIM_EV_CMD, 1);
		*(uint8_t *)ev->data = command;
		send_event(ev);
	}

	return (0);
}
예제 #6
0
static int
nandsim_send_address(device_t dev, uint8_t addr)
{
	struct nandsim_ev *ev;
	struct nandsim_softc *sc;
	struct nandsim_chip *chip;

	sc = device_get_softc(dev);
	chip = sc->active_chip;

	if (chip == NULL)
		return (0);

	KASSERT((sc->address_type != ADDR_NONE), ("unexpected address"));
	nandsim_log(chip, NANDSIM_LOG_EV, "Send addr %x\n", addr);

	ev = create_event(chip, NANDSIM_EV_ADDR, 1);

	*((uint8_t *)(ev->data)) = addr;

	send_event(ev);
	return (0);
}
예제 #7
0
static void
nandsim_write_word(device_t dev, uint16_t word)
{
	struct nandsim_softc *sc;
	struct nandsim_chip *chip;
	uint16_t *data_ptr;
	uint8_t  *byte_ptr = (uint8_t *)&word;

	sc = device_get_softc(dev);
	chip = sc->active_chip;

	if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) {
		if ((chip->data.index + 1) < chip->data.size) {
			byte_corrupt(chip, byte_ptr);
			byte_corrupt(chip, byte_ptr + 1);
			data_ptr =
			    (uint16_t *)&(chip->data.data_ptr[chip->data.index]);
			*data_ptr &= word;
			chip->data.index += 2;
		}

		nandsim_log(chip, NANDSIM_LOG_DATA, "write %04x\n", word);
	}
}
예제 #8
0
static uint8_t
nandsim_read_byte(device_t dev)
{
	struct nandsim_softc *sc;
	struct nandsim_chip *chip;
	uint8_t ret = 0xff;

	sc = device_get_softc(dev);
	chip = sc->active_chip;

	if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) {
		if (chip->flags & NANDSIM_CHIP_GET_STATUS) {
			nandsim_chip_timeout(chip);
			ret = nandchip_get_status(chip);
			chip->flags &= ~NANDSIM_CHIP_GET_STATUS;
		} else if (chip->data.index < chip->data.size) {
			ret = chip->data.data_ptr[chip->data.index++];
			byte_corrupt(chip, &ret);
		}
		nandsim_log(chip, NANDSIM_LOG_DATA, "read %02x\n", ret);
	}

	return (ret);
}