diff options
| author | Michael Brown | 2006-03-17 15:16:05 +0100 |
|---|---|---|
| committer | Michael Brown | 2006-03-17 15:16:05 +0100 |
| commit | 013ee958a142a8a12636faa136ea26249074fd59 (patch) | |
| tree | cff5ee767b8a03b98e7750f05d789d708f61784a /src/firmware/linuxbios/linuxbios.c | |
| parent | More purging (diff) | |
| download | ipxe-013ee958a142a8a12636faa136ea26249074fd59.tar.gz ipxe-013ee958a142a8a12636faa136ea26249074fd59.tar.xz ipxe-013ee958a142a8a12636faa136ea26249074fd59.zip | |
These can come back when someone wants to support them
Diffstat (limited to 'src/firmware/linuxbios/linuxbios.c')
| -rw-r--r-- | src/firmware/linuxbios/linuxbios.c | 386 |
1 files changed, 0 insertions, 386 deletions
diff --git a/src/firmware/linuxbios/linuxbios.c b/src/firmware/linuxbios/linuxbios.c deleted file mode 100644 index 0ad66dd58..000000000 --- a/src/firmware/linuxbios/linuxbios.c +++ /dev/null @@ -1,386 +0,0 @@ -#ifdef LINUXBIOS - -#include "etherboot.h" -#include "dev.h" -#include "linuxbios_tables.h" - -struct meminfo meminfo; -static int lb_failsafe = 1; -static unsigned lb_boot[MAX_BOOT_ENTRIES]; -static unsigned lb_boot_index; -static struct cmos_entries lb_countdown; -static struct cmos_checksum lb_checksum; - -#undef DEBUG_LINUXBIOS - -static void set_base_mem_k(struct meminfo *info, unsigned mem_k) -{ - if ((mem_k <= 640) && (info->basememsize <= mem_k)) { - info->basememsize = mem_k; - } -} -static void set_high_mem_k(struct meminfo *info, unsigned mem_k) -{ - /* Shave off a megabyte before playing */ - if (mem_k < 1024) { - return; - } - mem_k -= 1024; - if (info->memsize <= mem_k) { - info->memsize = mem_k; - } -} - -#define for_each_lbrec(head, rec) \ - for(rec = (struct lb_record *)(((char *)head) + sizeof(*head)); \ - (((char *)rec) < (((char *)head) + sizeof(*head) + head->table_bytes)) && \ - (rec->size >= 1) && \ - ((((char *)rec) + rec->size) <= (((char *)head) + sizeof(*head) + head->table_bytes)); \ - rec = (struct lb_record *)(((char *)rec) + rec->size)) - - -#define for_each_crec(tbl, rec) \ - for(rec = (struct lb_record *)(((char *)tbl) + tbl->header_length); \ - (((char *)rec) < (((char *)tbl) + tbl->size)) && \ - (rec->size >= 1) && \ - ((((char *)rec) + rec->size) <= (((char *)tbl) + tbl->size)); \ - rec = (struct lb_record *)(((char *)rec) + rec->size)) - - - -static void read_lb_memory( - struct meminfo *info, struct lb_memory *mem) -{ - int i; - int entries; - entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); - for(i = 0; (i < entries); i++) { - if (info->map_count < E820MAX) { - info->map[info->map_count].addr = mem->map[i].start; - info->map[info->map_count].size = mem->map[i].size; - info->map[info->map_count].type = mem->map[i].type; - info->map_count++; - } - switch(mem->map[i].type) { - case LB_MEM_RAM: - { - unsigned long long end; - unsigned long mem_k; - end = mem->map[i].start + mem->map[i].size; -#if defined(DEBUG_LINUXBIOS) - printf("lb: %X%X - %X%X (ram)\n", - (unsigned long)(mem->map[i].start >>32), - (unsigned long)(mem->map[i].start & 0xFFFFFFFF), - (unsigned long)(end >> 32), - (unsigned long)(end & 0xFFFFFFFF)); -#endif /* DEBUG_LINUXBIOS */ - end >>= 10; - mem_k = end; - if (end & 0xFFFFFFFF00000000ULL) { - mem_k = 0xFFFFFFFF; - } - set_base_mem_k(info, mem_k); - set_high_mem_k(info, mem_k); - break; - } - case LB_MEM_RESERVED: - default: -#if defined(DEBUG_LINUXBIOS) - { - unsigned long long end; - end = mem->map[i].start + mem->map[i].size; - printf("lb: %X%X - %X%X (reserved)\n", - (unsigned long)(mem->map[i].start >>32), - (unsigned long)(mem->map[i].start & 0xFFFFFFFF), - (unsigned long)(end >> 32), - (unsigned long)(end & 0xFFFFFFFF)); - } -#endif /* DEBUG_LINUXBIOS */ - break; - } - } -} - -static unsigned cmos_read(unsigned offset, unsigned int size) -{ - unsigned addr, old_addr; - unsigned value; - - addr = offset/8; - - old_addr = inb(0x70); - outb(addr | (old_addr &0x80), 0x70); - value = inb(0x71); - outb(old_addr, 0x70); - - value >>= offset & 0x7; - value &= ((1 << size) - 1); - - return value; -} - -static unsigned cmos_read_checksum(void) -{ - unsigned sum = - (cmos_read(lb_checksum.location, 8) << 8) | - cmos_read(lb_checksum.location +8, 8); - return sum & 0xffff; -} - -static int cmos_valid(void) -{ - unsigned i; - unsigned sum, old_sum; - sum = 0; - if ((lb_checksum.tag != LB_TAG_OPTION_CHECKSUM) || - (lb_checksum.type != CHECKSUM_PCBIOS) || - (lb_checksum.size != sizeof(lb_checksum))) { - return 0; - } - for(i = lb_checksum.range_start; i <= lb_checksum.range_end; i+= 8) { - sum += cmos_read(i, 8); - } - sum = (~sum)&0x0ffff; - old_sum = cmos_read_checksum(); - return sum == old_sum; -} - -static void cmos_write(unsigned offset, unsigned int size, unsigned setting) -{ - unsigned addr, old_addr; - unsigned value, mask, shift; - unsigned sum; - - addr = offset/8; - - shift = offset & 0x7; - mask = ((1 << size) - 1) << shift; - setting = (setting << shift) & mask; - - old_addr = inb(0x70); - sum = cmos_read_checksum(); - sum = (~sum) & 0xffff; - - outb(addr | (old_addr &0x80), 0x70); - value = inb(0x71); - sum -= value; - value &= ~mask; - value |= setting; - sum += value; - outb(value, 0x71); - - sum = (~sum) & 0x0ffff; - outb((lb_checksum.location/8) | (old_addr & 0x80), 0x70); - outb((sum >> 8) & 0xff, 0x71); - outb(((lb_checksum.location +8)/8) | (old_addr & 0x80), 0x70); - outb(sum & 0xff, 0x71); - - outb(old_addr, 0x70); - - return; -} - -static void read_linuxbios_values(struct meminfo *info, - struct lb_header *head) -{ - /* Read linuxbios tables... */ - struct lb_record *rec; - memset(lb_boot, 0, sizeof(lb_boot)); - for_each_lbrec(head, rec) { - switch(rec->tag) { - case LB_TAG_MEMORY: - { - struct lb_memory *mem; - mem = (struct lb_memory *) rec; - read_lb_memory(info, mem); - break; - } - case LB_TAG_CMOS_OPTION_TABLE: - { - struct cmos_option_table *tbl; - struct lb_record *crec; - struct cmos_entries *entry; - tbl = (struct cmos_option_table *)rec; - for_each_crec(tbl, crec) { - /* Pick off the checksum entry and keep it */ - if (crec->tag == LB_TAG_OPTION_CHECKSUM) { - memcpy(&lb_checksum, crec, sizeof(lb_checksum)); - continue; - } - if (crec->tag != LB_TAG_OPTION) - continue; - entry = (struct cmos_entries *)crec; - if ((entry->bit < 112) || (entry->bit > 1020)) - continue; - /* See if LinuxBIOS came up in fallback or normal mode */ - if (memcmp(entry->name, "last_boot", 10) == 0) { - lb_failsafe = cmos_read(entry->bit, entry->length) == 0; - continue; - } - /* Find where the boot countdown is */ - if (memcmp(entry->name, "boot_countdown", 15) == 0) { - lb_countdown = *entry; - continue; - } - /* Find the default boot index */ - if (memcmp(entry->name, "boot_index", 11) == 0) { - lb_boot_index = cmos_read(entry->bit, entry->length); - continue; - } - /* Now filter for the boot order options */ - if (entry->length != 4) - continue; - if (entry->config != 'e') - continue; - if (memcmp(entry->name, "boot_first", 11) == 0) { - lb_boot[0] = cmos_read(entry->bit, entry->length); - } - else if (memcmp(entry->name, "boot_second", 12) == 0) { - lb_boot[1] = cmos_read(entry->bit, entry->length); - } - else if (memcmp(entry->name, "boot_third", 11) == 0) { - lb_boot[2] = cmos_read(entry->bit, entry->length); - } - } - break; - } - default: - break; - }; - } -} - - - -static unsigned long count_lb_records(void *start, unsigned long length) -{ - struct lb_record *rec; - void *end; - unsigned long count; - count = 0; - end = ((char *)start) + length; - for(rec = start; ((void *)rec < end) && - ((signed long)rec->size <= (end - (void *)rec)); - rec = (void *)(((char *)rec) + rec->size)) { - count++; - } - return count; -} - -static int find_lb_table(void *start, void *end, struct lb_header **result) -{ - unsigned char *ptr; - - /* For now be stupid.... */ - for(ptr = start; virt_to_phys(ptr) < virt_to_phys(end); ptr += 16) { - struct lb_header *head = (struct lb_header *)ptr; - if ( (head->signature[0] != 'L') || - (head->signature[1] != 'B') || - (head->signature[2] != 'I') || - (head->signature[3] != 'O')) { - continue; - } - if (head->header_bytes != sizeof(*head)) - continue; -#if defined(DEBUG_LINUXBIOS) - printf("Found canidate at: %X\n", virt_to_phys(head)); -#endif - if (ipchksum((uint16_t *)head, sizeof(*head)) != 0) - continue; -#if defined(DEBUG_LINUXBIOS) - printf("header checksum o.k.\n"); -#endif - if (ipchksum((uint16_t *)(ptr + sizeof(*head)), head->table_bytes) != - head->table_checksum) { - continue; - } -#if defined(DEBUG_LINUXBIOS) - printf("table checksum o.k.\n"); -#endif - if (count_lb_records(ptr + sizeof(*head), head->table_bytes) != - head->table_entries) { - continue; - } -#if defined(DEBUG_LINUXBIOS) - printf("record count o.k.\n"); -#endif - *result = head; - return 1; - }; - return 0; -} - -void get_memsizes(void) -{ - struct lb_header *lb_table; - int found; -#if defined(DEBUG_LINUXBIOS) - printf("\nSearching for linuxbios tables...\n"); -#endif /* DEBUG_LINUXBIOS */ - found = 0; - meminfo.basememsize = 0; - meminfo.memsize = 0; - meminfo.map_count = 0; - /* This code is specific to linuxBIOS but could - * concievably be extended to work under a normal bios. - * but size is important... - */ - if (!found) { - found = find_lb_table(phys_to_virt(0x00000), phys_to_virt(0x01000), &lb_table); - } - if (!found) { - found = find_lb_table(phys_to_virt(0xf0000), phys_to_virt(0x100000), &lb_table); - } - if (found) { -#if defined (DEBUG_LINUXBIOS) - printf("Found LinuxBIOS table at: %X\n", virt_to_phys(lb_table)); -#endif - read_linuxbios_values(&meminfo, lb_table); - } - -#if defined(DEBUG_LINUXBIOS) - printf("base_mem_k = %d high_mem_k = %d\n", - meminfo.basememsize, meminfo.memsize); -#endif /* DEBUG_LINUXBIOS */ - -} - -unsigned long get_boot_order(unsigned long order, unsigned *index) -{ - static int again; - static int checksum_valid; - static unsigned boot_count; - int i; - - if (!lb_failsafe && !again) { - /* Decrement the boot countdown the first time through */ - checksum_valid = cmos_valid(); - boot_count = cmos_read(lb_countdown.bit, lb_countdown.length); - if (boot_count > 0) { - cmos_write(lb_countdown.bit, lb_countdown.length, boot_count -1); - } - again = 1; - } - if (lb_failsafe || !checksum_valid) { - /* When LinuxBIOS is in failsafe mode, or there is an - * invalid cmos checksum ignore all cmos options - */ - return order; - } - for(i = 0; i < MAX_BOOT_ENTRIES; i++) { - unsigned long boot; - boot = order >> (i*BOOT_BITS) & BOOT_MASK; - boot = lb_boot[i] & BOOT_TYPE_MASK; - if (boot >= BOOT_NOTHING) { - boot = BOOT_NOTHING; - } - if (boot_count == 0) { - boot |= BOOT_FAILSAFE; - } - order &= ~(BOOT_MASK << (i * BOOT_BITS)); - order |= (boot << (i*BOOT_BITS)); - } - *index = lb_boot_index; - return order; -} -#endif /* LINUXBIOS */ |
