| Summary: | Statclocks cannot be disabled on ServerWorks chipset (MB: Acer Altos 1200, Tyan S2510, ...) if APM is enabled in SMP environment | ||
|---|---|---|---|
| Product: | Base System | Reporter: | belian <belian> |
| Component: | i386 | Assignee: | Remko Lodder <remko> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | Unspecified | ||
| Hardware: | Any | ||
| OS: | Any | ||
Responsible Changed From-To: freebsd-bugs->freebsd-i386 This is i386-specific State Changed From-To: open->feedback Hi, Can you tell me whether this is still applicable to a modern world? (read: FreeBSD 5.4 and/or 6.0 or even the BETA's that were just released). Responsible Changed From-To: freebsd-i386->remko Grab the PR so that i can track the feedback etc. State Changed From-To: feedback->closed The submitter does no longer own a ServerWorks LE based motherboard so this cannot be tested anymore. Also the submitter (and I do as well) thinks that the problem is outdated. I will close the PR with the assumption that it had been solved. The submitter had been informed that if the problem still persists he should contact me so that i can try to obtain more information and delegate this to the proper person. |
The problem occurs with the two-processors configuration on the motherboards with ServerWorks chipset (such as described in the Environment section). The following configuration leads to freezing computer before mounting root partition: # To make an SMP kernel, the next two are needed options SMP # Symmetric MultiProcessor Kernel options APIC_IO # Symmetric (APIC) I/O # Power management support (see LINT for more options) device apm0 at nexus? flags 0x20 # Advanced Power Management Fix: It is necessary to fix the procedure cpu_initclocks() from /usr/src/sys/i386/isa/clock.c: /* * Start both clocks running. */ void cpu_initclocks() There we have that part: if (statclock_disable) { /* * The stat interrupt mask is different without the * statistics clock. Also, don't set the interrupt * flag which would normally cause the RTC to generate * interrupts. */ stat_imask = HWI_MASK | SWI_MASK; rtc_statusb = RTCSB_24HR; } else { /* Setting stathz to nonzero early helps avoid races. */ stathz = RTC_NOPROFRATE; profhz = RTC_PROFRATE; } For which flag 0x20 in the apm(4) is sufficient. That's Ok. But than: /* Finish initializing 8253 timer 0. */ #ifdef APIC_IO apic_8254_intr = isa_apic_irq(0); apic_8254_trial = 0; if (apic_8254_intr >= 0 ) { if (apic_int_type(0, 0) == 3) apic_8254_trial = 1; } else { /* look for ExtInt on pin 0 */ if (apic_int_type(0, 0) == 3) { apic_8254_intr = apic_irq(0, 0); setup_8254_mixed_mode(); } else panic("APIC_IO: Cannot route 8254 interrupt to CPU"); } we are detecting the flag ``apic_8254_trial''. That flag, as I understand, indicates that the check if 8254 is broken (or, at least, non-standard) should be performed. That's Ok as well. And now we do the following: clkdesc = inthand_add("clk", apic_8254_intr, (inthand2_t *)clkintr, NULL, &clk_imask, INTR_EXCL); INTREN(1 << apic_8254_intr); #else /* APIC_IO */ inthand_add("clk", 0, (inthand2_t *)clkintr, NULL, &clk_imask, INTR_EXCL); INTREN(IRQ0); #endif /* APIC_IO */ /* Initialize RTC. */ writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, RTCSB_24HR); /* Don't bother enabling the statistics clock. */ if (statclock_disable) return; - and those check, the necessaty of wich we marked in the previous piece of code will NEVER be done if we want to disable statclock. That's obviously wrong because in the case of the non-standard 8254 we will handle it in the wrong way. diag = rtcin(RTC_DIAG); if (diag != 0) printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); #ifdef APIC_IO if (isa_apic_irq(8) != 8) panic("APIC RTC != 8"); #endif /* APIC_IO */ inthand_add("rtc", 8, (inthand2_t *)rtcintr, NULL, &stat_imask, INTR_EXCL); #ifdef APIC_IO INTREN(APIC_IRQ8); #else INTREN(IRQ8); #endif /* APIC_IO */ writertc(RTC_STATUSB, rtc_statusb); #ifdef APIC_IO if (apic_8254_trial) { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The testing that should be done is here. As you can see it is necessary only if we have APIC_IO defined, i.e. in the SMP environment. It is possible that we need early return from the procedure if statclock is disabled but proper initialization of the APIC should be done anyway! Also, probably ``flags 0x20'' should be deleted from the standard GENERIC kernel since the most popular way of building new kernel config is stripping GENERIC config people can getting trouble leaving that flag: from the comment in the LINT it is absolutely unclear why it should be removed. At least, the comment about the trouble described above is necessary in that remark in the LINT config since it is not obvious at all that the apm flags can influence on the kernel boot-time freezes. By the way, it will be nice to have workaround for just turning power off without including all those big and (as said in the man pages) instable code in order to make possible to use FreeBSD on heavy-servers configurations without console at all. How-To-Repeat: 1) Include the srings above to the kernel config 2) Compile the kernel with the obtain config on the MB with ServerWorks chipset and dual processors 3) Boot After hardware initialization computer will freeze.