diff options
Diffstat (limited to 'sys/i386/isa/pcic.h')
-rw-r--r-- | sys/i386/isa/pcic.h | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/sys/i386/isa/pcic.h b/sys/i386/isa/pcic.h new file mode 100644 index 0000000..852f332 --- /dev/null +++ b/sys/i386/isa/pcic.h @@ -0,0 +1,181 @@ +/*- + * TODO: + * [1] integrate into current if_ed.c + * [2] parse tuples to find out where to map the shared memory buffer, + * and what to write into the configuration register + * [3] move pcic-specific code into a separate module. + * + * Device driver for IBM PCMCIA Credit Card Adapter for Ethernet, + * if_ze.c + * + * Based on the Device driver for National Semiconductor DS8390 ethernet + * adapters by David Greenman. Modifications for PCMCIA by Keith Moore. + * Adapted for FreeBSD 1.1.5 by Jordan Hubbard. + * + * Currently supports only the IBM Credit Card Adapter for Ethernet, but + * could probably work with other PCMCIA cards also, if it were modified + * to get the locations of the PCMCIA configuration option register (COR) + * by parsing the configuration tuples, rather than by hard-coding in + * the value expected by IBM's card. + * + * Sources for data on the PCMCIA/IBM CCAE specific portions of the driver: + * + * [1] _Local Area Network Credit Card Adapters Technical Reference_, + * IBM Corp., SC30-3585-00, part # 33G9243. + * [2] "pre-alpha" PCMCIA support code for Linux by Barry Jaspan. + * [3] Intel 82536SL PC Card Interface Controller Data Sheet, Intel + * Order Number 290423-002 + * [4] National Semiconductor DP83902A ST-NIC (tm) Serial Network + * Interface Controller for Twisted Pair data sheet. + * + * + * Copyright (C) 1993, David Greenman. This software may be used, modified, + * copied, distributed, and sold, in both source and binary form provided + * that the above copyright and these terms are retained. Under no + * circumstances is the author responsible for the proper functioning + * of this software, nor does the author assume any responsibility + * for damages incurred with its use. + */ + +#ifndef __PCIC_H__ +#define __PCIC_H__ + +/***************************************************************************** + * pcmcia controller chip (PCIC) support * + * (eventually, move this to a separate file) * + *****************************************************************************/ +#include "ic/i82365.h" + +/* + * Each PCIC chip (82365SL or clone) can handle two card slots, and there + * can be up to four PCICs in a system. (On some machines, not all of the + * address lines are decoded, so a card may appear to be in more than one + * slot.) + */ +#define MAXSLOT 8 + +/* + * To access a register on the PCIC for a particular slot, you + * first write the correct OFFSET value for that slot in the + * INDEX register for the PCIC controller. You then read or write + * the value from or to the DATA register for that controller. + * + * The first pair of chips shares I/O addresss for DATA and INDEX, + * as does the second pair. (To the programmer, it looks like each + * pair is a single chip.) The i/o port addresses are hard-wired + * into the PCIC; so the following addresses should be valid for + * any machine that uses this chip. + */ + +#define PCIC_INDEX_0 0x3E0 /* index reg, chips 0 and 1 */ +#define PCIC_DATA_0 0x3E1 /* data register, chips 0 and 1 */ +#define PCIC_INDEX_1 0x3E2 /* index reg, chips 1 and 2 */ +#define PCIC_DATA_1 0x3E3 /* data register, chips 1 and 2 */ + +/* + * Given a slot number, calculate the INDEX and DATA registers + * to talk to that slot. OFFSET is added to the register number + * to address the registers for a particular slot. + */ +#define INDEX(slot) ((slot) < 4 ? PCIC_INDEX_0 : PCIC_INDEX_1) +#define DATA(slot) ((slot) < 4 ? PCIC_DATA_0 : PCIC_DATA_1) +#define OFFSET(slot) ((slot) % 4 * 0x40) + +/* + * There are 5 sets (windows) of memory mapping registers on the PCIC chip + * for each slot, numbered 0..4. + * + * They start at 10/50 hex within the chip's register space (not system + * I/O space), and are eight addresses apart. These are actually pairs of + * 8-bit-wide registers (low byte first, then high byte) since the + * address fields are actually 12 bits long. The upper bits are used + * for other things like 8/16-bit select and wait states. + * + * Memory mapping registers include start/stop addresses to define the + * region to be mapped (in terms of system memory addresses), and + * an offset register to allow for translation from system space + * to card space. The lower 12 bits aren't included in these, so memory is + * mapped in 4K chunks. + */ +#define MEM_START_ADDR(window) (((window) * 0x08) + 0x10) +#define MEM_STOP_ADDR(window) (((window) * 0x08) + 0x12) +#define MEM_OFFSET(window) (((window) * 0x08) + 0x14) +/* + * this bit gets set in the address window enable register (PCIC_ADDRWINE) + * to enable a particular address window. + */ +#define MEM_ENABLE_BIT(window) ((1) << (window)) + +/* + * There are two i/o port addressing windows. I/O ports cannot be + * relocated within system i/o space (unless the card doesn't decode + * all of the address bits); unlike card memory, there is no address + * translation offset. + */ +#define IO_START_ADDR(window) ((window) ? PCIC_IO1_STL : PCIC_IO0_STL) +#define IO_STOP_ADDR(window) ((window) ? PCIC_IO1_SPL : PCIC_IO0_SPL) +#define IO_ENABLE_BIT(window) ((window) ? PCIC_IO1_EN : PCIC_IO0_EN) +#define IO_CS16_BIT(window) ((window) ? PCIC_IO1_CS16 : PCIC_IO0_CS16) + +/* + * types of mapped memory + */ +enum memtype { COMMON, ATTRIBUTE }; + +/* + * read a byte from a pcic register for a particular slot + */ +static inline unsigned char +pcic_getb (int slot, int reg) +{ + outb (INDEX(slot), OFFSET (slot) + reg); + return inb (DATA (slot)); +} + +/* + * write a byte to a pcic register for a particular slot + */ +static inline void +pcic_putb (int slot, int reg, unsigned char val) +{ + outb (INDEX(slot), OFFSET (slot) + reg); + outb (DATA (slot), val); +} + +/* + * read a word from a pcic register for a particular slot + */ +static inline unsigned short +pcic_getw (int slot, int reg) +{ + return pcic_getb (slot, reg) | (pcic_getb (slot, reg+1) << 8); +} + +/* + * write a word to a pcic register at a particular slot + */ +static inline void +pcic_putw (int slot, int reg, unsigned short val) +{ + pcic_putb (slot, reg, val & 0xff); + pcic_putb (slot, reg + 1, (val >> 8) & 0xff); +} + + +void pcic_print_regs (int slot); +void pcic_map_memory (int slot, int window, unsigned long sys_addr, + unsigned long card_addr, unsigned long length, + enum memtype type, int width); +void pcic_unmap_memory (int slot, int window); +void pcic_map_io (int slot, int window, unsigned short base, + unsigned short length, unsigned short width); +#ifdef TEST +void pcic_unmap_io (int slot, int window); +#endif /* TEST */ +void pcic_map_irq (int slot, int irq); +void pcic_power_on (int slot); +void pcic_power_off (int slot); +void pcic_reset (int slot); + + +#endif /* __PCIC_H__ */ |