[BACK]Return to efifdt.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / stand / efiboot

Annotation of src/sys/stand/efiboot/efifdt.c, Revision 1.7.2.2

1.7.2.2 ! pgoyette    1: /* $NetBSD: efifdt.c,v 1.7 2018/09/03 00:17:00 jmcneill Exp $ */
        !             2:
        !             3: /*-
        !             4:  * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  *
        !            16:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            17:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            18:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            19:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            20:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            21:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            22:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            24:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            25:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            26:  * SUCH DAMAGE.
        !            27:  */
        !            28:
        !            29: #include "efiboot.h"
        !            30: #include "efifdt.h"
        !            31: #include "efiblock.h"
        !            32:
        !            33: #include <libfdt.h>
        !            34:
        !            35: #define FDT_TABLE_GUID \
        !            36:        { 0xb1b621d5, 0xf19c, 0x41a5, { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } }
        !            37: static EFI_GUID FdtTableGuid = FDT_TABLE_GUID;
        !            38:
        !            39: #define        FDT_MEMORY_NODE_PATH    "/memory"
        !            40: #define        FDT_MEMORY_NODE_NAME    "memory"
        !            41: #define        FDT_CHOSEN_NODE_PATH    "/chosen"
        !            42: #define        FDT_CHOSEN_NODE_NAME    "chosen"
        !            43:
        !            44: #define        FDT_MEMORY_USABLE(_md)  \
        !            45:        ((_md)->Type == EfiLoaderCode || (_md)->Type == EfiLoaderData || \
        !            46:         (_md)->Type == EfiBootServicesCode || (_md)->Type == EfiBootServicesData || \
        !            47:         (_md)->Type == EfiConventionalMemory)
        !            48:
        !            49: static void *fdt_data = NULL;
        !            50:
        !            51: int
        !            52: efi_fdt_probe(void)
        !            53: {
        !            54:        EFI_STATUS status;
        !            55:
        !            56:        status = LibGetSystemConfigurationTable(&FdtTableGuid, &fdt_data);
        !            57:        if (EFI_ERROR(status))
        !            58:                return EIO;
        !            59:
        !            60:        if (fdt_check_header(fdt_data) != 0) {
        !            61:                fdt_data = NULL;
        !            62:                return EINVAL;
        !            63:        }
        !            64:
        !            65:        return 0;
        !            66: }
        !            67:
        !            68: void *
        !            69: efi_fdt_data(void)
        !            70: {
        !            71:        return fdt_data;
        !            72: }
        !            73:
        !            74: int
        !            75: efi_fdt_size(void)
        !            76: {
        !            77:        return fdt_data == NULL ? 0 : fdt_totalsize(fdt_data);
        !            78: }
        !            79:
        !            80: void
        !            81: efi_fdt_show(void)
        !            82: {
        !            83:        const char *model, *compat;
        !            84:        int n, ncompat;
        !            85:
        !            86:        if (fdt_data == NULL)
        !            87:                return;
        !            88:
        !            89:        model = fdt_getprop(fdt_data, fdt_path_offset(fdt_data, "/"), "model", NULL);
        !            90:        if (model)
        !            91:                printf("FDT: %s [", model);
        !            92:        ncompat = fdt_stringlist_count(fdt_data, fdt_path_offset(fdt_data, "/"), "compatible");
        !            93:        for (n = 0; n < ncompat; n++) {
        !            94:                compat = fdt_stringlist_get(fdt_data, fdt_path_offset(fdt_data, "/"),
        !            95:                    "compatible", n, NULL);
        !            96:                printf("%s%s", n == 0 ? "" : ", ", compat);
        !            97:        }
        !            98:        printf("]\n");
        !            99: }
        !           100:
        !           101: void
        !           102: efi_fdt_memory_map(void)
        !           103: {
        !           104:        UINTN nentries = 0, mapkey, descsize;
        !           105:        EFI_MEMORY_DESCRIPTOR *md, *memmap;
        !           106:        UINT32 descver;
        !           107:        UINT64 phys_start, phys_size;
        !           108:        int n, memory;
        !           109:
        !           110:        memory = fdt_path_offset(fdt_data, FDT_MEMORY_NODE_PATH);
        !           111:        if (memory < 0)
        !           112:                memory = fdt_add_subnode(fdt_data, fdt_path_offset(fdt_data, "/"), FDT_MEMORY_NODE_NAME);
        !           113:        if (memory < 0)
        !           114:                panic("FDT: Failed to create " FDT_MEMORY_NODE_PATH " node");
        !           115:
        !           116:        fdt_delprop(fdt_data, memory, "reg");
        !           117:        while (fdt_num_mem_rsv(fdt_data) > 0) {
        !           118:                if (fdt_del_mem_rsv(fdt_data, 0) < 0)
        !           119:                        panic("FDT: Failed to remove reserved memory map entry");
        !           120:        }
        !           121:
        !           122:        const int address_cells = fdt_address_cells(fdt_data, fdt_path_offset(fdt_data, "/"));
        !           123:        const int size_cells = fdt_size_cells(fdt_data, fdt_path_offset(fdt_data, "/"));
        !           124:
        !           125:        memmap = LibMemoryMap(&nentries, &mapkey, &descsize, &descver);
        !           126:        for (n = 0, md = memmap; n < nentries; n++, md = NextMemoryDescriptor(md, descsize)) {
        !           127: #ifdef EFI_MEMORY_DEBUG
        !           128:                printf("MEM: %u: Type 0x%x Attr 0x%lx Phys 0x%lx Virt 0x%lx Size 0x%lx\n",
        !           129:                    n, md->Type, md->Attribute,
        !           130:                    md->PhysicalStart, md->VirtualStart,
        !           131:                    (u_long)md->NumberOfPages * EFI_PAGE_SIZE);
        !           132: #endif
        !           133:                if ((md->Attribute & EFI_MEMORY_WB) == 0)
        !           134:                        continue;
        !           135:                if (!FDT_MEMORY_USABLE(md))
        !           136:                        continue;
        !           137:                if ((address_cells == 1 || size_cells == 1) && md->PhysicalStart + (md->NumberOfPages * EFI_PAGE_SIZE) > 0xffffffff)
        !           138:                        continue;
        !           139:                if (md->NumberOfPages <= 1)
        !           140:                        continue;
        !           141:
        !           142:                phys_start = md->PhysicalStart;
        !           143:                phys_size = md->NumberOfPages * EFI_PAGE_SIZE;
        !           144:
        !           145:                if (phys_start & EFI_PAGE_MASK) {
        !           146:                        /* UEFI spec says these should be 4KB aligned, but U-Boot doesn't always.. */
        !           147:                        phys_start = (phys_start + EFI_PAGE_SIZE) & ~EFI_PAGE_MASK;
        !           148:                        phys_size -= (EFI_PAGE_SIZE * 2);
        !           149:                        if (phys_size == 0)
        !           150:                                continue;
        !           151:                }
        !           152:
        !           153:                if (address_cells == 1)
        !           154:                        fdt_appendprop_u32(fdt_data, fdt_path_offset(fdt_data, FDT_MEMORY_NODE_PATH),
        !           155:                            "reg", (uint32_t)phys_start);
        !           156:                else
        !           157:                        fdt_appendprop_u64(fdt_data, fdt_path_offset(fdt_data, FDT_MEMORY_NODE_PATH),
        !           158:                            "reg", phys_start);
        !           159:
        !           160:                if (size_cells == 1)
        !           161:                        fdt_appendprop_u32(fdt_data, fdt_path_offset(fdt_data, FDT_MEMORY_NODE_PATH),
        !           162:                            "reg", (uint32_t)phys_size);
        !           163:                else
        !           164:                        fdt_appendprop_u64(fdt_data, fdt_path_offset(fdt_data, FDT_MEMORY_NODE_PATH),
        !           165:                            "reg", phys_size);
        !           166:        }
        !           167: }
        !           168:
        !           169: void
        !           170: efi_fdt_bootargs(const char *bootargs)
        !           171: {
        !           172:        struct efi_block_part *bpart = efi_block_boot_part();
        !           173:        int chosen;
        !           174:
        !           175:        chosen = fdt_path_offset(fdt_data, FDT_CHOSEN_NODE_PATH);
        !           176:        if (chosen < 0)
        !           177:                chosen = fdt_add_subnode(fdt_data, fdt_path_offset(fdt_data, "/"), FDT_CHOSEN_NODE_NAME);
        !           178:        if (chosen < 0)
        !           179:                panic("FDT: Failed to create " FDT_CHOSEN_NODE_PATH " node");
        !           180:
        !           181:        if (*bootargs)
        !           182:                fdt_setprop_string(fdt_data, chosen, "bootargs", bootargs);
        !           183:
        !           184:        if (bpart) {
        !           185:                switch (bpart->type) {
        !           186:                case EFI_BLOCK_PART_DISKLABEL:
        !           187:                        fdt_setprop(fdt_data, chosen, "netbsd,mbr",
        !           188:                            bpart->hash, sizeof(bpart->hash));
        !           189:                        fdt_setprop_u32(fdt_data, chosen, "netbsd,partition",
        !           190:                            bpart->index);
        !           191:                        break;
        !           192:                default:
        !           193:                        break;
        !           194:                }
        !           195:        }
        !           196: }

CVSweb <webmaster@jp.NetBSD.org>