summaryrefslogtreecommitdiffstats
path: root/arch/ppc
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-03-12 23:15:27 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-03-12 23:15:27 +0000
commitae38fd1e4c98588314a42097c5a5e77dcef23561 (patch)
treef9f10c203bb9e5fbad4810d1f8774c08dfad20ff /arch/ppc
parent466a823d79f41d0713b272e48fd73e494b0588e0 (diff)
Merge with Linux 2.3.50.
Diffstat (limited to 'arch/ppc')
-rw-r--r--arch/ppc/configs/common_defconfig19
-rw-r--r--arch/ppc/defconfig19
-rw-r--r--arch/ppc/kernel/Makefile4
-rw-r--r--arch/ppc/kernel/feature.c3
-rw-r--r--arch/ppc/kernel/head.S11
-rw-r--r--arch/ppc/kernel/irq.c159
-rw-r--r--arch/ppc/kernel/pci.c50
-rw-r--r--arch/ppc/kernel/pmac_pic.c1
-rw-r--r--arch/ppc/kernel/pmac_setup.c17
-rw-r--r--arch/ppc/kernel/ppc_htab.c12
-rw-r--r--arch/ppc/kernel/prom.c80
-rw-r--r--arch/ppc/kernel/setup.c10
-rw-r--r--arch/ppc/mm/init.c5
-rw-r--r--arch/ppc/xmon/start.c26
-rw-r--r--arch/ppc/xmon/xmon.c32
15 files changed, 321 insertions, 127 deletions
diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig
index 4ba96bde9..c849bac82 100644
--- a/arch/ppc/configs/common_defconfig
+++ b/arch/ppc/configs/common_defconfig
@@ -92,7 +92,14 @@ CONFIG_BLK_DEV_IDESCSI=y
#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_IDEDMA_PCI is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_AEC6210 is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_SL82C105=y
CONFIG_BLK_DEV_IDE_PMAC=y
CONFIG_BLK_DEV_IDEDMA_PMAC=y
@@ -194,6 +201,7 @@ CONFIG_SCSI_CONSTANTS=y
#
# SCSI low-level drivers
#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
@@ -249,7 +257,6 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20
CONFIG_SCSI_MESH=y
CONFIG_SCSI_MESH_SYNC_RATE=5
CONFIG_SCSI_MAC53C94=y
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
#
# IEEE 1394 (FireWire) support
@@ -266,6 +273,7 @@ CONFIG_NETDEVICES=y
#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_ETHERTAP is not set
# CONFIG_NET_SB1000 is not set
@@ -389,7 +397,7 @@ CONFIG_FB_MATROX_MYSTIQUE=y
CONFIG_FB_MATROX_G100=y
# CONFIG_FB_MATROX_MULTIHEAD is not set
CONFIG_FB_ATY=y
-CONFIG_FB_ATY128=y
+# CONFIG_FB_ATY128 is not set
CONFIG_FB_3DFX=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
@@ -448,6 +456,7 @@ CONFIG_PSMOUSE=y
# CONFIG_WATCHDOG is not set
CONFIG_NVRAM=y
# CONFIG_RTC is not set
+# CONFIG_EFI_RTC is not set
#
# Video For Linux
@@ -496,6 +505,8 @@ CONFIG_USB_OHCI=y
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_DABUSB is not set
# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RIO500 is not set
#
# USB HID
@@ -503,7 +514,7 @@ CONFIG_USB_OHCI=y
# CONFIG_USB_HID is not set
CONFIG_USB_KBD=y
CONFIG_USB_MOUSE=y
-# CONFIG_USB_GRAPHIRE is not set
+# CONFIG_USB_WACOM is not set
# CONFIG_USB_WMFORCE is not set
CONFIG_INPUT_KEYBDEV=y
CONFIG_INPUT_MOUSEDEV=y
diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig
index 4ba96bde9..c849bac82 100644
--- a/arch/ppc/defconfig
+++ b/arch/ppc/defconfig
@@ -92,7 +92,14 @@ CONFIG_BLK_DEV_IDESCSI=y
#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_IDEDMA_PCI is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_AEC6210 is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_SL82C105=y
CONFIG_BLK_DEV_IDE_PMAC=y
CONFIG_BLK_DEV_IDEDMA_PMAC=y
@@ -194,6 +201,7 @@ CONFIG_SCSI_CONSTANTS=y
#
# SCSI low-level drivers
#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
@@ -249,7 +257,6 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20
CONFIG_SCSI_MESH=y
CONFIG_SCSI_MESH_SYNC_RATE=5
CONFIG_SCSI_MAC53C94=y
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
#
# IEEE 1394 (FireWire) support
@@ -266,6 +273,7 @@ CONFIG_NETDEVICES=y
#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_ETHERTAP is not set
# CONFIG_NET_SB1000 is not set
@@ -389,7 +397,7 @@ CONFIG_FB_MATROX_MYSTIQUE=y
CONFIG_FB_MATROX_G100=y
# CONFIG_FB_MATROX_MULTIHEAD is not set
CONFIG_FB_ATY=y
-CONFIG_FB_ATY128=y
+# CONFIG_FB_ATY128 is not set
CONFIG_FB_3DFX=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
@@ -448,6 +456,7 @@ CONFIG_PSMOUSE=y
# CONFIG_WATCHDOG is not set
CONFIG_NVRAM=y
# CONFIG_RTC is not set
+# CONFIG_EFI_RTC is not set
#
# Video For Linux
@@ -496,6 +505,8 @@ CONFIG_USB_OHCI=y
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_DABUSB is not set
# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RIO500 is not set
#
# USB HID
@@ -503,7 +514,7 @@ CONFIG_USB_OHCI=y
# CONFIG_USB_HID is not set
CONFIG_USB_KBD=y
CONFIG_USB_MOUSE=y
-# CONFIG_USB_GRAPHIRE is not set
+# CONFIG_USB_WACOM is not set
# CONFIG_USB_WMFORCE is not set
CONFIG_INPUT_KEYBDEV=y
CONFIG_INPUT_MOUSEDEV=y
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 0f7167622..73db2269e 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -98,7 +98,7 @@ ifeq ($(CONFIG_ALL_PPC),y)
OX_OBJS += prep_setup.o
endif
ifeq ($(CONFIG_GEMINI),y)
- O_OBJS += gemini_prom.o gemini_pci.o gemini_setup.o
+ O_OBJS += gemini_prom.o gemini_pci.o gemini_setup.o open_pic.o
endif
all: $(KHEAD) kernel.o
@@ -114,6 +114,8 @@ ppc_defs.h: mk_defs.c ppc_defs.head \
$(TOPDIR)/include/asm/ptrace.h
$(CC) $(CFLAGS) -S mk_defs.c
cp ppc_defs.head ppc_defs.h
+# for bk, this way we can write to the file even if it's not checked out
+ chmod u+w ppc_defs.h
grep '^#define' mk_defs.s >> ppc_defs.h
rm mk_defs.s
diff --git a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c
index 156eb187e..d14c7380a 100644
--- a/arch/ppc/kernel/feature.c
+++ b/arch/ppc/kernel/feature.c
@@ -154,6 +154,9 @@ feature_init(void)
{
struct device_node *np;
+ if (_machine != _MACH_Pmac)
+ return;
+
np = find_devices("mac-io");
while (np != NULL) {
/* KeyLargo contains several (5 ?) FCR registers in mac-io,
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index b6d44ecb3..dab413c15 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -222,7 +222,7 @@ __after_prom_start:
mtspr IBAT0L,r8
mtspr IBAT0U,r11
#if 0 /* Useful debug code, please leave in for now so I don't have to
- * look at docs when I need to setup a BAT ;
+ * look at docs when I need to setup a BAT ...
*/
bl setup_screen_bat
#endif
@@ -256,6 +256,8 @@ __after_prom_start:
* prep needs the mmu to be turned on here, but pmac already has it on.
* this shouldn't bother the pmac since it just gets turned on again
* as we jump to our code at KERNELBASE. -- Cort
+ * Actually no, pmac doesn't have it on any more. BootX enters with MMU
+ * off, and in other cases, we now turn it off before changing BATs above.
*/
turn_on_mmu:
mfmsr r0
@@ -1423,6 +1425,7 @@ start_here:
li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
mtspr SRR0,r4
mtspr SRR1,r3
+ SYNC
rfi
/* Load up the kernel context */
2:
@@ -1433,6 +1436,7 @@ start_here:
tlbsync /* ... on all CPUs */
sync
#endif
+
bl load_up_mmu
/* Set up for using our exception vectors */
@@ -1448,6 +1452,7 @@ start_here:
ori r3,r3,start_kernel@l
mtspr SRR0,r3
mtspr SRR1,r4
+ SYNC
rfi /* enable MMU and jump to start_kernel */
/*
@@ -1530,11 +1535,11 @@ setup_screen_bat:
li r3,0
mtspr DBAT1U,r3
mtspr IBAT1U,r3
- lis r3, 0x9100
+ lis r3, 0x8200
ori r4,r3,0x2a
mtspr DBAT1L,r4
mtspr IBAT1L,r4
- ori r3,r3,(BL_8M<<2)|0x2 /* set up BAT registers for 604 */
+ ori r3,r3,(BL_16M<<2)|0x2 /* set up BAT registers for 604 */
mtspr DBAT1U,r3
mtspr IBAT1U,r3
blr
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index ffac1871a..f8e11ecc0 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -45,7 +45,9 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/irq.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
#include <asm/bitops.h>
#include <asm/hydra.h>
#include <asm/system.h>
@@ -611,3 +613,160 @@ void __global_restore_flags(unsigned long flags)
}
#endif /* __SMP__ */
+static struct proc_dir_entry * root_irq_dir;
+static struct proc_dir_entry * irq_dir [NR_IRQS];
+static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+
+unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0xffffffff};
+
+#define HEX_DIGITS 8
+
+static int irq_affinity_read_proc (char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ if (count < HEX_DIGITS+1)
+ return -EINVAL;
+ return sprintf (page, "%08x\n", irq_affinity[(int)data]);
+}
+
+static unsigned int parse_hex_value (const char *buffer,
+ unsigned long count, unsigned long *ret)
+{
+ unsigned char hexnum [HEX_DIGITS];
+ unsigned long value;
+ int i;
+
+ if (!count)
+ return -EINVAL;
+ if (count > HEX_DIGITS)
+ count = HEX_DIGITS;
+ if (copy_from_user(hexnum, buffer, count))
+ return -EFAULT;
+
+ /*
+ * Parse the first 8 characters as a hex string, any non-hex char
+ * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+ */
+ value = 0;
+
+ for (i = 0; i < count; i++) {
+ unsigned int c = hexnum[i];
+
+ switch (c) {
+ case '0' ... '9': c -= '0'; break;
+ case 'a' ... 'f': c -= 'a'-10; break;
+ case 'A' ... 'F': c -= 'A'-10; break;
+ default:
+ goto out;
+ }
+ value = (value << 4) | c;
+ }
+out:
+ *ret = value;
+ return 0;
+}
+
+static int irq_affinity_write_proc (struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ int irq = (int) data, full_count = count, err;
+ unsigned long new_value;
+
+ if (!irq_desc[irq].handler->set_affinity)
+ return -EIO;
+
+ err = parse_hex_value(buffer, count, &new_value);
+
+#if CONFIG_SMP
+ /*
+ * Do not allow disabling IRQs completely - it's a too easy
+ * way to make the system unusable accidentally :-) At least
+ * one online CPU still has to be targeted.
+ */
+ if (!(new_value & cpu_online_map))
+ return -EINVAL;
+#endif
+
+ irq_affinity[irq] = new_value;
+ irq_desc[irq].handler->set_affinity(irq, new_value);
+
+ return full_count;
+}
+
+static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ unsigned long *mask = (unsigned long *) data;
+ if (count < HEX_DIGITS+1)
+ return -EINVAL;
+ return sprintf (page, "%08lx\n", *mask);
+}
+
+static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ unsigned long *mask = (unsigned long *) data, full_count = count, err;
+ unsigned long new_value;
+
+ err = parse_hex_value(buffer, count, &new_value);
+ if (err)
+ return err;
+
+ *mask = new_value;
+ return full_count;
+}
+
+#define MAX_NAMELEN 10
+
+static void register_irq_proc (unsigned int irq)
+{
+ struct proc_dir_entry *entry;
+ char name [MAX_NAMELEN];
+
+ if (!root_irq_dir || (irq_desc[irq].handler == NULL))
+ return;
+
+ memset(name, 0, MAX_NAMELEN);
+ sprintf(name, "%d", irq);
+
+ /* create /proc/irq/1234 */
+ irq_dir[irq] = proc_mkdir(name, root_irq_dir);
+
+ /* create /proc/irq/1234/smp_affinity */
+ entry = create_proc_entry("smp_affinity", 0700, irq_dir[irq]);
+
+ entry->nlink = 1;
+ entry->data = (void *)irq;
+ entry->read_proc = irq_affinity_read_proc;
+ entry->write_proc = irq_affinity_write_proc;
+
+ smp_affinity_entry[irq] = entry;
+}
+
+unsigned long prof_cpu_mask = -1;
+
+void init_irq_proc (void)
+{
+ struct proc_dir_entry *entry;
+ int i;
+
+ /* create /proc/irq */
+ root_irq_dir = proc_mkdir("irq", 0);
+
+ /* create /proc/irq/prof_cpu_mask */
+ entry = create_proc_entry("prof_cpu_mask", 0700, root_irq_dir);
+
+ entry->nlink = 1;
+ entry->data = (void *)&prof_cpu_mask;
+ entry->read_proc = prof_cpu_mask_read_proc;
+ entry->write_proc = prof_cpu_mask_write_proc;
+
+ /*
+ * Create entries for all existing IRQs.
+ */
+ for (i = 0; i < NR_IRQS; i++) {
+ if (irq_desc[i].handler == NULL)
+ continue;
+ register_irq_proc(i);
+ }
+}
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 8326bc369..773c99b5c 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -131,11 +131,6 @@ char __init *pcibios_setup(char *str)
return str;
}
-int pcibios_assign_resource(struct pci_dev *pdev, int resource)
-{
- return 0;
-}
-
/* the next two are stolen from the alpha port... */
void __init
pcibios_update_resource(struct pci_dev *dev, struct resource *root,
@@ -189,48 +184,3 @@ int pcibios_enable_device(struct pci_dev *dev)
}
return 0;
}
-
-/*
- * Assign new address to PCI resource. We hope our resource information
- * is complete. We don't re-assign resources unless we are
- * forced to do so.
- *
- * Expects start=0, end=size-1, flags=resource type.
- */
-
-int pci_assign_resource(struct pci_dev *dev, int i)
-{
- struct resource *r = &dev->resource[i];
- struct resource *pr = pci_find_parent_resource(dev, r);
- unsigned long size = r->end + 1;
- u32 new, check;
-
- if (!pr) {
- printk(KERN_ERR "PCI: Cannot find parent resource for device %s\n", dev->slot_name);
- return -EINVAL;
- }
- if (r->flags & IORESOURCE_IO) {
- if (allocate_resource(pr, r, size, 0x100, ~0, size, NULL, NULL)) {
- printk(KERN_ERR "PCI: Allocation of I/O region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
- return -EBUSY;
- }
- } else {
- if (allocate_resource(pr, r, size, 0x10000, ~0, size, NULL, NULL)) {
- printk(KERN_ERR "PCI: Allocation of memory region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
- return -EBUSY;
- }
- }
- if (i < 6) {
- int reg = PCI_BASE_ADDRESS_0 + 4*i;
- new = r->start | (r->flags & PCI_REGION_FLAG_MASK);
- pci_write_config_dword(dev, reg, new);
- pci_read_config_dword(dev, reg, &check);
- if (new != check)
- printk(KERN_ERR "PCI: Error while updating region %s/%d (%08x != %08x)\n", dev->slot_name, i, new, check);
- } else if (i == PCI_ROM_RESOURCE) {
- r->flags |= PCI_ROM_ADDRESS_ENABLE;
- pci_write_config_dword(dev, dev->rom_base_reg, r->start | (r->flags & PCI_REGION_FLAG_MASK));
- }
- printk("PCI: Assigned addresses %08lx-%08lx to region %s/%d\n", r->start, r->end, dev->slot_name, i);
- return 0;
-}
diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c
index b0276ca2c..f2794ae5a 100644
--- a/arch/ppc/kernel/pmac_pic.c
+++ b/arch/ppc/kernel/pmac_pic.c
@@ -10,6 +10,7 @@
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/prom.h>
+#include <asm/pci-bridge.h>
#include "pmac_pic.h"
/* pmac */struct pmac_irq_hw {
diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c
index 5fef07e89..c2c4cbbf4 100644
--- a/arch/ppc/kernel/pmac_setup.c
+++ b/arch/ppc/kernel/pmac_setup.c
@@ -283,8 +283,6 @@ pmac_setup_arch(void)
ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
? "enabled" : "disabled");
- feature_init();
-
#ifdef CONFIG_KGDB
zs_kgdb_hook(0);
#endif
@@ -325,14 +323,15 @@ static void __init init_p2pbridge(void)
|| p2pbridge->parent == NULL
|| strcmp(p2pbridge->parent->name, "pci") != 0)
return;
-
if (pci_device_loc(p2pbridge, &bus, &devfn) < 0)
return;
-
- pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val);
+ if (ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val) < 0) {
+ printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n");
+ return;
+ }
val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
- pcibios_write_config_word(bus, devfn, PCI_BRIDGE_CONTROL, val);
- pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val);
+ ppc_md.pcibios_write_config_word(bus, devfn, PCI_BRIDGE_CONTROL, val);
+ ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val);
}
static void __init ohare_init(void)
@@ -703,8 +702,8 @@ pmac_progress(char *s, unsigned short hex)
{
if (disp_bi == 0)
return;
- drawstring(s);
- drawchar('\n');
+ prom_drawstring(s);
+ prom_drawchar('\n');
}
#endif CONFIG_BOOTX_TEXT
diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c
index da46f3c1c..441310e68 100644
--- a/arch/ppc/kernel/ppc_htab.c
+++ b/arch/ppc/kernel/ppc_htab.c
@@ -44,12 +44,6 @@ extern unsigned long htab_evicts;
extern unsigned long pte_misses;
extern unsigned long pte_errors;
-struct file_operations ppc_htab_operations = {
- llseek: ppc_htab_lseek,
- read: ppc_htab_read,
- write: ppc_htab_write,
-};
-
/* these will go into processor.h when I'm done debugging -- Cort */
#define MMCR0 952
#define MMCR0_PMC1_CYCLES (0x1<<7)
@@ -63,6 +57,12 @@ struct file_operations ppc_htab_operations = {
#define PMC1 953
#define PMC2 954
+struct file_operations ppc_htab_operations = {
+ llseek: ppc_htab_lseek,
+ read: ppc_htab_read,
+ write: ppc_htab_write,
+};
+
char *pmc1_lookup(unsigned long mmcr0)
{
switch ( mmcr0 & (0x7f<<7) )
diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c
index 4ee638f62..310e301e6 100644
--- a/arch/ppc/kernel/prom.c
+++ b/arch/ppc/kernel/prom.c
@@ -114,9 +114,9 @@ static struct device_node *allnodes = 0;
static void clearscreen(void);
static void flushscreen(void);
-void drawchar(char c);
-void drawstring(const char *c);
-static void drawhex(unsigned long v);
+void prom_drawchar(char c);
+void prom_drawstring(const char *c);
+void prom_drawhex(unsigned long v);
static void scrollscreen(void);
static void draw_byte(unsigned char c, long locX, long locY);
@@ -134,6 +134,8 @@ static long g_max_loc_Y = 0;
static unsigned char vga_font[cmapsz];
+int bootx_text_mapped = 1;
+
#endif /* CONFIG_BOOTX_TEXT */
@@ -257,7 +259,7 @@ prom_print(const char *msg)
{
#ifdef CONFIG_BOOTX_TEXT
if (RELOC(disp_bi) != 0)
- drawstring(msg);
+ prom_drawstring(msg);
#endif
return;
}
@@ -385,6 +387,7 @@ prom_init(int r3, int r4, prom_entry pp)
#ifdef CONFIG_BOOTX_TEXT
prom_print(RELOC("booting...\n"));
flushscreen();
+ RELOC(bootx_text_mapped) = 0;
#endif
return phys;
}
@@ -633,6 +636,7 @@ prom_init(int r3, int r4, prom_entry pp)
prom_welcome(PTRRELOC(RELOC(disp_bi)), phys);
prom_print(RELOC("booting...\n"));
}
+ RELOC(bootx_text_mapped) = 0;
#endif
return phys;
@@ -648,28 +652,30 @@ prom_welcome(boot_infos_t* bi, unsigned long phys)
prom_print(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n"));
prom_print(RELOC("\nstarted at : 0x"));
- drawhex(phys);
+ prom_drawhex(phys);
prom_print(RELOC("\nlinked at : 0x"));
- drawhex(KERNELBASE);
+ prom_drawhex(KERNELBASE);
prom_print(RELOC("\nframe buffer at : 0x"));
- drawhex((unsigned long)bi->dispDeviceBase);
+ prom_drawhex((unsigned long)bi->dispDeviceBase);
prom_print(RELOC(" (phys), 0x"));
- drawhex((unsigned long)bi->logicalDisplayBase);
+ prom_drawhex((unsigned long)bi->logicalDisplayBase);
prom_print(RELOC(" (log)"));
+ prom_print(RELOC("\nklimit : 0x"));
+ prom_drawhex(RELOC(klimit));
prom_print(RELOC("\nMSR : 0x"));
__asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
- drawhex(flags);
+ prom_drawhex(flags);
__asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
pvr >>= 16;
if (pvr > 1) {
prom_print(RELOC("\nHID0 : 0x"));
__asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
- drawhex(flags);
+ prom_drawhex(flags);
}
if (pvr == 8 || pvr == 12) {
prom_print(RELOC("\nICTC : 0x"));
__asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
- drawhex(flags);
+ prom_drawhex(flags);
}
prom_print(RELOC("\n\n"));
}
@@ -807,13 +813,18 @@ setup_disp_fake_bi(ihandle dp)
prom_print(RELOC("Initializing fake screen\n"));
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("width"), &width, sizeof(width));
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("height"), &height, sizeof(height));
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("depth"), &len, sizeof(len));
+ call_prom(RELOC("getprop"), 4, 1, dp, RELOC("width"),
+ &width, sizeof(width));
+ call_prom(RELOC("getprop"), 4, 1, dp, RELOC("height"),
+ &height, sizeof(height));
+ call_prom(RELOC("getprop"), 4, 1, dp, RELOC("depth"),
+ &depth, sizeof(depth));
pitch = width * ((depth + 7) / 8);
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("linebytes"), &len, sizeof(len));
+ call_prom(RELOC("getprop"), 4, 1, dp, RELOC("linebytes"),
+ &pitch, sizeof(pitch));
address = 0;
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("address"), &len, sizeof(len));
+ call_prom(RELOC("getprop"), 4, 1, dp, RELOC("address"),
+ &address, sizeof(address));
if (address == 0) {
prom_print(RELOC("Failed to get address\n"));
return;
@@ -837,7 +848,6 @@ setup_disp_fake_bi(ihandle dp)
bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0;
bi->dispDeviceRect[2] = width;
bi->dispDeviceRect[3] = height;
- RELOC(disp_bi) = 0;
}
#endif
@@ -1844,6 +1854,7 @@ map_bootx_text(void)
disp_bi->logicalDisplayBase =
ioremap((unsigned long) disp_bi->dispDeviceBase,
disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3]);
+ bootx_text_mapped = 1;
}
/* Calc the base address of a given point (x,y) */
@@ -1940,11 +1951,14 @@ scrollscreen(void)
__pmac
void
-drawchar(char c)
+prom_drawchar(char c)
{
unsigned long offset = reloc_offset();
int cline = 0, x;
+ if (!RELOC(bootx_text_mapped))
+ return;
+
switch (c) {
case '\b':
if (RELOC(g_loc_X) > 0)
@@ -1988,27 +2002,33 @@ drawchar(char c)
__pmac
void
-drawstring(const char *c)
+prom_drawstring(const char *c)
{
+ unsigned long offset = reloc_offset();
+
+ if (!RELOC(bootx_text_mapped))
+ return;
while (*c)
- drawchar(*c++);
+ prom_drawchar(*c++);
}
__pmac
-static void
-drawhex(unsigned long v)
+void
+prom_drawhex(unsigned long v)
{
static char hex_table[] = "0123456789abcdef";
unsigned long offset = reloc_offset();
- drawchar(RELOC(hex_table)[(v >> 28) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 24) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 20) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 16) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 12) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 8) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 4) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 0) & 0x0000000FUL]);
+ if (!RELOC(bootx_text_mapped))
+ return;
+ prom_drawchar(RELOC(hex_table)[(v >> 28) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 24) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 20) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 16) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 12) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 8) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 4) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 0) & 0x0000000FUL]);
}
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 5a57ba8a2..73a6c2bf7 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -29,6 +29,7 @@
#endif
#include <asm/bootx.h>
#include <asm/machdep.h>
+#include <asm/feature.h>
#ifdef CONFIG_OAK
#include "oak_setup.h"
#endif /* CONFIG_OAK */
@@ -417,7 +418,7 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
parse_bootinfo();
-
+
if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100);
#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
@@ -687,6 +688,7 @@ void __init setup_arch(char **cmdline_p)
ppc_md.setup_arch();
if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
+ paging_init();
}
void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
@@ -733,12 +735,12 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
id->eide_dma_time = __le16_to_cpu(id->eide_dma_time);
id->eide_pio = __le16_to_cpu(id->eide_pio);
id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
- for (i=0; i<2 i++)
+ for (i=0; i<2; i++)
id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
- for (i=0; i<4 i++)
+ for (i=0; i<4; i++)
id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
id->queue_depth = __le16_to_cpu(id->queue_depth);
- for (i=0; i<4 i++)
+ for (i=0; i<4; i++)
id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
id->major_rev_num = __le16_to_cpu(id->major_rev_num);
id->minor_rev_num = __le16_to_cpu(id->minor_rev_num);
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 2faccd042..eaa5924a2 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -961,8 +961,9 @@ void __init MMU_init(void)
}
#endif
#if 0
- setbat(0, disp_bi->dispDeviceBase, disp_bi->dispDeviceBase, 0x100000, IO_PAGE);
- disp_bi->logicalDisplayBase = disp_bi->dispDeviceBase;
+// This is bogus, BAT must be aligned.
+// setbat(0, disp_bi->dispDeviceBase, disp_bi->dispDeviceBase, 0x100000, IO_PAGE);
+// disp_bi->logicalDisplayBase = disp_bi->dispDeviceBase;
#endif
ioremap_base = 0xf0000000;
break;
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index 8e924699f..95b19ba47 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -17,12 +17,12 @@
static volatile unsigned char *sccc, *sccd;
unsigned long TXRDY, RXRDY;
extern void xmon_printf(const char *fmt, ...);
-extern void drawchar(char);
-extern void drawstring(const char *str);
+extern void prom_drawchar(char);
+extern void prom_drawstring(const char *str);
static int xmon_expect(const char *str, unsigned int timeout);
static int console = 0;
-static int use_screen = 0;
+static int use_screen = 1; /* default */
static int via_modem = 0;
static int xmon_use_sccb = 0;
static struct device_node *macio_node;
@@ -48,6 +48,8 @@ xmon_map_scc(void)
{
volatile unsigned char *base;
+ use_screen = 0;
+
if ( _machine == _MACH_Pmac )
{
struct device_node *np;
@@ -58,7 +60,7 @@ xmon_map_scc(void)
/* needs to be hacked if xmon_printk is to be used
from within find_via_pmu() */
if (!via_modem && disp_bi && find_via_pmu()) {
- drawstring("xmon uses screen and keyboard\n");
+ prom_drawstring("xmon uses screen and keyboard\n");
use_screen = 1;
return;
}
@@ -122,7 +124,7 @@ xmon_write(void *handle, void *ptr, int nb)
if (use_screen) {
/* write it on the screen */
for (i = 0; i < nb; ++i)
- drawchar(*p++);
+ prom_drawchar(*p++);
return nb;
}
#endif
@@ -142,6 +144,7 @@ xmon_write(void *handle, void *ptr, int nb)
ct = 1;
--i;
} else {
+ prom_drawchar(c);
if (console)
printk("%c", c);
ct = 0;
@@ -187,15 +190,15 @@ xmon_get_pmu_key(void)
do {
if (--t < 0) {
on = 1 - on;
- drawchar(on? 0xdb: 0x20);
- drawchar('\b');
+ prom_drawchar(on? 0xdb: 0x20);
+ prom_drawchar('\b');
t = 200000;
}
pmu_poll();
} while (xmon_pmu_keycode == -1);
k = xmon_pmu_keycode;
if (on)
- drawstring(" \b");
+ prom_drawstring(" \b");
/* test for shift keys */
if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
@@ -284,6 +287,8 @@ xmon_init_scc()
{
int i, x;
+ if (macio_node != 0)
+ feature_set(macio_node, FEATURE_Serial_enable);
if (via_modem && macio_node != 0) {
unsigned int t0;
@@ -399,15 +404,12 @@ int xmon_expect(const char *str, unsigned int timeout)
for (;;) {
c = xmon_read_poll();
if (c == -1) {
- if (readtb() - t0 > timeout) {
- printk("timeout\n");
+ if (readtb() - t0 > timeout)
return 0;
- }
continue;
}
if (c == '\n')
break;
- printk("%c", c);
if (c != '\r' && lineptr < &line[sizeof(line) - 1])
*lineptr++ = c;
}
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index d18d74dfd..620df9aea 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -119,7 +119,8 @@ void
xmon(struct pt_regs *excp)
{
struct pt_regs regs;
- int msr, cmd;
+ int msr, cmd, i;
+ unsigned *sp;
if (excp == NULL) {
asm volatile ("stw 0,0(%0)\n\
@@ -135,6 +136,29 @@ xmon(struct pt_regs *excp)
excp = &regs;
}
+ prom_drawstring("xmon pc="); prom_drawhex(excp->nip);
+ prom_drawstring(" lr="); prom_drawhex(excp->link);
+ prom_drawstring(" msr="); prom_drawhex(excp->msr);
+ prom_drawstring(" trap="); prom_drawhex(excp->trap);
+ prom_drawstring(" sp="); prom_drawhex(excp->gpr[1]);
+ sp = &excp->gpr[0];
+ for (i = 0; i < 32; ++i) {
+ if ((i & 7) == 0)
+ prom_drawstring("\n");
+ prom_drawstring(" ");
+ prom_drawhex(sp[i]);
+ }
+ sp = (unsigned *) excp->gpr[1];
+ for (i = 0; i < 64; ++i) {
+ if ((i & 7) == 0) {
+ prom_drawstring("\n");
+ prom_drawhex(sp);
+ prom_drawstring(" ");
+ }
+ prom_drawstring(" ");
+ prom_drawhex(sp[i]);
+ }
+ prom_drawstring("\n");
msr = get_msr();
set_msr(msr & ~0x8000); /* disable interrupts */
remove_bpts();
@@ -521,7 +545,7 @@ void
excprint(struct pt_regs *fp)
{
printf("vector: %x at pc = %x %s",
- fp->trap, fp->nip,/* pretty_lookup_name(fp->nip)*/"");
+ fp->trap, fp->nip, pretty_lookup_name(fp->nip));
printf(", msr = %x, sp = %x [%x]\n",
fp->msr, fp->gpr[1], fp);
if (fp->trap == 0x300 || fp->trap == 0x600)
@@ -1390,6 +1414,10 @@ static char *lookup_name(unsigned long addr)
if ( !sysmap || !sysmap_size )
return NULL;
+ /* adjust if addr is relative to kernelbase */
+ if ( addr < PAGE_OFFSET )
+ addr += PAGE_OFFSET;
+
cmp = simple_strtoul(c, &c, 8);
strcpy( last, strsep( &c, "\n"));
while ( c < (sysmap+sysmap_size) )