Index: sys/dev/nvdimm/nvdimm.c =================================================================== --- sys/dev/nvdimm/nvdimm.c +++ sys/dev/nvdimm/nvdimm.c @@ -51,250 +51,126 @@ ACPI_MODULE_NAME("NVDIMM") static devclass_t nvdimm_devclass; -static device_t *nvdimm_devs; -static int nvdimm_devcnt; MALLOC_DEFINE(M_NVDIMM, "nvdimm", "NVDIMM driver memory"); -struct nvdimm_dev * -nvdimm_find_by_handle(nfit_handle_t nv_handle) -{ - device_t dev; - struct nvdimm_dev *res, *nv; - int i; - - res = NULL; - for (i = 0; i < nvdimm_devcnt; i++) { - dev = nvdimm_devs[i]; - if (dev == NULL) - continue; - nv = device_get_softc(dev); - if (nv->nv_handle == nv_handle) { - res = nv; - break; - } - } - return (res); -} - -static int -nvdimm_parse_flush_addr(void *nfitsubtbl, void *arg) -{ - ACPI_NFIT_FLUSH_ADDRESS *nfitflshaddr; - struct nvdimm_dev *nv; - int i; - - nfitflshaddr = nfitsubtbl; - nv = arg; - if (nfitflshaddr->DeviceHandle != nv->nv_handle) - return (0); - - MPASS(nv->nv_flush_addr == NULL && nv->nv_flush_addr_cnt == 0); - nv->nv_flush_addr = malloc(nfitflshaddr->HintCount * sizeof(uint64_t *), - M_NVDIMM, M_WAITOK); - for (i = 0; i < nfitflshaddr->HintCount; i++) - nv->nv_flush_addr[i] = (uint64_t *)nfitflshaddr->HintAddress[i]; - nv->nv_flush_addr_cnt = nfitflshaddr->HintCount; - return (0); -} - -int -nvdimm_iterate_nfit(ACPI_TABLE_NFIT *nfitbl, enum AcpiNfitType type, - int (*cb)(void *, void *), void *arg) +static ACPI_STATUS +nvdimm_find_root_handle_callback(ACPI_HANDLE handle, UINT32 level, void *ctx, + void **st) { - ACPI_NFIT_HEADER *nfithdr; - ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr; - ACPI_NFIT_MEMORY_MAP *nfitmap; - ACPI_NFIT_INTERLEAVE *nfitintrl; - ACPI_NFIT_SMBIOS *nfitsmbios; - ACPI_NFIT_CONTROL_REGION *nfitctlreg; - ACPI_NFIT_DATA_REGION *nfitdtreg; - ACPI_NFIT_FLUSH_ADDRESS *nfitflshaddr; - char *ptr; - int error; + ACPI_HANDLE *out_handle; - error = 0; - for (ptr = (char *)(nfitbl + 1); - ptr < (char *)nfitbl + nfitbl->Header.Length; - ptr += nfithdr->Length) { - nfithdr = (ACPI_NFIT_HEADER *)ptr; - if (nfithdr->Type != type) - continue; - switch (nfithdr->Type) { - case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: - nfitaddr = __containerof(nfithdr, - ACPI_NFIT_SYSTEM_ADDRESS, Header); - error = cb(nfitaddr, arg); - break; - case ACPI_NFIT_TYPE_MEMORY_MAP: - nfitmap = __containerof(nfithdr, - ACPI_NFIT_MEMORY_MAP, Header); - error = cb(nfitmap, arg); - break; - case ACPI_NFIT_TYPE_INTERLEAVE: - nfitintrl = __containerof(nfithdr, - ACPI_NFIT_INTERLEAVE, Header); - error = cb(nfitintrl, arg); - break; - case ACPI_NFIT_TYPE_SMBIOS: - nfitsmbios = __containerof(nfithdr, - ACPI_NFIT_SMBIOS, Header); - error = cb(nfitsmbios, arg); - break; - case ACPI_NFIT_TYPE_CONTROL_REGION: - nfitctlreg = __containerof(nfithdr, - ACPI_NFIT_CONTROL_REGION, Header); - error = cb(nfitctlreg, arg); - break; - case ACPI_NFIT_TYPE_DATA_REGION: - nfitdtreg = __containerof(nfithdr, - ACPI_NFIT_DATA_REGION, Header); - error = cb(nfitdtreg, arg); - break; - case ACPI_NFIT_TYPE_FLUSH_ADDRESS: - nfitflshaddr = __containerof(nfithdr, - ACPI_NFIT_FLUSH_ADDRESS, Header); - error = cb(nfitflshaddr, arg); - break; - case ACPI_NFIT_TYPE_RESERVED: - default: - if (bootverbose) - printf("NFIT subtype %d unknown\n", - nfithdr->Type); - error = 0; - break; - } - if (error != 0) - break; - } - return (error); + if (acpi_MatchHid(handle, "ACPI0012") == ACPI_MATCHHID_NOMATCH) + return_ACPI_STATUS(AE_OK); + out_handle = st; + *out_handle = handle; + return_ACPI_STATUS(AE_CTRL_TERMINATE); } static ACPI_STATUS -nvdimm_walk_dev(ACPI_HANDLE handle, UINT32 level, void *ctx, void **st) +nvdimm_find_root_handle(ACPI_HANDLE *handle) { ACPI_STATUS status; - struct nvdimm_ns_walk_ctx *wctx; + ACPI_HANDLE sb_handle; - wctx = ctx; - status = wctx->func(handle, wctx->arg); + status = AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &sb_handle); + if (!ACPI_SUCCESS(status)) + return_ACPI_STATUS(status); + *handle = NULL; + status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, sb_handle, 1, + nvdimm_find_root_handle_callback, NULL, NULL, handle); + if (ACPI_SUCCESS(status) && *handle == NULL) + status = AE_NOT_FOUND; return_ACPI_STATUS(status); } static ACPI_STATUS -nvdimm_walk_root(ACPI_HANDLE handle, UINT32 level, void *ctx, void **st) +nvdimm_find_handle_callback(ACPI_HANDLE handle, UINT32 level, void *ctx, + void **st) { + ACPI_DEVICE_INFO *info; + ACPI_HANDLE *out_handle; ACPI_STATUS status; + nfit_handle_t adr; - if (!acpi_MatchHid(handle, "ACPI0012")) - return_ACPI_STATUS(AE_OK); - status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, handle, 100, - nvdimm_walk_dev, NULL, ctx, NULL); - if (ACPI_FAILURE(status)) + status = AcpiGetObjectInfo(handle, &info); + if (!ACPI_SUCCESS(status)) return_ACPI_STATUS(status); + adr = (intptr_t)ctx; + if (adr != info->Address) + return_ACPI_STATUS(AE_OK); + out_handle = st; + *out_handle = handle; return_ACPI_STATUS(AE_CTRL_TERMINATE); } static ACPI_STATUS -nvdimm_foreach_acpi(ACPI_STATUS (*func)(ACPI_HANDLE, void *), void *arg) +nvdimm_find_handle(ACPI_HANDLE *handle, ACPI_HANDLE root_handle, + nfit_handle_t adr) { - struct nvdimm_ns_walk_ctx wctx; ACPI_STATUS status; - wctx.func = func; - wctx.arg = arg; - status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 100, - nvdimm_walk_root, NULL, &wctx, NULL); + *handle = NULL; + status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, root_handle, 1, + nvdimm_find_handle_callback, NULL, (void *)(intptr_t)adr, handle); + if (ACPI_SUCCESS(status) && *handle == NULL) + status = AE_NOT_FOUND; return_ACPI_STATUS(status); } -static ACPI_STATUS -nvdimm_count_devs(ACPI_HANDLE handle __unused, void *arg) -{ - int *cnt; - - cnt = arg; - (*cnt)++; - - ACPI_BUFFER name; - ACPI_STATUS status; - if (bootverbose) { - name.Length = ACPI_ALLOCATE_BUFFER; - status = AcpiGetName(handle, ACPI_FULL_PATHNAME, &name); - if (ACPI_FAILURE(status)) - return_ACPI_STATUS(status); - printf("nvdimm: enumerated %s\n", (char *)name.Pointer); - AcpiOsFree(name.Pointer); - } - - return_ACPI_STATUS(AE_OK); -} - -struct nvdimm_create_dev_arg { - device_t acpi0; - int *cnt; -}; - -static ACPI_STATUS -nvdimm_create_dev(ACPI_HANDLE handle, void *arg) -{ - struct nvdimm_create_dev_arg *narg; - device_t child; - int idx; - - narg = arg; - idx = *(narg->cnt); - child = device_find_child(narg->acpi0, "nvdimm", idx); - if (child == NULL) - child = BUS_ADD_CHILD(narg->acpi0, 1, "nvdimm", idx); - if (child == NULL) { - if (bootverbose) - device_printf(narg->acpi0, - "failed to create nvdimm%d\n", idx); - return_ACPI_STATUS(AE_ERROR); - } - acpi_set_handle(child, handle); - KASSERT(nvdimm_devs[idx] == NULL, ("nvdimm_devs[%d] not NULL", idx)); - nvdimm_devs[idx] = child; - - (*(narg->cnt))++; - return_ACPI_STATUS(AE_OK); -} - -static bool -nvdimm_init(void) +struct nvdimm_dev * +nvdimm_find_by_handle(nfit_handle_t nv_handle) { + struct nvdimm_dev *res; + device_t dev; + ACPI_HANDLE root_handle, handle; ACPI_STATUS status; - if (nvdimm_devcnt != 0) - return (true); - if (acpi_disabled("nvdimm")) - return (false); - status = nvdimm_foreach_acpi(nvdimm_count_devs, &nvdimm_devcnt); - if (ACPI_FAILURE(status)) { - if (bootverbose) - printf("nvdimm_init: count failed\n"); - return (false); + res = NULL; + status = nvdimm_find_root_handle(&root_handle); + if (ACPI_SUCCESS(status)) { + status = nvdimm_find_handle(&handle, root_handle, nv_handle); + if (ACPI_SUCCESS(status)) { + dev = acpi_get_device(handle); + if (dev != NULL) + res = device_get_softc(dev); + } } - nvdimm_devs = malloc(nvdimm_devcnt * sizeof(device_t), M_NVDIMM, - M_WAITOK | M_ZERO); - return (true); + return (res); } static void nvdimm_identify(driver_t *driver, device_t parent) { - struct nvdimm_create_dev_arg narg; + device_t child; + nfit_handle_t *dimm_ids; + ACPI_TABLE_NFIT *nfitbl; ACPI_STATUS status; - int i; - - if (!nvdimm_init()) + ACPI_HANDLE handle, root_handle; + int i, dimm_count; + + if (acpi_disabled("nvdimm")) + return; + status = nvdimm_find_root_handle(&root_handle); + if (!ACPI_SUCCESS(status)) return; - narg.acpi0 = parent; - narg.cnt = &i; - i = 0; - status = nvdimm_foreach_acpi(nvdimm_create_dev, &narg); - if (ACPI_FAILURE(status) && bootverbose) - printf("nvdimm_identify: create failed\n"); + status = AcpiGetTable(ACPI_SIG_NFIT, 1, (ACPI_TABLE_HEADER **)&nfitbl); + if (!ACPI_SUCCESS(status)) + return; + acpi_nfit_get_dimm_ids(nfitbl, &dimm_ids, &dimm_count); + for (i = 0; i < dimm_count; i++) { + status = nvdimm_find_handle(&handle, root_handle, dimm_ids[i]); + if (!ACPI_SUCCESS(status)) { + device_printf(parent, "nvdimm with _ADR %x not found\n", + dimm_ids[i]); + continue; + } + child = device_find_child(parent, "nvdimm", dimm_ids[i]); + if (child == NULL) + child = BUS_ADD_CHILD(parent, 1, "nvdimm", dimm_ids[i]); + acpi_set_handle(child, handle); + } + free(dimm_ids, M_NVDIMM); + AcpiPutTable(&nfitbl->Header); } static int @@ -311,33 +187,25 @@ ACPI_TABLE_NFIT *nfitbl; ACPI_HANDLE handle; ACPI_STATUS status; - int i; nv = device_get_softc(dev); handle = acpi_get_handle(dev); if (handle == NULL) return (EINVAL); nv->nv_dev = dev; - for (i = 0; i < nvdimm_devcnt; i++) { - if (nvdimm_devs[i] == dev) { - nv->nv_devs_idx = i; - break; - } - } - MPASS(i < nvdimm_devcnt); - if (ACPI_FAILURE(acpi_GetInteger(handle, "_ADR", &nv->nv_handle))) { + status = acpi_GetInteger(handle, "_ADR", &nv->nv_handle); + if (!ACPI_SUCCESS(status)) { device_printf(dev, "cannot get handle\n"); return (ENXIO); } status = AcpiGetTable(ACPI_SIG_NFIT, 1, (ACPI_TABLE_HEADER **)&nfitbl); - if (ACPI_FAILURE(status)) { - if (bootverbose) - device_printf(dev, "cannot get NFIT\n"); + if (!ACPI_SUCCESS(status)) { + device_printf(dev, "cannot NFIT table\n"); return (ENXIO); } - nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_FLUSH_ADDRESS, - nvdimm_parse_flush_addr, nv); + acpi_nfit_get_flush_addrs(nfitbl, nv->nv_handle, &nv->nv_flush_addr, + &nv->nv_flush_addr_cnt); AcpiPutTable(&nfitbl->Header); return (0); } @@ -348,7 +216,6 @@ struct nvdimm_dev *nv; nv = device_get_softc(dev); - nvdimm_devs[nv->nv_devs_idx] = NULL; free(nv->nv_flush_addr, M_NVDIMM); return (0); } @@ -383,41 +250,5 @@ sizeof(struct nvdimm_dev), }; -static void -nvdimm_fini(void) -{ - - free(nvdimm_devs, M_NVDIMM); - nvdimm_devs = NULL; - nvdimm_devcnt = 0; -} - -static int -nvdimm_modev(struct module *mod, int what, void *arg) -{ - int error; - - switch (what) { - case MOD_LOAD: - error = 0; - break; - - case MOD_UNLOAD: - nvdimm_fini(); - error = 0; - break; - - case MOD_QUIESCE: - error = 0; - break; - - default: - error = EOPNOTSUPP; - break; - } - - return (error); -} - -DRIVER_MODULE(nvdimm, acpi, nvdimm_driver, nvdimm_devclass, nvdimm_modev, NULL); +DRIVER_MODULE(nvdimm, acpi, nvdimm_driver, nvdimm_devclass, NULL, NULL); MODULE_DEPEND(nvdimm, acpi, 1, 1, 1); Index: sys/dev/nvdimm/nvdimm_nfit.c =================================================================== --- /dev/null +++ sys/dev/nvdimm/nvdimm_nfit.c @@ -0,0 +1,199 @@ +/*- + * Copyright (c) 2018 Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include + +static int +uint32_t_compare(const void *_a, const void *_b) { + const uint32_t *a, *b; + + a = _a; + b = _b; + return *a - *b; +} + +static int +find_matches(ACPI_TABLE_NFIT *nfitbl, uint16_t type, uint16_t offset, + uint64_t mask, uint64_t value, void **ptrs, int ptrs_len) +{ + ACPI_NFIT_HEADER *h, *end; + uint64_t val; + int count; + + h = (ACPI_NFIT_HEADER *)(nfitbl + 1); + end = (ACPI_NFIT_HEADER *)((char *)nfitbl + + nfitbl->Header.Length); + count = 0; + + while (h < end) { + if (h->Type == type) { + val = *(uint64_t *)((char *)h + offset) & mask; + if (val == value) { + if (ptrs_len > 0) { + ptrs[count] = h; + ptrs_len--; + } + count++; + } + } + if (h->Length == 0) { + break; + } + h = (ACPI_NFIT_HEADER *)((char *)h + h->Length); + } + return (count); +} + +static void +malloc_find_matches(ACPI_TABLE_NFIT *nfitbl, uint16_t type, uint16_t offset, + uint64_t mask, uint64_t value, void ***ptrs, int *ptrs_len) +{ + int count; + + count = find_matches(nfitbl, type, offset, mask, value, NULL, 0); + *ptrs_len = count; + if (count == 0) { + *ptrs = NULL; + return; + } + *ptrs = mallocarray(count, sizeof(void *), M_NVDIMM, M_WAITOK); + find_matches(nfitbl, type, offset, mask, value, *ptrs, *ptrs_len); +} + +void +acpi_nfit_get_dimm_ids(ACPI_TABLE_NFIT *nfitbl, nfit_handle_t **listp, + int *countp) +{ + ACPI_NFIT_SYSTEM_ADDRESS **spas; + ACPI_NFIT_MEMORY_MAP ***regions; + int i, j, k, maxids, num_spas, *region_counts; + + acpi_nfit_get_spa_ranges(nfitbl, &spas, &num_spas); + if (num_spas == 0) { + *listp = NULL; + *countp = 0; + return; + } + regions = mallocarray(num_spas, sizeof(uint16_t *), M_NVDIMM, + M_WAITOK); + region_counts = mallocarray(num_spas, sizeof(int), M_NVDIMM, M_WAITOK); + for (i = 0; i < num_spas; i++) + acpi_nfit_get_region_mappings_by_spa_range(nfitbl, + spas[i]->RangeIndex, ®ions[i], ®ion_counts[i]); + maxids = 0; + for (i = 0; i < num_spas; i++) { + maxids += region_counts[i]; + } + *listp = mallocarray(maxids, sizeof(nfit_handle_t), M_NVDIMM, M_WAITOK); + k = 0; + for (i = 0; i < num_spas; i++) + for (j = 0; j < region_counts[i]; j++) + *listp[k++] = regions[i][j]->DeviceHandle; + qsort(*listp, maxids, sizeof(uint32_t), uint32_t_compare); + i = 0; + for (j = 1; j < maxids; j++) + if (*listp[i] != *listp[j]) + *listp[++i] = *listp[j]; + *countp = i + 1; + free(region_counts, M_NVDIMM); + for (i = 0; i < num_spas; i++) + free(regions[i], M_NVDIMM); + free(regions, M_NVDIMM); + free(spas, M_NVDIMM); +} + +void +acpi_nfit_get_spa_range(ACPI_TABLE_NFIT *nfitbl, uint16_t range_index, + ACPI_NFIT_SYSTEM_ADDRESS **spa) +{ + + *spa = NULL; + find_matches(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS, + offsetof(ACPI_NFIT_SYSTEM_ADDRESS, RangeIndex), UINT16_MAX, + range_index, (void **)spa, 1); +} + +void +acpi_nfit_get_spa_ranges(ACPI_TABLE_NFIT *nfitbl, + ACPI_NFIT_SYSTEM_ADDRESS ***listp, int *countp) +{ + + malloc_find_matches(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS, 0, 0, 0, + (void ***)listp, countp); +} + +void +acpi_nfit_get_region_mappings_by_spa_range(ACPI_TABLE_NFIT *nfitbl, + uint16_t spa_range_index, ACPI_NFIT_MEMORY_MAP ***listp, int *countp) +{ + + malloc_find_matches(nfitbl, ACPI_NFIT_TYPE_MEMORY_MAP, + offsetof(ACPI_NFIT_MEMORY_MAP, RangeIndex), UINT16_MAX, + spa_range_index, (void ***)listp, countp); +} + +void acpi_nfit_get_control_region(ACPI_TABLE_NFIT *nfitbl, + uint16_t control_region_index, ACPI_NFIT_CONTROL_REGION **out) +{ + + *out = NULL; + find_matches(nfitbl, ACPI_NFIT_TYPE_CONTROL_REGION, + offsetof(ACPI_NFIT_CONTROL_REGION, RegionIndex), UINT16_MAX, + control_region_index, (void **)out, 1); +} + +void +acpi_nfit_get_flush_addrs(ACPI_TABLE_NFIT *nfitbl, nfit_handle_t dimm, + uint64_t ***listp, int *countp) +{ + ACPI_NFIT_FLUSH_ADDRESS *subtable; + int i; + + subtable = NULL; + find_matches(nfitbl, ACPI_NFIT_TYPE_FLUSH_ADDRESS, + offsetof(ACPI_NFIT_FLUSH_ADDRESS, DeviceHandle), UINT32_MAX, + dimm, (void **)&subtable, 1); + if (subtable == NULL || subtable->HintCount == 0) { + *listp = NULL; + *countp = 0; + return; + } + *countp = subtable->HintCount; + *listp = mallocarray(subtable->HintCount, sizeof(uint64_t *), M_NVDIMM, + M_WAITOK); + for (i = 0; i < subtable->HintCount; i++) + (*listp)[i] = (uint64_t *)(intptr_t)subtable->HintAddress[i]; +} Index: sys/dev/nvdimm/nvdimm_spa.c =================================================================== --- sys/dev/nvdimm/nvdimm_spa.c +++ sys/dev/nvdimm/nvdimm_spa.c @@ -564,6 +564,7 @@ nvdimm_spa_init1(ACPI_TABLE_NFIT *nfitbl) { struct nvdimm_SPA_uuid_list_elm *sle; + ACPI_NFIT_SYSTEM_ADDRESS **spas; int error, i; for (i = 0; i < nitems(nvdimm_SPA_uuid_list); i++) { @@ -578,21 +579,20 @@ } } - error = nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS, - nvdimm_spa_count, &spa_mappings_cnt); - if (error != 0) - return (error); + acpi_nfit_get_spa_ranges(nfitbl, &spas, &spa_mappings_cnt); spa_mappings = malloc(sizeof(struct SPA_mapping) * spa_mappings_cnt, M_NVDIMM, M_WAITOK | M_ZERO); - i = 0; - error = nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS, - nvdimm_spa_parse, &i); + for (i = 0; i < spa_mappings_cnt; i++) { + error = nvdimm_spa_parse(spas[i], &spa_mappings[i]); + if (error != 0) + break; + } + free(spas, M_NVDIMM); if (error != 0) { free(spa_mappings, M_NVDIMM); spa_mappings = NULL; - return (error); } - return (0); + return (error); } static void Index: sys/dev/nvdimm/nvdimm_var.h =================================================================== --- sys/dev/nvdimm/nvdimm_var.h +++ sys/dev/nvdimm/nvdimm_var.h @@ -39,7 +39,6 @@ nfit_handle_t nv_handle; uint64_t **nv_flush_addr; int nv_flush_addr_cnt; - int nv_devs_idx; }; enum SPA_mapping_type { @@ -74,18 +73,24 @@ bool spa_g_proc_exiting; }; -struct nvdimm_ns_walk_ctx { - ACPI_STATUS (*func)(ACPI_HANDLE, void *); - void *arg; -}; - extern struct SPA_mapping *spa_mappings; extern int spa_mappings_cnt; MALLOC_DECLARE(M_NVDIMM); +void acpi_nfit_get_dimm_ids(ACPI_TABLE_NFIT *nfitbl, nfit_handle_t **listp, + int *countp); +void acpi_nfit_get_spa_range(ACPI_TABLE_NFIT *nfitbl, uint16_t range_index, + ACPI_NFIT_SYSTEM_ADDRESS **spa); +void acpi_nfit_get_spa_ranges(ACPI_TABLE_NFIT *nfitbl, + ACPI_NFIT_SYSTEM_ADDRESS ***listp, int *countp); +void acpi_nfit_get_region_mappings_by_spa_range(ACPI_TABLE_NFIT *nfitbl, + uint16_t spa_range_index, ACPI_NFIT_MEMORY_MAP ***listp, int *countp); +void acpi_nfit_get_control_region(ACPI_TABLE_NFIT *nfitbl, + uint16_t control_region_index, ACPI_NFIT_CONTROL_REGION **out); +void acpi_nfit_get_flush_addrs(ACPI_TABLE_NFIT *nfitbl, nfit_handle_t dimm, + uint64_t ***listp, int *countp); + struct nvdimm_dev *nvdimm_find_by_handle(nfit_handle_t nv_handle); -int nvdimm_iterate_nfit(ACPI_TABLE_NFIT *nfitbl, enum AcpiNfitType type, - int (*cb)(void *, void *), void *arg); #endif /* __DEV_NVDIMM_VAR_H__ */ Index: sys/modules/nvdimm/Makefile =================================================================== --- sys/modules/nvdimm/Makefile +++ sys/modules/nvdimm/Makefile @@ -4,6 +4,7 @@ KMOD= nvdimm SRCS= nvdimm.c \ + nvdimm_nfit.c \ nvdimm_spa.c SRCS+= acpi_if.h bus_if.h device_if.h