This source file includes following definitions.
- memconsole_read
- found_v1_header
- found_v2_header
- memconsole_ebda_init
- memconsole_find
- memconsole_x86_init
- memconsole_x86_exit
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <linux/kernel.h>
  11 #include <linux/module.h>
  12 #include <linux/dmi.h>
  13 #include <linux/mm.h>
  14 #include <asm/bios_ebda.h>
  15 #include <linux/acpi.h>
  16 
  17 #include "memconsole.h"
  18 
  19 #define BIOS_MEMCONSOLE_V1_MAGIC        0xDEADBABE
  20 #define BIOS_MEMCONSOLE_V2_MAGIC        (('M')|('C'<<8)|('O'<<16)|('N'<<24))
  21 
  22 struct biosmemcon_ebda {
  23         u32 signature;
  24         union {
  25                 struct {
  26                         u8  enabled;
  27                         u32 buffer_addr;
  28                         u16 start;
  29                         u16 end;
  30                         u16 num_chars;
  31                         u8  wrapped;
  32                 } __packed v1;
  33                 struct {
  34                         u32 buffer_addr;
  35                         
  36                         u16 num_bytes;
  37                         u16 start;
  38                         u16 end;
  39                 } __packed v2;
  40         };
  41 } __packed;
  42 
  43 static char *memconsole_baseaddr;
  44 static size_t memconsole_length;
  45 
  46 static ssize_t memconsole_read(char *buf, loff_t pos, size_t count)
  47 {
  48         return memory_read_from_buffer(buf, count, &pos, memconsole_baseaddr,
  49                                        memconsole_length);
  50 }
  51 
  52 static void found_v1_header(struct biosmemcon_ebda *hdr)
  53 {
  54         pr_info("memconsole: BIOS console v1 EBDA structure found at %p\n",
  55                 hdr);
  56         pr_info("memconsole: BIOS console buffer at 0x%.8x, start = %d, end = %d, num = %d\n",
  57                 hdr->v1.buffer_addr, hdr->v1.start,
  58                 hdr->v1.end, hdr->v1.num_chars);
  59 
  60         memconsole_baseaddr = phys_to_virt(hdr->v1.buffer_addr);
  61         memconsole_length = hdr->v1.num_chars;
  62         memconsole_setup(memconsole_read);
  63 }
  64 
  65 static void found_v2_header(struct biosmemcon_ebda *hdr)
  66 {
  67         pr_info("memconsole: BIOS console v2 EBDA structure found at %p\n",
  68                 hdr);
  69         pr_info("memconsole: BIOS console buffer at 0x%.8x, start = %d, end = %d, num_bytes = %d\n",
  70                 hdr->v2.buffer_addr, hdr->v2.start,
  71                 hdr->v2.end, hdr->v2.num_bytes);
  72 
  73         memconsole_baseaddr = phys_to_virt(hdr->v2.buffer_addr + hdr->v2.start);
  74         memconsole_length = hdr->v2.end - hdr->v2.start;
  75         memconsole_setup(memconsole_read);
  76 }
  77 
  78 
  79 
  80 
  81 
  82 static bool memconsole_ebda_init(void)
  83 {
  84         unsigned int address;
  85         size_t length, cur;
  86 
  87         address = get_bios_ebda();
  88         if (!address) {
  89                 pr_info("memconsole: BIOS EBDA non-existent.\n");
  90                 return false;
  91         }
  92 
  93         
  94         length = *(u8 *)phys_to_virt(address);
  95         length <<= 10; 
  96 
  97         
  98 
  99 
 100 
 101         for (cur = 0; cur < length; cur++) {
 102                 struct biosmemcon_ebda *hdr = phys_to_virt(address + cur);
 103 
 104                 
 105                 if (hdr->signature == BIOS_MEMCONSOLE_V1_MAGIC) {
 106                         found_v1_header(hdr);
 107                         return true;
 108                 }
 109 
 110                 
 111                 if (hdr->signature == BIOS_MEMCONSOLE_V2_MAGIC) {
 112                         found_v2_header(hdr);
 113                         return true;
 114                 }
 115         }
 116 
 117         pr_info("memconsole: BIOS console EBDA structure not found!\n");
 118         return false;
 119 }
 120 
 121 static const struct dmi_system_id memconsole_dmi_table[] __initconst = {
 122         {
 123                 .ident = "Google Board",
 124                 .matches = {
 125                         DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
 126                 },
 127         },
 128         {}
 129 };
 130 MODULE_DEVICE_TABLE(dmi, memconsole_dmi_table);
 131 
 132 static bool __init memconsole_find(void)
 133 {
 134         if (!dmi_check_system(memconsole_dmi_table))
 135                 return false;
 136 
 137         return memconsole_ebda_init();
 138 }
 139 
 140 static int __init memconsole_x86_init(void)
 141 {
 142         if (!memconsole_find())
 143                 return -ENODEV;
 144 
 145         return memconsole_sysfs_init();
 146 }
 147 
 148 static void __exit memconsole_x86_exit(void)
 149 {
 150         memconsole_exit();
 151 }
 152 
 153 module_init(memconsole_x86_init);
 154 module_exit(memconsole_x86_exit);
 155 
 156 MODULE_AUTHOR("Google, Inc.");
 157 MODULE_LICENSE("GPL");