kexec folks asked whether I could export the EFI memory map in /proc for use by their user level tools. Questions: 0) Is this information already available some place I missed? 1) Is /proc/efi_memmap a good name? 2) I used mm/slab.c as my model for using seq_file ... does this look right? -Tony Patch against the "test" branch of my GIT tree. --- diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -22,6 +22,8 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/types.h> #include <linux/time.h> #include <linux/efi.h> @@ -923,3 +925,89 @@ efi_memmap_init(unsigned long *s, unsign *s = (u64)kern_memmap; *e = (u64)++k; } + +#ifdef CONFIG_PROC_FS + +static void *s_start(struct seq_file *m, loff_t *pos) +{ + loff_t n = *pos; + void *efi_map_start, *efi_map_end, *p; + u64 efi_desc_size; + + if (!n) + seq_puts(m, "type start end attributes\n"); + + p = efi_map_start = __va(ia64_boot_param->efi_memmap); + efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; + efi_desc_size = ia64_boot_param->efi_memdesc_size; + + while (n--) { + p += efi_desc_size; + if (p >= efi_map_end) + return NULL; + } + + return p; +} + +static void *s_next(struct seq_file *m, void *p, loff_t *pos) +{ + void *efi_map_start, *efi_map_end; + u64 efi_desc_size; + + ++*pos; + + efi_map_start = __va(ia64_boot_param->efi_memmap); + efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; + efi_desc_size = ia64_boot_param->efi_memdesc_size; + + return (p + efi_desc_size >= efi_map_end) ? NULL : p + efi_desc_size; +} + +static void s_stop(struct seq_file *m, void *p) +{ +} + +static int s_show(struct seq_file *m, void *p) +{ + efi_memory_desc_t *md = p; + + seq_printf(m, "%4d %16.16lx %16.16lx %lx\n", md->type, md->phys_addr, + efi_md_end(md), md->attribute); + + return 0; +} + +static struct seq_operations efimeminfo_op = { + .start = s_start, + .next = s_next, + .stop = s_stop, + .show = s_show, +}; + +static int efimeminfo_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &efimeminfo_op); +} + +static struct file_operations proc_efimeminfo_operations = { + .open = efimeminfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int __init +efi_procmem(void) +{ + struct proc_dir_entry *entry; + + entry = create_proc_entry("efi_memmap", S_IRUGO, NULL); + if (entry) + entry->proc_fops = &proc_efimeminfo_operations; + + return 0; +} +late_initcall(efi_procmem); + +#endif - To unsubscribe from this list: send the line "unsubscribe linux-ia64" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.htmlReceived on Sat Sep 10 09:46:50 2005
This archive was generated by hypermail 2.1.8 : 2005-09-10 09:46:58 EST