/* a.out boot loader
 * As we have seek, this implementation can be straightforward.
 * 2003-07 by SONE Takeshi
 */

#include "config.h"
#include "kernel/kernel.h"

#ifdef CONFIG_SPARC64
#define CONFIG_SPARC64_PAGE_SIZE_8KB
#endif

#include "libopenbios/sys_info.h"
#include "libopenbios/bindings.h"
#include "libopenbios/aout_load.h"
#include "libopenbios/initprogram.h"
#include "libc/diskio.h"
#define printf printk
#define debug printk

#define addr_fixup(addr) ((addr) & 0x00ffffff)

static char *image_name, *image_version;
static int fd;

static int 
check_mem_ranges(struct sys_info *info,
                            unsigned long start,
                            unsigned long size)
{
    int j;
    unsigned long end;
    unsigned long prog_start, prog_end;
    struct memrange *mem;

    prog_start = virt_to_phys(&_start);
    prog_end = virt_to_phys(&_end);

    end = start + size;

    if (start < prog_start && end > prog_start)
        goto conflict;
    if (start < prog_end && end > prog_end)
        goto conflict;
    mem = info->memrange;
    for (j = 0; j < info->n_memranges; j++) {
        if (mem[j].base <= start && mem[j].base + mem[j].size >= end)
            break;
    }
    if (j >= info->n_memranges)
        goto badseg;
    return 1;

 conflict:
    printf("%s occupies [%#lx-%#lx]\n", program_name, prog_start, prog_end);

 badseg:
    printf("A.out file [%#lx-%#lx] doesn't fit into memory\n", start, end - 1);
    return 0;
}

int 
is_aout(struct exec *ehdr)
{
	return ((ehdr->a_info & 0xffff) == OMAGIC
		|| (ehdr->a_info & 0xffff) == NMAGIC
		|| (ehdr->a_info & 0xffff) == ZMAGIC
		|| (ehdr->a_info & 0xffff) == QMAGIC);
}

int 
aout_load(struct sys_info *info, ihandle_t dev)
{
    int retval = -1;
    struct exec ehdr;
    unsigned long start, size;
    unsigned int offset;

    image_name = image_version = NULL;

    /* Mark the saved-program-state as invalid */
    feval("0 state-valid !");
    
    fd = open_ih(dev);
    if (fd == -1) {
	goto out;
    }

    for (offset = 0; offset < 16 * 512; offset += 512) {
        seek_io(fd, offset);
        if (read_io(fd, &ehdr, sizeof ehdr) != sizeof ehdr) {
            debug("Can't read a.out header\n");
            retval = LOADER_NOT_SUPPORT;
            goto out;
        }
        if (is_aout(&ehdr))
            break;
    }

    if (!is_aout(&ehdr)) {
	debug("Not a bootable a.out image\n");
	retval = LOADER_NOT_SUPPORT;
	goto out;
    }

    if (ehdr.a_text == 0x30800007)
	ehdr.a_text=64*1024;

    if (N_MAGIC(ehdr) == NMAGIC) {
        size = addr_fixup(N_DATADDR(ehdr)) + addr_fixup(ehdr.a_data);
    } else {
        size = addr_fixup(ehdr.a_text) + addr_fixup(ehdr.a_data);
    }

    if (size < 7680)
        size = 7680;

    fword("load-base");
    start = POP(); // N_TXTADDR(ehdr);

    memcpy((void *)start, &ehdr, sizeof(ehdr));
    
    if (!check_mem_ranges(info, start, size))
	goto out;

    printf("Loading a.out %s...\n", image_name ? image_name : "image");
    seek_io(fd, offset + N_TXTOFF(ehdr));

    if (N_MAGIC(ehdr) == NMAGIC) {
        if ((size_t)read_io(fd, (void *)(start + N_TXTOFF(ehdr)), ehdr.a_text) != ehdr.a_text) {
            printf("Can't read program text segment (size 0x" FMT_aout_ehdr ")\n", ehdr.a_text);
            goto out;
        }
        if ((size_t)read_io(fd, (void *)(start + N_DATADDR(ehdr)), ehdr.a_data) != ehdr.a_data) {
            printf("Can't read program data segment (size 0x" FMT_aout_ehdr ")\n", ehdr.a_data);
            goto out;
        }
    } else {
        if ((size_t)read_io(fd, (void *)(start + N_TXTOFF(ehdr)), size) != size) {
            printf("Can't read program (size 0x" FMT_sizet ")\n", size);
            goto out;
        }
    }

    debug("Loaded %lu bytes\n", size);
    debug("entry point is %#lx\n", start);

    // Initialise saved-program-state
    PUSH(size);
    feval("load-state >ls.file-size !");
    feval("aout load-state >ls.file-type !");

out:
    close_io(fd);
    return retval;
}

void 
aout_init_program(void)
{
    ucell start, size;
    
    // Relocate a.out text down from load-base to load-base - header. This
    // is similar to what OBP does and is needed for NextStep.
    fword("load-base");
    start = POP();
    feval("load-state >ls.file-size @");
    size = POP();
    
    memmove((char *)start - sizeof(struct exec), (char *)start, size);
    
    PUSH(start);
    feval("load-state >ls.entry !");
    
    arch_init_program();
    
    feval("-1 state-valid !");
}
