From owner-freebsd-hackers Sun Mar 9 09:38:02 1997 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.5/8.8.5) id JAA01863 for hackers-outgoing; Sun, 9 Mar 1997 09:38:02 -0800 (PST) Received: from spoon.beta.com (root@[199.165.180.33]) by freefall.freebsd.org (8.8.5/8.8.5) with ESMTP id JAA01858 for ; Sun, 9 Mar 1997 09:37:54 -0800 (PST) Received: from spoon.beta.com (mcgovern@localhost [127.0.0.1]) by spoon.beta.com (8.8.4/8.6.9) with ESMTP id MAA17015 for ; Sun, 9 Mar 1997 12:37:50 -0500 (EST) Message-Id: <199703091737.MAA17015@spoon.beta.com> To: hackers@freebsd.org Subject: Mapping shared memory... Date: Sun, 09 Mar 1997 12:37:50 -0500 From: "Brian J. McGovern" Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk *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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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 */