/* linuxbios.c - MemTest-86  Version 3.3
 *
 * Released under version 2 of the Gnu Public License.
 * By Eric Biederman
 */

#include "linuxbios_tables.h"
#include "test.h"

static unsigned long ip_compute_csum(void *addr, unsigned long length)
{
	uint16_t *ptr;
	unsigned long sum;
	unsigned long len;
	unsigned long laddr;
	/* compute an ip style checksum */
	laddr = (unsigned long )addr;
	sum = 0;
	if (laddr & 1) {
		uint16_t buffer;
		unsigned char *ptr;
		/* copy the first byte into a 2 byte buffer.
		 * This way automatically handles the endian question
		 * of which byte (low or high) the last byte goes in.
		 */
		buffer = 0;
		ptr = addr;
		memmove(&buffer, ptr, 1);
		sum += buffer;
		if (sum > 0xFFFF)
			sum -= 0xFFFF;
		length -= 1;
		addr = ptr +1;
		
	}
	len = length >> 1;
	ptr = addr;
	while (len--) {
		sum += *(ptr++);
		if (sum > 0xFFFF)
			sum -= 0xFFFF;
	}
	addr = ptr;
	if (length & 1) {
		uint16_t buffer;
		unsigned char *ptr;
		/* copy the last byte into a 2 byte buffer.
		 * This way automatically handles the endian question
		 * of which byte (low or high) the last byte goes in.
		 */
		buffer = 0;
		ptr = addr;
		memmove(&buffer, ptr, 1);
		sum += buffer;
		if (sum > 0xFFFF)
			sum -= 0xFFFF;
	}
	return (~sum) & 0xFFFF;
	
}

#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)) 
		

static int count_lb_records(struct lb_header *head)
{
	struct lb_record *rec;
	int count;
	count = 0;
	for_each_lbrec(head, rec) {
		count++;
	}
	return count;
}

static struct lb_header * __find_lb_table(unsigned long start, unsigned long end)
{
	unsigned long addr;
	/* For now be stupid.... */
	for(addr = start; addr < end; addr += 16) {
		struct lb_header *head = (struct lb_header *)addr;
		struct lb_record *recs = (struct lb_record *)(addr + sizeof(*head));
		if (memcmp(head->signature, "LBIO", 4) != 0)
			continue;
		if (head->header_bytes != sizeof(*head))
			continue;
		if (ip_compute_csum((unsigned char *)head, sizeof(*head)) != 0)
			continue;
		if (ip_compute_csum((unsigned char *)recs, head->table_bytes) 
			!= head->table_checksum)
			continue;
		if (count_lb_records(head) != head->table_entries)
			continue;
		return head;
	};
	return 0;
}

static struct lb_header * find_lb_table(void)
{
	struct lb_header *head;

	/* First try at address 0 */
	head = __find_lb_table(0x00000, 0x1000);

	if (!head) {
		/* Then try at address 0xf0000 */
		head = __find_lb_table(0xf0000, 0x100000);
	}

	if (head) {
		struct lb_record *rec;

		/* Check whether there is a forward header */
		for_each_lbrec(head, rec) {
			if (rec->tag == LB_TAG_FORWARD) {
				struct lb_hwrpb *forward =
					(struct lb_hwrpb *)rec;
				head = __find_lb_table
					((unsigned)forward->hwrpb,
					 (unsigned)forward->hwrpb + 0x100);
				break;
			}
		}
	}
	return head;
}

int query_linuxbios(void)
{
	struct lb_header *head;
	struct lb_record *rec;
	struct lb_memory *mem;
	int i, entries;
	head = find_lb_table();
	if (!head) {
		return 0;
	}
	mem = 0;
	for_each_lbrec(head, rec) {
		if (rec->tag == LB_TAG_MEMORY) {
			mem = (struct lb_memory *)rec;
			break;
		}
	}
	if (!mem) {
		return 1;
	}
	entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
	if (entries == 0)
		return 1;
	mem_info.e820_nr = 0;
	for(i = 0; i < entries; i++) {
		unsigned long long start;
		unsigned long long size;
		unsigned long type;
		if (i >= E820MAX) {
			break;
		}
		start = mem->map[i].start;
		size = mem->map[i].size;
		type = (mem->map[i].type == LB_MEM_RAM)?E820_RAM: E820_RESERVED;
		mem_info.e820[mem_info.e820_nr].addr = start;
		mem_info.e820[mem_info.e820_nr].size = size;
		mem_info.e820[mem_info.e820_nr].type = type;
		mem_info.e820_nr++;
	}
	return 1;
}

