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

📄 sb_utils.c

📁 一个很好的嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Return the current speed the SB is running at. */uint32_tsb_clock(void){    uint32_t corecap;    uint32_t clockcontrol_n, clockcontrol_sb;    uint32_t pll_type;    corecap = READCSR(R_CORECAPABILITIES);    switch (G_CORECAP_PL(corecap)) {	case K_PL_4710:  pll_type = PLL_N3M;  break;	case K_PL_4704:  pll_type = PLL_N4M;  break;	case K_PL_5365:  pll_type = PLL_TYPE3; break;	default:         pll_type = PLL_NONE; break;	}    clockcontrol_n = READCSR(R_CLOCKCONTROLN);    clockcontrol_sb = READCSR(R_CLOCKCONTROLSB);    return sb_clock_rate(pll_type, clockcontrol_n, clockcontrol_sb);}/* Return the current speed the CPU is running at. */uint32_tsb_cpu_clock(void){    uint32_t corecap;    uint32_t clockcontrol_n, clockcontrol_m;    uint32_t pll_type;    corecap = READCSR(R_CORECAPABILITIES);    clockcontrol_n = READCSR(R_CLOCKCONTROLN);    switch (G_CORECAP_PL(corecap)) {	case K_PL_4710:	    pll_type = PLL_N3M;	    clockcontrol_m = READCSR(R_CLOCKCONTROLM0);	    break;	case K_PL_4704:	    pll_type = PLL_N4M;	    clockcontrol_m = READCSR(R_CLOCKCONTROLM3);	    break;	case K_PL_5365:	    pll_type = PLL_TYPE3;	    return 200000000;     /* until PLL_TYPE3 is documented */	    break;	default:	    pll_type = PLL_NONE;	    clockcontrol_m = 0;	    break;	}    return sb_clock_rate(pll_type, clockcontrol_n, clockcontrol_m);}/* Set the current speed of the CPU to the desired rate (as closely as   possible).  XXX Currently, cannot change CPU:SB ratio. */intsb_setclock(uint32_t cpu, uint32_t pci){    typedef struct {	uint32_t mipsclock;	uint32_t sbclock;	uint16_t n;	uint32_t sb;           /* aka m0 */	uint32_t pci33;        /* aka m1 */	uint32_t m2;           /* aka mii/uart/mipsref */	uint32_t m3;           /* aka mips */	uint32_t ratio;        /* cpu:sb */	uint32_t ratio_parm;   /* for CP0 register 22, sel 3 (ClkSync) */    } n4m_table_t;    /* XXX 9:4 ratio parm was 0x012a0115.  Current value from BMIPS docs. */    static const n4m_table_t type2_table[] = {	{ 180000000,  80000000, 0x0403, 0x01010000, 0x01020300,	  0x01020600, 0x05000100, 0x94, 0x012a00a9 },	{ 180000000,  90000000, 0x0403, 0x01000100, 0x01020300,	  0x01000100, 0x05000100, 0x21, 0x0aaa0555 },	{ 200000000, 100000000, 0x0303, 0x01000000, 0x01000600,	  0x01000000, 0x05000000, 0x21, 0x0aaa0555 },	{ 211200000, 105600000, 0x0902, 0x01000200, 0x01030400,	  0x01000200, 0x05000200, 0x21, 0x0aaa0555 },	{ 220800000, 110400000, 0x1500, 0x01000200, 0x01030400,	  0x01000200, 0x05000200, 0x21, 0x0aaa0555 },	{ 230400000, 115200000, 0x0604, 0x01000200, 0x01020600,	  0x01000200, 0x05000200, 0x21, 0x0aaa0555 },	{ 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700,	  0x01020600, 0x05000100, 0x94, 0x012a00a9 },	{ 240000000, 120000000,	0x0803,	0x01000200, 0x01020600,		  0x01000200, 0x05000200, 0x21, 0x0aaa0555 },	{ 252000000, 126000000,	0x0504,	0x01000100, 0x01020500,	  0x01000100, 0x05000100, 0x21, 0x0aaa0555 },	{ 264000000, 132000000, 0x0903, 0x01000200, 0x01020700,	  0x01000200, 0x05000200, 0x21, 0x0aaa0555 },	{ 270000000, 120000000, 0x0703, 0x01010000, 0x01030400,	  0x01020600, 0x05000100, 0x94, 0x012a00a9 },	{ 276000000, 122666666, 0x1500, 0x01010000, 0x01030400,	  0x01020600, 0x05000100, 0x94, 0x012a00a9 },	{ 280000000, 140000000, 0x0503, 0x01000000, 0x01010600,	  0x01000000, 0x05000000, 0x21, 0x0aaa0555 },	{ 288000000, 128000000, 0x0604, 0x01010000, 0x01030400,	  0x01020600, 0x05000100, 0x94, 0x012a00a9 },	{ 288000000, 144000000, 0x0404, 0x01000000, 0x01010600,	  0x01000000, 0x05000000, 0x21, 0x0aaa0555 },	{ 300000000, 133333333, 0x0803, 0x01010000, 0x01020600,	  0x01020600, 0x05000100, 0x94, 0x012a00a9 },	{ 300000000, 150000000, 0x0803, 0x01000100, 0x01020600,	  0x01000100, 0x05000100, 0x21, 0x0aaa0555 }    };    static const n4m_table_t type4_table[] = {	{ 192000000,  96000000, 0x0702,	0x04020011, 0x11030011,	  0x04020011, 0x04020003, 0x21, 0x0aaa0555 },	{ 200000000, 100000000, 0x0009,	0x04020011, 0x11030011,	  0x04020011, 0x04020003, 0x21, 0x0aaa0555 },	{ 216000000, 108000000, 0x0211, 0x11020005, 0x11030303,	  0x11020005, 0x04000005, 0x21, 0x0aaa0555 },	{ 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005,	  0x11030305, 0x04000005, 0x94, 0x012a00a9 },	{ 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005,	  0x11020005, 0x04000005, 0x21, 0x0aaa0555 },	{ 240000000, 120000000,	0x0109,	0x11030002, 0x01050203,	  0x11030002, 0x04000003, 0x21, 0x0aaa0555 },	{ 252000000, 126000000,	0x0203,	0x04000005, 0x11050005,	  0x04000005, 0x04000002, 0x21, 0x0aaa0555 },	{ 264000000, 132000000, 0x0602, 0x04000005, 0x11050005,	  0x04000005, 0x04000002, 0x21, 0x0aaa0555 },	{ 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909,	  0x02000221, 0x04000003, 0x73, 0x254a14a9 },	{ 280000000, 120000000, 0x0209, 0x04000021, 0x01030303,	  0x02000221, 0x04000003, 0x73, 0x254a14a9 },	{ 288000000, 123428571, 0x0111, 0x04000021, 0x01030303,	  0x02000221, 0x04000003, 0x73, 0x254a14a9 },	{ 300000000, 120000000, 0x0009, 0x04000009, 0x01030203,	  0x02000902, 0x04000002, 0x52, 0x02520129 }    };    const n4m_table_t *clock_table;    uint clock_entries;    uint i;    uint32_t old_n;    uint32_t old_m0, old_m1, old_m2, old_m3;    uint32_t new_n;    uint32_t new_m0, new_m1, new_m2, new_m3;    uint32_t old_ratio, new_ratio;    uint32_t corecap;    uint32_t pll_type;    clock_table = NULL;  clock_entries = 0;   /* defaults */    corecap = READCSR(R_CORECAPABILITIES);    switch (G_CORECAP_PL(corecap)) {	case K_PL_4710:    /* XXX Does this ever occur for CHIPC parts? */	    pll_type = PLL_N3M;	    break;	case K_PL_4704:	    pll_type = PLL_N4M;	    clock_table = type2_table;	    clock_entries = sizeof(type2_table)/sizeof(n4m_table_t);	    break;	case K_PL_5365:	    pll_type = PLL_TYPE3;	    clock_table = NULL;	    return 200000000;     /* until PLL_TYPE3 is documented */	    break;	case 0:    /* XXX Fix for expanded field. */	    pll_type = PLL_TYPE4;	    clock_entries = sizeof(type4_table)/sizeof(n4m_table_t);	    break;	default:	    pll_type = PLL_NONE;	    break;	}    if (clock_table == NULL)	return 0;    /* Remember the current settings */    old_n = READCSR(R_CLOCKCONTROLN);    old_m0 = READCSR(R_CLOCKCONTROLM0);    old_m1 = READCSR(R_CLOCKCONTROLM1);    old_m2 = READCSR(R_CLOCKCONTROLM2);    old_m3 = READCSR(R_CLOCKCONTROLM3);    /* Match to deduce current cpu:sb ratio. */    old_ratio = 0;    for (i = 0; i < clock_entries; i++) {	if (old_n == clock_table[i].n	    && old_m0 == clock_table[i].sb && old_m1 == clock_table[i].pci33	    && old_m2 == clock_table[i].m2 && old_m3 == clock_table[i].m3) {	    old_ratio = clock_table[i].ratio;	    break;	    }	}    if (i == clock_entries) {	/* No match; look for the supported ratios. */	uint32_t mips_clk = sb_clock_rate(pll_type, old_n, old_m3);	uint32_t sb_clk = sb_clock_rate(pll_type, old_n, old_m0);	if (mips_clk == 2*sb_clk)	    old_ratio = 0x21;	else if (mips_clk == (sb_clk/4)*9)	    old_ratio = 0x94;	}    if (old_ratio == 0)	return 0;    /* Find a supported CPU clock setting no faster than the request. */    new_ratio = 0;    if (cpu < clock_table[0].mipsclock)	return 0;    for (i = clock_entries-1; i > 0; i--) {	if (cpu >= clock_table[i].mipsclock)	    break;	}    new_ratio = clock_table[i].ratio;    if (new_ratio != old_ratio)  /* For now, can't change ratios. */	return 0;    new_n = clock_table[i].n;    new_m0 = clock_table[i].sb;    new_m1 = clock_table[i].pci33;    new_m2 = clock_table[i].m2;    new_m3 = clock_table[i].m3;    if (old_n != new_n || old_m0 != new_m0 || old_m1 != new_m1	|| old_m2 != new_m2 || old_m3 != new_m3) {	/* Reset to install the new clocks if any changed. */	WRITECSR(R_CLOCKCONTROLN, new_n);	WRITECSR(R_CLOCKCONTROLM0, new_m0);	WRITECSR(R_CLOCKCONTROLM1, new_m1);	WRITECSR(R_CLOCKCONTROLM2, new_m2);	WRITECSR(R_CLOCKCONTROLM3, new_m3);	/* No return from chip reset. */	sb_chip_reset();	}    return 1;}/* Return the reference clock being supplied to the internal UART(s). */uint32_tsb_uart_clock(void){    uint32_t coreid, corecap, corectl;    uint32_t pll_type;    uint32_t cc_n, cc_m;    uint32_t clock, div;    coreid = READCSR(R_SBIDHIGH);    corecap = READCSR(R_CORECAPABILITIES);    switch (G_CORECAP_PL(corecap)) {	case K_PL_4710:  pll_type = PLL_N3M;   break;	case K_PL_4704:  pll_type = PLL_N4M;   break;	case K_PL_5365:  pll_type = PLL_TYPE3; break;	default:         pll_type = PLL_NONE;  break;	}    cc_n = READCSR(R_CLOCKCONTROLN);    if (pll_type == PLL_N3M) {	cc_m = READCSR(R_CLOCKCONTROLM2);        clock = sb_clock_rate(PLL_N3M, cc_n, cc_m);	div = 1;	}    else if (pll_type == PLL_TYPE3) {	/* 5365 type clock, not documented */	clock = 100000000;	div = 54;  /* clock/1843200 */	WRITECSR(R_UARTCLOCKDIV, div);	}          else {	if (G_SBID_RV(coreid) >= 3) {	    /* Internal backplane clock. */	    cc_m = READCSR(R_CLOCKCONTROLSB);	    clock = sb_clock_rate(PLL_N4M, cc_n, cc_m);	    div = clock/1843200;	    WRITECSR(R_UARTCLOCKDIV, div);	    }	else {	    /* Fixed internal backplane clock (4310, certain 4306). */	    clock = 88000000;	    div = 48;	    }	}    /* Clock source depends on strapping if UartClkOverride is unset. */    corectl = READCSR(R_CORECONTROL);    if ((G_SBID_RV(coreid) > 0) && ((corectl & M_CORECTL_CO) == 0)) {	if (G_CORECAP_CS(corecap) == K_CS_INTERNAL) {	    /* Internal divided backplane clock */	    clock /= div;            }	else {	    /* Assume external clock of 1.8432 MHz */	    clock = 1843200;	    }	}    return clock;}#endif /* SB_CHIPC_BASE *//* Backplane interrupt mapping. */#if defined(SB_MIPS_BASE)#define SB_CPU_BASE SB_MIPS_BASE#elif defined(SB_MIPS33_BASE)#define SB_CPU_BASE SB_MIPS33_BASE#else#error "Neither MIPS nor MIPS33 core defined"#endif#define READREG(b,x)     (*(uint32_t *)PHYS_TO_K1((b)+(x)))#define WRITEREG(b,x,v)  (*(uint32_t *)PHYS_TO_K1((b)+(x)) = (v))/* * Map the interrupt index for a core (SBTPSFlagNum0 in SBTPSFlag * register) into the (external) interrupt priorities (IPn) defined by * the MIPS architecture. * * The mapping of backplane interrupts to MIPS interrupts is * controlled by the CPU core's SBIPSFLAG register.  Note that any * interrupt source not mapped by the four SBIPSFLAG fields will be * directed to IP0 (level 2) and must additionally be enabled in the * SBINTVEC register.  */unsigned intsb_map_irq(unsigned int flagnum){    unsigned int ip;    uint32_t ipsflags, intvec;    ipsflags = READREG(SB_CPU_BASE, R_SBIPSFLAG);    if (flagnum == G_SBISF_F1(ipsflags))        ip = 1;    else if (flagnum == G_SBISF_F2(ipsflags))        ip = 2;    else if (flagnum == G_SBISF_F3(ipsflags))        ip = 3;    else if (flagnum == G_SBISF_F4(ipsflags))        ip = 4;    else {	intvec = READREG(SB_CPU_BASE, R_SBINTVEC);	intvec |= (1 << flagnum);	WRITEREG(SB_CPU_BASE, R_SBINTVEC, intvec);	ip = 0;	}    return ip;}

⌨️ 快捷键说明

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