From owner-freebsd-hackers Fri Dec 10 16:42: 4 1999 Delivered-To: freebsd-hackers@freebsd.org Received: from cepheus.azstarnet.com (cepheus.azstarnet.com [169.197.56.195]) by hub.freebsd.org (Postfix) with ESMTP id A49CE1541F for ; Fri, 10 Dec 1999 16:41:52 -0800 (PST) (envelope-from bobkat@azstarnet.com) Received: from atlas.tic.toc (dialup06ip054.tus.azstarnet.com [169.197.32.182]) by cepheus.azstarnet.com (8.9.3+blt.Beta0/8.9.3) with SMTP id RAA04354 for ; Fri, 10 Dec 1999 17:41:43 -0700 (MST) X-Sent-via: StarNet http://www.azstarnet.com/ From: Bob Kot To: freebsd-hackers@FreeBSD.ORG Subject: Device driver - panics executing kvtop() when compiled as KLD module Date: Fri, 10 Dec 1999 17:15:43 -0700 X-Mailer: KMail [version 1.0.21] Content-Type: text/plain MIME-Version: 1.0 Message-Id: <99121017414100.00289@atlas.tic.toc> Content-Transfer-Encoding: 8bit Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG I am in the process of writing a device driver for the Turtle Beach Multisound Monterey soundcard. At the moment I am statically compiling my code into the kernel and it is somewhat operational. I have added conditional compilation code to also compile as a kld module. My problem is that when I kldload my module the machine panics in a subfunction of my attach() function that makes a call on kvtop() I drop into the debugger DDB and the instruction pointer is in the middle of the kvtop() function. If I disable my attach function the module will load and unload, but it is nonfunctional without the attach() being executed. Statically compiled into the kernel kvtop() executes with no problem. To be succinct can I use kvtop() in code that is a kld module? If not, what is the alternative to accomplish the same result? For those interested and/or willing to help more details follow, others can move on. The panic info is Fatal trap 12: page fault while in kernel mode fault virtual address = 0xbfc00340 fault code = supervisor read, page not present instruction pointer = 0x8:0xc01c98d9 stack pointer = 0x10:0xc2cdbe70 frame pointer = 0x10:0xc2cdbe70 code segment = base 0x0, limit 0xfffff, type 0x1b = DPL 0, pres 1, def32 1, gran 1 processor flags = interrupt enabled, resume, IOPL=0 current process = 250 (kldload) interrupt mask = kernel type 12 trap, code = 0 Stopped at kvtop+0x2d: movl PTmap(,%eax,4),%edx db> show registers cs 0x80000008 ds 0x10 es 0x10 ss 0x10 eax 0xd0 ecx 0xd0000 <<<< This is the physical address I want <<<<< edx 0 ebx 0xc0570a00 esp 0xc2cdbe70 ebp 0xc2cdbe70 esi 0xc0577100 edi 0 eip 0xc01c98d9 kvtop+0x2d efl 0x10212 end+0xb00e The TurtleBeach hardware demands that the driver has access to a 0x8000 (32K) byte contiguous chunk of physical memory in the ISA hole and more specifically it must start at one of the following locations B0000 || C8000 || D0000 || D8000 || E0000 || E8000 The line of my code that causes the panic as a module is switch (kvtop(msd->dev->id_maddr)) { ... } dev is a pointer to struct isa_device and id_maddr is 0xd0000 because my kernel config definition for this device is device msm0 at isa? port 0x290 irq 10 tty iomem 0xd0000 iosiz 0x8000 Which by some magic gets generated into ioconf.c in my kernel compile directory as struct isa_device isa_devtab_tty[] = { ..... other tty drivers omitted ..... { 18, &msmdriver, 0x0290, IRQ10, -1, C 0xD0000, 32768, 0, 0, 0x0000, 0 ,0, 0, 0, 1, 0, 0 }, 0}; My code to compile as a module must provide this information to the system as part of the module load. My conditional code as a module is as follows. static void msm_drvinit(void *unused) { dev_t dev; dev = makedev(CDEV_MAJOR, 0); cdevsw_add(&dev, &msm_cdevsw, NULL); } #ifndef MSM_MODULE SYSINIT(msmdev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR, msm_drvinit, NULL) #else /* MSM_MODULE */ /* * Here is the support for if we ARE a kld module */ #include /* * XXX Hardwiring this stuff is not wise, need to find some other * mechanism to specify this stuff */ static struct isa_device isadev = {0, &msmdriver, 0x290, IRQ10, -1, (caddr_t) 0x D0000, 0x8000, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}; static int msmm_event (module_t, modeventtype_t, void *); static int msmm_event (module_t mod, modeventtype_t cmd, void *arg) { int rv = 0; switch (cmd) { case MOD_LOAD: msm_drvinit(arg); if (msmprobe(&isadev) ) { msmattach(&isadev); } else { printf("msm driver: probe failed\n"); cdevsw[CDEV_MAJOR] = NULL; /* detach from cdevsw[] */ rv = 1; } break; case MOD_UNLOAD: if (sca[isadev.id_unit] != NULL) /* malloc in msmattach */ free(sca[isadev.id_unit], M_DEVBUF); /* deallocate buffers, MS_dev_t */ else printf("unload-msm0\n"); break; default: rv = EINVAL; break; } return rv; } /* This declares the kld module to the system MACRO in /sys/conf.h * I expanded this macro manually because the compiler was howling about the * msmm_event element structure initializer until I threw the cast on it. * I don't think this has anything to do with the problem I am having. * CDEV_MAJOR = 30 for soundcard drivers * CDEV_MODULE(msmm, CDEV_MAJOR, msm_cdevsw, msmm_event, 0); */ static struct cdevsw_module_data msmm_cdevsw_mod = { (modeventhand_t)msmm_event , 0 , 30 == NODEV ? NODEV : makedev( 30 , 0), & msm_cdevsw }; static moduledata_t msmm_mod = { "msmm", cdevsw_module_handler, & msmm_cdevsw_mod }; DECLARE_MODULE(msmm, msmm_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE + 30); #endif /* MSM_MODULE */ I added a directory to /sys/modules/msm and in it put the file msm.h which is #define NMSM 4 #define MSM_MODULE and my module Makefile which is .PATH: ${.CURDIR}/../../i386/isa/sndm KMOD= msm SRCS= msm.c msmio.h dsp_code.h NOMAN= NMSM?= 4 CLEANFILES+= msm.h msm.h: echo "#define NMSM ${NMSM}" > msm.h echo "#define MSM_MODULE" >> msm.h .include Executing # make msm.h creates the header file and a subsequent # make creates msm.ko which I then manually copy to /modules so kldload finds it in the default location. Any and all comments and hopefully some insight would be appreciated. Bob Kot To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message