Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Dec 1999 17:15:43 -0700
From:      Bob Kot <bobkat@azstarnet.com>
To:        freebsd-hackers@FreeBSD.ORG
Subject:   Device driver - panics executing kvtop() when compiled as KLD module
Message-ID:  <99121017414100.00289@atlas.tic.toc>

next in thread | raw e-mail | index | archive | help

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 <sys/module.h>
/*
 * 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 <bsd.kmod.mk>

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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?99121017414100.00289>