diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-06-15 01:55:58 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-06-15 01:55:58 +0000 |
commit | 53b3988d474435254a3b053a68bb24ce9e439295 (patch) | |
tree | f8da8e40f01f4ad02bbd76b8c9920749b118235f /arch/ppc | |
parent | b0cb48abe83d1a4389ea938bf624f8baa82c5047 (diff) |
Merge with 2.3.99-pre9.
Diffstat (limited to 'arch/ppc')
-rw-r--r-- | arch/ppc/8260_io/enet.c | 4 | ||||
-rw-r--r-- | arch/ppc/8260_io/uart.c | 12 | ||||
-rw-r--r-- | arch/ppc/configs/common_defconfig | 16 | ||||
-rw-r--r-- | arch/ppc/defconfig | 15 | ||||
-rw-r--r-- | arch/ppc/kernel/chrp_pci.c | 37 | ||||
-rw-r--r-- | arch/ppc/kernel/chrp_setup.c | 39 | ||||
-rw-r--r-- | arch/ppc/kernel/chrp_time.c | 9 | ||||
-rw-r--r-- | arch/ppc/kernel/entry.S | 89 | ||||
-rw-r--r-- | arch/ppc/kernel/head.S | 3 | ||||
-rw-r--r-- | arch/ppc/kernel/ppc_ksyms.c | 3 | ||||
-rw-r--r-- | arch/ppc/kernel/ptrace.c | 507 | ||||
-rw-r--r-- | arch/ppc/kernel/setup.c | 7 | ||||
-rw-r--r-- | arch/ppc/kernel/time.c | 24 | ||||
-rw-r--r-- | arch/ppc/kernel/traps.c | 9 | ||||
-rw-r--r-- | arch/ppc/mbxboot/Makefile | 75 | ||||
-rw-r--r-- | arch/ppc/mbxboot/embed_config.c | 13 | ||||
-rw-r--r-- | arch/ppc/mbxboot/gzimage.c | 8 | ||||
-rw-r--r-- | arch/ppc/mbxboot/head_8260.S | 11 | ||||
-rw-r--r-- | arch/ppc/mbxboot/misc.c | 9 | ||||
-rw-r--r-- | arch/ppc/mbxboot/rdimage.c | 8 | ||||
-rw-r--r-- | arch/ppc/mbxboot/vmlinux.lds | 152 | ||||
-rw-r--r-- | arch/ppc/mm/fault.c | 93 | ||||
-rw-r--r-- | arch/ppc/mm/init.c | 10 | ||||
-rw-r--r-- | arch/ppc/treeboot/mkevimg | 2 | ||||
-rw-r--r-- | arch/ppc/treeboot/mkirimg | 6 | ||||
-rw-r--r-- | arch/ppc/vmlinux.lds | 8 |
26 files changed, 615 insertions, 554 deletions
diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c index 82ed8f9ec..4a7c20df3 100644 --- a/arch/ppc/8260_io/enet.c +++ b/arch/ppc/8260_io/enet.c @@ -689,8 +689,8 @@ int __init scc_enet_init(void) cep->dirty_tx = cep->cur_tx = cep->tx_bd_base; cep->cur_rx = cep->rx_bd_base; - ep->sen_genscc.scc_rfcr = SCC_EB; - ep->sen_genscc.scc_tfcr = SCC_EB; + ep->sen_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; + ep->sen_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; /* Set maximum bytes per receive buffer. * This appears to be an Ethernet frame size, not the buffer diff --git a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c index 9e93bcdd5..c039a452c 100644 --- a/arch/ppc/8260_io/uart.c +++ b/arch/ppc/8260_io/uart.c @@ -2536,8 +2536,8 @@ int __init rs_8xx_init(void) /* Set up the uart parameters in the * parameter ram. */ - up->smc_rfcr = SMC_EB; - up->smc_tfcr = SMC_EB; + up->smc_rfcr = CPMFCR_GBL | CPMFCR_EB; + up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; /* Set this to 1 for now, so we get single * character interrupts. Using idle charater @@ -2579,8 +2579,8 @@ int __init rs_8xx_init(void) /* Set up the uart parameters in the * parameter ram. */ - sup->scc_genscc.scc_rfcr = SMC_EB; - sup->scc_genscc.scc_tfcr = SMC_EB; + sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; + sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; /* Set this to 1 for now, so we get single * character interrupts. Using idle charater @@ -2741,8 +2741,8 @@ static int __init serial_console_setup(struct console *co, char *options) */ up->smc_rbase = dp_addr; /* Base of receive buffer desc. */ up->smc_tbase = dp_addr+sizeof(cbd_t); /* Base of xmt buffer desc. */ - up->smc_rfcr = SMC_EB; - up->smc_tfcr = SMC_EB; + up->smc_rfcr = CPMFCR_GBL | CPMFCR_EB; + up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; /* Set this to 1 for now, so we get single character interrupts. */ diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig index caf15d27d..051e96402 100644 --- a/arch/ppc/configs/common_defconfig +++ b/arch/ppc/configs/common_defconfig @@ -15,10 +15,11 @@ CONFIG_PPC=y CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_PPC64 is not set -# CONFIG_82xx is not set +# CONFIG_8260 is not set # CONFIG_8xx is not set CONFIG_ALL_PPC=y # CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set # CONFIG_APUS is not set # CONFIG_SMP is not set CONFIG_ALTIVEC=y @@ -159,10 +160,10 @@ CONFIG_BLK_DEV_IDESCSI=y # CONFIG_BLK_DEV_RZ1000 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_IDEDMA_PCI=y # CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_IDEDMA_PCI_AUTO is not set -# CONFIG_BLK_DEV_IDEDMA is not set +CONFIG_IDEDMA_PCI_AUTO=y +CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_PCI_EXPERIMENTAL=y # CONFIG_IDEDMA_PCI_WIP is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set @@ -377,6 +378,11 @@ CONFIG_PPP=y # CONFIG_HAMRADIO is not set # +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# # ISDN subsystem # # CONFIG_ISDN is not set @@ -607,6 +613,7 @@ CONFIG_SOUND=y CONFIG_DMASOUND_AWACS=y CONFIG_DMASOUND=y # CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_ES1370 is not set # CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set @@ -688,3 +695,4 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set CONFIG_XMON=y + diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index c93118bae..a14aa41ab 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -15,10 +15,11 @@ CONFIG_PPC=y CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_PPC64 is not set -# CONFIG_82xx is not set +# CONFIG_8260 is not set # CONFIG_8xx is not set CONFIG_ALL_PPC=y # CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set # CONFIG_APUS is not set # CONFIG_SMP is not set CONFIG_ALTIVEC=y @@ -159,10 +160,10 @@ CONFIG_BLK_DEV_IDESCSI=y # CONFIG_BLK_DEV_RZ1000 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_IDEDMA_PCI=y # CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_IDEDMA_PCI_AUTO is not set -# CONFIG_BLK_DEV_IDEDMA is not set +CONFIG_IDEDMA_PCI_AUTO=y +CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_PCI_EXPERIMENTAL=y # CONFIG_IDEDMA_PCI_WIP is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set @@ -377,6 +378,11 @@ CONFIG_PPP=y # CONFIG_HAMRADIO is not set # +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# # ISDN subsystem # # CONFIG_ISDN is not set @@ -608,6 +614,7 @@ CONFIG_SOUND=y CONFIG_DMASOUND_AWACS=y CONFIG_DMASOUND=y # CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_ES1370 is not set # CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c index a2fbe5f14..e609906cb 100644 --- a/arch/ppc/kernel/chrp_pci.c +++ b/arch/ppc/kernel/chrp_pci.c @@ -17,6 +17,7 @@ #include <asm/prom.h> #include <asm/gg2.h> #include <asm/machdep.h> +#include <asm/init.h> #include "pci.h" @@ -31,7 +32,7 @@ volatile struct Hydra *Hydra = NULL; * limit the bus number to 3 bits */ -int gg2_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, +int __chrp gg2_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned char *val) { if (bus > 7) { @@ -42,7 +43,7 @@ int gg2_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int gg2_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, +int __chrp gg2_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned short *val) { if (bus > 7) { @@ -54,7 +55,7 @@ int gg2_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, } -int gg2_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, +int __chrp gg2_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned int *val) { if (bus > 7) { @@ -65,7 +66,7 @@ int gg2_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int gg2_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, +int __chrp gg2_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned char val) { if (bus > 7) @@ -74,7 +75,7 @@ int gg2_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int gg2_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, +int __chrp gg2_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned short val) { if (bus > 7) @@ -83,7 +84,7 @@ int gg2_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int gg2_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, +int __chrp gg2_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned int val) { if (bus > 7) @@ -98,7 +99,7 @@ int gg2_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, | (((o) & ~3) << 24)) unsigned int python_busnr = 0; -int python_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, +int __chrp python_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned char *val) { if (bus > python_busnr) { @@ -110,7 +111,7 @@ int python_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int python_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, +int __chrp python_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned short *val) { if (bus > python_busnr) { @@ -123,7 +124,7 @@ int python_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, } -int python_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, +int __chrp python_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned int *val) { if (bus > python_busnr) { @@ -135,7 +136,7 @@ int python_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int python_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, +int __chrp python_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned char val) { if (bus > python_busnr) @@ -145,7 +146,7 @@ int python_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int python_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, +int __chrp python_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned short val) { if (bus > python_busnr) @@ -156,7 +157,7 @@ int python_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int python_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, +int __chrp python_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned int val) { if (bus > python_busnr) @@ -167,7 +168,7 @@ int python_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, } -int rtas_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, +int __chrp rtas_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned char *val) { unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); @@ -176,7 +177,7 @@ int rtas_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int rtas_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, +int __chrp rtas_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned short *val) { unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); @@ -186,7 +187,7 @@ int rtas_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, } -int rtas_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, +int __chrp rtas_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned int *val) { unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); @@ -195,7 +196,7 @@ int rtas_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int rtas_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, +int __chrp rtas_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned char val) { unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); @@ -204,7 +205,7 @@ int rtas_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int rtas_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, +int __chrp rtas_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned short val) { unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); @@ -213,7 +214,7 @@ int rtas_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, return PCIBIOS_SUCCESSFUL; } -int rtas_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, +int __chrp rtas_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, unsigned char offset, unsigned int val) { unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c index 3b541c26f..d8c22e1a6 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/kernel/chrp_setup.c @@ -49,6 +49,7 @@ #include <asm/irq.h> #include <asm/hydra.h> #include <asm/keyboard.h> +#include <asm/init.h> #include "time.h" #include "local_irq.h" @@ -112,7 +113,7 @@ static const char *gg2_cachemodes[4] = { "Disabled", "Write-Through", "Copy-Back", "Transparent Mode" }; -int +int __chrp chrp_get_cpuinfo(char *buffer) { int i, len, sdramen; @@ -306,7 +307,7 @@ chrp_setup_arch(void) } } -void +void __chrp chrp_event_scan(void) { unsigned char log[1024]; @@ -317,7 +318,7 @@ chrp_event_scan(void) ppc_md.heartbeat_count = ppc_md.heartbeat_reset; } -void +void __chrp chrp_restart(char *cmd) { printk("RTAS system-reboot returned %d\n", @@ -325,7 +326,7 @@ chrp_restart(char *cmd) for (;;); } -void +void __chrp chrp_power_off(void) { /* allow power on only with power button press */ @@ -334,13 +335,13 @@ chrp_power_off(void) for (;;); } -void +void __chrp chrp_halt(void) { chrp_power_off(); } -u_int +u_int __chrp chrp_irq_cannonicalize(u_int irq) { if (irq == 2) @@ -353,7 +354,7 @@ chrp_irq_cannonicalize(u_int irq) } } -int chrp_get_irq( struct pt_regs *regs ) +int __chrp chrp_get_irq( struct pt_regs *regs ) { int irq; @@ -383,7 +384,7 @@ int chrp_get_irq( struct pt_regs *regs ) return irq; } -void chrp_post_irq(struct pt_regs* regs, int irq) +void __chrp chrp_post_irq(struct pt_regs* regs, int irq) { /* * If it's an i8259 irq then we've already done the @@ -445,7 +446,7 @@ int chrp_ide_ports_known = 0; ide_ioreg_t chrp_ide_regbase[MAX_HWIFS]; ide_ioreg_t chrp_idedma_regbase; -void +void __chrp chrp_ide_probe(void) { struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, NULL); @@ -460,19 +461,19 @@ chrp_ide_probe(void) } } -void +void __chrp chrp_ide_insw(ide_ioreg_t port, void *buf, int ns) { ide_insw(port+_IO_BASE, buf, ns); } -void +void __chrp chrp_ide_outsw(ide_ioreg_t port, void *buf, int ns) { ide_outsw(port+_IO_BASE, buf, ns); } -int +int __chrp chrp_ide_default_irq(ide_ioreg_t base) { if (chrp_ide_ports_known == 0) @@ -480,7 +481,7 @@ chrp_ide_default_irq(ide_ioreg_t base) return chrp_ide_irq; } -ide_ioreg_t +ide_ioreg_t __chrp chrp_ide_default_io_base(int index) { if (chrp_ide_ports_known == 0) @@ -488,13 +489,13 @@ chrp_ide_default_io_base(int index) return chrp_ide_regbase[index]; } -int +int __chrp chrp_ide_check_region(ide_ioreg_t from, unsigned int extent) { return check_region(from, extent); } -void +void __chrp chrp_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name) @@ -502,20 +503,20 @@ chrp_ide_request_region(ide_ioreg_t from, request_region(from, extent, name); } -void +void __chrp chrp_ide_release_region(ide_ioreg_t from, unsigned int extent) { release_region(from, extent); } -void +void __chrp chrp_ide_fix_driveid(struct hd_driveid *id) { ppc_generic_ide_fix_driveid(id); } -void +void __chrp chrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) { ide_ioreg_t reg = data_port; @@ -629,7 +630,7 @@ void __init if ( ppc_md.progress ) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0); } -void +void __chrp chrp_progress(char *s, unsigned short hex) { extern unsigned int rtas_data; diff --git a/arch/ppc/kernel/chrp_time.c b/arch/ppc/kernel/chrp_time.c index c692b54d0..6d275e517 100644 --- a/arch/ppc/kernel/chrp_time.c +++ b/arch/ppc/kernel/chrp_time.c @@ -25,6 +25,7 @@ #include <asm/processor.h> #include <asm/nvram.h> #include <asm/prom.h> +#include <asm/init.h> #include "time.h" static int nvram_as1 = NVRAM_AS1; @@ -45,7 +46,7 @@ void __init chrp_time_init(void) nvram_data = base + 1; } -int chrp_cmos_clock_read(int addr) +int __chrp chrp_cmos_clock_read(int addr) { if (nvram_as1 != 0) outb(addr>>8, nvram_as1); @@ -53,7 +54,7 @@ int chrp_cmos_clock_read(int addr) return (inb(nvram_data)); } -void chrp_cmos_clock_write(unsigned long val, int addr) +void __chrp chrp_cmos_clock_write(unsigned long val, int addr) { if (nvram_as1 != 0) outb(addr>>8, nvram_as1); @@ -65,7 +66,7 @@ void chrp_cmos_clock_write(unsigned long val, int addr) /* * Set the hardware clock. -- Cort */ -int chrp_set_rtc_time(unsigned long nowtime) +int __chrp chrp_set_rtc_time(unsigned long nowtime) { unsigned char save_control, save_freq_select; struct rtc_time tm; @@ -111,7 +112,7 @@ int chrp_set_rtc_time(unsigned long nowtime) return 0; } -unsigned long chrp_get_rtc_time(void) +unsigned long __chrp chrp_get_rtc_time(void) { unsigned int year, mon, day, hour, min, sec; int i; diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index cc647a58b..ad467894f 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -291,25 +291,9 @@ ret_from_intercept: * -- Cort */ cmpi 0,r3,0 - bne ret_from_except - /* - * If we're returning from user mode we do things differently - * -- Cort - */ - lwz r3,_MSR(r1) - andi. r3,r3,MSR_PR - beq+ 10f - b 8f - + beq restore .globl ret_from_except ret_from_except: -0: /* disable interrupts */ - lis r30,int_control@h - ori r30,r30,int_control@l - lwz r30,0(r30) - mtlr r30 - blrl - lwz r5,_MSR(r1) andi. r5,r5,MSR_EE beq 2f @@ -341,65 +325,58 @@ lost_irq_ret: bl do_softirq .globl do_bottom_half_ret do_bottom_half_ret: -2: /* disable interrupts */ - lis r30,int_control@h - ori r30,r30,int_control@l - lwz r30,0(r30) - mtlr r30 - blrl - lwz r3,_MSR(r1) /* Returning to user mode? */ +2: lwz r3,_MSR(r1) /* Returning to user mode? */ andi. r3,r3,MSR_PR - beq+ 10f /* if so, check need_resched and signals */ + beq+ restore /* if so, check need_resched and signals */ + .globl ret_to_user_hook +ret_to_user_hook: + nop lwz r3,NEED_RESCHED(r2) cmpi 0,r3,0 /* check need_resched flag */ beq+ 7f bl schedule - b 0b 7: lwz r5,SIGPENDING(r2) /* Check for pending unblocked signals */ cmpwi 0,r5,0 - beq+ 8f + beq+ restore li r3,0 addi r4,r1,STACK_FRAME_OVERHEAD bl do_signal .globl do_signal_ret do_signal_ret: - b 0b -8: /* - * We need to hard disable here even if RTL is active since - * being interrupted after here trashes the SPRG2 - * -- Cort - */ - mfmsr r0 /* Get current interrupt state */ - rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ - mtmsr r0 /* Update machine state */ - - addi r4,r1,INT_FRAME_SIZE /* size of frame */ - stw r4,THREAD+KSP(r2) /* save kernel stack pointer */ - tophys(r3,r1) - mtspr SPRG2,r3 /* phys exception stack pointer */ - b 11f -10: /* make sure we hard disable here, even if rtl is active -- Cort */ - mfmsr r0 /* Get current interrupt state */ - rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ - sync /* Some chip revs have problems here... */ - mtmsr r0 /* Update machine state */ -11: - lwz r2,_CTR(r1) +restore: + lwz r3,_CTR(r1) lwz r0,_LINK(r1) - mtctr r2 + mtctr r3 mtlr r0 - lwz r2,_XER(r1) - lwz r0,_CCR(r1) - mtspr XER,r2 - mtcrf 0xFF,r0 + lwz r3,_XER(r1) + mtspr XER,r3 REST_10GPRS(3, r1) REST_10GPRS(13, r1) REST_8GPRS(23, r1) REST_GPR(31, r1) - lwz r2,_NIP(r1) /* Restore environment */ + + /* make sure we hard disable here, even if rtl is active, to protect + * SRR[01] and SPRG2 -- Cort + */ + mfmsr r0 /* Get current interrupt state */ + rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ + sync /* Some chip revs have problems here... */ + mtmsr r0 /* Update machine state */ + + /* if returning to user mode, set new sprg2 and save kernel SP */ lwz r0,_MSR(r1) - mtspr SRR0,r2 mtspr SRR1,r0 + andi. r0,r0,MSR_PR + beq+ 1f + addi r0,r1,INT_FRAME_SIZE /* size of frame */ + stw r0,THREAD+KSP(r2) /* save kernel stack pointer */ + tophys(r2,r1) + mtspr SPRG2,r2 /* phys exception stack pointer */ +1: + lwz r2,_CCR(r1) + mtcrf 0xFF,r2 + lwz r2,_NIP(r1) + mtspr SRR0,r2 lwz r0,GPR0(r1) lwz r2,GPR2(r1) lwz r1,GPR1(r1) diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 6700806bd..f88c5383d 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -1459,7 +1459,8 @@ start_here: /* * Set up the segment registers for a new context. */ -_GLOBAL(set_context) + .globl set_context +set_context: rlwinm r3,r3,4,8,27 /* VSID = context << 4 */ addis r3,r3,0x6000 /* Set Ks, Ku bits */ li r0,12 /* TASK_SIZE / SEGMENT_SIZE */ diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 9b7d2be31..6d7f2aff7 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -58,6 +58,7 @@ long long __ashrdi3(long long, int); long long __ashldi3(long long, int); long long __lshrdi3(long long, int); int abs(int); +extern unsigned long ret_to_user_hook; EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(do_signal); @@ -284,3 +285,5 @@ EXPORT_SYMBOL(debugger_sstep); EXPORT_SYMBOL(debugger_iabr_match); EXPORT_SYMBOL(debugger_dabr_match); EXPORT_SYMBOL(debugger_fault_handler); + +EXPORT_SYMBOL(ret_to_user_hook); diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c index fe0bfcea2..3ccc8f518 100644 --- a/arch/ppc/kernel/ptrace.c +++ b/arch/ppc/kernel/ptrace.c @@ -1,7 +1,7 @@ /* * linux/arch/ppc/kernel/ptrace.c * - * PowerPC version + * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Derived from "arch/m68k/kernel/ptrace.c" @@ -9,14 +9,14 @@ * Taken from linux/kernel/ptrace.c and modified for M680x0. * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds * - * Modified by Cort Dougan (cort@cs.nmt.edu) + * Modified by Cort Dougan (cort@hq.fsmlabs.com) + * and Paul Mackerras (paulus@linuxcare.com.au). * * This file is subject to the terms and conditions of the GNU General * Public License. See the file README.legal in the main directory of * this archive for more details. */ -#include <stddef.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> @@ -26,7 +26,7 @@ #include <linux/ptrace.h> #include <linux/user.h> -#include <asm/segment.h> +#include <asm/uaccess.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/system.h> @@ -44,7 +44,7 @@ /* * Get contents of register REGNO in task TASK. */ -static inline long get_reg(struct task_struct *task, int regno) +static inline unsigned long get_reg(struct task_struct *task, int regno) { if (regno < sizeof(struct pt_regs) / sizeof(unsigned long)) return ((unsigned long *)task->thread.regs)[regno]; @@ -64,7 +64,7 @@ static inline int put_reg(struct task_struct *task, int regno, ((unsigned long *)task->thread.regs)[regno] = data; return 0; } - return -1; + return -EIO; } static inline void @@ -81,216 +81,10 @@ clear_single_step(struct task_struct *task) regs->msr &= ~MSR_SE; } -#if 0 -/* - * This routine gets a long from any process space by following the page - * tables. NOTE! You should check that the long isn't on a page boundary, - * and that it is in the task area before calling this: this routine does - * no checking. - * - */ -static unsigned long get_long(struct task_struct * tsk, - struct vm_area_struct * vma, unsigned long addr) -{ - pgd_t * pgdir; - pmd_t * pgmiddle; - pte_t * pgtable; - unsigned long page; - -repeat: - pgdir = pgd_offset(vma->vm_mm, addr); - if (pgd_none(*pgdir)) { - handle_mm_fault(tsk->mm, vma, addr, 0); - goto repeat; - } - if (pgd_bad(*pgdir)) { - printk("ptrace[1]: bad page directory %lx\n", pgd_val(*pgdir)); - pgd_clear(pgdir); - return 0; - } - pgmiddle = pmd_offset(pgdir,addr); - if (pmd_none(*pgmiddle)) { - handle_mm_fault(tsk->mm, vma, addr, 0); - goto repeat; - } - if (pmd_bad(*pgmiddle)) { - printk("ptrace[3]: bad pmd %lx\n", pmd_val(*pgmiddle)); - pmd_clear(pgmiddle); - return 0; - } - pgtable = pte_offset(pgmiddle, addr); - if (!pte_present(*pgtable)) { - handle_mm_fault(tsk->mm, vma, addr, 0); - goto repeat; - } - page = pte_page(*pgtable); -/* this is a hack for non-kernel-mapped video buffers and similar */ - if (MAP_NR(page) >= max_mapnr) - return 0; - page += addr & ~PAGE_MASK; - return *(unsigned long *) page; -} - -/* - * This routine puts a long into any process space by following the page - * tables. NOTE! You should check that the long isn't on a page boundary, - * and that it is in the task area before calling this: this routine does - * no checking. - * - * Now keeps R/W state of page so that a text page stays readonly - * even if a debugger scribbles breakpoints into it. -M.U- - */ -static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, - unsigned long addr, unsigned long data) -{ - pgd_t *pgdir; - pmd_t *pgmiddle; - pte_t *pgtable; - unsigned long page; - -repeat: - pgdir = pgd_offset(vma->vm_mm, addr); - if (!pgd_present(*pgdir)) { - handle_mm_fault(tsk->mm, vma, addr, 1); - goto repeat; - } - if (pgd_bad(*pgdir)) { - printk("ptrace[2]: bad page directory %lx\n", pgd_val(*pgdir)); - pgd_clear(pgdir); - return; - } - pgmiddle = pmd_offset(pgdir,addr); - if (pmd_none(*pgmiddle)) { - handle_mm_fault(tsk->mm, vma, addr, 1); - goto repeat; - } - if (pmd_bad(*pgmiddle)) { - printk("ptrace[4]: bad pmd %lx\n", pmd_val(*pgmiddle)); - pmd_clear(pgmiddle); - return; - } - pgtable = pte_offset(pgmiddle, addr); - if (!pte_present(*pgtable)) { - handle_mm_fault(tsk->mm, vma, addr, 1); - goto repeat; - } - page = pte_page(*pgtable); - if (!pte_write(*pgtable)) { - handle_mm_fault(tsk->mm, vma, addr, 1); - goto repeat; - } -/* this is a hack for non-kernel-mapped video buffers and similar */ - if (MAP_NR(page) < max_mapnr) { - unsigned long phys_addr = page + (addr & ~PAGE_MASK); - *(unsigned long *) phys_addr = data; - flush_icache_range(phys_addr, phys_addr+4); - } -/* we're bypassing pagetables, so we have to set the dirty bit ourselves */ -/* this should also re-instate whatever read-only mode there was before */ - set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot))); - flush_tlb_all(); -} - -/* - * This routine checks the page boundaries, and that the offset is - * within the task area. It then calls get_long() to read a long. - */ -static int read_long(struct task_struct * tsk, unsigned long addr, - unsigned long * result) -{ - struct vm_area_struct * vma = find_extend_vma(tsk->mm, addr); - - if (!vma) - return -EIO; - if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) { - unsigned long low,high; - struct vm_area_struct * vma_low = vma; - - if (addr + sizeof(long) >= vma->vm_end) { - vma_low = vma->vm_next; - if (!vma_low || vma_low->vm_start != vma->vm_end) - return -EIO; - } - high = get_long(tsk, vma,addr & ~(sizeof(long)-1)); - low = get_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1)); - switch (addr & (sizeof(long)-1)) { - case 3: - low >>= 8; - low |= high << 24; - break; - case 2: - low >>= 16; - low |= high << 16; - break; - case 1: - low >>= 24; - low |= high << 8; - break; - } - *result = low; - } else - *result = get_long(tsk, vma,addr); - return 0; -} - -/* - * This routine checks the page boundaries, and that the offset is - * within the task area. It then calls put_long() to write a long. - */ -static int write_long(struct task_struct * tsk, unsigned long addr, - unsigned long data) -{ - struct vm_area_struct * vma = find_extend_vma(tsk->mm, addr); - - if (!vma) - return -EIO; - if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) { - unsigned long low,high; - struct vm_area_struct * vma_low = vma; - - if (addr + sizeof(long) >= vma->vm_end) { - vma_low = vma->vm_next; - if (!vma_low || vma_low->vm_start != vma->vm_end) - return -EIO; - } - high = get_long(tsk, vma,addr & ~(sizeof(long)-1)); - low = get_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1)); - switch (addr & (sizeof(long)-1)) { - case 0: /* shouldn't happen, but safety first */ - high = data; - break; - case 3: - low &= 0x000000ff; - low |= data << 8; - high &= ~0xff; - high |= data >> 24; - break; - case 2: - low &= 0x0000ffff; - low |= data << 16; - high &= ~0xffff; - high |= data >> 16; - break; - case 1: - low &= 0x00ffffff; - low |= data << 24; - high &= ~0xffffff; - high |= data >> 8; - break; - } - put_long(tsk, vma,addr & ~(sizeof(long)-1),high); - put_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1),low); - } else - put_long(tsk, vma,addr,data); - return 0; -} -#endif - -asmlinkage int sys_ptrace(long request, long pid, long addr, long data) +int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; int ret = -EPERM; - unsigned long flags; lock_kernel(); if (request == PTRACE_TRACEME) { @@ -302,209 +96,209 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ret = 0; goto out; } - if (pid == 1) /* you may not mess with init */ - goto out; ret = -ESRCH; read_lock(&tasklist_lock); child = find_task_by_pid(pid); - read_unlock(&tasklist_lock); /* FIXME!!! */ - if ( !child ) + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + if (!child) goto out; + ret = -EPERM; + if (pid == 1) /* you may not mess with init */ + goto out_tsk; + if (request == PTRACE_ATTACH) { if (child == current) - goto out; + goto out_tsk; if ((!child->dumpable || (current->uid != child->euid) || - (current->uid != child->uid) || (current->uid != child->suid) || + (current->uid != child->uid) || (current->gid != child->egid) || - (current->gid != child->gid) || (current->gid != child->sgid) || - (!cap_issubset(child->cap_permitted, current->cap_permitted))) + (!cap_issubset(child->cap_permitted, current->cap_permitted)) || + (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) - goto out; + goto out_tsk; /* the same process cannot be attached many times */ if (child->flags & PF_PTRACED) - goto out; + goto out_tsk; child->flags |= PF_PTRACED; - - write_lock_irqsave(&tasklist_lock, flags); + + write_lock_irq(&tasklist_lock); if (child->p_pptr != current) { REMOVE_LINKS(child); child->p_pptr = current; SET_LINKS(child); } - write_unlock_irqrestore(&tasklist_lock, flags); + write_unlock_irq(&tasklist_lock); send_sig(SIGSTOP, child, 1); ret = 0; - goto out; + goto out_tsk; } ret = -ESRCH; if (!(child->flags & PF_PTRACED)) - goto out; + goto out_tsk; if (child->state != TASK_STOPPED) { if (request != PTRACE_KILL) - goto out; + goto out_tsk; } if (child->p_pptr != current) - goto out; + goto out_tsk; switch (request) { /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ - case PTRACE_PEEKDATA: { - unsigned long tmp; - int copied; + case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKDATA: { + unsigned long tmp; + int copied; + + copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); + ret = -EIO; + if (copied != sizeof(tmp)) + break; + ret = put_user(tmp,(unsigned long *) data); + break; + } - copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); - ret = -EIO; - if (copied != sizeof(tmp)) - goto out; - ret = put_user(tmp,(unsigned long *) data); - goto out; - } /* read the word at location addr in the USER area. */ - case PTRACE_PEEKUSR: { - unsigned long tmp; - - if ((addr & 3) || addr < 0 || addr > (PT_FPSCR << 2)) { - ret = -EIO; - goto out; - } - - ret = verify_area(VERIFY_WRITE, (void *) data, - sizeof(long)); - if (ret) - goto out; - tmp = 0; /* Default return condition */ - addr = addr >> 2; /* temporary hack. */ - if (addr < PT_FPR0) { - tmp = get_reg(child, addr); - } - else if (addr >= PT_FPR0 && addr <= PT_FPSCR) { - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); - tmp = ((long *)child->thread.fpr)[addr - PT_FPR0]; - } - else - ret = -EIO; - if (!ret) - put_user(tmp,(unsigned long *) data); - goto out; + /* XXX this will need fixing for 64-bit */ + case PTRACE_PEEKUSR: { + unsigned long index, tmp; + + ret = -EIO; + /* convert to index and check */ + index = (unsigned long) addr >> 2; + if ((addr & 3) || index > PT_FPSCR) + break; + + if (addr < PT_FPR0) { + tmp = get_reg(child, (int) index); + } else { + if (child->thread.regs->msr & MSR_FP) + giveup_fpu(child); + tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0]; } + ret = put_user(tmp,(unsigned long *) data); + break; + } - /* If I and D space are separate, this will have to be fixed. */ - case PTRACE_POKETEXT: /* write the word at location addr. */ - case PTRACE_POKEDATA: - ret = 0; - if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) - goto out; - ret = -EIO; - goto out; - case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ - ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= ((PT_FPR0 + 64) << 2)) - goto out; + /* If I and D space are separate, this will have to be fixed. */ + case PTRACE_POKETEXT: /* write the word at location addr. */ + case PTRACE_POKEDATA: + ret = 0; + if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) + break; + ret = -EIO; + break; - addr = addr >> 2; /* temporary hack. */ - - if (addr == PT_ORIG_R3) - goto out; - if (addr < PT_FPR0) { - if (put_reg(child, addr, data)) - goto out; - ret = 0; - goto out; - } - if (addr >= PT_FPR0 && addr < PT_FPR0 + 64) { - if (child->thread.regs->msr & MSR_FP) - giveup_fpu(child); - ((long *)child->thread.fpr)[addr - PT_FPR0] = data; - ret = 0; - goto out; - } - goto out; + /* write the word at location addr in the USER area */ + /* XXX this will need fixing for 64-bit */ + case PTRACE_POKEUSR: { + unsigned long index; - case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: { /* restart after signal. */ - ret = -EIO; - if ((unsigned long) data >= _NSIG) - goto out; - if (request == PTRACE_SYSCALL) - child->flags |= PF_TRACESYS; - else - child->flags &= ~PF_TRACESYS; - child->exit_code = data; - wake_up_process(child); - /* make sure the single step bit is not set. */ - clear_single_step(child); + ret = -EIO; + /* convert to index and check */ + index = (unsigned long) addr >> 2; + if ((addr & 3) || index > PT_FPSCR) + break; + + if (addr == PT_ORIG_R3) + break; + if (addr < PT_FPR0) { + ret = put_reg(child, addr, data); + } else { + if (child->thread.regs->msr & MSR_FP) + giveup_fpu(child); + ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data; ret = 0; - goto out; } + break; + } + + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ + case PTRACE_CONT: { /* restart after signal. */ + ret = -EIO; + if ((unsigned long) data > _NSIG) + break; + if (request == PTRACE_SYSCALL) + child->flags |= PF_TRACESYS; + else + child->flags &= ~PF_TRACESYS; + child->exit_code = data; + /* make sure the single step bit is not set. */ + clear_single_step(child); + wake_up_process(child); + ret = 0; + break; + } /* * make the child exit. Best I can do is send it a sigkill. * perhaps it should be put in the status that it wants to * exit. */ - case PTRACE_KILL: { - ret = 0; - if (child->state == TASK_ZOMBIE) /* already dead */ - goto out; - wake_up_process(child); - child->exit_code = SIGKILL; - /* make sure the single step bit is not set. */ - clear_single_step(child); - goto out; - } + case PTRACE_KILL: { + ret = 0; + if (child->state == TASK_ZOMBIE) /* already dead */ + break; + child->exit_code = SIGKILL; + /* make sure the single step bit is not set. */ + clear_single_step(child); + wake_up_process(child); + break; + } - case PTRACE_SINGLESTEP: { /* set the trap flag. */ - ret = -EIO; - if ((unsigned long) data >= _NSIG) - goto out; - child->flags &= ~PF_TRACESYS; - set_single_step(child); - child->exit_code = data; - /* give it a chance to run. */ - wake_up_process(child); - ret = 0; - goto out; - } + case PTRACE_SINGLESTEP: { /* set the trap flag. */ + ret = -EIO; + if ((unsigned long) data > _NSIG) + break; + child->flags &= ~PF_TRACESYS; + set_single_step(child); + child->exit_code = data; + /* give it a chance to run. */ + wake_up_process(child); + ret = 0; + break; + } - case PTRACE_DETACH: { /* detach a process that was attached. */ - ret = -EIO; - if ((unsigned long) data >= _NSIG) - goto out; - child->flags &= ~(PF_PTRACED|PF_TRACESYS); - wake_up_process(child); - child->exit_code = data; - write_lock_irqsave(&tasklist_lock, flags); - REMOVE_LINKS(child); - child->p_pptr = child->p_opptr; - SET_LINKS(child); - write_unlock_irqrestore(&tasklist_lock, flags); - /* make sure the single step bit is not set. */ - clear_single_step(child); - ret = 0; - goto out; - } + case PTRACE_DETACH: { /* detach a process that was attached. */ + ret = -EIO; + if ((unsigned long) data > _NSIG) + break; + child->flags &= ~(PF_PTRACED|PF_TRACESYS); + child->exit_code = data; + write_lock_irq(&tasklist_lock); + REMOVE_LINKS(child); + child->p_pptr = child->p_opptr; + SET_LINKS(child); + write_unlock_irq(&tasklist_lock); + /* make sure the single step bit is not set. */ + clear_single_step(child); + wake_up_process(child); + ret = 0; + break; + } - default: - ret = -EIO; - goto out; + default: + ret = -EIO; + break; } +out_tsk: + free_task_struct(child); out: unlock_kernel(); return ret; } -asmlinkage void syscall_trace(void) +void syscall_trace(void) { if ((current->flags & (PF_PTRACED|PF_TRACESYS)) != (PF_PTRACED|PF_TRACESYS)) - goto out; + return; current->exit_code = SIGTRAP; current->state = TASK_STOPPED; notify_parent(current, SIGCHLD); @@ -518,5 +312,4 @@ asmlinkage void syscall_trace(void) send_sig(current->exit_code, current, 1); current->exit_code = 0; } -out: } diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 49a8da139..67895b87d 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -776,8 +776,11 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id) id->word127 = __le16_to_cpu(id->word127); id->dlf = __le16_to_cpu(id->dlf); id->csfo = __le16_to_cpu(id->csfo); - for (i = 0; i < 30; i++) - id->words130_159[i] = __le16_to_cpu(id->words130_159[i]); + for (i = 0; i < 26; i++) + id->words130_155[i] = __le16_to_cpu(id->words130_155[i]); + id->word156 = __le16_to_cpu(id->word156); + for (i = 0; i < 4; i++) + id->words157_159[i] = __le16_to_cpu(id->words157_159[i]); for (i = 0; i < 96; i++) id->words160_255[i] = __le16_to_cpu(id->words160_255[i]); } diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index b821249d9..3877d11dc 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -41,10 +41,7 @@ #include <asm/processor.h> #include <asm/nvram.h> #include <asm/cache.h> -/* Fixme - Why is this here? - Corey */ -#ifdef CONFIG_8xx #include <asm/8xx_immap.h> -#endif #include <asm/machdep.h> #include "time.h" @@ -62,6 +59,7 @@ time_t last_rtc_update = 0; unsigned decrementer_count; /* count value for 1e6/HZ microseconds */ unsigned count_period_num; /* 1 decrementer count equals */ unsigned count_period_den; /* count_period_num / count_period_den us */ +unsigned long last_tb; /* * timer_interrupt - gets called when the decrementer overflows, @@ -103,6 +101,8 @@ int timer_interrupt(struct pt_regs * regs) */ while ((d = get_dec()) == dval) ; + asm volatile("mftb %0" : "=r" (last_tb) ); + /* * Don't play catchup between the call to time_init() * and sti() in init/main.c. @@ -149,20 +149,21 @@ int timer_interrupt(struct pt_regs * regs) */ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; + unsigned long flags, diff; save_flags(flags); cli(); *tv = xtime; /* XXX we don't seem to have the decrementers synced properly yet */ #ifndef CONFIG_SMP - tv->tv_usec += (decrementer_count - get_dec()) - * count_period_num / count_period_den; - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } + asm volatile("mftb %0" : "=r" (diff) ); + diff -= last_tb; + + tv->tv_usec += diff * count_period_num / count_period_den; + tv->tv_sec += tv->tv_usec / 1000000; + tv->tv_usec = tv->tv_usec % 1000000; #endif + restore_flags(flags); } @@ -334,6 +335,3 @@ void to_tm(int tim, struct rtc_time * tm) */ GregorianDay(tm); } - - - diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 28a5a5035..0701f7118 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -91,7 +91,7 @@ MachineCheckException(struct pt_regs *regs) { #if defined(CONFIG_8xx) && defined(CONFIG_PCI) /* the qspan pci read routines can cause machine checks -- Cort */ - bad_page_fault(regs,regs->dar); + bad_page_fault(regs, regs->dar); return; #endif #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) @@ -214,8 +214,6 @@ AlignmentException(struct pt_regs *regs) { int fixed; - if (regs->msr & MSR_FP) - giveup_fpu(current); fixed = fix_alignment(regs); if (fixed == 1) { regs->nip += 4; /* skip over emulated instruction */ @@ -223,7 +221,10 @@ AlignmentException(struct pt_regs *regs) } if (fixed == -EFAULT) { /* fixed == -EFAULT means the operand address was bad */ - bad_page_fault(regs, regs->dar); + if (user_mode(regs)) + force_sig(SIGSEGV, current); + else + bad_page_fault(regs, regs->dar); return; } _exception(SIGBUS, regs); diff --git a/arch/ppc/mbxboot/Makefile b/arch/ppc/mbxboot/Makefile index 9dd5d64f3..53611aa58 100644 --- a/arch/ppc/mbxboot/Makefile +++ b/arch/ppc/mbxboot/Makefile @@ -28,14 +28,14 @@ ISZ = 0 TFTPIMAGE=/tftpboot/zImage.embedded ifdef CONFIG_8xx -ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00180000 -OBJECTS := head.o misc.o ../coffboot/zlib.o m8xx_tty.o +ZLINKFLAGS = -T vmlinux.lds -Ttext 0x00180000 +OBJECTS := head.o misc.o ../coffboot/zlib.o m8xx_tty.o gzimage.o rdimage.o CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8xx endif ifdef CONFIG_8260 -ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00400000 -OBJECTS := head_8260.o misc.o ../coffboot/zlib.o m8260_tty.o embed_config.o +ZLINKFLAGS = -T vmlinux.lds -Ttext 0x00400000 +OBJECTS := head_8260.o misc.o ../coffboot/zlib.o m8260_tty.o embed_config.o gzimage.o rdimage.o CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8260 endif @@ -61,21 +61,32 @@ endif all: zImage zvmlinux.initrd: zvmlinux - $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp1 $(OBJECTS) +# +# Build the boot loader images +# + $(OBJCOPY) $(OBJCOPY_ARGS) -R .gzimage gzimage.o $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=ramdisk.image.gz \ - --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.initrd.tmp1 zvmlinux.initrd1 - $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd1 initrd` \ - -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd1 initrd` \ - -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd1 image` \ - -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd1 image` \ - -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) + --add-section=.gzimage=../coffboot/vmlinux.gz \ + --set-section-flags=.gzimage=alloc,load,readonly,data \ + gzimage.o + $(OBJCOPY) $(OBJCOPY_ARGS) -R .rdimage rdimage.o $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=ramdisk.image.gz \ - --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.initrd.tmp $@ + --add-section=.rdimage=ramdisk.image.gz \ + --set-section-flags=.rdimage=alloc,load,readonly,data \ + rdimage.o + $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS) +# +# Compute the sizes/offsets for the final image, and rebuild with these values. +# + $(CC) $(CFLAGS) \ + -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd .rdimage` \ + -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd .rdimage` \ + -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd .gzimage` \ + -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd .gzimage` \ + -c -o misc.o misc.c + $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment $@ + $(OBJDUMP) -h $@ zImage: zvmlinux ln -sf zvmlinux zImage @@ -85,23 +96,27 @@ zImage.initrd: zvmlinux.initrd zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz # -# build the boot loader image and then compute the offset into it -# for the kernel image +# Build the boot loader images # - $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.tmp $@ # -# then with the offset rebuild the bootloader so we know where the kernel is + $(OBJCOPY) $(OBJCOPY_ARGS) -R .gzimage gzimage.o + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=.gzimage=../coffboot/vmlinux.gz \ + --set-section-flags=.gzimage=alloc,load,readonly,data \ + gzimage.o + $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS) +# +# Compute the sizes/offsets for the final image, and rebuild with these values. # - $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ - -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux image` \ - -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` \ + $(CC) $(CFLAGS) \ + -DINITRD_OFFSET=0 \ + -DINITRD_SIZE=0 \ + -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux .gzimage` \ + -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux .gzimage` \ -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.tmp $@ - rm zvmlinux.tmp + $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment $@ + $(OBJDUMP) -h $@ znetboot : zImage cp zImage $(TFTPIMAGE) diff --git a/arch/ppc/mbxboot/embed_config.c b/arch/ppc/mbxboot/embed_config.c index 1d76be70c..048f8bcfe 100644 --- a/arch/ppc/mbxboot/embed_config.c +++ b/arch/ppc/mbxboot/embed_config.c @@ -236,12 +236,12 @@ embed_config(bd_t *bd) * here for those people that may load the kernel with * a JTAG/COP tool and not the rom monitor. */ - bd->bi_baudrate = 115200; - bd->bi_intfreq = 200; - bd->bi_busfreq = 66; - bd->bi_cpmfreq = 66; - bd->bi_brgfreq = 33; - bd->bi_memsize = 16 * 1024 * 1024; + bd->bi_baudrate = 19200; + bd->bi_intfreq = 165; + bd->bi_busfreq = 33; + bd->bi_cpmfreq = 132; + bd->bi_brgfreq = bd->bi_cpmfreq / 2; /* BRGCLK = (CPM*2/4) */ + bd->bi_memsize = 16 * 1024 * 1024; #endif cp = (u_char *)def_enet_addr; @@ -250,3 +250,4 @@ embed_config(bd_t *bd) } } #endif /* EST8260 */ + diff --git a/arch/ppc/mbxboot/gzimage.c b/arch/ppc/mbxboot/gzimage.c new file mode 100644 index 000000000..11ce5be8e --- /dev/null +++ b/arch/ppc/mbxboot/gzimage.c @@ -0,0 +1,8 @@ +/* + * gzimage.c + * + * Dummy file to allow a compressed zImage to be added + * into a linker section, accessed by the boot coode + */ + +char dummy_for_gzimage; diff --git a/arch/ppc/mbxboot/head_8260.S b/arch/ppc/mbxboot/head_8260.S index 79377a2ac..0895ce025 100644 --- a/arch/ppc/mbxboot/head_8260.S +++ b/arch/ppc/mbxboot/head_8260.S @@ -9,10 +9,17 @@ * $Id: head.S,v 1.33 1999/09/08 01:06:58 cort Exp $ * * Boot loader philosophy: + * * ROM loads us to some arbitrary location - * Move the boot code to the link address (8M) + * ROM loads these registers: + * + * R3 = Pointer to the board configuration data + * R5 = Pointer to Open Firmware data + * + * ROM jumps to start/start_ + * Move the boot code to the link address (4 MB) * Call decompress_kernel() - * Relocate the initrd, zimage and residual data to 8M + * Relocate the initrd, zimage and residual data to 4 MB * Decompress the kernel to 0 * Jump to the kernel entry * -- Cort diff --git a/arch/ppc/mbxboot/misc.c b/arch/ppc/mbxboot/misc.c index 683f53491..d5a44df1e 100644 --- a/arch/ppc/mbxboot/misc.c +++ b/arch/ppc/mbxboot/misc.c @@ -25,6 +25,15 @@ #endif /* + * The following references are needed to cause the linker to pull in the + * gzimage.o and rdimage.o files. These object files are special, + * since they get placed into the .gzimage and .rdimage ELF sections + * of the zvmlinux and zvmlinux.initrd files. + */ +extern char dummy_for_gzimage; +extern char dummy_for_rdimage; + +/* * Please send me load/board info and such data for hardware not * listed here so I can keep track since things are getting tricky * with the different load addrs with different firmware. This will diff --git a/arch/ppc/mbxboot/rdimage.c b/arch/ppc/mbxboot/rdimage.c new file mode 100644 index 000000000..e40fd1e2e --- /dev/null +++ b/arch/ppc/mbxboot/rdimage.c @@ -0,0 +1,8 @@ +/* + * rdimage.c + * + * Dummy file to allow a compressed initrd to be added + * into a linker section, accessed by the boot coode + */ + +char dummy_for_rdimage; diff --git a/arch/ppc/mbxboot/vmlinux.lds b/arch/ppc/mbxboot/vmlinux.lds new file mode 100644 index 000000000..2bf2c87b3 --- /dev/null +++ b/arch/ppc/mbxboot/vmlinux.lds @@ -0,0 +1,152 @@ +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } +/* .init : { *(.init) } =0*/ + .plt : { *(.plt) } + .text : + { + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.got.plt) *(.got) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + .fixup : { *(.fixup) } + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { + *(.data.init); + __vtop_table_begin = .; + *(.vtop_fixup); + __vtop_table_end = .; + __ptov_table_begin = .; + *(.ptov_fixup); + __ptov_table_end = .; + } + . = ALIGN(16); + __setup_start = .; + .setup.init : { *(.setup.init) } + __setup_end = .; + __initcall_start = .; + .initcall.init : { *(.initcall.init) } + __initcall_end = .; + . = ALIGN(4096); + __init_end = .; + + . = ALIGN(4096); + __pmac_begin = .; + .text.pmac : { *(.text.pmac) } + .data.pmac : { *(.data.pmac) } + . = ALIGN(4096); + __pmac_end = .; + + . = ALIGN(4096); + __prep_begin = .; + .text.prep : { *(.text.prep) } + .data.prep : { *(.data.prep) } + . = ALIGN(4096); + __prep_end = .; + + . = ALIGN(4096); + __apus_begin = .; + .text.apus : { *(.text.apus) } + .data.apus : { *(.data.apus) } + . = ALIGN(4096); + __apus_end = .; + + . = ALIGN(4096); + __apus_begin = .; + .text.apus : { *(.text.apus) } + .data.apus : { *(.data.apus) } + . = ALIGN(4096); + __apus_end = .; + + . = ALIGN(4096); + __openfirmware_begin = .; + .text.openfirmware : { *(.text.openfirmware) } + .data.openfirmware : { *(.data.openfirmware) } + . = ALIGN(4096); + __openfirmware_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); + + /* + * For loader only: Put the zImage after everything else + */ + _gzstart = . ; + .gzimage : { *(.gzimage) } + _gzend = . ; + + /* + * For loader only: Put the initrd after zImage + */ + _rdstart = . ; + .rdimage : { *(.rdimage) } + _rdend = . ; + +} diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index 076ee56e5..7a899252f 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -62,10 +62,21 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, { struct vm_area_struct * vma; struct mm_struct *mm = current->mm; + siginfo_t info; + int code = SEGV_MAPERR; #if defined(CONFIG_4xx) int is_write = error_code & ESR_DST; #else int is_write = error_code & 0x02000000; + + /* + * Fortunately the bit assignments in SRR1 for an instruction + * fault and DSISR for a data fault are mostly the same for the + * bits we are interested in. But there are some bits which + * indicate errors in DSISR but can validly be set in SRR1. + */ + if (regs->trap == 0x400) + error_code &= 0x48200000; #endif /* CONFIG_4xx */ #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) @@ -82,16 +93,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, #endif /* !CONFIG_4xx */ #endif /* CONFIG_XMON || CONFIG_KGDB */ - if (in_interrupt()) { - static int complained; - if (complained < 20) { - ++complained; - printk("page fault in interrupt handler, addr=%lx\n", - address); - show_regs(regs); - } - } - if (current == NULL || mm == NULL) { + if (in_interrupt() || mm == NULL) { bad_page_fault(regs, address); return; } @@ -107,10 +109,12 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, goto bad_area; good_area: + code = SEGV_ACCERR; #if defined(CONFIG_6xx) if (error_code & 0x95700000) /* an error such as lwarx to I/O controller space, address matching DABR, eciwx, etc. */ + goto bad_area; #endif /* CONFIG_6xx */ #if defined(CONFIG_8xx) /* The MPC8xx seems to always set 0x80000000, which is @@ -119,9 +123,8 @@ good_area: */ if (error_code & 0x10000000) /* Guarded storage error. */ -#endif /* CONFIG_8xx */ goto bad_area; - +#endif /* CONFIG_8xx */ /* a write */ if (is_write) { @@ -135,8 +138,25 @@ good_area: if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } - if (!handle_mm_fault(mm, vma, address, is_write)) - goto bad_area; + + /* + * If for any reason at all we couldn't handle the fault, + * make sure we exit gracefully rather than endlessly redo + * the fault. + */ + switch (handle_mm_fault(mm, vma, address, is_write)) { + case 1: + current->min_flt++; + break; + case 2: + current->maj_flt++; + break; + case 0: + goto do_sigbus; + default: + goto out_of_memory; + } + up(&mm->mmap_sem); /* * keep track of tlb+htab misses that are good addrs but @@ -147,22 +167,55 @@ good_area: return; bad_area: - up(&mm->mmap_sem); pte_errors++; + + /* User mode accesses cause a SIGSEGV */ + if (user_mode(regs)) { + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_code = code; + info.si_addr = (void *) address; + force_sig_info(SIGSEGV, &info, current); + return; + } + + bad_page_fault(regs, address); + return; + +/* + * We ran out of memory, or some other thing happened to us that made + * us unable to handle the page fault gracefully. + */ +out_of_memory: + up(&mm->mmap_sem); + printk("VM: killing process %s\n", current->comm); + if (user_mode(regs)) + do_exit(SIGKILL); bad_page_fault(regs, address); + return; + +do_sigbus: + up(&mm->mmap_sem); + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRERR; + info.si_addr = (void *)address; + force_sig_info (SIGBUS, &info, current); + if (!user_mode(regs)) + bad_page_fault(regs, address); } +/* + * bad_page_fault is called when we have a bad access from the kernel. + * It is called from do_page_fault above and from some of the procedures + * in traps.c. + */ void bad_page_fault(struct pt_regs *regs, unsigned long address) { unsigned long fixup; - if (user_mode(regs)) { - force_sig(SIGSEGV, current); - return; - } - /* Are we prepared to handle this fault? */ if ((fixup = search_exception_table(regs->nip)) != 0) { regs->nip = fixup; diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 80fb7575e..fc3acdd5c 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -83,6 +83,7 @@ extern char _start[], _end[]; extern char etext[], _stext[]; extern char __init_begin, __init_end; extern char __prep_begin, __prep_end; +extern char __chrp_begin, __chrp_end; extern char __pmac_begin, __pmac_end; extern char __apus_begin, __apus_end; extern char __openfirmware_begin, __openfirmware_end; @@ -777,7 +778,7 @@ void __init free_initmem(void) unsigned long a; unsigned long num_freed_pages = 0, num_prep_pages = 0, num_pmac_pages = 0, num_openfirmware_pages = 0, - num_apus_pages = 0; + num_apus_pages = 0, num_chrp_pages = 0; #define FREESEC(START,END,CNT) do { \ a = (unsigned long)(&START); \ for (; a < (unsigned long)(&END); a += PAGE_SIZE) { \ @@ -794,6 +795,7 @@ void __init free_initmem(void) case _MACH_Pmac: FREESEC(__apus_begin,__apus_end,num_apus_pages); FREESEC(__prep_begin,__prep_end,num_prep_pages); + FREESEC(__chrp_begin,__chrp_end,num_chrp_pages); break; case _MACH_chrp: FREESEC(__apus_begin,__apus_end,num_apus_pages); @@ -803,20 +805,24 @@ void __init free_initmem(void) case _MACH_prep: FREESEC(__apus_begin,__apus_end,num_apus_pages); FREESEC(__pmac_begin,__pmac_end,num_pmac_pages); + FREESEC(__chrp_begin,__chrp_end,num_chrp_pages); break; case _MACH_mbx: FREESEC(__apus_begin,__apus_end,num_apus_pages); FREESEC(__pmac_begin,__pmac_end,num_pmac_pages); FREESEC(__prep_begin,__prep_end,num_prep_pages); + FREESEC(__chrp_begin,__chrp_end,num_chrp_pages); break; case _MACH_apus: FREESEC(__pmac_begin,__pmac_end,num_pmac_pages); FREESEC(__prep_begin,__prep_end,num_prep_pages); + FREESEC(__chrp_begin,__chrp_end,num_chrp_pages); break; case _MACH_gemini: FREESEC(__apus_begin,__apus_end,num_apus_pages); FREESEC(__pmac_begin,__pmac_end,num_pmac_pages); FREESEC(__prep_begin,__prep_end,num_prep_pages); + FREESEC(__chrp_begin,__chrp_end,num_chrp_pages); break; } @@ -829,6 +835,8 @@ void __init free_initmem(void) if ( num_prep_pages ) printk(" %ldk prep", PGTOKB(num_prep_pages)); + if ( num_chrp_pages ) + printk(" %ldk chrp", PGTOKB(num_chrp_pages)); if ( num_pmac_pages ) printk(" %ldk pmac", PGTOKB(num_pmac_pages)); if ( num_openfirmware_pages ) diff --git a/arch/ppc/treeboot/mkevimg b/arch/ppc/treeboot/mkevimg index 76f849bb7..68eb4dd3f 100644 --- a/arch/ppc/treeboot/mkevimg +++ b/arch/ppc/treeboot/mkevimg @@ -1,4 +1,4 @@ -#!/usr/local/bin/perl +#!/usr/bin/perl # # Copyright (c) 1998-1999 TiVo, Inc. diff --git a/arch/ppc/treeboot/mkirimg b/arch/ppc/treeboot/mkirimg index e8aa24e3d..17a6f2328 100644 --- a/arch/ppc/treeboot/mkirimg +++ b/arch/ppc/treeboot/mkirimg @@ -1,4 +1,4 @@ -#!/usr/local/bin/perl +#!/usr/bin/perl # # Copyright (c) 1998-1999 TiVo, Inc. # Original ELF parsing code. @@ -332,7 +332,7 @@ require 'elf.pl'; syswrite(OUTPUT, $ibuf, $initialOffset); if ($imageFound) { - $testN = pack ("I2", $bss_addr + $bss_size, $image_size); + $testN = pack ("N2", $bss_addr + $bss_size, $image_size); syswrite(OUTPUT, $testN, length($testN)); printf("Updated symbol \"imageSect_start\" to 0x%08x\n", $bss_addr + $bss_size); @@ -342,7 +342,7 @@ require 'elf.pl'; } if ($initrdFound) { - $testN = pack ("I2", $bss_addr + $bss_size + $image_size, $initrd_size); + $testN = pack ("N2", $bss_addr + $bss_size + $image_size, $initrd_size); syswrite(OUTPUT, $testN, length($testN)); printf("Updated symbol \"initrdSect_start\" to 0x%08x\n", $bss_addr + $bss_size + $image_size); diff --git a/arch/ppc/vmlinux.lds b/arch/ppc/vmlinux.lds index 707c4ad2f..7bfdc4efb 100644 --- a/arch/ppc/vmlinux.lds +++ b/arch/ppc/vmlinux.lds @@ -104,6 +104,13 @@ SECTIONS __prep_end = .; . = ALIGN(4096); + __chrp_begin = .; + .text.chrp : { *(.text.chrp) } + .data.chrp : { *(.data.chrp) } + . = ALIGN(4096); + __chrp_end = .; + + . = ALIGN(4096); __apus_begin = .; .text.apus : { *(.text.apus) } .data.apus : { *(.data.apus) } @@ -135,4 +142,3 @@ SECTIONS _end = . ; PROVIDE (end = .); } - |