/* Support for Multiboot */

#include "config.h"
#include "asm/io.h"
#include "libopenbios/sys_info.h"
#include "multiboot.h"

#define printf printk
#ifdef CONFIG_DEBUG_BOOT
#define debug printk
#else
#define debug(x...)
#endif

struct mbheader {
    unsigned int magic, flags, checksum;
};
const struct mbheader multiboot_header
	__attribute__((section (".hdr"))) =
{
    MULTIBOOT_HEADER_MAGIC,
    MULTIBOOT_HEADER_FLAGS,
    -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
};

/* Multiboot information structure, provided by loader to us */

struct multiboot_mmap {
	unsigned entry_size;
	unsigned base_lo, base_hi;
	unsigned size_lo, size_hi;
	unsigned type;
};

#define MULTIBOOT_MEM_VALID       0x01
#define MULTIBOOT_BOOT_DEV_VALID  0x02
#define MULTIBOOT_CMDLINE_VALID   0x04
#define MULTIBOOT_MODS_VALID      0x08
#define MULTIBOOT_AOUT_SYMS_VALID 0x10
#define MULTIBOOT_ELF_SYMS_VALID  0x20
#define MULTIBOOT_MMAP_VALID      0x40

void collect_multiboot_info(struct sys_info *info);
void collect_multiboot_info(struct sys_info *info)
{
    struct multiboot_info *mbinfo;
    struct multiboot_mmap *mbmem;
    unsigned mbcount, mbaddr;
    unsigned int i;
    struct memrange *mmap;
    int mmap_count;
    module_t *mod;

    if (info->boot_type != 0x2BADB002)
	return;

    debug("Using Multiboot information at %#lx\n", info->boot_data);

    mbinfo = phys_to_virt(info->boot_data);

    if (mbinfo->mods_count != 1) {
	    printf("Multiboot: no dictionary\n");
	    return;
    }

    mod = (module_t *) mbinfo->mods_addr;
    info->dict_start=(unsigned long *)mod->mod_start;
    info->dict_end=(unsigned long *)mod->mod_end;

    if (mbinfo->flags & MULTIBOOT_MMAP_VALID) {
	/* convert mmap records */
	mbmem = phys_to_virt(mbinfo->mmap_addr);
	mbcount = mbinfo->mmap_length / (mbmem->entry_size + 4);
	mmap = malloc(mbcount * sizeof(struct memrange));
	mmap_count = 0;
	mbaddr = mbinfo->mmap_addr;
	for (i = 0; i < mbcount; i++) {
	    mbmem = phys_to_virt(mbaddr);
	    debug("%08x%08x %08x%08x (%d)\n",
		    mbmem->base_hi,
		    mbmem->base_lo,
		    mbmem->size_hi,
		    mbmem->size_lo,
		    mbmem->type);
	    if (mbmem->type == 1) { /* Only normal RAM */
		mmap[mmap_count].base = mbmem->base_lo
		    + (((unsigned long long) mbmem->base_hi) << 32);
		mmap[mmap_count].size = mbmem->size_lo
		    + (((unsigned long long) mbmem->size_hi) << 32);
		mmap_count++;
	    }
	    mbaddr += mbmem->entry_size + 4;
	    if (mbaddr >= mbinfo->mmap_addr + mbinfo->mmap_length)
		break;
	}
	/* simple sanity check - there should be at least 2 RAM segments
	 * (base 640k and extended) */
	if (mmap_count >= 2)
	    goto got_it;

	printf("Multiboot mmap is broken\n");
	free(mmap);
	/* fall back to mem_lower/mem_upper */
    }

    if (mbinfo->flags & MULTIBOOT_MEM_VALID) {
	/* use mem_lower and mem_upper */
	mmap_count = 2;
	mmap = malloc(2 * sizeof(*mmap));
	mmap[0].base = 0;
	mmap[0].size = mbinfo->mem_lower << 10;
	mmap[1].base = 1 << 20; /* 1MB */
	mmap[1].size = mbinfo->mem_upper << 10;
	goto got_it;
    }

    printf("Can't get memory information from Multiboot\n");
    return;

got_it:
    info->memrange = mmap;
    info->n_memranges = mmap_count;

    return;
}
