割り込みコントローラへのSMP対応コード
全く動作確認取ってないしコンパイルすら通してないけど、俺のゴーストはこれで大丈夫とささやいてるから多分大体あってるはず。
アクセスするレジスタ類はLinuxのip27のコードに合わせて、interm,imaskの配列化は以前ip30向けに実装したコードを参照。
Index: ip27_machdep.c =================================================================== RCS file: /cvs/src/sys/arch/sgi/sgi/ip27_machdep.c,v retrieving revision 1.51 diff -u -p -r1.51 ip27_machdep.c --- ip27_machdep.c 9 May 2010 18:37:47 -0000 1.51 +++ ip27_machdep.c 21 May 2010 05:58:48 -0000 @@ -108,7 +113,7 @@ struct intrhand *hubpi_intrhand1[HUBPI_N struct { uint64_t hw[2]; -} hubpi_intem, hubpi_imask[NIPLS]; +} hubpi_intem[MAXCPUS], hubpi_imask[MAXCPUS][NIPLS]; void ip27_setup() @@ -645,12 +663,13 @@ int ip27_hub_intr_register(int widget, int level, int *intrbit) { int bit; + u_long cpuid = cpu_number(); /* * Try to allocate a bit on hardware level 0 first. */ for (bit = HUBPI_INTR0_WIDGET_MAX; bit >= HUBPI_INTR0_WIDGET_MIN; bit--) - if ((hubpi_intem.hw[0] & (1UL << bit)) == 0) + if ((hubpi_intem[cpuid].hw[0] & (1UL << bit)) == 0) goto found; /* @@ -806,21 +825,25 @@ ip27_hub_splx(int newipl) #define INTR_FUNCTIONNAME hubpi_intr0 #define MASK_FUNCTIONNAME ip27_hub_intr_makemasks0 -#define INTR_LOCAL_DECLS -#define MASK_LOCAL_DECLS +#define INTR_LOCAL_DECLS \ + u_long cpuid = cpu_number(); +#define MASK_LOCAL_DECLS \ + u_long cpuid = cpu_number(); #define INTR_GETMASKS \ do { \ - /* XXX this assumes we run on cpu0 */ \ + int cpu = curcpu()->ci_hw.physid; \ isr = IP27_LHUB_L(HUBPI_IR0); \ - imr = IP27_LHUB_L(HUBPI_CPU0_IMR0); \ + imr = IP27_LHUB_L(cpu == 0 ? HUBPI_CPU0_IMR0 : HUBPI_CPU1_IMR0); \ bit = HUBPI_INTR0_WIDGET_MAX; \ } while (0) #define INTR_MASKPENDING \ do { \ - IP27_LHUB_S(HUBPI_CPU0_IMR0, imr & ~isr); \ + int cpu = curcpu()->ci_hw.physid; \ + IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR0 : HUBPI_CPU1_IMR0, \ + imr & ~isr); \ (void)IP27_LHUB_L(HUBPI_IR0); \ } while (0) -#define INTR_IMASK(ipl) hubpi_imask[ipl].hw[0] +#define INTR_IMASK(ipl) hubpi_imask[cpuid][ipl].hw[0] #define INTR_HANDLER(bit) hubpi_intrhand0[bit] #define INTR_SPURIOUS(bit) \ do { \ @@ -828,7 +851,8 @@ do { \ } while (0) #define INTR_MASKRESTORE \ do { \ - IP27_LHUB_S(HUBPI_CPU0_IMR0, imr); \ + int cpu = curcpu()->ci_hw.physid; \ + IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR0 : HUBPI_CPU1_IMR0, imr); \ (void)IP27_LHUB_L(HUBPI_IR0); \ } while (0) #define INTR_MASKSIZE HUBPI_NINTS @@ -837,21 +861,25 @@ do { \ #define INTR_FUNCTIONNAME hubpi_intr1 #define MASK_FUNCTIONNAME ip27_hub_intr_makemasks1 -#define INTR_LOCAL_DECLS -#define MASK_LOCAL_DECLS +#define INTR_LOCAL_DECLS \ + u_long cpuid = cpu_number(); +#define MASK_LOCAL_DECLS \ + u_long cpuid = cpu_number(); #define INTR_GETMASKS \ do { \ - /* XXX this assumes we run on cpu0 */ \ + int cpu = curcpu()->ci_hw.physid; \ isr = IP27_LHUB_L(HUBPI_IR1); \ - imr = IP27_LHUB_L(HUBPI_CPU0_IMR1); \ + imr = IP27_LHUB_L(cpuid == 0 ? HUBPI_CPU0_IMR1 : HUBPI_CPU1_IMR1); \ bit = HUBPI_INTR1_WIDGET_MAX; \ } while (0) #define INTR_MASKPENDING \ do { \ - IP27_LHUB_S(HUBPI_CPU0_IMR1, imr & ~isr); \ + int cpu = curcpu()->ci_hw.physid; \ + IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR1 : HUBPI_CPU1_IMR1, \ + imr & ~isr); \ (void)IP27_LHUB_L(HUBPI_IR1); \ } while (0) -#define INTR_IMASK(ipl) hubpi_imask[ipl].hw[1] +#define INTR_IMASK(ipl) hubpi_imask[cpuid][ipl].hw[1] #define INTR_HANDLER(bit) hubpi_intrhand1[bit] #define INTR_SPURIOUS(bit) \ do { \ @@ -859,7 +887,8 @@ do { \ } while (0) #define INTR_MASKRESTORE \ do { \ - IP27_LHUB_S(HUBPI_CPU0_IMR1, imr); \ + int cpu = curcpu()->ci_hw.physid; \ + IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR1 : HUBPI_CPU1_IMR1, imr); \ (void)IP27_LHUB_L(HUBPI_IR1); \ } while (0) #define INTR_MASKSIZE HUBPI_NINTS @@ -869,12 +898,13 @@ do { \ void ip27_hub_setintrmask(int level) { - /* XXX this assumes we run on cpu0 */ - IP27_LHUB_S(HUBPI_CPU0_IMR0, - hubpi_intem.hw[0] & ~hubpi_imask[level].hw[0]); + int cpu = curcpu()->ci_hw.physid; + u_long cpuid = cpu_number(); + IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR0 : HUBPI_CPU1_IMR0, + hubpi_intem[cpuid].hw[0] & ~hubpi_imask[cpuid][level].hw[0]); (void)IP27_LHUB_L(HUBPI_IR0); - IP27_LHUB_S(HUBPI_CPU0_IMR1, - hubpi_intem.hw[1] & ~hubpi_imask[level].hw[1]); + IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR1 : HUBPI_CPU1_IMR1, + hubpi_intem[cpuid].hw[1] & ~hubpi_imask[cpuid][level].hw[1]); (void)IP27_LHUB_L(HUBPI_IR1); }