diff options
Diffstat (limited to 'arch/ppc')
-rw-r--r-- | arch/ppc/kernel/apus_setup.c | 3 | ||||
-rw-r--r-- | arch/ppc/kernel/chrp_pci.c | 1 | ||||
-rw-r--r-- | arch/ppc/kernel/chrp_setup.c | 102 | ||||
-rw-r--r-- | arch/ppc/kernel/gemini_setup.c | 2 | ||||
-rw-r--r-- | arch/ppc/kernel/idle.c | 5 | ||||
-rw-r--r-- | arch/ppc/kernel/irq.c | 14 | ||||
-rw-r--r-- | arch/ppc/kernel/m8xx_setup.c | 10 | ||||
-rw-r--r-- | arch/ppc/kernel/mbx_setup.c | 11 | ||||
-rw-r--r-- | arch/ppc/kernel/misc.S | 4 | ||||
-rw-r--r-- | arch/ppc/kernel/pci.c | 22 | ||||
-rw-r--r-- | arch/ppc/kernel/pmac_pci.c | 22 | ||||
-rw-r--r-- | arch/ppc/kernel/pmac_pic.c | 9 | ||||
-rw-r--r-- | arch/ppc/kernel/pmac_setup.c | 8 | ||||
-rw-r--r-- | arch/ppc/kernel/ppc_ksyms.c | 1 | ||||
-rw-r--r-- | arch/ppc/kernel/prep_setup.c | 3 | ||||
-rw-r--r-- | arch/ppc/kernel/setup.c | 19 | ||||
-rw-r--r-- | arch/ppc/mbx_defconfig | 2 | ||||
-rw-r--r-- | arch/ppc/mm/init.c | 297 |
18 files changed, 232 insertions, 303 deletions
diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c index 80377490a..353482a18 100644 --- a/arch/ppc/kernel/apus_setup.c +++ b/arch/ppc/kernel/apus_setup.c @@ -255,8 +255,7 @@ struct pci_bus * __init pci_scan_peer_bridge(int bus) /*********************************************************** SETUP */ /* From arch/m68k/kernel/setup.c. */ -void __init apus_setup_arch(unsigned long * memory_start_p, - unsigned long * memory_end_p) +void __init apus_setup_arch(void) { #ifdef CONFIG_APUS extern char cmd_line[]; diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c index da752ccb6..983a9f2eb 100644 --- a/arch/ppc/kernel/chrp_pci.c +++ b/arch/ppc/kernel/chrp_pci.c @@ -16,7 +16,6 @@ #include <asm/hydra.h> #include <asm/prom.h> #include <asm/gg2.h> -#include <asm/ide.h> #include <asm/machdep.h> #include "pci.h" diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c index 4f71def9a..58d2003c4 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/kernel/chrp_setup.c @@ -28,6 +28,7 @@ #include <linux/reboot.h> #include <linux/init.h> #include <linux/blk.h> +#include <linux/ide.h> #include <linux/ioport.h> #include <linux/console.h> #include <linux/pci.h> @@ -35,13 +36,12 @@ #include <linux/version.h> #include <linux/adb.h> #include <linux/module.h> +#include <linux/delay.h> #include <asm/mmu.h> #include <asm/processor.h> #include <asm/io.h> #include <asm/pgtable.h> -#include <linux/ide.h> -#include <asm/ide.h> #include <asm/prom.h> #include <asm/gg2.h> #include <asm/pci-bridge.h> @@ -227,7 +227,7 @@ static void __init sio_init(void) void __init -chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) +chrp_setup_arch(void) { extern char cmd_line[]; struct device_node *device; @@ -278,7 +278,7 @@ chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif - *memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p); + pmac_find_bridges(); /* Get the event scan rate for the rtas so we know how * often it expects a heartbeat. -- Cort @@ -363,10 +363,7 @@ int chrp_get_irq( struct pt_regs *regs ) irq = *chrp_int_ack_special; else irq = i8259_irq( smp_processor_id() ); - /* - * Acknowledge as soon as possible to allow i8259 - * interrupt nesting */ - openpic_eoi( smp_processor_id() ); + openpic_eoi( smp_processor_id() ); } if (irq == OPENPIC_VEC_SPURIOUS) /* @@ -374,6 +371,11 @@ int chrp_get_irq( struct pt_regs *regs ) * acknowledged */ irq = -1; + /* + * I would like to openpic_eoi here but there seem to be timing problems + * between the openpic ack and the openpic eoi. + * -- Cort + */ return irq; } @@ -382,89 +384,15 @@ void chrp_post_irq(int irq) /* * If it's an i8259 irq then we've already done the * openpic irq. So we just check to make sure the controller - * is an openpic and if it is then eoi -- Cort + * is an openpic and if it is then eoi + * + * We do it this way since our irq_desc[irq].ctl can change + * with RTL and no longer be open_pic -- Cort */ - if ( irq_desc[irq].ctl == &open_pic ) + if ( irq >= open_pic.irq_offset) openpic_eoi( smp_processor_id() ); } -#if 0 -void -chrp_do_IRQ(struct pt_regs *regs, - int cpu, - int isfake) -{ - int irq; - unsigned long bits = 0; - int openpic_eoi_done = 0; - -#ifdef __SMP__ - { - unsigned int loops = 1000000; - while (test_bit(0, &global_irq_lock)) { - if (smp_processor_id() == global_irq_holder) { - printk("uh oh, interrupt while we hold global irq lock!\n"); -#ifdef CONFIG_XMON - xmon(0); -#endif - break; - } - if (loops-- == 0) { - printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder); -#ifdef CONFIG_XMON - xmon(0); -#endif - } - } - } -#endif /* __SMP__ */ - - irq = openpic_irq(0); - if (irq == IRQ_8259_CASCADE) - { - /* - * This magic address generates a PCI IACK cycle. - * - * This should go in the above mask/ack code soon. -- Cort - */ - if ( chrp_int_ack_special ) - irq = *chrp_int_ack_special; - else - irq = i8259_irq(0); - /* - * Acknowledge as soon as possible to allow i8259 - * interrupt nesting */ - openpic_eoi(0); - openpic_eoi_done = 1; - } - if (irq == OPENPIC_VEC_SPURIOUS) - { - /* - * Spurious interrupts should never be - * acknowledged - */ - ppc_spurious_interrupts++; - openpic_eoi_done = 1; - goto out; - } - bits = 1UL << irq; - - if (irq < 0) - { - printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", - irq, regs->nip); - ppc_spurious_interrupts++; - } - else - { - ppc_irq_dispatch_handler( regs, irq ); - } -out: - if (!openpic_eoi_done) - openpic_eoi(0); -} -#endif - void __init chrp_init_IRQ(void) { struct device_node *np; diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c index 6e599cff2..23060ba26 100644 --- a/arch/ppc/kernel/gemini_setup.c +++ b/arch/ppc/kernel/gemini_setup.c @@ -134,7 +134,7 @@ extern int root_mountflags; extern char cmd_line[]; -void __init gemini_setup_arch(unsigned long *memstart, unsigned long *memend) +void __init gemini_setup_arch(void) { unsigned int cpu; extern char cmd_line[]; diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index 09066a848..8f03ac79a 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -293,11 +293,8 @@ void power_save(void) /* set the POW bit in the MSR, and enable interrupts * so we wake up sometime! */ + __sti(); /* this keeps rtl from getting confused -- Cort */ _nmask_and_or_msr(0, MSR_POW | MSR_EE); - - /* Disable interrupts again so restore_flags will - * work. */ - _nmask_and_or_msr(MSR_EE, 0); } restore_flags(msr); default: diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index 9c157d41b..9ab3589f6 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -296,15 +296,19 @@ asmlinkage void do_IRQ(struct pt_regs *regs, int isfake) irq = ppc_md.get_irq( regs ); if ( irq < 0 ) { - printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", - irq, regs->nip); - ppc_spurious_interrupts++; - return; + /* -2 means ignore, already handled */ + if (irq != -2) { + printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", + irq, regs->nip); + ppc_spurious_interrupts++; + } + goto out; } ppc_irq_dispatch_handler( regs, irq ); if ( ppc_md.post_irq ) ppc_md.post_irq( irq ); - + + out: hardirq_exit( cpu ); } diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c index f99f5b335..4d510612b 100644 --- a/arch/ppc/kernel/m8xx_setup.c +++ b/arch/ppc/kernel/m8xx_setup.c @@ -33,6 +33,7 @@ #include <linux/blk.h> #include <linux/ioport.h> #include <linux/ide.h> +#include <linux/bootmem.h> #include <asm/mmu.h> #include <asm/processor.h> @@ -83,13 +84,12 @@ void __init adbdev_init(void) } void __init -m8xx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) +m8xx_setup_arch(void) { int cpm_page; extern char cmd_line[]; - cpm_page = *memory_start_p; - *memory_start_p += PAGE_SIZE; + cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE); printk("Boot arguments: %s\n", cmd_line); @@ -108,6 +108,9 @@ m8xx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) rd_doload = 1; rd_image_start = 0; #endif +#if 0 /* XXX this may need to be updated for the new bootmem stuff, + or possibly just deleted (see set_phys_avail() in init.c). + - paulus. */ /* initrd_start and size are setup by boot/head.S and kernel/head.S */ if ( initrd_start ) { @@ -120,6 +123,7 @@ m8xx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) } } #endif +#endif } void diff --git a/arch/ppc/kernel/mbx_setup.c b/arch/ppc/kernel/mbx_setup.c index 67cab4503..f6487783b 100644 --- a/arch/ppc/kernel/mbx_setup.c +++ b/arch/ppc/kernel/mbx_setup.c @@ -30,6 +30,7 @@ #include <linux/reboot.h> #include <linux/init.h> #include <linux/blk.h> +#include <linux/ide.h> #include <linux/ioport.h> #include <asm/mmu.h> @@ -37,7 +38,6 @@ #include <asm/residual.h> #include <asm/io.h> #include <asm/pgtable.h> -#include <asm/ide.h> #include <asm/mbx.h> #include <asm/machdep.h> @@ -76,13 +76,12 @@ void __init adbdev_init(void) } void __init -mbx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) +mbx_setup_arch(void) { int cpm_page; extern char cmd_line[]; - cpm_page = *memory_start_p; - *memory_start_p += PAGE_SIZE; + cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE); sprintf(cmd_line, "%s root=/dev/nfs nfsroot=/sys/mbxroot", @@ -104,6 +103,9 @@ mbx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) rd_doload = 1; rd_image_start = 0; #endif +#if 0 /* XXX this may need to be updated for the new bootmem stuff, + or possibly just deleted (see set_phys_avail() in init.c). + - paulus. */ /* initrd_start and size are setup by boot/head.S and kernel/head.S */ if ( initrd_start ) { @@ -116,6 +118,7 @@ mbx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) } } #endif +#endif #ifdef notdef request_region(0x20,0x20,"pic1"); diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 4d041cc98..89994881b 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -235,9 +235,9 @@ _GLOBAL(flush_dcache_range) * snoop from the data cache. * This is a no-op on the 601 which has a unified cache. * - * void flush_page_to_ram(void *page) + * void __flush_page_to_ram(void *page) */ -_GLOBAL(flush_page_to_ram) +_GLOBAL(__flush_page_to_ram) mfspr r5,PVR rlwinm r5,r5,16,16,31 cmpi 0,r5,1 diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index de0a0a36d..0d07c289d 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -146,3 +146,25 @@ 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, + struct resource *res, int resource) +{ + unsigned long where, size; + u32 reg; + + where = PCI_BASE_ADDRESS_0 + (resource * 4); + size = res->end - res->start; + pci_read_config_dword(dev, where, ®); + reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); + pci_write_config_dword(dev, where, reg); +} + +void __init +pcibios_update_irq(struct pci_dev *dev, int irq) +{ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); + /* XXX FIXME - update OF device tree node interrupt property */ +} diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c index 932e7dbb6..62161f68a 100644 --- a/arch/ppc/kernel/pmac_pci.c +++ b/arch/ppc/kernel/pmac_pci.c @@ -17,6 +17,7 @@ #include <linux/delay.h> #include <linux/string.h> #include <linux/init.h> +#include <linux/bootmem.h> #include <asm/init.h> #include <asm/io.h> @@ -30,7 +31,7 @@ struct bridge_data **bridges, *bridge_list; static int max_bus; -static void add_bridges(struct device_node *dev, unsigned long *mem_ptr); +static void add_bridges(struct device_node *dev); /* * Magic constants for enabling cache coherency in the bandit/PSX bridge. @@ -362,24 +363,22 @@ static void __init init_bandit(struct bridge_data *bp) bp->io_base); } -unsigned long __init pmac_find_bridges(unsigned long mem_start, unsigned long mem_end) +void __init pmac_find_bridges(void) { int bus; struct bridge_data *bridge; bridge_list = 0; max_bus = 0; - add_bridges(find_devices("bandit"), &mem_start); - add_bridges(find_devices("chaos"), &mem_start); - add_bridges(find_devices("pci"), &mem_start); - bridges = (struct bridge_data **) mem_start; - mem_start += (max_bus + 1) * sizeof(struct bridge_data *); + add_bridges(find_devices("bandit")); + add_bridges(find_devices("chaos")); + add_bridges(find_devices("pci")); + bridges = (struct bridge_data **) + alloc_bootmem((max_bus + 1) * sizeof(struct bridge_data *)); memset(bridges, 0, (max_bus + 1) * sizeof(struct bridge_data *)); for (bridge = bridge_list; bridge != NULL; bridge = bridge->next) for (bus = bridge->bus_number; bus <= bridge->max_bus; ++bus) bridges[bus] = bridge; - - return mem_start; } /* @@ -387,7 +386,7 @@ unsigned long __init pmac_find_bridges(unsigned long mem_start, unsigned long me * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise, * if we have one or more bandit or chaos bridges, we don't have a MPC106. */ -static void __init add_bridges(struct device_node *dev, unsigned long *mem_ptr) +static void __init add_bridges(struct device_node *dev) { int *bus_range; int len; @@ -413,8 +412,7 @@ static void __init add_bridges(struct device_node *dev, unsigned long *mem_ptr) printk(KERN_INFO "PCI buses %d..%d", bus_range[0], bus_range[1]); printk(" controlled by %s at %x\n", dev->name, addr->address); - bp = (struct bridge_data *) *mem_ptr; - *mem_ptr += sizeof(struct bridge_data); + bp = (struct bridge_data *) alloc_bootmem(sizeof(*bp)); if (strcmp(dev->name, "pci") != 0) { bp->cfg_addr = (volatile unsigned int *) ioremap(addr->address + 0x800000, 0x1000); diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c index 683aac568..f7224f5dd 100644 --- a/arch/ppc/kernel/pmac_pic.c +++ b/arch/ppc/kernel/pmac_pic.c @@ -225,7 +225,7 @@ pmac_get_irq(struct pt_regs *regs) xmon(regs); #endif smp_message_recv(); - return -1; + return -2; /* ignore, already handled */ } { @@ -374,7 +374,7 @@ pmac_pic_init(void) } /* get addresses of second controller */ - irqctrler = (irqctrler->next) ? irqctrler->next : NULL; + irqctrler = irqctrler->next; if (irqctrler && irqctrler->n_addrs > 0) { addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); @@ -382,6 +382,11 @@ pmac_pic_init(void) pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) (addr + (4 - i) * 0x10); } + } else { + /* older powermacs have a GC (grand central) or ohare at + f3000000, with interrupt control registers at f3000020. */ + addr = (unsigned long) ioremap(0xf3000000, 0x40); + pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20); } /* disable all interrupts in all controllers */ diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c index 3418a7e8b..0a23c4473 100644 --- a/arch/ppc/kernel/pmac_setup.c +++ b/arch/ppc/kernel/pmac_setup.c @@ -39,6 +39,7 @@ #include <linux/ioport.h> #include <linux/major.h> #include <linux/blk.h> +#include <linux/ide.h> #include <linux/vt_kern.h> #include <linux/console.h> #include <linux/ide.h> @@ -57,7 +58,6 @@ #include <asm/ohare.h> #include <asm/mediabay.h> #include <asm/feature.h> -#include <asm/ide.h> #include <asm/machdep.h> #include <asm/keyboard.h> #include <asm/dma.h> @@ -238,7 +238,7 @@ pmac_mksound(unsigned int hz, unsigned int ticks) static volatile u32 *sysctrl_regs; void __init -pmac_setup_arch(unsigned long *memory_start_p, unsigned long *memory_end_p) +pmac_setup_arch(void) { struct device_node *cpu; int *fp; @@ -269,7 +269,7 @@ pmac_setup_arch(unsigned long *memory_start_p, unsigned long *memory_end_p) __ioremap(0xffc00000, 0x400000, pgprot_val(PAGE_READONLY)); ohare_init(); - *memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p); + pmac_find_bridges(); init_p2pbridge(); /* Checks "l2cr-value" property in the registry */ @@ -421,7 +421,7 @@ note_scsi_host(struct device_node *node, void *host) #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) extern int pmac_ide_count; extern struct device_node *pmac_ide_node[]; -static int ide_majors[] = { 3, 22, 33, 34, 56, 57, 88, 89 }; +static int ide_majors[] = { 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 }; kdev_t __init find_ide_boot(void) { diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index cabce054c..399b99052 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -60,7 +60,6 @@ EXPORT_SYMBOL(do_signal); EXPORT_SYMBOL(syscall_trace); EXPORT_SYMBOL(transfer_to_handler); EXPORT_SYMBOL(do_IRQ); -EXPORT_SYMBOL(init_task_union); EXPORT_SYMBOL(MachineCheckException); EXPORT_SYMBOL(AlignmentException); EXPORT_SYMBOL(ProgramCheckException); diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c index 53c859a16..fe7043206 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/kernel/prep_setup.c @@ -41,7 +41,6 @@ #include <asm/residual.h> #include <asm/io.h> #include <asm/pgtable.h> -#include <asm/ide.h> #include <asm/cache.h> #include <asm/dma.h> #include <asm/machdep.h> @@ -211,7 +210,7 @@ no_l2: } void __init -prep_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) +prep_setup_arch() { extern char cmd_line[]; unsigned char reg; diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 57955efca..518446bf9 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -11,12 +11,11 @@ #include <linux/reboot.h> #include <linux/delay.h> #include <linux/blk.h> +#include <linux/ide.h> #include <asm/init.h> #include <asm/residual.h> #include <asm/io.h> -#include <linux/ide.h> -#include <asm/ide.h> #include <asm/prom.h> #include <asm/processor.h> #include <asm/pgtable.h> @@ -540,14 +539,12 @@ void __init ppc_init(void) } } -void __init setup_arch(char **cmdline_p, - unsigned long * memory_start_p, unsigned long * memory_end_p) +void __init setup_arch(char **cmdline_p) { extern int panic_timeout; extern char _etext[], _edata[]; extern char *klimit; - extern unsigned long find_available_memory(void); - extern unsigned long *end_of_DRAM; + extern void do_init_bootmem(void); #ifdef CONFIG_XMON extern void xmon_map_scc(void); @@ -556,22 +553,22 @@ void __init setup_arch(char **cmdline_p, xmon(0); #endif /* CONFIG_XMON */ - /* reboot on panic */ + /* reboot on panic */ panic_timeout = 180; init_mm.start_code = PAGE_OFFSET; init_mm.end_code = (unsigned long) _etext; init_mm.end_data = (unsigned long) _edata; - init_mm.brk = (unsigned long) klimit; + init_mm.brk = (unsigned long) klimit; /* Save unparsed command line copy for /proc/cmdline */ strcpy(saved_command_line, cmd_line); *cmdline_p = cmd_line; - *memory_start_p = find_available_memory(); - *memory_end_p = (unsigned long) end_of_DRAM; + /* set up the bootmem stuff with available memory */ + do_init_bootmem(); - ppc_md.setup_arch(memory_start_p, memory_end_p); + ppc_md.setup_arch(); /* clear the progress line */ if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); } diff --git a/arch/ppc/mbx_defconfig b/arch/ppc/mbx_defconfig index 494717c54..7080efb3e 100644 --- a/arch/ppc/mbx_defconfig +++ b/arch/ppc/mbx_defconfig @@ -74,7 +74,7 @@ CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_VIA82C586 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set # CONFIG_BLK_DEV_CMD646 is not set CONFIG_BLK_DEV_SL82C105=y # CONFIG_IDE_CHIPSETS is not set diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index eb158fb1e..240344314 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -35,6 +35,7 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/openpic.h> +#include <linux/bootmem.h> #ifdef CONFIG_BLK_DEV_INITRD #include <linux/blk.h> /* for initrd_* */ #endif @@ -59,6 +60,9 @@ int prom_trashed; atomic_t next_mmu_context; unsigned long *end_of_DRAM; int mem_init_done; +int init_bootmem_done; +int boot_mapsize; +unsigned long totalram_pages = 0; extern pgd_t swapper_pg_dir[]; extern char _start[], _end[]; extern char etext[], _stext[]; @@ -108,9 +112,9 @@ struct mem_pieces { }; struct mem_pieces phys_mem; struct mem_pieces phys_avail; -struct mem_pieces prom_mem; static void remove_mem_piece(struct mem_pieces *, unsigned, unsigned, int); +static void set_phys_avail(void); void *find_mem_piece(unsigned, unsigned); static void print_mem_pieces(struct mem_pieces *); #if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC) @@ -202,7 +206,7 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) pte = (pte_t *) MMU_get_page(); else if ((pte = (pte_t *) get_zero_page_fast()) == NULL) if ((pte = (pte_t *) __get_free_page(GFP_KERNEL))) - clear_page((unsigned long)pte); + clear_page(pte); if (pte) { pmd_val(*pmd) = (unsigned long)pte; return pte + offset; @@ -246,20 +250,20 @@ int do_check_pgt_cache(int low, int high) * ZERO_PAGE is a special page that is used for zero-initialized * data and COW. */ -unsigned long empty_bad_page_table; +pte_t *empty_bad_page_table; pte_t * __bad_pagetable(void) { - __clear_user((void *)empty_bad_page_table, PAGE_SIZE); - return (pte_t *) empty_bad_page_table; + clear_page(empty_bad_page_table); + return empty_bad_page_table; } -unsigned long empty_bad_page; +void *empty_bad_page; pte_t __bad_page(void) { - __clear_user((void *)empty_bad_page, PAGE_SIZE); - return pte_mkdirty(mk_pte(empty_bad_page, PAGE_SHARED)); + clear_page(empty_bad_page); + return pte_mkdirty(mk_pte_phys(__pa(empty_bad_page), PAGE_SHARED)); } void show_mem(void) @@ -289,6 +293,7 @@ void show_mem(void) printk("%d pages shared\n",shared); printk("%d pages swap cached\n",cached); printk("%d pages in page table cache\n",(int)pgtable_cache_size); + show_buffers(); #ifdef CONFIG_NET show_net_buffers(); #endif @@ -345,7 +350,7 @@ void si_meminfo(struct sysinfo *val) val->totalram = 0; val->sharedram = 0; val->freeram = nr_free_pages << PAGE_SHIFT; - val->bufferram = atomic_read(&buffermem); + val->bufferram = atomic_read(&buffermem_pages); while (i-- > 0) { if (PageReserved(mem_map+i)) continue; @@ -590,6 +595,37 @@ mmu_context_overflow(void) #endif /* CONFIG_8xx */ /* + * Set phys_avail to phys_mem less the kernel text/data/bss. + */ +static void __init set_phys_avail(void) +{ + unsigned long kstart, ksize; + + /* we can't call the prom any more at this stage, so + all of memory is available (after klimit) */ + phys_avail = phys_mem; + + /* + * phys_avail records memory we can use. + * Make sure the kernel text/data/bss is not in it. + */ + kstart = __pa(_stext); /* should be 0 */ + ksize = PAGE_ALIGN(klimit - _stext); + remove_mem_piece(&phys_avail, kstart, ksize, 0); + remove_mem_piece(&phys_avail, 0, 0x4000, 0); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) { + /* + * Remove the initialized ramdisk from the available memory. + */ + remove_mem_piece(&phys_avail, __pa(initrd_start), + initrd_end - initrd_start, 1); + } +#endif /* CONFIG_BLK_DEV_INITRD */ +} + +/* * Scan a region for a piece of a given size with the required alignment. */ void __init *find_mem_piece(unsigned size, unsigned align) @@ -681,7 +717,7 @@ static void __init print_mem_pieces(struct mem_pieces *mp) printk("\n"); } -#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_PPC_ALL) +#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC) /* * Add some memory to an array of pieces */ @@ -833,8 +869,8 @@ static void __init mapin_ram(void) { int i; unsigned long v, p, s, f; -#ifndef CONFIG_8xx +#ifndef CONFIG_8xx if (!__map_without_bats) { unsigned long tot, mem_base, bl, done; unsigned long max_size = (256<<20); @@ -869,24 +905,7 @@ static void __init mapin_ram(void) RAM_PAGE); } } - v = KERNELBASE; - for (i = 0; i < phys_mem.n_regions; ++i) { - p = phys_mem.regions[i].address; - for (s = 0; s < phys_mem.regions[i].size; s += PAGE_SIZE) { - f = _PAGE_PRESENT | _PAGE_ACCESSED; - if ((char *) v < _stext || (char *) v >= etext) - f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; - else - /* On the powerpc, no user access - forces R/W kernel access */ - f |= _PAGE_USER; - map_page(v, p, f); - v += PAGE_SIZE; - p += PAGE_SIZE; - } - } - -#else /* CONFIG_8xx */ +#endif /* CONFIG_8xx */ for (i = 0; i < phys_mem.n_regions; ++i) { v = (ulong)__va(phys_mem.regions[i].address); @@ -896,37 +915,35 @@ static void __init mapin_ram(void) * don't get ASID compares on kernel space. */ f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED; - - /* I don't really need the rest of this code, but - * I grabbed it because I think the line: - * f |= _PAGE_USER - * is incorrect. It needs to be set to bits we - * don't define to cause a kernel read-only. On - * the MPC8xx, the PAGE_DIRTY takes care of that - * for us (along with the RW software state). - */ if ((char *) v < _stext || (char *) v >= etext) f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; +#ifndef CONFIG_8xx + else + /* On the powerpc (not 8xx), no user access + forces R/W kernel access */ + f |= _PAGE_USER; +#endif /* CONFIG_8xx */ map_page(v, p, f); v += PAGE_SIZE; p += PAGE_SIZE; } - } -#endif /* CONFIG_8xx */ + } } -/* This can get called from ioremap, so don't make it an __init, OK? */ +/* In fact this is only called until mem_init is done. */ static void __init *MMU_get_page(void) { void *p; if (mem_init_done) { p = (void *) __get_free_page(GFP_KERNEL); - if (p == 0) - panic("couldn't get a page in MMU_get_page"); + } else if (init_bootmem_done) { + p = alloc_bootmem_pages(PAGE_SIZE); } else { p = find_mem_piece(PAGE_SIZE, PAGE_SIZE); } + if (p == 0) + panic("couldn't get a page in MMU_get_page"); __clear_user(p, PAGE_SIZE); return p; } @@ -1106,6 +1123,51 @@ void __init MMU_init(void) } /* + * Initialize the bootmem system and give it all the memory we + * have available. + */ +void __init do_init_bootmem(void) +{ + unsigned long start, size; + int i; + + /* + * Find an area to use for the bootmem bitmap. + * We look for the first area which is at least + * 128kB in length (128kB is enough for a bitmap + * for 4GB of memory, using 4kB pages), plus 1 page + * (in case the address isn't page-aligned). + */ + start = 0; + size = 0; + for (i = 0; i < phys_avail.n_regions; ++i) { + unsigned long a = phys_avail.regions[i].address; + unsigned long s = phys_avail.regions[i].size; + if (s <= size) + continue; + start = a; + size = s; + if (s >= 33 * PAGE_SIZE) + break; + } + start = PAGE_ALIGN(start); + + boot_mapsize = init_bootmem(start >> PAGE_SHIFT, + __pa(end_of_DRAM) >> PAGE_SHIFT); + + /* remove the bootmem bitmap from the available memory */ + remove_mem_piece(&phys_avail, start, start + boot_mapsize, 1); + + /* add everything in phys_avail into the bootmem map */ + for (i = 0; i < phys_avail.n_regions; ++i) + free_bootmem(phys_avail.regions[i].address, + phys_avail.regions[i].size); + + init_bootmem_done = 1; +} + +#if 0 +/* * Find some memory for setup_arch to return. * We use the largest chunk of available memory as the area * that setup_arch returns, making sure that there are at @@ -1143,97 +1205,56 @@ unsigned long __init find_available_memory(void) avail_start = (unsigned long) __va(a); return avail_start; } +#endif /* 0 */ /* * paging_init() sets up the page tables - in fact we've already done this. */ -unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem) +void __init paging_init(void) { - extern unsigned long free_area_init(unsigned long, unsigned long); /* * Grab some memory for bad_page and bad_pagetable to use. */ - empty_bad_page = PAGE_ALIGN(start_mem); - empty_bad_page_table = empty_bad_page + PAGE_SIZE; - start_mem = empty_bad_page + 2 * PAGE_SIZE; - - /* note: free_area_init uses its second argument - to size the mem_map array. */ - start_mem = free_area_init(start_mem, end_mem); - return start_mem; + empty_bad_page = alloc_bootmem_pages(PAGE_SIZE); + empty_bad_page_table = alloc_bootmem_pages(PAGE_SIZE); + + free_area_init(max_low_pfn); } -void __init mem_init(unsigned long start_mem, unsigned long end_mem) +void __init mem_init(void) { unsigned long addr; - int i; - unsigned long a, lim; int codepages = 0; int datapages = 0; int initpages = 0; extern unsigned int rtas_data, rtas_size; - end_mem &= PAGE_MASK; - high_memory = (void *) end_mem; - max_mapnr = MAP_NR(high_memory); - - /* mark usable pages in the mem_map[] */ - start_mem = PAGE_ALIGN(start_mem); - + max_mapnr = max_low_pfn; + high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); num_physpages = max_mapnr; /* RAM is assumed contiguous */ - remove_mem_piece(&phys_avail, __pa(avail_start), - start_mem - avail_start, 1); - for (i = 0; i < phys_avail.n_regions; ++i) { - a = (unsigned long) __va(phys_avail.regions[i].address); - lim = (a + phys_avail.regions[i].size) & PAGE_MASK; - a = PAGE_ALIGN(a); - for (; a < lim; a += PAGE_SIZE) - clear_bit(PG_reserved, &mem_map[MAP_NR(a)].flags); - } + totalram_pages += free_all_bootmem(); #ifdef CONFIG_BLK_DEV_INITRD /* if we are booted from BootX with an initial ramdisk, make sure the ramdisk pages aren't reserved. */ if (initrd_start) { - for (a = initrd_start; a < initrd_end; a += PAGE_SIZE) - clear_bit(PG_reserved, &mem_map[MAP_NR(a)].flags); + for (addr = initrd_start; addr < initrd_end; addr += PAGE_SIZE) + clear_bit(PG_reserved, &mem_map[MAP_NR(addr)].flags); } #endif /* CONFIG_BLK_DEV_INITRD */ - /* free the prom's memory - no-op on prep */ - for (i = 0; i < prom_mem.n_regions; ++i) { - a = (unsigned long) __va(prom_mem.regions[i].address); - lim = (a + prom_mem.regions[i].size) & PAGE_MASK; - a = PAGE_ALIGN(a); - for (; a < lim; a += PAGE_SIZE) - clear_bit(PG_reserved, &mem_map[MAP_NR(a)].flags); - } - - prom_trashed = 1; - - for (addr = PAGE_OFFSET; addr < end_mem; addr += PAGE_SIZE) { - if (PageReserved(mem_map + MAP_NR(addr))) { - if (addr < (ulong) etext) - codepages++; - else if (addr >= (unsigned long)&__init_begin - && addr < (unsigned long)&__init_end) - initpages++; - else if (addr < (ulong) start_mem) - datapages++; + for (addr = PAGE_OFFSET; addr < (unsigned long)end_of_DRAM; + addr += PAGE_SIZE) { + if (!PageReserved(mem_map + MAP_NR(addr))) continue; - } - set_page_count(mem_map + MAP_NR(addr), 1); -#ifdef CONFIG_BLK_DEV_INITRD - if (!initrd_start || - addr < (initrd_start & PAGE_MASK) || addr >= initrd_end) -#endif /* CONFIG_BLK_DEV_INITRD */ -#ifndef CONFIG_8xx - if ( !rtas_data || - addr < (rtas_data & PAGE_MASK) || - addr >= (rtas_data+rtas_size)) -#endif /* CONFIG_8xx */ - free_page(addr); + if (addr < (ulong) etext) + codepages++; + else if (addr >= (unsigned long)&__init_begin + && addr < (unsigned long)&__init_end) + initpages++; + else if (addr < (ulong) klimit) + datapages++; } printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08x,%08lx]\n", @@ -1241,7 +1262,7 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem) codepages << (PAGE_SHIFT-10), datapages << (PAGE_SHIFT-10), initpages << (PAGE_SHIFT-10), - PAGE_OFFSET, end_mem); + PAGE_OFFSET, (unsigned long) end_of_DRAM); mem_init_done = 1; } @@ -1257,11 +1278,9 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem) unsigned long __init *pmac_find_end_of_memory(void) { unsigned long a, total; - unsigned long kstart, ksize; - int i; /* max amount of RAM we allow -- Cort */ -#define RAM_LIMIT (256<<20) +#define RAM_LIMIT (768<<20) memory_node = find_devices("memory"); if (memory_node == NULL) { @@ -1309,32 +1328,8 @@ unsigned long __init *pmac_find_end_of_memory(void) phys_mem.n_regions = 1; } - if (boot_infos == 0) { - /* record which bits the prom is using */ - get_mem_prop("available", &phys_avail); - prom_mem = phys_mem; - for (i = 0; i < phys_avail.n_regions; ++i) - remove_mem_piece(&prom_mem, - phys_avail.regions[i].address, - phys_avail.regions[i].size, 0); - } else { - /* booted from BootX - it's all available (after klimit) */ - phys_avail = phys_mem; - prom_mem.n_regions = 0; - } + set_phys_avail(); - /* - * phys_avail records memory we can use now. - * prom_mem records memory allocated by the prom that we - * don't want to use now, but we'll reclaim later. - * Make sure the kernel text/data/bss is in neither. - */ - kstart = __pa(_stext); /* should be 0 */ - ksize = PAGE_ALIGN(klimit - _stext); - remove_mem_piece(&phys_avail, kstart, ksize, 0); - remove_mem_piece(&prom_mem, kstart, ksize, 0); - remove_mem_piece(&phys_avail, 0, 0x4000, 0); - remove_mem_piece(&prom_mem, 0, 0x4000, 0); #undef RAM_LIMIT return __va(total); } @@ -1349,7 +1344,6 @@ unsigned long __init *pmac_find_end_of_memory(void) */ unsigned long __init *prep_find_end_of_memory(void) { - unsigned long kstart, ksize; unsigned long total; total = res->TotalMemory; @@ -1364,11 +1358,7 @@ unsigned long __init *prep_find_end_of_memory(void) printk("Ramsize default to be %ldM\n", total>>20); } append_mem_piece(&phys_mem, 0, total); - phys_avail = phys_mem; - kstart = __pa(_stext); /* should be 0 */ - ksize = PAGE_ALIGN(klimit - _stext); - remove_mem_piece(&phys_avail, kstart, ksize, 0); - remove_mem_piece(&phys_avail, 0, 0x4000, 0); + set_phys_avail(); return (__va(total)); } @@ -1378,7 +1368,7 @@ unsigned long __init *prep_find_end_of_memory(void) #if defined(CONFIG_GEMINI) unsigned long __init *gemini_find_end_of_memory(void) { - unsigned long total, kstart, ksize, *ret; + unsigned long total, *ret; unsigned char reg; reg = readb(GEMINI_MEMCFG); @@ -1390,10 +1380,7 @@ unsigned long __init *gemini_find_end_of_memory(void) phys_mem.n_regions = 1; ret = __va(phys_mem.regions[0].size); - phys_avail = phys_mem; - kstart = __pa(_stext); - ksize = PAGE_ALIGN( _end - _stext ); - remove_mem_piece( &phys_avail, kstart, ksize, 0 ); + set_phys_avail(); return ret; } #endif /* defined(CONFIG_GEMINI) || defined(CONFIG_ALL_PPC) */ @@ -1429,15 +1416,8 @@ unsigned long __init *apus_find_end_of_memory(void) } /* Now register the memory block. */ - { - unsigned long kstart, ksize; - - append_mem_piece(&phys_mem, memory[0].addr, memory[0].size); - phys_avail = phys_mem; - kstart = __pa(_stext); - ksize = PAGE_ALIGN(klimit - _stext); - remove_mem_piece(&phys_avail, kstart, ksize, 0); - } + append_mem_piece(&phys_mem, memory[0].addr, memory[0].size); + set_phys_avail(); /* Remove the memory chunks that are controlled by special Phase5 hardware. */ @@ -1586,7 +1566,6 @@ static void __init hash_init(void) */ unsigned long __init *m8xx_find_end_of_memory(void) { - unsigned long kstart, ksize; bd_t *binfo; unsigned long *ret; extern unsigned char __res[]; @@ -1600,11 +1579,7 @@ unsigned long __init *m8xx_find_end_of_memory(void) ret = __va(phys_mem.regions[0].address+ phys_mem.regions[0].size); - phys_avail = phys_mem; - - kstart = __pa(_stext); /* should be 0 */ - ksize = PAGE_ALIGN(_end - _stext); - remove_mem_piece(&phys_avail, kstart, ksize, 0); + set_phys_avail(); return ret; } #endif /* ndef CONFIG_8xx */ |