⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sk_g16.c

📁 Linux启动程序grub的源码分析与实现;
💻 C
📖 第 1 页 / 共 3 页
字号:
}int SK_probe1(struct nic *nic, short ioaddr1){    int i,j;                /* Counters */    int sk_addr_flag = 0;   /* SK ADDR correct? 1 - no, 0 - yes */    unsigned int rom_addr;  /* used to store RAM address used for POS_ADDR */    struct priv *p;         /* SK_G16 private structure */    if (SK_ADDR & 0x3fff || SK_ADDR < 0xa0000)    {       /*        * Now here we could use a routine which searches for a free        * place in the ram and set SK_ADDR if found. TODO.        */            printf("%s: SK_ADDR %#hX is not valid. Check configuration.\n",                    SK_NAME, SK_ADDR);            return -1;    }    rom_addr = SK_ADDR;    outb(SK_ROM_RAM_OFF, SK_POS2); /* Boot_ROM + RAM off */    outb(POS_ADDR, SK_POS3);       /* Set RAM address */    outb(SK_ROM_RAM_ON, SK_POS2);  /* RAM on, BOOT_ROM on */#ifdef	SK_DEBUG    SK_print_pos(nic, "POS registers after ROM, RAM config");#endif    board = (SK_RAM *) rom_addr;	PRINTF(("adr[0]: %hX, adr[1]: %hX, adr[2]: %hX\n",	board->rom[0], board->rom[2], board->rom[4]));    /* Read in station address */    for (i = 0, j = 0; i < ETH_ALEN; i++, j+=2)    {	*(nic->node_addr+i) = board->rom[j];    }    /* Check for manufacturer code */#ifdef	SK_DEBUG    if (!(*(nic->node_addr+0) == SK_MAC0 &&	  *(nic->node_addr+1) == SK_MAC1 &&	  *(nic->node_addr+2) == SK_MAC2) )    {        PRINTF(("## %s: We did not find SK_G16 at RAM location.\n",                SK_NAME));	return -1;                     /* NO SK_G16 found */    }#endif    p = nic->priv_data;    /* Initialize private structure */    p->ram = (struct SK_ram *) rom_addr; /* Set dual ported RAM addr */    p->tmdhead = &(p->ram)->tmde[0];     /* Set TMD head */    p->rmdhead = &(p->ram)->rmde[0];     /* Set RMD head */    printf("Schneider & Koch G16 at %#hX, mem at %#hX, HW addr: %!\n",	    (unsigned int) ioaddr, (unsigned int) p->ram, nic->node_addr);    /* Initialize buffer pointers */    for (i = 0; i < TMDNUM; i++)    {	p->tmdbufs[i] = p->ram->tmdbuf[i];    }    for (i = 0; i < RMDNUM; i++)    {	p->rmdbufs[i] = p->ram->rmdbuf[i];    }    i = 0;    if (!(i = SK_lance_init(nic, MODE_NORMAL)))  /* LANCE init OK? */    {#ifdef	SK_DEBUG        /*         * This debug block tries to stop LANCE,         * reinit LANCE with transmitter and receiver disabled,         * then stop again and reinit with NORMAL_MODE         */        printf("## %s: After lance init. CSR0: %#hX\n",               SK_NAME, SK_read_reg(CSR0));        SK_write_reg(CSR0, CSR0_STOP);        printf("## %s: LANCE stopped. CSR0: %#hX\n",               SK_NAME, SK_read_reg(CSR0));        SK_lance_init(nic, MODE_DTX | MODE_DRX);        printf("## %s: Reinit with DTX + DRX off. CSR0: %#hX\n",               SK_NAME, SK_read_reg(CSR0));        SK_write_reg(CSR0, CSR0_STOP);        printf("## %s: LANCE stopped. CSR0: %#hX\n",               SK_NAME, SK_read_reg(CSR0));        SK_lance_init(nic, MODE_NORMAL);        printf("## %s: LANCE back to normal mode. CSR0: %#hX\n",               SK_NAME, SK_read_reg(CSR0));        SK_print_pos(nic, "POS regs before returning OK");#endif	/* SK_DEBUG */    }    else /* LANCE init failed */    {	PRINTF(("## %s: LANCE init failed: CSR0: %#hX\n",               SK_NAME, SK_read_reg(CSR0)));	return -1;    }#ifdef	SK_DEBUG    SK_print_pos(nic, "End of SK_probe1");    SK_print_ram(nic);#endif    return 0;                            /* Initialization done */} /* End of SK_probe1() */static int SK_lance_init(struct nic *nic, unsigned short mode){    int i;    struct priv *p = (struct priv *) nic->priv_data;    struct tmd  *tmdp;    struct rmd  *rmdp;    PRINTF(("## %s: At beginning of LANCE init. CSR0: %#hX\n",           SK_NAME, SK_read_reg(CSR0)));    /* Reset LANCE */    SK_reset_board();    /* Initialize TMD's with start values */    p->tmdnum = 0;                   /* First descriptor for transmitting */    p->tmdlast = 0;                  /* First descriptor for reading stats */    for (i = 0; i < TMDNUM; i++)     /* Init all TMD's */    {	tmdp = p->tmdhead + i;	tmdp->u.buffer = (unsigned long) p->tmdbufs[i]; /* assign buffer */	/* Mark TMD as start and end of packet */	tmdp->u.s.status = TX_STP | TX_ENP;    }    /* Initialize RMD's with start values */    p->rmdnum = 0;                   /* First RMD which will be used */    for (i = 0; i < RMDNUM; i++)     /* Init all RMD's */    {	rmdp = p->rmdhead + i;	rmdp->u.buffer = (unsigned long) p->rmdbufs[i]; /* assign buffer */	/*         * LANCE must be owner at beginning so that he can fill in	 * receiving packets, set status and release RMD	 */	rmdp->u.s.status = RX_OWN;	rmdp->blen = -PKT_BUF_SZ;    /* Buffer Size in a two's complement */	rmdp->mlen = 0;              /* init message length */    }    /* Fill LANCE Initialize Block */    (p->ram)->ib.mode = mode;        /* Set operation mode */    for (i = 0; i < ETH_ALEN; i++)   /* Set physical address */    {	(p->ram)->ib.paddr[i] = *(nic->node_addr+i);    }    for (i = 0; i < 8; i++)          /* Set multicast, logical address */    {	(p->ram)->ib.laddr[i] = 0;   /* We do not use logical addressing */    }    /* Set ring descriptor pointers and set number of descriptors */    (p->ram)->ib.rdrp = (int)  p->rmdhead | RMDNUMMASK;    (p->ram)->ib.tdrp = (int)  p->tmdhead | TMDNUMMASK;    /* Prepare LANCE Control and Status Registers */    SK_write_reg(CSR3, CSR3_ACON);   /* Ale Control !!!THIS MUST BE SET!!!! */    /*     * LANCE addresses the RAM from 0x0000 to 0x3fbf and has no access to     * PC Memory locations.     *     * In structure SK_ram is defined that the first thing in ram     * is the initialization block. So his address is for LANCE always     * 0x0000     *     * CSR1 contains low order bits 15:0 of initialization block address     * CSR2 is built of:     *    7:0  High order bits 23:16 of initialization block address     *   15:8  reserved, must be 0     */    /* Set initialization block address (must be on word boundary) */    SK_write_reg(CSR1, 0);          /* Set low order bits 15:0 */    SK_write_reg(CSR2, 0);          /* Set high order bits 23:16 */    PRINTF(("## %s: After setting CSR1-3. CSR0: %#hX\n",           SK_NAME, SK_read_reg(CSR0)));    /* Initialize LANCE */    /*     * INIT = Initialize, when set, causes the LANCE to begin the     * initialization procedure and access the Init Block.     */    SK_write_reg(CSR0, CSR0_INIT);    /* Wait until LANCE finished initialization */    SK_set_RAP(CSR0);              /* Register Address Pointer to CSR0 */    for (i = 0; (i < 100) && !(SK_rread_reg() & CSR0_IDON); i++)	; /* Wait until init done or go ahead if problems (i>=100) */    if (i >= 100) /* Something is wrong ! */    {	printf("%s: can't init am7990, status: %#hX "	       "init_block: %#hX\n",		SK_NAME, (int) SK_read_reg(CSR0),		(unsigned int) &(p->ram)->ib);#ifdef	SK_DEBUG	SK_print_pos(nic, "LANCE INIT failed");#endif	return -1;                 /* LANCE init failed */    }    PRINTF(("## %s: init done after %d ticks\n", SK_NAME, i));    /* Clear Initialize done, enable Interrupts, start LANCE */    SK_write_reg(CSR0, CSR0_IDON | CSR0_INEA | CSR0_STRT);    PRINTF(("## %s: LANCE started. CSR0: %#hX\n", SK_NAME,            SK_read_reg(CSR0)));    return 0;                      /* LANCE is up and running */} /* End of SK_lance_init() *//* LANCE access functions * * ! CSR1-3 can only be accessed when in CSR0 the STOP bit is set ! */static void SK_reset_board(void){    int i;	PRINTF(("## %s: At beginning of SK_reset_board.\n", SK_NAME));    SK_PORT = 0x00;           /* Reset active */    for (i = 0; i < 10 ; i++) /* Delay min 5ms */	;    SK_PORT = SK_RESET;       /* Set back to normal operation */} /* End of SK_reset_board() */static void SK_set_RAP(int reg_number){    SK_IOREG = reg_number;    SK_PORT  = SK_RESET | SK_RAP | SK_WREG;    SK_IOCOM = SK_DOIO;    while (SK_PORT & SK_IORUN)	;} /* End of SK_set_RAP() */static int SK_read_reg(int reg_number){    SK_set_RAP(reg_number);    SK_PORT  = SK_RESET | SK_RDATA | SK_RREG;    SK_IOCOM = SK_DOIO;    while (SK_PORT & SK_IORUN)	;    return (SK_IOREG);} /* End of SK_read_reg() */static int SK_rread_reg(void){    SK_PORT  = SK_RESET | SK_RDATA | SK_RREG;    SK_IOCOM = SK_DOIO;    while (SK_PORT & SK_IORUN)	;    return (SK_IOREG);} /* End of SK_rread_reg() */static void SK_write_reg(int reg_number, int value){    SK_set_RAP(reg_number);    SK_IOREG = value;    SK_PORT  = SK_RESET | SK_RDATA | SK_WREG;    SK_IOCOM = SK_DOIO;    while (SK_PORT & SK_IORUN)	;} /* End of SK_write_reg *//* * Debugging functions * ------------------- */#ifdef	SK_DEBUGstatic void SK_print_pos(struct nic *nic, char *text){    unsigned char pos0 = inb(SK_POS0),		  pos1 = inb(SK_POS1),		  pos2 = inb(SK_POS2),		  pos3 = inb(SK_POS3),		  pos4 = inb(SK_POS4);    printf("## %s: %s.\n"           "##   pos0=%#hX pos1=%#hX pos2=%#hX pos3=%#hX pos4=%#hX\n",           SK_NAME, text, pos0, pos1, pos2, (pos3<<14), pos4);} /* End of SK_print_pos() */static void SK_print_ram(struct nic *nic){    int i;    struct priv *p = (struct priv *) nic->priv_data;    printf("## %s: RAM Details.\n"           "##   RAM at %#hX tmdhead: %#hX rmdhead: %#hX initblock: %#hX\n",           SK_NAME,           (unsigned int) p->ram,           (unsigned int) p->tmdhead,           (unsigned int) p->rmdhead,           (unsigned int) &(p->ram)->ib);    printf("##   ");    for(i = 0; i < TMDNUM; i++)    {           if (!(i % 3)) /* Every third line do a newline */           {               printf("\n##   ");           }        printf("tmdbufs%d: %#hX ", (i+1), (int) p->tmdbufs[i]);    }    printf("##   ");    for(i = 0; i < RMDNUM; i++)    {         if (!(i % 3)) /* Every third line do a newline */           {               printf("\n##   ");           }        printf("rmdbufs%d: %#hX ", (i+1), (int) p->rmdbufs[i]);    }    putchar('\n');} /* End of SK_print_ram() */#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -