/*++ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. Copyright (c) 1995-1998 Microsoft Corporation Module Name: Abstract: Routines for the SMC9000 ethernet controller used for the debug ethernet services. This file has been stripped of all but the detect and functionality Functions: Notes: --*/ #include #include #include #include #include #include #include "loadcepc.h" #include "smchw.h" #include "wdm.h" #include "ethernet.h" #include "..\inc\bootarg.h" BOOT_ARGS BootArgs; // The base address for the card static BYTE volatile *pbEthernetBase; #define ReadWord( wOffset ) _inpw((USHORT)(pbEthernetBase + wOffset)) #define WriteWord( wOffset, Value ) _outpw((USHORT)(pbEthernetBase + wOffset), (USHORT)Value) typedef struct _SMC_CONFIG { BYTE *pbIoBase; USHORT wIRQ; } SMC_CONFIG; SMC_CONFIG Configs[] = { { 0x300, 2 }, { 0x320, 10}, { 0x340, 11}, { 0x360, 3} }; #define NUM_ELEMENTS(a) (sizeof(a)/sizeof(a[0])) #define NUM_SMC_CONFIGS (NUM_ELEMENTS(Configs)) BOOL SMCDetect(BYTE **ppbBaseAddress, USHORT *pwIrq) { int i; USHORT BSR; USHORT MyAddr[3]; for (i=0;i> 8, MyAddr[1] & 0x00FF, MyAddr[1] >> 8, MyAddr[2] & 0x00FF, MyAddr[2] >> 8 ); return TRUE; } else { printf("SMCDetect: Invalid Ethernet address (check switch settings)\n"); return FALSE; } } } printf("SMCDetect: SMC board not found\n"); return FALSE; } // SMCDetect WORD hex_atoi(char * hexstr) { WORD wRet = 0; while (*hexstr) { wRet <<= 4; switch (*hexstr) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': wRet += (WORD)(*hexstr - '0'); break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': wRet += (WORD)(*hexstr - 'a'); wRet += 10; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': wRet += (WORD)(*hexstr - 'A'); wRet += 10; break; } hexstr++; } return wRet; } // hex_atoi // // Function to extract the debug ethernet adapter options from the command line // // Expect argstr = "/E::::" // // Return FALSE for failure // BOOL ParseEthernetOptions(char * argstr) { BOOL bRet; char * begin; char * end; char endch; char CardType; char * card; BYTE *pBase; USHORT wIRQ; int a; // argument counter 0 = CardType, 1 = I/O Base Address, 2 = IRQ bRet = FALSE; if (strlen(argstr) < 10) { // "/E:1:123:1" at minimum goto peo_exit; } end = argstr + 2; // // Extract the CardType, I/O Base address and IRQ from the command line // (and super secret EDBG debug zone mask) // for (a = 0; a < 4; a++) { begin = end; // // Colon delimited list // if (*begin != ':') { break; } begin++; // skip colon end = begin; while ((*end) && (*end != ':')) { end++; } if (begin == end) { break; } endch = *end; *end = 0; // temporarily zero terminate the option string switch (a) { case 0: // CardType CardType = *begin; break; case 1: // I/O base address pBase = (BYTE *)hex_atoi(begin); break; case 2: // IRQ wIRQ = hex_atoi(begin); break; case 3: // EDBG Debug zone mask (defined in oak\inc\ethdbg.h) BootArgs.dwEdbgDebugZone = (DWORD)hex_atoi(begin); BootArgs.dwEdbgDebugZone |= 0x10000; break; default: // error! goto peo_exit; } *end = endch; // un-zero-terminate if need be. } if (a < 3) { goto peo_exit; } switch (CardType) { case '0': // Search for a SMC9000 debug Ethernet card if (SMCDetect(&pBase, &wIRQ)) BootArgs.ucEdbgAdapterType = EDBG_ADAPTER_SMC9000; else { printf("Could not detect SMC9000 debug Ethernet card\n"); goto peo_exit; } card = "SMC9000"; break; case '1': BootArgs.ucEdbgAdapterType = EDBG_ADAPTER_NE2000; card = "NE2000"; break; default: goto peo_exit; } BootArgs.ucEdbgIRQ = wIRQ; // WARNING - must mask off high bits BootArgs.dwEdbgBaseAddr = (DWORD)pBase & 0xFFFF; BootArgs.ucLoaderFlags |= LDRFL_USE_EDBG; printf("Debug network card: %s at I/O port 0x%x, IRQ 0x%x\n", card, pBase, wIRQ); bRet = TRUE; peo_exit: return bRet; } // ParseEthernetOptions