Example #1
0
static boolean_t
has_saved_fp(dis_handle_t *dhp, uint8_t *ins, int size)
{
	int 		i, j;
	uint32_t	n;
	boolean_t	found_push = B_FALSE;
	ssize_t		sz = 0;

	for (i = 0; i < size; i += sz) {
		if ((sz = instr_size(dhp, ins, i, size)) < 1)
			return (B_FALSE);

		if (found_push == B_FALSE) {
			if (sz != 1)
				continue;

			n = INSTR1(ins, i);
			for (j = 0; j <= NUM_FP_PUSHES; j++)
				if (save_fp_pushes[j] == n) {
					found_push = B_TRUE;
					break;
				}
		} else {
			if (sz != 3)
				continue;
			n = INSTR3(ins, i);
			for (j = 0; j <= NUM_FP_MOVS; j++)
				if (save_fp_movs[j] == n)
					return (B_TRUE);
		}
	}

	return (B_FALSE);
}
static void qspi_set_lut(struct fsl_qspi_priv *priv)
{
	struct fsl_qspi_regs *regs = priv->regs;
	u32 lut_base;

	/* Unlock the LUT */
	qspi_write32(priv->flags, &regs->lutkey, LUT_KEY_VALUE);
	qspi_write32(priv->flags, &regs->lckcr, QSPI_LCKCR_UNLOCK);

	/* Write Enable */
	lut_base = SEQID_WREN * 4;
	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_WREN) |
		PAD0(LUT_PAD1) | INSTR0(LUT_CMD));
	qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);

	/* Fast Read */
	lut_base = SEQID_FAST_READ * 4;
#ifdef CONFIG_SPI_FLASH_BAR
	qspi_write32(priv->flags, &regs->lut[lut_base],
		     OPRND0(QSPI_CMD_FAST_READ) | PAD0(LUT_PAD1) |
		     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
#else
	if (FSL_QSPI_FLASH_SIZE  <= SZ_16M)
		qspi_write32(priv->flags, &regs->lut[lut_base],
			     OPRND0(QSPI_CMD_FAST_READ) | PAD0(LUT_PAD1) |
			     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
			     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
	else
		qspi_write32(priv->flags, &regs->lut[lut_base],
			     OPRND0(QSPI_CMD_FAST_READ_4B) |
			     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) |
			     OPRND1(ADDR32BIT) | PAD1(LUT_PAD1) |
			     INSTR1(LUT_ADDR));
#endif
	qspi_write32(priv->flags, &regs->lut[lut_base + 1],
		     OPRND0(8) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) |
		     OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) |
		     INSTR1(LUT_READ));
	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);

	/* Read Status */
	lut_base = SEQID_RDSR * 4;
	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_RDSR) |
		PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
		PAD1(LUT_PAD1) | INSTR1(LUT_READ));
	qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);

	/* Erase a sector */
	lut_base = SEQID_SE * 4;
#ifdef CONFIG_SPI_FLASH_BAR
	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_SE) |
		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
#else
	if (FSL_QSPI_FLASH_SIZE  <= SZ_16M)
		qspi_write32(priv->flags, &regs->lut[lut_base],
			     OPRND0(QSPI_CMD_SE) | PAD0(LUT_PAD1) |
			     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
			     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
	else
		qspi_write32(priv->flags, &regs->lut[lut_base],
			     OPRND0(QSPI_CMD_SE_4B) | PAD0(LUT_PAD1) |
			     INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
			     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
#endif
	qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);

	/* Erase the whole chip */
	lut_base = SEQID_CHIP_ERASE * 4;
	qspi_write32(priv->flags, &regs->lut[lut_base],
		     OPRND0(QSPI_CMD_CHIP_ERASE) |
		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD));
	qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);

	/* Page Program */
	lut_base = SEQID_PP * 4;
#ifdef CONFIG_SPI_FLASH_BAR
	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_PP) |
		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
#else
	if (FSL_QSPI_FLASH_SIZE  <= SZ_16M)
		qspi_write32(priv->flags, &regs->lut[lut_base],
			     OPRND0(QSPI_CMD_PP) | PAD0(LUT_PAD1) |
			     INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
			     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
	else
		qspi_write32(priv->flags, &regs->lut[lut_base],
			     OPRND0(QSPI_CMD_PP_4B) | PAD0(LUT_PAD1) |
			     INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
			     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
#endif
#ifdef CONFIG_MX6SX
	/*
	 * To MX6SX, OPRND0(TX_BUFFER_SIZE) can not work correctly.
	 * So, Use IDATSZ in IPCR to determine the size and here set 0.
	 */
	qspi_write32(priv->flags, &regs->lut[lut_base + 1], OPRND0(0) |
		     PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
#else
	qspi_write32(priv->flags, &regs->lut[lut_base + 1],
		     OPRND0(TX_BUFFER_SIZE) |
		     PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
#endif
	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);

	/* READ ID */
	lut_base = SEQID_RDID * 4;
	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_RDID) |
		PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(8) |
		PAD1(LUT_PAD1) | INSTR1(LUT_READ));
	qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
	qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);

	/* SUB SECTOR 4K ERASE */
	lut_base = SEQID_BE_4K * 4;
	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_BE_4K) |
		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
		     PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));

#ifdef CONFIG_SPI_FLASH_BAR
	/*
	 * BRRD BRWR RDEAR WREAR are all supported, because it is hard to
	 * dynamically check whether to set BRRD BRWR or RDEAR WREAR during
	 * initialization.
	 */
	lut_base = SEQID_BRRD * 4;
	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_BRRD) |
		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
		     PAD1(LUT_PAD1) | INSTR1(LUT_READ));

	lut_base = SEQID_BRWR * 4;
	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_BRWR) |
		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
		     PAD1(LUT_PAD1) | INSTR1(LUT_WRITE));

	lut_base = SEQID_RDEAR * 4;
	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_RDEAR) |
		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
		     PAD1(LUT_PAD1) | INSTR1(LUT_READ));

	lut_base = SEQID_WREAR * 4;
	qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_WREAR) |
		     PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
		     PAD1(LUT_PAD1) | INSTR1(LUT_WRITE));
#endif
	/* Lock the LUT */
	qspi_write32(priv->flags, &regs->lutkey, LUT_KEY_VALUE);
	qspi_write32(priv->flags, &regs->lckcr, QSPI_LCKCR_LOCK);
}
Example #3
0
int
saveargs_has_args(uint8_t *ins, size_t size, uint_t argc, int start_index)
{
	int		i, j;
	uint32_t	n;
	uint8_t		found = 0;
	ssize_t		sz = 0;
	dis_handle_t	*dhp = NULL;
	int		ret = SAVEARGS_NO_ARGS;

	argc = MIN((start_index + argc), INSTR_ARRAY_SIZE);

	if ((dhp = dis_handle_create(DIS_X86_SIZE64, NULL, do_lookup,
	    do_read)) == NULL)
		return (SAVEARGS_NO_ARGS);

	if (!has_saved_fp(dhp, ins, size)) {
		dis_handle_destroy(dhp);
		return (SAVEARGS_NO_ARGS);
	}

	/*
	 * For each possible style of argument saving, walk the insn stream as
	 * we've been given it, and set bit N in 'found' if we find the
	 * instruction saving the Nth argument.
	 */

	/*
	 * Compare against regular implementation
	 */
	found = 0;
	for (i = 0; i < size; i += sz) {
		sz = instr_size(dhp, ins, i, size);

		if (sz < 1)
			break;
		else if (sz != 4)
			continue;

		n = INSTR4(ins, i);

		for (j = 0; j < argc; j++) {
			if (n == save_instr[j]) {
				found |= (1 << j);

				if (found == ((1 << argc) - 1)) {
					ret = start_index ?
					    SAVEARGS_STRUCT_ARGS :
					    SAVEARGS_TRAD_ARGS;
					goto done;
				}

				break;
			}
		}
	}

	/*
	 * Compare against GCC push-based implementation
	 */
	found = 0;
	for (i = 0; i < size; i += sz) {
		if ((sz = instr_size(dhp, ins, i, size)) < 1)
			break;

		for (j = start_index; j < argc; j++) {
			if (sz == 2) /* Two byte */
				n = INSTR2(ins, i);
			else if (sz == 1)
				n = INSTR1(ins, i);
			else
				continue;

			if (n == save_instr_push[j]) {
				found |= (1 << (j - start_index));

				if (found ==
				    ((1 << (argc - start_index)) - 1)) {
					ret = SAVEARGS_TRAD_ARGS;
					goto done;
				}

				break;
			}
		}
	}

	/*
	 * Look for a GCC-style returned structure.
	 */
	found = 0;
	if (start_index != 0) {
		for (i = 0; i < size; i += sz) {
			sz = instr_size(dhp, ins, i, size);

			if (sz < 1)
				break;
			else if (sz != 4)
				continue;

			n = INSTR4(ins, i);

			/* argc is inclusive of start_index, allow for that */
			for (j = 0; j < (argc - start_index); j++) {
				if (n == save_instr_sr[j]) {
					found |= (1 << j);

					if (found ==
					    ((1 << (argc - start_index)) - 1)) {
						ret = SAVEARGS_TRAD_ARGS;
						goto done;
					}

					break;
				}
			}
		}
	}

done:
	dis_handle_destroy(dhp);
	return (ret);
}
Example #4
0
PRIVATE void debug_dump_instr(byte *c, int ip) {
  printf("%p %04d ", current_thread, ip);

  switch (c[ip]) {
    case OP_AT:			INSTR1("AT      ");
    case OP_ATPUT:		INSTR1("ATPUT   ");
    case OP_MOV_A_LOCL:		INSTR2("A<-LOCL ");
    case OP_MOV_A_GLOB:		INSTR1("A<-GLOB ");
    case OP_MOV_A_SLOT:		INSTR1("A<-SLOT ");
    case OP_MOV_A_LITL:		INSTR1("A<-LITL ");
    case OP_MOV_A_SELF:		INSTR0("A<-SELF ");
    case OP_MOV_A_FRAM:		INSTR0("A<-FRAM ");
    case OP_MOV_LOCL_A:		INSTR2("LOCL<-A ");
    case OP_MOV_GLOB_A:		INSTR1("GLOB<-A ");
    case OP_MOV_SLOT_A:		INSTR1("SLOT<-A ");
    case OP_MOV_FRAM_A:		INSTR0("FRAM<-A ");
    case OP_PUSH:		INSTR0("PUSH    ");
    case OP_POP:		INSTR0("POP     ");
    case OP_SWAP:		INSTR0("SWAP    ");
    case OP_VECTOR:		INSTR1("VECTOR  ");
    case OP_ENTER_SCOPE:	INSTR1("ENTER   ");
    case OP_LEAVE_SCOPE:	INSTR0("LEAVE   ");
    case OP_MAKE_VECTOR:	INSTR1("MKVECT  ");
    /*    case OP_FRAME:		INSTR16("FRAME   "); */
    case OP_CLOSURE:		INSTR0("CLOSURE ");
    case OP_METHOD_CLOSURE:	INSTR1("METHCLS ");
    case OP_RET:		INSTR0("RETURN  ");
    case OP_CALL:		INSTR1("CALL    ");
    case OP_CALL_AS:		INSTR1("CALLAS  ");
    case OP_APPLY:		INSTR0("APPLY   ");
    case OP_JUMP:		INSTR16("J       ");
    case OP_JUMP_TRUE:		INSTR16("JT      ");
    case OP_JUMP_FALSE:		INSTR16("JF      ");
    case OP_NOT:		INSTR0("NOT     ");
    case OP_EQ:			INSTR0("EQ      ");
    case OP_NE:			INSTR0("NE      ");
    case OP_GT:			INSTR0("GT      ");
    case OP_LT:			INSTR0("LT      ");
    case OP_GE:			INSTR0("GE      ");
    case OP_LE:			INSTR0("LE      ");
    case OP_NEG:		INSTR0("NEG     ");
    case OP_BNOT:		INSTR0("BNOT    ");
    case OP_BOR:		INSTR0("BOR     ");
    case OP_BAND:		INSTR0("BAND    ");
    case OP_PLUS:		INSTR0("PLUS    ");
    case OP_MINUS:		INSTR0("MINUS   ");
    case OP_STAR:		INSTR0("STAR    ");
    case OP_SLASH:		INSTR0("SLASH   ");
    case OP_PERCENT:		INSTR0("PERCENT ");
    default:
      printf("Unknown instr: %d", c[ip]); break;
  }
  printf("\n");
}
Example #5
0
static void qspi_set_lut(struct fsl_qspi *qspi)
{
	struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
	u32 lut_base;

	/* Unlock the LUT */
	qspi_write32(&regs->lutkey, LUT_KEY_VALUE);
	qspi_write32(&regs->lckcr, QSPI_LCKCR_UNLOCK);

	/* Write Enable */
	lut_base = SEQID_WREN * 4;
	qspi_write32(&regs->lut[lut_base], OPRND0(OPCODE_WREN) |
		PAD0(LUT_PAD1) | INSTR0(LUT_CMD));
	qspi_write32(&regs->lut[lut_base + 1], 0);
	qspi_write32(&regs->lut[lut_base + 2], 0);
	qspi_write32(&regs->lut[lut_base + 3], 0);

	/* Fast Read */
	lut_base = SEQID_FAST_READ * 4;
	if (FSL_QSPI_FLASH_SIZE  <= SZ_16M)
		qspi_write32(&regs->lut[lut_base], OPRND0(OPCODE_FAST_READ) |
			PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
			PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
	else
		qspi_write32(&regs->lut[lut_base], OPRND0(OPCODE_FAST_READ_4B) |
			PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
			PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
	qspi_write32(&regs->lut[lut_base + 1], OPRND0(8) | PAD0(LUT_PAD1) |
		INSTR0(LUT_DUMMY) | OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) |
		INSTR1(LUT_READ));
	qspi_write32(&regs->lut[lut_base + 2], 0);
	qspi_write32(&regs->lut[lut_base + 3], 0);

	/* Read Status */
	lut_base = SEQID_RDSR * 4;
	qspi_write32(&regs->lut[lut_base], OPRND0(OPCODE_RDSR) |
		PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
		PAD1(LUT_PAD1) | INSTR1(LUT_READ));
	qspi_write32(&regs->lut[lut_base + 1], 0);
	qspi_write32(&regs->lut[lut_base + 2], 0);
	qspi_write32(&regs->lut[lut_base + 3], 0);

	/* Erase a sector */
	lut_base = SEQID_SE * 4;
	if (FSL_QSPI_FLASH_SIZE  <= SZ_16M)
		qspi_write32(&regs->lut[lut_base], OPRND0(OPCODE_SE) |
			PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
			PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
	else
		qspi_write32(&regs->lut[lut_base], OPRND0(OPCODE_SE_4B) |
			PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
			PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
	qspi_write32(&regs->lut[lut_base + 1], 0);
	qspi_write32(&regs->lut[lut_base + 2], 0);
	qspi_write32(&regs->lut[lut_base + 3], 0);

	/* Erase the whole chip */
	lut_base = SEQID_CHIP_ERASE * 4;
	qspi_write32(&regs->lut[lut_base], OPRND0(OPCODE_CHIP_ERASE) |
		PAD0(LUT_PAD1) | INSTR0(LUT_CMD));
	qspi_write32(&regs->lut[lut_base + 1], 0);
	qspi_write32(&regs->lut[lut_base + 2], 0);
	qspi_write32(&regs->lut[lut_base + 3], 0);

	/* Page Program */
	lut_base = SEQID_PP * 4;
	if (FSL_QSPI_FLASH_SIZE  <= SZ_16M)
		qspi_write32(&regs->lut[lut_base], OPRND0(OPCODE_PP) |
			PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
			PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
	else
		qspi_write32(&regs->lut[lut_base], OPRND0(OPCODE_PP_4B) |
			PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
			PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
	qspi_write32(&regs->lut[lut_base + 1], OPRND0(TX_BUFFER_SIZE) |
		PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
	qspi_write32(&regs->lut[lut_base + 2], 0);
	qspi_write32(&regs->lut[lut_base + 3], 0);

	/* READ ID */
	lut_base = SEQID_RDID * 4;
	qspi_write32(&regs->lut[lut_base], OPRND0(OPCODE_RDID) |
		PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(8) |
		PAD1(LUT_PAD1) | INSTR1(LUT_READ));
	qspi_write32(&regs->lut[lut_base + 1], 0);
	qspi_write32(&regs->lut[lut_base + 2], 0);
	qspi_write32(&regs->lut[lut_base + 3], 0);

	/* Lock the LUT */
	qspi_write32(&regs->lutkey, LUT_KEY_VALUE);
	qspi_write32(&regs->lckcr, QSPI_LCKCR_LOCK);
}