Annotation of qemu/pc-bios/bios-pq/0012-load-smbios-entries-and-files-from-qemu.patch, revision 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.