void display_cpus(Board_node *board) { Prom_node *cpu; uint_t freq; int ecache_size; int *l3_shares; int *mid; int *impl; int *mask; int *coreid; char fru_prev = 'X'; /* Valid frus are 'A','B' */ int mid_prev; int ecache_size_prev = 0; char fru_name; /* * display the CPUs' operating frequency, cache size, impl. field * and mask revision. */ for (cpu = dev_find_type(board->nodes, "cpu"); cpu != NULL; cpu = dev_next_type(cpu, "cpu")) { mid = (int *)get_prop_val(find_prop(cpu, "portid")); if (mid == NULL) mid = (int *)get_prop_val(find_prop(cpu, "cpuid")); freq = HZ_TO_MHZ(get_cpu_freq(cpu)); ecache_size = get_ecache_size(cpu); impl = (int *)get_prop_val(find_prop(cpu, "implementation#")); mask = (int *)get_prop_val(find_prop(cpu, "mask#")); l3_shares = (int *)get_prop_val(find_prop(cpu, "l3-cache-sharing")); /* Do not display a failed CPU node */ if ((impl == NULL) || (freq == 0) || (node_failed(cpu))) continue; fru_name = CHERRYSTONE_GETSLOT_LABEL(*mid); if (CPU_IMPL_IS_CMP(*impl)) { coreid = (int *)get_prop_val(find_prop(cpu, "reg")); if (coreid == NULL) { continue; } if ((fru_prev == 'X') || ((fru_prev != 'X') && (fru_name != fru_prev))) { fru_prev = fru_name; mid_prev = *mid; ecache_size_prev = ecache_size; continue; } else { /* * Some CMP chips have a split E$, * so the size for both cores is added * together to get the total size for * the chip. * * Still, other CMP chips have E$ (L3) * which is logically shared, so the * total size is equal to the core size. */ if ((l3_shares == NULL) || ((l3_shares != NULL) && MULTIPLE_BITS_SET(*l3_shares))) { ecache_size += ecache_size_prev; } ecache_size_prev = 0; fru_prev = 'X'; } } log_printf(" %c", fru_name); /* CPU Module ID */ if (CPU_IMPL_IS_CMP(*impl)) { log_printf("%3d,%3d ", mid_prev, *mid, 0); } else log_printf(" %2d ", *mid); /* Running frequency */ log_printf("%4u", freq); if (ecache_size == 0) log_printf(" N/A "); else log_printf(" %4.1f ", (float)ecache_size / (float)(1<<20)); /* Implementation */ if (impl == NULL) { log_printf(dgettext(TEXT_DOMAIN, " N/A ")); } else { if (IS_CHEETAH(*impl)) log_printf(dgettext(TEXT_DOMAIN, "US-III ")); else if (IS_CHEETAH_PLUS(*impl)) log_printf(dgettext(TEXT_DOMAIN, "US-III+ ")); else if (IS_JAGUAR(*impl)) log_printf(dgettext(TEXT_DOMAIN, "US-IV ")); else if (IS_PANTHER(*impl)) log_printf(dgettext(TEXT_DOMAIN, "US-IV+ ")); else log_printf("%-6x ", *impl); } /* CPU Mask */ if (mask == NULL) { log_printf(dgettext(TEXT_DOMAIN, " N/A\n")); } else { log_printf(dgettext(TEXT_DOMAIN, " %d.%d\n"), (*mask >> 4) & 0xf, *mask & 0xf); } } }
/* * Display the CPUs present on this board. */ void display_cpus(Board_node *board) { Prom_node *cpu; /* * display the CPUs' operating frequency, cache size, impl. field * and mask revision. */ for (cpu = dev_find_type(board->nodes, "cpu"); cpu != NULL; cpu = dev_next_type(cpu, "cpu")) { int freq; /* CPU clock frequency */ int ecache_size; /* External cache size */ int *mid; int *impl; int *mask, decoded_mask; mid = (int *)get_prop_val(find_prop(cpu, "upa-portid")); if (mid == NULL) { mid = (int *)get_prop_val(find_prop(cpu, "portid")); } freq = (get_cpu_freq(cpu) + 500000) / 1000000; ecache_size = get_ecache_size(cpu); impl = (int *)get_prop_val(find_prop(cpu, "implementation#")); mask = (int *)get_prop_val(find_prop(cpu, "mask#")); /* Do not display a failed CPU node */ if ((freq != 0) && (node_failed(cpu) == 0)) { /* Board number */ display_boardnum(board->board_num); /* CPU MID */ log_printf(" %2d ", *mid, 0); /* Module number */ display_mid(*mid); /* Running frequency */ log_printf(" %3d ", freq, 0); /* Ecache size */ if (ecache_size == 0) log_printf(" %3s ", "N/A", 0); else log_printf(" %4.1f ", (float)ecache_size / (float)(1<<20), 0); /* Implementation */ if (impl == NULL) { log_printf("%6s ", "N/A", 0); } else { switch (*impl) { case SPITFIRE_IMPL: log_printf("%-6s ", "US-I", 0); break; case BLACKBIRD_IMPL: log_printf("%-6s ", "US-II", 0); break; case CHEETAH_IMPL: log_printf("%-6s ", "US-III", 0); break; case CHEETAH_PLUS_IMPL: log_printf("%-7s ", "US-III+", 0); break; case JAGUAR_IMPL: log_printf("%-6s ", "US-IV", 0); break; default: log_printf("%-6x ", *impl, 0); break; } } /* CPU Mask */ if (mask == NULL) { log_printf(" %3s", "N/A", 0); } else { if ((impl) && IS_CHEETAH(*impl)) decoded_mask = REMAP_CHEETAH_MASK(*mask); else decoded_mask = *mask; log_printf(" %d.%d", (decoded_mask >> 4) & 0xf, decoded_mask & 0xf, 0); } log_printf("\n", 0); } }
/* * display_pci * Display all the PCI IO cards on this board. */ void display_pci(Board_node *board) { struct io_card *card_list = NULL; struct io_card card; void *value; Prom_node *pci; Prom_node *card_node; Prom_node *pci_bridge_node = NULL; char *slot_name_arr[MAX_SLOTS_PER_IO_BD] = {NULL}; char *slot_name = NULL; int slot_name_bits; int slot_name_offset = 0; char *child_name; char *name, *type; char buf[MAXSTRLEN]; int *int_val; int pci_bus; int pci_bridge = 0; int pci_bridge_dev_no; int child_dev_no; int i; int portid; int version, *pversion; if (board == NULL) return; /* Initialize all the common information */ card.display = TRUE; card.board = board->board_num; card.node_id = board->node_id; /* * Search for each schizo, then find/display all nodes under * each schizo node found. Since the model property "SUNW,schizo" * is not supported on Starcat, we must match on the compatible * property "pci108e,8001". */ for (pci = dev_find_node_by_compatible(board->nodes, SCHIZO_COMPATIBLE); pci != NULL; pci = dev_next_node_by_compatible(pci, SCHIZO_COMPATIBLE)) { /* set max freq for this board */ board_bus_max_freq = DEFAULT_MAX_FREQ; /* * Find out if this is a PCI or cPCI IO Board. * If "enum-impl" property exists in pci node => cPCI. */ value = get_prop_val(find_prop(pci, "enum-impl")); if (value == NULL) { (void) sprintf(card.bus_type, "PCI"); } else { (void) sprintf(card.bus_type, "cPCI"); } if (strstr((char *)get_prop_val( find_prop(pci, "compatible")), XMITS_COMPATIBLE)) { sprintf(card.notes, "%s", XMITS_COMPATIBLE); /* * With XMITS 3.X and PCI-X mode, the bus speed * can be higher than 66MHZ. */ value = (int *)get_prop_val (find_prop(pci, "module-revision#")); if (value) { pversion = (int *)value; version = *pversion; if (version >= 4) board_bus_max_freq = PCIX_MAX_FREQ; } } else if (strstr((char *)get_prop_val( find_prop(pci, "compatible")), SCHIZO_COMPATIBLE)) sprintf(card.notes, "%s", SCHIZO_COMPATIBLE); else sprintf(card.notes, " "); /* * Get slot-names property from parent node and * store the individual slot names in an array. * This is more general than Starcat requires, but * it is correct, according to the slot-names property. */ value = (char *)get_prop_val(find_prop(pci, "slot-names")); if (value == NULL) { /* * No slot_names property. This could be an Xmits * card, so check the child node for slot-names property */ value = (char *)get_prop_val( find_prop(pci->child, "slot-names")); } if (value != NULL) { /* Get the 4 byte bitmask and pointer to first name */ slot_name_bits = *(int *)value; if (slot_name_bits > 0) slot_name_offset = slot_name_bits - 1; slot_name = (char *)value + sizeof (int); for (i = 0; i < MAX_SLOTS_PER_IO_BD; i++) { if (! (slot_name_bits & (1 << i))) { slot_name_arr[i] = (char *)NULL; continue; } /* * Save the name pointer into the array * and advance it past the end of this * slot name */ slot_name_arr[i] = slot_name; slot_name += strlen(slot_name) + 1; } slot_name = (char *)NULL; } /* * Search for Children of this node ie. Cards. * Note: any of these cards can be a pci-bridge * that itself has children. If we find a * pci-bridge we need to handle it specially. */ card_node = pci->child; while (card_node != NULL) { pci_bridge = 0; /* If it doesn't have a name, skip it */ name = (char *)get_prop_val( find_prop(card_node, "name")); if (name == NULL) { card_node = card_node->sibling; continue; } /* * get dev# and func# for this card from the * 'reg' property. */ int_val = (int *)get_prop_val( find_prop(card_node, "reg")); if (int_val != NULL) { card.dev_no = (((*int_val) & 0xF800) >> 11); card.func_no = (((*int_val) & 0x700) >> 8); } else { card.dev_no = -1; card.func_no = -1; } /* * If this is a pci-bridge, then store it's dev# * as its children nodes need this to get their slot#. * We set the pci_bridge flag so that we know we are * looking at a pci-bridge node. This flag gets reset * every time we enter this while loop. */ /* * Check for a PCI-PCI Bridge for PCI and cPCI * IO Boards using the name and type properties. */ type = (char *)get_prop_val( find_prop(card_node, "device_type")); if ((type != NULL) && (strncmp(name, "pci", 3) == 0) && (strcmp(type, "pci") == 0)) { pci_bridge_dev_no = card.dev_no; pci_bridge_node = card_node; pci_bridge = TRUE; } /* * Get slot-names property from slot_names_arr. * If we are the child of a pci_bridge we use the * dev# of the pci_bridge as an index to get * the slot number. We know that we are a child of * a pci-bridge if our parent is the same as the last * pci_bridge node found above. */ if (card.dev_no != -1) { /* * We compare this card's parent node with the * pci_bridge_node to see if it's a child. */ if (card_node->parent == pci_bridge_node) { /* use dev_no of pci_bridge */ child_dev_no = pci_bridge_dev_no - 1; } else { /* use card's own dev_no */ child_dev_no = card.dev_no - 1; } if (child_dev_no < MAX_SLOTS_PER_IO_BD && child_dev_no >= 0 && slot_name_arr [child_dev_no + slot_name_offset] != NULL) { slot_name = slot_name_arr[ child_dev_no + slot_name_offset]; } else slot_name = (char *)NULL; if (slot_name != NULL && slot_name[0] != '\0') { (void) sprintf(card.slot_str, "%s", slot_name); } else { (void) sprintf(card.slot_str, "-"); } } else { (void) sprintf(card.slot_str, "%c", '-'); } /* * Get the portid of the schizo that this card * lives under. */ portid = -1; value = get_prop_val(find_prop(pci, "portid")); if (value != NULL) { portid = *(int *)value; } card.schizo_portid = portid; #ifdef DEBUG (void) sprintf(card.notes, "%s portid [%d]" " dev_no [%d] slot_name[%s] name_bits[%#x]", card.notes, portid, card.dev_no, ((slot_name != NULL) ? slot_name : "NULL"), slot_name_bits); #endif /* DEBUG */ /* * Find out whether this is PCI bus A or B * using the 'reg' property. */ int_val = (int *)get_prop_val (find_prop(pci, "reg")); if (int_val != NULL) { int_val ++; /* skip over first integer */ pci_bus = ((*int_val) & 0x7f0000); if (pci_bus == 0x600000) card.pci_bus = 'A'; else if (pci_bus == 0x700000) card.pci_bus = 'B'; else card.pci_bus = '-'; } else { card.pci_bus = '-'; } /* * Check for failed status. */ if (node_failed(card_node)) strcpy(card.status, "fail"); else strcpy(card.status, "ok"); /* Get the model of this card */ value = get_prop_val(find_prop(card_node, "model")); if (value == NULL) card.model[0] = '\0'; else { (void) sprintf(card.model, "%s", (char *)value); /* * If we wish to exclude onboard devices * (such as SBBC) then this is the place * and here is how to do it: * * if (strcmp(card.model, "SUNW,sbbc") == 0) { * card_node = card_node->sibling; * continue; * } */ } /* * The card may have a "clock-frequency" but we * are not interested in that. Instead we get the * "clock-frequency" of the PCI Bus that the card * resides on. PCI-A can operate at 33Mhz or 66Mhz * depending on what card is plugged into the Bus. * PCI-B always operates at 33Mhz. * */ int_val = get_prop_val(find_prop(pci, "clock-frequency")); if (int_val != NULL) { card.freq = HZ_TO_MHZ(*int_val); } else { card.freq = -1; } /* * Figure out how we want to display the name */ value = get_prop_val(find_prop(card_node, "compatible")); if (value != NULL) { /* use 'name'-'compatible' */ (void) sprintf(buf, "%s-%s", name, (char *)value); } else { /* just use 'name' */ (void) sprintf(buf, "%s", name); } name = buf; /* * If this node has children, add the device_type * of the child to the name value of this card. */ child_name = (char *)get_node_name(card_node->child); if ((card_node->child != NULL) && (child_name != NULL)) { value = get_prop_val(find_prop(card_node->child, "device_type")); if (value != NULL) { /* add device_type of child to name */ (void) sprintf(card.name, "%s/%s (%s)", name, child_name, (char *)value); } else { /* just add child's name */ (void) sprintf(card.name, "%s/%s", name, child_name); } } else { /* childless, just the card's name */ (void) sprintf(card.name, "%s", (char *)name); } /* * If this is a pci-bridge, then add the word * 'pci-bridge' to its model. */ if (pci_bridge) { if (card.model[0] == '\0') (void) sprintf(card.model, "%s", "pci-bridge"); else (void) strcat(card.model, "/pci-bridge"); } /* insert this card in the list to be displayed later */ card_list = insert_io_card(card_list, &card); /* * If we are dealing with a pci-bridge, we need to move * down to the children of this bridge, if there are * any, otherwise its siblings. * * If not a bridge, we are either dealing with a regular * card (in which case we move onto the sibling of this * card) or we are dealing with a child of a pci-bridge * (in which case we move onto the child's siblings or * if there are no more siblings for this child, we * move onto the parent's siblings). I hope you're * getting all this, there will be an exam later. */ if (pci_bridge) { if (card_node->child != NULL) card_node = card_node->child; else card_node = card_node->sibling; } else { /* * If our parent is a pci-bridge but there * are no more of its children to process we * move back up to our parent's sibling, * otherwise we move onto our own sibling. */ if ((card_node->parent == pci_bridge_node) && (card_node->sibling == NULL)) card_node = pci_bridge_node->sibling; else card_node = card_node->sibling; } } /* end while (card_node ...) loop */