Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 09 Mar 1997 12:37:50 -0500
From:      "Brian J. McGovern" <mcgovern@spoon.beta.com>
To:        hackers@freebsd.org
Subject:   Mapping shared memory...
Message-ID:  <199703091737.MAA17015@spoon.beta.com>

next in thread | raw e-mail | index | archive | help
*sigh* At least I'm making headway. I've looked at a couple of other drivers,
to see how they handle getting shared memory mapped on a PCI card, and this
is what I came up with... Can anybody let me know if this is right/wrong/there
is a better way? Thanks.

	-Brian
    /* First, set up our memory window. Its 512 Kb in size. We're supposed to
	get the pointer to it from the config register specified as BASE_ADDR_2 */
    czcontrol.window[board] = (unsigned char *) pmap_mapdev(pci_conf_read(config_id, CYZ_PCI_BASE_ADDR2), 0x80000);

    /* Next, we need to get the memory offset for the 9060 registers. Its 
	supposed to be at BASE_ADDR_1 */
    czcontrol.i9060[board] = (struct RUNTIME_9060 *) pmap_mapdev(pci_conf_read(config_id, CYZ_PCI_BASE_ADDR1), sizeof(struct RUNTIME_9060));

    /* Next, we find the firmware structure, which is supposed to be at
       an offset of ID_ADDRESS from the base of the window defined above */
    czcontrol.firmid[board] = (struct FIRM_ID *)(czcontrol.window[board] + ID_ADDRESS);



For those of you who'd like a better context, heres the whole driver function
to date:

#include "cz.h"

#if NCZ > 0
#include <unistd.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/reboot.h>
#include <sys/ioctl.h>
#include <sys/tty.h>
#include <sys/proc.h>
#include <sys/conf.h>
#include <sys/file.h>
#include <sys/uio.h>
#include <sys/kernel.h>
#include <sys/syslog.h>
#include <machine/clock.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <pci/pcivar.h>
#include <dev/cz/cz.h>
#include <dev/cz/lcz.h>
#include <dev/cz/cyclomz.h>
#include <dev/cz/zfwint.h>
#include <dev/cz/zfirm.h>

static char *cz_probe	__P((pcici_t, pcidi_t));
static void cz_attach	__P((pcici_t, int));
static void cz_intr	__P((void *));
static u_long cz_count = 0;

static struct pci_device cz_device={"cz", cz_probe, cz_attach, &cz_count, NULL};
DATA_SET(pcidevice_set, cz_device);

#define MAX_BOARDS 4

void delay1ms(void);


static struct czsoftc
  {
    unsigned long		active_boards;
    unsigned char		ports[MAX_BOARDS][MAX_CHAN];
    pcici_t			config_id[MAX_BOARDS];
    int				unit[MAX_BOARDS];
    unsigned char		*window[MAX_BOARDS];
    unsigned char		irq[MAX_BOARDS];
    struct FIRM_ID		*firmid[MAX_BOARDS];
    struct CUSTOM_REG		*custom_regs[MAX_BOARDS];
    struct ZFW_CTRL		*zfw_ctrl[MAX_BOARDS];
    struct RUNTIME_9060		*i9060[MAX_BOARDS];
    struct BOARD_CTRL		*board_ctrl[MAX_BOARDS];
    struct CH_CTRL		*channel_ctrl[MAX_BOARDS][MAX_CHAN];
    struct BUF_CTRL		*buffer_ctrl[MAX_BOARDS][MAX_CHAN];
  } czcontrol;

static unsigned char first_probe = 1;

static void cz_intr(void *token)
  {
  }

static char *cz_probe(pcici_t config_id, pcidi_t device_id)
  {
    if (((device_id & 0xffff) != CYZ_VENDOR_ID) || (((device_id >> 16) != 0x200) && ((device_id >> 16) != 0x201)))
      return NULL;
    else
      return "Cyclades Cyclom-Zo Serial Adapter";
  }

void cz_attach(pcici_t config_id, int unit)
  {
    int i;
    unsigned long reg;
    vm_offset_t paddr;
    int board, port;

    if (first_probe == 1)
      {
        czcontrol.active_boards = 0L;
	for (board = 0; board < MAX_BOARDS; board++)
	  {
	    for (port = 0;port < MAX_CHAN; port++)
	      {
	        czcontrol.ports[board][port] = 0;
 	        czcontrol.channel_ctrl[board][port] = NULL;
		czcontrol.buffer_ctrl[board][port] = NULL;
	      }
	    czcontrol.zfw_ctrl[board] = NULL;
	    czcontrol.i9060[board] = NULL;
	    czcontrol.window[board] = NULL;
	    czcontrol.irq[board] = 0;
	    czcontrol.unit[board] = 0;
	    czcontrol.firmid[board] = NULL;
	    czcontrol.custom_regs[board] = NULL;
	    czcontrol.board_ctrl[board] = NULL;
	  }
	first_probe = 0;
      }
    czcontrol.active_boards++;
    board = czcontrol.active_boards - 1;
    czcontrol.config_id[board] = config_id;
    czcontrol.window[board] = (unsigned char *) pmap_mapdev(pci_conf_read(config_id, CYZ_PCI_BASE_ADDR2), 0x80000);
    czcontrol.i9060[board] = (struct RUNTIME_9060 *) pmap_mapdev(pci_conf_read(config_id, CYZ_PCI_BASE_ADDR1), sizeof(struct RUNTIME_9060));
    czcontrol.firmid[board] = (struct FIRM_ID *)(czcontrol.window[board] + ID_ADDRESS);
    czcontrol.custom_regs[board] = (struct CUSTOM_REG *)czcontrol.window[board];

    reg = czcontrol.i9060[board]->init_ctrl;
    reg |=  (0x40000000);
    czcontrol.i9060[board]->init_ctrl = reg;
    DELAY(300);
    reg &= ~(0x40000000);
    czcontrol.i9060[board]->init_ctrl = reg;
    DELAY(300);

    czcontrol.i9060[board]->loc_addr_base = WIN_CREG;
    czcontrol.custom_regs[board]->cpu_stop = 0;

    czcontrol.i9060[board]->loc_addr_base = WIN_RAM;
    memcpy(czcontrol.window[board],zfw, zfw_SIZE);

    czcontrol.i9060[board]->loc_addr_base = WIN_CREG;
    czcontrol.custom_regs[board]->cpu_start = 0;
    czcontrol.i9060[board]->loc_addr_base = WIN_RAM;

    DELAY(1000);
    if (czcontrol.firmid[board]->signature == ZFIRM_ID)
      {
        czcontrol.zfw_ctrl[board] = (struct ZFW_CTRL *)(czcontrol.window[board] + czcontrol.firmid[board]->zfwctrl_addr);
      }
    else
      {
        czcontrol.active_boards = 0;
	printf("Board %d did not start properly. All boards shut down.\n",unit);
	return;
      }
    czcontrol.board_ctrl[board] = &czcontrol.zfw_ctrl[board]->board_ctrl;
    czcontrol.board_ctrl[board]->op_system = C_OS_BSD;
    czcontrol.board_ctrl[board]->dr_version - 0x001;
    i = czcontrol.board_ctrl[board]->n_channel;
    for (port=0;port < i;port++)
      {
        czcontrol.channel_ctrl[board][port] = (struct CH_CTRL *)(&czcontrol.zfw_ctrl[board]->ch_ctrl + sizeof(struct CH_CTRL));
        czcontrol.buffer_ctrl[board][port] = (struct BUF_CTRL *)(&czcontrol.zfw_ctrl[board]->buf_ctrl + sizeof(struct BUF_CTRL));
        czcontrol.ports[board][port] |= (1 << port);
      }

  }

#endif /* NCZ */



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