tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: 4.0/i386 auich_calibrate() and GENERIC.NOACPI failure



On Sat, Jan 12, 2008 at 05:16:53PM +0000, Andrew Doran wrote:
> >  1. splvm() didn't help
> >  2. splclock() _did_ fix the problem!
> >  3. the value of curcpu()->ci_ilevel is 0 (zero) before the loop.
> >     Are you sure we are supposed to be at IPL_HIGH?   I thought zero
> >     was IPL_NONE?
> 
> It's a misfeature but most of autoconf should happen with interrupts off.
> Something is dropping the spl - perhaps an "avoid uninitialized variable
> warning" commit at some point? I'll see if I can find it. It looks like the
> bug in kern_tc.c was masking that. But I guess the auich calibration loop
> should be wrapped in splhigh()/splx() or be a bit smarter so that it doesn't
> need to rely on interrupts being blocked.

Hmm.   The auich_calibrate() loop is being called from 
config_process_deferred().   If you believe the comments
in subr_autoconf.c, interrupts are supposed to be enabled
in config_process_deferred().


In fact, I added the following printfs to subr_autoconf.c:

        /*
         * Do the machine-dependent portion of autoconfiguration.  This 
         * sets the configuration machinery here in motion by "finding"
         * the root bus.  When this function returns, we expect interrupts 
         * to be enabled. 
         */
printf("auich: BEFORE cpu_configure %#x\n", curcpu()->ci_ilevel); 
        cpu_configure();
printf("auich: AFTER cpu_configure %#x\n", curcpu()->ci_ilevel);
  
        /*
         * Now that we've found all the hardware, start the real time
         * and statistics clocks.
         */
        initclocks();
printf("auich: AFTER initclocks %#x\n", curcpu()->ci_ilevel);
  
        cold = 0;       /* clocks are running, we're warm now! */
 
        /*
         * Now callback to finish configuration for devices which want
         * to do this once interrupts are enabled.
         */
        config_process_deferred(&interrupt_config_queue, NULL);
printf("auich: AFTER after DEffered %#x\n", curcpu()->ci_ilevel);



this results in (note that my old splvm() patch is still in there):

auich: BEFORE cpu_configure 0xe
auich0 at pci0 dev 31 function 5: i82801BA (ICH2) AC-97 Audio
auich0: interrupting at irq 10
auich0: ac97: Analog Devices AD1885 codec; headphone, Analog Devices Phat Stereo
auich0: ac97: ext id 1<VRA>
auich: AFTER cpu_configure 0
auich: AFTER initclocks 0
auich: BEFORE SPL 0
auich: AFTER SPL 0xa
auich0: measured ac97 link rate at 47007 Hz, will use 48000 Hz
audio0 at auich0: full duplex, mmap, independent
auich: AFTER after DEffered 0


The other thing I was wondering was if fix this by putting splhigh() 
in auich.c.   Will that spl block microtime() from advancing with some 
hardware configs?


chuck



Home | Main Index | Thread Index | Old Index