summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2011-07-16 19:56:07 +0000
committermarcel <marcel@FreeBSD.org>2011-07-16 19:56:07 +0000
commit21706948a50344e60f249fb0738da4912bd4ba3e (patch)
treee605afdc89490cc8bedec95f3164a10851a60f1d /sys/ia64
parente798ada01f1454e101057b020a078ae7b5766f9a (diff)
downloadFreeBSD-src-21706948a50344e60f249fb0738da4912bd4ba3e.zip
FreeBSD-src-21706948a50344e60f249fb0738da4912bd4ba3e.tar.gz
Add a few more helper functions for working with memory descriptors:
o efi_md_find() - returns the md that covers the given address o efi_md_last() - returns the last md in the list o efi_md_prev() - returns the md that preceeds the given md.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/efi.c55
-rw-r--r--sys/ia64/include/efi.h3
2 files changed, 54 insertions, 4 deletions
diff --git a/sys/ia64/ia64/efi.c b/sys/ia64/ia64/efi.c
index 5cd4518..32868a0 100644
--- a/sys/ia64/ia64/efi.c
+++ b/sys/ia64/ia64/efi.c
@@ -161,20 +161,67 @@ efi_get_time(struct efi_tm *tm)
struct efi_md *
efi_md_first(void)
{
+ struct efi_md *md;
+
+ if (bootinfo->bi_memmap == 0)
+ return (NULL);
+ md = (struct efi_md *)bootinfo->bi_memmap;
+ return (md);
+}
+
+struct efi_md *
+efi_md_last(void)
+{
+ struct efi_md *md;
if (bootinfo->bi_memmap == 0)
return (NULL);
- return ((struct efi_md *)bootinfo->bi_memmap);
+ md = (struct efi_md *)(bootinfo->bi_memmap + bootinfo->bi_memmap_size -
+ bootinfo->bi_memdesc_size);
+ return (md);
}
struct efi_md *
efi_md_next(struct efi_md *md)
{
- uint64_t plim;
+ struct efi_md *lim;
- plim = bootinfo->bi_memmap + bootinfo->bi_memmap_size;
+ lim = efi_md_last();
md = (struct efi_md *)((uintptr_t)md + bootinfo->bi_memdesc_size);
- return ((md >= (struct efi_md *)plim) ? NULL : md);
+ return ((md > lim) ? NULL : md);
+}
+
+struct efi_md *
+efi_md_prev(struct efi_md *md)
+{
+ struct efi_md *lim;
+
+ lim = efi_md_first();
+ md = (struct efi_md *)((uintptr_t)md - bootinfo->bi_memdesc_size);
+ return ((md < lim) ? NULL : md);
+}
+
+struct efi_md *
+efi_md_find(vm_paddr_t pa)
+{
+ static struct efi_md *last = NULL;
+ struct efi_md *md, *p0, *p1;
+
+ md = (last != NULL) ? last : efi_md_first();
+ p1 = p0 = NULL;
+ while (md != NULL && md != p1) {
+ if (pa >= md->md_phys &&
+ pa < md->md_phys + md->md_pages * EFI_PAGE_SIZE) {
+ last = md;
+ return (md);
+ }
+
+ p1 = p0;
+ p0 = md;
+ md = (pa < md->md_phys) ? efi_md_prev(md) : efi_md_next(md);
+ }
+
+ return (NULL);
}
void
diff --git a/sys/ia64/include/efi.h b/sys/ia64/include/efi.h
index f32f3fa..02bef10 100644
--- a/sys/ia64/include/efi.h
+++ b/sys/ia64/include/efi.h
@@ -161,8 +161,11 @@ void efi_boot_finish(void);
int efi_boot_minimal(uint64_t);
void *efi_get_table(struct uuid *);
void efi_get_time(struct efi_tm *);
+struct efi_md *efi_md_find(vm_paddr_t);
struct efi_md *efi_md_first(void);
+struct efi_md *efi_md_last(void);
struct efi_md *efi_md_next(struct efi_md *);
+struct efi_md *efi_md_prev(struct efi_md *);
void efi_reset_system(void);
int efi_set_time(struct efi_tm *);
int efi_var_get(efi_char *, struct uuid *, uint32_t *, size_t *, void *);
OpenPOWER on IntegriCloud