Print this page
12195 acpidump failed under EFI

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/i86pc/os/fakebop.c
          +++ new/usr/src/uts/i86pc/os/fakebop.c
↓ open down ↓ 18 lines elided ↑ open up ↑
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   *
  26   26   * Copyright (c) 2010, Intel Corporation.
  27   27   * All rights reserved.
  28   28   *
  29      - * Copyright (c) 2019, Joyent, Inc.
       29 + * Copyright 2020 Joyent, Inc.
  30   30   */
  31   31  
  32   32  /*
  33   33   * This file contains the functionality that mimics the boot operations
  34   34   * on SPARC systems or the old boot.bin/multiboot programs on x86 systems.
  35   35   * The x86 kernel now does everything on its own.
  36   36   */
  37   37  
  38   38  #include <sys/types.h>
  39   39  #include <sys/bootconf.h>
↓ open down ↓ 2224 lines elided ↑ open up ↑
2264 2264                  return (0);
2265 2265  
2266 2266          return (1);
2267 2267  }
2268 2268  
2269 2269  /*
2270 2270   * Scan memory range for an RSDP;
2271 2271   * see ACPI 3.0 Spec, 5.2.5.1
2272 2272   */
2273 2273  static ACPI_TABLE_RSDP *
2274      -scan_rsdp(paddr_t start, paddr_t end)
     2274 +scan_rsdp(paddr_t *paddrp, size_t len)
2275 2275  {
2276      -        ssize_t len  = end - start;
     2276 +        paddr_t paddr = *paddrp;
2277 2277          caddr_t ptr;
2278 2278  
2279      -        ptr = vmap_phys(len, start);
     2279 +        ptr = vmap_phys(len, paddr);
     2280 +
2280 2281          while (len > 0) {
2281 2282                  if (strncmp(ptr, ACPI_SIG_RSDP, strlen(ACPI_SIG_RSDP)) == 0 &&
2282      -                    valid_rsdp((ACPI_TABLE_RSDP *)ptr))
     2283 +                    valid_rsdp((ACPI_TABLE_RSDP *)ptr)) {
     2284 +                        *paddrp = paddr;
2283 2285                          return ((ACPI_TABLE_RSDP *)ptr);
     2286 +                }
2284 2287  
2285 2288                  ptr += ACPI_RSDP_SCAN_STEP;
     2289 +                paddr += ACPI_RSDP_SCAN_STEP;
2286 2290                  len -= ACPI_RSDP_SCAN_STEP;
2287 2291          }
2288 2292  
2289 2293          return (NULL);
2290 2294  }
2291 2295  
2292 2296  /*
2293      - * Refer to ACPI 3.0 Spec, section 5.2.5.1 to understand this function
     2297 + * Locate the ACPI RSDP.  We search in a particular order:
     2298 + *
     2299 + * - If the bootloader told us the location of the RSDP (via the EFI system
     2300 + *   table), try that first.
     2301 + * - Otherwise, look in the EBDA and BIOS memory as per ACPI 5.2.5.1 (legacy
     2302 + *   case).
     2303 + * - Finally, our bootloader may have a copy of the RSDP in its info: this might
     2304 + *   get freed after boot, so we always prefer to find the original RSDP first.
     2305 + *
     2306 + * Once found, we set acpi-root-tab property (a physical address) for the
     2307 + * benefit of acpica, acpidump etc.
2294 2308   */
     2309 +
2295 2310  static ACPI_TABLE_RSDP *
2296      -find_rsdp()
     2311 +find_rsdp(struct xboot_info *xbp)
2297 2312  {
2298      -        ACPI_TABLE_RSDP *rsdp;
2299      -        uint64_t rsdp_val = 0;
2300      -        uint16_t *ebda_seg;
2301      -        paddr_t  ebda_addr;
     2313 +        ACPI_TABLE_RSDP *rsdp = NULL;
     2314 +        paddr_t paddr = 0;
2302 2315  
2303      -        /* check for "acpi-root-tab" property */
2304 2316          if (do_bsys_getproplen(NULL, "acpi-root-tab") == sizeof (uint64_t)) {
2305      -                (void) do_bsys_getprop(NULL, "acpi-root-tab", &rsdp_val);
2306      -                if (rsdp_val != 0) {
2307      -                        rsdp = scan_rsdp(rsdp_val, rsdp_val + sizeof (*rsdp));
2308      -                        if (rsdp != NULL) {
2309      -                                if (kbm_debug) {
2310      -                                        bop_printf(NULL,
2311      -                                            "Using RSDP from bootloader: "
2312      -                                            "0x%p\n", (void *)rsdp);
2313      -                                }
2314      -                                return (rsdp);
2315      -                        }
2316      -                }
     2317 +                (void) do_bsys_getprop(NULL, "acpi-root-tab", &paddr);
     2318 +                rsdp = scan_rsdp(&paddr, sizeof (*rsdp));
2317 2319          }
2318 2320  
2319      -        /*
2320      -         * Get the EBDA segment and scan the first 1K
2321      -         */
2322      -        ebda_seg = (uint16_t *)vmap_phys(sizeof (uint16_t),
2323      -            ACPI_EBDA_PTR_LOCATION);
2324      -        ebda_addr = *ebda_seg << 4;
2325      -        rsdp = scan_rsdp(ebda_addr, ebda_addr + ACPI_EBDA_WINDOW_SIZE);
2326      -        if (rsdp == NULL)
2327      -                /* if EBDA doesn't contain RSDP, look in BIOS memory */
2328      -                rsdp = scan_rsdp(ACPI_HI_RSDP_WINDOW_BASE,
2329      -                    ACPI_HI_RSDP_WINDOW_BASE + ACPI_HI_RSDP_WINDOW_SIZE);
     2321 +#ifndef __xpv
     2322 +        if (rsdp == NULL && xbp->bi_acpi_rsdp != NULL) {
     2323 +                paddr = (uintptr_t)xbp->bi_acpi_rsdp;
     2324 +                rsdp = scan_rsdp(&paddr, sizeof (*rsdp));
     2325 +        }
     2326 +#endif
     2327 +
     2328 +        if (rsdp == NULL) {
     2329 +                uint16_t *ebda_seg = (uint16_t *)vmap_phys(sizeof (uint16_t),
     2330 +                    ACPI_EBDA_PTR_LOCATION);
     2331 +                paddr = *ebda_seg << 4;
     2332 +                rsdp = scan_rsdp(&paddr, ACPI_EBDA_WINDOW_SIZE);
     2333 +        }
     2334 +
     2335 +        if (rsdp == NULL) {
     2336 +                paddr = ACPI_HI_RSDP_WINDOW_BASE;
     2337 +                rsdp = scan_rsdp(&paddr, ACPI_HI_RSDP_WINDOW_SIZE);
     2338 +        }
     2339 +
     2340 +#ifndef __xpv
     2341 +        if (rsdp == NULL && xbp->bi_acpi_rsdp_copy != NULL) {
     2342 +                paddr = (uintptr_t)xbp->bi_acpi_rsdp_copy;
     2343 +                rsdp = scan_rsdp(&paddr, sizeof (*rsdp));
     2344 +        }
     2345 +#endif
     2346 +
     2347 +        if (rsdp == NULL) {
     2348 +                bop_printf(NULL, "no RSDP found!\n");
     2349 +                return (NULL);
     2350 +        }
     2351 +
     2352 +        if (kbm_debug)
     2353 +                bop_printf(NULL, "RSDP found at physical 0x%lx\n", paddr);
     2354 +
     2355 +        if (do_bsys_getproplen(NULL, "acpi-root-tab") != sizeof (uint64_t))
     2356 +                bsetprop64("acpi-root-tab", paddr);
     2357 +
2330 2358          return (rsdp);
2331 2359  }
2332 2360  
2333 2361  static ACPI_TABLE_HEADER *
2334 2362  map_fw_table(paddr_t table_addr)
2335 2363  {
2336 2364          ACPI_TABLE_HEADER *tp;
2337 2365          size_t len = MAX(sizeof (*tp), MMU_PAGESIZE);
2338 2366  
2339 2367          /*
2340 2368           * Map at least a page; if the table is larger than this, remap it
2341 2369           */
2342 2370          tp = (ACPI_TABLE_HEADER *)vmap_phys(len, table_addr);
2343 2371          if (tp->Length > len)
2344 2372                  tp = (ACPI_TABLE_HEADER *)vmap_phys(tp->Length, table_addr);
2345 2373          return (tp);
2346 2374  }
2347 2375  
2348 2376  static ACPI_TABLE_HEADER *
2349      -find_fw_table(char *signature)
     2377 +find_fw_table(ACPI_TABLE_RSDP *rsdp, char *signature)
2350 2378  {
2351 2379          static int revision = 0;
2352 2380          static ACPI_TABLE_XSDT *xsdt;
2353 2381          static int len;
2354 2382          paddr_t xsdt_addr;
2355      -        ACPI_TABLE_RSDP *rsdp;
2356 2383          ACPI_TABLE_HEADER *tp;
2357 2384          paddr_t table_addr;
2358 2385          int     n;
2359 2386  
2360 2387          if (strlen(signature) != ACPI_NAME_SIZE)
2361 2388                  return (NULL);
2362 2389  
2363 2390          /*
2364 2391           * Reading the ACPI 3.0 Spec, section 5.2.5.3 will help
2365 2392           * understand this code.  If we haven't already found the RSDT/XSDT,
2366 2393           * revision will be 0. Find the RSDP and check the revision
2367 2394           * to find out whether to use the RSDT or XSDT.  If revision is
2368 2395           * 0 or 1, use the RSDT and set internal revision to 1; if it is 2,
2369 2396           * use the XSDT.  If the XSDT address is 0, though, fall back to
2370 2397           * revision 1 and use the RSDT.
2371 2398           */
2372 2399          if (revision == 0) {
2373      -                if ((rsdp = find_rsdp()) != NULL) {
2374      -                        revision = rsdp->Revision;
     2400 +                if (rsdp == NULL)
     2401 +                        return (NULL);
     2402 +
     2403 +                revision = rsdp->Revision;
     2404 +                /*
     2405 +                 * ACPI 6.0 states that current revision is 2
     2406 +                 * from acpi_table_rsdp definition:
     2407 +                 * Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+
     2408 +                 */
     2409 +                if (revision > 2)
     2410 +                        revision = 2;
     2411 +                switch (revision) {
     2412 +                case 2:
2375 2413                          /*
2376      -                         * ACPI 6.0 states that current revision is 2
2377      -                         * from acpi_table_rsdp definition:
2378      -                         * Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+
     2414 +                         * Use the XSDT unless BIOS is buggy and
     2415 +                         * claims to be rev 2 but has a null XSDT
     2416 +                         * address
2379 2417                           */
2380      -                        if (revision > 2)
2381      -                                revision = 2;
2382      -                        switch (revision) {
2383      -                        case 2:
2384      -                                /*
2385      -                                 * Use the XSDT unless BIOS is buggy and
2386      -                                 * claims to be rev 2 but has a null XSDT
2387      -                                 * address
2388      -                                 */
2389      -                                xsdt_addr = rsdp->XsdtPhysicalAddress;
2390      -                                if (xsdt_addr != 0)
2391      -                                        break;
2392      -                                /* FALLTHROUGH */
2393      -                        case 0:
2394      -                                /* treat RSDP rev 0 as revision 1 internally */
2395      -                                revision = 1;
2396      -                                /* FALLTHROUGH */
2397      -                        case 1:
2398      -                                /* use the RSDT for rev 0/1 */
2399      -                                xsdt_addr = rsdp->RsdtPhysicalAddress;
     2418 +                        xsdt_addr = rsdp->XsdtPhysicalAddress;
     2419 +                        if (xsdt_addr != 0)
2400 2420                                  break;
2401      -                        default:
2402      -                                /* unknown revision */
2403      -                                revision = 0;
2404      -                                break;
2405      -                        }
     2421 +                        /* FALLTHROUGH */
     2422 +                case 0:
     2423 +                        /* treat RSDP rev 0 as revision 1 internally */
     2424 +                        revision = 1;
     2425 +                        /* FALLTHROUGH */
     2426 +                case 1:
     2427 +                        /* use the RSDT for rev 0/1 */
     2428 +                        xsdt_addr = rsdp->RsdtPhysicalAddress;
     2429 +                        break;
     2430 +                default:
     2431 +                        /* unknown revision */
     2432 +                        revision = 0;
     2433 +                        break;
2406 2434                  }
     2435 +
2407 2436                  if (revision == 0)
2408 2437                          return (NULL);
2409 2438  
2410 2439                  /* cache the XSDT info */
2411 2440                  xsdt = (ACPI_TABLE_XSDT *)map_fw_table(xsdt_addr);
2412 2441                  len = (xsdt->Header.Length - sizeof (xsdt->Header)) /
2413 2442                      ((revision == 1) ? sizeof (uint32_t) : sizeof (uint64_t));
2414 2443          }
2415 2444  
2416 2445          /*
↓ open down ↓ 416 lines elided ↑ open up ↑
2833 2862          bsetpropsi(BOOT_NCPUS_NAME, max_id+1);
2834 2863  
2835 2864  }
2836 2865  #endif /* __xpv */
2837 2866  
2838 2867  /*ARGSUSED*/
2839 2868  static void
2840 2869  build_firmware_properties(struct xboot_info *xbp)
2841 2870  {
2842 2871          ACPI_TABLE_HEADER *tp = NULL;
     2872 +        ACPI_TABLE_RSDP *rsdp;
2843 2873  
2844 2874  #ifndef __xpv
2845 2875          if (xbp->bi_uefi_arch == XBI_UEFI_ARCH_64) {
2846 2876                  bsetprops("efi-systype", "64");
2847 2877                  bsetprop64("efi-systab",
2848 2878                      (uint64_t)(uintptr_t)xbp->bi_uefi_systab);
2849 2879                  if (kbm_debug)
2850 2880                          bop_printf(NULL, "64-bit UEFI detected.\n");
2851 2881          } else if (xbp->bi_uefi_arch == XBI_UEFI_ARCH_32) {
2852 2882                  bsetprops("efi-systype", "32");
2853 2883                  bsetprop64("efi-systab",
2854 2884                      (uint64_t)(uintptr_t)xbp->bi_uefi_systab);
2855 2885                  if (kbm_debug)
2856 2886                          bop_printf(NULL, "32-bit UEFI detected.\n");
2857 2887          }
2858 2888  
2859      -        if (xbp->bi_acpi_rsdp != NULL) {
2860      -                bsetprop64("acpi-root-tab",
2861      -                    (uint64_t)(uintptr_t)xbp->bi_acpi_rsdp);
2862      -        }
2863      -
2864 2889          if (xbp->bi_smbios != NULL) {
2865 2890                  bsetprop64("smbios-address",
2866 2891                      (uint64_t)(uintptr_t)xbp->bi_smbios);
2867 2892          }
2868 2893  
2869      -        if ((tp = find_fw_table(ACPI_SIG_MSCT)) != NULL)
     2894 +        rsdp = find_rsdp(xbp);
     2895 +
     2896 +        if ((tp = find_fw_table(rsdp, ACPI_SIG_MSCT)) != NULL)
2870 2897                  msct_ptr = process_msct((ACPI_TABLE_MSCT *)tp);
2871 2898          else
2872 2899                  msct_ptr = NULL;
2873 2900  
2874      -        if ((tp = find_fw_table(ACPI_SIG_MADT)) != NULL)
     2901 +        if ((tp = find_fw_table(rsdp, ACPI_SIG_MADT)) != NULL)
2875 2902                  process_madt((ACPI_TABLE_MADT *)tp);
2876 2903  
2877 2904          if ((srat_ptr = (ACPI_TABLE_SRAT *)
2878      -            find_fw_table(ACPI_SIG_SRAT)) != NULL)
     2905 +            find_fw_table(rsdp, ACPI_SIG_SRAT)) != NULL)
2879 2906                  process_srat(srat_ptr);
2880 2907  
2881      -        if (slit_ptr = (ACPI_TABLE_SLIT *)find_fw_table(ACPI_SIG_SLIT))
     2908 +        if (slit_ptr = (ACPI_TABLE_SLIT *)find_fw_table(rsdp, ACPI_SIG_SLIT))
2882 2909                  process_slit(slit_ptr);
2883 2910  
2884      -        tp = find_fw_table(ACPI_SIG_MCFG);
     2911 +        tp = find_fw_table(rsdp, ACPI_SIG_MCFG);
2885 2912  #else /* __xpv */
2886 2913          enumerate_xen_cpus();
2887 2914          if (DOMAIN_IS_INITDOMAIN(xen_info))
2888      -                tp = find_fw_table(ACPI_SIG_MCFG);
     2915 +                tp = find_fw_table(rsdp, ACPI_SIG_MCFG);
2889 2916  #endif /* __xpv */
2890 2917          if (tp != NULL)
2891 2918                  process_mcfg((ACPI_TABLE_MCFG *)tp);
2892 2919  }
2893 2920  
2894 2921  /*
2895 2922   * fake up a boot property for deferred early console output
2896 2923   * this is used by both graphical boot and the (developer only)
2897 2924   * USB serial console
2898 2925   */
↓ open down ↓ 53 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX