diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2011-08-08 08:22:41 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2011-08-08 08:22:41 +0200 |
commit | 1a43f2012455a977397deffe35912fd3f3ce17b9 (patch) | |
tree | 5189f337df44e7a495fbd097cd476b0380babd8c /arch/microblaze | |
parent | e1b96ada659431669efaf3defa997abf5db68130 (diff) | |
parent | 322a8b034003c0d46d39af85bf24fee27b902f48 (diff) | |
download | op-kernel-dev-1a43f2012455a977397deffe35912fd3f3ce17b9.zip op-kernel-dev-1a43f2012455a977397deffe35912fd3f3ce17b9.tar.gz |
Merge commit 'v3.1-rc1' into imx-fixes
Diffstat (limited to 'arch/microblaze')
24 files changed, 275 insertions, 689 deletions
diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h index d8f0133..7d6831a 100644 --- a/arch/microblaze/include/asm/cpuinfo.h +++ b/arch/microblaze/include/asm/cpuinfo.h @@ -38,6 +38,7 @@ struct cpuinfo { u32 use_exc; u32 ver_code; u32 mmu; + u32 mmu_privins; u32 endian; /* CPU caches */ diff --git a/arch/microblaze/include/asm/irqflags.h b/arch/microblaze/include/asm/irqflags.h index c4532f0..c9a6262 100644 --- a/arch/microblaze/include/asm/irqflags.h +++ b/arch/microblaze/include/asm/irqflags.h @@ -14,7 +14,7 @@ #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR -static inline unsigned long arch_local_irq_save(void) +static inline notrace unsigned long arch_local_irq_save(void) { unsigned long flags; asm volatile(" msrclr %0, %1 \n" @@ -25,7 +25,7 @@ static inline unsigned long arch_local_irq_save(void) return flags; } -static inline void arch_local_irq_disable(void) +static inline notrace void arch_local_irq_disable(void) { /* this uses r0 without declaring it - is that correct? */ asm volatile(" msrclr r0, %0 \n" @@ -35,7 +35,7 @@ static inline void arch_local_irq_disable(void) : "memory"); } -static inline void arch_local_irq_enable(void) +static inline notrace void arch_local_irq_enable(void) { /* this uses r0 without declaring it - is that correct? */ asm volatile(" msrset r0, %0 \n" @@ -47,7 +47,7 @@ static inline void arch_local_irq_enable(void) #else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ -static inline unsigned long arch_local_irq_save(void) +static inline notrace unsigned long arch_local_irq_save(void) { unsigned long flags, tmp; asm volatile (" mfs %0, rmsr \n" @@ -61,7 +61,7 @@ static inline unsigned long arch_local_irq_save(void) return flags; } -static inline void arch_local_irq_disable(void) +static inline notrace void arch_local_irq_disable(void) { unsigned long tmp; asm volatile(" mfs %0, rmsr \n" @@ -74,7 +74,7 @@ static inline void arch_local_irq_disable(void) : "memory"); } -static inline void arch_local_irq_enable(void) +static inline notrace void arch_local_irq_enable(void) { unsigned long tmp; asm volatile(" mfs %0, rmsr \n" @@ -89,7 +89,7 @@ static inline void arch_local_irq_enable(void) #endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ -static inline unsigned long arch_local_save_flags(void) +static inline notrace unsigned long arch_local_save_flags(void) { unsigned long flags; asm volatile(" mfs %0, rmsr \n" @@ -100,7 +100,7 @@ static inline unsigned long arch_local_save_flags(void) return flags; } -static inline void arch_local_irq_restore(unsigned long flags) +static inline notrace void arch_local_irq_restore(unsigned long flags) { asm volatile(" mts rmsr, %0 \n" " nop \n" @@ -109,12 +109,12 @@ static inline void arch_local_irq_restore(unsigned long flags) : "memory"); } -static inline bool arch_irqs_disabled_flags(unsigned long flags) +static inline notrace bool arch_irqs_disabled_flags(unsigned long flags) { return (flags & MSR_IE) == 0; } -static inline bool arch_irqs_disabled(void) +static inline notrace bool arch_irqs_disabled(void) { return arch_irqs_disabled_flags(arch_local_save_flags()); } diff --git a/arch/microblaze/include/asm/mmu_context_mm.h b/arch/microblaze/include/asm/mmu_context_mm.h index 3e5c254..d686477 100644 --- a/arch/microblaze/include/asm/mmu_context_mm.h +++ b/arch/microblaze/include/asm/mmu_context_mm.h @@ -11,7 +11,7 @@ #ifndef _ASM_MICROBLAZE_MMU_CONTEXT_H #define _ASM_MICROBLAZE_MMU_CONTEXT_H -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/bitops.h> #include <asm/mmu.h> #include <asm-generic/mm_hooks.h> diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index 746df91..32764cd 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h @@ -10,31 +10,19 @@ #include <linux/pci.h> #include <linux/list.h> #include <linux/ioport.h> +#include <asm-generic/pci-bridge.h> struct device_node; -enum { - /* Force re-assigning all resources (ignore firmware - * setup completely) - */ - PCI_REASSIGN_ALL_RSRC = 0x00000001, - - /* Re-assign all bus numbers */ - PCI_REASSIGN_ALL_BUS = 0x00000002, - - /* Do not try to assign, just use existing setup */ - PCI_PROBE_ONLY = 0x00000004, - - /* Don't bother with ISA alignment unless the bridge has - * ISA forwarding enabled - */ - PCI_CAN_SKIP_ISA_ALIGN = 0x00000008, - - /* Enable domain numbers in /proc */ - PCI_ENABLE_PROC_DOMAINS = 0x00000010, - /* ... except for domain 0 */ - PCI_COMPAT_DOMAIN_0 = 0x00000020, -}; +#ifdef CONFIG_PCI +extern struct list_head hose_list; +extern int pcibios_vaddr_is_ioport(void __iomem *address); +#else +static inline int pcibios_vaddr_is_ioport(void __iomem *address) +{ + return 0; +} +#endif /* * Structure of a PCI controller (host bridge) @@ -110,16 +98,6 @@ static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) return bus->sysdata; } -static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) -{ - struct pci_controller *host; - - if (bus->self) - return pci_device_to_OF_node(bus->self); - host = pci_bus_to_host(bus); - return host ? host->dn : NULL; -} - static inline int isa_vaddr_is_ioport(void __iomem *address) { /* No specific ISA handling on ppc32 at this stage, it @@ -164,40 +142,5 @@ extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); extern void pcibios_free_controller(struct pci_controller *phb); extern void pcibios_setup_phb_resources(struct pci_controller *hose); -#ifdef CONFIG_PCI -extern unsigned int pci_flags; - -static inline void pci_set_flags(int flags) -{ - pci_flags = flags; -} - -static inline void pci_add_flags(int flags) -{ - pci_flags |= flags; -} - -static inline int pci_has_flag(int flag) -{ - return pci_flags & flag; -} - -extern struct list_head hose_list; - -extern int pcibios_vaddr_is_ioport(void __iomem *address); -#else -static inline int pcibios_vaddr_is_ioport(void __iomem *address) -{ - return 0; -} - -static inline void pci_set_flags(int flags) { } -static inline void pci_add_flags(int flags) { } -static inline int pci_has_flag(int flag) -{ - return 0; -} -#endif /* CONFIG_PCI */ - #endif /* __KERNEL__ */ #endif /* _ASM_MICROBLAZE_PCI_BRIDGE_H */ diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index ba65cf4..1dd9d6b 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -40,8 +40,7 @@ struct pci_dev; * Set this to 1 if you want the kernel to re-assign all PCI * bus numbers (don't do that on ppc64 yet !) */ -#define pcibios_assign_all_busses() \ - (pci_has_flag(PCI_REASSIGN_ALL_BUS)) +#define pcibios_assign_all_busses() 0 static inline void pcibios_set_master(struct pci_dev *dev) { diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h index aed2a6b..7283bfb 100644 --- a/arch/microblaze/include/asm/processor.h +++ b/arch/microblaze/include/asm/processor.h @@ -125,9 +125,6 @@ struct thread_struct { .pgdir = swapper_pg_dir, \ } -/* Do necessary setup to start up a newly executed thread. */ -void start_thread(struct pt_regs *regs, - unsigned long pc, unsigned long usp); /* Free all resources held by a thread. */ extern inline void release_thread(struct task_struct *dead_task) diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index d0890d3..20c5e8e 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -21,28 +21,17 @@ #include <linux/types.h> #include <asm/irq.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #define HAVE_ARCH_DEVTREE_FIXUPS /* Other Prototypes */ -extern int early_uartlite_console(void); -extern int early_uart16550_console(void); +enum early_consoles { + UARTLITE = 1, + UART16550 = 2, +}; -#ifdef CONFIG_PCI -/* - * PCI <-> OF matching functions - * (XXX should these be here?) - */ -struct pci_bus; -struct pci_dev; -extern int pci_device_from_OF_node(struct device_node *node, - u8 *bus, u8 *devfn); -extern struct device_node *pci_busdev_to_OF_node(struct pci_bus *bus, - int devfn); -extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev); -extern void pci_create_OF_bus_map(void); -#endif +extern int of_early_console(void *version); /* * OF address retreival & translation diff --git a/arch/microblaze/include/asm/ptrace.h b/arch/microblaze/include/asm/ptrace.h index d9b6630..816bee6 100644 --- a/arch/microblaze/include/asm/ptrace.h +++ b/arch/microblaze/include/asm/ptrace.h @@ -61,8 +61,6 @@ struct pt_regs { #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) -void show_regs(struct pt_regs *); - #else /* __KERNEL__ */ /* pt_regs offsets used by gdbserver etc in ptrace syscalls */ diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h index a10bec6..4bbdb4c 100644 --- a/arch/microblaze/include/asm/pvr.h +++ b/arch/microblaze/include/asm/pvr.h @@ -111,16 +111,16 @@ struct pvr_s { /* Target family PVR mask */ #define PVR10_TARGET_FAMILY_MASK 0xFF000000 -/* MMU descrtiption */ +/* MMU description */ #define PVR11_USE_MMU 0xC0000000 #define PVR11_MMU_ITLB_SIZE 0x38000000 #define PVR11_MMU_DTLB_SIZE 0x07000000 #define PVR11_MMU_TLB_ACCESS 0x00C00000 #define PVR11_MMU_ZONES 0x003C0000 +#define PVR11_MMU_PRIVINS 0x00010000 /* MSR Reset value PVR mask */ #define PVR11_MSR_RESET_VALUE_MASK 0x000007FF - /* PVR access macros */ #define PVR_IS_FULL(_pvr) (_pvr.pvr[0] & PVR0_PVR_FULL_MASK) #define PVR_USE_BARREL(_pvr) (_pvr.pvr[0] & PVR0_USE_BARREL_MASK) @@ -216,6 +216,7 @@ struct pvr_s { #define PVR_MMU_DTLB_SIZE(_pvr) (_pvr.pvr[11] & PVR11_MMU_DTLB_SIZE) #define PVR_MMU_TLB_ACCESS(_pvr) (_pvr.pvr[11] & PVR11_MMU_TLB_ACCESS) #define PVR_MMU_ZONES(_pvr) (_pvr.pvr[11] & PVR11_MMU_ZONES) +#define PVR_MMU_PRIVINS(pvr) (pvr.pvr[11] & PVR11_MMU_PRIVINS) /* endian */ #define PVR_ENDIAN(_pvr) (_pvr.pvr[0] & PVR0_ENDI) diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h index 8f39689..904e5ef 100644 --- a/arch/microblaze/include/asm/setup.h +++ b/arch/microblaze/include/asm/setup.h @@ -23,6 +23,7 @@ extern char cmd_line[COMMAND_LINE_SIZE]; void early_printk(const char *fmt, ...); int setup_early_printk(char *opt); +void remap_early_printk(void); void disable_early_printk(void); #if defined(CONFIG_EARLY_PRINTK) diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c index f70a604..916aaed 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c +++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c @@ -72,6 +72,7 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu) CI(pvr_user2, USER2); CI(mmu, USE_MMU); + CI(mmu_privins, MMU_PRIVINS); CI(endian, ENDIAN); CI(use_icache, USE_ICACHE); diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c index b16b994..592bb2e 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo-static.c +++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c @@ -119,6 +119,7 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu) ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2"); ci->mmu = fcpu(cpu, "xlnx,use-mmu"); + ci->mmu_privins = fcpu(cpu, "xlnx,mmu-privileged-instr"); ci->endian = fcpu(cpu, "xlnx,endianness"); ci->ver_code = 0; diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c index c1640c5..44394d8 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo.c +++ b/arch/microblaze/kernel/cpu/cpuinfo.c @@ -88,4 +88,8 @@ void __init setup_cpuinfo(void) printk(KERN_WARNING "%s: Unsupported PVR setting\n", __func__); set_cpuinfo_static(&cpuinfo, cpu); } + + if (cpuinfo.mmu_privins) + printk(KERN_WARNING "%s: Stream instructions enabled" + " - USERSPACE CAN LOCK THIS KERNEL!\n", __func__); } diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c index b4048af..7b5dca7 100644 --- a/arch/microblaze/kernel/cpu/mb.c +++ b/arch/microblaze/kernel/cpu/mb.c @@ -97,6 +97,10 @@ static int show_cpuinfo(struct seq_file *m, void *v) (cpuinfo.use_exc & PVR2_FPU_EXC_MASK) ? "fpu " : "", (cpuinfo.use_exc & PVR2_USE_FSL_EXC) ? "fsl " : ""); + count += seq_printf(m, + "Stream-insns:\t%sprivileged\n", + cpuinfo.mmu_privins ? "un" : ""); + if (cpuinfo.use_icache) count += seq_printf(m, "Icache:\t\t%ukB\tline length:\t%dB\n", @@ -110,10 +114,11 @@ static int show_cpuinfo(struct seq_file *m, void *v) "Dcache:\t\t%ukB\tline length:\t%dB\n", cpuinfo.dcache_size >> 10, cpuinfo.dcache_line_length); + seq_printf(m, "Dcache-Policy:\t"); if (cpuinfo.dcache_wb) - count += seq_printf(m, "\t\twrite-back\n"); + count += seq_printf(m, "write-back\n"); else - count += seq_printf(m, "\t\twrite-through\n"); + count += seq_printf(m, "write-through\n"); } else count += seq_printf(m, "Dcache:\t\tno\n"); diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c index c3616a08..d26d92d 100644 --- a/arch/microblaze/kernel/early_printk.c +++ b/arch/microblaze/kernel/early_printk.c @@ -35,7 +35,7 @@ static void early_printk_uartlite_putc(char c) * we'll never timeout on a working UART. */ - unsigned retries = 10000; + unsigned retries = 1000000; /* read status bit - 0x8 offset */ while (--retries && (in_be32(base_addr + 8) & (1 << 3))) ; @@ -60,7 +60,7 @@ static void early_printk_uartlite_write(struct console *unused, static struct console early_serial_uartlite_console = { .name = "earlyser", .write = early_printk_uartlite_write, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER | CON_BOOT, .index = -1, }; #endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ @@ -104,7 +104,7 @@ static void early_printk_uart16550_write(struct console *unused, static struct console early_serial_uart16550_console = { .name = "earlyser", .write = early_printk_uart16550_write, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER | CON_BOOT, .index = -1, }; #endif /* CONFIG_SERIAL_8250_CONSOLE */ @@ -127,48 +127,56 @@ void early_printk(const char *fmt, ...) int __init setup_early_printk(char *opt) { + int version = 0; + if (early_console_initialized) return 1; -#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE - base_addr = early_uartlite_console(); + base_addr = of_early_console(&version); if (base_addr) { - early_console_initialized = 1; #ifdef CONFIG_MMU early_console_reg_tlb_alloc(base_addr); #endif - early_console = &early_serial_uartlite_console; - early_printk("early_printk_console is enabled at 0x%08x\n", - base_addr); - - /* register_console(early_console); */ - - return 0; - } -#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ - + switch (version) { +#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE + case UARTLITE: + printk(KERN_INFO "Early console on uartlite " + "at 0x%08x\n", base_addr); + early_console = &early_serial_uartlite_console; + break; +#endif #ifdef CONFIG_SERIAL_8250_CONSOLE - base_addr = early_uart16550_console(); - base_addr &= ~3; /* clear register offset */ - if (base_addr) { - early_console_initialized = 1; -#ifdef CONFIG_MMU - early_console_reg_tlb_alloc(base_addr); + case UART16550: + printk(KERN_INFO "Early console on uart16650 " + "at 0x%08x\n", base_addr); + early_console = &early_serial_uart16550_console; + break; #endif - early_console = &early_serial_uart16550_console; - - early_printk("early_printk_console is enabled at 0x%08x\n", - base_addr); - - /* register_console(early_console); */ + default: + printk(KERN_INFO "Unsupported early console %d\n", + version); + return 1; + } + register_console(early_console); + early_console_initialized = 1; return 0; } -#endif /* CONFIG_SERIAL_8250_CONSOLE */ - return 1; } +/* Remap early console to virtual address and do not allocate one TLB + * only for early console because of performance degression */ +void __init remap_early_printk(void) +{ + if (!early_console_initialized || !early_console) + return; + printk(KERN_INFO "early_printk_console remaping from 0x%x to ", + base_addr); + base_addr = (u32) ioremap(base_addr, PAGE_SIZE); + printk(KERN_CONT "0x%x\n", base_addr); +} + void __init disable_early_printk(void) { if (!early_console_initialized || !early_console) diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S index 56572e9..e62be83 100644 --- a/arch/microblaze/kernel/hw_exception_handler.S +++ b/arch/microblaze/kernel/hw_exception_handler.S @@ -1113,23 +1113,23 @@ lw_r10_vm: R3_TO_LWREG_VM_V (10); lw_r11_vm: R3_TO_LWREG_VM_V (11); lw_r12_vm: R3_TO_LWREG_VM_V (12); lw_r13_vm: R3_TO_LWREG_VM_V (13); -lw_r14_vm: R3_TO_LWREG_VM (14); +lw_r14_vm: R3_TO_LWREG_VM_V (14); lw_r15_vm: R3_TO_LWREG_VM_V (15); -lw_r16_vm: R3_TO_LWREG_VM (16); +lw_r16_vm: R3_TO_LWREG_VM_V (16); lw_r17_vm: R3_TO_LWREG_VM_V (17); lw_r18_vm: R3_TO_LWREG_VM_V (18); -lw_r19_vm: R3_TO_LWREG_VM (19); -lw_r20_vm: R3_TO_LWREG_VM (20); -lw_r21_vm: R3_TO_LWREG_VM (21); -lw_r22_vm: R3_TO_LWREG_VM (22); -lw_r23_vm: R3_TO_LWREG_VM (23); -lw_r24_vm: R3_TO_LWREG_VM (24); -lw_r25_vm: R3_TO_LWREG_VM (25); -lw_r26_vm: R3_TO_LWREG_VM (26); -lw_r27_vm: R3_TO_LWREG_VM (27); -lw_r28_vm: R3_TO_LWREG_VM (28); -lw_r29_vm: R3_TO_LWREG_VM (29); -lw_r30_vm: R3_TO_LWREG_VM (30); +lw_r19_vm: R3_TO_LWREG_VM_V (19); +lw_r20_vm: R3_TO_LWREG_VM_V (20); +lw_r21_vm: R3_TO_LWREG_VM_V (21); +lw_r22_vm: R3_TO_LWREG_VM_V (22); +lw_r23_vm: R3_TO_LWREG_VM_V (23); +lw_r24_vm: R3_TO_LWREG_VM_V (24); +lw_r25_vm: R3_TO_LWREG_VM_V (25); +lw_r26_vm: R3_TO_LWREG_VM_V (26); +lw_r27_vm: R3_TO_LWREG_VM_V (27); +lw_r28_vm: R3_TO_LWREG_VM_V (28); +lw_r29_vm: R3_TO_LWREG_VM_V (29); +lw_r30_vm: R3_TO_LWREG_VM_V (30); lw_r31_vm: R3_TO_LWREG_VM_V (31); sw_table_vm: @@ -1147,23 +1147,23 @@ sw_r10_vm: SWREG_TO_R3_VM_V (10); sw_r11_vm: SWREG_TO_R3_VM_V (11); sw_r12_vm: SWREG_TO_R3_VM_V (12); sw_r13_vm: SWREG_TO_R3_VM_V (13); -sw_r14_vm: SWREG_TO_R3_VM (14); +sw_r14_vm: SWREG_TO_R3_VM_V (14); sw_r15_vm: SWREG_TO_R3_VM_V (15); -sw_r16_vm: SWREG_TO_R3_VM (16); +sw_r16_vm: SWREG_TO_R3_VM_V (16); sw_r17_vm: SWREG_TO_R3_VM_V (17); sw_r18_vm: SWREG_TO_R3_VM_V (18); -sw_r19_vm: SWREG_TO_R3_VM (19); -sw_r20_vm: SWREG_TO_R3_VM (20); -sw_r21_vm: SWREG_TO_R3_VM (21); -sw_r22_vm: SWREG_TO_R3_VM (22); -sw_r23_vm: SWREG_TO_R3_VM (23); -sw_r24_vm: SWREG_TO_R3_VM (24); -sw_r25_vm: SWREG_TO_R3_VM (25); -sw_r26_vm: SWREG_TO_R3_VM (26); -sw_r27_vm: SWREG_TO_R3_VM (27); -sw_r28_vm: SWREG_TO_R3_VM (28); -sw_r29_vm: SWREG_TO_R3_VM (29); -sw_r30_vm: SWREG_TO_R3_VM (30); +sw_r19_vm: SWREG_TO_R3_VM_V (19); +sw_r20_vm: SWREG_TO_R3_VM_V (20); +sw_r21_vm: SWREG_TO_R3_VM_V (21); +sw_r22_vm: SWREG_TO_R3_VM_V (22); +sw_r23_vm: SWREG_TO_R3_VM_V (23); +sw_r24_vm: SWREG_TO_R3_VM_V (24); +sw_r25_vm: SWREG_TO_R3_VM_V (25); +sw_r26_vm: SWREG_TO_R3_VM_V (26); +sw_r27_vm: SWREG_TO_R3_VM_V (27); +sw_r28_vm: SWREG_TO_R3_VM_V (28); +sw_r29_vm: SWREG_TO_R3_VM_V (29); +sw_r30_vm: SWREG_TO_R3_VM_V (30); sw_r31_vm: SWREG_TO_R3_VM_V (31); #endif /* CONFIG_MMU */ diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c index c88f066..eb41441 100644 --- a/arch/microblaze/kernel/intc.c +++ b/arch/microblaze/kernel/intc.c @@ -134,7 +134,7 @@ void __init init_IRQ(void) intr_type = be32_to_cpup(of_get_property(intc, "xlnx,kind-of-intr", NULL)); - if (intr_type >= (1 << (nr_irq + 1))) + if (intr_type > (u32)((1ULL << nr_irq) - 1)) printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n"); #ifdef CONFIG_SELFMOD_INTC diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c index 0e73f66..142426f 100644 --- a/arch/microblaze/kernel/module.c +++ b/arch/microblaze/kernel/module.c @@ -18,37 +18,6 @@ #include <asm/pgtable.h> #include <asm/cacheflush.h> -void *module_alloc(unsigned long size) -{ - void *ret; - ret = (size == 0) ? NULL : vmalloc(size); - pr_debug("module_alloc (%08lx@%08lx)\n", size, (unsigned long int)ret); - return ret; -} - -void module_free(struct module *module, void *region) -{ - pr_debug("module_free(%s,%08lx)\n", module->name, - (unsigned long)region); - vfree(region); -} - -int module_frob_arch_sections(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - char *secstrings, - struct module *mod) -{ - return 0; -} - -int apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, - unsigned int symindex, unsigned int relsec, struct module *module) -{ - printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", - module->name); - return -ENOEXEC; -} - int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, unsigned int relsec, struct module *module) { @@ -155,7 +124,3 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, flush_dcache(); return 0; } - -void module_arch_cleanup(struct module *mod) -{ -} diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c index 968648a..dbb8124 100644 --- a/arch/microblaze/kernel/process.c +++ b/arch/microblaze/kernel/process.c @@ -237,7 +237,6 @@ unsigned long get_wchan(struct task_struct *p) /* Set up a thread for executing a new program */ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp) { - set_fs(USER_DS); regs->pc = pc; regs->r1 = usp; regs->pt_mode = 0; diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index b15cc21..977484a 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c @@ -53,69 +53,58 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) } #ifdef CONFIG_EARLY_PRINTK -/* MS this is Microblaze specifig function */ -static int __init early_init_dt_scan_serial(unsigned long node, - const char *uname, int depth, void *data) -{ - unsigned long l; - char *p; - const __be32 *addr; - - pr_debug("search \"serial\", depth: %d, uname: %s\n", depth, uname); - -/* find all serial nodes */ - if (strncmp(uname, "serial", 6) != 0) - return 0; - -/* find compatible node with uartlite */ - p = of_get_flat_dt_prop(node, "compatible", &l); - if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && - (strncmp(p, "xlnx,opb-uartlite", 17) != 0) && - (strncmp(p, "xlnx,axi-uartlite", 17) != 0)) - return 0; - - addr = of_get_flat_dt_prop(node, "reg", &l); - return be32_to_cpup(addr); /* return address */ -} +char *stdout; -/* this function is looking for early uartlite console - Microblaze specific */ -int __init early_uartlite_console(void) -{ - return of_scan_flat_dt(early_init_dt_scan_serial, NULL); -} - -/* MS this is Microblaze specifig function */ -static int __init early_init_dt_scan_serial_full(unsigned long node, +int __init early_init_dt_scan_chosen_serial(unsigned long node, const char *uname, int depth, void *data) { unsigned long l; char *p; - unsigned int addr; - - pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); - -/* find all serial nodes */ - if (strncmp(uname, "serial", 6) != 0) - return 0; - early_init_dt_check_for_initrd(node); - -/* find compatible node with uartlite */ - p = of_get_flat_dt_prop(node, "compatible", &l); - - if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) && - (strncmp(p, "xlnx,axi-uart16550", 18) != 0)) - return 0; - - addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); - addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l); - return be32_to_cpu(addr); /* return address */ + pr_debug("%s: depth: %d, uname: %s\n", __func__, depth, uname); + + if (depth == 1 && (strcmp(uname, "chosen") == 0 || + strcmp(uname, "chosen@0") == 0)) { + p = of_get_flat_dt_prop(node, "linux,stdout-path", &l); + if (p != NULL && l > 0) + stdout = p; /* store pointer to stdout-path */ + } + + if (stdout && strstr(stdout, uname)) { + p = of_get_flat_dt_prop(node, "compatible", &l); + pr_debug("Compatible string: %s\n", p); + + if ((strncmp(p, "xlnx,xps-uart16550", 18) == 0) || + (strncmp(p, "xlnx,axi-uart16550", 18) == 0)) { + unsigned int addr; + + *(u32 *)data = UART16550; + + addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); + addr += *(u32 *)of_get_flat_dt_prop(node, + "reg-offset", &l); + /* clear register offset */ + return be32_to_cpu(addr) & ~3; + } + if ((strncmp(p, "xlnx,xps-uartlite", 17) == 0) || + (strncmp(p, "xlnx,opb-uartlite", 17) == 0) || + (strncmp(p, "xlnx,axi-uartlite", 17) == 0) || + (strncmp(p, "xlnx,mdm", 8) == 0)) { + unsigned int *addrp; + + *(u32 *)data = UARTLITE; + + addrp = of_get_flat_dt_prop(node, "reg", &l); + return be32_to_cpup(addrp); /* return address */ + } + } + return 0; } -/* this function is looking for early uartlite console - Microblaze specific */ -int __init early_uart16550_console(void) +/* this function is looking for early console - Microblaze specific */ +int __init of_early_console(void *version) { - return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL); + return of_scan_flat_dt(early_init_dt_scan_chosen_serial, version); } #endif diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 8e2c09b..0e654a1 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -59,6 +59,11 @@ void __init setup_arch(char **cmdline_p) setup_memory(); +#ifdef CONFIG_EARLY_PRINTK + /* remap early console to virtual address */ + remap_early_printk(); +#endif + xilinx_pci_init(); #if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER) diff --git a/arch/microblaze/pci/Makefile b/arch/microblaze/pci/Makefile index 9889cc2..d1114fb 100644 --- a/arch/microblaze/pci/Makefile +++ b/arch/microblaze/pci/Makefile @@ -2,5 +2,5 @@ # Makefile # -obj-$(CONFIG_PCI) += pci_32.o pci-common.o indirect_pci.o iomap.o +obj-$(CONFIG_PCI) += pci-common.o indirect_pci.o iomap.o obj-$(CONFIG_PCI_XILINX) += xilinx_pci.o diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 5359906..4cfae20 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -50,6 +50,11 @@ unsigned int pci_flags; static struct dma_map_ops *pci_dma_ops = &dma_direct_ops; +unsigned long isa_io_base; +unsigned long pci_dram_offset; +static int pci_bus_count; + + void set_pci_dma_ops(struct dma_map_ops *dma_ops) { pci_dma_ops = dma_ops; @@ -89,7 +94,7 @@ void pcibios_free_controller(struct pci_controller *phb) static resource_size_t pcibios_io_size(const struct pci_controller *hose) { - return hose->io_resource.end - hose->io_resource.start + 1; + return resource_size(&hose->io_resource); } int pcibios_vaddr_is_ioport(void __iomem *address) @@ -1558,6 +1563,112 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose) (unsigned long)hose->io_base_virt - _IO_BASE); } +struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) +{ + struct pci_controller *hose = bus->sysdata; + + return of_node_get(hose->dn); +} + +static void __devinit pcibios_scan_phb(struct pci_controller *hose) +{ + struct pci_bus *bus; + struct device_node *node = hose->dn; + unsigned long io_offset; + struct resource *res = &hose->io_resource; + + pr_debug("PCI: Scanning PHB %s\n", + node ? node->full_name : "<NO NAME>"); + + /* Create an empty bus for the toplevel */ + bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose); + if (bus == NULL) { + printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", + hose->global_number); + return; + } + bus->secondary = hose->first_busno; + hose->bus = bus; + + /* Fixup IO space offset */ + io_offset = (unsigned long)hose->io_base_virt - isa_io_base; + res->start = (res->start + io_offset) & 0xffffffffu; + res->end = (res->end + io_offset) & 0xffffffffu; + + /* Wire up PHB bus resources */ + pcibios_setup_phb_resources(hose); + + /* Scan children */ + hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); +} + +static int __init pcibios_init(void) +{ + struct pci_controller *hose, *tmp; + int next_busno = 0; + + printk(KERN_INFO "PCI: Probing PCI hardware\n"); + + /* Scan all of the recorded PCI controllers. */ + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { + hose->last_busno = 0xff; + pcibios_scan_phb(hose); + printk(KERN_INFO "calling pci_bus_add_devices()\n"); + pci_bus_add_devices(hose->bus); + if (next_busno <= hose->last_busno) + next_busno = hose->last_busno + 1; + } + pci_bus_count = next_busno; + + /* Call common code to handle resource allocation */ + pcibios_resource_survey(); + + return 0; +} + +subsys_initcall(pcibios_init); + +static struct pci_controller *pci_bus_to_hose(int bus) +{ + struct pci_controller *hose, *tmp; + + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) + if (bus >= hose->first_busno && bus <= hose->last_busno) + return hose; + return NULL; +} + +/* Provide information on locations of various I/O regions in physical + * memory. Do this on a per-card basis so that we choose the right + * root bridge. + * Note that the returned IO or memory base is a physical address + */ + +long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) +{ + struct pci_controller *hose; + long result = -EOPNOTSUPP; + + hose = pci_bus_to_hose(bus); + if (!hose) + return -ENODEV; + + switch (which) { + case IOBASE_BRIDGE_NUMBER: + return (long)hose->first_busno; + case IOBASE_MEMORY: + return (long)hose->pci_mem_offset; + case IOBASE_IO: + return (long)hose->io_base_phys; + case IOBASE_ISA_IO: + return (long)isa_io_base; + case IOBASE_ISA_MEM: + return (long)isa_mem_base; + } + + return result; +} + /* * Null PCI config access functions, for the case when we can't * find a hose. @@ -1626,3 +1737,4 @@ int early_find_capability(struct pci_controller *hose, int bus, int devfn, { return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap); } + diff --git a/arch/microblaze/pci/pci_32.c b/arch/microblaze/pci/pci_32.c deleted file mode 100644 index 92728a6..0000000 --- a/arch/microblaze/pci/pci_32.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Common pmac/prep/chrp pci routines. -- Cort - */ - -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/init.h> -#include <linux/capability.h> -#include <linux/sched.h> -#include <linux/errno.h> -#include <linux/bootmem.h> -#include <linux/irq.h> -#include <linux/list.h> -#include <linux/of.h> -#include <linux/slab.h> - -#include <asm/processor.h> -#include <asm/io.h> -#include <asm/prom.h> -#include <asm/sections.h> -#include <asm/pci-bridge.h> -#include <asm/byteorder.h> -#include <asm/uaccess.h> - -#undef DEBUG - -unsigned long isa_io_base; -unsigned long pci_dram_offset; -int pcibios_assign_bus_offset = 1; - -static u8 *pci_to_OF_bus_map; - -/* By default, we don't re-assign bus numbers. We do this only on - * some pmacs - */ -static int pci_assign_all_buses; - -static int pci_bus_count; - -/* - * Functions below are used on OpenFirmware machines. - */ -static void -make_one_node_map(struct device_node *node, u8 pci_bus) -{ - const int *bus_range; - int len; - - if (pci_bus >= pci_bus_count) - return; - bus_range = of_get_property(node, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, " - "assuming it starts at 0\n", node->full_name); - pci_to_OF_bus_map[pci_bus] = 0; - } else - pci_to_OF_bus_map[pci_bus] = bus_range[0]; - - for_each_child_of_node(node, node) { - struct pci_dev *dev; - const unsigned int *class_code, *reg; - - class_code = of_get_property(node, "class-code", NULL); - if (!class_code || - ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && - (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) - continue; - reg = of_get_property(node, "reg", NULL); - if (!reg) - continue; - dev = pci_get_bus_and_slot(pci_bus, ((reg[0] >> 8) & 0xff)); - if (!dev || !dev->subordinate) { - pci_dev_put(dev); - continue; - } - make_one_node_map(node, dev->subordinate->number); - pci_dev_put(dev); - } -} - -void -pcibios_make_OF_bus_map(void) -{ - int i; - struct pci_controller *hose, *tmp; - struct property *map_prop; - struct device_node *dn; - - pci_to_OF_bus_map = kmalloc(pci_bus_count, GFP_KERNEL); - if (!pci_to_OF_bus_map) { - printk(KERN_ERR "Can't allocate OF bus map !\n"); - return; - } - - /* We fill the bus map with invalid values, that helps - * debugging. - */ - for (i = 0; i < pci_bus_count; i++) - pci_to_OF_bus_map[i] = 0xff; - - /* For each hose, we begin searching bridges */ - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { - struct device_node *node = hose->dn; - - if (!node) - continue; - make_one_node_map(node, hose->first_busno); - } - dn = of_find_node_by_path("/"); - map_prop = of_find_property(dn, "pci-OF-bus-map", NULL); - if (map_prop) { - BUG_ON(pci_bus_count > map_prop->length); - memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count); - } - of_node_put(dn); -#ifdef DEBUG - printk(KERN_INFO "PCI->OF bus map:\n"); - for (i = 0; i < pci_bus_count; i++) { - if (pci_to_OF_bus_map[i] == 0xff) - continue; - printk(KERN_INFO "%d -> %d\n", i, pci_to_OF_bus_map[i]); - } -#endif -} - -typedef int (*pci_OF_scan_iterator)(struct device_node *node, void *data); - -static struct device_node *scan_OF_pci_childs(struct device_node *parent, - pci_OF_scan_iterator filter, void *data) -{ - struct device_node *node; - struct device_node *sub_node; - - for_each_child_of_node(parent, node) { - const unsigned int *class_code; - - if (filter(node, data)) { - of_node_put(node); - return node; - } - - /* For PCI<->PCI bridges or CardBus bridges, we go down - * Note: some OFs create a parent node "multifunc-device" as - * a fake root for all functions of a multi-function device, - * we go down them as well. - */ - class_code = of_get_property(node, "class-code", NULL); - if ((!class_code || - ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && - (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && - strcmp(node->name, "multifunc-device")) - continue; - sub_node = scan_OF_pci_childs(node, filter, data); - if (sub_node) { - of_node_put(node); - return sub_node; - } - } - return NULL; -} - -static struct device_node *scan_OF_for_pci_dev(struct device_node *parent, - unsigned int devfn) -{ - struct device_node *np, *cnp; - const u32 *reg; - unsigned int psize; - - for_each_child_of_node(parent, np) { - reg = of_get_property(np, "reg", &psize); - if (reg && psize >= 4 && ((reg[0] >> 8) & 0xff) == devfn) - return np; - - /* Note: some OFs create a parent node "multifunc-device" as - * a fake root for all functions of a multi-function device, - * we go down them as well. */ - if (!strcmp(np->name, "multifunc-device")) { - cnp = scan_OF_for_pci_dev(np, devfn); - if (cnp) - return cnp; - } - } - return NULL; -} - - -static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus) -{ - struct device_node *parent, *np; - - /* Are we a root bus ? */ - if (bus->self == NULL || bus->parent == NULL) { - struct pci_controller *hose = pci_bus_to_host(bus); - if (hose == NULL) - return NULL; - return of_node_get(hose->dn); - } - - /* not a root bus, we need to get our parent */ - parent = scan_OF_for_pci_bus(bus->parent); - if (parent == NULL) - return NULL; - - /* now iterate for children for a match */ - np = scan_OF_for_pci_dev(parent, bus->self->devfn); - of_node_put(parent); - - return np; -} - -/* - * Scans the OF tree for a device node matching a PCI device - */ -struct device_node * -pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) -{ - struct device_node *parent, *np; - - pr_debug("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn); - parent = scan_OF_for_pci_bus(bus); - if (parent == NULL) - return NULL; - pr_debug(" parent is %s\n", parent ? parent->full_name : "<NULL>"); - np = scan_OF_for_pci_dev(parent, devfn); - of_node_put(parent); - pr_debug(" result is %s\n", np ? np->full_name : "<NULL>"); - - /* XXX most callers don't release the returned node - * mostly because ppc64 doesn't increase the refcount, - * we need to fix that. - */ - return np; -} -EXPORT_SYMBOL(pci_busdev_to_OF_node); - -struct device_node* -pci_device_to_OF_node(struct pci_dev *dev) -{ - return pci_busdev_to_OF_node(dev->bus, dev->devfn); -} -EXPORT_SYMBOL(pci_device_to_OF_node); - -static int -find_OF_pci_device_filter(struct device_node *node, void *data) -{ - return ((void *)node == data); -} - -/* - * Returns the PCI device matching a given OF node - */ -int -pci_device_from_OF_node(struct device_node *node, u8 *bus, u8 *devfn) -{ - const unsigned int *reg; - struct pci_controller *hose; - struct pci_dev *dev = NULL; - - /* Make sure it's really a PCI device */ - hose = pci_find_hose_for_OF_device(node); - if (!hose || !hose->dn) - return -ENODEV; - if (!scan_OF_pci_childs(hose->dn, - find_OF_pci_device_filter, (void *)node)) - return -ENODEV; - reg = of_get_property(node, "reg", NULL); - if (!reg) - return -ENODEV; - *bus = (reg[0] >> 16) & 0xff; - *devfn = ((reg[0] >> 8) & 0xff); - - /* Ok, here we need some tweak. If we have already renumbered - * all busses, we can't rely on the OF bus number any more. - * the pci_to_OF_bus_map is not enough as several PCI busses - * may match the same OF bus number. - */ - if (!pci_to_OF_bus_map) - return 0; - - for_each_pci_dev(dev) - if (pci_to_OF_bus_map[dev->bus->number] == *bus && - dev->devfn == *devfn) { - *bus = dev->bus->number; - pci_dev_put(dev); - return 0; - } - - return -ENODEV; -} -EXPORT_SYMBOL(pci_device_from_OF_node); - -/* We create the "pci-OF-bus-map" property now so it appears in the - * /proc device tree - */ -void __init -pci_create_OF_bus_map(void) -{ - struct property *of_prop; - struct device_node *dn; - - of_prop = (struct property *) alloc_bootmem(sizeof(struct property) + \ - 256); - if (!of_prop) - return; - dn = of_find_node_by_path("/"); - if (dn) { - memset(of_prop, -1, sizeof(struct property) + 256); - of_prop->name = "pci-OF-bus-map"; - of_prop->length = 256; - of_prop->value = &of_prop[1]; - prom_add_property(dn, of_prop); - of_node_put(dn); - } -} - -static void __devinit pcibios_scan_phb(struct pci_controller *hose) -{ - struct pci_bus *bus; - struct device_node *node = hose->dn; - unsigned long io_offset; - struct resource *res = &hose->io_resource; - - pr_debug("PCI: Scanning PHB %s\n", - node ? node->full_name : "<NO NAME>"); - - /* Create an empty bus for the toplevel */ - bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose); - if (bus == NULL) { - printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", - hose->global_number); - return; - } - bus.dev->of_node = of_node_get(node); - bus->secondary = hose->first_busno; - hose->bus = bus; - - /* Fixup IO space offset */ - io_offset = (unsigned long)hose->io_base_virt - isa_io_base; - res->start = (res->start + io_offset) & 0xffffffffu; - res->end = (res->end + io_offset) & 0xffffffffu; - - /* Wire up PHB bus resources */ - pcibios_setup_phb_resources(hose); - - /* Scan children */ - hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); -} - -static int __init pcibios_init(void) -{ - struct pci_controller *hose, *tmp; - int next_busno = 0; - - printk(KERN_INFO "PCI: Probing PCI hardware\n"); - - if (pci_flags & PCI_REASSIGN_ALL_BUS) { - printk(KERN_INFO "setting pci_asign_all_busses\n"); - pci_assign_all_buses = 1; - } - - /* Scan all of the recorded PCI controllers. */ - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { - if (pci_assign_all_buses) - hose->first_busno = next_busno; - hose->last_busno = 0xff; - pcibios_scan_phb(hose); - printk(KERN_INFO "calling pci_bus_add_devices()\n"); - pci_bus_add_devices(hose->bus); - if (pci_assign_all_buses || next_busno <= hose->last_busno) - next_busno = hose->last_busno + \ - pcibios_assign_bus_offset; - } - pci_bus_count = next_busno; - - /* OpenFirmware based machines need a map of OF bus - * numbers vs. kernel bus numbers since we may have to - * remap them. - */ - if (pci_assign_all_buses) - pcibios_make_OF_bus_map(); - - /* Call common code to handle resource allocation */ - pcibios_resource_survey(); - - return 0; -} - -subsys_initcall(pcibios_init); - -static struct pci_controller* -pci_bus_to_hose(int bus) -{ - struct pci_controller *hose, *tmp; - - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) - if (bus >= hose->first_busno && bus <= hose->last_busno) - return hose; - return NULL; -} - -/* Provide information on locations of various I/O regions in physical - * memory. Do this on a per-card basis so that we choose the right - * root bridge. - * Note that the returned IO or memory base is a physical address - */ - -long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) -{ - struct pci_controller *hose; - long result = -EOPNOTSUPP; - - hose = pci_bus_to_hose(bus); - if (!hose) - return -ENODEV; - - switch (which) { - case IOBASE_BRIDGE_NUMBER: - return (long)hose->first_busno; - case IOBASE_MEMORY: - return (long)hose->pci_mem_offset; - case IOBASE_IO: - return (long)hose->io_base_phys; - case IOBASE_ISA_IO: - return (long)isa_io_base; - case IOBASE_ISA_MEM: - return (long)isa_mem_base; - } - - return result; -} |