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