Author: emaste
Date: Fri Aug 22 18:09:06 2014
New Revision: 270344
URL: http://svnweb.freebsd.org/changeset/base/270344

Log:
  MFC r263822: amd64: Parse the EFI memory map if present
  
    With this change (and loader.efi from [HEAD]) we can now boot under
    qemu using the OVMF UEFI firmware image with the limitation that a
    serial console is required.
  
  Sponsored by: The FreeBSD Foundation

Modified:
  stable/10/sys/amd64/amd64/machdep.c
  stable/10/sys/amd64/include/metadata.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/amd64/amd64/machdep.c
==============================================================================
--- stable/10/sys/amd64/amd64/machdep.c Fri Aug 22 17:49:24 2014        
(r270343)
+++ stable/10/sys/amd64/amd64/machdep.c Fri Aug 22 18:09:06 2014        
(r270344)
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/callout.h>
 #include <sys/cons.h>
 #include <sys/cpu.h>
+#include <sys/efi.h>
 #include <sys/eventhandler.h>
 #include <sys/exec.h>
 #include <sys/imgact.h>
@@ -1424,6 +1425,100 @@ add_smap_entries(struct bios_smap *smapb
        }
 }
 
+#define efi_next_descriptor(ptr, size) \
+       ((struct efi_md *)(((uint8_t *) ptr) + size))
+
+static void
+add_efi_map_entries(struct efi_map_header *efihdr, vm_paddr_t *physmap,
+    int *physmap_idx)
+{
+       struct efi_md *map, *p;
+       const char *type;
+       size_t efisz;
+       int ndesc, i;
+
+       static const char *types[] = {
+               "Reserved",
+               "LoaderCode",
+               "LoaderData",
+               "BootServicesCode",
+               "BootServicesData",
+               "RuntimeServicesCode",
+               "RuntimeServicesData",
+               "ConventionalMemory",
+               "UnusableMemory",
+               "ACPIReclaimMemory",
+               "ACPIMemoryNVS",
+               "MemoryMappedIO",
+               "MemoryMappedIOPortSpace",
+               "PalCode"
+       };
+
+       /*
+        * Memory map data provided by UEFI via the GetMemoryMap
+        * Boot Services API.
+        */
+       efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
+       map = (struct efi_md *)((uint8_t *)efihdr + efisz); 
+
+       if (efihdr->descriptor_size == 0)
+               return;
+       ndesc = efihdr->memory_size / efihdr->descriptor_size;
+
+       if (boothowto & RB_VERBOSE)
+               printf("%23s %12s %12s %8s %4s\n",
+                   "Type", "Physical", "Virtual", "#Pages", "Attr");
+
+       for (i = 0, p = map; i < ndesc; i++,
+           p = efi_next_descriptor(p, efihdr->descriptor_size)) {
+               if (boothowto & RB_VERBOSE) {
+                       if (p->md_type <= EFI_MD_TYPE_PALCODE)
+                               type = types[p->md_type];
+                       else
+                               type = "<INVALID>";
+                       printf("%23s %012lx %12p %08lx ", type, p->md_phys,
+                           p->md_virt, p->md_pages);
+                       if (p->md_attr & EFI_MD_ATTR_UC)
+                               printf("UC ");
+                       if (p->md_attr & EFI_MD_ATTR_WC)
+                               printf("WC ");
+                       if (p->md_attr & EFI_MD_ATTR_WT)
+                               printf("WT ");
+                       if (p->md_attr & EFI_MD_ATTR_WB)
+                               printf("WB ");
+                       if (p->md_attr & EFI_MD_ATTR_UCE)
+                               printf("UCE ");
+                       if (p->md_attr & EFI_MD_ATTR_WP)
+                               printf("WP ");
+                       if (p->md_attr & EFI_MD_ATTR_RP)
+                               printf("RP ");
+                       if (p->md_attr & EFI_MD_ATTR_XP)
+                               printf("XP ");
+                       if (p->md_attr & EFI_MD_ATTR_RT)
+                               printf("RUNTIME");
+                       printf("\n");
+               }
+
+               switch (p->md_type) {
+               case EFI_MD_TYPE_CODE:
+               case EFI_MD_TYPE_DATA:
+               case EFI_MD_TYPE_BS_CODE:
+               case EFI_MD_TYPE_BS_DATA:
+               case EFI_MD_TYPE_FREE:
+                       /*
+                        * We're allowed to use any entry with these types.
+                        */
+                       break;
+               default:
+                       continue;
+               }
+
+               if (!add_physmap_entry(p->md_phys, (p->md_pages * PAGE_SIZE),
+                   physmap, physmap_idx))
+                       break;
+       }
+}
+
 /*
  * Populate the (physmap) array with base/bound pairs describing the
  * available physical memory in the system, then test this memory and
@@ -1442,18 +1537,24 @@ getmemsize(caddr_t kmdp, u_int64_t first
        u_long physmem_start, physmem_tunable, memtest;
        pt_entry_t *pte;
        struct bios_smap *smapbase;
+       struct efi_map_header *efihdr;
        quad_t dcons_addr, dcons_size;
 
        bzero(physmap, sizeof(physmap));
        basemem = 0;
        physmap_idx = 0;
 
+       efihdr = (struct efi_map_header *)preload_search_info(kmdp,
+           MODINFO_METADATA | MODINFOMD_EFI_MAP);
        smapbase = (struct bios_smap *)preload_search_info(kmdp,
            MODINFO_METADATA | MODINFOMD_SMAP);
-       if (smapbase == NULL)
-               panic("No BIOS smap info from loader!");
 
-       add_smap_entries(smapbase, physmap, &physmap_idx);
+       if (efihdr != NULL)
+               add_efi_map_entries(efihdr, physmap, &physmap_idx);
+       else if (smapbase != NULL)
+               add_smap_entries(smapbase, physmap, &physmap_idx);
+       else
+               panic("No BIOS smap or EFI map info from loader!");
 
        /*
         * Find the 'base memory' segment for SMP

Modified: stable/10/sys/amd64/include/metadata.h
==============================================================================
--- stable/10/sys/amd64/include/metadata.h      Fri Aug 22 17:49:24 2014        
(r270343)
+++ stable/10/sys/amd64/include/metadata.h      Fri Aug 22 18:09:06 2014        
(r270344)
@@ -32,5 +32,12 @@
 #define        MODINFOMD_SMAP          0x1001
 #define        MODINFOMD_SMAP_XATTR    0x1002
 #define        MODINFOMD_DTBP          0x1003
+#define        MODINFOMD_EFI_MAP       0x1004
+
+struct efi_map_header {                                                        
+       size_t          memory_size;
+       size_t          descriptor_size;
+       uint32_t        descriptor_version;
+};
 
 #endif /* !_MACHINE_METADATA_H_ */
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to