aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/cputable.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/cputable.c')
-rw-r--r--arch/powerpc/kernel/cputable.c166
1 files changed, 105 insertions, 61 deletions
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 923f87aff20a..cd1b687544f3 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -35,6 +35,10 @@ const char *powerpc_base_platform;
35 * and ppc64 35 * and ppc64
36 */ 36 */
37#ifdef CONFIG_PPC32 37#ifdef CONFIG_PPC32
38extern void __setup_cpu_e200(unsigned long offset, struct cpu_spec* spec);
39extern void __setup_cpu_e500v1(unsigned long offset, struct cpu_spec* spec);
40extern void __setup_cpu_e500v2(unsigned long offset, struct cpu_spec* spec);
41extern void __setup_cpu_e500mc(unsigned long offset, struct cpu_spec* spec);
38extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec); 42extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
39extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec); 43extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
40extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec); 44extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec);
@@ -43,6 +47,7 @@ extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec);
43extern void __setup_cpu_440x5(unsigned long offset, struct cpu_spec* spec); 47extern void __setup_cpu_440x5(unsigned long offset, struct cpu_spec* spec);
44extern void __setup_cpu_460ex(unsigned long offset, struct cpu_spec* spec); 48extern void __setup_cpu_460ex(unsigned long offset, struct cpu_spec* spec);
45extern void __setup_cpu_460gt(unsigned long offset, struct cpu_spec* spec); 49extern void __setup_cpu_460gt(unsigned long offset, struct cpu_spec* spec);
50extern void __setup_cpu_460sx(unsigned long offset, struct cpu_spec *spec);
46extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); 51extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
47extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); 52extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
48extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); 53extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -726,6 +731,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
726 .cpu_setup = __setup_cpu_750, 731 .cpu_setup = __setup_cpu_750,
727 .machine_check = machine_check_generic, 732 .machine_check = machine_check_generic,
728 .platform = "ppc750", 733 .platform = "ppc750",
734 .oprofile_cpu_type = "ppc/750",
735 .oprofile_type = PPC_OPROFILE_G4,
729 }, 736 },
730 { /* 750FX rev 2.0 must disable HID0[DPM] */ 737 { /* 750FX rev 2.0 must disable HID0[DPM] */
731 .pvr_mask = 0xffffffff, 738 .pvr_mask = 0xffffffff,
@@ -741,6 +748,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
741 .cpu_setup = __setup_cpu_750, 748 .cpu_setup = __setup_cpu_750,
742 .machine_check = machine_check_generic, 749 .machine_check = machine_check_generic,
743 .platform = "ppc750", 750 .platform = "ppc750",
751 .oprofile_cpu_type = "ppc/750",
752 .oprofile_type = PPC_OPROFILE_G4,
744 }, 753 },
745 { /* 750FX (All revs except 2.0) */ 754 { /* 750FX (All revs except 2.0) */
746 .pvr_mask = 0xffff0000, 755 .pvr_mask = 0xffff0000,
@@ -756,6 +765,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
756 .cpu_setup = __setup_cpu_750fx, 765 .cpu_setup = __setup_cpu_750fx,
757 .machine_check = machine_check_generic, 766 .machine_check = machine_check_generic,
758 .platform = "ppc750", 767 .platform = "ppc750",
768 .oprofile_cpu_type = "ppc/750",
769 .oprofile_type = PPC_OPROFILE_G4,
759 }, 770 },
760 { /* 750GX */ 771 { /* 750GX */
761 .pvr_mask = 0xffff0000, 772 .pvr_mask = 0xffff0000,
@@ -771,6 +782,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
771 .cpu_setup = __setup_cpu_750fx, 782 .cpu_setup = __setup_cpu_750fx,
772 .machine_check = machine_check_generic, 783 .machine_check = machine_check_generic,
773 .platform = "ppc750", 784 .platform = "ppc750",
785 .oprofile_cpu_type = "ppc/750",
786 .oprofile_type = PPC_OPROFILE_G4,
774 }, 787 },
775 { /* 740/750 (L2CR bit need fixup for 740) */ 788 { /* 740/750 (L2CR bit need fixup for 740) */
776 .pvr_mask = 0xffff0000, 789 .pvr_mask = 0xffff0000,
@@ -1077,7 +1090,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1077 .cpu_name = "e300c2", 1090 .cpu_name = "e300c2",
1078 .cpu_features = CPU_FTRS_E300C2, 1091 .cpu_features = CPU_FTRS_E300C2,
1079 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, 1092 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
1080 .mmu_features = MMU_FTR_USE_HIGH_BATS, 1093 .mmu_features = MMU_FTR_USE_HIGH_BATS |
1094 MMU_FTR_NEED_DTLB_SW_LRU,
1081 .icache_bsize = 32, 1095 .icache_bsize = 32,
1082 .dcache_bsize = 32, 1096 .dcache_bsize = 32,
1083 .cpu_setup = __setup_cpu_603, 1097 .cpu_setup = __setup_cpu_603,
@@ -1090,7 +1104,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1090 .cpu_name = "e300c3", 1104 .cpu_name = "e300c3",
1091 .cpu_features = CPU_FTRS_E300, 1105 .cpu_features = CPU_FTRS_E300,
1092 .cpu_user_features = COMMON_USER, 1106 .cpu_user_features = COMMON_USER,
1093 .mmu_features = MMU_FTR_USE_HIGH_BATS, 1107 .mmu_features = MMU_FTR_USE_HIGH_BATS |
1108 MMU_FTR_NEED_DTLB_SW_LRU,
1094 .icache_bsize = 32, 1109 .icache_bsize = 32,
1095 .dcache_bsize = 32, 1110 .dcache_bsize = 32,
1096 .cpu_setup = __setup_cpu_603, 1111 .cpu_setup = __setup_cpu_603,
@@ -1105,7 +1120,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1105 .cpu_name = "e300c4", 1120 .cpu_name = "e300c4",
1106 .cpu_features = CPU_FTRS_E300, 1121 .cpu_features = CPU_FTRS_E300,
1107 .cpu_user_features = COMMON_USER, 1122 .cpu_user_features = COMMON_USER,
1108 .mmu_features = MMU_FTR_USE_HIGH_BATS, 1123 .mmu_features = MMU_FTR_USE_HIGH_BATS |
1124 MMU_FTR_NEED_DTLB_SW_LRU,
1109 .icache_bsize = 32, 1125 .icache_bsize = 32,
1110 .dcache_bsize = 32, 1126 .dcache_bsize = 32,
1111 .cpu_setup = __setup_cpu_603, 1127 .cpu_setup = __setup_cpu_603,
@@ -1634,6 +1650,19 @@ static struct cpu_spec __initdata cpu_specs[] = {
1634 .machine_check = machine_check_440A, 1650 .machine_check = machine_check_440A,
1635 .platform = "ppc440", 1651 .platform = "ppc440",
1636 }, 1652 },
1653 { /* 460SX */
1654 .pvr_mask = 0xffffff00,
1655 .pvr_value = 0x13541800,
1656 .cpu_name = "460SX",
1657 .cpu_features = CPU_FTRS_44X,
1658 .cpu_user_features = COMMON_USER_BOOKE,
1659 .mmu_features = MMU_FTR_TYPE_44x,
1660 .icache_bsize = 32,
1661 .dcache_bsize = 32,
1662 .cpu_setup = __setup_cpu_460sx,
1663 .machine_check = machine_check_440A,
1664 .platform = "ppc440",
1665 },
1637 { /* default match */ 1666 { /* default match */
1638 .pvr_mask = 0x00000000, 1667 .pvr_mask = 0x00000000,
1639 .pvr_value = 0x00000000, 1668 .pvr_value = 0x00000000,
@@ -1687,6 +1716,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1687 PPC_FEATURE_UNIFIED_CACHE, 1716 PPC_FEATURE_UNIFIED_CACHE,
1688 .mmu_features = MMU_FTR_TYPE_FSL_E, 1717 .mmu_features = MMU_FTR_TYPE_FSL_E,
1689 .dcache_bsize = 32, 1718 .dcache_bsize = 32,
1719 .cpu_setup = __setup_cpu_e200,
1690 .machine_check = machine_check_e200, 1720 .machine_check = machine_check_e200,
1691 .platform = "ppc5554", 1721 .platform = "ppc5554",
1692 } 1722 }
@@ -1706,6 +1736,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1706 .num_pmcs = 4, 1736 .num_pmcs = 4,
1707 .oprofile_cpu_type = "ppc/e500", 1737 .oprofile_cpu_type = "ppc/e500",
1708 .oprofile_type = PPC_OPROFILE_FSL_EMB, 1738 .oprofile_type = PPC_OPROFILE_FSL_EMB,
1739 .cpu_setup = __setup_cpu_e500v1,
1709 .machine_check = machine_check_e500, 1740 .machine_check = machine_check_e500,
1710 .platform = "ppc8540", 1741 .platform = "ppc8540",
1711 }, 1742 },
@@ -1724,6 +1755,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1724 .num_pmcs = 4, 1755 .num_pmcs = 4,
1725 .oprofile_cpu_type = "ppc/e500", 1756 .oprofile_cpu_type = "ppc/e500",
1726 .oprofile_type = PPC_OPROFILE_FSL_EMB, 1757 .oprofile_type = PPC_OPROFILE_FSL_EMB,
1758 .cpu_setup = __setup_cpu_e500v2,
1727 .machine_check = machine_check_e500, 1759 .machine_check = machine_check_e500,
1728 .platform = "ppc8548", 1760 .platform = "ppc8548",
1729 }, 1761 },
@@ -1733,12 +1765,14 @@ static struct cpu_spec __initdata cpu_specs[] = {
1733 .cpu_name = "e500mc", 1765 .cpu_name = "e500mc",
1734 .cpu_features = CPU_FTRS_E500MC, 1766 .cpu_features = CPU_FTRS_E500MC,
1735 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, 1767 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
1736 .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS, 1768 .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS |
1769 MMU_FTR_USE_TLBILX,
1737 .icache_bsize = 64, 1770 .icache_bsize = 64,
1738 .dcache_bsize = 64, 1771 .dcache_bsize = 64,
1739 .num_pmcs = 4, 1772 .num_pmcs = 4,
1740 .oprofile_cpu_type = "ppc/e500", /* xxx - galak, e500mc? */ 1773 .oprofile_cpu_type = "ppc/e500", /* xxx - galak, e500mc? */
1741 .oprofile_type = PPC_OPROFILE_FSL_EMB, 1774 .oprofile_type = PPC_OPROFILE_FSL_EMB,
1775 .cpu_setup = __setup_cpu_e500mc,
1742 .machine_check = machine_check_e500, 1776 .machine_check = machine_check_e500,
1743 .platform = "ppce500mc", 1777 .platform = "ppce500mc",
1744 }, 1778 },
@@ -1762,74 +1796,84 @@ static struct cpu_spec __initdata cpu_specs[] = {
1762 1796
1763static struct cpu_spec the_cpu_spec; 1797static struct cpu_spec the_cpu_spec;
1764 1798
1765struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr) 1799static void __init setup_cpu_spec(unsigned long offset, struct cpu_spec *s)
1766{ 1800{
1767 struct cpu_spec *s = cpu_specs;
1768 struct cpu_spec *t = &the_cpu_spec; 1801 struct cpu_spec *t = &the_cpu_spec;
1769 int i; 1802 struct cpu_spec old;
1770 1803
1771 s = PTRRELOC(s);
1772 t = PTRRELOC(t); 1804 t = PTRRELOC(t);
1805 old = *t;
1773 1806
1774 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) 1807 /* Copy everything, then do fixups */
1775 if ((pvr & s->pvr_mask) == s->pvr_value) { 1808 *t = *s;
1776 /* 1809
1777 * If we are overriding a previous value derived 1810 /*
1778 * from the real PVR with a new value obtained 1811 * If we are overriding a previous value derived from the real
1779 * using a logical PVR value, don't modify the 1812 * PVR with a new value obtained using a logical PVR value,
1780 * performance monitor fields. 1813 * don't modify the performance monitor fields.
1781 */ 1814 */
1782 if (t->num_pmcs && !s->num_pmcs) { 1815 if (old.num_pmcs && !s->num_pmcs) {
1783 t->cpu_name = s->cpu_name; 1816 t->num_pmcs = old.num_pmcs;
1784 t->cpu_features = s->cpu_features; 1817 t->pmc_type = old.pmc_type;
1785 t->cpu_user_features = s->cpu_user_features; 1818 t->oprofile_type = old.oprofile_type;
1786 t->icache_bsize = s->icache_bsize; 1819 t->oprofile_mmcra_sihv = old.oprofile_mmcra_sihv;
1787 t->dcache_bsize = s->dcache_bsize; 1820 t->oprofile_mmcra_sipr = old.oprofile_mmcra_sipr;
1788 t->cpu_setup = s->cpu_setup; 1821 t->oprofile_mmcra_clear = old.oprofile_mmcra_clear;
1789 t->cpu_restore = s->cpu_restore; 1822
1790 t->platform = s->platform; 1823 /*
1791 /* 1824 * If we have passed through this logic once before and
1792 * If we have passed through this logic once 1825 * have pulled the default case because the real PVR was
1793 * before and have pulled the default case 1826 * not found inside cpu_specs[], then we are possibly
1794 * because the real PVR was not found inside 1827 * running in compatibility mode. In that case, let the
1795 * cpu_specs[], then we are possibly running in 1828 * oprofiler know which set of compatibility counters to
1796 * compatibility mode. In that case, let the 1829 * pull from by making sure the oprofile_cpu_type string
1797 * oprofiler know which set of compatibility 1830 * is set to that of compatibility mode. If the
1798 * counters to pull from by making sure the 1831 * oprofile_cpu_type already has a value, then we are
1799 * oprofile_cpu_type string is set to that of 1832 * possibly overriding a real PVR with a logical one,
1800 * compatibility mode. If the oprofile_cpu_type 1833 * and, in that case, keep the current value for
1801 * already has a value, then we are possibly 1834 * oprofile_cpu_type.
1802 * overriding a real PVR with a logical one, and, 1835 */
1803 * in that case, keep the current value for 1836 if (old.oprofile_cpu_type == NULL)
1804 * oprofile_cpu_type. 1837 t->oprofile_cpu_type = s->oprofile_cpu_type;
1805 */ 1838 }
1806 if (t->oprofile_cpu_type == NULL)
1807 t->oprofile_cpu_type = s->oprofile_cpu_type;
1808 } else
1809 *t = *s;
1810 *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
1811 1839
1812 /* 1840 *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
1813 * Set the base platform string once; assumes 1841
1814 * we're called with real pvr first. 1842 /*
1815 */ 1843 * Set the base platform string once; assumes
1816 if (*PTRRELOC(&powerpc_base_platform) == NULL) 1844 * we're called with real pvr first.
1817 *PTRRELOC(&powerpc_base_platform) = t->platform; 1845 */
1846 if (*PTRRELOC(&powerpc_base_platform) == NULL)
1847 *PTRRELOC(&powerpc_base_platform) = t->platform;
1818 1848
1819#if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE) 1849#if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE)
1820 /* ppc64 and booke expect identify_cpu to also call 1850 /* ppc64 and booke expect identify_cpu to also call setup_cpu for
1821 * setup_cpu for that processor. I will consolidate 1851 * that processor. I will consolidate that at a later time, for now,
1822 * that at a later time, for now, just use #ifdef. 1852 * just use #ifdef. We also don't need to PTRRELOC the function
1823 * we also don't need to PTRRELOC the function pointer 1853 * pointer on ppc64 and booke as we are running at 0 in real mode
1824 * on ppc64 and booke as we are running at 0 in real 1854 * on ppc64 and reloc_offset is always 0 on booke.
1825 * mode on ppc64 and reloc_offset is always 0 on booke. 1855 */
1826 */ 1856 if (s->cpu_setup) {
1827 if (s->cpu_setup) { 1857 s->cpu_setup(offset, s);
1828 s->cpu_setup(offset, s); 1858 }
1829 }
1830#endif /* CONFIG_PPC64 || CONFIG_BOOKE */ 1859#endif /* CONFIG_PPC64 || CONFIG_BOOKE */
1860}
1861
1862struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr)
1863{
1864 struct cpu_spec *s = cpu_specs;
1865 int i;
1866
1867 s = PTRRELOC(s);
1868
1869 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) {
1870 if ((pvr & s->pvr_mask) == s->pvr_value) {
1871 setup_cpu_spec(offset, s);
1831 return s; 1872 return s;
1832 } 1873 }
1874 }
1875
1833 BUG(); 1876 BUG();
1877
1834 return NULL; 1878 return NULL;
1835} 1879}