Warner, I send you this hack that I may have your advice.
I haven't tried bringing up the SMP kernel on my T22. APIC_IO is needed in order for this to work, as we don't use the APIC within a uniprocessor build of -CURRENT on i386. But I imagine it should work. I couldn't find any other way within the chipset on the IBM T22 of generating the NMI. Caveats: 1) selfnmi.c is strictly for proof of concept. 2) the ACPI ASL patch makes assumptions about the BSP's APIC always being mapped in at its default address. Enjoy, BMS
/* $FreeBSD$ */ /* * Generate a soft-NMI by frobbing our own local APIC. * Note: kernel option APIC requires SMP. Leaving the local APIC enabled, * by patching the init_ppro() function in i386/i386/initcpu.c, will * panic the kernel; full APIC/SMP support is required. * XXX what about trying to run an SMP kernel on a UP box without an * mptable? */ /* * Copyright (c) 2003 Bruce M. Simpson <[EMAIL PROTECTED]> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Bruce M. Simpson. * 4. Neither the name of Bruce M. Simpson nor the names of co- * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bruce M. Simpson OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/param.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/fcntl.h> #include <sys/mman.h> #include <sys/memrange.h> #include <fcntl.h> #include <stddef.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <strings.h> #include <machine/sysarch.h> #include <machine/vm86.h> #include <machine/cpufunc.h> #include <machine/specialreg.h> #ifndef _DEV_MEM #define _DEV_MEM "/dev/mem" #endif #define LAPIC_BASE 0xFEE00000UL /* APIC base mapping */ #define LAPIC_ICRBASE 0x00000300UL /* APIC command register base */ #define LAPIC_SVR 0x000000F0UL /* spurious vector register */ #define LAPIC_SIZE 0x00004000UL /* size of APIC space (1 page)*/ #define SVR_APIC_ENABLE 0x100 void usage(void) { printf("usage: selfnmi\n"); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { int ret; int memfd; void *apicbase; struct mem_range_op mro; struct mem_range_desc mrd; u_int32_t cpuid[4]; u_int32_t reg; #if 0 /* see if the IA32_APIC_BASE MSR reveals anything */ /* XXX This is a privileged instruction */ reg = rdmsr(MSR_APICBASE); fprintf(stderr, "IA32_APIC_BASE MSR: %08lx\n", reg); #endif #if 1 /* Issue CPUID to discover Local APIC */ /* XXX init_ppro() in i386/i386/initcpu.c will disable the * local APIC for a non-UP kernel build. annoying. * is it possible to keep it enabled? */ do_cpuid(1, cpuid); fprintf(stderr, "cpuid(1): eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx\n", cpuid[0], cpuid[1], cpuid[2], cpuid[3]); if ((cpuid[3] & CPUID_APIC) == 0) { fprintf(stderr, "local apic was software disabled\n"); } #endif /* Open the mem(4) device. */ memfd = open(_DEV_MEM, O_RDWR); if (memfd == -1) { perror("open"); goto cleanup; } /* XXX Mark the APIC range as uncacheable */ bzero(&mro, sizeof(mro)); mro.mo_arg[0] = MEMRANGE_SET_UPDATE; mro.mo_desc = &mrd; bzero(&mrd, sizeof(mrd)); mrd.mr_base = LAPIC_BASE; mrd.mr_len = LAPIC_SIZE; mrd.mr_flags = MDF_UNCACHEABLE|MDF_ACTIVE|MDF_BUSY; strncpy(mrd.mr_owner, "APIC\0", sizeof(mrd.mr_owner)); ret = ioctl(memfd, MEMRANGE_SET, &mro); if (ret == -1) perror("ioctl MEMRANGE_SET_UPDATE"); /* Map the APIC into our address space. */ apicbase = mmap(NULL, LAPIC_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, LAPIC_BASE); if (apicbase == MAP_FAILED) { perror("mmap"); goto cleanup; } #if 1 fprintf(stderr, "LAPIC SVR: %08lx\n", *((u_int32_t *)apicbase + LAPIC_SVR)); #endif #if 1 /* * Issue an NMI via the APIC memory-mapped register set. * Destination: self. * Delivery mode: NMI. (Change 0400 to 0200 for SMI) */ *((u_int32_t *)(apicbase + LAPIC_ICRBASE + 0)) = 0x00040400; #endif cleanup: if (apicbase != MAP_FAILED) munmap(apicbase, LAPIC_SIZE); mrd.mr_flags = MDF_UNCACHEABLE; ret = ioctl(memfd, MEMRANGE_SET, &mro); if (ret == -1) perror("ioctl MEMRANGE_SET_UPDATE"); mro.mo_arg[0] = MEMRANGE_SET_REMOVE; ret = ioctl(memfd, MEMRANGE_SET, &mro); if (ret == -1) perror("ioctl MEMRANGE_SET_REMOVE"); close(memfd); exit(EXIT_SUCCESS); }
--- t22_dsdt_dist.dsl Fri Jun 13 12:06:30 2003 +++ t22_dsdt_nmi.dsl Mon Jun 23 06:35:42 2003 @@ -8725,9 +8725,18 @@ SMI (0x86, 0x02, 0x00, 0x00, 0x00) } + /* Define a region for the Local APIC */ + OperationRegion (APIC, SystemMemory, 0xFEE00000, 0x4000) + Field (APIC, DWordAcc, NoLock, Preserve) + { + Offset (0x300), + ICR0 , 32 + } + Method (TPKY, 0, NotSerialized) { - SMI (0x86, 0x03, 0x00, 0x00, 0x00) + /* Generate a Local APIC NMI interrupt */ + Store (0x00040400, \ICR0) } Method (BRIU, 0, NotSerialized)
_______________________________________________ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"