diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-04-05 04:55:58 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-04-05 04:55:58 +0000 |
commit | 74a9f2e1b4d3ab45a9f72cb5b556c9f521524ab3 (patch) | |
tree | 7c4cdb103ab1b388c9852a88bd6fb1e73eba0b5c /arch | |
parent | ee6374c8b0d333c08061c6a97bc77090d7461225 (diff) |
Merge with Linux 2.4.3.
Note that mingetty does no longer work with serial console, you have to
switch to another getty like getty_ps. This commit also includes a
fix for a setitimer bug which did prevent getty_ps from working on
older kernels.
Diffstat (limited to 'arch')
242 files changed, 9966 insertions, 2769 deletions
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig index 702778091..feb49e997 100644 --- a/arch/alpha/defconfig +++ b/arch/alpha/defconfig @@ -285,10 +285,8 @@ CONFIG_SR_EXTRA_DEVS=2 # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 -CONFIG_AIC7XXX_PROC_STATS=y -CONFIG_AIC7XXX_RESET_DELAY=5 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 +CONFIG_AIC7XXX_RESET_DELAY=5000 # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index d7bf13ec3..997cc772d 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -235,3 +235,4 @@ EXPORT_SYMBOL_NOVERS(memcpy); EXPORT_SYMBOL_NOVERS(memset); EXPORT_SYMBOL(get_wchan); +EXPORT_SYMBOL(flush_tlb_page); diff --git a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c index b946ce0ed..254ab65d3 100644 --- a/arch/alpha/kernel/console.c +++ b/arch/alpha/kernel/console.c @@ -21,8 +21,8 @@ unsigned long __vga_hose_io_base = 0; /* base for default hose */ unsigned long __vga_hose_mem_base = 0; /* base for default hose */ -static struct pci_controler * __init -default_vga_hose_select(struct pci_controler *h1, struct pci_controler *h2) +static struct pci_controller * __init +default_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2) { if (h2->index < h1->index) return h2; @@ -31,7 +31,7 @@ default_vga_hose_select(struct pci_controler *h1, struct pci_controler *h2) } void __init -set_vga_hose(struct pci_controler *hose) +set_vga_hose(struct pci_controller *hose) { if (hose) { __vga_hose_io_base = hose->io_space->start; @@ -42,7 +42,7 @@ set_vga_hose(struct pci_controler *hose) void __init locate_and_init_vga(void *(*sel_func)(void *, void *)) { - struct pci_controler *hose = NULL; + struct pci_controller *hose = NULL; struct pci_dev *dev = NULL; if (!sel_func) sel_func = (void *)default_vga_hose_select; diff --git a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c index 41143ff99..a44d941c0 100644 --- a/arch/alpha/kernel/core_apecs.c +++ b/arch/alpha/kernel/core_apecs.c @@ -357,7 +357,7 @@ struct pci_ops apecs_pci_ops = }; void -apecs_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) +apecs_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { wmb(); *(vip)APECS_IOC_TBIA = 0; @@ -367,13 +367,13 @@ apecs_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) void __init apecs_init_arch(void) { - struct pci_controler *hose; + struct pci_controller *hose; /* * Create our single hose. */ - pci_isa_hose = hose = alloc_pci_controler(); + pci_isa_hose = hose = alloc_pci_controller(); hose->io_space = &ioport_resource; hose->mem_space = &iomem_resource; hose->index = 0; diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c index 6203b0247..e2d957c98 100644 --- a/arch/alpha/kernel/core_cia.c +++ b/arch/alpha/kernel/core_cia.c @@ -299,7 +299,7 @@ struct pci_ops cia_pci_ops = */ void -cia_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) +cia_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { wmb(); *(vip)CIA_IOC_PCI_TBIA = 3; /* Flush all locked and unlocked. */ @@ -314,7 +314,7 @@ cia_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) */ static void -cia_pci_tbi_try1(struct pci_controler *hose, +cia_pci_tbi_try1(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { wmb(); @@ -359,7 +359,7 @@ cia_enable_broken_tbi_try2(void) } static void -cia_pci_tbi_try2(struct pci_controler *hose, +cia_pci_tbi_try2(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { unsigned long flags; @@ -595,7 +595,7 @@ failed: static void __init do_init_arch(int is_pyxis) { - struct pci_controler *hose; + struct pci_controller *hose; int temp; int cia_rev; @@ -628,7 +628,7 @@ do_init_arch(int is_pyxis) *(vip)CIA_IOC_HAE_IO = 0; /* For PYXIS, we always use BWX bus and i/o accesses. To that end, - make sure they're enabled on the controler. */ + make sure they're enabled on the controller. */ if (is_pyxis) { temp = *(vip)CIA_IOC_CIA_CNFG; temp |= CIA_CNFG_IOA_BWEN; @@ -643,7 +643,7 @@ do_init_arch(int is_pyxis) * Create our single hose. */ - pci_isa_hose = hose = alloc_pci_controler(); + pci_isa_hose = hose = alloc_pci_controller(); hose->io_space = &ioport_resource; hose->mem_space = &iomem_resource; hose->index = 0; diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c index 030348747..709e8bab2 100644 --- a/arch/alpha/kernel/core_irongate.c +++ b/arch/alpha/kernel/core_irongate.c @@ -367,7 +367,7 @@ again: void __init irongate_init_arch(void) { - struct pci_controler *hose; + struct pci_controller *hose; IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100; irongate_pci_clr_err(); @@ -377,7 +377,7 @@ irongate_init_arch(void) * Create our single hose. */ - pci_isa_hose = hose = alloc_pci_controler(); + pci_isa_hose = hose = alloc_pci_controller(); hose->io_space = &ioport_resource; hose->mem_space = &iomem_resource; hose->index = 0; diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c index 5329acfac..28d743dd5 100644 --- a/arch/alpha/kernel/core_lca.c +++ b/arch/alpha/kernel/core_lca.c @@ -279,7 +279,7 @@ struct pci_ops lca_pci_ops = }; void -lca_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) +lca_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { wmb(); *(vip)LCA_IOC_TBIA = 0; @@ -289,13 +289,13 @@ lca_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) void __init lca_init_arch(void) { - struct pci_controler *hose; + struct pci_controller *hose; /* * Create our single hose. */ - pci_isa_hose = hose = alloc_pci_controler(); + pci_isa_hose = hose = alloc_pci_controller(); hose->io_space = &ioport_resource; hose->mem_space = &iomem_resource; hose->index = 0; diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c index f114ab24f..94eec6988 100644 --- a/arch/alpha/kernel/core_mcpcia.c +++ b/arch/alpha/kernel/core_mcpcia.c @@ -89,7 +89,7 @@ static unsigned int conf_read(unsigned long addr, unsigned char type1, - struct pci_controler *hose) + struct pci_controller *hose) { unsigned long flags; unsigned long mid = MCPCIA_HOSE2MID(hose->index); @@ -137,7 +137,7 @@ conf_read(unsigned long addr, unsigned char type1, static void conf_write(unsigned long addr, unsigned int value, unsigned char type1, - struct pci_controler *hose) + struct pci_controller *hose) { unsigned long flags; unsigned long mid = MCPCIA_HOSE2MID(hose->index); @@ -171,7 +171,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1, } static int -mk_conf_addr(struct pci_dev *dev, int where, struct pci_controler *hose, +mk_conf_addr(struct pci_dev *dev, int where, struct pci_controller *hose, unsigned long *pci_addr, unsigned char *type1) { u8 bus = dev->bus->number; @@ -199,7 +199,7 @@ mk_conf_addr(struct pci_dev *dev, int where, struct pci_controler *hose, static int mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value) { - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; unsigned long addr, w; unsigned char type1; @@ -215,7 +215,7 @@ mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value) static int mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value) { - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; unsigned long addr, w; unsigned char type1; @@ -231,7 +231,7 @@ mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value) static int mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value) { - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; unsigned long addr; unsigned char type1; @@ -246,7 +246,7 @@ mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value) static int mcpcia_write_config(struct pci_dev *dev, int where, u32 value, long mask) { - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; unsigned long addr; unsigned char type1; @@ -288,7 +288,7 @@ struct pci_ops mcpcia_pci_ops = }; void -mcpcia_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) +mcpcia_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { wmb(); *(vuip)MCPCIA_SG_TBIA(MCPCIA_HOSE2MID(hose->index)) = 0; @@ -333,11 +333,11 @@ mcpcia_probe_hose(int h) static void __init mcpcia_new_hose(int h) { - struct pci_controler *hose; + struct pci_controller *hose; struct resource *io, *mem, *hae_mem; int mid = MCPCIA_HOSE2MID(h); - hose = alloc_pci_controler(); + hose = alloc_pci_controller(); if (h == 0) pci_isa_hose = hose; io = alloc_resource(); @@ -386,7 +386,7 @@ mcpcia_pci_clr_err(int mid) } static void __init -mcpcia_startup_hose(struct pci_controler *hose) +mcpcia_startup_hose(struct pci_controller *hose) { int mid = MCPCIA_HOSE2MID(hose->index); unsigned int tmp; @@ -464,7 +464,7 @@ mcpcia_init_arch(void) void __init mcpcia_init_hoses(void) { - struct pci_controler *hose; + struct pci_controller *hose; int hose_count; int h; @@ -561,7 +561,7 @@ static void mcpcia_print_system_area(unsigned long la_ptr) { struct el_common *frame; - struct pci_controler *hose; + struct pci_controller *hose; struct IOD_subpacket { unsigned long base; @@ -638,7 +638,7 @@ mcpcia_machine_check(unsigned long vector, unsigned long la_ptr, { /* FIXME: how do we figure out which hose the error was on? */ - struct pci_controler *hose; + struct pci_controller *hose; for (hose = hose_head; hose; hose = hose->next) mcpcia_pci_clr_err(MCPCIA_HOSE2MID(hose->index)); break; diff --git a/arch/alpha/kernel/core_polaris.c b/arch/alpha/kernel/core_polaris.c index 56601c4c5..2eb147c54 100644 --- a/arch/alpha/kernel/core_polaris.c +++ b/arch/alpha/kernel/core_polaris.c @@ -178,7 +178,7 @@ struct pci_ops polaris_pci_ops = void __init polaris_init_arch(void) { - struct pci_controler *hose; + struct pci_controller *hose; /* May need to initialize error reporting (see PCICTL0/1), but * for now assume that the firmware has done the right thing @@ -192,7 +192,7 @@ polaris_init_arch(void) * Create our single hose. */ - pci_isa_hose = hose = alloc_pci_controler(); + pci_isa_hose = hose = alloc_pci_controller(); hose->io_space = &ioport_resource; hose->mem_space = &iomem_resource; hose->index = 0; diff --git a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c index 26aac4a38..1fd7d1266 100644 --- a/arch/alpha/kernel/core_t2.c +++ b/arch/alpha/kernel/core_t2.c @@ -324,7 +324,7 @@ struct pci_ops t2_pci_ops = void __init t2_init_arch(void) { - struct pci_controler *hose; + struct pci_controller *hose; unsigned int i; for (i = 0; i < NR_CPUS; i++) { @@ -384,7 +384,7 @@ t2_init_arch(void) * Create our single hose. */ - pci_isa_hose = hose = alloc_pci_controler(); + pci_isa_hose = hose = alloc_pci_controller(); hose->io_space = &ioport_resource; hose->mem_space = &iomem_resource; hose->index = 0; diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c index 5e53d091c..350b106b3 100644 --- a/arch/alpha/kernel/core_titan.c +++ b/arch/alpha/kernel/core_titan.c @@ -83,7 +83,7 @@ static int mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr, unsigned char *type1) { - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; unsigned long addr; u8 bus = dev->bus->number; u8 device_fn = dev->devfn; @@ -200,7 +200,7 @@ struct pci_ops titan_pci_ops = void -titan_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) +titan_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { titan_pachip *pachip = (hose->index & 1) ? TITAN_pachip1 : TITAN_pachip0; @@ -243,7 +243,7 @@ titan_query_agp(titan_pachip_port *port) } static void __init -titan_init_agp(titan_pachip_port *port, struct pci_controler *hose) +titan_init_agp(titan_pachip_port *port, struct pci_controller *hose) { union TPAchipPCTL pctl; @@ -276,9 +276,9 @@ titan_init_agp(titan_pachip_port *port, struct pci_controler *hose) static void __init titan_init_one_pachip_port(titan_pachip_port *port, int index) { - struct pci_controler *hose; + struct pci_controller *hose; - hose = alloc_pci_controler(); + hose = alloc_pci_controller(); if (index == 0) pci_isa_hose = hose; hose->io_space = alloc_resource(); diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c index 45ff9bb12..282eb0347 100644 --- a/arch/alpha/kernel/core_tsunami.c +++ b/arch/alpha/kernel/core_tsunami.c @@ -90,7 +90,7 @@ static int mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr, unsigned char *type1) { - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; unsigned long addr; u8 bus = dev->bus->number; u8 device_fn = dev->devfn; @@ -206,7 +206,7 @@ struct pci_ops tsunami_pci_ops = }; void -tsunami_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) +tsunami_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { tsunami_pchip *pchip = hose->index ? TSUNAMI_pchip1 : TSUNAMI_pchip0; volatile unsigned long *csr; @@ -280,12 +280,12 @@ tsunami_probe_write(volatile unsigned long *vaddr) static void __init tsunami_init_one_pchip(tsunami_pchip *pchip, int index) { - struct pci_controler *hose; + struct pci_controller *hose; if (tsunami_probe_read(&pchip->pctl.csr) == 0) return; - hose = alloc_pci_controler(); + hose = alloc_pci_controller(); if (index == 0) pci_isa_hose = hose; hose->io_space = alloc_resource(); diff --git a/arch/alpha/kernel/core_wildfire.c b/arch/alpha/kernel/core_wildfire.c index 9b4f28c10..cf27355f9 100644 --- a/arch/alpha/kernel/core_wildfire.c +++ b/arch/alpha/kernel/core_wildfire.c @@ -64,10 +64,10 @@ unsigned long wildfire_mem_mask; void __init wildfire_init_hose(int qbbno, int hoseno) { - struct pci_controler *hose; + struct pci_controller *hose; wildfire_pci *pci; - hose = alloc_pci_controler(); + hose = alloc_pci_controller(); hose->io_space = alloc_resource(); hose->mem_space = alloc_resource(); @@ -346,7 +346,7 @@ wildfire_kill_arch(int mode) } void -wildfire_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end) +wildfire_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { int qbbno = hose->index >> 3; int hoseno = hose->index & 7; @@ -360,7 +360,7 @@ static int mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr, unsigned char *type1) { - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; unsigned long addr; u8 bus = dev->bus->number; u8 device_fn = dev->devfn; diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 6159457d9..109de59a2 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -242,9 +242,9 @@ asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len, goto out; } flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); ret = do_mmap(file, addr, len, prot, flags, off); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); out: diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c index d530ebb82..7beed3ab1 100644 --- a/arch/alpha/kernel/pci-noop.c +++ b/arch/alpha/kernel/pci-noop.c @@ -14,17 +14,17 @@ /* - * The PCI controler list. + * The PCI controller list. */ -struct pci_controler *hose_head, **hose_tail = &hose_head; -struct pci_controler *pci_isa_hose; +struct pci_controller *hose_head, **hose_tail = &hose_head; +struct pci_controller *pci_isa_hose; -struct pci_controler * __init -alloc_pci_controler(void) +struct pci_controller * __init +alloc_pci_controller(void) { - struct pci_controler *hose; + struct pci_controller *hose; hose = alloc_bootmem(sizeof(*hose)); @@ -47,7 +47,7 @@ alloc_resource(void) asmlinkage long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn) { - struct pci_controler *hose; + struct pci_controller *hose; struct pci_dev *dev; /* from hose or from bus.devfn */ diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index ddf3d9755..e473d21a2 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -43,11 +43,11 @@ const char pci_hae0_name[] = "HAE0"; /* - * The PCI controler list. + * The PCI controller list. */ -struct pci_controler *hose_head, **hose_tail = &hose_head; -struct pci_controler *pci_isa_hose; +struct pci_controller *hose_head, **hose_tail = &hose_head; +struct pci_controller *pci_isa_hose; /* * Quirks. @@ -136,7 +136,7 @@ void pcibios_align_resource(void *data, struct resource *res, unsigned long size) { struct pci_dev *dev = data; - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; unsigned long alignto; unsigned long start = res->start; @@ -224,7 +224,7 @@ void __init pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus) { /* Update device resources. */ - struct pci_controler *hose = (struct pci_controler *)bus->sysdata; + struct pci_controller *hose = (struct pci_controller *)bus->sysdata; int i; for (i = 0; i < PCI_NUM_RESOURCES; i++) { @@ -244,7 +244,7 @@ pcibios_fixup_bus(struct pci_bus *bus) { /* Propogate hose info into the subordinate devices. */ - struct pci_controler *hose = bus->sysdata; + struct pci_controller *hose = bus->sysdata; struct list_head *ln; struct pci_dev *dev = bus->self; @@ -284,7 +284,7 @@ void pcibios_update_resource(struct pci_dev *dev, struct resource *root, struct resource *res, int resource) { - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; int where; u32 reg; @@ -328,7 +328,7 @@ pcibios_update_irq(struct pci_dev *dev, int irq) u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp) { - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; if (dev->bus->number != hose->first_busno) { u8 pin = *pinp; @@ -349,7 +349,7 @@ void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges) { - struct pci_controler *hose = (struct pci_controler *)bus->sysdata; + struct pci_controller *hose = (struct pci_controller *)bus->sysdata; ranges->io_start -= hose->io_space->start; ranges->io_end -= hose->io_space->start; @@ -383,11 +383,11 @@ pcibios_set_master(struct pci_dev *dev) void __init common_init_pci(void) { - struct pci_controler *hose; + struct pci_controller *hose; struct pci_bus *bus; int next_busno; - /* Scan all of the recorded PCI controlers. */ + /* Scan all of the recorded PCI controllers. */ for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { hose->first_busno = next_busno; hose->last_busno = 0xff; @@ -402,10 +402,10 @@ common_init_pci(void) } -struct pci_controler * __init -alloc_pci_controler(void) +struct pci_controller * __init +alloc_pci_controller(void) { - struct pci_controler *hose; + struct pci_controller *hose; hose = alloc_bootmem(sizeof(*hose)); @@ -432,7 +432,7 @@ alloc_resource(void) asmlinkage long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn) { - struct pci_controler *hose; + struct pci_controller *hose; struct pci_dev *dev; /* from hose or from bus.devfn */ diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h index f434b329d..19fe6eea4 100644 --- a/arch/alpha/kernel/pci_impl.h +++ b/arch/alpha/kernel/pci_impl.h @@ -6,7 +6,7 @@ */ struct pci_dev; -struct pci_controler; +struct pci_controller; struct pci_iommu_arena; /* @@ -68,6 +68,7 @@ struct pci_iommu_arena; /* ??? Experimenting with no HAE for CIA. */ #define CIA_DEFAULT_MEM_BASE ((32+2)*1024*1024) +#define IRONGATE_DEFAULT_MEM_BASE ((256*8-16)*1024*1024) /* * A small note about bridges and interrupts. The DECchip 21050 (and @@ -133,7 +134,7 @@ static inline u8 bridge_swizzle(u8 pin, u8 slot) struct pci_iommu_arena { spinlock_t lock; - struct pci_controler *hose; + struct pci_controller *hose; unsigned long *ptes; dma_addr_t dma_base; unsigned int size; @@ -143,15 +144,15 @@ struct pci_iommu_arena /* The hose list. */ -extern struct pci_controler *hose_head, **hose_tail; -extern struct pci_controler *pci_isa_hose; +extern struct pci_controller *hose_head, **hose_tail; +extern struct pci_controller *pci_isa_hose; extern void common_init_pci(void); extern u8 common_swizzle(struct pci_dev *, u8 *); -extern struct pci_controler *alloc_pci_controler(void); +extern struct pci_controller *alloc_pci_controller(void); extern struct resource *alloc_resource(void); -extern struct pci_iommu_arena *iommu_arena_new(struct pci_controler *, +extern struct pci_iommu_arena *iommu_arena_new(struct pci_controller *, dma_addr_t, unsigned long, unsigned long); extern long iommu_arena_alloc(struct pci_iommu_arena *arena, long n); diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index d4eb6a5d9..13e2eab4e 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -43,7 +43,7 @@ calc_npages(long bytes) } struct pci_iommu_arena * -iommu_arena_new(struct pci_controler *hose, dma_addr_t base, +iommu_arena_new(struct pci_controller *hose, dma_addr_t base, unsigned long window_size, unsigned long align) { unsigned long mem_size; @@ -147,7 +147,7 @@ iommu_arena_free(struct pci_iommu_arena *arena, long ofs, long n) dma_addr_t pci_map_single(struct pci_dev *pdev, void *cpu_addr, long size, int direction) { - struct pci_controler *hose = pdev ? pdev->sysdata : pci_isa_hose; + struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose; dma_addr_t max_dma = pdev ? pdev->dma_mask : 0x00ffffff; struct pci_iommu_arena *arena; long npages, dma_ofs, i; @@ -215,7 +215,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, long size, int direction) { - struct pci_controler *hose = pdev ? pdev->sysdata : pci_isa_hose; + struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose; struct pci_iommu_arena *arena; long dma_ofs, npages; @@ -454,7 +454,7 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, int direction) { struct scatterlist *start, *end, *out; - struct pci_controler *hose; + struct pci_controller *hose; struct pci_iommu_arena *arena; dma_addr_t max_dma; @@ -528,7 +528,7 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, int direction) { - struct pci_controler *hose; + struct pci_controller *hose; struct pci_iommu_arena *arena; struct scatterlist *end; dma_addr_t max_dma; @@ -596,7 +596,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, int pci_dma_supported(struct pci_dev *pdev, dma_addr_t mask) { - struct pci_controler *hose; + struct pci_controller *hose; struct pci_iommu_arena *arena; #if !DEBUG_NODIRECT diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 5463c9fec..7be5f6dc8 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -10,14 +10,14 @@ struct pt_regs; struct task_struct; struct pci_dev; -struct pci_controler; +struct pci_controller; /* core_apecs.c */ extern struct pci_ops apecs_pci_ops; extern void apecs_init_arch(void); extern void apecs_pci_clr_err(void); extern void apecs_machine_check(u64, u64, struct pt_regs *); -extern void apecs_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t); +extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_cia.c */ extern struct pci_ops cia_pci_ops; @@ -25,7 +25,7 @@ extern void cia_init_pci(void); extern void cia_init_arch(void); extern void pyxis_init_arch(void); extern void cia_machine_check(u64, u64, struct pt_regs *); -extern void cia_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t); +extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_irongate.c */ extern struct pci_ops irongate_pci_ops; @@ -38,14 +38,14 @@ extern void irongate_machine_check(u64, u64, struct pt_regs *); extern struct pci_ops lca_pci_ops; extern void lca_init_arch(void); extern void lca_machine_check(u64, u64, struct pt_regs *); -extern void lca_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t); +extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_mcpcia.c */ extern struct pci_ops mcpcia_pci_ops; extern void mcpcia_init_arch(void); extern void mcpcia_init_hoses(void); extern void mcpcia_machine_check(u64, u64, struct pt_regs *); -extern void mcpcia_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t); +extern void mcpcia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_polaris.c */ extern struct pci_ops polaris_pci_ops; @@ -66,21 +66,21 @@ extern struct pci_ops titan_pci_ops; extern void titan_init_arch(void); extern void titan_kill_arch(int); extern void titan_machine_check(u64, u64, struct pt_regs *); -extern void titan_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t); +extern void titan_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_tsunami.c */ extern struct pci_ops tsunami_pci_ops; extern void tsunami_init_arch(void); extern void tsunami_kill_arch(int); extern void tsunami_machine_check(u64, u64, struct pt_regs *); -extern void tsunami_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t); +extern void tsunami_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_wildfire.c */ extern struct pci_ops wildfire_pci_ops; extern void wildfire_init_arch(void); extern void wildfire_kill_arch(int); extern void wildfire_machine_check(u64, u64, struct pt_regs *); -extern void wildfire_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t); +extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* setup.c */ extern unsigned long srm_hae; diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index a6443da53..cf5f62dee 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -201,7 +201,7 @@ reserve_std_resources(void) long i; if (hose_head) { - struct pci_controler *hose; + struct pci_controller *hose; for (hose = hose_head; hose; hose = hose->next) if (hose->index == 0) { io = hose->io_space; diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index 6197a6a14..c41daf689 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -404,13 +404,13 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin) }; const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5; - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; int irq = COMMON_TABLE_LOOKUP; if (irq > 0) { irq += 16 * hose->index; } else { - /* ??? The Contaq IDE controler on the ISA bridge uses + /* ??? The Contaq IDE controller on the ISA bridge uses "legacy" interrupts 14 and 15. I don't know if anything can wind up at the same slot+pin on hose1, so we'll just have to trust whatever value the console might @@ -455,7 +455,7 @@ monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) static u8 __init monet_swizzle(struct pci_dev *dev, u8 *pinp) { - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; int slot, pin = *pinp; if (hose->first_busno == dev->bus->number) { @@ -521,7 +521,7 @@ clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin) }; const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5; - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; int irq = COMMON_TABLE_LOOKUP; if (irq > 0) diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c index 4545ff0e2..06ad658d4 100644 --- a/arch/alpha/kernel/sys_eiger.c +++ b/arch/alpha/kernel/sys_eiger.c @@ -177,7 +177,7 @@ eiger_map_irq(struct pci_dev *dev, u8 slot, u8 pin) static u8 __init eiger_swizzle(struct pci_dev *dev, u8 *pinp) { - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; int slot, pin = *pinp; int bridge_count = 0; diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c index ae09ecbd1..ea7a104db 100644 --- a/arch/alpha/kernel/sys_jensen.c +++ b/arch/alpha/kernel/sys_jensen.c @@ -124,12 +124,12 @@ jensen_init_irq(void) static void __init jensen_init_arch(void) { - struct pci_controler *hose; + struct pci_controller *hose; /* Create a hose so that we can report i/o base addresses to userland. */ - pci_isa_hose = hose = alloc_pci_controler(); + pci_isa_hose = hose = alloc_pci_controller(); hose->io_space = &ioport_resource; hose->mem_space = &iomem_resource; hose->index = 0; diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index 2115b8d2c..2964ab56c 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -518,7 +518,7 @@ struct alpha_machine_vector nautilus_mv __initmv = { machine_check: nautilus_machine_check, max_dma_address: ALPHA_NAUTILUS_MAX_DMA_ADDRESS, min_io_address: DEFAULT_IO_BASE, - min_mem_address: DEFAULT_MEM_BASE, + min_mem_address: IRONGATE_DEFAULT_MEM_BASE, nr_irqs: 16, device_interrupt: isa_device_interrupt, diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c index b18c148d1..681c76ea6 100644 --- a/arch/alpha/kernel/sys_rawhide.c +++ b/arch/alpha/kernel/sys_rawhide.c @@ -139,7 +139,7 @@ rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) static void __init rawhide_init_irq(void) { - struct pci_controler *hose; + struct pci_controller *hose; long i; mcpcia_init_hoses(); @@ -204,7 +204,7 @@ rawhide_map_irq(struct pci_dev *dev, u8 slot, u8 pin) }; const long min_idsel = 1, max_idsel = 5, irqs_per_slot = 5; - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; int irq = COMMON_TABLE_LOOKUP; if (irq >= 0) irq += 24 * hose->index; diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 190b76bd9..9024644c1 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -321,10 +321,10 @@ privateer_map_irq(struct pci_dev *dev, u8 slot, u8 pin) } #ifdef CONFIG_VGA_HOSE -static struct pci_controler * __init -privateer_vga_hose_select(struct pci_controler *h1, struct pci_controler *h2) +static struct pci_controller * __init +privateer_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2) { - struct pci_controler *hose = h1; + struct pci_controller *hose = h1; int agp1, agp2; /* which hose(s) are agp? */ diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c index 8a7ad55c4..dbc4bee48 100644 --- a/arch/alpha/kernel/sys_wildfire.c +++ b/arch/alpha/kernel/sys_wildfire.c @@ -315,7 +315,7 @@ wildfire_map_irq(struct pci_dev *dev, u8 slot, u8 pin) }; const long min_idsel = 0, max_idsel = 7, irqs_per_slot = 5; - struct pci_controler *hose = dev->sysdata; + struct pci_controller *hose = dev->sysdata; int irq = COMMON_TABLE_LOOKUP; if (irq > 0) { diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index ddc677339..f27f0a9f2 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c @@ -113,7 +113,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, goto vmalloc_fault; #endif - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) goto bad_area; @@ -146,7 +146,7 @@ good_area: * the fault. */ fault = handle_mm_fault(mm, vma, address, cause > 0); - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); if (fault < 0) goto out_of_memory; @@ -160,7 +160,7 @@ good_area: * Fix it, but check if it's kernel or user first.. */ bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); if (user_mode(regs)) { force_sig(SIGSEGV, current); diff --git a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S index 65f70c727..dacad00b5 100644 --- a/arch/arm/kernel/entry-armo.S +++ b/arch/arm/kernel/entry-armo.S @@ -29,13 +29,12 @@ #include <linux/config.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/errno.h> #include <asm/hardware.h> -#include "../lib/constants.h" - .macro zero_fp -#ifdef CONFIG_FRAME_POINTER +#ifndef CONFIG_NO_FRAME_POINTER mov fp, #0 #endif .endm diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index e659b966d..145420266 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -17,19 +17,19 @@ #include <linux/linkage.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/errno.h> #include <asm/hardware.h> #include <asm/arch/irqs.h> #include <asm/proc-fns.h> -#include "../lib/constants.h" #ifndef MODE_SVC #define MODE_SVC 0x13 #endif .macro zero_fp -#ifdef CONFIG_FRAME_POINTER +#ifndef CONFIG_NO_FRAME_POINTER mov fp, #0 #endif .endm @@ -611,9 +611,9 @@ __und_invalid: sub sp, sp, #S_FRAME_SIZE #else wfs_mask_data: .word 0x0e200110 @ WFS/RFS .word 0x0fef0fff - .word 0x0d0d0100 @ LDF [sp]/STF [sp] - .word 0x0d0b0100 @ LDF [fp]/STF [fp] - .word 0x0f0f0f00 + .word 0x0d000100 @ LDF [sp]/STF [sp] + .word 0x0d000100 @ LDF [fp]/STF [fp] + .word 0x0f000f00 /* We get here if an undefined instruction happens and the floating * point emulator is not present. If the offending instruction was diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 8fe41f38c..1f295c8b3 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -215,7 +215,7 @@ sys_sigaltstack_wrapper: sys_mmap2: #if PAGE_SHIFT > 12 tst r5, #PGOFF_MASK - moveq r5, r5, lsr #PGOFF_SHIFT + moveq r5, r5, lsr #PAGE_SHIFT - 12 streq r5, [sp, #4] beq do_mmap2 mov r0, #-EINVAL diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 16b8e59ea..7cbec1406 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -65,9 +65,9 @@ inline long do_mmap2( goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index ee111801f..58106bff6 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -54,9 +54,3 @@ ifneq ($(MACHINE),ebsa110) endif include $(TOPDIR)/Rules.make - -constants.h: getconsdata.o extractconstants.pl - $(PERL) extractconstants.pl $(OBJDUMP) > $@ - -getconsdata.o: getconsdata.c - $(CC) $(CFLAGS) -c getconsdata.c diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S index d7cf6fe45..b930b613d 100644 --- a/arch/arm/lib/copy_page.S +++ b/arch/arm/lib/copy_page.S @@ -11,7 +11,7 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> -#include "constants.h" +#include <asm/constants.h> .text .align 5 diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S index 3799ccaec..9b5af1409 100644 --- a/arch/arm/lib/csumpartialcopyuser.S +++ b/arch/arm/lib/csumpartialcopyuser.S @@ -11,7 +11,7 @@ #include <linux/linkage.h> #include <asm/assembler.h> #include <asm/errno.h> -#include "constants.h" +#include <asm/constants.h> .text diff --git a/arch/arm/lib/extractconstants.pl b/arch/arm/lib/extractconstants.pl deleted file mode 100644 index 8c96b3f28..000000000 --- a/arch/arm/lib/extractconstants.pl +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/perl - -$OBJDUMP=$ARGV[0]; - -sub swapdata { - local ($num) = @_; - - return substr($num, 6, 2).substr($num, 4, 2).substr ($num, 2, 2).substr ($num, 0, 2); -} - -open (DATA, $OBJDUMP.' --full-contents --section=.data getconsdata.o | grep \'^ 00\' |') || - die ('Cant objdump!'); -while (<DATA>) { - ($addr, $data0, $data1, $data2, $data3) = split (' '); - $dat[hex($addr)] = hex(&swapdata($data0)); - $dat[hex($addr)+4] = hex(&swapdata($data1)); - $dat[hex($addr)+8] = hex(&swapdata($data2)); - $dat[hex($addr)+12] = hex(&swapdata($data3)); -} -close (DATA); - -open (DATA, $OBJDUMP.' --syms getconsdata.o |') || die ('Cant objdump!'); -while (<DATA>) { - /elf32/ && ( $elf = 1 ); - /a.out/ && ( $aout = 1 ); - next if ($aout && ! / 07 /); - next if ($elf && ! (/^0*0...... g/ && /.data/)); - next if (!$aout && !$elf); - - if ($aout) { - ($addr, $flags, $sect, $a1, $a2, $a3, $name) = split (' '); - $nam[hex($addr)] = substr($name, 1); - } - if ($elf) { - chomp; - $addr = substr ($_, 0, index($_, " ")); - $name = substr ($_, rindex($_, " ") + 1); - $nam[hex($addr)] = $name; - } -} -close (DATA); - -print "/*\n * *** This file is automatically generated from getconsdata.c. Do not edit! ***\n */\n"; -for ($i = 0; $i < hex($addr)+4; $i += 4) { - print "#define $nam[$i] $dat[$i]\n"; -} diff --git a/arch/arm/lib/getconsdata.c b/arch/arm/lib/getconsdata.c deleted file mode 100644 index ee8040be7..000000000 --- a/arch/arm/lib/getconsdata.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * linux/arch/arm/lib/getconsdata.c - * - * Copyright (C) 1995-2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/config.h> -#include <linux/sched.h> -#include <linux/mm.h> - -#include <asm/pgtable.h> -#include <asm/uaccess.h> - -/* - * Make sure that the compiler and target are compatible - */ -#if (defined(__APCS_32__) && defined(CONFIG_CPU_26)) -#error Your compiler targets APCS-32 but this kernel requires APCS-26. -#endif -#if (defined(__APCS_26__) && defined(CONFIG_CPU_32)) -#error Your compiler targets APCS-26 but this kernel requires APCS-32. -#endif - -#undef PAGE_READONLY - -#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n) -#define OFF_MM(n) (unsigned long)&(((struct mm_struct *)0)->n) - -unsigned long TSK_SIGPENDING = OFF_TSK(sigpending); -unsigned long TSK_ADDR_LIMIT = OFF_TSK(addr_limit); -unsigned long TSK_NEED_RESCHED = OFF_TSK(need_resched); -unsigned long TSK_PTRACE = OFF_TSK(ptrace); -unsigned long TSK_USED_MATH = OFF_TSK(used_math); - -unsigned long TSS_SAVE = OFF_TSK(thread.save); -unsigned long TSS_FPESAVE = OFF_TSK(thread.fpstate.soft.save); -#ifdef CONFIG_CPU_32 -unsigned long TSS_DOMAIN = OFF_TSK(thread.domain); -#endif - -#ifdef _PAGE_PRESENT -unsigned long PAGE_PRESENT = _PAGE_PRESENT; -#endif -#ifdef _PAGE_RW -unsigned long PAGE_RW = _PAGE_RW; -#endif -#ifdef _PAGE_USER -unsigned long PAGE_USER = _PAGE_USER; -#endif -#ifdef _PAGE_ACCESSED -unsigned long PAGE_ACCESSED = _PAGE_ACCESSED; -#endif -#ifdef _PAGE_DIRTY -unsigned long PAGE_DIRTY = _PAGE_DIRTY; -#endif -#ifdef _PAGE_READONLY -unsigned long PAGE_READONLY = _PAGE_READONLY; -#endif -#ifdef _PAGE_NOT_USER -unsigned long PAGE_NOT_USER = _PAGE_NOT_USER; -#endif -#ifdef _PAGE_OLD -unsigned long PAGE_OLD = _PAGE_OLD; -#endif -#ifdef _PAGE_CLEAN -unsigned long PAGE_CLEAN = _PAGE_CLEAN; -#endif - -#ifdef PTE_TYPE_SMALL -unsigned long HPTE_TYPE_SMALL = PTE_TYPE_SMALL; -unsigned long HPTE_AP_READ = PTE_AP_READ; -unsigned long HPTE_AP_WRITE = PTE_AP_WRITE; -#endif - -#ifdef L_PTE_PRESENT -unsigned long LPTE_PRESENT = L_PTE_PRESENT; -unsigned long LPTE_YOUNG = L_PTE_YOUNG; -unsigned long LPTE_BUFFERABLE = L_PTE_BUFFERABLE; -unsigned long LPTE_CACHEABLE = L_PTE_CACHEABLE; -unsigned long LPTE_USER = L_PTE_USER; -unsigned long LPTE_WRITE = L_PTE_WRITE; -unsigned long LPTE_EXEC = L_PTE_EXEC; -unsigned long LPTE_DIRTY = L_PTE_DIRTY; -#endif - -unsigned long PAGE_SZ = PAGE_SIZE; - -unsigned long KSWI_BASE = 0x900000; -unsigned long KSWI_SYS_BASE = 0x9f0000; -unsigned long SYS_ERROR0 = 0x9f0000; -unsigned long PGOFF_SHIFT = PAGE_SHIFT - 12; -unsigned long PGOFF_MASK = (1 << (PAGE_SHIFT - 12)) - 1; diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S index e652b5276..87342f299 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib/memcpy.S @@ -11,7 +11,6 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> -#include "constants.h" .text diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile new file mode 100644 index 000000000..0b6166c87 --- /dev/null +++ b/arch/arm/mach-integrator/Makefile @@ -0,0 +1,24 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). + +USE_STANDARD_AS_RULE := true + +O_TARGET := integrator.o + +# Object file lists. + +obj-y := arch.o irq.o mm.o time.o +obj-m := +obj-n := +obj- := + +export-objs := leds.o + +obj-$(CONFIG_LEDS) += leds.o +obj-$(CONFIG_PCI) += pci_v3.o pci.o + +include $(TOPDIR)/Rules.make diff --git a/arch/arm/mach-integrator/arch.c b/arch/arm/mach-integrator/arch.c new file mode 100644 index 000000000..a31549c07 --- /dev/null +++ b/arch/arm/mach-integrator/arch.c @@ -0,0 +1,70 @@ +/* + * linux/arch/arm/mach-integrator/arch.c + * + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/config.h> +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> +#include <asm/mach/amba_kmi.h> + +extern void integrator_map_io(void); +extern void integrator_init_irq(void); + +#ifdef CONFIG_KMI_KEYB +static struct kmi_info integrator_keyboard __initdata = { + base: IO_ADDRESS(KMI0_BASE), + irq: IRQ_KMIINT0, + divisor: 24 / 8 - 1, + type: KMI_KEYBOARD, +}; + +static struct kmi_info integrator_mouse __initdata = { + base: IO_ADDRESS(KMI1_BASE), + irq: IRQ_KMIINT1, + divisor: 24 / 8 - 1, + type: KMI_MOUSE, +}; +#endif + +static void __init +integrator_fixup(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ +#ifdef CONFIG_KMI_KEYB + register_kmi(&integrator_keyboard); + register_kmi(&integrator_mouse); +#endif +} + +MACHINE_START(INTEGRATOR, "ARM-Integrator") + MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") + BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) + BOOT_PARAMS(0x00000100) + FIXUP(integrator_fixup) + MAPIO(integrator_map_io) + INITIRQ(integrator_init_irq) +MACHINE_END diff --git a/arch/arm/mach-integrator/dma.c b/arch/arm/mach-integrator/dma.c new file mode 100644 index 000000000..aa5ba5a43 --- /dev/null +++ b/arch/arm/mach-integrator/dma.c @@ -0,0 +1,36 @@ +/* + * linux/arch/arm/mach-integrator/dma.c + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/sched.h> +#include <linux/malloc.h> +#include <linux/mman.h> +#include <linux/init.h> + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/hardware.h> + +#include <asm/mach/dma.h> + +void __init arch_dma_init(dma_t *dma) +{ +} diff --git a/arch/arm/mach-integrator/irq.c b/arch/arm/mach-integrator/irq.c new file mode 100644 index 000000000..546ade980 --- /dev/null +++ b/arch/arm/mach-integrator/irq.c @@ -0,0 +1,71 @@ +/* + * linux/arch/arm/mach-integrator/irq.c + * + * Copyright (C) 1999 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/mach/irq.h> + +/* + * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx + * is the (PA >> 12). + * + * Setup a VA for the Integrator interrupt controller (for header #0, + * just for now). + */ +#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) +#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET + +#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) ) + +static void sc_mask_irq(unsigned int irq) +{ + __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR); +} + +static void sc_unmask_irq(unsigned int irq) +{ + __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET); +} + +void __init integrator_init_irq(void) +{ + unsigned int i; + + for (i = 0; i < NR_IRQS; i++) { + if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) { + irq_desc[i].valid = 1; + irq_desc[i].probe_ok = 1; + irq_desc[i].mask_ack = sc_mask_irq; + irq_desc[i].mask = sc_mask_irq; + irq_desc[i].unmask = sc_unmask_irq; + } + } + + /* Disable all interrupts initially. */ + /* Do the core module ones */ + __raw_writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); + + /* do the header card stuff next */ + __raw_writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); + __raw_writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); +} diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c new file mode 100644 index 000000000..8fe7df14a --- /dev/null +++ b/arch/arm/mach-integrator/leds.c @@ -0,0 +1,94 @@ +/* + * linux/arch/arm/mach-integrator/leds.c + * + * Integrator LED control routines + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/leds.h> +#include <asm/system.h> +#include <asm/mach-types.h> + +static int saved_leds; + +static void integrator_leds_event(led_event_t ledevt) +{ + unsigned long flags; + const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE); + const unsigned int hdr_ctrl = IO_ADDRESS(INTEGRATOR_HDR_BASE) + + INTEGRATOR_HDR_CTRL_OFFSET; + unsigned int ctrl; + unsigned int update_alpha_leds; + + // yup, change the LEDs + local_irq_save(flags); + update_alpha_leds = 0; + + switch(ledevt) { + case led_idle_start: + ctrl = __raw_readl(hdr_ctrl); + ctrl &= ~INTEGRATOR_HDR_CTRL_LED; + __raw_writel(ctrl, hdr_ctrl); + break; + + case led_idle_end: + ctrl = __raw_readl(hdr_ctrl); + ctrl |= INTEGRATOR_HDR_CTRL_LED; + __raw_writel(ctrl, hdr_ctrl); + break; + + case led_timer: + saved_leds ^= GREEN_LED; + update_alpha_leds = 1; + break; + + case led_red_on: + saved_leds |= RED_LED; + update_alpha_leds = 1; + break; + + case led_red_off: + saved_leds &= ~RED_LED; + update_alpha_leds = 1; + break; + + default: + break; + } + + if (update_alpha_leds) { + while (__raw_readl(dbg_base + INTEGRATOR_DBG_ALPHA_OFFSET) & 1); + __raw_writel(saved_leds, dbg_base + INTEGRATOR_DBG_LEDS_OFFSET); + } + local_irq_restore(flags); +} + +static int __init leds_init(void) +{ + if (machine_is_integrator()) + leds_event = integrator_leds_event; + + return 0; +} + +__initcall(leds_init); diff --git a/arch/arm/mach-integrator/mm.c b/arch/arm/mach-integrator/mm.c new file mode 100644 index 000000000..234228c45 --- /dev/null +++ b/arch/arm/mach-integrator/mm.c @@ -0,0 +1,78 @@ +/* + * linux/arch/arm/mach-integrator/mm.c + * + * Extra MM routines for the ARM Integrator board + * + * Copyright (C) 1999,2000 Arm Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> + +#include <asm/mach/map.h> + +/* + * Logical Physical + * e8000000 40000000 PCI memory + * ec000000 62000000 PCI config space + * ed000000 61000000 PCI V3 regs + * ee000000 60000000 PCI IO + * ef000000 Cache flush + * f1000000 10000000 Core module registers + * f1100000 11000000 System controller registers + * f1200000 12000000 EBI registers + * f1300000 13000000 Counter/Timer + * f1400000 14000000 Interrupt controller + * f1500000 15000000 RTC + * f1600000 16000000 UART 0 + * f1700000 17000000 UART 1 + * f1800000 18000000 Keyboard + * f1900000 19000000 Mouse + * f1a00000 1a000000 Debug LEDs + * f1b00000 1b000000 GPIO + */ + +static struct map_desc integrator_io_desc[] __initdata = { + { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_RTC_BASE), INTEGRATOR_RTC_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_KBD_BASE), INTEGRATOR_KBD_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_MOUSE_BASE), INTEGRATOR_MOUSE_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K , DOMAIN_IO, 0, 1}, + { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M , DOMAIN_IO, 0, 1}, + { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M , DOMAIN_IO, 0, 1}, + { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_512K , DOMAIN_IO, 0, 1}, + { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K , DOMAIN_IO, 0, 1}, + LAST_DESC +}; + +void __init integrator_map_io(void) +{ + iotable_init(integrator_io_desc); +} diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c new file mode 100644 index 000000000..9339ceb1b --- /dev/null +++ b/arch/arm/mach-integrator/pci.c @@ -0,0 +1,119 @@ +/* + * linux/arch/arm/mach-integrator/pci-integrator.c + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * PCI functions for Integrator + */ +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/ptrace.h> +#include <linux/interrupt.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/mach/pci.h> + +/* + * A small note about bridges and interrupts. The DECchip 21050 (and + * later) adheres to the PCI-PCI bridge specification. This says that + * the interrupts on the other side of a bridge are swizzled in the + * following manner: + * + * Dev Interrupt Interrupt + * Pin on Pin on + * Device Connector + * + * 4 A A + * B B + * C C + * D D + * + * 5 A B + * B C + * C D + * D A + * + * 6 A C + * B D + * C A + * D B + * + * 7 A D + * B A + * C B + * D C + * + * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A. + * Thus, each swizzle is ((pin-1) + (device#-4)) % 4 + * + * The following code swizzles for exactly one bridge. + */ +static inline int bridge_swizzle(int pin, unsigned int slot) +{ + return (pin + slot) & 3; +} + +/* + * This routine handles multiple bridges. + */ +static u8 __init integrator_swizzle(struct pci_dev *dev, u8 *pinp) +{ + int pin = *pinp; + + if (pin == 0) + pin = 1; + + pin -= 1; + while (dev->bus->self) { + pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); + /* + * move up the chain of bridges, swizzling as we go. + */ + dev = dev->bus->self; + } + *pinp = pin + 1; + + return PCI_SLOT(dev->devfn); +} + +static int irq_tab[4] __initdata = { + IRQ_PCIINT0, IRQ_PCIINT1, IRQ_PCIINT2, IRQ_PCIINT3 +}; + +/* + * map the specified device/slot/pin to an IRQ. This works out such + * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1. + */ +static int __init integrator_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int intnr = ((slot - 9) + (pin - 1)) & 3; + + return irq_tab[intnr]; +} + +extern void pci_v3_init(struct arm_pci_sysdata *); + +struct hw_pci integrator_pci __initdata = { + init: pci_v3_init, + swizzle: integrator_swizzle, + map_irq: integrator_map_irq, +}; diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c new file mode 100644 index 000000000..1046e2826 --- /dev/null +++ b/arch/arm/mach-integrator/pci_v3.c @@ -0,0 +1,460 @@ +/* + * linux/arch/arm/mach-integrator/pci_v3.c + * + * PCI functions for V3 host PCI bridge + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/ptrace.h> +#include <linux/malloc.h> +#include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/mach/pci.h> + +#include <asm/hardware/pci_v3.h> + +/* + * The V3 PCI interface chip in Integrator provides several windows from + * local bus memory into the PCI memory areas. Unfortunately, there + * are not really enough windows for our usage, therefore we reuse + * one of the windows for access to PCI configuration space. The + * memory map is as follows: + * + * Local Bus Memory Usage + * + * 40000000 - 4FFFFFFF PCI memory. 256M non-prefetchable + * 50000000 - 5FFFFFFF PCI memory. 256M prefetchable + * 60000000 - 60FFFFFF PCI IO. 16M + * 68000000 - 68FFFFFF PCI Configuration. 16M + * + * There are three V3 windows, each described by a pair of V3 registers. + * These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2. + * Base0 and Base1 can be used for any type of PCI memory access. Base2 + * can be used either for PCI I/O or for I20 accesses. By default, uHAL + * uses this only for PCI IO space. + * + * PCI Memory is mapped so that assigned addresses in PCI Memory match + * local bus memory addresses. In other words, if a PCI device is assigned + * address 80200000 then that address is a valid local bus address as well + * as a valid PCI Memory address. PCI IO addresses are mapped to start + * at zero. This means that local bus address 60000000 maps to PCI IO address + * 00000000 and so on. Device driver writers need to be aware of this + * distinction. + * + * Normally these spaces are mapped using the following base registers: + * + * Usage Local Bus Memory Base/Map registers used + * + * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0 + * Mem 50000000 - 5FFFFFFF LB_BASE1/LB_MAP1 + * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2 + * Cfg 68000000 - 68FFFFFF + * + * This means that I20 and PCI configuration space accesses will fail. + * When PCI configuration accesses are needed (via the uHAL PCI + * configuration space primitives) we must remap the spaces as follows: + * + * Usage Local Bus Memory Base/Map registers used + * + * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0 + * Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0 + * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2 + * Cfg 68000000 - 68FFFFFF LB_BASE1/LB_MAP1 + * + * To make this work, the code depends on overlapping windows working. + * The V3 chip translates an address by checking its range within + * each of the BASE/MAP pairs in turn (in ascending register number + * order). It will use the first matching pair. So, for example, + * if the same address is mapped by both LB_BASE0/LB_MAP0 and + * LB_BASE1/LB_MAP1, the V3 will use the translation from + * LB_BASE0/LB_MAP0. + * + * To allow PCI Configuration space access, the code enlarges the + * window mapped by LB_BASE0/LB_MAP0 from 256M to 512M. This occludes + * the windows currently mapped by LB_BASE1/LB_MAP1 so that it can + * be remapped for use by configuration cycles. + * + * At the end of the PCI Configuration space accesses, + * LB_BASE1/LB_MAP1 is reset to map PCI Memory. Finally the window + * mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to + * reveal the now restored LB_BASE1/LB_MAP1 window. + * + * NOTE: We do not set up I2O mapping. I suspect that this is only + * for an intelligent (target) device. Using I2O disables most of + * the mappings into PCI memory. + */ + +// V3 access routines +#define _V3Write16(o,v) __raw_writew(v, PCI_V3_VADDR + (unsigned int)(o)) +#define _V3Read16(o) (__raw_readw(PCI_V3_VADDR + (unsigned int)(o))) + +#define _V3Write32(o,v) __raw_writel(v, PCI_V3_VADDR + (unsigned int)(o)) +#define _V3Read32(o) (__raw_readl(PCI_V3_VADDR + (unsigned int)(o))) + +/*============================================================================ + * + * routine: uHALir_PCIMakeConfigAddress() + * + * parameters: bus = which bus + * device = which device + * function = which function + * offset = configuration space register we are interested in + * + * description: this routine will generate a platform dependant config + * address. + * + * calls: none + * + * returns: configuration address to play on the PCI bus + * + * To generate the appropriate PCI configuration cycles in the PCI + * configuration address space, you present the V3 with the following pattern + * (which is very nearly a type 1 (except that the lower two bits are 00 and + * not 01). In order for this mapping to work you need to set up one of + * the local to PCI aperatures to 16Mbytes in length translating to + * PCI configuration space starting at 0x0000.0000. + * + * PCI configuration cycles look like this: + * + * Type 0: + * + * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 + * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * 31:11 Device select bit. + * 10:8 Function number + * 7:2 Register number + * + * Type 1: + * + * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 + * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * 31:24 reserved + * 23:16 bus number (8 bits = 128 possible buses) + * 15:11 Device number (5 bits) + * 10:8 function number + * 7:2 register number + * + */ +static spinlock_t v3_lock = SPIN_LOCK_UNLOCKED; + +#define PCI_BUS_NONMEM_START 0x00000000 +#define PCI_BUS_NONMEM_SIZE 0x10000000 + +#define PCI_BUS_PREMEM_START 0x10000000 +#define PCI_BUS_PREMEM_SIZE 0x10000000 + +#if PCI_BUS_NONMEM_START & 0x000fffff +#error PCI_BUS_NONMEM_START must be megabyte aligned +#endif +#if PCI_BUS_PREMEM_START & 0x000fffff +#error PCI_BUS_PREMEM_START must be megabyte aligned +#endif + +static unsigned long v3_open_config_window(struct pci_dev *dev, int offset) +{ + unsigned int address, mapaddress, busnr; + + busnr = dev->bus->number; + + /* + * Trap out illegal values + */ + if (offset > 255) + BUG(); + if (busnr > 255) + BUG(); + if (dev->devfn > 255) + BUG(); + + if (busnr == 0) { + int slot = PCI_SLOT(dev->devfn); + + /* + * local bus segment so need a type 0 config cycle + * + * build the PCI configuration "address" with one-hot in + * A31-A11 + * + * mapaddress: + * 3:1 = config cycle (101) + * 0 = PCI A1 & A0 are 0 (0) + */ + address = PCI_FUNC(dev->devfn) << 8; + mapaddress = 0x0a; + + if (slot > 12) + /* + * high order bits are handled by the MAP register + */ + mapaddress |= 1 << (slot - 4); + else + /* + * low order bits handled directly in the address + */ + address |= 1 << (slot + 11); + } else { + /* + * not the local bus segment so need a type 1 config cycle + * + * address: + * 23:16 = bus number + * 15:11 = slot number (7:3 of devfn) + * 10:8 = func number (2:0 of devfn) + * + * mapaddress: + * 3:1 = config cycle (101) + * 0 = PCI A1 & A0 from host bus (1) + */ + mapaddress = 0x0b; + address = (busnr << 16) | (dev->devfn << 8); + } + + /* + * Set up base0 to see all 512Mbytes of memory space (not prefetchable), this + * frees up base1 for re-use by configuration memory + */ + _V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xFFF00000) | 0x90 | V3_LB_BASE_M_ENABLE); + + /* + * Set up base1/map1 to point into configuration space. + */ + _V3Write32(V3_LB_BASE1, (PHYS_PCI_CONFIG_BASE & 0xFFF00000) | 0x40 | V3_LB_BASE_M_ENABLE); + _V3Write16(V3_LB_MAP1, mapaddress); + + return PCI_CONFIG_VADDR + address + offset; +} + +static void v3_close_config_window(void) +{ + /* + * Reassign base1 for use by prefetchable PCI memory + */ + _V3Write32(V3_LB_BASE1, ((PHYS_PCI_MEM_BASE + SZ_256M) & 0xFFF00000) | 0x84 | V3_LB_BASE_M_ENABLE); + _V3Write16(V3_LB_MAP1, ((PCI_BUS_PREMEM_START & 0xFFF00000) >> 16) | 0x0006); + + /* + * And shrink base0 back to a 256M window (NOTE: MAP0 already correct) + */ + _V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xFFF00000) | 0x80 | V3_LB_BASE_M_ENABLE); +} + +static int v3_read_config_byte(struct pci_dev *dev, int where, u8 *val) +{ + unsigned long addr; + unsigned long flags; + u8 v; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + v = __raw_readb(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + *val = v; + return PCIBIOS_SUCCESSFUL; +} + +static int v3_read_config_word(struct pci_dev *dev, int where, u16 *val) +{ + unsigned long addr; + unsigned long flags; + u16 v; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + v = __raw_readw(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + *val = v; + return PCIBIOS_SUCCESSFUL; +} + +static int v3_read_config_dword(struct pci_dev *dev, int where, u32 *val) +{ + unsigned long addr; + unsigned long flags; + u32 v; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + v = __raw_readl(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + *val = v; + return PCIBIOS_SUCCESSFUL; +} + +static int v3_write_config_byte(struct pci_dev *dev, int where, u8 val) +{ + unsigned long addr; + unsigned long flags; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + __raw_writeb(val, addr); + __raw_readb(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static int v3_write_config_word(struct pci_dev *dev, int where, u16 val) +{ + unsigned long addr; + unsigned long flags; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + __raw_writew(val, addr); + __raw_readw(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static int v3_write_config_dword(struct pci_dev *dev, int where, u32 val) +{ + unsigned long addr; + unsigned long flags; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(dev, where); + + __raw_writel(val, addr); + __raw_readl(addr); + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops pci_v3_ops = { + read_byte: v3_read_config_byte, + read_word: v3_read_config_word, + read_dword: v3_read_config_dword, + write_byte: v3_write_config_byte, + write_word: v3_write_config_word, + write_dword: v3_write_config_dword, +}; + +static struct resource non_mem = { + name: "PCI non-prefetchable", + start: PCI_BUS_NONMEM_START, + end: PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1, + flags: IORESOURCE_MEM, +}; + +static struct resource pre_mem = { + name: "PCI prefetchable", + start: PCI_BUS_PREMEM_START, + end: PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1, + flags: IORESOURCE_MEM | IORESOURCE_PREFETCH, +}; + +/* + * V3_LB_BASE? - local bus address + * V3_LB_MAP? - pci bus address + */ +void __init pci_v3_init(struct arm_pci_sysdata *sysdata) +{ + struct pci_bus *bus; + unsigned int pci_cmd; + unsigned long flags; + + spin_lock_irqsave(&v3_lock, flags); + + /* + * Setup window 0 - PCI non-prefetchable memory + * Local: 0x40000000 Bus: 0x00000000 Size: 256MB + */ + _V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xfff00000) | 0x80 | V3_LB_BASE_M_ENABLE); + _V3Write16(V3_LB_MAP0, (PCI_BUS_NONMEM_START >> 16) | 0x0006); + + /* + * Setup window 1 - PCI prefetchable memory + * Local: 0x50000000 Bus: 0x10000000 Size: 256MB + */ + _V3Write32(V3_LB_BASE1, ((PHYS_PCI_MEM_BASE + SZ_256M) & 0xFFF00000) | 0x84 | V3_LB_BASE_M_ENABLE); + _V3Write16(V3_LB_MAP1, (PCI_BUS_PREMEM_START >> 16) | 0x0006); + + /* + * Setup window 2 - PCI IO + */ +// _V3Write32(V3_LB_BASE2, (PHYS_PCI_IO_BASE & 0xff000000) | V3_LB_BASE_M_ENABLE); +// _V3Write16(V3_LB_MAP2, 0); + + spin_unlock_irqrestore(&v3_lock, flags); + + bus = pci_scan_bus(0, &pci_v3_ops, sysdata); + + if (request_resource(&iomem_resource, &non_mem)) + printk("PCI: unable to allocate non-prefetchable memory region"); + if (request_resource(&iomem_resource, &pre_mem)) + printk("PCI: unable to allocate prefetchable memory region"); + + /* + * bus->resource[0] is the IO resource for this bus + * bus->resource[1] is the mem resource for this bus + * bus->resource[2] is the prefetch mem resource for this bus + */ + bus->resource[1] = &non_mem; + bus->resource[2] = &pre_mem; + + pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; + + pci_cmd |= sysdata->bus[0].features; + + _V3Write16(V3_PCI_CMD, pci_cmd); + + printk("PCI: Fast back to back transfers %sabled\n", + (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ? + "en" : "dis"); +} diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c new file mode 100644 index 000000000..11dbd96e5 --- /dev/null +++ b/arch/arm/mach-integrator/time.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/mach-integrator/time.c + * + * Copyright (C) 2000 Deep Blue Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/init.h> + +#include <asm/hardware.h> + +#define RTC_DR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 0)) +#define RTC_MR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 4)) +#define RTC_STAT (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8)) +#define RTC_EOI (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8)) +#define RTC_LR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 12)) +#define RTC_CR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 16)) + +#define RTC_CR_MIE 0x00000001 + +extern int (*set_rtc)(void); + +static int integrator_set_rtc(void) +{ + RTC_LR = xtime.tv_sec; + return 1; +} + +static int integrator_rtc_init(void) +{ + RTC_CR = 0; + RTC_EOI = 0; + + xtime.tv_sec = RTC_DR; + + set_rtc = integrator_set_rtc; + + return 0; +} + +__initcall(integrator_rtc_init); diff --git a/arch/arm/mach-sa1100/arch.c b/arch/arm/mach-sa1100/arch.c index 32ac72379..89123d122 100644 --- a/arch/arm/mach-sa1100/arch.c +++ b/arch/arm/mach-sa1100/arch.c @@ -54,7 +54,7 @@ fixup_sa1100(struct machine_desc *desc, struct param_struct *params, if (machine_is_assabet()) { /* * On Assabet, we must probe for the Neponset board *before* - * paging_init() has occured to actually determine the amount + * paging_init() has occurred to actually determine the amount * of RAM available. */ extern void map_sa1100_gpio_regs(void); diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c index f79b618a2..b836cfe89 100644 --- a/arch/arm/mm/fault-common.c +++ b/arch/arm/mm/fault-common.c @@ -223,9 +223,9 @@ int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs) if (in_interrupt() || !mm) goto no_context; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); fault = __do_page_fault(mm, addr, mode, tsk); - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); ret: /* diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c index 023fee8e0..5695b2ede 100644 --- a/arch/arm/mm/mm-rpc.c +++ b/arch/arm/mm/mm-rpc.c @@ -9,6 +9,7 @@ * * Extra MM routines for RiscPC architecture */ +#include <linux/types.h> #include <linux/init.h> #include <asm/hardware.h> diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c index 54fe435c6..01e3725c8 100644 --- a/arch/arm/mm/mm-sa1100.c +++ b/arch/arm/mm/mm-sa1100.c @@ -199,7 +199,7 @@ pg_data_t sa1100_node_data[4] = /* * On Assabet, we must probe for the Neponset board *before* paging_init() - * has occured to actually determine the amount of RAM available. To do so, + * has occurred to actually determine the amount of RAM available. To do so, * we map the appropriate IO section in the page table here in order to * access GPIO registers. */ diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S index 76377cf9c..a550ac9d8 100644 --- a/arch/arm/mm/proc-arm2,3.S +++ b/arch/arm/mm/proc-arm2,3.S @@ -14,8 +14,8 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/procinfo.h> -#include "../lib/constants.h" /* * MEMC workhorse code. It's both a horse which things it's a pig. diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S index d26a98f75..a9a682b5f 100644 --- a/arch/arm/mm/proc-arm6,7.S +++ b/arch/arm/mm/proc-arm6,7.S @@ -12,8 +12,8 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/procinfo.h> -#include "../lib/constants.h" /* * Function: arm6_7_cache_clean_invalidate_all (void) @@ -29,10 +29,10 @@ ENTRY(cpu_arm6_cache_clean_invalidate_all) ENTRY(cpu_arm7_cache_clean_invalidate_all) ENTRY(cpu_arm6_cache_clean_invalidate_range) ENTRY(cpu_arm7_cache_clean_invalidate_range) -ENTRY(cpu_arm6_invalidate_icache_range) -ENTRY(cpu_arm7_invalidate_icache_range) -ENTRY(cpu_arm6_invalidate_icache_page) -ENTRY(cpu_arm7_invalidate_icache_page) +ENTRY(cpu_arm6_icache_invalidate_range) +ENTRY(cpu_arm7_icache_invalidate_range) +ENTRY(cpu_arm6_icache_invalidate_page) +ENTRY(cpu_arm7_icache_invalidate_page) ENTRY(cpu_arm6_dcache_clean_range) ENTRY(cpu_arm7_dcache_clean_range) ENTRY(cpu_arm6_dcache_invalidate_range) @@ -410,8 +410,8 @@ ENTRY(arm6_processor_functions) .word cpu_arm6_dcache_clean_entry /* icache */ - .word cpu_arm6_invalidate_icache_range - .word cpu_arm6_invalidate_icache_page + .word cpu_arm6_icache_invalidate_range + .word cpu_arm6_icache_invalidate_page /* tlb */ .word cpu_arm6_tlb_invalidate_all @@ -449,8 +449,8 @@ ENTRY(arm7_processor_functions) .word cpu_arm7_dcache_clean_entry /* icache */ - .word cpu_arm7_invalidate_icache_range - .word cpu_arm7_invalidate_icache_page + .word cpu_arm7_icache_invalidate_range + .word cpu_arm7_icache_invalidate_page /* tlb */ .word cpu_arm7_tlb_invalidate_all diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S index 77b689bdf..4cc7509c4 100644 --- a/arch/arm/mm/proc-arm720.S +++ b/arch/arm/mm/proc-arm720.S @@ -32,9 +32,9 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/procinfo.h> #include <asm/hardware.h> -#include "../lib/constants.h" /* * Function: arm720_cache_clean_invalidate_all (void) diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index 6f1f11601..d3643c400 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -25,9 +25,9 @@ #include <linux/linkage.h> #include <linux/config.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/procinfo.h> #include <asm/hardware.h> -#include "../lib/constants.h" /* * This is the maximum size of an area which will be invalidated diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index 45b0a31fe..3d75d7489 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -19,9 +19,9 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> +#include <asm/constants.h> #include <asm/procinfo.h> #include <asm/hardware.h> -#include "../lib/constants.h" /* This is the maximum size of an area which will be flushed. If the area * is larger than this, then we flush the whole cache diff --git a/arch/arm/nwfpe/entry26.S b/arch/arm/nwfpe/entry26.S index 5108ce63d..d96deaae2 100644 --- a/arch/arm/nwfpe/entry26.S +++ b/arch/arm/nwfpe/entry26.S @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "../lib/constants.h" +#include <asm/constants.h> /* This is the kernel's entry point into the floating point emulator. It is called from the kernel with code similar to this: diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile new file mode 100644 index 000000000..698083c67 --- /dev/null +++ b/arch/arm/tools/Makefile @@ -0,0 +1,36 @@ +# +# linux/arch/arm/tools/Makefile +# +# Copyright (C) 2001 Russell King +# + +all: $(TOPDIR)/include/asm-arm/mach-types.h \ + $(TOPDIR)/include/asm-arm/constants.h + +$(TOPDIR)/include/asm-arm/mach-types.h: mach-types gen-mach-types + awk -f gen-mach-types mach-types > $@ + +# Generate the constants.h header file using the compiler. We get +# the compiler to spit out assembly code, and then mundge it into +# what we want. + +$(TOPDIR)/include/asm-arm/constants.h: constants-hdr getconstants.c + $(CC) $(CFLAGS) -S -o - getconstants.c | \ + sed 's/^\(#define .* \)#\(.*\)/\1\2/;/^#define/!d' | \ + cat constants-hdr - > $@.tmp + cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@; $(RM) $@.tmp + +# Build our dependencies, and then generate the constants and +# mach-types header files. If we do it now, mkdep will pick +# the dependencies up later on when it runs through the other +# directories + +dep: + $(TOPDIR)/scripts/mkdep getconstants.c | sed s,getconstants.o,$(TOPDIR)/include/asm-arm/constants.h, > .depend + $(MAKE) all + +.PHONY: all dep + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/arch/arm/tools/constants-hdr b/arch/arm/tools/constants-hdr new file mode 100644 index 000000000..fd18d7cb8 --- /dev/null +++ b/arch/arm/tools/constants-hdr @@ -0,0 +1,5 @@ +/* + * This file is automatically generated from arch/arm/tools/getconstants.c. + * Do not edit! Only include this file in assembly (.S) files! + */ + diff --git a/arch/arm/tools/getconstants.c b/arch/arm/tools/getconstants.c new file mode 100644 index 000000000..3fd2d3e7c --- /dev/null +++ b/arch/arm/tools/getconstants.c @@ -0,0 +1,72 @@ +/* + * linux/arch/arm/tools/getconsdata.c + * + * Copyright (C) 1995-2001 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/pgtable.h> +#include <asm/uaccess.h> + +/* + * Make sure that the compiler and target are compatible + */ +#if (defined(__APCS_32__) && defined(CONFIG_CPU_26)) +#error Your compiler targets APCS-32 but this kernel requires APCS-26. +#endif +#if (defined(__APCS_26__) && defined(CONFIG_CPU_32)) +#error Your compiler targets APCS-26 but this kernel requires APCS-32. +#endif + +#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n) + +#define DEFN(name,off) asm("\n#define "name" %0" :: "I" (off)) + +void func(void) +{ +DEFN("TSK_SIGPENDING", OFF_TSK(sigpending)); +DEFN("TSK_ADDR_LIMIT", OFF_TSK(addr_limit)); +DEFN("TSK_NEED_RESCHED", OFF_TSK(need_resched)); +DEFN("TSK_PTRACE", OFF_TSK(ptrace)); +DEFN("TSK_USED_MATH", OFF_TSK(used_math)); + +DEFN("TSS_SAVE", OFF_TSK(thread.save)); +DEFN("TSS_FPESAVE", OFF_TSK(thread.fpstate.soft.save)); + +#ifdef CONFIG_CPU_32 +DEFN("TSS_DOMAIN", OFF_TSK(thread.domain)); + +DEFN("HPTE_TYPE_SMALL", PTE_TYPE_SMALL); +DEFN("HPTE_AP_READ", PTE_AP_READ); +DEFN("HPTE_AP_WRITE", PTE_AP_WRITE); + +DEFN("LPTE_PRESENT", L_PTE_PRESENT); +DEFN("LPTE_YOUNG", L_PTE_YOUNG); +DEFN("LPTE_BUFFERABLE", L_PTE_BUFFERABLE); +DEFN("LPTE_CACHEABLE", L_PTE_CACHEABLE); +DEFN("LPTE_USER", L_PTE_USER); +DEFN("LPTE_WRITE", L_PTE_WRITE); +DEFN("LPTE_EXEC", L_PTE_EXEC); +DEFN("LPTE_DIRTY", L_PTE_DIRTY); +#endif + +#ifdef CONFIG_CPU_26 +DEFN("PAGE_PRESENT", _PAGE_PRESENT); +DEFN("PAGE_READONLY", _PAGE_READONLY); +DEFN("PAGE_NOT_USER", _PAGE_NOT_USER); +DEFN("PAGE_OLD", _PAGE_OLD); +DEFN("PAGE_CLEAN", _PAGE_CLEAN); +#endif + +DEFN("PAGE_SZ", PAGE_SIZE); + +DEFN("KSWI_BASE", 0x900000); +DEFN("KSWI_SYS_BASE", 0x9f0000); +DEFN("SYS_ERROR0", 0x9f0000); +} diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index ff7ccec77..c4f540a25 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -4,7 +4,7 @@ # To add an entry into this database, please see Documentation/arm/README, # or contact rmk@arm.linux.org.uk # -# Last update: Mon Nov 20 22:59:11 2000 +# Last update: Fri Feb 9 22:27:32 2001 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -48,13 +48,23 @@ accelent_l7200 ARCH_L7200_ACCELENT ACCELENT_L7200 37 netport SA1100_NETPORT NETPORT 38 pangolin SA1100_PANGOLIN PANGOLIN 39 yopy SA1100_YOPY YOPY 40 -sa1100 SA1100_SA1100 SA1100 41 -huw_webpanel ARCH_HUW_WEBPANEL HUW_WEBPANEL 42 +coolidge SA1100_COOLIDGE coolidge 41 +huw_webpanel SA1100_HUW_WEBPANEL HUW_WEBPANEL 42 spotme ARCH_SPOTME SPOTME 43 freebird ARCH_FREEBIRD FREEBIRD 44 ti925 ARCH_TI925 TI925 45 riscstation ARCH_RISCSTATION RISCSTATION 46 cavy SA1100_CAVY CAVY 47 +jornada720 SA1100_JORNADA720 JORNADA720 48 +omnimeter SA1100_OMNIMETER OMNIMETER 49 +edb7211 ARCH_EDB7211 EDB7211 50 +citygo SA1100_CITYGO CITYGO 51 +pfs168 SA1100_PFS168 PFS168 52 +spot SA1100_SPOT SPOT 53 +flexanet ARCH_FLEXANET FLEXANET 54 +webpal ARCH_WEBPAL WEBPAL 55 +linpda SA1100_LINPDA LINPDA 56 +anakin ARCH_ANAKIN ANAKIN 57 # The following are unallocated empeg SA1100_EMPEG EMPEG diff --git a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in index 10661f414..08544b314 100644 --- a/arch/arm/vmlinux-armv.lds.in +++ b/arch/arm/vmlinux-armv.lds.in @@ -45,18 +45,22 @@ SECTIONS *(.glue_7) *(.glue_7t) *(.kstrtab) - . = ALIGN(16); - __start___ex_table = .; /* Exception table */ + *(.got) /* Global offset table */ + + _etext = .; /* End of text section */ + } + + . = ALIGN(16); + __ex_table : { /* Exception table */ + __start___ex_table = .; *(__ex_table) __stop___ex_table = .; + } - __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { /* Kernel symbol table */ + __start___ksymtab = .; *(__ksymtab) __stop___ksymtab = .; - - *(.got) /* Global offset table */ - - _etext = .; /* End of text section */ } . = ALIGN(8192); diff --git a/arch/cris/drivers/serial.c b/arch/cris/drivers/serial.c index 2dcb17a5e..feda9a0e0 100644 --- a/arch/cris/drivers/serial.c +++ b/arch/cris/drivers/serial.c @@ -146,7 +146,7 @@ * * Revision 1.24 2000/02/09 18:02:28 bjornw * * Clear serial errors (overrun, framing, parity) correctly. Before, the - * receiver would get stuck if an error occured and we did not restart + * receiver would get stuck if an error occurred and we did not restart * the input DMA. * * Cosmetics (indentation, some code made into inlines) * * Some more debug options @@ -1371,7 +1371,7 @@ ser_interrupt(int irq, void *dev_id, struct pt_regs *regs) } else { /* it was a valid byte, now let the dma do the rest */ #ifdef SERIAL_DEBUG_INTR - printk("** OK, disabling ser_interupts\n"); + printk("** OK, disabling ser_interrupts\n"); #endif e100_disable_serial_data_irq(info); } diff --git a/arch/cris/kernel/entry.S b/arch/cris/kernel/entry.S index 1af62eb2c..65a70922e 100644 --- a/arch/cris/kernel/entry.S +++ b/arch/cris/kernel/entry.S @@ -23,7 +23,7 @@ * Revision 1.8 2000/11/17 16:53:35 bjornw * Added detection of frame-type in Rexit, so that mmu_bus_fault can * use ret_from_intr in the return-path to check for signals (like SEGV) - * and other foul things that might have occured during the fault. + * and other foul things that might have occurred during the fault. * * Revision 1.7 2000/10/06 15:04:28 bjornw * Include mof in register savings diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c index cfcb097f9..94ef1c698 100644 --- a/arch/cris/kernel/sys_cris.c +++ b/arch/cris/kernel/sys_cris.c @@ -62,9 +62,9 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, } flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); ret = do_mmap(file, addr, len, prot, flags, offset); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); out: @@ -87,9 +87,9 @@ do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c index a4bb237b4..b1493b2d2 100644 --- a/arch/cris/mm/fault.c +++ b/arch/cris/mm/fault.c @@ -146,7 +146,7 @@ handle_mmu_bus_fault(struct pt_regs *regs) * routines. * * Notice that the address we're given is aligned to the page the fault - * occured in, since we only get the PFN in R_MMU_CAUSE not the complete + * occurred in, since we only get the PFN in R_MMU_CAUSE not the complete * address. * * error_code: @@ -212,7 +212,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, if (in_interrupt() || !mm) goto no_context; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) goto bad_area; @@ -270,7 +270,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, goto out_of_memory; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return; /* @@ -280,7 +280,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); bad_area_nosemaphore: DPG(show_registers(regs)); @@ -334,14 +334,14 @@ do_page_fault(unsigned long address, struct pt_regs *regs, */ out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if(user_mode(regs)) do_exit(SIGKILL); goto no_context; do_sigbus: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* * Send a sigbus, regardless of whether we were in kernel @@ -381,7 +381,7 @@ vmalloc_fault: pmd = pmd_offset(pgd, address); pmd_k = pmd_offset(pgd_k, address); - if (pmd_present(*pmd) || !pmd_present(*pmd_k)) + if (!pmd_present(*pmd_k)) goto bad_area_nosemaphore; set_pmd(pmd, *pmd_k); return; diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile index e75eb2fdf..f238d05c5 100644 --- a/arch/i386/boot/Makefile +++ b/arch/i386/boot/Makefile @@ -43,7 +43,7 @@ tools/build: tools/build.c $(HOSTCC) $(HOSTCFLAGS) -o $@ $< -I$(TOPDIR)/include bootsect: bootsect.o - $(LD) -Ttext 0x0 -s -oformat binary -o $@ $< + $(LD) -Ttext 0x0 -s --oformat binary -o $@ $< bootsect.o: bootsect.s $(AS) -o $@ $< @@ -52,7 +52,7 @@ bootsect.s: bootsect.S Makefile $(BOOT_INCL) $(CPP) $(CPPFLAGS) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ bbootsect: bbootsect.o - $(LD) -Ttext 0x0 -s -oformat binary $< -o $@ + $(LD) -Ttext 0x0 -s --oformat binary $< -o $@ bbootsect.o: bbootsect.s $(AS) -o $@ $< @@ -61,7 +61,7 @@ bbootsect.s: bootsect.S Makefile $(BOOT_INCL) $(CPP) $(CPPFLAGS) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ setup: setup.o - $(LD) -Ttext 0x0 -s -oformat binary -e begtext -o $@ $< + $(LD) -Ttext 0x0 -s --oformat binary -e begtext -o $@ $< setup.o: setup.s $(AS) -o $@ $< @@ -70,7 +70,7 @@ setup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h $(CPP) $(CPPFLAGS) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ bsetup: bsetup.o - $(LD) -Ttext 0x0 -s -oformat binary -e begtext -o $@ $< + $(LD) -Ttext 0x0 -s --oformat binary -e begtext -o $@ $< bsetup.o: bsetup.s $(AS) -o $@ $< diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 875a84bf9..5b62d741c 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -280,6 +280,7 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set @@ -382,7 +383,6 @@ CONFIG_EEPRO100=y # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139TOO is not set -# CONFIG_RTL8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -434,6 +434,7 @@ CONFIG_PCMCIA_PCNET=y # CONFIG_PCMCIA_XIRTULIP is not set CONFIG_NET_PCMCIA_RADIO=y CONFIG_PCMCIA_RAYCS=y +# CONFIG_PCMCIA_HERMES is not set # CONFIG_PCMCIA_NETWAVE is not set # CONFIG_PCMCIA_WAVELAN is not set # CONFIG_AIRONET4500_CS is not set @@ -529,13 +530,11 @@ CONFIG_DRM_TDFX=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set # CONFIG_DRM_MGA is not set -CONFIG_PCMCIA_SERIAL=y # -# PCMCIA character device support +# PCMCIA character devices # # CONFIG_PCMCIA_SERIAL_CS is not set -# CONFIG_PCMCIA_SERIAL_CB is not set # # Multimedia devices diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 400216f37..01b4cf8a2 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -415,23 +415,6 @@ ENTRY(pg1) ENTRY(empty_zero_page) .org 0x5000 -ENTRY(empty_bad_page) - -.org 0x6000 -ENTRY(empty_bad_pte_table) - -#if CONFIG_X86_PAE - - .org 0x7000 - ENTRY(empty_bad_pmd_table) - - .org 0x8000 - -#else - - .org 0x7000 - -#endif /* * This starts the data section. Note that the above is all diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 20bc14fc6..52eb1c79a 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -27,6 +27,7 @@ #include <asm/mmx.h> #include <asm/desc.h> #include <asm/pgtable.h> +#include <asm/pgalloc.h> extern void dump_thread(struct pt_regs *, struct user *); extern spinlock_t rtc_lock; @@ -134,6 +135,9 @@ EXPORT_SYMBOL(__global_sti); EXPORT_SYMBOL(__global_save_flags); EXPORT_SYMBOL(__global_restore_flags); EXPORT_SYMBOL(smp_call_function); + +/* TLB flushing */ +EXPORT_SYMBOL(flush_tlb_page); #endif #ifdef CONFIG_MCA diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c index ba97ca4bc..0a2973cfa 100644 --- a/arch/i386/kernel/i387.c +++ b/arch/i386/kernel/i387.c @@ -179,7 +179,7 @@ unsigned short get_fpu_twd( struct task_struct *tsk ) unsigned short get_fpu_mxcsr( struct task_struct *tsk ) { - if ( cpu_has_fxsr ) { + if ( cpu_has_xmm ) { return tsk->thread.i387.fxsave.mxcsr; } else { return 0x1f80; diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c index e94cbfbdc..b50d366af 100644 --- a/arch/i386/kernel/ldt.c +++ b/arch/i386/kernel/ldt.c @@ -86,7 +86,7 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode) * the GDT index of the LDT is allocated dynamically, and is * limited by MAX_LDT_DESCRIPTORS. */ - down(&mm->mmap_sem); + down_write(&mm->mmap_sem); if (!mm->context.segments) { error = -ENOMEM; mm->context.segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); @@ -141,7 +141,7 @@ install: error = 0; out_unlock: - up(&mm->mmap_sem); + up_write(&mm->mmap_sem); out: return error; } diff --git a/arch/i386/kernel/pci-pc.c b/arch/i386/kernel/pci-pc.c index d2a8afbbb..18696dedc 100644 --- a/arch/i386/kernel/pci-pc.c +++ b/arch/i386/kernel/pci-pc.c @@ -861,6 +861,8 @@ static void __init pci_fixup_serverworks(struct pci_dev *d) } } +#if 0 +/* Our bus code shouldnt need this fixup any more. Delete once verified */ /* * Compaq host bridges -- Find and scan all secondary buses. * This time registers 0xc8 and 0xc9. @@ -878,6 +880,7 @@ static void __init pci_fixup_compaq(struct pci_dev *d) printk("PCI: Compaq host bridge: last bus %02x\n", busno2); } } +#endif static void __init pci_fixup_umc_ide(struct pci_dev *d) { @@ -934,35 +937,106 @@ static void __init pci_fixup_latency(struct pci_dev *d) pcibios_max_latency = 32; } +static void __init pci_fixup_via_acpi(struct pci_dev *d) +{ + /* + * VIA ACPI device: IRQ line in PCI config byte 0x42 + */ + u8 irq; + pci_read_config_byte(d, 0x42, &irq); + irq &= 0x0f; + if (irq && (irq != 2)) + d->irq = irq; +} + +static void __init pci_fixup_piix4_acpi(struct pci_dev *d) +{ + /* + * PIIX4 ACPI device: hardwired IRQ9 + */ + d->irq = 9; +} + static void __init pci_fixup_vt8363(struct pci_dev *d) { /* - * VIA VT8363 host bridge has broken feature 'PCI Master Read - * Caching'. It caches more than is good for it, sometimes - * serving the bus master with stale data. Some BIOSes enable - * it by default, so we disable it. + * The VIA bridge will corrupt disks without these settings. + */ + u8 tmp; + pci_read_config_byte(d, 0x54, &tmp); + if(tmp & (1<<2)) { + printk("PCI: Bus master Pipeline request disabled\n"); + pci_write_config_byte(d, 0x54, tmp & ~(1<<2)); + } + pci_read_config_byte(d, 0x70, &tmp); + if(tmp & (1<<3)) { + printk("PCI: Disabled enhanced CPU to PCI writes\n"); + pci_write_config_byte(d, 0x70, tmp & ~(1<<3)); + } + pci_read_config_byte(d, 0x71, &tmp); + if((tmp & (1<<3)) == 0) { + printk("PCI: Bursting cornercase bug worked around\n"); + pci_write_config_byte(d, 0x71, tmp | (1<<3)); + } + pci_read_config_byte(d, 0x76, &tmp); + if(tmp & (1<<7)) { + printk("PCI: Post Write Fail set to Retry\n"); + pci_write_config_byte(d, 0x76, tmp & ~(1<<7)); + } +} + +static void __init pci_fixup_via691(struct pci_dev *d) +{ + /* + * The VIA bridge corrupts with Posting enabled */ u8 tmp; + pci_read_config_byte(d, 0x70, &tmp); - if(tmp & 4) { - printk("PCI: Bus master read caching disabled\n"); - pci_write_config_byte(d, 0x70, tmp & ~4); + if(tmp & (1<<7)) { + printk("PCI: Disabled enhanced CPU to PCI posting\n"); + pci_write_config_byte(d, 0x70, tmp & ~(1<<7)); } } +static void __init pci_fixup_via691_2(struct pci_dev *d) +{ + /* + * The VIA bridge corrupts with Posting enabled + */ + u8 tmp; + + pci_read_config_byte(d, 0x40, &tmp); + if(tmp & (1<<7)) { + printk("PCI: Disabled enhanced CPU to PCI posting #2\n"); + pci_write_config_byte(d, 0x40, tmp & ~(1<<7)); + } +} + struct pci_fixup pcibios_fixups[] = { { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx }, +#if 0 +/* Until we get proper handling pray the BIOS gets it right */ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HE, pci_fixup_serverworks }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE, pci_fixup_serverworks }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CMIC_HE, pci_fixup_serverworks }, +#endif +#if 0 +/* Our bus code shouldnt need this fixup any more. Delete once verified */ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_6010, pci_fixup_compaq }, +#endif { PCI_FIXUP_HEADER, PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, pci_fixup_umc_ide }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, pci_fixup_ide_trash }, { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, pci_fixup_latency }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5598, pci_fixup_latency }, - { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_vt8363 }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, pci_fixup_via_acpi }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, pci_fixup_via_acpi }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_vt8363 }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C691, pci_fixup_via691 }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, pci_fixup_via691_2 }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci_fixup_piix4_acpi }, { 0 } }; diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index b374f8e99..2065727ae 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -167,8 +167,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if (request == PTRACE_ATTACH) { if (child == current) goto out_tsk; - if ((!child->dumpable || - (current->uid != child->euid) || + if(((current->uid != child->euid) || (current->uid != child->suid) || (current->uid != child->uid) || (current->gid != child->egid) || @@ -176,6 +175,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) (!cap_issubset(child->cap_permitted, current->cap_permitted)) || (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) goto out_tsk; + rmb(); + if (!child->dumpable && !capable(CAP_SYS_PTRACE)) + goto out_tsk; /* the same process cannot be attached many times */ if (child->ptrace & PT_PTRACED) goto out_tsk; diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 03eeabc2f..9c0033110 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -294,7 +294,7 @@ visws_get_board_type_and_rev(void) visws_board_rev = raw; } - printk("Silicon Graphics %s (rev %d)\n", + printk(KERN_INFO "Silicon Graphics %s (rev %d)\n", visws_board_type == VISWS_320 ? "320" : (visws_board_type == VISWS_540 ? "540" : "unknown"), @@ -401,7 +401,7 @@ void __init add_memory_region(unsigned long long start, int x = e820.nr_map; if (x == E820MAX) { - printk("Ooops! Too many entries in the memory map!\n"); + printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); return; } @@ -418,8 +418,9 @@ static void __init print_memory_map(char *who) int i; for (i = 0; i < e820.nr_map; i++) { - printk(" %s: %016Lx @ %016Lx ", who, - e820.map[i].size, e820.map[i].addr); + printk(" %s: %016Lx - %016Lx ", who, + e820.map[i].addr, + e820.map[i].addr + e820.map[i].size); switch (e820.map[i].type) { case E820_RAM: printk("(usable)\n"); break; @@ -521,7 +522,7 @@ void __init setup_memory_region(void) add_memory_region(0, LOWMEMSIZE(), E820_RAM); add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); } - printk("BIOS-provided physical RAM map:\n"); + printk(KERN_INFO "BIOS-provided physical RAM map:\n"); print_memory_map(who); } /* setup_memory_region */ @@ -591,7 +592,7 @@ static inline void parse_mem_cmdline (char ** cmdline_p) *to = '\0'; *cmdline_p = command_line; if (usermem) { - printk("user-defined physical RAM map:\n"); + printk(KERN_INFO "user-defined physical RAM map:\n"); print_memory_map("user"); } } @@ -798,7 +799,7 @@ void __init setup_arch(char **cmdline_p) initrd_end = initrd_start+INITRD_SIZE; } else { - printk("initrd extends beyond end of memory " + printk(KERN_ERR "initrd extends beyond end of memory " "(0x%08lx > 0x%08lx)\ndisabling initrd\n", INITRD_START + INITRD_SIZE, max_low_pfn << PAGE_SHIFT); @@ -902,7 +903,7 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c) if (n >= 0x80000005) { cpuid(0x80000005, &dummy, &dummy, &ecx, &edx); - printk("CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n", + printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n", edx>>24, edx&0xFF, ecx>>24, ecx&0xFF); c->x86_cache_size=(ecx>>24)+(edx>>24); } @@ -926,7 +927,7 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c) c->x86_cache_size = l2size; - printk("CPU: L2 Cache: %dK (%d bytes/line)\n", + printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n", l2size, ecx & 0xFF); } @@ -1339,7 +1340,7 @@ static void __init init_centaur(struct cpuinfo_x86 *c) name="C6"; fcr_set=ECX8|DSMC|EDCTLB|EMMX|ERETSTK; fcr_clr=DPDC; - printk("Disabling bugged TSC.\n"); + printk(KERN_NOTICE "Disabling bugged TSC.\n"); clear_bit(X86_FEATURE_TSC, &c->x86_capability); break; case 8: @@ -1376,10 +1377,10 @@ static void __init init_centaur(struct cpuinfo_x86 *c) newlo=(lo|fcr_set) & (~fcr_clr); if (newlo!=lo) { - printk("Centaur FCR was 0x%X now 0x%X\n", lo, newlo ); + printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n", lo, newlo ); wrmsr(0x107, newlo, hi ); } else { - printk("Centaur FCR is 0x%X\n",lo); + printk(KERN_INFO "Centaur FCR is 0x%X\n",lo); } /* Emulate MTRRs using Centaur's MCR. */ set_bit(X86_FEATURE_CENTAUR_MCR, &c->x86_capability); @@ -1432,7 +1433,7 @@ static void __init init_transmeta(struct cpuinfo_x86 *c) max = cpuid_eax(0x80860000); if ( max >= 0x80860001 ) { cpuid(0x80860001, &dummy, &cpu_rev, &cpu_freq, &cpu_flags); - printk("CPU: Processor revision %u.%u.%u.%u, %u MHz\n", + printk(KERN_INFO "CPU: Processor revision %u.%u.%u.%u, %u MHz\n", (cpu_rev >> 24) & 0xff, (cpu_rev >> 16) & 0xff, (cpu_rev >> 8) & 0xff, @@ -1441,7 +1442,7 @@ static void __init init_transmeta(struct cpuinfo_x86 *c) } if ( max >= 0x80860002 ) { cpuid(0x80860002, &dummy, &cms_rev1, &cms_rev2, &dummy); - printk("CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n", + printk(KERN_INFO "CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n", (cms_rev1 >> 24) & 0xff, (cms_rev1 >> 16) & 0xff, (cms_rev1 >> 8) & 0xff, @@ -1470,7 +1471,7 @@ static void __init init_transmeta(struct cpuinfo_x86 *c) (void *)&cpu_info[56], (void *)&cpu_info[60]); cpu_info[64] = '\0'; - printk("CPU: %s\n", cpu_info); + printk(KERN_INFO "CPU: %s\n", cpu_info); } /* Unhide possibly hidden capability flags */ @@ -1502,7 +1503,7 @@ static void __init init_intel(struct cpuinfo_x86 *c) c->f00f_bug = 1; if ( !f00f_workaround_enabled ) { trap_init_f00f_bug(); - printk(KERN_INFO "Intel Pentium with F0 0F bug - workaround enabled.\n"); + printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n"); f00f_workaround_enabled = 1; } } @@ -1610,12 +1611,12 @@ static void __init init_intel(struct cpuinfo_x86 *c) } } if ( l1i || l1d ) - printk("CPU: L1 I cache: %dK, L1 D cache: %dK\n", + printk(KERN_INFO "CPU: L1 I cache: %dK, L1 D cache: %dK\n", l1i, l1d); if ( l2 ) - printk("CPU: L2 cache: %dK\n", l2); + printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); if ( l3 ) - printk("CPU: L3 cache: %dK\n", l3); + printk(KERN_INFO "CPU: L3 cache: %dK\n", l3); /* * This assumes the L3 cache is shared; it typically lives in @@ -1785,7 +1786,7 @@ static void __init squash_the_stupid_serial_number(struct cpuinfo_x86 *c) rdmsr(0x119,lo,hi); lo |= 0x200000; wrmsr(0x119,lo,hi); - printk(KERN_INFO "CPU serial number disabled.\n"); + printk(KERN_NOTICE "CPU serial number disabled.\n"); clear_bit(X86_FEATURE_PN, &c->x86_capability); } } @@ -1976,7 +1977,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) } } - printk("CPU: Before vendor init, caps: %08x %08x %08x, vendor = %d\n", + printk(KERN_DEBUG "CPU: Before vendor init, caps: %08x %08x %08x, vendor = %d\n", c->x86_capability[0], c->x86_capability[1], c->x86_capability[2], @@ -2023,7 +2024,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) break; } - printk("CPU: After vendor init, caps: %08x %08x %08x %08x\n", + printk(KERN_DEBUG "CPU: After vendor init, caps: %08x %08x %08x %08x\n", c->x86_capability[0], c->x86_capability[1], c->x86_capability[2], @@ -2063,7 +2064,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) /* Now the feature flags better reflect actual CPU features! */ - printk("CPU: After generic, caps: %08x %08x %08x %08x\n", + printk(KERN_DEBUG "CPU: After generic, caps: %08x %08x %08x %08x\n", c->x86_capability[0], c->x86_capability[1], c->x86_capability[2], @@ -2081,7 +2082,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; } - printk("CPU: Common caps: %08x %08x %08x %08x\n", + printk(KERN_DEBUG "CPU: Common caps: %08x %08x %08x %08x\n", boot_cpu_data.x86_capability[0], boot_cpu_data.x86_capability[1], boot_cpu_data.x86_capability[2], @@ -2249,16 +2250,16 @@ void __init cpu_init (void) struct tss_struct * t = &init_tss[nr]; if (test_and_set_bit(nr, &cpu_initialized)) { - printk("CPU#%d already initialized!\n", nr); + printk(KERN_WARNING "CPU#%d already initialized!\n", nr); for (;;) __sti(); } - printk("Initializing CPU#%d\n", nr); + printk(KERN_INFO "Initializing CPU#%d\n", nr); if (cpu_has_vme || cpu_has_tsc || cpu_has_de) clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); #ifndef CONFIG_X86_TSC if (tsc_disable && cpu_has_tsc) { - printk("Disabling TSC...\n"); + printk(KERN_NOTICE "Disabling TSC...\n"); /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/ clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability); set_in_cr4(X86_CR4_TSD); diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c index 21a941be6..5fd6910b9 100644 --- a/arch/i386/kernel/sys_i386.c +++ b/arch/i386/kernel/sys_i386.c @@ -55,9 +55,9 @@ static inline long do_mmap2( goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 6fa43476a..b8cc4fad4 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -388,7 +388,7 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) #if CONFIG_X86_IO_APIC -int nmi_watchdog = 1; +int nmi_watchdog = 0; static int __init setup_nmi_watchdog(char *str) { diff --git a/arch/i386/lib/mmx.c b/arch/i386/lib/mmx.c index dfbf7ba8e..d9301040b 100644 --- a/arch/i386/lib/mmx.c +++ b/arch/i386/lib/mmx.c @@ -3,6 +3,7 @@ #include <linux/sched.h> #include <asm/i387.h> +#include <asm/hardirq.h> /* * MMX 3DNow! library helper functions @@ -25,8 +26,14 @@ void *_mmx_memcpy(void *to, const void *from, size_t len) { - void *p=to; - int i= len >> 6; /* len/64 */ + void *p; + int i; + + if (in_interrupt()) + return __memcpy(to, from, len); + + p = to; + i = len >> 6; /* len/64 */ kernel_fpu_begin(); diff --git a/arch/i386/mm/extable.c b/arch/i386/mm/extable.c index 2eb7ca6aa..223d05af4 100644 --- a/arch/i386/mm/extable.c +++ b/arch/i386/mm/extable.c @@ -49,7 +49,7 @@ search_exception_table(unsigned long addr) spin_lock_irqsave(&modlist_lock, flags); for (mp = module_list; mp != NULL; mp = mp->next) { - if (mp->ex_table_start == NULL) + if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING))) continue; ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, addr); diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index ccbc5dce1..18ae8b950 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -141,7 +141,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) if (in_interrupt() || !mm) goto no_context; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -214,7 +214,7 @@ good_area: if (bit < 32) tsk->thread.screen_bitmap |= 1 << bit; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return; /* @@ -222,7 +222,7 @@ good_area: * Fix it, but check if it's kernel or user first.. */ bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ @@ -290,14 +290,14 @@ no_context: * us unable to handle the page fault gracefully. */ out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if (error_code & 4) do_exit(SIGKILL); goto no_context; do_sigbus: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* * Send a sigbus, regardless of whether we were in kernel diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 6414b508c..202a42b69 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -40,132 +40,23 @@ unsigned long highstart_pfn, highend_pfn; static unsigned long totalram_pages; static unsigned long totalhigh_pages; -/* - * BAD_PAGE is the page that is used for page faults when linux - * is out-of-memory. Older versions of linux just did a - * do_exit(), but using this instead means there is less risk - * for a process dying in kernel mode, possibly leaving an inode - * unused etc.. - * - * BAD_PAGETABLE is the accompanying page-table: it is initialized - * to point to BAD_PAGE entries. - * - * ZERO_PAGE is a special page that is used for zero-initialized - * data and COW. - */ - -/* - * These are allocated in head.S so that we get proper page alignment. - * If you change the size of these then change head.S as well. - */ -extern char empty_bad_page[PAGE_SIZE]; -#if CONFIG_X86_PAE -extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD]; -#endif -extern pte_t empty_bad_pte_table[PTRS_PER_PTE]; - -/* - * We init them before every return and make them writable-shared. - * This guarantees we get out of the kernel in some more or less sane - * way. - */ -#if CONFIG_X86_PAE -static pmd_t * get_bad_pmd_table(void) -{ - pmd_t v; - int i; - - set_pmd(&v, __pmd(_PAGE_TABLE + __pa(empty_bad_pte_table))); - - for (i = 0; i < PAGE_SIZE/sizeof(pmd_t); i++) - empty_bad_pmd_table[i] = v; - - return empty_bad_pmd_table; -} -#endif - -static pte_t * get_bad_pte_table(void) -{ - pte_t v; - int i; - - v = pte_mkdirty(mk_pte_phys(__pa(empty_bad_page), PAGE_SHARED)); - - for (i = 0; i < PAGE_SIZE/sizeof(pte_t); i++) - empty_bad_pte_table[i] = v; - - return empty_bad_pte_table; -} - - - -void __handle_bad_pmd(pmd_t *pmd) -{ - pmd_ERROR(*pmd); - set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(get_bad_pte_table()))); -} - -void __handle_bad_pmd_kernel(pmd_t *pmd) -{ - pmd_ERROR(*pmd); - set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table()))); -} - -pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset) -{ - pte_t *pte; - - pte = (pte_t *) __get_free_page(GFP_KERNEL); - if (pmd_none(*pmd)) { - if (pte) { - clear_page(pte); - set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); - return pte + offset; - } - set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table()))); - return NULL; - } - free_page((unsigned long)pte); - if (pmd_bad(*pmd)) { - __handle_bad_pmd_kernel(pmd); - return NULL; - } - return (pte_t *) pmd_page(*pmd) + offset; -} - -pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) -{ - unsigned long pte; - - pte = (unsigned long) __get_free_page(GFP_KERNEL); - if (pmd_none(*pmd)) { - if (pte) { - clear_page((void *)pte); - set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); - return (pte_t *)pte + offset; - } - set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(get_bad_pte_table()))); - return NULL; - } - free_page(pte); - if (pmd_bad(*pmd)) { - __handle_bad_pmd(pmd); - return NULL; - } - return (pte_t *) pmd_page(*pmd) + offset; -} - int do_check_pgt_cache(int low, int high) { int freed = 0; if(pgtable_cache_size > high) { do { - if(pgd_quicklist) - free_pgd_slow(get_pgd_fast()), freed++; - if(pmd_quicklist) - free_pmd_slow(get_pmd_fast()), freed++; - if(pte_quicklist) - free_pte_slow(get_pte_fast()), freed++; + if (pgd_quicklist) { + free_pgd_slow(get_pgd_fast()); + freed++; + } + if (pmd_quicklist) { + pmd_free_slow(pmd_alloc_one_fast(NULL, 0)); + freed++; + } + if (pte_quicklist) { + pte_free_slow(pte_alloc_one_fast(NULL, 0)); + freed++; + } } while(pgtable_cache_size > low); } return freed; @@ -327,10 +218,8 @@ static void __init pagetable_init (void) pgd_base = swapper_pg_dir; #if CONFIG_X86_PAE - for (i = 0; i < PTRS_PER_PGD; i++) { - pgd = pgd_base + i; - __pgd_clear(pgd); - } + for (i = 0; i < PTRS_PER_PGD; i++) + set_pgd(pgd_base + i, __pgd(1 + __pa(empty_zero_page))); #endif i = __pgd_offset(PAGE_OFFSET); pgd = pgd_base + i; diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index bb72da8c8..55b8b3fcf 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c @@ -49,7 +49,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo if (address >= end) BUG(); do { - pte_t * pte = pte_alloc_kernel(pmd, address); + pte_t * pte = pte_alloc(&init_mm, pmd, address); if (!pte) return -ENOMEM; remap_area_pte(pte, address, end - address, address + phys_addr, flags); @@ -62,6 +62,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo static int remap_area_pages(unsigned long address, unsigned long phys_addr, unsigned long size, unsigned long flags) { + int error; pgd_t * dir; unsigned long end = address + size; @@ -70,19 +71,23 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr, flush_cache_all(); if (address >= end) BUG(); + spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc_kernel(dir, address); + pmd = pmd_alloc(&init_mm, dir, address); + error = -ENOMEM; if (!pmd) - return -ENOMEM; + break; if (remap_area_pmd(pmd, address, end - address, phys_addr + address, flags)) - return -ENOMEM; + break; + error = 0; address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); + spin_unlock(&init_mm.page_table_lock); flush_tlb_all(); - return 0; + return error; } /* diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c index aab0db860..8ae1e84e6 100644 --- a/arch/ia64/ia32/binfmt_elf32.c +++ b/arch/ia64/ia32/binfmt_elf32.c @@ -204,7 +204,6 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm) for (i = 0 ; i < MAX_ARG_PAGES ; i++) { if (bprm->page[i]) { - current->mm->rss++; put_dirty_page(current,bprm->page[i],stack_base); } stack_base += PAGE_SIZE; @@ -260,11 +259,11 @@ elf_map32 (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int p # define IA32_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1)) # define IA32_PAGEALIGN(_v) (((_v) + ELF_EXEC_PAGESIZE - 1) & ~(ELF_EXEC_PAGESIZE - 1)) - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); retval = ia32_do_mmap(filep, IA32_PAGESTART(addr), eppnt->p_filesz + IA32_PAGEOFFSET(eppnt->p_vaddr), prot, type, eppnt->p_offset - IA32_PAGEOFFSET(eppnt->p_vaddr)); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); #endif return retval; } diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 555c6097e..425e8f5ac 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -120,12 +120,12 @@ int stack) * `execve' frees all current memory we only have to do an * `munmap' if the `execve' failes. */ - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); av = (char **) do_mmap_pgoff(0, 0UL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (IS_ERR(av)) return (long)av; @@ -247,9 +247,9 @@ do_mmap_fake(struct file *file, unsigned long addr, unsigned long len, back = kmalloc(PAGE_SIZE - ((addr + len) & ~PAGE_MASK), GFP_KERNEL); __copy_user(back, (char *)addr + len, PAGE_SIZE - ((addr + len) & ~PAGE_MASK)); } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); r = do_mmap(0, baddr, len + (addr - baddr), prot, flags | MAP_ANONYMOUS, 0); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (r < 0) return(r); if (addr == 0) @@ -293,9 +293,9 @@ ia32_do_mmap (struct file *file, unsigned int addr, unsigned int len, unsigned i poff = offset & PAGE_MASK; len += offset - poff; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, poff >> PAGE_SHIFT); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (!IS_ERR((void *) error)) error += offset - poff; @@ -2573,7 +2573,7 @@ sys_iopl (int level, long arg1, long arg2, long arg3) return(-EFAULT); } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); lock_kernel(); addr = do_mmap_pgoff(file, IA32_IOBASE, @@ -2581,7 +2581,7 @@ sys_iopl (int level, long arg1, long arg2, long arg3) (ia64_iobase & ~PAGE_OFFSET) >> PAGE_SHIFT); unlock_kernel(); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (addr >= 0) { __asm__ __volatile__("mov ar.k0=%0 ;;" :: "r"(addr)); diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index 2713d7fd9..8cf1b3aa6 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -102,7 +102,7 @@ ia64_brk (unsigned long brk, long arg1, long arg2, long arg3, * check and the clearing of r8. However, we can't call sys_brk() because we need * to acquire the mmap_sem before we can do the test... */ - down(&mm->mmap_sem); + down_write(&mm->mmap_sem); if (brk < mm->end_code) goto out; @@ -142,7 +142,7 @@ set_brk: mm->brk = brk; out: retval = mm->brk; - up(&mm->mmap_sem); + up_write(&mm->mmap_sem); regs->r8 = 0; /* ensure large retval isn't mistaken as error code */ return retval; } @@ -200,9 +200,9 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un if (flags & MAP_SHARED) current->thread.flags |= IA64_THREAD_MAP_SHARED; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); current->thread.flags &= ~IA64_THREAD_MAP_SHARED; diff --git a/arch/ia64/lib/copy_user.S b/arch/ia64/lib/copy_user.S index ec9e2bf0a..135158d7a 100644 --- a/arch/ia64/lib/copy_user.S +++ b/arch/ia64/lib/copy_user.S @@ -16,7 +16,7 @@ * in2 number of bytes to copy * * Outputs: - * ret0 0 in case of sucess. The number of bytes NOT copied in + * ret0 0 in case of success. The number of bytes NOT copied in * case of error. * * Copyright (C) 2000 Hewlett-Packard Co diff --git a/arch/ia64/lib/strlen.S b/arch/ia64/lib/strlen.S index fbc786b41..3e7dd1e16 100644 --- a/arch/ia64/lib/strlen.S +++ b/arch/ia64/lib/strlen.S @@ -198,5 +198,5 @@ recover: ;; sub ret0=ret0,tmp // length=now - back -1 mov ar.pfs=saved_pfs // because of ar.ec, restore no matter what - br.ret.sptk.few rp // end of sucessful recovery code + br.ret.sptk.few rp // end of successful recovery code END(strlen) diff --git a/arch/ia64/lib/strlen_user.S b/arch/ia64/lib/strlen_user.S index 7f222bb13..4f3715d55 100644 --- a/arch/ia64/lib/strlen_user.S +++ b/arch/ia64/lib/strlen_user.S @@ -204,7 +204,7 @@ recover: ;; sub ret0=ret0,tmp // length=now - back -1 mov ar.pfs=saved_pfs // because of ar.ec, restore no matter what - br.ret.sptk.few rp // end of sucessful recovery code + br.ret.sptk.few rp // end of successful recovery code // // We failed even on the normal load (called from exception handler) diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 1a2438917..6f0b8f28b 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c @@ -60,7 +60,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re if (in_interrupt() || !mm) goto no_context; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma_prev(mm, address, &prev_vma); if (!vma) @@ -112,7 +112,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re default: goto out_of_memory; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return; check_expansion: @@ -135,7 +135,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re goto good_area; bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); if (isr & IA64_ISR_SP) { /* * This fault was due to a speculative load set the "ed" bit in the psr to @@ -185,7 +185,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re return; out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) do_exit(SIGKILL); diff --git a/arch/ia64/sn/io/l1.c b/arch/ia64/sn/io/l1.c index 6f4bf9f47..2bd1edc0a 100644 --- a/arch/ia64/sn/io/l1.c +++ b/arch/ia64/sn/io/l1.c @@ -2788,7 +2788,7 @@ _elscuart_getc( l1sc_t *sc ) while( (r = _elscuart_poll( sc )) == 0 ); if( r < 0 ) { - /* some error occured */ + /* some error occurred */ return r; } diff --git a/arch/ia64/sn/io/pcibr.c b/arch/ia64/sn/io/pcibr.c index 9c71b8569..6a3409b89 100644 --- a/arch/ia64/sn/io/pcibr.c +++ b/arch/ia64/sn/io/pcibr.c @@ -3925,7 +3925,7 @@ pcibr_attach(devfs_handle_t xconn_vhdl) * above. * * Need to set the D_INTR_ISERR flag - * in the dev_desc used for alocating the + * in the dev_desc used for allocating the * error interrupt, so our interrupt will * be properly routed and prioritized. * @@ -5540,7 +5540,7 @@ pcibr_dmamap_addr(pcibr_dmamap_t pcibr_dmamap, } else xio_port = pcibr_dmamap->bd_xio_port; - /* If this DMA is to an addres that + /* If this DMA is to an address that * refers back to this Bridge chip, * reduce it back to the correct * PCI MEM address. @@ -8540,7 +8540,7 @@ pcibr_pioerror( * * CAUTION: Resetting bit BRIDGE_IRR_PCI_GRP_CLR, acknowledges * a group of interrupts. If while handling this error, - * some other error has occured, that would be + * some other error has occurred, that would be * implicitly cleared by this write. * Need a way to ensure we don't inadvertently clear some * other errors. diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index d46ba0852..0f5c012c3 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c @@ -24,7 +24,7 @@ void dn_process_int(int irq, struct pt_regs *fp) { dn_irqs[irq-160].handler(irq,dn_irqs[irq-160].dev_id,fp); } else { - printk("spurious irq %d occured\n",irq); + printk("spurious irq %d occurred\n",irq); } *(volatile unsigned char *)(pica)=0x20; diff --git a/arch/m68k/ifpsp060/src/fpsp.S b/arch/m68k/ifpsp060/src/fpsp.S index 400d556c1..d3c78c8c0 100644 --- a/arch/m68k/ifpsp060/src/fpsp.S +++ b/arch/m68k/ifpsp060/src/fpsp.S @@ -23523,7 +23523,7 @@ no_exc: # in INEX2. # # # # A10. Or in INEX. # -# If INEX is set, round error occured. This is # +# If INEX is set, round error occurred. This is # # compensated for by 'or-ing' in the INEX2 flag to # # the lsb of Y. # # # @@ -23989,7 +23989,7 @@ A9_con: fmul.x %fp1,%fp0 # calculate X * SCALE -> Y to fp0 # A10. Or in INEX. -# If INEX is set, round error occured. This is compensated +# If INEX is set, round error occurred. This is compensated # for by 'or-ing' in the INEX2 flag to the lsb of Y. # # Register usage: diff --git a/arch/m68k/ifpsp060/src/ilsp.S b/arch/m68k/ifpsp060/src/ilsp.S index cd09bc7b9..43d220fc4 100644 --- a/arch/m68k/ifpsp060/src/ilsp.S +++ b/arch/m68k/ifpsp060/src/ilsp.S @@ -514,7 +514,7 @@ _060LSP__imulu64_: # fmovm.l &0x0,-(%sp) # save no fpregs # PROLOGUE END ########################################################## - mov.w %cc,MUL64_CC(%a6) # save incomming ccodes + mov.w %cc,MUL64_CC(%a6) # save incoming ccodes mov.l 0x8(%a6),%d0 # store multiplier in d0 beq.w mulu64_zero # handle zero separately @@ -625,7 +625,7 @@ _060LSP__imuls64_: # fmovm.l &0x0,-(%sp) # save no fpregs # PROLOGUE END ########################################################## - mov.w %cc,MUL64_CC(%a6) # save incomming ccodes + mov.w %cc,MUL64_CC(%a6) # save incoming ccodes mov.l 0x8(%a6),%d0 # store multiplier in d0 beq.b mulu64_zero # handle zero separately diff --git a/arch/m68k/ifpsp060/src/isp.S b/arch/m68k/ifpsp060/src/isp.S index f779e2c8f..2dc40bbc2 100644 --- a/arch/m68k/ifpsp060/src/isp.S +++ b/arch/m68k/ifpsp060/src/isp.S @@ -3835,7 +3835,7 @@ CAS2W2_FILLER: # assert LOCKE* for the final write operation. # # (13)Exit. # # # -# The algorithm is actually implemented slightly diferently # +# The algorithm is actually implemented slightly differently # # depending on the size of the operation and the misalignment of the # # operand. A misaligned operand must be written in aligned chunks or # # else the BUSCR register control gets confused. # diff --git a/arch/m68k/ifpsp060/src/pfpsp.S b/arch/m68k/ifpsp060/src/pfpsp.S index d175f7af0..21d2c507d 100644 --- a/arch/m68k/ifpsp060/src/pfpsp.S +++ b/arch/m68k/ifpsp060/src/pfpsp.S @@ -13483,7 +13483,7 @@ no_exc: # in INEX2. # # # # A10. Or in INEX. # -# If INEX is set, round error occured. This is # +# If INEX is set, round error occurred. This is # # compensated for by 'or-ing' in the INEX2 flag to # # the lsb of Y. # # # @@ -13949,7 +13949,7 @@ A9_con: fmul.x %fp1,%fp0 # calculate X * SCALE -> Y to fp0 # A10. Or in INEX. -# If INEX is set, round error occured. This is compensated +# If INEX is set, round error occurred. This is compensated # for by 'or-ing' in the INEX2 flag to the lsb of Y. # # Register usage: diff --git a/arch/m68k/kernel/bios32.c b/arch/m68k/kernel/bios32.c index d9cf9d9b8..a70bb6b89 100644 --- a/arch/m68k/kernel/bios32.c +++ b/arch/m68k/kernel/bios32.c @@ -444,7 +444,7 @@ static void __init pcibios_claim_resources(struct pci_bus *bus) * dev - device. * i - resource. * - * Result: 0 if successfull. + * Result: 0 if successful. */ int __init pcibios_assign_resource(struct pci_dev *dev, int i) diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index 461bf9c9b..9f385103a 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -840,7 +840,7 @@ L(getvmetype): #ifdef CONFIG_MVME16x is_not_mvme16x(L(gvtdone)) - /* Need to get the BRD_ID info to diferentiate between 162, 167, + /* Need to get the BRD_ID info to differentiate between 162, 167, * etc. This is available as a BI_VME_BRDINFO tag with later * versions of VMELILO and TFTPLILO, otherwise we call the Bug. */ diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 805ce9b83..240bb3c7c 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -184,7 +184,7 @@ void sys_free_irq(unsigned int irq, void *dev_id) /* * Do we need these probe functions on the m68k? * - * ... may be usefull with ISA devices + * ... may be useful with ISA devices */ unsigned long probe_irq_on (void) { diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index f7386cbc6..3d3f94062 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -59,9 +59,9 @@ static inline long do_mmap2( goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); @@ -146,9 +146,9 @@ asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg) } a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); out: diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index bc27a1722..bbea6ea2d 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c @@ -101,7 +101,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, if (in_interrupt() || !mm) goto no_context; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -168,7 +168,7 @@ good_area: #warning should be obsolete now... if (CPU_IS_040_OR_060) flush_tlb_page(vma, address); - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return 0; /* @@ -203,6 +203,6 @@ acc_err: current->thread.faddr = address; send_sig: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return send_fault_sig(regs); } diff --git a/arch/m68k/q40/README b/arch/m68k/q40/README index b61ee9c6a..8c93eb160 100644 --- a/arch/m68k/q40/README +++ b/arch/m68k/q40/README @@ -127,7 +127,7 @@ problems, email me idealy this: - exact keypress/release sequence - 'showkey -s' run on q40, non-X session - 'showkey -s' run on a PC, non-X session - - AT codes as displayed by the q40 debuging ROM + - AT codes as displayed by the q40 debugging ROM btw if the showkey output from PC and Q40 doesn't differ then you have some classic configuration problem - don't send me anything in this case diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 294765dd2..1063bf5e5 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -238,7 +238,7 @@ void __init config_q40(void) mach_max_dma_address = 32*1024*1024; /* no DMA at all, but ide-scsi requires it.. */ -/* userfull for early debuging stages writes kernel messages into SRAM */ +/* userfull for early debugging stages writes kernel messages into SRAM */ if (!strncmp( m68k_debug_device,"mem",3 )) { diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 7fb774003..fc2f0a391 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -206,6 +206,7 @@ CONFIG_SGIWD93_SCSI=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set diff --git a/arch/mips/defconfig-atlas b/arch/mips/defconfig-atlas index 70cfecd43..ba8632bd9 100644 --- a/arch/mips/defconfig-atlas +++ b/arch/mips/defconfig-atlas @@ -206,6 +206,7 @@ CONFIG_SD_EXTRA_DEVS=40 # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set diff --git a/arch/mips/defconfig-ddb5476 b/arch/mips/defconfig-ddb5476 index d8e786b14..4e821708a 100644 --- a/arch/mips/defconfig-ddb5476 +++ b/arch/mips/defconfig-ddb5476 @@ -305,7 +305,9 @@ CONFIG_NE2K_PCI=y # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139TOO is not set -# CONFIG_RTL8129 is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set diff --git a/arch/mips/defconfig-decstation b/arch/mips/defconfig-decstation index 7d19c59db..f6ac3193d 100644 --- a/arch/mips/defconfig-decstation +++ b/arch/mips/defconfig-decstation @@ -199,6 +199,7 @@ CONFIG_SCSI_DECNCR=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set diff --git a/arch/mips/defconfig-ev64120 b/arch/mips/defconfig-ev64120 index e2487dd19..aa209c1e1 100644 --- a/arch/mips/defconfig-ev64120 +++ b/arch/mips/defconfig-ev64120 @@ -238,7 +238,9 @@ CONFIG_NE2K_PCI=y # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139TOO is not set -# CONFIG_RTL8129 is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set diff --git a/arch/mips/defconfig-ev96100 b/arch/mips/defconfig-ev96100 index b112acd86..d3300ed4a 100644 --- a/arch/mips/defconfig-ev96100 +++ b/arch/mips/defconfig-ev96100 @@ -235,7 +235,9 @@ CONFIG_TULIP=y # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139TOO is not set -# CONFIG_RTL8129 is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set diff --git a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22 index 7fb774003..fc2f0a391 100644 --- a/arch/mips/defconfig-ip22 +++ b/arch/mips/defconfig-ip22 @@ -206,6 +206,7 @@ CONFIG_SGIWD93_SCSI=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set diff --git a/arch/mips/defconfig-it8172 b/arch/mips/defconfig-it8172 index 59330e6ce..3881cd44f 100644 --- a/arch/mips/defconfig-it8172 +++ b/arch/mips/defconfig-it8172 @@ -365,7 +365,9 @@ CONFIG_TULIP=y # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set CONFIG_8139TOO=y -# CONFIG_RTL8129 is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set diff --git a/arch/mips/defconfig-malta b/arch/mips/defconfig-malta index 01fe15970..1e02a2837 100644 --- a/arch/mips/defconfig-malta +++ b/arch/mips/defconfig-malta @@ -205,6 +205,7 @@ CONFIG_SD_EXTRA_DEVS=40 # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set @@ -294,7 +295,9 @@ CONFIG_PCNET32=y # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139TOO is not set -# CONFIG_RTL8129 is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set diff --git a/arch/mips/defconfig-ocelot b/arch/mips/defconfig-ocelot index c93bb6685..22f0adcf7 100644 --- a/arch/mips/defconfig-ocelot +++ b/arch/mips/defconfig-ocelot @@ -232,7 +232,9 @@ CONFIG_EEPRO100=y # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139TOO is not set -# CONFIG_RTL8129 is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index 8daf876c1..684e435fc 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -314,12 +314,12 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex, (unsigned long) elf_prot, (unsigned long) elf_type, (unsigned long) (eppnt->p_offset & 0xfffff000)); #endif - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap(interpreter, vaddr, eppnt->p_filesz + (eppnt->p_vaddr & 0xfff), elf_prot, elf_type, eppnt->p_offset & 0xfffff000); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if(error < 0 && error > -1024) { printk("Aieee IRIX interp mmap error=%d\n", error); @@ -498,12 +498,12 @@ static inline void map_executable(struct file *fp, struct elf_phdr *epp, int pnu prot = (epp->p_flags & PF_R) ? PROT_READ : 0; prot |= (epp->p_flags & PF_W) ? PROT_WRITE : 0; prot |= (epp->p_flags & PF_X) ? PROT_EXEC : 0; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); (void) do_mmap(fp, (epp->p_vaddr & 0xfffff000), (epp->p_filesz + (epp->p_vaddr & 0xfff)), prot, EXEC_MAP_FLAGS, (epp->p_offset & 0xfffff000)); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); /* Fixup location tracking vars. */ if((epp->p_vaddr & 0xfffff000) < *estack) @@ -762,10 +762,10 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs) * Since we do not have the power to recompile these, we * emulate the SVr4 behavior. Sigh. */ - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); (void) do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); #endif start_thread(regs, elf_entry, bprm->p); @@ -837,14 +837,14 @@ static int load_irix_library(struct file *file) while(elf_phdata->p_type != PT_LOAD) elf_phdata++; /* Now use mmap to map the library into memory. */ - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap(file, elf_phdata->p_vaddr & 0xfffff000, elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, elf_phdata->p_offset & 0xfffff000); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); k = elf_phdata->p_vaddr + elf_phdata->p_filesz; if (k > elf_bss) elf_bss = k; @@ -916,12 +916,12 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt) prot = (hp->p_flags & PF_R) ? PROT_READ : 0; prot |= (hp->p_flags & PF_W) ? PROT_WRITE : 0; prot |= (hp->p_flags & PF_X) ? PROT_EXEC : 0; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); retval = do_mmap(filp, (hp->p_vaddr & 0xfffff000), (hp->p_filesz + (hp->p_vaddr & 0xfff)), prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE), (hp->p_offset & 0xfffff000)); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if(retval != (hp->p_vaddr & 0xfffff000)) { printk("irix_mapelf: do_mmap fails with %d!\n", retval); diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 229ce8d12..0a8f79664 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -69,9 +69,9 @@ do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index ab051858e..18ec04e23 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -471,7 +471,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs) if (retval) return retval; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); pgdp = pgd_offset(mm, addr); pmdp = pmd_offset(pgdp, addr); ptep = pte_offset(pmdp, addr); @@ -484,7 +484,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs) PAGE_SHIFT, pageno); } } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); break; } @@ -534,7 +534,7 @@ asmlinkage int irix_brk(unsigned long brk) struct mm_struct *mm = current->mm; int ret; - down(&mm->mmap_sem); + down_write(&mm->mmap_sem); if (brk < mm->end_code) { ret = -ENOMEM; goto out; @@ -592,7 +592,7 @@ asmlinkage int irix_brk(unsigned long brk) ret = 0; out: - up(&mm->mmap_sem); + up_write(&mm->mmap_sem); return ret; } @@ -1082,9 +1082,9 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot, flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); retval = do_mmap(file, addr, len, prot, flags, offset); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); @@ -1642,9 +1642,9 @@ asmlinkage int irix_mmap64(struct pt_regs *regs) flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); diff --git a/arch/mips/mm/extable.c b/arch/mips/mm/extable.c index e563e8267..4c2cf3b43 100644 --- a/arch/mips/mm/extable.c +++ b/arch/mips/mm/extable.c @@ -49,7 +49,7 @@ search_exception_table(unsigned long addr) spin_lock_irqsave(&modlist_lock, flags); for (mp = module_list; mp != NULL; mp = mp->next) { - if (mp->ex_table_start == NULL) + if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING))) continue; ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, addr); diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index ed3d2a2ac..6820df7c5 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -72,7 +72,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, printk("[%s:%d:%08lx:%ld:%08lx]\n", current->comm, current->pid, address, write, regs->cp0_epc); #endif - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) goto bad_area; @@ -115,7 +115,7 @@ good_area: goto out_of_memory; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return; /* @@ -123,7 +123,7 @@ good_area: * Fix it, but check if it's kernel or user first.. */ bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ @@ -177,14 +177,14 @@ no_context: * us unable to handle the page fault gracefully. */ out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) do_exit(SIGKILL); goto no_context; do_sigbus: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* * Send a sigbus, regardless of whether we were in kernel diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 7fa5c9582..8d6c9a9f2 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -5,15 +5,10 @@ * * Copyright (C) 1994 - 2000 by Ralf Baechle * Copyright (C) 2000 Silicon Graphics, Inc. - */ -/************************************************************************** - * 9 Nov, 2000. - * Use mips_cpu structure. * - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - *************************************************************************/ - + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + */ #include <linux/config.h> #include <linux/init.h> #include <linux/signal.h> @@ -52,63 +47,6 @@ static unsigned long totalram_pages; extern void prom_free_prom_memory(void); -void __bad_pte_kernel(pmd_t *pmd) -{ - printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd)); - pmd_set(pmd, BAD_PAGETABLE); -} - -void __bad_pte(pmd_t *pmd) -{ - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_set(pmd, BAD_PAGETABLE); -} - -pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset) -{ - pte_t *page; - - page = (pte_t *) __get_free_page(GFP_USER); - if (pmd_none(*pmd)) { - if (page) { - clear_page(page); - pmd_val(*pmd) = (unsigned long)page; - return page + offset; - } - pmd_set(pmd, BAD_PAGETABLE); - return NULL; - } - free_page((unsigned long)page); - if (pmd_bad(*pmd)) { - __bad_pte_kernel(pmd); - return NULL; - } - return (pte_t *) pmd_page(*pmd) + offset; -} - -pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) -{ - pte_t *page; - - page = (pte_t *) __get_free_page(GFP_KERNEL); - if (pmd_none(*pmd)) { - if (page) { - clear_page(page); - pmd_val(*pmd) = (unsigned long)page; - return page + offset; - } - pmd_set(pmd, BAD_PAGETABLE); - return NULL; - } - free_page((unsigned long)page); - if (pmd_bad(*pmd)) { - __bad_pte(pmd); - return NULL; - } - return (pte_t *) pmd_page(*pmd) + offset; -} - - asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) { /* This should flush more selectivly ... */ @@ -170,48 +108,6 @@ int do_check_pgt_cache(int low, int high) return freed; } -/* - * BAD_PAGE is the page that is used for page faults when linux - * is out-of-memory. Older versions of linux just did a - * do_exit(), but using this instead means there is less risk - * for a process dying in kernel mode, possibly leaving a inode - * unused etc.. - * - * BAD_PAGETABLE is the accompanying page-table: it is initialized - * to point to BAD_PAGE entries. - * - * ZERO_PAGE is a special page that is used for zero-initialized - * data and COW. - */ -pte_t * __bad_pagetable(void) -{ - extern char empty_bad_page_table[PAGE_SIZE]; - unsigned long page, dummy1, dummy2; - - page = (unsigned long) empty_bad_page_table; - __asm__ __volatile__( - ".set\tnoreorder\n" - "1:\tsw\t%2,(%0)\n\t" - "subu\t%1,1\n\t" - "bnez\t%1,1b\n\t" - "addiu\t%0,4\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2) - :"r" (pte_val(BAD_PAGE)), "0" (page), "1" (PAGE_SIZE/4) - :"$1"); - - return (pte_t *)page; -} - -pte_t __bad_page(void) -{ - extern char empty_bad_page[PAGE_SIZE]; - unsigned long page = (unsigned long) empty_bad_page; - - clear_page((void *)page); - return pte_mkdirty(mk_pte_phys(__pa(page), PAGE_SHARED)); -} - void show_mem(void) { int i, free = 0, total = 0, reserved = 0; diff --git a/arch/mips/mm/umap.c b/arch/mips/mm/umap.c index c952004c9..100cb148d 100644 --- a/arch/mips/mm/umap.c +++ b/arch/mips/mm/umap.c @@ -93,7 +93,7 @@ remove_mapping (struct task_struct *task, unsigned long start, unsigned long end unsigned long beg = start; pgd_t *dir; - down (&task->mm->mmap_sem); + down_write (&task->mm->mmap_sem); dir = pgd_offset (task->mm, start); flush_cache_range (task->mm, beg, end); while (start < end){ @@ -102,7 +102,7 @@ remove_mapping (struct task_struct *task, unsigned long start, unsigned long end dir++; } flush_tlb_range (task->mm, beg, end); - up (&task->mm->mmap_sem); + up_write (&task->mm->mmap_sem); } EXPORT_SYMBOL(remove_mapping); @@ -181,7 +181,7 @@ vmap_pmd_range (pmd_t *pmd, unsigned long address, unsigned long size, unsigned end = PGDIR_SIZE; vaddr -= address; do { - pte_t * pte = pte_alloc(pmd, address); + pte_t * pte = pte_alloc(current->mm, pmd, address); if (!pte) return -ENOMEM; vmap_pte_range(pte, address, end - address, address + vaddr); @@ -203,7 +203,7 @@ vmap_page_range (unsigned long from, unsigned long size, unsigned long vaddr) dir = pgd_offset(current->mm, from); flush_cache_range(current->mm, beg, end); while (from < end) { - pmd_t *pmd = pmd_alloc(dir, from); + pmd_t *pmd = pmd_alloc(current->mm, dir, from); error = -ENOMEM; if (!pmd) break; diff --git a/arch/mips/sgi/kernel/setup.c b/arch/mips/sgi/kernel/setup.c index 09a291844..898e242bf 100644 --- a/arch/mips/sgi/kernel/setup.c +++ b/arch/mips/sgi/kernel/setup.c @@ -152,14 +152,16 @@ static unsigned long dosample(volatile unsigned char *tcwp, ct1 = read_32bit_cp0_register(CP0_COUNT); } while(msb); - /* Stop the counter. */ - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST); + /* Stop the counter. */ + *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST); - /* Return the difference, this is how far the r4k counter increments - * for every 1/HZ seconds. We round off the nearest 1 MHz of - * master clock (= 1000000 / 100 / 2 = 5000 count). - */ - return ((ct1 - ct0) / 5000) * 5000; + /* + * Return the difference, this is how far the r4k counter increments + * for every 1/HZ seconds. We round off the nearest 1 MHz of master + * clock (= 1000000 / 100 / 2 = 5000 count). + */ + + return ((ct1 - ct0) / 5000) * 5000; } #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig index f6c37c426..6d73c9fae 100644 --- a/arch/mips64/defconfig +++ b/arch/mips64/defconfig @@ -176,6 +176,7 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22 index 8e182f626..b457a1d82 100644 --- a/arch/mips64/defconfig-ip22 +++ b/arch/mips64/defconfig-ip22 @@ -185,6 +185,7 @@ CONFIG_SGIWD93_SCSI=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27 index f6c37c426..6d73c9fae 100644 --- a/arch/mips64/defconfig-ip27 +++ b/arch/mips64/defconfig-ip27 @@ -176,6 +176,7 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set diff --git a/arch/mips64/kernel/head.S b/arch/mips64/kernel/head.S index e9e35aa20..0ed458b80 100644 --- a/arch/mips64/kernel/head.S +++ b/arch/mips64/kernel/head.S @@ -176,8 +176,6 @@ NESTED(bootstrap, 16, sp) page swapper_pg_dir, 1 page invalid_pte_table, 0 page invalid_pmd_table, 1 - page empty_bad_page_table, 0 - page empty_bad_pmd_table, 1 page kptbl, KPTBL_PAGE_ORDER .globl ekptbl page kpmdtbl, 0 diff --git a/arch/mips64/kernel/linux32.c b/arch/mips64/kernel/linux32.c index f1a6084e5..206f09377 100644 --- a/arch/mips64/kernel/linux32.c +++ b/arch/mips64/kernel/linux32.c @@ -443,10 +443,10 @@ sys32_execve(abi64_no_regargs, struct pt_regs regs) * `execve' frees all current memory we only have to do an * `munmap' if the `execve' failes. */ - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); av = (char **) do_mmap_pgoff(0, 0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (IS_ERR(av)) return (long) av; @@ -742,7 +742,9 @@ sys32_getrusage(int who, struct rusage32 *ru) set_fs (KERNEL_DS); ret = sys_getrusage(who, &r); set_fs (old_fs); - if (put_rusage (ru, &r)) return -EFAULT; + if (put_rusage (ru, &r)) + return -EFAULT; + return ret; } @@ -752,7 +754,6 @@ get_tv32(struct timeval *o, struct timeval32 *i) return (!access_ok(VERIFY_READ, i, sizeof(*i)) || (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec))); - return ENOSYS; } static inline long @@ -763,7 +764,6 @@ get_it32(struct itimerval *o, struct itimerval32 *i) __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) | __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) | __get_user(o->it_value.tv_usec, &i->it_value.tv_usec))); - return ENOSYS; } static inline long @@ -777,12 +777,11 @@ put_tv32(struct timeval32 *o, struct timeval *i) static inline long put_it32(struct itimerval32 *o, struct itimerval *i) { - return (!access_ok(VERIFY_WRITE, i, sizeof(*i)) || + return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) | __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) | __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) | __put_user(i->it_value.tv_usec, &o->it_value.tv_usec))); - return ENOSYS; } extern int do_getitimer(int which, struct itimerval *value); @@ -839,6 +838,7 @@ sys32_alarm(unsigned int seconds) /* And we'd better return too much than too little anyway */ if (it_old.it_value.tv_usec) oldalarm++; + return oldalarm; } diff --git a/arch/mips64/kernel/syscall.c b/arch/mips64/kernel/syscall.c index 8b36b6e5e..a5694b3fc 100644 --- a/arch/mips64/kernel/syscall.c +++ b/arch/mips64/kernel/syscall.c @@ -64,9 +64,9 @@ sys_mmap(unsigned long addr, size_t len, unsigned long prot, } flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap(file, addr, len, prot, flags, offset); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); out: diff --git a/arch/mips64/mm/fault.c b/arch/mips64/mm/fault.c index 710b6b309..42e810176 100644 --- a/arch/mips64/mm/fault.c +++ b/arch/mips64/mm/fault.c @@ -95,7 +95,7 @@ do_page_fault(struct pt_regs *regs, unsigned long write, unsigned long address) printk("Cpu%d[%s:%d:%08lx:%ld:%08lx]\n", smp_processor_id(), current->comm, current->pid, address, write, regs->cp0_epc); #endif - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) goto bad_area; @@ -138,7 +138,7 @@ good_area: goto out_of_memory; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return; /* @@ -146,7 +146,7 @@ good_area: * Fix it, but check if it's kernel or user first.. */ bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* * Quickly check for vmalloc range faults. @@ -209,14 +209,14 @@ no_context: * us unable to handle the page fault gracefully. */ out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) do_exit(SIGKILL); goto no_context; do_sigbus: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* * Send a sigbus, regardless of whether we were in kernel diff --git a/arch/mips64/mm/init.c b/arch/mips64/mm/init.c index 848c1dd34..d0da581b3 100644 --- a/arch/mips64/mm/init.c +++ b/arch/mips64/mm/init.c @@ -1,5 +1,4 @@ -/* $Id: init.c,v 1.13 2000/02/23 00:41:00 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -40,25 +39,6 @@ unsigned long totalram_pages; -void __bad_pte_kernel(pmd_t *pmd) -{ - printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd)); - pmd_set(pmd, BAD_PAGETABLE); -} - -void __bad_pte(pmd_t *pmd) -{ - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_set(pmd, BAD_PAGETABLE); -} - -/* Fixme, we need something like BAD_PMDTABLE ... */ -void __bad_pmd(pgd_t *pgd) -{ - printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd)); - pgd_set(pgd, empty_bad_pmd_table); -} - void pgd_init(unsigned long page) { unsigned long *p, *end; @@ -113,72 +93,6 @@ void pmd_init(unsigned long addr, unsigned long pagetable) } } -pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset) -{ - pmd_t *pmd; - - pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 1); - if (pgd_none(*pgd)) { - if (pmd) { - pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table); - pgd_set(pgd, pmd); - return pmd + offset; - } - pgd_set(pgd, BAD_PMDTABLE); - return NULL; - } - free_page((unsigned long)pmd); - if (pgd_bad(*pgd)) { - __bad_pmd(pgd); - return NULL; - } - return (pmd_t *) pgd_page(*pgd) + offset; -} - -pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset) -{ - pte_t *page; - - page = (pte_t *) __get_free_pages(GFP_USER, 1); - if (pmd_none(*pmd)) { - if (page) { - clear_page(page); - pmd_set(pmd, page); - return page + offset; - } - pmd_set(pmd, BAD_PAGETABLE); - return NULL; - } - free_page((unsigned long)page); - if (pmd_bad(*pmd)) { - __bad_pte_kernel(pmd); - return NULL; - } - return (pte_t *) pmd_page(*pmd) + offset; -} - -pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) -{ - pte_t *page; - - page = (pte_t *) __get_free_pages(GFP_KERNEL, 0); - if (pmd_none(*pmd)) { - if (page) { - clear_page(page); - pmd_val(*pmd) = (unsigned long)page; - return page + offset; - } - pmd_set(pmd, BAD_PAGETABLE); - return NULL; - } - free_pages((unsigned long)page, 0); - if (pmd_bad(*pmd)) { - __bad_pte(pmd); - return NULL; - } - return (pte_t *) pmd_page(*pmd) + offset; -} - int do_check_pgt_cache(int low, int high) { int freed = 0; @@ -247,34 +161,6 @@ unsigned long setup_zero_pages(void) return 1UL << order; } -/* - * BAD_PAGE is the page that is used for page faults when linux - * is out-of-memory. Older versions of linux just did a - * do_exit(), but using this instead means there is less risk - * for a process dying in kernel mode, possibly leaving a inode - * unused etc.. - * - * BAD_PAGETABLE is the accompanying page-table: it is initialized - * to point to BAD_PAGE entries. - * - * ZERO_PAGE is a special page that is used for zero-initialized - * data and COW. - */ -pmd_t * __bad_pmd_table(void) -{ - return empty_bad_pmd_table; -} - -pte_t * __bad_pagetable(void) -{ - return empty_bad_page_table; -} - -pte_t __bad_page(void) -{ - return __pte(0); -} - void __init add_memory_region(unsigned long start, unsigned long size, long type) { @@ -474,8 +360,6 @@ void __init paging_init(void) pgd_init((unsigned long)swapper_pg_dir); pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE); - pmd_init((unsigned long)empty_bad_pmd_table, (unsigned long)empty_bad_page_table); - memset((void *)empty_bad_page_table, 0, sizeof(pte_t) * PTRS_PER_PTE); max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; low = max_low_pfn; diff --git a/arch/mips64/mm/umap.c b/arch/mips64/mm/umap.c index 8690d9961..ba018c599 100644 --- a/arch/mips64/mm/umap.c +++ b/arch/mips64/mm/umap.c @@ -90,7 +90,7 @@ remove_mapping (struct task_struct *task, unsigned long start, unsigned long end unsigned long beg = start; pgd_t *dir; - down (&task->mm->mmap_sem); + down_write (&task->mm->mmap_sem); dir = pgd_offset (task->mm, start); flush_cache_range (task->mm, beg, end); while (start < end){ @@ -99,7 +99,7 @@ remove_mapping (struct task_struct *task, unsigned long start, unsigned long end dir++; } flush_tlb_range (task->mm, beg, end); - up (&task->mm->mmap_sem); + up_write (&task->mm->mmap_sem); } EXPORT_SYMBOL(remove_mapping); diff --git a/arch/mips64/sgi-ip27/ip27-memory.c b/arch/mips64/sgi-ip27/ip27-memory.c index 0e469ce4b..62749a773 100644 --- a/arch/mips64/sgi-ip27/ip27-memory.c +++ b/arch/mips64/sgi-ip27/ip27-memory.c @@ -234,8 +234,6 @@ void __init paging_init(void) pgd_init((unsigned long)swapper_pg_dir); pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE); - pmd_init((unsigned long)empty_bad_pmd_table, (unsigned long)empty_bad_page_table); - memset((void *)empty_bad_page_table, 0, sizeof(pte_t) * PTRS_PER_PTE); for (node = 0; node < numnodes; node++) { pfn_t start_pfn = slot_getbasepfn(node, 0); diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 85aca70af..1e365cc76 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -51,7 +51,7 @@ int sys_mmap(unsigned long addr, unsigned long len, struct file * file = NULL; int error; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); lock_kernel(); if (!(flags & MAP_ANONYMOUS)) { error = -EBADF; @@ -65,7 +65,7 @@ int sys_mmap(unsigned long addr, unsigned long len, fput(file); out: unlock_kernel(); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); return error; } diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 68d4614ec..d7ca72dd9 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -175,7 +175,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, if (in_interrupt() || !mm) goto no_context; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = pa_find_vma(mm, address); if (!vma) goto bad_area; @@ -218,14 +218,14 @@ good_area: default: goto out_of_memory; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return; /* * Something tried to access memory that isn't in our memory map.. */ bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); if (user_mode(regs)) { struct siginfo si; @@ -275,7 +275,7 @@ no_context: parisc_terminate("Bad Address (null pointer deref?)",regs,code,address); out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) do_exit(SIGKILL); diff --git a/arch/ppc/8xx_io/Config.in b/arch/ppc/8xx_io/Config.in index 090c09cb4..7ca789288 100644 --- a/arch/ppc/8xx_io/Config.in +++ b/arch/ppc/8xx_io/Config.in @@ -7,24 +7,24 @@ comment 'MPC8xx CPM Options' if [ "$CONFIG_NET_ETHERNET" = "y" ]; then bool 'CPM SCC Ethernet' CONFIG_SCC_ENET if [ "$CONFIG_SCC_ENET" = "y" ]; then - bool 'Ethernet on SCC1' CONFIG_SCC1_ENET - if [ "$CONFIG_SCC1_ENET" != "y" ]; then - bool 'Ethernet on SCC2' CONFIG_SCC2_ENET - fi + choice 'SCC used for Ethernet' \ + "SCC1 CONFIG_SCC1_ENET \ + SCC2 CONFIG_SCC2_ENET \ + SCC3 CONFIG_SCC3_ENET" SCC1 fi bool '860T FEC Ethernet' CONFIG_FEC_ENET + if [ "$CONFIG_FEC_ENET" = "y" ]; then + bool 'Use MDIO for PHY configuration' CONFIG_USE_MDIO + fi bool 'Use Big CPM Ethernet Buffers' CONFIG_ENET_BIG_BUFFERS fi bool 'Use SMC2 for UART' CONFIG_8xxSMC2 if [ "$CONFIG_8xxSMC2" = "y" ]; then bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_8xx_ALTSMC2 + bool 'Use SMC2 for Console' CONFIG_8xx_CONS_SMC2 fi bool 'Enable SCC2 and SCC3 for UART' CONFIG_8xxSCC -if [ "$CONFIG_TQM860" = "y" -o "$CONFIG_TQM860L" = "y" -o "$CONFIG_TQM8xxL" = "y" ]; then - bool 'Use SMC2 for Console' TQM_SMC2_CONSOLE -fi - # This doesn't really belong here, but it is convenient to ask # 8xx specific questions. @@ -32,4 +32,7 @@ comment 'Generic MPC8xx Options' bool 'Copy-Back Data Cache (else Writethrough)' CONFIG_8xx_COPYBACK bool 'CPU6 Silicon Errata (860 Pre Rev. C)' CONFIG_8xx_CPU6 +if [ "$CONFIG_IDE" = "y" ]; then + bool 'MPC8xx direct IDE support on PCMCIA port' CONFIG_BLK_DEV_MPC8xx_IDE +fi endmenu diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c index 0790a81c5..19d7f3dd1 100644 --- a/arch/ppc/8xx_io/commproc.c +++ b/arch/ppc/8xx_io/commproc.c @@ -61,22 +61,6 @@ m8xx_cpm_reset(uint host_page_addr) imp = (immap_t *)IMAP_ADDR; commproc = (cpm8xx_t *)&imp->im_cpm; -#ifdef notdef - /* We can't do this. It seems to blow away the microcode - * patch that EPPC-Bug loaded for us. EPPC-Bug uses SCC1 for - * Ethernet, SMC1 for the console, and I2C for serial EEPROM. - * Our own drivers quickly reset all of these. - */ - - /* Perform a reset. - */ - commproc->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG); - - /* Wait for it. - */ - while (commproc->cp_cpcr & CPM_CR_FLG); -#endif - /* Set SDMA Bus Request priority 5. * On 860T, this also enables FEC priority 6. I am not sure * this is what we realy want for some applications, but the @@ -168,6 +152,14 @@ cpm_error_interrupt(void *dev) void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id) { + + /* If null handler, assume we are trying to free the IRQ. + */ + if (!handler) { + cpm_free_handler(vec); + return; + } + if (cpm_vecs[vec].handler != 0) printk("CPM interrupt %x replacing %x\n", (uint)handler, (uint)cpm_vecs[vec].handler); @@ -226,8 +218,9 @@ m8xx_cpm_hostalloc(uint size) * The internal baud rate clock is the system clock divided by 16. * This assumes the baudrate is 16x oversampled by the uart. */ -#define BRG_INT_CLK (((bd_t *)__res)->bi_intfreq * 1000000) -#define BRG_UART_CLK (BRG_INT_CLK/16) +#define BRG_INT_CLK (((bd_t *)__res)->bi_intfreq * 1000000) +#define BRG_UART_CLK (BRG_INT_CLK/16) +#define BRG_UART_CLK_DIV16 (BRG_UART_CLK/16) void m8xx_cpm_setbrg(uint brg, uint rate) @@ -238,6 +231,12 @@ m8xx_cpm_setbrg(uint brg, uint rate) */ bp = (uint *)&cpmp->cp_brgc1; bp += brg; - *bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN; + /* The BRG has a 12-bit counter. For really slow baud rates (or + * really fast processors), we may have to further divide by 16. + */ + if (((BRG_UART_CLK / rate) - 1) < 4096) + *bp = (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN; + else + *bp = (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) | + CPM_BRG_EN | CPM_BRG_DIV16; } - diff --git a/arch/ppc/8xx_io/commproc.h b/arch/ppc/8xx_io/commproc.h index a8194cb21..6eda9d5bf 100644 --- a/arch/ppc/8xx_io/commproc.h +++ b/arch/ppc/8xx_io/commproc.h @@ -324,7 +324,7 @@ typedef struct scc_param { */ #define SCC_EB ((u_char)0x10) /* Set big endian byte order */ -/* CPM Ethernet through SCC1. +/* CPM Ethernet through SCCx. */ typedef struct scc_enet { sccp_t sen_genscc; @@ -379,6 +379,8 @@ typedef struct scc_enet { ushort sen_taddrl; /* temp address (LSB) */ } scc_enet_t; +/*** MBX ************************************************************/ + #ifdef CONFIG_MBX /* Bits in parallel I/O port registers that have to be set/cleared * to configure the pins for SCC1 use. The TCLK and RCLK seem unique @@ -399,7 +401,9 @@ typedef struct scc_enet { */ #define SICR_ENET_MASK ((uint)0x000000ff) #define SICR_ENET_CLKRT ((uint)0x0000003d) -#endif +#endif /* CONFIG_MBX */ + +/*** RPXLITE ********************************************************/ #ifdef CONFIG_RPXLITE /* This ENET stuff is for the MPC850 with ethernet on SCC2. Some of @@ -416,7 +420,9 @@ typedef struct scc_enet { #define SICR_ENET_MASK ((uint)0x0000ff00) #define SICR_ENET_CLKRT ((uint)0x00003d00) -#endif +#endif /* CONFIG_RPXLITE */ + +/*** BSEIP **********************************************************/ #ifdef CONFIG_BSEIP /* This ENET stuff is for the MPC823 with ethernet on SCC2. @@ -438,7 +444,9 @@ typedef struct scc_enet { #define SICR_ENET_MASK ((uint)0x0000ff00) #define SICR_ENET_CLKRT ((uint)0x00002c00) -#endif +#endif /* CONFIG_BSEIP */ + +/*** RPXCLASSIC *****************************************************/ #ifdef CONFIG_RPXCLASSIC /* Bits in parallel I/O port registers that have to be set/cleared @@ -457,27 +465,63 @@ typedef struct scc_enet { */ #define SICR_ENET_MASK ((uint)0x000000ff) #define SICR_ENET_CLKRT ((uint)0x0000003d) -#endif +#endif /* CONFIG_RPXCLASSIC */ -#if (defined(CONFIG_TQM860) || defined(CONFIG_TQM860L)) -/* - * TQM860 and TQM860L Configuration: - * - * Signal PAR DIR ODR DAT Function - * Port A, 5 1 0 - - TCLK (CLK3) for Ethernet - * Port A, 7 1 0 - - RCLK (CLK1) for Ethernet - * Port A, 14 1 0 - - TXD for Ethernet (SCC1) - * Port A, 15 1 0 - - RXD for Ethernet (SCC1) - * Port C, 7 0 0 0 - -> ETH-LOOP - * Port C, 10 0 0 1 - CD for Ethernet (SCC1) - * Port C, 11 0 0 1 - CTS for Ethernet (SCC1) - * Port C, 15 * * 0 - TENA/RTS for Ethernet +/*** TQM823L, TQM850L ***********************************************/ + +#if defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L) +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. */ +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ +#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */ + +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to + * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002600) +#endif /* CONFIG_TQM823L, CONFIG_TQM850L */ + +/*** FPS850L *********************************************************/ + +#ifdef CONFIG_FPS850L +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + */ +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ + +#define PC_ENET_TENA ((ushort)0x0002) /* PC 14 */ +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ + +/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to + * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002600) +#endif /* CONFIG_FPS850L */ + +/*** TQM860L ********************************************************/ + +#ifdef CONFIG_TQM860L +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + */ #define PA_ENET_RXD ((ushort)0x0001) /* PA 15 */ #define PA_ENET_TXD ((ushort)0x0002) /* PA 14 */ -#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ #define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ #define PC_ENET_TENA ((ushort)0x0001) /* PC 15 */ #define PC_ENET_CLSN ((ushort)0x0010) /* PC 11 */ @@ -488,51 +532,59 @@ typedef struct scc_enet { */ #define SICR_ENET_MASK ((uint)0x000000ff) #define SICR_ENET_CLKRT ((uint)0x00000026) +#endif /* CONFIG_TQM860L */ -#endif /* CONFIG_TQM860, TQM860L */ +/*** SPD823TS *******************************************************/ -#ifdef CONFIG_TQM8xxL -/* - * TQM8xxL Configuration (except TQM860L): - * - * Signal PAR DIR ODR DAT Function - * Port A, 5 1 0 - - TCLK (CLK3) for Ethernet - * Port A, 7 1 0 - - RCLK (CLK1) for Ethernet - * Port A, 12 1 0 - - TXD for Ethernet (SCC2) - * Port A, 13 1 0 - - RXD for Ethernet (SCC2) - * Port B, 18 1 1 - - TENA/RTS for Ethernet on STK8xx - * Port C, 7 0 0 0 - -> ETH-LOOP - * Port C, 8 0 0 1 - CD for Ethernet (SCC2) - * Port C, 9 0 0 1 - CTS for Ethernet (SCC2) - * Port C, 14 * * 0 - TENA/RTS for Ethernet on FPS850 - * - * Note: Using PC14 as RTS2 (TENA) does not work on the TQM850L when - * used with the starter-kit mainboard; we *must* use PB18 instead. - * For the FPS850 system, we *must* use PC14 :-( +#ifdef CONFIG_SPD823TS +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC2 use. */ - +#define PA_ENET_MDC ((ushort)0x0001) /* PA 15 !!! */ +#define PA_ENET_MDIO ((ushort)0x0002) /* PA 14 !!! */ #define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ #define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ -#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */ +#define PA_ENET_RCLK ((ushort)0x0200) /* PA 6 */ #define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ -#ifndef CONFIG_FPS850 /* not valid on FPS board */ -#define PB_ENET_TENA ((uint)0x00002000) -#endif /* !CONFIG_FPS850 */ +#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */ -#ifdef CONFIG_FPS850 /* FPS uses default configuration */ -#define PC_ENET_TENA ((ushort)0x0002) /* PC 14 */ -#endif /* CONFIG_FPS850 */ #define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ #define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ +#define PC_ENET_RESET ((ushort)0x0100) /* PC 7 !!! */ -/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK2) to * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero. */ #define SICR_ENET_MASK ((uint)0x0000ff00) -#define SICR_ENET_CLKRT ((uint)0x00002600) +#define SICR_ENET_CLKRT ((uint)0x00002E00) +#endif /* CONFIG_SPD823TS */ + + +/*** SM850 *********************************************************/ + +/* The SM850 Service Module uses SCC2 for IrDA and SCC3 for Ethernet */ + +#ifdef CONFIG_SM850 +#define PB_ENET_RXD ((uint)0x00000004) /* PB 29 */ +#define PB_ENET_TXD ((uint)0x00000002) /* PB 30 */ +#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ + +#define PC_ENET_LBK ((ushort)0x0008) /* PC 12 */ +#define PC_ENET_TENA ((ushort)0x0004) /* PC 13 */ -#endif /* CONFIG_TQM8xxL */ +#define PC_ENET_RENA ((ushort)0x0800) /* PC 4 */ +#define PC_ENET_CLSN ((ushort)0x0400) /* PC 5 */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to + * SCC3. Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero. + */ +#define SICR_ENET_MASK ((uint)0x00FF0000) +#define SICR_ENET_CLKRT ((uint)0x00260000) +#endif /* CONFIG_SM850 */ + +/*********************************************************************/ /* SCC Event register as used by Ethernet. */ @@ -723,8 +775,6 @@ typedef struct iic { #define CPMVEC_PIO_PC4 ((ushort)0x01) #define CPMVEC_ERROR ((ushort)0x00) -extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id); - /* CPM interrupt configuration vector. */ #define CICR_SCD_SCC4 ((uint)0x00c00000) /* SCC4 @ SCCd */ @@ -735,4 +785,8 @@ extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id); #define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */ #define CICR_IEN ((uint)0x00000080) /* Int. enable */ #define CICR_SPS ((uint)0x00000001) /* SCC Spread */ + +extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id); +extern void cpm_free_handler(int vec); + #endif /* __CPM_8XX__ */ diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index 39628da04..600046bb8 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -154,20 +154,26 @@ static void set_multicast_list(struct net_device *dev); /*static ushort my_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };*/ /* Typically, 860(T) boards use SCC1 for Ethernet, and other 8xx boards - * use SCC2. This is easily extended if necessary. + * use SCC2. Some even may use SCC3. + * This is easily extended if necessary. */ -#ifdef CONFIG_SCC2_ENET +#if defined(CONFIG_SCC3_ENET) +#define CPM_CR_ENET CPM_CR_CH_SCC3 +#define PROFF_ENET PROFF_SCC3 +#define SCC_ENET 2 /* Index, not number! */ +#define CPMVEC_ENET CPMVEC_SCC3 +#elif defined(CONFIG_SCC2_ENET) #define CPM_CR_ENET CPM_CR_CH_SCC2 #define PROFF_ENET PROFF_SCC2 #define SCC_ENET 1 /* Index, not number! */ #define CPMVEC_ENET CPMVEC_SCC2 -#endif - -#ifdef CONFIG_SCC1_ENET -#define CPM_CR_ENET CPM_CR_CH_SCC1 +#elif defined(CONFIG_SCC1_ENET) +#define CPM_CR_ENET CPM_CR_CH_SCC1 #define PROFF_ENET PROFF_SCC1 -#define SCC_ENET 0 +#define SCC_ENET 0 /* Index, not number! */ #define CPMVEC_ENET CPMVEC_SCC1 +#else +#error CONFIG_SCCx_ENET not defined #endif static int @@ -642,10 +648,11 @@ int __init scc_enet_init(void) volatile scc_t *sccp; volatile scc_enet_t *ep; volatile immap_t *immap; + extern unsigned long _get_IMMR(void); cp = cpmp; /* Get pointer to Communication Processor */ - immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ + immap = (immap_t *)(_get_IMMR() & 0xFFFF0000); /* and to internal registers */ bd = (bd_t *)__res; @@ -683,28 +690,47 @@ int __init scc_enet_init(void) * It can't last though...... */ +#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD)) /* Configure port A pins for Txd and Rxd. */ - immap->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD); + immap->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD); immap->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD); - immap->im_ioport.iop_paodr &= ~PA_ENET_TXD; + immap->im_ioport.iop_paodr &= ~PA_ENET_TXD; +#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD)) + /* Configure port B pins for Txd and Rxd. + */ + immap->im_cpm.cp_pbpar |= (PB_ENET_RXD | PB_ENET_TXD); + immap->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD); + immap->im_cpm.cp_pbodr &= ~PB_ENET_TXD; +#else +#error Exactly ONE pair of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined +#endif + +#if defined(PC_ENET_LBK) + /* Configure port C pins to disable External Loopback + */ + immap->im_ioport.iop_pcpar &= ~PC_ENET_LBK; + immap->im_ioport.iop_pcdir |= PC_ENET_LBK; + immap->im_ioport.iop_pcso &= ~PC_ENET_LBK; + immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */ +#endif /* PC_ENET_LBK */ /* Configure port C pins to enable CLSN and RENA. */ immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA); immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA); - immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA); + immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA); /* Configure port A for TCLK and RCLK. */ - immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK); + immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK); immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK); /* Configure Serial Interface clock routing. * First, clear all SCC bits to zero, then set the ones we want. */ cp->cp_sicr &= ~SICR_ENET_MASK; - cp->cp_sicr |= SICR_ENET_CLKRT; + cp->cp_sicr |= SICR_ENET_CLKRT; /* Manual says set SDDR, but I can't find anything with that * name. I think it is a misprint, and should be SDCR. This @@ -884,20 +910,17 @@ int __init scc_enet_init(void) /* It is now OK to enable the Ethernet transmitter. * Unfortunately, there are board implementation differences here. */ -#if (defined(CONFIG_MBX) || defined(CONFIG_TQM860) || defined(CONFIG_TQM860L) || defined(CONFIG_FPS850)) - immap->im_ioport.iop_pcpar |= PC_ENET_TENA; +#if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA)) + immap->im_ioport.iop_pcpar |= PC_ENET_TENA; immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA; -#endif - -#if (defined(CONFIG_TQM8xxL) && !defined(CONFIG_FPS850)) +#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA)) cp->cp_pbpar |= PB_ENET_TENA; cp->cp_pbdir |= PB_ENET_TENA; +#else +#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA #endif #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) - cp->cp_pbpar |= PB_ENET_TENA; - cp->cp_pbdir |= PB_ENET_TENA; - /* And while we are here, set the configuration to enable ethernet. */ *((volatile uint *)RPX_CSR_ADDR) &= ~BCSR0_ETHLPBK; @@ -906,9 +929,6 @@ int __init scc_enet_init(void) #endif #ifdef CONFIG_BSEIP - cp->cp_pbpar |= PB_ENET_TENA; - cp->cp_pbdir |= PB_ENET_TENA; - /* BSE uses port B and C for PHY control. */ cp->cp_pbpar &= ~(PB_BSE_POWERUP | PB_BSE_FDXDIS); @@ -941,7 +961,7 @@ int __init scc_enet_init(void) */ sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - printk("%s: CPM ENET Version 0.2, ", dev->name); + printk("%s: CPM ENET Version 0.2 on SCC%d, ", dev->name, SCC_ENET+1); for (i=0; i<5; i++) printk("%02x:", dev->dev_addr[i]); printk("%02x\n", dev->dev_addr[5]); @@ -949,3 +969,4 @@ int __init scc_enet_init(void) return 0; } + diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c index 33849ea0e..848a2fc4d 100644 --- a/arch/ppc/8xx_io/fec.c +++ b/arch/ppc/8xx_io/fec.c @@ -8,7 +8,9 @@ * describes connections using the internal parallel port I/O, which * is basically all of Port D. * - * Right now, I am very watseful with the buffers. I allocate memory + * Includes support for the following PHYs: QS6612, LXT970, LXT971/2. + * + * Right now, I am very wasteful with the buffers. I allocate memory * pages and then divide them into 2K frame buffers. This way I know I * have buffers large enough to hold one frame within one buffer descriptor. * Once I get this working, I will use 64 or 128 byte CPM buffers, which @@ -18,13 +20,16 @@ * Much better multiple PHY support by Magnus Damm. * Copyright (c) 2000 Ericsson Radio Systems AB. * + * Make use of MII for PHY control configurable. + * Some fixes. + * Copyright (c) 2000 Wolfgang Denk, DENX Software Engineering. */ /* List of PHYs we wish to support. */ -#define CONFIG_FEC_LXT970 -#define CONFIG_FEC_LXT971 -#define CONFIG_FEC_QS6612 +#undef CONFIG_FEC_LXT970 +#define CONFIG_FEC_LXT971 +#undef CONFIG_FEC_QS6612 #include <linux/config.h> #include <linux/kernel.h> @@ -54,6 +59,7 @@ #include <asm/uaccess.h> #include "commproc.h" +#ifdef CONFIG_USE_MDIO /* Forward declarations of some structures to support different PHYs */ @@ -71,6 +77,7 @@ typedef struct { const phy_cmd_t *ack_int; const phy_cmd_t *shutdown; } phy_info_t; +#endif /* CONFIG_USE_MDIO */ /* The number of Tx and Rx buffers. These are allocated from the page * pool. The code may assume these are power of two, so it is best @@ -78,20 +85,20 @@ typedef struct { * We don't need to allocate pages for the transmitter. We just use * the skbuffer directly. */ -#if 1 -#define FEC_ENET_RX_PAGES 4 +#ifdef CONFIG_ENET_BIG_BUFFERS +#define FEC_ENET_RX_PAGES 16 #define FEC_ENET_RX_FRSIZE 2048 #define FEC_ENET_RX_FRPPG (PAGE_SIZE / FEC_ENET_RX_FRSIZE) #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES) -#define TX_RING_SIZE 8 /* Must be power of two */ -#define TX_RING_MOD_MASK 7 /* for this to work */ +#define TX_RING_SIZE 16 /* Must be power of two */ +#define TX_RING_MOD_MASK 15 /* for this to work */ #else -#define FEC_ENET_RX_PAGES 16 +#define FEC_ENET_RX_PAGES 4 #define FEC_ENET_RX_FRSIZE 2048 #define FEC_ENET_RX_FRPPG (PAGE_SIZE / FEC_ENET_RX_FRSIZE) #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES) -#define TX_RING_SIZE 16 /* Must be power of two */ -#define TX_RING_MOD_MASK 15 /* for this to work */ +#define TX_RING_SIZE 8 /* Must be power of two */ +#define TX_RING_MOD_MASK 7 /* for this to work */ #endif /* Interrupt events/masks. @@ -107,6 +114,26 @@ typedef struct { #define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */ #define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */ +/* +*/ +#define FEC_ECNTRL_PINMUX 0x00000004 +#define FEC_ECNTRL_ETHER_EN 0x00000002 +#define FEC_ECNTRL_RESET 0x00000001 + +#define FEC_RCNTRL_BC_REJ 0x00000010 +#define FEC_RCNTRL_PROM 0x00000008 +#define FEC_RCNTRL_MII_MODE 0x00000004 +#define FEC_RCNTRL_DRT 0x00000002 +#define FEC_RCNTRL_LOOP 0x00000001 + +#define FEC_TCNTRL_FDEN 0x00000004 +#define FEC_TCNTRL_HBC 0x00000002 +#define FEC_TCNTRL_GTS 0x00000001 + +/* Delay to wait for FEC reset command to complete (in us) +*/ +#define FEC_RESET_DELAY 50 + /* The FEC stores dest/src/type, data, and checksum for receive packets. */ #define PKT_MAXBUF_SIZE 1518 @@ -138,6 +165,7 @@ struct fec_enet_private { uint tx_full; spinlock_t lock; +#ifdef CONFIG_USE_MDIO uint phy_id; uint phy_id_done; uint phy_status; @@ -148,6 +176,7 @@ struct fec_enet_private { uint sequence_done; uint phy_addr; +#endif /* CONFIG_USE_MDIO */ int link; int old_link; @@ -165,7 +194,9 @@ struct fec_enet_private { static int fec_enet_open(struct net_device *dev); static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); +#ifdef CONFIG_USE_MDIO static void fec_enet_mii(struct net_device *dev); +#endif /* CONFIG_USE_MDIO */ static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs); #ifdef CONFIG_FEC_PACKETHOOK static void fec_enet_tx(struct net_device *dev, __u32 regval); @@ -181,6 +212,7 @@ static void fec_restart(struct net_device *dev, int duplex); static void fec_stop(struct net_device *dev); static ushort my_enet_addr[3]; +#ifdef CONFIG_USE_MDIO /* MII processing. We keep this as simple as possible. Requests are * placed on the list (if there is room). When the request is finished * by the MII, an optional function may be called. @@ -197,7 +229,7 @@ mii_list_t *mii_free; mii_list_t *mii_head; mii_list_t *mii_tail; -static int mii_queue(struct net_device *dev, int request, +static int mii_queue(struct net_device *dev, int request, void (*func)(uint, struct net_device *)); /* Make MII read/write commands for the FEC. @@ -206,11 +238,13 @@ static int mii_queue(struct net_device *dev, int request, #define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \ (VAL & 0xffff)) #define mk_mii_end 0 +#endif /* CONFIG_USE_MDIO */ /* Transmitter timeout. */ #define TX_TIMEOUT (2*HZ) +#ifdef CONFIG_USE_MDIO /* Register definitions for the PHY. */ @@ -218,7 +252,7 @@ static int mii_queue(struct net_device *dev, int request, #define MII_REG_SR 1 /* Status Register */ #define MII_REG_PHYIR1 2 /* PHY Identification Register 1 */ #define MII_REG_PHYIR2 3 /* PHY Identification Register 2 */ -#define MII_REG_ANAR 4 /* A-N Advertisement Register */ +#define MII_REG_ANAR 4 /* A-N Advertisement Register */ #define MII_REG_ANLPAR 5 /* A-N Link Partner Ability Register */ #define MII_REG_ANER 6 /* A-N Expansion Register */ #define MII_REG_ANNPTR 7 /* A-N Next Page Transmit Register */ @@ -230,18 +264,19 @@ static int mii_queue(struct net_device *dev, int request, #define PHY_CONF_LOOP 0x0002 /* 1 loopback mode enabled */ #define PHY_CONF_SPMASK 0x00f0 /* mask for speed */ #define PHY_CONF_10HDX 0x0010 /* 10 Mbit half duplex supported */ -#define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */ +#define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */ #define PHY_CONF_100HDX 0x0040 /* 100 Mbit half duplex supported */ -#define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */ +#define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */ #define PHY_STAT_LINK 0x0100 /* 1 up - 0 down */ #define PHY_STAT_FAULT 0x0200 /* 1 remote fault */ #define PHY_STAT_ANC 0x0400 /* 1 auto-negotiation complete */ #define PHY_STAT_SPMASK 0xf000 /* mask for speed */ #define PHY_STAT_10HDX 0x1000 /* 10 Mbit half duplex selected */ -#define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */ +#define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */ #define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ -#define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ +#define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ +#endif /* CONFIG_USE_MDIO */ #ifdef CONFIG_FEC_PACKETHOOK int @@ -291,7 +326,7 @@ fec_unregister_ph(struct net_device *dev) fep->ph_proto = 0; fep->ph_regaddr = NULL; fep->ph_priv = NULL; - + fep->ph_lock = 0; return retval; @@ -345,7 +380,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) fep->stats.tx_bytes += skb->len; fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK; - + /* Push the data cache so the CPM does not get stale memory * data. */ @@ -404,7 +439,7 @@ fec_timeout(struct net_device *dev) bdp = fep->tx_bd_base; printk(" tx: %u buffers\n", TX_RING_SIZE); for (i = 0 ; i < TX_RING_SIZE; i++) { - printk(" %08x: %04x %04x %08x\n", + printk(" %08x: %04x %04x %08x\n", (uint) bdp, bdp->cbd_sc, bdp->cbd_datlen, @@ -443,7 +478,6 @@ fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) if (fep->ph_regaddr) regval = *fep->ph_regaddr; #endif - fecp = (volatile fec_t*)dev->base_addr; /* Get the interrupt events that caused us to be here. @@ -478,9 +512,13 @@ fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) } if (int_events & FEC_ENET_MII) { +#ifdef CONFIG_USE_MDIO fec_enet_mii(dev); +#else +printk("%s[%d] %s: unexpected FEC_ENET_MII event\n", __FILE__,__LINE__,__FUNCTION__); +#endif /* CONFIG_USE_MDIO */ } - + } } @@ -541,23 +579,23 @@ fec_enet_tx(struct net_device *dev) */ if (bdp->cbd_sc & BD_ENET_TX_DEF) fep->stats.collisions++; - + /* Free the sk buffer associated with this last transmit. */ #if 0 printk("TXI: %x %x %x\n", bdp, skb, fep->skb_dirty); #endif - dev_kfree_skb(skb/*, FREE_WRITE*/); + dev_kfree_skb_irq (skb/*, FREE_WRITE*/); fep->tx_skbuff[fep->skb_dirty] = NULL; fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK; - + /* Update pointer to next buffer descriptor to be transmitted. */ if (bdp->cbd_sc & BD_ENET_TX_WRAP) bdp = fep->tx_bd_base; else bdp++; - + /* Since we have freed up a buffer, the ring is no longer * full. */ @@ -617,7 +655,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { /* Check for errors. */ if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { - fep->stats.rx_errors++; + fep->stats.rx_errors++; if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { /* Frame too long or too short. */ fep->stats.rx_length_errors++; @@ -703,7 +741,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { bdp = fep->rx_bd_base; else bdp++; - + #if 1 /* Doing this here will keep the FEC running while we process * incoming frames. On a heavily loaded network, we should be @@ -732,6 +770,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { } +#ifdef CONFIG_USE_MDIO static void fec_enet_mii(struct net_device *dev) { @@ -743,7 +782,7 @@ fec_enet_mii(struct net_device *dev) fep = (struct fec_enet_private *)dev->priv; ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); mii_reg = ep->fec_mii_data; - + if ((mip = mii_head) == NULL) { printk("MII and no head!\n"); return; @@ -756,8 +795,9 @@ fec_enet_mii(struct net_device *dev) mip->mii_next = mii_free; mii_free = mip; - if ((mip = mii_head) != NULL) + if ((mip = mii_head) != NULL) { ep->fec_mii_data = mip->mii_regval; + } } static int @@ -786,13 +826,11 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi if (mii_head) { mii_tail->mii_next = mip; mii_tail = mip; - } - else { + } else { mii_head = mii_tail = mip; (&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_mii_data = regval; } - } - else { + } else { retval = 1; } @@ -808,7 +846,7 @@ static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c) if(!c) return; - for(k = 0; (c+k)->mii_data != mk_mii_end; k++) + for(k = 0; (c+k)->mii_data != mk_mii_end; k++) mii_queue(dev, (c+k)->mii_data, (c+k)->funct); } @@ -896,7 +934,7 @@ static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev) } static phy_info_t phy_info_lxt970 = { - 0x07810000, + 0x07810000, "LXT970", (const phy_cmd_t []) { /* config */ @@ -919,12 +957,12 @@ static phy_info_t phy_info_lxt970 = { }, (const phy_cmd_t []) { /* ack_int */ /* read SR and ISR to acknowledge */ - + { mk_mii_read(MII_REG_SR), mii_parse_sr }, { mk_mii_read(MII_LXT970_ISR), NULL }, /* find out the current status */ - + { mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr }, { mk_mii_end, } }, @@ -933,7 +971,7 @@ static phy_info_t phy_info_lxt970 = { { mk_mii_end, } }, }; - + #endif /* CONFIG_FEC_LXT970 */ /* ------------------------------------------------------------------------- */ @@ -950,7 +988,7 @@ static phy_info_t phy_info_lxt970 = { #define MII_LXT971_LCR 20 /* LED Control Register */ #define MII_LXT971_TCR 30 /* Transmit Control Register */ -/* +/* * I had some nice ideas of running the MDIO faster... * The 971 should support 8MHz and I tried it, but things acted really * weird, so 2.5 MHz ought to be enough for anyone... @@ -980,14 +1018,11 @@ static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev) } static phy_info_t phy_info_lxt971 = { - 0x0001378e, + 0x0001378e, "LXT971", - - (const phy_cmd_t []) { /* config */ - /* limit to 10MBit because my protorype board - * doesn't work with 100. */ - { mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10 MBit */ + (const phy_cmd_t []) { /* config */ +// { mk_mii_write(MII_REG_ANAR, 0x021), NULL }, /* 10 Mbps, HD */ { mk_mii_read(MII_REG_CR), mii_parse_cr }, { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, { mk_mii_end, } @@ -995,12 +1030,12 @@ static phy_info_t phy_info_lxt971 = { (const phy_cmd_t []) { /* startup - enable interrupts */ { mk_mii_write(MII_LXT971_IER, 0x00f2), NULL }, { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ - + /* Somehow does the 971 tell me that the link is down * the first read after power-up. * read here to get a valid value in ack_int */ - { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_read(MII_REG_SR), mii_parse_sr }, { mk_mii_end, } }, (const phy_cmd_t []) { /* ack_int */ @@ -1008,9 +1043,9 @@ static phy_info_t phy_info_lxt971 = { { mk_mii_read(MII_REG_SR), mii_parse_sr }, { mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 }, - + /* we only need to read ISR to acknowledge */ - + { mk_mii_read(MII_LXT971_ISR), NULL }, { mk_mii_end, } }, @@ -1053,13 +1088,13 @@ static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev) } static phy_info_t phy_info_qs6612 = { - 0x00181440, + 0x00181440, "QS6612", - - (const phy_cmd_t []) { /* config */ -// { mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10 MBit */ - /* The PHY powers up isolated on the RPX, + (const phy_cmd_t []) { /* config */ +// { mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10 Mbps */ + + /* The PHY powers up isolated on the RPX, * so send a command to allow operation. */ @@ -1077,9 +1112,9 @@ static phy_info_t phy_info_qs6612 = { { mk_mii_end, } }, (const phy_cmd_t []) { /* ack_int */ - + /* we need to read ISR, SR and ANER to acknowledge */ - + { mk_mii_read(MII_QS6612_ISR), NULL }, { mk_mii_read(MII_REG_SR), mii_parse_sr }, { mk_mii_read(MII_REG_ANER), NULL }, @@ -1134,10 +1169,10 @@ static void mii_display_status(struct net_device *dev) printk("link up"); switch(*s & PHY_STAT_SPMASK) { - case PHY_STAT_100FDX: printk(", 100MBit Full Duplex"); break; - case PHY_STAT_100HDX: printk(", 100MBit Half Duplex"); break; - case PHY_STAT_10FDX: printk(", 10MBit Full Duplex"); break; - case PHY_STAT_10HDX: printk(", 10MBit Half Duplex"); break; + case PHY_STAT_100FDX: printk(", 100 Mbps Full Duplex"); break; + case PHY_STAT_100HDX: printk(", 100 Mbps Half Duplex"); break; + case PHY_STAT_10FDX: printk(", 10 Mbps Full Duplex"); break; + case PHY_STAT_10HDX: printk(", 10 Mbps Half Duplex"); break; default: printk(", Unknown speed/duplex"); } @@ -1177,7 +1212,7 @@ static void mii_display_config(struct net_device *dev) if (*s & PHY_CONF_LOOP) printk(", loopback enabled"); - + printk(".\n"); fep->sequence_done = 1; @@ -1194,7 +1229,7 @@ static void mii_relink(struct net_device *dev) if (fep->link) { duplex = 0; - if (fep->phy_status + if (fep->phy_status & (PHY_STAT_100FDX | PHY_STAT_10FDX)) duplex = 1; fec_restart(dev, duplex); @@ -1245,18 +1280,20 @@ mii_discover_phy3(uint mii_reg, struct net_device *dev) fep = dev->priv; fep->phy_id |= (mii_reg & 0xffff); - printk("fec: Phy @ 0x%x, type 0x%08x\n", fep->phy_addr, fep->phy_id); for(i = 0; phy_info[i]; i++) if(phy_info[i]->id == (fep->phy_id >> 4)) break; if(!phy_info[i]) - panic("%s: PHY id 0x%08x is not supported!\n", + panic("%s: PHY id 0x%08x is not supported!\n", dev->name, fep->phy_id); - + fep->phy = phy_info[i]; fep->phy_id_done = 1; + + printk("%s: Phy @ 0x%x, type %s (0x%08x)\n", + dev->name, fep->phy_addr, fep->phy->name, fep->phy_id); } /* Scan all of the MII PHY addresses looking for someone to respond @@ -1270,25 +1307,23 @@ mii_discover_phy(uint mii_reg, struct net_device *dev) fep = dev->priv; - if (fep->phy_addr < 32) { - if ((phytype = (mii_reg & 0xffff)) != 0xffff) { - - /* Got first part of ID, now get remainder. - */ - fep->phy_id = phytype << 16; - mii_queue(dev, mk_mii_read(MII_REG_PHYIR2), - mii_discover_phy3); - } - else { - fep->phy_addr++; + if ((phytype = (mii_reg & 0xffff)) != 0xffff) { + + /* Got first part of ID, now get remainder. + */ + fep->phy_id = phytype << 16; + mii_queue(dev, mk_mii_read(MII_REG_PHYIR2), mii_discover_phy3); + } else { + fep->phy_addr++; + if (fep->phy_addr < 32) { mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy); + } else { + printk("fec: No PHY device found.\n"); } } - else { - printk("FEC: No PHY device found.\n"); - } } +#endif /* CONFIG_USE_MDIO */ /* This interrupt occurs when the PHY detects a link change. */ @@ -1299,16 +1334,36 @@ mii_link_interrupt(void *dev_id) mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs) #endif { +#ifdef CONFIG_USE_MDIO struct net_device *dev = dev_id; struct fec_enet_private *fep = dev->priv; + volatile immap_t *immap = (immap_t *)IMAP_ADDR; + volatile fec_t *fecp = &(immap->im_cpm.cp_fec); + unsigned int ecntrl = fecp->fec_ecntrl; + + /* We need the FEC enabled to access the MII + */ + if ((ecntrl & FEC_ECNTRL_ETHER_EN) == 0) { + fecp->fec_ecntrl |= FEC_ECNTRL_ETHER_EN; + } +#endif /* CONFIG_USE_MDIO */ #if 0 disable_irq(fep->mii_irq); /* disable now, enable later */ #endif + +#ifdef CONFIG_USE_MDIO mii_do_cmd(dev, fep->phy->ack_int); mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ + if ((ecntrl & FEC_ECNTRL_ETHER_EN) == 0) { + fecp->fec_ecntrl = ecntrl; /* restore old settings */ + } +#else +printk("%s[%d] %s: unexpected Link interrupt\n", __FILE__,__LINE__,__FUNCTION__); +#endif /* CONFIG_USE_MDIO */ + } static int @@ -1320,6 +1375,7 @@ fec_enet_open(struct net_device *dev) * a simple way to do that. */ +#ifdef CONFIG_USE_MDIO fep->sequence_done = 0; fep->link = 0; @@ -1327,7 +1383,6 @@ fec_enet_open(struct net_device *dev) mii_do_cmd(dev, fep->phy->ack_int); mii_do_cmd(dev, fep->phy->config); mii_do_cmd(dev, phy_cmd_config); /* display configuration */ - while(!fep->sequence_done) schedule(); @@ -1335,8 +1390,12 @@ fec_enet_open(struct net_device *dev) netif_start_queue(dev); return 0; /* Success */ } - return -ENODEV; /* No PHY we understand */ +#else + fep->link = 1; + netif_start_queue(dev); + return 0; /* Success */ +#endif /* CONFIG_USE_MDIO */ } @@ -1377,13 +1436,13 @@ static void set_multicast_list(struct net_device *dev) ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); if (dev->flags&IFF_PROMISC) { - + /* Log any net taps. */ printk("%s: Promiscuous mode enabled.\n", dev->name); - ep->fec_r_cntrl |= 0x0008; + ep->fec_r_cntrl |= FEC_RCNTRL_PROM; } else { - ep->fec_r_cntrl &= ~0x0008; + ep->fec_r_cntrl &= ~FEC_RCNTRL_PROM; if (dev->flags & IFF_ALLMULTI) { /* Catch all multicast addresses, so set the @@ -1404,7 +1463,7 @@ static void set_multicast_list(struct net_device *dev) dmi = dev->mc_list; for (i=0; i<dev->mc_count; i++) { - + /* Only support group multicast for now. */ if (!(dmi->dmi_addr[0] & 1)) @@ -1448,7 +1507,7 @@ int __init fec_enet_init(void) volatile fec_t *fecp; bd_t *bd; extern uint _get_IMMR(void); -#ifdef CONFIG_RPXCLASSIC +#ifdef CONFIG_SCC_ENET unsigned char tmpaddr[6]; #endif @@ -1472,8 +1531,15 @@ int __init fec_enet_init(void) /* Whack a reset. We should wait for this. */ - fecp->fec_ecntrl = 1; - udelay(10); + fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET; + for (i = 0; + (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY); + ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printk ("FEC Reset timeout!\n"); + } /* Set the Ethernet address. If using multiple Enets on the 8xx, * this needs some work to get unique addresses. @@ -1481,12 +1547,13 @@ int __init fec_enet_init(void) eap = (unsigned char *)my_enet_addr; iap = bd->bi_enetaddr; -#ifdef CONFIG_RPXCLASSIC - /* The Embedded Planet boards have only one MAC address in - * the EEPROM, but can have two Ethernet ports. For the - * FEC port, we create another address by setting one of - * the address bits above something that would have (up to - * now) been allocated. +#ifdef CONFIG_SCC_ENET + /* + * If a board has Ethernet configured both on a SCC and the + * FEC, it needs (at least) 2 MAC addresses (we know that Sun + * disagrees, but anyway). For the FEC port, we create + * another address by setting one of the address bits above + * something that would have (up to now) been allocated. */ for (i=0; i<6; i++) tmpaddr[i] = *iap++; @@ -1494,8 +1561,9 @@ int __init fec_enet_init(void) iap = tmpaddr; #endif - for (i=0; i<6; i++) + for (i=0; i<6; i++) { dev->dev_addr[i] = *eap++ = *iap++; + } /* Allocate memory for buffer descriptors. */ @@ -1518,9 +1586,6 @@ int __init fec_enet_init(void) fep->rx_bd_base = cbd_base; fep->tx_bd_base = cbd_base + RX_RING_SIZE; - fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; - fep->cur_rx = fep->rx_bd_base; - fep->skb_cur = fep->skb_dirty = 0; /* Initialize the receive buffer descriptors. @@ -1565,22 +1630,27 @@ int __init fec_enet_init(void) */ if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0) panic("Could not allocate FEC IRQ!"); + #ifdef CONFIG_RPXCLASSIC /* Make Port C, bit 15 an input that causes interrupts. */ immap->im_ioport.iop_pcpar &= ~0x0001; immap->im_ioport.iop_pcdir &= ~0x0001; - immap->im_ioport.iop_pcso &= ~0x0001; - immap->im_ioport.iop_pcint |= 0x0001; + immap->im_ioport.iop_pcso &= ~0x0001; + immap->im_ioport.iop_pcint |= 0x0001; cpm_install_handler(CPMVEC_PIO_PC15, mii_link_interrupt, dev); /* Make LEDS reflect Link status. */ *((uint *) RPX_CSR_ADDR) &= ~BCSR2_FETHLEDMODE; #endif -#ifdef CONFIG_FADS - if (request_8xxirq(SIU_IRQ2, mii_link_interrupt, 0, "mii", dev) != 0) + +#ifdef PHY_INTERRUPT + if (request_8xxirq(PHY_INTERRUPT, mii_link_interrupt, 0, "mii", dev) != 0) panic("Could not allocate MII IRQ!"); + + ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |= + (0x80000000 >> PHY_INTERRUPT); #endif dev->base_addr = (unsigned long)fecp; @@ -1595,9 +1665,11 @@ int __init fec_enet_init(void) dev->get_stats = fec_enet_get_stats; dev->set_multicast_list = set_multicast_list; +#ifdef CONFIG_USE_MDIO for (i=0; i<NMII-1; i++) mii_cmds[i].mii_next = &mii_cmds[i+1]; mii_free = mii_cmds; +#endif /* CONFIG_USE_MDIO */ /* Configure all of port D for MII. */ @@ -1609,23 +1681,46 @@ int __init fec_enet_init(void) immap->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */ else immap->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */ - + +#ifdef CONFIG_USE_MDIO /* Set MII speed to 2.5 MHz */ - fecp->fec_mii_speed = fep->phy_speed = - ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e; + fecp->fec_mii_speed = fep->phy_speed = + ( + ( ((bd->bi_intfreq * 1000000) + 500000) / 2500000 / 2 ) + & 0x3F + ) << 1; +#else + fecp->fec_mii_speed = 0; /* turn off MDIO */ +#endif /* CONFIG_USE_MDIO */ + + printk ("%s: FEC ENET Version 0.2, FEC irq %d" +#ifdef PHY_INTERRUPT + ", MII irq %d" +#endif + ", addr ", + dev->name, FEC_INTERRUPT +#ifdef PHY_INTERRUPT + , PHY_INTERRUPT +#endif + ); + for (i=0; i<6; i++) + printk("%02x%c", dev->dev_addr[i], (i==5) ? '\n' : ':'); - printk("%s: FEC ENET Version 0.2, ", dev->name); - for (i=0; i<5; i++) - printk("%02x:", dev->dev_addr[i]); - printk("%02x\n", dev->dev_addr[5]); +#ifdef CONFIG_USE_MDIO /* start in full duplex mode, and negotiate speed */ + fec_restart (dev, 1); +#else /* always use half duplex mode only */ + fec_restart (dev, 0); +#endif +#ifdef CONFIG_USE_MDIO /* Queue up command to detect the PHY and initialize the * remainder of the interface. */ fep->phy_id_done = 0; fep->phy_addr = 0; mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy); +#endif /* CONFIG_USE_MDIO */ return 0; } @@ -1639,7 +1734,6 @@ fec_restart(struct net_device *dev, int duplex) { struct fec_enet_private *fep; int i; - unsigned char *eap; volatile cbd_t *bdp; volatile immap_t *immap; volatile fec_t *fecp; @@ -1652,33 +1746,25 @@ fec_restart(struct net_device *dev, int duplex) /* Whack a reset. We should wait for this. */ - fecp->fec_ecntrl = 1; - udelay(10); - - /* Enable interrupts we wish to service. - */ - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | - FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); - - /* Clear any outstanding interrupt. - */ - fecp->fec_ievent = 0xffc0; - - fecp->fec_ivec = (FEC_INTERRUPT/2) << 29; + fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET; + for (i = 0; + (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY); + ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printk ("FEC Reset timeout!\n"); + } /* Set station address. */ - fecp->fec_addr_low = (my_enet_addr[0] << 16) | my_enet_addr[1]; - fecp->fec_addr_high = my_enet_addr[2]; - - eap = (unsigned char *)&my_enet_addr[0]; - for (i=0; i<6; i++) - dev->dev_addr[i] = *eap++; + fecp->fec_addr_low = (my_enet_addr[0] << 16) | my_enet_addr[1]; + fecp->fec_addr_high = my_enet_addr[2]; /* Reset all multicast. */ fecp->fec_hash_table_high = 0; - fecp->fec_hash_table_low = 0; + fecp->fec_hash_table_low = 0; /* Set maximum receive buffer size. */ @@ -1739,12 +1825,12 @@ fec_restart(struct net_device *dev, int duplex) /* Enable MII mode. */ if (duplex) { - fecp->fec_r_cntrl = 0x04; /* MII enable */ - fecp->fec_x_cntrl = 0x04; /* FD enable */ + fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE; /* MII enable */ + fecp->fec_x_cntrl = FEC_TCNTRL_FDEN; /* FD enable */ } else { - fecp->fec_r_cntrl = 0x06; /* MII enable|No Rcv on Xmit */ - fecp->fec_x_cntrl = 0x00; + fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT; + fecp->fec_x_cntrl = 0; } fep->full_duplex = duplex; @@ -1752,13 +1838,26 @@ fec_restart(struct net_device *dev, int duplex) */ fecp->fec_fun_code = 0x78000000; +#ifdef CONFIG_USE_MDIO /* Set MII speed. */ fecp->fec_mii_speed = fep->phy_speed; +#endif /* CONFIG_USE_MDIO */ + + /* Clear any outstanding interrupt. + */ + fecp->fec_ievent = 0xffc0; + + fecp->fec_ivec = (FEC_INTERRUPT/2) << 29; + + /* Enable interrupts we wish to service. + */ + fecp->fec_imask = ( FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII ); /* And last, enable the transmit and receive processing. */ - fecp->fec_ecntrl = 6; + fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN; fecp->fec_r_des_active = 0x01000000; } @@ -1768,33 +1867,45 @@ fec_stop(struct net_device *dev) volatile immap_t *immap; volatile fec_t *fecp; struct fec_enet_private *fep; + int i; immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */ - + fecp = &(immap->im_cpm.cp_fec); - + + if ((fecp->fec_ecntrl & FEC_ECNTRL_ETHER_EN) == 0) + return; /* already down */ + fep = dev->priv; fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ - while(!(fecp->fec_ievent & 0x10000000)); - - /* Whack a reset. We should wait for this. - */ - fecp->fec_ecntrl = 1; - udelay(10); + for (i = 0; + ((fecp->fec_ievent & 0x10000000) == 0) && (i < FEC_RESET_DELAY); + ++i) { + udelay(1); + } + if (i == FEC_RESET_DELAY) { + printk ("FEC timeout on graceful transmit stop\n"); + } /* Clear outstanding MII command interrupts. */ fecp->fec_ievent = FEC_ENET_MII; - /* Enable MII command finihed interrupt + /* Enable MII command finished interrupt */ fecp->fec_ivec = (FEC_INTERRUPT/2) << 29; fecp->fec_imask = FEC_ENET_MII; +#ifdef CONFIG_USE_MDIO /* Set MII speed. */ fecp->fec_mii_speed = fep->phy_speed; +#endif /* CONFIG_USE_MDIO */ + + /* Disable FEC + */ + fecp->fec_ecntrl &= ~(FEC_ECNTRL_ETHER_EN); } diff --git a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c index 4688d57a8..1f426ae10 100644 --- a/arch/ppc/8xx_io/uart.c +++ b/arch/ppc/8xx_io/uart.c @@ -53,10 +53,22 @@ extern int kgdb_output_string (const char* s, unsigned int count); /* this defines the index into rs_table for the port to use */ -#ifndef CONFIG_SERIAL_CONSOLE_PORT -#define CONFIG_SERIAL_CONSOLE_PORT 0 -#endif -#endif +# ifndef CONFIG_SERIAL_CONSOLE_PORT +# ifdef CONFIG_SCC3_ENET +# ifdef CONFIG_8xx_CONS_SMC2 +# define CONFIG_SERIAL_CONSOLE_PORT 0 /* Console on SMC2 is 1st port */ +# else +# error "Can't use SMC1 for console with Ethernet on SCC3" +# endif +# else /* ! CONFIG_SCC3_ENET */ +# ifdef CONFIG_8xx_CONS_SMC2 /* Console on SMC2 */ +# define CONFIG_SERIAL_CONSOLE_PORT 1 +# else /* Console on SMC1 */ +# define CONFIG_SERIAL_CONSOLE_PORT 0 +# endif /* CONFIG_8xx_CONS_SMC2 */ +# endif /* CONFIG_SCC3_ENET */ +# endif /* CONFIG_SERIAL_CONSOLE_PORT */ +#endif /* CONFIG_SERIAL_CONSOLE */ #if 0 /* SCC2 for console @@ -118,14 +130,22 @@ static int serial_console_setup(struct console *co, char *options); */ static struct serial_state rs_table[] = { /* UART CLK PORT IRQ FLAGS NUM */ - { 0, 0, PROFF_SMC1, CPMVEC_SMC1, 0, 0 }, /* SMC1 ttyS0 */ -#ifdef CONFIG_8xxSMC2 - { 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, 1 }, /* SMC2 ttyS1 */ -#endif -#ifdef CONFIG_8xxSCC - { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, (NUM_IS_SCC | 1) }, /* SCC2 ttyS2 */ - { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */ -#endif +#ifndef CONFIG_SCC3_ENET /* SMC1 not usable with Ethernet on SCC3 */ + { 0, 0, PROFF_SMC1, CPMVEC_SMC1, 0, 0 }, /* SMC1 ttyS0 */ +#endif +#if !defined(CONFIG_USB_MPC8xx) && !defined(CONFIG_USB_CLIENT_MPC8xx) +# ifdef CONFIG_8xxSMC2 + { 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, 1 }, /* SMC2 ttyS1 */ +# endif +# ifdef CONFIG_8xxSCC + { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, (NUM_IS_SCC | 1) }, /* SCC2 ttyS2 */ + { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */ +# endif + #else /* CONFIG_USB_xxx */ +# ifdef CONFIG_8xxSCC + { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */ +# endif +#endif /* CONFIG_USB_xxx */ }; #define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) @@ -2733,10 +2753,10 @@ int __init rs_8xx_init(void) cp->cp_pbdir &= ~iobits; cp->cp_pbodr &= ~iobits; #else + iobits = 0xc0; if (idx == 0) { /* SMC1 on Port B, like all 8xx. */ - iobits = 0xc0; cp->cp_pbpar |= iobits; cp->cp_pbdir &= ~iobits; cp->cp_pbodr &= ~iobits; @@ -2744,7 +2764,6 @@ int __init rs_8xx_init(void) else { /* SMC2 is on Port A. */ - iobits = 0x300; immap->im_ioport.iop_papar |= iobits; immap->im_ioport.iop_padir &= ~iobits; immap->im_ioport.iop_paodr &= ~iobits; @@ -2836,6 +2855,9 @@ static int __init serial_console_setup(struct console *co, char *options) for (bidx = 0; bidx < (sizeof(baud_table) / sizeof(int)); bidx++) if (bd->bi_baudrate == baud_table[bidx]) break; + /* make sure we have a useful value */ + if (bidx == (sizeof(baud_table) / sizeof(int))) + bidx = 13; /* B9600 */ co->cflag = CREAD|CLOCAL|bidx|CS8; baud_idx = bidx; @@ -2958,7 +2980,7 @@ static int __init serial_console_setup(struct console *co, char *options) */ chan = smc_chan_map[idx]; cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG; - printk(""); + printk("%s", ""); while (cp->cp_cpcr & CPM_CR_FLG); /* Set UART mode, 8 bit, no parity, one stop. diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 3b4c2c141..2d07ee819 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -57,14 +57,25 @@ if [ "$CONFIG_8xx" = "y" ]; then "RPX-Lite CONFIG_RPXLITE \ RPX-Classic CONFIG_RPXCLASSIC \ BSE-IP CONFIG_BSEIP \ - TQM8xxL CONFIG_TQM8xxL \ - TQM860L CONFIG_TQM860L \ - TQM860 CONFIG_TQM860 \ + TQM823L CONFIG_TQM823L \ + TQM850L CONFIG_TQM850L \ + TQM855L CONFIG_TQM855L \ + TQM860L CONFIG_TQM860L \ + FPS850L CONFIG_FPS850L \ + TQM860 CONFIG_TQM860 \ + SPD823TS CONFIG_SPD823TS \ + IVMS8 CONFIG_IVMS8 \ + SM850 CONFIG_SM850 \ MBX CONFIG_MBX \ WinCept CONFIG_WINCEPT" RPX-Lite - - if [ "$CONFIG_TQM8xxL" = "y" ]; then - bool 'FPS850 Mainboard' CONFIG_FPS850 + + if [ "$CONFIG_TQM823L" = "y" -o \ + "$CONFIG_TQM850L" = "y" -o \ + "$CONFIG_FPS850L" = "y" -o \ + "$CONFIG_TQM855L" = "y" -o \ + "$CONFIG_TQM860L" = "y" -o \ + "$CONFIG_SM850" = "y" ]; then + define_bool CONFIG_TQM8xxL y fi fi @@ -299,6 +310,11 @@ if [ "$CONFIG_ALL_PPC" = "y" ]; then bool ' Support for ADB keyboard (old driver)' CONFIG_ADB_KEYBOARD fi fi + # This is for drivers/macintosh/mac_hid.o, which is needed if the input + # layer is used. + if [ "$CONFIG_INPUT" != "n" ]; then + define_bool CONFIG_MAC_HID y + fi fi endmenu diff --git a/arch/ppc/configs/IVMS8_defconfig b/arch/ppc/configs/IVMS8_defconfig new file mode 100644 index 000000000..f73b69efc --- /dev/null +++ b/arch/ppc/configs/IVMS8_defconfig @@ -0,0 +1,452 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +# CONFIG_6xx is not set +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8260 is not set +CONFIG_8xx=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_TQM860 is not set +# CONFIG_SPD823TS is not set +CONFIG_IVMS8=y +# CONFIG_SM850 is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +CONFIG_MACH_SPECIFIC=y +CONFIG_MATH_EMULATION=y +CONFIG_SASH=y +CONFIG_SASH_PATH="/bin/sash" + +# +# General setup +# +# CONFIG_ISA is not set +# CONFIG_SBUS is not set +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_MPC8xx_IDE=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_FLASH is not set + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_DRM is not set +# CONFIG_AGP is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC8xx CPM Options +# +# CONFIG_SCC_ENET is not set +CONFIG_FEC_ENET=y +CONFIG_USE_MDIO=y +CONFIG_ENET_BIG_BUFFERS=y +# CONFIG_8xxSMC2 is not set +# CONFIG_8xxSCC is not set + +# +# Generic MPC8xx Options +# +CONFIG_8xx_COPYBACK=y +# CONFIG_8xx_CPU6 is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff --git a/arch/ppc/configs/SM850_defconfig b/arch/ppc/configs/SM850_defconfig new file mode 100644 index 000000000..bab9ddd55 --- /dev/null +++ b/arch/ppc/configs/SM850_defconfig @@ -0,0 +1,420 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +# CONFIG_6xx is not set +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8260 is not set +CONFIG_8xx=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_TQM860 is not set +# CONFIG_SPD823TS is not set +CONFIG_SM850=y +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +CONFIG_TQM8xxL=y +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +CONFIG_MACH_SPECIFIC=y +CONFIG_MATH_EMULATION=y +CONFIG_SASH=y +CONFIG_SASH_PATH="/bin/sash" + +# +# General setup +# +# CONFIG_ISA is not set +# CONFIG_SBUS is not set +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_FLASH=y +CONFIG_AMD_FLASH=y + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_DRM is not set +# CONFIG_AGP is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_EXT2_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +# CONFIG_SCC1_ENET is not set +# CONFIG_SCC2_ENET is not set +CONFIG_SCC3_ENET=y +# CONFIG_FEC_ENET is not set +CONFIG_ENET_BIG_BUFFERS=y +CONFIG_8xxSMC2=y +CONFIG_8xx_ALTSMC2=y +CONFIG_8xx_CONS_SMC2=y +# CONFIG_8xxSCC is not set + +# +# Generic MPC8xx Options +# +CONFIG_8xx_COPYBACK=y +CONFIG_8xx_CPU6=y + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff --git a/arch/ppc/configs/SPD823TS_defconfig b/arch/ppc/configs/SPD823TS_defconfig new file mode 100644 index 000000000..899b29436 --- /dev/null +++ b/arch/ppc/configs/SPD823TS_defconfig @@ -0,0 +1,416 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +# CONFIG_6xx is not set +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8260 is not set +CONFIG_8xx=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_TQM860 is not set +CONFIG_SPD823TS=y +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +CONFIG_MACH_SPECIFIC=y +CONFIG_MATH_EMULATION=y +CONFIG_SASH=y +CONFIG_SASH_PATH="/bin/sash" + +# +# General setup +# +# CONFIG_ISA is not set +# CONFIG_SBUS is not set +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_FLASH is not set + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_DRM is not set +# CONFIG_AGP is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_EXT2_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +# CONFIG_SCC1_ENET is not set +CONFIG_SCC2_ENET=y +# CONFIG_FEC_ENET is not set +CONFIG_ENET_BIG_BUFFERS=y +CONFIG_8xxSMC2=y +CONFIG_8xx_ALTSMC2=y +# CONFIG_8xx_CONS_SMC2 is not set +# CONFIG_8xxSCC is not set + +# +# Generic MPC8xx Options +# +CONFIG_8xx_COPYBACK=y +# CONFIG_8xx_CPU6 is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff --git a/arch/ppc/configs/TQM823L_defconfig b/arch/ppc/configs/TQM823L_defconfig new file mode 100644 index 000000000..9724fd901 --- /dev/null +++ b/arch/ppc/configs/TQM823L_defconfig @@ -0,0 +1,419 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +# CONFIG_6xx is not set +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8260 is not set +CONFIG_8xx=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +CONFIG_TQM823L=y +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_TQM860 is not set +# CONFIG_SPD823TS is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +CONFIG_TQM8xxL=y +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +CONFIG_MACH_SPECIFIC=y +CONFIG_MATH_EMULATION=y +CONFIG_SASH=y +CONFIG_SASH_PATH="/bin/sash" + +# +# General setup +# +# CONFIG_ISA is not set +# CONFIG_SBUS is not set +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_FLASH=y +CONFIG_AMD_FLASH=y + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_DRM is not set +# CONFIG_AGP is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_EXT2_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +# CONFIG_SCC1_ENET is not set +CONFIG_SCC2_ENET=y +# CONFIG_SCC3_ENET is not set +# CONFIG_FEC_ENET is not set +CONFIG_ENET_BIG_BUFFERS=y +CONFIG_8xxSMC2=y +CONFIG_8xx_ALTSMC2=y +# CONFIG_8xx_CONS_SMC2 is not set +# CONFIG_8xxSCC is not set + +# +# Generic MPC8xx Options +# +CONFIG_8xx_COPYBACK=y +# CONFIG_8xx_CPU6 is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff --git a/arch/ppc/configs/TQM850L_defconfig b/arch/ppc/configs/TQM850L_defconfig new file mode 100644 index 000000000..eb1e130ad --- /dev/null +++ b/arch/ppc/configs/TQM850L_defconfig @@ -0,0 +1,419 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +# CONFIG_6xx is not set +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8260 is not set +CONFIG_8xx=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_TQM823L is not set +CONFIG_TQM850L=y +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_TQM860 is not set +# CONFIG_SPD823TS is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +CONFIG_TQM8xxL=y +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +CONFIG_MACH_SPECIFIC=y +CONFIG_MATH_EMULATION=y +CONFIG_SASH=y +CONFIG_SASH_PATH="/bin/sash" + +# +# General setup +# +# CONFIG_ISA is not set +# CONFIG_SBUS is not set +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_FLASH=y +CONFIG_AMD_FLASH=y + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_DRM is not set +# CONFIG_AGP is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_EXT2_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +# CONFIG_SCC1_ENET is not set +CONFIG_SCC2_ENET=y +# CONFIG_SCC3_ENET is not set +# CONFIG_FEC_ENET is not set +CONFIG_ENET_BIG_BUFFERS=y +CONFIG_8xxSMC2=y +CONFIG_8xx_ALTSMC2=y +# CONFIG_8xx_CONS_SMC2 is not set +# CONFIG_8xxSCC is not set + +# +# Generic MPC8xx Options +# +CONFIG_8xx_COPYBACK=y +CONFIG_8xx_CPU6=y + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff --git a/arch/ppc/configs/TQM860L_defconfig b/arch/ppc/configs/TQM860L_defconfig new file mode 100644 index 000000000..ebe47c109 --- /dev/null +++ b/arch/ppc/configs/TQM860L_defconfig @@ -0,0 +1,419 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +# CONFIG_6xx is not set +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8260 is not set +CONFIG_8xx=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +CONFIG_TQM860L=y +# CONFIG_FPS850L is not set +# CONFIG_TQM860 is not set +# CONFIG_SPD823TS is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +CONFIG_TQM8xxL=y +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +CONFIG_MACH_SPECIFIC=y +CONFIG_MATH_EMULATION=y +CONFIG_SASH=y +CONFIG_SASH_PATH="/bin/sash" + +# +# General setup +# +# CONFIG_ISA is not set +# CONFIG_SBUS is not set +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_FLASH=y +CONFIG_AMD_FLASH=y + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_DRM is not set +# CONFIG_AGP is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_EXT2_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +CONFIG_SCC1_ENET=y +# CONFIG_SCC2_ENET is not set +# CONFIG_SCC3_ENET is not set +# CONFIG_FEC_ENET is not set +CONFIG_ENET_BIG_BUFFERS=y +CONFIG_8xxSMC2=y +# CONFIG_8xx_ALTSMC2 is not set +# CONFIG_8xx_CONS_SMC2 is not set +# CONFIG_8xxSCC is not set + +# +# Generic MPC8xx Options +# +CONFIG_8xx_COPYBACK=y +# CONFIG_8xx_CPU6 is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig index 210887de7..6017c8a1c 100644 --- a/arch/ppc/configs/common_defconfig +++ b/arch/ppc/configs/common_defconfig @@ -295,11 +295,11 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_AHA152X is not set # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set -CONFIG_SCSI_AIC7XXX=y -# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set -CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 -CONFIG_AIC7XXX_PROC_STATS=y -CONFIG_AIC7XXX_RESET_DELAY=15 +CONFIG_SCSI_AIC7XXX=m +CONFIG_SCSI_AIC7XXX_OLD=m +# CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT is not set +CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_OLD_PROC_STATS=y # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index 210887de7..d0c66555e 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -296,10 +296,9 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set CONFIG_SCSI_AIC7XXX=y -# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set -CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 -CONFIG_AIC7XXX_PROC_STATS=y -CONFIG_AIC7XXX_RESET_DELAY=15 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 +CONFIG_AIC7XXX_RESET_DELAY=15000 +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 545fce0cd..c9bc4e23f 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o include $(TOPDIR)/Rules.make +entry.o: entry.S ppc_defs.h head.o: head.S ppc_defs.h head_4xx.o: head_4xx.S ppc_defs.h head_8xx.o: head_8xx.S ppc_defs.h diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c index 914ed02ff..684b1889a 100644 --- a/arch/ppc/kernel/chrp_pci.c +++ b/arch/ppc/kernel/chrp_pci.c @@ -298,8 +298,9 @@ static void __init gg2_pcibios_fixup_bus(struct pci_bus *bus) bus->resource[1] = &gg2_resources.pci_mem; } -static void process_bridge_ranges(struct pci_controller *hose, - struct device_node *dev, int index) +/* this is used by the pmac_pci code too... - paulus */ +void process_bridge_ranges(struct pci_controller *hose, + struct device_node *dev, int primary) { unsigned int *ranges; int rlen = 0; @@ -316,31 +317,34 @@ static void process_bridge_ranges(struct pci_controller *hose, break; hose->io_base_phys = ranges[3]; hose->io_base_virt = ioremap(ranges[3], ranges[5]); - if (index == 0) { + if (primary) isa_io_base = (unsigned long) hose->io_base_virt; - printk("isa_io_base=%lx\n", isa_io_base); - } res = &hose->io_resource; res->flags = IORESOURCE_IO; + res->start = ranges[2]; break; case 2: /* memory space */ - if (index == 0 && ranges[1] == 0 && ranges[2] == 0){ - isa_mem_base = ranges[3]; - printk("isa_mem_base=%lx\n", isa_mem_base); + memno = 0; + if (ranges[1] == 0 && ranges[2] == 0 + && ranges[5] <= (16 << 20)) { + /* 1st 16MB, i.e. ISA memory area */ + if (primary) + isa_mem_base = ranges[3]; + memno = 1; } - if (memno == 0) { + while (memno < 3 && hose->mem_resources[memno].flags) + ++memno; + if (memno == 0) hose->pci_mem_offset = ranges[3] - ranges[2]; - printk("pci_mem_offset=%lx for this bridge\n", - hose->pci_mem_offset); + if (memno < 3) { + res = &hose->mem_resources[memno]; + res->flags = IORESOURCE_MEM; + res->start = ranges[3]; } - res = &hose->mem_resources[memno]; - res->flags = IORESOURCE_MEM; - ++memno; break; } if (res != NULL) { res->name = dev->full_name; - res->start = ranges[3]; res->end = res->start + ranges[5] - 1; res->parent = NULL; res->sibling = NULL; @@ -401,7 +405,7 @@ ibm_add_bridges(struct device_node *dev) hose->cfg_addr = (volatile unsigned int *) cfg; hose->cfg_data = cfg + 0x10; - process_bridge_ranges(hose, dev, index); + process_bridge_ranges(hose, dev, index == 0); #ifdef CONFIG_POWER3 openpic_setup_ISU(index, opprop[index+1]); diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c index 04b812268..b7136d001 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/kernel/chrp_setup.c @@ -84,7 +84,7 @@ extern void mackbd_leds(unsigned char leds); extern void mackbd_init_hw(void); extern unsigned char mackbd_sysrq_xlate[128]; -kdev_t boot_dev; +extern kdev_t boot_dev; extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; @@ -237,7 +237,6 @@ static void __init sio_init(void) void __init chrp_setup_arch(void) { - extern char cmd_line[]; struct device_node *device; /* init to some ~sane value until calibrate_delay() runs */ @@ -252,7 +251,6 @@ chrp_setup_arch(void) else #endif ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */ - printk("Boot arguments: %s\n", cmd_line); /* Lookup PCI host bridges */ chrp_find_bridges(); diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index f296d1606..89f5b6d68 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -1135,7 +1135,7 @@ copy_and_flush: #ifdef CONFIG_APUS /* * On APUS the physical base address of the kernel is not known at compile - * time, which means the __pa/__va constants used are incorect. In the + * time, which means the __pa/__va constants used are incorrect. In the * __init section is recorded the virtual addresses of instructions using * these constants, so all that has to be done is fix these before * continuing the kernel boot. diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S index 40579ce63..3bdf141e8 100644 --- a/arch/ppc/kernel/head_8xx.S +++ b/arch/ppc/kernel/head_8xx.S @@ -968,26 +968,6 @@ _GLOBAL(set_context) SYNC blr -/* Jump into the system reset for the rom. - * We first disable the MMU, and then jump to the ROM reset address. - * - * r3 is the board info structure, r4 is the location for starting. - * I use this for building a small kernel that can load other kernels, - * rather than trying to write or rely on a rom monitor that can tftp load. - */ - .globl m8xx_gorom -m8xx_gorom: - li r5,MSR_KERNEL & ~(MSR_IR|MSR_DR) - lis r6,2f@h - addis r6,r6,-KERNELBASE@h - ori r6,r6,2f@l - mtspr SRR0,r6 - mtspr SRR1,r5 - rfi -2: - mtlr r4 - blr - #ifdef CONFIG_8xx_CPU6 /* It's here because it is unique to the 8xx. * It is important we get called with interrupts disabled. I used to diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index 279bccf0a..6609ecda2 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -7,8 +7,8 @@ * Copyright (C) 1992 Linus Torvalds * Adapted from arch/i386 by Gary Thomas * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * Updated and modified by Cort Dougan (cort@cs.nmt.edu) - * Copyright (C) 1996 Cort Dougan + * Updated and modified by Cort Dougan <cort@fsmlabs.com> + * Copyright (C) 1996-2001 Cort Dougan * Adapted for Power Macintosh by Paul Mackerras * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). @@ -258,7 +258,10 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) retval = setup_irq(irq, action); if (retval) + { kfree(action); + return retval; + } return 0; } @@ -464,13 +467,11 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) ppc_spurious_interrupts++; printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq); /* We can't call disable_irq here, it would deadlock */ - if (!desc->depth) - desc->depth = 1; + ++desc->depth; desc->status |= IRQ_DISABLED; - /* This is not a real spurrious interrupt, we - * have to eoi it, so we jump to out - */ mask_irq(irq); + /* This is a real interrupt, we have to eoi it, + so we jump to out */ goto out; } status &= ~IRQ_PENDING; /* we commit to handling */ diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c index 91114e459..4185e5b44 100644 --- a/arch/ppc/kernel/m8260_setup.c +++ b/arch/ppc/kernel/m8260_setup.c @@ -85,10 +85,6 @@ void __init adbdev_init(void) void __init m8260_setup_arch(void) { - extern char cmd_line[]; - - printk("Boot arguments: %s\n", cmd_line); - /* Reset the Communication Processor Module. */ m8260_cpm_reset(); diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c index fb585641c..1d3260d78 100644 --- a/arch/ppc/kernel/m8xx_setup.c +++ b/arch/ppc/kernel/m8xx_setup.c @@ -32,6 +32,7 @@ #include <linux/init.h> #include <linux/blk.h> #include <linux/ioport.h> +#include <asm/mpc8xx.h> /* Before ide.h to avoid warning: `MAX_HWIFS' redefined */ #include <linux/ide.h> #include <linux/bootmem.h> @@ -41,7 +42,6 @@ #include <asm/io.h> #include <asm/pgtable.h> #include <asm/ide.h> -#include <asm/mpc8xx.h> #include <asm/8xx_immap.h> #include <asm/machdep.h> @@ -52,19 +52,65 @@ static int m8xx_set_rtc_time(unsigned long time); unsigned long m8xx_get_rtc_time(void); void m8xx_calibrate_decr(void); -#if 0 -extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode); -extern int mackbd_getkeycode(unsigned int scancode); -extern int mackbd_pretranslate(unsigned char scancode, char raw_mode); -extern int mackbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode); -extern char mackbd_unexpected_up(unsigned char keycode); -extern void mackbd_leds(unsigned char leds); -extern void mackbd_init_hw(void); -#endif - unsigned char __res[sizeof(bd_t)]; unsigned long empty_zero_page[1024]; +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + +#ifdef CONFIG_BLK_DEV_MPC8xx_IDE +#include "../../../drivers/ide/ide_modes.h" + +static void m8xx_ide_tuneproc(ide_drive_t *drive, byte pio); + +typedef struct ide_ioport_desc { + unsigned long base_off; /* Offset to PCMCIA memory */ + ide_ioreg_t reg_off[IDE_NR_PORTS]; /* controller reg. offsets */ + int irq; /* IRQ */ +} ide_ioport_desc_t; + +ide_ioport_desc_t ioport_dsc[MAX_HWIFS] = { +#ifdef IDE0_BASE_OFFSET + { IDE0_BASE_OFFSET, + { + IDE0_DATA_REG_OFFSET, + IDE0_ERROR_REG_OFFSET, + IDE0_NSECTOR_REG_OFFSET, + IDE0_SECTOR_REG_OFFSET, + IDE0_LCYL_REG_OFFSET, + IDE0_HCYL_REG_OFFSET, + IDE0_SELECT_REG_OFFSET, + IDE0_STATUS_REG_OFFSET, + IDE0_CONTROL_REG_OFFSET, + IDE0_IRQ_REG_OFFSET, + }, + IDE0_INTERRUPT, + }, +# ifdef IDE1_BASE_OFFSET + { IDE1_BASE_OFFSET, + { + IDE1_DATA_REG_OFFSET, + IDE1_ERROR_REG_OFFSET, + IDE1_NSECTOR_REG_OFFSET, + IDE1_SECTOR_REG_OFFSET, + IDE1_LCYL_REG_OFFSET, + IDE1_HCYL_REG_OFFSET, + IDE1_SELECT_REG_OFFSET, + IDE1_STATUS_REG_OFFSET, + IDE1_CONTROL_REG_OFFSET, + IDE1_IRQ_REG_OFFSET, + }, + IDE1_INTERRUPT, + }, +# endif /* IDE1_BASE_OFFSET */ +#endif /* IDE0_BASE_OFFSET */ +}; + +ide_pio_timings_t ide_pio_clocks[6]; + +/* Make clock cycles and always round up */ +#define PCMCIA_MK_CLKS( t, T ) (( (t) * (T) + 999U ) / 1000U ) + +#endif /* CONFIG_BLK_DEV_MPC8xx_IDE */ +#endif /* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */ #ifdef CONFIG_BLK_DEV_RAM extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ @@ -77,6 +123,8 @@ extern char saved_command_line[256]; extern unsigned long find_available_memory(void); extern void m8xx_cpm_reset(uint); +static void ide_interrupt_handler(void* dev_id); + void __init adbdev_init(void) { } @@ -85,12 +133,9 @@ void __init m8xx_setup_arch(void) { int cpm_page; - extern char cmd_line[]; cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE); - printk("Boot arguments: %s\n", cmd_line); - /* Reset the Communication Processor Module. */ m8xx_cpm_reset(cpm_page); @@ -137,7 +182,7 @@ abort(void) */ void timebase_interrupt(int irq, void * dev, struct pt_regs * regs) { - printk("timebase_interrupt()\n"); + printk ("timebase_interrupt()\n"); } /* The decrementer counts at the system (internal) clock frequency divided by @@ -164,7 +209,7 @@ void __init m8xx_calibrate_decr(void) fp = (binfo->bi_intfreq * 1000000) / 16; freq = fp*60; /* try to make freq/1e6 an integer */ divisor = 60; - printk("time_init: decrementer frequency = %d/%d\n", freq, divisor); + printk("Decrementer Frequency = %d/%d\n", freq, divisor); tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); @@ -232,9 +277,21 @@ m8xx_get_rtc_time(void) void m8xx_restart(char *cmd) { - extern void m8xx_gorom(void); + __volatile__ unsigned char dummy; + uint msr; - m8xx_gorom(); + cli(); + ((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr |= 0x00000080; + + /* Clear the ME bit in MSR to cause checkstop on machine check + */ + __asm__("mfmsr %0" : "=r" (msr) ); + msr &= ~0x1000; + __asm__("mtmsr %0" : : "r" (msr) ); + + dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0]; + printk("Restart failed\n"); + while(1); } void @@ -257,8 +314,8 @@ int m8xx_setup_residual(char *buffer) bp = (bd_t *)__res; - len += sprintf(len+buffer,"clock\t\t: %dMHz\n" - "bus clock\t: %dMHz\n", + len += sprintf(len+buffer,"clock\t\t: %ldMHz\n" + "bus clock\t: %ldMHz\n", bp->bi_intfreq /*/ 1000000*/, bp->bi_busfreq /*/ 1000000*/); @@ -298,17 +355,13 @@ m8xx_init_IRQ(void) #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) -/* Define this to make a PCMCIA ATA Flash card work. -*/ -#define ATA_FLASH 1 - /* * IDE stuff. */ void m8xx_ide_insw(ide_ioreg_t port, void *buf, int ns) { -#ifdef ATA_FLASH +#ifdef CONFIG_BLK_DEV_MPC8xx_IDE ide_insw(port, buf, ns); #else ide_insw(port+_IO_BASE, buf, ns); @@ -318,7 +371,7 @@ m8xx_ide_insw(ide_ioreg_t port, void *buf, int ns) void m8xx_ide_outsw(ide_ioreg_t port, void *buf, int ns) { -#ifdef ATA_FLASH +#ifdef CONFIG_BLK_DEV_MPC8xx_IDE ide_outsw(port, buf, ns); #else ide_outsw(port+_IO_BASE, buf, ns); @@ -328,8 +381,11 @@ m8xx_ide_outsw(ide_ioreg_t port, void *buf, int ns) int m8xx_ide_default_irq(ide_ioreg_t base) { -#ifdef ATA_FLASH - return PCMCIA_INTERRUPT; +#ifdef CONFIG_BLK_DEV_MPC8xx_IDE + if (base >= MAX_HWIFS) + return 0; + + return (ioport_dsc[base].irq); #else return 14; #endif @@ -348,60 +404,105 @@ m8xx_ide_request_irq(unsigned int irq, const char *device, void *dev_id) { -#ifdef ATA_FLASH +#ifdef CONFIG_BLK_DEV_MPC8xx_IDE return request_8xxirq(irq, handler, flags, device, dev_id); #else return request_irq(irq, handler, flags, device, dev_id); #endif } -/* We can use an external IDE controller or wire the IDE interface to - * the internal PCMCIA controller. +/* We can use an external IDE controller + * or wire the IDE interface to the internal PCMCIA controller. + * + * See include/linux/ide.h for definition of hw_regs_t (p, base) */ -void __init m8xx_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq) +void m8xx_ide_init_hwif_ports(hw_regs_t *hw, + ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) { - ide_ioreg_t port = base; + ide_ioreg_t *p = hw->io_ports; int i; -#ifdef ATA_FLASH +#ifdef CONFIG_BLK_DEV_MPC8xx_IDE volatile pcmconf8xx_t *pcmp; + + static unsigned long pcmcia_base = 0; +#else + ide_ioreg_t port = data_port; /* ??? XXX ??? XXX */ #endif + unsigned long base; -#ifdef ATA_FLASH +#ifdef CONFIG_BLK_DEV_MPC8xx_IDE *p = 0; - *irq = 0; + if (irq) + *irq = 0; + + pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia)); - if (base != 0) /* Only map the first ATA flash drive */ + if (!pcmcia_base) { + /* relies PCMCIA registers being set up by firmware */ + pcmcia_base = (unsigned long) ioremap(PCMCIA_MEM_ADDR, + PCMCIA_MEM_SIZE); + + /* Compute clock cycles for PIO timings */ + for (i=0; i<6; ++i) { + bd_t *binfo = (bd_t *)__res; + + ide_pio_clocks[i].hold_time = + PCMCIA_MK_CLKS (ide_pio_timings[i].hold_time, + binfo->bi_busfreq); + ide_pio_clocks[i].setup_time = + PCMCIA_MK_CLKS (ide_pio_timings[i].setup_time, + binfo->bi_busfreq); + ide_pio_clocks[i].active_time = + PCMCIA_MK_CLKS (ide_pio_timings[i].active_time, + binfo->bi_busfreq); + ide_pio_clocks[i].cycle_time = + PCMCIA_MK_CLKS (ide_pio_timings[i].cycle_time, + binfo->bi_busfreq); +#if 0 + printk ("PIO mode %d timings: %d/%d/%d => %d/%d/%d\n", + i, + ide_pio_clocks[i].setup_time, + ide_pio_clocks[i].active_time, + ide_pio_clocks[i].hold_time, + ide_pio_clocks[i].cycle_time, + ide_pio_timings[i].setup_time, + ide_pio_timings[i].active_time, + ide_pio_timings[i].hold_time, + ide_pio_timings[i].cycle_time); +#endif + } + } + + if (data_port >= MAX_HWIFS) return; - pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia)); + base = pcmcia_base + ioport_dsc[data_port].base_off; + +# if (!defined(CONFIG_SPD823TS) && !defined(CONFIG_IVMS8)) + /* SPD823TS and IVMS8 have a direct connection */ if (pcmp->pcmc_pipr & 0x18000000) return; /* No card in slot */ +# endif /* CONFIG_SPD823TS, CONFIG_IVMS8 */ - base = (unsigned long) ioremap(PCMCIA_MEM_ADDR, 0x200); + for (i = 0; i < IDE_NR_PORTS; ++i) { + *p++ = base + ioport_dsc[data_port].reg_off[i]; + } - /* For the M-Systems ATA card, the first 8 registers map 1:1. - * The following register, control/Altstatus, is located at 0x0e. - * Following that, the irq offset, is not used, so we place it in - * an unused location, 0x0a. - */ - *p++ = base + 8; - for (i = 1; i < 8; ++i) - *p++ = base + i; - *p++ = base + 0x0e; /* control/altstatus */ - *p = base + 0x0a; /* IRQ, not used */ - if (irq) - *irq = PCMCIA_INTERRUPT; + if (irq) { + *irq = ioport_dsc[data_port].irq; + } - /* Configure the interface for this interrupt. - */ - pcmp->pcmc_pgcra = (mk_int_int_mask(PCMCIA_INTERRUPT) << 24) | - (mk_int_int_mask(PCMCIA_INTERRUPT) << 16); + /* register routine to tune PIO mode */ + ide_hwifs[data_port].tuneproc = m8xx_ide_tuneproc; - /* Enable status change interrupt from slot A. - */ - pcmp->pcmc_per = 0xff100000; - pcmp->pcmc_pscr = ~0; -#else + /* Enable Harddisk Interrupt, + * and make it edge sensitive + */ + hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_handler; + ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |= + (0x80000000 >> ioport_dsc[data_port].irq); + +#else /* ! CONFIG_BLK_DEV_MPC8xx_IDE */ /* Just a regular IDE drive on some I/O port. */ @@ -411,10 +512,84 @@ void __init m8xx_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq) *p++ = base + 0x206; if (irq != NULL) *irq = 0; -#endif +#endif /* CONFIG_BLK_DEV_MPC8xx_IDE */ } +#endif /* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */ + + +/* -------------------------------------------------------------------- */ + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +#ifdef CONFIG_BLK_DEV_MPC8xx_IDE + +/* PCMCIA Timing */ +#ifndef PCMCIA_SHT +#define PCMCIA_SHT(t) ((t & 0x0F)<<16) /* Strobe Hold Time */ +#define PCMCIA_SST(t) ((t & 0x0F)<<12) /* Strobe Setup Time */ +#define PCMCIA_SL(t) ((t==32) ? 0 : ((t & 0x1F)<<7)) /* Strobe Length */ #endif + +/* Calculate PIO timings */ +static void +m8xx_ide_tuneproc(ide_drive_t *drive, byte pio) +{ + volatile pcmconf8xx_t *pcmp; + ide_pio_data_t d; + ulong timing, mask, reg; + + pio = ide_get_best_pio_mode(drive, pio, 4, &d); + +#if 1 + printk("%s[%d] %s: best PIO mode: %d\n", + __FILE__,__LINE__,__FUNCTION__, pio); +#endif + pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia)); + + mask = ~(PCMCIA_SHT(0xFF) | PCMCIA_SST(0xFF) | PCMCIA_SL(0xFF)); + + timing = PCMCIA_SHT(ide_pio_clocks[pio].hold_time ) + | PCMCIA_SST(ide_pio_clocks[pio].setup_time ) + | PCMCIA_SL (ide_pio_clocks[pio].active_time) + ; + +#if 1 + printk ("Setting timing bits 0x%08lx in PCMCIA controller\n", timing); +#endif + if ((reg = pcmp->pcmc_por0 & mask) != 0) + pcmp->pcmc_por0 = reg | timing; + + if ((reg = pcmp->pcmc_por1 & mask) != 0) + pcmp->pcmc_por1 = reg | timing; + + if ((reg = pcmp->pcmc_por2 & mask) != 0) + pcmp->pcmc_por2 = reg | timing; + + if ((reg = pcmp->pcmc_por3 & mask) != 0) + pcmp->pcmc_por3 = reg | timing; + + if ((reg = pcmp->pcmc_por4 & mask) != 0) + pcmp->pcmc_por4 = reg | timing; + + if ((reg = pcmp->pcmc_por5 & mask) != 0) + pcmp->pcmc_por5 = reg | timing; + + if ((reg = pcmp->pcmc_por6 & mask) != 0) + pcmp->pcmc_por6 = reg | timing; + + if ((reg = pcmp->pcmc_por7 & mask) != 0) + pcmp->pcmc_por7 = reg | timing; +} + +void ide_interrupt_handler (void *dev) +{ +} + +#endif /* CONFIG_BLK_DEV_MPC8xx_IDE */ +#endif /* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */ + +/* -------------------------------------------------------------------- */ + void __init m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) @@ -490,7 +665,6 @@ m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_ide_md.default_io_base = m8xx_ide_default_io_base; ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; - ppc_ide_md.ide_request_irq = m8xx_ide_request_irq; ppc_ide_md.io_base = _IO_BASE; #endif diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c index 0cbd4f553..919cb57eb 100644 --- a/arch/ppc/kernel/open_pic.c +++ b/arch/ppc/kernel/open_pic.c @@ -42,6 +42,45 @@ static volatile unsigned char* chrp_int_ack_special; OpenPIC_SourcePtr ISU[OPENPIC_MAX_ISU]; +/* Global Operations */ +static void openpic_disable_8259_pass_through(void); +static u_int openpic_irq(void); +static void openpic_eoi(void); +static void openpic_set_priority(u_int pri); +static void openpic_set_spurious(u_int vector); + +#ifdef CONFIG_SMP +/* Interprocessor Interrupts */ +static void openpic_initipi(u_int ipi, u_int pri, u_int vector); +static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs); +#endif + +/* Timer Interrupts */ +static void openpic_inittimer(u_int timer, u_int pri, u_int vector); +static void openpic_maptimer(u_int timer, u_int cpumask); + +/* Interrupt Sources */ +static void openpic_enable_irq(u_int irq); +static void openpic_disable_irq(u_int irq); +static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity, + int is_level); +static void openpic_mapirq(u_int irq, u_int cpumask); + +/* + * These functions are not used but the code is kept here + * for completeness and future reference. + */ +#ifdef notused +static void openpic_reset(void); +static void openpic_enable_8259_pass_through(void); +static u_int openpic_get_priority(void); +static u_int openpic_get_spurious(void); +static void openpic_set_sense(u_int irq, int sense); +#endif /* notused */ + +/* + * Description of the openpic for the higher-level irq code + */ static void openpic_end_irq(unsigned int irq_nr); static void openpic_ack_irq(unsigned int irq_nr); static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask); @@ -370,17 +409,19 @@ void find_ISUs(void) #endif } -static inline void openpic_reset(void) +#ifdef notused +static void openpic_reset(void) { openpic_setfield(&OpenPIC->Global.Global_Configuration0, OPENPIC_CONFIG_RESET); } -static inline void openpic_enable_8259_pass_through(void) +static void openpic_enable_8259_pass_through(void) { openpic_clearfield(&OpenPIC->Global.Global_Configuration0, OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); } +#endif /* notused */ static void openpic_disable_8259_pass_through(void) { @@ -412,8 +453,8 @@ static void openpic_eoi(void) (void)openpic_read(&OpenPIC->THIS_CPU.EOI); } - -static inline u_int openpic_get_priority(void) +#ifdef notused +static u_int openpic_get_priority(void) { DECL_THIS_CPU; @@ -421,6 +462,7 @@ static inline u_int openpic_get_priority(void) return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority, OPENPIC_CURRENT_TASK_PRIORITY_MASK); } +#endif /* notused */ static void openpic_set_priority(u_int pri) { @@ -435,11 +477,13 @@ static void openpic_set_priority(u_int pri) /* * Get/set the spurious vector */ -static inline u_int openpic_get_spurious(void) +#ifdef notused +static u_int openpic_get_spurious(void) { return openpic_readfield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK); } +#endif /* notused */ static void openpic_set_spurious(u_int vec) { @@ -604,21 +648,6 @@ static void __init openpic_maptimer(u_int timer, u_int cpumask) static void openpic_enable_irq(u_int irq) { check_arg_irq(irq); - - /* - * Never want to disable a timer or ipi irq - * (only want to disable irqs within an ISU). - */ - if (((irq >= OPENPIC_VEC_IPI+open_pic_irq_offset) && - (irq < OPENPIC_VEC_IPI+open_pic_irq_offset+OPENPIC_NUM_IPI)) || - ((irq >= OPENPIC_VEC_TIMER+open_pic_irq_offset) && - (irq < OPENPIC_VEC_TIMER+open_pic_irq_offset+OPENPIC_NUM_TIMERS))) - { - /* silently ignore the enable of the timer or ipi irq. */ - return; - } - - openpic_clearfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK); /* make sure mask gets to controller before we return to user */ do { @@ -632,19 +661,6 @@ static void openpic_disable_irq(u_int irq) u32 vp; check_arg_irq(irq); - /* - * Never want to disable a timer or ipi irq - * (only want to disable irqs within an ISU). - */ - if (((irq >= OPENPIC_VEC_IPI+open_pic_irq_offset) && - (irq < OPENPIC_VEC_IPI+open_pic_irq_offset+OPENPIC_NUM_IPI)) || - ((irq >= OPENPIC_VEC_TIMER+open_pic_irq_offset) && - (irq < OPENPIC_VEC_TIMER+open_pic_irq_offset+OPENPIC_NUM_TIMERS))) - { - panic("openpic_disable_irq - disabling non-ISU irq"); - } - - openpic_setfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK); /* make sure mask gets to controller before we return to user */ do { @@ -667,11 +683,13 @@ void openpic_enable_ipi(u_int irq) openpic_clearfield_IPI(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK); } + void openpic_disable_ipi(u_int irq) { - /* NEVER disable an IPI... that's just plain wrong! */ + irq -= (OPENPIC_VEC_IPI+open_pic_irq_offset); + check_arg_ipi(irq); + openpic_setfield_IPI(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK); } - #endif /* @@ -702,39 +720,33 @@ static void openpic_mapirq(u_int irq, u_int physmask) openpic_write(&GET_ISU(irq).Destination, physmask); } +#ifdef notused /* * Set the sense for an interrupt source (and disable it!) * * sense: 1 for level, 0 for edge */ -static inline void openpic_set_sense(u_int irq, int sense) +static void openpic_set_sense(u_int irq, int sense) { openpic_safe_writefield(&GET_ISU(irq).Vector_Priority, OPENPIC_SENSE_LEVEL, (sense ? OPENPIC_SENSE_LEVEL : 0)); } +#endif /* notused */ /* No spinlocks, should not be necessary with the OpenPIC * (1 register = 1 interrupt and we have the desc lock). */ static void openpic_ack_irq(unsigned int irq_nr) { -#if 1 /* masking should be unnecessary, but I still get spurrious */ openpic_disable_irq(irq_nr); -#endif - if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) - openpic_eoi(); + openpic_eoi(); } static void openpic_end_irq(unsigned int irq_nr) { - if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0) - openpic_eoi(); - -#if 1 /* masking should be unnecessary, but I still get spurrious */ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) openpic_enable_irq(irq_nr); -#endif } static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask) @@ -745,23 +757,11 @@ static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask) #ifdef CONFIG_SMP static void openpic_ack_ipi(unsigned int irq_nr) { + openpic_eoi(); } static void openpic_end_ipi(unsigned int irq_nr) { - /* IPIs are marked IRQ_PER_CPU. This has the side effect of - * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from - * applying to them. We EOI them late to avoid re-entering. - * however, I'm wondering if we could simply let them have the - * SA_INTERRUPT flag and let them execute with all interrupts OFF. - * This would have the side effect of either running cross-CPU - * functions with interrupts off, or we can re-enable them explicitely - * with a __sti() in smp_call_function_interrupt(), since - * smp_call_function() is protected by a spinlock. - * Or maybe we shouldn't set the IRQ_PER_CPU flag on cross-CPU - * function calls IPI at all but that would make a special case. - */ - openpic_eoi(); } static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) @@ -791,8 +791,11 @@ openpic_get_irq(struct pt_regs *regs) irq = i8259_irq( smp_processor_id() ); openpic_eoi(); } - if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset) + if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset) { irq = -1; + /* That's not SMP safe ... but who cares ? */ + ppc_spurious_interrupts++; + } return irq; } diff --git a/arch/ppc/kernel/open_pic_defs.h b/arch/ppc/kernel/open_pic_defs.h index fed4dd1cc..c0ea1ea86 100644 --- a/arch/ppc/kernel/open_pic_defs.h +++ b/arch/ppc/kernel/open_pic_defs.h @@ -28,8 +28,6 @@ #ifdef __KERNEL__ -#include <linux/config.h> - /* * OpenPIC supports up to 2048 interrupt sources and up to 32 processors */ @@ -289,40 +287,6 @@ extern volatile struct OpenPIC *OpenPIC; #define Vector_Priority _Vector_Priority.Reg #define Destination _Destination.Reg - /* - * Local (static) OpenPIC Operations - */ - - -/* Global Operations */ -static void openpic_reset(void); -static void openpic_enable_8259_pass_through(void); -static void openpic_disable_8259_pass_through(void); -static u_int openpic_irq(void); -static void openpic_eoi(void); -static u_int openpic_get_priority(void); -static void openpic_set_priority(u_int pri); -static u_int openpic_get_spurious(void); -static void openpic_set_spurious(u_int vector); - -#ifdef CONFIG_SMP -/* Interprocessor Interrupts */ -static void openpic_initipi(u_int ipi, u_int pri, u_int vector); -static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs); -#endif - -/* Timer Interrupts */ -static void openpic_inittimer(u_int timer, u_int pri, u_int vector); -static void openpic_maptimer(u_int timer, u_int cpumask); - -/* Interrupt Sources */ -static void openpic_enable_irq(u_int irq); -static void openpic_disable_irq(u_int irq); -static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity, - int is_level); -static void openpic_mapirq(u_int irq, u_int cpumask); -static void openpic_set_sense(u_int irq, int sense); - #endif /* __KERNEL__ */ #endif /* _LINUX_OPENPIC_H */ diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 1e503fae4..56a724bc0 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -109,7 +109,7 @@ pcibios_fixup_resources(struct pci_dev* dev) struct resource *res = dev->resource + i; if (!res->start) continue; - if (res->flags & IORESOURCE_MEM) { + if ((res->flags & IORESOURCE_MEM) && hose->pci_mem_offset) { res->start += hose->pci_mem_offset; res->end += hose->pci_mem_offset; #ifdef DEBUG @@ -121,7 +121,9 @@ pcibios_fixup_resources(struct pci_dev* dev) if ((res->flags & IORESOURCE_IO) && (unsigned long) hose->io_base_virt != isa_io_base) { - unsigned long offs = (unsigned long) hose->io_base_virt - isa_io_base; + unsigned long offs; + + offs = (unsigned long)hose->io_base_virt - isa_io_base; res->start += offs; res->end += offs; printk("Fixup IO res, dev: %x.%x, res_start: %lx->%lx\n", @@ -245,13 +247,30 @@ pcibios_allocate_bus_resources(struct list_head *bus_list) } } +static inline void alloc_resource(struct pci_dev *dev, int idx) +{ + struct resource *pr, *r = &dev->resource[idx]; + + DBG("PCI:%x:%x:%x: Resource %08lx-%08lx (f=%lx)\n", + dev->bus->number, dev->devfn >> 3, dev->devfn & 7, + r->start, r->end, r->flags); + pr = pci_find_parent_resource(dev, r); + if (!pr || request_resource(pr, r) < 0) { + printk(KERN_ERR "PCI: Cannot allocate resource region %d" + " of device %s\n", idx, dev->slot_name); + /* We'll assign a new address later */ + r->end -= r->start; + r->start = 0; + } +} + static void __init pcibios_allocate_resources(int pass) { struct pci_dev *dev; int idx, disabled; u16 command; - struct resource *r, *pr; + struct resource *r; pci_for_each_dev(dev) { pci_read_config_word(dev, PCI_COMMAND, &command); @@ -259,7 +278,7 @@ pcibios_allocate_resources(int pass) r = &dev->resource[idx]; if (r->parent) /* Already allocated */ continue; - if (!r->start) /* Address not assigned at all */ + if (!r->start) /* Not assigned at all */ continue; if (r->end == 0xffffffff) { /* LongTrail OF quirk: unassigned */ @@ -273,28 +292,19 @@ pcibios_allocate_resources(int pass) disabled = !(command & PCI_COMMAND_IO); else disabled = !(command & PCI_COMMAND_MEMORY); - if (pass == disabled) { - DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n", - r->start, r->end, r->flags, disabled, pass); - pr = pci_find_parent_resource(dev, r); - if (!pr || request_resource(pr, r) < 0) { - printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, dev->slot_name); - /* We'll assign a new address later */ - r->end -= r->start; - r->start = 0; - } - } + if (pass == disabled) + alloc_resource(dev, idx); } - if (!pass) { - r = &dev->resource[PCI_ROM_RESOURCE]; - if (r->flags & PCI_ROM_ADDRESS_ENABLE) { - /* Turn the ROM off, leave the resource region, but keep it unregistered. */ - u32 reg; - DBG("PCI: Switching off ROM of %s\n", dev->slot_name); - r->flags &= ~PCI_ROM_ADDRESS_ENABLE; - pci_read_config_dword(dev, dev->rom_base_reg, ®); - pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE); - } + if (pass) + continue; + r = &dev->resource[PCI_ROM_RESOURCE]; + if (r->flags & PCI_ROM_ADDRESS_ENABLE) { + /* Turn the ROM off, leave the resource region, but keep it unregistered. */ + u32 reg; + DBG("PCI: Switching off ROM of %s\n", dev->slot_name); + r->flags &= ~PCI_ROM_ADDRESS_ENABLE; + pci_read_config_dword(dev, dev->rom_base_reg, ®); + pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE); } } } @@ -315,17 +325,18 @@ pcibios_assign_resources(void) for(idx=0; idx<6; idx++) { r = &dev->resource[idx]; - +#if 0 /* we don't need this PC-ism */ /* * Don't touch IDE controllers and I/O ports of video cards! */ if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) || (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO))) continue; +#endif /* * We shall assign a new address to this resource, either because - * the BIOS forgot to do so or because we have decided the old + * the BIOS (sic) forgot to do so or because we have decided the old * address was unusable for some reason. */ if (!r->start && r->end && @@ -572,7 +583,7 @@ pcibios_init(void) { struct pci_controller *hose; struct pci_bus *bus; - int next_busno; + int next_busno, i; printk("PCI: Probing PCI hardware\n"); @@ -582,6 +593,17 @@ pcibios_init(void) hose->first_busno = next_busno; hose->last_busno = 0xff; bus = pci_scan_bus(hose->first_busno, hose->ops, hose); + if (hose->io_resource.flags) { + unsigned long offs; + + offs = (unsigned long)hose->io_base_virt - isa_io_base; + hose->io_resource.start += offs; + hose->io_resource.end += offs; + bus->resource[0] = &hose->io_resource; + } + for (i = 0; i < 3; ++i) + if (hose->mem_resources[i].flags) + bus->resource[i+1] = &hose->mem_resources[i]; hose->bus = bus; hose->last_busno = bus->subordinate; if (pci_assign_all_busses || next_busno <= hose->last_busno) @@ -654,8 +676,20 @@ unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, void __init pcibios_fixup_bus(struct pci_bus *bus) { + struct pci_controller *hose; + pci_read_bridge_bases(bus); - + + hose = pci_bus_to_hose(bus->number); + + /* Apply pci_mem_offset to bridge mem resource */ + if (hose->first_busno != bus->number) + if (bus->resource[1]->start && (bus->resource[1]->end != -1)) + { + bus->resource[1]->start += hose->pci_mem_offset; + bus->resource[1]->end += hose->pci_mem_offset; + } + if ( ppc_md.pcibios_fixup_bus ) ppc_md.pcibios_fixup_bus(bus); } @@ -774,6 +808,32 @@ pci_resource_to_bus(struct pci_dev *pdev, struct resource *res) * is fixed */ unsigned long +phys_to_bus(unsigned long pa) +{ + struct pci_controller *hose; + int i; + + for (hose = hose_head; hose; hose = hose->next) { + for (i = 0; i < 3; ++i) { + if (pa >= hose->mem_resources[i].start + && pa <= hose->mem_resources[i].end) { + /* + * XXX the hose->pci_mem_offset really + * only applies to mem_resources[0]. + * We need a way to store an offset for + * the others. -- paulus + */ + if (i == 0) + pa -= hose->pci_mem_offset; + return pa; + } + } + } + /* hmmm, didn't find it */ + return 0; +} + +unsigned long pci_phys_to_bus(unsigned long pa, int busnr) { #ifdef CONFIG_POWER4 diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c index 9e1fffb49..597f4417a 100644 --- a/arch/ppc/kernel/pmac_pci.c +++ b/arch/ppc/kernel/pmac_pci.c @@ -29,6 +29,8 @@ #undef DEBUG +extern void process_bridge_ranges(struct pci_controller *hose, + struct device_node *dev, int primary); static void add_bridges(struct device_node *dev); /* XXX Could be per-controller, but I don't think we risk anything by @@ -372,7 +374,7 @@ static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) (void)in_le32((volatile unsigned int *)bp->cfg_data); } -static void __init +static int __init setup_uninorth(struct pci_controller* hose, struct reg_property* addr) { pci_assign_all_busses = 1; @@ -380,6 +382,7 @@ setup_uninorth(struct pci_controller* hose, struct reg_property* addr) hose->ops = ¯isc_pci_ops; hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); +#if 0 /* done in process_bridge_ranges now - paulus */ hose->io_base_phys = addr->address; /* is 0x10000 enough for io space ? */ hose->io_base_virt = (void *)ioremap(addr->address, 0x10000); @@ -389,6 +392,9 @@ setup_uninorth(struct pci_controller* hose, struct reg_property* addr) */ if (addr->address == 0xf2000000) isa_io_base = (unsigned long)hose->io_base_virt; +#endif + /* We "know" that the bridge at f2000000 has the PCI slots. */ + return addr->address == 0xf2000000; } static void __init @@ -399,8 +405,10 @@ setup_bandit(struct pci_controller* hose, struct reg_property* addr) ioremap(addr->address + 0x800000, 0x1000); hose->cfg_data = (volatile unsigned char *) ioremap(addr->address + 0xc00000, 0x1000); +#if 0 /* done in process_bridge_ranges now - paulus */ hose->io_base_phys = addr->address; hose->io_base_virt = (void *) ioremap(addr->address, 0x10000); +#endif init_bandit(hose); } @@ -413,19 +421,23 @@ setup_chaos(struct pci_controller* hose, struct reg_property* addr) ioremap(addr->address + 0x800000, 0x1000); hose->cfg_data = (volatile unsigned char *) ioremap(addr->address + 0xc00000, 0x1000); +#if 0 /* done in process_bridge_ranges now - paulus */ hose->io_base_phys = addr->address; hose->io_base_virt = (void *) ioremap(addr->address, 0x10000); +#endif } void __init setup_grackle(struct pci_controller *hose, unsigned io_space_size) { setup_indirect_pci(hose, 0xfec00000, 0xfee00000); +#if 0 /* done in process_bridge_ranges now - paulus */ hose->io_base_phys = 0xfe000000; hose->io_base_virt = (void *) ioremap(0xfe000000, io_space_size); pci_dram_offset = 0; isa_mem_base = 0xfd000000; isa_io_base = (unsigned long) hose->io_base_virt; +#endif if (machine_is_compatible("AAPL,PowerBook1998")) grackle_set_loop_snoop(hose, 1); #if 0 /* Disabled for now, HW problems ??? */ @@ -445,6 +457,7 @@ static void __init add_bridges(struct device_node *dev) struct reg_property *addr; char* disp_name; int *bus_range; + int first = 1, primary; for (; dev != NULL; dev = dev->next) { addr = (struct reg_property *) get_property(dev, "reg", &len); @@ -467,8 +480,9 @@ static void __init add_bridges(struct device_node *dev) hose->last_busno = bus_range ? bus_range[1] : 0xff; disp_name = NULL; + primary = first; if (device_is_compatible(dev, "uni-north")) { - setup_uninorth(hose, addr); + primary = setup_uninorth(hose, addr); disp_name = "UniNorth"; } else if (strcmp(dev->name, "pci") == 0) { /* XXX assume this is a mpc106 (grackle) */ @@ -480,6 +494,7 @@ static void __init add_bridges(struct device_node *dev) } else if (strcmp(dev->name, "chaos") == 0) { setup_chaos(hose, addr); disp_name = "Chaos"; + primary = 0; } printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n", disp_name, addr->address, hose->first_busno, hose->last_busno); @@ -488,12 +503,14 @@ static void __init add_bridges(struct device_node *dev) hose, hose->cfg_addr, hose->cfg_data); #endif - /* Setup a default isa_io_base */ - if (isa_io_base == 0) - isa_io_base = (unsigned long)hose->io_base_virt; + /* Interpret the "ranges" property */ + /* This also maps the I/O region and sets isa_io/mem_base */ + process_bridge_ranges(hose, dev, primary); /* Fixup "bus-range" OF property */ fixup_bus_range(dev); + + first &= !primary; } } diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c index 839f66d80..0251a36e3 100644 --- a/arch/ppc/kernel/pmac_setup.c +++ b/arch/ppc/kernel/pmac_setup.c @@ -81,7 +81,7 @@ extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int mackbd_getkeycode(unsigned int scancode); extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode); -extern int mackbd_unexpected_up(unsigned char keycode); +extern char mackbd_unexpected_up(unsigned char keycode); extern void mackbd_leds(unsigned char leds); extern void __init mackbd_init_hw(void); extern int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode, @@ -253,6 +253,7 @@ pmac_get_cpuinfo(char *buffer) #endif +#ifdef CONFIG_VT /* * Dummy mksound function that does nothing. * The real one is in the dmasound driver. @@ -262,6 +263,7 @@ static void pmac_mksound(unsigned int hz, unsigned int ticks) { } +#endif /* CONFIG_VT */ static volatile u32 *sysctrl_regs; @@ -345,9 +347,9 @@ pmac_setup_arch(void) #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif - +#ifdef CONFIG_VT kd_mksound = pmac_mksound; - +#endif #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); @@ -380,7 +382,7 @@ extern char *bootdevice; void *boot_host; int boot_target; int boot_part; -kdev_t boot_dev; +extern kdev_t boot_dev; void __init pmac_init2(void) diff --git a/arch/ppc/kernel/ppc8xx_pic.c b/arch/ppc/kernel/ppc8xx_pic.c index e2db1e34d..0ec85e541 100644 --- a/arch/ppc/kernel/ppc8xx_pic.c +++ b/arch/ppc/kernel/ppc8xx_pic.c @@ -153,6 +153,20 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) irq += i8259_pic.irq_offset; return (request_8xxirq(irq, handler, irqflags, devname, dev_id)); #else - panic("request_irq"); + /* + * Handle other "well-known" interrupts, but panic on unknown ones. + */ + switch (irq) { +#ifdef IDE0_INTERRUPT + case IDE0_INTERRUPT: /* fall through */ +#endif +#ifdef IDE1_INTERRUPT + case IDE1_INTERRUPT: /* fall through */ +#endif + return (request_8xxirq(irq, handler, irqflags, devname, dev_id)); + + default: /* unknown IRQ -> panic */ + panic("request_irq"); + } #endif } diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 43a05659d..3ffecdb67 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -46,6 +46,10 @@ #endif /* CONFIG_SMP */ #include <asm/time.h> +#ifdef CONFIG_8xx +#include "../8xx_io/commproc.h" +#endif + /* Tell string.h we don't want memcpy etc. as cpp defines */ #define EXPORT_SYMTAB_STROPS @@ -94,7 +98,7 @@ EXPORT_SYMBOL_NOVERS(isa_mem_base); EXPORT_SYMBOL_NOVERS(pci_dram_offset); #endif EXPORT_SYMBOL(ISA_DMA_THRESHOLD); -EXPORT_SYMBOL(DMA_MODE_READ); +EXPORT_SYMBOL_NOVERS(DMA_MODE_READ); EXPORT_SYMBOL(DMA_MODE_WRITE); #ifndef CONFIG_8xx #if defined(CONFIG_ALL_PPC) @@ -192,6 +196,9 @@ EXPORT_SYMBOL(last_task_used_altivec); EXPORT_SYMBOL(giveup_altivec); #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_SMP +EXPORT_SYMBOL(global_irq_lock); +EXPORT_SYMBOL(global_irq_count); +EXPORT_SYMBOL(global_irq_holder); EXPORT_SYMBOL(__global_cli); EXPORT_SYMBOL(__global_sti); EXPORT_SYMBOL(__global_save_flags); @@ -242,11 +249,11 @@ EXPORT_SYMBOL(set_backlight_level); EXPORT_SYMBOL(set_backlight_enable); EXPORT_SYMBOL(register_backlight_controller); #endif /* CONFIG_PMAC_BACKLIGHT */ -EXPORT_SYMBOL_NOVERS(sys_ctrler); #ifndef CONFIG_MACH_SPECIFIC EXPORT_SYMBOL_NOVERS(have_of); #endif /* CONFIG_MACH_SPECIFIC */ #if defined(CONFIG_ALL_PPC) +EXPORT_SYMBOL_NOVERS(sys_ctrler); EXPORT_SYMBOL(find_devices); EXPORT_SYMBOL(find_type_devices); EXPORT_SYMBOL(find_compatible_devices); @@ -280,7 +287,9 @@ EXPORT_SYMBOL(bootx_update_display); #if defined(CONFIG_SCSI) && defined(CONFIG_ALL_PPC) EXPORT_SYMBOL(note_scsi_host); #endif +#ifdef CONFIG_VT EXPORT_SYMBOL(kd_mksound); +#endif #ifdef CONFIG_NVRAM EXPORT_SYMBOL(nvram_read_byte); EXPORT_SYMBOL(nvram_write_byte); @@ -342,11 +351,18 @@ EXPORT_SYMBOL(debugger_dabr_match); EXPORT_SYMBOL(debugger_fault_handler); #endif +#ifdef CONFIG_8xx +EXPORT_SYMBOL(request_8xxirq); +EXPORT_SYMBOL(cpm_install_handler); +EXPORT_SYMBOL(cpm_free_handler); +#endif /* CONFIG_8xx */ + EXPORT_SYMBOL(ret_to_user_hook); EXPORT_SYMBOL(do_softirq); EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); EXPORT_SYMBOL(mmu_context_overflow); +EXPORT_SYMBOL_NOVERS(disarm_decr); #if !defined(CONFIG_8xx) && !defined(CONFIG_4xx) extern long *intercept_table; EXPORT_SYMBOL(intercept_table); diff --git a/arch/ppc/kernel/prep_pci.c b/arch/ppc/kernel/prep_pci.c index 2f556d83d..369e8c47c 100644 --- a/arch/ppc/kernel/prep_pci.c +++ b/arch/ppc/kernel/prep_pci.c @@ -37,6 +37,10 @@ unsigned char *Motherboard_map_name; /* How is the 82378 PIRQ mapping setup? */ unsigned char *Motherboard_routes; +void (*Motherboard_non0)(struct pci_dev *); + +void Powerplus_Map_Non0(struct pci_dev *); + /* Used for Motorola to store system config register */ static unsigned long *ProcInfo; @@ -505,6 +509,52 @@ static char Nobis_pci_IRQ_routes[] __prepdata = { 13 /* Line 4 */ }; +/* Motorola PowerPlus architecture PCI IRQ tables */ +/* Interrupt line values for INTA-D on primary/secondary MPIC inputs */ + +struct powerplus_irq_list +{ + unsigned char primary[4]; /* INT A-D */ + unsigned char secondary[4]; /* INT A-D */ +}; + +/* + * For standard PowerPlus boards, bus 0 PCI INTs A-D are routed to + * OpenPIC inputs 9-12. PCI INTs A-D from the on board P2P bridge + * are routed to OpenPIC inputs 5-8. These values are offset by + * 16 in the table to reflect the Linux kernel interrupt value. + */ +struct powerplus_irq_list Powerplus_pci_IRQ_list = +{ + {25, 26, 27, 28}, + {21, 22, 23, 24} +}; + +/* + * For the MCP750 (system slot board), cPCI INTs A-D are routed to + * OpenPIC inputs 8-11 and the PMC INTs A-D are routed to OpenPIC + * input 3. On a hot swap MCP750, the companion card PCI INTs A-D + * are routed to OpenPIC inputs 12-15. These values are offset by + * 16 in the table to reflect the Linux kernel interrupt value. + */ +struct powerplus_irq_list Mesquite_pci_IRQ_list = +{ + {24, 25, 26, 27}, + {28, 29, 30, 31} +}; + +/* + * This table represents the standard PCI swizzle defined in the + * PCI bus specification. + */ +static unsigned char prep_pci_intpins[4][4] = +{ + { 1, 2, 3, 4}, /* Buses 0, 4, 8, ... */ + { 2, 3, 4, 1}, /* Buses 1, 5, 9, ... */ + { 3, 4, 1, 2}, /* Buses 2, 6, 10 ... */ + { 4, 1, 2, 3}, /* Buses 3, 7, 11 ... */ +}; + /* We have to turn on LEVEL mode for changed IRQ's */ /* All PCI IRQ's need to be level mode, so this should be something * other than hard-coded as well... IRQ's are individually mappable @@ -599,6 +649,7 @@ static u_char mvme2600_openpic_initsenses[] __initdata = { #define MOT_RAVEN_PRESENT 0x1 #define MOT_HAWK_PRESENT 0x2 +int mot_entry = -1; int prep_keybd_present = 1; int MotMPIC; int mot_multi; @@ -682,33 +733,36 @@ struct mot_info { const char *name; unsigned char *map; unsigned char *routes; + void (*map_non0_bus)(struct pci_dev *); /* For boards with more than bus 0 devices. */ + struct powerplus_irq_list *pci_irq_list; /* List of PCI MPIC inputs */ + unsigned char secondary_bridge_devfn; /* devfn of secondary bus transparent bridge */ } mot_info[] = { - {0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes}, - {0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes}, - {0x040, 0x00, 0x00, "Blackhawk (Powerstack)", Blackhawk_pci_IRQ_map, Blackhawk_pci_IRQ_routes}, - {0x050, 0x00, 0x00, "Omaha (PowerStack II Pro3000)", Omaha_pci_IRQ_map, Omaha_pci_IRQ_routes}, - {0x060, 0x00, 0x00, "Utah (Powerstack II Pro4000)", Utah_pci_IRQ_map, Utah_pci_IRQ_routes}, - {0x0A0, 0x00, 0x00, "Powerstack (Series EX)", Comet2_pci_IRQ_map, Comet2_pci_IRQ_routes}, - {0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", Sitka_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xF6, 0x80, "MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xFA, 0x00, "MVME 2300SC/2600", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x1E0, 0xFF, 0x00, "MVME 1600-001 or 1600-011", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes}, - {0x000, 0x00, 0x00, "", NULL, NULL} + {0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, + {0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, + {0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes, NULL, NULL, 0x00}, + {0x040, 0x00, 0x00, "Blackhawk (Powerstack)", Blackhawk_pci_IRQ_map, Blackhawk_pci_IRQ_routes, NULL, NULL, 0x00}, + {0x050, 0x00, 0x00, "Omaha (PowerStack II Pro3000)", Omaha_pci_IRQ_map, Omaha_pci_IRQ_routes, NULL, NULL, 0x00}, + {0x060, 0x00, 0x00, "Utah (Powerstack II Pro4000)", Utah_pci_IRQ_map, Utah_pci_IRQ_routes, NULL, NULL, 0x00}, + {0x0A0, 0x00, 0x00, "Powerstack (Series EX)", Comet2_pci_IRQ_map, Comet2_pci_IRQ_routes, NULL, NULL, 0x00}, + {0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Mesquite_pci_IRQ_list, 0xFF}, + {0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", Sitka_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, + {0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Mesquite_pci_IRQ_list, 0xC0}, + {0x1E0, 0xF6, 0x80, "MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xA0}, + {0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xA0}, + {0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, + {0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, + {0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, + {0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, + {0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, + {0x1E0, 0xFA, 0x00, "MVME 2300SC/2600", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, + {0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, + {0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, + {0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00}, + {0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, + {0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, + {0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, + {0x1E0, 0xFF, 0x00, "MVME 1600-001 or 1600-011", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF}, + {0x000, 0x00, 0x00, "", NULL, NULL, NULL, NULL, 0x00} }; unsigned long __init prep_route_pci_interrupts(void) @@ -723,7 +777,6 @@ unsigned long __init prep_route_pci_interrupts(void) unsigned char cpu_type; unsigned char base_mod; int entry; - int mot_entry = -1; cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0; base_mod = inb(MOTOROLA_BASETYPE_REG); @@ -769,6 +822,7 @@ unsigned long __init prep_route_pci_interrupts(void) Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name; Motherboard_map = mot_info[mot_entry].map; Motherboard_routes = mot_info[mot_entry].routes; + Motherboard_non0 = mot_info[mot_entry].map_non0_bus; if (!(mot_info[entry].cpu_type & 0x100)) { /* AJF adjust level/edge control according to routes */ @@ -836,6 +890,157 @@ unsigned long __init prep_route_pci_interrupts(void) } void __init +prep_pib_init(void) +{ +unsigned char reg; +unsigned short short_reg; + +struct pci_dev *dev = NULL; + + if (( _prep_type == _PREP_Motorola) && (OpenPIC_Addr)) { + /* + * Perform specific configuration for the Via Tech or + * or Winbond PCI-ISA-Bridge part. + */ + if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_1, dev))) { + /* + * PPCBUG does not set the enable bits + * for the IDE device. Force them on here. + */ + pcibios_read_config_byte(dev->bus->number, + dev->devfn, 0x40, ®); + + reg |= 0x03; /* IDE: Chip Enable Bits */ + pcibios_write_config_byte(dev->bus->number, + dev->devfn, 0x40, reg); + + /* Force correct IDE function interrupt */ + dev->irq = 14; + pcibios_write_config_byte(dev->bus->number, + dev->devfn, + PCI_INTERRUPT_LINE, + dev->irq); + + } else if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_83C553, dev))) { + /* + * Clear the PCI Interrupt Routing Control Register. + */ + short_reg = 0x0000; + pci_write_config_word(dev, 0x44, short_reg); + if (OpenPIC_Addr){ + /* + * Route both IDE interrupts to IRQ 14 + */ + reg = 0xEE; + pci_write_config_byte(dev, 0x44, reg); + } + } + if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_2, + dev))) + { + /* Force correct USB function interrupt */ + dev->irq = 11; + pcibios_write_config_byte(dev->bus->number, + dev->devfn, + PCI_INTERRUPT_LINE, + dev->irq); + } + } + if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_82C105, dev))){ + if (OpenPIC_Addr){ + /* Disable LEGIRQ mode so PCI INTs are routed to + the 8259 */ + printk("Set winbond IDE to native mode\n"); + pci_write_config_dword(dev, 0x40, 0x10ff00a1); + }else{ + /* Enable LEGIRQ for PCI INT -> 8259 IRQ routing */ + pci_write_config_dword(dev, 0x40, 0x10ff08a1); + } + } +} + +void +Powerplus_Map_Non0(struct pci_dev *dev) +{ + struct pci_bus *pbus; /* Parent bus structure pointer */ + struct pci_dev *tdev = dev; /* Temporary device structure */ + unsigned int devnum; /* Accumulated device number */ + unsigned char intline; /* Linux interrupt value */ + unsigned char intpin; /* PCI interrupt pin */ + + /* Check for valid PCI dev pointer */ + if (dev == NULL) return; + + /* Initialize bridge IDSEL variable */ + devnum = PCI_SLOT(tdev->devfn); + + /* Read the interrupt pin of the device and adjust for indexing */ + pcibios_read_config_byte(dev->bus->number, dev->devfn, + PCI_INTERRUPT_PIN, &intpin); + + /* If device doesn't request an interrupt, return */ + if ( (intpin < 1) || (intpin > 4) ) + return; + + intpin--; + + /* + * Walk up to bus 0, adjusting the interrupt pin for the standard + * PCI bus swizzle. + */ + do { + intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1; + pbus = tdev->bus; /* up one level */ + tdev = pbus->self; + devnum = PCI_SLOT(tdev->devfn); + } while(tdev->bus->number); + + /* Use the primary interrupt inputs by default */ + intline = mot_info[mot_entry].pci_irq_list->primary[intpin]; + + /* + * If the board has secondary interrupt inputs, walk the bus and + * note the devfn of the bridge from bus 0. If it is the same as + * the devfn of the bus bridge with secondary inputs, use those. + * Otherwise, assume it's a PMC site and get the interrupt line + * value from the interrupt routing table. + */ + if (mot_info[mot_entry].secondary_bridge_devfn) + { + pbus = dev->bus; + + while (pbus->primary != 0) + pbus = pbus->parent; + + if ((pbus->self)->devfn != 0xA0) + { + if ((pbus->self)->devfn == mot_info[mot_entry].secondary_bridge_devfn) + intline = mot_info[mot_entry].pci_irq_list->secondary[intpin]; + else + { + if ((char *)(mot_info[mot_entry].map) == (char *)Mesquite_pci_IRQ_map) + intline = mot_info[mot_entry].map[((pbus->self)->devfn)/8] + 16; + else + { + int i; + for (i=0;i<3;i++) + intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1; + intline = mot_info[mot_entry].pci_irq_list->primary[intpin]; + } + } + } + } + + /* Write calculated interrupt value to header and device list */ + dev->irq = intline; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, (u8)dev->irq); +} + +void __init prep_pcibios_fixup(void) { struct pci_dev *dev; @@ -849,11 +1054,21 @@ prep_pcibios_fixup(void) if (OpenPIC_Addr) { /* PCI interrupts are controlled by the OpenPIC */ pci_for_each_dev(dev) { - if (dev->bus->number == 0) { + if (dev->bus->number == 0) + { dev->irq = openpic_to_irq(Motherboard_map[PCI_SLOT(dev->devfn)]); - pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_INTERRUPT_PIN, dev->irq); + pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_INTERRUPT_LINE, dev->irq); + } + else + { + if (Motherboard_non0 != NULL) + Motherboard_non0(dev); } } + + /* Setup the Winbond or Via PIB */ + prep_pib_init(); + return; } @@ -912,6 +1127,7 @@ prep_find_bridges(void) hose->first_busno = 0; hose->last_busno = 0xff; hose->pci_mem_offset = PREP_ISA_MEM_BASE; + hose->io_base_virt = (void *)PREP_ISA_IO_BASE; printk("PReP architecture\n"); { diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c index 0c23c51ac..772cceb61 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/kernel/prep_setup.c @@ -215,7 +215,6 @@ no_l2: void __init prep_setup_arch(void) { - extern char cmd_line[]; unsigned char reg; #if 0 /* unused?? */ unsigned char ucMothMemType; @@ -272,8 +271,6 @@ prep_setup_arch(void) } } - printk("Boot arguments: %s\n", cmd_line); - #ifdef CONFIG_SOUND_CS4232 /* * setup proper values for the cs4232 driver so we don't have diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c index f3b39c222..f8eb0729d 100644 --- a/arch/ppc/kernel/prom.c +++ b/arch/ppc/kernel/prom.c @@ -757,8 +757,11 @@ prom_init(int r3, int r4, prom_entry pp) setup_disp_fake_bi(RELOC(prom_disp_node)); #endif - /* If OpenFirmware version >= 3, then use quiesce call */ - if (prom_version >= 3) { + /* If pmac, then use quiesce call. We can't rely on prom_version + * since some old iMacs appear to have an incorrect /openprom/model + * entry in the device tree + */ + if (!chrp) { prom_print(RELOC("Calling quiesce ...\n")); call_prom(RELOC("quiesce"), 0, 0); } diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 73afefc56..5ad504503 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -386,8 +386,8 @@ int get_cpuinfo(char *buffer) if ( i ) len += sprintf(buffer+len, "\n"); len += sprintf(buffer+len,"total bogomips\t: %lu.%02lu\n", - (bogosum+2500)/500000, - (bogosum+2500)/5000 % 100); + (bogosum+2500)/(500000/HZ), + (bogosum+2500)/(5000/HZ) % 100); #endif /* CONFIG_SMP */ /* diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index 7edf7209d..29166ba77 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -100,14 +100,14 @@ extern void __secondary_start_psurge3(void); /* Temporary horrible hack */ #define PSURGE_QUAD_CKSTOP_RDBK 8 #define PSURGE_QUAD_RESET_CTL 11 -#define PSURGE_QUAD_OUT(r, v) (out_8((u8 *)(quad_base+((r)<<2)+1), (v))) -#define PSURGE_QUAD_IN(r) (in_8((u8 *)(quad_base+((r)<<2)+1)) & 0x0f) +#define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v))) +#define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f) #define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v))) #define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v))) /* virtual addresses for the above */ static volatile u8 *hhead_base; -static volatile u32 *quad_base; +static volatile u8 *quad_base; static volatile u32 *psurge_pri_intr; static volatile u8 *psurge_sec_intr; static volatile u32 *psurge_start; @@ -216,7 +216,7 @@ smp_psurge_message_pass(int target, int msg, unsigned long data, int wait) /* * Determine a quad card presence. We read the board ID register, we - * for the data bus to change to something else, and we read it again. + * force the data bus to change to something else, and we read it again. * It it's stable, then the register probably exist (ugh !) */ static int __init psurge_quad_probe(void) @@ -303,11 +303,7 @@ static int __init smp_psurge_probe(void) psurge_type = psurge_quad_probe(); if (psurge_type != PSURGE_DUAL) { psurge_quad_init(); - /* I believe we could "count" CPUs by counting 1 bits - * in procbits on a quad board. For now, we assume 4, - * non-present CPUs will just be seen as "stuck". - * (hope they are the higher-numbered ones -- paulus) - */ + /* All released cards using this HW design have 4 CPUs */ ncpus = 4; } else { iounmap((void *) quad_base); @@ -424,11 +420,10 @@ smp_openpic_message_pass(int target, int msg, unsigned long data, int wait) break; case MSG_ALL_BUT_SELF: openpic_cause_IPI(msg, - 0xffffffff & ~(1 << smp_hw_index[smp_processor_id()])); - + 0xffffffff & ~(1 << smp_processor_id())); break; default: - openpic_cause_IPI(msg, smp_hw_index[1<<target]); + openpic_cause_IPI(msg, 1<<target); break; } } @@ -437,27 +432,14 @@ static int smp_core99_probe(void) { struct device_node *cpus; - int *pp; int i, ncpus = 1; if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345); -#if 0 /* Paulus method.. doesn't seem to work on earlier dual G4's??*/ - cpus = find_devices("cpus"); - if (cpus != 0) { - pp = (int *) get_property(cpus, "#cpus", NULL); - if (pp != NULL) - ncpus = *pp; - } -#else /* My original method -- Troy <hozer@drgw.net> */ - cpus = find_type_devices("cpu"); - if (cpus){ - for ( ncpus = 1; cpus->next; cpus = cpus->next ){ - ncpus++; - } - } -#endif - printk("smp_core99_probe: OF reports %d cpus\n", ncpus); + if (cpus) + while ((cpus = cpus->next) != NULL) + ++ncpus; + printk("smp_core99_probe: found %d cpus\n", ncpus); if (ncpus > 1) { openpic_request_IPIs(); for (i = 1; i < ncpus; ++i) @@ -1010,6 +992,9 @@ void __init smp_boot_cpus(void) /* Setup CPU 0 last (important) */ smp_ops->setup_cpu(0); + + if (smp_num_cpus < 2) + smp_tb_synchronized = 1; } void __init smp_software_tb_sync(int cpu) @@ -1027,17 +1012,6 @@ void __init smp_software_tb_sync(int cpu) register unsigned long start = 0; register unsigned long stop = 0; register unsigned long temp = 0; - - if (smp_num_cpus < 2) { - smp_tb_synchronized = 1; - return; - } - - /* This code need fixing on >2 CPUs --BenH/paulus */ - if (smp_num_cpus > 2) { - smp_tb_synchronized = 0; - return; - } set_tb(0, 0); @@ -1107,6 +1081,7 @@ void __init smp_commence(void) if (ppc_md.progress) ppc_md.progress("smp_commence", 0x370); wmb(); smp_commenced = 1; + /* if the smp_ops->setup_cpu function has not already synched the * timebases with a nicer hardware-based method, do so now * @@ -1117,9 +1092,9 @@ void __init smp_commence(void) * since if this code runs pretty early and needs all cpus that * reported in in smp_callin_map to be working * - * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus + * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus/BenH */ - if (!smp_tb_synchronized) { + if (!smp_tb_synchronized && smp_num_cpus == 2) { unsigned long flags; __save_and_cli(flags); smp_software_tb_sync(0); @@ -1142,7 +1117,7 @@ void __init smp_callin(void) while(!smp_commenced) barrier(); /* see smp_commence for more info */ - if (!smp_tb_synchronized){ + if (!smp_tb_synchronized && smp_num_cpus == 2) { smp_software_tb_sync(cpu); } __sti(); diff --git a/arch/ppc/kernel/softemu8xx.c b/arch/ppc/kernel/softemu8xx.c index 26a8fe165..e8879d0a0 100644 --- a/arch/ppc/kernel/softemu8xx.c +++ b/arch/ppc/kernel/softemu8xx.c @@ -75,12 +75,12 @@ Soft_emulate_8xx(struct pt_regs *regs) sdisp = (instword & 0xffff); ea = (uint *)(regs->gpr[idxreg] + sdisp); if (copy_from_user(ip, ea, sizeof(double))) - retval = EFAULT; + retval = -EFAULT; break; case LFDU: if (copy_from_user(ip, ea, sizeof(double))) - retval = EFAULT; + retval = -EFAULT; else regs->gpr[idxreg] = (uint)ea; break; @@ -88,7 +88,7 @@ Soft_emulate_8xx(struct pt_regs *regs) sdisp = (instword & 0xffff); ea = (uint *)(regs->gpr[idxreg] + sdisp); if (copy_from_user(ip, ea, sizeof(float))) - retval = EFAULT; + retval = -EFAULT; break; case STFD: /* this is a 16 bit quantity that is sign extended @@ -97,12 +97,12 @@ Soft_emulate_8xx(struct pt_regs *regs) sdisp = (instword & 0xffff); ea = (uint *)(regs->gpr[idxreg] + sdisp); if (copy_to_user(ea, ip, sizeof(double))) - retval = EFAULT; + retval = -EFAULT; break; case STFDU: if (copy_to_user(ea, ip, sizeof(double))) - retval = EFAULT; + retval = -EFAULT; else regs->gpr[idxreg] = (uint)ea; break; diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c index d0fee4344..f4ed98698 100644 --- a/arch/ppc/kernel/syscalls.c +++ b/arch/ppc/kernel/syscalls.c @@ -198,9 +198,9 @@ unsigned long sys_mmap(unsigned long addr, size_t len, goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); ret = do_mmap(file, addr, len, prot, flags, offset); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); out: diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index 5b36cedcc..76a550214 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -67,6 +67,8 @@ #include <asm/time.h> +unsigned long disarm_decr[NR_CPUS]; + #ifdef CONFIG_SMP extern void smp_local_timer_interrupt(struct pt_regs *); extern int smp_tb_synchronized; @@ -147,7 +149,6 @@ int timer_interrupt(struct pt_regs * regs) if (!user_mode(regs)) ppc_do_profile(instruction_pointer(regs)); - do { jiffy_stamp += tb_ticks_per_jiffy; if (smp_processor_id()) continue; @@ -184,7 +185,8 @@ int timer_interrupt(struct pt_regs * regs) } write_unlock(&xtime_lock); } while((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0); - set_dec(next_dec); + if ( !disarm_decr[smp_processor_id()] ) + set_dec(next_dec); last_jiffy_stamp(cpu) = jiffy_stamp; #ifdef CONFIG_SMP diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 0269254cf..29d302267 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -237,7 +237,7 @@ emulate_instruction(struct pt_regs *regs) return retval; if (get_user(instword, (uint *)(regs->nip))) - return EFAULT; + return -EFAULT; /* Emulate the mfspr rD, PVR. */ @@ -281,7 +281,7 @@ ProgramCheckException(struct pt_regs *regs) /* Try to emulate it if we should. */ int errcode; if ((errcode = emulate_instruction(regs))) { - if (errcode == EFAULT) + if (errcode == -EFAULT) _exception(SIGBUS, regs); else _exception(SIGILL, regs); diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index 97bb6dbc1..507c60019 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -99,7 +99,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, bad_page_fault(regs, address, SIGSEGV); return; } - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) goto bad_area; @@ -159,7 +159,7 @@ good_area: goto out_of_memory; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* * keep track of tlb+htab misses that are good addrs but * just need pte's created via handle_mm_fault() @@ -169,7 +169,7 @@ good_area: return; bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); pte_errors++; /* User mode accesses cause a SIGSEGV */ @@ -190,7 +190,7 @@ bad_area: * us unable to handle the page fault gracefully. */ out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) do_exit(SIGKILL); @@ -198,7 +198,7 @@ out_of_memory: return; do_sigbus: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; @@ -276,7 +276,7 @@ unsigned long va_to_phys(unsigned long address) pte = va_to_pte(address); if (pte) - return(((unsigned long)(pte_val(*pte)) & PAGE_MASK) | (address & ~(PAGE_MASK-1))); + return(((unsigned long)(pte_val(*pte)) & PAGE_MASK) | (address & ~(PAGE_MASK))); return (0); } diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 839b618d0..5b9cac931 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -110,7 +110,7 @@ pgprot_t kmap_prot; #endif void MMU_init(void); -static void *MMU_get_page(void); +void *early_get_page(void); unsigned long prep_find_end_of_memory(void); unsigned long pmac_find_end_of_memory(void); unsigned long apus_find_end_of_memory(void); @@ -125,7 +125,7 @@ unsigned long oak_find_end_of_memory(void); unsigned long m8260_find_end_of_memory(void); #endif /* CONFIG_8260 */ static void mapin_ram(void); -void map_page(unsigned long va, unsigned long pa, int flags); +int map_page(unsigned long va, unsigned long pa, int flags); void set_phys_avail(unsigned long total_ram); extern void die_if_kernel(char *,struct pt_regs *,long); @@ -206,41 +206,20 @@ void __bad_pte(pmd_t *pmd) pmd_val(*pmd) = (unsigned long) BAD_PAGETABLE; } -pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) -{ - pte_t *pte; - - if (pmd_none(*pmd)) { - if (!mem_init_done) - pte = (pte_t *) MMU_get_page(); - else if ((pte = (pte_t *) __get_free_page(GFP_KERNEL))) - clear_page(pte); - if (pte) { - pmd_val(*pmd) = (unsigned long)pte; - return pte + offset; - } - pmd_val(*pmd) = (unsigned long)BAD_PAGETABLE; - return NULL; - } - if (pmd_bad(*pmd)) { - __bad_pte(pmd); - return NULL; - } - return (pte_t *) pmd_page(*pmd) + offset; -} - int do_check_pgt_cache(int low, int high) { int freed = 0; - if(pgtable_cache_size > high) { + if (pgtable_cache_size > high) { do { - if(pgd_quicklist) - free_pgd_slow(get_pgd_fast()), freed++; - if(pmd_quicklist) - free_pmd_slow(get_pmd_fast()), freed++; - if(pte_quicklist) - free_pte_slow(get_pte_fast()), freed++; - } while(pgtable_cache_size > low); + if (pgd_quicklist) { + free_pgd_slow(get_pgd_fast()); + freed++; + } + if (pte_quicklist) { + pte_free_slow(pte_alloc_one_fast(NULL, 0)); + freed++; + } + } while (pgtable_cache_size > low); } return freed; } @@ -383,6 +362,7 @@ void * __ioremap(unsigned long addr, unsigned long size, unsigned long flags) { unsigned long p, v, i; + int err; /* * Choose an address to map it to. @@ -453,10 +433,20 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags) flags |= _PAGE_GUARDED; /* - * Is it a candidate for a BAT mapping? + * Should check if it is a candidate for a BAT mapping */ - for (i = 0; i < size; i += PAGE_SIZE) - map_page(v+i, p+i, flags); + + spin_lock(&init_mm.page_table_lock); + err = 0; + for (i = 0; i < size && err == 0; i += PAGE_SIZE) + err = map_page(v+i, p+i, flags); + spin_unlock(&init_mm.page_table_lock); + if (err) { + if (mem_init_done) + vfree((void *)v); + return NULL; + } + out: return (void *) (v + (addr & ~PAGE_MASK)); } @@ -492,7 +482,7 @@ unsigned long iopa(unsigned long addr) return (pte_val(*pg) & PAGE_MASK) | (addr & ~PAGE_MASK); } -void +int map_page(unsigned long va, unsigned long pa, int flags) { pmd_t *pd; @@ -501,10 +491,13 @@ map_page(unsigned long va, unsigned long pa, int flags) /* Use upper 10 bits of VA to index the first level map */ pd = pmd_offset(pgd_offset_k(va), va); /* Use middle 10 bits of VA to index the second-level map */ - pg = pte_alloc(pd, va); + pg = pte_alloc(&init_mm, pd, va); + if (pg == 0) + return -ENOMEM; set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags))); if (mem_init_done) flush_hash_page(0, va); + return 0; } #ifndef CONFIG_8xx @@ -830,21 +823,16 @@ static void __init mapin_ram(void) } } -/* In fact this is only called until mem_init is done. */ -static void __init *MMU_get_page(void) +/* This is only called until mem_init is done. */ +void __init *early_get_page(void) { void *p; - if (mem_init_done) { - p = (void *) __get_free_page(GFP_KERNEL); - } else if (init_bootmem_done) { + if (init_bootmem_done) { p = alloc_bootmem_pages(PAGE_SIZE); } else { p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE); } - if (p == 0) - panic("couldn't get a page in MMU_get_page"); - __clear_user(p, PAGE_SIZE); return p; } @@ -889,13 +877,14 @@ void free_initmem(void) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + for (; start < end; start += PAGE_SIZE) { ClearPageReserved(virt_to_page(start)); set_page_count(virt_to_page(start), 1); free_page(start); totalram_pages++; } - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); } #endif diff --git a/arch/ppc/treeboot/mkevimg b/arch/ppc/treeboot/mkevimg index 68eb4dd3f..ca3ca0e8f 100644 --- a/arch/ppc/treeboot/mkevimg +++ b/arch/ppc/treeboot/mkevimg @@ -431,7 +431,7 @@ require 'elf.pl'; close(BOOT); - print("\nBoot image file \"$ofile\" built successfuly.\n\n"); + print("\nBoot image file \"$ofile\" built successfully.\n\n"); exit(0); } diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index a1125e933..de40410b0 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -687,7 +687,7 @@ pgm_no_sv: lr %r3,%r8 la %r0,0x7f nr %r3,%r0 # clear per-event-bit - be BASED(pgm_dn) # none of Martins exceptions occured bypass + be BASED(pgm_dn) # none of Martins exceptions occurred bypass l %r9,BASED(.Ljump_table) sll %r3,2 l %r9,0(%r3,%r9) # load address of handler routine diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index cc7700864..594fa34a5 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c @@ -61,9 +61,9 @@ static inline long do_mmap2( goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 2c75918af..527f08282 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -122,7 +122,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) * task's user address space, so we search the VMAs */ - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -173,7 +173,7 @@ good_area: goto out_of_memory; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return; /* @@ -181,7 +181,7 @@ good_area: * Fix it, but check if it's kernel or user first.. */ bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* User mode accesses just cause a SIGSEGV */ if (psw_mask & PSW_PROBLEM_STATE) { @@ -240,14 +240,14 @@ no_context: * us unable to handle the page fault gracefully. */ out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if (psw_mask & PSW_PROBLEM_STATE) do_exit(SIGKILL); goto no_context; do_sigbus: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* * Send a sigbus, regardless of whether we were in kernel diff --git a/arch/s390/tools/dasdfmt/dasdfmt.c b/arch/s390/tools/dasdfmt/dasdfmt.c index 2820fc91d..560feff6b 100644 --- a/arch/s390/tools/dasdfmt/dasdfmt.c +++ b/arch/s390/tools/dasdfmt/dasdfmt.c @@ -477,7 +477,7 @@ do_format_dasd(char *dev_name,format_data_t format_params,int testmode, rc=stat(dev_name,&stat_buf); if (rc) { - ERRMSG_EXIT(EXIT_FAILURE,"%s: error occured during stat: " \ + ERRMSG_EXIT(EXIT_FAILURE,"%s: error occurred during stat: " \ "%s\n",prog_name,strerror(errno)); } else { if (!S_ISBLK(stat_buf.st_mode)) diff --git a/arch/s390x/kernel/binfmt_elf32.c b/arch/s390x/kernel/binfmt_elf32.c index b08f0f686..d21f6966b 100644 --- a/arch/s390x/kernel/binfmt_elf32.c +++ b/arch/s390x/kernel/binfmt_elf32.c @@ -193,11 +193,11 @@ elf_map32 (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int p if(!addr) addr = 0x40000000; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); map_addr = do_mmap(filep, ELF_PAGESTART(addr), eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type, eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr)); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); return(map_addr); } diff --git a/arch/s390x/kernel/entry.S b/arch/s390x/kernel/entry.S index c5fbdd61f..0dddf63c7 100644 --- a/arch/s390x/kernel/entry.S +++ b/arch/s390x/kernel/entry.S @@ -724,7 +724,7 @@ pgm_no_sv: stosm 48(%r15),0x03 # reenable interrupts lghi %r3,0x7f nr %r3,%r8 # clear per-event-bit & move to r3 - je pgm_dn # none of Martins exceptions occured bypass + je pgm_dn # none of Martins exceptions occurred bypass sll %r3,3 larl %r9,pgm_check_table lg %r9,0(%r3,%r9) # load address of handler routine diff --git a/arch/s390x/kernel/exec32.c b/arch/s390x/kernel/exec32.c index 3e6f44558..8c517456a 100644 --- a/arch/s390x/kernel/exec32.c +++ b/arch/s390x/kernel/exec32.c @@ -54,7 +54,7 @@ int setup_arg_pages32(struct linux_binprm *bprm) if (!mpnt) return -ENOMEM; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); { mpnt->vm_mm = current->mm; mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p; @@ -73,12 +73,11 @@ int setup_arg_pages32(struct linux_binprm *bprm) struct page *page = bprm->page[i]; if (page) { bprm->page[i] = NULL; - current->mm->rss++; put_dirty_page(current,page,stack_base); } stack_base += PAGE_SIZE; } - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); return 0; } diff --git a/arch/s390x/kernel/linux32.c b/arch/s390x/kernel/linux32.c index 668ac46c4..c567d4b49 100644 --- a/arch/s390x/kernel/linux32.c +++ b/arch/s390x/kernel/linux32.c @@ -4184,9 +4184,9 @@ static inline long do_mmap2( goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); diff --git a/arch/s390x/kernel/sys_s390.c b/arch/s390x/kernel/sys_s390.c index 4c06bd326..e05a8be0b 100644 --- a/arch/s390x/kernel/sys_s390.c +++ b/arch/s390x/kernel/sys_s390.c @@ -61,9 +61,9 @@ static inline long do_mmap2( goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); diff --git a/arch/s390x/mm/fault.c b/arch/s390x/mm/fault.c index 4c324b690..cd60eb61d 100644 --- a/arch/s390x/mm/fault.c +++ b/arch/s390x/mm/fault.c @@ -122,7 +122,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) * task's user address space, so we search the VMAs */ - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) { @@ -176,7 +176,7 @@ good_area: goto out_of_memory; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return; /* @@ -184,7 +184,7 @@ good_area: * Fix it, but check if it's kernel or user first.. */ bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* User mode accesses just cause a SIGSEGV */ if (psw_mask & PSW_PROBLEM_STATE) { @@ -243,14 +243,14 @@ no_context: * us unable to handle the page fault gracefully. */ out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if (psw_mask & PSW_PROBLEM_STATE) do_exit(SIGKILL); goto no_context; do_sigbus: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* * Send a sigbus, regardless of whether we were in kernel diff --git a/arch/s390x/tools/dasdfmt/dasdfmt.c b/arch/s390x/tools/dasdfmt/dasdfmt.c index 2820fc91d..560feff6b 100644 --- a/arch/s390x/tools/dasdfmt/dasdfmt.c +++ b/arch/s390x/tools/dasdfmt/dasdfmt.c @@ -477,7 +477,7 @@ do_format_dasd(char *dev_name,format_data_t format_params,int testmode, rc=stat(dev_name,&stat_buf); if (rc) { - ERRMSG_EXIT(EXIT_FAILURE,"%s: error occured during stat: " \ + ERRMSG_EXIT(EXIT_FAILURE,"%s: error occurred during stat: " \ "%s\n",prog_name,strerror(errno)); } else { if (!S_ISBLK(stat_buf.st_mode)) diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index 2bdcd75ea..e3a27f414 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -77,3 +77,4 @@ DECLARE_EXPORT(__ashldi3); /* needed by some modules */ EXPORT_SYMBOL(flush_dcache_page); #endif +EXPORT_SYMBOL(flush_tlb_page); diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 64007b236..1aaf5a04b 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -57,9 +57,9 @@ do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index e284fa65d..7d75f92b5 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -109,7 +109,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, if (in_interrupt() || !mm) goto no_context; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -151,7 +151,7 @@ good_area: goto out_of_memory; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return; /* @@ -159,7 +159,7 @@ good_area: * Fix it, but check if it's kernel or user first.. */ bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); if (user_mode(regs)) { tsk->thread.address = address; @@ -208,14 +208,14 @@ no_context: * us unable to handle the page fault gracefully. */ out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) do_exit(SIGKILL); goto no_context; do_sigbus: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* * Send a sigbus, regardless of whether we were in kernel diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig index 20c0782e7..79e281b96 100644 --- a/arch/sparc/defconfig +++ b/arch/sparc/defconfig @@ -105,8 +105,8 @@ CONFIG_SUN_AURORA=m # # CONFIG_SPARCAUDIO is not set # CONFIG_SPARCAUDIO_AMD7930 is not set -# CONFIG_SPARCAUDIO_CS4231 is not set # CONFIG_SPARCAUDIO_DBRI is not set +# CONFIG_SPARCAUDIO_CS4231 is not set # CONFIG_SPARCAUDIO_DUMMY is not set # @@ -126,7 +126,6 @@ CONFIG_BLK_DEV_NBD=m # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y @@ -266,6 +265,8 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set CONFIG_AFFS_FS=m diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c index cba111a71..32f418f99 100644 --- a/arch/sparc/kernel/ptrace.c +++ b/arch/sparc/kernel/ptrace.c @@ -305,7 +305,13 @@ asmlinkage void do_ptrace(struct pt_regs *regs) goto out; } #endif - if(!(child = find_task_by_pid(pid))) { + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + + if (!child) { pt_error_return(regs, ESRCH); goto out; } @@ -319,7 +325,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) * You'll never be able to kill the process. ;-) */ pt_error_return(regs, EPERM); - goto out; + goto out_tsk; } if((!child->dumpable || (current->uid != child->euid) || @@ -330,12 +336,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs) (!cap_issubset(child->cap_permitted, current->cap_permitted)) || (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) { pt_error_return(regs, EPERM); - goto out; + goto out_tsk; } /* the same process cannot be attached many times */ if (child->ptrace & PT_PTRACED) { pt_error_return(regs, EPERM); - goto out; + goto out_tsk; } child->ptrace |= PT_PTRACED; write_lock_irqsave(&tasklist_lock, flags); @@ -347,21 +353,21 @@ asmlinkage void do_ptrace(struct pt_regs *regs) write_unlock_irqrestore(&tasklist_lock, flags); send_sig(SIGSTOP, child, 1); pt_succ_return(regs, 0); - goto out; + goto out_tsk; } if (!(child->ptrace & PT_PTRACED)) { pt_error_return(regs, ESRCH); - goto out; + goto out_tsk; } if(child->state != TASK_STOPPED) { if(request != PTRACE_KILL) { pt_error_return(regs, ESRCH); - goto out; + goto out_tsk; } } if(child->p_pptr != current) { pt_error_return(regs, ESRCH); - goto out; + goto out_tsk; } switch(request) { case PTRACE_PEEKTEXT: /* read word at location addr. */ @@ -373,16 +379,16 @@ asmlinkage void do_ptrace(struct pt_regs *regs) pt_os_succ_return(regs, tmp, (long *)data); else pt_error_return(regs, EIO); - goto out; + goto out_tsk; } case PTRACE_PEEKUSR: read_sunos_user(regs, addr, child, (long *) data); - goto out; + goto out_tsk; case PTRACE_POKEUSR: write_sunos_user(regs, addr, child); - goto out; + goto out_tsk; case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKEDATA: { @@ -391,7 +397,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) pt_succ_return(regs, 0); else pt_error_return(regs, EIO); - goto out; + goto out_tsk; } case PTRACE_GETREGS: { @@ -402,7 +408,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) rval = verify_area(VERIFY_WRITE, pregs, sizeof(struct pt_regs)); if(rval) { pt_error_return(regs, -rval); - goto out; + goto out_tsk; } __put_user(cregs->psr, (&pregs->psr)); __put_user(cregs->pc, (&pregs->pc)); @@ -414,7 +420,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) #ifdef DEBUG_PTRACE printk ("PC=%x nPC=%x o7=%x\n", cregs->pc, cregs->npc, cregs->u_regs [15]); #endif - goto out; + goto out_tsk; } case PTRACE_SETREGS: { @@ -429,7 +435,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) i = verify_area(VERIFY_READ, pregs, sizeof(struct pt_regs)); if(i) { pt_error_return(regs, -i); - goto out; + goto out_tsk; } __get_user(psr, (&pregs->psr)); __get_user(pc, (&pregs->pc)); @@ -446,7 +452,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) for(i = 1; i < 16; i++) __get_user(cregs->u_regs[i], (&pregs->u_regs[i-1])); pt_succ_return(regs, 0); - goto out; + goto out_tsk; } case PTRACE_GETFPREGS: { @@ -466,7 +472,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) i = verify_area(VERIFY_WRITE, fps, sizeof(struct fps)); if(i) { pt_error_return(regs, -i); - goto out; + goto out_tsk; } for(i = 0; i < 32; i++) __put_user(child->thread.float_regs[i], (&fps->regs[i])); @@ -480,7 +486,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) __put_user(child->thread.fpqueue[i].insn, (&fps->fpq[i].insn)); } pt_succ_return(regs, 0); - goto out; + goto out_tsk; } case PTRACE_SETFPREGS: { @@ -500,7 +506,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) i = verify_area(VERIFY_READ, fps, sizeof(struct fps)); if(i) { pt_error_return(regs, -i); - goto out; + goto out_tsk; } copy_from_user(&child->thread.float_regs[0], &fps->regs[0], (32 * sizeof(unsigned long))); __get_user(child->thread.fsr, (&fps->fsr)); @@ -511,7 +517,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) __get_user(child->thread.fpqueue[i].insn, (&fps->fpq[i].insn)); } pt_succ_return(regs, 0); - goto out; + goto out_tsk; } case PTRACE_READTEXT: @@ -520,13 +526,13 @@ asmlinkage void do_ptrace(struct pt_regs *regs) if (res == data) { pt_succ_return(regs, 0); - goto out; + goto out_tsk; } /* Partial read is an IO failure */ if (res >= 0) res = -EIO; pt_error_return(regs, -res); - goto out; + goto out_tsk; } case PTRACE_WRITETEXT: @@ -535,13 +541,13 @@ asmlinkage void do_ptrace(struct pt_regs *regs) if (res == data) { pt_succ_return(regs, 0); - goto out; + goto out_tsk; } /* Partial write is an IO failure */ if (res >= 0) res = -EIO; pt_error_return(regs, -res); - goto out; + goto out_tsk; } case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */ @@ -550,12 +556,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_CONT: { /* restart after signal. */ if ((unsigned long) data > _NSIG) { pt_error_return(regs, EIO); - goto out; + goto out_tsk; } if (addr != 1) { if (addr & 3) { pt_error_return(regs, EINVAL); - goto out; + goto out_tsk; } #ifdef DEBUG_PTRACE printk ("Original: %08lx %08lx\n", child->thread.kregs->pc, child->thread.kregs->npc); @@ -580,7 +586,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) #endif wake_up_process(child); pt_succ_return(regs, 0); - goto out; + goto out_tsk; } /* @@ -591,19 +597,19 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_KILL: { if (child->state == TASK_ZOMBIE) { /* already dead */ pt_succ_return(regs, 0); - goto out; + goto out_tsk; } wake_up_process(child); child->exit_code = SIGKILL; pt_succ_return(regs, 0); - goto out; + goto out_tsk; } case PTRACE_SUNDETACH: { /* detach a process that was attached. */ unsigned long flags; if ((unsigned long) data > _NSIG) { pt_error_return(regs, EIO); - goto out; + goto out_tsk; } child->ptrace &= ~(PT_PTRACED|PT_TRACESYS); wake_up_process(child); @@ -614,15 +620,18 @@ asmlinkage void do_ptrace(struct pt_regs *regs) SET_LINKS(child); write_unlock_irqrestore(&tasklist_lock, flags); pt_succ_return(regs, 0); - goto out; + goto out_tsk; } /* PTRACE_DUMPCORE unsupported... */ default: pt_error_return(regs, EIO); - goto out; + goto out_tsk; } +out_tsk: + if (child) + free_task_struct(child); out: unlock_kernel(); } diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 498fdb26f..3b71c98e1 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.67 2000/11/30 08:37:31 anton Exp $ +/* $Id: sys_sparc.c,v 1.68 2001/03/24 09:36:10 davem Exp $ * linux/arch/sparc/kernel/sys_sparc.c * * This file contains various random system calls that @@ -236,9 +236,9 @@ static unsigned long do_mmap2(unsigned long addr, unsigned long len, if (flags & MAP_SHARED) current->thread.flags |= SPARC_FLAG_MMAPSHARED; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED); @@ -284,7 +284,7 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr, if (old_len > TASK_SIZE - PAGE_SIZE || new_len > TASK_SIZE - PAGE_SIZE) goto out; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); vma = find_vma(current->mm, addr); if (vma && (vma->vm_flags & VM_SHARED)) current->thread.flags |= SPARC_FLAG_MMAPSHARED; @@ -309,7 +309,7 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr, ret = do_mremap(addr, old_len, new_len, flags, new_addr); out_sem: current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); out: return ret; } diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index adaae6062..5a9b4752a 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos.c,v 1.132 2001/02/13 01:16:43 davem Exp $ +/* $Id: sys_sunos.c,v 1.133 2001/03/24 09:36:10 davem Exp $ * sys_sunos.c: SunOS specific syscall compatibility support. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -116,9 +116,9 @@ asmlinkage unsigned long sunos_mmap(unsigned long addr, unsigned long len, } flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); retval = do_mmap(file, addr, len, prot, flags, off); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if(!ret_type) retval = ((retval < PAGE_OFFSET) ? 0 : retval); @@ -145,7 +145,7 @@ asmlinkage int sunos_brk(unsigned long brk) unsigned long rlim; unsigned long newbrk, oldbrk; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); if(ARCH_SUN4C_SUN4) { if(brk >= 0x20000000 && brk < 0xe0000000) { goto out; @@ -208,7 +208,7 @@ asmlinkage int sunos_brk(unsigned long brk) do_brk(oldbrk, newbrk-oldbrk); retval = 0; out: - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); return retval; } diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c index 1521d3246..764bca89b 100644 --- a/arch/sparc/mm/fault.c +++ b/arch/sparc/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.118 2000/12/29 07:52:41 anton Exp $ +/* $Id: fault.c,v 1.119 2001/03/24 09:36:10 davem Exp $ * fault.c: Page fault handlers for the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -224,7 +224,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, if (in_interrupt() || !mm) goto no_context; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); /* * The kernel referencing a bad kernel pointer can lock up @@ -274,7 +274,7 @@ good_area: default: goto out_of_memory; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return; /* @@ -282,7 +282,7 @@ good_area: * Fix it, but check if it's kernel or user first.. */ bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ @@ -338,14 +338,14 @@ no_context: * us unable to handle the page fault gracefully. */ out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if (from_user) do_exit(SIGKILL); goto no_context; do_sigbus: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; @@ -479,7 +479,7 @@ inline void force_user_fault(unsigned long address, int write) printk("wf<pid=%d,wr=%d,addr=%08lx>\n", tsk->pid, write, address); #endif - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if(!vma) goto bad_area; @@ -500,10 +500,10 @@ good_area: } if (!handle_mm_fault(mm, vma, address, write)) goto do_sigbus; - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return; bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); #if 0 printk("Window whee %s [%d]: segfaults at %08lx\n", tsk->comm, tsk->pid, address); @@ -518,7 +518,7 @@ bad_area: return; do_sigbus: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index d27495bd6..89807b38a 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -1,10 +1,10 @@ -/* $Id: init.c,v 1.96 2000/11/30 08:51:50 anton Exp $ +/* $Id: init.c,v 1.97 2001/02/26 02:57:34 anton Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1995 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com) + * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au) */ #include <linux/config.h> @@ -53,7 +53,7 @@ extern unsigned int sparc_ramdisk_size; unsigned long highstart_pfn, highend_pfn; unsigned long totalram_pages; -static unsigned long totalhigh_pages; +unsigned long totalhigh_pages; /* * BAD_PAGE is the page that is used for page faults when linux @@ -134,42 +134,79 @@ void __init sparc_context_init(int numctx) #define DEBUG_BOOTMEM extern unsigned long cmdline_memory_size; -extern unsigned long last_valid_pfn; +unsigned long last_valid_pfn; + +unsigned long calc_highpages(void) +{ + int i; + int nr = 0; + + for (i = 0; sp_banks[i].num_bytes != 0; i++) { + unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT; + unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT; + + if (end_pfn <= max_low_pfn) + continue; + + if (start_pfn < max_low_pfn) + start_pfn = max_low_pfn; + + nr += end_pfn - start_pfn; + } + + return nr; +} + +unsigned long calc_max_low_pfn(void) +{ + int i; + unsigned long tmp = (SRMMU_MAXMEM >> PAGE_SHIFT); + unsigned long curr_pfn, last_pfn; + + last_pfn = (sp_banks[0].base_addr + sp_banks[0].num_bytes) >> PAGE_SHIFT; + for (i = 1; sp_banks[i].num_bytes != 0; i++) { + curr_pfn = sp_banks[i].base_addr >> PAGE_SHIFT; -void __init bootmem_init(void) + if (curr_pfn >= tmp) { + if (last_pfn < tmp) + tmp = last_pfn; + break; + } + + last_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT; + } + + return tmp; +} + +unsigned long __init bootmem_init(unsigned long *pages_avail) { unsigned long bootmap_size, start_pfn, max_pfn; unsigned long end_of_phys_memory = 0UL; - unsigned long bootmap_pfn; + unsigned long bootmap_pfn, bytes_avail, size; int i; - /* XXX It is a bit ambiguous here, whether we should - * XXX treat the user specified mem=xxx as total wanted - * XXX physical memory, or as a limit to the upper - * XXX physical address we allow. For now it is the - * XXX latter. -DaveM - */ #ifdef DEBUG_BOOTMEM prom_printf("bootmem_init: Scan sp_banks, "); #endif + bytes_avail = 0UL; for (i = 0; sp_banks[i].num_bytes != 0; i++) { end_of_phys_memory = sp_banks[i].base_addr + sp_banks[i].num_bytes; + bytes_avail += sp_banks[i].num_bytes; if (cmdline_memory_size) { - if (end_of_phys_memory > cmdline_memory_size) { - if (cmdline_memory_size < sp_banks[i].base_addr) { - end_of_phys_memory = - sp_banks[i-1].base_addr + - sp_banks[i-1].num_bytes; + if (bytes_avail > cmdline_memory_size) { + unsigned long slack = bytes_avail - cmdline_memory_size; + + bytes_avail -= slack; + end_of_phys_memory -= slack; + + sp_banks[i].num_bytes -= slack; + if (sp_banks[i].num_bytes == 0) { sp_banks[i].base_addr = 0xdeadbeef; - sp_banks[i].num_bytes = 0; } else { - sp_banks[i].num_bytes -= - (end_of_phys_memory - - cmdline_memory_size); - end_of_phys_memory = cmdline_memory_size; - sp_banks[++i].base_addr = 0xdeadbeef; - sp_banks[i].num_bytes = 0; + sp_banks[i+1].num_bytes = 0; + sp_banks[i+1].base_addr = 0xdeadbeef; } break; } @@ -195,9 +232,9 @@ void __init bootmem_init(void) highstart_pfn = highend_pfn = max_pfn; if (max_low_pfn > (SRMMU_MAXMEM >> PAGE_SHIFT)) { - highstart_pfn = max_low_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT); - printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", - (highend_pfn - highstart_pfn) >> (20-PAGE_SHIFT)); + highstart_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT); + max_low_pfn = calc_max_low_pfn(); + printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", calc_highpages()); } #ifdef CONFIG_BLK_DEV_INITRD @@ -225,13 +262,14 @@ void __init bootmem_init(void) prom_printf("init_bootmem(spfn[%lx],bpfn[%lx],mlpfn[%lx])\n", start_pfn, bootmap_pfn, max_low_pfn); #endif - bootmap_size = init_bootmem(bootmap_pfn, max_low_pfn); + bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, phys_base>>PAGE_SHIFT, max_low_pfn); /* Now register the available physical memory with the * allocator. */ + *pages_avail = 0; for (i = 0; sp_banks[i].num_bytes != 0; i++) { - unsigned long curr_pfn, last_pfn, size; + unsigned long curr_pfn, last_pfn; curr_pfn = sp_banks[i].base_addr >> PAGE_SHIFT; if (curr_pfn >= max_low_pfn) @@ -249,7 +287,7 @@ void __init bootmem_init(void) continue; size = (last_pfn - curr_pfn) << PAGE_SHIFT; - + *pages_avail += last_pfn - curr_pfn; #ifdef DEBUG_BOOTMEM prom_printf("free_bootmem: base[%lx] size[%lx]\n", sp_banks[i].base_addr, @@ -259,29 +297,42 @@ void __init bootmem_init(void) size); } - /* Reserve the kernel text/data/bss, the bootmem bitmap and initrd. */ -#ifdef DEBUG_BOOTMEM #ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start) + if (initrd_start) { + size = initrd_end - initrd_start; +#ifdef DEBUG_BOOTMEM prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", - initrd_start, initrd_end - initrd_start); + initrd_start, size); #endif - prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", - phys_base, (start_pfn << PAGE_SHIFT) - phys_base); - prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", - (bootmap_pfn << PAGE_SHIFT), bootmap_size); -#endif -#ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start) { - reserve_bootmem(initrd_start, initrd_end - initrd_start); + /* Reserve the initrd image area. */ + reserve_bootmem(initrd_start, size); + *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; + initrd_start += PAGE_OFFSET; initrd_end += PAGE_OFFSET; } #endif - reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) - phys_base); - reserve_bootmem((bootmap_pfn << PAGE_SHIFT), bootmap_size); + /* Reserve the kernel text/data/bss. */ + size = (start_pfn << PAGE_SHIFT) - phys_base; +#ifdef DEBUG_BOOTMEM + prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", phys_base, size); +#endif + reserve_bootmem(phys_base, size); + *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; + + /* Reserve the bootmem map. We do not account for it + * in pages_avail because we will release that memory + * in free_all_bootmem. + */ + size = bootmap_size; +#ifdef DEBUG_BOOTMEM + prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", + (bootmap_pfn << PAGE_SHIFT), size); +#endif + reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size); + *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; - last_valid_pfn = max_pfn; + return max_pfn; } /* @@ -293,8 +344,6 @@ extern void sun4c_paging_init(void); extern void srmmu_paging_init(void); extern void device_scan(void); -unsigned long last_valid_pfn; - void __init paging_init(void) { switch(sparc_cpu_model) { @@ -359,71 +408,6 @@ static void __init taint_real_pages(void) } } -void __init free_mem_map_range(struct page *first, struct page *last) -{ - first = (struct page *) PAGE_ALIGN((unsigned long)first); - last = (struct page *) ((unsigned long)last & PAGE_MASK); -#ifdef DEBUG_BOOTMEM - prom_printf("[%p,%p] ", first, last); -#endif - while (first < last) { - ClearPageReserved(virt_to_page(first)); - set_page_count(virt_to_page(first), 1); - free_page((unsigned long)first); - totalram_pages++; - num_physpages++; - - first = (struct page *)((unsigned long)first + PAGE_SIZE); - } -} - -/* Walk through holes in sp_banks regions, if the mem_map array - * areas representing those holes consume a page or more, free - * up such pages. This helps a lot on machines where physical - * ram is configured such that it begins at some hugh value. - * - * The sp_banks array is sorted by base address. - */ -void __init free_unused_mem_map(void) -{ - int i; - -#ifdef DEBUG_BOOTMEM - prom_printf("free_unused_mem_map: "); -#endif - for (i = 0; sp_banks[i].num_bytes; i++) { - if (i == 0) { - struct page *first, *last; - - first = mem_map; - last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT]; - free_mem_map_range(first, last); - } else { - struct page *first, *last; - unsigned long prev_end; - - prev_end = sp_banks[i-1].base_addr + - sp_banks[i-1].num_bytes; - prev_end = PAGE_ALIGN(prev_end); - first = &mem_map[prev_end >> PAGE_SHIFT]; - last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT]; - - free_mem_map_range(first, last); - - if (!sp_banks[i+1].num_bytes) { - prev_end = sp_banks[i].base_addr + - sp_banks[i].num_bytes; - first = &mem_map[prev_end >> PAGE_SHIFT]; - last = &mem_map[last_valid_pfn]; - free_mem_map_range(first, last); - } - } - } -#ifdef DEBUG_BOOTMEM - prom_printf("\n"); -#endif -} - void map_high_region(unsigned long start_pfn, unsigned long end_pfn) { unsigned long tmp; @@ -458,9 +442,8 @@ void __init mem_init(void) /* Saves us work later. */ memset((void *)&empty_zero_page, 0, PAGE_SIZE); - i = last_valid_pfn >> (8 + 5); + i = last_valid_pfn >> ((20 - PAGE_SHIFT) + 5); i += 1; - sparc_valid_addr_bitmap = (unsigned long *) __alloc_bootmem(i << 2, SMP_CACHE_BYTES, 0UL); @@ -472,7 +455,7 @@ void __init mem_init(void) taint_real_pages(); - max_mapnr = last_valid_pfn; + max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT); high_memory = __va(max_low_pfn << PAGE_SHIFT); #ifdef DEBUG_BOOTMEM @@ -480,10 +463,6 @@ void __init mem_init(void) #endif num_physpages = totalram_pages = free_all_bootmem(); -#if 0 - free_unused_mem_map(); -#endif - for (i = 0; sp_banks[i].num_bytes != 0; i++) { unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT; unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT; @@ -513,19 +492,6 @@ void __init mem_init(void) initpages << (PAGE_SHIFT-10), totalhigh_pages << (PAGE_SHIFT-10), (unsigned long)PAGE_OFFSET, (last_valid_pfn << PAGE_SHIFT)); - - /* NOTE NOTE NOTE NOTE - * Please keep track of things and make sure this - * always matches the code in mm/page_alloc.c -DaveM - */ - i = nr_free_pages() >> 7; - if (i < 48) - i = 48; - if (i > 256) - i = 256; - freepages.min = i; - freepages.low = i << 1; - freepages.high = freepages.low + i; } void free_initmem (void) diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index a5b2b117b..e2b6116ff 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.226 2001/02/13 01:16:44 davem Exp $ +/* $Id: srmmu.c,v 1.228 2001/03/16 06:56:20 davem Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1124,6 +1124,15 @@ static unsigned long __init map_spbank(unsigned long vbase, int sp_entry) unsigned long pstart = (sp_banks[sp_entry].base_addr & SRMMU_PGDIR_MASK); unsigned long vstart = (vbase & SRMMU_PGDIR_MASK); unsigned long vend = SRMMU_PGDIR_ALIGN(vbase + sp_banks[sp_entry].num_bytes); + /* Map "low" memory only */ + const unsigned long min_vaddr = PAGE_OFFSET; + const unsigned long max_vaddr = PAGE_OFFSET + SRMMU_MAXMEM; + + if (vstart < min_vaddr || vstart >= max_vaddr) + return vstart; + + if (vend > max_vaddr || vend < min_vaddr) + vend = max_vaddr; while(vstart < vend) { do_large_mapping(vstart, pstart); @@ -1159,10 +1168,11 @@ static inline void map_kernel(void) extern void sparc_context_init(int); extern int linux_num_cpus; +extern unsigned long totalhigh_pages; void (*poke_srmmu)(void) __initdata = NULL; -extern void bootmem_init(void); +extern unsigned long bootmem_init(unsigned long *pages_avail); extern void sun_serial_setup(void); void __init srmmu_paging_init(void) @@ -1172,6 +1182,7 @@ void __init srmmu_paging_init(void) pgd_t *pgd; pmd_t *pmd; pte_t *pte; + unsigned long pages_avail; sparc_iomap.start = SUN4M_IOBASE_VADDR; /* 16MB of IOSPACE on all sun4m's. */ @@ -1196,7 +1207,8 @@ void __init srmmu_paging_init(void) prom_halt(); } - bootmem_init(); + pages_avail = 0; + last_valid_pfn = bootmem_init(&pages_avail); srmmu_nocache_init(); srmmu_inherit_prom_mappings(0xfe400000,(LINUX_OPPROM_ENDVM-PAGE_SIZE)); @@ -1245,11 +1257,25 @@ void __init srmmu_paging_init(void) kmap_init(); { - unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0}; + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long zholes_size[MAX_NR_ZONES]; + unsigned long npages; + int znum; + + for (znum = 0; znum < MAX_NR_ZONES; znum++) + zones_size[znum] = zholes_size[znum] = 0; + + npages = max_low_pfn - (phys_base >> PAGE_SHIFT); + + zones_size[ZONE_DMA] = npages; + zholes_size[ZONE_DMA] = npages - pages_avail; + + npages = highend_pfn - max_low_pfn; + zones_size[ZONE_HIGHMEM] = npages; + zholes_size[ZONE_HIGHMEM] = npages - calc_highpages(); - zones_size[ZONE_DMA] = max_low_pfn; - zones_size[ZONE_HIGHMEM] = highend_pfn - max_low_pfn; - free_area_init(zones_size); + free_area_init_node(0, NULL, NULL, zones_size, + phys_base, zholes_size); } } diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index ef5157b05..91a1d571e 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -1,4 +1,4 @@ -/* $Id: sun4c.c,v 1.202 2000/12/01 03:17:31 anton Exp $ +/* $Id: sun4c.c,v 1.205 2001/03/16 06:57:41 davem Exp $ * sun4c.c: Doing in software what should be done in hardware. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -15,6 +15,7 @@ #include <linux/mm.h> #include <linux/init.h> #include <linux/bootmem.h> +#include <linux/highmem.h> #include <asm/scatterlist.h> #include <asm/page.h> @@ -31,6 +32,7 @@ #include <asm/openprom.h> #include <asm/mmu_context.h> #include <asm/sun4paddr.h> +#include <asm/highmem.h> /* Because of our dynamic kernel TLB miss strategy, and how * our DVMA mapping allocation works, you _MUST_: @@ -2432,7 +2434,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p extern void sparc_context_init(int); extern unsigned long end; -extern void bootmem_init(void); +extern unsigned long bootmem_init(unsigned long *pages_avail); extern unsigned long last_valid_pfn; extern void sun_serial_setup(void); @@ -2441,13 +2443,14 @@ void __init sun4c_paging_init(void) int i, cnt; unsigned long kernel_end, vaddr; extern struct resource sparc_iomap; - unsigned long end_pfn; + unsigned long end_pfn, pages_avail; kernel_end = (unsigned long) &end; kernel_end += (SUN4C_REAL_PGDIR_SIZE * 4); kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end); - bootmem_init(); + pages_avail = 0; + last_valid_pfn = bootmem_init(&pages_avail); end_pfn = last_valid_pfn; /* This does not logically belong here, but we need to @@ -2488,10 +2491,25 @@ void __init sun4c_paging_init(void) sparc_context_init(num_contexts); { - unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0}; + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long zholes_size[MAX_NR_ZONES]; + unsigned long npages; + int znum; - zones_size[ZONE_DMA] = end_pfn; - free_area_init(zones_size); + for (znum = 0; znum < MAX_NR_ZONES; znum++) + zones_size[znum] = zholes_size[znum] = 0; + + npages = max_low_pfn - (phys_base >> PAGE_SHIFT); + + zones_size[ZONE_DMA] = npages; + zholes_size[ZONE_DMA] = npages - pages_avail; + + npages = highend_pfn - max_low_pfn; + zones_size[ZONE_HIGHMEM] = npages; + zholes_size[ZONE_HIGHMEM] = npages - calc_highpages(); + + free_area_init_node(0, NULL, NULL, zones_size, + phys_base, zholes_size); } cnt = 0; diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index 2d67b5e54..888b96c6f 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.130 2001/01/18 04:47:44 davem Exp $ +# $Id: config.in,v 1.136 2001/03/24 06:04:24 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -47,6 +47,9 @@ define_bool CONFIG_SUN_CONSOLE y define_bool CONFIG_SUN_AUXIO y define_bool CONFIG_SUN_IO y bool 'PCI support' CONFIG_PCI +if [ "$CONFIG_PCI" = "y" ] ; then + define_bool CONFIG_RTC y +fi source drivers/pci/Config.in tristate 'Openprom tree appears in /proc/openprom' CONFIG_SUN_OPENPROMFS @@ -74,6 +77,7 @@ if [ "$CONFIG_PCI" = "y" ]; then tristate 'SUNW, envctrl support' CONFIG_ENVCTRL tristate '7-Segment Display support' CONFIG_DISPLAY7SEG tristate 'CP1XXX Hardware Watchdog support' CONFIG_WATCHDOG_CP1XXX + tristate 'RIO Hardware Watchdog support' CONFIG_WATCHDOG_RIO fi endmenu @@ -165,12 +169,14 @@ if [ "$CONFIG_SCSI" != "n" ]; then dep_tristate 'PTI Qlogic, ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI if [ "$CONFIG_PCI" != "n" ]; then - dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI - if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then - bool ' Enable tagged command queueing (TCQ) by default' CONFIG_AIC7XXX_TAGGED_QUEUEING - int ' Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8 - bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS - int ' Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5 + source drivers/scsi/aic7xxx/Config.in + if [ "$CONFIG_SCSI_AIC7XXX" != "y" ]; then + dep_tristate 'Old Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX_OLD $CONFIG_SCSI + if [ "$CONFIG_SCSI_AIC7XXX_OLD" != "n" ]; then + bool ' Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT + int ' Maximum number of TCQ commands per device' CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE 8 + bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_OLD_PROC_STATS + fi fi dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI dep_tristate 'SYM53C8XX SCSI support' CONFIG_SCSI_SYM53C8XX $CONFIG_SCSI @@ -197,8 +203,6 @@ if [ "$CONFIG_SCSI" != "n" ]; then fi endmenu -source drivers/message/fusion/Config.in - source drivers/fc4/Config.in if [ "$CONFIG_PCI" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then @@ -284,6 +288,7 @@ if [ "$CONFIG_NET" = "y" ]; then bool ' Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I fi tristate 'SysKonnect SK-98xx support' CONFIG_SK98LIN + tristate 'Sun GEM support' CONFIG_SUNGEM fi tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS endmenu @@ -325,8 +330,12 @@ bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM dep_tristate ' Creator/Creator3D' CONFIG_DRM_FFB $CONFIG_DRM endmenu +source drivers/input/Config.in + source fs/Config.in +source drivers/usb/Config.in + mainmenu_option next_comment comment 'Watchdog' diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index d80f93cf6..beb7ee7ff 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -38,6 +38,7 @@ CONFIG_SUN_CONSOLE=y CONFIG_SUN_AUXIO=y CONFIG_SUN_IO=y CONFIG_PCI=y +CONFIG_RTC=y CONFIG_PCI_NAMES=y CONFIG_SUN_OPENPROMFS=m CONFIG_NET=y @@ -70,6 +71,7 @@ CONFIG_PRINTER=m CONFIG_ENVCTRL=m CONFIG_DISPLAY7SEG=m CONFIG_WATCHDOG_CP1XXX=m +CONFIG_WATCHDOG_RIO=m # # Console drivers @@ -125,8 +127,8 @@ CONFIG_SUN_AURORA=m # # Linux/SPARC audio subsystem (EXPERIMENTAL) # -CONFIG_SPARCAUDIO=y -CONFIG_SPARCAUDIO_CS4231=y +CONFIG_SPARCAUDIO=m +CONFIG_SPARCAUDIO_CS4231=m # CONFIG_SPARCAUDIO_DUMMY is not set # @@ -151,7 +153,6 @@ CONFIG_BLK_DEV_NBD=m # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set @@ -305,10 +306,12 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SUNESP=y CONFIG_SCSI_QLOGICPTI=m CONFIG_SCSI_AIC7XXX=m -CONFIG_AIC7XXX_TAGGED_QUEUEING=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 -CONFIG_AIC7XXX_PROC_STATS=y -CONFIG_AIC7XXX_RESET_DELAY=5 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 +CONFIG_AIC7XXX_RESET_DELAY=5000 +CONFIG_SCSI_AIC7XXX_OLD=m +CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y +CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_OLD_PROC_STATS=y CONFIG_SCSI_NCR53C8XX=m CONFIG_SCSI_SYM53C8XX=y CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=4 @@ -318,7 +321,7 @@ CONFIG_SCSI_NCR53C8XX_SYNC=40 # CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set # CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set CONFIG_SCSI_QLOGIC_ISP=m -CONFIG_SCSI_QLOGIC_FC=m +CONFIG_SCSI_QLOGIC_FC=y # # Fibre Channel support @@ -388,6 +391,7 @@ CONFIG_ADAPTEC_STARFIRE=m CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I is not set CONFIG_SK98LIN=m +CONFIG_SUNGEM=y CONFIG_MYRI_SBUS=m CONFIG_FDDI=y CONFIG_SKFP=m @@ -411,6 +415,17 @@ CONFIG_DRM=y CONFIG_DRM_FFB=m # +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# # File systems # # CONFIG_QUOTA is not set @@ -524,6 +539,99 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_UTF8 is not set # +# USB support +# +CONFIG_USB=y +CONFIG_USB_DEBUG=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +CONFIG_USB_BLUETOOTH=m +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_WACOM=m + +# +# USB Imaging devices +# +CONFIG_USB_DC2XX=m +CONFIG_USB_MDC800=m +CONFIG_USB_SCANNER=m +CONFIG_USB_MICROTEK=m + +# +# USB Multimedia devices +# +CONFIG_USB_IBMCAM=m +CONFIG_USB_OV511=m +CONFIG_USB_DSBR=m +CONFIG_USB_DABUSB=m + +# +# USB Network adaptors +# +CONFIG_USB_PLUSB=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_NET1080=m + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_DEBUG is not set +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_OMNINET=m + +# +# USB misc drivers +# +CONFIG_USB_RIO500=m + +# # Watchdog # # CONFIG_SOFT_WATCHDOG is not set diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 8648bb190..218242631 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.63 2000/12/14 22:57:25 davem Exp $ +# $Id: Makefile,v 1.64 2001/02/28 05:59:45 davem Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -27,7 +27,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ power.o sbus.o iommu_common.o sparc64_ksyms.o obj-$(CONFIG_PCI) += ebus.o pci_common.o pci_iommu.o \ - pci_psycho.o pci_sabre.o + pci_psycho.o pci_sabre.o pci_schizo.o obj-$(CONFIG_SMP) += smp.o trampoline.o obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o ioctl32.o obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c index cc26817b4..10787f22f 100644 --- a/arch/sparc64/kernel/auxio.c +++ b/arch/sparc64/kernel/auxio.c @@ -18,6 +18,7 @@ #include <asm/sbus.h> #include <asm/ebus.h> #include <asm/fhc.h> +#include <asm/spitfire.h> #include <asm/starfire.h> /* Probe and map in the Auxiliary I/O register */ @@ -56,7 +57,7 @@ found_sdev: return; } #endif - if(central_bus || this_is_starfire) { + if (central_bus || this_is_starfire || (tlb_type == cheetah)) { auxio_register = 0UL; return; } diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c index bda2fb6a5..314230ef2 100644 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ b/arch/sparc64/kernel/binfmt_aout32.c @@ -277,24 +277,24 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs) goto beyond_if; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (error != N_TXTADDR(ex)) { send_sig(SIGKILL, current, 0); return error; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset + ex.a_text); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (error != N_DATADDR(ex)) { send_sig(SIGKILL, current, 0); return error; @@ -318,7 +318,8 @@ beyond_if: unsigned long pgd_cache; pgd_cache = ((unsigned long)current->mm->pgd[0])<<11UL; - __asm__ __volatile__("stxa\t%0, [%1] %2" + __asm__ __volatile__("stxa\t%0, [%1] %2\n\t" + "membar #Sync" : /* no outputs */ : "r" (pgd_cache), "r" (TSB_REG), "i" (ASI_DMMU)); @@ -368,12 +369,12 @@ static int load_aout32_library(struct file *file) start_addr = ex.a_entry & 0xfffff000; /* Now use mmap to map the library into memory. */ - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap(file, start_addr, ex.a_text + ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, N_TXTOFF(ex)); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr) goto out; diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c index 8e1a0367c..a3bf89bb2 100644 --- a/arch/sparc64/kernel/cpu.c +++ b/arch/sparc64/kernel/cpu.c @@ -34,7 +34,8 @@ struct cpu_fp_info linux_sparc_fpu[] = { { 0x22, 0x10, 0, "UltraSparc II integrated FPU"}, { 0x17, 0x11, 0, "UltraSparc II integrated FPU"}, { 0x17, 0x12, 0, "UltraSparc IIi integrated FPU"}, - { 0x17, 0x14, 0, "UltraSparc III integrated FPU"}, + { 0x17, 0x13, 0, "UltraSparc IIe integrated FPU"}, + { 0x3e, 0x14, 0, "UltraSparc III integrated FPU"}, }; #define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info)) @@ -44,7 +45,8 @@ struct cpu_iu_info linux_sparc_chips[] = { { 0x22, 0x10, "TI UltraSparc II (BlackBird)"}, { 0x17, 0x11, "TI UltraSparc II (BlackBird)"}, { 0x17, 0x12, "TI UltraSparc IIi"}, - { 0x17, 0x14, "TI UltraSparc III (Cheetah)"}, /* A guess... */ + { 0x17, 0x13, "TI UltraSparc IIe"}, + { 0x3e, 0x14, "TI UltraSparc III (Cheetah)"}, }; #define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info)) diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c index be8771985..849a44c87 100644 --- a/arch/sparc64/kernel/devices.c +++ b/arch/sparc64/kernel/devices.c @@ -13,6 +13,7 @@ #include <asm/oplib.h> #include <asm/system.h> #include <asm/smp.h> +#include <asm/spitfire.h> struct prom_cpuinfo linux_cpus[64] __initdata = { { 0 } }; unsigned prom_cpu_nodes[64]; @@ -50,8 +51,14 @@ void __init device_scan(void) if(strcmp(node_str, "cpu") == 0) { cpu_nds[cpu_ctr] = scan; linux_cpus[cpu_ctr].prom_node = scan; - prom_getproperty(scan, "upa-portid", - (char *) &thismid, sizeof(thismid)); + thismid = 0; + if (tlb_type == spitfire) { + prom_getproperty(scan, "upa-portid", + (char *) &thismid, sizeof(thismid)); + } else if (tlb_type == cheetah) { + prom_getproperty(scan, "portid", + (char *) &thismid, sizeof(thismid)); + } linux_cpus[cpu_ctr].mid = thismid; printk("Found CPU %d (node=%08x,mid=%d)\n", cpu_ctr, (unsigned) scan, thismid); diff --git a/arch/sparc64/kernel/dtlb_base.S b/arch/sparc64/kernel/dtlb_base.S index 80c74aa18..f3a32d714 100644 --- a/arch/sparc64/kernel/dtlb_base.S +++ b/arch/sparc64/kernel/dtlb_base.S @@ -1,4 +1,4 @@ -/* $Id: dtlb_base.S,v 1.8 2000/11/10 08:28:45 davem Exp $ +/* $Id: dtlb_base.S,v 1.9 2001/03/22 00:12:32 davem Exp $ * dtlb_base.S: Front end to DTLB miss replacement strategy. * This is included directly into the trap table. * @@ -10,8 +10,6 @@ #define VPTE_SHIFT (PAGE_SHIFT - 3) #define KERN_HIGHBITS ((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000) #define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W) -#define KERN_LOWBITS_IO (_PAGE_E | _PAGE_P | _PAGE_W) -#define KERN_IOBITS (KERN_LOWBITS ^ KERN_LOWBITS_IO) /* %g1 TLB_SFSR (%g1 + %g1 == TLB_TAG_ACCESS) * %g2 (KERN_HIGHBITS | KERN_LOWBITS) @@ -94,5 +92,3 @@ #undef VPTE_SHIFT #undef KERN_HIGHBITS #undef KERN_LOWBITS -#undef KERN_LOWBITS_IO -#undef KERN_IOBITS diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index 6dbe45a6c..a1e633353 100644 --- a/arch/sparc64/kernel/ebus.c +++ b/arch/sparc64/kernel/ebus.c @@ -1,4 +1,4 @@ -/* $Id: ebus.c,v 1.54 2001/02/13 01:16:44 davem Exp $ +/* $Id: ebus.c,v 1.60 2001/03/15 02:11:09 davem Exp $ * ebus.c: PCI to EBus bridge device. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -25,6 +25,7 @@ struct linux_ebus *ebus_chain = 0; #ifdef CONFIG_SUN_AUXIO extern void auxio_probe(void); #endif +extern void rs_init(void); static inline void *ebus_alloc(size_t size) { @@ -159,7 +160,7 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg, struct pci_controller_info *p = pbm->parent; if (ebus_intmap_match(dev->bus, preg, &irqs[i]) != -1) { - dev->irqs[i] = p->irq_build(p, + dev->irqs[i] = p->irq_build(pbm, dev->bus->self, irqs[i]); } else { @@ -200,7 +201,10 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev) dev->num_addrs = len / sizeof(struct linux_prom_registers); for (i = 0; i < dev->num_addrs; i++) { - n = (regs[i].which_io - 0x10) >> 2; + if (dev->bus->is_rio == 0) + n = (regs[i].which_io - 0x10) >> 2; + else + n = regs[i].which_io; dev->resource[i].start = dev->bus->self->resource[n].start; dev->resource[i].start += (unsigned long)regs[i].phys_addr; @@ -222,7 +226,7 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev) struct pci_controller_info *p = pbm->parent; if (ebus_intmap_match(dev->bus, ®s[0], &irqs[i]) != -1) { - dev->irqs[i] = p->irq_build(p, + dev->irqs[i] = p->irq_build(pbm, dev->bus->self, irqs[i]); } else { @@ -269,14 +273,19 @@ void __init ebus_init(void) struct linux_ebus *ebus; struct pci_dev *pdev; struct pcidev_cookie *cookie; - int nd, ebusnd; + int nd, ebusnd, is_rio; int num_ebus = 0; if (!pci_present()) return; + is_rio = 0; pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0); if (!pdev) { + pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_RIO_EBUS, 0); + is_rio = 1; + } + if (!pdev) { printk("ebus: No EBus's found.\n"); return; } @@ -286,6 +295,7 @@ void __init ebus_init(void) ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus)); ebus->next = 0; + ebus->is_rio = is_rio; while (ebusnd) { /* SUNW,pci-qfe uses four empty ebuses on it. @@ -295,8 +305,16 @@ void __init ebus_init(void) we'd have to tweak with the ebus_chain in the runtime after initialization. -jj */ if (!prom_getchild (ebusnd)) { + struct pci_dev *orig_pdev = pdev; + + is_rio = 0; pdev = pci_find_device(PCI_VENDOR_ID_SUN, - PCI_DEVICE_ID_SUN_EBUS, pdev); + PCI_DEVICE_ID_SUN_EBUS, orig_pdev); + if (!pdev) { + pdev = pci_find_device(PCI_VENDOR_ID_SUN, + PCI_DEVICE_ID_SUN_RIO_EBUS, orig_pdev); + is_rio = 1; + } if (!pdev) { if (ebus == ebus_chain) { ebus_chain = NULL; @@ -305,7 +323,7 @@ void __init ebus_init(void) } break; } - + ebus->is_rio = is_rio; cookie = pdev->sysdata; ebusnd = cookie->prom_node; continue; @@ -346,10 +364,20 @@ void __init ebus_init(void) next_ebus: printk("\n"); - pdev = pci_find_device(PCI_VENDOR_ID_SUN, - PCI_DEVICE_ID_SUN_EBUS, pdev); - if (!pdev) - break; + { + struct pci_dev *orig_pdev = pdev; + + is_rio = 0; + pdev = pci_find_device(PCI_VENDOR_ID_SUN, + PCI_DEVICE_ID_SUN_EBUS, orig_pdev); + if (!pdev) { + pdev = pci_find_device(PCI_VENDOR_ID_SUN, + PCI_DEVICE_ID_SUN_RIO_EBUS, orig_pdev); + is_rio = 1; + } + if (!pdev) + break; + } cookie = pdev->sysdata; ebusnd = cookie->prom_node; @@ -357,9 +385,11 @@ void __init ebus_init(void) ebus->next = ebus_alloc(sizeof(struct linux_ebus)); ebus = ebus->next; ebus->next = 0; + ebus->is_rio = is_rio; ++num_ebus; } + rs_init(); #ifdef CONFIG_SUN_AUXIO auxio_probe(); #endif diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index fd6096ec5..9aed69e26 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.120 2000/09/08 13:58:12 jj Exp $ +/* $Id: entry.S,v 1.127 2001/03/23 07:56:30 davem Exp $ * arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points. * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -42,13 +42,29 @@ sparc64_vpte_patchme2: /* This is trivial with the new code... */ .globl do_fpdis do_fpdis: - ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g5 ! Load Group sethi %hi(TSTATE_PEF), %g4 ! IEU0 + rdpr %tstate, %g5 + andcc %g5, %g4, %g0 + be,pt %xcc, 1f + nop + rd %fprs, %g5 + andcc %g5, FPRS_FEF, %g0 + be,pt %xcc, 1f + nop + + /* Legal state when DCR_IFPOE is set in Cheetah %dcr. */ + sethi %hi(109f), %g7 + ba,pt %xcc, etrap +109: or %g7, %lo(109b), %g7 + add %g0, %g0, %g0 + ba,a,pt %xcc, rtrap_clr_l6 + +1: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g5 ! Load Group wr %g0, FPRS_FEF, %fprs ! LSU Group+4bubbles andcc %g5, FPRS_FEF, %g0 ! IEU1 Group be,a,pt %icc, 1f ! CTI clr %g7 ! IEU0 - ldub [%g6 + AOFF_task_thread + AOFF_thread_gsr], %g7 ! Load Group + ldx [%g6 + AOFF_task_thread + AOFF_thread_gsr], %g7 ! Load Group 1: andcc %g5, FPRS_DL, %g0 ! IEU1 bne,pn %icc, 2f ! CTI fzero %f0 ! FPA @@ -92,10 +108,9 @@ do_fpdis: ldxa [%g3] ASI_DMMU, %g5 add %g6, AOFF_task_fpregs + 0xc0, %g2 stxa %g0, [%g3] ASI_DMMU + membar #Sync faddd %f0, %f2, %f8 fmuld %f0, %f2, %f10 - flush %g6 - membar #StoreLoad | #LoadLoad ldda [%g1] ASI_BLK_S, %f32 ! grrr, where is ASI_BLK_NUCLEUS 8-( ldda [%g2] ASI_BLK_S, %f48 faddd %f0, %f2, %f12 @@ -118,11 +133,10 @@ do_fpdis: ldxa [%g3] ASI_DMMU, %g5 add %g6, AOFF_task_fpregs, %g1 stxa %g0, [%g3] ASI_DMMU + membar #Sync add %g6, AOFF_task_fpregs + 0x40, %g2 faddd %f32, %f34, %f36 fmuld %f32, %f34, %f38 - flush %g6 - membar #StoreLoad | #LoadLoad ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( ldda [%g2] ASI_BLK_S, %f16 faddd %f32, %f34, %f40 @@ -137,15 +151,14 @@ do_fpdis: fmuld %f32, %f34, %f58 faddd %f32, %f34, %f60 fmuld %f32, %f34, %f62 - b,pt %xcc, fpdis_exit + ba,pt %xcc, fpdis_exit membar #Sync 3: mov SECONDARY_CONTEXT, %g3 add %g6, AOFF_task_fpregs, %g1 ldxa [%g3] ASI_DMMU, %g5 mov 0x40, %g2 stxa %g0, [%g3] ASI_DMMU - flush %g6 - membar #StoreLoad | #LoadLoad + membar #Sync ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( ldda [%g1 + %g2] ASI_BLK_S, %f16 add %g1, 0x80, %g1 @@ -154,7 +167,7 @@ do_fpdis: membar #Sync fpdis_exit: stxa %g5, [%g3] ASI_DMMU - flush %g6 + membar #Sync fpdis_exit2: wr %g7, 0, %gsr ldx [%g6 + AOFF_task_thread + AOFF_thread_xfsr], %fsr @@ -164,22 +177,152 @@ fpdis_exit2: wr %g0, FPRS_FEF, %fprs ! clean DU/DL bits retry + .align 32 +fp_other_bounce: + call do_fpother + add %sp, STACK_BIAS + REGWIN_SZ, %o0 + ba,pt %xcc, rtrap + clr %l6 + + .globl do_fpother_check_fitos + .align 32 +do_fpother_check_fitos: + sethi %hi(fp_other_bounce - 4), %g7 + or %g7, %lo(fp_other_bounce - 4), %g7 + + /* NOTE: Need to preserve %g7 until we fully commit + * to the fitos fixup. + */ + stx %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr] + rdpr %tstate, %g3 + andcc %g3, TSTATE_PRIV, %g0 + bne,pn %xcc, do_fptrap_after_fsr + nop + ldx [%g6 + AOFF_task_thread + AOFF_thread_xfsr], %g3 + srlx %g3, 14, %g1 + and %g1, 7, %g1 + cmp %g1, 2 ! Unfinished FP-OP + bne,pn %xcc, do_fptrap_after_fsr + sethi %hi(1 << 23), %g1 ! Inexact + andcc %g3, %g1, %g0 + bne,pn %xcc, do_fptrap_after_fsr + rdpr %tpc, %g1 + lduwa [%g1] ASI_AIUP, %g3 ! This cannot ever fail +#define FITOS_MASK 0xc1f83fe0 +#define FITOS_COMPARE 0x81a01880 + sethi %hi(FITOS_MASK), %g1 + or %g1, %lo(FITOS_MASK), %g1 + and %g3, %g1, %g1 + sethi %hi(FITOS_COMPARE), %g2 + or %g2, %lo(FITOS_COMPARE), %g2 + cmp %g1, %g2 + bne,pn %xcc, do_fptrap_after_fsr + nop + std %f62, [%g6 + AOFF_task_fpregs + (62 * 4)] + sethi %hi(fitos_table_1), %g1 + and %g3, 0x1f, %g2 + or %g1, %lo(fitos_table_1), %g1 + sllx %g2, 2, %g2 + jmpl %g1 + %g2, %g0 + ba,pt %xcc, fitos_emul_continue + +fitos_table_1: + fitod %f0, %f62 + fitod %f1, %f62 + fitod %f2, %f62 + fitod %f3, %f62 + fitod %f4, %f62 + fitod %f5, %f62 + fitod %f6, %f62 + fitod %f7, %f62 + fitod %f8, %f62 + fitod %f9, %f62 + fitod %f10, %f62 + fitod %f11, %f62 + fitod %f12, %f62 + fitod %f13, %f62 + fitod %f14, %f62 + fitod %f15, %f62 + fitod %f16, %f62 + fitod %f17, %f62 + fitod %f18, %f62 + fitod %f19, %f62 + fitod %f20, %f62 + fitod %f21, %f62 + fitod %f22, %f62 + fitod %f23, %f62 + fitod %f24, %f62 + fitod %f25, %f62 + fitod %f26, %f62 + fitod %f27, %f62 + fitod %f28, %f62 + fitod %f29, %f62 + fitod %f30, %f62 + fitod %f31, %f62 + +fitos_emul_continue: + sethi %hi(fitos_table_2), %g1 + srl %g3, 25, %g2 + or %g1, %lo(fitos_table_2), %g1 + and %g2, 0x1f, %g2 + sllx %g2, 2, %g2 + jmpl %g1 + %g2, %g0 + ba,pt %xcc, fitos_emul_fini + +fitos_table_2: + fdtos %f62, %f0 + fdtos %f62, %f1 + fdtos %f62, %f2 + fdtos %f62, %f3 + fdtos %f62, %f4 + fdtos %f62, %f5 + fdtos %f62, %f6 + fdtos %f62, %f7 + fdtos %f62, %f8 + fdtos %f62, %f9 + fdtos %f62, %f10 + fdtos %f62, %f11 + fdtos %f62, %f12 + fdtos %f62, %f13 + fdtos %f62, %f14 + fdtos %f62, %f15 + fdtos %f62, %f16 + fdtos %f62, %f17 + fdtos %f62, %f18 + fdtos %f62, %f19 + fdtos %f62, %f20 + fdtos %f62, %f21 + fdtos %f62, %f22 + fdtos %f62, %f23 + fdtos %f62, %f24 + fdtos %f62, %f25 + fdtos %f62, %f26 + fdtos %f62, %f27 + fdtos %f62, %f28 + fdtos %f62, %f29 + fdtos %f62, %f30 + fdtos %f62, %f31 + +fitos_emul_fini: + ldd [%g6 + AOFF_task_fpregs + (62 * 4)], %f62 + done + .globl do_fptrap .align 32 do_fptrap: - ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3 stx %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr] +do_fptrap_after_fsr: + ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3 rd %fprs, %g1 or %g3, %g1, %g3 stb %g3, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved] rd %gsr, %g3 - stb %g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr] + stx %g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr] mov SECONDARY_CONTEXT, %g3 add %g6, AOFF_task_fpregs, %g2 ldxa [%g3] ASI_DMMU, %g5 stxa %g0, [%g3] ASI_DMMU - flush %g6 - membar #StoreStore | #LoadStore + membar #Sync andcc %g1, FPRS_DL, %g0 be,pn %icc, 4f mov 0x40, %g3 @@ -193,7 +336,7 @@ do_fptrap: 5: mov SECONDARY_CONTEXT, %g1 membar #Sync stxa %g5, [%g1] ASI_DMMU - flush %g6 + membar #Sync ba,pt %xcc, etrap wr %g0, 0, %fprs @@ -215,7 +358,7 @@ do_fptrap: .globl do_ivec do_ivec: mov 0x40, %g3 - ldxa [%g3 + %g0] ASI_UDB_INTR_R, %g3 + ldxa [%g3 + %g0] ASI_INTR_R, %g3 sethi %hi(KERNBASE), %g4 cmp %g3, %g4 bgeu,pn %xcc, do_ivec_xcall @@ -242,10 +385,10 @@ do_ivec: do_ivec_xcall: mov 0x50, %g1 - ldxa [%g1 + %g0] ASI_UDB_INTR_R, %g1 + ldxa [%g1 + %g0] ASI_INTR_R, %g1 srl %g3, 0, %g3 mov 0x60, %g7 - ldxa [%g7 + %g0] ASI_UDB_INTR_R, %g7 + ldxa [%g7 + %g0] ASI_INTR_R, %g7 stxa %g0, [%g0] ASI_INTR_RECEIVE membar #Sync jmpl %g3, %g0 @@ -1114,9 +1257,18 @@ do_gettimeofday: /* %o0 = timevalp */ ldx [%g3 + %lo(timer_tick_offset)], %g3 or %g2, %lo(xtime), %g2 or %g1, %lo(timer_tick_compare), %g1 -1: ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o4 - rd %tick, %o1 - ldx [%g1], %g7 +1: rdpr %ver, %o2 + sethi %hi(0x003e0014), %o1 + srlx %o2, 32, %o2 + or %o1, %lo(0x003e0014), %o1 + ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o4 + cmp %o2, %o1 + bne,pt %xcc, 2f + nop + ba,pt %xcc, 3f + rd %asr24, %o1 +2: rd %tick, %o1 +3: ldx [%g1], %g7 ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o2 xor %o4, %o2, %o2 xor %o5, %o3, %o3 diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S index b0a8f766d..c6df20212 100644 --- a/arch/sparc64/kernel/etrap.S +++ b/arch/sparc64/kernel/etrap.S @@ -1,4 +1,4 @@ -/* $Id: etrap.S,v 1.43 2000/03/29 09:55:30 davem Exp $ +/* $Id: etrap.S,v 1.44 2001/03/22 00:51:25 davem Exp $ * etrap.S: Preparing for entry into the kernel on Sparc V9. * * Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -186,3 +186,5 @@ scetrap: rdpr %pil, %g2 ! Single Group nop #undef TASK_REGOFF +#undef ETRAP_PSTATE1 +#undef ETRAP_PSTATE2 diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index 5e855ad2c..6d52fb821 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.65 2000/05/09 17:40:13 davem Exp $ +/* $Id: head.S,v 1.75 2001/03/22 09:54:26 davem Exp $ * head.S: Initial boot code for the Sparc64 port of Linux. * * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu) @@ -21,6 +21,8 @@ #include <asm/signal.h> #include <asm/processor.h> #include <asm/lsu.h> +#include <asm/dcr.h> +#include <asm/dcu.h> #include <asm/head.h> #include <asm/ttable.h> @@ -76,11 +78,145 @@ sparc_ramdisk_size: * PROM entry point is on %o4 */ sparc64_boot: + rdpr %ver, %g1 + sethi %hi(0x003e0014), %g5 + srlx %g1, 32, %g1 + or %g5, %lo(0x003e0014), %g5 + cmp %g1, %g5 + bne,pt %icc, spitfire_boot + nop + +cheetah_boot: + mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1 + wr %g1, %asr18 + + sethi %uhi(DCU_ME | DCU_RE | DCU_PE | DCU_HPE | DCU_SPE | DCU_SL | DCU_WE), %g5 + or %g5, %ulo(DCU_ME | DCU_RE | DCU_PE | DCU_HPE | DCU_SPE | DCU_SL | DCU_WE), %g5 + sllx %g5, 32, %g5 + or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5 + ldxa [%g0] ASI_DCU_CONTROL_REG, %g3 + or %g5, %g3, %g5 + stxa %g5, [%g0] ASI_DCU_CONTROL_REG + membar #Sync + + wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate + wr %g0, 0, %fprs + + /* Just like for Spitfire, we probe itlb-2 for a mapping which + * matches our current %pc. We take the physical address in + * that mapping and use it to make our own. + */ + + /* %g5 holds the tlb data */ + sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5 + sllx %g5, 32, %g5 + or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5 + + /* Put PADDR tlb data mask into %g3. */ + sethi %uhi(_PAGE_PADDR), %g3 + or %g3, %ulo(_PAGE_PADDR), %g3 + sllx %g3, 32, %g3 + sethi %hi(_PAGE_PADDR), %g7 + or %g7, %lo(_PAGE_PADDR), %g7 + or %g3, %g7, %g3 + + set 2 << 16, %l0 /* TLB entry walker. */ + set 0x1fff, %l2 /* Page mask. */ + rd %pc, %l3 + andn %l3, %l2, %g2 /* vaddr comparator */ + +1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 + membar #Sync + andn %g1, %l2, %g1 + cmp %g1, %g2 + be,pn %xcc, cheetah_got_tlbentry + nop + and %l0, (127 << 3), %g1 + cmp %g1, (127 << 3) + blu,pt %xcc, 1b + add %l0, (1 << 3), %l0 + +cheetah_got_tlbentry: + ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1 + membar #Sync + and %g1, %g3, %g1 + sub %g1, %g2, %g1 + or %g5, %g1, %g5 + + /* Clear out any KERNBASE area entries. */ + set 2 << 16, %l0 + sethi %hi(KERNBASE), %g3 + sethi %hi(KERNBASE<<1), %g7 + mov TLB_TAG_ACCESS, %l7 + + /* First, check ITLB */ +1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 + membar #Sync + andn %g1, %l2, %g1 + cmp %g1, %g3 + blu,pn %xcc, 2f + cmp %g1, %g7 + bgeu,pn %xcc, 2f + nop + stxa %g0, [%l7] ASI_IMMU + membar #Sync + stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS + membar #Sync + +2: and %l0, (127 << 3), %g1 + cmp %g1, (127 << 3) + blu,pt %xcc, 1b + add %l0, (1 << 3), %l0 + + /* Next, check DTLB */ + set 2 << 16, %l0 +1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1 + membar #Sync + andn %g1, %l2, %g1 + cmp %g1, %g3 + blu,pn %xcc, 2f + cmp %g1, %g7 + bgeu,pn %xcc, 2f + nop + stxa %g0, [%l7] ASI_DMMU + membar #Sync + stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS + membar #Sync + +2: and %l0, (511 << 3), %g1 + cmp %g1, (511 << 3) + blu,pt %xcc, 1b + add %l0, (1 << 3), %l0 + + /* Now lock the TTE we created into ITLB-0 and DTLB-0, + * entry 15. + */ + sethi %hi(KERNBASE), %g3 + set (0 << 16) | (15 << 3), %g7 + stxa %g3, [%l7] ASI_DMMU + membar #Sync + stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS + membar #Sync + stxa %g3, [%l7] ASI_IMMU + membar #Sync + stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS + membar #Sync + flush %g3 + membar #Sync + ba,pt %xcc, 1f + nop + +1: set sun4u_init, %g2 + jmpl %g2 + %g0, %g0 + nop + +spitfire_boot: /* Typically PROM has already enabled both MMU's and both on-chip * caches, but we do it here anyway just to be paranoid. */ mov (LSU_CONTROL_IC|LSU_CONTROL_DC|LSU_CONTROL_IM|LSU_CONTROL_DM), %g1 stxa %g1, [%g0] ASI_LSU_CONTROL + membar #Sync /* * Make sure we are in privileged mode, have address masking, @@ -93,7 +229,7 @@ sparc64_boot: wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate wr %g0, 0, %fprs -create_mappings: +spitfire_create_mappings: /* %g5 holds the tlb data */ sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5 sllx %g5, 32, %g5 @@ -104,11 +240,11 @@ create_mappings: */ /* Put PADDR tlb data mask into %g3. */ - sethi %uhi(_PAGE_PADDR), %g3 - or %g3, %ulo(_PAGE_PADDR), %g3 + sethi %uhi(_PAGE_PADDR_SF), %g3 + or %g3, %ulo(_PAGE_PADDR_SF), %g3 sllx %g3, 32, %g3 - sethi %hi(_PAGE_PADDR), %g7 - or %g7, %lo(_PAGE_PADDR), %g7 + sethi %hi(_PAGE_PADDR_SF), %g7 + or %g7, %lo(_PAGE_PADDR_SF), %g7 or %g3, %g7, %g3 /* Walk through entire ITLB, looking for entry which maps @@ -126,13 +262,13 @@ create_mappings: nop andn %g1, %l2, %g1 /* Get vaddr */ cmp %g1, %g2 - be,a,pn %xcc, got_tlbentry + be,a,pn %xcc, spitfire_got_tlbentry ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1 cmp %l0, (63 << 3) blu,pt %xcc, 1b add %l0, (1 << 3), %l0 -got_tlbentry: +spitfire_got_tlbentry: /* Nops here again, perhaps Cheetah/Blackbird are better behaved... */ nop nop @@ -164,6 +300,7 @@ got_tlbentry: nop stxa %g0, [%l7] ASI_IMMU stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS + membar #Sync 2: cmp %l0, (63 << 3) blu,pt %xcc, 1b @@ -186,6 +323,7 @@ got_tlbentry: nop stxa %g0, [%l7] ASI_DMMU stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS + membar #Sync 2: cmp %l0, (63 << 3) blu,pt %xcc, 1b @@ -235,7 +373,47 @@ sun4u_init: mov TLB_TAG_ACCESS, %g2 stxa %g3, [%g2] ASI_IMMU stxa %g3, [%g2] ASI_DMMU + membar #Sync + + rdpr %ver, %g1 + sethi %hi(0x003e0014), %g5 + srlx %g1, 32, %g1 + or %g5, %lo(0x003e0014), %g5 + cmp %g1, %g5 + bne,pt %icc, spitfire_tlb_fixup + nop + +cheetah_tlb_fixup: + set (0 << 16) | (15 << 3), %g7 + ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1 + andn %g1, (_PAGE_G), %g1 + stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS + membar #Sync + ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1 + andn %g1, (_PAGE_G), %g1 + stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS + membar #Sync + + /* Kill instruction prefetch queues. */ + flush %g3 + membar #Sync + + /* Set TLB type to cheetah. */ + mov 1, %g2 + sethi %hi(tlb_type), %g5 + stw %g2, [%g5 + %lo(tlb_type)] + + /* Patch copy/page operations to cheetah optimized versions. */ + call cheetah_patch_copyops + nop + call cheetah_patch_pgcopyops + nop + + ba,pt %xcc, tlb_fixup_done + nop + +spitfire_tlb_fixup: mov (63 << 3), %g7 ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1 andn %g1, (_PAGE_G), %g1 @@ -251,6 +429,12 @@ sun4u_init: flush %g3 membar #Sync + /* Set TLB type to spitfire. */ + mov 0, %g2 + sethi %hi(tlb_type), %g5 + stw %g2, [%g5 + %lo(tlb_type)] + +tlb_fixup_done: sethi %hi(init_task_union), %g6 or %g6, %lo(init_task_union), %g6 mov %sp, %l6 @@ -285,28 +469,19 @@ sun4u_init: wrpr %g0, 0x0, %tl /* Clear the bss */ - sethi %hi(8191), %l2 - or %l2, %lo(8191), %l2 - sethi %hi(__bss_start), %l0 - or %l0, %lo(__bss_start), %l0 - sethi %hi(_end), %l1 - or %l1, %lo(_end), %l1 - add %l1, %l2, %l1 - andn %l1, %l2, %l1 - add %l2, 1, %l2 - add %l0, %g0, %o0 -1: - mov %l2, %o1 + sethi %hi(__bss_start), %o0 + or %o0, %lo(__bss_start), %o0 + sethi %hi(_end), %o1 + or %o1, %lo(_end), %o1 call __bzero - add %l0, %l2, %l0 - cmp %l0, %l1 - blu,pt %xcc, 1b - add %l0, %g0, %o0 + sub %o1, %o0, %o1 /* Now clear empty_zero_page */ - mov %l2, %o1 + sethi %hi(8192), %o1 + or %o1, %lo(8192), %o1 + sethi %hi(KERNBASE), %g3 call __bzero - mov %g3, %o0 + or %g3, %lo(KERNBASE), %o0 mov %l6, %o1 ! OpenPROM stack call prom_init @@ -340,14 +515,16 @@ setup_tba: /* i0 = is_starfire */ wrpr %o1, (PSTATE_MG|PSTATE_IE), %pstate /* Set fixed globals used by dTLB miss handler. */ -#define KERN_HIGHBITS ((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000) +#define KERN_HIGHBITS ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000) #define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W) -#ifdef THIS_IS_CHEETAH -#error Dave, make sure you took care of other issues in rest of sparc64 code... -#define VPTE_BASE 0xffe0000000000000 -#else /* Spitfire/Blackbird */ -#define VPTE_BASE 0xfffffffe00000000 + +#define VPTE_BASE_SPITFIRE 0xfffffffe00000000 +#if 1 +#define VPTE_BASE_CHEETAH VPTE_BASE_SPITFIRE +#else +#define VPTE_BASE_CHEETAH 0xffe0000000000000 #endif + mov TSB_REG, %g1 stxa %g0, [%g1] ASI_DMMU membar #Sync @@ -356,13 +533,30 @@ setup_tba: /* i0 = is_starfire */ or %g2, %ulo(KERN_HIGHBITS), %g2 sllx %g2, 32, %g2 or %g2, KERN_LOWBITS, %g2 - sethi %uhi(VPTE_BASE), %g3 - or %g3, %ulo(VPTE_BASE), %g3 - sllx %g3, 32, %g3 + + rdpr %ver, %g3 + sethi %hi(0x003e0014), %g7 + srlx %g3, 32, %g3 + or %g7, %lo(0x003e0014), %g7 + cmp %g3, %g7 + bne,pt %icc, 1f + nop + + sethi %uhi(VPTE_BASE_CHEETAH), %g3 + or %g3, %ulo(VPTE_BASE_CHEETAH), %g3 + ba,pt %xcc, 2f + sllx %g3, 32, %g3 +1: + sethi %uhi(VPTE_BASE_SPITFIRE), %g3 + or %g3, %ulo(VPTE_BASE_SPITFIRE), %g3 + sllx %g3, 32, %g3 + +2: clr %g7 #undef KERN_HIGHBITS #undef KERN_LOWBITS -#undef VPTE_BASE +#undef VPTE_BASE_SPITFIRE +#undef VPTE_BASE_CHEETAH /* Setup Interrupt globals */ wrpr %o1, (PSTATE_IG|PSTATE_IE), %pstate @@ -371,9 +565,6 @@ setup_tba: /* i0 = is_starfire */ or %g5, %lo(__up_workvec), %g6 #else /* By definition of where we are, this is boot_cpu. */ - sethi %hi(cpu_data), %g5 - or %g5, %lo(cpu_data), %g5 - brz,pt %i0, not_starfire sethi %hi(0x1fff4000), %g1 or %g1, %lo(0x1fff4000), %g1 @@ -384,12 +575,27 @@ setup_tba: /* i0 = is_starfire */ nop not_starfire: + rdpr %ver, %g1 + sethi %hi(0x003e0014), %g5 + srlx %g1, 32, %g1 + or %g7, %lo(0x003e0014), %g5 + cmp %g1, %g5 + bne,pt %icc, not_cheetah + nop + + ldxa [%g0] ASI_SAFARI_CONFIG, %g1 + srlx %g1, 17, %g1 + and %g1, 0x3ff, %g1 ! 10bit Safari Agent ID + +not_cheetah: ldxa [%g0] ASI_UPA_CONFIG, %g1 srlx %g1, 17, %g1 and %g1, 0x1f, %g1 /* In theory this is: &(cpu_data[boot_cpu_id].irq_worklists[0]) */ set_worklist: + sethi %hi(cpu_data), %g5 + or %g5, %lo(cpu_data), %g5 sllx %g1, 7, %g1 add %g5, %g1, %g5 add %g5, 64, %g6 @@ -398,9 +604,23 @@ set_worklist: /* Kill PROM timer */ wr %g0, 0, %tick_cmpr + rdpr %ver, %g1 + sethi %hi(0x003e0014), %g5 + srlx %g1, 32, %g1 + or %g7, %lo(0x003e0014), %g5 + cmp %g1, %g5 + bne,pt %icc, 1f + nop + + /* Disable STICK_INT interrupts. */ + sethi %hi(0x80000000), %g1 + sllx %g1, 32, %g1 + wr %g1, %asr25 + /* Ok, we're done setting up all the state our trap mechanims needs, * now get back into normal globals and let the PROM know what is up. */ +1: wrpr %g0, %g0, %wstate wrpr %o1, PSTATE_IE, %pstate diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index e2cdc3613..621e5762f 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.107 2001/02/13 01:16:44 davem Exp $ +/* $Id: ioctl32.c,v 1.110 2001/03/22 12:51:25 davem Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -48,6 +48,7 @@ #include <linux/blkpg.h> #include <linux/blk.h> #include <linux/elevator.h> +#include <linux/rtc.h> #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) /* Ugh. This header really is not clean */ #define min min @@ -67,7 +68,6 @@ #include <asm/fbio.h> #include <asm/kbio.h> #include <asm/vuid_event.h> -#include <asm/rtc.h> #include <asm/openpromio.h> #include <asm/envctrl.h> #include <asm/audioio.h> @@ -2068,6 +2068,7 @@ typedef struct { u32 proc; u32 pv[ABS_MAX_PV + 1]; u32 lv[ABS_MAX_LV + 1]; + uint8_t vg_uuid[UUID_LEN+1]; /* volume group UUID */ } vg32_t; typedef struct { @@ -2093,6 +2094,7 @@ typedef struct { uint32_t pe_stale; u32 pe; u32 inode; + uint8_t pv_uuid[UUID_LEN+1]; } pv32_t; typedef struct { @@ -2103,9 +2105,16 @@ typedef struct { typedef struct { u32 lv_index; u32 lv; + /* Transfer size because user space and kernel space differ */ + uint16_t size; } lv_status_byindex_req32_t; typedef struct { + dev_t dev; + u32 lv; +} lv_status_bydev_req32_t; + +typedef struct { uint8_t lv_name[NAME_LEN]; kdev_t old_dev; kdev_t new_dev; @@ -2204,11 +2213,12 @@ static lv_t *get_lv_t(u32 p, int *errp) if (l->lv_block_exception) { lbe32 = (lv_block_exception32_t *)A(ptr2); memset(lbe, 0, size); - for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) { - err |= get_user(lbe->rsector_org, &lbe32->rsector_org); - err |= __get_user(lbe->rdev_org, &lbe32->rdev_org); - err |= __get_user(lbe->rsector_new, &lbe32->rsector_new); - err |= __get_user(lbe->rdev_new, &lbe32->rdev_new); + for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) { + err |= get_user(lbe->rsector_org, &lbe32->rsector_org); + err |= __get_user(lbe->rdev_org, &lbe32->rdev_org); + err |= __get_user(lbe->rsector_new, &lbe32->rsector_new); + err |= __get_user(lbe->rdev_new, &lbe32->rdev_new); + } } } @@ -2239,8 +2249,9 @@ static int copy_lv_t(u32 ptr, lv_t *l) err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr, ((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr)); size = l->lv_allocated_le * sizeof(pe_t); - err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size); - return -EFAULT; + if (ptr1) + err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size); + return err ? -EFAULT : 0; } static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) @@ -2250,7 +2261,8 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) lv_req_t lv_req; le_remap_req_t le_remap; lv_status_byindex_req_t lv_byindex; - pv_status_req32_t pv_status; + lv_status_bydev_req_t lv_bydev; + pv_status_req_t pv_status; } u; pv_t p; int err; @@ -2273,6 +2285,11 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) kfree(v); return -EFAULT; } + if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) { + kfree(v); + return -EFAULT; + } + karg = v; memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv)); if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV) @@ -2286,11 +2303,18 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) err = -ENOMEM; break; } - err = copy_from_user(v->pv[i], (void *)A(ptr), sizeof(pv32_t) - 8); + err = copy_from_user(v->pv[i], (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1); if (err) { err = -EFAULT; break; } + err = copy_from_user(v->pv[i]->pv_uuid, ((pv32_t *)A(ptr))->pv_uuid, UUID_LEN+1); + if (err) { + err = -EFAULT; + break; + } + + v->pv[i]->pe = NULL; v->pv[i]->inode = NULL; } } @@ -2309,8 +2333,9 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) case LV_EXTEND: case LV_REDUCE: case LV_REMOVE: + case LV_RENAME: case LV_STATUS_BYNAME: - err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name)); + err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name)); if (err) return -EFAULT; if (cmd != LV_REMOVE) { err = __get_user(ptr, &((lv_req32_t *)arg)->lv); @@ -2319,24 +2344,29 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) } else u.lv_req.lv = NULL; break; + + case LV_STATUS_BYINDEX: err = get_user(u.lv_byindex.lv_index, &((lv_status_byindex_req32_t *)arg)->lv_index); err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv); if (err) return err; u.lv_byindex.lv = get_lv_t(ptr, &err); break; + case LV_STATUS_BYDEV: + err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev); + u.lv_bydev.lv = get_lv_t(ptr, &err); + if (err) return err; + u.lv_bydev.lv = &p; + p.pe = NULL; p.inode = NULL; + break; case VG_EXTEND: - err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8); + err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1); + if (err) return -EFAULT; + err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1); if (err) return -EFAULT; p.pe = NULL; p.inode = NULL; karg = &p; break; - case LE_REMAP: - err = copy_from_user(&u.le_remap, (void *)arg, sizeof(le_remap_req32_t)); - if (err) return -EFAULT; - u.le_remap.new_pe = ((le_remap_req32_t *)&u.le_remap)->new_pe; - u.le_remap.old_pe = ((le_remap_req32_t *)&u.le_remap)->old_pe; - break; case PV_CHANGE: case PV_STATUS: err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name)); @@ -2345,7 +2375,7 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) if (err) return err; u.pv_status.pv = &p; if (cmd == PV_CHANGE) { - err = copy_from_user(&p, (void *)A(ptr), sizeof(pv32_t) - 8); + err = copy_from_user(&p, (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1); if (err) return -EFAULT; p.pe = NULL; p.inode = NULL; } @@ -2361,6 +2391,9 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc)) err = -EFAULT; } + if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) { + err = -EFAULT; + } kfree(v); break; case VG_CREATE: @@ -2383,12 +2416,21 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) if (!err) err = copy_lv_t(ptr, u.lv_byindex.lv); put_lv_t(u.lv_byindex.lv); } + break; case PV_STATUS: if (!err) { - err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8); - if (err) return -EFAULT; + err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1); + if (err) return -EFAULT; + err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1); + if (err) return -EFAULT; } break; + case LV_STATUS_BYDEV: + if (!err) { + if (!err) err = copy_lv_t(ptr, u.lv_bydev.lv); + put_lv_t(u.lv_byindex.lv); + } + break; } return err; } @@ -3222,8 +3264,22 @@ COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int)) COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int)) COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int)) /* Little p (/dev/rtc, /dev/envctrl, etc.) */ -COMPATIBLE_IOCTL(RTCGET) -COMPATIBLE_IOCTL(RTCSET) +COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */ +COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */ +COMPATIBLE_IOCTL(RTC_AIE_ON) +COMPATIBLE_IOCTL(RTC_AIE_OFF) +COMPATIBLE_IOCTL(RTC_UIE_ON) +COMPATIBLE_IOCTL(RTC_UIE_OFF) +COMPATIBLE_IOCTL(RTC_PIE_ON) +COMPATIBLE_IOCTL(RTC_PIE_OFF) +COMPATIBLE_IOCTL(RTC_WIE_ON) +COMPATIBLE_IOCTL(RTC_WIE_OFF) +COMPATIBLE_IOCTL(RTC_ALM_SET) +COMPATIBLE_IOCTL(RTC_ALM_READ) +COMPATIBLE_IOCTL(RTC_RD_TIME) +COMPATIBLE_IOCTL(RTC_SET_TIME) +COMPATIBLE_IOCTL(RTC_WKALM_SET) +COMPATIBLE_IOCTL(RTC_WKALM_RD) COMPATIBLE_IOCTL(ENVCTRL_RD_WARNING_TEMPERATURE) COMPATIBLE_IOCTL(ENVCTRL_RD_SHUTDOWN_TEMPERATURE) COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_TEMPERATURE) @@ -3331,6 +3387,7 @@ COMPATIBLE_IOCTL(PPPIOCSMRRU) COMPATIBLE_IOCTL(PPPIOCCONNECT) COMPATIBLE_IOCTL(PPPIOCDISCONN) COMPATIBLE_IOCTL(PPPIOCATTCHAN) +COMPATIBLE_IOCTL(PPPIOCGCHAN) /* PPPOX */ COMPATIBLE_IOCTL(PPPOEIOCSFWD); COMPATIBLE_IOCTL(PPPOEIOCDFWD); @@ -3565,6 +3622,7 @@ COMPATIBLE_IOCTL(VG_SET_EXTENDABLE) COMPATIBLE_IOCTL(VG_STATUS_GET_COUNT) COMPATIBLE_IOCTL(VG_STATUS_GET_NAMELIST) COMPATIBLE_IOCTL(VG_REMOVE) +COMPATIBLE_IOCTL(VG_RENAME) COMPATIBLE_IOCTL(VG_REDUCE) COMPATIBLE_IOCTL(PE_LOCK_UNLOCK) COMPATIBLE_IOCTL(PV_FLUSH) @@ -3576,6 +3634,9 @@ COMPATIBLE_IOCTL(LVM_RESET) COMPATIBLE_IOCTL(LV_SET_ACCESS) COMPATIBLE_IOCTL(LV_SET_STATUS) COMPATIBLE_IOCTL(LV_SET_ALLOCATION) +COMPATIBLE_IOCTL(LE_REMAP) +COMPATIBLE_IOCTL(LV_BMAP) +COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE) #endif /* LVM */ #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE) COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC) @@ -3749,9 +3810,9 @@ HANDLE_IOCTL(LV_CREATE, do_lvm_ioctl) HANDLE_IOCTL(LV_REMOVE, do_lvm_ioctl) HANDLE_IOCTL(LV_EXTEND, do_lvm_ioctl) HANDLE_IOCTL(LV_REDUCE, do_lvm_ioctl) +HANDLE_IOCTL(LV_RENAME, do_lvm_ioctl) HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl) HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl) -HANDLE_IOCTL(LE_REMAP, do_lvm_ioctl) HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl) HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl) #endif /* LVM */ @@ -3766,6 +3827,12 @@ HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs); HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma); HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx); #endif /* DRM */ +#if 0 +HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl) +HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl) +HANDLE_IOCTL(RTC32_EPOCH_READ, do_rtc_ioctl) +HANDLE_IOCTL(RTC32_EPOCH_SET, do_rtc_ioctl) +#endif IOCTL_TABLE_END unsigned int ioctl32_hash_table[1024]; diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 1bd29505b..dbb55aaed 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.95 2001/02/13 01:16:44 davem Exp $ +/* $Id: irq.c,v 1.99 2001/03/22 02:19:23 davem Exp $ * irq.c: UltraSparc IRQ handling/init/registry. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -132,14 +132,23 @@ void enable_irq(unsigned int irq) if (imap == 0UL) return; - if(this_is_starfire == 0) { + if (tlb_type == cheetah) { + /* We set it to our Safari AID. */ + __asm__ __volatile__("ldxa [%%g0] %1, %0" + : "=r" (tid) + : "i" (ASI_SAFARI_CONFIG)); + tid = ((tid & (0x3ffUL<<17)) << 9); + tid &= IMAP_AID_SAFARI; + } else if (this_is_starfire == 0) { /* We set it to our UPA MID. */ __asm__ __volatile__("ldxa [%%g0] %1, %0" : "=r" (tid) : "i" (ASI_UPA_CONFIG)); tid = ((tid & UPA_CONFIG_MID) << 9); + tid &= IMAP_TID_UPA; } else { tid = (starfire_translate(imap, current->processor) << 26); + tid &= IMAP_TID_UPA; } /* NOTE NOTE NOTE, IGN and INO are read-only, IGN is a product @@ -150,7 +159,7 @@ void enable_irq(unsigned int irq) * * Things like FFB can now be handled via the new IRQ mechanism. */ - upa_writel(IMAP_VALID | (tid & IMAP_TID), imap); + upa_writel(tid | IMAP_VALID, imap); } /* This now gets passed true ino's as well. */ @@ -729,6 +738,10 @@ void handler_irq(int irq, struct pt_regs *regs) /* Voo-doo programming. */ if (cpu_data[buddy].idle_volume < FORWARD_VOLUME) should_forward = 0; + + /* This just so happens to be correct on Cheetah + * at the moment. + */ buddy <<= 26; } #endif @@ -737,10 +750,23 @@ void handler_irq(int irq, struct pt_regs *regs) /* * Check for TICK_INT on level 14 softint. */ - if ((irq == 14) && (get_softint() & (1UL << 0))) - irq = 0; -#endif + { + unsigned long clr_mask = 1 << irq; + unsigned long tick_mask; + + if (SPARC64_USE_STICK) + tick_mask = (1UL << 16); + else + tick_mask = (1UL << 0); + if ((irq == 14) && (get_softint() & tick_mask)) { + irq = 0; + clr_mask = tick_mask; + } + clear_softint(clr_mask); + } +#else clear_softint(1 << irq); +#endif irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; @@ -952,8 +978,13 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *), extern void smp_tick_init(void); #endif - node = linux_cpus[0].prom_node; - *clock = prom_getint(node, "clock-frequency"); + if (!SPARC64_USE_STICK) { + node = linux_cpus[0].prom_node; + *clock = prom_getint(node, "clock-frequency"); + } else { + node = prom_root_node; + *clock = prom_getint(node, "stick-frequency"); + } timer_tick_offset = *clock / HZ; #ifdef CONFIG_SMP smp_tick_init(); @@ -1003,6 +1034,7 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *), * at the start of an I-cache line, and perform a dummy * read back from %tick_cmpr right after writing to it. -DaveM */ + if (!SPARC64_USE_STICK) { __asm__ __volatile__(" rd %%tick, %%g1 ba,pt %%xcc, 1f @@ -1013,6 +1045,26 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *), : /* no outputs */ : "r" (timer_tick_offset) : "g1"); + } else { + /* Let the user get at STICK too. */ + __asm__ __volatile__(" + sethi %%hi(0x80000000), %%g1 + sllx %%g1, 32, %%g1 + rd %%asr24, %%g2 + andn %%g2, %%g1, %%g2 + wr %%g2, 0, %%asr24" + : /* no outputs */ + : /* no inputs */ + : "g1", "g2"); + + __asm__ __volatile__(" + rd %%asr24, %%g1 + add %%g1, %0, %%g1 + wr %%g1, 0x0, %%asr25" + : /* no outputs */ + : "r" (timer_tick_offset) + : "g1"); + } /* Restore PSTATE_IE. */ __asm__ __volatile__("wrpr %0, 0x0, %%pstate" @@ -1033,12 +1085,17 @@ static int retarget_one_irq(struct irqaction *p, int goal_cpu) if (bucket->pil == 12) return goal_cpu; - if(this_is_starfire == 0) { + if (tlb_type == cheetah) { + tid = __cpu_logical_map[goal_cpu] << 26; + tid &= IMAP_AID_SAFARI; + } else if (this_is_starfire == 0) { tid = __cpu_logical_map[goal_cpu] << 26; + tid &= IMAP_TID_UPA; } else { tid = (starfire_translate(imap, __cpu_logical_map[goal_cpu]) << 26); + tid &= IMAP_TID_UPA; } - upa_writel(IMAP_VALID | (tid & IMAP_TID), imap); + upa_writel(tid | IMAP_VALID, imap); goal_cpu++; if(goal_cpu >= NR_CPUS || @@ -1120,7 +1177,7 @@ static void kill_prom_timer(void) stxa %%g0, [%%g0] %0 membar #Sync " : /* no outputs */ - : "i" (ASI_INTR_RECEIVE), "i" (ASI_UDB_INTR_R) + : "i" (ASI_INTR_RECEIVE), "i" (ASI_INTR_R) : "g1", "g2"); } diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 009900165..fbdb39748 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -1,4 +1,4 @@ -/* $Id: pci.c,v 1.21 2001/01/10 18:22:59 davem Exp $ +/* $Id: pci.c,v 1.23 2001/03/14 04:17:14 davem Exp $ * pci.c: UltraSparc PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -78,9 +78,7 @@ volatile int pci_poke_faulted; /* Probe for all PCI controllers in the system. */ extern void sabre_init(int); extern void psycho_init(int); -#if 0 extern void schizo_init(int); -#endif static struct { char *model_name; @@ -88,12 +86,11 @@ static struct { } pci_controller_table[] = { { "SUNW,sabre", sabre_init }, { "pci108e,a000", sabre_init }, + { "pci108e,a001", sabre_init }, { "SUNW,psycho", psycho_init }, - { "pci108e,8000", psycho_init } -#if 0 + { "pci108e,8000", psycho_init }, { "SUNW,schizo", schizo_init }, { "pci108e,8001", schizo_init } -#endif }; #define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ sizeof(pci_controller_table[0])) diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index ff7060c0a..bcf950ee0 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -1,4 +1,4 @@ -/* $Id: pci_common.c,v 1.13 2001/02/13 01:16:44 davem Exp $ +/* $Id: pci_common.c,v 1.14 2001/02/28 03:28:55 davem Exp $ * pci_common.c: PCI controller common support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -560,19 +560,19 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev) /* Fully specified already? */ if (((prom_irq & PCI_IRQ_IGN) >> 6) == portid) { - pdev->irq = p->irq_build(p, pdev, prom_irq); + pdev->irq = p->irq_build(pbm, pdev, prom_irq); goto have_irq; } /* An onboard device? (bit 5 set) */ if ((prom_irq & PCI_IRQ_INO) & 0x20) { - pdev->irq = p->irq_build(p, pdev, (portid << 6 | prom_irq)); + pdev->irq = p->irq_build(pbm, pdev, (portid << 6 | prom_irq)); goto have_irq; } /* Can we find a matching entry in the interrupt-map? */ if (pci_intmap_match(pdev, &prom_irq)) { - pdev->irq = p->irq_build(p, pdev, (portid << 6) | prom_irq); + pdev->irq = p->irq_build(pbm, pdev, (portid << 6) | prom_irq); goto have_irq; } @@ -609,7 +609,7 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev) } slot = slot << 2; - pdev->irq = p->irq_build(p, pdev, + pdev->irq = p->irq_build(pbm, pdev, ((portid << 6) & PCI_IRQ_IGN) | (bus | slot | line)); } @@ -632,17 +632,11 @@ void __init pci_fixup_irq(struct pci_pbm_info *pbm, pci_fixup_irq(pbm, pci_bus_b(walk)); } -#undef DEBUG_BUSMASTERING - static void pdev_setup_busmastering(struct pci_dev *pdev, int is_66mhz) { u16 cmd; u8 hdr_type, min_gnt, ltimer; -#ifdef DEBUG_BUSMASTERING - printk("PCI: Checking DEV(%s), ", pdev->name); -#endif - pci_read_config_word(pdev, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_MASTER; pci_write_config_word(pdev, PCI_COMMAND, cmd); @@ -652,43 +646,28 @@ static void pdev_setup_busmastering(struct pci_dev *pdev, int is_66mhz) * mastering so we have nothing to do here. */ pci_read_config_word(pdev, PCI_COMMAND, &cmd); - if ((cmd & PCI_COMMAND_MASTER) == 0) { -#ifdef DEBUG_BUSMASTERING - printk("no bus mastering...\n"); -#endif + if ((cmd & PCI_COMMAND_MASTER) == 0) return; - } /* Set correct cache line size, 64-byte on all * Sparc64 PCI systems. Note that the value is * measured in 32-bit words. */ -#ifdef DEBUG_BUSMASTERING - printk("set cachelinesize, "); -#endif pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 64 / sizeof(u32)); pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr_type); hdr_type &= ~0x80; - if (hdr_type != PCI_HEADER_TYPE_NORMAL) { -#ifdef DEBUG_BUSMASTERING - printk("hdr_type=%x, exit\n", hdr_type); -#endif + if (hdr_type != PCI_HEADER_TYPE_NORMAL) return; - } /* If the latency timer is already programmed with a non-zero * value, assume whoever set it (OBP or whoever) knows what * they are doing. */ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, <imer); - if (ltimer != 0) { -#ifdef DEBUG_BUSMASTERING - printk("ltimer was %x, exit\n", ltimer); -#endif + if (ltimer != 0) return; - } /* XXX Since I'm tipping off the min grant value to * XXX choose a suitable latency timer value, I also @@ -738,9 +717,6 @@ static void pdev_setup_busmastering(struct pci_dev *pdev, int is_66mhz) } pci_write_config_byte(pdev, PCI_LATENCY_TIMER, ltimer); -#ifdef DEBUG_BUSMASTERING - printk("set ltimer to %x\n", ltimer); -#endif } void pci_determine_66mhz_disposition(struct pci_pbm_info *pbm, diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 08d5b8ee3..5e21a9649 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c @@ -1,4 +1,4 @@ -/* $Id: pci_iommu.c,v 1.12 2001/01/11 16:26:45 davem Exp $ +/* $Id: pci_iommu.c,v 1.13 2001/03/14 08:42:38 davem Exp $ * pci_iommu.c: UltraSparc PCI controller IOM/STC support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -213,9 +213,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad first_page += PAGE_SIZE; } - if (iommu->iommu_ctxflush) { - pci_iommu_write(iommu->iommu_ctxflush, ctx); - } else { + { int i; u32 daddr = *dma_addrp; diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 7a671158e..ac7f5ab81 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1,4 +1,4 @@ -/* $Id: pci_psycho.c,v 1.19 2001/02/13 01:16:44 davem Exp $ +/* $Id: pci_psycho.c,v 1.21 2001/02/28 03:28:55 davem Exp $ * pci_psycho.c: PSYCHO/U2P specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) @@ -72,7 +72,7 @@ * --------------------------------------------------------- */ #define PSYCHO_CONFIG_BASE(PBM) \ - ((PBM)->parent->config_space | (1UL << 24)) + ((PBM)->config_space | (1UL << 24)) #define PSYCHO_CONFIG_ENCODE(BUS, DEVFN, REG) \ (((unsigned long)(BUS) << 16) | \ ((unsigned long)(DEVFN) << 8) | \ @@ -376,10 +376,11 @@ static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino) return ret; } -static unsigned int __init psycho_irq_build(struct pci_controller_info *p, +static unsigned int __init psycho_irq_build(struct pci_pbm_info *pbm, struct pci_dev *pdev, unsigned int ino) { + struct pci_controller_info *p = pbm->parent; struct ino_bucket *bucket; unsigned long imap, iclr; unsigned long imap_off, iclr_off; @@ -1002,12 +1003,13 @@ static void psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) #define PSYCHO_PCIERR_B_INO 0x31 static void __init psycho_register_error_handlers(struct pci_controller_info *p) { + struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ unsigned long base = p->controller_regs; unsigned int irq, portid = p->portid; u64 tmp; /* Build IRQs and register handlers. */ - irq = psycho_irq_build(p, NULL, (portid << 6) | PSYCHO_UE_INO); + irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_UE_INO); if (request_irq(irq, psycho_ue_intr, SA_SHIRQ, "PSYCHO UE", p) < 0) { prom_printf("PSYCHO%d: Cannot register UE interrupt.\n", @@ -1015,7 +1017,7 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p) prom_halt(); } - irq = psycho_irq_build(p, NULL, (portid << 6) | PSYCHO_CE_INO); + irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_CE_INO); if (request_irq(irq, psycho_ce_intr, SA_SHIRQ, "PSYCHO CE", p) < 0) { prom_printf("PSYCHO%d: Cannot register CE interrupt.\n", @@ -1023,7 +1025,7 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p) prom_halt(); } - irq = psycho_irq_build(p, NULL, (portid << 6) | PSYCHO_PCIERR_A_INO); + irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_A_INO); if (request_irq(irq, psycho_pcierr_intr, SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_A) < 0) { prom_printf("PSYCHO%d(PBMA): Cannot register PciERR interrupt.\n", @@ -1031,7 +1033,7 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p) prom_halt(); } - irq = psycho_irq_build(p, NULL, (portid << 6) | PSYCHO_PCIERR_B_INO); + irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_B_INO); if (request_irq(irq, psycho_pcierr_intr, SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_B) < 0) { prom_printf("PSYCHO%d(PBMB): Cannot register PciERR interrupt.\n", @@ -1574,8 +1576,10 @@ void __init psycho_init(int node) printk("PCI: Found PSYCHO, control regs at %016lx\n", p->controller_regs); - p->config_space = pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE; - printk("PSYCHO: PCI config space at %016lx\n", p->config_space); + p->pbm_A.config_space = p->pbm_B.config_space = + (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); + printk("PSYCHO: Shared PCI config space at %016lx\n", + p->pbm_A.config_space); /* * Psycho's PCI MEM space is mapped to a 2GB aligned area, so diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index cce2e5467..07632eaec 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -1,4 +1,4 @@ -/* $Id: pci_sabre.c,v 1.23 2001/02/13 01:16:44 davem Exp $ +/* $Id: pci_sabre.c,v 1.25 2001/02/28 03:28:55 davem Exp $ * pci_sabre.c: Sabre specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) @@ -209,7 +209,7 @@ * --------------------------------------------------------- */ #define SABRE_CONFIG_BASE(PBM) \ - ((PBM)->parent->config_space | (1UL << 24)) + ((PBM)->config_space | (1UL << 24)) #define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG) \ (((unsigned long)(BUS) << 16) | \ ((unsigned long)(DEVFN) << 8) | \ @@ -604,10 +604,11 @@ static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino) return ret; } -static unsigned int __init sabre_irq_build(struct pci_controller_info *p, +static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm, struct pci_dev *pdev, unsigned int ino) { + struct pci_controller_info *p = pbm->parent; struct ino_bucket *bucket; unsigned long imap, iclr; unsigned long imap_off, iclr_off; @@ -961,6 +962,7 @@ static void sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) #define SABRE_PCIERR_INO 0x30 static void __init sabre_register_error_handlers(struct pci_controller_info *p) { + struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ unsigned long base = p->controller_regs; unsigned long irq, portid = p->portid; u64 tmp; @@ -973,7 +975,7 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p) (SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR | SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR | SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE)); - irq = sabre_irq_build(p, NULL, (portid << 6) | SABRE_UE_INO); + irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_UE_INO); if (request_irq(irq, sabre_ue_intr, SA_SHIRQ, "SABRE UE", p) < 0) { prom_printf("SABRE%d: Cannot register UE interrupt.\n", @@ -984,7 +986,7 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p) sabre_write(base + SABRE_CE_AFSR, (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR | SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR)); - irq = sabre_irq_build(p, NULL, (portid << 6) | SABRE_CE_INO); + irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_CE_INO); if (request_irq(irq, sabre_ce_intr, SA_SHIRQ, "SABRE CE", p) < 0) { prom_printf("SABRE%d: Cannot register CE interrupt.\n", @@ -992,7 +994,7 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p) prom_halt(); } - irq = sabre_irq_build(p, NULL, (portid << 6) | SABRE_PCIERR_INO); + irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_PCIERR_INO); if (request_irq(irq, sabre_pcierr_intr, SA_SHIRQ, "SABRE PCIERR", p) < 0) { prom_printf("SABRE%d: Cannot register PciERR interrupt.\n", @@ -1434,8 +1436,10 @@ void __init sabre_init(int pnode) SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN)); /* Now map in PCI config space for entire SABRE. */ - p->config_space = p->controller_regs + SABRE_CONFIGSPACE; - printk("SABRE: PCI config space at %016lx\n", p->config_space); + p->pbm_A.config_space = p->pbm_B.config_space = + (p->controller_regs + SABRE_CONFIGSPACE); + printk("SABRE: Shared PCI config space at %016lx\n", + p->pbm_A.config_space); err = prom_getproperty(pnode, "virtual-dma", (char *)&vdma[0], sizeof(vdma)); diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index daac0d783..ebeeb0bfa 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1,4 +1,4 @@ -/* $Id: pci_schizo.c,v 1.3 2001/02/13 01:16:44 davem Exp $ +/* $Id: pci_schizo.c,v 1.13 2001/03/21 00:29:58 davem Exp $ * pci_schizo.c: SCHIZO specific PCI controller support. * * Copyright (C) 2001 David S. Miller (davem@redhat.com) @@ -13,37 +13,244 @@ #include <asm/pbm.h> #include <asm/iommu.h> #include <asm/irq.h> +#include <asm/upa.h> #include "pci_impl.h" +/* All SCHIZO registers are 64-bits. The following accessor + * routines are how they are accessed. The REG parameter + * is a physical address. + */ +#define schizo_read(__reg) \ +({ u64 __ret; \ + __asm__ __volatile__("ldxa [%1] %2, %0" \ + : "=r" (__ret) \ + : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \ + : "memory"); \ + __ret; \ +}) +#define schizo_write(__reg, __val) \ + __asm__ __volatile__("stxa %0, [%1] %2" \ + : /* no outputs */ \ + : "r" (__val), "r" (__reg), \ + "i" (ASI_PHYS_BYPASS_EC_E)) + +/* This is a convention that at least Excalibur and Merlin + * follow. I suppose the SCHIZO used in Starcat and friends + * will do similar. + * + * The only way I could see this changing is if the newlink + * block requires more space in Schizo's address space than + * they predicted, thus requiring an address space reorg when + * the newer Schizo is taped out. + * + * These offsets look weird because I keep in p->controller_regs + * the second PROM register property minus 0x10000 which is the + * base of the Safari and UPA64S registers of SCHIZO. + */ +#define SCHIZO_PBM_A_REGS_OFF (0x600000UL - 0x400000UL) +#define SCHIZO_PBM_B_REGS_OFF (0x700000UL - 0x400000UL) + +/* Streaming buffer control register. */ +#define SCHIZO_STRBUF_CTRL_LPTR 0x00000000000000f0UL /* LRU Lock Pointer */ +#define SCHIZO_STRBUF_CTRL_LENAB 0x0000000000000008UL /* LRU Lock Enable */ +#define SCHIZO_STRBUF_CTRL_RRDIS 0x0000000000000004UL /* Rerun Disable */ +#define SCHIZO_STRBUF_CTRL_DENAB 0x0000000000000002UL /* Diagnostic Mode Enable */ +#define SCHIZO_STRBUF_CTRL_ENAB 0x0000000000000001UL /* Streaming Buffer Enable */ + +/* IOMMU control register. */ +#define SCHIZO_IOMMU_CTRL_RESV 0xfffffffff9000000 /* Reserved */ +#define SCHIZO_IOMMU_CTRL_XLTESTAT 0x0000000006000000 /* Translation Error Status */ +#define SCHIZO_IOMMU_CTRL_XLTEERR 0x0000000001000000 /* Translation Error encountered */ +#define SCHIZO_IOMMU_CTRL_LCKEN 0x0000000000800000 /* Enable translation locking */ +#define SCHIZO_IOMMU_CTRL_LCKPTR 0x0000000000780000 /* Translation lock pointer */ +#define SCHIZO_IOMMU_CTRL_TSBSZ 0x0000000000070000 /* TSB Size */ +#define SCHIZO_IOMMU_TSBSZ_1K 0x0000000000000000 /* TSB Table 1024 8-byte entries */ +#define SCHIZO_IOMMU_TSBSZ_2K 0x0000000000010000 /* TSB Table 2048 8-byte entries */ +#define SCHIZO_IOMMU_TSBSZ_4K 0x0000000000020000 /* TSB Table 4096 8-byte entries */ +#define SCHIZO_IOMMU_TSBSZ_8K 0x0000000000030000 /* TSB Table 8192 8-byte entries */ +#define SCHIZO_IOMMU_TSBSZ_16K 0x0000000000040000 /* TSB Table 16k 8-byte entries */ +#define SCHIZO_IOMMU_TSBSZ_32K 0x0000000000050000 /* TSB Table 32k 8-byte entries */ +#define SCHIZO_IOMMU_TSBSZ_64K 0x0000000000060000 /* TSB Table 64k 8-byte entries */ +#define SCHIZO_IOMMU_TSBSZ_128K 0x0000000000070000 /* TSB Table 128k 8-byte entries */ +#define SCHIZO_IOMMU_CTRL_RESV2 0x000000000000fff8 /* Reserved */ +#define SCHIZO_IOMMU_CTRL_TBWSZ 0x0000000000000004 /* Assumed page size, 0=8k 1=64k */ +#define SCHIZO_IOMMU_CTRL_DENAB 0x0000000000000002 /* Diagnostic mode enable */ +#define SCHIZO_IOMMU_CTRL_ENAB 0x0000000000000001 /* IOMMU Enable */ + +/* Schizo config space address format is nearly identical to + * that of PSYCHO: + * + * 32 24 23 16 15 11 10 8 7 2 1 0 + * --------------------------------------------------------- + * |0 0 0 0 0 0 0 0 0| bus | device | function | reg | 0 0 | + * --------------------------------------------------------- + */ +#define SCHIZO_CONFIG_BASE(PBM) ((PBM)->config_space) +#define SCHIZO_CONFIG_ENCODE(BUS, DEVFN, REG) \ + (((unsigned long)(BUS) << 16) | \ + ((unsigned long)(DEVFN) << 8) | \ + ((unsigned long)(REG))) + +static void *schizo_pci_config_mkaddr(struct pci_pbm_info *pbm, + unsigned char bus, + unsigned int devfn, + int where) +{ + if (!pbm) + return NULL; + return (void *) + (SCHIZO_CONFIG_BASE(pbm) | + SCHIZO_CONFIG_ENCODE(bus, devfn, where)); +} + +/* 4 slots on pbm A, and 6 slots on pbm B. In both cases + * slot 0 is the SCHIZO host bridge itself. + */ +static int schizo_out_of_range(struct pci_pbm_info *pbm, + unsigned char bus, + unsigned char devfn) +{ + return ((pbm->parent == 0) || + ((pbm == &pbm->parent->pbm_B) && + (bus == pbm->pci_first_busno) && + PCI_SLOT(devfn) > 6) || + ((pbm == &pbm->parent->pbm_A) && + (bus == pbm->pci_first_busno) && + PCI_SLOT(devfn) > 4)); +} + +/* SCHIZO PCI configuration space accessors. */ + static int schizo_read_byte(struct pci_dev *dev, int where, u8 *value) { - /* IMPLEMENT ME */ + struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; + unsigned char bus = dev->bus->number; + unsigned int devfn = dev->devfn; + u8 *addr; + + *value = 0xff; + addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); + if (!addr) + return PCIBIOS_SUCCESSFUL; + + if (schizo_out_of_range(pbm, bus, devfn)) + return PCIBIOS_SUCCESSFUL; + pci_config_read8(addr, value); + return PCIBIOS_SUCCESSFUL; } static int schizo_read_word(struct pci_dev *dev, int where, u16 *value) { - /* IMPLEMENT ME */ + struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; + unsigned char bus = dev->bus->number; + unsigned int devfn = dev->devfn; + u16 *addr; + + *value = 0xffff; + addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); + if (!addr) + return PCIBIOS_SUCCESSFUL; + + if (schizo_out_of_range(pbm, bus, devfn)) + return PCIBIOS_SUCCESSFUL; + + if (where & 0x01) { + printk("pcibios_read_config_word: misaligned reg [%x]\n", + where); + return PCIBIOS_SUCCESSFUL; + } + pci_config_read16(addr, value); + return PCIBIOS_SUCCESSFUL; } static int schizo_read_dword(struct pci_dev *dev, int where, u32 *value) { - /* IMPLEMENT ME */ + struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; + unsigned char bus = dev->bus->number; + unsigned int devfn = dev->devfn; + u32 *addr; + + *value = 0xffffffff; + addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); + if (!addr) + return PCIBIOS_SUCCESSFUL; + + if (schizo_out_of_range(pbm, bus, devfn)) + return PCIBIOS_SUCCESSFUL; + + if (where & 0x03) { + printk("pcibios_read_config_dword: misaligned reg [%x]\n", + where); + return PCIBIOS_SUCCESSFUL; + } + + pci_config_read32(addr, value); + return PCIBIOS_SUCCESSFUL; } static int schizo_write_byte(struct pci_dev *dev, int where, u8 value) { - /* IMPLEMENT ME */ + struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; + unsigned char bus = dev->bus->number; + unsigned int devfn = dev->devfn; + u8 *addr; + + addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); + if (!addr) + return PCIBIOS_SUCCESSFUL; + + if (schizo_out_of_range(pbm, bus, devfn)) + return PCIBIOS_SUCCESSFUL; + + pci_config_write8(addr, value); + return PCIBIOS_SUCCESSFUL; } static int schizo_write_word(struct pci_dev *dev, int where, u16 value) { - /* IMPLEMENT ME */ + struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; + unsigned char bus = dev->bus->number; + unsigned int devfn = dev->devfn; + u16 *addr; + + addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); + if (!addr) + return PCIBIOS_SUCCESSFUL; + + if (schizo_out_of_range(pbm, bus, devfn)) + return PCIBIOS_SUCCESSFUL; + + if (where & 0x01) { + printk("pcibios_write_config_word: misaligned reg [%x]\n", + where); + return PCIBIOS_SUCCESSFUL; + } + pci_config_write16(addr, value); + return PCIBIOS_SUCCESSFUL; } static int schizo_write_dword(struct pci_dev *dev, int where, u32 value) { - /* IMPLEMENT ME */ + struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; + unsigned char bus = dev->bus->number; + unsigned int devfn = dev->devfn; + u32 *addr; + + addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); + if (!addr) + return PCIBIOS_SUCCESSFUL; + + if (schizo_out_of_range(pbm, bus, devfn)) + return PCIBIOS_SUCCESSFUL; + + if (where & 0x03) { + printk("pcibios_write_config_dword: misaligned reg [%x]\n", + where); + return PCIBIOS_SUCCESSFUL; + } + pci_config_write32(addr, value); + return PCIBIOS_SUCCESSFUL; } static struct pci_ops schizo_ops = { @@ -55,34 +262,1445 @@ static struct pci_ops schizo_ops = { schizo_write_dword }; -static void __init schizo_scan_bus(struct pci_controller_info *p) +/* SCHIZO interrupt mapping support. Unlike Psycho, for this controller the + * imap/iclr registers are per-PBM. + */ +#define SCHIZO_IMAP_BASE 0x1000UL +#define SCHIZO_ICLR_BASE 0x1400UL + +static unsigned long schizo_imap_offset(unsigned long ino) { - /* IMPLEMENT ME */ + return SCHIZO_IMAP_BASE + (ino * 8UL); } -static unsigned int __init schizo_irq_build(struct pci_controller_info *p, +static unsigned long schizo_iclr_offset(unsigned long ino) +{ + return SCHIZO_ICLR_BASE + (ino * 8UL); +} + +/* PCI SCHIZO INO number to Sparc PIL level. This table only matters for + * INOs which will not have an associated PCI device struct, ie. onboard + * EBUS devices and PCI controller internal error interrupts. + */ +static unsigned char schizo_pil_table[] = { +/*0x00*/0, 0, 0, 0, /* PCI slot 0 Int A, B, C, D */ +/*0x04*/0, 0, 0, 0, /* PCI slot 1 Int A, B, C, D */ +/*0x08*/0, 0, 0, 0, /* PCI slot 2 Int A, B, C, D */ +/*0x0c*/0, 0, 0, 0, /* PCI slot 3 Int A, B, C, D */ +/*0x10*/0, 0, 0, 0, /* PCI slot 4 Int A, B, C, D */ +/*0x14*/0, 0, 0, 0, /* PCI slot 5 Int A, B, C, D */ +/*0x18*/3, /* SCSI */ +/*0x19*/3, /* second SCSI */ +/*0x1a*/0, /* UNKNOWN */ +/*0x1b*/0, /* UNKNOWN */ +/*0x1c*/8, /* Parallel */ +/*0x1d*/5, /* Ethernet */ +/*0x1e*/8, /* Firewire-1394 */ +/*0x1f*/9, /* USB */ +/*0x20*/13, /* Audio Record */ +/*0x21*/14, /* Audio Playback */ +/*0x22*/12, /* Serial */ +/*0x23*/2, /* EBUS I2C */ +/*0x24*/10, /* RTC Clock */ +/*0x25*/11, /* Floppy */ +/*0x26*/0, /* UNKNOWN */ +/*0x27*/0, /* UNKNOWN */ +/*0x28*/0, /* UNKNOWN */ +/*0x29*/0, /* UNKNOWN */ +/*0x2a*/10, /* UPA 1 */ +/*0x2b*/10, /* UPA 2 */ +/*0x2c*/0, /* UNKNOWN */ +/*0x2d*/0, /* UNKNOWN */ +/*0x2e*/0, /* UNKNOWN */ +/*0x2f*/0, /* UNKNOWN */ +/*0x30*/15, /* Uncorrectable ECC */ +/*0x31*/15, /* Correctable ECC */ +/*0x32*/15, /* PCI Bus A Error */ +/*0x33*/15, /* PCI Bus B Error */ +/*0x34*/15, /* Safari Bus Error */ +/*0x35*/0, /* Reserved */ +/*0x36*/0, /* Reserved */ +/*0x37*/0, /* Reserved */ +/*0x38*/0, /* Reserved for NewLink */ +/*0x39*/0, /* Reserved for NewLink */ +/*0x3a*/0, /* Reserved for NewLink */ +/*0x3b*/0, /* Reserved for NewLink */ +/*0x3c*/0, /* Reserved for NewLink */ +/*0x3d*/0, /* Reserved for NewLink */ +/*0x3e*/0, /* Reserved for NewLink */ +/*0x3f*/0, /* Reserved for NewLink */ +}; + +static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino) +{ + int ret; + + ret = schizo_pil_table[ino]; + if (ret == 0 && pdev == NULL) { + ret = 1; + } else if (ret == 0) { + switch ((pdev->class >> 16) & 0x0f) { + case PCI_BASE_CLASS_STORAGE: + ret = 4; + + case PCI_BASE_CLASS_NETWORK: + ret = 6; + + case PCI_BASE_CLASS_DISPLAY: + ret = 9; + + case PCI_BASE_CLASS_MULTIMEDIA: + case PCI_BASE_CLASS_MEMORY: + case PCI_BASE_CLASS_BRIDGE: + ret = 10; + + default: + ret = 1; + }; + } + + return ret; +} + +static unsigned int __init schizo_irq_build(struct pci_pbm_info *pbm, struct pci_dev *pdev, unsigned int ino) { - /* IMPLEMENT ME */ + struct pci_controller_info *p = pbm->parent; + struct ino_bucket *bucket; + unsigned long imap, iclr, pbm_off; + unsigned long imap_off, iclr_off; + int pil, inofixup = 0; + + if (pbm == &p->pbm_A) + pbm_off = SCHIZO_PBM_A_REGS_OFF; + else + pbm_off = SCHIZO_PBM_B_REGS_OFF; + + ino &= PCI_IRQ_INO; + imap_off = schizo_imap_offset(ino); + + /* Now build the IRQ bucket. */ + pil = schizo_ino_to_pil(pdev, ino); + imap = p->controller_regs + pbm_off + imap_off; + imap += 4; + + iclr_off = schizo_iclr_offset(ino); + iclr = p->controller_regs + pbm_off + iclr_off; + iclr += 4; + + if (ino < 0x18) + inofixup = ino & 0x03; + + bucket = __bucket(build_irq(pil, inofixup, iclr, imap)); + bucket->flags |= IBF_PCI; + + return __irq(bucket); +} + +/* SCHIZO error handling support. */ +enum schizo_error_type { + UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR +}; + +static spinlock_t stc_buf_lock = SPIN_LOCK_UNLOCKED; +static unsigned long stc_error_buf[128]; +static unsigned long stc_tag_buf[16]; +static unsigned long stc_line_buf[16]; + +static void schizo_clear_other_err_intr(int irq) +{ + struct ino_bucket *bucket = __bucket(irq); + unsigned long iclr = bucket->iclr; + + iclr += (SCHIZO_PBM_B_REGS_OFF - SCHIZO_PBM_A_REGS_OFF); + upa_writel(ICLR_IDLE, iclr); +} + +#define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */ +#define SCHIZO_STC_TAG 0xba00UL /* --> 0xba80 */ +#define SCHIZO_STC_LINE 0xbb00UL /* --> 0xbb80 */ + +#define SCHIZO_STCERR_WRITE 0x2UL +#define SCHIZO_STCERR_READ 0x1UL + +#define SCHIZO_STCTAG_PPN 0x3fffffff00000000UL +#define SCHIZO_STCTAG_VPN 0x00000000ffffe000UL +#define SCHIZO_STCTAG_VALID 0x8000000000000000UL +#define SCHIZO_STCTAG_READ 0x4000000000000000UL + +#define SCHIZO_STCLINE_LINDX 0x0000000007800000UL +#define SCHIZO_STCLINE_SPTR 0x000000000007e000UL +#define SCHIZO_STCLINE_LADDR 0x0000000000001fc0UL +#define SCHIZO_STCLINE_EPTR 0x000000000000003fUL +#define SCHIZO_STCLINE_VALID 0x0000000000600000UL +#define SCHIZO_STCLINE_FOFN 0x0000000000180000UL + +static void __schizo_check_stc_error_pbm(struct pci_pbm_info *pbm, + enum schizo_error_type type) +{ + struct pci_controller_info *p = pbm->parent; + struct pci_strbuf *strbuf = &pbm->stc; + unsigned long regbase = p->controller_regs; + unsigned long err_base, tag_base, line_base; + u64 control; + char pbm_name = (pbm == &p->pbm_A ? 'A' : 'B'); + int i; + + if (pbm == &p->pbm_A) + regbase += SCHIZO_PBM_A_REGS_OFF; + else + regbase += SCHIZO_PBM_B_REGS_OFF; + + err_base = regbase + SCHIZO_STC_ERR; + tag_base = regbase + SCHIZO_STC_TAG; + line_base = regbase + SCHIZO_STC_LINE; + + spin_lock(&stc_buf_lock); + + /* This is __REALLY__ dangerous. When we put the + * streaming buffer into diagnostic mode to probe + * it's tags and error status, we _must_ clear all + * of the line tag valid bits before re-enabling + * the streaming buffer. If any dirty data lives + * in the STC when we do this, we will end up + * invalidating it before it has a chance to reach + * main memory. + */ + control = schizo_read(strbuf->strbuf_control); + schizo_write(strbuf->strbuf_control, + (control | SCHIZO_STRBUF_CTRL_DENAB)); + for (i = 0; i < 128; i++) { + unsigned long val; + + val = schizo_read(err_base + (i * 8UL)); + schizo_write(err_base + (i * 8UL), 0UL); + stc_error_buf[i] = val; + } + for (i = 0; i < 16; i++) { + stc_tag_buf[i] = schizo_read(tag_base + (i * 8UL)); + stc_line_buf[i] = schizo_read(line_base + (i * 8UL)); + schizo_write(tag_base + (i * 8UL), 0UL); + schizo_write(line_base + (i * 8UL), 0UL); + } + + /* OK, state is logged, exit diagnostic mode. */ + schizo_write(strbuf->strbuf_control, control); + + for (i = 0; i < 16; i++) { + int j, saw_error, first, last; + + saw_error = 0; + first = i * 8; + last = first + 8; + for (j = first; j < last; j++) { + unsigned long errval = stc_error_buf[j]; + if (errval != 0) { + saw_error++; + printk("SCHIZO%d: PBM-%c STC_ERR(%d)[wr(%d)rd(%d)]\n", + p->index, pbm_name, + j, + (errval & SCHIZO_STCERR_WRITE) ? 1 : 0, + (errval & SCHIZO_STCERR_READ) ? 1 : 0); + } + } + if (saw_error != 0) { + unsigned long tagval = stc_tag_buf[i]; + unsigned long lineval = stc_line_buf[i]; + printk("SCHIZO%d: PBM-%c STC_TAG(%d)[PA(%016lx)VA(%08lx)V(%d)R(%d)]\n", + p->index, pbm_name, + i, + ((tagval & SCHIZO_STCTAG_PPN) >> 19UL), + (tagval & SCHIZO_STCTAG_VPN), + ((tagval & SCHIZO_STCTAG_VALID) ? 1 : 0), + ((tagval & SCHIZO_STCTAG_READ) ? 1 : 0)); + + /* XXX Should spit out per-bank error information... -DaveM */ + printk("SCHIZO%d: PBM-%c STC_LINE(%d)[LIDX(%lx)SP(%lx)LADDR(%lx)EP(%lx)" + "V(%d)FOFN(%d)]\n", + p->index, pbm_name, + i, + ((lineval & SCHIZO_STCLINE_LINDX) >> 23UL), + ((lineval & SCHIZO_STCLINE_SPTR) >> 13UL), + ((lineval & SCHIZO_STCLINE_LADDR) >> 6UL), + ((lineval & SCHIZO_STCLINE_EPTR) >> 0UL), + ((lineval & SCHIZO_STCLINE_VALID) ? 1 : 0), + ((lineval & SCHIZO_STCLINE_FOFN) ? 1 : 0)); + } + } + + spin_unlock(&stc_buf_lock); +} + +/* IOMMU is per-PBM in Schizo, so interrogate both for anonymous + * controller level errors. + */ + +#define SCHIZO_IOMMU_TAG 0xa580UL +#define SCHIZO_IOMMU_DATA 0xa600UL + +#define SCHIZO_IOMMU_TAG_CTXT 0x0000001ffe000000UL +#define SCHIZO_IOMMU_TAG_ERRSTS 0x0000000001800000UL +#define SCHIZO_IOMMU_TAG_ERR 0x0000000000400000UL +#define SCHIZO_IOMMU_TAG_WRITE 0x0000000000200000UL +#define SCHIZO_IOMMU_TAG_STREAM 0x0000000000100000UL +#define SCHIZO_IOMMU_TAG_SIZE 0x0000000000080000UL +#define SCHIZO_IOMMU_TAG_VPAGE 0x000000000007ffffUL + +#define SCHIZO_IOMMU_DATA_VALID 0x0000000100000000UL +#define SCHIZO_IOMMU_DATA_CACHE 0x0000000040000000UL +#define SCHIZO_IOMMU_DATA_PPAGE 0x000000003fffffffUL + +static void schizo_check_iommu_error_pbm(struct pci_pbm_info *pbm, + enum schizo_error_type type) +{ + struct pci_controller_info *p = pbm->parent; + struct pci_iommu *iommu = pbm->iommu; + unsigned long iommu_tag[16]; + unsigned long iommu_data[16]; + unsigned long flags; + u64 control; + char pbm_name = (pbm == &p->pbm_A ? 'A' : 'B'); + int i; + + spin_lock_irqsave(&iommu->lock, flags); + control = schizo_read(iommu->iommu_control); + if (control & SCHIZO_IOMMU_CTRL_XLTEERR) { + unsigned long base; + char *type_string; + + /* Clear the error encountered bit. */ + control &= ~SCHIZO_IOMMU_CTRL_XLTEERR; + schizo_write(iommu->iommu_control, control); + + switch((control & SCHIZO_IOMMU_CTRL_XLTESTAT) >> 25UL) { + case 0: + type_string = "Protection Error"; + break; + case 1: + type_string = "Invalid Error"; + break; + case 2: + type_string = "TimeOut Error"; + break; + case 3: + default: + type_string = "ECC Error"; + break; + }; + printk("SCHIZO%d: PBM-%c IOMMU Error, type[%s]\n", + p->index, pbm_name, type_string); + + /* Put the IOMMU into diagnostic mode and probe + * it's TLB for entries with error status. + * + * It is very possible for another DVMA to occur + * while we do this probe, and corrupt the system + * further. But we are so screwed at this point + * that we are likely to crash hard anyways, so + * get as much diagnostic information to the + * console as we can. + */ + schizo_write(iommu->iommu_control, + control | SCHIZO_IOMMU_CTRL_DENAB); + + base = p->controller_regs; + if (pbm == &p->pbm_A) + base += SCHIZO_PBM_A_REGS_OFF; + else + base += SCHIZO_PBM_B_REGS_OFF; + + for (i = 0; i < 16; i++) { + iommu_tag[i] = + schizo_read(base + SCHIZO_IOMMU_TAG + (i * 8UL)); + iommu_data[i] = + schizo_read(base + SCHIZO_IOMMU_DATA + (i * 8UL)); + + /* Now clear out the entry. */ + schizo_write(base + SCHIZO_IOMMU_TAG + (i * 8UL), 0); + schizo_write(base + SCHIZO_IOMMU_DATA + (i * 8UL), 0); + } + + /* Leave diagnostic mode. */ + schizo_write(iommu->iommu_control, control); + + for (i = 0; i < 16; i++) { + unsigned long tag, data; + + tag = iommu_tag[i]; + if (!(tag & SCHIZO_IOMMU_TAG_ERR)) + continue; + + data = iommu_data[i]; + switch((tag & SCHIZO_IOMMU_TAG_ERRSTS) >> 23UL) { + case 0: + type_string = "Protection Error"; + break; + case 1: + type_string = "Invalid Error"; + break; + case 2: + type_string = "TimeOut Error"; + break; + case 3: + default: + type_string = "ECC Error"; + break; + }; + printk("SCHIZO%d: PBM-%c IOMMU TAG(%d)[error(%s) ctx(%x) wr(%d) str(%d) " + "sz(%dK) vpg(%08lx)]\n", + p->index, pbm_name, i, type_string, + (int)((tag & SCHIZO_IOMMU_TAG_CTXT) >> 25UL), + ((tag & SCHIZO_IOMMU_TAG_WRITE) ? 1 : 0), + ((tag & SCHIZO_IOMMU_TAG_STREAM) ? 1 : 0), + ((tag & SCHIZO_IOMMU_TAG_SIZE) ? 64 : 8), + (tag & SCHIZO_IOMMU_TAG_VPAGE) << PAGE_SHIFT); + printk("SCHIZO%d: PBM-%c IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]\n", + p->index, pbm_name, i, + ((data & SCHIZO_IOMMU_DATA_VALID) ? 1 : 0), + ((data & SCHIZO_IOMMU_DATA_CACHE) ? 1 : 0), + (data & SCHIZO_IOMMU_DATA_PPAGE) << PAGE_SHIFT); + } + } + __schizo_check_stc_error_pbm(pbm, type); + spin_unlock_irqrestore(&iommu->lock, flags); +} + +static void schizo_check_iommu_error(struct pci_controller_info *p, + enum schizo_error_type type) +{ + schizo_check_iommu_error_pbm(&p->pbm_A, type); + schizo_check_iommu_error_pbm(&p->pbm_B, type); +} + +/* Uncorrectable ECC error status gathering. */ +#define SCHIZO_UE_AFSR 0x10030UL +#define SCHIZO_UE_AFAR 0x10038UL + +#define SCHIZO_UEAFSR_PPIO 0x8000000000000000UL +#define SCHIZO_UEAFSR_PDRD 0x4000000000000000UL +#define SCHIZO_UEAFSR_PDWR 0x2000000000000000UL +#define SCHIZO_UEAFSR_SPIO 0x1000000000000000UL +#define SCHIZO_UEAFSR_SDMA 0x0800000000000000UL +#define SCHIZO_UEAFSR_ERRPNDG 0x0300000000000000UL +#define SCHIZO_UEAFSR_BMSK 0x000003ff00000000UL +#define SCHIZO_UEAFSR_QOFF 0x00000000c0000000UL +#define SCHIZO_UEAFSR_AID 0x000000001f000000UL +#define SCHIZO_UEAFSR_PARTIAL 0x0000000000800000UL +#define SCHIZO_UEAFSR_OWNEDIN 0x0000000000400000UL +#define SCHIZO_UEAFSR_MTAGSYND 0x00000000000f0000UL +#define SCHIZO_UEAFSR_MTAG 0x000000000000e000UL +#define SCHIZO_UEAFSR_ECCSYND 0x00000000000001ffUL + +static void schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct pci_controller_info *p = dev_id; + unsigned long afsr_reg = p->controller_regs + SCHIZO_UE_AFSR; + unsigned long afar_reg = p->controller_regs + SCHIZO_UE_AFAR; + unsigned long afsr, afar, error_bits; + int reported, limit; + + /* Latch uncorrectable error status. */ + afar = schizo_read(afar_reg); + + /* If either of the error pending bits are set in the + * AFSR, the error status is being actively updated by + * the hardware and we must re-read to get a clean value. + */ + limit = 1000; + do { + afsr = schizo_read(afsr_reg); + } while ((afsr & SCHIZO_UEAFSR_ERRPNDG) != 0 && --limit); + + /* Clear the primary/secondary error status bits. */ + error_bits = afsr & + (SCHIZO_UEAFSR_PPIO | SCHIZO_UEAFSR_PDRD | SCHIZO_UEAFSR_PDWR | + SCHIZO_UEAFSR_SPIO | SCHIZO_UEAFSR_SDMA); + schizo_write(afsr_reg, error_bits); + + /* Log the error. */ + printk("SCHIZO%d: Uncorrectable Error, primary error type[%s]\n", + p->index, + (((error_bits & SCHIZO_UEAFSR_PPIO) ? + "PIO" : + ((error_bits & SCHIZO_UEAFSR_PDRD) ? + "DMA Read" : + ((error_bits & SCHIZO_UEAFSR_PDWR) ? + "DMA Write" : "???"))))); + printk("SCHIZO%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", + p->index, + (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, + (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, + (afsr & SCHIZO_UEAFSR_AID) >> 24UL); + printk("SCHIZO%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", + p->index, + (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, + (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, + (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, + (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, + (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); + printk("SCHIZO%d: UE AFAR [%016lx]\n", p->index, afar); + printk("SCHIZO%d: UE Secondary errors [", p->index); + reported = 0; + if (afsr & SCHIZO_UEAFSR_SPIO) { + reported++; + printk("(PIO)"); + } + if (afsr & SCHIZO_UEAFSR_SDMA) { + reported++; + printk("(DMA)"); + } + if (!reported) + printk("(none)"); + printk("]\n"); + + /* Interrogate IOMMU for error status. */ + schizo_check_iommu_error(p, UE_ERR); + + schizo_clear_other_err_intr(irq); +} + +#define SCHIZO_CE_AFSR 0x10040UL +#define SCHIZO_CE_AFAR 0x10048UL + +#define SCHIZO_CEAFSR_PPIO 0x8000000000000000UL +#define SCHIZO_CEAFSR_PDRD 0x4000000000000000UL +#define SCHIZO_CEAFSR_PDWR 0x2000000000000000UL +#define SCHIZO_CEAFSR_SPIO 0x1000000000000000UL +#define SCHIZO_CEAFSR_SDMA 0x0800000000000000UL +#define SCHIZO_CEAFSR_ERRPNDG 0x0300000000000000UL +#define SCHIZO_CEAFSR_BMSK 0x000003ff00000000UL +#define SCHIZO_CEAFSR_QOFF 0x00000000c0000000UL +#define SCHIZO_CEAFSR_AID 0x000000001f000000UL +#define SCHIZO_CEAFSR_PARTIAL 0x0000000000800000UL +#define SCHIZO_CEAFSR_OWNEDIN 0x0000000000400000UL +#define SCHIZO_CEAFSR_MTAGSYND 0x00000000000f0000UL +#define SCHIZO_CEAFSR_MTAG 0x000000000000e000UL +#define SCHIZO_CEAFSR_ECCSYND 0x00000000000001ffUL + +static void schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct pci_controller_info *p = dev_id; + unsigned long afsr_reg = p->controller_regs + SCHIZO_CE_AFSR; + unsigned long afar_reg = p->controller_regs + SCHIZO_CE_AFAR; + unsigned long afsr, afar, error_bits; + int reported, limit; + + /* Latch error status. */ + afar = schizo_read(afar_reg); + + /* If either of the error pending bits are set in the + * AFSR, the error status is being actively updated by + * the hardware and we must re-read to get a clean value. + */ + limit = 1000; + do { + afsr = schizo_read(afsr_reg); + } while ((afsr & SCHIZO_UEAFSR_ERRPNDG) != 0 && --limit); + + /* Clear primary/secondary error status bits. */ + error_bits = afsr & + (SCHIZO_CEAFSR_PPIO | SCHIZO_CEAFSR_PDRD | SCHIZO_CEAFSR_PDWR | + SCHIZO_CEAFSR_SPIO | SCHIZO_CEAFSR_SDMA); + schizo_write(afsr_reg, error_bits); + + /* Log the error. */ + printk("SCHIZO%d: Correctable Error, primary error type[%s]\n", + p->index, + (((error_bits & SCHIZO_CEAFSR_PPIO) ? + "PIO" : + ((error_bits & SCHIZO_CEAFSR_PDRD) ? + "DMA Read" : + ((error_bits & SCHIZO_CEAFSR_PDWR) ? + "DMA Write" : "???"))))); + + /* XXX Use syndrome and afar to print out module string just like + * XXX UDB CE trap handler does... -DaveM + */ + printk("SCHIZO%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", + p->index, + (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, + (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, + (afsr & SCHIZO_UEAFSR_AID) >> 24UL); + printk("SCHIZO%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", + p->index, + (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, + (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, + (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, + (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, + (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); + printk("SCHIZO%d: CE AFAR [%016lx]\n", p->index, afar); + printk("SCHIZO%d: CE Secondary errors [", p->index); + reported = 0; + if (afsr & SCHIZO_CEAFSR_SPIO) { + reported++; + printk("(PIO)"); + } + if (afsr & SCHIZO_CEAFSR_SDMA) { + reported++; + printk("(DMA)"); + } + if (!reported) + printk("(none)"); + printk("]\n"); + + schizo_clear_other_err_intr(irq); +} + +#define SCHIZO_PCI_AFSR 0x2010UL +#define SCHIZO_PCI_AFAR 0x2018UL + +#define SCHIZO_PCIAFSR_PMA 0x8000000000000000UL +#define SCHIZO_PCIAFSR_PTA 0x4000000000000000UL +#define SCHIZO_PCIAFSR_PRTRY 0x2000000000000000UL +#define SCHIZO_PCIAFSR_PPERR 0x1000000000000000UL +#define SCHIZO_PCIAFSR_PTTO 0x0800000000000000UL +#define SCHIZO_PCIAFSR_PUNUS 0x0400000000000000UL +#define SCHIZO_PCIAFSR_SMA 0x0200000000000000UL +#define SCHIZO_PCIAFSR_STA 0x0100000000000000UL +#define SCHIZO_PCIAFSR_SRTRY 0x0080000000000000UL +#define SCHIZO_PCIAFSR_SPERR 0x0040000000000000UL +#define SCHIZO_PCIAFSR_STTO 0x0020000000000000UL +#define SCHIZO_PCIAFSR_SUNUS 0x0010000000000000UL +#define SCHIZO_PCIAFSR_BMSK 0x000003ff00000000UL +#define SCHIZO_PCIAFSR_BLK 0x0000000080000000UL +#define SCHIZO_PCIAFSR_CFG 0x0000000040000000UL +#define SCHIZO_PCIAFSR_MEM 0x0000000020000000UL +#define SCHIZO_PCIAFSR_IO 0x0000000010000000UL + +static void schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct pci_pbm_info *pbm = dev_id; + struct pci_controller_info *p = pbm->parent; + unsigned long afsr_reg, afar_reg, base; + unsigned long afsr, afar, error_bits; + int reported; + char pbm_name; + + base = p->controller_regs; + if (pbm == &pbm->parent->pbm_A) { + base += SCHIZO_PBM_A_REGS_OFF; + pbm_name = 'A'; + } else { + base += SCHIZO_PBM_B_REGS_OFF; + pbm_name = 'B'; + } + + afsr_reg = base + SCHIZO_PCI_AFSR; + afar_reg = base + SCHIZO_PCI_AFAR; + + /* Latch error status. */ + afar = schizo_read(afar_reg); + afsr = schizo_read(afsr_reg); + + /* Clear primary/secondary error status bits. */ + error_bits = afsr & + (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | + SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | + SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | + SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA | + SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | + SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS); + schizo_write(afsr_reg, error_bits); + + /* Log the error. */ + printk("SCHIZO%d: PBM-%c PCI Error, primary error type[%s]\n", + p->index, pbm_name, + (((error_bits & SCHIZO_PCIAFSR_PMA) ? + "Master Abort" : + ((error_bits & SCHIZO_PCIAFSR_PTA) ? + "Target Abort" : + ((error_bits & SCHIZO_PCIAFSR_PRTRY) ? + "Excessive Retries" : + ((error_bits & SCHIZO_PCIAFSR_PPERR) ? + "Parity Error" : + ((error_bits & SCHIZO_PCIAFSR_PTTO) ? + "Timeout" : + ((error_bits & SCHIZO_PCIAFSR_PUNUS) ? + "Bus Unusable" : "???")))))))); + printk("SCHIZO%d: PBM-%c bytemask[%04lx] was_block(%d) space(%s)\n", + p->index, pbm_name, + (afsr & SCHIZO_PCIAFSR_BMSK) >> 32UL, + (afsr & SCHIZO_PCIAFSR_BLK) ? 1 : 0, + ((afsr & SCHIZO_PCIAFSR_CFG) ? + "Config" : + ((afsr & SCHIZO_PCIAFSR_MEM) ? + "Memory" : + ((afsr & SCHIZO_PCIAFSR_IO) ? + "I/O" : "???")))); + printk("SCHIZO%d: PBM-%c PCI AFAR [%016lx]\n", + p->index, pbm_name, afar); + printk("SCHIZO%d: PBM-%c PCI Secondary errors [", + p->index, pbm_name); + reported = 0; + if (afsr & SCHIZO_PCIAFSR_SMA) { + reported++; + printk("(Master Abort)"); + } + if (afsr & SCHIZO_PCIAFSR_STA) { + reported++; + printk("(Target Abort)"); + } + if (afsr & SCHIZO_PCIAFSR_SRTRY) { + reported++; + printk("(Excessive Retries)"); + } + if (afsr & SCHIZO_PCIAFSR_SPERR) { + reported++; + printk("(Parity Error)"); + } + if (afsr & SCHIZO_PCIAFSR_STTO) { + reported++; + printk("(Timeout)"); + } + if (afsr & SCHIZO_PCIAFSR_SUNUS) { + reported++; + printk("(Bus Unusable)"); + } + if (!reported) + printk("(none)"); + printk("]\n"); + + /* For the error types shown, scan PBM's PCI bus for devices + * which have logged that error type. + */ + + /* If we see a Target Abort, this could be the result of an + * IOMMU translation error of some sort. It is extremely + * useful to log this information as usually it indicates + * a bug in the IOMMU support code or a PCI device driver. + */ + if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) { + schizo_check_iommu_error(p, PCI_ERR); + pci_scan_for_target_abort(p, pbm, pbm->pci_bus); + } + if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA)) + pci_scan_for_master_abort(p, pbm, pbm->pci_bus); + + /* For excessive retries, PSYCHO/PBM will abort the device + * and there is no way to specifically check for excessive + * retries in the config space status registers. So what + * we hope is that we'll catch it via the master/target + * abort events. + */ + + if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR)) + pci_scan_for_parity_error(p, pbm, pbm->pci_bus); + + schizo_clear_other_err_intr(irq); +} + +#define SCHIZO_SAFARI_ERRLOG 0x10018UL + +#define SAFARI_ERRLOG_ERROUT 0x8000000000000000UL + +#define SAFARI_ERROR_BADCMD 0x4000000000000000UL +#define SAFARI_ERROR_SSMDIS 0x2000000000000000UL +#define SAFARI_ERROR_BADMA 0x1000000000000000UL +#define SAFARI_ERROR_BADMB 0x0800000000000000UL +#define SAFARI_ERROR_BADMC 0x0400000000000000UL +#define SAFARI_ERROR_CPU1PS 0x0000000000002000UL +#define SAFARI_ERROR_CPU1PB 0x0000000000001000UL +#define SAFARI_ERROR_CPU0PS 0x0000000000000800UL +#define SAFARI_ERROR_CPU0PB 0x0000000000000400UL +#define SAFARI_ERROR_CIQTO 0x0000000000000200UL +#define SAFARI_ERROR_LPQTO 0x0000000000000100UL +#define SAFARI_ERROR_SFPQTO 0x0000000000000080UL +#define SAFARI_ERROR_UFPQTO 0x0000000000000040UL +#define SAFARI_ERROR_APERR 0x0000000000000020UL +#define SAFARI_ERROR_UNMAP 0x0000000000000010UL +#define SAFARI_ERROR_BUSERR 0x0000000000000004UL +#define SAFARI_ERROR_TIMEOUT 0x0000000000000002UL +#define SAFARI_ERROR_ILL 0x0000000000000001UL + +/* We only expect UNMAP errors here. The rest of the Safari errors + * are marked fatal and thus cause a system reset. + */ +static void schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct pci_controller_info *p = dev_id; + u64 errlog; + + errlog = schizo_read(p->controller_regs + SCHIZO_SAFARI_ERRLOG); + schizo_write(p->controller_regs + SCHIZO_SAFARI_ERRLOG, + errlog & ~(SAFARI_ERRLOG_ERROUT)); + + if (!(errlog & SAFARI_ERROR_UNMAP)) { + printk("SCHIZO%d: Unexpected Safari error interrupt, errlog[%016lx]\n", + p->index, errlog); + + schizo_clear_other_err_intr(irq); + return; + } + + printk("SCHIZO%d: Safari interrupt, UNMAPPED error, interrogating IOMMUs.\n", + p->index); + schizo_check_iommu_error(p, SAFARI_ERR); + + schizo_clear_other_err_intr(irq); +} + +/* Nearly identical to PSYCHO equivalents... */ +#define SCHIZO_ECC_CTRL 0x10020UL +#define SCHIZO_ECCCTRL_EE 0x8000000000000000 /* Enable ECC Checking */ +#define SCHIZO_ECCCTRL_UE 0x4000000000000000 /* Enable UE Interrupts */ +#define SCHIZO_ECCCTRL_CE 0x2000000000000000 /* Enable CE INterrupts */ + +#define SCHIZO_SAFARI_ERRCTRL 0x10008UL +#define SCHIZO_SAFERRCTRL_EN 0x8000000000000000UL +#define SCHIZO_SAFARI_IRQCTRL 0x10010UL +#define SCHIZO_SAFIRQCTRL_EN 0x8000000000000000UL + +#define SCHIZO_UE_INO 0x30 /* Uncorrectable ECC error */ +#define SCHIZO_CE_INO 0x31 /* Correctable ECC error */ +#define SCHIZO_PCIERR_A_INO 0x32 /* PBM A PCI bus error */ +#define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ +#define SCHIZO_SERR_INO 0x34 /* Safari interface error */ + +#define SCHIZO_PCIA_CTRL (SCHIZO_PBM_A_REGS_OFF + 0x2000UL) +#define SCHIZO_PCIB_CTRL (SCHIZO_PBM_B_REGS_OFF + 0x2000UL) +#define SCHIZO_PCICTRL_BUNUS (1UL << 63UL) +#define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) +#define SCHIZO_PCICTRL_TTO_ERR (1UL << 38UL) +#define SCHIZO_PCICTRL_RTRY_ERR (1UL << 37UL) +#define SCHIZO_PCICTRL_DTO_ERR (1UL << 36UL) +#define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL) +#define SCHIZO_PCICTRL_SERR (1UL << 34UL) +#define SCHIZO_PCICTRL_SBH_INT (1UL << 18UL) +#define SCHIZO_PCICTRL_EEN (1UL << 17UL) + +static void __init schizo_register_error_handlers(struct pci_controller_info *p) +{ + struct pci_pbm_info *pbm_a = &p->pbm_A; + struct pci_pbm_info *pbm_b = &p->pbm_B; + unsigned long base = p->controller_regs; + unsigned int irq, portid = p->portid; + struct ino_bucket *bucket; + u64 tmp; + + /* Build IRQs and register handlers. */ + irq = schizo_irq_build(pbm_a, NULL, (portid << 6) | SCHIZO_UE_INO); + if (request_irq(irq, schizo_ue_intr, + SA_SHIRQ, "SCHIZO UE", p) < 0) { + prom_printf("SCHIZO%d: Cannot register UE interrupt.\n", + p->index); + prom_halt(); + } + bucket = __bucket(irq); + tmp = readl(bucket->imap); + upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_UE_INO) + 4)); + + irq = schizo_irq_build(pbm_a, NULL, (portid << 6) | SCHIZO_CE_INO); + if (request_irq(irq, schizo_ce_intr, + SA_SHIRQ, "SCHIZO CE", p) < 0) { + prom_printf("SCHIZO%d: Cannot register CE interrupt.\n", + p->index); + prom_halt(); + } + bucket = __bucket(irq); + tmp = upa_readl(bucket->imap); + upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_CE_INO) + 4)); + + irq = schizo_irq_build(pbm_a, NULL, (portid << 6) | SCHIZO_PCIERR_A_INO); + if (request_irq(irq, schizo_pcierr_intr, + SA_SHIRQ, "SCHIZO PCIERR", pbm_a) < 0) { + prom_printf("SCHIZO%d(PBMA): Cannot register PciERR interrupt.\n", + p->index); + prom_halt(); + } + bucket = __bucket(irq); + tmp = upa_readl(bucket->imap); + upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4)); + + irq = schizo_irq_build(pbm_a, NULL, (portid << 6) | SCHIZO_PCIERR_B_INO); + if (request_irq(irq, schizo_pcierr_intr, + SA_SHIRQ, "SCHIZO PCIERR", pbm_b) < 0) { + prom_printf("SCHIZO%d(PBMB): Cannot register PciERR interrupt.\n", + p->index); + prom_halt(); + } + bucket = __bucket(irq); + tmp = upa_readl(bucket->imap); + upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4)); + + irq = schizo_irq_build(pbm_a, NULL, (portid << 6) | SCHIZO_SERR_INO); + if (request_irq(irq, schizo_safarierr_intr, + SA_SHIRQ, "SCHIZO SERR", p) < 0) { + prom_printf("SCHIZO%d(PBMB): Cannot register SafariERR interrupt.\n", + p->index); + prom_halt(); + } + bucket = __bucket(irq); + tmp = upa_readl(bucket->imap); + upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_SERR_INO) + 4)); + + /* Enable UE and CE interrupts for controller. */ + schizo_write(base + SCHIZO_ECC_CTRL, + (SCHIZO_ECCCTRL_EE | + SCHIZO_ECCCTRL_UE | + SCHIZO_ECCCTRL_CE)); + + /* Enable PCI Error interrupts and clear error + * bits for each PBM. + */ + tmp = schizo_read(base + SCHIZO_PCIA_CTRL); + tmp |= (SCHIZO_PCICTRL_BUNUS | + SCHIZO_PCICTRL_ESLCK | + SCHIZO_PCICTRL_TTO_ERR | + SCHIZO_PCICTRL_RTRY_ERR | + SCHIZO_PCICTRL_DTO_ERR | + SCHIZO_PCICTRL_SBH_ERR | + SCHIZO_PCICTRL_SERR | + SCHIZO_PCICTRL_SBH_INT | + SCHIZO_PCICTRL_EEN); + schizo_write(base + SCHIZO_PCIA_CTRL, tmp); + + tmp = schizo_read(base + SCHIZO_PCIB_CTRL); + tmp |= (SCHIZO_PCICTRL_BUNUS | + SCHIZO_PCICTRL_ESLCK | + SCHIZO_PCICTRL_TTO_ERR | + SCHIZO_PCICTRL_RTRY_ERR | + SCHIZO_PCICTRL_DTO_ERR | + SCHIZO_PCICTRL_SBH_ERR | + SCHIZO_PCICTRL_SERR | + SCHIZO_PCICTRL_SBH_INT | + SCHIZO_PCICTRL_EEN); + schizo_write(base + SCHIZO_PCIB_CTRL, tmp); + + schizo_write(base + SCHIZO_PBM_A_REGS_OFF + SCHIZO_PCI_AFSR, + (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | + SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | + SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | + SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA | + SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | + SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS)); + schizo_write(base + SCHIZO_PBM_B_REGS_OFF + SCHIZO_PCI_AFSR, + (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | + SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | + SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | + SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA | + SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | + SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS)); + + /* Make all Safari error conditions fatal except unmapped errors + * which we make generate interrupts. + */ + schizo_write(base + SCHIZO_SAFARI_ERRCTRL, + (SCHIZO_SAFERRCTRL_EN | + (SAFARI_ERROR_BADCMD | SAFARI_ERROR_SSMDIS | + SAFARI_ERROR_BADMA | SAFARI_ERROR_BADMB | + SAFARI_ERROR_BADMC | SAFARI_ERROR_CPU1PS | + SAFARI_ERROR_CPU1PB | SAFARI_ERROR_CPU0PS | + SAFARI_ERROR_CPU0PB | SAFARI_ERROR_CIQTO | + SAFARI_ERROR_LPQTO | SAFARI_ERROR_SFPQTO | + SAFARI_ERROR_UFPQTO | SAFARI_ERROR_APERR | + SAFARI_ERROR_BUSERR | SAFARI_ERROR_TIMEOUT | + SAFARI_ERROR_ILL))); + + schizo_write(base + SCHIZO_SAFARI_IRQCTRL, + (SCHIZO_SAFIRQCTRL_EN | (SAFARI_ERROR_UNMAP))); +} + +/* We have to do the config space accesses by hand, thus... */ +#define PBM_BRIDGE_BUS 0x40 +#define PBM_BRIDGE_SUBORDINATE 0x41 +static void __init pbm_renumber(struct pci_pbm_info *pbm, u8 orig_busno) +{ + u8 *addr, busno; + int nbus; + + busno = pci_highest_busnum; + nbus = pbm->pci_last_busno - pbm->pci_first_busno; + + addr = schizo_pci_config_mkaddr(pbm, orig_busno, + 0, PBM_BRIDGE_BUS); + pci_config_write8(addr, busno); + addr = schizo_pci_config_mkaddr(pbm, busno, + 0, PBM_BRIDGE_SUBORDINATE); + pci_config_write8(addr, busno + nbus); + + pbm->pci_first_busno = busno; + pbm->pci_last_busno = busno + nbus; + pci_highest_busnum = busno + nbus + 1; + + do { + pci_bus2pbm[busno++] = pbm; + } while (nbus--); +} + +/* We have to do the config space accesses by hand here since + * the pci_bus2pbm array is not ready yet. + */ +static void __init pbm_pci_bridge_renumber(struct pci_pbm_info *pbm, + u8 busno) +{ + u32 devfn, l, class; + u8 hdr_type; + int is_multi = 0; + + for(devfn = 0; devfn < 0xff; ++devfn) { + u32 *dwaddr; + u8 *baddr; + + if (PCI_FUNC(devfn) != 0 && is_multi == 0) + continue; + + /* Anything there? */ + dwaddr = schizo_pci_config_mkaddr(pbm, busno, devfn, PCI_VENDOR_ID); + l = 0xffffffff; + pci_config_read32(dwaddr, &l); + if (l == 0xffffffff || l == 0x00000000 || + l == 0x0000ffff || l == 0xffff0000) { + is_multi = 0; + continue; + } + + baddr = schizo_pci_config_mkaddr(pbm, busno, devfn, PCI_HEADER_TYPE); + pci_config_read8(baddr, &hdr_type); + if (PCI_FUNC(devfn) == 0) + is_multi = hdr_type & 0x80; + + dwaddr = schizo_pci_config_mkaddr(pbm, busno, devfn, PCI_CLASS_REVISION); + class = 0xffffffff; + pci_config_read32(dwaddr, &class); + if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) { + u32 buses = 0xffffffff; + + dwaddr = schizo_pci_config_mkaddr(pbm, busno, devfn, + PCI_PRIMARY_BUS); + pci_config_read32(dwaddr, &buses); + pbm_pci_bridge_renumber(pbm, (buses >> 8) & 0xff); + buses &= 0xff000000; + pci_config_write32(dwaddr, buses); + } + } +} + +static void __init pbm_bridge_reconfigure(struct pci_controller_info *p) +{ + struct pci_pbm_info *pbm; + u8 *addr; + + /* Clear out primary/secondary/subordinate bus numbers on + * all PCI-to-PCI bridges under each PBM. The generic bus + * probing will fix them up. + */ + pbm_pci_bridge_renumber(&p->pbm_B, p->pbm_B.pci_first_busno); + pbm_pci_bridge_renumber(&p->pbm_A, p->pbm_A.pci_first_busno); + + /* Move PBM A out of the way. */ + pbm = &p->pbm_A; + addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno, + 0, PBM_BRIDGE_BUS); + pci_config_write8(addr, 0xff); + addr = schizo_pci_config_mkaddr(pbm, 0xff, + 0, PBM_BRIDGE_SUBORDINATE); + pci_config_write8(addr, 0xff); + + /* Now we can safely renumber both PBMs. */ + pbm_renumber(&p->pbm_B, p->pbm_B.pci_first_busno); + pbm_renumber(&p->pbm_A, 0xff); +} + +static void __init pbm_config_busmastering(struct pci_pbm_info *pbm) +{ + u8 *addr; + + /* Set cache-line size to 64 bytes, this is actually + * a nop but I do it for completeness. + */ + addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno, + 0, PCI_CACHE_LINE_SIZE); + pci_config_write8(addr, 64 / sizeof(u32)); + + /* Set PBM latency timer to 64 PCI clocks. */ + addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno, + 0, PCI_LATENCY_TIMER); + pci_config_write8(addr, 64); +} + +static void __init pbm_scan_bus(struct pci_controller_info *p, + struct pci_pbm_info *pbm) +{ + pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, + p->pci_ops, + pbm); + pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node); + pci_record_assignments(pbm, pbm->pci_bus); + pci_assign_unassigned(pbm, pbm->pci_bus); + pci_fixup_irq(pbm, pbm->pci_bus); + pci_determine_66mhz_disposition(pbm, pbm->pci_bus); + pci_setup_busmastering(pbm, pbm->pci_bus); +} + +static void __init schizo_scan_bus(struct pci_controller_info *p) +{ + pbm_bridge_reconfigure(p); + pbm_config_busmastering(&p->pbm_B); + p->pbm_B.is_66mhz_capable = 0; + pbm_config_busmastering(&p->pbm_A); + p->pbm_A.is_66mhz_capable = 1; + pbm_scan_bus(p, &p->pbm_B); + pbm_scan_bus(p, &p->pbm_A); + + /* After the PCI bus scan is complete, we can register + * the error interrupt handlers. + */ + schizo_register_error_handlers(p); } static void __init schizo_base_address_update(struct pci_dev *pdev, int resource) { - /* IMPLEMENT ME */ + struct pcidev_cookie *pcp = pdev->sysdata; + struct pci_pbm_info *pbm = pcp->pbm; + struct resource *res, *root; + u32 reg; + int where, size, is_64bit; + + res = &pdev->resource[resource]; + where = PCI_BASE_ADDRESS_0 + (resource * 4); + + is_64bit = 0; + if (res->flags & IORESOURCE_IO) + root = &pbm->io_space; + else { + root = &pbm->mem_space; + if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) + == PCI_BASE_ADDRESS_MEM_TYPE_64) + is_64bit = 1; + } + + size = res->end - res->start; + pci_read_config_dword(pdev, where, ®); + reg = ((reg & size) | + (((u32)(res->start - root->start)) & ~size)); + pci_write_config_dword(pdev, where, reg); + + /* This knows that the upper 32-bits of the address + * must be zero. Our PCI common layer enforces this. + */ + if (is_64bit) + pci_write_config_dword(pdev, where + 4, 0); } static void __init schizo_resource_adjust(struct pci_dev *pdev, struct resource *res, struct resource *root) { - /* IMPLEMENT ME */ + res->start += root->start; + res->end += root->start; +} + +/* Interrogate Safari match/mask registers to figure out where + * PCI MEM, I/O, and Config space are for this PCI bus module. + */ + +#define SCHIZO_PCI_A_MEM_MATCH 0x00040UL +#define SCHIZO_PCI_A_MEM_MASK 0x00048UL +#define SCHIZO_PCI_A_IO_MATCH 0x00050UL +#define SCHIZO_PCI_A_IO_MASK 0x00058UL +#define SCHIZO_PCI_B_MEM_MATCH 0x00060UL +#define SCHIZO_PCI_B_MEM_MASK 0x00068UL +#define SCHIZO_PCI_B_IO_MATCH 0x00070UL +#define SCHIZO_PCI_B_IO_MASK 0x00078UL + +/* VAL must be non-zero. */ +static unsigned long strip_to_lowest_bit_set(unsigned long val) +{ + unsigned long tmp; + + tmp = 1UL; + while (!(tmp & val)) + tmp <<= 1UL; + + return tmp; +} + +static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm, + int is_pbm_a, unsigned long reg_base) +{ + u64 mem_match, mem_mask; + u64 io_match; + u64 long a, b; + + if (is_pbm_a) { + mem_match = reg_base + SCHIZO_PCI_A_MEM_MATCH; + io_match = reg_base + SCHIZO_PCI_A_IO_MATCH; + } else { + mem_match = reg_base + SCHIZO_PCI_B_MEM_MATCH; + io_match = reg_base + SCHIZO_PCI_B_IO_MATCH; + } + mem_mask = mem_match + 0x8UL; + + a = schizo_read(mem_match) & ~0x8000000000000000UL; + b = strip_to_lowest_bit_set(schizo_read(mem_mask)); + + /* It should be 2GB in size. */ + pbm->mem_space.start = a; + pbm->mem_space.end = a + (b - 1UL); + pbm->mem_space.flags = IORESOURCE_MEM; + + /* This 32MB area is divided into two pieces. The first + * 16MB is Config space, the next 16MB is I/O space. + */ + + a = schizo_read(io_match) & ~0x8000000000000000UL; + pbm->config_space = a; + printk("SCHIZO PBM%c: Local PCI config space at %016lx\n", + (is_pbm_a ? 'A' : 'B'), pbm->config_space); + + a += (16UL * 1024UL * 1024UL); + pbm->io_space.start = a; + pbm->io_space.end = a + ((16UL * 1024UL * 1024UL) - 1UL); + pbm->io_space.flags = IORESOURCE_IO; +} + +static void __init pbm_register_toplevel_resources(struct pci_controller_info *p, + struct pci_pbm_info *pbm) +{ + char *name = pbm->name; + + sprintf(name, "SCHIZO%d PBM%c", + p->index, + (pbm == &p->pbm_A ? 'A' : 'B')); + pbm->io_space.name = pbm->mem_space.name = name; + + request_resource(&ioport_resource, &pbm->io_space); + request_resource(&iomem_resource, &pbm->mem_space); +} + +#define SCHIZO_STRBUF_CONTROL_A (SCHIZO_PBM_A_REGS_OFF + 0x02800UL) +#define SCHIZO_STRBUF_FLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x02808UL) +#define SCHIZO_STRBUF_FSYNC_A (SCHIZO_PBM_A_REGS_OFF + 0x02810UL) +#define SCHIZO_STRBUF_CTXFLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x02818UL) +#define SCHIZO_STRBUF_CTXMATCH_A (SCHIZO_PBM_A_REGS_OFF + 0x10000UL) + +#define SCHIZO_STRBUF_CONTROL_B (SCHIZO_PBM_B_REGS_OFF + 0x02800UL) +#define SCHIZO_STRBUF_FLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x02808UL) +#define SCHIZO_STRBUF_FSYNC_B (SCHIZO_PBM_B_REGS_OFF + 0x02810UL) +#define SCHIZO_STRBUF_CTXFLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x02818UL) +#define SCHIZO_STRBUF_CTXMATCH_B (SCHIZO_PBM_B_REGS_OFF + 0x10000UL) + +static void schizo_pbm_strbuf_init(struct pci_controller_info *p, + struct pci_pbm_info *pbm, + int is_pbm_a) +{ + unsigned long base = p->controller_regs; + u64 control; + + /* SCHIZO has context flushing. */ + if (is_pbm_a) { + pbm->stc.strbuf_control = base + SCHIZO_STRBUF_CONTROL_A; + pbm->stc.strbuf_pflush = base + SCHIZO_STRBUF_FLUSH_A; + pbm->stc.strbuf_fsync = base + SCHIZO_STRBUF_FSYNC_A; + pbm->stc.strbuf_ctxflush = base + SCHIZO_STRBUF_CTXFLUSH_A; + pbm->stc.strbuf_ctxmatch_base = base + SCHIZO_STRBUF_CTXMATCH_A; + } else { + pbm->stc.strbuf_control = base + SCHIZO_STRBUF_CONTROL_B; + pbm->stc.strbuf_pflush = base + SCHIZO_STRBUF_FLUSH_B; + pbm->stc.strbuf_fsync = base + SCHIZO_STRBUF_FSYNC_B; + pbm->stc.strbuf_ctxflush = base + SCHIZO_STRBUF_CTXFLUSH_B; + pbm->stc.strbuf_ctxmatch_base = base + SCHIZO_STRBUF_CTXMATCH_B; + } + + pbm->stc.strbuf_flushflag = (volatile unsigned long *) + ((((unsigned long)&pbm->stc.__flushflag_buf[0]) + + 63UL) + & ~63UL); + pbm->stc.strbuf_flushflag_pa = (unsigned long) + __pa(pbm->stc.strbuf_flushflag); + + /* Turn off LRU locking and diag mode, enable the + * streaming buffer and leave the rerun-disable + * setting however OBP set it. + */ + control = schizo_read(pbm->stc.strbuf_control); + control &= ~(SCHIZO_STRBUF_CTRL_LPTR | + SCHIZO_STRBUF_CTRL_LENAB | + SCHIZO_STRBUF_CTRL_DENAB); + control |= SCHIZO_STRBUF_CTRL_ENAB; + schizo_write(pbm->stc.strbuf_control, control); + + pbm->stc.strbuf_enabled = 1; +} + +#define SCHIZO_IOMMU_CONTROL_A (SCHIZO_PBM_A_REGS_OFF + 0x00200UL) +#define SCHIZO_IOMMU_TSBBASE_A (SCHIZO_PBM_A_REGS_OFF + 0x00208UL) +#define SCHIZO_IOMMU_FLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x00210UL) +#define SCHIZO_IOMMU_CTXFLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x00218UL) +#define SCHIZO_IOMMU_TAG_A (SCHIZO_PBM_A_REGS_OFF + 0x0a580UL) +#define SCHIZO_IOMMU_DATA_A (SCHIZO_PBM_A_REGS_OFF + 0x0a600UL) +#define SCHIZO_IOMMU_CONTROL_B (SCHIZO_PBM_B_REGS_OFF + 0x00200UL) +#define SCHIZO_IOMMU_TSBBASE_B (SCHIZO_PBM_B_REGS_OFF + 0x00208UL) +#define SCHIZO_IOMMU_FLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x00210UL) +#define SCHIZO_IOMMU_CTXFLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x00218UL) +#define SCHIZO_IOMMU_TAG_B (SCHIZO_PBM_B_REGS_OFF + 0x0a580UL) +#define SCHIZO_IOMMU_DATA_B (SCHIZO_PBM_B_REGS_OFF + 0x0a600UL) + +static void schizo_pbm_iommu_init(struct pci_controller_info *p, + struct pci_pbm_info *pbm, + int is_pbm_a) +{ + struct pci_iommu *iommu = pbm->iommu; + unsigned long tsbbase, i, tagbase, database; + u64 control; + + /* Setup initial software IOMMU state. */ + spin_lock_init(&iommu->lock); + iommu->iommu_cur_ctx = 0; + + /* Register addresses, SCHIZO has iommu ctx flushing. */ + if (is_pbm_a) { + iommu->iommu_control = p->controller_regs + SCHIZO_IOMMU_CONTROL_A; + iommu->iommu_tsbbase = p->controller_regs + SCHIZO_IOMMU_TSBBASE_A; + iommu->iommu_flush = p->controller_regs + SCHIZO_IOMMU_FLUSH_A; + iommu->iommu_ctxflush = p->controller_regs + SCHIZO_IOMMU_CTXFLUSH_A; + } else { + iommu->iommu_control = p->controller_regs + SCHIZO_IOMMU_CONTROL_B; + iommu->iommu_tsbbase = p->controller_regs + SCHIZO_IOMMU_TSBBASE_B; + iommu->iommu_flush = p->controller_regs + SCHIZO_IOMMU_FLUSH_B; + iommu->iommu_ctxflush = p->controller_regs + SCHIZO_IOMMU_CTXFLUSH_B; + } + + /* We use the main control/status register of SCHIZO as the write + * completion register. + */ + iommu->write_complete_reg = p->controller_regs + 0x10000UL; + + /* + * Invalidate TLB Entries. + */ + control = schizo_read(iommu->iommu_control); + control |= SCHIZO_IOMMU_CTRL_DENAB; + schizo_write(iommu->iommu_control, control); + + if (is_pbm_a) + tagbase = SCHIZO_IOMMU_TAG_A, database = SCHIZO_IOMMU_DATA_A; + else + tagbase = SCHIZO_IOMMU_TAG_B, database = SCHIZO_IOMMU_DATA_B; + for(i = 0; i < 16; i++) { + schizo_write(p->controller_regs + tagbase + (i * 8UL), 0); + schizo_write(p->controller_regs + database + (i * 8UL), 0); + } + + /* Leave diag mode enabled for full-flushing done + * in pci_iommu.c + */ + + /* Using assumed page size 8K with 128K entries we need 1MB iommu page + * table (128K ioptes * 8 bytes per iopte). This is + * page order 7 on UltraSparc. + */ + tsbbase = __get_free_pages(GFP_KERNEL, 7); + if (!tsbbase) { + prom_printf("SCHIZO_IOMMU: Error, gfp(tsb) failed.\n"); + prom_halt(); + } + iommu->page_table = (iopte_t *)tsbbase; + iommu->page_table_sz_bits = 17; + iommu->page_table_map_base = 0xc0000000; + iommu->dma_addr_mask = 0xffffffff; + memset((char *)tsbbase, 0, PAGE_SIZE << 7); + + /* We start with no consistent mappings. */ + iommu->lowest_consistent_map = + 1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS); + + for (i = 0; i < PBM_NCLUSTERS; i++) { + iommu->alloc_info[i].flush = 0; + iommu->alloc_info[i].next = 0; + } + + schizo_write(iommu->iommu_tsbbase, __pa(tsbbase)); + + control = schizo_read(iommu->iommu_control); + control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ); + control |= (SCHIZO_IOMMU_TSBSZ_128K | SCHIZO_IOMMU_CTRL_ENAB); + schizo_write(iommu->iommu_control, control); } static void schizo_pbm_init(struct pci_controller_info *p, int prom_node, int is_pbm_a) { - /* IMPLEMENT ME */ + unsigned int busrange[2]; + struct pci_pbm_info *pbm; + int err; + + if (is_pbm_a) + pbm = &p->pbm_A; + else + pbm = &p->pbm_B; + + schizo_determine_mem_io_space(pbm, is_pbm_a, p->controller_regs); + pbm_register_toplevel_resources(p, pbm); + + pbm->parent = p; + pbm->prom_node = prom_node; + prom_getstring(prom_node, "name", + pbm->prom_name, + sizeof(pbm->prom_name)); + + err = prom_getproperty(prom_node, "ranges", + (char *) pbm->pbm_ranges, + sizeof(pbm->pbm_ranges)); + if (err != -1) + pbm->num_pbm_ranges = + (err / sizeof(struct linux_prom_pci_ranges)); + else + pbm->num_pbm_ranges = 0; + + err = prom_getproperty(prom_node, "interrupt-map", + (char *)pbm->pbm_intmap, + sizeof(pbm->pbm_intmap)); + if (err != -1) { + pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); + err = prom_getproperty(prom_node, "interrupt-map-mask", + (char *)&pbm->pbm_intmask, + sizeof(pbm->pbm_intmask)); + if (err == -1) { + prom_printf("SCHIZO-PBM: Fatal error, no " + "interrupt-map-mask.\n"); + prom_halt(); + } + } else { + pbm->num_pbm_intmap = 0; + memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask)); + } + + err = prom_getproperty(prom_node, "bus-range", + (char *)&busrange[0], + sizeof(busrange)); + if (err == 0 || err == -1) { + prom_printf("SCHIZO-PBM: Fatal error, no bus-range.\n"); + prom_halt(); + } + pbm->pci_first_busno = busrange[0]; + pbm->pci_last_busno = busrange[1]; + + schizo_pbm_iommu_init(p, pbm, is_pbm_a); + schizo_pbm_strbuf_init(p, pbm, is_pbm_a); +} + +static void schizo_controller_hwinit(struct pci_controller_info *p) +{ + unsigned long pbm_a_base, pbm_b_base; + u64 tmp; + + pbm_a_base = p->controller_regs + SCHIZO_PBM_A_REGS_OFF; + pbm_b_base = p->controller_regs + SCHIZO_PBM_B_REGS_OFF; + + /* Set IRQ retry to infinity. */ + schizo_write(pbm_a_base + 0x1a00UL, 0xff); + schizo_write(pbm_b_base + 0x1a00UL, 0xff); + + /* Enable arbiter for all PCI slots. */ + tmp = schizo_read(pbm_a_base + 0x2000UL); + tmp |= 0x3fUL; + schizo_write(pbm_a_base + 0x2000UL, tmp); + + tmp = schizo_read(pbm_b_base + 0x2000UL); + tmp |= 0x3fUL; + schizo_write(pbm_b_base + 0x2000UL, tmp); } void __init schizo_init(int node) @@ -90,6 +1708,7 @@ void __init schizo_init(int node) struct linux_prom64_registers pr_regs[3]; struct pci_controller_info *p; struct pci_iommu *iommu; + unsigned long flags; u32 portid; int is_pbm_a, err; @@ -142,11 +1761,10 @@ void __init schizo_init(int node) p->resource_adjust = schizo_resource_adjust; p->pci_ops = &schizo_ops; -pbm_init: /* Three OBP regs: * 1) PBM controller regs * 2) Schizo front-end controller regs (same for both PBMs) - * 3) Unknown... (0x7ffec000000 and 0x7ffee000000 on Excalibur) + * 3) PBM PCI config space */ err = prom_getproperty(node, "reg", (char *)&pr_regs[0], @@ -156,14 +1774,16 @@ pbm_init: prom_halt(); } - /* XXX Read REG base, record in controller/pbm structures. */ - - /* XXX Report controller to console. */ + p->controller_regs = pr_regs[1].phys_addr - 0x10000UL; + printk("PCI: Found SCHIZO, control regs at %016lx\n", + p->controller_regs); - /* XXX Setup pci_memspace_mask */ + /* Like PSYCHO we have a 2GB aligned area for memory space. */ + pci_memspace_mask = 0x7fffffffUL; - /* XXX Init core controller and IOMMU */ + /* Init core controller. */ + schizo_controller_hwinit(p); - is_pbm_a = XXX; /* Figure out this test */ + is_pbm_a = ((pr_regs[0].phys_addr & 0x00700000) == 0x00600000); schizo_pbm_init(p, node, is_pbm_a); } diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 3fc337d71..e0930d55e 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.114 2001/02/13 01:16:44 davem Exp $ +/* $Id: process.c,v 1.116 2001/03/24 09:36:01 davem Exp $ * arch/sparc64/kernel/process.c * * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) @@ -416,14 +416,14 @@ void flush_thread(void) unsigned long pgd_cache; if (pgd_none(*pgd0)) { - pmd_t *page = get_pmd_fast(); + pmd_t *page = pmd_alloc_one_fast(NULL, 0); if (!page) - (void) get_pmd_slow(pgd0, 0); - else - pgd_set(pgd0, page); + page = pmd_alloc_one(NULL, 0); + pgd_set(pgd0, page); } pgd_cache = pgd_val(*pgd0) << 11UL; - __asm__ __volatile__("stxa %0, [%1] %2" + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" : /* no outputs */ : "r" (pgd_cache), "r" (TSB_REG), diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index 7f791c4d0..031ec5582 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -53,10 +53,10 @@ static inline void pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long *addr) { if (current->thread.flags & SPARC_FLAG_32BIT) { - if(put_user(value, (unsigned int *)addr)) + if (put_user(value, (unsigned int *)addr)) return pt_error_return(regs, EFAULT); } else { - if(put_user(value, addr)) + if (put_user(value, addr)) return pt_error_return(regs, EFAULT); } regs->u_regs[UREG_I0] = 0; @@ -137,7 +137,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) s, request, pid, addr, data, addr2); } #endif - if(request == PTRACE_TRACEME) { + if (request == PTRACE_TRACEME) { /* are we already being traced? */ if (current->ptrace & PT_PTRACED) { pt_error_return(regs, EPERM); @@ -149,7 +149,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) goto out; } #ifndef ALLOW_INIT_TRACING - if(pid == 1) { + if (pid == 1) { /* Can't dork with init. */ pt_error_return(regs, EPERM); goto out; @@ -157,9 +157,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs) #endif read_lock(&tasklist_lock); child = find_task_by_pid(pid); + if (child) + get_task_struct(child); read_unlock(&tasklist_lock); - if(!child) { + if (!child) { pt_error_return(regs, ESRCH); goto out; } @@ -168,32 +170,32 @@ asmlinkage void do_ptrace(struct pt_regs *regs) || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { unsigned long flags; - if(child == current) { + if (child == current) { /* Try this under SunOS/Solaris, bwa haha * You'll never be able to kill the process. ;-) */ pt_error_return(regs, EPERM); - goto out; + goto out_tsk; } - if((!child->dumpable || - (current->uid != child->euid) || - (current->uid != child->uid) || - (current->uid != child->suid) || - (current->gid != child->egid) || - (current->gid != child->sgid) || - (!cap_issubset(child->cap_permitted, current->cap_permitted)) || - (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) { + if ((!child->dumpable || + (current->uid != child->euid) || + (current->uid != child->uid) || + (current->uid != child->suid) || + (current->gid != child->egid) || + (current->gid != child->sgid) || + (!cap_issubset(child->cap_permitted, current->cap_permitted)) || + (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) { pt_error_return(regs, EPERM); - goto out; + goto out_tsk; } /* the same process cannot be attached many times */ if (child->ptrace & PT_PTRACED) { pt_error_return(regs, EPERM); - goto out; + goto out_tsk; } child->ptrace |= PT_PTRACED; write_lock_irqsave(&tasklist_lock, flags); - if(child->p_pptr != current) { + if (child->p_pptr != current) { REMOVE_LINKS(child); child->p_pptr = current; SET_LINKS(child); @@ -201,32 +203,32 @@ asmlinkage void do_ptrace(struct pt_regs *regs) write_unlock_irqrestore(&tasklist_lock, flags); send_sig(SIGSTOP, child, 1); pt_succ_return(regs, 0); - goto out; + goto out_tsk; } if (!(child->ptrace & PT_PTRACED)) { pt_error_return(regs, ESRCH); - goto out; + goto out_tsk; } - if(child->state != TASK_STOPPED) { - if(request != PTRACE_KILL) { + if (child->state != TASK_STOPPED) { + if (request != PTRACE_KILL) { pt_error_return(regs, ESRCH); - goto out; + goto out_tsk; } } - if(child->p_pptr != current) { + if (child->p_pptr != current) { pt_error_return(regs, ESRCH); - goto out; + goto out_tsk; } - if(!(child->thread.flags & SPARC_FLAG_32BIT) && - ((request == PTRACE_READDATA64) || - (request == PTRACE_WRITEDATA64) || - (request == PTRACE_READTEXT64) || - (request == PTRACE_WRITETEXT64) || - (request == PTRACE_PEEKTEXT64) || - (request == PTRACE_POKETEXT64) || - (request == PTRACE_PEEKDATA64) || - (request == PTRACE_POKEDATA64))) { + if (!(child->thread.flags & SPARC_FLAG_32BIT) && + ((request == PTRACE_READDATA64) || + (request == PTRACE_WRITEDATA64) || + (request == PTRACE_READTEXT64) || + (request == PTRACE_WRITETEXT64) || + (request == PTRACE_PEEKTEXT64) || + (request == PTRACE_POKETEXT64) || + (request == PTRACE_PEEKDATA64) || + (request == PTRACE_POKEDATA64))) { addr = regs->u_regs[UREG_G2]; addr2 = regs->u_regs[UREG_G3]; request -= 30; /* wheee... */ @@ -278,7 +280,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) if (copied == sizeof(tmp64)) res = 0; } - if(res < 0) + if (res < 0) pt_error_return(regs, -res); else pt_succ_return(regs, res); @@ -295,42 +297,45 @@ asmlinkage void do_ptrace(struct pt_regs *regs) __put_user(cregs->tnpc, (&pregs->npc)) || __put_user(cregs->y, (&pregs->y))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; } - for(rval = 1; rval < 16; rval++) + for (rval = 1; rval < 16; rval++) if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; } pt_succ_return(regs, 0); #ifdef DEBUG_PTRACE printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]); #endif - goto out; + goto out_tsk; } case PTRACE_GETREGS64: { struct pt_regs *pregs = (struct pt_regs *) addr; struct pt_regs *cregs = child->thread.kregs; + unsigned long tpc = cregs->tpc; int rval; + if ((child->thread.flags & SPARC_FLAG_32BIT) != 0) + tpc &= 0xffffffff; if (__put_user(cregs->tstate, (&pregs->tstate)) || - __put_user(cregs->tpc, (&pregs->tpc)) || + __put_user(tpc, (&pregs->tpc)) || __put_user(cregs->tnpc, (&pregs->tnpc)) || __put_user(cregs->y, (&pregs->y))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; } - for(rval = 1; rval < 16; rval++) + for (rval = 1; rval < 16; rval++) if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; } pt_succ_return(regs, 0); #ifdef DEBUG_PTRACE printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]); #endif - goto out; + goto out_tsk; } case PTRACE_SETREGS: { @@ -347,23 +352,23 @@ asmlinkage void do_ptrace(struct pt_regs *regs) __get_user(npc, (&pregs->npc)) || __get_user(y, (&pregs->y))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; } cregs->tstate &= ~(TSTATE_ICC); cregs->tstate |= psr_to_tstate_icc(psr); - if(!((pc | npc) & 3)) { + if (!((pc | npc) & 3)) { cregs->tpc = pc; cregs->tnpc = npc; } cregs->y = y; - for(i = 1; i < 16; i++) { + for (i = 1; i < 16; i++) { if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; } } pt_succ_return(regs, 0); - goto out; + goto out_tsk; } case PTRACE_SETREGS64: { @@ -380,24 +385,28 @@ asmlinkage void do_ptrace(struct pt_regs *regs) __get_user(tnpc, (&pregs->tnpc)) || __get_user(y, (&pregs->y))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; + } + if ((child->thread.flags & SPARC_FLAG_32BIT) != 0) { + tpc &= 0xffffffff; + tnpc &= 0xffffffff; } tstate &= (TSTATE_ICC | TSTATE_XCC); cregs->tstate &= ~(TSTATE_ICC | TSTATE_XCC); cregs->tstate |= tstate; - if(!((tpc | tnpc) & 3)) { + if (!((tpc | tnpc) & 3)) { cregs->tpc = tpc; cregs->tnpc = tnpc; } cregs->y = y; - for(i = 1; i < 16; i++) { + for (i = 1; i < 16; i++) { if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; } } pt_succ_return(regs, 0); - goto out; + goto out_tsk; } case PTRACE_GETFPREGS: { @@ -422,10 +431,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs) __put_user(0, (&fps->extra)) || clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; } pt_succ_return(regs, 0); - goto out; + goto out_tsk; } case PTRACE_GETFPREGS64: { @@ -439,10 +448,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs) (64 * sizeof(unsigned int))) || __put_user(child->thread.xfsr[0], (&fps->fsr))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; } pt_succ_return(regs, 0); - goto out; + goto out_tsk; } case PTRACE_SETFPREGS: { @@ -464,7 +473,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) (32 * sizeof(unsigned int))) || __get_user(fsr, (&fps->fsr))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; } child->thread.xfsr[0] &= 0xffffffff00000000UL; child->thread.xfsr[0] |= fsr; @@ -472,7 +481,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) child->thread.gsr[0] = 0; child->thread.fpsaved[0] |= (FPRS_FEF | FPRS_DL); pt_succ_return(regs, 0); - goto out; + goto out_tsk; } case PTRACE_SETFPREGS64: { @@ -486,13 +495,13 @@ asmlinkage void do_ptrace(struct pt_regs *regs) (64 * sizeof(unsigned int))) || __get_user(child->thread.xfsr[0], (&fps->fsr))) { pt_error_return(regs, EFAULT); - goto out; + goto out_tsk; } if (!(child->thread.fpsaved[0] & FPRS_FEF)) child->thread.gsr[0] = 0; child->thread.fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU); pt_succ_return(regs, 0); - goto out; + goto out_tsk; } case PTRACE_READTEXT: @@ -528,19 +537,24 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_CONT: { /* restart after signal. */ if (data > _NSIG) { pt_error_return(regs, EIO); - goto out; + goto out_tsk; } if (addr != 1) { + unsigned long pc_mask = ~0UL; + + if ((child->thread.flags & SPARC_FLAG_32BIT) != 0) + pc_mask = 0xffffffff; + if (addr & 3) { pt_error_return(regs, EINVAL); - goto out; + goto out_tsk; } #ifdef DEBUG_PTRACE printk ("Original: %016lx %016lx\n", child->thread.kregs->tpc, child->thread.kregs->tnpc); printk ("Continuing with %016lx %016lx\n", addr, addr+4); #endif - child->thread.kregs->tpc = addr; - child->thread.kregs->tnpc = addr + 4; + child->thread.kregs->tpc = (addr & pc_mask); + child->thread.kregs->tnpc = ((addr + 4) & pc_mask); } if (request == PTRACE_SYSCALL) @@ -558,7 +572,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) #endif wake_up_process(child); pt_succ_return(regs, 0); - goto out; + goto out_tsk; } /* @@ -569,12 +583,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_KILL: { if (child->state == TASK_ZOMBIE) { /* already dead */ pt_succ_return(regs, 0); - goto out; + goto out_tsk; } child->exit_code = SIGKILL; wake_up_process(child); pt_succ_return(regs, 0); - goto out; + goto out_tsk; } case PTRACE_SUNDETACH: { /* detach a process that was attached. */ @@ -582,7 +596,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) if ((unsigned long) data > _NSIG) { pt_error_return(regs, EIO); - goto out; + goto out_tsk; } child->ptrace &= ~(PT_PTRACED|PT_TRACESYS); child->exit_code = data; @@ -595,29 +609,39 @@ asmlinkage void do_ptrace(struct pt_regs *regs) wake_up_process(child); pt_succ_return(regs, 0); - goto out; + goto out_tsk; } /* PTRACE_DUMPCORE unsupported... */ default: pt_error_return(regs, EIO); - goto out; + goto out_tsk; } flush_and_out: { unsigned long va; - for(va = 0; va < (PAGE_SIZE << 1); va += 32) - spitfire_put_dcache_tag(va, 0x0); - if (request == PTRACE_PEEKTEXT || - request == PTRACE_POKETEXT || - request == PTRACE_READTEXT || - request == PTRACE_WRITETEXT) { - for(va = 0; va < (PAGE_SIZE << 1); va += 32) - spitfire_put_icache_tag(va, 0x0); - __asm__ __volatile__("flush %g6"); + + if (tlb_type == cheetah) { + for (va = 0; va < (1 << 16); va += (1 << 5)) + spitfire_put_dcache_tag(va, 0x0); + /* No need to mess with I-cache on Cheetah. */ + } else { + for (va = 0; va < (PAGE_SIZE << 1); va += 32) + spitfire_put_dcache_tag(va, 0x0); + if (request == PTRACE_PEEKTEXT || + request == PTRACE_POKETEXT || + request == PTRACE_READTEXT || + request == PTRACE_WRITETEXT) { + for (va = 0; va < (PAGE_SIZE << 1); va += 32) + spitfire_put_icache_tag(va, 0x0); + __asm__ __volatile__("flush %g6"); + } } } +out_tsk: + if (child) + free_task_struct(child); out: unlock_kernel(); } diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index 729ecd911..952f0caa5 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S @@ -1,4 +1,4 @@ -/* $Id: rtrap.S,v 1.53 2000/08/06 05:20:35 davem Exp $ +/* $Id: rtrap.S,v 1.54 2001/03/08 22:08:51 davem Exp $ * rtrap.S: Preparing for return from trap on Sparc V9. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -192,7 +192,7 @@ to_kernel: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5 rd %fprs, %g5 wr %g5, FPRS_FEF, %fprs - ldub [%o1 + %o0], %g5 + ldx [%o1 + %o5], %g5 add %g6, AOFF_task_thread + AOFF_thread_xfsr, %o1 membar #StoreLoad | #LoadLoad sll %o0, 8, %o2 diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 7817f4566..cf6bbb896 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.59 2001/02/13 01:16:44 davem Exp $ +/* $Id: setup.c,v 1.63 2001/03/09 22:04:25 davem Exp $ * linux/arch/sparc64/kernel/setup.c * * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) @@ -43,8 +43,6 @@ #include <net/ipconfig.h> #endif -#undef PROM_DEBUG_CONSOLE - struct screen_info screen_info = { 0, 0, /* orig-x, orig-y */ 0, /* unused */ @@ -166,10 +164,14 @@ int prom_callback(long *args) "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); /* - * Locked down tlb entry 63. + * Locked down tlb entry. */ - tte = spitfire_get_dtlb_data(63); + if (tlb_type == spitfire) + tte = spitfire_get_dtlb_data(SPITFIRE_HIGHEST_LOCKED_TLBENT); + else if (tlb_type == cheetah) + tte = cheetah_get_ldtlb_data(CHEETAH_HIGHEST_LOCKED_TLBENT); + res = PROM_TRUE; goto done; } @@ -253,7 +255,7 @@ int prom_callback(long *args) unsigned long tte; tte = args[3]; - prom_printf("%lx ", (tte & _PAGE_SOFT2) >> 50); + prom_printf("%lx ", (tte & 0x07FC000000000000) >> 50); args[2] = 2; args[args[1] + 3] = 0; @@ -285,14 +287,12 @@ static int console_fb __initdata = 0; /* Exported for mm/init.c:paging_init. */ unsigned long cmdline_memory_size = 0; -#ifdef PROM_DEBUG_CONSOLE static struct console prom_debug_console = { name: "debug", write: prom_console_write, flags: CON_PRINTBUFFER, index: -1, }; -#endif /* XXX Implement this at some point... */ void kernel_enter_debugger(void) @@ -326,6 +326,10 @@ static void __init process_switch(char c) prom_printf("boot_flags_init: Halt!\n"); prom_halt(); break; + case 'p': + /* Use PROM debug console. */ + register_console(&prom_debug_console); + break; default: printk("Unknown boot switch (-%c)\n", c); break; @@ -454,10 +458,6 @@ void __init setup_arch(char **cmdline_p) *cmdline_p = prom_getbootargs(); strcpy(saved_command_line, *cmdline_p); -#ifdef PROM_DEBUG_CONSOLE - register_console(&prom_debug_console); -#endif - printk("ARCH: SUN4U\n"); #ifdef CONFIG_DUMMY_CONSOLE diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 23d0774b4..354021278 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.55 2001/01/24 21:05:13 davem Exp $ +/* $Id: signal.c,v 1.56 2001/03/21 11:46:20 davem Exp $ * arch/sparc64/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -108,6 +108,10 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); } + if ((tp->flags & SPARC_FLAG_32BIT) != 0) { + pc &= 0xffffffff; + npc &= 0xffffffff; + } regs->tpc = pc; regs->tnpc = npc; err |= __get_user(regs->y, &((*grp)[MC_Y])); @@ -190,9 +194,13 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs) grp = &mcp->mc_gregs; /* Skip over the trap instruction, first. */ - regs->tpc = regs->tnpc; - regs->tnpc += 4; - + if ((tp->flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc = (regs->tnpc & 0xffffffff); + regs->tnpc = (regs->tnpc + 4) & 0xffffffff; + } else { + regs->tpc = regs->tnpc; + regs->tnpc += 4; + } err = 0; if (_NSIG_WORDS == 1) err |= __put_user(current->blocked.sig[0], @@ -289,8 +297,13 @@ asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs) recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - regs->tpc = regs->tnpc; - regs->tnpc += 4; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc = (regs->tnpc & 0xffffffff); + regs->tnpc = (regs->tnpc + 4) & 0xffffffff; + } else { + regs->tpc = regs->tnpc; + regs->tnpc += 4; + } /* Condition codes and return value where set here for sigpause, * and so got used by setup_frame, which again causes sigreturn() @@ -344,8 +357,13 @@ asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize, struct pt_re recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - regs->tpc = regs->tnpc; - regs->tnpc += 4; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc = (regs->tnpc & 0xffffffff); + regs->tnpc = (regs->tnpc + 4) & 0xffffffff; + } else { + regs->tpc = regs->tnpc; + regs->tnpc += 4; + } /* Condition codes and return value where set here for sigpause, * and so got used by setup_frame, which again causes sigreturn() @@ -407,6 +425,10 @@ void do_rt_sigreturn(struct pt_regs *regs) err = get_user(tpc, &sf->regs.tpc); err |= __get_user(tnpc, &sf->regs.tnpc); + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + tpc &= 0xffffffff; + tnpc &= 0xffffffff; + } err |= ((tpc | tnpc) & 3); /* 2. Restore the state */ @@ -555,7 +577,10 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, /* 5. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tnpc = (regs->tpc + 4); - + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } /* 4. return to kernel instructions */ regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; return; diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 0886d9d39..9613c7869 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -1,4 +1,4 @@ -/* $Id: signal32.c,v 1.68 2001/01/24 21:05:13 davem Exp $ +/* $Id: signal32.c,v 1.69 2001/03/21 11:46:20 davem Exp $ * arch/sparc64/kernel/signal32.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -155,6 +155,10 @@ asmlinkage void _sigpause32_common(old_sigset_t32 set, struct pt_regs *regs) regs->tpc = regs->tnpc; regs->tnpc += 4; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } /* Condition codes and return value where set here for sigpause, * and so got used by setup_frame, which again causes sigreturn() @@ -206,6 +210,10 @@ asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs * regs->tpc = regs->tnpc; regs->tnpc += 4; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } /* Condition codes and return value where set here for sigpause, * and so got used by setup_frame, which again causes sigreturn() @@ -268,6 +276,10 @@ void do_new_sigreturn32(struct pt_regs *regs) if ((pc | npc) & 3) goto segv; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + pc &= 0xffffffff; + npc &= 0xffffffff; + } regs->tpc = pc; regs->tnpc = npc; @@ -355,6 +367,10 @@ asmlinkage void do_sigreturn32(struct pt_regs *regs) recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + pc &= 0xffffffff; + npc &= 0xffffffff; + } regs->tpc = pc; regs->tnpc = npc; err = __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp); @@ -398,6 +414,10 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) if ((pc | npc) & 3) goto segv; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + pc &= 0xffffffff; + npc &= 0xffffffff; + } regs->tpc = pc; regs->tnpc = npc; @@ -489,6 +509,11 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o #endif unsigned psr; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + pc &= 0xffffffff; + npc &= 0xffffffff; + } + synchronize_user_stack(); save_and_clear_fpu(); @@ -615,6 +640,10 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o regs->u_regs[UREG_FP] = (unsigned long) sframep; regs->tpc = (unsigned long) sa->sa_handler; regs->tnpc = (regs->tpc + 4); + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } return; sigsegv: @@ -678,6 +707,10 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg } /* 2. Save the current process state */ + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } err = put_user(regs->tpc, &sf->info.si_regs.pc); err |= __put_user(regs->tnpc, &sf->info.si_regs.npc); err |= __put_user(regs->y, &sf->info.si_regs.y); @@ -728,11 +761,15 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg /* 4. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tnpc = (regs->tpc + 4); + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } /* 5. return to kernel instructions */ - if (ka->ka_restorer) + if (ka->ka_restorer) { regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; - else { + } else { /* Flush instruction space. */ unsigned long address = ((unsigned long)&(sf->insns[0])); pgd_t *pgdp = pgd_offset(current->mm, address); @@ -819,6 +856,10 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned)); /* Store registers */ + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } err |= __put_user(regs->tpc, &((*gr) [SVR4_PC])); err |= __put_user(regs->tnpc, &((*gr) [SVR4_NPC])); psr = tstate_to_psr (regs->tstate); @@ -883,6 +924,10 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, regs->u_regs[UREG_FP] = (unsigned long) sfp; regs->tpc = (unsigned long) sa->sa_handler; regs->tnpc = (regs->tpc + 4); + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } #ifdef DEBUG_SIGNALS printk ("Solaris-frame: %x %x\n", (int) regs->tpc, (int) regs->tnpc); @@ -940,6 +985,10 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs) err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned)); /* Store registers */ + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } err |= __put_user(regs->tpc, &uc->mcontext.greg [SVR4_PC]); err |= __put_user(regs->tnpc, &uc->mcontext.greg [SVR4_NPC]); #if 1 @@ -1037,6 +1086,10 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) spin_unlock_irq(¤t->sigmask_lock); regs->tpc = pc; regs->tnpc = npc | 1; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } err |= __get_user(regs->y, &((*gr) [SVR4_Y])); err |= __get_user(psr, &((*gr) [SVR4_PSR])); regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); @@ -1095,6 +1148,10 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs } /* 2. Save the current process state */ + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } err = put_user(regs->tpc, &sf->regs.pc); err |= __put_user(regs->tnpc, &sf->regs.npc); err |= __put_user(regs->y, &sf->regs.y); @@ -1150,6 +1207,10 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs /* 4. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tnpc = (regs->tpc + 4); + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } /* 5. return to kernel instructions */ if (ka->ka_restorer) diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 76045d0d2..bceac6597 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -65,7 +65,7 @@ int smp_info(char *buf) strcpy(buf, "State:\n"); for (i = 0; i < NR_CPUS; i++) - if(cpu_present_map & (1UL << i)) + if (cpu_present_map & (1UL << i)) len += sprintf(buf + len, "CPU%d:\t\tonline\n", i); return len; @@ -76,7 +76,7 @@ int smp_bogo(char *buf) int len = 0, i; for (i = 0; i < NR_CPUS; i++) - if(cpu_present_map & (1UL << i)) + if (cpu_present_map & (1UL << i)) len += sprintf(buf + len, "Cpu%dBogo\t: %lu.%02lu\n", i, cpu_data[i].udelay_val / (500000/HZ), @@ -99,7 +99,7 @@ void __init smp_store_cpu_info(int id) cpu_data[id].pgd_cache = NULL; cpu_data[id].idle_volume = 1; - for(i = 0; i < 16; i++) + for (i = 0; i < 16; i++) cpu_data[id].irq_worklists[i] = 0; } @@ -153,6 +153,19 @@ void __init smp_callin(void) : /* no inputs */ : "g1", "g2"); + if (SPARC64_USE_STICK) { + /* Let the user get at STICK too. */ + __asm__ __volatile__(" + sethi %%hi(0x80000000), %%g1 + sllx %%g1, 32, %%g1 + rd %%asr24, %%g2 + andn %%g2, %%g1, %%g2 + wr %%g2, 0, %%asr24" + : /* no outputs */ + : /* no inputs */ + : "g1", "g2"); + } + /* Restore PSTATE_IE. */ __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : /* no outputs */ @@ -177,7 +190,7 @@ void __init smp_callin(void) atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; - while(!smp_processors_ready) + while (!smp_processors_ready) membar("#LoadLoad"); } @@ -222,14 +235,14 @@ void __init smp_boot_cpus(void) smp_tune_scheduling(); init_idle(); - if(linux_num_cpus == 1) + if (linux_num_cpus == 1) return; - for(i = 0; i < NR_CPUS; i++) { - if(i == boot_cpu_id) + for (i = 0; i < NR_CPUS; i++) { + if (i == boot_cpu_id) continue; - if(cpu_present_map & (1UL << i)) { + if (cpu_present_map & (1UL << i)) { unsigned long entry = (unsigned long)(&sparc64_cpu_startup); unsigned long cookie = (unsigned long)(&cpu_new_task); struct task_struct *p; @@ -256,12 +269,12 @@ void __init smp_boot_cpus(void) cpu_new_task = p; prom_startcpu(linux_cpus[no].prom_node, entry, cookie); - for(timeout = 0; timeout < 5000000; timeout++) { - if(callin_flag) + for (timeout = 0; timeout < 5000000; timeout++) { + if (callin_flag) break; udelay(100); } - if(callin_flag) { + if (callin_flag) { __cpu_number_map[i] = cpucount; __cpu_logical_map[cpucount] = i; prom_cpu_nodes[i] = linux_cpus[no].prom_node; @@ -272,20 +285,20 @@ void __init smp_boot_cpus(void) prom_printf("FAILED\n"); } } - if(!callin_flag) { + if (!callin_flag) { cpu_present_map &= ~(1UL << i); __cpu_number_map[i] = -1; } } cpu_new_task = NULL; - if(cpucount == 0) { + if (cpucount == 0) { printk("Error: only one processor found.\n"); cpu_present_map = (1UL << smp_processor_id()); } else { unsigned long bogosum = 0; - for(i = 0; i < NR_CPUS; i++) { - if(cpu_present_map & (1UL << i)) + for (i = 0; i < NR_CPUS; i++) { + if (cpu_present_map & (1UL << i)) bogosum += cpu_data[i].udelay_val; } printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n", @@ -299,9 +312,7 @@ void __init smp_boot_cpus(void) membar("#StoreStore | #StoreLoad"); } -/* #define XCALL_DEBUG */ - -static inline void xcall_deliver(u64 data0, u64 data1, u64 data2, u64 pstate, unsigned long cpu) +static void spitfire_xcall_helper(u64 data0, u64 data1, u64 data2, u64 pstate, unsigned long cpu) { u64 result, target; int stuck, tmp; @@ -314,10 +325,6 @@ static inline void xcall_deliver(u64 data0, u64 data1, u64 data2, u64 pstate, un } target = (cpu << 14) | 0x70; -#ifdef XCALL_DEBUG - printk("CPU[%d]: xcall(data[%016lx:%016lx:%016lx],tgt[%016lx])\n", - smp_processor_id(), data0, data1, data2, target); -#endif again: /* Ok, this is the real Spitfire Errata #54. * One must read back from a UDB internal register @@ -340,7 +347,7 @@ again: ldxa [%%g1] 0x7f, %%g0 membar #Sync" : "=r" (tmp) - : "r" (pstate), "i" (PSTATE_IE), "i" (ASI_UDB_INTR_W), + : "r" (pstate), "i" (PSTATE_IE), "i" (ASI_INTR_W), "r" (data0), "r" (data1), "r" (data2), "r" (target), "r" (0x10), "0" (tmp) : "g1"); @@ -350,46 +357,155 @@ again: __asm__ __volatile__("ldxa [%%g0] %1, %0" : "=r" (result) : "i" (ASI_INTR_DISPATCH_STAT)); - if(result == 0) { + if (result == 0) { __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); return; } stuck -= 1; - if(stuck == 0) + if (stuck == 0) break; - } while(result & 0x1); + } while (result & 0x1); __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); - if(stuck == 0) { -#ifdef XCALL_DEBUG + if (stuck == 0) { printk("CPU[%d]: mondo stuckage result[%016lx]\n", smp_processor_id(), result); -#endif } else { -#ifdef XCALL_DEBUG - printk("CPU[%d]: Penguin %d NACK's master.\n", smp_processor_id(), cpu); -#endif udelay(2); goto again; } } -void smp_cross_call(unsigned long *func, u32 ctx, u64 data1, u64 data2) +static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, unsigned long mask) { - if(smp_processors_ready) { - unsigned long mask = (cpu_present_map & ~(1UL<<smp_processor_id())); - u64 pstate, data0 = (((u64)ctx)<<32 | (((u64)func) & 0xffffffff)); + int ncpus = smp_num_cpus - 1; + int i; + u64 pstate; + + __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); + for (i = 0; (i < NR_CPUS) && ncpus; i++) { + if (mask & (1UL << i)) { + spitfire_xcall_helper(data0, data1, data2, pstate, i); + ncpus--; + } + } +} + +/* Cheetah now allows to send the whole 64-bytes of data in the interrupt + * packet, but we have no use for that. However we do take advantage of + * the new pipelining feature (ie. dispatch to multiple cpus simultaneously). + */ +#if NR_CPUS > 32 +#error Fixup cheetah_xcall_deliver Dave... +#endif +static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, unsigned long mask) +{ + u64 pstate; + int nack_busy_id; + + if (!mask) + return; + + __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); + +retry: + __asm__ __volatile__("wrpr %0, %1, %%pstate\n\t" + : : "r" (pstate), "i" (PSTATE_IE)); + + /* Setup the dispatch data registers. */ + __asm__ __volatile__("stxa %0, [%3] %6\n\t" + "membar #Sync\n\t" + "stxa %1, [%4] %6\n\t" + "membar #Sync\n\t" + "stxa %2, [%5] %6\n\t" + "membar #Sync\n\t" + : /* no outputs */ + : "r" (data0), "r" (data1), "r" (data2), + "r" (0x40), "r" (0x50), "r" (0x60), + "i" (ASI_INTR_W)); + + nack_busy_id = 0; + { int i, ncpus = smp_num_cpus - 1; - __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); - for(i = 0; i < NR_CPUS; i++) { - if(mask & (1UL << i)) { - xcall_deliver(data0, data1, data2, pstate, i); + for (i = 0; (i < NR_CPUS) && ncpus; i++) { + if (mask & (1UL << i)) { + u64 target = (i << 14) | 0x70; + + target |= (nack_busy_id++ << 24); + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync\n\t" + : /* no outputs */ + : "r" (target), "i" (ASI_INTR_W)); ncpus--; } - if (!ncpus) break; } + } + + /* Now, poll for completion. */ + { + u64 dispatch_stat; + long stuck; + + stuck = 100000 * nack_busy_id; + do { + __asm__ __volatile__("ldxa [%%g0] %1, %0" + : "=r" (dispatch_stat) + : "i" (ASI_INTR_DISPATCH_STAT)); + if (dispatch_stat == 0UL) { + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" + : : "r" (pstate)); + return; + } + if (!--stuck) + break; + } while (dispatch_stat & 0x5555555555555555UL); + + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" + : : "r" (pstate)); + + if ((stuck & ~(0x5555555555555555UL)) == 0) { + /* Busy bits will not clear, continue instead + * of freezing up on this cpu. + */ + printk("CPU[%d]: mondo stuckage result[%016lx]\n", + smp_processor_id(), dispatch_stat); + } else { + int i, this_busy_nack = 0; + + /* Delay some random time with interrupts enabled + * to prevent deadlock. + */ + udelay(2 * nack_busy_id); + + /* Clear out the mask bits for cpus which did not + * NACK us. + */ + for (i = 0; i < NR_CPUS; i++) { + if (mask & (1UL << i)) { + if ((dispatch_stat & (0x2 << this_busy_nack)) == 0) + mask &= ~(1UL << i); + this_busy_nack += 2; + } + } + + goto retry; + } + } +} + +void smp_cross_call(unsigned long *func, u32 ctx, u64 data1, u64 data2) +{ + if (smp_processors_ready) { + unsigned long mask = (cpu_present_map & ~(1UL<<smp_processor_id())); + u64 data0 = (((u64)ctx)<<32 | (((u64)func) & 0xffffffff)); + + if (tlb_type == spitfire) + spitfire_xcall_deliver(data0, data1, data2, mask); + else + cheetah_xcall_deliver(data0, data1, data2, mask); + /* NOTE: Caller runs local copy on master. */ } } @@ -445,11 +561,17 @@ extern unsigned long xcall_receive_signal; void smp_receive_signal(int cpu) { - if(smp_processors_ready && - (cpu_present_map & (1UL<<cpu)) != 0) { - u64 pstate, data0 = (((u64)&xcall_receive_signal) & 0xffffffff); - __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); - xcall_deliver(data0, 0, 0, pstate, cpu); + if (smp_processors_ready) { + unsigned long mask = 1UL << cpu; + + if ((cpu_present_map & mask) != 0) { + u64 data0 = (((u64)&xcall_receive_signal) & 0xffffffff); + + if (tlb_type == spitfire) + spitfire_xcall_deliver(data0, 0, 0, mask); + else + cheetah_xcall_deliver(data0, 0, 0, mask); + } } } @@ -609,7 +731,7 @@ void smp_capture(void) int result = __atomic_add(1, &smp_capture_depth); membar("#StoreStore | #LoadStore"); - if(result == 1) { + if (result == 1) { int ncpus = smp_num_cpus; #ifdef CAPTURE_DEBUG @@ -620,7 +742,7 @@ void smp_capture(void) membar("#StoreStore | #LoadStore"); atomic_inc(&smp_capture_registry); smp_cross_call(&xcall_capture, 0, 0, 0); - while(atomic_read(&smp_capture_registry) != ncpus) + while (atomic_read(&smp_capture_registry) != ncpus) membar("#LoadLoad"); #ifdef CAPTURE_DEBUG printk("done\n"); @@ -631,8 +753,8 @@ void smp_capture(void) void smp_release(void) { - if(smp_processors_ready) { - if(atomic_dec_and_test(&smp_capture_depth)) { + if (smp_processors_ready) { + if (atomic_dec_and_test(&smp_capture_depth)) { #ifdef CAPTURE_DEBUG printk("CPU[%d]: Giving pardon to imprisoned penguins\n", smp_processor_id()); @@ -659,7 +781,7 @@ void smp_penguin_jailcell(void) prom_world(1); atomic_inc(&smp_capture_registry); membar("#StoreLoad | #StoreStore"); - while(penguins_are_doing_time) + while (penguins_are_doing_time) membar("#LoadLoad"); restore_alternate_globals(global_save); atomic_dec(&smp_capture_registry); @@ -690,14 +812,23 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs) /* * Check for level 14 softint. */ - if (!(get_softint() & (1UL << 0))) { - extern void handler_irq(int, struct pt_regs *); + { + unsigned long tick_mask; - handler_irq(14, regs); - return; + if (SPARC64_USE_STICK) + tick_mask = (1UL << 16); + else + tick_mask = (1UL << 0); + + if (!(get_softint() & tick_mask)) { + extern void handler_irq(int, struct pt_regs *); + + handler_irq(14, regs); + return; + } + clear_softint(tick_mask); } - clear_softint((1UL << 0)); do { if (!user) sparc64_do_profile(regs->tpc, regs->u_regs[UREG_RETPC]); @@ -740,6 +871,7 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs) * that %tick is not prone to this bug, but I am not * taking any chances. */ + if (!SPARC64_USE_STICK) { __asm__ __volatile__("rd %%tick_cmpr, %0\n\t" "ba,pt %%xcc, 1f\n\t" " add %0, %2, %0\n\t" @@ -750,6 +882,14 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs) "mov %1, %1" : "=&r" (compare), "=r" (tick) : "r" (current_tick_offset)); + } else { + __asm__ __volatile__("rd %%asr25, %0\n\t" + "add %0, %2, %0\n\t" + "wr %0, 0x0, %%asr25\n\t" + "rd %%asr24, %1\n\t" + : "=&r" (compare), "=r" (tick) + : "r" (current_tick_offset)); + } /* Restore PSTATE_IE. */ __asm__ __volatile__("wrpr %0, 0x0, %%pstate" @@ -782,6 +922,7 @@ static void __init smp_setup_percpu_timer(void) * at the start of an I-cache line, and perform a dummy * read back from %tick_cmpr right after writing to it. -DaveM */ + if (!SPARC64_USE_STICK) { __asm__ __volatile__(" rd %%tick, %%g1 ba,pt %%xcc, 1f @@ -792,6 +933,15 @@ static void __init smp_setup_percpu_timer(void) : /* no outputs */ : "r" (current_tick_offset) : "g1"); + } else { + __asm__ __volatile__(" + rd %%asr24, %%g1 + add %%g1, %0, %%g1 + wr %%g1, 0x0, %%asr25" + : /* no outputs */ + : "r" (current_tick_offset) + : "g1"); + } /* Restore PSTATE_IE. */ __asm__ __volatile__("wrpr %0, 0x0, %%pstate" @@ -806,9 +956,9 @@ void __init smp_tick_init(void) boot_cpu_id = hard_smp_processor_id(); current_tick_offset = timer_tick_offset; cpu_present_map = 0; - for(i = 0; i < linux_num_cpus; i++) + for (i = 0; i < linux_num_cpus; i++) cpu_present_map |= (1UL << linux_cpus[i].mid); - for(i = 0; i < NR_CPUS; i++) { + for (i = 0; i < NR_CPUS; i++) { __cpu_number_map[i] = -1; __cpu_logical_map[i] = -1; } @@ -827,11 +977,11 @@ static inline unsigned long find_flush_base(unsigned long size) size = PAGE_ALIGN(size); found = size; base = (unsigned long) page_address(p); - while(found != 0) { + while (found != 0) { /* Failure. */ - if(p >= (mem_map + max_mapnr)) + if (p >= (mem_map + max_mapnr)) return 0UL; - if(PageReserved(p)) { + if (PageReserved(p)) { found = size; base = (unsigned long) page_address(p); } else { @@ -924,12 +1074,12 @@ int setup_profiling_timer(unsigned int multiplier) unsigned long flags; int i; - if((!multiplier) || (timer_tick_offset / multiplier) < 1000) + if ((!multiplier) || (timer_tick_offset / multiplier) < 1000) return -EINVAL; save_and_cli(flags); - for(i = 0; i < NR_CPUS; i++) { - if(cpu_present_map & (1UL << i)) + for (i = 0; i < NR_CPUS; i++) { + if (cpu_present_map & (1UL << i)) prof_multiplier(i) = multiplier; } current_tick_offset = (timer_tick_offset / multiplier); diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index f35e38a5d..2dc8ddb4f 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.100 2001/01/11 15:07:09 davem Exp $ +/* $Id: sparc64_ksyms.c,v 1.102 2001/03/24 09:36:01 davem Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -179,6 +179,8 @@ EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(__flushw_user); +EXPORT_SYMBOL(tlb_type); + EXPORT_SYMBOL(flush_icache_range); EXPORT_SYMBOL(__flush_dcache_page); @@ -232,8 +234,7 @@ EXPORT_SYMBOL(_sigpause_common); /* Should really be in linux/kernel/ksyms.c */ EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(dump_fpu); -EXPORT_SYMBOL(get_pmd_slow); -EXPORT_SYMBOL(get_pte_slow); +EXPORT_SYMBOL(pte_alloc_one); #ifndef CONFIG_SMP EXPORT_SYMBOL(pgt_quicklists); #endif diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index e3cd81c97..16c9e7e19 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.48 2001/02/13 01:16:44 davem Exp $ +/* $Id: sys_sparc.c,v 1.50 2001/03/24 09:36:10 davem Exp $ * linux/arch/sparc64/kernel/sys_sparc.c * * This file contains various random system calls that @@ -243,9 +243,9 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, if (flags & MAP_SHARED) current->thread.flags |= SPARC_FLAG_MMAPSHARED; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); retval = do_mmap(file, addr, len, prot, flags, off); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED); @@ -263,9 +263,9 @@ asmlinkage long sys64_munmap(unsigned long addr, size_t len) if (len > -PAGE_OFFSET || (addr < PAGE_OFFSET && addr + len > -PAGE_OFFSET)) return -EINVAL; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); ret = do_munmap(current->mm, addr, len); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); return ret; } @@ -285,7 +285,7 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr, goto out; if (addr < PAGE_OFFSET && addr + old_len > -PAGE_OFFSET) goto out; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); vma = find_vma(current->mm, addr); if (vma && (vma->vm_flags & VM_SHARED)) current->thread.flags |= SPARC_FLAG_MMAPSHARED; @@ -305,7 +305,7 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr, ret = do_mremap(addr, old_len, new_len, flags, new_addr); out_sem: current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); out: return ret; } @@ -335,6 +335,10 @@ sparc_breakpoint (struct pt_regs *regs) { siginfo_t info; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } #ifdef DEBUG_SPARC_BREAKPOINT printk ("TRAP: Entering kernel PC=%lx, nPC=%lx\n", regs->tpc, regs->tnpc); #endif @@ -384,6 +388,10 @@ asmlinkage int solaris_syscall(struct pt_regs *regs) regs->tpc = regs->tnpc; regs->tnpc += 4; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } if(++count <= 5) { printk ("For Solaris binary emulation you need solaris module loaded\n"); show_regs (regs); @@ -400,6 +408,10 @@ asmlinkage int sunos_syscall(struct pt_regs *regs) regs->tpc = regs->tnpc; regs->tnpc += 4; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } if(++count <= 20) printk ("SunOS binary emulation not compiled in\n"); force_sig(SIGSEGV, current); diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index d68b75cab..571826a12 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.173 2001/02/13 01:16:44 davem Exp $ +/* $Id: sys_sparc32.c,v 1.174 2001/03/24 09:36:10 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -4133,7 +4133,7 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr, goto out; if (addr > 0xf0000000UL - old_len) goto out; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); vma = find_vma(current->mm, addr); if (vma && (vma->vm_flags & VM_SHARED)) current->thread.flags |= SPARC_FLAG_MMAPSHARED; @@ -4152,7 +4152,7 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr, ret = do_mremap(addr, old_len, new_len, flags, new_addr); out_sem: current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); out: return ret; } diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index bfbd8841c..a51b69783 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos32.c,v 1.57 2001/02/13 01:16:44 davem Exp $ +/* $Id: sys_sunos32.c,v 1.59 2001/03/24 09:36:11 davem Exp $ * sys_sunos32.c: SunOS binary compatability layer on sparc64. * * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -100,12 +100,12 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 of flags &= ~_MAP_NEW; flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); retval = do_mmap(file, (unsigned long) addr, (unsigned long) len, (unsigned long) prot, (unsigned long) flags, (unsigned long) off); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if(!ret_type) retval = ((retval < 0xf0000000) ? 0 : retval); out_putf: @@ -126,7 +126,7 @@ asmlinkage int sunos_brk(u32 baddr) unsigned long rlim; unsigned long newbrk, oldbrk, brk = (unsigned long) baddr; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); if (brk < current->mm->end_code) goto out; newbrk = PAGE_ALIGN(brk); @@ -170,7 +170,7 @@ asmlinkage int sunos_brk(u32 baddr) do_brk(oldbrk, newbrk-oldbrk); retval = 0; out: - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); return retval; } @@ -456,6 +456,10 @@ asmlinkage int sunos_nosys(void) static int cnt; regs = current->thread.kregs; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } info.si_signo = SIGSYS; info.si_errno = 0; info.si_code = __SI_FAULT|0x100; diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index a3340f54a..f369368d2 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.33 2001/01/11 15:07:09 davem Exp $ +/* $Id: time.c,v 1.36 2001/03/15 08:51:24 anton Exp $ * time.c: UltraSparc timer and TOD clock support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -20,6 +20,8 @@ #include <linux/timex.h> #include <linux/init.h> #include <linux/ioport.h> +#include <linux/mc146818rtc.h> +#include <linux/delay.h> #include <asm/oplib.h> #include <asm/mostek.h> @@ -35,7 +37,11 @@ extern rwlock_t xtime_lock; spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED; +spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; unsigned long mstk48t02_regs = 0UL; +#ifdef CONFIG_PCI +unsigned long ds1287_regs = 0UL; +#endif static unsigned long mstk48t08_regs = 0UL; static unsigned long mstk48t59_regs = 0UL; @@ -77,6 +83,7 @@ void sparc64_do_profile(unsigned long pc, unsigned long o7) extern int rwlock_impl_begin, rwlock_impl_end; extern int atomic_impl_begin, atomic_impl_end; extern int __memcpy_begin, __memcpy_end; + extern int __bzero_begin, __bzero_end; extern int __bitops_begin, __bitops_end; if ((pc >= (unsigned long) &atomic_impl_begin && @@ -85,6 +92,8 @@ void sparc64_do_profile(unsigned long pc, unsigned long o7) pc < (unsigned long) &rwlock_impl_end) || (pc >= (unsigned long) &__memcpy_begin && pc < (unsigned long) &__memcpy_end) || + (pc >= (unsigned long) &__bzero_begin && + pc < (unsigned long) &__bzero_end) || (pc >= (unsigned long) &__bitops_begin && pc < (unsigned long) &__bitops_end)) pc = o7; @@ -135,6 +144,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) * that %tick is not prone to this bug, but I am not * taking any chances. */ + if (!SPARC64_USE_STICK) { __asm__ __volatile__(" rd %%tick_cmpr, %0 ba,pt %%xcc, 1f @@ -146,6 +156,15 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) mov %1, %1" : "=&r" (timer_tick_compare), "=r" (ticks) : "r" (timer_tick_offset)); + } else { + __asm__ __volatile__(" + rd %%asr25, %0 + add %0, %2, %0 + wr %0, 0, %%asr25 + rd %%asr24, %1" + : "=&r" (timer_tick_compare), "=r" (ticks) + : "r" (timer_tick_offset)); + } /* Restore PSTATE_IE. */ __asm__ __volatile__("wrpr %0, 0x0, %%pstate" @@ -168,11 +187,19 @@ void timer_tick_interrupt(struct pt_regs *regs) /* * Only keep timer_tick_offset uptodate, but don't set TICK_CMPR. */ + if (!SPARC64_USE_STICK) { __asm__ __volatile__(" rd %%tick_cmpr, %0 add %0, %1, %0" : "=&r" (timer_tick_compare) : "r" (timer_tick_offset)); + } else { + __asm__ __volatile__(" + rd %%asr25, %0 + add %0, %1, %0" + : "=&r" (timer_tick_compare) + : "r" (timer_tick_offset)); + } timer_check_rtc(); @@ -282,41 +309,95 @@ static int __init has_low_battery(void) return (data1 == data2); /* Was the write blocked? */ } +#ifndef BCD_TO_BIN +#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10) +#endif + +#ifndef BIN_TO_BCD +#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10) +#endif /* Probe for the real time clock chip. */ static void __init set_system_time(void) { unsigned int year, mon, day, hour, min, sec; unsigned long mregs = mstk48t02_regs; +#ifdef CONFIG_PCI + unsigned long dregs = ds1287_regs; +#else + unsigned long dregs = 0UL; +#endif u8 tmp; do_get_fast_time = do_gettimeofday; - if(!mregs) { + if (!mregs && !dregs) { prom_printf("Something wrong, clock regs not mapped yet.\n"); prom_halt(); } - spin_lock_irq(&mostek_lock); + if (mregs) { + spin_lock_irq(&mostek_lock); - tmp = mostek_read(mregs + MOSTEK_CREG); - tmp |= MSTK_CREG_READ; - mostek_write(mregs + MOSTEK_CREG, tmp); + /* Traditional Mostek chip. */ + tmp = mostek_read(mregs + MOSTEK_CREG); + tmp |= MSTK_CREG_READ; + mostek_write(mregs + MOSTEK_CREG, tmp); + + sec = MSTK_REG_SEC(mregs); + min = MSTK_REG_MIN(mregs); + hour = MSTK_REG_HOUR(mregs); + day = MSTK_REG_DOM(mregs); + mon = MSTK_REG_MONTH(mregs); + year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) ); + } else { + int i; + + /* Dallas 12887 RTC chip. */ + + /* Stolen from arch/i386/kernel/time.c, see there for + * credits and descriptive comments. + */ + for (i = 0; i < 1000000; i++) { + if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) + break; + udelay(10); + } + for (i = 0; i < 1000000; i++) { + if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) + break; + udelay(10); + } + do { + sec = CMOS_READ(RTC_SECONDS); + min = CMOS_READ(RTC_MINUTES); + hour = CMOS_READ(RTC_HOURS); + day = CMOS_READ(RTC_DAY_OF_MONTH); + mon = CMOS_READ(RTC_MONTH); + year = CMOS_READ(RTC_YEAR); + } while (sec != CMOS_READ(RTC_SECONDS)); + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + if ((year += 1900) < 1970) + year += 100; + } - sec = MSTK_REG_SEC(mregs); - min = MSTK_REG_MIN(mregs); - hour = MSTK_REG_HOUR(mregs); - day = MSTK_REG_DOM(mregs); - mon = MSTK_REG_MONTH(mregs); - year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) ); xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_usec = 0; - tmp = mostek_read(mregs + MOSTEK_CREG); - tmp &= ~MSTK_CREG_READ; - mostek_write(mregs + MOSTEK_CREG, tmp); + if (mregs) { + tmp = mostek_read(mregs + MOSTEK_CREG); + tmp &= ~MSTK_CREG_READ; + mostek_write(mregs + MOSTEK_CREG, tmp); - spin_unlock_irq(&mostek_lock); + spin_unlock_irq(&mostek_lock); + } } void __init clock_probe(void) @@ -358,21 +439,22 @@ void __init clock_probe(void) busnd = sbus_root->prom_node; } - if(busnd == -1) { + if (busnd == -1) { prom_printf("clock_probe: problem, cannot find bus to search.\n"); prom_halt(); } node = prom_getchild(busnd); - while(1) { + while (1) { if (!node) model[0] = 0; else prom_getstring(node, "model", model, sizeof(model)); - if(strcmp(model, "mk48t02") && - strcmp(model, "mk48t08") && - strcmp(model, "mk48t59")) { + if (strcmp(model, "mk48t02") && + strcmp(model, "mk48t08") && + strcmp(model, "mk48t59") && + strcmp(model, "ds1287")) { if (node) node = prom_getsibling(node); #ifdef CONFIG_PCI @@ -384,7 +466,7 @@ void __init clock_probe(void) } } #endif - if(node == 0) { + if (node == 0) { prom_printf("clock_probe: Cannot find timer chip\n"); prom_halt(); } @@ -415,8 +497,12 @@ void __init clock_probe(void) prom_halt(); } - mstk48t59_regs = edev->resource[0].start; - mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02; + if (!strcmp(model, "ds1287")) { + ds1287_regs = edev->resource[0].start; + } else { + mstk48t59_regs = edev->resource[0].start; + mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02; + } break; } #endif @@ -456,27 +542,21 @@ void __init clock_probe(void) break; } - /* Report a low battery voltage condition. */ - if (has_low_battery()) - prom_printf("NVRAM: Low battery voltage!\n"); + if (mstk48t02_regs != 0UL) { + /* Report a low battery voltage condition. */ + if (has_low_battery()) + prom_printf("NVRAM: Low battery voltage!\n"); - /* Kick start the clock if it is completely stopped. */ - if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP) - kick_start_clock(); + /* Kick start the clock if it is completely stopped. */ + if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP) + kick_start_clock(); + } set_system_time(); __restore_flags(flags); } -#ifndef BCD_TO_BIN -#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10) -#endif - -#ifndef BIN_TO_BCD -#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10) -#endif - extern void init_timers(void (*func)(int, void *, struct pt_regs *), unsigned long *); @@ -497,6 +577,7 @@ static __inline__ unsigned long do_gettimeoffset(void) { unsigned long ticks; + if (!SPARC64_USE_STICK) { __asm__ __volatile__(" rd %%tick, %%g1 add %1, %%g1, %0 @@ -505,6 +586,14 @@ static __inline__ unsigned long do_gettimeoffset(void) : "=r" (ticks) : "r" (timer_tick_offset), "r" (timer_tick_compare) : "g1", "g2"); + } else { + __asm__ __volatile__("rd %%asr24, %%g1\n\t" + "add %1, %%g1, %0\n\t" + "sub %0, %2, %0\n\t" + : "=&r" (ticks) + : "r" (timer_tick_offset), "r" (timer_tick_compare) + : "g1"); + } return (ticks * timer_ticks_per_usec_quotient) >> 32UL; } @@ -533,8 +622,13 @@ void do_settimeofday(struct timeval *tv) static int set_rtc_mmss(unsigned long nowtime) { - int real_seconds, real_minutes, mostek_minutes; - unsigned long regs = mstk48t02_regs; + int real_seconds, real_minutes, chip_minutes; + unsigned long mregs = mstk48t02_regs; +#ifdef CONFIG_PCI + unsigned long dregs = ds1287_regs; +#else + unsigned long dregs = 0UL; +#endif unsigned long flags; u8 tmp; @@ -542,52 +636,96 @@ static int set_rtc_mmss(unsigned long nowtime) * Not having a register set can lead to trouble. * Also starfire doesnt have a tod clock. */ - if (!regs) + if (!mregs && !dregs) return -1; - spin_lock_irqsave(&mostek_lock, flags); + if (mregs) { + spin_lock_irqsave(&mostek_lock, flags); - /* Read the current RTC minutes. */ - tmp = mostek_read(regs + MOSTEK_CREG); - tmp |= MSTK_CREG_READ; - mostek_write(regs + MOSTEK_CREG, tmp); + /* Read the current RTC minutes. */ + tmp = mostek_read(mregs + MOSTEK_CREG); + tmp |= MSTK_CREG_READ; + mostek_write(mregs + MOSTEK_CREG, tmp); - mostek_minutes = MSTK_REG_MIN(regs); + chip_minutes = MSTK_REG_MIN(mregs); - tmp = mostek_read(regs + MOSTEK_CREG); - tmp &= ~MSTK_CREG_READ; - mostek_write(regs + MOSTEK_CREG, tmp); + tmp = mostek_read(mregs + MOSTEK_CREG); + tmp &= ~MSTK_CREG_READ; + mostek_write(mregs + MOSTEK_CREG, tmp); - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - chip_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; - if (abs(real_minutes - mostek_minutes) < 30) { - tmp = mostek_read(regs + MOSTEK_CREG); - tmp |= MSTK_CREG_WRITE; - mostek_write(regs + MOSTEK_CREG, tmp); + if (abs(real_minutes - chip_minutes) < 30) { + tmp = mostek_read(mregs + MOSTEK_CREG); + tmp |= MSTK_CREG_WRITE; + mostek_write(mregs + MOSTEK_CREG, tmp); - MSTK_SET_REG_SEC(regs,real_seconds); - MSTK_SET_REG_MIN(regs,real_minutes); + MSTK_SET_REG_SEC(mregs,real_seconds); + MSTK_SET_REG_MIN(mregs,real_minutes); - tmp = mostek_read(regs + MOSTEK_CREG); - tmp &= ~MSTK_CREG_WRITE; - mostek_write(regs + MOSTEK_CREG, tmp); + tmp = mostek_read(mregs + MOSTEK_CREG); + tmp &= ~MSTK_CREG_WRITE; + mostek_write(mregs + MOSTEK_CREG, tmp); + + spin_unlock_irqrestore(&mostek_lock, flags); - spin_unlock_irqrestore(&mostek_lock, flags); + return 0; + } else { + spin_unlock_irqrestore(&mostek_lock, flags); - return 0; + return -1; + } } else { - spin_unlock_irqrestore(&mostek_lock, flags); + int retval = 0; + unsigned char save_control, save_freq_select; - return -1; + /* Stolen from arch/i386/kernel/time.c, see there for + * credits and descriptive comments. + */ + spin_lock_irqsave(&rtc_lock, flags); + save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ + CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); + + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + + chip_minutes = CMOS_READ(RTC_MINUTES); + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + BCD_TO_BIN(chip_minutes); + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - chip_minutes) + 15)/30) & 1) + real_minutes += 30; + real_minutes %= 60; + + if (abs(real_minutes - chip_minutes) < 30) { + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); + } + CMOS_WRITE(real_seconds,RTC_SECONDS); + CMOS_WRITE(real_minutes,RTC_MINUTES); + } else { + printk(KERN_WARNING + "set_rtc_mmss: can't update from %d to %d\n", + chip_minutes, real_minutes); + retval = -1; + } + + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); + spin_unlock_irqrestore(&rtc_lock, flags); + + return retval; } } diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 4f2606c97..578a5ae80 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S @@ -1,4 +1,4 @@ -/* $Id: trampoline.S,v 1.12 1999/12/15 15:45:12 davem Exp $ +/* $Id: trampoline.S,v 1.19 2001/03/22 09:54:26 davem Exp $ * trampoline.S: Jump start slave processors on sparc64. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -7,6 +7,8 @@ #include <asm/head.h> #include <asm/asi.h> #include <asm/lsu.h> +#include <asm/dcr.h> +#include <asm/dcu.h> #include <asm/pstate.h> #include <asm/page.h> #include <asm/pgtable.h> @@ -30,177 +32,246 @@ dtlb_load: sparc64_cpu_startup: flushw - mov (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1 - stxa %g1, [%g0] ASI_LSU_CONTROL - membar #Sync + rdpr %ver, %g1 + sethi %hi(0x003e0014), %g5 + srlx %g1, 32, %g1 + or %g5, %lo(0x003e0014), %g5 + cmp %g1, %g5 + bne,pt %icc, spitfire_startup + nop + +cheetah_startup: + mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1 + wr %g1, %asr18 + + sethi %uhi(DCU_ME | DCU_RE | DCU_PE | DCU_HPE | DCU_SPE | DCU_SL | DCU_WE), %g5 + or %g5, %ulo(DCU_ME | DCU_RE | DCU_PE | DCU_HPE | DCU_SPE | DCU_SL | DCU_WE), %g5 + sllx %g5, 32, %g5 + or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5 + ldxa [%g0] ASI_DCU_CONTROL_REG, %g3 + or %g5, %g3, %g5 + stxa %g5, [%g0] ASI_DCU_CONTROL_REG + membar #Sync + + /* Disable STICK_INT interrupts. */ + sethi %hi(0x80000000), %g5 + sllx %g5, 32, %g5 + wr %g5, %asr25 + + ba,pt %xcc, startup_continue + nop - wrpr %g0, 15, %pil - wr %g0, 0, %tick_cmpr +spitfire_startup: + mov (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1 + stxa %g1, [%g0] ASI_LSU_CONTROL + membar #Sync + +startup_continue: + wrpr %g0, 15, %pil + wr %g0, 0, %tick_cmpr /* Call OBP by hand to lock KERNBASE into i/d tlbs. */ - mov %o0, %l0 - - sethi %hi(prom_entry_lock), %g2 -1: ldstub [%g2 + %lo(prom_entry_lock)], %g1 - brnz,pn %g1, 1b - membar #StoreLoad | #StoreStore - - sethi %hi(p1275buf), %g2 - or %g2, %lo(p1275buf), %g2 - ldx [%g2 + 0x10], %l2 - mov %sp, %l1 - add %l2, -(192 + 128), %sp + mov %o0, %l0 + + sethi %hi(prom_entry_lock), %g2 +1: ldstub [%g2 + %lo(prom_entry_lock)], %g1 + brnz,pn %g1, 1b + membar #StoreLoad | #StoreStore + + sethi %hi(p1275buf), %g2 + or %g2, %lo(p1275buf), %g2 + ldx [%g2 + 0x10], %l2 + mov %sp, %l1 + add %l2, -(192 + 128), %sp flushw - sethi %hi(call_method), %g2 - or %g2, %lo(call_method), %g2 - stx %g2, [%sp + 2047 + 128 + 0x00] - mov 5, %g2 - stx %g2, [%sp + 2047 + 128 + 0x08] - mov 1, %g2 - stx %g2, [%sp + 2047 + 128 + 0x10] - sethi %hi(itlb_load), %g2 - or %g2, %lo(itlb_load), %g2 - stx %g2, [%sp + 2047 + 128 + 0x18] - sethi %hi(mmu_ihandle_cache), %g2 - lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 - stx %g2, [%sp + 2047 + 128 + 0x20] - sethi %hi(KERNBASE), %g2 - stx %g2, [%sp + 2047 + 128 + 0x28] - sethi %hi(kern_locked_tte_data), %g2 - ldx [%g2 + %lo(kern_locked_tte_data)], %g2 - stx %g2, [%sp + 2047 + 128 + 0x30] - mov 63, %g2 - stx %g2, [%sp + 2047 + 128 + 0x38] - sethi %hi(p1275buf), %g2 - or %g2, %lo(p1275buf), %g2 - ldx [%g2 + 0x08], %o1 - call %o1 - add %sp, (2047 + 128), %o0 - - sethi %hi(call_method), %g2 - or %g2, %lo(call_method), %g2 - stx %g2, [%sp + 2047 + 128 + 0x00] - mov 5, %g2 - stx %g2, [%sp + 2047 + 128 + 0x08] - mov 1, %g2 - stx %g2, [%sp + 2047 + 128 + 0x10] - sethi %hi(dtlb_load), %g2 - or %g2, %lo(dtlb_load), %g2 - stx %g2, [%sp + 2047 + 128 + 0x18] - sethi %hi(mmu_ihandle_cache), %g2 - lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 - stx %g2, [%sp + 2047 + 128 + 0x20] - sethi %hi(KERNBASE), %g2 - stx %g2, [%sp + 2047 + 128 + 0x28] - sethi %hi(kern_locked_tte_data), %g2 - ldx [%g2 + %lo(kern_locked_tte_data)], %g2 - stx %g2, [%sp + 2047 + 128 + 0x30] - mov 63, %g2 - stx %g2, [%sp + 2047 + 128 + 0x38] - sethi %hi(p1275buf), %g2 - or %g2, %lo(p1275buf), %g2 - ldx [%g2 + 0x08], %o1 - call %o1 - add %sp, (2047 + 128), %o0 - - sethi %hi(prom_entry_lock), %g2 - stb %g0, [%g2 + %lo(prom_entry_lock)] - membar #StoreStore | #StoreLoad - - mov %l1, %sp + sethi %hi(call_method), %g2 + or %g2, %lo(call_method), %g2 + stx %g2, [%sp + 2047 + 128 + 0x00] + mov 5, %g2 + stx %g2, [%sp + 2047 + 128 + 0x08] + mov 1, %g2 + stx %g2, [%sp + 2047 + 128 + 0x10] + sethi %hi(itlb_load), %g2 + or %g2, %lo(itlb_load), %g2 + stx %g2, [%sp + 2047 + 128 + 0x18] + sethi %hi(mmu_ihandle_cache), %g2 + lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 + stx %g2, [%sp + 2047 + 128 + 0x20] + sethi %hi(KERNBASE), %g2 + stx %g2, [%sp + 2047 + 128 + 0x28] + sethi %hi(kern_locked_tte_data), %g2 + ldx [%g2 + %lo(kern_locked_tte_data)], %g2 + stx %g2, [%sp + 2047 + 128 + 0x30] + + rdpr %ver, %g1 + sethi %hi(0x003e0014), %g5 + srlx %g1, 32, %g1 + or %g5, %lo(0x003e0014), %g5 + cmp %g1, %g5 + bne,a,pt %icc, 1f + mov 63, %g2 + mov 15, %g2 +1: + stx %g2, [%sp + 2047 + 128 + 0x38] + sethi %hi(p1275buf), %g2 + or %g2, %lo(p1275buf), %g2 + ldx [%g2 + 0x08], %o1 + call %o1 + add %sp, (2047 + 128), %o0 + + sethi %hi(call_method), %g2 + or %g2, %lo(call_method), %g2 + stx %g2, [%sp + 2047 + 128 + 0x00] + mov 5, %g2 + stx %g2, [%sp + 2047 + 128 + 0x08] + mov 1, %g2 + stx %g2, [%sp + 2047 + 128 + 0x10] + sethi %hi(dtlb_load), %g2 + or %g2, %lo(dtlb_load), %g2 + stx %g2, [%sp + 2047 + 128 + 0x18] + sethi %hi(mmu_ihandle_cache), %g2 + lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 + stx %g2, [%sp + 2047 + 128 + 0x20] + sethi %hi(KERNBASE), %g2 + stx %g2, [%sp + 2047 + 128 + 0x28] + sethi %hi(kern_locked_tte_data), %g2 + ldx [%g2 + %lo(kern_locked_tte_data)], %g2 + stx %g2, [%sp + 2047 + 128 + 0x30] + + rdpr %ver, %g1 + sethi %hi(0x003e0014), %g5 + srlx %g1, 32, %g1 + or %g5, %lo(0x003e0014), %g5 + cmp %g1, %g5 + bne,a,pt %icc, 1f + mov 63, %g2 + mov 15, %g2 +1: + + stx %g2, [%sp + 2047 + 128 + 0x38] + sethi %hi(p1275buf), %g2 + or %g2, %lo(p1275buf), %g2 + ldx [%g2 + 0x08], %o1 + call %o1 + add %sp, (2047 + 128), %o0 + + sethi %hi(prom_entry_lock), %g2 + stb %g0, [%g2 + %lo(prom_entry_lock)] + membar #StoreStore | #StoreLoad + + mov %l1, %sp flushw - mov %l0, %o0 + mov %l0, %o0 - wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate - wr %g0, 0, %fprs + wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate + wr %g0, 0, %fprs - sethi %uhi(PAGE_OFFSET), %g4 - sllx %g4, 32, %g4 + sethi %uhi(PAGE_OFFSET), %g4 + sllx %g4, 32, %g4 /* XXX Buggy PROM... */ - srl %o0, 0, %o0 - ldx [%o0], %g6 + srl %o0, 0, %o0 + ldx [%o0], %g6 - wr %g0, ASI_P, %asi + wr %g0, ASI_P, %asi - mov PRIMARY_CONTEXT, %g7 - stxa %g0, [%g7] ASI_DMMU - membar #Sync - mov SECONDARY_CONTEXT, %g7 - stxa %g0, [%g7] ASI_DMMU - membar #Sync + mov PRIMARY_CONTEXT, %g7 + stxa %g0, [%g7] ASI_DMMU + membar #Sync + mov SECONDARY_CONTEXT, %g7 + stxa %g0, [%g7] ASI_DMMU + membar #Sync - mov 1, %g5 - sllx %g5, (PAGE_SHIFT + 1), %g5 - sub %g5, (REGWIN_SZ + STACK_BIAS), %g5 - add %g6, %g5, %sp - mov 0, %fp + mov 1, %g5 + sllx %g5, (PAGE_SHIFT + 1), %g5 + sub %g5, (REGWIN_SZ + STACK_BIAS), %g5 + add %g6, %g5, %sp + mov 0, %fp - wrpr %g0, 0, %wstate - wrpr %g0, 0, %tl + wrpr %g0, 0, %wstate + wrpr %g0, 0, %tl /* Setup the trap globals, then we can resurface. */ - rdpr %pstate, %o1 - mov %g6, %o2 - wrpr %o1, PSTATE_AG, %pstate - sethi %hi(sparc64_ttable_tl0), %g5 - wrpr %g5, %tba - mov %o2, %g6 - - wrpr %o1, PSTATE_MG, %pstate -#define KERN_HIGHBITS ((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000) + rdpr %pstate, %o1 + mov %g6, %o2 + wrpr %o1, PSTATE_AG, %pstate + sethi %hi(sparc64_ttable_tl0), %g5 + wrpr %g5, %tba + mov %o2, %g6 + + wrpr %o1, PSTATE_MG, %pstate +#define KERN_HIGHBITS ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000) #define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W) -#ifdef THIS_IS_CHEETAH -#error Dave, make sure you took care of other issues in rest of sparc64 code... -#define VPTE_BASE 0xffe0000000000000 -#else /* Spitfire/Blackbird */ -#define VPTE_BASE 0xfffffffe00000000 + +#define VPTE_BASE_SPITFIRE 0xfffffffe00000000 +#if 1 +#define VPTE_BASE_CHEETAH VPTE_BASE_SPITFIRE +#else +#define VPTE_BASE_CHEETAH 0xffe0000000000000 #endif - mov TSB_REG, %g1 - stxa %g0, [%g1] ASI_DMMU - membar #Sync - mov TLB_SFSR, %g1 - sethi %uhi(KERN_HIGHBITS), %g2 - or %g2, %ulo(KERN_HIGHBITS), %g2 - sllx %g2, 32, %g2 - or %g2, KERN_LOWBITS, %g2 - sethi %uhi(VPTE_BASE), %g3 - or %g3, %ulo(VPTE_BASE), %g3 - sllx %g3, 32, %g3 + + mov TSB_REG, %g1 + stxa %g0, [%g1] ASI_DMMU + membar #Sync + mov TLB_SFSR, %g1 + sethi %uhi(KERN_HIGHBITS), %g2 + or %g2, %ulo(KERN_HIGHBITS), %g2 + sllx %g2, 32, %g2 + or %g2, KERN_LOWBITS, %g2 + + rdpr %ver, %g3 + sethi %hi(0x003e0014), %g7 + srlx %g3, 32, %g3 + or %g7, %lo(0x003e0014), %g7 + cmp %g3, %g7 + bne,pt %icc, 1f + nop + + sethi %uhi(VPTE_BASE_CHEETAH), %g3 + or %g3, %ulo(VPTE_BASE_CHEETAH), %g3 + ba,pt %xcc, 2f + sllx %g3, 32, %g3 +1: + sethi %uhi(VPTE_BASE_SPITFIRE), %g3 + or %g3, %ulo(VPTE_BASE_SPITFIRE), %g3 + sllx %g3, 32, %g3 + +2: clr %g7 #undef KERN_HIGHBITS #undef KERN_LOWBITS -#undef VPTE_BASE +#undef VPTE_BASE_SPITFIRE +#undef VPTE_BASE_CHEETAH /* Setup interrupt globals, we are always SMP. */ - wrpr %o1, PSTATE_IG, %pstate + wrpr %o1, PSTATE_IG, %pstate /* Get our UPA MID. */ - lduw [%o2 + AOFF_task_processor], %g1 - sethi %hi(cpu_data), %g5 - or %g5, %lo(cpu_data), %g5 + lduw [%o2 + AOFF_task_processor], %g1 + sethi %hi(cpu_data), %g5 + or %g5, %lo(cpu_data), %g5 /* In theory this is: &(cpu_data[this_upamid].irq_worklists[0]) */ - sllx %g1, 7, %g1 - add %g5, %g1, %g1 - add %g1, 64, %g6 + sllx %g1, 7, %g1 + add %g5, %g1, %g1 + add %g1, 64, %g6 - wrpr %g0, 0, %wstate - or %o1, PSTATE_IE, %o1 - wrpr %o1, 0, %pstate + wrpr %g0, 0, %wstate + or %o1, PSTATE_IE, %o1 + wrpr %o1, 0, %pstate - call prom_set_trap_table - sethi %hi(sparc64_ttable_tl0), %o0 + call prom_set_trap_table + sethi %hi(sparc64_ttable_tl0), %o0 - call smp_callin + call smp_callin nop - call cpu_idle - mov 0, %o0 - call cpu_panic + call cpu_idle + mov 0, %o0 + call cpu_panic nop -1: b,a,pt %xcc, 1b +1: b,a,pt %xcc, 1b .align 8 sparc64_cpu_startup_end: diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index cc703d3bc..0a368bcee 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.70 2001/02/09 05:46:44 davem Exp $ +/* $Id: traps.c,v 1.73 2001/03/22 07:26:03 davem Exp $ * arch/sparc64/kernel/traps.c * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -26,6 +26,7 @@ #include <asm/uaccess.h> #include <asm/fpumacro.h> #include <asm/lsu.h> +#include <asm/dcu.h> #include <asm/psrcompat.h> #ifdef CONFIG_KMOD #include <linux/kmod.h> @@ -263,6 +264,10 @@ void bad_trap (struct pt_regs *regs, long lvl) } if (regs->tstate & TSTATE_PRIV) die_if_kernel ("Kernel bad trap", regs); + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLTRP; @@ -291,6 +296,10 @@ void instruction_access_exception (struct pt_regs *regs, #endif die_if_kernel("Iax", regs); } + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } info.si_signo = SIGSEGV; info.si_errno = 0; info.si_code = SEGV_MAPERR; @@ -342,32 +351,41 @@ void data_access_exception (struct pt_regs *regs, #ifdef CONFIG_PCI /* This is really pathetic... */ -/* #define DEBUG_PCI_POKES */ extern volatile int pci_poke_in_progress; extern volatile int pci_poke_faulted; #endif /* When access exceptions happen, we must do this. */ -static __inline__ void clean_and_reenable_l1_caches(void) +static void clean_and_reenable_l1_caches(void) { unsigned long va; - /* Clean 'em. */ - for(va = 0; va < (PAGE_SIZE << 1); va += 32) { - spitfire_put_icache_tag(va, 0x0); - spitfire_put_dcache_tag(va, 0x0); - } + if (tlb_type == spitfire) { + /* Clean 'em. */ + for (va = 0; va < (PAGE_SIZE << 1); va += 32) { + spitfire_put_icache_tag(va, 0x0); + spitfire_put_dcache_tag(va, 0x0); + } - /* Re-enable. */ - __asm__ __volatile__("flush %%g6\n\t" - "membar #Sync\n\t" - "stxa %0, [%%g0] %1\n\t" - "membar #Sync" - : /* no outputs */ - : "r" (LSU_CONTROL_IC | LSU_CONTROL_DC | - LSU_CONTROL_IM | LSU_CONTROL_DM), - "i" (ASI_LSU_CONTROL) - : "memory"); + /* Re-enable in LSU. */ + __asm__ __volatile__("flush %%g6\n\t" + "membar #Sync\n\t" + "stxa %0, [%%g0] %1\n\t" + "membar #Sync" + : /* no outputs */ + : "r" (LSU_CONTROL_IC | LSU_CONTROL_DC | + LSU_CONTROL_IM | LSU_CONTROL_DM), + "i" (ASI_LSU_CONTROL) + : "memory"); + } else if (tlb_type == cheetah) { + /* Flush D-cache */ + for (va = 0; va < (1 << 16); va += (1 << 5)) { + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* no outputs */ + : "r" (va), "i" (ASI_DCACHE_TAG)); + } + } } void do_iae(struct pt_regs *regs) @@ -387,20 +405,16 @@ void do_iae(struct pt_regs *regs) void do_dae(struct pt_regs *regs) { #ifdef CONFIG_PCI - if(pci_poke_in_progress) { -#ifdef DEBUG_PCI_POKES - prom_printf(" (POKE tpc[%016lx] tnpc[%016lx] ", - regs->tpc, regs->tnpc); -#endif + if (pci_poke_in_progress) { + clean_and_reenable_l1_caches(); + pci_poke_faulted = 1; - regs->tnpc = regs->tpc + 4; + /* Why the fuck did they have to change this? */ + if (tlb_type == cheetah) + regs->tpc += 4; -#ifdef DEBUG_PCI_POKES - prom_printf("PCI) "); - /* prom_halt(); */ -#endif - clean_and_reenable_l1_caches(); + regs->tnpc = regs->tpc + 4; return; } #endif @@ -534,6 +548,10 @@ void do_fpe_common(struct pt_regs *regs) unsigned long fsr = current->thread.xfsr[0]; siginfo_t info; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } info.si_signo = SIGFPE; info.si_errno = 0; info.si_addr = (void *)regs->tpc; @@ -589,6 +607,10 @@ void do_tof(struct pt_regs *regs) if(regs->tstate & TSTATE_PRIV) die_if_kernel("Penguin overflow trap from kernel mode", regs); + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } info.si_signo = SIGEMT; info.si_errno = 0; info.si_code = EMT_TAGOVF; @@ -601,6 +623,10 @@ void do_div0(struct pt_regs *regs) { siginfo_t info; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } info.si_signo = SIGFPE; info.si_errno = 0; info.si_code = FPE_INTDIV; @@ -700,8 +726,13 @@ void die_if_kernel(char *str, struct pt_regs *regs) (rw->ins[6] + STACK_BIAS); } instruction_dump ((unsigned int *) regs->tpc); - } else + } else { + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } user_instruction_dump ((unsigned int *) regs->tpc); + } #ifdef CONFIG_SMP smp_report_regs(); #endif @@ -765,6 +796,10 @@ void do_privop(struct pt_regs *regs) { siginfo_t info; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_PRVOPC; @@ -907,6 +942,10 @@ void do_getpsr(struct pt_regs *regs) regs->u_regs[UREG_I0] = tstate_to_psr(regs->tstate); regs->tpc = regs->tnpc; regs->tnpc += 4; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } } void trap_init(void) diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S index b1081b9fe..2f7e0e16c 100644 --- a/arch/sparc64/kernel/ttable.S +++ b/arch/sparc64/kernel/ttable.S @@ -1,4 +1,4 @@ -/* $Id: ttable.S,v 1.31 2000/05/09 17:40:14 davem Exp $ +/* $Id: ttable.S,v 1.32 2001/03/23 07:56:30 davem Exp $ * ttable.S: Sparc V9 Trap Table(s) with SpitFire extensions. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -22,7 +22,7 @@ tl0_resv018: BTRAP(0x18) BTRAP(0x19) BTRAP(0x1a) BTRAP(0x1b) BTRAP(0x1c) BTRAP(0 tl0_resv01e: BTRAP(0x1e) BTRAP(0x1f) tl0_fpdis: TRAP_NOSAVE(do_fpdis) tl0_fpieee: TRAP_SAVEFPU(do_fpieee) -tl0_fpother: TRAP_SAVEFPU(do_fpother) +tl0_fpother: TRAP_NOSAVE(do_fpother_check_fitos) tl0_tof: TRAP(do_tof) tl0_cwin: CLEAN_WINDOW tl0_div0: TRAP(do_div0) diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c index f43204c3b..7a21f0080 100644 --- a/arch/sparc64/kernel/unaligned.c +++ b/arch/sparc64/kernel/unaligned.c @@ -1,4 +1,4 @@ -/* $Id: unaligned.c,v 1.20 2000/04/29 08:05:21 anton Exp $ +/* $Id: unaligned.c,v 1.21 2001/03/21 11:46:20 davem Exp $ * unaligned.c: Unaligned load/store trap handling with special * cases for the kernel to do them more quickly. * @@ -334,6 +334,10 @@ static inline void advance(struct pt_regs *regs) { regs->tpc = regs->tnpc; regs->tnpc += 4; + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; + } } static inline int floating_point_load_or_store_p(unsigned int insn) diff --git a/arch/sparc64/lib/U3copy_in_user.S b/arch/sparc64/lib/U3copy_in_user.S index 0fc169b9d..e28d34ac0 100644 --- a/arch/sparc64/lib/U3copy_in_user.S +++ b/arch/sparc64/lib/U3copy_in_user.S @@ -1,4 +1,4 @@ -/* $Id: U3copy_in_user.S,v 1.3 2000/11/01 09:29:19 davem Exp $ +/* $Id: U3copy_in_user.S,v 1.4 2001/03/21 05:58:47 davem Exp $ * U3memcpy.S: UltraSparc-III optimized copy within userspace. * * Copyright (C) 1999, 2000 David S. Miller (davem@redhat.com) @@ -231,25 +231,25 @@ U3copy_in_user_enter: .align 64 U3copy_in_user_begin: - prefetch [%o1 + 0x000], #one_read ! MS Group1 - prefetch [%o1 + 0x040], #one_read ! MS Group2 + prefetcha [%o1 + 0x000] %asi, #one_read ! MS Group1 + prefetcha [%o1 + 0x040] %asi, #one_read ! MS Group2 andn %o2, (0x40 - 1), %o4 ! A0 - prefetch [%o1 + 0x080], #one_read ! MS Group3 + prefetcha [%o1 + 0x080] %asi, #one_read ! MS Group3 cmp %o4, 0x140 ! A0 - prefetch [%o1 + 0x0c0], #one_read ! MS Group4 + prefetcha [%o1 + 0x0c0] %asi, #one_read ! MS Group4 EX(ldda [%o1 + 0x000] %asi, %f0, add %o2, %g0) ! MS Group5 (%f0 results at G8) bge,a,pt %icc, 1f ! BR - prefetch [%o1 + 0x100], #one_read ! MS Group6 + prefetcha [%o1 + 0x100] %asi, #one_read ! MS Group6 1: EX(ldda [%o1 + 0x008] %asi, %f2, add %o2, %g0) ! AX (%f2 results at G9) cmp %o4, 0x180 ! A1 bge,a,pt %icc, 1f ! BR - prefetch [%o1 + 0x140], #one_read ! MS Group7 + prefetcha [%o1 + 0x140] %asi, #one_read ! MS Group7 1: EX(ldda [%o1 + 0x010] %asi, %f4, add %o2, %g0) ! AX (%f4 results at G10) cmp %o4, 0x1c0 ! A1 bge,a,pt %icc, 1f ! BR - prefetch [%o1 + 0x180], #one_read ! MS Group8 + prefetcha [%o1 + 0x180] %asi, #one_read ! MS Group8 1: faligndata %f0, %f2, %f16 ! FGA Group9 (%f16 at G12) EX(ldda [%o1 + 0x018] %asi, %f6, add %o2, %g0) ! AX (%f6 results at G12) faligndata %f2, %f4, %f18 ! FGA Group10 (%f18 results at G13) @@ -305,7 +305,7 @@ U3copy_in_user_loop1: faligndata %f8, %f10, %f24 ! FGA Group16 (%f24 results at G19) EXBLK1(ldda [%o1 + 0x040] %asi, %f0) ! AX (%f0 results at G19) - prefetch [%o1 + 0x180], #one_read ! MS + prefetcha [%o1 + 0x180] %asi, #one_read ! MS faligndata %f10, %f12, %f26 ! FGA Group17 (%f26 results at G20) subcc %o4, 0x40, %o4 ! A0 add %o1, 0x40, %o1 ! A1 diff --git a/arch/sparc64/lib/VISbzero.S b/arch/sparc64/lib/VISbzero.S index 610740d37..c8713995c 100644 --- a/arch/sparc64/lib/VISbzero.S +++ b/arch/sparc64/lib/VISbzero.S @@ -1,4 +1,4 @@ -/* $Id: VISbzero.S,v 1.10 1999/05/25 16:52:56 jj Exp $ +/* $Id: VISbzero.S,v 1.11 2001/03/15 08:51:24 anton Exp $ * VISbzero.S: High speed clear operations utilizing the UltraSparc * Visual Instruction Set. * @@ -83,6 +83,8 @@ .text .align 32 #ifdef __KERNEL__ + .globl __bzero_begin +__bzero_begin: .globl __bzero, __bzero_noasi __bzero_noasi: rd %asi, %g5 @@ -272,3 +274,5 @@ VISbzerofixup_zb: ba,pt %xcc, VISbzerofixup_ret0 sub %o1, %g2, %o0 #endif + .globl __bzero_end +__bzero_end: diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S index 2254ba5c5..d1b257174 100644 --- a/arch/sparc64/lib/VISsave.S +++ b/arch/sparc64/lib/VISsave.S @@ -1,4 +1,4 @@ -/* $Id: VISsave.S,v 1.4 1999/07/30 09:35:37 davem Exp $ +/* $Id: VISsave.S,v 1.5 2001/03/08 22:08:51 davem Exp $ * VISsave.S: Code for saving FPU register state for * VIS routines. One should not call this directly, * but use macros provided in <asm/visasm.h>. @@ -37,14 +37,15 @@ vis1: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3 clr %g1 ba,pt %xcc, 3f - stb %g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr] + stx %g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr] 2: add %g6, %g1, %g3 cmp %o5, FPRS_DU be,pn %icc, 6f sll %g1, 3, %g1 stb %o5, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved] rd %gsr, %g2 - stb %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr] + add %g6, %g1, %g3 + stx %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr] add %g6, %g1, %g2 stx %fsr, [%g2 + AOFF_task_thread + AOFF_thread_xfsr] @@ -106,7 +107,8 @@ VISenterhalf: stb %g2, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved] rd %gsr, %g2 - stb %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr] + add %g6, %g1, %g3 + stx %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr] add %g6, %g1, %g2 stx %fsr, [%g2 + AOFF_task_thread + AOFF_thread_xfsr] sll %g1, 5, %g1 diff --git a/arch/sparc64/lib/blockops.S b/arch/sparc64/lib/blockops.S index 8d2b749e1..006ab5228 100644 --- a/arch/sparc64/lib/blockops.S +++ b/arch/sparc64/lib/blockops.S @@ -1,4 +1,4 @@ -/* $Id: blockops.S,v 1.27 2000/07/14 01:12:49 davem Exp $ +/* $Id: blockops.S,v 1.30 2001/03/22 13:10:10 davem Exp $ * blockops.S: UltraSparc block zero optimized routines. * * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com) @@ -83,6 +83,8 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ or %g2, %g3, %g2 add %o0, %o3, %o0 add %o0, %o1, %o1 +#define FIX_INSN_1 0x96102068 /* mov (13 << 3), %o3 */ +cheetah_patch_1: mov TLBTEMP_ENT1, %o3 rdpr %pstate, %g3 wrpr %g3, PSTATE_IE, %pstate @@ -96,16 +98,14 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ /* Spitfire Errata #32 workaround */ mov 0x8, %o4 stxa %g0, [%o4] ASI_DMMU - sethi %hi(empty_zero_page), %o4 - flush %o4 + membar #Sync ldxa [%o3] ASI_DTLB_TAG_READ, %o4 /* Spitfire Errata #32 workaround */ mov 0x8, %o5 stxa %g0, [%o5] ASI_DMMU - sethi %hi(empty_zero_page), %o5 - flush %o5 + membar #Sync ldxa [%o3] ASI_DTLB_DATA_ACCESS, %o5 stxa %o0, [%o2] ASI_DMMU @@ -116,16 +116,14 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ /* Spitfire Errata #32 workaround */ mov 0x8, %g5 stxa %g0, [%g5] ASI_DMMU - sethi %hi(empty_zero_page), %g5 - flush %g5 + membar #Sync ldxa [%o3] ASI_DTLB_TAG_READ, %g5 /* Spitfire Errata #32 workaround */ mov 0x8, %g7 stxa %g0, [%g7] ASI_DMMU - sethi %hi(empty_zero_page), %g7 - flush %g7 + membar #Sync ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g7 stxa %o1, [%o2] ASI_DMMU @@ -136,6 +134,107 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ bne,pn %xcc, copy_page_using_blkcommit nop + rdpr %ver, %g3 + sllx %g3, 16, %g3 + srlx %g3, 32 + 16, %g3 + cmp %g3, 0x14 + bne,pt %icc, spitfire_copy_user_page + nop + +cheetah_copy_user_page: + mov 121, %o2 ! A0 Group + prefetch [%o1 + 0x000], #one_read ! MS + prefetch [%o1 + 0x040], #one_read ! MS Group + prefetch [%o1 + 0x080], #one_read ! MS Group + prefetch [%o1 + 0x0c0], #one_read ! MS Group + ldd [%o1 + 0x000], %f0 ! MS Group + prefetch [%o1 + 0x100], #one_read ! MS Group + ldd [%o1 + 0x008], %f2 ! AX + prefetch [%o1 + 0x140], #one_read ! MS Group + ldd [%o1 + 0x010], %f4 ! AX + prefetch [%o1 + 0x180], #one_read ! MS Group + fmovd %f0, %f32 ! FGA Group + ldd [%o1 + 0x018], %f6 ! AX + fmovd %f2, %f34 ! FGA Group + ldd [%o1 + 0x020], %f8 ! MS + fmovd %f4, %f36 ! FGA Group + ldd [%o1 + 0x028], %f10 ! AX + membar #StoreStore ! MS + fmovd %f6, %f38 ! FGA Group + ldd [%o1 + 0x030], %f12 ! MS + fmovd %f8, %f40 ! FGA Group + ldd [%o1 + 0x038], %f14 ! AX + fmovd %f10, %f42 ! FGA Group + ldd [%o1 + 0x040], %f16 ! MS +1: ldd [%o1 + 0x048], %f2 ! AX (Group) + fmovd %f12, %f44 ! FGA + ldd [%o1 + 0x050], %f4 ! MS + fmovd %f14, %f46 ! FGA Group + stda %f32, [%o0] ASI_BLK_P ! MS + ldd [%o1 + 0x058], %f6 ! AX + fmovd %f16, %f32 ! FGA Group (8-cycle stall) + ldd [%o1 + 0x060], %f8 ! MS + fmovd %f2, %f34 ! FGA Group + ldd [%o1 + 0x068], %f10 ! AX + fmovd %f4, %f36 ! FGA Group + ldd [%o1 + 0x070], %f12 ! MS + fmovd %f6, %f38 ! FGA Group + ldd [%o1 + 0x078], %f14 ! AX + fmovd %f8, %f40 ! FGA Group + ldd [%o1 + 0x080], %f16 ! AX + prefetch [%o1 + 0x180], #one_read ! MS + fmovd %f10, %f42 ! FGA Group + subcc %o2, 1, %o2 ! A0 + add %o0, 0x40, %o0 ! A1 + bne,pt %xcc, 1b ! BR + add %o1, 0x40, %o1 ! A0 Group + + mov 5, %o2 ! A0 Group +1: ldd [%o1 + 0x048], %f2 ! AX + fmovd %f12, %f44 ! FGA + ldd [%o1 + 0x050], %f4 ! MS + fmovd %f14, %f46 ! FGA Group + stda %f32, [%o0] ASI_BLK_P ! MS + ldd [%o1 + 0x058], %f6 ! AX + fmovd %f16, %f32 ! FGA Group (8-cycle stall) + ldd [%o1 + 0x060], %f8 ! MS + fmovd %f2, %f34 ! FGA Group + ldd [%o1 + 0x068], %f10 ! AX + fmovd %f4, %f36 ! FGA Group + ldd [%o1 + 0x070], %f12 ! MS + fmovd %f6, %f38 ! FGA Group + ldd [%o1 + 0x078], %f14 ! AX + fmovd %f8, %f40 ! FGA Group + ldd [%o1 + 0x080], %f16 ! MS + fmovd %f10, %f42 ! FGA Group + subcc %o2, 1, %o2 ! A0 + add %o0, 0x40, %o0 ! A1 + bne,pt %xcc, 1b ! BR + add %o1, 0x40, %o1 ! A0 Group + + ldd [%o1 + 0x048], %f2 ! AX + fmovd %f12, %f44 ! FGA + ldd [%o1 + 0x050], %f4 ! MS + fmovd %f14, %f46 ! FGA Group + stda %f32, [%o0] ASI_BLK_P ! MS + ldd [%o1 + 0x058], %f6 ! AX + fmovd %f16, %f32 ! FGA Group (8-cycle stall) + ldd [%o1 + 0x060], %f8 ! MS + fmovd %f2, %f34 ! FGA Group + ldd [%o1 + 0x068], %f10 ! AX + fmovd %f4, %f36 ! FGA Group + ldd [%o1 + 0x070], %f12 ! MS + fmovd %f6, %f38 ! FGA Group + add %o0, 0x40, %o0 ! A0 + ldd [%o1 + 0x078], %f14 ! AX + fmovd %f8, %f40 ! FGA Group + fmovd %f10, %f42 ! FGA Group + fmovd %f12, %f44 ! FGA Group + fmovd %f14, %f46 ! FGA Group + stda %f32, [%o0] ASI_BLK_P ! MS + ba,a,pt %xcc, copy_user_page_continue + +spitfire_copy_user_page: ldda [%o1] ASI_BLK_P, %f0 add %o1, 0x40, %o1 ldda [%o1] ASI_BLK_P, %f16 @@ -237,6 +336,8 @@ clear_user_page: /* %o0=dest, %o1=vaddr */ or %g3, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), %g3 or %g1, %g3, %g1 add %o0, %o3, %o0 +#define FIX_INSN_2 0x96102070 /* mov (14 << 3), %o3 */ +cheetah_patch_2: mov TLBTEMP_ENT2, %o3 rdpr %pstate, %g3 wrpr %g3, PSTATE_IE, %pstate @@ -244,16 +345,14 @@ clear_user_page: /* %o0=dest, %o1=vaddr */ /* Spitfire Errata #32 workaround */ mov 0x8, %g5 stxa %g0, [%g5] ASI_DMMU - sethi %hi(empty_zero_page), %g5 - flush %g5 + membar #Sync ldxa [%o3] ASI_DTLB_TAG_READ, %g5 /* Spitfire Errata #32 workaround */ mov 0x8, %g7 stxa %g0, [%g7] ASI_DMMU - sethi %hi(empty_zero_page), %g7 - flush %g7 + membar #Sync ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g7 stxa %o0, [%o2] ASI_DMMU @@ -299,3 +398,24 @@ clear_page_common: membar #Sync jmpl %o7 + 0x8, %g0 wrpr %g3, 0x0, %pstate + + /* We will write cheetah optimized versions later. */ + .globl cheetah_patch_pgcopyops +cheetah_patch_pgcopyops: + sethi %hi(FIX_INSN_1), %g1 + or %g1, %lo(FIX_INSN_1), %g1 + sethi %hi(cheetah_patch_1), %g2 + or %g2, %lo(cheetah_patch_1), %g2 + stw %g1, [%g2] + flush %g2 + sethi %hi(FIX_INSN_2), %g1 + or %g1, %lo(FIX_INSN_2), %g1 + sethi %hi(cheetah_patch_2), %g2 + or %g2, %lo(cheetah_patch_2), %g2 + stw %g1, [%g2] + flush %g2 + retl + nop + +#undef FIX_INSN1 +#undef FIX_INSN2 diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 12006b58a..f161898c0 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.51 2000/09/14 06:22:32 anton Exp $ +/* $Id: fault.c,v 1.54 2001/03/24 09:36:11 davem Exp $ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -142,7 +142,7 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, { unsigned long g2; unsigned char asi = ASI_P; - + if (!insn) { if (regs->tstate & TSTATE_PRIV) { if (!regs->tpc || (regs->tpc & 0x3)) @@ -234,7 +234,12 @@ asmlinkage void do_sparc64_fault(struct pt_regs *regs) if (in_interrupt() || !mm) goto handle_kernel_fault; - down(&mm->mmap_sem); + if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs->tpc &= 0xffffffff; + address &= 0xffffffff; + } + + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) goto bad_area; @@ -286,7 +291,12 @@ good_area: if (fault_code & FAULT_CODE_WRITE) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; - if ((vma->vm_flags & VM_EXEC) != 0 && + + /* Spitfire has an icache which does not snoop + * processor stores. Later processors do... + */ + if (tlb_type == spitfire && + (vma->vm_flags & VM_EXEC) != 0 && vma->vm_file != NULL) current->thread.use_blkcommit = 1; } else { @@ -308,7 +318,7 @@ good_area: goto out_of_memory; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); goto fault_done; /* @@ -316,7 +326,7 @@ good_area: * Fix it, but check if it's kernel or user first.. */ bad_area: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); handle_kernel_fault: do_kernel_fault(regs, si_code, fault_code, insn, address); @@ -328,14 +338,14 @@ handle_kernel_fault: * us unable to handle the page fault gracefully. */ out_of_memory: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); printk("VM: killing process %s\n", current->comm); if (!(regs->tstate & TSTATE_PRIV)) do_exit(SIGKILL); goto handle_kernel_fault; do_sigbus: - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); /* * Send a sigbus, regardless of whether we were in kernel diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c index 68b77cfab..954c4b493 100644 --- a/arch/sparc64/mm/generic.c +++ b/arch/sparc64/mm/generic.c @@ -1,4 +1,4 @@ -/* $Id: generic.c,v 1.14 2000/08/09 00:00:15 davem Exp $ +/* $Id: generic.c,v 1.16 2001/03/25 04:40:05 davem Exp $ * generic.c: Generic Sparc mm routines that are not dependent upon * MMU type but are Sparc specific. * @@ -104,12 +104,10 @@ static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigne end = PGDIR_SIZE; offset -= address; do { - pte_t * pte = pte_alloc(pmd, address); + pte_t * pte = pte_alloc(current->mm, pmd, address); if (!pte) return -ENOMEM; - spin_lock(¤t->mm->page_table_lock); io_remap_pte_range(pte, address, end - address, address + offset, prot, space); - spin_unlock(¤t->mm->page_table_lock); address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address < end); @@ -122,13 +120,16 @@ int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long pgd_t * dir; unsigned long beg = from; unsigned long end = from + size; + struct mm_struct *mm = current->mm; prot = __pgprot(pg_iobits); offset -= from; - dir = pgd_offset(current->mm, from); - flush_cache_range(current->mm, beg, end); + dir = pgd_offset(mm, from); + flush_cache_range(mm, beg, end); + + spin_lock(&mm->page_table_lock); while (from < end) { - pmd_t *pmd = pmd_alloc(dir, from); + pmd_t *pmd = pmd_alloc(current->mm, dir, from); error = -ENOMEM; if (!pmd) break; @@ -138,6 +139,8 @@ int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long from = (from + PGDIR_SIZE) & PGDIR_MASK; dir++; } + spin_unlock(&mm->page_table_lock); + flush_tlb_range(current->mm, beg, end); return error; } diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 15407f4f4..a4cc8ad81 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.162 2001/02/13 01:16:44 davem Exp $ +/* $Id: init.c,v 1.172 2001/03/24 09:36:01 davem Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -40,6 +40,8 @@ unsigned long *sparc64_valid_addr_bitmap; /* Ugly, but necessary... -DaveM */ unsigned long phys_base; +enum ultra_tlb_layout tlb_type = spitfire; + /* get_new_mmu_context() uses "cache + 1". */ spinlock_t ctx_alloc_lock = SPIN_LOCK_UNLOCKED; unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1; @@ -57,17 +59,17 @@ int do_check_pgt_cache(int low, int high) { int freed = 0; - if(pgtable_cache_size > high) { + if (pgtable_cache_size > high) { do { #ifdef CONFIG_SMP - if(pgd_quicklist) + if (pgd_quicklist) free_pgd_slow(get_pgd_fast()), freed++; #endif - if(pte_quicklist[0]) - free_pte_slow(get_pte_fast(0)), freed++; - if(pte_quicklist[1]) - free_pte_slow(get_pte_fast(1)), freed++; - } while(pgtable_cache_size > low); + if (pte_quicklist[0]) + free_pte_slow(pte_alloc_one_fast(NULL, 0)), freed++; + if (pte_quicklist[1]) + free_pte_slow(pte_alloc_one_fast(NULL, 1 << (PAGE_SHIFT + 10))), freed++; + } while (pgtable_cache_size > low); } #ifndef CONFIG_SMP if (pgd_cache_size > high / 4) { @@ -107,7 +109,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p if (VALID_PAGE(page) && page->mapping && test_bit(PG_dcache_dirty, &page->flags)) { - __flush_dcache_page(page->virtual, 1); + __flush_dcache_page(page->virtual, + (tlb_type == spitfire)); clear_bit(PG_dcache_dirty, &page->flags); } __update_mmu_cache(vma, address, pte); @@ -118,10 +121,13 @@ extern void __flush_icache_page(unsigned long); void flush_icache_range(unsigned long start, unsigned long end) { - unsigned long kaddr; + /* Cheetah has coherent I-cache. */ + if (tlb_type == spitfire) { + unsigned long kaddr; - for (kaddr = start; kaddr < end; kaddr += PAGE_SIZE) - __flush_icache_page(__get_phys(kaddr)); + for (kaddr = start; kaddr < end; kaddr += PAGE_SIZE) + __flush_icache_page(__get_phys(kaddr)); + } } /* @@ -163,13 +169,12 @@ void show_mem(void) int mmu_info(char *buf) { - /* We'll do the rest later to make it nice... -DaveM */ -#if 0 - if (this_is_cheetah) - sprintf(buf, "MMU Type\t: One bad ass cpu\n"); + if (tlb_type == cheetah) + return sprintf(buf, "MMU Type\t: Cheetah\n"); + else if (tlb_type == spitfire) + return sprintf(buf, "MMU Type\t: Spitfire\n"); else -#endif - return sprintf(buf, "MMU Type\t: Spitfire\n"); + return sprintf(buf, "MMU Type\t: ???\n"); } struct linux_prom_translation { @@ -231,6 +236,8 @@ static void inherit_prom_mappings(void) for (vaddr = trans[i].virt; vaddr < trans[i].virt + trans[i].size; vaddr += PAGE_SIZE) { + unsigned long val; + pgdp = pgd_offset(&init_mm, vaddr); if (pgd_none(*pgdp)) { pmdp = __alloc_bootmem(PMD_TABLE_SIZE, @@ -252,7 +259,14 @@ static void inherit_prom_mappings(void) pmd_set(pmdp, ptep); } ptep = pte_offset(pmdp, vaddr); - set_pte (ptep, __pte(trans[i].data | _PAGE_MODIFIED)); + + val = trans[i].data; + + /* Clear diag TTE bits. */ + if (tlb_type == spitfire) + val &= ~0x0003fe0000000000UL; + + set_pte (ptep, __pte(val | _PAGE_MODIFIED)); trans[i].data += PAGE_SIZE; } } @@ -268,26 +282,59 @@ static void inherit_prom_mappings(void) : "r" (0), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); - phys_page = spitfire_get_dtlb_data(63) & _PAGE_PADDR; + switch (tlb_type) { + default: + case spitfire: + phys_page = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()); + break; + + case cheetah: + phys_page = cheetah_get_litlb_data(sparc64_highest_locked_tlbent()); + break; + }; + + phys_page &= _PAGE_PADDR; phys_page += ((unsigned long)&prom_boot_page - (unsigned long)&empty_zero_page); - /* Lock this into i/d tlb entry 59 */ - __asm__ __volatile__( - "stxa %%g0, [%2] %3\n\t" - "stxa %0, [%1] %4\n\t" - "membar #Sync\n\t" - "flush %%g6\n\t" - "stxa %%g0, [%2] %5\n\t" - "stxa %0, [%1] %6\n\t" - "membar #Sync\n\t" - "flush %%g6" - : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP | - _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), - "r" (59 << 3), "r" (TLB_TAG_ACCESS), - "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), - "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS) - : "memory"); + if (tlb_type == spitfire) { + /* Lock this into i/d tlb entry 59 */ + __asm__ __volatile__( + "stxa %%g0, [%2] %3\n\t" + "stxa %0, [%1] %4\n\t" + "membar #Sync\n\t" + "flush %%g6\n\t" + "stxa %%g0, [%2] %5\n\t" + "stxa %0, [%1] %6\n\t" + "membar #Sync\n\t" + "flush %%g6" + : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP | + _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), + "r" (59 << 3), "r" (TLB_TAG_ACCESS), + "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), + "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS) + : "memory"); + } else if (tlb_type == cheetah) { + /* Lock this into i/d tlb-0 entry 11 */ + __asm__ __volatile__( + "stxa %%g0, [%2] %3\n\t" + "stxa %0, [%1] %4\n\t" + "membar #Sync\n\t" + "flush %%g6\n\t" + "stxa %%g0, [%2] %5\n\t" + "stxa %0, [%1] %6\n\t" + "membar #Sync\n\t" + "flush %%g6" + : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP | + _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), + "r" ((0 << 16) | (11 << 3)), "r" (TLB_TAG_ACCESS), + "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), + "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS) + : "memory"); + } else { + /* Implement me :-) */ + BUG(); + } tte_vaddr = (unsigned long) &empty_zero_page; @@ -298,7 +345,12 @@ static void inherit_prom_mappings(void) : "r" (0), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); - kern_locked_tte_data = tte_data = spitfire_get_dtlb_data(63); + if (tlb_type == spitfire) + tte_data = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()); + else + tte_data = cheetah_get_ldtlb_data(sparc64_highest_locked_tlbent()); + + kern_locked_tte_data = tte_data; remap_func = (void *) ((unsigned long) &prom_remap - (unsigned long) &prom_boot_page); @@ -311,7 +363,9 @@ static void inherit_prom_mappings(void) : "r" (0), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); - remap_func(spitfire_get_dtlb_data(63) & _PAGE_PADDR, + remap_func((tlb_type == spitfire ? + (spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR) : + (cheetah_get_litlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR)), (unsigned long) &empty_zero_page, prom_get_mmu_ihandle()); @@ -320,8 +374,8 @@ static void inherit_prom_mappings(void) spitfire_flush_itlb_nucleus_page(0x0); /* Now lock us back into the TLBs via OBP. */ - prom_dtlb_load(63, tte_data, tte_vaddr); - prom_itlb_load(63, tte_data, tte_vaddr); + prom_dtlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr); + prom_itlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr); /* Re-read translations property. */ if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) { @@ -372,26 +426,43 @@ static void __flush_nucleus_vptes(void) int i; /* Only DTLB must be checked for VPTE entries. */ - for(i = 0; i < 63; i++) { - unsigned long tag; - - /* Spitfire Errata #32 workaround */ - __asm__ __volatile__("stxa %0, [%1] %2\n\t" - "flush %%g6" - : /* No outputs */ - : "r" (0), - "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); - - tag = spitfire_get_dtlb_tag(i); - if(((tag & ~(PAGE_MASK)) == 0) && - ((tag & (PAGE_MASK)) >= prom_reserved_base)) { - __asm__ __volatile__("stxa %%g0, [%0] %1" - : /* no outputs */ - : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); - membar("#Sync"); - spitfire_put_dtlb_data(i, 0x0UL); - membar("#Sync"); + if (tlb_type == spitfire) { + for (i = 0; i < 63; i++) { + unsigned long tag; + + /* Spitfire Errata #32 workaround */ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "flush %%g6" + : /* No outputs */ + : "r" (0), + "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); + + tag = spitfire_get_dtlb_tag(i); + if (((tag & ~(PAGE_MASK)) == 0) && + ((tag & (PAGE_MASK)) >= prom_reserved_base)) { + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* no outputs */ + : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); + spitfire_put_dtlb_data(i, 0x0UL); + } } + } else if (tlb_type == cheetah) { + for (i = 0; i < 512; i++) { + unsigned long tag = cheetah_get_dtlb_tag(i); + + if ((tag & ~PAGE_MASK) == 0 && + (tag & PAGE_MASK) >= prom_reserved_base) { + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* no outputs */ + : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); + cheetah_put_dtlb_data(i, 0x0UL); + } + } + } else { + /* Implement me :-) */ + BUG(); } } @@ -401,7 +472,7 @@ struct prom_tlb_entry { unsigned long tlb_tag; unsigned long tlb_data; }; -struct prom_tlb_entry prom_itlb[8], prom_dtlb[8]; +struct prom_tlb_entry prom_itlb[16], prom_dtlb[16]; void prom_world(int enter) { @@ -426,42 +497,53 @@ void prom_world(int enter) __flush_nucleus_vptes(); /* Install PROM world. */ - for (i = 0; i < 8; i++) { + for (i = 0; i < 16; i++) { if (prom_dtlb[i].tlb_ent != -1) { - __asm__ __volatile__("stxa %0, [%1] %2" + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" : : "r" (prom_dtlb[i].tlb_tag), "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); - membar("#Sync"); - spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, - prom_dtlb[i].tlb_data); - membar("#Sync"); + if (tlb_type == spitfire) + spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, + prom_dtlb[i].tlb_data); + else if (tlb_type == cheetah) + cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent, + prom_dtlb[i].tlb_data); } - if (prom_itlb[i].tlb_ent != -1) { - __asm__ __volatile__("stxa %0, [%1] %2" - : : "r" (prom_itlb[i].tlb_tag), "r" (TLB_TAG_ACCESS), - "i" (ASI_IMMU)); - membar("#Sync"); - spitfire_put_itlb_data(prom_itlb[i].tlb_ent, - prom_itlb[i].tlb_data); - membar("#Sync"); + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : : "r" (prom_itlb[i].tlb_tag), + "r" (TLB_TAG_ACCESS), + "i" (ASI_IMMU)); + if (tlb_type == spitfire) + spitfire_put_itlb_data(prom_itlb[i].tlb_ent, + prom_itlb[i].tlb_data); + else if (tlb_type == cheetah) + cheetah_put_litlb_data(prom_itlb[i].tlb_ent, + prom_itlb[i].tlb_data); } } } else { - for (i = 0; i < 8; i++) { + for (i = 0; i < 16; i++) { if (prom_dtlb[i].tlb_ent != -1) { - __asm__ __volatile__("stxa %%g0, [%0] %1" + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); - membar("#Sync"); - spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, 0x0UL); - membar("#Sync"); + if (tlb_type == spitfire) + spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, 0x0UL); + else + cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent, 0x0UL); } if (prom_itlb[i].tlb_ent != -1) { - __asm__ __volatile__("stxa %%g0, [%0] %1" - : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU)); - membar("#Sync"); - spitfire_put_itlb_data(prom_itlb[i].tlb_ent, 0x0UL); - membar("#Sync"); + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : : "r" (TLB_TAG_ACCESS), + "i" (ASI_IMMU)); + if (tlb_type == spitfire) + spitfire_put_itlb_data(prom_itlb[i].tlb_ent, 0x0UL); + else + cheetah_put_litlb_data(prom_itlb[i].tlb_ent, 0x0UL); } } } @@ -490,25 +572,14 @@ void inherit_locked_prom_mappings(int save_p) * UNDOCUMENTED!!!!!! Thanks S(t)un! */ if (save_p) { - for(i = 0; i < 8; i++) { - prom_dtlb[i].tlb_ent = -1; + for (i = 0; i < 16; i++) { prom_itlb[i].tlb_ent = -1; + prom_dtlb[i].tlb_ent = -1; } } - for(i = 0; i < 63; i++) { - unsigned long data; - - - /* Spitfire Errata #32 workaround */ - __asm__ __volatile__("stxa %0, [%1] %2\n\t" - "flush %%g6" - : /* No outputs */ - : "r" (0), - "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); - - data = spitfire_get_dtlb_data(i); - if((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) { - unsigned long tag; + if (tlb_type == spitfire) { + for (i = 0; i < SPITFIRE_HIGHEST_LOCKED_TLBENT; i++) { + unsigned long data; /* Spitfire Errata #32 workaround */ __asm__ __volatile__("stxa %0, [%1] %2\n\t" @@ -517,36 +588,36 @@ void inherit_locked_prom_mappings(int save_p) : "r" (0), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); - tag = spitfire_get_dtlb_tag(i); - if(save_p) { - prom_dtlb[dtlb_seen].tlb_ent = i; - prom_dtlb[dtlb_seen].tlb_tag = tag; - prom_dtlb[dtlb_seen].tlb_data = data; + data = spitfire_get_dtlb_data(i); + if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) { + unsigned long tag; + + /* Spitfire Errata #32 workaround */ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "flush %%g6" + : /* No outputs */ + : "r" (0), + "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); + + tag = spitfire_get_dtlb_tag(i); + if (save_p) { + prom_dtlb[dtlb_seen].tlb_ent = i; + prom_dtlb[dtlb_seen].tlb_tag = tag; + prom_dtlb[dtlb_seen].tlb_data = data; + } + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); + spitfire_put_dtlb_data(i, 0x0UL); + + dtlb_seen++; + if (dtlb_seen > 15) + break; } - __asm__ __volatile__("stxa %%g0, [%0] %1" - : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); - membar("#Sync"); - spitfire_put_dtlb_data(i, 0x0UL); - membar("#Sync"); - - dtlb_seen++; - if(dtlb_seen > 7) - break; } - } - for(i = 0; i < 63; i++) { - unsigned long data; - - /* Spitfire Errata #32 workaround */ - __asm__ __volatile__("stxa %0, [%1] %2\n\t" - "flush %%g6" - : /* No outputs */ - : "r" (0), - "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); - - data = spitfire_get_itlb_data(i); - if((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) { - unsigned long tag; + + for (i = 0; i < SPITFIRE_HIGHEST_LOCKED_TLBENT; i++) { + unsigned long data; /* Spitfire Errata #32 workaround */ __asm__ __volatile__("stxa %0, [%1] %2\n\t" @@ -555,22 +626,84 @@ void inherit_locked_prom_mappings(int save_p) : "r" (0), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); - tag = spitfire_get_itlb_tag(i); - if(save_p) { - prom_itlb[itlb_seen].tlb_ent = i; - prom_itlb[itlb_seen].tlb_tag = tag; - prom_itlb[itlb_seen].tlb_data = data; + data = spitfire_get_itlb_data(i); + if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) { + unsigned long tag; + + /* Spitfire Errata #32 workaround */ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "flush %%g6" + : /* No outputs */ + : "r" (0), + "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); + + tag = spitfire_get_itlb_tag(i); + if (save_p) { + prom_itlb[itlb_seen].tlb_ent = i; + prom_itlb[itlb_seen].tlb_tag = tag; + prom_itlb[itlb_seen].tlb_data = data; + } + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU)); + spitfire_put_itlb_data(i, 0x0UL); + + itlb_seen++; + if (itlb_seen > 15) + break; + } + } + } else if (tlb_type == cheetah) { + for (i = 0; i < CHEETAH_HIGHEST_LOCKED_TLBENT; i++) { + unsigned long data; + + data = cheetah_get_ldtlb_data(i); + if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) { + unsigned long tag; + + tag = cheetah_get_ldtlb_tag(i); + if (save_p) { + prom_dtlb[dtlb_seen].tlb_ent = i; + prom_dtlb[dtlb_seen].tlb_tag = tag; + prom_dtlb[dtlb_seen].tlb_data = data; + } + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); + cheetah_put_ldtlb_data(i, 0x0UL); + + dtlb_seen++; + if (dtlb_seen > 15) + break; } - __asm__ __volatile__("stxa %%g0, [%0] %1" - : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU)); - membar("#Sync"); - spitfire_put_itlb_data(i, 0x0UL); - membar("#Sync"); - - itlb_seen++; - if(itlb_seen > 7) - break; } + + for (i = 0; i < CHEETAH_HIGHEST_LOCKED_TLBENT; i++) { + unsigned long data; + + data = cheetah_get_litlb_data(i); + if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) { + unsigned long tag; + + tag = cheetah_get_litlb_tag(i); + if (save_p) { + prom_itlb[itlb_seen].tlb_ent = i; + prom_itlb[itlb_seen].tlb_tag = tag; + prom_itlb[itlb_seen].tlb_data = data; + } + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU)); + cheetah_put_litlb_data(i, 0x0UL); + + itlb_seen++; + if (itlb_seen > 15) + break; + } + } + } else { + /* Implement me :-) */ + BUG(); } if (save_p) prom_ditlb_set = 1; @@ -581,25 +714,32 @@ void prom_reload_locked(void) { int i; - for (i = 0; i < 8; i++) { + for (i = 0; i < 16; i++) { if (prom_dtlb[i].tlb_ent != -1) { - __asm__ __volatile__("stxa %0, [%1] %2" + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" : : "r" (prom_dtlb[i].tlb_tag), "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); - membar("#Sync"); - spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, - prom_dtlb[i].tlb_data); - membar("#Sync"); + if (tlb_type == spitfire) + spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, + prom_dtlb[i].tlb_data); + else if (tlb_type == cheetah) + cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent, + prom_dtlb[i].tlb_data); } if (prom_itlb[i].tlb_ent != -1) { - __asm__ __volatile__("stxa %0, [%1] %2" - : : "r" (prom_itlb[i].tlb_tag), "r" (TLB_TAG_ACCESS), - "i" (ASI_IMMU)); - membar("#Sync"); - spitfire_put_itlb_data(prom_itlb[i].tlb_ent, - prom_itlb[i].tlb_data); - membar("#Sync"); + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "membar #Sync" + : : "r" (prom_itlb[i].tlb_tag), + "r" (TLB_TAG_ACCESS), + "i" (ASI_IMMU)); + if (tlb_type == spitfire) + spitfire_put_itlb_data(prom_itlb[i].tlb_ent, + prom_itlb[i].tlb_data); + else + cheetah_put_litlb_data(prom_itlb[i].tlb_ent, + prom_itlb[i].tlb_data); } } } @@ -607,22 +747,38 @@ void prom_reload_locked(void) void __flush_dcache_range(unsigned long start, unsigned long end) { unsigned long va; - int n = 0; - for (va = start; va < end; va += 32) { - spitfire_put_dcache_tag(va & 0x3fe0, 0x0); - if (++n >= 512) - break; + if (tlb_type == spitfire) { + int n = 0; + + for (va = start; va < end; va += 32) { + spitfire_put_dcache_tag(va & 0x3fe0, 0x0); + if (++n >= 512) + break; + } + } else { + start = __pa(start); + end = __pa(end); + for (va = start; va < end; va += 32) + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* no outputs */ + : "r" (va), + "i" (ASI_DCACHE_INVALIDATE)); } } void __flush_cache_all(void) { - unsigned long va; - - flushw_all(); - for(va = 0; va < (PAGE_SIZE << 1); va += 32) - spitfire_put_icache_tag(va, 0x0); + /* Cheetah should be fine here too. */ + if (tlb_type == spitfire) { + unsigned long va; + + flushw_all(); + for (va = 0; va < (PAGE_SIZE << 1); va += 32) + spitfire_put_icache_tag(va, 0x0); + __asm__ __volatile__("flush %g6"); + } } /* If not locked, zap it. */ @@ -636,38 +792,41 @@ void __flush_tlb_all(void) "wrpr %0, %1, %%pstate" : "=r" (pstate) : "i" (PSTATE_IE)); - for(i = 0; i < 64; i++) { - /* Spitfire Errata #32 workaround */ - __asm__ __volatile__("stxa %0, [%1] %2\n\t" - "flush %%g6" - : /* No outputs */ - : "r" (0), - "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); - - if(!(spitfire_get_dtlb_data(i) & _PAGE_L)) { - __asm__ __volatile__("stxa %%g0, [%0] %1" - : /* no outputs */ - : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); - membar("#Sync"); - spitfire_put_dtlb_data(i, 0x0UL); - membar("#Sync"); - } + if (tlb_type == spitfire) { + for (i = 0; i < 64; i++) { + /* Spitfire Errata #32 workaround */ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "flush %%g6" + : /* No outputs */ + : "r" (0), + "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); - /* Spitfire Errata #32 workaround */ - __asm__ __volatile__("stxa %0, [%1] %2\n\t" - "flush %%g6" - : /* No outputs */ - : "r" (0), - "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); + if (!(spitfire_get_dtlb_data(i) & _PAGE_L)) { + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* no outputs */ + : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); + spitfire_put_dtlb_data(i, 0x0UL); + } - if(!(spitfire_get_itlb_data(i) & _PAGE_L)) { - __asm__ __volatile__("stxa %%g0, [%0] %1" - : /* no outputs */ - : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU)); - membar("#Sync"); - spitfire_put_itlb_data(i, 0x0UL); - membar("#Sync"); + /* Spitfire Errata #32 workaround */ + __asm__ __volatile__("stxa %0, [%1] %2\n\t" + "flush %%g6" + : /* No outputs */ + : "r" (0), + "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); + + if (!(spitfire_get_itlb_data(i) & _PAGE_L)) { + __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" + "membar #Sync" + : /* no outputs */ + : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU)); + spitfire_put_itlb_data(i, 0x0UL); + } } + } else if (tlb_type == cheetah) { + cheetah_flush_dtlb_all(); + cheetah_flush_itlb_all(); } __asm__ __volatile__("wrpr %0, 0, %%pstate" : : "r" (pstate)); @@ -709,7 +868,7 @@ void get_new_mmu_context(struct mm_struct *mm) mmu_context_bmap[1] = 0; mmu_context_bmap[2] = 0; mmu_context_bmap[3] = 0; - for(i = 4; i < CTX_BMAP_SLOTS; i += 4) { + for (i = 4; i < CTX_BMAP_SLOTS; i += 4) { mmu_context_bmap[i + 0] = 0; mmu_context_bmap[i + 1] = 0; mmu_context_bmap[i + 2] = 0; @@ -731,23 +890,6 @@ out: struct pgtable_cache_struct pgt_quicklists; #endif -/* For PMDs we don't care about the color, writes are - * only done via Dcache which is write-thru, so non-Dcache - * reads will always see correct data. - */ -pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset) -{ - pmd_t *pmd; - - pmd = (pmd_t *) __get_free_page(GFP_KERNEL); - if(pmd) { - memset(pmd, 0, PAGE_SIZE); - pgd_set(pgd, pmd); - return pmd + offset; - } - return NULL; -} - /* OK, we have to color these pages because during DTLB * protection faults we set the dirty bit via a non-Dcache * enabled mapping in the VPTE area. The kernel can end @@ -762,9 +904,10 @@ pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset) * 3) Process faults back in the page, the old pre-dirtied copy * is provided and here is the corruption. */ -pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset, unsigned long color) +pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) { struct page *page = alloc_pages(GFP_KERNEL, 1); + unsigned long color = ((address >> (PAGE_SHIFT + 10)) & 1UL); if (page) { unsigned long *to_free; @@ -788,8 +931,7 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset, unsigned long color) pte_quicklist[color ^ 0x1] = to_free; pgtable_cache_size++; - pmd_set(pmd, pte); - return pte + offset; + return pte; } return NULL; } @@ -798,31 +940,77 @@ void sparc_ultra_dump_itlb(void) { int slot; - printk ("Contents of itlb: "); - for (slot = 0; slot < 14; slot++) printk (" "); - printk ("%2x:%016lx,%016lx\n", 0, spitfire_get_itlb_tag(0), spitfire_get_itlb_data(0)); - for (slot = 1; slot < 64; slot+=3) { - printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx %2x:%016lx,%016lx\n", - slot, spitfire_get_itlb_tag(slot), spitfire_get_itlb_data(slot), - slot+1, spitfire_get_itlb_tag(slot+1), spitfire_get_itlb_data(slot+1), - slot+2, spitfire_get_itlb_tag(slot+2), spitfire_get_itlb_data(slot+2)); - } + if (tlb_type == spitfire) { + printk ("Contents of itlb: "); + for (slot = 0; slot < 14; slot++) printk (" "); + printk ("%2x:%016lx,%016lx\n", + 0, + spitfire_get_itlb_tag(0), spitfire_get_itlb_data(0)); + for (slot = 1; slot < 64; slot+=3) { + printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx %2x:%016lx,%016lx\n", + slot, + spitfire_get_itlb_tag(slot), spitfire_get_itlb_data(slot), + slot+1, + spitfire_get_itlb_tag(slot+1), spitfire_get_itlb_data(slot+1), + slot+2, + spitfire_get_itlb_tag(slot+2), spitfire_get_itlb_data(slot+2)); + } + } else if (tlb_type == cheetah) { + printk ("Contents of itlb0:\n"); + for (slot = 0; slot < 16; slot+=2) { + printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n", + slot, + cheetah_get_litlb_tag(slot), cheetah_get_litlb_data(slot), + slot+1, + cheetah_get_litlb_tag(slot+1), cheetah_get_litlb_data(slot+1)); + } + printk ("Contents of itlb2:\n"); + for (slot = 0; slot < 128; slot+=2) { + printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n", + slot, + cheetah_get_itlb_tag(slot), cheetah_get_itlb_data(slot), + slot+1, + cheetah_get_itlb_tag(slot+1), cheetah_get_itlb_data(slot+1)); + } + } } void sparc_ultra_dump_dtlb(void) { int slot; - printk ("Contents of dtlb: "); - for (slot = 0; slot < 14; slot++) printk (" "); - printk ("%2x:%016lx,%016lx\n", 0, spitfire_get_dtlb_tag(0), - spitfire_get_dtlb_data(0)); - for (slot = 1; slot < 64; slot+=3) { - printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx %2x:%016lx,%016lx\n", - slot, spitfire_get_dtlb_tag(slot), spitfire_get_dtlb_data(slot), - slot+1, spitfire_get_dtlb_tag(slot+1), spitfire_get_dtlb_data(slot+1), - slot+2, spitfire_get_dtlb_tag(slot+2), spitfire_get_dtlb_data(slot+2)); - } + if (tlb_type == spitfire) { + printk ("Contents of dtlb: "); + for (slot = 0; slot < 14; slot++) printk (" "); + printk ("%2x:%016lx,%016lx\n", 0, + spitfire_get_dtlb_tag(0), spitfire_get_dtlb_data(0)); + for (slot = 1; slot < 64; slot+=3) { + printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx %2x:%016lx,%016lx\n", + slot, + spitfire_get_dtlb_tag(slot), spitfire_get_dtlb_data(slot), + slot+1, + spitfire_get_dtlb_tag(slot+1), spitfire_get_dtlb_data(slot+1), + slot+2, + spitfire_get_dtlb_tag(slot+2), spitfire_get_dtlb_data(slot+2)); + } + } else if (tlb_type == cheetah) { + printk ("Contents of dtlb0:\n"); + for (slot = 0; slot < 16; slot+=2) { + printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n", + slot, + cheetah_get_ldtlb_tag(slot), cheetah_get_ldtlb_data(slot), + slot+1, + cheetah_get_ldtlb_tag(slot+1), cheetah_get_ldtlb_data(slot+1)); + } + printk ("Contents of dtlb2:\n"); + for (slot = 0; slot < 512; slot+=2) { + printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n", + slot, + cheetah_get_dtlb_tag(slot), cheetah_get_dtlb_data(slot), + slot+1, + cheetah_get_dtlb_tag(slot+1), cheetah_get_dtlb_data(slot+1)); + } + } } extern unsigned long cmdline_memory_size; @@ -959,20 +1147,35 @@ void __init paging_init(void) pt = phys_base | _PAGE_VALID | _PAGE_SZ4MB; pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W; __save_and_cli(flags); - __asm__ __volatile__(" - stxa %1, [%0] %3 - stxa %2, [%5] %4 - membar #Sync - flush %%g6 - nop - nop - nop" - : /* No outputs */ - : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt), - "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3) - : "memory"); - if (((unsigned long)&_end) >= KERNBASE + 0x340000) { - second_alias_page = alias_base + 0x400000; + if (tlb_type == spitfire) { + __asm__ __volatile__(" + stxa %1, [%0] %3 + stxa %2, [%5] %4 + membar #Sync + flush %%g6 + nop + nop + nop" + : /* No outputs */ + : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt), + "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3) + : "memory"); + if (((unsigned long)&_end) >= KERNBASE + 0x340000) { + second_alias_page = alias_base + 0x400000; + __asm__ __volatile__(" + stxa %1, [%0] %3 + stxa %2, [%5] %4 + membar #Sync + flush %%g6 + nop + nop + nop" + : /* No outputs */ + : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000), + "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (60 << 3) + : "memory"); + } + } else if (tlb_type == cheetah) { __asm__ __volatile__(" stxa %1, [%0] %3 stxa %2, [%5] %4 @@ -982,9 +1185,24 @@ void __init paging_init(void) nop nop" : /* No outputs */ - : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000), - "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (60 << 3) + : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt), + "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (13<<3)) : "memory"); + if (((unsigned long)&_end) >= KERNBASE + 0x340000) { + second_alias_page = alias_base + 0x400000; + __asm__ __volatile__(" + stxa %1, [%0] %3 + stxa %2, [%5] %4 + membar #Sync + flush %%g6 + nop + nop + nop" + : /* No outputs */ + : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000), + "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (12<<3)) + : "memory"); + } } __restore_flags(flags); diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index daaf580a0..b9b25bb84 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -1,4 +1,4 @@ -/* $Id: ultra.S,v 1.48 2000/11/06 06:59:04 davem Exp $ +/* $Id: ultra.S,v 1.54 2001/03/22 07:26:04 davem Exp $ * ultra.S: Don't expand these all over the place... * * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com) @@ -10,6 +10,22 @@ #include <asm/page.h> #include <asm/spitfire.h> + /* Basically, all this madness has to do with the + * fact that Cheetah does not support IMMU flushes + * out of the secondary context. Someone needs to + * throw a south lake birthday party for the folks + * in Microelectronics who refused to fix this shit. + */ +#define BRANCH_IF_CHEETAH(tmp1, tmp2, label) \ + rdpr %ver, %tmp1; \ + sethi %hi(0x003e0014), %tmp2; \ + srlx %tmp1, 32, %tmp1; \ + or %tmp2, %lo(0x003e0014), %tmp2; \ + cmp %tmp1, %tmp2; \ + be,pn %icc, label; \ + nop; \ + nop; + /* This file is meant to be read efficiently by the CPU, not humans. * Staraj sie tego nikomu nie pierdolnac... */ @@ -17,37 +33,77 @@ .align 32 .globl __flush_tlb_page, __flush_tlb_mm, __flush_tlb_range __flush_tlb_page: /* %o0=(ctx & 0x3ff), %o1=page&PAGE_MASK, %o2=SECONDARY_CONTEXT */ -/*IC1*/ ldxa [%o2] ASI_DMMU, %g2 +/*IC1*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_page) +__spitfire_flush_tlb_page: +/*IC2*/ ldxa [%o2] ASI_DMMU, %g2 cmp %g2, %o0 - bne,pn %icc, __flush_tlb_page_slow + bne,pn %icc, __spitfire_flush_tlb_page_slow or %o1, 0x10, %g3 stxa %g0, [%g3] ASI_DMMU_DEMAP stxa %g0, [%g3] ASI_IMMU_DEMAP retl flush %g6 +__cheetah_flush_tlb_page: +/*IC3*/ rdpr %pstate, %g5 + andn %g5, PSTATE_IE, %g2 + wrpr %g2, 0x0, %pstate + wrpr %g0, 1, %tl + mov PRIMARY_CONTEXT, %o2 + ldxa [%o2] ASI_DMMU, %g2 + stxa %o0, [%o2] ASI_DMMU + stxa %g0, [%o1] ASI_DMMU_DEMAP +/*IC4*/ stxa %g0, [%o1] ASI_IMMU_DEMAP + stxa %g2, [%o2] ASI_DMMU + flush %g6 + wrpr %g0, 0, %tl + retl + wrpr %g5, 0x0, %pstate + nop + nop __flush_tlb_mm: /* %o0=(ctx & 0x3ff), %o1=SECONDARY_CONTEXT */ -/*IC2*/ ldxa [%o1] ASI_DMMU, %g2 +/*IC5*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_mm) +__spitfire_flush_tlb_mm: +/*IC6*/ ldxa [%o1] ASI_DMMU, %g2 cmp %g2, %o0 - bne,pn %icc, __flush_tlb_mm_slow + bne,pn %icc, __spitfire_flush_tlb_mm_slow mov 0x50, %g3 stxa %g0, [%g3] ASI_DMMU_DEMAP stxa %g0, [%g3] ASI_IMMU_DEMAP retl flush %g6 +__cheetah_flush_tlb_mm: +/*IC7*/ rdpr %pstate, %g5 + andn %g5, PSTATE_IE, %g2 + wrpr %g2, 0x0, %pstate + wrpr %g0, 1, %tl + mov PRIMARY_CONTEXT, %o2 + mov 0x40, %g3 + ldxa [%o2] ASI_DMMU, %g2 + stxa %o0, [%o2] ASI_DMMU +/*IC8*/ stxa %g0, [%g3] ASI_DMMU_DEMAP + stxa %g0, [%g3] ASI_IMMU_DEMAP + stxa %g2, [%o2] ASI_DMMU + flush %g6 + wrpr %g0, 0, %tl + retl + wrpr %g5, 0x0, %pstate + nop __flush_tlb_range: /* %o0=(ctx&0x3ff), %o1=start&PAGE_MASK, %o2=SECONDARY_CONTEXT, * %o3=end&PAGE_MASK, %o4=PAGE_SIZE, %o5=(end - start) */ +/*IC9*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_range) +__spitfire_flush_tlb_range: #define TLB_MAGIC 207 /* Students, do you know how I calculated this? -DaveM */ -/*IC3*/ cmp %o5, %o4 +/*IC10*/cmp %o5, %o4 bleu,pt %xcc, __flush_tlb_page srlx %o5, 13, %g5 cmp %g5, TLB_MAGIC - bgeu,pn %icc, __flush_tlb_range_constant_time + bgeu,pn %icc, __spitfire_flush_tlb_range_constant_time or %o1, 0x10, %g5 ldxa [%o2] ASI_DMMU, %g2 cmp %g2, %o0 -__flush_tlb_range_page_by_page: -/*IC4*/ bne,pn %icc, __flush_tlb_range_pbp_slow +__spitfire_flush_tlb_range_page_by_page: +/*IC11*/bne,pn %icc, __spitfire_flush_tlb_range_pbp_slow sub %o5, %o4, %o5 1: stxa %g0, [%g5 + %o5] ASI_DMMU_DEMAP stxa %g0, [%g5 + %o5] ASI_IMMU_DEMAP @@ -55,10 +111,11 @@ __flush_tlb_range_page_by_page: sub %o5, %o4, %o5 retl flush %g6 -__flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */ -/*IC5*/ rdpr %pstate, %g1 +__spitfire_flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */ +/*IC12*/rdpr %pstate, %g1 wrpr %g1, PSTATE_IE, %pstate mov TLB_TAG_ACCESS, %g3 + /* XXX Spitfire dependency... */ mov (62 << 3), %g2 /* Spitfire Errata #32 workaround. */ @@ -70,7 +127,7 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */ and %o4, 0x3ff, %o5 cmp %o5, %o0 bne,pt %icc, 2f -/*IC6*/ andn %o4, 0x3ff, %o4 +/*IC13*/ andn %o4, 0x3ff, %o4 cmp %o4, %o1 blu,pt %xcc, 2f cmp %o4, %o3 @@ -78,7 +135,7 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */ 2: ldxa [%g2] ASI_DTLB_TAG_READ, %o4 and %o4, 0x3ff, %o5 cmp %o5, %o0 -/*IC7*/ andn %o4, 0x3ff, %o4 +/*IC14*/andn %o4, 0x3ff, %o4 bne,pt %icc, 3f cmp %o4, %o1 blu,pt %xcc, 3f @@ -86,7 +143,7 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */ blu,pn %xcc, 5f nop 3: brnz,pt %g2, 1b -/*IC8*/ sub %g2, (1 << 3), %g2 +/*IC15*/ sub %g2, (1 << 3), %g2 retl wrpr %g1, 0x0, %pstate 4: stxa %g0, [%g3] ASI_IMMU @@ -102,7 +159,7 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */ nop 5: stxa %g0, [%g3] ASI_DMMU -/*IC9*/ stxa %g0, [%g2] ASI_DTLB_DATA_ACCESS +/*IC16*/stxa %g0, [%g2] ASI_DTLB_DATA_ACCESS flush %g6 /* Spitfire Errata #32 workaround. */ @@ -114,45 +171,70 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */ nop .align 32 -__flush_tlb_mm_slow: -/*IC10*/rdpr %pstate, %g1 +__cheetah_flush_tlb_range: + cmp %o5, %o4 + bleu,pt %xcc, __cheetah_flush_tlb_page + nop +/*IC17*/rdpr %pstate, %g5 + andn %g5, PSTATE_IE, %g2 + wrpr %g2, 0x0, %pstate + wrpr %g0, 1, %tl + mov PRIMARY_CONTEXT, %o2 + sub %o5, %o4, %o5 + ldxa [%o2] ASI_DMMU, %g2 + stxa %o0, [%o2] ASI_DMMU + +/*IC18*/ +1: stxa %g0, [%o1 + %o5] ASI_DMMU_DEMAP + stxa %g0, [%o1 + %o5] ASI_IMMU_DEMAP + membar #Sync + brnz,pt %o5, 1b + sub %o5, %o4, %o5 + + stxa %g2, [%o2] ASI_DMMU + flush %g6 + wrpr %g0, 0, %tl + retl +/*IC19*/ wrpr %g5, 0x0, %pstate + +__spitfire_flush_tlb_mm_slow: + rdpr %pstate, %g1 wrpr %g1, PSTATE_IE, %pstate stxa %o0, [%o1] ASI_DMMU stxa %g0, [%g3] ASI_DMMU_DEMAP stxa %g0, [%g3] ASI_IMMU_DEMAP flush %g6 stxa %g2, [%o1] ASI_DMMU - flush %g6 -/*IC11*/retl +/*IC18*/flush %g6 + retl wrpr %g1, 0, %pstate - .align 32 -__flush_tlb_page_slow: -/*IC12*/rdpr %pstate, %g1 +__spitfire_flush_tlb_page_slow: + rdpr %pstate, %g1 wrpr %g1, PSTATE_IE, %pstate stxa %o0, [%o2] ASI_DMMU stxa %g0, [%g3] ASI_DMMU_DEMAP stxa %g0, [%g3] ASI_IMMU_DEMAP - flush %g6 +/*IC20*/flush %g6 stxa %g2, [%o2] ASI_DMMU flush %g6 -/*IC13*/retl + retl wrpr %g1, 0, %pstate - .align 32 -__flush_tlb_range_pbp_slow: -/*IC13*/rdpr %pstate, %g1 +__spitfire_flush_tlb_range_pbp_slow: + rdpr %pstate, %g1 wrpr %g1, PSTATE_IE, %pstate stxa %o0, [%o2] ASI_DMMU +/*IC21*/ 2: stxa %g0, [%g5 + %o5] ASI_DMMU_DEMAP stxa %g0, [%g5 + %o5] ASI_IMMU_DEMAP brnz,pt %o5, 2b sub %o5, %o4, %o5 flush %g6 -/*IC14*/stxa %g2, [%o2] ASI_DMMU + stxa %g2, [%o2] ASI_DMMU flush %g6 retl - wrpr %g1, 0x0, %pstate +/*IC22*/ wrpr %g1, 0x0, %pstate .align 32 .globl __flush_icache_page @@ -210,6 +292,27 @@ iflush2:sub %o1, 0x20, %g3 .globl __flush_dcache_page __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */ sub %o0, %g4, %o0 + + rdpr %ver, %g1 + sethi %hi(0x003e0014), %g2 + srlx %g1, 32, %g1 + or %g2, %lo(0x003e0014), %g2 + cmp %g1, %g2 + bne,pt %icc, flush_dcpage_spitfire + nop + +flush_dcpage_cheetah: + sethi %hi(8192), %o4 +1: subcc %o4, (1 << 5), %o4 + stxa %g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE + membar #Sync + bne,pt %icc, 1b + nop + /* I-cache flush never needed on Cheetah, see callers. */ + retl + nop + +flush_dcpage_spitfire: clr %o4 srlx %o0, 11, %o0 sethi %hi(1 << 14), %o2 @@ -317,18 +420,18 @@ __update_mmu_cache: /* %o0=vma, %o1=address, %o2=pte */ .align 32 .globl xcall_flush_tlb_page, xcall_flush_tlb_mm, xcall_flush_tlb_range xcall_flush_tlb_page: - mov SECONDARY_CONTEXT, %g2 - or %g1, 0x10, %g4 + mov PRIMARY_CONTEXT, %g2 ldxa [%g2] ASI_DMMU, %g3 stxa %g5, [%g2] ASI_DMMU - stxa %g0, [%g4] ASI_DMMU_DEMAP - stxa %g0, [%g4] ASI_IMMU_DEMAP + stxa %g0, [%g1] ASI_DMMU_DEMAP + stxa %g0, [%g1] ASI_IMMU_DEMAP stxa %g3, [%g2] ASI_DMMU retry + nop xcall_flush_tlb_mm: - mov SECONDARY_CONTEXT, %g2 - mov 0x50, %g4 + mov PRIMARY_CONTEXT, %g2 + mov 0x40, %g4 ldxa [%g2] ASI_DMMU, %g3 stxa %g5, [%g2] ASI_DMMU stxa %g0, [%g4] ASI_DMMU_DEMAP @@ -343,20 +446,21 @@ xcall_flush_tlb_range: andn %g7, %g2, %g7 sub %g7, %g1, %g3 add %g2, 1, %g2 - orcc %g1, 0x10, %g1 srlx %g3, 13, %g4 - cmp %g4, 96 + bgu,pn %icc, xcall_flush_tlb_mm - mov SECONDARY_CONTEXT, %g4 + mov PRIMARY_CONTEXT, %g4 ldxa [%g4] ASI_DMMU, %g7 sub %g3, %g2, %g3 stxa %g5, [%g4] ASI_DMMU nop nop + nop 1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP + membar #Sync brnz,pt %g3, 1b sub %g3, %g2, %g3 stxa %g7, [%g4] ASI_DMMU @@ -433,7 +537,8 @@ errata32_hwbug: /* These two are not performance critical... */ .globl xcall_flush_tlb_all xcall_flush_tlb_all: - + BRANCH_IF_CHEETAH(g2, g3, __cheetah_xcall_flush_tlb_all) +__spitfire_xcall_flush_tlb_all: /* Spitfire Errata #32 workaround. */ sethi %hi(errata32_hwbug), %g4 stx %g0, [%g4 + %lo(errata32_hwbug)] @@ -475,12 +580,21 @@ xcall_flush_tlb_all: flush %g6 retry +__cheetah_xcall_flush_tlb_all: + mov 0x80, %g2 + stxa %g0, [%g2] ASI_DMMU_DEMAP + stxa %g0, [%g2] ASI_IMMU_DEMAP + retry + .globl xcall_flush_cache_all xcall_flush_cache_all: + BRANCH_IF_CHEETAH(g2, g3, __cheetah_xcall_flush_cache_all) +__spitfire_xcall_flush_cache_all: sethi %hi(16383), %g2 or %g2, %lo(16383), %g2 clr %g3 1: stxa %g0, [%g3] ASI_IC_TAG + membar #Sync add %g3, 32, %g3 cmp %g3, %g2 bleu,pt %xcc, 1b @@ -488,6 +602,13 @@ xcall_flush_cache_all: flush %g6 retry + /* Cheetah's caches are fully coherent in the sense that + * caches are flushed here. We need to verify this and + * really just not even send out the xcall at the top level. + */ +__cheetah_xcall_flush_cache_all: + retry + .globl xcall_call_function xcall_call_function: mov TLB_TAG_ACCESS, %g5 ! wheee... diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index 15c8736ef..8d56b895a 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.31 2000/12/14 22:57:25 davem Exp $ +/* $Id: misc.c,v 1.32 2001/03/24 09:36:11 davem Exp $ * misc.c: Miscelaneous syscall emulation for Solaris * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -92,12 +92,12 @@ static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 o ret_type = flags & _MAP_NEW; flags &= ~_MAP_NEW; - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); retval = do_mmap(file, (unsigned long) addr, (unsigned long) len, (unsigned long) prot, (unsigned long) flags, off); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if(!ret_type) retval = ((retval < 0xf0000000) ? 0 : retval); |