| 286 | } |
| 287 | |
| 288 | int |
| 289 | aw_sid_get_fuse(enum aw_sid_fuse_id id, uint8_t *out, uint32_t *size) |
| 290 | { |
| 291 | struct aw_sid_softc *sc; |
| 292 | uint32_t val; |
| 293 | int i, j; |
| 294 | |
| 295 | sc = aw_sid_sc; |
| 296 | if (sc == NULL) |
| 297 | return (ENXIO); |
| 298 | |
| 299 | for (i = 0; i < sc->sid_conf->nfuses; i++) |
| 300 | if (id == sc->sid_conf->efuses[i].id) |
| 301 | break; |
| 302 | |
| 303 | if (i == sc->sid_conf->nfuses) |
| 304 | return (ENOENT); |
| 305 | |
| 306 | if (*size != sc->sid_conf->efuses[i].size) { |
| 307 | *size = sc->sid_conf->efuses[i].size; |
| 308 | return (ENOMEM); |
| 309 | } |
| 310 | |
| 311 | if (out == NULL) |
| 312 | return (ENOMEM); |
| 313 | |
| 314 | if (sc->sid_conf->efuses[i].public == false) |
| 315 | mtx_lock(&sc->prctl_mtx); |
| 316 | for (j = 0; j < sc->sid_conf->efuses[i].size; j += 4) { |
| 317 | if (sc->sid_conf->efuses[i].public == false) { |
| 318 | val = SID_PRCTL_OFFSET(sc->sid_conf->efuses[i].offset + j) | |
| 319 | SID_PRCTL_LOCK | |
| 320 | SID_PRCTL_READ; |
| 321 | WR4(sc, SID_PRCTL, val); |
| 322 | /* Read bit will be cleared once read has concluded */ |
| 323 | while (RD4(sc, SID_PRCTL) & SID_PRCTL_READ) |
| 324 | continue; |
| 325 | val = RD4(sc, SID_RDKEY); |
| 326 | } else |
| 327 | val = RD4(sc, sc->sid_conf->efuses[i].base + |
| 328 | sc->sid_conf->efuses[i].offset + j); |
| 329 | out[j] = val & 0xFF; |
| 330 | if (j + 1 < *size) |
| 331 | out[j + 1] = (val & 0xFF00) >> 8; |
| 332 | if (j + 2 < *size) |
| 333 | out[j + 2] = (val & 0xFF0000) >> 16; |
| 334 | if (j + 3 < *size) |
| 335 | out[j + 3] = (val & 0xFF000000) >> 24; |
| 336 | } |
| 337 | if (sc->sid_conf->efuses[i].public == false) |
| 338 | mtx_unlock(&sc->prctl_mtx); |
| 339 | |
| 340 | return (0); |
| 341 | } |
| 342 | |
| 343 | static int |
| 344 | aw_sid_read(device_t dev, uint32_t offset, uint32_t size, uint8_t *buffer) |
no test coverage detected