11738dd6eSToomas Soome /*
21738dd6eSToomas Soome * This file and its contents are supplied under the terms of the
31738dd6eSToomas Soome * Common Development and Distribution License ("CDDL"), version 1.0.
41738dd6eSToomas Soome * You may only use this file in accordance with the terms of version
51738dd6eSToomas Soome * 1.0 of the CDDL.
61738dd6eSToomas Soome *
71738dd6eSToomas Soome * A full copy of the text of the CDDL should have accompanied this
81738dd6eSToomas Soome * source. A copy of the CDDL is also available via the Internet at
91738dd6eSToomas Soome * http://www.illumos.org/license/CDDL.
101738dd6eSToomas Soome */
111738dd6eSToomas Soome
121738dd6eSToomas Soome /*
131738dd6eSToomas Soome * Copyright 2016 Toomas Soome <tsoome@me.com>
141738dd6eSToomas Soome */
151738dd6eSToomas Soome
161738dd6eSToomas Soome /*
171738dd6eSToomas Soome * dboot module utility functions for multiboot 2 tags processing.
181738dd6eSToomas Soome */
191738dd6eSToomas Soome
201738dd6eSToomas Soome #include <sys/inttypes.h>
211738dd6eSToomas Soome #include <sys/param.h>
22*111b966eSToomas Soome #include <sys/machparam.h>
231738dd6eSToomas Soome #include <sys/systm.h>
241738dd6eSToomas Soome #include <sys/sysmacros.h>
251738dd6eSToomas Soome #include <sys/multiboot2.h>
261738dd6eSToomas Soome #include <sys/multiboot2_impl.h>
27*111b966eSToomas Soome #include <sys/efi.h>
281738dd6eSToomas Soome
291738dd6eSToomas Soome struct dboot_multiboot2_iterate_ctx;
301738dd6eSToomas Soome
311738dd6eSToomas Soome typedef boolean_t (*dboot_multiboot2_iterate_cb_t)
321738dd6eSToomas Soome (int, multiboot_tag_t *, struct dboot_multiboot2_iterate_ctx *);
331738dd6eSToomas Soome
341738dd6eSToomas Soome struct dboot_multiboot2_iterate_ctx {
351738dd6eSToomas Soome dboot_multiboot2_iterate_cb_t dboot_iter_callback;
361738dd6eSToomas Soome int dboot_iter_index; /* item from set */
371738dd6eSToomas Soome uint32_t dboot_iter_tag; /* tag to search */
381738dd6eSToomas Soome multiboot_tag_t *dboot_iter_tagp; /* search result */
391738dd6eSToomas Soome };
401738dd6eSToomas Soome
411738dd6eSToomas Soome /*
421738dd6eSToomas Soome * Multiboot2 tag list elements are aligned to MULTIBOOT_TAG_ALIGN.
431738dd6eSToomas Soome * To get the next item from the list, we first add the tag's size
441738dd6eSToomas Soome * to the start of the current tag. Next, we round up that address to the
451738dd6eSToomas Soome * nearest MULTIBOOT_TAG_ALIGN address.
461738dd6eSToomas Soome */
471738dd6eSToomas Soome
481738dd6eSToomas Soome static multiboot_tag_t *
dboot_multiboot2_first_tag(multiboot2_info_header_t * mbi)491738dd6eSToomas Soome dboot_multiboot2_first_tag(multiboot2_info_header_t *mbi)
501738dd6eSToomas Soome {
511738dd6eSToomas Soome return (&mbi->mbi_tags[0]);
521738dd6eSToomas Soome }
531738dd6eSToomas Soome
541738dd6eSToomas Soome static multiboot_tag_t *
dboot_multiboot2_next_tag(multiboot_tag_t * tag)551738dd6eSToomas Soome dboot_multiboot2_next_tag(multiboot_tag_t *tag)
561738dd6eSToomas Soome {
571738dd6eSToomas Soome if (tag == NULL || tag->mb_type == MULTIBOOT_TAG_TYPE_END)
581738dd6eSToomas Soome return (NULL);
591738dd6eSToomas Soome
601738dd6eSToomas Soome return ((multiboot_tag_t *)P2ROUNDUP((uintptr_t)tag +
611738dd6eSToomas Soome tag->mb_size, MULTIBOOT_TAG_ALIGN));
621738dd6eSToomas Soome }
631738dd6eSToomas Soome
641738dd6eSToomas Soome /*
651738dd6eSToomas Soome * Walk the tag list until we hit the first instance of a given tag or
661738dd6eSToomas Soome * the end of the list.
671738dd6eSToomas Soome * MB2_NEXT_TAG() will return NULL on end of list.
681738dd6eSToomas Soome */
691738dd6eSToomas Soome static void *
dboot_multiboot2_find_tag_impl(multiboot_tag_t * tagp,uint32_t tag)701738dd6eSToomas Soome dboot_multiboot2_find_tag_impl(multiboot_tag_t *tagp, uint32_t tag)
711738dd6eSToomas Soome {
721738dd6eSToomas Soome while (tagp != NULL && tagp->mb_type != tag) {
731738dd6eSToomas Soome tagp = dboot_multiboot2_next_tag(tagp);
741738dd6eSToomas Soome }
751738dd6eSToomas Soome return (tagp);
761738dd6eSToomas Soome }
771738dd6eSToomas Soome
781738dd6eSToomas Soome /*
791738dd6eSToomas Soome * Walk the entire list to find the first instance of the given tag.
801738dd6eSToomas Soome */
811738dd6eSToomas Soome void *
dboot_multiboot2_find_tag(multiboot2_info_header_t * mbi,uint32_t tag)821738dd6eSToomas Soome dboot_multiboot2_find_tag(multiboot2_info_header_t *mbi, uint32_t tag)
831738dd6eSToomas Soome {
841738dd6eSToomas Soome multiboot_tag_t *tagp = dboot_multiboot2_first_tag(mbi);
851738dd6eSToomas Soome
861738dd6eSToomas Soome return (dboot_multiboot2_find_tag_impl(tagp, tag));
871738dd6eSToomas Soome }
881738dd6eSToomas Soome
891738dd6eSToomas Soome /*
901738dd6eSToomas Soome * dboot_multiboot2_iterate()
911738dd6eSToomas Soome *
921738dd6eSToomas Soome * While most tags in tag list are unique, the modules are specified
931738dd6eSToomas Soome * one module per tag and therefore we need an mechanism to process
941738dd6eSToomas Soome * tags in set.
951738dd6eSToomas Soome *
961738dd6eSToomas Soome * Arguments:
971738dd6eSToomas Soome * mbi: multiboot info header
981738dd6eSToomas Soome * data: callback context.
991738dd6eSToomas Soome *
1001738dd6eSToomas Soome * Return value:
1011738dd6eSToomas Soome * Processed item count.
1021738dd6eSToomas Soome * Callback returning B_TRUE will terminate the iteration.
1031738dd6eSToomas Soome */
1041738dd6eSToomas Soome static int
dboot_multiboot2_iterate(multiboot2_info_header_t * mbi,struct dboot_multiboot2_iterate_ctx * ctx)1051738dd6eSToomas Soome dboot_multiboot2_iterate(multiboot2_info_header_t *mbi,
1061738dd6eSToomas Soome struct dboot_multiboot2_iterate_ctx *ctx)
1071738dd6eSToomas Soome {
1081738dd6eSToomas Soome dboot_multiboot2_iterate_cb_t callback = ctx->dboot_iter_callback;
1091738dd6eSToomas Soome multiboot_tag_t *tagp;
1101738dd6eSToomas Soome uint32_t tag = ctx->dboot_iter_tag;
1111738dd6eSToomas Soome int index = 0;
1121738dd6eSToomas Soome
1131738dd6eSToomas Soome tagp = dboot_multiboot2_find_tag(mbi, tag);
1141738dd6eSToomas Soome while (tagp != NULL) {
1151738dd6eSToomas Soome if (callback != NULL) {
1161738dd6eSToomas Soome if (callback(index, tagp, ctx) == B_TRUE) {
1171738dd6eSToomas Soome return (index + 1);
1181738dd6eSToomas Soome }
1191738dd6eSToomas Soome }
1201738dd6eSToomas Soome tagp = dboot_multiboot2_next_tag(tagp);
1211738dd6eSToomas Soome tagp = dboot_multiboot2_find_tag_impl(tagp, tag);
1221738dd6eSToomas Soome index++;
1231738dd6eSToomas Soome }
1241738dd6eSToomas Soome return (index);
1251738dd6eSToomas Soome }
1261738dd6eSToomas Soome
1271738dd6eSToomas Soome char *
dboot_multiboot2_cmdline(multiboot2_info_header_t * mbi)1281738dd6eSToomas Soome dboot_multiboot2_cmdline(multiboot2_info_header_t *mbi)
1291738dd6eSToomas Soome {
1301738dd6eSToomas Soome multiboot_tag_string_t *tag;
1311738dd6eSToomas Soome
1321738dd6eSToomas Soome tag = dboot_multiboot2_find_tag(mbi, MULTIBOOT_TAG_TYPE_CMDLINE);
1331738dd6eSToomas Soome
1341738dd6eSToomas Soome if (tag != NULL)
1351738dd6eSToomas Soome return (&tag->mb_string[0]);
1361738dd6eSToomas Soome else
1371738dd6eSToomas Soome return (NULL);
1381738dd6eSToomas Soome }
1391738dd6eSToomas Soome
1401738dd6eSToomas Soome /*
1411738dd6eSToomas Soome * Simple callback to index item in set.
1421738dd6eSToomas Soome * Terminates iteration if the indexed item is found.
1431738dd6eSToomas Soome */
1441738dd6eSToomas Soome static boolean_t
dboot_multiboot2_iterate_callback(int index,multiboot_tag_t * tagp,struct dboot_multiboot2_iterate_ctx * ctx)1451738dd6eSToomas Soome dboot_multiboot2_iterate_callback(int index, multiboot_tag_t *tagp,
1461738dd6eSToomas Soome struct dboot_multiboot2_iterate_ctx *ctx)
1471738dd6eSToomas Soome {
1481738dd6eSToomas Soome if (index == ctx->dboot_iter_index) {
1491738dd6eSToomas Soome ctx->dboot_iter_tagp = tagp;
1501738dd6eSToomas Soome return (B_TRUE);
1511738dd6eSToomas Soome }
1521738dd6eSToomas Soome return (B_FALSE);
1531738dd6eSToomas Soome }
1541738dd6eSToomas Soome
1551738dd6eSToomas Soome int
dboot_multiboot2_modcount(multiboot2_info_header_t * mbi)1561738dd6eSToomas Soome dboot_multiboot2_modcount(multiboot2_info_header_t *mbi)
1571738dd6eSToomas Soome {
1581738dd6eSToomas Soome struct dboot_multiboot2_iterate_ctx ctx = {
1591738dd6eSToomas Soome .dboot_iter_callback = NULL,
1601738dd6eSToomas Soome .dboot_iter_index = 0,
1611738dd6eSToomas Soome .dboot_iter_tag = MULTIBOOT_TAG_TYPE_MODULE,
1621738dd6eSToomas Soome .dboot_iter_tagp = NULL
1631738dd6eSToomas Soome };
1641738dd6eSToomas Soome
1651738dd6eSToomas Soome return (dboot_multiboot2_iterate(mbi, &ctx));
1661738dd6eSToomas Soome }
1671738dd6eSToomas Soome
1681738dd6eSToomas Soome uint32_t
dboot_multiboot2_modstart(multiboot2_info_header_t * mbi,int index)1691738dd6eSToomas Soome dboot_multiboot2_modstart(multiboot2_info_header_t *mbi, int index)
1701738dd6eSToomas Soome {
1711738dd6eSToomas Soome multiboot_tag_module_t *tagp;
1721738dd6eSToomas Soome struct dboot_multiboot2_iterate_ctx ctx = {
1731738dd6eSToomas Soome .dboot_iter_callback = dboot_multiboot2_iterate_callback,
1741738dd6eSToomas Soome .dboot_iter_index = index,
1751738dd6eSToomas Soome .dboot_iter_tag = MULTIBOOT_TAG_TYPE_MODULE,
1761738dd6eSToomas Soome .dboot_iter_tagp = NULL
1771738dd6eSToomas Soome };
1781738dd6eSToomas Soome
1791738dd6eSToomas Soome if (dboot_multiboot2_iterate(mbi, &ctx) != 0) {
1801738dd6eSToomas Soome tagp = (multiboot_tag_module_t *)ctx.dboot_iter_tagp;
1811738dd6eSToomas Soome
1821738dd6eSToomas Soome if (tagp != NULL)
1831738dd6eSToomas Soome return (tagp->mb_mod_start);
1841738dd6eSToomas Soome }
1851738dd6eSToomas Soome return (0);
1861738dd6eSToomas Soome }
1871738dd6eSToomas Soome
1881738dd6eSToomas Soome uint32_t
dboot_multiboot2_modend(multiboot2_info_header_t * mbi,int index)1891738dd6eSToomas Soome dboot_multiboot2_modend(multiboot2_info_header_t *mbi, int index)
1901738dd6eSToomas Soome {
1911738dd6eSToomas Soome multiboot_tag_module_t *tagp;
1921738dd6eSToomas Soome struct dboot_multiboot2_iterate_ctx ctx = {
1931738dd6eSToomas Soome .dboot_iter_callback = dboot_multiboot2_iterate_callback,
1941738dd6eSToomas Soome .dboot_iter_index = index,
1951738dd6eSToomas Soome .dboot_iter_tag = MULTIBOOT_TAG_TYPE_MODULE,
1961738dd6eSToomas Soome .dboot_iter_tagp = NULL
1971738dd6eSToomas Soome };
1981738dd6eSToomas Soome
1991738dd6eSToomas Soome if (dboot_multiboot2_iterate(mbi, &ctx) != 0) {
2001738dd6eSToomas Soome tagp = (multiboot_tag_module_t *)ctx.dboot_iter_tagp;
2011738dd6eSToomas Soome
2021738dd6eSToomas Soome if (tagp != NULL)
2031738dd6eSToomas Soome return (tagp->mb_mod_end);
2041738dd6eSToomas Soome }
2051738dd6eSToomas Soome return (0);
2061738dd6eSToomas Soome }
2071738dd6eSToomas Soome
2081738dd6eSToomas Soome char *
dboot_multiboot2_modcmdline(multiboot2_info_header_t * mbi,int index)2091738dd6eSToomas Soome dboot_multiboot2_modcmdline(multiboot2_info_header_t *mbi, int index)
2101738dd6eSToomas Soome {
2111738dd6eSToomas Soome multiboot_tag_module_t *tagp;
2121738dd6eSToomas Soome struct dboot_multiboot2_iterate_ctx ctx = {
2131738dd6eSToomas Soome .dboot_iter_callback = dboot_multiboot2_iterate_callback,
2141738dd6eSToomas Soome .dboot_iter_index = index,
2151738dd6eSToomas Soome .dboot_iter_tag = MULTIBOOT_TAG_TYPE_MODULE,
2161738dd6eSToomas Soome .dboot_iter_tagp = NULL
2171738dd6eSToomas Soome };
2181738dd6eSToomas Soome
2191738dd6eSToomas Soome if (dboot_multiboot2_iterate(mbi, &ctx) != 0) {
2201738dd6eSToomas Soome tagp = (multiboot_tag_module_t *)ctx.dboot_iter_tagp;
2211738dd6eSToomas Soome
2221738dd6eSToomas Soome if (tagp != NULL)
2231738dd6eSToomas Soome return (&tagp->mb_cmdline[0]);
2241738dd6eSToomas Soome }
2251738dd6eSToomas Soome return (NULL);
2261738dd6eSToomas Soome }
2271738dd6eSToomas Soome
2281738dd6eSToomas Soome multiboot_tag_mmap_t *
dboot_multiboot2_get_mmap_tagp(multiboot2_info_header_t * mbi)2291738dd6eSToomas Soome dboot_multiboot2_get_mmap_tagp(multiboot2_info_header_t *mbi)
2301738dd6eSToomas Soome {
2311738dd6eSToomas Soome return (dboot_multiboot2_find_tag(mbi, MULTIBOOT_TAG_TYPE_MMAP));
2321738dd6eSToomas Soome }
2331738dd6eSToomas Soome
234*111b966eSToomas Soome multiboot_tag_efi_mmap_t *
dboot_multiboot2_get_efi_mmap_tagp(multiboot2_info_header_t * mbi)235*111b966eSToomas Soome dboot_multiboot2_get_efi_mmap_tagp(multiboot2_info_header_t *mbi)
236*111b966eSToomas Soome {
237*111b966eSToomas Soome multiboot_tag_efi_mmap_t *tagp;
238*111b966eSToomas Soome
239*111b966eSToomas Soome /* Find tag and check the descriptor version. */
240*111b966eSToomas Soome tagp = dboot_multiboot2_find_tag(mbi, MULTIBOOT_TAG_TYPE_EFI_MMAP);
241*111b966eSToomas Soome if (tagp != NULL &&
242*111b966eSToomas Soome tagp->mb_descr_vers != EFI_MEMORY_DESCRIPTOR_VERSION)
243*111b966eSToomas Soome tagp = NULL;
244*111b966eSToomas Soome
245*111b966eSToomas Soome return (tagp);
246*111b966eSToomas Soome }
247*111b966eSToomas Soome
2481738dd6eSToomas Soome boolean_t
dboot_multiboot2_basicmeminfo(multiboot2_info_header_t * mbi,uint32_t * lower,uint32_t * upper)2491738dd6eSToomas Soome dboot_multiboot2_basicmeminfo(multiboot2_info_header_t *mbi,
2501738dd6eSToomas Soome uint32_t *lower, uint32_t *upper)
2511738dd6eSToomas Soome {
2521738dd6eSToomas Soome multiboot_tag_basic_meminfo_t *mip;
2531738dd6eSToomas Soome
2541738dd6eSToomas Soome mip = dboot_multiboot2_find_tag(mbi, MULTIBOOT_TAG_TYPE_BASIC_MEMINFO);
2551738dd6eSToomas Soome if (mip != NULL) {
2561738dd6eSToomas Soome *lower = mip->mb_mem_lower;
2571738dd6eSToomas Soome *upper = mip->mb_mem_upper;
2581738dd6eSToomas Soome return (B_TRUE);
2591738dd6eSToomas Soome }
2601738dd6eSToomas Soome return (B_FALSE);
2611738dd6eSToomas Soome }
2621738dd6eSToomas Soome
2631738dd6eSToomas Soome /*
2641738dd6eSToomas Soome * Return the type of mmap entry referenced by index.
2651738dd6eSToomas Soome */
266*111b966eSToomas Soome boolean_t
dboot_multiboot2_mmap_get_type(multiboot2_info_header_t * mbi,int index,uint32_t * typep)267*111b966eSToomas Soome dboot_multiboot2_mmap_get_type(multiboot2_info_header_t *mbi, int index,
268*111b966eSToomas Soome uint32_t *typep)
2691738dd6eSToomas Soome {
270*111b966eSToomas Soome multiboot_tag_mmap_t *mb2_mmap_tagp;
2711738dd6eSToomas Soome multiboot_mmap_entry_t *mapentp;
2721738dd6eSToomas Soome
273*111b966eSToomas Soome if (dboot_multiboot2_mmap_nentries(mbi) < index)
274*111b966eSToomas Soome return (B_FALSE);
275*111b966eSToomas Soome
2761738dd6eSToomas Soome mb2_mmap_tagp = dboot_multiboot2_get_mmap_tagp(mbi);
2771738dd6eSToomas Soome if (mb2_mmap_tagp == NULL)
278*111b966eSToomas Soome return (B_FALSE);
2791738dd6eSToomas Soome
280*111b966eSToomas Soome if (dboot_multiboot2_mmap_nentries(mbi) < index)
281*111b966eSToomas Soome return (B_FALSE);
2821738dd6eSToomas Soome
2831738dd6eSToomas Soome mapentp = (multiboot_mmap_entry_t *)(mb2_mmap_tagp->mb_entries +
2841738dd6eSToomas Soome index * mb2_mmap_tagp->mb_entry_size);
285*111b966eSToomas Soome *typep = mapentp->mmap_type;
286*111b966eSToomas Soome return (B_TRUE);
2871738dd6eSToomas Soome }
2881738dd6eSToomas Soome
2891738dd6eSToomas Soome /*
2901738dd6eSToomas Soome * Return the length of mmap entry referenced by index.
2911738dd6eSToomas Soome */
292*111b966eSToomas Soome boolean_t
dboot_multiboot2_mmap_get_length(multiboot2_info_header_t * mbi,int index,uint64_t * lengthp)293*111b966eSToomas Soome dboot_multiboot2_mmap_get_length(multiboot2_info_header_t *mbi, int index,
294*111b966eSToomas Soome uint64_t *lengthp)
2951738dd6eSToomas Soome {
296*111b966eSToomas Soome multiboot_tag_mmap_t *mb2_mmap_tagp;
2971738dd6eSToomas Soome multiboot_mmap_entry_t *mapentp;
2981738dd6eSToomas Soome
299*111b966eSToomas Soome if (dboot_multiboot2_mmap_nentries(mbi) < index)
300*111b966eSToomas Soome return (B_FALSE);
301*111b966eSToomas Soome
3021738dd6eSToomas Soome mb2_mmap_tagp = dboot_multiboot2_get_mmap_tagp(mbi);
3031738dd6eSToomas Soome if (mb2_mmap_tagp == NULL)
304*111b966eSToomas Soome return (B_FALSE);
3051738dd6eSToomas Soome
3061738dd6eSToomas Soome mapentp = (multiboot_mmap_entry_t *)(mb2_mmap_tagp->mb_entries +
3071738dd6eSToomas Soome index * mb2_mmap_tagp->mb_entry_size);
308*111b966eSToomas Soome *lengthp = mapentp->mmap_len;
309*111b966eSToomas Soome return (B_TRUE);
3101738dd6eSToomas Soome }
3111738dd6eSToomas Soome
3121738dd6eSToomas Soome /*
3131738dd6eSToomas Soome * Return the address from mmap entry referenced by index.
3141738dd6eSToomas Soome */
315*111b966eSToomas Soome boolean_t
dboot_multiboot2_mmap_get_base(multiboot2_info_header_t * mbi,int index,uint64_t * basep)316*111b966eSToomas Soome dboot_multiboot2_mmap_get_base(multiboot2_info_header_t *mbi, int index,
317*111b966eSToomas Soome uint64_t *basep)
3181738dd6eSToomas Soome {
319*111b966eSToomas Soome multiboot_tag_mmap_t *mb2_mmap_tagp;
3201738dd6eSToomas Soome multiboot_mmap_entry_t *mapentp;
3211738dd6eSToomas Soome
322*111b966eSToomas Soome if (dboot_multiboot2_mmap_nentries(mbi) < index)
323*111b966eSToomas Soome return (B_FALSE);
324*111b966eSToomas Soome
3251738dd6eSToomas Soome mb2_mmap_tagp = dboot_multiboot2_get_mmap_tagp(mbi);
3261738dd6eSToomas Soome if (mb2_mmap_tagp == NULL)
327*111b966eSToomas Soome return (B_FALSE);
3281738dd6eSToomas Soome
3291738dd6eSToomas Soome mapentp = (multiboot_mmap_entry_t *)(mb2_mmap_tagp->mb_entries +
3301738dd6eSToomas Soome index * mb2_mmap_tagp->mb_entry_size);
331*111b966eSToomas Soome *basep = mapentp->mmap_addr;
332*111b966eSToomas Soome return (B_TRUE);
3331738dd6eSToomas Soome }
3341738dd6eSToomas Soome
3351738dd6eSToomas Soome /*
3361738dd6eSToomas Soome * Count and return the number of mmap entries provided by the tag.
3371738dd6eSToomas Soome */
3381738dd6eSToomas Soome int
dboot_multiboot2_mmap_nentries(multiboot2_info_header_t * mbi)339*111b966eSToomas Soome dboot_multiboot2_mmap_nentries(multiboot2_info_header_t *mbi)
3401738dd6eSToomas Soome {
341*111b966eSToomas Soome multiboot_tag_mmap_t *mb2_mmap_tagp;
3421738dd6eSToomas Soome
343*111b966eSToomas Soome mb2_mmap_tagp = dboot_multiboot2_get_mmap_tagp(mbi);
3441738dd6eSToomas Soome if (mb2_mmap_tagp != NULL) {
3451738dd6eSToomas Soome return ((mb2_mmap_tagp->mb_size -
3461738dd6eSToomas Soome offsetof(multiboot_tag_mmap_t, mb_entries)) /
3471738dd6eSToomas Soome mb2_mmap_tagp->mb_entry_size);
3481738dd6eSToomas Soome }
3491738dd6eSToomas Soome return (0);
3501738dd6eSToomas Soome }
3511738dd6eSToomas Soome
3521738dd6eSToomas Soome /*
353*111b966eSToomas Soome * Return the type of efi mmap entry referenced by index.
354*111b966eSToomas Soome */
355*111b966eSToomas Soome boolean_t
dboot_multiboot2_efi_mmap_get_type(multiboot2_info_header_t * mbi,int index,uint32_t * typep)356*111b966eSToomas Soome dboot_multiboot2_efi_mmap_get_type(multiboot2_info_header_t *mbi, int index,
357*111b966eSToomas Soome uint32_t *typep)
358*111b966eSToomas Soome {
359*111b966eSToomas Soome multiboot_tag_efi_mmap_t *mb2_efi_mmap_tagp;
360*111b966eSToomas Soome EFI_MEMORY_DESCRIPTOR *mapentp;
361*111b966eSToomas Soome
362*111b966eSToomas Soome if (dboot_multiboot2_efi_mmap_nentries(mbi) < index)
363*111b966eSToomas Soome return (B_FALSE);
364*111b966eSToomas Soome
365*111b966eSToomas Soome mb2_efi_mmap_tagp = dboot_multiboot2_get_efi_mmap_tagp(mbi);
366*111b966eSToomas Soome if (mb2_efi_mmap_tagp == NULL)
367*111b966eSToomas Soome return (B_FALSE);
368*111b966eSToomas Soome
369*111b966eSToomas Soome mapentp = (EFI_MEMORY_DESCRIPTOR *)(mb2_efi_mmap_tagp->mb_efi_mmap +
370*111b966eSToomas Soome index * mb2_efi_mmap_tagp->mb_descr_size);
371*111b966eSToomas Soome
372*111b966eSToomas Soome *typep = mapentp->Type;
373*111b966eSToomas Soome return (B_TRUE);
374*111b966eSToomas Soome }
375*111b966eSToomas Soome
376*111b966eSToomas Soome /*
377*111b966eSToomas Soome * Return the length of efi mmap entry referenced by index.
378*111b966eSToomas Soome */
379*111b966eSToomas Soome boolean_t
dboot_multiboot2_efi_mmap_get_length(multiboot2_info_header_t * mbi,int index,uint64_t * lengthp)380*111b966eSToomas Soome dboot_multiboot2_efi_mmap_get_length(multiboot2_info_header_t *mbi, int index,
381*111b966eSToomas Soome uint64_t *lengthp)
382*111b966eSToomas Soome {
383*111b966eSToomas Soome multiboot_tag_efi_mmap_t *mb2_efi_mmap_tagp;
384*111b966eSToomas Soome EFI_MEMORY_DESCRIPTOR *mapentp;
385*111b966eSToomas Soome
386*111b966eSToomas Soome if (dboot_multiboot2_efi_mmap_nentries(mbi) < index)
387*111b966eSToomas Soome return (B_FALSE);
388*111b966eSToomas Soome
389*111b966eSToomas Soome mb2_efi_mmap_tagp = dboot_multiboot2_get_efi_mmap_tagp(mbi);
390*111b966eSToomas Soome if (mb2_efi_mmap_tagp == NULL)
391*111b966eSToomas Soome return (B_FALSE);
392*111b966eSToomas Soome
393*111b966eSToomas Soome mapentp = (EFI_MEMORY_DESCRIPTOR *)(mb2_efi_mmap_tagp->mb_efi_mmap +
394*111b966eSToomas Soome index * mb2_efi_mmap_tagp->mb_descr_size);
395*111b966eSToomas Soome *lengthp = mapentp->NumberOfPages << PAGESHIFT;
396*111b966eSToomas Soome return (B_TRUE);
397*111b966eSToomas Soome }
398*111b966eSToomas Soome
399*111b966eSToomas Soome /*
400*111b966eSToomas Soome * Return the address from efi mmap entry referenced by index.
401*111b966eSToomas Soome */
402*111b966eSToomas Soome boolean_t
dboot_multiboot2_efi_mmap_get_base(multiboot2_info_header_t * mbi,int index,uint64_t * basep)403*111b966eSToomas Soome dboot_multiboot2_efi_mmap_get_base(multiboot2_info_header_t *mbi, int index,
404*111b966eSToomas Soome uint64_t *basep)
405*111b966eSToomas Soome {
406*111b966eSToomas Soome multiboot_tag_efi_mmap_t *mb2_efi_mmap_tagp;
407*111b966eSToomas Soome EFI_MEMORY_DESCRIPTOR *mapentp;
408*111b966eSToomas Soome
409*111b966eSToomas Soome if (dboot_multiboot2_efi_mmap_nentries(mbi) < index)
410*111b966eSToomas Soome return (B_FALSE);
411*111b966eSToomas Soome
412*111b966eSToomas Soome mb2_efi_mmap_tagp = dboot_multiboot2_get_efi_mmap_tagp(mbi);
413*111b966eSToomas Soome if (mb2_efi_mmap_tagp == NULL)
414*111b966eSToomas Soome return (B_FALSE);
415*111b966eSToomas Soome
416*111b966eSToomas Soome mapentp = (EFI_MEMORY_DESCRIPTOR *)(mb2_efi_mmap_tagp->mb_efi_mmap +
417*111b966eSToomas Soome index * mb2_efi_mmap_tagp->mb_descr_size);
418*111b966eSToomas Soome *basep = mapentp->PhysicalStart;
419*111b966eSToomas Soome return (B_TRUE);
420*111b966eSToomas Soome }
421*111b966eSToomas Soome
422*111b966eSToomas Soome /*
423*111b966eSToomas Soome * Count and return the number of efi mmap entries provided by the tag.
424*111b966eSToomas Soome */
425*111b966eSToomas Soome int
dboot_multiboot2_efi_mmap_nentries(multiboot2_info_header_t * mbi)426*111b966eSToomas Soome dboot_multiboot2_efi_mmap_nentries(multiboot2_info_header_t *mbi)
427*111b966eSToomas Soome {
428*111b966eSToomas Soome multiboot_tag_efi_mmap_t *mb2_efi_mmap_tagp;
429*111b966eSToomas Soome
430*111b966eSToomas Soome mb2_efi_mmap_tagp = dboot_multiboot2_get_efi_mmap_tagp(mbi);
431*111b966eSToomas Soome if (mb2_efi_mmap_tagp != NULL) {
432*111b966eSToomas Soome return ((mb2_efi_mmap_tagp->mb_size -
433*111b966eSToomas Soome offsetof(multiboot_tag_efi_mmap_t, mb_efi_mmap)) /
434*111b966eSToomas Soome mb2_efi_mmap_tagp->mb_descr_size);
435*111b966eSToomas Soome }
436*111b966eSToomas Soome return (0);
437*111b966eSToomas Soome }
438*111b966eSToomas Soome
439*111b966eSToomas Soome /*
4401738dd6eSToomas Soome * Return the highest address used by info header.
4411738dd6eSToomas Soome */
4421738dd6eSToomas Soome paddr_t
dboot_multiboot2_highest_addr(multiboot2_info_header_t * mbi)4431738dd6eSToomas Soome dboot_multiboot2_highest_addr(multiboot2_info_header_t *mbi)
4441738dd6eSToomas Soome {
4451738dd6eSToomas Soome return ((paddr_t)(uintptr_t)mbi + mbi->mbi_total_size);
4461738dd6eSToomas Soome }
447