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, ®s->lutkey, LUT_KEY_VALUE); qspi_write32(priv->flags, ®s->lckcr, QSPI_LCKCR_UNLOCK); /* Write Enable */ lut_base = SEQID_WREN * 4; qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_WREN) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD)); qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* Fast Read */ lut_base = SEQID_FAST_READ * 4; #ifdef CONFIG_SPI_FLASH_BAR qspi_write32(priv->flags, ®s->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, ®s->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, ®s->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, ®s->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, ®s->lut[lut_base + 2], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* Read Status */ lut_base = SEQID_RDSR * 4; qspi_write32(priv->flags, ®s->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, ®s->lut[lut_base + 1], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* Erase a sector */ lut_base = SEQID_SE * 4; #ifdef CONFIG_SPI_FLASH_BAR qspi_write32(priv->flags, ®s->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, ®s->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, ®s->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, ®s->lut[lut_base + 1], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* Erase the whole chip */ lut_base = SEQID_CHIP_ERASE * 4; qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_CHIP_ERASE) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD)); qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* Page Program */ lut_base = SEQID_PP * 4; #ifdef CONFIG_SPI_FLASH_BAR qspi_write32(priv->flags, ®s->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, ®s->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, ®s->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, ®s->lut[lut_base + 1], OPRND0(0) | PAD0(LUT_PAD1) | INSTR0(LUT_WRITE)); #else qspi_write32(priv->flags, ®s->lut[lut_base + 1], OPRND0(TX_BUFFER_SIZE) | PAD0(LUT_PAD1) | INSTR0(LUT_WRITE)); #endif qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* READ ID */ lut_base = SEQID_RDID * 4; qspi_write32(priv->flags, ®s->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, ®s->lut[lut_base + 1], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* SUB SECTOR 4K ERASE */ lut_base = SEQID_BE_4K * 4; qspi_write32(priv->flags, ®s->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, ®s->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, ®s->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, ®s->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, ®s->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, ®s->lutkey, LUT_KEY_VALUE); qspi_write32(priv->flags, ®s->lckcr, QSPI_LCKCR_LOCK); }
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); }
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"); }
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(®s->lutkey, LUT_KEY_VALUE); qspi_write32(®s->lckcr, QSPI_LCKCR_UNLOCK); /* Write Enable */ lut_base = SEQID_WREN * 4; qspi_write32(®s->lut[lut_base], OPRND0(OPCODE_WREN) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD)); qspi_write32(®s->lut[lut_base + 1], 0); qspi_write32(®s->lut[lut_base + 2], 0); qspi_write32(®s->lut[lut_base + 3], 0); /* Fast Read */ lut_base = SEQID_FAST_READ * 4; if (FSL_QSPI_FLASH_SIZE <= SZ_16M) qspi_write32(®s->lut[lut_base], OPRND0(OPCODE_FAST_READ) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); else qspi_write32(®s->lut[lut_base], OPRND0(OPCODE_FAST_READ_4B) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); qspi_write32(®s->lut[lut_base + 1], OPRND0(8) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) | OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) | INSTR1(LUT_READ)); qspi_write32(®s->lut[lut_base + 2], 0); qspi_write32(®s->lut[lut_base + 3], 0); /* Read Status */ lut_base = SEQID_RDSR * 4; qspi_write32(®s->lut[lut_base], OPRND0(OPCODE_RDSR) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | PAD1(LUT_PAD1) | INSTR1(LUT_READ)); qspi_write32(®s->lut[lut_base + 1], 0); qspi_write32(®s->lut[lut_base + 2], 0); qspi_write32(®s->lut[lut_base + 3], 0); /* Erase a sector */ lut_base = SEQID_SE * 4; if (FSL_QSPI_FLASH_SIZE <= SZ_16M) qspi_write32(®s->lut[lut_base], OPRND0(OPCODE_SE) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); else qspi_write32(®s->lut[lut_base], OPRND0(OPCODE_SE_4B) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); qspi_write32(®s->lut[lut_base + 1], 0); qspi_write32(®s->lut[lut_base + 2], 0); qspi_write32(®s->lut[lut_base + 3], 0); /* Erase the whole chip */ lut_base = SEQID_CHIP_ERASE * 4; qspi_write32(®s->lut[lut_base], OPRND0(OPCODE_CHIP_ERASE) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD)); qspi_write32(®s->lut[lut_base + 1], 0); qspi_write32(®s->lut[lut_base + 2], 0); qspi_write32(®s->lut[lut_base + 3], 0); /* Page Program */ lut_base = SEQID_PP * 4; if (FSL_QSPI_FLASH_SIZE <= SZ_16M) qspi_write32(®s->lut[lut_base], OPRND0(OPCODE_PP) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); else qspi_write32(®s->lut[lut_base], OPRND0(OPCODE_PP_4B) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); qspi_write32(®s->lut[lut_base + 1], OPRND0(TX_BUFFER_SIZE) | PAD0(LUT_PAD1) | INSTR0(LUT_WRITE)); qspi_write32(®s->lut[lut_base + 2], 0); qspi_write32(®s->lut[lut_base + 3], 0); /* READ ID */ lut_base = SEQID_RDID * 4; qspi_write32(®s->lut[lut_base], OPRND0(OPCODE_RDID) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(8) | PAD1(LUT_PAD1) | INSTR1(LUT_READ)); qspi_write32(®s->lut[lut_base + 1], 0); qspi_write32(®s->lut[lut_base + 2], 0); qspi_write32(®s->lut[lut_base + 3], 0); /* Lock the LUT */ qspi_write32(®s->lutkey, LUT_KEY_VALUE); qspi_write32(®s->lckcr, QSPI_LCKCR_LOCK); }