9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 * Copyright (c) 2010, Intel Corporation.
27 * All rights reserved.
28 *
29 * Copyright (c) 2019, Joyent, Inc.
30 */
31
32 /*
33 * This file contains the functionality that mimics the boot operations
34 * on SPARC systems or the old boot.bin/multiboot programs on x86 systems.
35 * The x86 kernel now does everything on its own.
36 */
37
38 #include <sys/types.h>
39 #include <sys/bootconf.h>
40 #include <sys/bootsvcs.h>
41 #include <sys/bootinfo.h>
42 #include <sys/multiboot.h>
43 #include <sys/multiboot2.h>
44 #include <sys/multiboot2_impl.h>
45 #include <sys/bootvfs.h>
46 #include <sys/bootprops.h>
47 #include <sys/varargs.h>
48 #include <sys/param.h>
49 #include <sys/machparam.h>
2254 /* validate the V1.x checksum */
2255 if (checksum_table((uint8_t *)rp, ACPI_RSDP_CHECKSUM_LENGTH) != 0)
2256 return (0);
2257
2258 /* If pre-ACPI 2.0, this is a valid RSDP */
2259 if (rp->Revision < 2)
2260 return (1);
2261
2262 /* validate the V2.x checksum */
2263 if (checksum_table((uint8_t *)rp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)
2264 return (0);
2265
2266 return (1);
2267 }
2268
2269 /*
2270 * Scan memory range for an RSDP;
2271 * see ACPI 3.0 Spec, 5.2.5.1
2272 */
2273 static ACPI_TABLE_RSDP *
2274 scan_rsdp(paddr_t start, paddr_t end)
2275 {
2276 ssize_t len = end - start;
2277 caddr_t ptr;
2278
2279 ptr = vmap_phys(len, start);
2280 while (len > 0) {
2281 if (strncmp(ptr, ACPI_SIG_RSDP, strlen(ACPI_SIG_RSDP)) == 0 &&
2282 valid_rsdp((ACPI_TABLE_RSDP *)ptr))
2283 return ((ACPI_TABLE_RSDP *)ptr);
2284
2285 ptr += ACPI_RSDP_SCAN_STEP;
2286 len -= ACPI_RSDP_SCAN_STEP;
2287 }
2288
2289 return (NULL);
2290 }
2291
2292 /*
2293 * Refer to ACPI 3.0 Spec, section 5.2.5.1 to understand this function
2294 */
2295 static ACPI_TABLE_RSDP *
2296 find_rsdp()
2297 {
2298 ACPI_TABLE_RSDP *rsdp;
2299 uint64_t rsdp_val = 0;
2300 uint16_t *ebda_seg;
2301 paddr_t ebda_addr;
2302
2303 /* check for "acpi-root-tab" property */
2304 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 }
2318
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);
2330 return (rsdp);
2331 }
2332
2333 static ACPI_TABLE_HEADER *
2334 map_fw_table(paddr_t table_addr)
2335 {
2336 ACPI_TABLE_HEADER *tp;
2337 size_t len = MAX(sizeof (*tp), MMU_PAGESIZE);
2338
2339 /*
2340 * Map at least a page; if the table is larger than this, remap it
2341 */
2342 tp = (ACPI_TABLE_HEADER *)vmap_phys(len, table_addr);
2343 if (tp->Length > len)
2344 tp = (ACPI_TABLE_HEADER *)vmap_phys(tp->Length, table_addr);
2345 return (tp);
2346 }
2347
2348 static ACPI_TABLE_HEADER *
2349 find_fw_table(char *signature)
2350 {
2351 static int revision = 0;
2352 static ACPI_TABLE_XSDT *xsdt;
2353 static int len;
2354 paddr_t xsdt_addr;
2355 ACPI_TABLE_RSDP *rsdp;
2356 ACPI_TABLE_HEADER *tp;
2357 paddr_t table_addr;
2358 int n;
2359
2360 if (strlen(signature) != ACPI_NAME_SIZE)
2361 return (NULL);
2362
2363 /*
2364 * Reading the ACPI 3.0 Spec, section 5.2.5.3 will help
2365 * understand this code. If we haven't already found the RSDT/XSDT,
2366 * revision will be 0. Find the RSDP and check the revision
2367 * to find out whether to use the RSDT or XSDT. If revision is
2368 * 0 or 1, use the RSDT and set internal revision to 1; if it is 2,
2369 * use the XSDT. If the XSDT address is 0, though, fall back to
2370 * revision 1 and use the RSDT.
2371 */
2372 if (revision == 0) {
2373 if ((rsdp = find_rsdp()) != NULL) {
2374 revision = rsdp->Revision;
2375 /*
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+
2379 */
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;
2400 break;
2401 default:
2402 /* unknown revision */
2403 revision = 0;
2404 break;
2405 }
2406 }
2407 if (revision == 0)
2408 return (NULL);
2409
2410 /* cache the XSDT info */
2411 xsdt = (ACPI_TABLE_XSDT *)map_fw_table(xsdt_addr);
2412 len = (xsdt->Header.Length - sizeof (xsdt->Header)) /
2413 ((revision == 1) ? sizeof (uint32_t) : sizeof (uint64_t));
2414 }
2415
2416 /*
2417 * Scan the table headers looking for a signature match
2418 */
2419 for (n = 0; n < len; n++) {
2420 ACPI_TABLE_RSDT *rsdt = (ACPI_TABLE_RSDT *)xsdt;
2421 table_addr = (revision == 1) ? rsdt->TableOffsetEntry[n] :
2422 xsdt->TableOffsetEntry[n];
2423
2424 if (table_addr == 0)
2425 continue;
2426 tp = map_fw_table(table_addr);
2823 /*
2824 * Probe every possible virtual CPU id and remember the
2825 * highest id present; the count of CPUs is one greater
2826 * than this. This tacitly assumes at least cpu 0 is present.
2827 */
2828 max_id = 0;
2829 for (id = 0; id < MAX_VIRT_CPUS; id++)
2830 if (HYPERVISOR_vcpu_op(VCPUOP_is_up, id, NULL) == 0)
2831 max_id = id;
2832
2833 bsetpropsi(BOOT_NCPUS_NAME, max_id+1);
2834
2835 }
2836 #endif /* __xpv */
2837
2838 /*ARGSUSED*/
2839 static void
2840 build_firmware_properties(struct xboot_info *xbp)
2841 {
2842 ACPI_TABLE_HEADER *tp = NULL;
2843
2844 #ifndef __xpv
2845 if (xbp->bi_uefi_arch == XBI_UEFI_ARCH_64) {
2846 bsetprops("efi-systype", "64");
2847 bsetprop64("efi-systab",
2848 (uint64_t)(uintptr_t)xbp->bi_uefi_systab);
2849 if (kbm_debug)
2850 bop_printf(NULL, "64-bit UEFI detected.\n");
2851 } else if (xbp->bi_uefi_arch == XBI_UEFI_ARCH_32) {
2852 bsetprops("efi-systype", "32");
2853 bsetprop64("efi-systab",
2854 (uint64_t)(uintptr_t)xbp->bi_uefi_systab);
2855 if (kbm_debug)
2856 bop_printf(NULL, "32-bit UEFI detected.\n");
2857 }
2858
2859 if (xbp->bi_acpi_rsdp != NULL) {
2860 bsetprop64("acpi-root-tab",
2861 (uint64_t)(uintptr_t)xbp->bi_acpi_rsdp);
2862 }
2863
2864 if (xbp->bi_smbios != NULL) {
2865 bsetprop64("smbios-address",
2866 (uint64_t)(uintptr_t)xbp->bi_smbios);
2867 }
2868
2869 if ((tp = find_fw_table(ACPI_SIG_MSCT)) != NULL)
2870 msct_ptr = process_msct((ACPI_TABLE_MSCT *)tp);
2871 else
2872 msct_ptr = NULL;
2873
2874 if ((tp = find_fw_table(ACPI_SIG_MADT)) != NULL)
2875 process_madt((ACPI_TABLE_MADT *)tp);
2876
2877 if ((srat_ptr = (ACPI_TABLE_SRAT *)
2878 find_fw_table(ACPI_SIG_SRAT)) != NULL)
2879 process_srat(srat_ptr);
2880
2881 if (slit_ptr = (ACPI_TABLE_SLIT *)find_fw_table(ACPI_SIG_SLIT))
2882 process_slit(slit_ptr);
2883
2884 tp = find_fw_table(ACPI_SIG_MCFG);
2885 #else /* __xpv */
2886 enumerate_xen_cpus();
2887 if (DOMAIN_IS_INITDOMAIN(xen_info))
2888 tp = find_fw_table(ACPI_SIG_MCFG);
2889 #endif /* __xpv */
2890 if (tp != NULL)
2891 process_mcfg((ACPI_TABLE_MCFG *)tp);
2892 }
2893
2894 /*
2895 * fake up a boot property for deferred early console output
2896 * this is used by both graphical boot and the (developer only)
2897 * USB serial console
2898 */
2899 void *
2900 defcons_init(size_t size)
2901 {
2902 static char *p = NULL;
2903
2904 p = do_bsys_alloc(NULL, NULL, size, MMU_PAGESIZE);
2905 *p = 0;
2906 bsetprop32("deferred-console-buf", (uint32_t)((uintptr_t)&p));
2907 return (p);
2908 }
|
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 * Copyright (c) 2010, Intel Corporation.
27 * All rights reserved.
28 *
29 * Copyright 2020 Joyent, Inc.
30 */
31
32 /*
33 * This file contains the functionality that mimics the boot operations
34 * on SPARC systems or the old boot.bin/multiboot programs on x86 systems.
35 * The x86 kernel now does everything on its own.
36 */
37
38 #include <sys/types.h>
39 #include <sys/bootconf.h>
40 #include <sys/bootsvcs.h>
41 #include <sys/bootinfo.h>
42 #include <sys/multiboot.h>
43 #include <sys/multiboot2.h>
44 #include <sys/multiboot2_impl.h>
45 #include <sys/bootvfs.h>
46 #include <sys/bootprops.h>
47 #include <sys/varargs.h>
48 #include <sys/param.h>
49 #include <sys/machparam.h>
2254 /* validate the V1.x checksum */
2255 if (checksum_table((uint8_t *)rp, ACPI_RSDP_CHECKSUM_LENGTH) != 0)
2256 return (0);
2257
2258 /* If pre-ACPI 2.0, this is a valid RSDP */
2259 if (rp->Revision < 2)
2260 return (1);
2261
2262 /* validate the V2.x checksum */
2263 if (checksum_table((uint8_t *)rp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)
2264 return (0);
2265
2266 return (1);
2267 }
2268
2269 /*
2270 * Scan memory range for an RSDP;
2271 * see ACPI 3.0 Spec, 5.2.5.1
2272 */
2273 static ACPI_TABLE_RSDP *
2274 scan_rsdp(paddr_t *paddrp, size_t len)
2275 {
2276 paddr_t paddr = *paddrp;
2277 caddr_t ptr;
2278
2279 ptr = vmap_phys(len, paddr);
2280
2281 while (len > 0) {
2282 if (strncmp(ptr, ACPI_SIG_RSDP, strlen(ACPI_SIG_RSDP)) == 0 &&
2283 valid_rsdp((ACPI_TABLE_RSDP *)ptr)) {
2284 *paddrp = paddr;
2285 return ((ACPI_TABLE_RSDP *)ptr);
2286 }
2287
2288 ptr += ACPI_RSDP_SCAN_STEP;
2289 paddr += ACPI_RSDP_SCAN_STEP;
2290 len -= ACPI_RSDP_SCAN_STEP;
2291 }
2292
2293 return (NULL);
2294 }
2295
2296 /*
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.
2308 */
2309
2310 static ACPI_TABLE_RSDP *
2311 find_rsdp(struct xboot_info *xbp)
2312 {
2313 ACPI_TABLE_RSDP *rsdp = NULL;
2314 paddr_t paddr = 0;
2315
2316 if (do_bsys_getproplen(NULL, "acpi-root-tab") == sizeof (uint64_t)) {
2317 (void) do_bsys_getprop(NULL, "acpi-root-tab", &paddr);
2318 rsdp = scan_rsdp(&paddr, sizeof (*rsdp));
2319 }
2320
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
2358 return (rsdp);
2359 }
2360
2361 static ACPI_TABLE_HEADER *
2362 map_fw_table(paddr_t table_addr)
2363 {
2364 ACPI_TABLE_HEADER *tp;
2365 size_t len = MAX(sizeof (*tp), MMU_PAGESIZE);
2366
2367 /*
2368 * Map at least a page; if the table is larger than this, remap it
2369 */
2370 tp = (ACPI_TABLE_HEADER *)vmap_phys(len, table_addr);
2371 if (tp->Length > len)
2372 tp = (ACPI_TABLE_HEADER *)vmap_phys(tp->Length, table_addr);
2373 return (tp);
2374 }
2375
2376 static ACPI_TABLE_HEADER *
2377 find_fw_table(ACPI_TABLE_RSDP *rsdp, char *signature)
2378 {
2379 static int revision = 0;
2380 static ACPI_TABLE_XSDT *xsdt;
2381 static int len;
2382 paddr_t xsdt_addr;
2383 ACPI_TABLE_HEADER *tp;
2384 paddr_t table_addr;
2385 int n;
2386
2387 if (strlen(signature) != ACPI_NAME_SIZE)
2388 return (NULL);
2389
2390 /*
2391 * Reading the ACPI 3.0 Spec, section 5.2.5.3 will help
2392 * understand this code. If we haven't already found the RSDT/XSDT,
2393 * revision will be 0. Find the RSDP and check the revision
2394 * to find out whether to use the RSDT or XSDT. If revision is
2395 * 0 or 1, use the RSDT and set internal revision to 1; if it is 2,
2396 * use the XSDT. If the XSDT address is 0, though, fall back to
2397 * revision 1 and use the RSDT.
2398 */
2399 if (revision == 0) {
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:
2413 /*
2414 * Use the XSDT unless BIOS is buggy and
2415 * claims to be rev 2 but has a null XSDT
2416 * address
2417 */
2418 xsdt_addr = rsdp->XsdtPhysicalAddress;
2419 if (xsdt_addr != 0)
2420 break;
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;
2434 }
2435
2436 if (revision == 0)
2437 return (NULL);
2438
2439 /* cache the XSDT info */
2440 xsdt = (ACPI_TABLE_XSDT *)map_fw_table(xsdt_addr);
2441 len = (xsdt->Header.Length - sizeof (xsdt->Header)) /
2442 ((revision == 1) ? sizeof (uint32_t) : sizeof (uint64_t));
2443 }
2444
2445 /*
2446 * Scan the table headers looking for a signature match
2447 */
2448 for (n = 0; n < len; n++) {
2449 ACPI_TABLE_RSDT *rsdt = (ACPI_TABLE_RSDT *)xsdt;
2450 table_addr = (revision == 1) ? rsdt->TableOffsetEntry[n] :
2451 xsdt->TableOffsetEntry[n];
2452
2453 if (table_addr == 0)
2454 continue;
2455 tp = map_fw_table(table_addr);
2852 /*
2853 * Probe every possible virtual CPU id and remember the
2854 * highest id present; the count of CPUs is one greater
2855 * than this. This tacitly assumes at least cpu 0 is present.
2856 */
2857 max_id = 0;
2858 for (id = 0; id < MAX_VIRT_CPUS; id++)
2859 if (HYPERVISOR_vcpu_op(VCPUOP_is_up, id, NULL) == 0)
2860 max_id = id;
2861
2862 bsetpropsi(BOOT_NCPUS_NAME, max_id+1);
2863
2864 }
2865 #endif /* __xpv */
2866
2867 /*ARGSUSED*/
2868 static void
2869 build_firmware_properties(struct xboot_info *xbp)
2870 {
2871 ACPI_TABLE_HEADER *tp = NULL;
2872 ACPI_TABLE_RSDP *rsdp;
2873
2874 #ifndef __xpv
2875 if (xbp->bi_uefi_arch == XBI_UEFI_ARCH_64) {
2876 bsetprops("efi-systype", "64");
2877 bsetprop64("efi-systab",
2878 (uint64_t)(uintptr_t)xbp->bi_uefi_systab);
2879 if (kbm_debug)
2880 bop_printf(NULL, "64-bit UEFI detected.\n");
2881 } else if (xbp->bi_uefi_arch == XBI_UEFI_ARCH_32) {
2882 bsetprops("efi-systype", "32");
2883 bsetprop64("efi-systab",
2884 (uint64_t)(uintptr_t)xbp->bi_uefi_systab);
2885 if (kbm_debug)
2886 bop_printf(NULL, "32-bit UEFI detected.\n");
2887 }
2888
2889 if (xbp->bi_smbios != NULL) {
2890 bsetprop64("smbios-address",
2891 (uint64_t)(uintptr_t)xbp->bi_smbios);
2892 }
2893
2894 rsdp = find_rsdp(xbp);
2895
2896 if ((tp = find_fw_table(rsdp, ACPI_SIG_MSCT)) != NULL)
2897 msct_ptr = process_msct((ACPI_TABLE_MSCT *)tp);
2898 else
2899 msct_ptr = NULL;
2900
2901 if ((tp = find_fw_table(rsdp, ACPI_SIG_MADT)) != NULL)
2902 process_madt((ACPI_TABLE_MADT *)tp);
2903
2904 if ((srat_ptr = (ACPI_TABLE_SRAT *)
2905 find_fw_table(rsdp, ACPI_SIG_SRAT)) != NULL)
2906 process_srat(srat_ptr);
2907
2908 if (slit_ptr = (ACPI_TABLE_SLIT *)find_fw_table(rsdp, ACPI_SIG_SLIT))
2909 process_slit(slit_ptr);
2910
2911 tp = find_fw_table(rsdp, ACPI_SIG_MCFG);
2912 #else /* __xpv */
2913 enumerate_xen_cpus();
2914 if (DOMAIN_IS_INITDOMAIN(xen_info))
2915 tp = find_fw_table(rsdp, ACPI_SIG_MCFG);
2916 #endif /* __xpv */
2917 if (tp != NULL)
2918 process_mcfg((ACPI_TABLE_MCFG *)tp);
2919 }
2920
2921 /*
2922 * fake up a boot property for deferred early console output
2923 * this is used by both graphical boot and the (developer only)
2924 * USB serial console
2925 */
2926 void *
2927 defcons_init(size_t size)
2928 {
2929 static char *p = NULL;
2930
2931 p = do_bsys_alloc(NULL, NULL, size, MMU_PAGESIZE);
2932 *p = 0;
2933 bsetprop32("deferred-console-buf", (uint32_t)((uintptr_t)&p));
2934 return (p);
2935 }
|