diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-05-25 18:49:59 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-05-29 05:49:41 -0400 |
commit | 5cbc30737398b49f62ae8603129ce43ac7db1a41 (patch) | |
tree | 45d01a686865e6fd9c32b670f77af1e37db03008 /arch/sparc64/kernel/prom.c | |
parent | e01c0d6d8cf29c1c11725837b265598cab687952 (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.c | 148 |
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 | ||
32 | static struct device_node *allnodes; | 33 | static 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 | ||
1669 | static const char *get_mid_prop(void) | ||
1670 | { | ||
1671 | return (tlb_type == spitfire ? "upa-portid" : "portid"); | ||
1672 | } | ||
1673 | |||
1674 | struct 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 | |||
1699 | static 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 | |||
1668 | void __init prom_build_devicetree(void) | 1813 | void __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 | } |