1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Architecture specific OF callbacks. 4 */ 5 #include <linux/export.h> 6 #include <linux/io.h> 7 #include <linux/interrupt.h> 8 #include <linux/list.h> 9 #include <linux/of.h> 10 #include <linux/of_fdt.h> 11 #include <linux/of_address.h> 12 #include <linux/of_platform.h> 13 #include <linux/of_irq.h> 14 #include <linux/libfdt.h> 15 #include <linux/slab.h> 16 #include <linux/pci.h> 17 #include <linux/of_pci.h> 18 #include <linux/initrd.h> 19 20 #include <asm/irqdomain.h> 21 #include <asm/hpet.h> 22 #include <asm/apic.h> 23 #include <asm/io_apic.h> 24 #include <asm/pci_x86.h> 25 #include <asm/setup.h> 26 #include <asm/i8259.h> 27 #include <asm/numa.h> 28 #include <asm/prom.h> 29 30 __initdata u64 initial_dtb; 31 char __initdata cmd_line[COMMAND_LINE_SIZE]; 32 33 int __initdata of_ioapic; 34 35 void __init add_dtb(u64 data) 36 { 37 initial_dtb = data + offsetof(struct setup_data, data); 38 } 39 40 /* 41 * CE4100 ids. Will be moved to machine_device_initcall() once we have it. 42 */ 43 static struct of_device_id __initdata ce4100_ids[] = { 44 { .compatible = "intel,ce4100-cp", }, 45 { .compatible = "isa", }, 46 { .compatible = "pci", }, 47 {}, 48 }; 49 50 static int __init add_bus_probe(void) 51 { 52 if (!of_have_populated_dt()) 53 return 0; 54 55 return of_platform_bus_probe(NULL, ce4100_ids, NULL); 56 } 57 device_initcall(add_bus_probe); 58 59 #ifdef CONFIG_PCI 60 struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) 61 { 62 struct device_node *np; 63 64 for_each_node_by_type(np, "pci") { 65 const void *prop; 66 unsigned int bus_min; 67 68 prop = of_get_property(np, "bus-range", NULL); 69 if (!prop) 70 continue; 71 bus_min = be32_to_cpup(prop); 72 if (bus->number == bus_min) 73 return np; 74 } 75 return NULL; 76 } 77 78 static int x86_of_pci_irq_enable(struct pci_dev *dev) 79 { 80 u32 virq; 81 int ret; 82 u8 pin; 83 84 ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 85 if (ret) 86 return pcibios_err_to_errno(ret); 87 if (!pin) 88 return 0; 89 90 virq = of_irq_parse_and_map_pci(dev, 0, 0); 91 if (virq == 0) 92 return -EINVAL; 93 dev->irq = virq; 94 return 0; 95 } 96 97 static void x86_of_pci_irq_disable(struct pci_dev *dev) 98 { 99 } 100 101 void x86_of_pci_init(void) 102 { 103 pcibios_enable_irq = x86_of_pci_irq_enable; 104 pcibios_disable_irq = x86_of_pci_irq_disable; 105 } 106 #endif 107 108 static void __init dtb_setup_hpet(void) 109 { 110 #ifdef CONFIG_HPET_TIMER 111 struct device_node *dn; 112 struct resource r; 113 int ret; 114 115 dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-hpet"); 116 if (!dn) 117 return; 118 ret = of_address_to_resource(dn, 0, &r); 119 if (ret) { 120 WARN_ON(1); 121 return; 122 } 123 hpet_address = r.start; 124 #endif 125 } 126 127 #ifdef CONFIG_X86_LOCAL_APIC 128 129 static void __init dtb_cpu_setup(void) 130 { 131 struct device_node *dn; 132 u32 apic_id; 133 134 for_each_of_cpu_node(dn) { 135 apic_id = of_get_cpu_hwid(dn, 0); 136 if (apic_id == ~0U) { 137 pr_warn("%pOF: missing local APIC ID\n", dn); 138 continue; 139 } 140 topology_register_apic(apic_id, CPU_ACPIID_INVALID, true); 141 set_apicid_to_node(apic_id, of_node_to_nid(dn)); 142 } 143 } 144 145 static void __init dtb_lapic_setup(void) 146 { 147 struct device_node *dn; 148 struct resource r; 149 unsigned long lapic_addr = APIC_DEFAULT_PHYS_BASE; 150 int ret; 151 152 dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-lapic"); 153 if (dn) { 154 ret = of_address_to_resource(dn, 0, &r); 155 if (WARN_ON(ret)) 156 return; 157 lapic_addr = r.start; 158 } 159 160 /* Did the boot loader setup the local APIC ? */ 161 if (!boot_cpu_has(X86_FEATURE_APIC)) { 162 /* Try force enabling, which registers the APIC address */ 163 if (!apic_force_enable(lapic_addr)) 164 return; 165 } else { 166 register_lapic_address(lapic_addr); 167 } 168 smp_found_config = 1; 169 pic_mode = !of_property_read_bool(dn, "intel,virtual-wire-mode"); 170 pr_info("%s compatibility mode.\n", pic_mode ? "IMCR and PIC" : "Virtual Wire"); 171 } 172 173 #endif /* CONFIG_X86_LOCAL_APIC */ 174 175 #ifdef CONFIG_X86_IO_APIC 176 static unsigned int ioapic_id; 177 178 struct of_ioapic_type { 179 u32 out_type; 180 u32 is_level; 181 u32 active_low; 182 }; 183 184 static struct of_ioapic_type of_ioapic_type[] = 185 { 186 { 187 .out_type = IRQ_TYPE_EDGE_FALLING, 188 .is_level = 0, 189 .active_low = 1, 190 }, 191 { 192 .out_type = IRQ_TYPE_LEVEL_HIGH, 193 .is_level = 1, 194 .active_low = 0, 195 }, 196 { 197 .out_type = IRQ_TYPE_LEVEL_LOW, 198 .is_level = 1, 199 .active_low = 1, 200 }, 201 { 202 .out_type = IRQ_TYPE_EDGE_RISING, 203 .is_level = 0, 204 .active_low = 0, 205 }, 206 }; 207 208 static int dt_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, 209 unsigned int nr_irqs, void *arg) 210 { 211 struct irq_fwspec *fwspec = (struct irq_fwspec *)arg; 212 struct of_ioapic_type *it; 213 struct irq_alloc_info tmp; 214 int type_index; 215 216 if (WARN_ON(fwspec->param_count < 2)) 217 return -EINVAL; 218 219 type_index = fwspec->param[1]; 220 if (type_index >= ARRAY_SIZE(of_ioapic_type)) 221 return -EINVAL; 222 223 it = &of_ioapic_type[type_index]; 224 ioapic_set_alloc_attr(&tmp, NUMA_NO_NODE, it->is_level, it->active_low); 225 tmp.devid = mpc_ioapic_id(mp_irqdomain_ioapic_idx(domain)); 226 tmp.ioapic.pin = fwspec->param[0]; 227 228 return mp_irqdomain_alloc(domain, virq, nr_irqs, &tmp); 229 } 230 231 static const struct irq_domain_ops ioapic_irq_domain_ops = { 232 .alloc = dt_irqdomain_alloc, 233 .free = mp_irqdomain_free, 234 .activate = mp_irqdomain_activate, 235 .deactivate = mp_irqdomain_deactivate, 236 }; 237 238 static void __init dtb_add_ioapic(struct device_node *dn) 239 { 240 struct resource r; 241 int ret; 242 struct ioapic_domain_cfg cfg = { 243 .type = IOAPIC_DOMAIN_DYNAMIC, 244 .ops = &ioapic_irq_domain_ops, 245 .dev = dn, 246 }; 247 248 ret = of_address_to_resource(dn, 0, &r); 249 if (ret) { 250 pr_err("Can't obtain address from device node %pOF.\n", dn); 251 return; 252 } 253 mp_register_ioapic(++ioapic_id, r.start, gsi_top, &cfg); 254 } 255 256 static void __init dtb_ioapic_setup(void) 257 { 258 struct device_node *dn; 259 260 for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic") 261 dtb_add_ioapic(dn); 262 263 if (nr_ioapics) { 264 of_ioapic = 1; 265 return; 266 } 267 pr_err("Error: No information about IO-APIC in OF.\n"); 268 } 269 #else 270 static void __init dtb_ioapic_setup(void) {} 271 #endif 272 273 static void __init dtb_apic_setup(void) 274 { 275 #ifdef CONFIG_X86_LOCAL_APIC 276 dtb_lapic_setup(); 277 dtb_cpu_setup(); 278 #endif 279 dtb_ioapic_setup(); 280 } 281 282 static void __init x86_dtb_parse_smp_config(void) 283 { 284 if (!of_have_populated_dt()) 285 return; 286 287 dtb_setup_hpet(); 288 dtb_apic_setup(); 289 } 290 291 void __init x86_flattree_get_config(void) 292 { 293 #ifdef CONFIG_OF_EARLY_FLATTREE 294 u32 size, map_len; 295 void *dt; 296 297 if (initial_dtb) { 298 map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128); 299 300 dt = early_memremap(initial_dtb, map_len); 301 size = fdt_totalsize(dt); 302 if (map_len < size) { 303 early_memunmap(dt, map_len); 304 dt = early_memremap(initial_dtb, size); 305 map_len = size; 306 } 307 308 early_init_dt_verify(dt, __pa(dt)); 309 } 310 311 unflatten_and_copy_device_tree(); 312 313 if (initial_dtb) 314 early_memunmap(dt, map_len); 315 #endif 316 if (of_have_populated_dt()) 317 x86_init.mpparse.parse_smp_cfg = x86_dtb_parse_smp_config; 318 } 319