/* * 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); }
/* * 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); }
/* * 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); } }
/* * 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); } }
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; }
/* * 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); }