Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86: Add device tree support

This patch adds minimal support for device tree on x86. The device
tree blob is passed to the kernel via setup_data which requires at
least boot protocol 2.09.

Memory size, restricted memory regions, boot arguments are gathered
the traditional way so things like cmd_line are just here to let the
code compile.

The current plan is use the device tree as an extension and to gather
information which can not be enumerated and would have to be hardcoded
otherwise. This includes things like
- which devices are on this I2C/SPI bus?
- how are the interrupts wired to IO APIC?
- where could my hpet be?

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Cc: sodaville@linutronix.de
Cc: devicetree-discuss@lists.ozlabs.org
LKML-Reference: <1298405266-1624-3-git-send-email-bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by

Sebastian Andrzej Siewior and committed by
Thomas Gleixner
da6b737b f1c2b357

+126 -13
+20
Documentation/devicetree/booting-without-of.txt
··· 13 13 14 14 I - Introduction 15 15 1) Entry point for arch/powerpc 16 + 2) Entry point for arch/x86 16 17 17 18 II - The DT block format 18 19 1) Header ··· 226 225 cannot support both configurations with Book E and configurations 227 226 with classic Powerpc architectures. 228 227 228 + 2) Entry point for arch/x86 229 + ------------------------------- 230 + 231 + There is one single 32bit entry point to the kernel at code32_start, 232 + the decompressor (the real mode entry point goes to the same 32bit 233 + entry point once it switched into protected mode). That entry point 234 + supports one calling convention which is documented in 235 + Documentation/x86/boot.txt 236 + The physical pointer to the device-tree block (defined in chapter II) 237 + is passed via setup_data which requires at least boot protocol 2.09. 238 + The type filed is defined as 239 + 240 + #define SETUP_DTB 2 241 + 242 + This device-tree is used as an extension to the "boot page". As such it 243 + does not parse / consider data which is already covered by the boot 244 + page. This includes memory size, reserved ranges, command line arguments 245 + or initrd address. It simply holds information which can not be retrieved 246 + otherwise like interrupt routing or a list of devices behind an I2C bus. 229 247 230 248 II - The DT block format 231 249 ========================
+2
arch/x86/Kconfig
··· 382 382 depends on X86_32 383 383 depends on X86_EXTENDED_PLATFORM 384 384 select X86_REBOOTFIXUPS 385 + select OF 386 + select OF_EARLY_FLATTREE 385 387 ---help--- 386 388 Select for the Intel CE media processor (CE4100) SOC. 387 389 This option compiles in support for the CE4100 SOC for settop
+1
arch/x86/include/asm/bootparam.h
··· 12 12 /* setup data types */ 13 13 #define SETUP_NONE 0 14 14 #define SETUP_E820_EXT 1 15 + #define SETUP_DTB 2 15 16 16 17 /* extensible setup data list node */ 17 18 struct setup_data {
-3
arch/x86/include/asm/irq.h
··· 10 10 #include <asm/apicdef.h> 11 11 #include <asm/irq_vectors.h> 12 12 13 - /* Even though we don't support this, supply it to appease OF */ 14 - static inline void irq_dispose_mapping(unsigned int virq) { } 15 - 16 13 static inline int irq_canonicalize(int irq) 17 14 { 18 15 return ((irq == 2) ? 9 : irq);
+47 -1
arch/x86/include/asm/prom.h
··· 1 - /* dummy prom.h; here to make linux/of.h's #includes happy */ 1 + /* 2 + * Definitions for Device tree / OpenFirmware handling on X86 3 + * 4 + * based on arch/powerpc/include/asm/prom.h which is 5 + * Copyright (C) 1996-2005 Paul Mackerras. 6 + * 7 + * This program is free software; you can redistribute it and/or 8 + * modify it under the terms of the GNU General Public License 9 + * as published by the Free Software Foundation; either version 10 + * 2 of the License, or (at your option) any later version. 11 + */ 12 + 13 + #ifndef _ASM_X86_PROM_H 14 + #define _ASM_X86_PROM_H 15 + #ifndef __ASSEMBLY__ 16 + 17 + #include <linux/of.h> 18 + #include <linux/types.h> 19 + 20 + #include <asm/irq.h> 21 + #include <asm/atomic.h> 22 + #include <asm/setup.h> 23 + 24 + #ifdef CONFIG_OF 25 + extern void add_dtb(u64 data); 26 + #else 27 + static inline void add_dtb(u64 data) { } 28 + #endif 29 + 30 + extern char cmd_line[COMMAND_LINE_SIZE]; 31 + 32 + #define pci_address_to_pio pci_address_to_pio 33 + unsigned long pci_address_to_pio(phys_addr_t addr); 34 + 35 + /** 36 + * irq_dispose_mapping - Unmap an interrupt 37 + * @virq: linux virq number of the interrupt to unmap 38 + * 39 + * FIXME: We really should implement proper virq handling like power, 40 + * but that's going to be major surgery. 41 + */ 42 + static inline void irq_dispose_mapping(unsigned int virq) { } 43 + 44 + #define HAVE_ARCH_DEVTREE_FIXUPS 45 + 46 + #endif /* __ASSEMBLY__ */ 47 + #endif
+1
arch/x86/kernel/Makefile
··· 109 109 obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o 110 110 111 111 obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o 112 + obj-$(CONFIG_OF) += devicetree.o 112 113 113 114 ### 114 115 # 64 bit specific files
+51
arch/x86/kernel/devicetree.c
··· 1 + /* 2 + * Architecture specific OF callbacks. 3 + */ 4 + #include <linux/bootmem.h> 5 + #include <linux/io.h> 6 + #include <linux/list.h> 7 + #include <linux/of.h> 8 + #include <linux/of_fdt.h> 9 + #include <linux/of_platform.h> 10 + #include <linux/slab.h> 11 + 12 + char __initdata cmd_line[COMMAND_LINE_SIZE]; 13 + 14 + unsigned int irq_create_of_mapping(struct device_node *controller, 15 + const u32 *intspec, unsigned int intsize) 16 + { 17 + return intspec[0]; 18 + 19 + } 20 + EXPORT_SYMBOL_GPL(irq_create_of_mapping); 21 + 22 + unsigned long pci_address_to_pio(phys_addr_t address) 23 + { 24 + /* 25 + * The ioport address can be directly used by inX / outX 26 + */ 27 + BUG_ON(address >= (1 << 16)); 28 + return (unsigned long)address; 29 + } 30 + EXPORT_SYMBOL_GPL(pci_address_to_pio); 31 + 32 + void __init early_init_dt_scan_chosen_arch(unsigned long node) 33 + { 34 + BUG(); 35 + } 36 + 37 + void __init early_init_dt_add_memory_arch(u64 base, u64 size) 38 + { 39 + BUG(); 40 + } 41 + 42 + void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) 43 + { 44 + return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); 45 + } 46 + 47 + void __init add_dtb(u64 data) 48 + { 49 + initial_boot_params = phys_to_virt((u64) (u32) data + 50 + offsetof(struct setup_data, data)); 51 + }
-9
arch/x86/kernel/irq.c
··· 276 276 277 277 EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); 278 278 279 - #ifdef CONFIG_OF 280 - unsigned int irq_create_of_mapping(struct device_node *controller, 281 - const u32 *intspec, unsigned int intsize) 282 - { 283 - return intspec[0]; 284 - } 285 - EXPORT_SYMBOL_GPL(irq_create_of_mapping); 286 - #endif 287 - 288 279 #ifdef CONFIG_HOTPLUG_CPU 289 280 /* A cpu has been removed from cpu_online_mask. Reset irq affinities. */ 290 281 void fixup_irqs(void)
+4
arch/x86/kernel/setup.c
··· 113 113 #endif 114 114 #include <asm/mce.h> 115 115 #include <asm/alternative.h> 116 + #include <asm/prom.h> 116 117 117 118 /* 118 119 * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. ··· 445 444 switch (data->type) { 446 445 case SETUP_E820_EXT: 447 446 parse_e820_ext(data); 447 + break; 448 + case SETUP_DTB: 449 + add_dtb(pa_data); 448 450 break; 449 451 default: 450 452 break;