patch-2.4.19 linux-2.4.19/arch/ppc/kernel/pmac_setup.c
Next file: linux-2.4.19/arch/ppc/kernel/pmac_smp.c
Previous file: linux-2.4.19/arch/ppc/kernel/pmac_pci.c
Back to the patch index
Back to the overall index
- Lines: 393
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/ppc/kernel/pmac_setup.c
- Orig date:
Mon Feb 25 11:37:55 2002
diff -urN linux-2.4.18/arch/ppc/kernel/pmac_setup.c linux-2.4.19/arch/ppc/kernel/pmac_setup.c
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.pmac_setup.c 1.45 12/01/01 20:09:06 benh
+ * BK Id: SCCS/s.pmac_setup.c 1.54 04/16/02 20:08:22 paulus
*/
/*
* linux/arch/ppc/kernel/setup.c
@@ -50,6 +50,8 @@
#include <linux/cuda.h>
#include <linux/pmu.h>
#include <linux/seq_file.h>
+#include <linux/blkdev.h>
+#include <linux/genhd.h>
#include <asm/processor.h>
#include <asm/sections.h>
@@ -67,14 +69,14 @@
#include <asm/bootx.h>
#include <asm/cputable.h>
#include <asm/btext.h>
-
#include <asm/pmac_feature.h>
#include <asm/time.h>
+
#include "local_irq.h"
#include "pmac_pic.h"
-#include "../mm/mem_pieces.h"
-
-#undef SHOW_GATWICK_IRQS
+#include "mem_pieces.h"
+#include "scsi.h" /* sd_find_target */
+#include "sd.h"
extern long pmac_time_init(void);
extern unsigned long pmac_get_rtc_time(void);
@@ -140,26 +142,6 @@
#ifdef CONFIG_SMP
extern struct smp_ops_t psurge_smp_ops;
extern struct smp_ops_t core99_smp_ops;
-
-volatile static long int core99_l2_cache;
-void __init
-core99_init_l2(void)
-{
- int cpu = smp_processor_id();
-
- if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR))
- return;
-
- if (cpu == 0){
- core99_l2_cache = _get_L2CR();
- printk("CPU0: L2CR is %lx\n", core99_l2_cache);
- } else {
- printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
- _set_L2CR(0);
- _set_L2CR(core99_l2_cache);
- printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
- }
-}
#endif /* CONFIG_SMP */
/*
@@ -189,7 +171,15 @@
struct device_node *np;
char *pp;
int plen;
+ int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+ NULL, PMAC_MB_INFO_MODEL, 0);
+ unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+ NULL, PMAC_MB_INFO_FLAGS, 0);
+ char* mbname;
+ if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0)
+ mbname = "Unknown";
+
/* find motherboard type */
seq_printf(m, "machine\t\t: ");
np = find_devices("device-tree");
@@ -213,6 +203,10 @@
} else
seq_printf(m, "PowerMac\n");
+ /* print parsed model */
+ seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
+ seq_printf(m, "pmac flags\t: %08x\n", mbflags);
+
/* find l2 cache info */
np = find_devices("l2-cache");
if (np == 0)
@@ -275,16 +269,6 @@
return 0;
}
-#ifdef CONFIG_SCSI
-/* Find the device number for the disk (if any) at target tgt
- on host adaptor host. We just need to get the prototype from
- sd.h */
-#include <linux/blkdev.h>
-#include "../../../drivers/scsi/scsi.h"
-#include "../../../drivers/scsi/sd.h"
-
-#endif
-
#ifdef CONFIG_VT
/*
* Dummy mksound function that does nothing.
@@ -352,11 +336,6 @@
printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n",
ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
? "enabled" : "disabled");
-
-#ifdef CONFIG_SMP
- /* somewhat of a hack */
- core99_init_l2();
-#endif
#ifdef CONFIG_KGDB
zs_kgdb_hook(0);
@@ -444,6 +423,34 @@
pmac_feature_late_init();
}
+/* That include would have to be in include/linux/ ideally */
+#include "../../../fs/partitions/mac.h"
+
+/* Borrowed from fs/partition/check.c */
+static unsigned char* __init
+read_one_block(struct block_device *bdev, unsigned long n, struct page **v)
+{
+ struct address_space *mapping = bdev->bd_inode->i_mapping;
+ int sect = PAGE_CACHE_SIZE / 512;
+ struct page *page;
+
+ page = read_cache_page(mapping, n/sect,
+ (filler_t *)mapping->a_ops->readpage, NULL);
+ if (!IS_ERR(page)) {
+ wait_on_page(page);
+ if (!Page_Uptodate(page))
+ goto fail;
+ if (PageError(page))
+ goto fail;
+ *v = page;
+ return (unsigned char *)page_address(page) + 512 * (n % sect);
+fail:
+ page_cache_release(page);
+ }
+ *v = NULL;
+ return NULL;
+}
+
#ifdef CONFIG_SCSI
void __init
note_scsi_host(struct device_node *node, void *host)
@@ -473,7 +480,7 @@
}
}
}
-#endif
+#endif /* CONFIG_SCSI */
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
kdev_t __init
@@ -509,32 +516,132 @@
#endif
}
-/* can't be __init - can be called whenever a disk is first accessed */
-void __pmac
-note_bootable_part(kdev_t dev, int part, int goodness)
+static void __init
+check_bootable_part(kdev_t dev, int blk, struct mac_partition *part)
{
- static int found_boot = 0;
- char *p;
+ int goodness = 0;
+
+ macpart_fix_string(part->processor, 16);
+ macpart_fix_string(part->name, 32);
+ macpart_fix_string(part->type, 32);
+
+ if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
+ && strcasecmp(part->processor, "powerpc") == 0)
+ goodness++;
+
+ if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0
+ || (strnicmp(part->type, "Linux", 5) == 0
+ && strcasecmp(part->type, "Linux_swap") != 0)) {
+ int i, l;
+
+ goodness++;
+ l = strlen(part->name);
+ if (strcmp(part->name, "/") == 0)
+ goodness++;
+ for (i = 0; i <= l - 4; ++i) {
+ if (strnicmp(part->name + i, "root",
+ 4) == 0) {
+ goodness += 2;
+ break;
+ }
+ }
+ if (strnicmp(part->name, "swap", 4) == 0)
+ goodness--;
+ }
+
+ if (goodness > current_root_goodness) {
+ ROOT_DEV = MKDEV(MAJOR(dev), MINOR(dev) + blk);
+ current_root_goodness = goodness;
+ }
+}
- /* Do nothing if the root has been mounted already. */
- if (init_task.fs->rootmnt != NULL)
+static void __init
+check_bootable_disk(kdev_t dev, struct block_device *bdev)
+{
+ struct mac_partition *part;
+ struct mac_driver_desc *md;
+ struct page* pg;
+ unsigned secsize, blocks_in_map, blk;
+ unsigned char* data;
+
+ /* Check driver descriptor */
+ md = (struct mac_driver_desc *) read_one_block(bdev, 0, &pg);
+ if (!md)
return;
- if ((goodness <= current_root_goodness) &&
- (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE)))
+ if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC)
+ goto fail;
+ secsize = be16_to_cpu(md->block_size);
+ page_cache_release(pg);
+
+ /* Check if it looks like a mac partition map */
+ data = read_one_block(bdev, secsize/512, &pg);
+ if (!data)
+ goto fail;
+ part = (struct mac_partition *) (data + secsize%512);
+ if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
+ goto fail;
+
+ /* Iterate the partition map */
+ blocks_in_map = be32_to_cpu(part->map_count);
+ for (blk = 1; blk <= blocks_in_map; ++blk) {
+ int pos = blk * secsize;
+ page_cache_release(pg);
+ data = read_one_block(bdev, pos/512, &pg);
+ if (!data)
+ break;
+ part = (struct mac_partition *) (data + pos%512);
+ if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
+ break;
+ check_bootable_part(dev, blk, part);
+ }
+fail:
+ if (pg)
+ page_cache_release(pg);
+}
+
+static int __init
+walk_bootable(struct gendisk *hd, void *data)
+{
+ int drive;
+
+ for (drive=0; drive<hd->nr_real; drive++) {
+ kdev_t dev;
+ struct block_device *bdev;
+ int rc;
+
+ dev = MKDEV(hd->major, drive << hd->minor_shift);
+ if (boot_dev && boot_dev != dev)
+ continue;
+ bdev = bdget(kdev_t_to_nr(dev));
+ if (bdev == NULL)
+ continue;
+ rc = blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW);
+ if (rc == 0) {
+ check_bootable_disk(dev, bdev);
+ blkdev_put(bdev, BDEV_RAW);
+ }
+ }
+
+ return 0;
+}
+
+void __init
+pmac_discover_root(void)
+{
+ char* p;
+
+ /* Check if root devices already got selected by other ways */
+ if (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE))
return;
p = strstr(saved_command_line, "root=");
if (p != NULL && (p == saved_command_line || p[-1] == ' '))
return;
- if (!found_boot) {
- find_boot_device();
- found_boot = 1;
- }
- if (boot_dev == 0 || dev == boot_dev) {
- ROOT_DEV = MKDEV(MAJOR(dev), MINOR(dev) + part);
- boot_dev = NODEV;
- current_root_goodness = goodness;
- }
+ /* Find the device used for booting if we can */
+ find_boot_device();
+
+ /* Try to locate a partition */
+ walk_gendisk(walk_bootable, NULL);
}
void __pmac
@@ -664,7 +771,7 @@
* Read in a property describing some pieces of memory.
*/
-static void __init
+static int __init
get_mem_prop(char *name, struct mem_pieces *mp)
{
struct reg_property *rp;
@@ -677,7 +784,7 @@
if (ip == NULL) {
printk(KERN_ERR "error: couldn't get %s property on /memory\n",
name);
- abort();
+ return 0;
}
s /= (nsc + nac) * 4;
rp = mp->regions;
@@ -696,6 +803,7 @@
/* Make sure the pieces are sorted. */
mem_pieces_sort(mp);
mem_pieces_coalesce(mp);
+ return 1;
}
/*
@@ -711,12 +819,6 @@
unsigned long a, total;
struct mem_pieces phys_mem;
- memory_node = find_devices("memory");
- if (memory_node == NULL) {
- printk(KERN_ERR "can't find memory node\n");
- abort();
- }
-
/*
* Find out where physical memory is, and check that it
* starts at 0 and is contiguous. It seems that RAM is
@@ -727,8 +829,9 @@
* more complicated (or else you end up wasting space
* in mem_map).
*/
- get_mem_prop("reg", &phys_mem);
- if (phys_mem.n_regions == 0)
+ memory_node = find_devices("memory");
+ if (memory_node == NULL || !get_mem_prop("reg", &phys_mem)
+ || phys_mem.n_regions == 0)
panic("No RAM??");
a = phys_mem.regions[0].address;
if (a != 0)
@@ -805,6 +908,8 @@
ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook;
ppc_md.pcibios_after_init = pmac_pcibios_after_init;
+ ppc_md.discover_root = pmac_discover_root;
+
ppc_md.restart = pmac_restart;
ppc_md.power_off = pmac_power_off;
ppc_md.halt = pmac_halt;
@@ -841,15 +946,12 @@
}
#ifdef CONFIG_BOOTX_TEXT
-extern void drawchar(char c);
-extern void drawstring(const char *c);
-extern boot_infos_t *disp_bi;
void __init
pmac_progress(char *s, unsigned short hex)
{
- if (disp_bi == 0)
- return;
- btext_drawstring(s);
- btext_drawchar('\n');
+ if (boot_text_mapped) {
+ btext_drawstring(s);
+ btext_drawchar('\n');
+ }
}
#endif /* CONFIG_BOOTX_TEXT */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)