⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hifn7751.c

📁 linux下基于加密芯片的加密设备
💻 C
📖 第 1 页 / 共 5 页
字号:
	for (i = 0; i < sizeof(data); i++)		data[i] = dataexpect[i] = 0xaa;	if (hifn_writeramaddr(sc, 0, data))		return (-1);	if (hifn_readramaddr(sc, 0, data))		return (-1);	if (bcmp(data, dataexpect, sizeof(data)) != 0) {		sc->sc_drammodel = 1;		return (0);	}	return (0);}#define	HIFN_SRAM_MAX		(32 << 20)#define	HIFN_SRAM_STEP_SIZE	16384#define	HIFN_SRAM_GRANULARITY	(HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)static inthifn_sramsize(struct hifn_softc *sc){	u_int32_t a;	u_int8_t data[8];	u_int8_t dataexpect[sizeof(data)];	int32_t i;	for (i = 0; i < sizeof(data); i++)		data[i] = dataexpect[i] = i ^ 0x5a;	for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {		a = i * HIFN_SRAM_STEP_SIZE;		bcopy(&i, data, sizeof(i));		hifn_writeramaddr(sc, a, data);	}	for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {		a = i * HIFN_SRAM_STEP_SIZE;		bcopy(&i, dataexpect, sizeof(i));		if (hifn_readramaddr(sc, a, data) < 0)			return (0);		if (bcmp(data, dataexpect, sizeof(data)) != 0)			return (0);		sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;	}	return (0);}/* * XXX For dram boards, one should really try all of the * HIFN_PUCNFG_DSZ_*'s.  This just assumes that PUCNFG * is already set up correctly. */static inthifn_dramsize(struct hifn_softc *sc){	u_int32_t cnfg;	if (sc->sc_flags & HIFN_IS_7956) {		/*		 * 7955/7956 have a fixed internal ram of only 32K.		 */		sc->sc_ramsize = 32768;	} else {		cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &		    HIFN_PUCNFG_DRAMMASK;		sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);	}	return (0);}static voidhifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp){	struct hifn_dma *dma = sc->sc_dma;	DPRINTF("%s()\n", __FUNCTION__);	if (dma->cmdi == HIFN_D_CMD_RSIZE) {		dma->cmdi = 0;		dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);		dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);		HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);	}	*cmdp = dma->cmdi++;	dma->cmdk = dma->cmdi;	if (dma->srci == HIFN_D_SRC_RSIZE) {		dma->srci = 0;		dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);		dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);		HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);	}	*srcp = dma->srci++;	dma->srck = dma->srci;	if (dma->dsti == HIFN_D_DST_RSIZE) {		dma->dsti = 0;		dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);		dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);		HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);	}	*dstp = dma->dsti++;	dma->dstk = dma->dsti;	if (dma->resi == HIFN_D_RES_RSIZE) {		dma->resi = 0;		dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);		dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);		HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);	}	*resp = dma->resi++;	dma->resk = dma->resi;}static inthifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data){	struct hifn_dma *dma = sc->sc_dma;	hifn_base_command_t wc;	const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;	int r, cmdi, resi, srci, dsti;	DPRINTF("%s()\n", __FUNCTION__);	wc.masks = htole16(3 << 13);	wc.session_num = htole16(addr >> 14);	wc.total_source_count = htole16(8);	wc.total_dest_count = htole16(addr & 0x3fff);	hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);	WRITE_REG_1(sc, HIFN_1_DMA_CSR,	    HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |	    HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);	/* build write command */	bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);	*(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;	bcopy(data, &dma->test_src, sizeof(dma->test_src));	dma->srcr[srci].p = htole32(sc->sc_dma_physaddr	    + offsetof(struct hifn_dma, test_src));	dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr	    + offsetof(struct hifn_dma, test_dst));	dma->cmdr[cmdi].l = htole32(16 | masks);	dma->srcr[srci].l = htole32(8 | masks);	dma->dstr[dsti].l = htole32(4 | masks);	dma->resr[resi].l = htole32(4 | masks);	for (r = 10000; r >= 0; r--) {		DELAY(10);		if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)			break;	}	if (r == 0) {		device_printf(sc->sc_dev, "writeramaddr -- "		    "result[%d](addr %d) still valid\n", resi, addr);		r = -1;		return (-1);	} else		r = 0;	WRITE_REG_1(sc, HIFN_1_DMA_CSR,	    HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |	    HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);	return (r);}static inthifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data){	struct hifn_dma *dma = sc->sc_dma;	hifn_base_command_t rc;	const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;	int r, cmdi, srci, dsti, resi;	DPRINTF("%s()\n", __FUNCTION__);	rc.masks = htole16(2 << 13);	rc.session_num = htole16(addr >> 14);	rc.total_source_count = htole16(addr & 0x3fff);	rc.total_dest_count = htole16(8);	hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);	WRITE_REG_1(sc, HIFN_1_DMA_CSR,	    HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |	    HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);	bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);	*(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;	dma->srcr[srci].p = htole32(sc->sc_dma_physaddr +	    offsetof(struct hifn_dma, test_src));	dma->test_src = 0;	dma->dstr[dsti].p =  htole32(sc->sc_dma_physaddr +	    offsetof(struct hifn_dma, test_dst));	dma->test_dst = 0;	dma->cmdr[cmdi].l = htole32(8 | masks);	dma->srcr[srci].l = htole32(8 | masks);	dma->dstr[dsti].l = htole32(8 | masks);	dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);	for (r = 10000; r >= 0; r--) {		DELAY(10);		if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)			break;	}	if (r == 0) {		device_printf(sc->sc_dev, "readramaddr -- "		    "result[%d](addr %d) still valid\n", resi, addr);		r = -1;	} else {		r = 0;		bcopy(&dma->test_dst, data, sizeof(dma->test_dst));	}	WRITE_REG_1(sc, HIFN_1_DMA_CSR,	    HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |	    HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);	return (r);}/* * Initialize the descriptor rings. */static void hifn_init_dma(struct hifn_softc *sc){	struct hifn_dma *dma = sc->sc_dma;	int i;	DPRINTF("%s()\n", __FUNCTION__);	hifn_set_retry(sc);	/* initialize static pointer values */	for (i = 0; i < HIFN_D_CMD_RSIZE; i++)		dma->cmdr[i].p = htole32(sc->sc_dma_physaddr +		    offsetof(struct hifn_dma, command_bufs[i][0]));	for (i = 0; i < HIFN_D_RES_RSIZE; i++)		dma->resr[i].p = htole32(sc->sc_dma_physaddr +		    offsetof(struct hifn_dma, result_bufs[i][0]));	dma->cmdr[HIFN_D_CMD_RSIZE].p =	    htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));	dma->srcr[HIFN_D_SRC_RSIZE].p =	    htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));	dma->dstr[HIFN_D_DST_RSIZE].p =	    htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));	dma->resr[HIFN_D_RES_RSIZE].p =	    htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));	dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;	dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;	dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;}/* * Writes out the raw command buffer space.  Returns the * command buffer size. */static u_inthifn_write_command(struct hifn_command *cmd, u_int8_t *buf){	u_int8_t *buf_pos;	hifn_base_command_t *base_cmd;	hifn_mac_command_t *mac_cmd;	hifn_crypt_command_t *cry_cmd;	int using_mac, using_crypt, len, ivlen;	u_int32_t dlen, slen;	DPRINTF("%s()\n", __FUNCTION__);	buf_pos = buf;	using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;	using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;	base_cmd = (hifn_base_command_t *)buf_pos;	base_cmd->masks = htole16(cmd->base_masks);	slen = cmd->src_mapsize;	if (cmd->sloplen)		dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);	else		dlen = cmd->dst_mapsize;	base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);	base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);	dlen >>= 16;	slen >>= 16;	base_cmd->session_num = htole16(	    ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |	    ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));	buf_pos += sizeof(hifn_base_command_t);	if (using_mac) {		mac_cmd = (hifn_mac_command_t *)buf_pos;		dlen = cmd->maccrd->crd_len;		mac_cmd->source_count = htole16(dlen & 0xffff);		dlen >>= 16;		mac_cmd->masks = htole16(cmd->mac_masks |		    ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));		mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);		mac_cmd->reserved = 0;		buf_pos += sizeof(hifn_mac_command_t);	}	if (using_crypt) {		cry_cmd = (hifn_crypt_command_t *)buf_pos;		dlen = cmd->enccrd->crd_len;		cry_cmd->source_count = htole16(dlen & 0xffff);		dlen >>= 16;		cry_cmd->masks = htole16(cmd->cry_masks |		    ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));		cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);		cry_cmd->reserved = 0;		buf_pos += sizeof(hifn_crypt_command_t);	}	if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {		bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);		buf_pos += HIFN_MAC_KEY_LENGTH;	}	if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {		switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {		case HIFN_CRYPT_CMD_ALG_3DES:			bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);			buf_pos += HIFN_3DES_KEY_LENGTH;			break;		case HIFN_CRYPT_CMD_ALG_DES:			bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);			buf_pos += HIFN_DES_KEY_LENGTH;			break;		case HIFN_CRYPT_CMD_ALG_RC4:			len = 256;			do {				int clen;				clen = MIN(cmd->cklen, len);				bcopy(cmd->ck, buf_pos, clen);				len -= clen;				buf_pos += clen;			} while (len > 0);			bzero(buf_pos, 4);			buf_pos += 4;			break;		case HIFN_CRYPT_CMD_ALG_AES:			/*			 * AES keys are variable 128, 192 and			 * 256 bits (16, 24 and 32 bytes).			 */			bcopy(cmd->ck, buf_pos, cmd->cklen);			buf_pos += cmd->cklen;			break;		}	}	if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {		switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {		case HIFN_CRYPT_CMD_ALG_AES:			ivlen = HIFN_AES_IV_LENGTH;			break;		default:			ivlen = HIFN_IV_LENGTH;			break;		}		bcopy(cmd->iv, buf_pos, ivlen);		buf_pos += ivlen;	}	if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {		bzero(buf_pos, 8);		buf_pos += 8;	}	return (buf_pos - buf);}static inthifn_dmamap_aligned(struct hifn_operand *op){	int i;	DPRINTF("%s()\n", __FUNCTION__);	for (i = 0; i < op->nsegs; i++) {		if (op->segs[i].ds_addr & 3)			return (0);		if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))			return (0);	}	return (1);}static inthifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd){	struct hifn_dma *dma = sc->sc_dma;	struct hifn_operand *dst = &cmd->dst;	u_int32_t p, l;	int idx, used = 0, i;	DPRINTF("%s()\n", __FUNCTION__);	idx = dma->dsti;	for (i = 0; i < dst->nsegs - 1; i++) {		dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);		dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);		dma->dstr[idx].l |= htole32(HIFN_D_VALID);		HIFN_DSTR_SYNC(sc, idx,		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);		used++;		if (++idx == HIFN_D_DST_RSIZE) {			dma->dstr[idx].l = htole32(HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);			dma->dstr[idx].l |= htole32(HIFN_D_VALID);			HIFN_DSTR_SYNC(sc, idx,			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);			idx = 0;		}	}	if (cmd->sloplen == 0) {		p = dst->segs[i].ds_addr;		l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |		    dst->segs[i].ds_len;	} else {		p = sc->sc_dma_physaddr +		    offsetof(struct hifn_dma, slop[cmd->slopidx]);		l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |		    sizeof(u_int32_t);		if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {			dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);			dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |			    (dst->segs[i].ds_len - cmd->sloplen));			dma->dstr[idx].l |= htole32(HIFN_D_VALID);			HIFN_DSTR_SYNC(sc, idx,			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);			used++;			if (++idx == HIFN_D_DST_RSIZE) {				dma->dstr[idx].l = htole32(HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);				dma->dstr[idx].l |= htole32(HIFN_D_VALID);				HIFN_DSTR_SYNC(sc, idx,				    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);				idx = 0;			}		}	}	dma->dstr[idx].p = htole32(p);	dma->dstr[idx].l = htole32(l);	dma->dstr[idx].l |= htole32(HIFN_D_VALID);	HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);	used++;	if (++idx == HIFN_D_DST_RSIZE) {		dma->dstr[idx].l = htole32(HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);		dma->dstr[idx].l |= htole32(HIFN_D_VALID);		HIFN_DSTR_SYNC(sc, idx,		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);		idx = 0;	}	dma->dsti = idx;	dma->dstu += used;	return (idx);}static inthifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd){	struct hifn_dma *dma = sc->sc_dma;	struct hifn_operand *src = &cmd->src;	int idx, i;	u_int32_t last = 0;	DPRINTF("%s()\n", __FUNCTION__);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -