Annotation of qemu/pc-bios/bios-pq/0012-load-smbios-entries-and-files-from-qemu.patch, revision 1.1.1.1

1.1       root        1: qemu:bios: Load SMBIOS entries and files from qemu (Alex Williamson)
                      2: 
                      3: Allow SMBIOS fields to be overridden and entries replaced by those
                      4: read from qemu.
                      5: 
                      6: Signed-off-by: Alex Williamson <[email protected]>
                      7: Signed-off-by: Anthony Liguori <[email protected]>
                      8: 
                      9: diff --git a/bios/rombios32.c b/bios/rombios32.c
                     10: index 7be4216..1a1ed64 100644
                     11: --- a/bios/rombios32.c
                     12: +++ b/bios/rombios32.c
                     13: @@ -441,7 +441,6 @@ uint32_t cpuid_features;
                     14:  uint32_t cpuid_ext_features;
                     15:  unsigned long ram_size;
                     16:  uint64_t ram_end;
                     17: -uint8_t bios_uuid[16];
                     18:  #ifdef BX_USE_EBDA_TABLES
                     19:  unsigned long ebda_cur_addr;
                     20:  #endif
                     21: @@ -471,6 +470,7 @@ void wrmsr_smp(uint32_t index, uint64_t val)
                     22:  #define QEMU_CFG_UUID       0x02
                     23:  #define QEMU_CFG_ARCH_LOCAL     0x8000
                     24:  #define QEMU_CFG_ACPI_TABLES  (QEMU_CFG_ARCH_LOCAL + 0)
                     25: +#define QEMU_CFG_SMBIOS_ENTRIES  (QEMU_CFG_ARCH_LOCAL + 1)
                     26:  
                     27:  int qemu_cfg_port;
                     28:  
                     29: @@ -519,19 +519,17 @@ static int acpi_load_table(int i, uint32_t addr, uint16_t *len)
                     30:      qemu_cfg_read((uint8_t*)addr, *len);
                     31:      return 0;
                     32:  }
                     33: -#endif
                     34:  
                     35: -void uuid_probe(void)
                     36: +static uint16_t smbios_entries(void)
                     37:  {
                     38: -#ifdef BX_QEMU
                     39: -    if(qemu_cfg_port) {
                     40: -        qemu_cfg_select(QEMU_CFG_UUID);
                     41: -        qemu_cfg_read(bios_uuid, 16);
                     42: -        return;
                     43: -    }
                     44: -#endif
                     45: -    memset(bios_uuid, 0, 16);
                     46: +    uint16_t cnt;
                     47: +
                     48: +    qemu_cfg_select(QEMU_CFG_SMBIOS_ENTRIES);
                     49: +    qemu_cfg_read((uint8_t*)&cnt, sizeof(cnt));
                     50: +
                     51: +    return cnt;
                     52:  }
                     53: +#endif
                     54:  
                     55:  void cpu_probe(void)
                     56:  {
                     57: @@ -1963,21 +1961,105 @@ smbios_entry_point_init(void *start,
                     58:      ep->intermediate_checksum = -sum;
                     59:      }
                     60:  
                     61: +struct smbios_header {
                     62: +    uint16_t length;
                     63: +    uint8_t type;
                     64: +} __attribute__((__packed__));
                     65: +
                     66: +struct smbios_field {
                     67: +    struct smbios_header header;
                     68: +    uint8_t type;
                     69: +    uint16_t offset;
                     70: +    uint8_t data[];
                     71: +} __attribute__((__packed__));
                     72: +
                     73: +struct smbios_table {
                     74: +    struct smbios_header header;
                     75: +    uint8_t data[];
                     76: +} __attribute__((__packed__));
                     77: +
                     78: +#define SMBIOS_FIELD_ENTRY 0
                     79: +#define SMBIOS_TABLE_ENTRY 1
                     80: +
                     81: +static size_t
                     82: +smbios_load_field(int type, size_t offset, void *addr)
                     83: +{
                     84: +#ifdef BX_QEMU
                     85: +    int i;
                     86: +
                     87: +    for (i = smbios_entries(); i > 0; i--) {
                     88: +        struct smbios_field field;
                     89: +
                     90: +        qemu_cfg_read((uint8_t *)&field, sizeof(struct smbios_header));
                     91: +        field.header.length -= sizeof(struct smbios_header);
                     92: +
                     93: +        if (field.header.type != SMBIOS_FIELD_ENTRY) {
                     94: +            while (field.header.length--)
                     95: +                inb(QEMU_CFG_DATA_PORT);
                     96: +            continue;
                     97: +        }
                     98: +
                     99: +        qemu_cfg_read((uint8_t *)&field.type,
                    100: +                      sizeof(field) - sizeof(struct smbios_header));
                    101: +        field.header.length -= sizeof(field) - sizeof(struct smbios_header);
                    102: +
                    103: +        if (field.type != type || field.offset != offset) {
                    104: +            while (field.header.length--)
                    105: +                inb(QEMU_CFG_DATA_PORT);
                    106: +            continue;
                    107: +        }
                    108: +
                    109: +        qemu_cfg_read(addr, field.header.length);
                    110: +        return (size_t)field.header.length;
                    111: +    }
                    112: +#endif
                    113: +    return 0;
                    114: +}
                    115: + 
                    116: +#define load_str_field_with_default(type, field, def) do {             \
                    117: +    size = smbios_load_field(type, offsetof(struct smbios_type_##type, \
                    118: +                                            field), end);              \
                    119: +    if (size > 0) {                                                    \
                    120: +        end += size;                                                   \
                    121: +    } else {                                                           \
                    122: +        memcpy(end, def, sizeof(def));                                 \
                    123: +        end += sizeof(def);                                            \
                    124: +    }                                                                  \
                    125: +    p->field = ++str_index;                                            \
                    126: +} while (0)
                    127: +
                    128: +#define load_str_field_or_skip(type, field) do {                       \
                    129: +    size = smbios_load_field(type, offsetof(struct smbios_type_##type, \
                    130: +                                            field), end);              \
                    131: +    if (size > 0) {                                                    \
                    132: +        end += size;                                                   \
                    133: +        p->field = ++str_index;                                        \
                    134: +    } else {                                                           \
                    135: +        p->field = 0;                                                  \
                    136: +    }                                                                  \
                    137: +} while (0)
                    138: +
                    139:  /* Type 0 -- BIOS Information */
                    140:  #define RELEASE_DATE_STR "01/01/2007"
                    141:  static void *
                    142: -smbios_type_0_init(void *start)
                    143: +smbios_init_type_0(void *start)
                    144:  {
                    145:      struct smbios_type_0 *p = (struct smbios_type_0 *)start;
                    146: +    char *end = (char *)start + sizeof(struct smbios_type_0);
                    147: +    size_t size;
                    148: +    int str_index = 0;
                    149:  
                    150:      p->header.type = 0;
                    151:      p->header.length = sizeof(struct smbios_type_0);
                    152:      p->header.handle = 0;
                    153:  
                    154: -    p->vendor_str = 1;
                    155: -    p->bios_version_str = 1;
                    156: +    load_str_field_with_default(0, vendor_str, BX_APPNAME);
                    157: +    load_str_field_with_default(0, bios_version_str, BX_APPNAME);
                    158: +
                    159:      p->bios_starting_address_segment = 0xe800;
                    160: -    p->bios_release_date_str = 2;
                    161: +
                    162: +    load_str_field_with_default(0, bios_release_date_str, RELEASE_DATE_STR);
                    163: +
                    164:      p->bios_rom_size = 0; /* FIXME */
                    165:  
                    166:      memset(p->bios_characteristics, 0, 8);
                    167: @@ -1985,50 +2067,66 @@ smbios_type_0_init(void *start)
                    168:      p->bios_characteristics_extension_bytes[0] = 0;
                    169:      p->bios_characteristics_extension_bytes[1] = 0;
                    170:  
                    171: -    p->system_bios_major_release = 1;
                    172: -    p->system_bios_minor_release = 0;
                    173: +    if (!smbios_load_field(0, offsetof(struct smbios_type_0,
                    174: +                                       system_bios_major_release),
                    175: +                           &p->system_bios_major_release))
                    176: +        p->system_bios_major_release = 1;
                    177: +
                    178: +    if (!smbios_load_field(0, offsetof(struct smbios_type_0,
                    179: +                                       system_bios_minor_release),
                    180: +                           &p->system_bios_minor_release))
                    181: +        p->system_bios_minor_release = 0;
                    182: +
                    183:      p->embedded_controller_major_release = 0xff;
                    184:      p->embedded_controller_minor_release = 0xff;
                    185:  
                    186: -    start += sizeof(struct smbios_type_0);
                    187: -    memcpy((char *)start, BX_APPNAME, sizeof(BX_APPNAME));
                    188: -    start += sizeof(BX_APPNAME);
                    189: -    memcpy((char *)start, RELEASE_DATE_STR, sizeof(RELEASE_DATE_STR));
                    190: -    start += sizeof(RELEASE_DATE_STR);
                    191: -    *((uint8_t *)start) = 0;
                    192: +    *end = 0;
                    193: +    end++;
                    194:  
                    195: -    return start+1;
                    196: +    return end;
                    197:  }
                    198:  
                    199:  /* Type 1 -- System Information */
                    200:  static void *
                    201: -smbios_type_1_init(void *start)
                    202: +smbios_init_type_1(void *start)
                    203:  {
                    204:      struct smbios_type_1 *p = (struct smbios_type_1 *)start;
                    205: +    char *end = (char *)start + sizeof(struct smbios_type_1);
                    206: +    size_t size;
                    207: +    int str_index = 0;
                    208: +
                    209:      p->header.type = 1;
                    210:      p->header.length = sizeof(struct smbios_type_1);
                    211:      p->header.handle = 0x100;
                    212:  
                    213: -    p->manufacturer_str = 0;
                    214: -    p->product_name_str = 0;
                    215: -    p->version_str = 0;
                    216: -    p->serial_number_str = 0;
                    217: +    load_str_field_or_skip(1, manufacturer_str);
                    218: +    load_str_field_or_skip(1, product_name_str);
                    219: +    load_str_field_or_skip(1, version_str);
                    220: +    load_str_field_or_skip(1, serial_number_str);
                    221:  
                    222: -    memcpy(p->uuid, bios_uuid, 16);
                    223: +    size = smbios_load_field(1, offsetof(struct smbios_type_1,
                    224: +                                         uuid), &p->uuid);
                    225: +    if (size == 0)
                    226: +        memset(p->uuid, 0, 16);
                    227:  
                    228:      p->wake_up_type = 0x06; /* power switch */
                    229: -    p->sku_number_str = 0;
                    230: -    p->family_str = 0;
                    231:  
                    232: -    start += sizeof(struct smbios_type_1);
                    233: -    *((uint16_t *)start) = 0;
                    234: +    load_str_field_or_skip(1, sku_number_str);
                    235: +    load_str_field_or_skip(1, family_str);
                    236:  
                    237: -    return start+2;
                    238: +    *end = 0;
                    239: +    end++;
                    240: +    if (!str_index) {
                    241: +        *end = 0;
                    242: +        end++;
                    243: +    }
                    244: +
                    245: +    return end;
                    246:  }
                    247:  
                    248:  /* Type 3 -- System Enclosure */
                    249:  static void *
                    250: -smbios_type_3_init(void *start)
                    251: +smbios_init_type_3(void *start)
                    252:  {
                    253:      struct smbios_type_3 *p = (struct smbios_type_3 *)start;
                    254:  
                    255: @@ -2058,7 +2156,7 @@ smbios_type_3_init(void *start)
                    256:  
                    257:  /* Type 4 -- Processor Information */
                    258:  static void *
                    259: -smbios_type_4_init(void *start, unsigned int cpu_number)
                    260: +smbios_init_type_4(void *start, unsigned int cpu_number)
                    261:  {
                    262:      struct smbios_type_4 *p = (struct smbios_type_4 *)start;
                    263:  
                    264: @@ -2098,7 +2196,7 @@ smbios_type_4_init(void *start, unsigned int cpu_number)
                    265:  
                    266:  /* Type 16 -- Physical Memory Array */
                    267:  static void *
                    268: -smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs)
                    269: +smbios_init_type_16(void *start, uint32_t memsize, int nr_mem_devs)
                    270:  {
                    271:      struct smbios_type_16 *p = (struct smbios_type_16*)start;
                    272:  
                    273: @@ -2121,7 +2219,7 @@ smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs)
                    274:  
                    275:  /* Type 17 -- Memory Device */
                    276:  static void *
                    277: -smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance)
                    278: +smbios_init_type_17(void *start, uint32_t memory_size_mb, int instance)
                    279:  {
                    280:      struct smbios_type_17 *p = (struct smbios_type_17 *)start;
                    281:  
                    282: @@ -2151,7 +2249,7 @@ smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance)
                    283:  
                    284:  /* Type 19 -- Memory Array Mapped Address */
                    285:  static void *
                    286: -smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance)
                    287: +smbios_init_type_19(void *start, uint32_t memory_size_mb, int instance)
                    288:  {
                    289:      struct smbios_type_19 *p = (struct smbios_type_19 *)start;
                    290:  
                    291: @@ -2172,7 +2270,7 @@ smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance)
                    292:  
                    293:  /* Type 20 -- Memory Device Mapped Address */
                    294:  static void *
                    295: -smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance)
                    296: +smbios_init_type_20(void *start, uint32_t memory_size_mb, int instance)
                    297:  {
                    298:      struct smbios_type_20 *p = (struct smbios_type_20 *)start;
                    299:  
                    300: @@ -2196,7 +2294,7 @@ smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance)
                    301:  
                    302:  /* Type 32 -- System Boot Information */
                    303:  static void *
                    304: -smbios_type_32_init(void *start)
                    305: +smbios_init_type_32(void *start)
                    306:  {
                    307:      struct smbios_type_32 *p = (struct smbios_type_32 *)start;
                    308:  
                    309: @@ -2214,7 +2312,7 @@ smbios_type_32_init(void *start)
                    310:  
                    311:  /* Type 127 -- End of Table */
                    312:  static void *
                    313: -smbios_type_127_init(void *start)
                    314: +smbios_init_type_127(void *start)
                    315:  {
                    316:      struct smbios_type_127 *p = (struct smbios_type_127 *)start;
                    317:  
                    318: @@ -2228,6 +2326,78 @@ smbios_type_127_init(void *start)
                    319:      return start + 2;
                    320:  }
                    321:  
                    322: +static int
                    323: +smbios_load_external(int type, char **p, unsigned *nr_structs,
                    324: +                     unsigned *max_struct_size)
                    325: +{
                    326: +#ifdef BX_QEMU
                    327: +    static uint64_t used_bitmap[4] = { 0 };
                    328: +    char *start = *p;
                    329: +    int i;
                    330: +
                    331: +    /* Check if we've already reported these tables */
                    332: +    if (used_bitmap[(type >> 6) & 0x3] & (1ULL << (type & 0x3f)))
                    333: +        return 1;
                    334: +
                    335: +    /* Don't introduce spurious end markers */
                    336: +    if (type == 127)
                    337: +        return 0;
                    338: +
                    339: +    for (i = smbios_entries(); i > 0; i--) {
                    340: +        struct smbios_table table;
                    341: +        struct smbios_structure_header *header = (void *)*p;
                    342: +        int string;
                    343: +
                    344: +        qemu_cfg_read((uint8_t *)&table, sizeof(struct smbios_header));
                    345: +        table.header.length -= sizeof(struct smbios_header);
                    346: +
                    347: +        if (table.header.type != SMBIOS_TABLE_ENTRY) {
                    348: +            while (table.header.length--)
                    349: +                inb(QEMU_CFG_DATA_PORT);
                    350: +            continue;
                    351: +        }
                    352: +
                    353: +        qemu_cfg_read((uint8_t *)*p, sizeof(struct smbios_structure_header));
                    354: +        table.header.length -= sizeof(struct smbios_structure_header);
                    355: +
                    356: +        if (header->type != type) {
                    357: +            while (table.header.length--)
                    358: +                inb(QEMU_CFG_DATA_PORT);
                    359: +            continue;
                    360: +        }
                    361: +
                    362: +        *p += sizeof(struct smbios_structure_header);
                    363: +
                    364: +        /* Entries end with a double NULL char, if there's a string at
                    365: +         * the end (length is greater than formatted length), the string
                    366: +         * terminator provides the first NULL. */
                    367: +        string = header->length < table.header.length +
                    368: +                 sizeof(struct smbios_structure_header);
                    369: +
                    370: +        /* Read the rest and terminate the entry */
                    371: +        qemu_cfg_read((uint8_t *)*p, table.header.length);
                    372: +        *p += table.header.length;
                    373: +        *((uint8_t*)*p) = 0;
                    374: +        (*p)++;
                    375: +        if (!string) {
                    376: +            *((uint8_t*)*p) = 0;
                    377: +            (*p)++;
                    378: +        }
                    379: +
                    380: +        (*nr_structs)++;
                    381: +        if (*p - (char *)header > *max_struct_size)
                    382: +            *max_struct_size = *p - (char *)header;
                    383: +    }
                    384: +
                    385: +    /* Mark that we've reported on this type */
                    386: +    used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
                    387: +
                    388: +    return (start != *p);
                    389: +#else /* !BX_QEMU */
                    390: +    return 0;
                    391: +#endif
                    392: +}
                    393: +
                    394:  void smbios_init(void)
                    395:  {
                    396:      unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
                    397: @@ -2246,34 +2416,39 @@ void smbios_init(void)
                    398:  
                    399:        p = (char *)start + sizeof(struct smbios_entry_point);
                    400:  
                    401: -#define add_struct(fn) do{ \
                    402: -    q = (fn); \
                    403: -    nr_structs++; \
                    404: -    if ((q - p) > max_struct_size) \
                    405: -        max_struct_size = q - p; \
                    406: -    p = q; \
                    407: -}while (0)
                    408: -
                    409: -    add_struct(smbios_type_0_init(p));
                    410: -    add_struct(smbios_type_1_init(p));
                    411: -    add_struct(smbios_type_3_init(p));
                    412: +#define add_struct(type, args...) do {                                    \
                    413: +    if (!smbios_load_external(type, &p, &nr_structs, &max_struct_size)) { \
                    414: +        q = smbios_init_type_##type(args);                                \
                    415: +        nr_structs++;                                                     \
                    416: +        if ((q - p) > max_struct_size)                                    \
                    417: +            max_struct_size = q - p;                                      \
                    418: +        p = q;                                                            \
                    419: +    }                                                                     \
                    420: +} while (0)
                    421: +
                    422: +    add_struct(0, p);
                    423: +    add_struct(1, p);
                    424: +    add_struct(3, p);
                    425:      for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
                    426: -        add_struct(smbios_type_4_init(p, cpu_num));
                    427: +        add_struct(4, p, cpu_num);
                    428:  
                    429:      /* Each 'memory device' covers up to 16GB of address space. */
                    430:      nr_mem_devs = (memsize + 0x3fff) >> 14;
                    431: -    add_struct(smbios_type_16_init(p, memsize, nr_mem_devs));
                    432: +    add_struct(16, p, memsize, nr_mem_devs);
                    433:      for ( i = 0; i < nr_mem_devs; i++ )
                    434:      {
                    435:          uint32_t dev_memsize = ((i == (nr_mem_devs - 1))
                    436:                                  ? (((memsize-1) & 0x3fff)+1) : 0x4000);
                    437: -        add_struct(smbios_type_17_init(p, dev_memsize, i));
                    438: -        add_struct(smbios_type_19_init(p, dev_memsize, i));
                    439: -        add_struct(smbios_type_20_init(p, dev_memsize, i));
                    440: +        add_struct(17, p, dev_memsize, i);
                    441: +        add_struct(19, p, dev_memsize, i);
                    442: +        add_struct(20, p, dev_memsize, i);
                    443:      }
                    444:  
                    445: -    add_struct(smbios_type_32_init(p));
                    446: -    add_struct(smbios_type_127_init(p));
                    447: +    add_struct(32, p);
                    448: +    /* Add any remaining provided entries before the end marker */
                    449: +    for (i = 0; i < 256; i++)
                    450: +        smbios_load_external(i, &p, &nr_structs, &max_struct_size);
                    451: +    add_struct(127, p);
                    452:  
                    453:  #undef add_struct
                    454:  
                    455: @@ -2380,8 +2555,6 @@ void rombios32_init(uint32_t *s3_resume_vector, uint8_t *shutdown_flag)
                    456:  
                    457:          mptable_init();
                    458:  
                    459: -        uuid_probe();
                    460: -
                    461:          smbios_init();
                    462:  
                    463:          if (acpi_enabled)
                    464: 
                    465: 
                    466: --
                    467: To unsubscribe from this list: send the line "unsubscribe kvm" in
                    468: the body of a message to [email protected]
                    469: More majordomo info at  http://vger.kernel.org/majordomo-info.html
                    470: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.