aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/prom.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-05-25 18:49:59 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-05-29 05:49:41 -0400
commit5cbc30737398b49f62ae8603129ce43ac7db1a41 (patch)
tree45d01a686865e6fd9c32b670f77af1e37db03008 /arch/sparc64/kernel/prom.c
parente01c0d6d8cf29c1c11725837b265598cab687952 (diff)
[SPARC64]: Use machine description and OBP properly for cpu probing.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/prom.c')
-rw-r--r--arch/sparc64/kernel/prom.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index 02830e4671f5..dad4b3ba705f 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -28,6 +28,7 @@
28#include <asm/irq.h> 28#include <asm/irq.h>
29#include <asm/asi.h> 29#include <asm/asi.h>
30#include <asm/upa.h> 30#include <asm/upa.h>
31#include <asm/smp.h>
31 32
32static struct device_node *allnodes; 33static struct device_node *allnodes;
33 34
@@ -1665,6 +1666,150 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl
1665 return ret; 1666 return ret;
1666} 1667}
1667 1668
1669static const char *get_mid_prop(void)
1670{
1671 return (tlb_type == spitfire ? "upa-portid" : "portid");
1672}
1673
1674struct device_node *of_find_node_by_cpuid(int cpuid)
1675{
1676 struct device_node *dp;
1677 const char *mid_prop = get_mid_prop();
1678
1679 for_each_node_by_type(dp, "cpu") {
1680 int id = of_getintprop_default(dp, mid_prop, -1);
1681 const char *this_mid_prop = mid_prop;
1682
1683 if (id < 0) {
1684 this_mid_prop = "cpuid";
1685 id = of_getintprop_default(dp, this_mid_prop, -1);
1686 }
1687
1688 if (id < 0) {
1689 prom_printf("OF: Serious problem, cpu lacks "
1690 "%s property", this_mid_prop);
1691 prom_halt();
1692 }
1693 if (cpuid == id)
1694 return dp;
1695 }
1696 return NULL;
1697}
1698
1699static void __init of_fill_in_cpu_data(void)
1700{
1701 struct device_node *dp;
1702 const char *mid_prop = get_mid_prop();
1703
1704 ncpus_probed = 0;
1705 for_each_node_by_type(dp, "cpu") {
1706 int cpuid = of_getintprop_default(dp, mid_prop, -1);
1707 const char *this_mid_prop = mid_prop;
1708 struct device_node *portid_parent;
1709 int portid = -1;
1710
1711 portid_parent = NULL;
1712 if (cpuid < 0) {
1713 this_mid_prop = "cpuid";
1714 cpuid = of_getintprop_default(dp, this_mid_prop, -1);
1715 if (cpuid >= 0) {
1716 int limit = 2;
1717
1718 portid_parent = dp;
1719 while (limit--) {
1720 portid_parent = portid_parent->parent;
1721 if (!portid_parent)
1722 break;
1723 portid = of_getintprop_default(portid_parent,
1724 "portid", -1);
1725 if (portid >= 0)
1726 break;
1727 }
1728 }
1729 }
1730
1731 if (cpuid < 0) {
1732 prom_printf("OF: Serious problem, cpu lacks "
1733 "%s property", this_mid_prop);
1734 prom_halt();
1735 }
1736
1737 ncpus_probed++;
1738
1739#ifdef CONFIG_SMP
1740 if (cpuid >= NR_CPUS)
1741 continue;
1742#else
1743 /* On uniprocessor we only want the values for the
1744 * real physical cpu the kernel booted onto, however
1745 * cpu_data() only has one entry at index 0.
1746 */
1747 if (cpuid != real_hard_smp_processor_id())
1748 continue;
1749 cpuid = 0;
1750#endif
1751
1752 cpu_data(cpuid).clock_tick =
1753 of_getintprop_default(dp, "clock-frequency", 0);
1754
1755 if (portid_parent) {
1756 cpu_data(cpuid).dcache_size =
1757 of_getintprop_default(dp, "l1-dcache-size",
1758 16 * 1024);
1759 cpu_data(cpuid).dcache_line_size =
1760 of_getintprop_default(dp, "l1-dcache-line-size",
1761 32);
1762 cpu_data(cpuid).icache_size =
1763 of_getintprop_default(dp, "l1-icache-size",
1764 8 * 1024);
1765 cpu_data(cpuid).icache_line_size =
1766 of_getintprop_default(dp, "l1-icache-line-size",
1767 32);
1768 cpu_data(cpuid).ecache_size =
1769 of_getintprop_default(dp, "l2-cache-size", 0);
1770 cpu_data(cpuid).ecache_line_size =
1771 of_getintprop_default(dp, "l2-cache-line-size", 0);
1772 if (!cpu_data(cpuid).ecache_size ||
1773 !cpu_data(cpuid).ecache_line_size) {
1774 cpu_data(cpuid).ecache_size =
1775 of_getintprop_default(portid_parent,
1776 "l2-cache-size",
1777 (4 * 1024 * 1024));
1778 cpu_data(cpuid).ecache_line_size =
1779 of_getintprop_default(portid_parent,
1780 "l2-cache-line-size", 64);
1781 }
1782
1783 cpu_data(cpuid).core_id = portid + 1;
1784 } else {
1785 cpu_data(cpuid).dcache_size =
1786 of_getintprop_default(dp, "dcache-size", 16 * 1024);
1787 cpu_data(cpuid).dcache_line_size =
1788 of_getintprop_default(dp, "dcache-line-size", 32);
1789
1790 cpu_data(cpuid).icache_size =
1791 of_getintprop_default(dp, "icache-size", 16 * 1024);
1792 cpu_data(cpuid).icache_line_size =
1793 of_getintprop_default(dp, "icache-line-size", 32);
1794
1795 cpu_data(cpuid).ecache_size =
1796 of_getintprop_default(dp, "ecache-size",
1797 (4 * 1024 * 1024));
1798 cpu_data(cpuid).ecache_line_size =
1799 of_getintprop_default(dp, "ecache-line-size", 64);
1800
1801 cpu_data(cpuid).core_id = 0;
1802 }
1803
1804#ifdef CONFIG_SMP
1805 cpu_set(cpuid, cpu_present_map);
1806 cpu_set(cpuid, phys_cpu_present_map);
1807#endif
1808 }
1809
1810 smp_fill_in_sib_core_maps();
1811}
1812
1668void __init prom_build_devicetree(void) 1813void __init prom_build_devicetree(void)
1669{ 1814{
1670 struct device_node **nextp; 1815 struct device_node **nextp;
@@ -1679,4 +1824,7 @@ void __init prom_build_devicetree(void)
1679 &nextp); 1824 &nextp);
1680 printk("PROM: Built device tree with %u bytes of memory.\n", 1825 printk("PROM: Built device tree with %u bytes of memory.\n",
1681 prom_early_allocated); 1826 prom_early_allocated);
1827
1828 if (tlb_type != hypervisor)
1829 of_fill_in_cpu_data();
1682} 1830}