static int rtas_node(void) { int node = fdt_path_offset(dt_fdt(), "/rtas"); if (node < 0) { printf("%s: /rtas: %s\n", __func__, fdt_strerror(node)); abort(); } return node; }
int rtas_token(const char *service) { const struct fdt_property *prop; u32 *token; prop = fdt_get_property(dt_fdt(), rtas_node(), service, NULL); if (prop) { token = (u32 *)prop->data; return fdt32_to_cpu(*token); } return RTAS_UNKNOWN_SERVICE; }
void rtas_init(void) { bool broken_sc1 = hcall_have_broken_sc1(); int node = rtas_node(), len, words, i; const struct fdt_property *prop; u32 *data, *insns; if (!dt_available()) { printf("%s: No device tree!\n", __func__); abort(); } prop = fdt_get_property(dt_fdt(), node, "linux,rtas-entry", &len); if (!prop) { printf("%s: /rtas/linux,rtas-entry: %s\n", __func__, fdt_strerror(len)); abort(); } data = (u32 *)prop->data; rtas_entry = (unsigned long)fdt32_to_cpu(*data); insns = (u32 *)rtas_entry; prop = fdt_get_property(dt_fdt(), node, "rtas-size", &len); if (!prop) { printf("%s: /rtas/rtas-size: %s\n", __func__, fdt_strerror(len)); abort(); } data = (u32 *)prop->data; words = (int)fdt32_to_cpu(*data)/4; for (i = 0; i < words; ++i) { if (broken_sc1 && insns[i] == cpu_to_be32(SC1)) insns[i] = cpu_to_be32(SC1_REPLACEMENT); } }
/* * Start all stopped threads (vcpus) on cpu_node * Returns: Number of stopped cpus which were successfully started */ struct start_threads start_cpu(int cpu_node, secondary_entry_fn entry, uint32_t r3) { int len, i, nr_threads, nr_started = 0; const struct fdt_property *prop; u32 *threads; /* Get the id array of threads on this cpu_node */ prop = fdt_get_property(dt_fdt(), cpu_node, "ibm,ppc-interrupt-server#s", &len); assert(prop); nr_threads = len >> 2; /* Divide by 4 since 4 bytes per thread */ threads = (u32 *)prop->data; /* Array of valid ids */ for (i = 0; i < nr_threads; i++) { if (!start_thread(fdt32_to_cpu(threads[i]), entry, r3)) nr_started++; } return (struct start_threads) { nr_threads, nr_started }; }