Lines Matching +full:programmable +full:- +full:security

1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
5 * Copyright (c) 2012-2013, SRI International
10 * (FA8750-10-C-0237) ("CTSRD"), as part of the DARPA CRASH research
21 * 3. Neither the name of the author nor the names of any co-contributors
69 ofs &= ~(sc->sc_width - 1);
70 switch (sc->sc_width) {
72 val = bus_space_read_1(sc->sc_tag, sc->sc_handle, ofs);
75 val = bus_space_read_2(sc->sc_tag, sc->sc_handle, ofs);
78 val = bus_space_read_4(sc->sc_tag, sc->sc_handle, ofs);
93 ofs &= ~(sc->sc_width - 1);
94 switch (sc->sc_width) {
96 val = bus_space_read_1(sc->sc_tag, sc->sc_handle, ofs);
99 sval = bus_space_read_2(sc->sc_tag, sc->sc_handle, ofs);
107 val = bus_space_read_4(sc->sc_tag, sc->sc_handle, ofs);
123 ofs &= ~(sc->sc_width - 1);
124 switch (sc->sc_width) {
126 bus_space_write_1(sc->sc_tag, sc->sc_handle, ofs, val);
130 bus_space_write_2(sc->sc_tag, sc->sc_handle, ofs, val);
132 bus_space_write_2(sc->sc_tag, sc->sc_handle, ofs, htole16(val));
138 bus_space_write_4(sc->sc_tag, sc->sc_handle, ofs, val);
140 bus_space_write_4(sc->sc_tag, sc->sc_handle, ofs, htole32(val));
162 cfi_write(sc, CFI_QRY_CMD_ADDR * sc->sc_width, CFI_QRY_CMD_DATA);
163 val = cfi_read(sc, ofs * sc->sc_width);
203 sc->sc_dev = dev;
205 sc->sc_rid = 0;
206 sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid,
208 if (sc->sc_res == NULL)
211 sc->sc_tag = rman_get_bustag(sc->sc_res);
212 sc->sc_handle = rman_get_bushandle(sc->sc_res);
214 if (sc->sc_width == 0) {
215 sc->sc_width = 1;
216 while (sc->sc_width <= 4) {
219 sc->sc_width <<= 1;
225 if (sc->sc_width > 4) {
241 sc->sc_cmdset = vend;
264 sc->sc_size = 1U << cfi_read_qry(sc, CFI_QRY_SIZE);
266 /* Sanity-check the I/F */
271 * Adding 1 to iface will give us a bit-wise "switch"
277 error = (iface & sc->sc_width) ? 0 : EINVAL;
281 device_set_descf(dev, "%s - %s", vend_str, cfi_fmtsize(sc->sc_size));
284 bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res);
301 sc->sc_dev = dev;
303 sc->sc_rid = 0;
304 sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid,
310 if (sc->sc_res == NULL)
313 sc->sc_tag = rman_get_bustag(sc->sc_res);
314 sc->sc_handle = rman_get_bushandle(sc->sc_res);
316 /* Get time-out values for erase, write, and buffer write. */
337 sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE] = SBT_1MS * (1ULL << ttoexp);
338 sc->sc_max_timeouts[CFI_TIMEOUT_ERASE] =
339 sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE] * (1ULL << mtoexp);
361 sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE] = SBT_1US * (1ULL << ttoexp);
362 sc->sc_max_timeouts[CFI_TIMEOUT_WRITE] =
363 sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE] * (1ULL << mtoexp);
367 /* Don't check for 0, it means not-supported. */
377 sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] =
379 sc->sc_max_timeouts[CFI_TIMEOUT_BUFWRITE] =
380 sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] *
384 if (sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] != 0)
385 sc->sc_maxbuf = 1 << (cfi_read_qry(sc, CFI_QRY_MAXBUF) |
388 sc->sc_maxbuf = 0;
391 sc->sc_regions = cfi_read_qry(sc, CFI_QRY_NREGIONS);
392 sc->sc_region = malloc(sc->sc_regions * sizeof(struct cfi_region),
394 for (r = 0; r < sc->sc_regions; r++) {
397 sc->sc_region[r].r_blocks = blocks + 1;
401 sc->sc_region[r].r_blksz = (blksz == 0) ? 128 :
410 for (r = 0; r < sc->sc_regions; r++) {
411 printf("%ux%s%s", sc->sc_region[r].r_blocks,
412 cfi_fmtsize(sc->sc_region[r].r_blksz),
413 (r == sc->sc_regions - 1) ? "]\n" : ",");
417 if (sc->sc_cmdset == CFI_VEND_AMD_ECS ||
418 sc->sc_cmdset == CFI_VEND_AMD_SCS) {
420 sc->sc_manid = cfi_read(sc, 0);
421 sc->sc_devid = cfi_read(sc, 2);
423 sc->sc_manid, sc->sc_devid);
428 sc->sc_nod = make_dev(&cfi_cdevsw, u, UID_ROOT, GID_WHEEL, 0600,
430 sc->sc_nod->si_drv1 = sc;
441 device_get_nameunit(dev)) < (sizeof(name) - 1) &&
443 (sizeof(value) - 1))
460 ctx = device_get_sysctl_ctx(sc->sc_dev);
461 children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
465 CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_ERASE],
469 CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_ERASE], 0,
473 CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_WRITE], 0,
477 CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_WRITE], 0,
479 if (sc->sc_maxbuf > 0) {
482 CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_BUFWRITE], 0,
487 CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_BUFWRITE], 0,
500 destroy_dev(sc->sc_nod);
501 free(sc->sc_region, M_TEMP);
502 bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res);
514 for (i = 0; i < sz; i += sc->sc_width) {
516 switch (sc->sc_width) {
555 switch (sc->sc_cmdset) {
584 now > start + sc->sc_typical_timeouts[cmd]) {
587 sc->sc_tto_counts[cmd]++;
589 device_printf(sc->sc_dev,
593 if (now > start + sc->sc_max_timeouts[cmd]) {
594 sc->sc_mto_counts[cmd]++;
596 device_printf(sc->sc_dev,
626 switch (sc->sc_cmdset) {
629 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_LBS);
630 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_UB);
631 cfi_write(sc, sc->sc_wrofs, CFI_BCS_READ_ARRAY);
636 for (i = 0; i < sc->sc_wrbufsz; i++)
637 if ((sc->sc_wrbuf[i] & sc->sc_wrbufcpy[i]) != sc->sc_wrbuf[i]) {
646 switch (sc->sc_cmdset) {
649 cfi_write(sc, sc->sc_wrofs, CFI_BCS_BLOCK_ERASE);
650 cfi_write(sc, sc->sc_wrofs, CFI_BCS_CONFIRM);
655 minsz = sc->sc_region[0].r_blksz;
656 for (i = 1; i < sc->sc_regions; i++) {
657 if (sc->sc_region[i].r_blksz < minsz)
658 minsz = sc->sc_region[i].r_blksz;
660 cfi_amd_write(sc, sc->sc_wrofs, AMD_ADDR_START,
662 cfi_amd_write(sc, sc->sc_wrofs,
663 sc->sc_wrofs >> (ffs(minsz) - 1),
666 if (cfi_check_erase(sc, sc->sc_wrofs,
667 sc->sc_wrbufsz))
682 error = cfi_wait_ready(sc, sc->sc_wrofs, start,
690 ptr.x8 = sc->sc_wrbuf;
691 cpyprt.x8 = sc->sc_wrbufcpy;
692 if (sc->sc_maxbuf > sc->sc_width) {
693 switch (sc->sc_cmdset) {
696 for (i = 0; i < sc->sc_wrbufsz; i += wlen) {
697 wlen = MIN(sc->sc_maxbuf, sc->sc_wrbufsz - i);
703 cfi_write(sc, sc->sc_wrofs + i,
705 if (sbinuptime() > start + sc->sc_max_timeouts[CFI_TIMEOUT_BUFWRITE]) {
709 st = cfi_read(sc, sc->sc_wrofs + i);
712 cfi_write(sc, sc->sc_wrofs + i,
713 (wlen / sc->sc_width) - 1);
714 switch (sc->sc_width) {
716 bus_space_write_region_1(sc->sc_tag,
717 sc->sc_handle, sc->sc_wrofs + i,
721 bus_space_write_region_2(sc->sc_tag,
722 sc->sc_handle, sc->sc_wrofs + i,
726 bus_space_write_region_4(sc->sc_tag,
727 sc->sc_handle, sc->sc_wrofs + i,
732 cfi_write(sc, sc->sc_wrofs + i,
737 error = cfi_wait_ready(sc, sc->sc_wrofs + i,
750 for (i = 0; i < sc->sc_wrbufsz; i += sc->sc_width) {
753 switch (sc->sc_width) {
771 * actual write happens back-to-back without any
777 switch (sc->sc_cmdset) {
780 cfi_write(sc, sc->sc_wrofs + i, CFI_BCS_PROGRAM);
787 switch (sc->sc_width) {
789 bus_space_write_1(sc->sc_tag, sc->sc_handle,
790 sc->sc_wrofs + i, *(ptr.x8 + i));
793 bus_space_write_2(sc->sc_tag, sc->sc_handle,
794 sc->sc_wrofs + i, *(ptr.x16 + i / 2));
797 bus_space_write_4(sc->sc_tag, sc->sc_handle,
798 sc->sc_wrofs + i, *(ptr.x32 + i / 4));
804 if (sc->sc_cmdset == CFI_VEND_AMD_ECS ||
805 sc->sc_cmdset == CFI_VEND_AMD_SCS) {
807 switch (sc->sc_width) {
819 if (cfi_read(sc, sc->sc_wrofs + i) == val)
830 error = cfi_wait_ready(sc, sc->sc_wrofs, start,
843 switch (sc->sc_cmdset) {
846 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_LBS);
847 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_LB);
848 cfi_write(sc, sc->sc_wrofs, CFI_BCS_READ_ARRAY);
858 * The memory includes a 128-bit Protection Register that can be
859 * used for security. There are two 64-bit segments; one is programmed
860 * at the factory with a unique 64-bit number which is immutable.
862 * The User/OEM segment is One Time Programmable (OTP). It can also
870 uint16_t v = bus_space_read_2(sc->sc_tag, sc->sc_handle, off<<1);
878 bus_space_write_2(sc->sc_tag, sc->sc_handle, off<<1, v);
883 * Read the factory-defined 64-bit segment of the PR.
888 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
890 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));
902 * Read the User/OEM 64-bit segment of the PR.
907 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
909 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));
921 * Write the User/OEM 64-bit segment of the PR.
933 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
935 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));
938 for (i = 7; i >= 4; i--, id >>= 16) {
952 device_printf(sc->sc_dev, "%s: OEM PR not set, "
964 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
966 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));
976 * user-settable segment of the Protection Register.
987 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
989 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));
993 device_printf(sc->sc_dev, "set PLR\n");
1004 device_printf(sc->sc_dev, "%s: PLR not set, "