Annotation of qemu/roms/openbios/libopenbios/linuxbios_info.c, revision 1.1.1.1

1.1       root        1: /* Adapted from Etherboot 5.1.8 */
                      2: 
                      3: #include "config.h"
                      4: #include "sysinclude.h"
                      5: #include "asm/types.h"
                      6: #include "asm/io.h"
                      7: #include "linuxbios.h"
                      8: #include "libopenbios/ipchecksum.h"
                      9: #include "libopenbios/sys_info.h"
                     10: 
                     11: #ifdef CONFIG_DEBUG_BOOT
                     12: #define debug printk
                     13: #else
                     14: #define debug(x...)
                     15: #endif
                     16: 
                     17: #define for_each_lbrec(head, rec) \
                     18:        for(rec = (struct lb_record *)(((char *)head) + sizeof(*head)); \
                     19:                (((char *)rec) < (((char *)head) + sizeof(*head) + head->table_bytes))  && \
                     20:                (rec->size >= 1) && \
                     21:                ((((char *)rec) + rec->size) <= (((char *)head) + sizeof(*head) + head->table_bytes)); \
                     22:                rec = (struct lb_record *)(((char *)rec) + rec->size))
                     23: 
                     24: static void convert_memmap(struct lb_memory *lbmem, struct sys_info *info)
                     25: {
                     26:     int lbcount;
                     27:     int i;
                     28: 
                     29:     lbcount = lbmem->size / sizeof(struct lb_memory_range);
                     30:     info->memrange = malloc(lbcount * sizeof(struct memrange));
                     31:     info->n_memranges = 0;
                     32:     for (i = 0; i < lbcount; i++) {
                     33:        debug("%#016llx %#016llx %d\n",
                     34:               (long long)lbmem->map[i].start, (long long)lbmem->map[i].size,
                     35:               (int) lbmem->map[i].type);
                     36:        if (lbmem->map[i].type != LB_MEM_RAM)
                     37:            continue;
                     38:        info->memrange[info->n_memranges].base = lbmem->map[i].start;
                     39:        info->memrange[info->n_memranges].size = lbmem->map[i].size;
                     40:        info->n_memranges++;
                     41:     }
                     42: }
                     43: 
                     44: static int read_lbtable(struct lb_header *head, struct sys_info *info)
                     45: {
                     46:        int retval = 0;
                     47: 
                     48:        /* Read linuxbios tables... */
                     49:        struct lb_record *rec;
                     50: 
                     51:        for_each_lbrec(head, rec) {
                     52:                switch(rec->tag) {
                     53:                case LB_TAG_MEMORY:
                     54:                        convert_memmap((struct lb_memory *) rec, info);
                     55:                        retval = 1;
                     56:                        break;
                     57:                };
                     58:        }
                     59:        return retval;
                     60: }
                     61: 
                     62: static unsigned long count_lb_records(void *start, unsigned long length)
                     63: {
                     64:        struct lb_record *rec;
                     65:        void *end;
                     66:        unsigned long count;
                     67:        count = 0;
                     68:        end = ((char *)start) + length;
                     69:        for(rec = start; ((void *)rec < end) &&
                     70:                ((signed long)rec->size <=
                     71:                  ((signed long)end - (signed long)rec));
                     72:                rec = (void *)(((char *)rec) + rec->size)) {
                     73:                count++;
                     74:        }
                     75:        return count;
                     76: }
                     77: 
                     78: static int find_lb_table(void *start, void *end, struct lb_header **result)
                     79: {
                     80:        unsigned char *ptr;
                     81:        /* For now be stupid.... */
                     82:        for(ptr = start; (void *)ptr < end; ptr += 16) {
                     83:                struct lb_header *head = (struct lb_header *)ptr;
                     84:                if (    (head->signature[0] != 'L') ||
                     85:                        (head->signature[1] != 'B') ||
                     86:                        (head->signature[2] != 'I') ||
                     87:                        (head->signature[3] != 'O')) {
                     88:                        continue;
                     89:                }
                     90:                if (head->header_bytes != sizeof(*head))
                     91:                        continue;
                     92:                debug("Found canidate at: %p\n", head);
                     93:                if (ipchksum((uint16_t *)head, sizeof(*head)) != 0)
                     94:                        continue;
                     95:                debug("header checksum o.k.\n");
                     96:                if (ipchksum((uint16_t *)(ptr + sizeof(*head)), head->table_bytes) !=
                     97:                        head->table_checksum) {
                     98:                        continue;
                     99:                }
                    100:                debug("table checksum o.k.\n");
                    101:                if (count_lb_records(ptr + sizeof(*head), head->table_bytes) !=
                    102:                        head->table_entries) {
                    103:                        continue;
                    104:                }
                    105:                debug("record count o.k.\n");
                    106:                *result = head;
                    107:                return 1;
                    108:        };
                    109:        return 0;
                    110: }
                    111: 
                    112: void collect_linuxbios_info(struct sys_info *info)
                    113: {
                    114:        struct lb_header *lb_table;
                    115:        int found;
                    116:        debug("Searching for LinuxBIOS tables...\n");
                    117:        found = 0;
                    118:        if (!found) {
                    119:                found = find_lb_table(phys_to_virt(0x00000), phys_to_virt(0x01000), &lb_table);
                    120:        }
                    121:        if (!found) {
                    122:                found = find_lb_table(phys_to_virt(0xf0000), phys_to_virt(0x100000), &lb_table);
                    123:        }
                    124:        if (!found)
                    125:                return;
                    126: 
                    127:        debug("Found LinuxBIOS table at: %p\n", lb_table);
                    128:        info->firmware = "LinuxBIOS";
                    129:        read_lbtable(lb_table, info);
                    130: }

unix.superglobalmegacorp.com

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