#include <boot_tty.h>
#include <defs.h>

#define in_reset         __attribute__((section (".reset")))
#define in_reset_data     __attribute__((section (".reset_data")))

in_reset int boot_getc(int *c)
{
        unsigned int* tty_address = (unsigned int*) TTY_BASE;
	if (ioread32(tty_address[TTY_STATUS]) == 0)
		return 0;
        *c = ioread32(&tty_address[TTY_READ]);
	return 1;
}

in_reset void boot_putc(const char c)
{
        unsigned int* tty_address = (unsigned int*) TTY_BASE;
        iowrite32(&tty_address[TTY_WRITE], (unsigned int)c);
}

in_reset void boot_puts(const char *buffer) 
{
    unsigned int n;

    for ( n=0; n<100; n++)
    {
        if (buffer[n] == 0) break;
	boot_putc(buffer[n]);
    }
} 

in_reset void boot_putx(unsigned int val)
{
    in_reset_data static const char HexaTab[] = "0123456789ABCDEF";
    char                buf[11];
    unsigned int        c;

    buf[0]  = '0';
    buf[1]  = 'x';
    buf[10] = 0;

    for ( c = 0 ; c < 8 ; c++ )
    { 
        buf[9-c] = HexaTab[val&0xF];
        val = val >> 4;
    }
    boot_puts(buf);
}

in_reset void boot_putd(unsigned int val)
{
    in_reset_data static const char DecTab[]  = "0123456789";
    char                buf[11];
    unsigned int        i;
    unsigned int        first = 0;

    buf[10] = 0;

    for ( i = 0 ; i < 10 ; i++ )
    {
        if ((val != 0) || (i == 0))
        {
            buf[9-i] = DecTab[val % 10];
            first    = 9-i;
        }
        else
        {
            break;
        }
        val /= 10;
    }
    boot_puts( &buf[first] );
}

in_reset void boot_exit()
{
    in_reset_data static const char exit_str[] = "\n\r!!! Exit Processor ";
    in_reset_data static const char eol_str[] = " !!!\n\r";

    register int pid;
    asm volatile( "mfc0 %0, $15, 1": "=r"(pid) );

    boot_puts(exit_str);
    boot_putx(pid);
    boot_puts(eol_str);

    while(1) asm volatile("nop");   // infinite loop...
}

