#include <lib/libsa/stand.h>
#include <lib/libsa/ufs.h>
#include <lib/libsa/loadfile.h>
#include <lib/libkern/libkern.h>
#include <machine/tsar_firmware.h>
#include "vers.h"
#include <arch/tsarmips/stand/common/bootinfo.h>

void main(void *);

void doboot(char *);
void dohelp(char *);

static uint8_t bootinfo[BOOTINFO_SIZE];
struct btinfo_symtab bi_syms;
struct btinfo_fdt bi_fdt;
struct btinfo_cons bi_cons;

const struct tsar_firmware_info *TFI_DATA = (void *)TFI_ADDRESS;

void
main(void *p)
{
#if 0
	static char input[80];
	char *c;
#endif
	void (*entry)(void *);
	u_long marks[MARK_MAX];
	int err;

	if ((paddr_t)p != 0) {
		TFI_DATA = p;
	} else {
		printf("\r\nboot1 didn't provide pointer to firmware info\r\n");
	}

	printf("\r\n%s %s Bootstrap, Revision %s\r\n",
	    bootprog_name, bootprog_kernrev, bootprog_rev);
	memset(marks, 0, sizeof marks);
	bi_init(bootinfo);
#if 0
	for(;;) {
		c = input;
		input[0] = '\0';
		printf("> ");
		gets(input);
		printf("got %s\r\n", input);
		while(*c == ' ') c++;
		if(*c) {
			if (strcmp(input, "help") == 0)
				dohelp(NULL);
			if (strcmp(input, "help") == 0)
				dohelp(NULL);
			if (strcmp(input, "boot") == 0) {
				if (loadfile("netbsd", marks, LOAD_KERNEL) < 0)
					printf("boot: %s\r\n", strerror(errno));
				else
					printf("boot returned\r\n");
			}
		}
	}
#else
				marks[MARK_START] = 0;
				if (loadfile("netbsd", marks, LOAD_KERNEL) < 0) {
					printf("boot: %s\r\n", strerror(errno));
					ls("/");
					goto bad;
				}
				bi_syms.nsym = marks[MARK_NSYM];
				bi_syms.ssym = marks[MARK_SYM];
				bi_syms.esym = marks[MARK_END];
				bi_add(&bi_syms, BTINFO_SYMTAB, sizeof(bi_syms));
				entry = (void *)marks[MARK_ENTRY];
				printf("Starting at %p, "
				    "syms %d/0x%x/0x%x at %p\r\n\r\n",
				    entry,
				    bi_syms.nsym, bi_syms.ssym,
				    bi_syms.esym, bootinfo);

				err = fdt_parse_header(
				    TFI_DATA->tfi_dtb_addr, fdt);
				if (err) {
					printf("bad fdt header %d at %p\r\n",
					    err, TFI_DATA->tfi_dtb_addr);
					goto bad;
				}
				fdt_walk(&fdt->fdt_root_node, "device_type",
				    fdt_fill_cons, &bi_cons);
				if (bi_cons.cons_physaddr == 0 ||
				    bi_cons.cons_size == 0) {
					printf("console not found\r\n");
					goto bad;
				}
				printf("found tty at 0x%x/0x%x\r\n",
				    bi_cons.cons_physaddr, bi_cons.cons_size);
				bi_add(&bi_cons, BTINFO_CONS, sizeof(bi_cons));
				bi_fdt.fdt_physaddr = (uint32_t)fdt->fdt_header;
				bi_fdt.fdt_size = be32toh(
				    fdt->fdt_header->fdt_totalsize);
				bi_add(&bi_fdt, BTINFO_FDT, sizeof(bi_fdt));
				(*entry)(bootinfo);
				printf("kernel returned\r\n");
#endif
bad:
	while (1);
}

void
dohelp(char *unused)
{
	printf("nothing for now\r\n");
}

void
putchar(int c)
{
	TFI_DATA->tfi_putc(c);
}

int
getchar(void)
{
	int c;

	while (TFI_DATA->tfi_getc(&c) == 0)
		;

	return c;
}
