did2さんにOpenBSDの立派な環境構築メモを書いて頂きまんた
「もちろんOpenBSDですよね、わかります。RT @did2memo: OSなど買ってきた」
という私のTwitterでのネタつぶやきが発端でdid2さんにOpenBSDの立派な環境構築メモを書いて頂きました!
こちらからどうぞ↓
OpenBSDのインストール方法詳細メモ(1) - 情報科学屋さんを目指す人のメモ(FC2ブログ版)
感謝。
cpu1にIPIがかからないずら。
現状:
- cpu1でクロック割り込みはかかる
- cpu0→cpu0のIPIはかかる
- cpu1→cpu0のIPIはかかる
- cpu1→cpu1のIPIはかからない
- cpu0→cpu1のIPIはかからない
何となく、割り込みコントローラへの設定などなどがしくってるような気がするけど、IMR0の値もステータスレジスタの値も一見正しく見えるし、どこが悪いのか良く分からない。
実はIRQが違うとか?
そしてコミット出来ぬまま太り続けるパッチ。
Index: mips64/include/autoconf.h =================================================================== RCS file: /cvs/src/sys/arch/mips64/include/autoconf.h,v retrieving revision 1.1 diff -u -p -r1.1 autoconf.h --- mips64/include/autoconf.h 9 Jan 2010 20:33:16 -0000 1.1 +++ mips64/include/autoconf.h 31 May 2010 14:20:54 -0000 @@ -30,6 +30,6 @@ struct cpu_attach_args { struct cpu_hwinfo *caa_hw; }; -extern struct cpu_hwinfo bootcpu_hwinfo; +extern struct cpu_hwinfo cpu_hwinfo[MAXCPUS]; #endif /* _MIPS64_AUTOCONF_H_ */ Index: mips64/include/cpu.h =================================================================== RCS file: /cvs/src/sys/arch/mips64/include/cpu.h,v retrieving revision 1.58 diff -u -p -r1.58 cpu.h --- mips64/include/cpu.h 28 Apr 2010 16:20:28 -0000 1.58 +++ mips64/include/cpu.h 31 May 2010 14:20:55 -0000 @@ -370,6 +370,10 @@ struct cpu_hwinfo { uint32_t tlbsize; uint type; uint32_t l2size; +#ifdef TGT_ORIGIN + int nasid; + int physid; +#endif }; struct cpu_info { Index: mips64/mips64/clock.c =================================================================== RCS file: /cvs/src/sys/arch/mips64/mips64/clock.c,v retrieving revision 1.33 diff -u -p -r1.33 clock.c --- mips64/mips64/clock.c 28 Feb 2010 17:23:25 -0000 1.33 +++ mips64/mips64/clock.c 31 May 2010 14:20:55 -0000 @@ -194,7 +194,7 @@ delay(int n) delayconst = ci->ci_delayconst; if (delayconst == 0) - delayconst = bootcpu_hwinfo.clock / 2; + delayconst = cpu_hwinfo[cpu_number()].clock / 2; p = cp0_get_count(); dly = (delayconst / 1000000) * n; while (dly > 0) { Index: sgi/include/intr.h =================================================================== RCS file: /cvs/src/sys/arch/sgi/include/intr.h,v retrieving revision 1.41 diff -u -p -r1.41 intr.h --- sgi/include/intr.h 18 Jan 2010 16:59:23 -0000 1.41 +++ sgi/include/intr.h 31 May 2010 14:20:56 -0000 @@ -190,6 +190,8 @@ void dosoftint(void); #ifdef MULTIPROCESSOR #if defined (TGT_OCTANE) #define ENABLEIPI() updateimask(~CR_INT_2) /* enable IPI interrupt level */ +#elif defined (TGT_ORIGIN) +#define ENABLEIPI() updateimask(~CR_INT_0) /* enable IPI interrupt level */ #else #error MULTIPROCESSOR kernel not supported on this configuration #endif Index: sgi/sgi/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 --- sgi/sgi/ip27_machdep.c 9 May 2010 18:37:47 -0000 1.51 +++ sgi/sgi/ip27_machdep.c 31 May 2010 14:20:56 -0000 @@ -28,6 +28,7 @@ #include <sys/malloc.h> #include <sys/reboot.h> #include <sys/tty.h> +#include <sys/proc.h> #include <mips64/arcbios.h> #include <mips64/archtype.h> @@ -56,6 +57,7 @@ extern char *hw_prod; extern void (*md_halt)(int); + paddr_t ip27_widget_short(int16_t, u_int); paddr_t ip27_widget_long(int16_t, u_int); paddr_t ip27_widget_map(int16_t, u_int,bus_addr_t *, bus_size_t *); @@ -108,7 +110,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() @@ -297,6 +299,10 @@ ip27_setup() void ip27_autoconf(struct device *parent) { +#ifdef MULTIPROCESSOR + int cpuid; +#endif + union { struct mainbus_attach_args maa; struct cpu_attach_args caa; @@ -313,11 +319,20 @@ ip27_autoconf(struct device *parent) bzero(&u, sizeof u); u.maa.maa_name = "cpu"; u.maa.maa_nasid = currentnasid = masternasid; - u.caa.caa_hw = &bootcpu_hwinfo; + u.caa.caa_hw = &cpu_hwinfo[0]; config_found(parent, &u, ip27_print); u.maa.maa_name = "clock"; config_found(parent, &u, ip27_print); - +#ifdef MULTIPROCESSOR + for (cpuid = 1; cpuid < MAXCPUS; cpuid++) + if (cpu_hwinfo[cpuid].clock != 0 + && cpu_hwinfo[cpuid].nasid == currentnasid) { + u.maa.maa_name = "cpu"; + u.maa.maa_nasid = currentnasid; + u.caa.caa_hw = &cpu_hwinfo[cpuid]; + config_found(parent, &u, ip27_print); + } +#endif /* * Now attach all nodes' I/O devices. */ @@ -645,12 +660,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; /* @@ -658,7 +674,7 @@ ip27_hub_intr_register(int widget, int l * level 1. */ for (bit = HUBPI_INTR1_WIDGET_MAX; bit >= HUBPI_INTR1_WIDGET_MIN; bit--) - if ((hubpi_intem.hw[1] & (1UL << bit)) == 0) { + if ((hubpi_intem[cpuid].hw[1] & (1UL << bit)) == 0) { bit += HUBPI_NINTS; goto found; } @@ -679,6 +695,7 @@ ip27_hub_intr_establish(int (*func)(void { struct intrhand *ih, **anchor; int s; + u_long cpuid = cpu_number(); #ifdef DIAGNOSTIC if (intrbit < 0 || intrbit >= HUBPI_NINTS + HUBPI_NINTS) @@ -723,7 +740,8 @@ ip27_hub_intr_establish(int (*func)(void *anchor = ih; - hubpi_intem.hw[intrbit / HUBPI_NINTS] |= 1UL << (intrbit % HUBPI_NINTS); + hubpi_intem[cpuid].hw[intrbit / HUBPI_NINTS] + |= 1UL << (intrbit % HUBPI_NINTS); if (intrbit / HUBPI_NINTS != 0) ip27_hub_intr_makemasks1(); else @@ -739,6 +757,7 @@ ip27_hub_intr_disestablish(int intrbit) { struct intrhand *ih, **anchor; int s; + u_long cpuid = cpu_number(); #ifdef DIAGNOSTIC if (intrbit < 0 || intrbit >= HUBPI_NINTS + HUBPI_NINTS) @@ -759,7 +778,7 @@ ip27_hub_intr_disestablish(int intrbit) *anchor = NULL; - hubpi_intem.hw[intrbit / HUBPI_NINTS] &= + hubpi_intem[cpuid].hw[intrbit / HUBPI_NINTS] &= ~(1UL << (intrbit % HUBPI_NINTS)); if (intrbit / HUBPI_NINTS != 0) ip27_hub_intr_makemasks1(); @@ -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 physid = curcpu()->ci_hw.physid; \ isr = IP27_LHUB_L(HUBPI_IR0); \ - imr = IP27_LHUB_L(HUBPI_CPU0_IMR0); \ + imr = IP27_LHUB_L(!physid ? 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 physid = curcpu()->ci_hw.physid; \ + IP27_LHUB_S(!physid ? 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 physid = curcpu()->ci_hw.physid; \ + IP27_LHUB_S(!physid ? 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 physid = curcpu()->ci_hw.physid; \ isr = IP27_LHUB_L(HUBPI_IR1); \ - imr = IP27_LHUB_L(HUBPI_CPU0_IMR1); \ + imr = IP27_LHUB_L(!physid ? 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 physid = curcpu()->ci_hw.physid; \ + IP27_LHUB_S(!physid ? 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 physid = curcpu()->ci_hw.physid; \ + IP27_LHUB_S(!physid ? 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 physid = curcpu()->ci_hw.physid; + u_long cpuid = cpu_number(); + IP27_LHUB_S(!physid ? 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(!physid ? HUBPI_CPU0_IMR1 : HUBPI_CPU1_IMR1, + hubpi_intem[cpuid].hw[1] & ~hubpi_imask[cpuid][level].hw[1]); (void)IP27_LHUB_L(HUBPI_IR1); } @@ -919,3 +949,142 @@ ip27_nmi(void *arg) printf("Resetting system...\n"); boot(RB_USERREQ); } + +#ifdef MULTIPROCESSOR +void build_trampoline(vaddr_t, vaddr_t); + +#define LAUNCH_SLAVE \ + (*(void (*)(int nasid, int cpu, void *call_addr, uint64_t call_parm, \ + void *stack_addr, void *gp_addr)) PHYS_TO_CKSEG1(0x1fc00038)) + +void +hw_cpu_boot_secondary(struct cpu_info *ci) +{ + vaddr_t kstack; + + kstack = alloc_contiguous_pages(USPACE); + if (kstack == NULL) + panic("unable to allocate idle stack\n"); + ci->ci_curprocpaddr = (void *)kstack; + + LAUNCH_SLAVE(ci->ci_hw.nasid, ci->ci_hw.physid, + hw_cpu_spinup_trampoline, (uint64_t)ci, + (void *)(kstack + USPACE), 0); + + while (!cpuset_isset(&cpus_running, ci)) + ; +} + +void +hw_cpu_hatch(struct cpu_info *ci) +{ + int s; + vaddr_t xtlb_handler; + extern char exception[], e_exception[]; + + /* + * Set curcpu address on this processor. + */ + setcurcpu(ci); + + /* + * Make sure we can access the extended address space. + * Note that r10k and later do not allow XUSEG accesses + * from kernel mode unless SR_UX is set. + */ + setsr(getsr() | SR_KX | SR_UX); + + tlb_set_page_mask(TLB_PAGE_MASK); + tlb_set_wired(0); + tlb_flush(64); + tlb_set_wired(UPAGES / 2); + + tlb_set_pid(0); + + /* + * Copy down exception vector code. + */ + bcopy(exception, (char *)CACHE_ERR_EXC_VEC, e_exception - exception); + bcopy(exception, (char *)GEN_EXC_VEC, e_exception - exception); + + /* + * Build proper TLB refill handler trampolines. + */ + extern void xtlb_miss; + xtlb_handler = (vaddr_t)&xtlb_miss; + + build_trampoline(TLB_MISS_EXC_VEC, xtlb_handler); + build_trampoline(XTLB_MISS_EXC_VEC, xtlb_handler); + + /* + * Turn off bootstrap exception vectors. + */ + setsr(getsr() & ~SR_BOOT_EXC_VEC); + + /* + * Clear out the I and D caches. + */ + Mips10k_ConfigCache(ci); + Mips_SyncCache(ci); + + cpu_startclock(ci); + ncpus++; + cpuset_add(&cpus_running, ci); + mips64_ipi_init(); + ip27_hub_setintrmask(0); + spl0(); + (void)updateimask(0); + +#ifdef DEBUG + printf("imr0: %x\n", + IP27_LHUB_L(HUBPI_CPU1_IMR0)); + printf("sr: %x\n", + getsr()); +#endif + + SCHED_LOCK(s); + cpu_switchto(NULL, sched_chooseproc()); +} + +int +hw_ipi_intr_establish(int (*func)(void *), u_long cpuid) +{ + int physid = get_cpu_info(cpuid)->ci_hw.physid; + int level = !physid ? HUBPI_ISR0_CPU_ACTION_A : HUBPI_ISR0_CPU_ACTION_B; + +#ifdef DEBUG + printf("hw_ipi_intr_establish(%d)\n", cpuid); +#endif + ip27_hub_intr_establish(func, (void *)cpuid, level, + IPL_IPI, NULL, &curcpu()->ci_ipiih); + + return 0; +}; + +void +hw_ipi_intr_set(u_long cpuid) +{ + int physid = get_cpu_info(cpuid)->ci_hw.physid; + int level = !physid ? HUBPI_ISR0_CPU_ACTION_A : HUBPI_ISR0_CPU_ACTION_B; + +#ifdef DEBUG + printf("hw_ipi_intr_set(%d)\n", cpuid); +#endif + + ip27_hub_intr_set(level); +} + +void +hw_ipi_intr_clear(u_long cpuid) +{ + int physid = get_cpu_info(cpuid)->ci_hw.physid; + int level = !physid ? HUBPI_ISR0_CPU_ACTION_A : HUBPI_ISR0_CPU_ACTION_B; + +#ifdef DEBUG + printf("hw_ipi_intr_clear(%d)\n", cpuid); +#endif + + ip27_hub_intr_clear(level); +} + +#endif Index: sgi/sgi/ip30_machdep.c =================================================================== RCS file: /cvs/src/sys/arch/sgi/sgi/ip30_machdep.c,v retrieving revision 1.42 diff -u -p -r1.42 ip30_machdep.c --- sgi/sgi/ip30_machdep.c 28 Apr 2010 16:20:28 -0000 1.42 +++ sgi/sgi/ip30_machdep.c 31 May 2010 14:20:56 -0000 @@ -160,14 +160,14 @@ ip30_setup() xbow_widget_map = ip30_widget_map; xbow_widget_id = ip30_widget_id; - bootcpu_hwinfo.c0prid = cp0_get_prid(); - bootcpu_hwinfo.c1prid = cp1_get_prid(); + cpu_hwinfo[0].c0prid = cp0_get_prid(); + cpu_hwinfo[0].c1prid = cp1_get_prid(); cpuspeed = bios_getenvint("cpufreq"); if (cpuspeed < 100) cpuspeed = 175; /* reasonable default */ - bootcpu_hwinfo.clock = cpuspeed * 1000000; - bootcpu_hwinfo.tlbsize = 64; /* R10000 family */ - bootcpu_hwinfo.type = (bootcpu_hwinfo.c0prid >> 8) & 0xff; + cpu_hwinfo[0].clock = cpuspeed * 1000000; + cpu_hwinfo[0].tlbsize = 64; /* R10000 family */ + cpu_hwinfo[0].type = (cpu_hwinfo[0].c0prid >> 8) & 0xff; /* * Initialize the early console parameters. @@ -232,7 +232,7 @@ ip30_autoconf(struct device *parent) bzero(&caa, sizeof caa); caa.caa_maa.maa_nasid = masternasid; caa.caa_maa.maa_name = "cpu"; - caa.caa_hw = &bootcpu_hwinfo; + caa.caa_hw = &cpu_hwinfo[0]; config_found(parent, &caa, mbprint); #ifdef MULTIPROCESSOR @@ -245,7 +245,7 @@ ip30_autoconf(struct device *parent) * since Octane processors should be identical * (model, speed and cache), this should be safe. */ - bcopy(&bootcpu_hwinfo, &hw, sizeof(struct cpu_hwinfo)); + bcopy(&cpu_hwinfo[0], &hw, sizeof(struct cpu_hwinfo)); hw.c0prid = *(volatile uint32_t *)(mpconf + MPCONF_PRID(cpuid)); hw.type = (hw.c0prid >> 8) & 0xff; Index: sgi/sgi/ip32_machdep.c =================================================================== RCS file: /cvs/src/sys/arch/sgi/sgi/ip32_machdep.c,v retrieving revision 1.15 diff -u -p -r1.15 ip32_machdep.c --- sgi/sgi/ip32_machdep.c 6 Apr 2010 19:15:29 -0000 1.15 +++ sgi/sgi/ip32_machdep.c 31 May 2010 14:20:57 -0000 @@ -127,18 +127,18 @@ ip32_setup() break; } - bootcpu_hwinfo.c0prid = cp0_get_prid(); - bootcpu_hwinfo.c1prid = cp1_get_prid(); + cpu_hwinfo[0].c0prid = cp0_get_prid(); + cpu_hwinfo[0].c1prid = cp1_get_prid(); cpuspeed = bios_getenvint("cpufreq"); if (cpuspeed < 100) cpuspeed = 180; /* reasonable default */ - bootcpu_hwinfo.clock = cpuspeed * 1000000; - bootcpu_hwinfo.type = (bootcpu_hwinfo.c0prid >> 8) & 0xff; + cpu_hwinfo[0].clock = cpuspeed * 1000000; + cpu_hwinfo[0].type = (cpu_hwinfo[0].c0prid >> 8) & 0xff; /* * Figure out how many TLB are available. */ - switch (bootcpu_hwinfo.type) { + switch (cpu_hwinfo[0].type) { #ifdef CPU_RM7000 case MIPS_RM7000: /* @@ -162,8 +162,8 @@ ip32_setup() * the highest valid TLB entry we can find and * see if it is in the upper 16 entries or not. */ - bootcpu_hwinfo.tlbsize = 48; - if (((bootcpu_hwinfo.c0prid >> 4) & 0x0f) >= 2) { + cpu_hwinfo[0].tlbsize = 48; + if (((cpu_hwinfo[0].c0prid >> 4) & 0x0f) >= 2) { struct tlb_entry te; int e, lastvalid; @@ -180,7 +180,7 @@ ip32_setup() } tlb_flush(64); if (lastvalid >= 48) - bootcpu_hwinfo.tlbsize = 64; + cpu_hwinfo[0].tlbsize = 64; } break; #endif @@ -188,11 +188,11 @@ ip32_setup() case MIPS_R10000: case MIPS_R12000: case MIPS_R14000: - bootcpu_hwinfo.tlbsize = 64; + cpu_hwinfo[0].tlbsize = 64; break; #endif default: /* R5000, RM52xx */ - bootcpu_hwinfo.tlbsize = 48; + cpu_hwinfo[0].tlbsize = 48; break; } Index: sgi/sgi/machdep.c =================================================================== RCS file: /cvs/src/sys/arch/sgi/sgi/machdep.c,v retrieving revision 1.102 diff -u -p -r1.102 machdep.c --- sgi/sgi/machdep.c 28 Apr 2010 21:26:47 -0000 1.102 +++ sgi/sgi/machdep.c 31 May 2010 14:20:57 -0000 @@ -111,7 +111,7 @@ int16_t masternasid; int32_t *environment; struct sys_rec sys_config; -struct cpu_hwinfo bootcpu_hwinfo; +struct cpu_hwinfo cpu_hwinfo[MAXCPUS]; /* Pointers to the start and end of the symbol table. */ caddr_t ssym; @@ -352,7 +352,7 @@ mips_init(int argc, void *argv, caddr_t /* * Configure cache. */ - switch (bootcpu_hwinfo.type) { + switch (cpu_hwinfo[0].type) { #ifdef CPU_R10000 case MIPS_R10000: case MIPS_R12000: @@ -425,7 +425,7 @@ mips_init(int argc, void *argv, caddr_t tlb_set_page_mask(TLB_PAGE_MASK); tlb_set_wired(0); - tlb_flush(bootcpu_hwinfo.tlbsize); + tlb_flush(cpu_hwinfo[0].tlbsize); tlb_set_wired(UPAGES / 2); /* Index: sgi/sgi/mainbus.c =================================================================== RCS file: /cvs/src/sys/arch/sgi/sgi/mainbus.c,v retrieving revision 1.8 diff -u -p -r1.8 mainbus.c --- sgi/sgi/mainbus.c 9 Jan 2010 20:33:16 -0000 1.8 +++ sgi/sgi/mainbus.c 31 May 2010 14:20:57 -0000 @@ -96,7 +96,7 @@ mbattach(struct device *parent, struct d bzero(&caa, sizeof caa); caa.caa_maa.maa_name = "cpu"; - caa.caa_hw = &bootcpu_hwinfo; + caa.caa_hw = &cpu_hwinfo[0]; config_found(self, &caa, mbprint); caa.caa_maa.maa_name = "clock"; Index: sgi/sgi/sginode.c =================================================================== RCS file: /cvs/src/sys/arch/sgi/sgi/sginode.c,v retrieving revision 1.19 diff -u -p -r1.19 sginode.c --- sgi/sgi/sginode.c 6 Apr 2010 19:09:50 -0000 1.19 +++ sgi/sgi/sginode.c 31 May 2010 14:20:57 -0000 @@ -76,6 +76,7 @@ int kl_n_mode = 0; u_int kl_n_shift = 32; klinfo_t *kl_glass_console = NULL; + void kl_init(int ip35) { @@ -249,17 +250,33 @@ kl_first_pass_comp(klinfo_t *comp, void * XXX this assumes the first cpu encountered is the boot * XXX cpu. */ - if (bootcpu_hwinfo.clock == 0) { - bootcpu_hwinfo.c0prid = cpucomp->cpu_prid; + if (cpu_hwinfo[0].clock == 0) { + cpu_hwinfo[0].c0prid = cpucomp->cpu_prid; + if (ip35) + cpu_hwinfo[0].c1prid = cpucomp->cpu_prid; + else + cpu_hwinfo[0].c1prid = cpucomp->cpu_fpirr; + cpu_hwinfo[0].clock = cpucomp->cpu_speed * 1000000; + cpu_hwinfo[0].tlbsize = 64; + cpu_hwinfo[0].type = (cpucomp->cpu_prid >> 8) & 0xff; + cpu_hwinfo[0].nasid = comp->nasid; + cpu_hwinfo[0].physid = comp->physid; + } else { +#ifdef MULTIPROCESSOR + int cpuid = ncpusfound; + cpu_hwinfo[cpuid].c0prid = cpucomp->cpu_prid; if (ip35) - bootcpu_hwinfo.c1prid = cpucomp->cpu_prid; + cpu_hwinfo[cpuid].c1prid = cpucomp->cpu_prid; else - bootcpu_hwinfo.c1prid = cpucomp->cpu_fpirr; - bootcpu_hwinfo.clock = cpucomp->cpu_speed * 1000000; - bootcpu_hwinfo.tlbsize = 64; - bootcpu_hwinfo.type = (cpucomp->cpu_prid >> 8) & 0xff; - } else + cpu_hwinfo[cpuid].c1prid = cpucomp->cpu_fpirr; + cpu_hwinfo[cpuid].clock = cpucomp->cpu_speed * 1000000; + cpu_hwinfo[cpuid].tlbsize = 64; + cpu_hwinfo[cpuid].type = (cpucomp->cpu_prid >> 8) & 0xff; + cpu_hwinfo[cpuid].nasid = comp->nasid; + cpu_hwinfo[cpuid].physid = comp->physid; +#endif ncpusfound++; + } break; case KLSTRUCT_MEMBNK: Index: sgi/xbow/hub.h =================================================================== RCS file: /cvs/src/sys/arch/sgi/xbow/hub.h,v retrieving revision 1.7 diff -u -p -r1.7 hub.h --- sgi/xbow/hub.h 8 Nov 2009 22:44:16 -0000 1.7 +++ sgi/xbow/hub.h 31 May 2010 14:20:57 -0000 @@ -145,7 +145,9 @@ /* 35-0 available */ /** Level 0 interrupt */ -/* 63-7 available */ +/* 63-9 available */ +#define HUBPI_ISR0_CPU_ACTION_B 8 +#define HUBPI_ISR0_CPU_ACTION_A 7 /* IPI interrupts */ #define HUBPI_ISR0_IPI_B 6 #define HUBPI_ISR0_IPI_A 5
IPI
Index: hub.h =================================================================== RCS file: /cvs/src/sys/arch/sgi/xbow/hub.h,v retrieving revision 1.7 diff -u -p -r1.7 hub.h --- hub.h 8 Nov 2009 22:44:16 -0000 1.7 +++ hub.h 22 May 2010 12:08:57 -0000 @@ -145,7 +145,11 @@ /* 35-0 available */ /** Level 0 interrupt */ -/* 63-7 available */ +/* 63-11 available */ +#define HUBPI_ISR0_CPU_CALL_B 10 +#define HUBPI_ISR0_CPU_CALL_A 9 +#define HUBPI_ISR0_CPU_RESCHED_B 8 +#define HUBPI_ISR0_CPU_RESCHED_A 7 /* IPI interrupts */ #define HUBPI_ISR0_IPI_B 6 #define HUBPI_ISR0_IPI_A 5
しかし、元々IPI_A、IPI_Bというのがあるような…?なんでIRQがLinuxと一致しとらんのかちょっとよく分かってない。
一つづつ試すしか無いのか。
LinuxではIPIの初期化・割り込み発生を直接HUBへの書き込みで設定していたが、OpenBSDには既に汎用化された関数が定義されてるのでこれを使ってみる。
やり方はIP30(Octane)の時と同じ。
+int +hw_ipi_intr_establish(int (*func)(void *), u_long cpuid) +{ + printf("%s %s %d\n", __FILE__, __func__, __LINE__); + int irq = cpuid == 0 ? HUBPI_ISR0_CPU_CALL_A : HUBPI_ISR0_CPU_CALL_B; + return xbow_intr_establish(func, (void *)cpuid, irq, + IPL_IPI, NULL, &curcpu()->ci_ipiih); + printf("%s %s %d\n", __FILE__, __func__, __LINE__); + return 0; +}; + +void +hw_ipi_intr_set(u_long cpuid) +{ + printf("%s %s %d\n", __FILE__, __func__, __LINE__); + int irq = cpuid == 0 ? HUBPI_ISR0_CPU_CALL_A : HUBPI_ISR0_CPU_CALL_B; + xbow_intr_set(irq); + printf("%s %s %d\n", __FILE__, __func__, __LINE__); +} + +void +hw_ipi_intr_clear(u_long cpuid) +{ + printf("%s %s %d\n", __FILE__, __func__, __LINE__); + int irq = cpuid == 0 ? HUBPI_ISR0_CPU_CALL_A : HUBPI_ISR0_CPU_CALL_B; + xbow_intr_clear(irq); + printf("%s %s %d\n", __FILE__, __func__, __LINE__); +} + +#endif
テストしてみる。
…割り込み掛からない。
原因は2通り考えられる:
・割り込みの起こし方が間違っている。hw_ipi_intr_set()側。
・割り込みの有効化方法が間違っている。hw_ipi_intr_establish()側。
どちらだか今の所分かっていない。
Linuxと同じく、一度低レベルな方法(直接HUBへアクセス)でためしてみるべきか。
追記:
HUBPI_ISR0_IPI_A|Bで再チャレンジしてみたが、やはり割り込みがかからない。
未だ理由は良く分からない。
割り込みコントローラへの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); }
Exceptionはハンドル出来てるぽ
hw_cpu_hatch()で割り込み有効にしてbreakかけてddbが上がるかどうか確かめればExceptionをハンドルしてtrap出来てるか分かるという単純極まりない事実に気づいて早速試してみる。
/* * Build proper TLB refill handler trampolines. */ extern void xtlb_miss; xtlb_handler = (vaddr_t)&xtlb_miss; build_trampoline(TLB_MISS_EXC_VEC, xtlb_handler); build_trampoline(XTLB_MISS_EXC_VEC, xtlb_handler); /* * Turn off bootstrap exception vectors. */ setsr(getsr() & ~SR_BOOT_EXC_VEC); /* * Clear out the I and D caches. */ Mips10k_ConfigCache(ci); Mips_SyncCache(ci); // cpu_startclock(ci); // ncpus++; // cpuset_add(&cpus_running, ci); // mips64_ipi_init(); /* XXX: setintrmask(0) here */ spl0(); (void)updateimask(0); Debugger();
vscsi0 at root scsibus2 at vscsi0: 256 targets softraid0 at root boot device: sd0 root on sd0a swap on sd0b dump on sd0b clock_int5 Stopped at 0xa800000000439064: jr ra 0xa800000000439068: nop ddb{1}>
おk。ちゃんと動いとる。
Origin 350のセカンダリプロセッサ起動パッチを投げた
この間の起動テストコードに、CPU初期化時にセカンダリプロセッサを探してnasid, physidをstruct cpu_hwinfo secondarycpu_hwinfo[MAXCPUS]に保存し、後でこれを見に行って順に起こすというコードを足した。
でもbootcpu_hwinfoとsecondarycpu_hwinfo[]が分かれてるのはちょっとキモイよな。
と思うのでコメント求む的なメールを投げてみる。
Index: mips64/include/cpu.h =================================================================== RCS file: /cvs/src/sys/arch/mips64/include/cpu.h,v retrieving revision 1.58 diff -u -p -r1.58 cpu.h --- mips64/include/cpu.h 28 Apr 2010 16:20:28 -0000 1.58 +++ mips64/include/cpu.h 18 May 2010 04:31:55 -0000 @@ -370,6 +370,10 @@ struct cpu_hwinfo { uint32_t tlbsize; uint type; uint32_t l2size; +#ifdef TGT_ORIGIN + int nasid; + int physid; +#endif }; struct cpu_info { Index: sgi/include/intr.h =================================================================== RCS file: /cvs/src/sys/arch/sgi/include/intr.h,v retrieving revision 1.41 diff -u -p -r1.41 intr.h --- sgi/include/intr.h 18 Jan 2010 16:59:23 -0000 1.41 +++ sgi/include/intr.h 18 May 2010 04:31:55 -0000 @@ -190,6 +190,8 @@ void dosoftint(void); #ifdef MULTIPROCESSOR #if defined (TGT_OCTANE) #define ENABLEIPI() updateimask(~CR_INT_2) /* enable IPI interrupt level */ +#elif defined (TGT_ORIGIN) +#define ENABLEIPI() /* notyet */ #else #error MULTIPROCESSOR kernel not supported on this configuration #endif Index: sgi/sgi/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 --- sgi/sgi/ip27_machdep.c 9 May 2010 18:37:47 -0000 1.51 +++ sgi/sgi/ip27_machdep.c 18 May 2010 04:31:55 -0000 @@ -28,6 +28,7 @@ #include <sys/malloc.h> #include <sys/reboot.h> #include <sys/tty.h> +#include <sys/proc.h> #include <mips64/arcbios.h> #include <mips64/archtype.h> @@ -56,6 +57,10 @@ extern char *hw_prod; extern void (*md_halt)(int); +#ifdef MULTIPROCESSOR +extern struct cpu_hwinfo secondarycpu_hwinfo[MAXCPUS]; +#endif + paddr_t ip27_widget_short(int16_t, u_int); paddr_t ip27_widget_long(int16_t, u_int); paddr_t ip27_widget_map(int16_t, u_int,bus_addr_t *, bus_size_t *); @@ -297,6 +302,10 @@ ip27_setup() void ip27_autoconf(struct device *parent) { +#ifdef MULTIPROCESSOR + int cpuid; +#endif + union { struct mainbus_attach_args maa; struct cpu_attach_args caa; @@ -318,6 +327,15 @@ ip27_autoconf(struct device *parent) u.maa.maa_name = "clock"; config_found(parent, &u, ip27_print); + for (cpuid = 1; cpuid < MAXCPUS; cpuid++) + if (secondarycpu_hwinfo[cpuid].clock != 0 + && secondarycpu_hwinfo[cpuid].nasid == currentnasid) { + u.maa.maa_name = "cpu"; + u.maa.maa_nasid = currentnasid; + u.caa.caa_hw = &secondarycpu_hwinfo[cpuid]; + config_found(parent, &u, ip27_print); + } + /* * Now attach all nodes' I/O devices. */ @@ -919,3 +937,90 @@ ip27_nmi(void *arg) printf("Resetting system...\n"); boot(RB_USERREQ); } + +#ifdef MULTIPROCESSOR + +#define LAUNCH_SLAVE \ + (*(void (*)(int nasid, int cpu, void *call_addr, uint64_t call_parm, \ + void *stack_addr, void *gp_addr)) PHYS_TO_CKSEG1(0x1fc00038)) + +void +hw_cpu_boot_secondary(struct cpu_info *ci) +{ + vaddr_t kstack; + + kstack = alloc_contiguous_pages(USPACE); + if (kstack == NULL) + panic("unable to allocate idle stack\n"); + bzero((char *)kstack, USPACE); + ci->ci_curprocpaddr = (void *)kstack; + + LAUNCH_SLAVE(ci->ci_hw.nasid, ci->ci_hw.physid, hw_cpu_spinup_trampoline, + (uint64_t)ci, (void *)(kstack + USPACE), 0); + + while (!cpuset_isset(&cpus_running, ci)) + ; +} + +void +hw_cpu_hatch(struct cpu_info *ci) +{ + int s; + + /* + * Make sure we can access the extended address space. + * Note that r10k and later do not allow XUSEG accesses + * from kernel mode unless SR_UX is set. + */ + setsr(getsr() | SR_KX | SR_UX); + + tlb_set_page_mask(TLB_PAGE_MASK); + tlb_set_wired(0); + tlb_flush(64); + tlb_set_wired(UPAGES / 2); + + tlb_set_pid(0); + + /* + * Turn off bootstrap exception vectors. + */ + setsr(getsr() & ~SR_BOOT_EXC_VEC); + + /* + * Clear out the I and D caches. + */ + Mips10k_ConfigCache(ci); + Mips_SyncCache(ci); + + cpu_startclock(ci); + + ncpus++; + cpuset_add(&cpus_running, ci); + + mips64_ipi_init(); + /* XXX: setintrmask(0) here */ + + spl0(); + (void)updateimask(0); + + SCHED_LOCK(s); + cpu_switchto(NULL, sched_chooseproc()); +} + +int +hw_ipi_intr_establish(int (*func)(void *), u_long cpuid) +{ + return 0; +}; + +void +hw_ipi_intr_set(u_long cpuid) +{ +} + +void +hw_ipi_intr_clear(u_long cpuid) +{ +} + +#endif Index: sgi/sgi/sginode.c =================================================================== RCS file: /cvs/src/sys/arch/sgi/sgi/sginode.c,v retrieving revision 1.19 diff -u -p -r1.19 sginode.c --- sgi/sgi/sginode.c 6 Apr 2010 19:09:50 -0000 1.19 +++ sgi/sgi/sginode.c 18 May 2010 04:31:56 -0000 @@ -76,6 +76,10 @@ int kl_n_mode = 0; u_int kl_n_shift = 32; klinfo_t *kl_glass_console = NULL; +#ifdef MULTIPROCESSOR +struct cpu_hwinfo secondarycpu_hwinfo[MAXCPUS]; +#endif + void kl_init(int ip35) { @@ -258,8 +262,24 @@ kl_first_pass_comp(klinfo_t *comp, void bootcpu_hwinfo.clock = cpucomp->cpu_speed * 1000000; bootcpu_hwinfo.tlbsize = 64; bootcpu_hwinfo.type = (cpucomp->cpu_prid >> 8) & 0xff; - } else + bootcpu_hwinfo.nasid = comp->nasid; + bootcpu_hwinfo.physid = comp->physid; + } else { +#ifdef MULTIPROCESSOR + int cpuid = ncpusfound; + secondarycpu_hwinfo[cpuid].c0prid = cpucomp->cpu_prid; + if (ip35) + secondarycpu_hwinfo[cpuid].c1prid = cpucomp->cpu_prid; + else + secondarycpu_hwinfo[cpuid].c1prid = cpucomp->cpu_fpirr; + secondarycpu_hwinfo[cpuid].clock = cpucomp->cpu_speed * 1000000; + secondarycpu_hwinfo[cpuid].tlbsize = 64; + secondarycpu_hwinfo[cpuid].type = (cpucomp->cpu_prid >> 8) & 0xff; + secondarycpu_hwinfo[cpuid].nasid = comp->nasid; + secondarycpu_hwinfo[cpuid].physid = comp->physid; +#endif ncpusfound++; + } break; case KLSTRUCT_MEMBNK:
CAlias
第四回 カーネル/VM探検隊でも話した通り、Originのメモリレイアウトでは物理メモリの先頭64KBずつが各プロセッサで排他的に使えるメモリ領域として割り当てられており、実際の位置に関わらず物理アドレスは0x0になっている。
ので、Exception Vectorがこの仕様に巻き込まれて迷惑な訳で…。
Exception Vectorはarch/sgi/sgi/machdep.cで作っているんだが、ここへゴリゴリ#ifdef入れるのはあまりにも不恰好だろう、と思いarch/sgi/sgi/ip27_machdep.cのhw_cpu_hatch()にException Vectorを作るコードをそのまま持ってきた。
セカンダリプロセッサが起動した時に自力で初期化させる。
一応printfとか動いてたし多分イケてると思うんだけど…何か未だ自信なし。クロック割り込みの動作確認は取れず。
ところでCPUと完全独立なL1コンソールはCPUのデバッグに使えないのだろうか??
+void +hw_cpu_hatch(struct cpu_info *ci) +{ + int s; + vaddr_t xtlb_handler; + extern char exception[], e_exception[]; + + /* + * Set curcpu address on this processor. + */ + setcurcpu(ci); + + /* + * Make sure we can access the extended address space. + * Note that r10k and later do not allow XUSEG accesses + * from kernel mode unless SR_UX is set. + */ + setsr(getsr() | SR_KX | SR_UX); + + tlb_set_page_mask(TLB_PAGE_MASK); + tlb_set_wired(0); + tlb_flush(64); + tlb_set_wired(UPAGES / 2); + + tlb_set_pid(0); + + /* + * Copy down exception vector code. + */ + bcopy(exception, (char *)CACHE_ERR_EXC_VEC, e_exception - exception); + bcopy(exception, (char *)GEN_EXC_VEC, e_exception - exception); + + /* + * Build proper TLB refill handler trampolines. + */ + extern void xtlb_miss; + xtlb_handler = (vaddr_t)&xtlb_miss; + + build_trampoline(TLB_MISS_EXC_VEC, xtlb_handler); + build_trampoline(XTLB_MISS_EXC_VEC, xtlb_handler); + + /* + * Turn off bootstrap exception vectors. + */ + setsr(getsr() & ~SR_BOOT_EXC_VEC); + + /* + * Clear out the I and D caches. + */ + Mips10k_ConfigCache(ci); + Mips_SyncCache(ci); + + cpu_startclock(ci); + +// ncpus++; +// cpuset_add(&cpus_running, ci); + +// mips64_ipi_init(); + /* XXX: setintrmask(0) here */ + + spl0(); + (void)updateimask(0); + + while(1) + printf("cpu_hatch\n"); + + SCHED_LOCK(s); + cpu_switchto(NULL, sched_chooseproc()); +}