NetBSD-5.0.2/sys/arch/cesfic/cesfic/eeprom.c
/* $NetBSD: eeprom.c,v 1.3 2005/12/11 12:17:04 christos Exp $ */
/*
* Copyright (c) 1997, 1999
* Matthias Drochner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: eeprom.c,v 1.3 2005/12/11 12:17:04 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <machine/autoconf.h>
/* Physical EEPROM */
#define EEPROMBASE 0x5a800000
#define EEPROMSIZE 0x2000
#define EEPROMEND (EEPROMBASE + 4*EEPROMSIZE)
/* Part of EEPROM used for system parameters: last 256 bytes */
#define EEPSIZE 256
#define EEPSTART (EEPROMEND - 4*EEPSIZE)
struct MemRange {
unsigned short Start;
unsigned short End;
unsigned short Attr;
};
#define MAX_EXP 2
#define MAX_CACHE 3
struct uEEPROMDATA {
unsigned long uSignature;
unsigned char uMemA;
unsigned char uMemB;
unsigned char uEtherAddr[6];
unsigned short uEthNFM;
unsigned short uBusNFM;
unsigned long uInternet;
unsigned long uInterbroad;
unsigned long uIntermask;
struct MemRange uMemList[2][MAX_EXP];
struct MemRange uCacheList[2][MAX_CACHE];
};
typedef unsigned short CHECKSUM;
struct EEPROMData {
struct uEEPROMDATA u;
char pad[EEPSIZE - sizeof(struct uEEPROMDATA) - sizeof(CHECKSUM)];
CHECKSUM CheckSum;
};
#define Signature u.uSignature
#define MemA u.uMemA
#define MemB u.uMemB
#define EtherAddr u.uEtherAddr
#define EthNFM u.uEthNFM
#define BusNFM u.uBusNFM
#define Internet u.uInternet
#define Interbroad u.uInterbroad
#define Intermask u.uIntermask
#define MemList u.uMemList
#define CacheList u.uCacheList
#define SIGNATURE (('D'<<24) + ('a'<<16) + ('t'<<8) + 'a')
static CHECKSUM CheckSum(CHECKSUM *);
static int GetEEPROMData(struct EEPROMData *);
static CHECKSUM
CheckSum(data)
CHECKSUM *data;
{
CHECKSUM c;
int i;
c = -1;
for (i = 0; i < (EEPSIZE / sizeof(CHECKSUM) - 1); i++)
c -= data[i];
return (c);
}
static int
GetEEPROMData(data)
struct EEPROMData *data;
{
unsigned char *eep;
int i;
mainbus_map(EEPSTART, 4*EEPSIZE, 0, (void *)&eep);
for (i = 0; i < EEPSIZE; i++)
((char *)data)[i] = eep[4*i + 3];
if (data->Signature != SIGNATURE)
return (1);
if (CheckSum((void *)data) != data->CheckSum)
return (2);
return (0);
}
static struct EEPROMData eeprom;
static int eeprom_read;
int
cesfic_getetheraddr(buf)
unsigned char *buf;
{
int res;
if (!eeprom_read) {
res = GetEEPROMData(&eeprom);
if (res) {
printf("error %d reading EEPROM\n", res);
return (-1);
}
eeprom_read = 1;
}
bcopy(eeprom.EtherAddr, buf, 6);
return (0);
}