/* Miscelaneous functions

   Copyright (C) 1996 David Miller
   1996 Pete A. Zaitcev
   1996,1997 Jakub Jelinek

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
   USA.  */

#include <silo.h>
#include <asm/idprom.h>
#include <asm/machines.h>
#include <stringops.h>

void silo_fatal(const char *msg)
{
    printf("\nFatal error: %s\n", msg);
}

char *silo_v0_device(char *imagename)
{
    if (((imagename[0] == 's' && strchr ("dt", imagename[1])) ||
        (imagename[0] == 'x' && strchr ("dy", imagename[1])) ||
        (imagename[0] == 'f' && imagename[1] == 'd') ||
        (imagename[0] == 'l' && imagename[1] == 'e') ||
        (imagename[0] == 'i' && imagename[1] == 'e')) && 
        imagename[2] == '(') {
        return strchr (imagename, ')');
    } else
        return 0;
}

char *seed_part_into_device (char *device, int part)
{
	static char buffer[256];
	
	strcpy (buffer, device);
	if (prom_vers != PROM_V0) {
	    	char *p = strchr (buffer, ':');
	    	
	    	if (!p) {
	    	    p = strchr (buffer, 0);
	    	    *p++ = ':';
	    	} else
	    	    p++;
	    	*p++ = 'a' + part - 1;
	    	*p = 0;
	} else {
	        int i = strlen (device);
	        char *p;
	        
	        if (i >= 4 && buffer[2] == '(' && buffer[i - 1] == ')') {
	        	if (i == 4) {
	        	    strcpy (buffer + 3, "0,0,");
	        	    buffer [7] = '0' + part - 1;
	        	    strcpy (buffer + 8, ")");
	        	} else {
	        	    p = strchr (buffer + 3, ',');
	        	    if (!p) {
	        	    	strcpy (buffer + i - 1, ",0,");
	        	    	buffer [i + 2] = '0' + part - 1;
	        	    	strcpy (buffer + i + 3, ")");
	        	    } else {
	        	    	p = strchr (p + 1, ',');
	        	    	if (!p) {
	        	    	    buffer [i - 1] = ',';
	        	    	    buffer [i] = '0' + part - 1;
	        	    	    strcpy (buffer + i + 1, ")");
	        	    	} else {
	        	    	    *p = '0' - part - 1;
	        	    	    strcpy (p + 1, ")");
	        	    	}
	        	    }
	        	}
	        }
	}
	return buffer;
}

static char barg_buf[1024];
char barg_out[1024];

void silo_set_bootargs(char *params, char *device)
{
    char *q, *r;
    char **p;
    int iter, i;

    /*
     * We expect a kernel to extract a command line
     * from our dead body promptly, if the arguments are longer than 90 or so. 
     */
    if (params) {
        q = params;
        r = barg_out;
        /* Remove unnecessary spaces */
        do {
            while (*q == ' ') q++;
            if (!*q) break;
            if (r != barg_out) *r++ = ' ';
            while (*q && *q != ' ') *r++ = *q++;
        } while (*q);
        *r = 0;
    } else
        *barg_out = 0;
    switch (prom_vers) {
    case PROM_V0:
        if (strlen (barg_out) > 100 - 12) {
	    p = (*(romvec->pv_v0bootargs))->argv;
	    p [0] = "silo()";
	    q = barg_out;
	    for (iter = 1; iter < 7; iter++) {
	        while (*q == ' ') q++;
	        if (!*q) {
	            p [iter] = 0;
	            continue;
	        }
	        r = q;
	        while (*r && *r != ' ') r++;
	        if (!p[iter] || strlen (p[iter]) != r - q || strncmp (q, p[iter], r - q)) {
	    	    if (*r) *r++ = 0;
	            p [iter] = q;
	        }
	        q = r;
	    }
	    while (*q == ' ') q++;
	    if (*q)
	        p [7] = q;
	    else
	        p [7] = 0;
	    return;
	} else {
	    q = (*(romvec->pv_v0bootargs))->args;
	    p = (*(romvec->pv_v0bootargs))->argv;
	    p[0] = q;
	    if (!device) {
	    	strcpy (q, "silo()");
	    	q += 7;
	    	strcpy (q, barg_out);
	    } else {
	    	strcpy (q, device);
	    	q = strchr (q, 0);
	    	strcpy (q, barg_out);
	    	r = strchr (q, ' ');
	    	if (!r)
	    	    r = strchr (q, 0);
	    	else {
	    	    *r = 0;
	    	    r++;
	    	}
	    	(*(romvec->pv_v0bootargs))->kernel_file_name = q;
	    	(*(romvec->pv_v0bootargs))->boot_dev[0] = device[0];
	    	(*(romvec->pv_v0bootargs))->boot_dev[1] = device[1];
	    	q = device + 3;
	    	i = 0;	
	    	while (*q != ',' && *q != ')') {
	    	    i = i * 10 + *q - '0';
	    	    q++;
	    	}
	    	if (*q == ',') q++;
	    	(*(romvec->pv_v0bootargs))->boot_dev_ctrl = i;
	    	i = 0;	
	    	while (*q != ',' && *q != ')') {
	    	    i = i * 10 + *q - '0';
	    	    q++;
	    	}
	    	if (*q == ',') q++;
	    	(*(romvec->pv_v0bootargs))->boot_dev_unit = i;
	    	i = 0;	
	    	while (*q != ',' && *q != ')') {
	    	    i = i * 10 + *q - '0';
	    	    q++;
	    	}
	    	(*(romvec->pv_v0bootargs))->dev_partition = i;
	    	q = r;
	    }
	    for (i = 1; i < 7; i++) {
	    	if (*q) {
	    	    r = strchr (q, ' ');
	    	    if (r) {
	    	        *r = 0;
	    	        r++;
	    	    } else
	    	    	r = strchr (q, 0);
	    	    p[i] = q;
	    	    q = r;
	    	} else
	    	    p[i] = 0;
	    }
	    if (*q)
	        p[7] = q;
	    else
	        p[7] = 0;
	    return;
	}
    case PROM_V2:
    case PROM_V3:
    	if (strlen (barg_out) < 128)
    	    strcpy (*romvec->pv_v2bootargs.bootargs, barg_out);
    	else
            *romvec->pv_v2bootargs.bootargs = barg_out;
        if (device)
            strcpy (*romvec->pv_v2bootargs.bootpath, device);
        break;
    case PROM_P1275:
	break;
    }
}

char *silo_get_bootargs(int full)
{
    int iter;
    char *cp, *q;
    char **p;

    switch (prom_vers) {
    case PROM_V0:
        p = (*(romvec->pv_v0bootargs))->argv;
	cp = barg_buf;
	*cp = 0;
	if (p [0]) {
	    for (iter = 0; iter < 8; iter++) {
	    	q = p [iter];
	        if (q) {
	            if (!iter && !full) {
	                q = silo_v0_device(q);
	                
	                if (q && !q[1])
	                    continue;
	                else if (q)
	                    q++;
	                else
	                    q = p [iter];
	            }
	            strcpy (cp, q);
	            cp += strlen (cp);
	            *cp++ = ' ';
	        } else
	            break;
	    }
	    if (cp != barg_buf)
	        cp[-1] = 0;
	}
	break;
    case PROM_V2:
    case PROM_V3:
    	if (!full)
    	    q = barg_buf;
    	else {
            strcpy (barg_buf, *romvec->pv_v2bootargs.bootpath);
            q = strchr (barg_buf, 0);
        }
        if (*romvec->pv_v2bootargs.bootargs) {
            if (full)
                *q++ = ' ';
	    strcpy (q, *romvec->pv_v2bootargs.bootargs);
	} else if (!full)
	    *q = 0;
	break;
    case PROM_P1275:
    	if (!full)
    	    q = barg_buf;
    	else {
    	    iter = prom_getproperty (prom_chosen, "bootpath", barg_buf, 510);
    	    if (iter != -1)
    	        if (iter && !barg_buf [iter - 1])
    	            q = barg_buf + iter - 1;
    	        else
    	            q = barg_buf + iter;
    	    else
    	        q = barg_buf;
    	}
    	iter = prom_getproperty (prom_chosen, "bootargs", full ? q + 1 : q, 512);
    	if (iter == -1 || !iter)
    	    *q = 0;
    	else {
    	    if (full)
    	        *q = ' ';
    	    if (q [iter + 1])
    	    	q [iter + 1] = 0;
    	}
    	break;
    }
    return barg_buf;
}

void silo_show_bootargs(void)
{
    printf("Kernel args: %s\n", silo_get_bootargs(0));
}

unsigned char *silo_find_linux_HdrS(char *base, int len)
{
    /* Ugly magic to find HdrS, we dig into first jmp gokernel */
    char *p = base + ((*(unsigned short *) (base+2)) << 2) - 512;
    char *q;

    q = base+8;
    if (*q == 'H' && q[1] == 'd' && q[2] == 'r' && q[3] == 'S')
    	return (unsigned char *)q;
    if (p >= base + len || p <= base)
	return 0;
    for (q = p + 512; p < q; p += 4) {
	if (*p == 'H' && p[1] == 'd' && p[2] == 'r' && p[3] == 'S')
	    return (unsigned char *)p;
    }
    return 0;
}

static struct idp_struct idprm;

/* Here is the master table of Sun machines which use some implementation
 * of the Sparc CPU and have a meaningful IDPROM machtype value that we
 * know about.  See asm/machines.h for empirical constants.
 */
struct SMM {
    char *name;
    char *package;
    enum arch architecture;
    unsigned char id_machtype;
} Machines[NUM_SUN_MACHINES] = {
/* First, Sun4's */
{ "Sun 4/100 Series", "sun4", sun4, (SM_SUN4 | SM_4_110) },
{ "Sun 4/200 Series", "sun4", sun4, (SM_SUN4 | SM_4_260) },
{ "Sun 4/300 Series", "sun4", sun4, (SM_SUN4 | SM_4_330) },
{ "Sun 4/400 Series", "sun4", sun4, (SM_SUN4 | SM_4_470) },
/* Now, Sun4c's */
{ "SparcStation 1", 	"SUNW,Sun_4_60", sun4c, (SM_SUN4C | SM_4C_SS1) },
{ "SparcStation IPC", 	"SUNW,Sun_4_40", sun4c, (SM_SUN4C | SM_4C_IPC) },
{ "SparcStation 1+", 	"SUNW,Sun_4_65", sun4c, (SM_SUN4C | SM_4C_SS1PLUS) },
{ "SparcStation SLC", 	"SUNW,Sun_4_20", sun4c, (SM_SUN4C | SM_4C_SLC) },
{ "SparcStation 2", 	"SUNW,Sun_4_75", sun4c, (SM_SUN4C | SM_4C_SS2) },
{ "SparcStation ELC", 	"SUNW,Sun_4_25", sun4c, (SM_SUN4C | SM_4C_ELC) },
{ "SparcStation IPX", 	"SUNW,Sun_4_50", sun4c, (SM_SUN4C | SM_4C_IPX) },
/* Finally, early Sun4m's */
{ "SparcSystem 600", 	"SUNW,Sun_4_600", sun4m, (SM_SUN4M | SM_4M_SS60) },
{ "SparcStation 10/20", 	"sun4m", sun4m, (SM_SUN4M | SM_4M_SS50) },
{ "SparcStation 4/5", 	"sun4m", sun4m, (SM_SUN4M | SM_4M_SS40) },
/* One entry for the OBP arch's which are sun4d, sun4e, sun4u and newer sun4m's */
{ "OBP based system", 	"sun4m", sun4m, (SM_SUN4M_OBP | 0x0) } };

char *get_systype(void)
{
    static char system_name[128];
    int i;

    for(i = 0; i < NUM_SUN_MACHINES; i++)
	if(Machines[i].id_machtype == idprm.id_machtype) {
	    if(idprm.id_machtype!=(SM_SUN4M_OBP | 0x0))
		return Machines[i].name;
	    else {
		prom_getproperty(prom_root_node, "banner-name",
			         system_name, sizeof(system_name));
		return system_name;
	    }
	}
    return "Unknown Sparc";
}

char *get_syspackage(void)
{
    static char system_name[128];
    int i;

    *system_name = 0;
    prom_getproperty(prom_root_node, "name",
		     system_name, sizeof(system_name));
    if (*system_name)
	return system_name;
    for(i = 0; i < NUM_SUN_MACHINES; i++)
	if(Machines[i].id_machtype == idprm.id_machtype) {
	    return Machines[i].package;
	}
    return "sun4c";
}

void
get_idprom(void)
{
    prom_getproperty (prom_root_node, "idprom", (char *)&idprm, sizeof (idprm));
}

void print_message (char *msg)
{
    char *p = msg, *q = 0;
    int curly;
    int i;

    while (*p) {
        while (*p && *p != '$') p++;

	if (!*p)
		break;

	*p = 0;
	printf ("%s", msg);
	msg = p;
	*p++ = '$';
	if ((curly = (*p == '{')))
		p++;

	if (!strncmp (p, "ARCH", 4)) {
		switch (silo_get_architecture()) {
			case sun4: q = "SUN4"; break;
			case sun4c: q = "SUN4C"; break;
			case sun4d: q = "SUN4D"; break;
			case sun4m: q = "SUN4M"; break;
			case sun4e: q = "SUN4E"; break;
			case sun4p: q = "SUN4P"; break;
			case sun4u: q = "SUN4U"; break;
			default: break;
		}
		printf ("%s", q);
		p += 4;
	} else if (!strncmp (p, "PROM", 4)) {
		switch (prom_vers) {
			case PROM_V0: printf ("0"); break;
			case PROM_V2: printf ("2"); break;
			case PROM_V3: printf ("3"); break;
			case PROM_P1275: printf ("IEEE"); break;
		}
		p += 4;
	} else if (!strncmp (p, "ETHER", 5)) {
		for (i = 0; i < 6; i++)
			printf ("%x%x%s", ((unsigned char)idprm.id_eaddr[i]) >> 4, idprm.id_eaddr[i] & 0xf, i == 5 ? "" : ":");
		p += 5;
	} else if (!strncmp (p, "SYSTYPE", 7)) {
		printf ("%s", get_systype ());
		p += 7;
	} else
		continue;

	if (curly && *p == '}')
		p++;

	msg = p;
    }

    if (*msg)
	    printf ("%s", msg);
	
}

void silo_set_prollargs(char *params, unsigned int kbase, int ksize)
{
    struct silo_to_proll {
        char magic[4];          /* SiPR */
        int kern_base;          /* Always 256K so far. But who knows... */
        int kern_size;
        int xxx;
        char kern_args[256];
    } *p;
    int *v;

    /*
     * Old, bad way:
     * p = ((struct silo_to_proll *) 0x40000) - sizeof (struct silo_to_proll);
     *
     * New way allows to warn if PROLL is not cooperative.
     */
    v = (int *) 0x4000;
    if (v[2] != 0x5377) {
        printf ("PROLL does not accept arguments\n");
        return;
    }
    /* PROLL's base address is floating often. Mask the linking address off. */
    p = (struct silo_to_proll *)(v[3] & (0x40000-1));
    if (p->magic[0] != 'L' || p->magic[1] != 'R') {
	printf ("Bad magic in PROLL parameter");
	return;
    }
    p->magic[0] = 'S';
    p->magic[1] = 'i';
    p->magic[2] = 'L';
    p->magic[3] = 'o';
    p->kern_base = kbase;	/* Hopefuly >= 0x40000 */
    p->kern_size = ksize;
    p->xxx = 0;
    strcpy(p->kern_args, params);
}

enum arch silo_get_architecture(void)
{
    char buffer[] = "sun4c    ";
    int i;

    if (prom_vers == PROM_P1275) {
	i = prom_getchild(prom_root_node);
        if ((i = prom_searchsiblings(i, "MicroSPARC-IIep")) != 0) {
            return sun4p;
        }
	buffer[4] = 'u';
    }
    i = prom_getproperty (prom_root_node, "compatability", buffer, 8);

    if (!i || i == -1)
	i = prom_getproperty (prom_root_node, "compatible", buffer, 8);

    switch (buffer[4]) {
    case 'c':
	return sun4c;
    case 'm':
	return sun4m;
    case 'd':
	return sun4d;
    case 'e':
	return sun4e;
    case 'v':
	sun4v_cpu = 1;
	/* FALLTHRU */
    case 'u':
	return sun4u;
    default:
    	for(i = 0; i < NUM_SUN_MACHINES; i++)
	    if(Machines[i].id_machtype == idprm.id_machtype)
	    	return Machines[i].architecture;
	return sununknown;
    }
}
