Example #1
0
/*
 * Get Fcode into supplied buffer.
 */
int
prom_get_fcode(char *str, char *buf)
{
	cell_t ci[6];
	int rv;

	if (prom_test("SUNW,get-fcode") != 0) {
		return (0);
	}

	ci[0] = p1275_ptr2cell("SUNW,get-fcode");
	ci[1] = (cell_t)2;	/* 2 input args: str + buf */
	ci[2] = (cell_t)1;	/* 1 output result: true or false */
	ci[3] = p1275_ptr2cell(buf);	/* Arg#1: buffer to put fcode */
	ci[4] = p1275_ptr2cell(str);	/* Arg#2: name of drop-in */
	ci[5] = (cell_t)0;

	promif_preprom();
	rv = p1275_cif_handler(&ci);
	promif_postprom();

	if (rv == 0)
		return (p1275_cell2int(ci[5]));
	return (0);
}
Example #2
0
/*
 * Internal cpu startup sequencer
 * The sequence is as follows:
 *
 * MASTER	SLAVE
 * -------	----------
 * assume the kernel data is initialized
 * clear the proxy bit
 * start the slave cpu
 * wait for the slave cpu to set the proxy
 *
 *		the slave runs slave_startup and then sets the proxy
 *		the slave waits for the master to add slave to the ready set
 *
 * the master finishes the initialization and
 * adds the slave to the ready set
 *
 *		the slave exits the startup thread and is running
 */
void
start_cpu(int cpuid, void(*flag_func)(int))
{
	extern void cpu_startup(int);
	int timout;

	ASSERT(MUTEX_HELD(&cpu_lock));

	/*
	 * Before we begin the dance, tell DTrace that we're about to start
	 * a CPU.
	 */
	if (dtrace_cpustart_init != NULL)
		(*dtrace_cpustart_init)();

	/* start the slave cpu */
	CPUSET_DEL(proxy_ready_set, cpuid);
	if (prom_test("SUNW,start-cpu-by-cpuid") == 0) {
		(void) prom_startcpu_bycpuid(cpuid, (caddr_t)&cpu_startup,
		    cpuid);
	} else {
		/* "by-cpuid" interface didn't exist.  Do it the old way */
		pnode_t nodeid = cpunodes[cpuid].nodeid;

		ASSERT(nodeid != (pnode_t)0);
		(void) prom_startcpu(nodeid, (caddr_t)&cpu_startup, cpuid);
	}

	/* wait for the slave cpu to check in. */
	for (timout = CPU_WAKEUP_GRACE_MSEC; timout; timout--) {
		if (CPU_IN_SET(proxy_ready_set, cpuid))
			break;
		DELAY(1000);
	}
	if (timout == 0) {
		panic("cpu%d failed to start (2)", cpuid);
	}

	/*
	 * The slave has started; we can tell DTrace that it's safe again.
	 */
	if (dtrace_cpustart_fini != NULL)
		(*dtrace_cpustart_fini)();

	/* run the master side of stick synchronization for the slave cpu */
	sticksync_master();

	/*
	 * deal with the cpu flags in a phase-specific manner
	 * for various reasons, this needs to run after the slave
	 * is checked in but before the slave is released.
	 */
	(*flag_func)(cpuid);

	/* release the slave */
	CPUSET_ADD(cpu_ready_set, cpuid);
}
Example #3
0
/*
 * Request that OBP write 'len' bytes from the memory indicated by 'buf' into
 * the IOSRAM chunk associated with 'key', starting at 'offset'.  Although there
 * is a driver that provides this functionality, there are certain cases where
 * the OS requires access to IOSRAM before the driver is loaded.  Return 0 on
 * success, non-zero on failure.
 */
int
prom_starcat_iosram_write(uint32_t key, uint32_t offset, uint32_t len,
    caddr_t buf)
{
	static uint8_t	warned = 0;
	cell_t 		ci[8];
	int 		rv;

	/*
	 * Make sure we have the necessary support in OBP.
	 */
	if (prom_test(iosram_write_cmd) == 0) {
		ci[0] = p1275_ptr2cell(iosram_write_cmd); /* name */
	} else {
		if (!warned) {
			warned = 1;
			prom_printf(
			    "Warning: No prom support for iosram-write!\n");
		}
		return (-1);
	}

	/*
	 * Set up the arguments and call into OBP.  Note that the argument order
	 * needs to be reversed to accomodate OBP.  The order must remain as it
	 * is in the function prototype to maintain intercompatibility with the
	 * IOSRAM driver's equivalent routine.
	 */
	ci[1] = (cell_t)4;				/* #argument cells */
	ci[2] = (cell_t)1;				/* #result cells */
	ci[3] = p1275_ptr2cell(buf);
	ci[4] = p1275_uint2cell(len);
	ci[5] = p1275_uint2cell(offset);
	ci[6] = p1275_uint2cell(key);

	promif_preprom();
	rv = p1275_cif_handler(&ci);
	promif_postprom();

	/*
	 * p1275_cif_handler will return 0 on success, non-zero on failure.  If
	 * it fails, the return cell from OBP is meaningless, because the OBP
	 * client interface probably wasn't even invoked.  OBP will return 0 on
	 * success and non-zero on failure for this interface.
	 */
	if (rv != 0) {
		return (rv);
	} else if (p1275_cell2int(ci[7]) == 0)	{
		return (0);
	} else {
		return (-1);
	}
}
Example #4
0
/*
 * Given the portid of the IOB to which the tunnel should be moved and the type
 * of move that should be performed, ask OBP to switch the IOSRAM tunnel from
 * its current host IOB to a new location.  If the move type is 0, OBP will
 * coordinate the change with SMS and will copy data from the current location
 * to the new location.  If the move type is 1, OBP will simply mark the new
 * location valid and start using it, without doing any data copying and without
 * communicating with SMS.  Return 0 on success, non-zero on failure.
 */
int
prom_starcat_switch_tunnel(uint_t portid, uint_t msgtype)
{
	static uint8_t	warned = 0;
	cell_t		ci[6];
	int		rv;

	/*
	 * Make sure we have the necessary support in OBP.
	 */
	if (prom_test(switch_tunnel_cmd) == 0) {
		ci[0] = p1275_ptr2cell(switch_tunnel_cmd); /* name */
	} else {
		if (!warned) {
			warned = 1;
			prom_printf(
			    "Warning: No prom support for switch-tunnel!\n");
		}
		return (-1);
	}

	/*
	 * Set up the arguments and call into OBP.
	 */
	ci[1] = (cell_t)2;				/* #argument cells */
	ci[2] = (cell_t)1;				/* #result cells */
	ci[3] = p1275_uint2cell(portid);
	ci[4] = p1275_uint2cell(msgtype);

	promif_preprom();
	rv = p1275_cif_handler(&ci);
	promif_postprom();

	/*
	 * p1275_cif_handler will return 0 on success, non-zero on failure.  If
	 * it fails, the return cell from OBP is meaningless, because the OBP
	 * client interface probably wasn't even invoked.  OBP will return 0 on
	 * failure and non-zero on success for this interface.
	 */
	if (rv != 0) {
		return (rv);
	} else if (p1275_cell2int(ci[5]) == 0)	{
		return (-1);
	} else {
		return (0);
	}
}
Example #5
0
void
set_platform_defaults(void)
{
	extern char *tod_module_name;
	extern int ts_dispatch_extended;
	extern void cpu_sgn_update(ushort_t, uchar_t, uchar_t, int);

	uint32_t	revlevel;
	char		buf[20];

#ifdef DEBUG
	ce_verbose_memory = 2;
	ce_verbose_other = 2;
#endif

	/*
	 * Check to see if we have the right firmware
	 * We simply do a prom_test to see if
	 * "SUNW,UE10000-prom-version" interface exist.
	 */
	if (prom_test("SUNW,UE10000-prom-version") != 0) {
		halt("Firmware upgrade is required to boot this OS!");
	} else {
		/*
		 * Versions 5 to 50 and 150 or above  can support this OS
		 */
		(void) sprintf(buf, "cpu-prom-version swap l!");
		prom_interpret(buf, (uintptr_t)&revlevel, 0, 0, 0, 0);
		if ((revlevel < 5) || ((revlevel > 50) && (revlevel < 150)))
			halt("Firmware upgrade is required to boot this OS!");
	}

	/* Set the CPU signature function pointer */
	cpu_sgn_func = cpu_sgn_update;

	/* Set appropriate tod module for starfire */
	ASSERT(tod_module_name == NULL);
	tod_module_name = "todstarfire";

	/*
	 * Use the alternate TS dispatch table, which is better
	 * tuned for large servers.
	 */
	if (ts_dispatch_extended == -1) /* use platform default */
		ts_dispatch_extended = 1;
}
Example #6
0
/*
 * Get Fcode size, test if OBP supports this interface.
 */
int
prom_get_fcode_size(char *str)
{
	cell_t ci[5];
	int rv;

	if (prom_test("SUNW,get-fcode-size") != 0) {
		return (0);
	}

	ci[0] = p1275_ptr2cell("SUNW,get-fcode-size");
	ci[1] = (cell_t)1;	/* 1 input arg: str */
	ci[2] = (cell_t)1;	/* 1 output result: len or zero */
	ci[3] = p1275_ptr2cell(str);
	ci[4] = (cell_t)0;

	promif_preprom();
	rv = p1275_cif_handler(&ci);
	promif_postprom();

	if (rv == 0)
		return (p1275_cell2int(ci[4]));
	return (0);
}