📄 embed_config.c
字号:
/* Board specific functions for those embedded 8xx boards that do * not have boot monitor support for board information. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */#include <linux/types.h>#include <linux/string.h>#include <asm/reg.h>#ifdef CONFIG_8xx#include <asm/mpc8xx.h>#endif#ifdef CONFIG_8260#include <asm/mpc8260.h>#include <asm/immap_cpm2.h>#endif#ifdef CONFIG_40x#include <asm/io.h>#endif#ifdef CONFIG_XILINX_VIRTEX#include <platforms/4xx/xparameters/xparameters.h>#endifextern unsigned long timebase_period_ns;/* For those boards that don't provide one.*/#if !defined(CONFIG_MBX)static bd_t bdinfo;#endif/* IIC functions. * These are just the basic master read/write operations so we can * examine serial EEPROM. */extern void iic_read(uint devaddr, u_char *buf, uint offset, uint count);/* Supply a default Ethernet address for those eval boards that don't * ship with one. This is an address from the MBX board I have, so * it is unlikely you will find it on your network. */static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };#if defined(CONFIG_MBX)/* The MBX hands us a pretty much ready to go board descriptor. This * is where the idea started in the first place. */voidembed_config(bd_t **bdp){ u_char *mp; u_char eebuf[128]; int i = 8; bd_t *bd; bd = *bdp; /* Read the first 128 bytes of the EEPROM. There is more, * but this is all we need. */ iic_read(0xa4, eebuf, 0, 128); /* All we are looking for is the Ethernet MAC address. The * first 8 bytes are 'MOTOROLA', so check for part of that. * Next, the VPD describes a MAC 'packet' as being of type 08 * and size 06. So we look for that and the MAC must follow. * If there are more than one, we still only care about the first. * If it's there, assume we have a valid MAC address. If not, * grab our default one. */ if ((*(uint *)eebuf) == 0x4d4f544f) { while (i < 127 && !(eebuf[i] == 0x08 && eebuf[i + 1] == 0x06)) i += eebuf[i + 1] + 2; /* skip this packet */ if (i == 127) /* Couldn't find. */ mp = (u_char *)def_enet_addr; else mp = &eebuf[i + 2]; } else mp = (u_char *)def_enet_addr; for (i=0; i<6; i++) bd->bi_enetaddr[i] = *mp++; /* The boot rom passes these to us in MHz. Linux now expects * them to be in Hz. */ bd->bi_intfreq *= 1000000; bd->bi_busfreq *= 1000000; /* Stuff a baud rate here as well. */ bd->bi_baudrate = 9600;}#endif /* CONFIG_MBX */#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || \ defined(CONFIG_RPX8260) || defined(CONFIG_EP405)/* Helper functions for Embedded Planet boards.*//* Because I didn't find anything that would do this.......*/u_charaschex_to_byte(u_char *cp){ u_char byte, c; c = *cp++; if ((c >= 'A') && (c <= 'F')) { c -= 'A'; c += 10; } else if ((c >= 'a') && (c <= 'f')) { c -= 'a'; c += 10; } else c -= '0'; byte = c * 16; c = *cp; if ((c >= 'A') && (c <= 'F')) { c -= 'A'; c += 10; } else if ((c >= 'a') && (c <= 'f')) { c -= 'a'; c += 10; } else c -= '0'; byte += c; return(byte);}static voidrpx_eth(bd_t *bd, u_char *cp){ int i; for (i=0; i<6; i++) { bd->bi_enetaddr[i] = aschex_to_byte(cp); cp += 2; }}#ifdef CONFIG_RPX8260static uintrpx_baseten(u_char *cp){ uint retval; retval = 0; while (*cp != '\n') { retval *= 10; retval += (*cp) - '0'; cp++; } return(retval);}#endif#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)static voidrpx_brate(bd_t *bd, u_char *cp){ uint rate; rate = 0; while (*cp != '\n') { rate *= 10; rate += (*cp) - '0'; cp++; } bd->bi_baudrate = rate * 100;}static voidrpx_cpuspeed(bd_t *bd, u_char *cp){ uint num, den; num = den = 0; while (*cp != '\n') { num *= 10; num += (*cp) - '0'; cp++; if (*cp == '/') { cp++; den = (*cp) - '0'; break; } } /* I don't know why the RPX just can't state the actual * CPU speed..... */ if (den) { num /= den; num *= den; } bd->bi_intfreq = bd->bi_busfreq = num * 1000000; /* The 8xx can only run a maximum 50 MHz bus speed (until * Motorola changes this :-). Greater than 50 MHz parts * run internal/2 for bus speed. */ if (num > 50) bd->bi_busfreq /= 2;}#endif#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_EP405)static voidrpx_memsize(bd_t *bd, u_char *cp){ uint size; size = 0; while (*cp != '\n') { size *= 10; size += (*cp) - '0'; cp++; } bd->bi_memsize = size * 1024 * 1024;}#endif /* LITE || CLASSIC || EP405 */#if defined(CONFIG_EP405)static voidrpx_nvramsize(bd_t *bd, u_char *cp){ uint size; size = 0; while (*cp != '\n') { size *= 10; size += (*cp) - '0'; cp++; } bd->bi_nvramsize = size * 1024;}#endif /* CONFIG_EP405 */#endif /* Embedded Planet boards */#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)/* Read the EEPROM on the RPX-Lite board.*/voidembed_config(bd_t **bdp){ u_char eebuf[256], *cp; bd_t *bd; /* Read the first 256 bytes of the EEPROM. I think this * is really all there is, and I hope if it gets bigger the * info we want is still up front. */ bd = &bdinfo; *bdp = bd;#if 1 iic_read(0xa8, eebuf, 0, 128); iic_read(0xa8, &eebuf[128], 128, 128); /* We look for two things, the Ethernet address and the * serial baud rate. The records are separated by * newlines. */ cp = eebuf; for (;;) { if (*cp == 'E') { cp++; if (*cp == 'A') { cp += 2; rpx_eth(bd, cp); } } if (*cp == 'S') { cp++; if (*cp == 'B') { cp += 2; rpx_brate(bd, cp); } } if (*cp == 'D') { cp++; if (*cp == '1') { cp += 2; rpx_memsize(bd, cp); } } if (*cp == 'H') { cp++; if (*cp == 'Z') { cp += 2; rpx_cpuspeed(bd, cp); } } /* Scan to the end of the record. */ while ((*cp != '\n') && (*cp != 0xff)) cp++; /* If the next character is a 0 or ff, we are done. */ cp++; if ((*cp == 0) || (*cp == 0xff)) break; } bd->bi_memstart = 0;#else /* For boards without initialized EEPROM. */ bd->bi_memstart = 0; bd->bi_memsize = (8 * 1024 * 1024); bd->bi_intfreq = 48000000; bd->bi_busfreq = 48000000; bd->bi_baudrate = 9600;#endif}#endif /* RPXLITE || RPXCLASSIC */#ifdef CONFIG_BSEIP/* Build a board information structure for the BSE ip-Engine. * There is more to come since we will add some environment * variables and a function to read them. */voidembed_config(bd_t **bdp){ u_char *cp; int i; bd_t *bd; bd = &bdinfo; *bdp = bd; /* Baud rate and processor speed will eventually come * from the environment variables. */ bd->bi_baudrate = 9600; /* Get the Ethernet station address from the Flash ROM. */ cp = (u_char *)0xfe003ffa; for (i=0; i<6; i++) { bd->bi_enetaddr[i] = *cp++; } /* The rest of this should come from the environment as well. */ bd->bi_memstart = 0; bd->bi_memsize = (16 * 1024 * 1024); bd->bi_intfreq = 48000000; bd->bi_busfreq = 48000000;}#endif /* BSEIP */#ifdef CONFIG_FADS/* Build a board information structure for the FADS. */voidembed_config(bd_t **bdp){ u_char *cp; int i; bd_t *bd; bd = &bdinfo; *bdp = bd; /* Just fill in some known values. */ bd->bi_baudrate = 9600; /* Use default enet. */ cp = (u_char *)def_enet_addr; for (i=0; i<6; i++) { bd->bi_enetaddr[i] = *cp++; } bd->bi_memstart = 0; bd->bi_memsize = (8 * 1024 * 1024); bd->bi_intfreq = 40000000; bd->bi_busfreq = 40000000;}#endif /* FADS */#ifdef CONFIG_8260/* Compute 8260 clock values if the rom doesn't provide them. */static unsigned char bus2core_8260[] = {/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2, 6, 5, 13, 2, 14, 4, 15, 2, 3, 11, 8, 10, 16, 12, 7, 2,};static voidclk_8260(bd_t *bd){ uint scmr, vco_out, clkin; uint plldf, pllmf, corecnf; volatile cpm2_map_t *ip; ip = (cpm2_map_t *)CPM_MAP_ADDR; scmr = ip->im_clkrst.car_scmr; /* The clkin is always bus frequency. */ clkin = bd->bi_busfreq; /* Collect the bits from the scmr. */ plldf = (scmr >> 12) & 1; pllmf = scmr & 0xfff; corecnf = (scmr >> 24) &0x1f; /* This is arithmetic from the 8260 manual. */ vco_out = clkin / (plldf + 1); vco_out *= 2 * (pllmf + 1); bd->bi_vco = vco_out; /* Save for later */ bd->bi_cpmfreq = vco_out / 2; /* CPM Freq, in MHz */ bd->bi_intfreq = bd->bi_busfreq * bus2core_8260[corecnf] / 2; /* Set Baud rate divisor. The power up default is divide by 16, * but we set it again here in case it was changed. */ ip->im_clkrst.car_sccr = 1; /* DIV 16 BRG */ bd->bi_brgfreq = vco_out / 16;}static unsigned char bus2core_8280[] = {/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2, 6, 5, 13, 2, 14, 2, 15, 2, 3, 2, 2, 2, 16, 2, 2, 2,};static voidclk_8280(bd_t *bd){ uint scmr, main_clk, clkin; uint pllmf, corecnf; volatile cpm2_map_t *ip; ip = (cpm2_map_t *)CPM_MAP_ADDR; scmr = ip->im_clkrst.car_scmr; /* The clkin is always bus frequency. */ clkin = bd->bi_busfreq;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -