5 #include <linux/kernel.h>
6 #include <linux/types.h>
9 #include <linux/list.h>
10 #include <linux/slab.h>
14 #include <linux/export.h>
17 #include <asm/hypervisor.h>
20 #include <asm/uaccess.h>
21 #include <asm/oplib.h>
44 #define MD_LIST_END 0x00
46 #define MD_NODE_END 0x45
48 #define MD_PROP_ARC 0x61
49 #define MD_PROP_VAL 0x76
50 #define MD_PROP_STR 0x73
51 #define MD_PROP_DATA 0x64
79 unsigned int handle_size,
84 memset(hp, 0, handle_size);
85 INIT_LIST_HEAD(&hp->
list);
107 mdesc_handle_init(hp, handle_size, hp);
114 unsigned int alloc_size;
126 .alloc = mdesc_memblock_alloc,
127 .free = mdesc_memblock_free,
130 static struct mdesc_handle *mdesc_kmalloc(
unsigned int mdesc_size)
144 addr = (
unsigned long)base;
145 addr = (addr + 15
UL) & ~15
UL;
148 mdesc_handle_init(hp, handle_size, base);
164 .alloc = mdesc_kmalloc,
168 static struct mdesc_handle *mdesc_alloc(
unsigned int mdesc_size,
197 spin_unlock_irqrestore(&mdesc_lock, flags);
209 list_del_init(&hp->
list);
212 spin_unlock_irqrestore(&mdesc_lock, flags);
224 client->
next = client_list;
228 client->
add(cur_mdesc, node);
253 static void invoke_on_missing(
const char *
name,
261 int found = 0, is_vdc_port = 0;
262 const char *name_prop;
267 if (name_prop && !
strcmp(name_prop,
"vdc-port")) {
269 id = parent_cfg_handle(a, node);
275 (name_prop ? name_prop : name));
286 strcmp(name_prop,
"vdc-port"))
288 fid = parent_cfg_handle(b, fnode);
291 "for vdc-port node.\n");
313 invoke_on_missing(p->
node_name, new_hp, old_hp, p->
add);
316 static void mdesc_notify_clients(
struct mdesc_handle *old_hp,
322 notify_one(p, old_hp, new_hp);
337 hp = mdesc_alloc(len, &kmalloc_mdesc_memops);
344 if (status !=
HV_EOK || real_len > len) {
355 spin_unlock_irqrestore(&mdesc_lock, flags);
357 mdesc_notify_clients(orig_hp, hp);
363 list_add(&orig_hp->
list, &mdesc_zombie_list);
364 spin_unlock_irqrestore(&mdesc_lock, flags);
375 static void *name_block(
struct mdesc_hdr *mdesc)
377 return ((
void *) node_block(mdesc)) + mdesc->
node_sz;
380 static void *data_block(
struct mdesc_hdr *mdesc)
382 return ((
void *) name_block(mdesc)) + mdesc->
name_sz;
386 u64 from_node,
const char *name)
389 const char *names = name_block(&hp->
mdesc);
390 u64 last_node = hp->
mdesc.node_sz / 16;
395 }
else if (from_node >= last_node) {
398 ret = ep[from_node].
d.
val;
401 while (ret < last_node) {
408 if (ret >= last_node)
415 const char *name,
int *lenp)
417 const char *names = name_block(&hp->
mdesc);
418 u64 last_node = hp->
mdesc.node_sz / 16;
439 val = data + ep->
d.
data.data_offset;
440 len = ep->
d.
data.data_len;
463 const char *names = name_block(&hp->
mdesc);
464 u64 last_node = hp->
mdesc.node_sz / 16;
499 const char *names = name_block(&hp->
mdesc);
500 u64 last_node = hp->
mdesc.node_sz / 16;
513 static u64 max_cpus = 64;
515 static void __init report_platform_properties(
void)
523 prom_printf(
"No platform node in machine-description.\n");
528 printk(
"PLATFORM: banner-name [%s]\n", s);
530 printk(
"PLATFORM: name [%s]\n", s);
534 printk(
"PLATFORM: hostid [%08llx]\n", *v);
537 printk(
"PLATFORM: serial# [%08llx]\n", *v);
539 printk(
"PLATFORM: stick-frequency [%08llx]\n", *v);
542 printk(
"PLATFORM: mac-address [%llx]\n", *v);
545 printk(
"PLATFORM: watchdog-resolution [%llu ms]\n", *v);
548 printk(
"PLATFORM: watchdog-max-timeout [%llu ms]\n", *v);
552 printk(
"PLATFORM: max-cpus [%llu]\n", max_cpus);
566 for (i = 0; i < max_cpu; i++)
613 if (!
strcmp(name,
"cache"))
614 fill_in_one_cache(c, hp, target);
629 if (!
strcmp(name,
"cpu")) {
641 if (
strcmp(n_name,
"cpu"))
671 mark_core_ids(hp, mp, idx);
711 mark_proc_ids(hp, mp, idx);
719 __set_proc_ids(hp,
"exec_unit");
720 __set_proc_ids(hp,
"exec-unit");
724 unsigned long def,
unsigned long max)
732 if (!val || val >= 64)
738 *mask = ((1
U <<
val) * 64
U) - 1
U;
742 *mask = ((1
U << def) * 64
U) - 1
U;
763 pr_info(
"SUN4V: Mondo queue sizes "
764 "[cpu(%u) dev(%u) r(%u) nr(%u)]\n",
793 ret =
func(hp, mp, cpuid, arg);
817 mdesc_iterate_over_cpus(record_one_cpu,
NULL, mask);
823 unsigned long *pgsz_mask =
arg;
841 mdesc_iterate_over_cpus(check_one_pgsz, pgsz_mask, mask);
865 get_mondo_data(hp, mp, tb);
872 if (!
strcmp(t_name,
"cache")) {
873 fill_in_one_cache(c, hp, t);
882 if (!
strcmp(n_name,
"cache"))
883 fill_in_one_cache(c, hp, n);
897 mdesc_iterate_over_cpus(fill_in_one_cpu,
NULL, mask);
900 sparc64_multi_core = 1;
914 size_t len, loff_t *offp)
923 if (len < hp->handle_size)
944 static int __init mdesc_misc_init(
void)
954 unsigned long len, real_len,
status;
958 printk(
"MDESC: Size is %lu bytes.\n", len);
960 hp = mdesc_alloc(len, &memblock_mdesc_ops);
962 prom_printf(
"MDESC: alloc of %lu bytes failed.\n", len);
967 if (status !=
HV_EOK || real_len > len) {
969 "len(%lu), real_len(%lu)\n",
970 status, len, real_len);
977 report_platform_properties();