Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (36 commits) [POWERPC] Generic BUG for powerpc [PPC] Fix compile failure do to introduction of PHY_POLL [POWERPC] Only export __mtdcr/__mfdcr if CONFIG_PPC_DCR is set [POWERPC] Remove old dcr.S [POWERPC] Fix SPU coredump code for max_fdset removal [POWERPC] Fix irq routing on some 32-bit PowerMacs [POWERPC] ps3: Add vuart support [POWERPC] Support ibm,dynamic-reconfiguration-memory nodes [POWERPC] dont allow pSeries_probe to succeed without initialising MMU [POWERPC] micro optimise pSeries_probe [POWERPC] Add SPURR SPR to sysfs [POWERPC] Add DSCR SPR to sysfs [POWERPC] Fix 440SPe CPU table entry [POWERPC] Add support for FP emulation for the e300c2 core [POWERPC] of_device_register: propagate device_create_file return code [POWERPC] Fix mmap of PCI resource with hack for X [POWERPC] iSeries: head_64.o needs to depend on lparmap.s [POWERPC] cbe_thermal: Fix initialization of sysfs attribute_group [POWERPC] Remove QE header files from lite5200.c [POWERPC] of_platform_make_bus_id(): make `magic' int ...
This commit is contained in:
@@ -77,6 +77,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_PPC_ISERIES),y)
|
||||
extra-y += lparmap.s
|
||||
$(obj)/head_64.o: $(obj)/lparmap.s
|
||||
AFLAGS_head_64.o += -I$(obj)
|
||||
endif
|
||||
|
||||
|
@@ -833,7 +833,7 @@ static struct cpu_spec cpu_specs[] = {
|
||||
.pvr_mask = 0x7fff0000,
|
||||
.pvr_value = 0x00840000,
|
||||
.cpu_name = "e300c2",
|
||||
.cpu_features = CPU_FTRS_E300,
|
||||
.cpu_features = CPU_FTRS_E300C2,
|
||||
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
|
||||
.icache_bsize = 32,
|
||||
.dcache_bsize = 32,
|
||||
@@ -1136,8 +1136,7 @@ static struct cpu_spec cpu_specs[] = {
|
||||
.pvr_mask = 0xff000fff,
|
||||
.pvr_value = 0x53000890,
|
||||
.cpu_name = "440SPe Rev. A",
|
||||
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||
CPU_FTR_USE_TB,
|
||||
.cpu_features = CPU_FTRS_44X,
|
||||
.cpu_user_features = COMMON_USER_BOOKE,
|
||||
.icache_bsize = 32,
|
||||
.dcache_bsize = 32,
|
||||
|
@@ -437,6 +437,13 @@ Alignment:
|
||||
/* Floating-point unavailable */
|
||||
. = 0x800
|
||||
FPUnavailable:
|
||||
BEGIN_FTR_SECTION
|
||||
/*
|
||||
* Certain Freescale cores don't have a FPU and treat fp instructions
|
||||
* as a FP Unavailable exception. Redirect to illegal/emulation handling.
|
||||
*/
|
||||
b ProgramCheck
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE)
|
||||
EXCEPTION_PROLOG
|
||||
bne load_up_fpu /* if from user, just load it up */
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/bug.h>
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
@@ -290,23 +291,11 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||
struct module *me)
|
||||
{
|
||||
const Elf_Shdr *sect;
|
||||
int err;
|
||||
|
||||
me->arch.bug_table = NULL;
|
||||
me->arch.num_bugs = 0;
|
||||
|
||||
/* Find the __bug_table section, if present */
|
||||
sect = find_section(hdr, sechdrs, "__bug_table");
|
||||
if (sect != NULL) {
|
||||
me->arch.bug_table = (void *) sect->sh_addr;
|
||||
me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry);
|
||||
}
|
||||
|
||||
/*
|
||||
* Strictly speaking this should have a spinlock to protect against
|
||||
* traversals, but since we only traverse on BUG()s, a spinlock
|
||||
* could potentially lead to deadlock and thus be counter-productive.
|
||||
*/
|
||||
list_add(&me->arch.bug_list, &module_bug_list);
|
||||
err = module_bug_finalize(hdr, sechdrs, me);
|
||||
if (err) /* never true, currently */
|
||||
return err;
|
||||
|
||||
/* Apply feature fixups */
|
||||
sect = find_section(hdr, sechdrs, "__ftr_fixup");
|
||||
@@ -320,7 +309,7 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||
|
||||
void module_arch_cleanup(struct module *mod)
|
||||
{
|
||||
list_del(&mod->arch.bug_list);
|
||||
module_bug_cleanup(mod);
|
||||
}
|
||||
|
||||
struct bug_entry *module_find_bug(unsigned long bugaddr)
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include <linux/moduleloader.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/bug.h>
|
||||
#include <asm/module.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/firmware.h>
|
||||
@@ -439,23 +440,11 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||
const Elf_Shdr *sechdrs, struct module *me)
|
||||
{
|
||||
const Elf_Shdr *sect;
|
||||
int err;
|
||||
|
||||
me->arch.bug_table = NULL;
|
||||
me->arch.num_bugs = 0;
|
||||
|
||||
/* Find the __bug_table section, if present */
|
||||
sect = find_section(hdr, sechdrs, "__bug_table");
|
||||
if (sect != NULL) {
|
||||
me->arch.bug_table = (void *) sect->sh_addr;
|
||||
me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry);
|
||||
}
|
||||
|
||||
/*
|
||||
* Strictly speaking this should have a spinlock to protect against
|
||||
* traversals, but since we only traverse on BUG()s, a spinlock
|
||||
* could potentially lead to deadlock and thus be counter-productive.
|
||||
*/
|
||||
list_add(&me->arch.bug_list, &module_bug_list);
|
||||
err = module_bug_finalize(hdr, sechdrs, me);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Apply feature fixups */
|
||||
sect = find_section(hdr, sechdrs, "__ftr_fixup");
|
||||
@@ -475,7 +464,7 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||
|
||||
void module_arch_cleanup(struct module *mod)
|
||||
{
|
||||
list_del(&mod->arch.bug_list);
|
||||
module_bug_cleanup(mod);
|
||||
}
|
||||
|
||||
struct bug_entry *module_find_bug(unsigned long bugaddr)
|
||||
|
@@ -109,9 +109,7 @@ int of_device_register(struct of_device *ofdev)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
device_create_file(&ofdev->dev, &dev_attr_devspec);
|
||||
|
||||
return 0;
|
||||
return device_create_file(&ofdev->dev, &dev_attr_devspec);
|
||||
}
|
||||
|
||||
void of_device_unregister(struct of_device *ofdev)
|
||||
|
@@ -169,7 +169,7 @@ static void of_platform_make_bus_id(struct of_device *dev)
|
||||
char *name = dev->dev.bus_id;
|
||||
const u32 *reg;
|
||||
u64 addr;
|
||||
long magic;
|
||||
int magic;
|
||||
|
||||
/*
|
||||
* If it's a DCR based device, use 'd' for native DCRs
|
||||
|
@@ -736,25 +736,51 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
scan_OF_pci_childs_iterator(struct device_node* node, void* data)
|
||||
static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
|
||||
unsigned int devfn)
|
||||
{
|
||||
const unsigned int *reg;
|
||||
u8* fdata = (u8*)data;
|
||||
|
||||
reg = get_property(node, "reg", NULL);
|
||||
if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
|
||||
&& ((reg[0] >> 16) & 0xff) == fdata[0])
|
||||
return 1;
|
||||
return 0;
|
||||
struct device_node *np = NULL;
|
||||
const u32 *reg;
|
||||
unsigned int psize;
|
||||
|
||||
while ((np = of_get_next_child(parent, np)) != NULL) {
|
||||
reg = get_property(np, "reg", &psize);
|
||||
if (reg == NULL || psize < 4)
|
||||
continue;
|
||||
if (((reg[0] >> 8) & 0xff) == devfn)
|
||||
return np;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct device_node*
|
||||
scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
|
||||
{
|
||||
u8 filter_data[2] = {bus, dev_fn};
|
||||
|
||||
return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data);
|
||||
static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct device_node *parent, *np;
|
||||
|
||||
/* Are we a root bus ? */
|
||||
if (bus->self == NULL || bus->parent == NULL) {
|
||||
struct pci_controller *hose = pci_bus_to_hose(bus->number);
|
||||
if (hose == NULL)
|
||||
return NULL;
|
||||
return of_node_get(hose->arch_data);
|
||||
}
|
||||
|
||||
/* not a root bus, we need to get our parent */
|
||||
parent = scan_OF_for_pci_bus(bus->parent);
|
||||
if (parent == NULL)
|
||||
return NULL;
|
||||
|
||||
/* now iterate for children for a match */
|
||||
np = scan_OF_for_pci_dev(parent, bus->self->devfn);
|
||||
of_node_put(parent);
|
||||
|
||||
/* sanity check */
|
||||
if (strcmp(np->type, "pci") != 0)
|
||||
printk(KERN_WARNING "pci: wrong type \"%s\" for bridge %s\n",
|
||||
np->type, np->full_name);
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -763,43 +789,25 @@ scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
|
||||
struct device_node *
|
||||
pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
struct device_node *node;
|
||||
int busnr;
|
||||
struct device_node *parent, *np;
|
||||
|
||||
if (!have_of)
|
||||
return NULL;
|
||||
|
||||
/* Lookup the hose */
|
||||
busnr = bus->number;
|
||||
hose = pci_bus_to_hose(busnr);
|
||||
if (!hose)
|
||||
return NULL;
|
||||
|
||||
/* Check it has an OF node associated */
|
||||
node = (struct device_node *) hose->arch_data;
|
||||
if (!node)
|
||||
DBG("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn);
|
||||
parent = scan_OF_for_pci_bus(bus);
|
||||
if (parent == NULL)
|
||||
return NULL;
|
||||
DBG(" parent is %s\n", parent ? parent->full_name : "<NULL>");
|
||||
np = scan_OF_for_pci_dev(parent, devfn);
|
||||
of_node_put(parent);
|
||||
DBG(" result is %s\n", np ? np->full_name : "<NULL>");
|
||||
|
||||
/* Fixup bus number according to what OF think it is. */
|
||||
#ifdef CONFIG_PPC_PMAC
|
||||
/* The G5 need a special case here. Basically, we don't remap all
|
||||
* busses on it so we don't create the pci-OF-map. However, we do
|
||||
* remap the AGP bus and so have to deal with it. A future better
|
||||
* fix has to be done by making the remapping per-host and always
|
||||
* filling the pci_to_OF map. --BenH
|
||||
/* XXX most callers don't release the returned node
|
||||
* mostly because ppc64 doesn't increase the refcount,
|
||||
* we need to fix that.
|
||||
*/
|
||||
if (machine_is(powermac) && busnr >= 0xf0)
|
||||
busnr -= 0xf0;
|
||||
else
|
||||
#endif
|
||||
if (pci_to_OF_bus_map)
|
||||
busnr = pci_to_OF_bus_map[busnr];
|
||||
if (busnr == 0xff)
|
||||
return NULL;
|
||||
|
||||
/* Now, lookup childs of the hose */
|
||||
return scan_OF_childs_for_device(node->child, busnr, devfn);
|
||||
return np;
|
||||
}
|
||||
EXPORT_SYMBOL(pci_busdev_to_OF_node);
|
||||
|
||||
@@ -1544,7 +1552,7 @@ pci_resource_to_bus(struct pci_dev *pdev, struct resource *res)
|
||||
|
||||
|
||||
static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
|
||||
unsigned long *offset,
|
||||
resource_size_t *offset,
|
||||
enum pci_mmap_state mmap_state)
|
||||
{
|
||||
struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
|
||||
@@ -1556,7 +1564,9 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
|
||||
|
||||
/* If memory, add on the PCI bridge address offset */
|
||||
if (mmap_state == pci_mmap_mem) {
|
||||
#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
|
||||
*offset += hose->pci_mem_offset;
|
||||
#endif
|
||||
res_bit = IORESOURCE_MEM;
|
||||
} else {
|
||||
io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE;
|
||||
@@ -1624,9 +1634,6 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
|
||||
else
|
||||
prot |= _PAGE_GUARDED;
|
||||
|
||||
printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev),
|
||||
(unsigned long long)rp->start, prot);
|
||||
|
||||
return __pgprot(prot);
|
||||
}
|
||||
|
||||
@@ -1695,7 +1702,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
enum pci_mmap_state mmap_state,
|
||||
int write_combine)
|
||||
{
|
||||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
struct resource *rp;
|
||||
int ret;
|
||||
|
||||
@@ -1808,22 +1815,42 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
|
||||
resource_size_t *start, resource_size_t *end)
|
||||
{
|
||||
struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
|
||||
unsigned long offset = 0;
|
||||
resource_size_t offset = 0;
|
||||
|
||||
if (hose == NULL)
|
||||
return;
|
||||
|
||||
if (rsrc->flags & IORESOURCE_IO)
|
||||
offset = (void __iomem *)_IO_BASE - hose->io_base_virt
|
||||
+ hose->io_base_phys;
|
||||
offset = (unsigned long)hose->io_base_virt - _IO_BASE;
|
||||
|
||||
*start = rsrc->start + offset;
|
||||
*end = rsrc->end + offset;
|
||||
/* We pass a fully fixed up address to userland for MMIO instead of
|
||||
* a BAR value because X is lame and expects to be able to use that
|
||||
* to pass to /dev/mem !
|
||||
*
|
||||
* That means that we'll have potentially 64 bits values where some
|
||||
* userland apps only expect 32 (like X itself since it thinks only
|
||||
* Sparc has 64 bits MMIO) but if we don't do that, we break it on
|
||||
* 32 bits CHRPs :-(
|
||||
*
|
||||
* Hopefully, the sysfs insterface is immune to that gunk. Once X
|
||||
* has been fixed (and the fix spread enough), we can re-enable the
|
||||
* 2 lines below and pass down a BAR value to userland. In that case
|
||||
* we'll also have to re-enable the matching code in
|
||||
* __pci_mmap_make_offset().
|
||||
*
|
||||
* BenH.
|
||||
*/
|
||||
#if 0
|
||||
else if (rsrc->flags & IORESOURCE_MEM)
|
||||
offset = hose->pci_mem_offset;
|
||||
#endif
|
||||
|
||||
*start = rsrc->start - offset;
|
||||
*end = rsrc->end - offset;
|
||||
}
|
||||
|
||||
void __init
|
||||
pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
|
||||
int flags, char *name)
|
||||
void __init pci_init_resource(struct resource *res, resource_size_t start,
|
||||
resource_size_t end, int flags, char *name)
|
||||
{
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
|
@@ -682,7 +682,7 @@ int pci_proc_domain(struct pci_bus *bus)
|
||||
* Returns negative error code on failure, zero on success.
|
||||
*/
|
||||
static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
|
||||
unsigned long *offset,
|
||||
resource_size_t *offset,
|
||||
enum pci_mmap_state mmap_state)
|
||||
{
|
||||
struct pci_controller *hose = pci_bus_to_host(dev->bus);
|
||||
@@ -694,7 +694,9 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
|
||||
|
||||
/* If memory, add on the PCI bridge address offset */
|
||||
if (mmap_state == pci_mmap_mem) {
|
||||
#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
|
||||
*offset += hose->pci_mem_offset;
|
||||
#endif
|
||||
res_bit = IORESOURCE_MEM;
|
||||
} else {
|
||||
io_offset = (unsigned long)hose->io_base_virt - pci_io_base;
|
||||
@@ -762,9 +764,6 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
|
||||
else
|
||||
prot |= _PAGE_GUARDED;
|
||||
|
||||
printk(KERN_DEBUG "PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start,
|
||||
prot);
|
||||
|
||||
return __pgprot(prot);
|
||||
}
|
||||
|
||||
@@ -832,7 +831,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
|
||||
int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
enum pci_mmap_state mmap_state, int write_combine)
|
||||
{
|
||||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
struct resource *rp;
|
||||
int ret;
|
||||
|
||||
@@ -1333,20 +1332,41 @@ EXPORT_SYMBOL(pci_read_irq_line);
|
||||
|
||||
void pci_resource_to_user(const struct pci_dev *dev, int bar,
|
||||
const struct resource *rsrc,
|
||||
u64 *start, u64 *end)
|
||||
resource_size_t *start, resource_size_t *end)
|
||||
{
|
||||
struct pci_controller *hose = pci_bus_to_host(dev->bus);
|
||||
unsigned long offset = 0;
|
||||
resource_size_t offset = 0;
|
||||
|
||||
if (hose == NULL)
|
||||
return;
|
||||
|
||||
if (rsrc->flags & IORESOURCE_IO)
|
||||
offset = pci_io_base - (unsigned long)hose->io_base_virt +
|
||||
hose->io_base_phys;
|
||||
offset = (unsigned long)hose->io_base_virt - pci_io_base;
|
||||
|
||||
*start = rsrc->start + offset;
|
||||
*end = rsrc->end + offset;
|
||||
/* We pass a fully fixed up address to userland for MMIO instead of
|
||||
* a BAR value because X is lame and expects to be able to use that
|
||||
* to pass to /dev/mem !
|
||||
*
|
||||
* That means that we'll have potentially 64 bits values where some
|
||||
* userland apps only expect 32 (like X itself since it thinks only
|
||||
* Sparc has 64 bits MMIO) but if we don't do that, we break it on
|
||||
* 32 bits CHRPs :-(
|
||||
*
|
||||
* Hopefully, the sysfs insterface is immune to that gunk. Once X
|
||||
* has been fixed (and the fix spread enough), we can re-enable the
|
||||
* 2 lines below and pass down a BAR value to userland. In that case
|
||||
* we'll also have to re-enable the matching code in
|
||||
* __pci_mmap_make_offset().
|
||||
*
|
||||
* BenH.
|
||||
*/
|
||||
#if 0
|
||||
else if (rsrc->flags & IORESOURCE_MEM)
|
||||
offset = hose->pci_mem_offset;
|
||||
#endif
|
||||
|
||||
*start = rsrc->start - offset;
|
||||
*end = rsrc->end - offset;
|
||||
}
|
||||
|
||||
struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
|
||||
|
@@ -208,7 +208,7 @@ EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */
|
||||
extern long *intercept_table;
|
||||
EXPORT_SYMBOL(intercept_table);
|
||||
#endif /* CONFIG_PPC_STD_MMU_32 */
|
||||
#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
|
||||
#ifdef CONFIG_PPC_DCR_NATIVE
|
||||
EXPORT_SYMBOL(__mtdcr);
|
||||
EXPORT_SYMBOL(__mfdcr);
|
||||
#endif
|
||||
|
@@ -804,6 +804,56 @@ static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
|
||||
return of_read_ulong(p, s);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_PSERIES
|
||||
/*
|
||||
* Interpret the ibm,dynamic-memory property in the
|
||||
* /ibm,dynamic-reconfiguration-memory node.
|
||||
* This contains a list of memory blocks along with NUMA affinity
|
||||
* information.
|
||||
*/
|
||||
static int __init early_init_dt_scan_drconf_memory(unsigned long node)
|
||||
{
|
||||
cell_t *dm, *ls;
|
||||
unsigned long l, n;
|
||||
unsigned long base, size, lmb_size, flags;
|
||||
|
||||
ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
|
||||
if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t))
|
||||
return 0;
|
||||
lmb_size = dt_mem_next_cell(dt_root_size_cells, &ls);
|
||||
|
||||
dm = (cell_t *)of_get_flat_dt_prop(node, "ibm,dynamic-memory", &l);
|
||||
if (dm == NULL || l < sizeof(cell_t))
|
||||
return 0;
|
||||
|
||||
n = *dm++; /* number of entries */
|
||||
if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(cell_t))
|
||||
return 0;
|
||||
|
||||
for (; n != 0; --n) {
|
||||
base = dt_mem_next_cell(dt_root_addr_cells, &dm);
|
||||
flags = dm[3];
|
||||
/* skip DRC index, pad, assoc. list index, flags */
|
||||
dm += 4;
|
||||
/* skip this block if the reserved bit is set in flags (0x80)
|
||||
or if the block is not assigned to this partition (0x8) */
|
||||
if ((flags & 0x80) || !(flags & 0x8))
|
||||
continue;
|
||||
size = lmb_size;
|
||||
if (iommu_is_off) {
|
||||
if (base >= 0x80000000ul)
|
||||
continue;
|
||||
if ((base + size) > 0x80000000ul)
|
||||
size = 0x80000000ul - base;
|
||||
}
|
||||
lmb_add(base, size);
|
||||
}
|
||||
lmb_dump_all();
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define early_init_dt_scan_drconf_memory(node) 0
|
||||
#endif /* CONFIG_PPC_PSERIES */
|
||||
|
||||
static int __init early_init_dt_scan_memory(unsigned long node,
|
||||
const char *uname, int depth, void *data)
|
||||
@@ -812,6 +862,11 @@ static int __init early_init_dt_scan_memory(unsigned long node,
|
||||
cell_t *reg, *endp;
|
||||
unsigned long l;
|
||||
|
||||
/* Look for the ibm,dynamic-reconfiguration-memory node */
|
||||
if (depth == 1 &&
|
||||
strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0)
|
||||
return early_init_dt_scan_drconf_memory(node);
|
||||
|
||||
/* We are scanning "memory" nodes only */
|
||||
if (type == NULL) {
|
||||
/*
|
||||
|
@@ -679,7 +679,7 @@ static unsigned char ibm_architecture_vec[] = {
|
||||
/* option vector 5: PAPR/OF options */
|
||||
3 - 2, /* length */
|
||||
0, /* don't ignore, don't halt */
|
||||
OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES,
|
||||
OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY,
|
||||
};
|
||||
|
||||
/* Old method - ELF header with PT_NOTE sections */
|
||||
|
@@ -303,6 +303,12 @@ int rtas_token(const char *service)
|
||||
}
|
||||
EXPORT_SYMBOL(rtas_token);
|
||||
|
||||
int rtas_service_present(const char *service)
|
||||
{
|
||||
return rtas_token(service) != RTAS_UNKNOWN_SERVICE;
|
||||
}
|
||||
EXPORT_SYMBOL(rtas_service_present);
|
||||
|
||||
#ifdef CONFIG_RTAS_ERROR_LOGGING
|
||||
/*
|
||||
* Return the firmware-specified size of the error log buffer
|
||||
@@ -810,32 +816,6 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
/* This version can't take the spinlock, because it never returns */
|
||||
static struct rtas_args rtas_stop_self_args = {
|
||||
/* The token is initialized for real in setup_system() */
|
||||
.token = RTAS_UNKNOWN_SERVICE,
|
||||
.nargs = 0,
|
||||
.nret = 1,
|
||||
.rets = &rtas_stop_self_args.args[0],
|
||||
};
|
||||
|
||||
void rtas_stop_self(void)
|
||||
{
|
||||
struct rtas_args *rtas_args = &rtas_stop_self_args;
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
BUG_ON(rtas_args->token == RTAS_UNKNOWN_SERVICE);
|
||||
|
||||
printk("cpu %u (hwid %u) Ready to die...\n",
|
||||
smp_processor_id(), hard_smp_processor_id());
|
||||
enter_rtas(__pa(rtas_args));
|
||||
|
||||
panic("Alas, I survived.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Call early during boot, before mem init or bootmem, to retrieve the RTAS
|
||||
* informations from the device-tree and allocate the RMO buffer for userland
|
||||
@@ -880,9 +860,6 @@ void __init rtas_initialize(void)
|
||||
#endif
|
||||
rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region);
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
rtas_stop_self_args.token = rtas_token("stop-self");
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
#ifdef CONFIG_RTAS_ERROR_LOGGING
|
||||
rtas_last_error_token = rtas_token("rtas-last-error");
|
||||
#endif
|
||||
|
@@ -181,6 +181,8 @@ SYSFS_PMCSETUP(pmc6, SPRN_PMC6);
|
||||
SYSFS_PMCSETUP(pmc7, SPRN_PMC7);
|
||||
SYSFS_PMCSETUP(pmc8, SPRN_PMC8);
|
||||
SYSFS_PMCSETUP(purr, SPRN_PURR);
|
||||
SYSFS_PMCSETUP(spurr, SPRN_SPURR);
|
||||
SYSFS_PMCSETUP(dscr, SPRN_DSCR);
|
||||
|
||||
static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0);
|
||||
static SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1);
|
||||
@@ -194,6 +196,8 @@ static SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6);
|
||||
static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7);
|
||||
static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8);
|
||||
static SYSDEV_ATTR(purr, 0600, show_purr, NULL);
|
||||
static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL);
|
||||
static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr);
|
||||
|
||||
static void register_cpu_online(unsigned int cpu)
|
||||
{
|
||||
@@ -231,6 +235,12 @@ static void register_cpu_online(unsigned int cpu)
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_PURR))
|
||||
sysdev_create_file(s, &attr_purr);
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_SPURR))
|
||||
sysdev_create_file(s, &attr_spurr);
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_DSCR))
|
||||
sysdev_create_file(s, &attr_dscr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
@@ -272,6 +282,12 @@ static void unregister_cpu_online(unsigned int cpu)
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_PURR))
|
||||
sysdev_remove_file(s, &attr_purr);
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_SPURR))
|
||||
sysdev_remove_file(s, &attr_spurr);
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_DSCR))
|
||||
sysdev_remove_file(s, &attr_dscr);
|
||||
}
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/bug.h>
|
||||
|
||||
#include <asm/kdebug.h>
|
||||
#include <asm/pgtable.h>
|
||||
@@ -727,54 +728,9 @@ static int emulate_instruction(struct pt_regs *regs)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look through the list of trap instructions that are used for BUG(),
|
||||
* BUG_ON() and WARN_ON() and see if we hit one. At this point we know
|
||||
* that the exception was caused by a trap instruction of some kind.
|
||||
* Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
|
||||
* otherwise.
|
||||
*/
|
||||
extern struct bug_entry __start___bug_table[], __stop___bug_table[];
|
||||
|
||||
#ifndef CONFIG_MODULES
|
||||
#define module_find_bug(x) NULL
|
||||
#endif
|
||||
|
||||
struct bug_entry *find_bug(unsigned long bugaddr)
|
||||
int is_valid_bugaddr(unsigned long addr)
|
||||
{
|
||||
struct bug_entry *bug;
|
||||
|
||||
for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
|
||||
if (bugaddr == bug->bug_addr)
|
||||
return bug;
|
||||
return module_find_bug(bugaddr);
|
||||
}
|
||||
|
||||
static int check_bug_trap(struct pt_regs *regs)
|
||||
{
|
||||
struct bug_entry *bug;
|
||||
unsigned long addr;
|
||||
|
||||
if (regs->msr & MSR_PR)
|
||||
return 0; /* not in kernel */
|
||||
addr = regs->nip; /* address of trap instruction */
|
||||
if (addr < PAGE_OFFSET)
|
||||
return 0;
|
||||
bug = find_bug(regs->nip);
|
||||
if (bug == NULL)
|
||||
return 0;
|
||||
if (bug->line & BUG_WARNING_TRAP) {
|
||||
/* this is a WARN_ON rather than BUG/BUG_ON */
|
||||
printk(KERN_ERR "Badness in %s at %s:%ld\n",
|
||||
bug->function, bug->file,
|
||||
bug->line & ~BUG_WARNING_TRAP);
|
||||
dump_stack();
|
||||
return 1;
|
||||
}
|
||||
printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n",
|
||||
bug->function, bug->file, bug->line);
|
||||
|
||||
return 0;
|
||||
return is_kernel_addr(addr);
|
||||
}
|
||||
|
||||
void __kprobes program_check_exception(struct pt_regs *regs)
|
||||
@@ -782,6 +738,8 @@ void __kprobes program_check_exception(struct pt_regs *regs)
|
||||
unsigned int reason = get_reason(regs);
|
||||
extern int do_mathemu(struct pt_regs *regs);
|
||||
|
||||
/* We can now get here via a FP Unavailable exception if the core
|
||||
* has no FPU, in that case no reason flags will be set */
|
||||
#ifdef CONFIG_MATH_EMULATION
|
||||
/* (reason & REASON_ILLEGAL) would be the obvious thing here,
|
||||
* but there seems to be a hardware bug on the 405GP (RevD)
|
||||
@@ -808,7 +766,9 @@ void __kprobes program_check_exception(struct pt_regs *regs)
|
||||
return;
|
||||
if (debugger_bpt(regs))
|
||||
return;
|
||||
if (check_bug_trap(regs)) {
|
||||
|
||||
if (!(regs->msr & MSR_PR) && /* not user-mode */
|
||||
report_bug(regs->nip) == BUG_TRAP_TYPE_WARN) {
|
||||
regs->nip += 4;
|
||||
return;
|
||||
}
|
||||
|
@@ -62,11 +62,7 @@ SECTIONS
|
||||
__stop___ex_table = .;
|
||||
}
|
||||
|
||||
__bug_table : {
|
||||
__start___bug_table = .;
|
||||
*(__bug_table)
|
||||
__stop___bug_table = .;
|
||||
}
|
||||
BUG_TABLE
|
||||
|
||||
/*
|
||||
* Init sections discarded at runtime
|
||||
|
Reference in New Issue
Block a user