This appendix contains the source listing for the /dev/envram device driver.
Note
The /dev/envram device driver does not operate on the ISA bus.
/*************************************************** * * * Copyright (c) 1994 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under the terms and * * conditions of the TURBOchannel Technology * * license and may be used and copied only in * * accordance with the terms of such license and * * with the inclusion of the above copyright * * notice. No title to and ownership of the * * software is hereby transferred. * * * * The information in this software is subject to * * change without notice and should not be * * construed as a commitment by Digital Equipment * * Corporation. * * * * Digital assumes no responsibility for the use * * or reliability of its software on equipment * * which is not supplied by Digital. * ***************************************************/
/*************************************************** * envram_reg.h Device Register Header File for * * envram.c 13-April-1993 * ***************************************************/
/*************************************************** * EISA NVRAM register definitions * * * * Define offsets to nvram device registers * ***************************************************/
#define ENVRAM_CSR 0xc00 /* CSR */ #define ENVRAM_BAT 0xc04 /* Battery Disconnect */ #define ENVRAM_HIBASE 0xc08 /* Ext. Mem Config */ #define ENVRAM_CONFIG 0xc0c /* EISA config reg */ #define ENVRAM_ID 0xc80 /* EISA ID reg */ #define ENVRAM_CTRL 0xc84 /* EISA control */ #define ENVRAM_DMA0 0xc88 /* DMA addr reg 0 */ #define ENVRAM_DMA1 0xc8c /* DMA addr reg 1 */
/*************************************************** * psgfix: wired up and ignored for power on. * * Diagnostic soft register tells us if * * diagnostics passed and the size of the board. * ***************************************************/
#define ENVRAM_DIAG_REGISTER 0x3f8 /* 1k - 1 */ #define BOARD_FAILED 0x00000008 /* Bit is set if board passed diags */ #define ENVRAM_DIAG_RESVED 0x400 /* The amount of space diagnostics require and assure 2K alignment for DMA */
/*************************************************** * Where firmware puts offset to cache last 32 * * bits in nvram 4mb space * ***************************************************/
#define ENVRAM_CACHE_OFFSET 0x400 /* PSGFIX - this is my cookie */ /* location */
/*************************************************** * CSR register bit mask definitions * ***************************************************/
#define SET_LED 0x0100 /* Turn LED on */ #define BAT_FAIL 0x0800 /* Indicated Battery failure */ #define WRMEM 0x2000 /* Enable writes to ENVRAM memory */ #define SET_DREQ 0x4000 /* Set DREQ for DMA */ #define DMA_CHAN_7 0X80 /* Channel 7 for DMA */ #define DMA_CHAN_5 0x40 /* Channel 5 for DMA */
/******************************************************** * Battery disconnect register bit mask defs * * * ********************************************************/ #define BAT_DISCON_BIT 0x0080 /* Bit to hit with connect sequence */
/*************************************************** * EISA Control Register bit masks * ***************************************************/
#define EISA_ENABLE_BOARD 0x1 /* EISA config enable - makes memory visible */
/*************************************************** * EISA ID register bit mask * ***************************************************/
#define ENVRAM_ID_MASK 0x0025a310 /* EISA ID register bit mask */
/*************************************************** * Define constants used for communication with * * the /dev/presto driver. * ***************************************************/
#define ENVRAM_MAPPED 1 /* Buffer is mapped */ #define ENVRAM_NOTMAPPED 0 /* Buffer is not mapped */ #define ENVRAM_CACHED 1 /* Use kseg space */ #define ENVRAM_NOTCAHCED 0 /* Use a cached space */
/******************************************************** * Define allignment boundaries * * * ********************************************************/
#define ENVRAM_XFER_SIZE 1024 /* Maximum DMA transfer size to NVRAM module */ #define ENVRAM_ALLIGN 8192 /* DMA allignment required */
/*************************************************** * * * Copyright (c) 1994 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under the terms and * * conditions of the TURBOchannel Technology * * license and may be used and copied only in * * accordance with the terms of such license and * * with the inclusion of the above copyright * * notice. No title to and ownership of the * * software is hereby transferred. * * * * The information in this software is subject to * * change without notice and should not be * * construed as a commitment by Digital Equipment * * Corporation. * * * * Digital assumes no responsibility for the use * * or reliability of its software on equipment * * which is not supplied by Digital. * ***************************************************/ /********************************************************** * envram_data.c data.c file for envram.c 13-April-1994 * * * **********************************************************/
/*************************************************** * Digital EISA non-voltile RAM driver (DEC2500) * ***************************************************/
/*************************************************** * Define the softc structure for the EISA NVRAM * * driver * ***************************************************/ struct envram_softc { io_handle_t regbase; /* base address for registers */ io_handle_t cache_phys_start; /* Physical start address of NVRAM cache of NVRAM cache */ io_handle_t cache_base; /* base address of NVRAM in */ EISA address space */ vm_offset_t cache_kseg_start; /* KSEG start addr of the presto cache */ u_long saved_mem_sysmap; /* sysmap portion of mem io_handle_t */ u_int cache_size; /* Size of NVRAM cache */ u_int cache_offset; /* Offset to the first nvram location from start of EISA slot address */ io_handle_t diag_status; /* If the board passed diags or not */ dma_handle_t sglp; /* Pointer to byte address/byte count pair */ struct controller *ctlr; /* Pointer to nvram controller */ };
struct envram_softc *envram_softc; struct controller *envram_info[NENVRAM];
/*************************************************** * envram.c Driver for presto device 13-Apr-1994 * * * * The /dev/envram device driver is an example * * driver that performs read/write services for * * the /dev/presto device driver. * * * ***************************************************/ /*************************************************** * The /dev/envram device driver written by * * Randy Arnott, Paul Grist, and Randall Brown. * ***************************************************/
/*************************************************** * Include Files Section * ***************************************************/
#include "envram.h" /* Driver header file created by config */
#include <vm/vm_kern.h> #include <sys/presto.h> /* Definitions for the /dev/presto device driver */ #include <io/common/devdriver.h> #include <io/dec/eisa/eisa.h> /* Header file specific to the EISA bus */ #include <data/envram_data.c> /* data.c file specific to the /dev/envram driver */ #include <machine/rpb.h> #include <io/dec/eisa/envram_reg.h> /* Device register header file */
/*************************************************** * EISA NVRAM I/O register Read/Write Macros * * * * These macros are built using the standard I/O * * bus interfaces read_io_port and write_io_port. * * The base address is referenced from * * sc->regbase. Simply || the register offset. * ***************************************************/
#define ENVRAM_READIO_D8(a) \ read_io_port((io_handle_t)sc->regbase | a, 1, 0)) #define ENVRAM_READIO_D16(a) \ read_io_port((io_handle_t)sc->regbase | a, 2, 0)) #define ENVRAM_READIO_D32(a) \ read_io_port((io_handle_t)sc->regbase | a, 4, 0))
#define ENVRAM_WRITEIO_D8(a,d) \ write_io_port((io_handle_t)sc->regbase | a, 1, 0, d)) #define ENVRAM_WRITEIO_D16(a,d) \ write_io_port((io_handle_t)sc->regbase | a, 2, 0, d)) #define ENVRAM_WRITEIO_D32(a,d) \ write_io_port((io_handle_t)sc->regbase | a, 4, 0, d))
/*************************************************** * Declarations Section * ***************************************************/
/*************************************************** * Do forward declaration of driver entry points * * and define information structures for driver * * structure definition and initialization below. * ***************************************************/
int envram_probe(), envram_attach(), eisa_nvram_status(); int eisa_nvram_battery_enable(), eisa_nvram_battery_disable(); void envram_read(), envram_write(), envram_zero();struct driver envramdriver = { envram_probe, /* probe */ 0, /* slave */ envram_attach, /* cattach */ 0, /* dattach */ 0, /* go */ 0, /* addr_list */ 0, /* dev_name */ 0, /* dev_list */ "envram", /* ctlr_name */ envram_info, /* ctlr_list */ 0, /* xclu */ 0, /* addr1_size */ 0, /* addr1_atype */ 0, /* addr2_size */ 0, /* addr2_atype */ 0, /* ctlr_unattach */ 0 /* dev_unattach */ }; /*************************************************** * External references * ***************************************************/
/******************************************************************** * Autoconfiguration Support Section * ********************************************************************/
/******************************************************************** * The autoconfiguration support section for the /dev/envram device * * device driver contains these interfaces: * * * * o envram_probe * * o envram_attach * ********************************************************************/
/******************************************************************** * INTERFACE NAME: envram_probe * * * * FUNCTIONAL DESCRIPTION: * * * * The envram_probe interface: * * * * o Determines if the controller for the EISA bus NVRAM memory * * board exists * * o Allocates and fills in the driver's softc data structure * * o Enables the EISA bus NVRAM memory board to handle reads and * * writes, if the controller exists on the system * * * * CALLED BY: Bus configuration code at boot time * * * * FORMAL PARAMETERS: * * * * o addr -- Base physical address of the EISA bus NVRAM memory * * board registers * * o ctlr -- Pointer to the controller structure for this device * * * * IMPLICIT INPUTS: * * * * o ctlr->slot -- EISA slot number of this controller * * o ctlr->conn_priv[0] -- Pointer to eisainfo structure * * o eisainfo->irq.intr.intr_num -- EISA interrupt level for this * * controller * * o eisainfo->irq.intr.trigger -- EISA interrupt high/low flag, * * 0 = edge (high), * * 1 = level (low) * * o ctlr->addr -- KSEG address of controller's base register * * o ctlr->physaddr -- Controller's base register physical * * address * * * * IMPLICIT OUTPUTS: None * * * * RETURN VALUE: * * * * Success: Size of the softc structure. * * Failure: NULL. * ********************************************************************/
envram_probe(bus_io_handle, ctlr) io_handle_t bus_io_handle; /* Base physical address of the EISA bus NVRAM registers*/ struct controller *ctlr; /* Pointer to controller structure */
{ /* Pointer to softc structure */ register struct envram_softc *sc; u_int hw_id = 0; /* Stores EISA bus ID register */ struct bus_mem mem; /* bus_mem structure describes EISA */ bus memory characteristics */ struct dma dma_p; /* dma structure */ u_long eisa_addr_mask = 0xffffffff; /* EISA address mask */
/********************************************************************* * Determine if this is unit 0. Currently, there is support for * * only one EISA bus NVRAM memory expansion board. * * Changes must be made to the /dev/presto device driver * * interface before multiple units (memory boards) can be supported. * ********************************************************************/
if (ctlr->ctlr_num > 0) return(0); /******************************************************************** * Allocate memory for softc structure. * ********************************************************************/ sc = (struct envram_softc *)kalloc(sizeof(struct envram_softc));
if (!sc) return(0); bzero((char *)sc, sizeof(struct envram_softc)); envram_softc = sc;
/******************************************************************** * Save the ctrl struct pointer in the driver's softc structure. * ********************************************************************/ sc->ctlr = ctlr;
/********************************************************************** ******** I/O Register Access Scheme ********************************** * * * The /dev/envram device driver uses a logical addressing scheme * * for I/O register access. This logical addressing scheme: * * * * o Uses the envram_softc data structure to store the io_handle_t * * for the physical base address * * o Passes the offset of the target register to the ENVRAM_READIO- * * and ENVRAM_WRITE_IO-related macros, which perform the I/O * * access. * * * * The ENVRAM_READIO- and ENVRAM_WRITE_IO-related macros are defined * * in envram_data.c. They use the read_io_port and write_io_port * * interfaces and OR the offset with the sc->regbase value. The * * sc->regbase value is the per-option physical base address of the * * EISA NVRAM I/O registers. * **********************************************************************/
/********************************************************************** * This next sequence of code gets the controller's base address and * * saves the slot number. For EISA bus controllers, the physical * * address of the adapter base register can be calculated by shifting * * the EISA slot number by 12 bits. It is also passed in the * * controller structure. * **********************************************************************/ sc->regbase = bus_io_handle;
/******************************************************************** * Read the controller's ID register to ensure that it is actually * * a DEC 2500. * ********************************************************************/
hw_id = ENVRAM_READIO_D32(ENVRAM_ID);
if (hw_id != ENVRAM_ID_MASK) { printf("envram_probe: Failed to read ID register\n"); /* deallocate sc resources */ kfree(sc, sizeof(struct envram_softc)); return(0); } else printf("envram_probe: EISA NVRAM present\n");
/******************************************************************** ********* EISA Configuration *************************************** ********************************************************************/
/******************************************************************** * Set up the members of the softc structure for the location and * * offset of NVRAM cache for the /dev/presto device driver. The * * starting io_handle_t of the NVRAM bus memory is available from * * the bus support information. * ********************************************************************/
sc->cache_offset = ENVRAM_CACHE_OFFSET; /* 1MB and 0x400 offset */
/******************************************************************** * Get nvram size and io_handle_t of starting address by calling * * the get_config interface. * ********************************************************************/
if (get_config(ctlr, RES_MEM, , &mem, 0)) { printf("envram probe error\n"); return(0); } sc->cache_size = mem.size; sc->cache_base = (u_long)mem.start_addr; sc->cache_phys_start = (u_long)(sc->cache_base + sc->cache_offset); sc->cache_kseg_start = (vm_offset_t) (PHYS_TO_KSEG(sc->cache_phys_start&eisa_addr_mask)); sc->saved_mem_sysmap = sc->cache_phys_start & ~eisa_addr_mask;
/******************************************************************** * Account for the diagnostic space. * ********************************************************************/ sc->cache_size = sc->cache_size - EISA_DIAG_RESVED;
/******************************************************************** * Get nvram dma channel information * ********************************************************************/ if (get_config(ctlr, EISA_DMA, , &dma_p, 0)) { printf("envram probe error dma channel\n"); return(0); }
/******************************************************************** * Fail the probe if invalid dma channel. * ********************************************************************/ if (dma_p.channel != 7 && dma_p.channel != 5) { printf("envram: invalid dma channel %d\n",dma_p.channel); return(0); }
/******************************************************************** * Enable the module by calling the ENVRAM_WRITEIO_D8 interface. * * Call the mb interface after the write completes. * ********************************************************************/
ENVRAM_WRITEIO_D8(ENVRAM_CTRL, EISA_ENABLE_BOARD); mb();
/******************************************************************** * Initialize the CSR and enable the NVRAM memory for writes * ********************************************************************/
ENVRAM_WRITEIO_D16(ENVRAM_CSR,WRMEM); mb();
/******************************************************************** * Check the console diagnostic results * ********************************************************************/
envram_read(sc->cache_phys_start-8, &sc->diag_status, 4);
if (sc->diag_status & BOARD_FAILED) { printf("Envram diag reg 0x%x\n",sc->diag_status); sc->diag_status = 0; } else { sc->diag_status = 1; } return(1); }
/******************************************************************** * INTERFACE NAME: envram_attach * * * * FUNCTIONAL DESCRIPTION: * * * * The envram_attach interface defines the /dev/envram driver * * interfaces to the /dev/presto device driver. It also calls * * presto_init to initialize the /dev/presto device driver. * * * * CALLED BY: Bus configuration code at boot time * * * * FORMAL PARAMETERS: * * * * o ctlr -- Pointer to the controller structure for this device * * o dev -- Pointer to the device structure for this device * * * * IMPLICIT INPUTS: * * * * o ctlr->slot -- EISA slot number of this controller * * o ctlr->conn_priv[0] -- Pointer to eisainfo structure * * o eisainfo->irq.intr.intr_num -- EISA interrupt level for this * * controller * * o eisainfo->irq.intr.trigger -- EISA interrupt high/low flag, * * 0 = edge (high), * * 1 = level (low) * * o ctlr->addr -- KSEG address of controller's base register * * o ctlr->physaddr -- Controller's base register physical * * address * * o softc structure is available with all EISA NVRAM values * * * * IMPLICIT OUTPUTS: None * * * * RETURN VALUE: None * ********************************************************************/
envram_attach(ctlr) struct controller *ctlr; /* Pointer to controller structure */ { /* Pointer to softc structure */ register struct envram_softc *sc = envram_softc;
/******************************************************************** * Allocate resources for DMA data transfers by calling the * * dma_map_alloc interface. * ********************************************************************/
if (dma_map_alloc(ENVRAM_XFER_SIZE, sc->ctlr, &sc->sglp, 0) == 0) panic("envram: dma_map_alloc error\n");
/******************************************************************** * The following code initializes the presto_interface0 data * * structure to the /dev/envram device driver interfaces that allow * * the /dev/presto device driver to access the NVRAM data cache. * ********************************************************************/
presto_interface0.nvram_status = eisa_nvram_status; presto_interface0.nvram_battery_status= eisa_nvram_battery_status; presto_interface0.nvram_battery_disable= eisa_nvram_battery_disable; presto_interface0.nvram_battery_enable= eisa_nvram_battery_enable;
/******************************************************************** * The following code initializes the presto_interface0 data * * structure to the /dev/envram device driver interfaces that allow * * the /dev/presto device driver to access the EISA NVRAM. Note * * that the ioreg and block interfaces are all expected to have * * these formal parameters: src, dest, and count. However, the * * envram_zero interface has these formal parameters: addr and * * length. * ********************************************************************/
presto_interface0.nvram_ioreg_read = envram_read; presto_interface0.nvram_ioreg_write = envram_write; presto_interface0.nvram_block_read = envram_read; presto_interface0.nvram_block_write = envram_write; presto_interface0.nvram_ioreg_zero = envram_zero; presto_interface0.nvram_block_zero = envram_zero;
/******************************************************************** * The EISA granularity is a byte, but force the use of 32-bit * * quantities for performance reasons. * ********************************************************************/
/******************************************************************** * Minimum size of a "small" ioreg data block * ********************************************************************/ presto_interface0.nvram_min_ioreg = sizeof(int);
/******************************************************************** * Byte alignment restriction for ioreg block * ********************************************************************/ presto_interface0.nvram_ioreg_align = sizeof(int); /******************************************************************** * Minimum size of a "large" block data transfer in bytes. * ********************************************************************/ presto_interface0.nvram_min_block = PRFSIZE;
/******************************************************************** * Byte alignment restriction for block data transfers * ********************************************************************/ presto_interface0.nvram_block_align = PRFSIZE;
/******************************************************************** * PRFSIZE = smallest fragment size for buffer (1K) * ********************************************************************/
/******************************************************************** * Call the presto_init interface to initialize the /dec/presto * * device driver interfaces. * ********************************************************************/
/******************************************************************** * RMA - fix Need unique sysid without etherrom!! * * Call the presto_init interface to perform initialization tasks * * the /dev/presto device driver. * ********************************************************************/ presto_init(sc->cache_kseg_start, sc->cache_size, ENVRAM_NOTMAPPED, ENVRAM_CACHED, envram_ssn()); }
/******************************************************************** * INTERFACE NAME: envram_ssn * * * * FUNCTIONAL DESCRIPTION: * * * * The envram_ssn interface determines an unsigned 32-bit unique * * number from the system serial number in the hwrbp. It converts * * the serial number from ASCII to a hexadecimal number. It also * * converts to 0xf modulo any letter over 'F' (or f). * * * * CALLED BY: * * * * The envram_attach interface passes envram_ssn as an argument to * * presto_init. The presto_init interface calls envram_ssn to * * obtain the machine (CPU) ID. * * * * FORMAL PARAMETERS: None * * * * IMPLICIT INPUTS: None * * * * IMPLICIT OUTPUTS: None * * * * RETURN VALUE: The machine (CPU) ID. * ********************************************************************/
envram_ssn() { extern struct rpb *rpb; /* Pointer to restart parameter */ /* block (rpb) structure */ u_int ssn = 0; /* Stores the system serial number */ int i; char *cp;
/* Grab the system serial number */cp = rpb->rpb_ssn + 9;
/******************************************************************** * Display an appropriate message on the console terminal if the * * system serial number equals the null character. * ********************************************************************/
if (*cp == '\0') { cp = "NO System Serial Number"+8; printf("envram_ssn: %s\n",cp-8); } /******************************************************************** * Use a for loop to parse the serial number and convert it to * * hexadecimal * ********************************************************************/ for (i = 0 ; i < 8 ; i++, cp--){ if (*cp < '9') ssn += (*cp - '0' ) << (i*4); else if (*cp < 'G') ssn += (*cp - 'A' + 0xa ) << (i*4); else if (*cp < 'a') ssn += ( *cp % 0xf ) << (i*4); else if (*cp < 'g') ssn += (*cp - 'a' + 0xa ) << (i*4); else ssn += ( *cp % 0xf ) << (i*4); } return(ssn); /* Return the system serial number */ }
/******************************************************************** * INTERFACE NAME: eisa_nvram_status * * * * FUNCTIONAL DESCRIPTION: * * * * The eisa_envram_status interface provides the /dev/presto device * * driver with the status of diagnostics run on the NVRAM. * * * * CALLED BY: The /dev/presto device driver. The nvram_status * * member of the presto_interface0 structure is set to * * eisa_nvram_status by envram_attach. The /dev/presto * * driver accesses the NVRAM cache interfaces through * * presto_interface0 structure. * * * * FORMAL PARAMETERS: None * * * * IMPLICIT INPUTS: * * * * o sc->diag_status -- diagnostic flag set in envram_probe * * * * IMPLICIT OUTPUTS: None * * * * RETURN VALUE: (sys/presto.h defined status values) * * * * NVRAM_RDWR -- Passed R/W diags * * NVRAM_RDONLY -- Passed RO diags * * NVRAM_BAD -- Failed diags * ********************************************************************/
int eisa_nvram_status() { /* Pointer to softc structure */ register struct envram_softc *sc = envram_softc;
if (sc->diag_status) return(NVRAM_RDONLY); /* Passed RO diags */ else return(NVRAM_BAD); /* Failed diags */ }
/******************************************************************** * INTERFACE NAME: eisa_nvram_battery_status * * * * FUNCTIONAL DESCRIPTION: * * * * The eisa_nvram_battery_status interface provides the /dev/presto * * device driver with the status of the battery on the EISA bus * * NVRAM memory expansion board. * * * * CALLED BY: * * * * The /dev/presto device driver calls this interface through the * * nvram_battery_status member of the presto_interface0 structure: * * * * presto_interface0.nvram_battery_status=eisa_nvram_battery_status;* * * * The envram_attach interface performs the initialization of * * nvram_battery_status. * * * * FORMAL PARAMETERS: None * * * * IMPLICIT INPUTS: None * * * * IMPLICIT OUTPUTS: * * * * The eisa_nvram_battery_status interface fills in the battery- * * related members of the nvram_battery_info data structure. Note * * that presto.h defines an external data structure called * * nvram_batteries0, which is an instance of nvram_battery_info. * * * * RETURN VALUE: (sys/presto.h defined status values) * * * * BATT_NONE -- No battery * * BATT_ENABLED -- Battery enabled * * BATT_HIGH -- Battery has minimal energy stored * * BATT_OK -- Battery ok * * BATT_SELFTEST -- Battery exists, but charge state unknown * * BATT_CHARGING -- Battery does not have enough power * ********************************************************************/
int eisa_nvram_battery_status() { /* Pointer to softc structure */ register struct envram_softc *sc = envram_softc;
nvram_batteries0.nv_nbatteries = 1; /* always one battery */ nvram_batteries0.nv_minimum_ok = 1; /* Battery must be good */ nvram_batteries0.nv_primary_mandatory = 1; /* Primary battery must be OK */ nvram_batteries0.nv_test_retries = 1; /* Call this interface one time */
/******************************************************************** * Check the battery status by reading the CSR. If the battery is * * okay, set the battery's nv_status and return zero (0) to the * * /dev/presto device driver. Otherwise, return 1 to indicate the * * the battery is not okay. * ********************************************************************/
if ((ENVRAM_READIO_D16(ENVRAM_CSR) & BAT_FAIL)) { nvram_batteries0.nv_status[0] = BATT_OK; return(0); } else {
return(1); } }
/******************************************************************** * INTERFACE NAME: eisa_nvram_battery_enable * * * * FUNCTIONAL DESCRIPTION: * * * * The eisa_nvram_battery_enable provides the /dev/presto device * * driver with the ability to enable the battery on the EISA bus * * NVRAM memory expansion board. * * * * CALLED BY: * * * * The /dev/presto device driver calls this interface through the * * nvram_battery_enable member of the presto_interface0 structure: * * * * presto_interface0.nvram_battery_enable=eisa_nvram_battery_enable;* * * * The envram_attach interface performs the initialization of * * nvram_battery_enable. * * * * FORMAL PARAMETERS: None * * * * IMPLICIT INPUTS: None * * * * IMPLICIT OUTPUTS: None * * * * RETURN VALUE: * * * * 0 -- Battery enabled successfully * * 1 -- Battery not enabled * ********************************************************************/
int eisa_nvram_battery_enable() { /* Pointer to softc structure */ register struct envram_softc *sc = envram_softc; /******************************************************************** * The required action is to zero the BDISC control bit. This * * disables the battery disconnect circuit, thus enabling the * * battery. * ********************************************************************/ ENVRAM_WRITEIO_D16(ENVRAM_CSR, WRMEM|SET_LED); ENVRAM_WRITEIO_D8(ENVRAM_BAT,!BAT_DISCON_BIT); mb(); /* Perform a memory barrier after the writes. */
return(0); /* Battery successfully enabled */ }
/********************************************************************** * INTERFACE NAME: eisa_nvram_battery_disable * * * * FUNCTIONAL DESCRIPTION: * * * * The eisa_nvram_battery_disable provides the /dev/presto device * * driver with the ability to disable the battery on the EISA bus * * NVRAM memory expansion board. * * * * The /dev/presto device driver calls this interface through the * * nvram_battery_disable member of the presto_interface0 structure: * * * * presto_interface0.nvram_battery_disable=eisa_nvram_battery_disable;* * * * The envram_attach interface performs the initialization of * * nvram_battery_disable. * * * * FORMAL PARAMETERS: None * * * * IMPLICIT INPUTS: None * * * * IMPLICIT OUTPUTS: None * * * * RETURN VALUE: * * * * 0 -- Battery disabled successfully * * 1 -- Battery not disabled * **********************************************************************/
int eisa_nvram_battery_disable() { /* Pointer to softc structure */ register struct envram_softc *sc = envram_softc;
/******************************************************************** * The required action is to send sequence "11001" to the battery * * disconnect device register. This enables the battery disconnect * * circuit. * ********************************************************************/ ENVRAM_WRITEIO_D16(ENVRAM_CSR,WRMEM); ENVRAM_WRITEIO_D8(ENVRAM_BAT,BAT_DISCON_BIT); mb(); ENVRAM_WRITEIO_D8(ENVRAM_BAT,BAT_DISCON_BIT); mb(); ENVRAM_WRITEIO_D8(ENVRAM_BAT,!BAT_DISCON_BIT); mb(); ENVRAM_WRITEIO_D8(ENVRAM_BAT,!BAT_DISCON_BIT); mb(); ENVRAM_WRITEIO_D8(ENVRAM_BAT,BAT_DISCON_BIT); mb();
return(0); /* Battery successfully disabled */ }
/******************************************************************** * INTERFACE NAME: envram_read * * * * FUNCTIONAL DESCRIPTION: * * * * The envram_read interface provides the DMA slave capability to: * * * * o Convert the source address passed in by envram_probe and the * * /dev/presto driver from the NVRAM address into a * * physical address * * o Copies data from the NVRAM bus address space to * * system memory * * * * Specifically, the envram_read interface reads the length block * * of data pointed to by the source address parameter to the EISA * * NVRAM destination parameter. This assumes: * * * * 1. The source is *always* from the NVRAM * * 2. The destination is to Host (Main) memory * * * * CALLED BY: * * * * The /dev/presto device driver calls this interface through the * * nvram_ioreg_read and nvram_block_read members of the * * presto_interface0 structure: * * * * presto_interface0.nvram_ioreg_read=envram_read; * * presto_interface0.nvram_block_read=envram_read * * * * The envram_attach interface performs the initialization of * * nvram_ioreg_read and nvram_block_read. * * * * The envram_probe interface also calls envram_read. * * * * FORMAL PARAMETERS: * * * * o srcaddr -- Specifies the source address of the data to be * * written. Because this source address is passed * * in to envram_read by envram_probe and the * * /dev/presto device driver, the address format is * * a kernel segment(KSEG) logical physical address. * * * * o destaddr -- Specifies the destination address of where to * * write the data. Because this destination * * address is passed in by the envram_probe and the * * /dev/presto device device driver, the format is * * a kernel segment (KSEG) logical physical * * address. * * * * o length -- Specifies the length of the block of data to be * * written. This length is passed in by envram_probe * * and the /dev/presto device driver. * * * * IMPLICIT INPUTS: * * * * o srcaddr (See above description) * * o destaddr (See above description) * * o length (See above description) * * * * IMPLICIT OUTPUTS: None * * * * RETURN VALUE: None * ********************************************************************/
void envram_read(source, dest, len) caddr_t source; /* Address of the source data */ caddr_t dest; /* Destination for the source data */ u_int len; /* Length of the block */ { /* Pointer to softc structure */ register struct envram_softc *sc = envram_softc;
/******************************************************************** * Copy the data from bus address space to system memory by calling * * the io_copyin interface. This is a generic interface that maps * * to a machine-specific interface that actually performs the copy * * from bus address space to system memory. Using io_copyin to * * perform the copy operation makes the device driver more portable * * across different CPU architectures and different CPU types * * within the same architecture. * ********************************************************************/
io_copyin((io_handle_t) KSEG_TO_PHYS((u_long)source|sc->saved_mem_sysmap), (vm_offset_t)dest,len); }
/******************************************************************** * INTERFACE NAME: envram_write * * * * FUNCTIONAL DESCRIPTION: * * * * The envram_write interface provides the DMA slave capability to: * * * * o Write to the NVRAM * * o Perform programmed I/O * * o Copy to the NVRAM * * * * Specifically, the envram_write interface writes * * the length block of data pointed to by the source * * address parameter to the EISA NVRAM destination * * parameter. This assumes: * * * * 1. The destination is *always* the NVRAM * * 2. The source is from Host (Main) memory * * * * CALLED BY: * * * * The /dev/presto device driver calls this interface through the * * nvram_ioreg_write and nvram_block_write members of the * * presto_interface0 structure: * * * * presto_interface0.nvram_ioreg_write=envram_write; * * presto_interface0.nvram_block_write=envram_write * * * * The envram_attach interface performs the initialization of * * nvram_ioreg_write and nvram_block_write. * * * * FORMAL PARAMETERS: * * * * o srcaddr -- Specifies the source address of the data to be * * written. Because this source address is passed * * in to envram_read by the /dev/presto device * * driver, the address format is a kernel * * segment(KSEG) logical physical address. * * * * o destaddr -- Specifies the destination address of where to * * write the data. Because this destination * * address is passed in by the /dev/presto device * * device driver, the format is a kernel * * segment (KSEG) logical physical address. * * * * o length -- Specifies the length of the block of data to be * * written. This length is passed in by the * * /dev/presto device driver. * * * * IMPLICIT INPUTS: * * * * o srcaddr (See above description) * * o destaddr (See above description) * * o length (See above description) * * * * IMPLICIT OUTPUTS: None * * * * RETURN VALUE: None * ********************************************************************/
void envram_write(source, dest, len) caddr_t source; /* Address of the source data */ caddr_t dest; /* Destination for the source data */ u_int len; /* Length of the block */ { /* Pointer to softc structure */ register struct envram_softc *sc = envram_softc; vm_offset_t destptr; /* Stores the destination address */ register int xfer; /* size of each partial transfer */ int retry; /* retry counter */ char *ddest = dest; /* destination pointer */
/******************************************************************** * Presto WRITE operation: Write to NVRAM from Main Memory * ********************************************************************/
/******************************************************************** * Use DMA if size is larger than 32 bytes * ********************************************************************/ if (len > 32) {
/* * Set up destination address passed from Presto, * the dest is a main memory virtual address */ destptr = KSEG_TO_PHYS(dest) - sc->cache_base; ddest = (char *)destptr;
/* * Allign destination to 1K */ if (!(xfer = ENVRAM_XFER_SIZE - ((int)ddest & (ENVRAM_XFER_SIZE-1)))) xfer = ENVRAM_XFER_SIZE;
if (xfer > len) xfer = len;
/* * Allign source to 8K */ if ((u_int)source/ENVRAM_ALLIGN != ((u_int)source+xfer)/ENVRAM_ALLIGN) xfer = xfer - (((u_int)source+xfer) & (ENVRAM_ALLIGN-1));
while (1) {
/* * Set up the 82357 dma controller */ if (!(dma_map_load(xfer, source, (struct proc *)0, sc->ctlr, &sc->sglp, 0, DMA_OUT))) panic("envram: dma_map_load failure\n");
/* * Set up NVRAM source address */ ENVRAM_WRITEIO_D16(ENVRAM_DMA0,((u_int)(ddest-4) << 6)); ENVRAM_WRITEIO_D16(ENVRAM_DMA1,((u_int)ddest >> 5));
/* * Start NVRAM transfer */ ENVRAM_WRITEIO_D16(ENVRAM_CSR,SET_DREQ|WRMEM|SET_LED); mb();
/* * Bookeeping, bury behind DMA */ len -= xfer; source += xfer; ddest += xfer;
/* * Set up for next, align destination to 1K, * NVRAM only handles DMAs inside of a 1k * alligned address range. */ if (!(xfer = ENVRAM_XFER_SIZE - (((int)ddest & (ENVRAM_XFER_SIZE-1))))) xfer = ENVRAM_XFER_SIZE;
if (xfer > len) xfer = len;
/* * Align source to 8K, source will be memory * hence 8K for Digital UNIX pages. */ if ((u_int)source/ENVRAM_ALLIGN != ((u_int)source+xfer)/ENVRAM_ALLIGN) xfer = xfer - (((u_int)source+xfer) & (ENVRAM_ALLIGN-1));
/* * Spin on SET_DREQ bit. If the hardware * works, this bit should never be set. */ retry = 10; while (--retry) if (!(ENVRAM_READIO_D16(ENVRAM_CSR) & SET_DREQ)) break;
if (!length) break;
/* * If retry expires the hardware is broken. */ if (!retry) panic("envram: DMA retry expired\n"); } return; }
/* * The envram_write interface copies the data from system * memory to bus address space by calling io_copyout. * The io_copyout interface is a generic interface that * maps to a bus- and machine-specific interface that * actually performs the copy to bus address space. * Using io_copyout to perform the copy operation * makes the device driver more portable across different * CPU architectures and different CPU types within * the same architecture. */ io_copyout((vm_offset_t)source, (io_handle_t) (KSEG_TO_PHYS((u_long)dest)|sc->saved_mem_sysmap), len); }
/******************************************************************** * INTERFACE NAME: envram_zero * * * * FUNCTIONAL DESCRIPTION: * * * * The envram_zero interface zeroes the "len" bytes of EISA NVRAM * * memory starting at "addr". * * * * FORMAL PARAMETERS: * * * * o addr - Specifies the starting address of the * * NVRAM for this EISA bus memory expansion board to * * zero. Because this address is passed in by the * * /dev/presto device driver, the format is a kernel * * segment (KSEG) logical physical address. * * * * o length - Specifies the number of bytes to zero. This length * * is passed in by the /dev/presto device driver. * * * * CALLED BY: * * * * The /dev/presto device driver calls this interface through the * * nvram_ioreg_zero and nvram_block_zero members of the * * presto_interface0 structure: * * * * presto_interface0.nvram_ioreg_zero=envram_zero; * * presto_interface0.nvram_block_zero=envram_zero; * * * * The envram_attach interface performs the initialization of * * nvram_ioreg_zero and nvram_block_zero. * * * * IMPLICIT INPUTS: * * * * o addr (See above description) * * o length (See above description) * * * * IMPLICIT OUTPUTS: None * * * * RETURN VALUE: None. * ********************************************************************/
void envram_zero(addr, len) caddr_t addr; /* Starting address of EISA NVRAM to zero */ u_int len; /* Number of bytes to zero */ { /* Pointer to softc structure */ register struct envram_softc *sc = envram_softc;
/******************************************************************** * Zero a block of memory in bus address space by calling the * * io_zero interface. This is a generic interface that maps to a * * machine-specific interface that actually writes zeros to some * * location in bus address space. Using io_zero to perform the * * zero operation makes the device driver more portable across * * different CPU architectures and different CPU types within the * * same architecture. * ********************************************************************/
io_zero((io_handle_t) KSEG_TO_PHYS((u_long)addr|sc->saved_mem_sysmap), len); }