powerpc/haleakala: Add network driver

close 1405
This commit is contained in:
Nigel Spon
2014-11-21 11:15:22 -06:00
committed by Joel Sherrill
parent ed4c5568c7
commit 502609c80d
9 changed files with 1845 additions and 42 deletions

View File

@@ -7,6 +7,7 @@ include_bspdir = $(includedir)/bsp
dist_project_lib_DATA = bsp_specs dist_project_lib_DATA = bsp_specs
include_HEADERS = include/bsp.h include_HEADERS = include/bsp.h
include_HEADERS += include/mmu_405.h
include_HEADERS += ../../shared/include/tm27.h include_HEADERS += ../../shared/include/tm27.h
nodist_include_HEADERS = include/bspopts.h nodist_include_HEADERS = include/bspopts.h
@@ -30,7 +31,7 @@ libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
startup/bspstart.c ../../shared/bootcard.c \ startup/bspstart.c ../../shared/bootcard.c \
../../shared/bsppredriverhook.c ../../shared/bspgetworkarea.c \ ../../shared/bsppredriverhook.c ../../shared/bspgetworkarea.c \
../../shared/bsppretaskinghook.c ../../shared/sbrk.c \ ../../shared/bsppretaskinghook.c ../../shared/sbrk.c \
../../shared/gnatinstallhandler.c ../../shared/gnatinstallhandler.c mmu/mmu_405.c mmu/mmu_405asm.S
# dlentry # dlentry
libbsp_a_SOURCES += dlentry/dlentry.S libbsp_a_SOURCES += dlentry/dlentry.S
@@ -47,6 +48,14 @@ include_bsp_HEADERS += irq/irq.h \
# irq # irq
libbsp_a_SOURCES += irq/irq_init.c irq/irq.c libbsp_a_SOURCES += irq/irq_init.c irq/irq.c
if HAS_NETWORKING
network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
noinst_PROGRAMS = network.rel
network_rel_SOURCES = network/network.c
network_rel_CPPFLAGS = $(AM_CPPFLAGS) $(network_CPPFLAGS)
network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \ libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \
../../../libcpu/@RTEMS_CPU@/@exceptions@/exc_bspsupport.rel \ ../../../libcpu/@RTEMS_CPU@/@exceptions@/exc_bspsupport.rel \
../../../libcpu/@RTEMS_CPU@/@exceptions@/irq_bspsupport.rel \ ../../../libcpu/@RTEMS_CPU@/@exceptions@/irq_bspsupport.rel \
@@ -55,5 +64,9 @@ libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \
../../../libcpu/@RTEMS_CPU@/ppc403/clock.rel \ ../../../libcpu/@RTEMS_CPU@/ppc403/clock.rel \
../../../libcpu/@RTEMS_CPU@/ppc403/timer.rel ../../../libcpu/@RTEMS_CPU@/ppc403/timer.rel
if HAS_NETWORKING
libbsp_a_LIBADD += network.rel
endif
include $(srcdir)/preinstall.am include $(srcdir)/preinstall.am
include $(top_srcdir)/../../../../automake/local.am include $(top_srcdir)/../../../../automake/local.am

View File

@@ -14,7 +14,6 @@ RTEMS_CANONICALIZE_TOOLS
RTEMS_PROG_CCAS RTEMS_PROG_CCAS
RTEMS_CHECK_NETWORKING RTEMS_CHECK_NETWORKING
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes") AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
RTEMS_BSPOPTS_SET([PPC_USE_SPRG],[*],[1]) RTEMS_BSPOPTS_SET([PPC_USE_SPRG],[*],[1])

View File

@@ -0,0 +1,77 @@
#ifndef _mmu_405_h
#define _mmu_405_h
/*
Simple interface to the PowerPC 405 MMU
The intention here is just to allow the MMU to be used to define cacheability and
read/write/execute permissions in a simple enough way to fit entirely into the
64-entry TLB cache.
This code does not do address relocation and does not generate any MMU-related interrupts.
The process ID support is there for a possible future extension where RTEMS supports
setting the process ID on task switches, which allows per-process stack protection
This code will call fatal_error() if your add_space() calls overrun the 64 entries
Michael Hamel ADInstruments 2008
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "stdint.h"
enum {
kAllProcessIDs = 0
};
typedef enum MMUAccessType {
executable,
readOnlyData,
readOnlyNoCache,
readWriteData,
readWriteNoCache,
readWriteExecutable
} MMUAccessType;
/* Initialise and clear the MMU */
void mmu_initialise();
/* Turn on/off data access translation */
bool mmu_enable_data(bool enable);
/* Turn on instruction translation */
bool mmu_enable_code(bool enable);
/* Define properties for an area of memory (must be 1K-aligned) */
void mmu_add_space(uint32_t startAddr, uint32_t endAddr, MMUAccessType permissions, uint8_t processID);
/* Delete a memory property definition */
void mmu_remove_space(uint32_t startAddr, uint32_t endAddr);
/* Return number of TLB entries out of total in use */
int mmu_get_tlb_count();
/* Allocate a new process ID and return it */
uint8_t mmu_new_processID();
/* Free a process ID that has been in use */
void mmu_free_processID(uint8_t freeThis);
/* Return the current process ID */
uint8_t mmu_current_processID();
/* Change the process ID to ID and return the old value */
uint8_t mmu_set_processID(uint8_t toID);
#ifdef __cplusplus
}
#endif
#endif //_mmu_405.h

View File

@@ -0,0 +1,281 @@
/*
* Simple interface to the PowerPC 405 MMU
*
* Michael Hamel ADInstruments 2008
*
*/
#include <bsp.h>
#include <libcpu/powerpc-utility.h>
#include "mmu_405.h"
/* #define qLogTLB */
/* #define qLogTLBDetails */
/*--------------------------------- TLB handling ------------------------------------- */
/* The following are in assembler in mmu_405asm.S */
extern void MMU_GetTLBEntry(uint8_t index, uint32_t* tagword, uint32_t* dataword, uint8_t* pid);
extern void MMU_SetTLBEntry(uint8_t index, uint32_t hiword, uint32_t loword, uint8_t pid);
extern void MMU_ClearTLBs();
extern int16_t MMU_FindTLBEntry(uint32_t address);
enum { kNTLBs = 64 }; /* for 403GCX and 405 */
static bool sFreeTLBs[kNTLBs];
static uint8_t sLastIndex = 0;
static int sNInUse = 0;
static void MMUFault(const char* what)
/* Used for all setup faults; these can't really be ignored */
{
printk("\n>>>MMU fatal error %s\n",what);
rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
}
static uint8_t AllocTLB()
{
uint8_t index;
index = sLastIndex;
do {
index++;
if (index == kNTLBs)
index = 0;
if (index == sLastIndex)
MMUFault("TLB table full");
} while (! sFreeTLBs[index]);
sFreeTLBs[index] = false;
sLastIndex = index;
sNInUse++;
return index;
}
static void FreeTLB(uint8_t index)
{
MMU_SetTLBEntry(index,0,0,0);
sFreeTLBs[index] = true;
sLastIndex = index-1;
sNInUse--;
}
/*---------------------------- MMU operations ---------------------------------- */
int DataMissException(BSP_Exception_frame *f, unsigned int vector);
int InstructionMissException(BSP_Exception_frame *f, unsigned int vector);
int InstructionFetchException(BSP_Exception_frame *f, unsigned int vector);
void
mmu_initialise()
/* Clear the TLBs and set up exception handlers for the MMU miss handlers */
{
int i;
MMU_ClearTLBs();
for (i=0; i<kNTLBs; i++) {
sFreeTLBs[i] = true;
MMU_SetTLBEntry(i,0,0,0xFF);
}
ppc_exc_set_handler(ASM_ISI_VECTOR ,InstructionFetchException);
ppc_exc_set_handler(ASM_BOOKE_ITLBMISS_VECTOR ,DataMissException);
ppc_exc_set_handler(ASM_BOOKE_DTLBMISS_VECTOR ,InstructionMissException);
}
static void
MakeTLBEntries(uint32_t startAt, uint32_t nBytes, bool EX, bool WR, bool I, uint8_t PID)
{
uint32_t mask, options, tagWord, dataWord;
uint8_t index, sizeCode, pid;
if ((startAt & 0x3FF) != 0)
MMUFault("TLB entry not on 1K boundary");
if ((nBytes & 0x3FF) != 0)
MMUFault("TLB size not on 1K boundary");
options = 0;
if (EX) options += 0x200;
if (WR) options += 0x100;
if (I) options += 5;
#ifdef qLogTLB
printk("TLB: make entries for $%X bytes from $%X..$%X PID %d",nBytes, startAt, startAt+nBytes-1, PID);
if (EX) printk(" EX");
if (WR) printk(" WR");
if (I) printk(" I");
printk("\n");
#endif
while (nBytes > 0) {
/* Find the largest block we can base on this address */
mask = 0x3FF;
sizeCode = 0;
while (mask < nBytes && ((startAt & mask)==0) && sizeCode < 8) {
mask = (mask<<2) + 3;
sizeCode++;
}
mask >>= 2;
sizeCode--;
/* Make a TLB entry describing this, ZSEL=0 */
tagWord = startAt | (sizeCode<<7) | 0x40;
dataWord = startAt | options;
index = AllocTLB();
MMU_SetTLBEntry( index , tagWord, dataWord, PID);
{
/* Paranoia: check that we can read that back... */
uint8_t tdex, oldpid;
oldpid = mmu_current_processID();
mmu_set_processID(PID);
tdex = MMU_FindTLBEntry(startAt);
mmu_set_processID(oldpid);
if (tdex != index) {
printk(" Add TLB %d: At %X for $%X sizecode %d tagWord $%X ",index, startAt, mask+1,sizeCode,tagWord);
printk(" -- find failed, %d/%d!\n",tdex,index);
MMU_GetTLBEntry(index, &tagWord, &dataWord, &pid);
printk(" -- reads back $%X : $%X, PID %d\n",tagWord,dataWord,pid);
} else {
#ifdef qLogTLBDetails
printk(" Add TLB %d: At %X for $%X sizecode %d tagWord $%X\n",index, startAt, mask+1,sizeCode,tagWord);
#endif
}
}
/* Subtract block from startAddr and nBytes */
mask++; /* Convert to a byte count */
startAt += mask;
nBytes -= mask;
}
#ifdef qLogTLB
printk(" %d in use\n",sNInUse);
#endif
}
void
mmu_remove_space(uint32_t startAt, uint32_t endAt)
{
int16_t index;
int32_t size;
uint32_t tagword, dataword, nBytes;
uint8_t pid, sCode;
nBytes = endAt - startAt;
#ifdef qLogTLB
printk("TLB: delete entries for $%X bytes from $%X\n",nBytes,startAt);
#endif
while (nBytes > 0) {
index = MMU_FindTLBEntry( (uint32_t)startAt );
size = 1024;
if (index >= 0) {
MMU_GetTLBEntry(index, &tagword, &dataword, &pid);
if ((tagword & 0x40) == 0)
MMUFault("Undefine failed: redundant entries?");
if ((tagword & 0xFFFFFC00) != (uint32_t)startAt)
MMUFault("Undefine not on TLB boundary");
FreeTLB(index);
sCode = (tagword >> 7) & 7;
while (sCode > 0) {
size <<= 2;
sCode--;
}
#ifdef qLogTLBDetails
printk(" Free TLB %d: At %X for $%X\n",index, startAt, size);
#endif
}
startAt += size;
nBytes -= size;
}
}
void
mmu_add_space(uint32_t startAddr, uint32_t endAddr, MMUAccessType permissions, uint8_t processID)
/* Convert accesstype to write-enable, executable, and cache-inhibit bits */
{
bool EX, WR, I;
EX = false;
WR = false;
I = false;
switch (permissions) {
case executable : EX = true; break;
case readOnlyData : break;
case readOnlyNoCache : I = true; break;
case readWriteData : WR = true; break;
case readWriteNoCache : WR = true; I= true; break;
case readWriteExecutable: WR = true; EX = true; break;
}
MakeTLBEntries( (uint32_t)startAddr, (uint32_t)(endAddr-startAddr+1), EX, WR, I, processID);
}
int
mmu_get_tlb_count()
{
return sNInUse;
}
/*---------------------------- CPU process ID handling ----------------------------------
* Really dumb system where we just hand out sequential numbers and eventually fail
* As long as we only use 8-9 processes this isn't a problem */
static uint8_t sNextPID = 1;
#define SPR_PID 0x3B1
uint8_t mmu_new_processID()
{
return sNextPID++;
}
void mmu_free_processID(uint8_t freeThis)
{
}
uint8_t mmu_current_processID()
{
return PPC_SPECIAL_PURPOSE_REGISTER(SPR_PID);
}
uint8_t mmu_set_processID(uint8_t newID)
{
uint8_t prev = mmu_current_processID();
PPC_SET_SPECIAL_PURPOSE_REGISTER(SPR_PID,newID);
return prev;
}
/* ------------------ Fault handlers ------------------ */
#define SPR_ESR 0x3D4
#define SPR_DEAR 0x3D5
enum { kESR_DST = 0x00800000 };
int DataMissException(BSP_Exception_frame *f, unsigned int vector)
{
uint32_t addr, excSyn;
addr = PPC_SPECIAL_PURPOSE_REGISTER(SPR_DEAR);
excSyn = PPC_SPECIAL_PURPOSE_REGISTER(SPR_ESR);
if (excSyn & kESR_DST) printk("\n---Data write to $%X attempted at $%X\n",addr,f->EXC_SRR0);
else printk("\n---Data read from $%X attempted at $%X\n",addr,f->EXC_SRR0);
return -1;
}
int InstructionMissException(BSP_Exception_frame *f, unsigned int vector)
{
printk("\n---Instruction fetch attempted from $%X, no TLB exists\n",f->EXC_SRR0);
return -1;
}
int InstructionFetchException(BSP_Exception_frame *f, unsigned int vector)
{
printk("\n---Instruction fetch attempted from $%X, TLB is no-execute\n",f->EXC_SRR0);
return -1;
}

View File

@@ -0,0 +1,83 @@
/*
Low-level interface to the PPC405 MMU
M.Hamel ADInstruments 2008
*/
#include <rtems/asm.h>
/* Useful MMU SPR values */
#define SPR_ZPR 0x3B0
#define SPR_PID 0x3B1
.text
/* void MMU_ClearTLBs(); */
PUBLIC_VAR(MMU_ClearTLBs)
SYM (MMU_ClearTLBs):
tlbia
isync
lis r3,0x5555 // *** Gratuitous fiddle of ZPR to 0101010101 to take it out of
mtspr SPR_ZPR,r3 // the picture
blr
/* void MMU_SetTLBEntry(UInt8 index, UInt32 tagword, UInt32 dataword, UInt8 SPR_PID) */
PUBLIC_VAR(MMU_SetTLBEntry)
SYM (MMU_SetTLBEntry):
mfspr r7,SPR_PID // Save the current SPR_PID
mtspr SPR_PID,r6 // Write to SPR_PID
tlbwehi r4,r3 // Write hiword
mtspr SPR_PID,r7 // Restore the SPR_PID
tlbwelo r5,r3 // Write loword
isync
blr
/* void MMU_GetTLBEntry(UInt8 index, UInt32& tagword, UInt32& dataword, UInt8& SPR_PID) */
PUBLIC_VAR(MMU_GetTLBEntry)
SYM (MMU_GetTLBEntry):
mfspr r7,SPR_PID // Save the current SPR_PID
tlbrehi r8,r3 // Read hiword & SPR_PID
mfspr r9,SPR_PID // Copy the SPR_PID
mtspr SPR_PID,r7 // Restore original SPR_PID so we can proceed
stw r8,0(r4) // Write to r4 pointer
stb r9,0(r6) // Write to r6 pointer
tlbrelo r8,r3 // Read loword
stw r8,0(r5) // Write to r5 pointer
blr
/* SInt16 MMU_FindTLBEntry(UInt32 address) */
/* Returns index of covering TLB entry (0..63), or -1 if there isn't one */
PUBLIC_VAR(MMU_FindTLBEntry)
SYM (MMU_FindTLBEntry):
tlbsx. r3,0,r3
beqlr
li r3,0xFFFFFFFF
blr
/* bool mmu_enable_code(bool enable); */
PUBLIC_VAR(mmu_enable_code)
SYM (mmu_enable_code):
li r5,0x20 // IR bit
b msrbits
/* bool mmu_enable_data(bool enable); */
PUBLIC_VAR(mmu_enable_data)
SYM (mmu_enable_data):
li r5,0x10 // DR bit
msrbits: cmpwi r3,0 // Common code: parameter 0?
mfmsr r4 // r4 = MSR state
beq clrBit
or r6,r4,r5 // If 1, r6 = MSR with bit set
b setmsr
clrBit: andc r6,r4,r5 // If 0 r6 = MSR with bit clear
setmsr: mtmsr r6 // Write new MSR
and. r3,r4,r5 // Result = old MSR bit
beqlr // If zero return zero
li r3,0xFF // If nonzero return byte -1
blr

File diff suppressed because it is too large Load Diff

View File

@@ -41,6 +41,10 @@ $(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
$(PROJECT_INCLUDE)/mmu_405.h: include/mmu_405.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mmu_405.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mmu_405.h
$(PROJECT_INCLUDE)/tm27.h: ../../shared/include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp) $(PROJECT_INCLUDE)/tm27.h: ../../shared/include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h

View File

@@ -78,59 +78,86 @@ enum {
}; };
enum { enum {
SDR0_PINSTP = 0x40,
SDR0_UART0 = 0x120, SDR0_UART0 = 0x120,
SDR0_UART1 = 0x121, SDR0_UART1 = 0x121,
SDR0_C405 = 0x180, SDR0_C405 = 0x180,
SDR0_SRST0 = 0x200,
SDR0_MALTBL = 0x280, SDR0_MALTBL = 0x280,
SDR0_MALRBL = 0x2A0, SDR0_MALRBL = 0x2A0,
SDR0_MALTBS = 0x2C0, SDR0_MALTBS = 0x2C0,
SDR0_MALRBS = 0x2E0 SDR0_MALRBS = 0x2E0,
SDR0_PFC2 = 0x4102,
SDR0_MFR = 0x4300,
SDR0_EMAC0RXST = 0x4301,
SDR0_HSF = 0x4400
}; };
enum {
CPR0_CLKUPD = 0x20,
CPR0_PLLC = 0x40,
CPR0_PLLD = 0x60,
CPR0_CPUD = 0x80,
CPR0_PLBD = 0xA0,
CPR0_OPBD = 0xC0,
CPR0_PERD = 0xE0,
CPR0_AHBD = 0x100,
CPR0_ICFG = 0x140
};
/* Memory-mapped registers */ /* Memory-mapped registers */
/*======================= Ethernet =================== */ /*======================= Ethernet =================== */
typedef struct EthernetRegisters_EX {
uint32_t mode0;
uint32_t mode1;
uint32_t xmtMode0;
uint32_t xmtMode1;
uint32_t rcvMode;
uint32_t intStatus;
uint32_t intEnable;
uint32_t addrHi;
uint32_t addrLo;
uint32_t VLANTPID;
uint32_t VLANTCI;
uint32_t pauseTimer;
uint32_t multicastAddr[2];
uint32_t multicastMask[2];
uint32_t unused[4];
uint32_t lastSrcLo;
uint32_t lastSrcHi;
uint32_t IPGap;
uint32_t STAcontrol;
uint32_t xmtReqThreshold;
uint32_t rcvWatermark;
uint32_t bytesXmtd;
uint32_t bytesRcvd;
uint32_t unused2;
uint32_t revID;
uint32_t unused3[2];
uint32_t indivHash[8];
uint32_t groupHash[8];
uint32_t xmtPause;
} EthernetRegisters_EX;
enum { enum {
EMAC0Address = 0xEF600900, EMAC0EXAddress = 0xEF600900,
EMAC1Address = 0xEF600A00 EMAC1EXAddress = 0xEF600A00,
};
/* 405EX-specific bits in EMAC_MR1 */
keEMAC1000Mbps = 0x00800000,
keEMAC16KRxFIFO = 0x00280000,
keEMAC8KRxFIFO = 0x00200000,
keEMAC4KRxFIFO = 0x00180000,
keEMAC2KRxFIFO = 0x00100000,
keEMAC1KRxFIFO = 0x00080000,
keEMAC16KTxFIFO = 0x00050000,
keEMAC8KTxFIFO = 0x00040000,
keEMAC4KTxFIFO = 0x00030000,
keEMAC2KTxFIFO = 0x00020000,
keEMAC1KTxFIFO = 0x00010000,
keEMACJumbo = 0x00000800,
keEMACIPHYAddr4 = 0x180,
keEMACOPB50MHz = 0x00,
keEMACOPB66MHz = 0x08,
keEMACOPB83MHz = 0x10,
keEMACOPB100MHz = 0x18,
keEMACOPBGt100 = 0x20,
/* 405EX-specific bits in MAL0_CFG */
keMALRdMaxBurst4 = 0,
keMALRdMaxBurst8 = 0x00100000,
keMALRdMaxBurst16 = 0x00200000,
keMALRdMaxBurst32 = 0x00300000,
keMALWrLowPriority = 0,
keMALWrMedLowPriority = 0x00040000,
keMALWrMedHiPriority = 0x00080000,
keMALWrHighPriority = 0x000C0000,
keMALWrMaxBurst4 = 0,
keMALWrMaxBurst8 = 0x00010000,
keMALWrMaxBurst16 = 0x00020000,
keMALWrMaxBurst32 = 0x00030000,
/* 405EX-specific STA bits */
keSTARun = 0x8000,
keSTADirectRd = 0x1000,
keSTADirectWr = 0x0800,
keSTAIndirAddr = 0x2000,
keSTAIndirRd = 0x3000,
keSTAIndirWr = 0x2800
};
typedef struct GPIORegisters { typedef struct GPIORegisters {
uint32_t OR; uint32_t OR;
@@ -155,3 +182,10 @@ typedef struct GPIORegisters {
enum { GPIOAddress = 0xEF600800 }; enum { GPIOAddress = 0xEF600800 };
typedef struct RGMIIRegisters {
uint32_t FER;
uint32_t SSR;
} RGMIIRegisters;
enum { RGMIIAddress = 0xEF600B00 };

View File

@@ -36,6 +36,25 @@ enum {
EBC0_CFG = 0x23 EBC0_CFG = 0x23
}; };
/* MAL DCRs, have to be #defines */
#define MAL0_CFG 0x180
#define MAL0_ESR 0x181
#define MAL0_IER 0x182
#define MAL0_TXCASR 0x184
#define MAL0_TXCARR 0x185
#define MAL0_TXEOBISR 0x186
#define MAL0_TXDEIR 0x187
#define MAL0_RXCASR 0x190
#define MAL0_RXCARR 0x191
#define MAL0_RXEOBISR 0x192
#define MAL0_RXDEIR 0x193
#define MAL0_TXCTP0R 0x1A0
#define MAL0_TXCTP1R 0x1A1
#define MAL0_RXCTP0R 0x1C0
#define MAL0_RXCTP1R 0x1C1
#define MAL0_RCBS0 0x1E0
#define MAL0_RCBS1 0x1E1
/* Memory-mapped registers */ /* Memory-mapped registers */
typedef struct EthernetRegisters_GP { typedef struct EthernetRegisters_GP {
@@ -51,19 +70,28 @@ typedef struct EthernetRegisters_GP {
uint32_t VLANTPID; uint32_t VLANTPID;
uint32_t VLANTCI; uint32_t VLANTCI;
uint32_t pauseTimer; uint32_t pauseTimer;
uint32_t indivHash[4]; uint32_t g_indivHash[4]; /* EX non-IP multicast addr/mask */
uint32_t groupHash[4]; uint32_t g_groupHash[4];
uint32_t lastSrcLo; uint32_t lastSrcLo;
uint32_t lastSrcHi; uint32_t lastSrcHi;
uint32_t IPGap; uint32_t IPGap;
uint32_t STAcontrol; uint32_t STAcontrol;
uint32_t xmtReqThreshold; uint32_t xmtReqThreshold;
uint32_t rcvWatermark; uint32_t rcvWatermarks;
uint32_t bytesXmtd; uint32_t bytesXmtd;
uint32_t bytesRcvd; uint32_t bytesRcvd;
uint32_t e_unused2;
uint32_t e_revID;
uint32_t e_unused3[2];
uint32_t e_indivHash[8];
uint32_t e_groupHash[8];
uint32_t e_xmtPause;
} EthernetRegisters_GP; } EthernetRegisters_GP;
typedef struct EthernetRegisters_GP EthernetRegisters_EX;
enum { EMACAddress = 0xEF600800 }; enum { EMACAddress = 0xEF600800 };
enum { EMAC0GPAddress = 0xEF600800 };
enum { enum {
// Mode 0 bits // Mode 0 bits
@@ -75,12 +103,19 @@ enum {
// Mode 1 bits // Mode 1 bits
kEMACFullDuplex = 0x80000000, kEMACFullDuplex = 0x80000000,
kEMACDoFlowControl = 0x10000000,
kEMACIgnoreSQE = 0x01000000, kEMACIgnoreSQE = 0x01000000,
kEMAC100MBbps = 0x00400000, kEMAC100MBbps = 0x00400000,
kEMAC4KRxFIFO = 0x00300000, kEMAC4KRxFIFO = 0x00300000,
kEMAC2KTxFIFO = 0x00080000, kEMAC2KTxFIFO = 0x00080000,
kEMACTx0Multi = 0x00008000, kEMACTx0Multi = 0x00008000,
kEMACTxDependent= 0x00014000, kEMACTxDependent= 0x00014000,
kEMAC100Mbps = 0x00400000,
kgEMAC4KRxFIFO = 0x00300000,
kgEMAC2KTxFIFO = 0x00080000,
kgEMACTx0Multi = 0x00008000,
kgEMACTxDependent= 0x00014000,
// Tx mode bits // Tx mode bits
kEMACNewPacket0 = 0x80000000, kEMACNewPacket0 = 0x80000000,
@@ -98,6 +133,25 @@ enum {
kEMACHashRcv = 0x00200000, kEMACHashRcv = 0x00200000,
kEMACBrcastRcv = 0x00100000, kEMACBrcastRcv = 0x00100000,
kEMACMultcastRcv = 0x00080000, kEMACMultcastRcv = 0x00080000,
keEMACNonIPMultcast = 0x00040000,
keEMACRxFIFOAFMax = 7,
// EMAC_STACR bits
kgSTAComplete = 0x8000,
kSTAErr = 0x4000,
// Interrupt status bits
kEMACIOverrun = 0x02000000,
kEMACIPause = 0x01000000,
kEMACIBadPkt = 0x00800000,
kEMACIRuntPkt = 0x00400000,
kEMACIShortEvt= 0x00200000,
kEMACIAlignErr= 0x00100000,
kEMACIBadFCS = 0x00080000,
kEMACIOverSize= 0x00040000,
kEMACILLCRange= 0x00020000,
kEMACISQEErr = 0x00000080,
kEMACITxErr = 0x00000040,
// Buffer descriptor control bits // Buffer descriptor control bits
kMALTxReady = 0x8000, kMALTxReady = 0x8000,
@@ -108,6 +162,21 @@ enum {
kMALRxFirst = 0x0800, kMALRxFirst = 0x0800,
kMALInterrupt = 0x0400, kMALInterrupt = 0x0400,
kMALReset = 0x80000000,
kMALLowPriority = 0,
kMALMedLowPriority = 0x00400000,
kMALMedHiPriority = 0x00800000,
kMALHighPriority = 0x00C00000,
kMALLatency8 = 0x00040000,
kMALLockErr = 0x8000,
kMALCanBurst = 0x4000,
kMALLocksOPB = 0x80,
kMALLocksErrs = 0x2,
// MAL channel masks
kMALChannel0 = 0x80000000,
kMALChannel1 = 0x40000000,
// EMAC Tx descriptor bits sent // EMAC Tx descriptor bits sent
kEMACGenFCS = 0x200, kEMACGenFCS = 0x200,
kEMACGenPad = 0x100, kEMACGenPad = 0x100,