diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-03-28 23:15:54 +1100 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-03-28 23:15:54 +1100 |
commit | e8222502ee6157e2713da9e0792c21f4ad458d50 (patch) | |
tree | 0f970fb99912c257a7e5254f863a53f79d22ab14 /arch/powerpc/kernel | |
parent | 056cb48a2fb6fb31debf665695a9f97b45cfb8ec (diff) |
[PATCH] powerpc: Kill _machine and hard-coded platform numbers
This removes statically assigned platform numbers and reworks the
powerpc platform probe code to use a better mechanism. With this,
board support files can simply declare a new machine type with a
macro, and implement a probe() function that uses the flattened
device-tree to detect if they apply for a given machine.
We now have a machine_is() macro that replaces the comparisons of
_machine with the various PLATFORM_* constants. This commit also
changes various drivers to use the new macro instead of looking at
_machine.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/nvram_64.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_32.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/proc_ppc64.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom.c | 56 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 51 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas-proc.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup-common.c | 52 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_32.c | 58 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 56 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 35 | ||||
-rw-r--r-- | arch/powerpc/kernel/vdso.c | 9 | ||||
-rw-r--r-- | arch/powerpc/kernel/vmlinux.lds.S | 381 |
14 files changed, 327 insertions, 389 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 882889b1592..54b48f33005 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -105,8 +105,6 @@ int main(void) DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); - DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); - /* paca */ DEFINE(PACA_SIZE, sizeof(struct paca_struct)); DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index)); diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 6c3989f6247..ada50aa5b60 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -160,7 +160,7 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file, case IOC_NVRAM_GET_OFFSET: { int part, offset; - if (_machine != PLATFORM_POWERMAC) + if (!machine_is(powermac)) return -EINVAL; if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) return -EFAULT; @@ -444,7 +444,7 @@ static int nvram_setup_partition(void) * in our nvram, as Apple defined partitions use pretty much * all of the space */ - if (_machine == PLATFORM_POWERMAC) + if (machine_is(powermac)) return -ENOSPC; /* see if we have an OS partition that meets our needs. diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 704c846b2b0..b129d2e4b75 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -787,7 +787,7 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) * fix has to be done by making the remapping per-host and always * filling the pci_to_OF map. --BenH */ - if (_machine == _MACH_Pmac && busnr >= 0xf0) + if (machine_is(powermac) && busnr >= 0xf0) busnr -= 0xf0; else #endif @@ -1728,7 +1728,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) * (bus 0 is HT root), we return the AGP one instead. */ #ifdef CONFIG_PPC_PMAC - if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4")) + if (machine_is(powermac) && machine_is_compatible("MacRISC4")) if (bus == 0) bus = 0xf0; #endif /* CONFIG_PPC_PMAC */ diff --git a/arch/powerpc/kernel/proc_ppc64.c b/arch/powerpc/kernel/proc_ppc64.c index 7ba42a405f4..3c2cf661f6d 100644 --- a/arch/powerpc/kernel/proc_ppc64.c +++ b/arch/powerpc/kernel/proc_ppc64.c @@ -23,6 +23,7 @@ #include <linux/slab.h> #include <linux/kernel.h> +#include <asm/machdep.h> #include <asm/vdso_datapage.h> #include <asm/rtas.h> #include <asm/uaccess.h> @@ -51,7 +52,7 @@ static int __init proc_ppc64_create(void) if (!root) return 1; - if (!(platform_is_pseries() || _machine == PLATFORM_CELL)) + if (!machine_is(pseries) && !machine_is(cell)) return 0; if (!proc_mkdir("rtas", root)) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index a2bc433f361..4336390bcf3 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -383,14 +383,14 @@ static int __devinit finish_node_interrupts(struct device_node *np, /* Apple uses bits in there in a different way, let's * only keep the real sense bit on macs */ - if (_machine == PLATFORM_POWERMAC) + if (machine_is(powermac)) sense &= 0x1; np->intrs[intrcount].sense = map_mpic_senses[sense]; } #ifdef CONFIG_PPC64 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ - if (_machine == PLATFORM_POWERMAC && ic && ic->parent) { + if (machine_is(powermac) && ic && ic->parent) { char *name = get_property(ic->parent, "name", NULL); if (name && !strcmp(name, "u3")) np->intrs[intrcount].line += 128; @@ -570,6 +570,18 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, return rc; } +unsigned long __init of_get_flat_dt_root(void) +{ + unsigned long p = ((unsigned long)initial_boot_params) + + initial_boot_params->off_dt_struct; + + while(*((u32 *)p) == OF_DT_NOP) + p += 4; + BUG_ON (*((u32 *)p) != OF_DT_BEGIN_NODE); + p += 4; + return _ALIGN(p + strlen((char *)p) + 1, 4); +} + /** * This function can be used within scan_flattened_dt callback to get * access to properties @@ -612,6 +624,25 @@ void* __init of_get_flat_dt_prop(unsigned long node, const char *name, } while(1); } +int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) +{ + const char* cp; + unsigned long cplen, l; + + cp = of_get_flat_dt_prop(node, "compatible", &cplen); + if (cp == NULL) + return 0; + while (cplen > 0) { + if (strncasecmp(cp, compat, strlen(compat)) == 0) + return 1; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + } + + return 0; +} + static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, unsigned long align) { @@ -686,7 +717,7 @@ static unsigned long __init unflatten_dt_node(unsigned long mem, #ifdef DEBUG if ((strlen(p) + l + 1) != allocl) { DBG("%s: p: %d, l: %d, a: %d\n", - pathp, strlen(p), l, allocl); + pathp, (int)strlen(p), l, allocl); } #endif p += strlen(p); @@ -951,7 +982,6 @@ static int __init early_init_dt_scan_cpus(unsigned long node, static int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, int depth, void *data) { - u32 *prop; unsigned long *lprop; unsigned long l; char *p; @@ -962,14 +992,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node, (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) return 0; - /* get platform type */ - prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL); - if (prop == NULL) - return 0; -#ifdef CONFIG_PPC_MULTIPLATFORM - _machine = *prop; -#endif - #ifdef CONFIG_PPC64 /* check if iommu is forced on or off */ if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) @@ -996,15 +1018,15 @@ static int __init early_init_dt_scan_chosen(unsigned long node, * set of RTAS infos now if available */ { - u64 *basep, *entryp; + u64 *basep, *entryp, *sizep; basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); - prop = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); - if (basep && entryp && prop) { + sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); + if (basep && entryp && sizep) { rtas.base = *basep; rtas.entry = *entryp; - rtas.size = *prop; + rtas.size = *sizep; } } #endif /* CONFIG_PPC_RTAS */ @@ -1775,7 +1797,7 @@ static int of_finish_dynamic_node(struct device_node *node) /* We don't support that function on PowerMac, at least * not yet */ - if (_machine == PLATFORM_POWERMAC) + if (machine_is(powermac)) return -ENODEV; /* fix up new node's linux_phandle field */ diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 0d088784450..d66c5e77fcf 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -180,6 +180,16 @@ static unsigned long __initdata prom_tce_alloc_start; static unsigned long __initdata prom_tce_alloc_end; #endif +/* Platforms codes are now obsolete in the kernel. Now only used within this + * file and ultimately gone too. Feel free to change them if you need, they + * are not shared with anything outside of this file anymore + */ +#define PLATFORM_PSERIES 0x0100 +#define PLATFORM_PSERIES_LPAR 0x0101 +#define PLATFORM_LPAR 0x0001 +#define PLATFORM_POWERMAC 0x0400 +#define PLATFORM_GENERIC 0x0500 + static int __initdata of_platform; static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; @@ -1492,7 +1502,10 @@ static int __init prom_find_machine_type(void) int len, i = 0; #ifdef CONFIG_PPC64 phandle rtas; + int x; #endif + + /* Look for a PowerMac */ len = prom_getprop(_prom->root, "compatible", compat, sizeof(compat)-1); if (len > 0) { @@ -1505,28 +1518,36 @@ static int __init prom_find_machine_type(void) if (strstr(p, RELOC("Power Macintosh")) || strstr(p, RELOC("MacRISC"))) return PLATFORM_POWERMAC; -#ifdef CONFIG_PPC64 - if (strstr(p, RELOC("Momentum,Maple"))) - return PLATFORM_MAPLE; - if (strstr(p, RELOC("IBM,CPB"))) - return PLATFORM_CELL; -#endif i += sl + 1; } } #ifdef CONFIG_PPC64 + /* If not a mac, try to figure out if it's an IBM pSeries or any other + * PAPR compliant platform. We assume it is if : + * - /device_type is "chrp" (please, do NOT use that for future + * non-IBM designs ! + * - it has /rtas + */ + len = prom_getprop(_prom->root, "model", + compat, sizeof(compat)-1); + if (len <= 0) + return PLATFORM_GENERIC; + compat[len] = 0; + if (strcmp(compat, "chrp")) + return PLATFORM_GENERIC; + /* Default to pSeries. We need to know if we are running LPAR */ rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); - if (PHANDLE_VALID(rtas)) { - int x = prom_getproplen(rtas, "ibm,hypertas-functions"); - if (x != PROM_ERROR) { - prom_printf("Hypertas detected, assuming LPAR !\n"); - return PLATFORM_PSERIES_LPAR; - } + if (!PHANDLE_VALID(rtas)) + return PLATFORM_GENERIC; + x = prom_getproplen(rtas, "ibm,hypertas-functions"); + if (x != PROM_ERROR) { + prom_printf("Hypertas detected, assuming LPAR !\n"); + return PLATFORM_PSERIES_LPAR; } return PLATFORM_PSERIES; #else - return PLATFORM_CHRP; + return PLATFORM_GENERIC; #endif } @@ -2034,7 +2055,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, { struct prom_t *_prom; unsigned long hdr; - u32 getprop_rval; unsigned long offset = reloc_offset(); #ifdef CONFIG_PPC32 @@ -2070,9 +2090,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, * between pSeries SMP and pSeries LPAR */ RELOC(of_platform) = prom_find_machine_type(); - getprop_rval = RELOC(of_platform); - prom_setprop(_prom->chosen, "/chosen", "linux,platform", - &getprop_rval, sizeof(getprop_rval)); /* Bail if this is a kdump kernel. */ if (PHYSICAL_START > 0) diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index 1f03fb28cc0..456286cf1d1 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c @@ -257,7 +257,7 @@ static int __init proc_rtas_init(void) { struct proc_dir_entry *entry; - if (_machine != PLATFORM_PSERIES && _machine != PLATFORM_PSERIES_LPAR) + if (!machine_is(pseries)) return 1; rtas_node = of_find_node_by_name(NULL, "rtas"); diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 142d818a31a..4b78ee0e586 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -25,6 +25,7 @@ #include <asm/hvcall.h> #include <asm/semaphore.h> #include <asm/machdep.h> +#include <asm/firmware.h> #include <asm/page.h> #include <asm/param.h> #include <asm/system.h> @@ -768,7 +769,7 @@ void __init rtas_initialize(void) * the stop-self token if any */ #ifdef CONFIG_PPC64 - if (_machine == PLATFORM_PSERIES_LPAR) { + if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) { rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); ibm_suspend_me_token = rtas_token("ibm,suspend-me"); } diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index b17630ad4ac..3473cb9cb0a 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -9,6 +9,9 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ + +#undef DEBUG + #include <linux/config.h> #include <linux/module.h> #include <linux/string.h> @@ -41,6 +44,7 @@ #include <asm/time.h> #include <asm/cputable.h> #include <asm/sections.h> +#include <asm/firmware.h> #include <asm/btext.h> #include <asm/nvram.h> #include <asm/setup.h> @@ -56,8 +60,6 @@ #include "setup.h" -#undef DEBUG - #ifdef DEBUG #include <asm/udbg.h> #define DBG(fmt...) udbg_printf(fmt) @@ -65,10 +67,12 @@ #define DBG(fmt...) #endif -#ifdef CONFIG_PPC_MULTIPLATFORM -int _machine = 0; -EXPORT_SYMBOL(_machine); -#endif +/* The main machine-dep calls structure + */ +struct machdep_calls ppc_md; +EXPORT_SYMBOL(ppc_md); +struct machdep_calls *machine_id; +EXPORT_SYMBOL(machine_id); unsigned long klimit = (unsigned long) _end; @@ -168,7 +172,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); #endif /* CONFIG_SMP && CONFIG_PPC32 */ seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); - + if (ppc_md.name) + seq_printf(m, "platform\t: %s\n", ppc_md.name); if (ppc_md.show_cpuinfo != NULL) ppc_md.show_cpuinfo(m); @@ -387,7 +392,7 @@ void __init smp_setup_cpu_maps(void) * On pSeries LPAR, we need to know how many cpus * could possibly be added to this partition. */ - if (_machine == PLATFORM_PSERIES_LPAR && + if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) && (dn = of_find_node_by_path("/rtas"))) { int num_addr_cell, num_size_cell, maxcpus; unsigned int *ireg; @@ -456,3 +461,34 @@ static int __init early_xmon(char *p) } early_param("xmon", early_xmon); #endif + +void probe_machine(void) +{ + extern struct machdep_calls __machine_desc_start; + extern struct machdep_calls __machine_desc_end; + + /* + * Iterate all ppc_md structures until we find the proper + * one for the current machine type + */ + DBG("Probing machine type ...\n"); + + for (machine_id = &__machine_desc_start; + machine_id < &__machine_desc_end; + machine_id++) { + DBG(" %s ...", machine_id->name); + memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls)); + if (ppc_md.probe()) { + DBG(" match !\n"); + break; + } + DBG("\n"); + } + /* What can we do if we didn't find ? */ + if (machine_id >= &__machine_desc_end) { + DBG("No suitable machine found !\n"); + for (;;); + } + + printk(KERN_INFO "Using %s machine description\n", ppc_md.name); +} diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index a2c89435abe..ae9c33d7073 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -67,10 +67,6 @@ unsigned int DMA_MODE_WRITE; int have_of = 1; #ifdef CONFIG_PPC_MULTIPLATFORM -extern void prep_init(void); -extern void pmac_init(void); -extern void chrp_init(void); - dev_t boot_dev; #endif /* CONFIG_PPC_MULTIPLATFORM */ @@ -82,9 +78,6 @@ unsigned long SYSRQ_KEY = 0x54; unsigned long vgacon_remap_base; #endif -struct machdep_calls ppc_md; -EXPORT_SYMBOL(ppc_md); - /* * These are used in binfmt_elf.c to put aux entries on the stack * for each elf executable being started. @@ -120,48 +113,6 @@ unsigned long __init early_init(unsigned long dt_ptr) return KERNELBASE + offset; } -#ifdef CONFIG_PPC_MULTIPLATFORM -/* - * The PPC_MULTIPLATFORM version of platform_init... - */ -void __init platform_init(void) -{ - /* if we didn't get any bootinfo telling us what we are... */ - if (_machine == 0) { - /* prep boot loader tells us if we're prep or not */ - if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) - _machine = _MACH_prep; - } - -#ifdef CONFIG_PPC_PREP - /* not much more to do here, if prep */ - if (_machine == _MACH_prep) { - prep_init(); - return; - } -#endif - -#ifdef CONFIG_ADB - if (strstr(cmd_line, "adb_sync")) { - extern int __adb_probe_sync; - __adb_probe_sync = 1; - } -#endif /* CONFIG_ADB */ - - switch (_machine) { -#ifdef CONFIG_PPC_PMAC - case _MACH_Pmac: - pmac_init(); - break; -#endif -#ifdef CONFIG_PPC_CHRP - case _MACH_chrp: - chrp_init(); - break; -#endif - } -} -#endif /* * Find out what kind of machine we're on and save any data we need @@ -187,8 +138,12 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys) strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); #endif /* CONFIG_CMDLINE */ - /* Base init based on machine type */ +#ifdef CONFIG_PPC_MULTIPLATFORM + probe_machine(); +#else + /* Base init based on machine type. Obsoloete, please kill ! */ platform_init(); +#endif #ifdef CONFIG_6xx if (cpu_has_feature(CPU_FTR_CAN_DOZE) || @@ -359,7 +314,4 @@ void __init setup_arch(char **cmdline_p) if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); paging_init(); - - /* this is for modules since _machine can be a define -- Cort */ - ppc_md.ppc_machine = _machine; } diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 5b63a861ef4..6aea1fb74b6 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -95,11 +95,6 @@ int dcache_bsize; int icache_bsize; int ucache_bsize; -/* The main machine-dep calls structure - */ -struct machdep_calls ppc_md; -EXPORT_SYMBOL(ppc_md); - #ifdef CONFIG_MAGIC_SYSRQ unsigned long SYSRQ_KEY; #endif /* CONFIG_MAGIC_SYSRQ */ @@ -160,32 +155,6 @@ early_param("smt-enabled", early_smt_enabled); #define check_smt_enabled() #endif /* CONFIG_SMP */ -extern struct machdep_calls pSeries_md; -extern struct machdep_calls pmac_md; -extern struct machdep_calls maple_md; -extern struct machdep_calls cell_md; -extern struct machdep_calls iseries_md; - -/* Ultimately, stuff them in an elf section like initcalls... */ -static struct machdep_calls __initdata *machines[] = { -#ifdef CONFIG_PPC_PSERIES - &pSeries_md, -#endif /* CONFIG_PPC_PSERIES */ -#ifdef CONFIG_PPC_PMAC - &pmac_md, -#endif /* CONFIG_PPC_PMAC */ -#ifdef CONFIG_PPC_MAPLE - &maple_md, -#endif /* CONFIG_PPC_MAPLE */ -#ifdef CONFIG_PPC_CELL - &cell_md, -#endif -#ifdef CONFIG_PPC_ISERIES - &iseries_md, -#endif - NULL -}; - /* * Early initialization entry point. This is called by head.S * with MMU translation disabled. We rely on the "feature" of @@ -207,12 +176,10 @@ static struct machdep_calls __initdata *machines[] = { void __init early_setup(unsigned long dt_ptr) { - static struct machdep_calls **mach; - /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); - DBG(" -> early_setup()\n"); + DBG(" -> early_setup(), dt_ptr: 0x%lx\n", dt_ptr); /* * Do early initializations using the flattened device @@ -229,22 +196,8 @@ void __init early_setup(unsigned long dt_ptr) get_paca()->stab_real = __pa((u64)&initial_stab); get_paca()->stab_addr = (u64)&initial_stab; - /* - * Iterate all ppc_md structures until we find the proper - * one for the current machine type - */ - DBG("Probing machine type for platform %x...\n", _machine); - - for (mach = machines; *mach; mach++) { - if ((*mach)->probe(_machine)) - break; - } - /* What can we do if we didn't find ? */ - if (*mach == NULL) { - DBG("No suitable machine found !\n"); - for (;;); - } - ppc_md = **mach; + /* Probe the machine type */ + probe_machine(); #ifdef CONFIG_CRASH_DUMP kdump_setup(); @@ -346,7 +299,7 @@ static void __init initialize_cache_info(void) const char *dc, *ic; /* Then read cache informations */ - if (_machine == PLATFORM_POWERMAC) { + if (machine_is(powermac)) { dc = "d-cache-block-size"; ic = "i-cache-block-size"; } else { @@ -490,7 +443,6 @@ void __init setup_system(void) printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller); - printk("platform = 0x%x\n", _machine); printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size()); printk("ppc64_caches.dcache_line_size = 0x%x\n", ppc64_caches.dline_size); diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 98660aedeeb..27600c9432b 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -97,7 +97,6 @@ static DEFINE_SPINLOCK(die_lock); int die(const char *str, struct pt_regs *regs, long err) { static int die_counter, crash_dump_start = 0; - int nl = 0; if (debugger(regs)) return 1; @@ -106,7 +105,7 @@ int die(const char *str, struct pt_regs *regs, long err) spin_lock_irq(&die_lock); bust_spinlocks(1); #ifdef CONFIG_PMAC_BACKLIGHT - if (_machine == _MACH_Pmac) { + if (machine_is(powermac)) { set_backlight_enable(1); set_backlight_level(BACKLIGHT_MAX); } @@ -114,46 +113,18 @@ int die(const char *str, struct pt_regs *regs, long err) printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); #ifdef CONFIG_PREEMPT printk("PREEMPT "); - nl = 1; #endif #ifdef CONFIG_SMP printk("SMP NR_CPUS=%d ", NR_CPUS); - nl = 1; #endif #ifdef CONFIG_DEBUG_PAGEALLOC printk("DEBUG_PAGEALLOC "); - nl = 1; #endif #ifdef CONFIG_NUMA printk("NUMA "); - nl = 1; #endif -#ifdef CONFIG_PPC64 - switch (_machine) { - case PLATFORM_PSERIES: - printk("PSERIES "); - nl = 1; - break; - case PLATFORM_PSERIES_LPAR: - printk("PSERIES LPAR "); - nl = 1; - break; - case PLATFORM_ISERIES_LPAR: - printk("ISERIES LPAR "); - nl = 1; - break; - case PLATFORM_POWERMAC: - printk("POWERMAC "); - nl = 1; - break; - case PLATFORM_CELL: - printk("CELL "); - nl = 1; - break; - } -#endif - if (nl) - printk("\n"); + printk("%s\n", ppc_md.name ? "" : ppc_md.name); + print_modules(); show_regs(regs); bust_spinlocks(0); diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index ec837036842..573afb68d69 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -33,6 +33,7 @@ #include <asm/machdep.h> #include <asm/cputable.h> #include <asm/sections.h> +#include <asm/firmware.h> #include <asm/vdso.h> #include <asm/vdso_datapage.h> @@ -667,7 +668,13 @@ void __init vdso_init(void) vdso_data->version.major = SYSTEMCFG_MAJOR; vdso_data->version.minor = SYSTEMCFG_MINOR; vdso_data->processor = mfspr(SPRN_PVR); - vdso_data->platform = _machine; + /* + * Fake the old platform number for pSeries and iSeries and add + * in LPAR bit if necessary + */ + vdso_data->platform = machine_is(iseries) ? 0x200 : 0x100; + if (firmware_has_feature(FW_FEATURE_LPAR)) + vdso_data->platform |= 1; vdso_data->physicalMemorySize = lmb_phys_mem_size(); vdso_data->dcache_size = ppc64_caches.dsize; vdso_data->dcache_line_size = ppc64_caches.dline_size; diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 7fa7b15fd8e..fe79c2584cb 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -1,9 +1,11 @@ #include <linux/config.h> #ifdef CONFIG_PPC64 #include <asm/page.h> +#define PROVIDE32(x) PROVIDE(__unused__##x) #else #define PAGE_SIZE 4096 #define KERNELBASE CONFIG_KERNEL_START +#define PROVIDE32(x) PROVIDE(x) #endif #include <asm-generic/vmlinux.lds.h> @@ -18,43 +20,42 @@ jiffies = jiffies_64 + 4; #endif SECTIONS { - /* Sections to be discarded. */ - /DISCARD/ : { - *(.exitcall.exit) - *(.exit.data) - } - - . = KERNELBASE; - - /* Read-only sections, merged into text segment: */ - .text : { - *(.text .text.*) - SCHED_TEXT - LOCK_TEXT - KPROBES_TEXT - *(.fixup) -#ifdef CONFIG_PPC32 - *(.got1) - __got2_start = .; - *(.got2) - __got2_end = .; -#else - . = ALIGN(PAGE_SIZE); - _etext = .; -#endif - } -#ifdef CONFIG_PPC32 - _etext = .; - PROVIDE (etext = .); + /* Sections to be discarded. */ + /DISCARD/ : { + *(.exitcall.exit) + *(.exit.data) + } - RODATA - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } + . = KERNELBASE; - .fixup : { *(.fixup) } -#endif +/* + * Text, read only data and other permanent read-only sections + */ + + /* Text and gots */ + .text : { + *(.text .text.*) + SCHED_TEXT + LOCK_TEXT + KPROBES_TEXT + *(.fixup) +#ifdef CONFIG_PPC32 + *(.got1) + __got2_start = .; + *(.got2) + __got2_end = .; +#endif /* CONFIG_PPC32 */ + + . = ALIGN(PAGE_SIZE); + _etext = .; + PROVIDE32 (etext = .); + } + + /* Read-only data */ + RODATA + + /* Exception & bug tables */ __ex_table : { __start___ex_table = .; *(__ex_table) @@ -67,192 +68,172 @@ SECTIONS __stop___bug_table = .; } -#ifdef CONFIG_PPC64 +/* + * Init sections discarded at runtime + */ + . = ALIGN(PAGE_SIZE); + __init_begin = .; + + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + + /* .exit.text is discarded at runtime, not link time, + * to deal with references from __bug_table + */ + .exit.text : { *(.exit.text) } + + .init.data : { + *(.init.data); + __vtop_table_begin = .; + *(.vtop_fixup); + __vtop_table_end = .; + __ptov_table_begin = .; + *(.ptov_fixup); + __ptov_table_end = .; + } + + . = ALIGN(16); + .init.setup : { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } + + .initcall.init : { + __initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + __initcall_end = .; + } + + .con_initcall.init : { + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + } + + SECURITY_INIT + + . = ALIGN(8); __ftr_fixup : { __start___ftr_fixup = .; *(__ftr_fixup) __stop___ftr_fixup = .; } - RODATA -#endif + . = ALIGN(PAGE_SIZE); + .init.ramfs : { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + } #ifdef CONFIG_PPC32 - /* Read-write section, merged into data segment: */ - . = ALIGN(PAGE_SIZE); - _sdata = .; - .data : - { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.got.plt) *(.got) - *(.dynamic) - CONSTRUCTORS - } - - . = ALIGN(PAGE_SIZE); - __nosave_begin = .; - .data_nosave : { *(.data.nosave) } - . = ALIGN(PAGE_SIZE); - __nosave_end = .; - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - _edata = .; - PROVIDE (edata = .); - - . = ALIGN(8192); - .data.init_task : { *(.data.init_task) } + . = ALIGN(32); +#else + . = ALIGN(128); #endif + .data.percpu : { + __per_cpu_start = .; + *(.data.percpu) + __per_cpu_end = .; + } - /* will be freed after init */ - . = ALIGN(PAGE_SIZE); - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } -#ifdef CONFIG_PPC32 - /* .exit.text is discarded at runtime, not link time, - to deal with references from __bug_table */ - .exit.text : { *(.exit.text) } -#endif - .init.data : { - *(.init.data); - __vtop_table_begin = .; - *(.vtop_fixup); - __vtop_table_end = .; - __ptov_table_begin = .; - *(.ptov_fixup); - __ptov_table_end = .; - } - - . = ALIGN(16); - .init.setup : { - __setup_start = .; - *(.init.setup) - __setup_end = .; - } - - .initcall.init : { - __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - __initcall_end = .; - } - - .con_initcall.init : { - __con_initcall_start = .; - *(.con_initcall.init) - __con_initcall_end = .; - } - - SECURITY_INIT + . = ALIGN(8); + .machine.desc : { + __machine_desc_start = . ; + *(.machine.desc) + __machine_desc_end = . ; + } + + /* freed after init ends here */ + . = ALIGN(PAGE_SIZE); + __init_end = .; + +/* + * And now the various read/write data + */ + + . = ALIGN(PAGE_SIZE); + _sdata = .; #ifdef CONFIG_PPC32 - __start___ftr_fixup = .; - __ftr_fixup : { *(__ftr_fixup) } - __stop___ftr_fixup = .; + .data : + { + *(.data) + *(.sdata) + *(.got.plt) *(.got) + } #else - . = ALIGN(PAGE_SIZE); - .init.ramfs : { - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; - } -#endif + .data : { + *(.data .data.rel* .toc1) + *(.branch_lt) + } -#ifdef CONFIG_PPC32 - . = ALIGN(32); + .opd : { + *(.opd) + } + + .got : { + __toc_start = .; + *(.got) + *(.toc) + } #endif - .data.percpu : { - __per_cpu_start = .; - *(.data.percpu) - __per_cpu_end = .; - } - . = ALIGN(PAGE_SIZE); -#ifdef CONFIG_PPC64 - . = ALIGN(16384); - __init_end = .; - /* freed after init ends here */ - - /* Read/write sections */ - . = ALIGN(PAGE_SIZE); - . = ALIGN(16384); - _sdata = .; - /* The initial task and kernel stack */ - .data.init_task : { - *(.data.init_task) - } - - . = ALIGN(PAGE_SIZE); - .data.page_aligned : { - *(.data.page_aligned) - } - - .data.cacheline_aligned : { - *(.data.cacheline_aligned) - } - - .data : { - *(.data .data.rel* .toc1) - *(.branch_lt) - } - - .opd : { - *(.opd) - } - - .got : { - __toc_start = .; - *(.got) - *(.toc) - . = ALIGN(PAGE_SIZE); - _edata = .; - } - - . = ALIGN(PAGE_SIZE); + . = ALIGN(PAGE_SIZE); + _edata = .; + PROVIDE32 (edata = .); + + /* The initial task and kernel stack */ +#ifdef CONFIG_PPC32 + . = ALIGN(8192); #else - __initramfs_start = .; - .init.ramfs : { - *(.init.ramfs) - } - __initramfs_end = .; + . = ALIGN(16384); +#endif + .data.init_task : { + *(.data.init_task) + } - . = ALIGN(4096); - __init_end = .; + . = ALIGN(PAGE_SIZE); + .data.page_aligned : { + *(.data.page_aligned) + } - . = ALIGN(4096); - _sextratext = .; - _eextratext = .; + .data.cacheline_aligned : { + *(.data.cacheline_aligned) + } - __bss_start = .; -#endif + . = ALIGN(PAGE_SIZE); + __data_nosave : { + __nosave_begin = .; + *(.data.nosave) + . = ALIGN(PAGE_SIZE); + __nosave_end = .; + } - .bss : { - __bss_start = .; - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - __bss_stop = .; - } +/* + * And finally the bss + */ + + .bss : { + __bss_start = .; + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + __bss_stop = .; + } -#ifdef CONFIG_PPC64 - . = ALIGN(PAGE_SIZE); -#endif - _end = . ; -#ifdef CONFIG_PPC32 - PROVIDE (end = .); -#endif + . = ALIGN(PAGE_SIZE); + _end = . ; + PROVIDE32 (end = .); } |