#include <asm/irq.h>
#include <asm/asi.h>
#include <asm/upa.h>
+#include <asm/smp.h>
static struct device_node *allnodes;
* This should conform to both Sunfire/Wildfire server and Fusion
* desktop designs.
*/
-#define SYSIO_IMAP_SLOT0 0x2c04UL
-#define SYSIO_IMAP_SLOT1 0x2c0cUL
-#define SYSIO_IMAP_SLOT2 0x2c14UL
-#define SYSIO_IMAP_SLOT3 0x2c1cUL
-#define SYSIO_IMAP_SCSI 0x3004UL
-#define SYSIO_IMAP_ETH 0x300cUL
-#define SYSIO_IMAP_BPP 0x3014UL
-#define SYSIO_IMAP_AUDIO 0x301cUL
-#define SYSIO_IMAP_PFAIL 0x3024UL
-#define SYSIO_IMAP_KMS 0x302cUL
-#define SYSIO_IMAP_FLPY 0x3034UL
-#define SYSIO_IMAP_SHW 0x303cUL
-#define SYSIO_IMAP_KBD 0x3044UL
-#define SYSIO_IMAP_MS 0x304cUL
-#define SYSIO_IMAP_SER 0x3054UL
-#define SYSIO_IMAP_TIM0 0x3064UL
-#define SYSIO_IMAP_TIM1 0x306cUL
-#define SYSIO_IMAP_UE 0x3074UL
-#define SYSIO_IMAP_CE 0x307cUL
-#define SYSIO_IMAP_SBERR 0x3084UL
-#define SYSIO_IMAP_PMGMT 0x308cUL
-#define SYSIO_IMAP_GFX 0x3094UL
-#define SYSIO_IMAP_EUPA 0x309cUL
+#define SYSIO_IMAP_SLOT0 0x2c00UL
+#define SYSIO_IMAP_SLOT1 0x2c08UL
+#define SYSIO_IMAP_SLOT2 0x2c10UL
+#define SYSIO_IMAP_SLOT3 0x2c18UL
+#define SYSIO_IMAP_SCSI 0x3000UL
+#define SYSIO_IMAP_ETH 0x3008UL
+#define SYSIO_IMAP_BPP 0x3010UL
+#define SYSIO_IMAP_AUDIO 0x3018UL
+#define SYSIO_IMAP_PFAIL 0x3020UL
+#define SYSIO_IMAP_KMS 0x3028UL
+#define SYSIO_IMAP_FLPY 0x3030UL
+#define SYSIO_IMAP_SHW 0x3038UL
+#define SYSIO_IMAP_KBD 0x3040UL
+#define SYSIO_IMAP_MS 0x3048UL
+#define SYSIO_IMAP_SER 0x3050UL
+#define SYSIO_IMAP_TIM0 0x3060UL
+#define SYSIO_IMAP_TIM1 0x3068UL
+#define SYSIO_IMAP_UE 0x3070UL
+#define SYSIO_IMAP_CE 0x3078UL
+#define SYSIO_IMAP_SBERR 0x3080UL
+#define SYSIO_IMAP_PMGMT 0x3088UL
+#define SYSIO_IMAP_GFX 0x3090UL
+#define SYSIO_IMAP_EUPA 0x3098UL
#define bogon ((unsigned long) -1)
static unsigned long sysio_irq_offsets[] = {
* Interrupt Clear register pointer, SYSIO specific version.
*/
#define SYSIO_ICLR_UNUSED0 0x3400UL
-#define SYSIO_ICLR_SLOT0 0x340cUL
-#define SYSIO_ICLR_SLOT1 0x344cUL
-#define SYSIO_ICLR_SLOT2 0x348cUL
-#define SYSIO_ICLR_SLOT3 0x34ccUL
+#define SYSIO_ICLR_SLOT0 0x3408UL
+#define SYSIO_ICLR_SLOT1 0x3448UL
+#define SYSIO_ICLR_SLOT2 0x3488UL
+#define SYSIO_ICLR_SLOT3 0x34c8UL
static unsigned long sysio_imap_to_iclr(unsigned long imap)
{
unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0;
return ret;
}
+static const char *get_mid_prop(void)
+{
+ return (tlb_type == spitfire ? "upa-portid" : "portid");
+}
+
+struct device_node *of_find_node_by_cpuid(int cpuid)
+{
+ struct device_node *dp;
+ const char *mid_prop = get_mid_prop();
+
+ for_each_node_by_type(dp, "cpu") {
+ int id = of_getintprop_default(dp, mid_prop, -1);
+ const char *this_mid_prop = mid_prop;
+
+ if (id < 0) {
+ this_mid_prop = "cpuid";
+ id = of_getintprop_default(dp, this_mid_prop, -1);
+ }
+
+ if (id < 0) {
+ prom_printf("OF: Serious problem, cpu lacks "
+ "%s property", this_mid_prop);
+ prom_halt();
+ }
+ if (cpuid == id)
+ return dp;
+ }
+ return NULL;
+}
+
+static void __init of_fill_in_cpu_data(void)
+{
+ struct device_node *dp;
+ const char *mid_prop = get_mid_prop();
+
+ ncpus_probed = 0;
+ for_each_node_by_type(dp, "cpu") {
+ int cpuid = of_getintprop_default(dp, mid_prop, -1);
+ const char *this_mid_prop = mid_prop;
+ struct device_node *portid_parent;
+ int portid = -1;
+
+ portid_parent = NULL;
+ if (cpuid < 0) {
+ this_mid_prop = "cpuid";
+ cpuid = of_getintprop_default(dp, this_mid_prop, -1);
+ if (cpuid >= 0) {
+ int limit = 2;
+
+ portid_parent = dp;
+ while (limit--) {
+ portid_parent = portid_parent->parent;
+ if (!portid_parent)
+ break;
+ portid = of_getintprop_default(portid_parent,
+ "portid", -1);
+ if (portid >= 0)
+ break;
+ }
+ }
+ }
+
+ if (cpuid < 0) {
+ prom_printf("OF: Serious problem, cpu lacks "
+ "%s property", this_mid_prop);
+ prom_halt();
+ }
+
+ ncpus_probed++;
+
+#ifdef CONFIG_SMP
+ if (cpuid >= NR_CPUS)
+ continue;
+#else
+ /* On uniprocessor we only want the values for the
+ * real physical cpu the kernel booted onto, however
+ * cpu_data() only has one entry at index 0.
+ */
+ if (cpuid != real_hard_smp_processor_id())
+ continue;
+ cpuid = 0;
+#endif
+
+ cpu_data(cpuid).clock_tick =
+ of_getintprop_default(dp, "clock-frequency", 0);
+
+ if (portid_parent) {
+ cpu_data(cpuid).dcache_size =
+ of_getintprop_default(dp, "l1-dcache-size",
+ 16 * 1024);
+ cpu_data(cpuid).dcache_line_size =
+ of_getintprop_default(dp, "l1-dcache-line-size",
+ 32);
+ cpu_data(cpuid).icache_size =
+ of_getintprop_default(dp, "l1-icache-size",
+ 8 * 1024);
+ cpu_data(cpuid).icache_line_size =
+ of_getintprop_default(dp, "l1-icache-line-size",
+ 32);
+ cpu_data(cpuid).ecache_size =
+ of_getintprop_default(dp, "l2-cache-size", 0);
+ cpu_data(cpuid).ecache_line_size =
+ of_getintprop_default(dp, "l2-cache-line-size", 0);
+ if (!cpu_data(cpuid).ecache_size ||
+ !cpu_data(cpuid).ecache_line_size) {
+ cpu_data(cpuid).ecache_size =
+ of_getintprop_default(portid_parent,
+ "l2-cache-size",
+ (4 * 1024 * 1024));
+ cpu_data(cpuid).ecache_line_size =
+ of_getintprop_default(portid_parent,
+ "l2-cache-line-size", 64);
+ }
+
+ cpu_data(cpuid).core_id = portid + 1;
+ cpu_data(cpuid).proc_id = portid;
+#ifdef CONFIG_SMP
+ sparc64_multi_core = 1;
+#endif
+ } else {
+ cpu_data(cpuid).dcache_size =
+ of_getintprop_default(dp, "dcache-size", 16 * 1024);
+ cpu_data(cpuid).dcache_line_size =
+ of_getintprop_default(dp, "dcache-line-size", 32);
+
+ cpu_data(cpuid).icache_size =
+ of_getintprop_default(dp, "icache-size", 16 * 1024);
+ cpu_data(cpuid).icache_line_size =
+ of_getintprop_default(dp, "icache-line-size", 32);
+
+ cpu_data(cpuid).ecache_size =
+ of_getintprop_default(dp, "ecache-size",
+ (4 * 1024 * 1024));
+ cpu_data(cpuid).ecache_line_size =
+ of_getintprop_default(dp, "ecache-line-size", 64);
+
+ cpu_data(cpuid).core_id = 0;
+ cpu_data(cpuid).proc_id = -1;
+ }
+
+#ifdef CONFIG_SMP
+ cpu_set(cpuid, cpu_present_map);
+ cpu_set(cpuid, phys_cpu_present_map);
+#endif
+ }
+
+ smp_fill_in_sib_core_maps();
+}
+
void __init prom_build_devicetree(void)
{
struct device_node **nextp;
&nextp);
printk("PROM: Built device tree with %u bytes of memory.\n",
prom_early_allocated);
+
+ if (tlb_type != hypervisor)
+ of_fill_in_cpu_data();
}