1 /* 2 * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) 3 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 4 */ 5 #include <linux/kernel.h> 6 #include <linux/sched.h> 7 #include <linux/interrupt.h> 8 #include <linux/kernel_stat.h> 9 #include <linux/param.h> 10 #include <linux/timex.h> 11 #include <linux/mm.h> 12 13 #include <asm/sn/klconfig.h> 14 #include <asm/sn/arch.h> 15 #include <asm/sn/gda.h> 16 17 klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type) 18 { 19 int index, j; 20 21 if (kli == (klinfo_t *)NULL) { 22 index = 0; 23 } else { 24 for (j = 0; j < KLCF_NUM_COMPS(brd); j++) 25 if (kli == KLCF_COMP(brd, j)) 26 break; 27 index = j; 28 if (index == KLCF_NUM_COMPS(brd)) { 29 printk("find_component: Bad pointer: 0x%p\n", kli); 30 return (klinfo_t *)NULL; 31 } 32 index++; /* next component */ 33 } 34 35 for (; index < KLCF_NUM_COMPS(brd); index++) { 36 kli = KLCF_COMP(brd, index); 37 if (KLCF_COMP_TYPE(kli) == struct_type) 38 return kli; 39 } 40 41 /* Didn't find it. */ 42 return (klinfo_t *)NULL; 43 } 44 45 klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type) 46 { 47 return find_component(brd, (klinfo_t *)NULL, struct_type); 48 } 49 50 lboard_t *find_lboard(lboard_t *start, unsigned char brd_type) 51 { 52 /* Search all boards stored on this node. */ 53 while (start) { 54 if (start->brd_type == brd_type) 55 return start; 56 start = KLCF_NEXT(start); 57 } 58 /* Didn't find it. */ 59 return (lboard_t *)NULL; 60 } 61 62 lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_type) 63 { 64 /* Search all boards stored on this node. */ 65 while (start) { 66 if (KLCLASS(start->brd_type) == KLCLASS(brd_type)) 67 return start; 68 start = KLCF_NEXT(start); 69 } 70 71 /* Didn't find it. */ 72 return (lboard_t *)NULL; 73 } 74 75 cnodeid_t get_cpu_cnode(cpuid_t cpu) 76 { 77 return CPUID_TO_COMPACT_NODEID(cpu); 78 } 79 80 klcpu_t *nasid_slice_to_cpuinfo(nasid_t nasid, int slice) 81 { 82 lboard_t *brd; 83 klcpu_t *acpu; 84 85 if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27))) 86 return (klcpu_t *)NULL; 87 88 if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU))) 89 return (klcpu_t *)NULL; 90 91 do { 92 if ((acpu->cpu_info.physid) == slice) 93 return acpu; 94 } while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, 95 KLSTRUCT_CPU))); 96 return (klcpu_t *)NULL; 97 } 98 99 klcpu_t *sn_get_cpuinfo(cpuid_t cpu) 100 { 101 nasid_t nasid; 102 int slice; 103 klcpu_t *acpu; 104 gda_t *gdap = GDA; 105 cnodeid_t cnode; 106 107 if (!(cpu < MAXCPUS)) { 108 printk("sn_get_cpuinfo: illegal cpuid 0x%lx\n", cpu); 109 return NULL; 110 } 111 112 cnode = get_cpu_cnode(cpu); 113 if (cnode == INVALID_CNODEID) 114 return NULL; 115 116 if ((nasid = gdap->g_nasidtable[cnode]) == INVALID_NASID) 117 return NULL; 118 119 for (slice = 0; slice < CPUS_PER_NODE; slice++) { 120 acpu = nasid_slice_to_cpuinfo(nasid, slice); 121 if (acpu && acpu->cpu_info.virtid == cpu) 122 return acpu; 123 } 124 return NULL; 125 } 126 127 int get_cpu_slice(cpuid_t cpu) 128 { 129 klcpu_t *acpu; 130 131 if ((acpu = sn_get_cpuinfo(cpu)) == NULL) 132 return -1; 133 return acpu->cpu_info.physid; 134 } 135