diff options
author | Anton Arapov <anton@redhat.com> | 2012-04-16 10:05:28 +0200 |
---|---|---|
committer | Anton Arapov <anton@redhat.com> | 2012-04-16 10:05:28 +0200 |
commit | b4b6116a13633898cf868f2f103c96a90c4c20f8 (patch) | |
tree | 93d1b7e2cfcdf473d8d4ff3ad141fa864f8491f6 /arch/powerpc | |
parent | edd4be777c953e5faafc80d091d3084b4343f5d3 (diff) | |
download | kernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.tar.gz kernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.tar.xz kernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.zip |
fedora kernel: d9aad82f3319f3cfd1aebc01234254ef0c37ad84v3.3.2-1
Signed-off-by: Anton Arapov <anton@redhat.com>
Diffstat (limited to 'arch/powerpc')
1626 files changed, 401986 insertions, 0 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig new file mode 100644 index 00000000000..1919634a9b3 --- /dev/null +++ b/arch/powerpc/Kconfig @@ -0,0 +1,1017 @@ +source "arch/powerpc/platforms/Kconfig.cputype" + +config PPC32 + bool + default y if !PPC64 + +config 32BIT + bool + default y if PPC32 + +config 64BIT + bool + default y if PPC64 + +config WORD_SIZE + int + default 64 if PPC64 + default 32 if !PPC64 + +config ARCH_PHYS_ADDR_T_64BIT + def_bool PPC64 || PHYS_64BIT + +config ARCH_DMA_ADDR_T_64BIT + def_bool ARCH_PHYS_ADDR_T_64BIT + +config MMU + bool + default y + +config GENERIC_CMOS_UPDATE + def_bool y + +config GENERIC_TIME_VSYSCALL + def_bool y + +config GENERIC_CLOCKEVENTS + def_bool y + +config HAVE_SETUP_PER_CPU_AREA + def_bool PPC64 + +config NEED_PER_CPU_EMBED_FIRST_CHUNK + def_bool PPC64 + +config NR_IRQS + int "Number of virtual interrupt numbers" + range 32 32768 + default "512" + help + This defines the number of virtual interrupt numbers the kernel + can manage. Virtual interrupt numbers are what you see in + /proc/interrupts. If you configure your system to have too few, + drivers will fail to load or worse - handle with care. + +config STACKTRACE_SUPPORT + bool + default y + +config HAVE_LATENCYTOP_SUPPORT + def_bool y + +config TRACE_IRQFLAGS_SUPPORT + bool + default y + +config LOCKDEP_SUPPORT + bool + default y + +config RWSEM_GENERIC_SPINLOCK + bool + +config RWSEM_XCHGADD_ALGORITHM + bool + default y + +config GENERIC_LOCKBREAK + bool + default y + depends on SMP && PREEMPT + +config ARCH_HAS_ILOG2_U32 + bool + default y + +config ARCH_HAS_ILOG2_U64 + bool + default y if 64BIT + +config ARCH_HAS_CPU_IDLE_WAIT + bool + default y + +config GENERIC_HWEIGHT + bool + default y + +config GENERIC_GPIO + bool + help + Generic GPIO API support + +config ARCH_NO_VIRT_TO_BUS + def_bool PPC64 + +config PPC + bool + default y + select OF + select OF_EARLY_FLATTREE + select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_DYNAMIC_FTRACE + select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_GRAPH_TRACER + select ARCH_WANT_OPTIONAL_GPIOLIB + select HAVE_IDE + select HAVE_IOREMAP_PROT + select HAVE_EFFICIENT_UNALIGNED_ACCESS + select HAVE_KPROBES + select HAVE_ARCH_KGDB + select HAVE_KRETPROBES + select HAVE_ARCH_TRACEHOOK + select HAVE_MEMBLOCK + select HAVE_MEMBLOCK_NODE_MAP + select HAVE_DMA_ATTRS + select HAVE_DMA_API_DEBUG + select USE_GENERIC_SMP_HELPERS if SMP + select HAVE_OPROFILE + select HAVE_SYSCALL_WRAPPERS if PPC64 + select GENERIC_ATOMIC64 if PPC32 + select HAVE_IRQ_WORK + select HAVE_PERF_EVENTS + select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64 + select HAVE_GENERIC_HARDIRQS + select HAVE_SPARSE_IRQ + select IRQ_PER_CPU + select GENERIC_IRQ_SHOW + select GENERIC_IRQ_SHOW_LEVEL + select IRQ_FORCED_THREADING + select HAVE_RCU_TABLE_FREE if SMP + select HAVE_SYSCALL_TRACEPOINTS + select HAVE_BPF_JIT if (PPC64 && NET) + select HAVE_ARCH_JUMP_LABEL + select ARCH_HAVE_NMI_SAFE_CMPXCHG + +config EARLY_PRINTK + bool + default y + +config COMPAT + bool + default y if PPC64 + select COMPAT_BINFMT_ELF + +config SYSVIPC_COMPAT + bool + depends on COMPAT && SYSVIPC + default y + +# All PPC32s use generic nvram driver through ppc_md +config GENERIC_NVRAM + bool + default y if PPC32 + +config SCHED_OMIT_FRAME_POINTER + bool + default y + +config ARCH_MAY_HAVE_PC_FDC + bool + default !PPC_PSERIES || PCI + +config PPC_OF + def_bool y + +config PPC_UDBG_16550 + bool + default n + +config GENERIC_TBSYNC + bool + default y if PPC32 && SMP + default n + +config AUDIT_ARCH + bool + default y + +config GENERIC_BUG + bool + default y + depends on BUG + +config SYS_SUPPORTS_APM_EMULATION + default y if PMAC_APM_EMU + bool + +config EPAPR_BOOT + bool + help + Used to allow a board to specify it wants an ePAPR compliant wrapper. + default n + +config DEFAULT_UIMAGE + bool + help + Used to allow a board to specify it wants a uImage built by default + default n + +config REDBOOT + bool + +config ARCH_HIBERNATION_POSSIBLE + bool + default y + +config ARCH_SUSPEND_POSSIBLE + def_bool y + depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ + (PPC_85xx && !SMP) || PPC_86xx || PPC_PSERIES || 44x || 40x + +config PPC_DCR_NATIVE + bool + default n + +config PPC_DCR_MMIO + bool + default n + +config PPC_DCR + bool + depends on PPC_DCR_NATIVE || PPC_DCR_MMIO + default y + +config PPC_OF_PLATFORM_PCI + bool + depends on PCI + depends on PPC64 # not supported on 32 bits yet + default n + +config ARCH_SUPPORTS_DEBUG_PAGEALLOC + def_bool y + +config PPC_ADV_DEBUG_REGS + bool + depends on 40x || BOOKE + default y + +config PPC_ADV_DEBUG_IACS + int + depends on PPC_ADV_DEBUG_REGS + default 4 if 44x + default 2 + +config PPC_ADV_DEBUG_DACS + int + depends on PPC_ADV_DEBUG_REGS + default 2 + +config PPC_ADV_DEBUG_DVCS + int + depends on PPC_ADV_DEBUG_REGS + default 2 if 44x + default 0 + +config PPC_ADV_DEBUG_DAC_RANGE + bool + depends on PPC_ADV_DEBUG_REGS && 44x + default y + +source "init/Kconfig" + +source "kernel/Kconfig.freezer" + +source "arch/powerpc/sysdev/Kconfig" +source "arch/powerpc/platforms/Kconfig" + +menu "Kernel options" + +config HIGHMEM + bool "High memory support" + depends on PPC32 + +source kernel/time/Kconfig +source kernel/Kconfig.hz +source kernel/Kconfig.preempt +source "fs/Kconfig.binfmt" + +config HUGETLB_PAGE_SIZE_VARIABLE + bool + depends on HUGETLB_PAGE + default y + +config MATH_EMULATION + bool "Math emulation" + depends on 4xx || 8xx || E200 || PPC_MPC832x || E500 + ---help--- + Some PowerPC chips designed for embedded applications do not have + a floating-point unit and therefore do not implement the + floating-point instructions in the PowerPC instruction set. If you + say Y here, the kernel will include code to emulate a floating-point + unit, which will allow programs that use floating-point + instructions to run. + +config 8XX_MINIMAL_FPEMU + bool "Minimal math emulation for 8xx" + depends on 8xx && !MATH_EMULATION + help + Older arch/ppc kernels still emulated a few floating point + instructions such as load and store, even when full math + emulation is disabled. Say "Y" here if you want to preserve + this behavior. + + It is recommended that you build a soft-float userspace instead. + +config IOMMU_HELPER + def_bool PPC64 + +config SWIOTLB + bool "SWIOTLB support" + default n + select IOMMU_HELPER + ---help--- + Support for IO bounce buffering for systems without an IOMMU. + This allows us to DMA to the full physical address space on + platforms where the size of a physical address is larger + than the bus address. Not all platforms support this. + +config HOTPLUG_CPU + bool "Support for enabling/disabling CPUs" + depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC || PPC_POWERNV) + ---help--- + Say Y here to be able to disable and re-enable individual + CPUs at runtime on SMP machines. + + Say N if you are unsure. + +config ARCH_CPU_PROBE_RELEASE + def_bool y + depends on HOTPLUG_CPU + +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + +config ARCH_HAS_WALK_MEMORY + def_bool y + +config ARCH_ENABLE_MEMORY_HOTREMOVE + def_bool y + +config KEXEC + bool "kexec system call (EXPERIMENTAL)" + depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP && !PPC_47x)) && EXPERIMENTAL + help + kexec is a system call that implements the ability to shutdown your + current kernel, and to start another kernel. It is like a reboot + but it is independent of the system firmware. And like a reboot + you can start any kernel with it, not just Linux. + + The name comes from the similarity to the exec system call. + + It is an ongoing process to be certain the hardware in a machine + is properly shutdown, so do not be surprised if this code does not + initially work for you. It may help to enable device hotplugging + support. As of this writing the exact hardware interface is + strongly in flux, so no good recommendation can be made. + +config CRASH_DUMP + bool "Build a kdump crash kernel" + depends on PPC64 || 6xx || FSL_BOOKE || (44x && !SMP && !PPC_47x) + select RELOCATABLE if PPC64 || 44x + select DYNAMIC_MEMSTART if FSL_BOOKE + help + Build a kernel suitable for use as a kdump capture kernel. + The same kernel binary can be used as production kernel and dump + capture kernel. + +config PHYP_DUMP + bool "Hypervisor-assisted dump (EXPERIMENTAL)" + depends on PPC_PSERIES && EXPERIMENTAL + help + Hypervisor-assisted dump is meant to be a kdump replacement + offering robustness and speed not possible without system + hypervisor assistance. + + If unsure, say "N" + +config IRQ_ALL_CPUS + bool "Distribute interrupts on all CPUs by default" + depends on SMP && !MV64360 + help + This option gives the kernel permission to distribute IRQs across + multiple CPUs. Saying N here will route all IRQs to the first + CPU. Generally saying Y is safe, although some problems have been + reported with SMP Power Macintoshes with this option enabled. + +config NUMA + bool "NUMA support" + depends on PPC64 + default y if SMP && PPC_PSERIES + +config NODES_SHIFT + int + default "8" if PPC64 + default "4" + depends on NEED_MULTIPLE_NODES + +config MAX_ACTIVE_REGIONS + int + default "256" if PPC64 + default "32" + +config ARCH_SELECT_MEMORY_MODEL + def_bool y + depends on PPC64 + +config ARCH_FLATMEM_ENABLE + def_bool y + depends on (PPC64 && !NUMA) || PPC32 + +config ARCH_SPARSEMEM_ENABLE + def_bool y + depends on PPC64 + select SPARSEMEM_VMEMMAP_ENABLE + +config ARCH_SPARSEMEM_DEFAULT + def_bool y + depends on (SMP && PPC_PSERIES) || PPC_PS3 + +config SYS_SUPPORTS_HUGETLBFS + bool + +source "mm/Kconfig" + +config ARCH_MEMORY_PROBE + def_bool y + depends on MEMORY_HOTPLUG + +# Some NUMA nodes have memory ranges that span +# other nodes. Even though a pfn is valid and +# between a node's start and end pfns, it may not +# reside on that node. See memmap_init_zone() +# for details. +config NODES_SPAN_OTHER_NODES + def_bool y + depends on NEED_MULTIPLE_NODES + +config PPC_HAS_HASH_64K + bool + depends on PPC64 + default n + +config STDBINUTILS + bool "Using standard binutils settings" + depends on 44x + default y + help + Turning this option off allows you to select 256KB PAGE_SIZE on 44x. + Note, that kernel will be able to run only those applications, + which had been compiled using binutils later than 2.17.50.0.3 with + '-zmax-page-size' set to 256K (the default is 64K). Or, if using + the older binutils, you can patch them with a trivial patch, which + changes the ELF_MAXPAGESIZE definition from 0x10000 to 0x40000. + +choice + prompt "Page size" + default PPC_4K_PAGES + help + Select the kernel logical page size. Increasing the page size + will reduce software overhead at each page boundary, allow + hardware prefetch mechanisms to be more effective, and allow + larger dma transfers increasing IO efficiency and reducing + overhead. However the utilization of memory will increase. + For example, each cached file will using a multiple of the + page size to hold its contents and the difference between the + end of file and the end of page is wasted. + + Some dedicated systems, such as software raid serving with + accelerated calculations, have shown significant increases. + + If you configure a 64 bit kernel for 64k pages but the + processor does not support them, then the kernel will simulate + them with 4k pages, loading them on demand, but with the + reduced software overhead and larger internal fragmentation. + For the 32 bit kernel, a large page option will not be offered + unless it is supported by the configured processor. + + If unsure, choose 4K_PAGES. + +config PPC_4K_PAGES + bool "4k page size" + +config PPC_16K_PAGES + bool "16k page size" if 44x + +config PPC_64K_PAGES + bool "64k page size" if 44x || PPC_STD_MMU_64 || PPC_BOOK3E_64 + select PPC_HAS_HASH_64K if PPC_STD_MMU_64 + +config PPC_256K_PAGES + bool "256k page size" if 44x + depends on !STDBINUTILS + help + Make the page size 256k. + + As the ELF standard only requires alignment to support page + sizes up to 64k, you will need to compile all of your user + space applications with a non-standard binutils settings + (see the STDBINUTILS description for details). + + Say N unless you know what you are doing. + +endchoice + +config FORCE_MAX_ZONEORDER + int "Maximum zone order" + range 9 64 if PPC64 && PPC_64K_PAGES + default "9" if PPC64 && PPC_64K_PAGES + range 13 64 if PPC64 && !PPC_64K_PAGES + default "13" if PPC64 && !PPC_64K_PAGES + range 9 64 if PPC32 && PPC_16K_PAGES + default "9" if PPC32 && PPC_16K_PAGES + range 7 64 if PPC32 && PPC_64K_PAGES + default "7" if PPC32 && PPC_64K_PAGES + range 5 64 if PPC32 && PPC_256K_PAGES + default "5" if PPC32 && PPC_256K_PAGES + range 11 64 + default "11" + help + The kernel memory allocator divides physically contiguous memory + blocks into "zones", where each zone is a power of two number of + pages. This option selects the largest power of two that the kernel + keeps in the memory allocator. If you need to allocate very large + blocks of physically contiguous memory, then you may need to + increase this value. + + This config option is actually maximum order plus one. For example, + a value of 11 means that the largest free memory block is 2^10 pages. + + The page size is not necessarily 4KB. For example, on 64-bit + systems, 64KB pages can be enabled via CONFIG_PPC_64K_PAGES. Keep + this in mind when choosing a value for this option. + +config PPC_SUBPAGE_PROT + bool "Support setting protections for 4k subpages" + depends on PPC_STD_MMU_64 && PPC_64K_PAGES + help + This option adds support for a system call to allow user programs + to set access permissions (read/write, readonly, or no access) + on the 4k subpages of each 64k page. + +config SCHED_SMT + bool "SMT (Hyperthreading) scheduler support" + depends on PPC64 && SMP + help + SMT scheduler support improves the CPU scheduler's decision making + when dealing with POWER5 cpus at a cost of slightly increased + overhead in some places. If unsure say N here. + +config CMDLINE_BOOL + bool "Default bootloader kernel arguments" + +config CMDLINE + string "Initial kernel command string" + depends on CMDLINE_BOOL + default "console=ttyS0,9600 console=tty0 root=/dev/sda2" + help + On some platforms, there is currently no way for the boot loader to + pass arguments to the kernel. For these platforms, you can supply + some command-line options at build time by entering them here. In + most cases you will need to specify the root device here. + +config EXTRA_TARGETS + string "Additional default image types" + help + List additional targets to be built by the bootwrapper here (separated + by spaces). This is useful for targets that depend of device tree + files in the .dts directory. + + Targets in this list will be build as part of the default build + target, or when the user does a 'make zImage' or a + 'make zImage.initrd'. + + If unsure, leave blank + +config ARCH_WANTS_FREEZER_CONTROL + def_bool y + depends on ADB_PMU + +source kernel/power/Kconfig + +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + depends on PROC_FS + default y + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via /proc/<pid>/seccomp, it cannot be disabled + and the task is only allowed to execute a few safe syscalls + defined by each seccomp mode. + + If unsure, say Y. Only embedded should say N here. + +endmenu + +config ISA_DMA_API + bool + default !PPC_ISERIES || PCI + +menu "Bus options" + +config ISA + bool "Support for ISA-bus hardware" + depends on PPC_PREP || PPC_CHRP + select PPC_I8259 + help + Find out whether you have ISA slots on your motherboard. ISA is the + name of a bus system, i.e. the way the CPU talks to the other stuff + inside your box. If you have an Apple machine, say N here; if you + have an IBM RS/6000 or pSeries machine or a PReP machine, say Y. If + you have an embedded board, consult your board documentation. + +config ZONE_DMA + bool + default y + +config NEED_DMA_MAP_STATE + def_bool (PPC64 || NOT_COHERENT_CACHE) + +config NEED_SG_DMA_LENGTH + def_bool y + +config GENERIC_ISA_DMA + bool + depends on ISA_DMA_API + default y + +config PPC_INDIRECT_PCI + bool + depends on PCI + default y if 40x || 44x + default n + +config EISA + bool + +config SBUS + bool + +config FSL_SOC + bool + select HAVE_CAN_FLEXCAN if NET && CAN + select PPC_CLOCK if CAN_FLEXCAN + +config FSL_PCI + bool + select PPC_INDIRECT_PCI + select PCI_QUIRKS + +config FSL_PMC + bool + default y + depends on SUSPEND && (PPC_85xx || PPC_86xx) + help + Freescale MPC85xx/MPC86xx power management controller support + (suspend/resume). For MPC83xx see platforms/83xx/suspend.c + +config PPC4xx_CPM + bool + default y + depends on SUSPEND && (44x || 40x) + help + PPC4xx Clock Power Management (CPM) support (suspend/resume). + It also enables support for two different idle states (idle-wait + and idle-doze). + +config 4xx_SOC + bool + +config FSL_LBC + bool "Freescale Local Bus support" + depends on FSL_SOC + help + Enables reporting of errors from the Freescale local bus + controller. Also contains some common code used by + drivers for specific local bus peripherals. + +config FSL_IFC + bool + depends on FSL_SOC + +config FSL_GTM + bool + depends on PPC_83xx || QUICC_ENGINE || CPM2 + help + Freescale General-purpose Timers support + +# Yes MCA RS/6000s exist but Linux-PPC does not currently support any +config MCA + bool + +# Platforms that what PCI turned unconditionally just do select PCI +# in their config node. Platforms that want to choose at config +# time should select PPC_PCI_CHOICE +config PPC_PCI_CHOICE + bool + +config PCI + bool "PCI support" if PPC_PCI_CHOICE + default y if !40x && !CPM2 && !8xx && !PPC_83xx \ + && !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON + default PCI_PERMEDIA if !4xx && !CPM2 && !8xx + default PCI_QSPAN if !4xx && !CPM2 && 8xx + select ARCH_SUPPORTS_MSI + select GENERIC_PCI_IOMAP + help + Find out whether your system includes a PCI bus. PCI is the name of + a bus system, i.e. the way the CPU talks to the other stuff inside + your box. If you say Y here, the kernel will include drivers and + infrastructure code to support PCI bus devices. + +config PCI_DOMAINS + def_bool PCI + +config PCI_SYSCALL + def_bool PCI + +config PCI_QSPAN + bool "QSpan PCI" + depends on !4xx && !CPM2 && 8xx + select PPC_I8259 + help + Say Y here if you have a system based on a Motorola 8xx-series + embedded processor with a QSPAN PCI interface, otherwise say N. + +config PCI_8260 + bool + depends on PCI && 8260 + select PPC_INDIRECT_PCI + default y + +config 8260_PCI9 + bool "Enable workaround for MPC826x erratum PCI 9" + depends on PCI_8260 && !8272 + default y + +source "drivers/pci/pcie/Kconfig" + +source "drivers/pci/Kconfig" + +source "drivers/pcmcia/Kconfig" + +source "drivers/pci/hotplug/Kconfig" + +config HAS_RAPIDIO + bool + default n + +config RAPIDIO + bool "RapidIO support" + depends on HAS_RAPIDIO || PCI + help + If you say Y here, the kernel will include drivers and + infrastructure code to support RapidIO interconnect devices. + +config FSL_RIO + bool "Freescale Embedded SRIO Controller support" + depends on RAPIDIO && HAS_RAPIDIO + default "n" + ---help--- + Include support for RapidIO controller on Freescale embedded + processors (MPC8548, MPC8641, etc). + +source "drivers/rapidio/Kconfig" + +endmenu + +config NONSTATIC_KERNEL + bool + default n + +menu "Advanced setup" + depends on PPC32 + +config ADVANCED_OPTIONS + bool "Prompt for advanced kernel configuration options" + help + This option will enable prompting for a variety of advanced kernel + configuration options. These options can cause the kernel to not + work if they are set incorrectly, but can be used to optimize certain + aspects of kernel memory management. + + Unless you know what you are doing, say N here. + +comment "Default settings for advanced configuration options are used" + depends on !ADVANCED_OPTIONS + +config LOWMEM_SIZE_BOOL + bool "Set maximum low memory" + depends on ADVANCED_OPTIONS + help + This option allows you to set the maximum amount of memory which + will be used as "low memory", that is, memory which the kernel can + access directly, without having to set up a kernel virtual mapping. + This can be useful in optimizing the layout of kernel virtual + memory. + + Say N here unless you know what you are doing. + +config LOWMEM_SIZE + hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL + default "0x30000000" + +config LOWMEM_CAM_NUM_BOOL + bool "Set number of CAMs to use to map low memory" + depends on ADVANCED_OPTIONS && FSL_BOOKE + help + This option allows you to set the maximum number of CAM slots that + will be used to map low memory. There are a limited number of slots + available and even more limited number that will fit in the L1 MMU. + However, using more entries will allow mapping more low memory. This + can be useful in optimizing the layout of kernel virtual memory. + + Say N here unless you know what you are doing. + +config LOWMEM_CAM_NUM + depends on FSL_BOOKE + int "Number of CAMs to use to map low memory" if LOWMEM_CAM_NUM_BOOL + default 3 + +config DYNAMIC_MEMSTART + bool "Enable page aligned dynamic load address for kernel (EXPERIMENTAL)" + depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && (FSL_BOOKE || 44x) + select NONSTATIC_KERNEL + help + This option enables the kernel to be loaded at any page aligned + physical address. The kernel creates a mapping from KERNELBASE to + the address where the kernel is loaded. The page size here implies + the TLB page size of the mapping for kernel on the particular platform. + Please refer to the init code for finding the TLB page size. + + DYNAMIC_MEMSTART is an easy way of implementing pseudo-RELOCATABLE + kernel image, where the only restriction is the page aligned kernel + load address. When this option is enabled, the compile time physical + address CONFIG_PHYSICAL_START is ignored. + + This option is overridden by CONFIG_RELOCATABLE + +config RELOCATABLE + bool "Build a relocatable kernel (EXPERIMENTAL)" + depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && 44x + select NONSTATIC_KERNEL + help + This builds a kernel image that is capable of running at the + location the kernel is loaded at, without any alignment restrictions. + This feature is a superset of DYNAMIC_MEMSTART and hence overrides it. + + One use is for the kexec on panic case where the recovery kernel + must live at a different physical address than the primary + kernel. + + Note: If CONFIG_RELOCATABLE=y, then the kernel runs from the address + it has been loaded at and the compile time physical addresses + CONFIG_PHYSICAL_START is ignored. However CONFIG_PHYSICAL_START + setting can still be useful to bootwrappers that need to know the + load address of the kernel (eg. u-boot/mkimage). + +config RELOCATABLE_PPC32 + def_bool y + depends on PPC32 && RELOCATABLE + +config PAGE_OFFSET_BOOL + bool "Set custom page offset address" + depends on ADVANCED_OPTIONS + help + This option allows you to set the kernel virtual address at which + the kernel will map low memory. This can be useful in optimizing + the virtual memory layout of the system. + + Say N here unless you know what you are doing. + +config PAGE_OFFSET + hex "Virtual address of memory base" if PAGE_OFFSET_BOOL + default "0xc0000000" + +config KERNEL_START_BOOL + bool "Set custom kernel base address" + depends on ADVANCED_OPTIONS + help + This option allows you to set the kernel virtual address at which + the kernel will be loaded. Normally this should match PAGE_OFFSET + however there are times (like kdump) that one might not want them + to be the same. + + Say N here unless you know what you are doing. + +config KERNEL_START + hex "Virtual address of kernel base" if KERNEL_START_BOOL + default PAGE_OFFSET if PAGE_OFFSET_BOOL + default "0xc2000000" if CRASH_DUMP && !NONSTATIC_KERNEL + default "0xc0000000" + +config PHYSICAL_START_BOOL + bool "Set physical address where the kernel is loaded" + depends on ADVANCED_OPTIONS && FLATMEM && FSL_BOOKE + help + This gives the physical address where the kernel is loaded. + + Say N here unless you know what you are doing. + +config PHYSICAL_START + hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL + default "0x02000000" if PPC_STD_MMU && CRASH_DUMP && !NONSTATIC_KERNEL + default "0x00000000" + +config PHYSICAL_ALIGN + hex + default "0x04000000" if FSL_BOOKE + help + This value puts the alignment restrictions on physical address + where kernel is loaded and run from. Kernel is compiled for an + address which meets above alignment restriction. + +config TASK_SIZE_BOOL + bool "Set custom user task size" + depends on ADVANCED_OPTIONS + help + This option allows you to set the amount of virtual address space + allocated to user tasks. This can be useful in optimizing the + virtual memory layout of the system. + + Say N here unless you know what you are doing. + +config TASK_SIZE + hex "Size of user task space" if TASK_SIZE_BOOL + default "0x80000000" if PPC_PREP || PPC_8xx + default "0xc0000000" + +config CONSISTENT_SIZE_BOOL + bool "Set custom consistent memory pool size" + depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE + help + This option allows you to set the size of the + consistent memory pool. This pool of virtual memory + is used to make consistent memory allocations. + +config CONSISTENT_SIZE + hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL + default "0x00200000" if NOT_COHERENT_CACHE + +config PIN_TLB + bool "Pinned Kernel TLBs (860 ONLY)" + depends on ADVANCED_OPTIONS && 8xx +endmenu + +if PPC64 +config RELOCATABLE + bool "Build a relocatable kernel" + select NONSTATIC_KERNEL + help + This builds a kernel image that is capable of running anywhere + in the RMA (real memory area) at any 16k-aligned base address. + The kernel is linked as a position-independent executable (PIE) + and contains dynamic relocations which are processed early + in the bootup process. + + One use is for the kexec on panic case where the recovery kernel + must live at a different physical address than the primary + kernel. + +config PAGE_OFFSET + hex + default "0xc000000000000000" +config KERNEL_START + hex + default "0xc000000000000000" +config PHYSICAL_START + hex + default "0x00000000" +endif + +source "net/Kconfig" + +source "drivers/Kconfig" + +source "fs/Kconfig" + +source "arch/powerpc/sysdev/qe_lib/Kconfig" + +source "lib/Kconfig" + +source "arch/powerpc/Kconfig.debug" + +source "security/Kconfig" + +config KEYS_COMPAT + bool + depends on COMPAT && KEYS + default y + +source "crypto/Kconfig" + +config PPC_CLOCK + bool + default n + select HAVE_CLK + +config PPC_LIB_RHEAP + bool + +source "arch/powerpc/kvm/Kconfig" diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug new file mode 100644 index 00000000000..4ccb2a009f7 --- /dev/null +++ b/arch/powerpc/Kconfig.debug @@ -0,0 +1,351 @@ +menu "Kernel hacking" + +source "lib/Kconfig.debug" + +config PPC_DISABLE_WERROR + bool "Don't build arch/powerpc code with -Werror" + default n + help + This option tells the compiler NOT to build the code under + arch/powerpc with the -Werror flag (which means warnings + are treated as errors). + + Only enable this if you are hitting a build failure in the + arch/powerpc code caused by a warning, and you don't feel + inclined to fix it. + +config PPC_WERROR + bool + depends on !PPC_DISABLE_WERROR + default y + +config PRINT_STACK_DEPTH + int "Stack depth to print" if DEBUG_KERNEL + default 64 + help + This option allows you to set the stack depth that the kernel + prints in stack traces. This can be useful if your display is + too small and stack traces cause important information to + scroll off the screen. + +config DEBUG_STACKOVERFLOW + bool "Check for stack overflows" + depends on DEBUG_KERNEL + help + This option will cause messages to be printed if free stack space + drops below a certain limit. + +config HCALL_STATS + bool "Hypervisor call instrumentation" + depends on PPC_PSERIES && DEBUG_FS && TRACEPOINTS + help + Adds code to keep track of the number of hypervisor calls made and + the amount of time spent in hypervisor calls. Wall time spent in + each call is always calculated, and if available CPU cycles spent + are also calculated. A directory named hcall_inst is added at the + root of the debugfs filesystem. Within the hcall_inst directory + are files that contain CPU specific call statistics. + + This option will add a small amount of overhead to all hypervisor + calls. + +config PPC_EMULATED_STATS + bool "Emulated instructions tracking" + depends on DEBUG_FS + help + Adds code to keep track of the number of instructions that are + emulated by the in-kernel emulator. Counters for the various classes + of emulated instructions are available under + powerpc/emulated_instructions/ in the root of the debugfs file + system. Optionally (controlled by + powerpc/emulated_instructions/do_warn in debugfs), rate-limited + warnings can be printed to the console when instructions are + emulated. + +config CODE_PATCHING_SELFTEST + bool "Run self-tests of the code-patching code." + depends on DEBUG_KERNEL + default n + +config FTR_FIXUP_SELFTEST + bool "Run self-tests of the feature-fixup code." + depends on DEBUG_KERNEL + default n + +config MSI_BITMAP_SELFTEST + bool "Run self-tests of the MSI bitmap code." + depends on DEBUG_KERNEL + default n + +config XMON + bool "Include xmon kernel debugger" + depends on DEBUG_KERNEL + help + Include in-kernel hooks for the xmon kernel monitor/debugger. + Unless you are intending to debug the kernel, say N here. + Make sure to enable also CONFIG_BOOTX_TEXT on Macs. Otherwise + nothing will appear on the screen (xmon writes directly to the + framebuffer memory). + The cmdline option 'xmon' or 'xmon=early' will drop into xmon + very early during boot. 'xmon=on' will just enable the xmon + debugger hooks. 'xmon=off' will disable the debugger hooks + if CONFIG_XMON_DEFAULT is set. + xmon will print a backtrace on the very first invocation. + 'xmon=nobt' will disable this autobacktrace. + +config XMON_DEFAULT + bool "Enable xmon by default" + depends on XMON + help + xmon is normally disabled unless booted with 'xmon=on'. + Use 'xmon=off' to disable xmon init during runtime. + +config XMON_DISASSEMBLY + bool "Include disassembly support in xmon" + depends on XMON + default y + help + Include support for disassembling in xmon. You probably want + to say Y here, unless you're building for a memory-constrained + system. + +config DEBUGGER + bool + depends on KGDB || XMON + default y + +config VIRQ_DEBUG + bool "Expose hardware/virtual IRQ mapping via debugfs" + depends on DEBUG_FS + help + This option will show the mapping relationship between hardware irq + numbers and virtual irq numbers. The mapping is exposed via debugfs + in the file powerpc/virq_mapping. + + If you don't know what this means you don't need it. + +config BDI_SWITCH + bool "Include BDI-2000 user context switcher" + depends on DEBUG_KERNEL && PPC32 + help + Include in-kernel support for the Abatron BDI2000 debugger. + Unless you are intending to debug the kernel with one of these + machines, say N here. + +config BOOTX_TEXT + bool "Support for early boot text console (BootX or OpenFirmware only)" + depends on PPC_OF && PPC_BOOK3S + help + Say Y here to see progress messages from the boot firmware in text + mode. Requires either BootX or Open Firmware. + +config PPC_EARLY_DEBUG + bool "Early debugging (dangerous)" + help + Say Y to enable some early debugging facilities that may be available + for your processor/board combination. Those facilities are hacks + intended to debug problems early during boot, this should not be + enabled in a production kernel. + Note that enabling this will also cause the kernel default log level + to be pushed to max automatically very early during boot + +choice + prompt "Early debugging console" + depends on PPC_EARLY_DEBUG + help + Use the selected console for early debugging. Careful, if you + enable debugging for the wrong type of machine your kernel + _will not boot_. + +config PPC_EARLY_DEBUG_LPAR + bool "LPAR HV Console" + depends on PPC_PSERIES + help + Select this to enable early debugging for a machine with a HVC + console on vterm 0. + +config PPC_EARLY_DEBUG_LPAR_HVSI + bool "LPAR HVSI Console" + depends on PPC_PSERIES + help + Select this to enable early debugging for a machine with a HVSI + console on a specified vterm. + +config PPC_EARLY_DEBUG_G5 + bool "Apple G5" + depends on PPC_PMAC64 + help + Select this to enable early debugging for Apple G5 machines. + +config PPC_EARLY_DEBUG_RTAS_PANEL + bool "RTAS Panel" + depends on PPC_RTAS + help + Select this to enable early debugging via the RTAS panel. + +config PPC_EARLY_DEBUG_RTAS_CONSOLE + bool "RTAS Console" + depends on PPC_RTAS + select UDBG_RTAS_CONSOLE + help + Select this to enable early debugging via the RTAS console. + +config PPC_EARLY_DEBUG_MAPLE + bool "Maple real mode" + depends on PPC_MAPLE + help + Select this to enable early debugging for Maple. + +config PPC_EARLY_DEBUG_ISERIES + bool "iSeries HV Console" + depends on PPC_ISERIES + help + Select this to enable early debugging for legacy iSeries. You need + to hit "Ctrl-x Ctrl-x" to see the messages on the console. + +config PPC_EARLY_DEBUG_PAS_REALMODE + bool "PA Semi real mode" + depends on PPC_PASEMI + help + Select this to enable early debugging for PA Semi. + Output will be on UART0. + +config PPC_EARLY_DEBUG_BEAT + bool "Beat HV Console" + depends on PPC_CELLEB + select PPC_UDBG_BEAT + help + Select this to enable early debugging for Celleb with Beat. + +config PPC_EARLY_DEBUG_44x + bool "Early serial debugging for IBM/AMCC 44x CPUs" + # PPC_EARLY_DEBUG on 440 leaves AS=1 mappings above the TLB high water + # mark, which doesn't work with current 440 KVM. + depends on 44x && !KVM + help + Select this to enable early debugging for IBM 44x chips via the + inbuilt serial port. If you enable this, ensure you set + PPC_EARLY_DEBUG_44x_PHYSLOW below to suit your target board. + +config PPC_EARLY_DEBUG_40x + bool "Early serial debugging for IBM/AMCC 40x CPUs" + depends on 40x + help + Select this to enable early debugging for IBM 40x chips via the + inbuilt serial port. This works on chips with a 16550 compatible + UART. Xilinx chips with uartlite cannot use this option. + +config PPC_EARLY_DEBUG_CPM + bool "Early serial debugging for Freescale CPM-based serial ports" + depends on SERIAL_CPM + select PIN_TLB if PPC_8xx + help + Select this to enable early debugging for Freescale chips + using a CPM-based serial port. This assumes that the bootwrapper + has run, and set up the CPM in a particular way. + +config PPC_EARLY_DEBUG_USBGECKO + bool "Early debugging through the USB Gecko adapter" + depends on GAMECUBE_COMMON + select USBGECKO_UDBG + help + Select this to enable early debugging for Nintendo GameCube/Wii + consoles via an external USB Gecko adapter. + +config PPC_EARLY_DEBUG_WSP + bool "Early debugging via WSP's internal UART" + depends on PPC_WSP + select PPC_UDBG_16550 + +config PPC_EARLY_DEBUG_PS3GELIC + bool "Early debugging through the PS3 Ethernet port" + depends on PPC_PS3 + select PS3GELIC_UDBG + help + Select this to enable early debugging for the PlayStation3 via + UDP broadcasts sent out through the Ethernet port. + +config PPC_EARLY_DEBUG_OPAL_RAW + bool "OPAL raw console" + depends on HVC_OPAL + help + Select this to enable early debugging for the PowerNV platform + using a "raw" console + +config PPC_EARLY_DEBUG_OPAL_HVSI + bool "OPAL hvsi console" + depends on HVC_OPAL + help + Select this to enable early debugging for the PowerNV platform + using an "hvsi" console + +endchoice + +config PPC_EARLY_DEBUG_OPAL + def_bool y + depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI + + +config PPC_EARLY_DEBUG_HVSI_VTERMNO + hex "vterm number to use with early debug HVSI" + depends on PPC_EARLY_DEBUG_LPAR_HVSI + default "0x30000000" + help + You probably want 0x30000000 for your first serial port and + 0x30000001 for your second one + +config PPC_EARLY_DEBUG_OPAL_VTERMNO + hex "vterm number to use with OPAL early debug" + depends on PPC_EARLY_DEBUG_OPAL + default "0" + help + This correspond to which /dev/hvcN you want to use for early + debug. + + On OPAL v1 (takeover) this should always be 0 + On OPAL v2, this will be 0 for network console and 1 or 2 for + the machine built-in serial ports. + +config PPC_EARLY_DEBUG_44x_PHYSLOW + hex "Low 32 bits of early debug UART physical address" + depends on PPC_EARLY_DEBUG_44x + default "0x40000200" + help + You probably want 0x40000200 for ebony boards and + 0x40000300 for taishan + +config PPC_EARLY_DEBUG_44x_PHYSHIGH + hex "EPRN of early debug UART physical address" + depends on PPC_EARLY_DEBUG_44x + default "0x1" + +config PPC_EARLY_DEBUG_40x_PHYSADDR + hex "Early debug UART physical address" + depends on PPC_EARLY_DEBUG_40x + default "0xef600300" + +config PPC_EARLY_DEBUG_CPM_ADDR + hex "CPM UART early debug transmit descriptor address" + depends on PPC_EARLY_DEBUG_CPM + default "0xfa202008" if PPC_EP88XC + default "0xf0001ff8" if CPM2 + default "0xff002008" if CPM1 + help + This specifies the address of the transmit descriptor + used for early debug output. Because it is needed before + platform probing is done, all platforms selected must + share the same address. + +config STRICT_DEVMEM + def_bool y + prompt "Filter access to /dev/mem" + help + This option restricts access to /dev/mem. If this option is + disabled, you allow userspace access to all memory, including + kernel and userspace memory. Accidental memory access is likely + to be disastrous. + Memory access is required for experts who want to debug the kernel. + + If you are unsure, say Y. + +endmenu diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile new file mode 100644 index 00000000000..b8b105c01c6 --- /dev/null +++ b/arch/powerpc/Makefile @@ -0,0 +1,259 @@ +# This file is included by the global makefile so that you can add your own +# architecture-specific flags and dependencies. Remember to do have actions +# for "archclean" and "archdep" for cleaning up and making dependencies for +# this architecture. +# +# 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. +# +# Copyright (C) 1994 by Linus Torvalds +# Changes for PPC by Gary Thomas +# Rewritten by Cort Dougan and Paul Mackerras +# + +HAS_BIARCH := $(call cc-option-yn, -m32) + +# Set default 32 bits cross compilers for vdso and boot wrapper +CROSS32_COMPILE ?= + +CROSS32CC := $(CROSS32_COMPILE)gcc +CROSS32AR := $(CROSS32_COMPILE)ar + +ifeq ($(HAS_BIARCH),y) +ifeq ($(CROSS32_COMPILE),) +CROSS32CC := $(CC) -m32 +CROSS32AR := GNUTARGET=elf32-powerpc $(AR) +endif +endif + +export CROSS32CC CROSS32AR + +ifeq ($(CROSS_COMPILE),) +KBUILD_DEFCONFIG := $(shell uname -m)_defconfig +else +KBUILD_DEFCONFIG := ppc64_defconfig +endif + +ifeq ($(CONFIG_PPC64),y) +OLDARCH := ppc64 + +new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi) + +ifeq ($(new_nm),y) +NM := $(NM) --synthetic +endif + +else +OLDARCH := ppc +endif + +# It seems there are times we use this Makefile without +# including the config file, but this replicates the old behaviour +ifeq ($(CONFIG_WORD_SIZE),) +CONFIG_WORD_SIZE := 32 +endif + +UTS_MACHINE := $(OLDARCH) + +ifeq ($(HAS_BIARCH),y) +override AS += -a$(CONFIG_WORD_SIZE) +override LD += -m elf$(CONFIG_WORD_SIZE)ppc +override CC += -m$(CONFIG_WORD_SIZE) +override AR := GNUTARGET=elf$(CONFIG_WORD_SIZE)-powerpc $(AR) +endif + +LDFLAGS_vmlinux-y := -Bstatic +LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie +LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-y) + +CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=no -mcall-aixdesc +CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple +KBUILD_CPPFLAGS += -Iarch/$(ARCH) +KBUILD_AFLAGS += -Iarch/$(ARCH) +KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y) +CPP = $(CC) -E $(KBUILD_CFLAGS) + +CHECKFLAGS += -m$(CONFIG_WORD_SIZE) -D__powerpc__ -D__powerpc$(CONFIG_WORD_SIZE)__ + +ifeq ($(CONFIG_PPC64),y) +GCC_BROKEN_VEC := $(call cc-ifversion, -lt, 0400, y) + +ifeq ($(CONFIG_POWER4_ONLY),y) +ifeq ($(CONFIG_ALTIVEC),y) +ifeq ($(GCC_BROKEN_VEC),y) + KBUILD_CFLAGS += $(call cc-option,-mcpu=970) +else + KBUILD_CFLAGS += $(call cc-option,-mcpu=power4) +endif +else + KBUILD_CFLAGS += $(call cc-option,-mcpu=power4) +endif +else + KBUILD_CFLAGS += $(call cc-option,-mtune=power4) +endif +endif + +KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o + +ifeq ($(CONFIG_TUNE_CELL),y) + KBUILD_CFLAGS += $(call cc-option,-mtune=cell) +endif + +# No AltiVec instruction when building kernel +KBUILD_CFLAGS += $(call cc-option,-mno-altivec) + +# No SPE instruction when building kernel +# (We use all available options to help semi-broken compilers) +KBUILD_CFLAGS += $(call cc-option,-mno-spe) +KBUILD_CFLAGS += $(call cc-option,-mspe=no) + +# Enable unit-at-a-time mode when possible. It shrinks the +# kernel considerably. +KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) + +# FIXME: the module load should be taught about the additional relocs +# generated by this. +# revert to pre-gcc-4.4 behaviour of .eh_frame +KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) + +# Never use string load/store instructions as they are +# often slow when they are implemented at all +KBUILD_CFLAGS += -mno-string + +ifeq ($(CONFIG_6xx),y) +KBUILD_CFLAGS += -mcpu=powerpc +endif + +# Work around a gcc code-gen bug with -fno-omit-frame-pointer. +ifeq ($(CONFIG_FUNCTION_TRACER),y) +KBUILD_CFLAGS += -mno-sched-epilog +endif + +cpu-as-$(CONFIG_4xx) += -Wa,-m405 +cpu-as-$(CONFIG_ALTIVEC) += -Wa,-maltivec +cpu-as-$(CONFIG_E500) += -Wa,-me500 +cpu-as-$(CONFIG_E200) += -Wa,-me200 + +KBUILD_AFLAGS += $(cpu-as-y) +KBUILD_CFLAGS += $(cpu-as-y) + +head-y := arch/powerpc/kernel/head_$(CONFIG_WORD_SIZE).o +head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o +head-$(CONFIG_40x) := arch/powerpc/kernel/head_40x.o +head-$(CONFIG_44x) := arch/powerpc/kernel/head_44x.o +head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o + +head-$(CONFIG_PPC64) += arch/powerpc/kernel/entry_64.o +head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o +head-$(CONFIG_ALTIVEC) += arch/powerpc/kernel/vector.o + +core-y += arch/powerpc/kernel/ \ + arch/powerpc/mm/ \ + arch/powerpc/lib/ \ + arch/powerpc/sysdev/ \ + arch/powerpc/platforms/ \ + arch/powerpc/math-emu/ \ + arch/powerpc/net/ +core-$(CONFIG_XMON) += arch/powerpc/xmon/ +core-$(CONFIG_KVM) += arch/powerpc/kvm/ + +drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ + +# Default to zImage, override when needed +all: zImage + +# With make 3.82 we cannot mix normal and wildcard targets +BOOT_TARGETS1 := zImage zImage.initrd uImage +BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% uImage.% + +PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) + +boot := arch/$(ARCH)/boot + +ifeq ($(CONFIG_RELOCATABLE),y) +quiet_cmd_relocs_check = CALL $< + cmd_relocs_check = perl $< "$(OBJDUMP)" "$(obj)/vmlinux" + +PHONY += relocs_check +relocs_check: arch/powerpc/relocs_check.pl vmlinux + $(call cmd,relocs_check) + +zImage: relocs_check +endif + +$(BOOT_TARGETS1): vmlinux + $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) +$(BOOT_TARGETS2): vmlinux + $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) + + +bootwrapper_install: + $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) + +%.dtb: + $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) + +define archhelp + @echo '* zImage - Build default images selected by kernel config' + @echo ' zImage.* - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)' + @echo ' uImage - U-Boot native image format' + @echo ' cuImage.<dt> - Backwards compatible U-Boot image for older' + @echo ' versions which do not support device trees' + @echo ' dtbImage.<dt> - zImage with an embedded device tree blob' + @echo ' simpleImage.<dt> - Firmware independent image.' + @echo ' treeImage.<dt> - Support for older IBM 4xx firmware (not U-Boot)' + @echo ' install - Install kernel using' + @echo ' (your) ~/bin/$(INSTALLKERNEL) or' + @echo ' (distribution) /sbin/$(INSTALLKERNEL) or' + @echo ' install to $$(INSTALL_PATH) and run lilo' + @echo ' *_defconfig - Select default config from arch/$(ARCH)/configs' + @echo '' + @echo ' Targets with <dt> embed a device tree blob inside the image' + @echo ' These targets support board with firmware that does not' + @echo ' support passing a device tree directly. Replace <dt> with the' + @echo ' name of a dts file from the arch/$(ARCH)/boot/dts/ directory' + @echo ' (minus the .dts extension).' +endef + +install: + $(Q)$(MAKE) $(build)=$(boot) install + +vdso_install: +ifeq ($(CONFIG_PPC64),y) + $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@ +endif + $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@ + +archclean: + $(Q)$(MAKE) $(clean)=$(boot) + +archprepare: checkbin + +# Use the file '.tmp_gas_check' for binutils tests, as gas won't output +# to stdout and these checks are run even on install targets. +TOUT := .tmp_gas_check +# Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec +# instructions. +# gcc-3.4 and binutils-2.14 are a fatal combination. + +checkbin: + @if test "$(call cc-version)" = "0304" ; then \ + if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \ + echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \ + echo 'correctly with gcc-3.4 and your version of binutils.'; \ + echo '*** Please upgrade your binutils or downgrade your gcc'; \ + false; \ + fi ; \ + fi + @if test "$(call cc-fullversion)" = "040200" \ + && test "x${CONFIG_MODULES}${CONFIG_PPC64}" = "xyy" ; then \ + echo -n '*** GCC-4.2.0 cannot compile the 64-bit powerpc ' ; \ + echo 'kernel with modules enabled.' ; \ + echo -n '*** Please use a different GCC version or ' ; \ + echo 'disable kernel modules' ; \ + false ; \ + fi + +CLEAN_FILES += $(TOUT) + diff --git a/arch/powerpc/boot/44x.h b/arch/powerpc/boot/44x.h new file mode 100644 index 00000000000..02563443788 --- /dev/null +++ b/arch/powerpc/boot/44x.h @@ -0,0 +1,16 @@ +/* + * PowerPC 44x related functions + * + * Copyright 2007 David Gibson, IBM Corporation. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#ifndef _PPC_BOOT_44X_H_ +#define _PPC_BOOT_44X_H_ + +void ebony_init(void *mac0, void *mac1); +void bamboo_init(void *mac0, void *mac1); + +#endif /* _PPC_BOOT_44X_H_ */ diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c new file mode 100644 index 00000000000..9d3bd4c45a2 --- /dev/null +++ b/arch/powerpc/boot/4xx.c @@ -0,0 +1,803 @@ +/* + * Copyright 2007 David Gibson, IBM Corporation. + * + * Based on earlier code: + * Matt Porter <mporter@kernel.crashing.org> + * Copyright 2002-2005 MontaVista Software Inc. + * + * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> + * Copyright (c) 2003, 2004 Zultys Technologies + * + * Copyright (C) 2009 Wind River Systems, Inc. + * Updated for supporting PPC405EX on Kilauea. + * Tiejun Chen <tiejun.chen@windriver.com> + * + * 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. + */ +#include <stddef.h> +#include "types.h" +#include "string.h" +#include "stdio.h" +#include "ops.h" +#include "reg.h" +#include "dcr.h" + +static unsigned long chip_11_errata(unsigned long memsize) +{ + unsigned long pvr; + + pvr = mfpvr(); + + switch (pvr & 0xf0000ff0) { + case 0x40000850: + case 0x400008d0: + case 0x200008d0: + memsize -= 4096; + break; + default: + break; + } + + return memsize; +} + +/* Read the 4xx SDRAM controller to get size of system memory. */ +void ibm4xx_sdram_fixup_memsize(void) +{ + int i; + unsigned long memsize, bank_config; + + memsize = 0; + for (i = 0; i < ARRAY_SIZE(sdram_bxcr); i++) { + bank_config = SDRAM0_READ(sdram_bxcr[i]); + if (bank_config & SDRAM_CONFIG_BANK_ENABLE) + memsize += SDRAM_CONFIG_BANK_SIZE(bank_config); + } + + memsize = chip_11_errata(memsize); + dt_fixup_memory(0, memsize); +} + +/* Read the 440SPe MQ controller to get size of system memory. */ +#define DCRN_MQ0_B0BAS 0x40 +#define DCRN_MQ0_B1BAS 0x41 +#define DCRN_MQ0_B2BAS 0x42 +#define DCRN_MQ0_B3BAS 0x43 + +static u64 ibm440spe_decode_bas(u32 bas) +{ + u64 base = ((u64)(bas & 0xFFE00000u)) << 2; + + /* open coded because I'm paranoid about invalid values */ + switch ((bas >> 4) & 0xFFF) { + case 0: + return 0; + case 0xffc: + return base + 0x000800000ull; + case 0xff8: + return base + 0x001000000ull; + case 0xff0: + return base + 0x002000000ull; + case 0xfe0: + return base + 0x004000000ull; + case 0xfc0: + return base + 0x008000000ull; + case 0xf80: + return base + 0x010000000ull; + case 0xf00: + return base + 0x020000000ull; + case 0xe00: + return base + 0x040000000ull; + case 0xc00: + return base + 0x080000000ull; + case 0x800: + return base + 0x100000000ull; + } + printf("Memory BAS value 0x%08x unsupported !\n", bas); + return 0; +} + +void ibm440spe_fixup_memsize(void) +{ + u64 banktop, memsize = 0; + + /* Ultimately, we should directly construct the memory node + * so we are able to handle holes in the memory address space + */ + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B0BAS)); + if (banktop > memsize) + memsize = banktop; + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B1BAS)); + if (banktop > memsize) + memsize = banktop; + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B2BAS)); + if (banktop > memsize) + memsize = banktop; + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B3BAS)); + if (banktop > memsize) + memsize = banktop; + + dt_fixup_memory(0, memsize); +} + + +/* 4xx DDR1/2 Denali memory controller support */ +/* DDR0 registers */ +#define DDR0_02 2 +#define DDR0_08 8 +#define DDR0_10 10 +#define DDR0_14 14 +#define DDR0_42 42 +#define DDR0_43 43 + +/* DDR0_02 */ +#define DDR_START 0x1 +#define DDR_START_SHIFT 0 +#define DDR_MAX_CS_REG 0x3 +#define DDR_MAX_CS_REG_SHIFT 24 +#define DDR_MAX_COL_REG 0xf +#define DDR_MAX_COL_REG_SHIFT 16 +#define DDR_MAX_ROW_REG 0xf +#define DDR_MAX_ROW_REG_SHIFT 8 +/* DDR0_08 */ +#define DDR_DDR2_MODE 0x1 +#define DDR_DDR2_MODE_SHIFT 0 +/* DDR0_10 */ +#define DDR_CS_MAP 0x3 +#define DDR_CS_MAP_SHIFT 8 +/* DDR0_14 */ +#define DDR_REDUC 0x1 +#define DDR_REDUC_SHIFT 16 +/* DDR0_42 */ +#define DDR_APIN 0x7 +#define DDR_APIN_SHIFT 24 +/* DDR0_43 */ +#define DDR_COL_SZ 0x7 +#define DDR_COL_SZ_SHIFT 8 +#define DDR_BANK8 0x1 +#define DDR_BANK8_SHIFT 0 + +#define DDR_GET_VAL(val, mask, shift) (((val) >> (shift)) & (mask)) + +/* + * Some U-Boot versions set the number of chipselects to two + * for Sequoia/Rainier boards while they only have one chipselect + * hardwired. Hardcode the number of chipselects to one + * for sequioa/rainer board models or read the actual value + * from the memory controller register DDR0_10 otherwise. + */ +static inline u32 ibm4xx_denali_get_cs(void) +{ + void *devp; + char model[64]; + u32 val, cs; + + devp = finddevice("/"); + if (!devp) + goto read_cs; + + if (getprop(devp, "model", model, sizeof(model)) <= 0) + goto read_cs; + + model[sizeof(model)-1] = 0; + + if (!strcmp(model, "amcc,sequoia") || + !strcmp(model, "amcc,rainier")) + return 1; + +read_cs: + /* get CS value */ + val = SDRAM0_READ(DDR0_10); + + val = DDR_GET_VAL(val, DDR_CS_MAP, DDR_CS_MAP_SHIFT); + cs = 0; + while (val) { + if (val & 0x1) + cs++; + val = val >> 1; + } + return cs; +} + +void ibm4xx_denali_fixup_memsize(void) +{ + u32 val, max_cs, max_col, max_row; + u32 cs, col, row, bank, dpath; + unsigned long memsize; + + val = SDRAM0_READ(DDR0_02); + if (!DDR_GET_VAL(val, DDR_START, DDR_START_SHIFT)) + fatal("DDR controller is not initialized\n"); + + /* get maximum cs col and row values */ + max_cs = DDR_GET_VAL(val, DDR_MAX_CS_REG, DDR_MAX_CS_REG_SHIFT); + max_col = DDR_GET_VAL(val, DDR_MAX_COL_REG, DDR_MAX_COL_REG_SHIFT); + max_row = DDR_GET_VAL(val, DDR_MAX_ROW_REG, DDR_MAX_ROW_REG_SHIFT); + + cs = ibm4xx_denali_get_cs(); + if (!cs) + fatal("No memory installed\n"); + if (cs > max_cs) + fatal("DDR wrong CS configuration\n"); + + /* get data path bytes */ + val = SDRAM0_READ(DDR0_14); + + if (DDR_GET_VAL(val, DDR_REDUC, DDR_REDUC_SHIFT)) + dpath = 4; /* 32 bits */ + else + dpath = 8; /* 64 bits */ + + /* get address pins (rows) */ + val = SDRAM0_READ(DDR0_42); + + row = DDR_GET_VAL(val, DDR_APIN, DDR_APIN_SHIFT); + if (row > max_row) + fatal("DDR wrong APIN configuration\n"); + row = max_row - row; + + /* get collomn size and banks */ + val = SDRAM0_READ(DDR0_43); + + col = DDR_GET_VAL(val, DDR_COL_SZ, DDR_COL_SZ_SHIFT); + if (col > max_col) + fatal("DDR wrong COL configuration\n"); + col = max_col - col; + + if (DDR_GET_VAL(val, DDR_BANK8, DDR_BANK8_SHIFT)) + bank = 8; /* 8 banks */ + else + bank = 4; /* 4 banks */ + + memsize = cs * (1 << (col+row)) * bank * dpath; + memsize = chip_11_errata(memsize); + dt_fixup_memory(0, memsize); +} + +#define SPRN_DBCR0_40X 0x3F2 +#define SPRN_DBCR0_44X 0x134 +#define DBCR0_RST_SYSTEM 0x30000000 + +void ibm44x_dbcr_reset(void) +{ + unsigned long tmp; + + asm volatile ( + "mfspr %0,%1\n" + "oris %0,%0,%2@h\n" + "mtspr %1,%0" + : "=&r"(tmp) : "i"(SPRN_DBCR0_44X), "i"(DBCR0_RST_SYSTEM) + ); + +} + +void ibm40x_dbcr_reset(void) +{ + unsigned long tmp; + + asm volatile ( + "mfspr %0,%1\n" + "oris %0,%0,%2@h\n" + "mtspr %1,%0" + : "=&r"(tmp) : "i"(SPRN_DBCR0_40X), "i"(DBCR0_RST_SYSTEM) + ); +} + +#define EMAC_RESET 0x20000000 +void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1) +{ + /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't + * do this for us + */ + if (emac0) + *emac0 = EMAC_RESET; + if (emac1) + *emac1 = EMAC_RESET; + + mtdcr(DCRN_MAL0_CFG, MAL_RESET); + while (mfdcr(DCRN_MAL0_CFG) & MAL_RESET) + ; /* loop until reset takes effect */ +} + +/* Read 4xx EBC bus bridge registers to get mappings of the peripheral + * banks into the OPB address space */ +void ibm4xx_fixup_ebc_ranges(const char *ebc) +{ + void *devp; + u32 bxcr; + u32 ranges[EBC_NUM_BANKS*4]; + u32 *p = ranges; + int i; + + for (i = 0; i < EBC_NUM_BANKS; i++) { + mtdcr(DCRN_EBC0_CFGADDR, EBC_BXCR(i)); + bxcr = mfdcr(DCRN_EBC0_CFGDATA); + + if ((bxcr & EBC_BXCR_BU) != EBC_BXCR_BU_OFF) { + *p++ = i; + *p++ = 0; + *p++ = bxcr & EBC_BXCR_BAS; + *p++ = EBC_BXCR_BANK_SIZE(bxcr); + } + } + + devp = finddevice(ebc); + if (! devp) + fatal("Couldn't locate EBC node %s\n\r", ebc); + + setprop(devp, "ranges", ranges, (p - ranges) * sizeof(u32)); +} + +/* Calculate 440GP clocks */ +void ibm440gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk) +{ + u32 sys0 = mfdcr(DCRN_CPC0_SYS0); + u32 cr0 = mfdcr(DCRN_CPC0_CR0); + u32 cpu, plb, opb, ebc, tb, uart0, uart1, m; + u32 opdv = CPC0_SYS0_OPDV(sys0); + u32 epdv = CPC0_SYS0_EPDV(sys0); + + if (sys0 & CPC0_SYS0_BYPASS) { + /* Bypass system PLL */ + cpu = plb = sys_clk; + } else { + if (sys0 & CPC0_SYS0_EXTSL) + /* PerClk */ + m = CPC0_SYS0_FWDVB(sys0) * opdv * epdv; + else + /* CPU clock */ + m = CPC0_SYS0_FBDV(sys0) * CPC0_SYS0_FWDVA(sys0); + cpu = sys_clk * m / CPC0_SYS0_FWDVA(sys0); + plb = sys_clk * m / CPC0_SYS0_FWDVB(sys0); + } + + opb = plb / opdv; + ebc = opb / epdv; + + /* FIXME: Check if this is for all 440GP, or just Ebony */ + if ((mfpvr() & 0xf0000fff) == 0x40000440) + /* Rev. B 440GP, use external system clock */ + tb = sys_clk; + else + /* Rev. C 440GP, errata force us to use internal clock */ + tb = cpu; + + if (cr0 & CPC0_CR0_U0EC) + /* External UART clock */ + uart0 = ser_clk; + else + /* Internal UART clock */ + uart0 = plb / CPC0_CR0_UDIV(cr0); + + if (cr0 & CPC0_CR0_U1EC) + /* External UART clock */ + uart1 = ser_clk; + else + /* Internal UART clock */ + uart1 = plb / CPC0_CR0_UDIV(cr0); + + printf("PPC440GP: SysClk = %dMHz (%x)\n\r", + (sys_clk + 500000) / 1000000, sys_clk); + + dt_fixup_cpu_clocks(cpu, tb, 0); + + dt_fixup_clock("/plb", plb); + dt_fixup_clock("/plb/opb", opb); + dt_fixup_clock("/plb/opb/ebc", ebc); + dt_fixup_clock("/plb/opb/serial@40000200", uart0); + dt_fixup_clock("/plb/opb/serial@40000300", uart1); +} + +#define SPRN_CCR1 0x378 + +static inline u32 __fix_zero(u32 v, u32 def) +{ + return v ? v : def; +} + +static unsigned int __ibm440eplike_fixup_clocks(unsigned int sys_clk, + unsigned int tmr_clk, + int per_clk_from_opb) +{ + /* PLL config */ + u32 pllc = CPR0_READ(DCRN_CPR0_PLLC); + u32 plld = CPR0_READ(DCRN_CPR0_PLLD); + + /* Dividers */ + u32 fbdv = __fix_zero((plld >> 24) & 0x1f, 32); + u32 fwdva = __fix_zero((plld >> 16) & 0xf, 16); + u32 fwdvb = __fix_zero((plld >> 8) & 7, 8); + u32 lfbdv = __fix_zero(plld & 0x3f, 64); + u32 pradv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PRIMAD) >> 24) & 7, 8); + u32 prbdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PRIMBD) >> 24) & 7, 8); + u32 opbdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_OPBD) >> 24) & 3, 4); + u32 perdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PERD) >> 24) & 3, 4); + + /* Input clocks for primary dividers */ + u32 clk_a, clk_b; + + /* Resulting clocks */ + u32 cpu, plb, opb, ebc, vco; + + /* Timebase */ + u32 ccr1, tb = tmr_clk; + + if (pllc & 0x40000000) { + u32 m; + + /* Feedback path */ + switch ((pllc >> 24) & 7) { + case 0: + /* PLLOUTx */ + m = ((pllc & 0x20000000) ? fwdvb : fwdva) * lfbdv; + break; + case 1: + /* CPU */ + m = fwdva * pradv0; + break; + case 5: + /* PERClk */ + m = fwdvb * prbdv0 * opbdv0 * perdv0; + break; + default: + printf("WARNING ! Invalid PLL feedback source !\n"); + goto bypass; + } + m *= fbdv; + vco = sys_clk * m; + clk_a = vco / fwdva; + clk_b = vco / fwdvb; + } else { +bypass: + /* Bypass system PLL */ + vco = 0; + clk_a = clk_b = sys_clk; + } + + cpu = clk_a / pradv0; + plb = clk_b / prbdv0; + opb = plb / opbdv0; + ebc = (per_clk_from_opb ? opb : plb) / perdv0; + + /* Figure out timebase. Either CPU or default TmrClk */ + ccr1 = mfspr(SPRN_CCR1); + + /* If passed a 0 tmr_clk, force CPU clock */ + if (tb == 0) { + ccr1 &= ~0x80u; + mtspr(SPRN_CCR1, ccr1); + } + if ((ccr1 & 0x0080) == 0) + tb = cpu; + + dt_fixup_cpu_clocks(cpu, tb, 0); + dt_fixup_clock("/plb", plb); + dt_fixup_clock("/plb/opb", opb); + dt_fixup_clock("/plb/opb/ebc", ebc); + + return plb; +} + +static void eplike_fixup_uart_clk(int index, const char *path, + unsigned int ser_clk, + unsigned int plb_clk) +{ + unsigned int sdr; + unsigned int clock; + + switch (index) { + case 0: + sdr = SDR0_READ(DCRN_SDR0_UART0); + break; + case 1: + sdr = SDR0_READ(DCRN_SDR0_UART1); + break; + case 2: + sdr = SDR0_READ(DCRN_SDR0_UART2); + break; + case 3: + sdr = SDR0_READ(DCRN_SDR0_UART3); + break; + default: + return; + } + + if (sdr & 0x00800000u) + clock = ser_clk; + else + clock = plb_clk / __fix_zero(sdr & 0xff, 256); + + dt_fixup_clock(path, clock); +} + +void ibm440ep_fixup_clocks(unsigned int sys_clk, + unsigned int ser_clk, + unsigned int tmr_clk) +{ + unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 0); + + /* serial clocks need fixup based on int/ext */ + eplike_fixup_uart_clk(0, "/plb/opb/serial@ef600300", ser_clk, plb_clk); + eplike_fixup_uart_clk(1, "/plb/opb/serial@ef600400", ser_clk, plb_clk); + eplike_fixup_uart_clk(2, "/plb/opb/serial@ef600500", ser_clk, plb_clk); + eplike_fixup_uart_clk(3, "/plb/opb/serial@ef600600", ser_clk, plb_clk); +} + +void ibm440gx_fixup_clocks(unsigned int sys_clk, + unsigned int ser_clk, + unsigned int tmr_clk) +{ + unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1); + + /* serial clocks need fixup based on int/ext */ + eplike_fixup_uart_clk(0, "/plb/opb/serial@40000200", ser_clk, plb_clk); + eplike_fixup_uart_clk(1, "/plb/opb/serial@40000300", ser_clk, plb_clk); +} + +void ibm440spe_fixup_clocks(unsigned int sys_clk, + unsigned int ser_clk, + unsigned int tmr_clk) +{ + unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1); + + /* serial clocks need fixup based on int/ext */ + eplike_fixup_uart_clk(0, "/plb/opb/serial@f0000200", ser_clk, plb_clk); + eplike_fixup_uart_clk(1, "/plb/opb/serial@f0000300", ser_clk, plb_clk); + eplike_fixup_uart_clk(2, "/plb/opb/serial@f0000600", ser_clk, plb_clk); +} + +void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk) +{ + u32 pllmr = mfdcr(DCRN_CPC0_PLLMR); + u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0); + u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1); + u32 psr = mfdcr(DCRN_405_CPC0_PSR); + u32 cpu, plb, opb, ebc, tb, uart0, uart1, m; + u32 fwdv, fwdvb, fbdv, cbdv, opdv, epdv, ppdv, udiv; + + fwdv = (8 - ((pllmr & 0xe0000000) >> 29)); + fbdv = (pllmr & 0x1e000000) >> 25; + if (fbdv == 0) + fbdv = 16; + cbdv = ((pllmr & 0x00060000) >> 17) + 1; /* CPU:PLB */ + opdv = ((pllmr & 0x00018000) >> 15) + 1; /* PLB:OPB */ + ppdv = ((pllmr & 0x00001800) >> 13) + 1; /* PLB:PCI */ + epdv = ((pllmr & 0x00001800) >> 11) + 2; /* PLB:EBC */ + udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1; + + /* check for 405GPr */ + if ((mfpvr() & 0xfffffff0) == (0x50910951 & 0xfffffff0)) { + fwdvb = 8 - (pllmr & 0x00000007); + if (!(psr & 0x00001000)) /* PCI async mode enable == 0 */ + if (psr & 0x00000020) /* New mode enable */ + m = fwdvb * 2 * ppdv; + else + m = fwdvb * cbdv * ppdv; + else if (psr & 0x00000020) /* New mode enable */ + if (psr & 0x00000800) /* PerClk synch mode */ + m = fwdvb * 2 * epdv; + else + m = fbdv * fwdv; + else if (epdv == fbdv) + m = fbdv * cbdv * epdv; + else + m = fbdv * fwdvb * cbdv; + + cpu = sys_clk * m / fwdv; + plb = sys_clk * m / (fwdvb * cbdv); + } else { + m = fwdv * fbdv * cbdv; + cpu = sys_clk * m / fwdv; + plb = cpu / cbdv; + } + opb = plb / opdv; + ebc = plb / epdv; + + if (cpc0_cr0 & 0x80) + /* uart0 uses the external clock */ + uart0 = ser_clk; + else + uart0 = cpu / udiv; + + if (cpc0_cr0 & 0x40) + /* uart1 uses the external clock */ + uart1 = ser_clk; + else + uart1 = cpu / udiv; + + /* setup the timebase clock to tick at the cpu frequency */ + cpc0_cr1 = cpc0_cr1 & ~0x00800000; + mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1); + tb = cpu; + + dt_fixup_cpu_clocks(cpu, tb, 0); + dt_fixup_clock("/plb", plb); + dt_fixup_clock("/plb/opb", opb); + dt_fixup_clock("/plb/ebc", ebc); + dt_fixup_clock("/plb/opb/serial@ef600300", uart0); + dt_fixup_clock("/plb/opb/serial@ef600400", uart1); +} + + +void ibm405ep_fixup_clocks(unsigned int sys_clk) +{ + u32 pllmr0 = mfdcr(DCRN_CPC0_PLLMR0); + u32 pllmr1 = mfdcr(DCRN_CPC0_PLLMR1); + u32 cpc0_ucr = mfdcr(DCRN_CPC0_UCR); + u32 cpu, plb, opb, ebc, uart0, uart1; + u32 fwdva, fwdvb, fbdv, cbdv, opdv, epdv; + u32 pllmr0_ccdv, tb, m; + + fwdva = 8 - ((pllmr1 & 0x00070000) >> 16); + fwdvb = 8 - ((pllmr1 & 0x00007000) >> 12); + fbdv = (pllmr1 & 0x00f00000) >> 20; + if (fbdv == 0) + fbdv = 16; + + cbdv = ((pllmr0 & 0x00030000) >> 16) + 1; /* CPU:PLB */ + epdv = ((pllmr0 & 0x00000300) >> 8) + 2; /* PLB:EBC */ + opdv = ((pllmr0 & 0x00003000) >> 12) + 1; /* PLB:OPB */ + + m = fbdv * fwdvb; + + pllmr0_ccdv = ((pllmr0 & 0x00300000) >> 20) + 1; + if (pllmr1 & 0x80000000) + cpu = sys_clk * m / (fwdva * pllmr0_ccdv); + else + cpu = sys_clk / pllmr0_ccdv; + + plb = cpu / cbdv; + opb = plb / opdv; + ebc = plb / epdv; + tb = cpu; + uart0 = cpu / (cpc0_ucr & 0x0000007f); + uart1 = cpu / ((cpc0_ucr & 0x00007f00) >> 8); + + dt_fixup_cpu_clocks(cpu, tb, 0); + dt_fixup_clock("/plb", plb); + dt_fixup_clock("/plb/opb", opb); + dt_fixup_clock("/plb/ebc", ebc); + dt_fixup_clock("/plb/opb/serial@ef600300", uart0); + dt_fixup_clock("/plb/opb/serial@ef600400", uart1); +} + +static u8 ibm405ex_fwdv_multi_bits[] = { + /* values for: 1 - 16 */ + 0x01, 0x02, 0x0e, 0x09, 0x04, 0x0b, 0x10, 0x0d, 0x0c, 0x05, + 0x06, 0x0f, 0x0a, 0x07, 0x08, 0x03 +}; + +u32 ibm405ex_get_fwdva(unsigned long cpr_fwdv) +{ + u32 index; + + for (index = 0; index < ARRAY_SIZE(ibm405ex_fwdv_multi_bits); index++) + if (cpr_fwdv == (u32)ibm405ex_fwdv_multi_bits[index]) + return index + 1; + + return 0; +} + +static u8 ibm405ex_fbdv_multi_bits[] = { + /* values for: 1 - 100 */ + 0x00, 0xff, 0x7e, 0xfd, 0x7a, 0xf5, 0x6a, 0xd5, 0x2a, 0xd4, + 0x29, 0xd3, 0x26, 0xcc, 0x19, 0xb3, 0x67, 0xce, 0x1d, 0xbb, + 0x77, 0xee, 0x5d, 0xba, 0x74, 0xe9, 0x52, 0xa5, 0x4b, 0x96, + 0x2c, 0xd8, 0x31, 0xe3, 0x46, 0x8d, 0x1b, 0xb7, 0x6f, 0xde, + 0x3d, 0xfb, 0x76, 0xed, 0x5a, 0xb5, 0x6b, 0xd6, 0x2d, 0xdb, + 0x36, 0xec, 0x59, 0xb2, 0x64, 0xc9, 0x12, 0xa4, 0x48, 0x91, + 0x23, 0xc7, 0x0e, 0x9c, 0x38, 0xf0, 0x61, 0xc2, 0x05, 0x8b, + 0x17, 0xaf, 0x5f, 0xbe, 0x7c, 0xf9, 0x72, 0xe5, 0x4a, 0x95, + 0x2b, 0xd7, 0x2e, 0xdc, 0x39, 0xf3, 0x66, 0xcd, 0x1a, 0xb4, + 0x68, 0xd1, 0x22, 0xc4, 0x09, 0x93, 0x27, 0xcf, 0x1e, 0xbc, + /* values for: 101 - 200 */ + 0x78, 0xf1, 0x62, 0xc5, 0x0a, 0x94, 0x28, 0xd0, 0x21, 0xc3, + 0x06, 0x8c, 0x18, 0xb0, 0x60, 0xc1, 0x02, 0x84, 0x08, 0x90, + 0x20, 0xc0, 0x01, 0x83, 0x07, 0x8f, 0x1f, 0xbf, 0x7f, 0xfe, + 0x7d, 0xfa, 0x75, 0xea, 0x55, 0xaa, 0x54, 0xa9, 0x53, 0xa6, + 0x4c, 0x99, 0x33, 0xe7, 0x4e, 0x9d, 0x3b, 0xf7, 0x6e, 0xdd, + 0x3a, 0xf4, 0x69, 0xd2, 0x25, 0xcb, 0x16, 0xac, 0x58, 0xb1, + 0x63, 0xc6, 0x0d, 0x9b, 0x37, 0xef, 0x5e, 0xbd, 0x7b, 0xf6, + 0x6d, 0xda, 0x35, 0xeb, 0x56, 0xad, 0x5b, 0xb6, 0x6c, 0xd9, + 0x32, 0xe4, 0x49, 0x92, 0x24, 0xc8, 0x11, 0xa3, 0x47, 0x8e, + 0x1c, 0xb8, 0x70, 0xe1, 0x42, 0x85, 0x0b, 0x97, 0x2f, 0xdf, + /* values for: 201 - 255 */ + 0x3e, 0xfc, 0x79, 0xf2, 0x65, 0xca, 0x15, 0xab, 0x57, 0xae, + 0x5c, 0xb9, 0x73, 0xe6, 0x4d, 0x9a, 0x34, 0xe8, 0x51, 0xa2, + 0x44, 0x89, 0x13, 0xa7, 0x4f, 0x9e, 0x3c, 0xf8, 0x71, 0xe2, + 0x45, 0x8a, 0x14, 0xa8, 0x50, 0xa1, 0x43, 0x86, 0x0c, 0x98, + 0x30, 0xe0, 0x41, 0x82, 0x04, 0x88, 0x10, 0xa0, 0x40, 0x81, + 0x03, 0x87, 0x0f, 0x9f, 0x3f /* END */ +}; + +u32 ibm405ex_get_fbdv(unsigned long cpr_fbdv) +{ + u32 index; + + for (index = 0; index < ARRAY_SIZE(ibm405ex_fbdv_multi_bits); index++) + if (cpr_fbdv == (u32)ibm405ex_fbdv_multi_bits[index]) + return index + 1; + + return 0; +} + +void ibm405ex_fixup_clocks(unsigned int sys_clk, unsigned int uart_clk) +{ + /* PLL config */ + u32 pllc = CPR0_READ(DCRN_CPR0_PLLC); + u32 plld = CPR0_READ(DCRN_CPR0_PLLD); + u32 cpud = CPR0_READ(DCRN_CPR0_PRIMAD); + u32 plbd = CPR0_READ(DCRN_CPR0_PRIMBD); + u32 opbd = CPR0_READ(DCRN_CPR0_OPBD); + u32 perd = CPR0_READ(DCRN_CPR0_PERD); + + /* Dividers */ + u32 fbdv = ibm405ex_get_fbdv(__fix_zero((plld >> 24) & 0xff, 1)); + + u32 fwdva = ibm405ex_get_fwdva(__fix_zero((plld >> 16) & 0x0f, 1)); + + u32 cpudv0 = __fix_zero((cpud >> 24) & 7, 8); + + /* PLBDV0 is hardwared to 010. */ + u32 plbdv0 = 2; + u32 plb2xdv0 = __fix_zero((plbd >> 16) & 7, 8); + + u32 opbdv0 = __fix_zero((opbd >> 24) & 3, 4); + + u32 perdv0 = __fix_zero((perd >> 24) & 3, 4); + + /* Resulting clocks */ + u32 cpu, plb, opb, ebc, vco, tb, uart0, uart1; + + /* PLL's VCO is the source for primary forward ? */ + if (pllc & 0x40000000) { + u32 m; + + /* Feedback path */ + switch ((pllc >> 24) & 7) { + case 0: + /* PLLOUTx */ + m = fbdv; + break; + case 1: + /* CPU */ + m = fbdv * fwdva * cpudv0; + break; + case 5: + /* PERClk */ + m = fbdv * fwdva * plb2xdv0 * plbdv0 * opbdv0 * perdv0; + break; + default: + printf("WARNING ! Invalid PLL feedback source !\n"); + goto bypass; + } + + vco = (unsigned int)(sys_clk * m); + } else { +bypass: + /* Bypass system PLL */ + vco = 0; + } + + /* CPU = VCO / ( FWDVA x CPUDV0) */ + cpu = vco / (fwdva * cpudv0); + /* PLB = VCO / ( FWDVA x PLB2XDV0 x PLBDV0) */ + plb = vco / (fwdva * plb2xdv0 * plbdv0); + /* OPB = PLB / OPBDV0 */ + opb = plb / opbdv0; + /* EBC = OPB / PERDV0 */ + ebc = opb / perdv0; + + tb = cpu; + uart0 = uart1 = uart_clk; + + dt_fixup_cpu_clocks(cpu, tb, 0); + dt_fixup_clock("/plb", plb); + dt_fixup_clock("/plb/opb", opb); + dt_fixup_clock("/plb/opb/ebc", ebc); + dt_fixup_clock("/plb/opb/serial@ef600200", uart0); + dt_fixup_clock("/plb/opb/serial@ef600300", uart1); +} diff --git a/arch/powerpc/boot/4xx.h b/arch/powerpc/boot/4xx.h new file mode 100644 index 00000000000..7dc5d45361b --- /dev/null +++ b/arch/powerpc/boot/4xx.h @@ -0,0 +1,33 @@ +/* + * PowerPC 4xx related functions + * + * Copyright 2007 IBM Corporation. + * Josh Boyer <jwboyer@linux.vnet.ibm.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#ifndef _POWERPC_BOOT_4XX_H_ +#define _POWERPC_BOOT_4XX_H_ + +void ibm4xx_sdram_fixup_memsize(void); +void ibm440spe_fixup_memsize(void); +void ibm4xx_denali_fixup_memsize(void); +void ibm44x_dbcr_reset(void); +void ibm40x_dbcr_reset(void); +void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1); +void ibm4xx_fixup_ebc_ranges(const char *ebc); + +void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk); +void ibm405ep_fixup_clocks(unsigned int sys_clk); +void ibm405ex_fixup_clocks(unsigned int sys_clk, unsigned int uart_clk); +void ibm440gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk); +void ibm440ep_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk, + unsigned int tmr_clk); +void ibm440gx_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk, + unsigned int tmr_clk); +void ibm440spe_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk, + unsigned int tmr_clk); + +#endif /* _POWERPC_BOOT_4XX_H_ */ diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile new file mode 100644 index 00000000000..8844a17ce8e --- /dev/null +++ b/arch/powerpc/boot/Makefile @@ -0,0 +1,422 @@ +# Makefile for making ELF bootable images for booting on CHRP +# using Open Firmware. +# +# Geert Uytterhoeven September 1997 +# +# Based on coffboot by Paul Mackerras +# Simplified for ppc64 by Todd Inglett +# +# NOTE: this code is built for 32 bit in ELF32 format even though +# it packages a 64 bit kernel. We do this to simplify the +# bootloader and increase compatibility with OpenFirmware. +# +# To this end we need to define BOOTCC, etc, as the tools +# needed to build the 32 bit image. That's normally the same +# compiler for the rest of the kernel, with the -m32 flag added. +# To make it easier to setup a cross compiler, +# CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE +# in the toplevel makefile. + +all: $(obj)/zImage + +BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ + -fno-strict-aliasing -Os -msoft-float -pipe \ + -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ + -isystem $(shell $(CROSS32CC) -print-file-name=include) +BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc + +ifdef CONFIG_DEBUG_INFO +BOOTCFLAGS += -g +endif + +ifeq ($(call cc-option-yn, -fstack-protector),y) +BOOTCFLAGS += -fno-stack-protector +endif + +BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) + +DTC_FLAGS ?= -p 1024 + +$(obj)/4xx.o: BOOTCFLAGS += -mcpu=405 +$(obj)/ebony.o: BOOTCFLAGS += -mcpu=405 +$(obj)/cuboot-hotfoot.o: BOOTCFLAGS += -mcpu=405 +$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405 +$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405 +$(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405 +$(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405 +$(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405 +$(obj)/treeboot-currituck.o: BOOTCFLAGS += -mcpu=405 +$(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405 + + +zlib := inffast.c inflate.c inftrees.c +zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h +zliblinuxheader := zlib.h zconf.h zutil.h + +$(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o prpmc2800.o): \ + $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) + +libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c +libfdtheader := fdt.h libfdt.h libfdt_internal.h + +$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o): \ + $(addprefix $(obj)/,$(libfdtheader)) + +src-wlib := string.S crt0.S crtsavres.S stdio.c main.c \ + $(libfdt) libfdt-wrapper.c \ + ns16550.c serial.c simple_alloc.c div64.S util.S \ + gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \ + 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \ + cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \ + fsl-soc.c mpc8xx.c pq2.c ugecon.c +src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \ + cuboot-ebony.c cuboot-hotfoot.c epapr.c treeboot-ebony.c \ + prpmc2800.c \ + ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \ + cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c \ + cuboot-bamboo.c cuboot-mpc7448hpc2.c cuboot-taishan.c \ + fixed-head.S ep88xc.c ep405.c cuboot-c2k.c \ + cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \ + cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \ + virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \ + cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c \ + gamecube-head.S gamecube.c wii-head.S wii.c treeboot-iss4xx.c \ + treeboot-currituck.c +src-boot := $(src-wlib) $(src-plat) empty.c + +src-boot := $(addprefix $(obj)/, $(src-boot)) +obj-boot := $(addsuffix .o, $(basename $(src-boot))) +obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib)))) +obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat)))) + +quiet_cmd_copy_zlib = COPY $@ + cmd_copy_zlib = sed "s@__used@@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ + +quiet_cmd_copy_zlibheader = COPY $@ + cmd_copy_zlibheader = sed "s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ +# stddef.h for NULL +quiet_cmd_copy_zliblinuxheader = COPY $@ + cmd_copy_zliblinuxheader = sed "s@<linux/string.h>@\"string.h\"@;s@<linux/kernel.h>@<stddef.h>@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ + +$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/% + $(call cmd,copy_zlib) + +$(addprefix $(obj)/,$(zlibheader)): $(obj)/%: $(srctree)/lib/zlib_inflate/% + $(call cmd,copy_zlibheader) + +$(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/% + $(call cmd,copy_zliblinuxheader) + +quiet_cmd_copy_libfdt = COPY $@ + cmd_copy_libfdt = cp $< $@ + +$(addprefix $(obj)/,$(libfdt) $(libfdtheader)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/% + $(call cmd,copy_libfdt) + +$(obj)/empty.c: + @touch $@ + +$(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds: $(obj)/%: $(srctree)/$(src)/%.S + @cp $< $@ + +clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ + $(libfdt) $(libfdtheader) \ + empty.c zImage.coff.lds zImage.ps3.lds zImage.lds + +quiet_cmd_bootcc = BOOTCC $@ + cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< + +quiet_cmd_bootas = BOOTAS $@ + cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< + +quiet_cmd_bootar = BOOTAR $@ + cmd_bootar = $(CROSS32AR) -cr$(KBUILD_ARFLAGS) $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@ + +$(obj-libfdt): $(obj)/%.o: $(srctree)/scripts/dtc/libfdt/%.c FORCE + $(call if_changed_dep,bootcc) +$(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c FORCE + $(Q)mkdir -p $(dir $@) + $(call if_changed_dep,bootcc) +$(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE + $(Q)mkdir -p $(dir $@) + $(call if_changed_dep,bootas) + +$(obj)/wrapper.a: $(obj-wlib) FORCE + $(call if_changed,bootar) + +hostprogs-y := addnote hack-coff mktree + +targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) +extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ + $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds + +dtstree := $(srctree)/$(src)/dts + +wrapper :=$(srctree)/$(src)/wrapper +wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \ + $(wrapper) FORCE + +############# +# Bits for building various flavours of zImage + +ifneq ($(CROSS32_COMPILE),) +CROSSWRAP := -C "$(CROSS32_COMPILE)" +else +ifneq ($(CROSS_COMPILE),) +CROSSWRAP := -C "$(CROSS_COMPILE)" +endif +endif + +# args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd +quiet_cmd_wrap = WRAP $@ + cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \ + $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux + +image-$(CONFIG_PPC_PSERIES) += zImage.pseries +image-$(CONFIG_PPC_POWERNV) += zImage.pseries +image-$(CONFIG_PPC_MAPLE) += zImage.maple +image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries +image-$(CONFIG_PPC_PS3) += dtbImage.ps3 +image-$(CONFIG_PPC_CELLEB) += zImage.pseries +image-$(CONFIG_PPC_CELL_QPACE) += zImage.pseries +image-$(CONFIG_PPC_CHRP) += zImage.chrp +image-$(CONFIG_PPC_EFIKA) += zImage.chrp +image-$(CONFIG_PPC_PMAC) += zImage.pmac +image-$(CONFIG_PPC_HOLLY) += dtbImage.holly +image-$(CONFIG_PPC_PRPMC2800) += dtbImage.prpmc2800 +image-$(CONFIG_PPC_ISERIES) += zImage.iseries +image-$(CONFIG_DEFAULT_UIMAGE) += uImage +image-$(CONFIG_EPAPR_BOOT) += zImage.epapr + +# +# Targets which embed a device tree blob +# +# Theses are default targets to build images which embed device tree blobs. +# They are only required on boards which do not have FDT support in firmware. +# Boards with newish u-boot firmware can use the uImage target above +# + +# Board ports in arch/powerpc/platform/40x/Kconfig +image-$(CONFIG_EP405) += dtbImage.ep405 +image-$(CONFIG_HOTFOOT) += cuImage.hotfoot +image-$(CONFIG_WALNUT) += treeImage.walnut +image-$(CONFIG_ACADIA) += cuImage.acadia +image-$(CONFIG_OBS600) += uImage.obs600 + +# Board ports in arch/powerpc/platform/44x/Kconfig +image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony +image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo +image-$(CONFIG_SAM440EP) += cuImage.sam440ep +image-$(CONFIG_SEQUOIA) += cuImage.sequoia +image-$(CONFIG_RAINIER) += cuImage.rainier +image-$(CONFIG_TAISHAN) += cuImage.taishan +image-$(CONFIG_KATMAI) += cuImage.katmai +image-$(CONFIG_WARP) += cuImage.warp +image-$(CONFIG_YOSEMITE) += cuImage.yosemite +image-$(CONFIG_ISS4xx) += treeImage.iss4xx \ + treeImage.iss4xx-mpic +image-$(CONFIG_CURRITUCK) += treeImage.currituck + +# Board ports in arch/powerpc/platform/8xx/Kconfig +image-$(CONFIG_MPC86XADS) += cuImage.mpc866ads +image-$(CONFIG_MPC885ADS) += cuImage.mpc885ads +image-$(CONFIG_PPC_EP88XC) += dtbImage.ep88xc +image-$(CONFIG_PPC_ADDER875) += cuImage.adder875-uboot \ + dtbImage.adder875-redboot + +# Board ports in arch/powerpc/platform/52xx/Kconfig +image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 lite5200.dtb +image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200b lite5200b.dtb +image-$(CONFIG_PPC_MEDIA5200) += cuImage.media5200 media5200.dtb + +# Board ports in arch/powerpc/platform/82xx/Kconfig +image-$(CONFIG_MPC8272_ADS) += cuImage.mpc8272ads +image-$(CONFIG_PQ2FADS) += cuImage.pq2fads +image-$(CONFIG_EP8248E) += dtbImage.ep8248e + +# Board ports in arch/powerpc/platform/83xx/Kconfig +image-$(CONFIG_MPC832x_MDS) += cuImage.mpc832x_mds +image-$(CONFIG_MPC832x_RDB) += cuImage.mpc832x_rdb +image-$(CONFIG_MPC834x_ITX) += cuImage.mpc8349emitx \ + cuImage.mpc8349emitxgp +image-$(CONFIG_MPC834x_MDS) += cuImage.mpc834x_mds +image-$(CONFIG_MPC836x_MDS) += cuImage.mpc836x_mds +image-$(CONFIG_ASP834x) += dtbImage.asp834x-redboot + +# Board ports in arch/powerpc/platform/85xx/Kconfig +image-$(CONFIG_MPC8540_ADS) += cuImage.mpc8540ads +image-$(CONFIG_MPC8560_ADS) += cuImage.mpc8560ads +image-$(CONFIG_MPC85xx_CDS) += cuImage.mpc8541cds \ + cuImage.mpc8548cds \ + cuImage.mpc8555cds +image-$(CONFIG_MPC85xx_MDS) += cuImage.mpc8568mds +image-$(CONFIG_MPC85xx_DS) += cuImage.mpc8544ds \ + cuImage.mpc8572ds +image-$(CONFIG_TQM8540) += cuImage.tqm8540 +image-$(CONFIG_TQM8541) += cuImage.tqm8541 +image-$(CONFIG_TQM8548) += cuImage.tqm8548 +image-$(CONFIG_TQM8555) += cuImage.tqm8555 +image-$(CONFIG_TQM8560) += cuImage.tqm8560 +image-$(CONFIG_SBC8548) += cuImage.sbc8548 +image-$(CONFIG_SBC8560) += cuImage.sbc8560 +image-$(CONFIG_KSI8560) += cuImage.ksi8560 + +# Board ports in arch/powerpc/platform/embedded6xx/Kconfig +image-$(CONFIG_STORCENTER) += cuImage.storcenter +image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2 +image-$(CONFIG_PPC_C2K) += cuImage.c2k +image-$(CONFIG_GAMECUBE) += dtbImage.gamecube +image-$(CONFIG_WII) += dtbImage.wii + +# Board port in arch/powerpc/platform/amigaone/Kconfig +image-$(CONFIG_AMIGAONE) += cuImage.amigaone + +# For 32-bit powermacs, build the COFF and miboot images +# as well as the ELF images. +ifeq ($(CONFIG_PPC32),y) +image-$(CONFIG_PPC_PMAC) += zImage.coff zImage.miboot +endif + +# Allow extra targets to be added to the defconfig +image-y += $(subst ",,$(CONFIG_EXTRA_TARGETS)) + +initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-)) +initrd-y := $(patsubst zImage%, zImage.initrd%, \ + $(patsubst dtbImage%, dtbImage.initrd%, \ + $(patsubst simpleImage%, simpleImage.initrd%, \ + $(patsubst treeImage%, treeImage.initrd%, $(image-y))))) +initrd-y := $(filter-out $(image-y), $(initrd-y)) +targets += $(image-y) $(initrd-y) + +$(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz + +# Don't put the ramdisk on the pattern rule; when its missing make will try +# the pattern rule with less dependencies that also matches (even with the +# hard dependency listed). +$(obj)/zImage.initrd.%: vmlinux $(wrapperbits) + $(call if_changed,wrap,$*,,,$(obj)/ramdisk.image.gz) + +$(obj)/zImage.%: vmlinux $(wrapperbits) + $(call if_changed,wrap,$*) + +# dtbImage% - a dtbImage is a zImage with an embedded device tree blob +$(obj)/dtbImage.initrd.%: vmlinux $(wrapperbits) $(obj)/%.dtb + $(call if_changed,wrap,$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) + +$(obj)/dtbImage.%: vmlinux $(wrapperbits) $(obj)/%.dtb + $(call if_changed,wrap,$*,,$(obj)/$*.dtb) + +# This cannot be in the root of $(src) as the zImage rule always adds a $(obj) +# prefix +$(obj)/vmlinux.strip: vmlinux + $(STRIP) -s -R .comment $< -o $@ + +# The iseries hypervisor won't take an ET_DYN executable, so this +# changes the type (byte 17) in the file to ET_EXEC (2). +$(obj)/zImage.iseries: vmlinux + $(STRIP) -s -R .comment $< -o $@ + printf "\x02" | dd of=$@ conv=notrunc bs=1 seek=17 + +$(obj)/uImage: vmlinux $(wrapperbits) + $(call if_changed,wrap,uboot) + +$(obj)/uImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) + $(call if_changed,wrap,uboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) + +$(obj)/uImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) + $(call if_changed,wrap,uboot-$*,,$(obj)/$*.dtb) + +$(obj)/cuImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) + $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) + +$(obj)/cuImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) + $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb) + +$(obj)/simpleImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) + $(call if_changed,wrap,simpleboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) + +$(obj)/simpleImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) + $(call if_changed,wrap,simpleboot-$*,,$(obj)/$*.dtb) + +$(obj)/treeImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) + $(call if_changed,wrap,treeboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) + +$(obj)/treeImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) + $(call if_changed,wrap,treeboot-$*,,$(obj)/$*.dtb) + +# Rule to build device tree blobs +$(obj)/%.dtb: $(src)/dts/%.dts FORCE + $(call if_changed_dep,dtc) + +# If there isn't a platform selected then just strip the vmlinux. +ifeq (,$(image-y)) +image-y := vmlinux.strip +endif + +$(obj)/zImage: $(addprefix $(obj)/, $(image-y)) + @rm -f $@; ln $< $@ +$(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y)) + @rm -f $@; ln $< $@ + +install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) + sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $^ + +# anything not in $(targets) +clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \ + zImage zImage.initrd zImage.chrp zImage.coff zImage.holly \ + zImage.iseries zImage.miboot zImage.pmac zImage.pseries \ + zImage.maple simpleImage.* otheros.bld *.dtb + +# clean up files cached by wrapper +clean-kernel := vmlinux.strip vmlinux.bin +clean-kernel += $(addsuffix .gz,$(clean-kernel)) +# If not absolute clean-files are relative to $(obj). +clean-files += $(addprefix $(objtree)/, $(clean-kernel)) + +WRAPPER_OBJDIR := /usr/lib/kernel-wrapper +WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts +WRAPPER_BINDIR := /usr/sbin +INSTALL := install + +extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y)) +hostprogs-installed := $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs-y)) +wrapper-installed := $(DESTDIR)$(WRAPPER_BINDIR)/wrapper +dts-installed := $(patsubst $(dtstree)/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(dtstree)/*.dts)) + +all-installed := $(extra-installed) $(hostprogs-installed) $(wrapper-installed) $(dts-installed) + +quiet_cmd_mkdir = MKDIR $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) + cmd_mkdir = mkdir -p $@ + +quiet_cmd_install = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,%,$@) + cmd_install = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,$(obj)/%,$@) $@ + +quiet_cmd_install_dts = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,dts/%,$@) + cmd_install_dts = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,$(srctree)/$(obj)/dts/%,$@) $@ + +quiet_cmd_install_exe = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@) + cmd_install_exe = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(obj)/%,$@) $@ + +quiet_cmd_install_wrapper = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@) + cmd_install_wrapper = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(srctree)/$(obj)/%,$@) $@ ;\ + sed -i $@ -e 's%^object=.*%object=$(WRAPPER_OBJDIR)%' \ + -e 's%^objbin=.*%objbin=$(WRAPPER_BINDIR)%' \ + + +$(DESTDIR)$(WRAPPER_OBJDIR) $(DESTDIR)$(WRAPPER_DTSDIR) $(DESTDIR)$(WRAPPER_BINDIR): + $(call cmd,mkdir) + +$(extra-installed) : $(DESTDIR)$(WRAPPER_OBJDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_OBJDIR) + $(call cmd,install) + +$(hostprogs-installed) : $(DESTDIR)$(WRAPPER_BINDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_BINDIR) + $(call cmd,install_exe) + +$(dts-installed) : $(DESTDIR)$(WRAPPER_DTSDIR)/% : $(srctree)/$(obj)/dts/% | $(DESTDIR)$(WRAPPER_DTSDIR) + $(call cmd,install_dts) + +$(wrapper-installed): $(DESTDIR)$(WRAPPER_BINDIR) $(srctree)/$(obj)/wrapper | $(DESTDIR)$(WRAPPER_BINDIR) + $(call cmd,install_wrapper) + +$(obj)/bootwrapper_install: $(all-installed) + diff --git a/arch/powerpc/boot/README b/arch/powerpc/boot/README new file mode 100644 index 00000000000..3e11058760e --- /dev/null +++ b/arch/powerpc/boot/README @@ -0,0 +1,11 @@ + +To extract the kernel vmlinux, System.map, .config or initrd from the zImage binary: + +objcopy -j .kernel:vmlinux -O binary zImage vmlinux.gz +objcopy -j .kernel:System.map -O binary zImage System.map.gz +objcopy -j .kernel:.config -O binary zImage config.gz +objcopy -j .kernel:initrd -O binary zImage.initrd initrd.gz + + + Peter + diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c new file mode 100644 index 00000000000..349b5530d2c --- /dev/null +++ b/arch/powerpc/boot/addnote.c @@ -0,0 +1,205 @@ +/* + * Program to hack in a PT_NOTE program header entry in an ELF file. + * This is needed for OF on RS/6000s to load an image correctly. + * Note that OF needs a program header entry for the note, not an + * ELF section. + * + * Copyright 2000 Paul Mackerras. + * + * 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. + * + * Usage: addnote zImage + */ +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> + +/* CHRP note section */ +static const char arch[] = "PowerPC"; + +#define N_DESCR 6 +unsigned int descr[N_DESCR] = { + 0xffffffff, /* real-mode = true */ + 0x02000000, /* real-base, i.e. where we expect OF to be */ + 0xffffffff, /* real-size */ + 0xffffffff, /* virt-base */ + 0xffffffff, /* virt-size */ + 0x4000, /* load-base */ +}; + +/* RPA note section */ +static const char rpaname[] = "IBM,RPA-Client-Config"; + +/* + * Note: setting ignore_my_client_config *should* mean that OF ignores + * all the other fields, but there is a firmware bug which means that + * it looks at the splpar field at least. So these values need to be + * reasonable. + */ +#define N_RPA_DESCR 8 +unsigned int rpanote[N_RPA_DESCR] = { + 0, /* lparaffinity */ + 64, /* min_rmo_size */ + 0, /* min_rmo_percent */ + 40, /* max_pft_size */ + 1, /* splpar */ + -1, /* min_load */ + 0, /* new_mem_def */ + 1, /* ignore_my_client_config */ +}; + +#define ROUNDUP(len) (((len) + 3) & ~3) + +unsigned char buf[512]; + +#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) +#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2)) + +#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \ + buf[(off) + 1] = (v) & 0xff) +#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \ + PUT_16BE((off) + 2, (v))) + +/* Structure of an ELF file */ +#define E_IDENT 0 /* ELF header */ +#define E_PHOFF 28 +#define E_PHENTSIZE 42 +#define E_PHNUM 44 +#define E_HSIZE 52 /* size of ELF header */ + +#define EI_MAGIC 0 /* offsets in E_IDENT area */ +#define EI_CLASS 4 +#define EI_DATA 5 + +#define PH_TYPE 0 /* ELF program header */ +#define PH_OFFSET 4 +#define PH_FILESZ 16 +#define PH_HSIZE 32 /* size of program header */ + +#define PT_NOTE 4 /* Program header type = note */ + +#define ELFCLASS32 1 +#define ELFDATA2MSB 2 + +unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; + +int +main(int ac, char **av) +{ + int fd, n, i; + int ph, ps, np; + int nnote, nnote2, ns; + + if (ac != 2) { + fprintf(stderr, "Usage: %s elf-file\n", av[0]); + exit(1); + } + fd = open(av[1], O_RDWR); + if (fd < 0) { + perror(av[1]); + exit(1); + } + + nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr); + nnote2 = 12 + ROUNDUP(strlen(rpaname) + 1) + sizeof(rpanote); + + n = read(fd, buf, sizeof(buf)); + if (n < 0) { + perror("read"); + exit(1); + } + + if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0) + goto notelf; + + if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 + || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { + fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", + av[1]); + exit(1); + } + + ph = GET_32BE(E_PHOFF); + ps = GET_16BE(E_PHENTSIZE); + np = GET_16BE(E_PHNUM); + if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) + goto notelf; + if (ph + (np + 2) * ps + nnote + nnote2 > n) + goto nospace; + + for (i = 0; i < np; ++i) { + if (GET_32BE(ph + PH_TYPE) == PT_NOTE) { + fprintf(stderr, "%s already has a note entry\n", + av[1]); + exit(0); + } + ph += ps; + } + + /* XXX check that the area we want to use is all zeroes */ + for (i = 0; i < 2 * ps + nnote + nnote2; ++i) + if (buf[ph + i] != 0) + goto nospace; + + /* fill in the program header entry */ + ns = ph + 2 * ps; + PUT_32BE(ph + PH_TYPE, PT_NOTE); + PUT_32BE(ph + PH_OFFSET, ns); + PUT_32BE(ph + PH_FILESZ, nnote); + + /* fill in the note area we point to */ + /* XXX we should probably make this a proper section */ + PUT_32BE(ns, strlen(arch) + 1); + PUT_32BE(ns + 4, N_DESCR * 4); + PUT_32BE(ns + 8, 0x1275); + strcpy((char *) &buf[ns + 12], arch); + ns += 12 + strlen(arch) + 1; + for (i = 0; i < N_DESCR; ++i, ns += 4) + PUT_32BE(ns, descr[i]); + + /* fill in the second program header entry and the RPA note area */ + ph += ps; + PUT_32BE(ph + PH_TYPE, PT_NOTE); + PUT_32BE(ph + PH_OFFSET, ns); + PUT_32BE(ph + PH_FILESZ, nnote2); + + /* fill in the note area we point to */ + PUT_32BE(ns, strlen(rpaname) + 1); + PUT_32BE(ns + 4, sizeof(rpanote)); + PUT_32BE(ns + 8, 0x12759999); + strcpy((char *) &buf[ns + 12], rpaname); + ns += 12 + ROUNDUP(strlen(rpaname) + 1); + for (i = 0; i < N_RPA_DESCR; ++i, ns += 4) + PUT_32BE(ns, rpanote[i]); + + /* Update the number of program headers */ + PUT_16BE(E_PHNUM, np + 2); + + /* write back */ + lseek(fd, (long) 0, SEEK_SET); + i = write(fd, buf, n); + if (i < 0) { + perror("write"); + exit(1); + } + if (i < n) { + fprintf(stderr, "%s: write truncated\n", av[1]); + exit(1); + } + + exit(0); + + notelf: + fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]); + exit(1); + + nospace: + fprintf(stderr, "sorry, I can't find space in %s to put the note\n", + av[1]); + exit(1); +} diff --git a/arch/powerpc/boot/bamboo.c b/arch/powerpc/boot/bamboo.c new file mode 100644 index 00000000000..b82cacbc60d --- /dev/null +++ b/arch/powerpc/boot/bamboo.c @@ -0,0 +1,48 @@ +/* + * Copyright IBM Corporation, 2007 + * Josh Boyer <jwboyer@linux.vnet.ibm.com> + * + * Based on ebony wrapper: + * Copyright 2007 David Gibson, IBM Corporation. + * + * Clocking code based on code by: + * Stefan Roese <sr@denx.de> + * + * 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; version 2 of the License + */ +#include <stdarg.h> +#include <stddef.h> +#include "types.h" +#include "elf.h" +#include "string.h" +#include "stdio.h" +#include "page.h" +#include "ops.h" +#include "dcr.h" +#include "4xx.h" +#include "44x.h" + +static u8 *bamboo_mac0, *bamboo_mac1; + +static void bamboo_fixups(void) +{ + unsigned long sysclk = 33333333; + + ibm440ep_fixup_clocks(sysclk, 11059200, 25000000); + ibm4xx_sdram_fixup_memsize(); + ibm4xx_quiesce_eth((u32 *)0xef600e00, (u32 *)0xef600f00); + dt_fixup_mac_address_by_alias("ethernet0", bamboo_mac0); + dt_fixup_mac_address_by_alias("ethernet1", bamboo_mac1); +} + +void bamboo_init(void *mac0, void *mac1) +{ + platform_ops.fixups = bamboo_fixups; + platform_ops.exit = ibm44x_dbcr_reset; + bamboo_mac0 = mac0; + bamboo_mac1 = mac1; + fdt_init(_dtb_start); + serial_console_init(); +} diff --git a/arch/powerpc/boot/cpm-serial.c b/arch/powerpc/boot/cpm-serial.c new file mode 100644 index 00000000000..19dc15abe43 --- /dev/null +++ b/arch/powerpc/boot/cpm-serial.c @@ -0,0 +1,294 @@ +/* + * CPM serial console support. + * + * Copyright 2007 Freescale Semiconductor, Inc. + * Author: Scott Wood <scottwood@freescale.com> + * + * It is assumed that the firmware (or the platform file) has already set + * up the port. + */ + +#include "types.h" +#include "io.h" +#include "ops.h" +#include "page.h" + +struct cpm_scc { + u32 gsmrl; + u32 gsmrh; + u16 psmr; + u8 res1[2]; + u16 todr; + u16 dsr; + u16 scce; + u8 res2[2]; + u16 sccm; + u8 res3; + u8 sccs; + u8 res4[8]; +}; + +struct cpm_smc { + u8 res1[2]; + u16 smcmr; + u8 res2[2]; + u8 smce; + u8 res3[3]; + u8 smcm; + u8 res4[5]; +}; + +struct cpm_param { + u16 rbase; + u16 tbase; + u8 rfcr; + u8 tfcr; + u16 mrblr; + u32 rstate; + u8 res1[4]; + u16 rbptr; + u8 res2[6]; + u32 tstate; + u8 res3[4]; + u16 tbptr; + u8 res4[6]; + u16 maxidl; + u16 idlc; + u16 brkln; + u16 brkec; + u16 brkcr; + u16 rmask; + u8 res5[4]; +}; + +struct cpm_bd { + u16 sc; /* Status and Control */ + u16 len; /* Data length in buffer */ + u8 *addr; /* Buffer address in host memory */ +}; + +static void *cpcr; +static struct cpm_param *param; +static struct cpm_smc *smc; +static struct cpm_scc *scc; +static struct cpm_bd *tbdf, *rbdf; +static u32 cpm_cmd; +static void *cbd_addr; +static u32 cbd_offset; + +static void (*do_cmd)(int op); +static void (*enable_port)(void); +static void (*disable_port)(void); + +#define CPM_CMD_STOP_TX 4 +#define CPM_CMD_RESTART_TX 6 +#define CPM_CMD_INIT_RX_TX 0 + +static void cpm1_cmd(int op) +{ + while (in_be16(cpcr) & 1) + ; + + out_be16(cpcr, (op << 8) | cpm_cmd | 1); + + while (in_be16(cpcr) & 1) + ; +} + +static void cpm2_cmd(int op) +{ + while (in_be32(cpcr) & 0x10000) + ; + + out_be32(cpcr, op | cpm_cmd | 0x10000); + + while (in_be32(cpcr) & 0x10000) + ; +} + +static void smc_disable_port(void) +{ + do_cmd(CPM_CMD_STOP_TX); + out_be16(&smc->smcmr, in_be16(&smc->smcmr) & ~3); +} + +static void scc_disable_port(void) +{ + do_cmd(CPM_CMD_STOP_TX); + out_be32(&scc->gsmrl, in_be32(&scc->gsmrl) & ~0x30); +} + +static void smc_enable_port(void) +{ + out_be16(&smc->smcmr, in_be16(&smc->smcmr) | 3); + do_cmd(CPM_CMD_RESTART_TX); +} + +static void scc_enable_port(void) +{ + out_be32(&scc->gsmrl, in_be32(&scc->gsmrl) | 0x30); + do_cmd(CPM_CMD_RESTART_TX); +} + +static int cpm_serial_open(void) +{ + disable_port(); + + out_8(¶m->rfcr, 0x10); + out_8(¶m->tfcr, 0x10); + out_be16(¶m->mrblr, 1); + out_be16(¶m->maxidl, 0); + out_be16(¶m->brkec, 0); + out_be16(¶m->brkln, 0); + out_be16(¶m->brkcr, 0); + + rbdf = cbd_addr; + rbdf->addr = (u8 *)rbdf - 1; + rbdf->sc = 0xa000; + rbdf->len = 1; + + tbdf = rbdf + 1; + tbdf->addr = (u8 *)rbdf - 2; + tbdf->sc = 0x2000; + tbdf->len = 1; + + sync(); + out_be16(¶m->rbase, cbd_offset); + out_be16(¶m->tbase, cbd_offset + sizeof(struct cpm_bd)); + + do_cmd(CPM_CMD_INIT_RX_TX); + + enable_port(); + return 0; +} + +static void cpm_serial_putc(unsigned char c) +{ + while (tbdf->sc & 0x8000) + barrier(); + + sync(); + + tbdf->addr[0] = c; + eieio(); + tbdf->sc |= 0x8000; +} + +static unsigned char cpm_serial_tstc(void) +{ + barrier(); + return !(rbdf->sc & 0x8000); +} + +static unsigned char cpm_serial_getc(void) +{ + unsigned char c; + + while (!cpm_serial_tstc()) + ; + + sync(); + c = rbdf->addr[0]; + eieio(); + rbdf->sc |= 0x8000; + + return c; +} + +int cpm_console_init(void *devp, struct serial_console_data *scdp) +{ + void *vreg[2]; + u32 reg[2]; + int is_smc = 0, is_cpm2 = 0; + void *parent, *muram; + void *muram_addr; + unsigned long muram_offset, muram_size; + + if (dt_is_compatible(devp, "fsl,cpm1-smc-uart")) { + is_smc = 1; + } else if (dt_is_compatible(devp, "fsl,cpm2-scc-uart")) { + is_cpm2 = 1; + } else if (dt_is_compatible(devp, "fsl,cpm2-smc-uart")) { + is_cpm2 = 1; + is_smc = 1; + } + + if (is_smc) { + enable_port = smc_enable_port; + disable_port = smc_disable_port; + } else { + enable_port = scc_enable_port; + disable_port = scc_disable_port; + } + + if (is_cpm2) + do_cmd = cpm2_cmd; + else + do_cmd = cpm1_cmd; + + if (getprop(devp, "fsl,cpm-command", &cpm_cmd, 4) < 4) + return -1; + + if (dt_get_virtual_reg(devp, vreg, 2) < 2) + return -1; + + if (is_smc) + smc = vreg[0]; + else + scc = vreg[0]; + + param = vreg[1]; + + parent = get_parent(devp); + if (!parent) + return -1; + + if (dt_get_virtual_reg(parent, &cpcr, 1) < 1) + return -1; + + muram = finddevice("/soc/cpm/muram/data"); + if (!muram) + return -1; + + /* For bootwrapper-compatible device trees, we assume that the first + * entry has at least 128 bytes, and that #address-cells/#data-cells + * is one for both parent and child. + */ + + if (dt_get_virtual_reg(muram, &muram_addr, 1) < 1) + return -1; + + if (getprop(muram, "reg", reg, 8) < 8) + return -1; + + muram_offset = reg[0]; + muram_size = reg[1]; + + /* Store the buffer descriptors at the end of the first muram chunk. + * For SMC ports on CPM2-based platforms, relocate the parameter RAM + * just before the buffer descriptors. + */ + + cbd_offset = muram_offset + muram_size - 2 * sizeof(struct cpm_bd); + + if (is_cpm2 && is_smc) { + u16 *smc_base = (u16 *)param; + u16 pram_offset; + + pram_offset = cbd_offset - 64; + pram_offset = _ALIGN_DOWN(pram_offset, 64); + + disable_port(); + out_be16(smc_base, pram_offset); + param = muram_addr - muram_offset + pram_offset; + } + + cbd_addr = muram_addr - muram_offset + cbd_offset; + + scdp->open = cpm_serial_open; + scdp->putc = cpm_serial_putc; + scdp->getc = cpm_serial_getc; + scdp->tstc = cpm_serial_tstc; + + return 0; +} diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S new file mode 100644 index 00000000000..0f7428a37ef --- /dev/null +++ b/arch/powerpc/boot/crt0.S @@ -0,0 +1,128 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * 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. + * + * NOTE: this code runs in 32 bit mode, is position-independent, + * and is packaged as ELF32. + */ + +#include "ppc_asm.h" + + .text + /* A procedure descriptor used when booting this as a COFF file. + * When making COFF, this comes first in the link and we're + * linked at 0x500000. + */ + .globl _zimage_start_opd +_zimage_start_opd: + .long 0x500000, 0, 0, 0 + +p_start: .long _start +p_etext: .long _etext +p_bss_start: .long __bss_start +p_end: .long _end + + .weak _platform_stack_top +p_pstack: .long _platform_stack_top + + .weak _zimage_start + .globl _zimage_start +_zimage_start: + .globl _zimage_start_lib +_zimage_start_lib: + /* Work out the offset between the address we were linked at + and the address where we're running. */ + bl .+4 +p_base: mflr r10 /* r10 now points to runtime addr of p_base */ + /* grab the link address of the dynamic section in r11 */ + addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha + lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11) + cmpwi r11,0 + beq 3f /* if not linked -pie */ + /* get the runtime address of the dynamic section in r12 */ + .weak __dynamic_start + addis r12,r10,(__dynamic_start-p_base)@ha + addi r12,r12,(__dynamic_start-p_base)@l + subf r11,r11,r12 /* runtime - linktime offset */ + + /* The dynamic section contains a series of tagged entries. + * We need the RELA and RELACOUNT entries. */ +RELA = 7 +RELACOUNT = 0x6ffffff9 + li r9,0 + li r0,0 +9: lwz r8,0(r12) /* get tag */ + cmpwi r8,0 + beq 10f /* end of list */ + cmpwi r8,RELA + bne 11f + lwz r9,4(r12) /* get RELA pointer in r9 */ + b 12f +11: addis r8,r8,(-RELACOUNT)@ha + cmpwi r8,RELACOUNT@l + bne 12f + lwz r0,4(r12) /* get RELACOUNT value in r0 */ +12: addi r12,r12,8 + b 9b + + /* The relocation section contains a list of relocations. + * We now do the R_PPC_RELATIVE ones, which point to words + * which need to be initialized with addend + offset. + * The R_PPC_RELATIVE ones come first and there are RELACOUNT + * of them. */ +10: /* skip relocation if we don't have both */ + cmpwi r0,0 + beq 3f + cmpwi r9,0 + beq 3f + + add r9,r9,r11 /* Relocate RELA pointer */ + mtctr r0 +2: lbz r0,4+3(r9) /* ELF32_R_INFO(reloc->r_info) */ + cmpwi r0,22 /* R_PPC_RELATIVE */ + bne 3f + lwz r12,0(r9) /* reloc->r_offset */ + lwz r0,8(r9) /* reloc->r_addend */ + add r0,r0,r11 + stwx r0,r11,r12 + addi r9,r9,12 + bdnz 2b + + /* Do a cache flush for our text, in case the loader didn't */ +3: lwz r9,p_start-p_base(r10) /* note: these are relocated now */ + lwz r8,p_etext-p_base(r10) +4: dcbf r0,r9 + icbi r0,r9 + addi r9,r9,0x20 + cmplw cr0,r9,r8 + blt 4b + sync + isync + + /* Clear the BSS */ + lwz r9,p_bss_start-p_base(r10) + lwz r8,p_end-p_base(r10) + li r0,0 +5: stw r0,0(r9) + addi r9,r9,4 + cmplw cr0,r9,r8 + blt 5b + + /* Possibly set up a custom stack */ + lwz r8,p_pstack-p_base(r10) + cmpwi r8,0 + beq 6f + lwz r1,0(r8) + li r0,0 + stwu r0,-16(r1) /* establish a stack frame */ +6: + + /* Call platform_init() */ + bl platform_init + + /* Call start */ + b start diff --git a/arch/powerpc/boot/crtsavres.S b/arch/powerpc/boot/crtsavres.S new file mode 100644 index 00000000000..f3d9b35c07d --- /dev/null +++ b/arch/powerpc/boot/crtsavres.S @@ -0,0 +1,233 @@ +/* + * Special support for eabi and SVR4 + * + * Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc. + * Copyright 2008 Freescale Semiconductor, Inc. + * Written By Michael Meissner + * + * Based on gcc/config/rs6000/crtsavres.asm from gcc + * + * This file 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, or (at your option) any + * later version. + * + * In addition to the permissions in the GNU General Public License, the + * Free Software Foundation gives you unlimited permission to link the + * compiled version of this file with other programs, and to distribute + * those programs without any restriction coming from the use of this + * file. (The General Public License restrictions do apply in other + * respects; for example, they cover modification of the file, and + * distribution when not linked into another program.) + * + * This file 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; see the file COPYING. If not, write to + * the Free Software Foundation, 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, if you link this library with files + * compiled with GCC to produce an executable, this does not cause + * the resulting executable to be covered by the GNU General Public License. + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + */ + + .file "crtsavres.S" + .section ".text" + +/* On PowerPC64 Linux, these functions are provided by the linker. */ +#ifndef __powerpc64__ + +#define _GLOBAL(name) \ + .type name,@function; \ + .globl name; \ +name: + +/* Routines for saving integer registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the integer save area. */ + +_GLOBAL(_savegpr_14) +_GLOBAL(_save32gpr_14) + stw 14,-72(11) /* save gp registers */ +_GLOBAL(_savegpr_15) +_GLOBAL(_save32gpr_15) + stw 15,-68(11) +_GLOBAL(_savegpr_16) +_GLOBAL(_save32gpr_16) + stw 16,-64(11) +_GLOBAL(_savegpr_17) +_GLOBAL(_save32gpr_17) + stw 17,-60(11) +_GLOBAL(_savegpr_18) +_GLOBAL(_save32gpr_18) + stw 18,-56(11) +_GLOBAL(_savegpr_19) +_GLOBAL(_save32gpr_19) + stw 19,-52(11) +_GLOBAL(_savegpr_20) +_GLOBAL(_save32gpr_20) + stw 20,-48(11) +_GLOBAL(_savegpr_21) +_GLOBAL(_save32gpr_21) + stw 21,-44(11) +_GLOBAL(_savegpr_22) +_GLOBAL(_save32gpr_22) + stw 22,-40(11) +_GLOBAL(_savegpr_23) +_GLOBAL(_save32gpr_23) + stw 23,-36(11) +_GLOBAL(_savegpr_24) +_GLOBAL(_save32gpr_24) + stw 24,-32(11) +_GLOBAL(_savegpr_25) +_GLOBAL(_save32gpr_25) + stw 25,-28(11) +_GLOBAL(_savegpr_26) +_GLOBAL(_save32gpr_26) + stw 26,-24(11) +_GLOBAL(_savegpr_27) +_GLOBAL(_save32gpr_27) + stw 27,-20(11) +_GLOBAL(_savegpr_28) +_GLOBAL(_save32gpr_28) + stw 28,-16(11) +_GLOBAL(_savegpr_29) +_GLOBAL(_save32gpr_29) + stw 29,-12(11) +_GLOBAL(_savegpr_30) +_GLOBAL(_save32gpr_30) + stw 30,-8(11) +_GLOBAL(_savegpr_31) +_GLOBAL(_save32gpr_31) + stw 31,-4(11) + blr + +/* Routines for restoring integer registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the integer restore area. */ + +_GLOBAL(_restgpr_14) +_GLOBAL(_rest32gpr_14) + lwz 14,-72(11) /* restore gp registers */ +_GLOBAL(_restgpr_15) +_GLOBAL(_rest32gpr_15) + lwz 15,-68(11) +_GLOBAL(_restgpr_16) +_GLOBAL(_rest32gpr_16) + lwz 16,-64(11) +_GLOBAL(_restgpr_17) +_GLOBAL(_rest32gpr_17) + lwz 17,-60(11) +_GLOBAL(_restgpr_18) +_GLOBAL(_rest32gpr_18) + lwz 18,-56(11) +_GLOBAL(_restgpr_19) +_GLOBAL(_rest32gpr_19) + lwz 19,-52(11) +_GLOBAL(_restgpr_20) +_GLOBAL(_rest32gpr_20) + lwz 20,-48(11) +_GLOBAL(_restgpr_21) +_GLOBAL(_rest32gpr_21) + lwz 21,-44(11) +_GLOBAL(_restgpr_22) +_GLOBAL(_rest32gpr_22) + lwz 22,-40(11) +_GLOBAL(_restgpr_23) +_GLOBAL(_rest32gpr_23) + lwz 23,-36(11) +_GLOBAL(_restgpr_24) +_GLOBAL(_rest32gpr_24) + lwz 24,-32(11) +_GLOBAL(_restgpr_25) +_GLOBAL(_rest32gpr_25) + lwz 25,-28(11) +_GLOBAL(_restgpr_26) +_GLOBAL(_rest32gpr_26) + lwz 26,-24(11) +_GLOBAL(_restgpr_27) +_GLOBAL(_rest32gpr_27) + lwz 27,-20(11) +_GLOBAL(_restgpr_28) +_GLOBAL(_rest32gpr_28) + lwz 28,-16(11) +_GLOBAL(_restgpr_29) +_GLOBAL(_rest32gpr_29) + lwz 29,-12(11) +_GLOBAL(_restgpr_30) +_GLOBAL(_rest32gpr_30) + lwz 30,-8(11) +_GLOBAL(_restgpr_31) +_GLOBAL(_rest32gpr_31) + lwz 31,-4(11) + blr + +/* Routines for restoring integer registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the integer restore area. */ + +_GLOBAL(_restgpr_14_x) +_GLOBAL(_rest32gpr_14_x) + lwz 14,-72(11) /* restore gp registers */ +_GLOBAL(_restgpr_15_x) +_GLOBAL(_rest32gpr_15_x) + lwz 15,-68(11) +_GLOBAL(_restgpr_16_x) +_GLOBAL(_rest32gpr_16_x) + lwz 16,-64(11) +_GLOBAL(_restgpr_17_x) +_GLOBAL(_rest32gpr_17_x) + lwz 17,-60(11) +_GLOBAL(_restgpr_18_x) +_GLOBAL(_rest32gpr_18_x) + lwz 18,-56(11) +_GLOBAL(_restgpr_19_x) +_GLOBAL(_rest32gpr_19_x) + lwz 19,-52(11) +_GLOBAL(_restgpr_20_x) +_GLOBAL(_rest32gpr_20_x) + lwz 20,-48(11) +_GLOBAL(_restgpr_21_x) +_GLOBAL(_rest32gpr_21_x) + lwz 21,-44(11) +_GLOBAL(_restgpr_22_x) +_GLOBAL(_rest32gpr_22_x) + lwz 22,-40(11) +_GLOBAL(_restgpr_23_x) +_GLOBAL(_rest32gpr_23_x) + lwz 23,-36(11) +_GLOBAL(_restgpr_24_x) +_GLOBAL(_rest32gpr_24_x) + lwz 24,-32(11) +_GLOBAL(_restgpr_25_x) +_GLOBAL(_rest32gpr_25_x) + lwz 25,-28(11) +_GLOBAL(_restgpr_26_x) +_GLOBAL(_rest32gpr_26_x) + lwz 26,-24(11) +_GLOBAL(_restgpr_27_x) +_GLOBAL(_rest32gpr_27_x) + lwz 27,-20(11) +_GLOBAL(_restgpr_28_x) +_GLOBAL(_rest32gpr_28_x) + lwz 28,-16(11) +_GLOBAL(_restgpr_29_x) +_GLOBAL(_rest32gpr_29_x) + lwz 29,-12(11) +_GLOBAL(_restgpr_30_x) +_GLOBAL(_rest32gpr_30_x) + lwz 30,-8(11) +_GLOBAL(_restgpr_31_x) +_GLOBAL(_rest32gpr_31_x) + lwz 0,4(11) + lwz 31,-4(11) + mtlr 0 + mr 1,11 + blr +#endif diff --git a/arch/powerpc/boot/cuboot-52xx.c b/arch/powerpc/boot/cuboot-52xx.c new file mode 100644 index 00000000000..4c42ec8687b --- /dev/null +++ b/arch/powerpc/boot/cuboot-52xx.c @@ -0,0 +1,63 @@ +/* + * Old U-boot compatibility for MPC5200 + * + * Author: Grant Likely <grant.likely@secretlab.ca> + * + * Copyright (c) 2007 Secret Lab Technologies Ltd. + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * + * 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 "ops.h" +#include "stdio.h" +#include "io.h" +#include "cuboot.h" + +#define TARGET_PPC_MPC52xx +#include "ppcboot.h" + +static bd_t bd; + +static void platform_fixups(void) +{ + void *soc, *reg; + int div; + u32 sysfreq; + + + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); + dt_fixup_mac_addresses(bd.bi_enetaddr); + dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq); + + /* Unfortunately, the specific model number is encoded in the + * soc node name in existing dts files -- once that is fixed, + * this can do a simple path lookup. + */ + soc = find_node_by_devtype(NULL, "soc"); + if (!soc) + soc = find_node_by_compatible(NULL, "fsl,mpc5200-immr"); + if (!soc) + soc = find_node_by_compatible(NULL, "fsl,mpc5200b-immr"); + if (soc) { + setprop(soc, "bus-frequency", &bd.bi_ipbfreq, + sizeof(bd.bi_ipbfreq)); + + if (!dt_xlate_reg(soc, 0, (void*)®, NULL)) + return; + div = in_8(reg + 0x204) & 0x0020 ? 8 : 4; + sysfreq = bd.bi_busfreq * div; + setprop(soc, "system-frequency", &sysfreq, sizeof(sysfreq)); + } +} + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + fdt_init(_dtb_start); + serial_console_init(); + platform_ops.fixups = platform_fixups; +} diff --git a/arch/powerpc/boot/cuboot-824x.c b/arch/powerpc/boot/cuboot-824x.c new file mode 100644 index 00000000000..ced90c53de4 --- /dev/null +++ b/arch/powerpc/boot/cuboot-824x.c @@ -0,0 +1,53 @@ +/* + * Old U-boot compatibility for 824x + * + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * + * 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 "ops.h" +#include "stdio.h" +#include "cuboot.h" + +#define TARGET_824x +#include "ppcboot.h" + +static bd_t bd; + + +static void platform_fixups(void) +{ + void *soc; + + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); + dt_fixup_mac_addresses(bd.bi_enetaddr); + dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq); + + soc = find_node_by_devtype(NULL, "soc"); + if (soc) { + void *serial = NULL; + + setprop(soc, "bus-frequency", &bd.bi_busfreq, + sizeof(bd.bi_busfreq)); + + while ((serial = find_node_by_devtype(serial, "serial"))) { + if (get_parent(serial) != soc) + continue; + + setprop(serial, "clock-frequency", &bd.bi_busfreq, + sizeof(bd.bi_busfreq)); + } + } +} + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + fdt_init(_dtb_start); + serial_console_init(); + platform_ops.fixups = platform_fixups; +} diff --git a/arch/powerpc/boot/cuboot-83xx.c b/arch/powerpc/boot/cuboot-83xx.c new file mode 100644 index 00000000000..61af1c1e825 --- /dev/null +++ b/arch/powerpc/boot/cuboot-83xx.c @@ -0,0 +1,59 @@ +/* + * Old U-boot compatibility for 83xx + * + * Author: Scott Wood <scottwood@freescale.com> + * + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * + * 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 "ops.h" +#include "stdio.h" +#include "cuboot.h" + +#define TARGET_83xx +#include "ppcboot.h" + +static bd_t bd; + +static void platform_fixups(void) +{ + void *soc; + + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); + dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr); + dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr); + dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq); + + /* Unfortunately, the specific model number is encoded in the + * soc node name in existing dts files -- once that is fixed, + * this can do a simple path lookup. + */ + soc = find_node_by_devtype(NULL, "soc"); + if (soc) { + void *serial = NULL; + + setprop(soc, "bus-frequency", &bd.bi_busfreq, + sizeof(bd.bi_busfreq)); + + while ((serial = find_node_by_devtype(serial, "serial"))) { + if (get_parent(serial) != soc) + continue; + + setprop(serial, "clock-frequency", &bd.bi_busfreq, + sizeof(bd.bi_busfreq)); + } + } +} + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + fdt_init(_dtb_start); + serial_console_init(); + platform_ops.fixups = platform_fixups; +} diff --git a/arch/powerpc/boot/cuboot-85xx-cpm2.c b/arch/powerpc/boot/cuboot-85xx-cpm2.c new file mode 100644 index 00000000000..723872ddd44 --- /dev/null +++ b/arch/powerpc/boot/cuboot-85xx-cpm2.c @@ -0,0 +1,66 @@ +/* + * Old U-boot compatibility for 85xx + * + * Author: Scott Wood <scottwood@freescale.com> + * + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * + * 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 "ops.h" +#include "stdio.h" +#include "cuboot.h" + +#define TARGET_85xx +#define TARGET_CPM2 +#include "ppcboot.h" + +static bd_t bd; + +static void platform_fixups(void) +{ + void *devp; + + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); + dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr); + dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr); + dt_fixup_mac_address_by_alias("ethernet2", bd.bi_enet2addr); + dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 8, bd.bi_busfreq); + + /* Unfortunately, the specific model number is encoded in the + * soc node name in existing dts files -- once that is fixed, + * this can do a simple path lookup. + */ + devp = find_node_by_devtype(NULL, "soc"); + if (devp) { + void *serial = NULL; + + setprop(devp, "bus-frequency", &bd.bi_busfreq, + sizeof(bd.bi_busfreq)); + + while ((serial = find_node_by_devtype(serial, "serial"))) { + if (get_parent(serial) != devp) + continue; + + setprop(serial, "clock-frequency", &bd.bi_busfreq, + sizeof(bd.bi_busfreq)); + } + } + + devp = find_node_by_compatible(NULL, "fsl,cpm2-brg"); + if (devp) + setprop(devp, "clock-frequency", &bd.bi_brgfreq, + sizeof(bd.bi_brgfreq)); +} + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + fdt_init(_dtb_start); + serial_console_init(); + platform_ops.fixups = platform_fixups; +} diff --git a/arch/powerpc/boot/cuboot-85xx.c b/arch/powerpc/boot/cuboot-85xx.c new file mode 100644 index 00000000000..277ba4a79b5 --- /dev/null +++ b/arch/powerpc/boot/cuboot-85xx.c @@ -0,0 +1,62 @@ +/* + * Old U-boot compatibility for 85xx + * + * Author: Scott Wood <scottwood@freescale.com> + * + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * + * 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 "ops.h" +#include "stdio.h" +#include "cuboot.h" + +#define TARGET_85xx +#define TARGET_HAS_ETH3 +#include "ppcboot.h" + +static bd_t bd; + +static void platform_fixups(void) +{ + void *soc; + + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); + dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr); + dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr); + dt_fixup_mac_address_by_alias("ethernet2", bd.bi_enet2addr); + dt_fixup_mac_address_by_alias("ethernet3", bd.bi_enet3addr); + dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 8, bd.bi_busfreq); + + /* Unfortunately, the specific model number is encoded in the + * soc node name in existing dts files -- once that is fixed, + * this can do a simple path lookup. + */ + soc = find_node_by_devtype(NULL, "soc"); + if (soc) { + void *serial = NULL; + + setprop(soc, "bus-frequency", &bd.bi_busfreq, + sizeof(bd.bi_busfreq)); + + while ((serial = find_node_by_devtype(serial, "serial"))) { + if (get_parent(serial) != soc) + continue; + + setprop(serial, "clock-frequency", &bd.bi_busfreq, + sizeof(bd.bi_busfreq)); + } + } +} + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + fdt_init(_dtb_start); + serial_console_init(); + platform_ops.fixups = platform_fixups; +} diff --git a/arch/powerpc/boot/cuboot-8xx.c b/arch/powerpc/boot/cuboot-8xx.c new file mode 100644 index 00000000000..c202c8868bd --- /dev/null +++ b/arch/powerpc/boot/cuboot-8xx.c @@ -0,0 +1,47 @@ +/* + * Old U-boot compatibility for 8xx + * + * Author: Scott Wood <scottwood@freescale.com> + * + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * + * 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 "ops.h" +#include "stdio.h" +#include "cuboot.h" + +#define TARGET_8xx +#define TARGET_HAS_ETH1 +#include "ppcboot.h" + +static bd_t bd; + +static void platform_fixups(void) +{ + void *node; + + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); + dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr); + dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 16, bd.bi_busfreq); + + node = finddevice("/soc/cpm"); + if (node) + setprop(node, "clock-frequency", &bd.bi_busfreq, 4); + + node = finddevice("/soc/cpm/brg"); + if (node) + setprop(node, "clock-frequency", &bd.bi_busfreq, 4); +} + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + fdt_init(_dtb_start); + serial_console_init(); + platform_ops.fixups = platform_fixups; +} diff --git a/arch/powerpc/boot/cuboot-acadia.c b/arch/powerpc/boot/cuboot-acadia.c new file mode 100644 index 00000000000..0634aba6348 --- /dev/null +++ b/arch/powerpc/boot/cuboot-acadia.c @@ -0,0 +1,174 @@ +/* + * Old U-boot compatibility for Acadia + * + * Author: Josh Boyer <jwboyer@linux.vnet.ibm.com> + * + * Copyright 2008 IBM Corporation + * + * 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 "ops.h" +#include "io.h" +#include "dcr.h" +#include "stdio.h" +#include "4xx.h" +#include "44x.h" +#include "cuboot.h" + +#define TARGET_4xx +#include "ppcboot.h" + +static bd_t bd; + +#define CPR_PERD0_SPIDV_MASK 0x000F0000 /* SPI Clock Divider */ + +#define PLLC_SRC_MASK 0x20000000 /* PLL feedback source */ + +#define PLLD_FBDV_MASK 0x1F000000 /* PLL feedback divider value */ +#define PLLD_FWDVA_MASK 0x000F0000 /* PLL forward divider A value */ +#define PLLD_FWDVB_MASK 0x00000700 /* PLL forward divider B value */ + +#define PRIMAD_CPUDV_MASK 0x0F000000 /* CPU Clock Divisor Mask */ +#define PRIMAD_PLBDV_MASK 0x000F0000 /* PLB Clock Divisor Mask */ +#define PRIMAD_OPBDV_MASK 0x00000F00 /* OPB Clock Divisor Mask */ +#define PRIMAD_EBCDV_MASK 0x0000000F /* EBC Clock Divisor Mask */ + +#define PERD0_PWMDV_MASK 0xFF000000 /* PWM Divider Mask */ +#define PERD0_SPIDV_MASK 0x000F0000 /* SPI Divider Mask */ +#define PERD0_U0DV_MASK 0x0000FF00 /* UART 0 Divider Mask */ +#define PERD0_U1DV_MASK 0x000000FF /* UART 1 Divider Mask */ + +static void get_clocks(void) +{ + unsigned long sysclk, cpr_plld, cpr_pllc, cpr_primad, plloutb, i; + unsigned long pllFwdDiv, pllFwdDivB, pllFbkDiv, pllPlbDiv, pllExtBusDiv; + unsigned long pllOpbDiv, freqEBC, freqUART, freqOPB; + unsigned long div; /* total divisor udiv * bdiv */ + unsigned long umin; /* minimum udiv */ + unsigned short diff; /* smallest diff */ + unsigned long udiv; /* best udiv */ + unsigned short idiff; /* current diff */ + unsigned short ibdiv; /* current bdiv */ + unsigned long est; /* current estimate */ + unsigned long baud; + void *np; + + /* read the sysclk value from the CPLD */ + sysclk = (in_8((unsigned char *)0x80000000) == 0xc) ? 66666666 : 33333000; + + /* + * Read PLL Mode registers + */ + cpr_plld = CPR0_READ(DCRN_CPR0_PLLD); + cpr_pllc = CPR0_READ(DCRN_CPR0_PLLC); + + /* + * Determine forward divider A + */ + pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16); + + /* + * Determine forward divider B + */ + pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8); + if (pllFwdDivB == 0) + pllFwdDivB = 8; + + /* + * Determine FBK_DIV. + */ + pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24); + if (pllFbkDiv == 0) + pllFbkDiv = 256; + + /* + * Read CPR_PRIMAD register + */ + cpr_primad = CPR0_READ(DCRN_CPR0_PRIMAD); + + /* + * Determine PLB_DIV. + */ + pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16); + if (pllPlbDiv == 0) + pllPlbDiv = 16; + + /* + * Determine EXTBUS_DIV. + */ + pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK); + if (pllExtBusDiv == 0) + pllExtBusDiv = 16; + + /* + * Determine OPB_DIV. + */ + pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8); + if (pllOpbDiv == 0) + pllOpbDiv = 16; + + /* There is a bug in U-Boot that prevents us from using + * bd.bi_opbfreq because U-Boot doesn't populate it for + * 405EZ. We get to calculate it, yay! + */ + freqOPB = (sysclk *pllFbkDiv) /pllOpbDiv; + + freqEBC = (sysclk * pllFbkDiv) / pllExtBusDiv; + + plloutb = ((sysclk * ((cpr_pllc & PLLC_SRC_MASK) ? + pllFwdDivB : pllFwdDiv) * + pllFbkDiv) / pllFwdDivB); + + np = find_node_by_alias("serial0"); + if (getprop(np, "current-speed", &baud, sizeof(baud)) != sizeof(baud)) + fatal("no current-speed property\n\r"); + + udiv = 256; /* Assume lowest possible serial clk */ + div = plloutb / (16 * baud); /* total divisor */ + umin = (plloutb / freqOPB) << 1; /* 2 x OPB divisor */ + diff = 256; /* highest possible */ + + /* i is the test udiv value -- start with the largest + * possible (256) to minimize serial clock and constrain + * search to umin. + */ + for (i = 256; i > umin; i--) { + ibdiv = div / i; + est = i * ibdiv; + idiff = (est > div) ? (est-div) : (div-est); + if (idiff == 0) { + udiv = i; + break; /* can't do better */ + } else if (idiff < diff) { + udiv = i; /* best so far */ + diff = idiff; /* update lowest diff*/ + } + } + freqUART = plloutb / udiv; + + dt_fixup_cpu_clocks(bd.bi_procfreq, bd.bi_intfreq, bd.bi_plb_busfreq); + dt_fixup_clock("/plb/ebc", freqEBC); + dt_fixup_clock("/plb/opb", freqOPB); + dt_fixup_clock("/plb/opb/serial@ef600300", freqUART); + dt_fixup_clock("/plb/opb/serial@ef600400", freqUART); +} + +static void acadia_fixups(void) +{ + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); + get_clocks(); + dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr); +} + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + platform_ops.fixups = acadia_fixups; + platform_ops.exit = ibm40x_dbcr_reset; + fdt_init(_dtb_start); + serial_console_init(); +} diff --git a/arch/powerpc/boot/cuboot-amigaone.c b/arch/powerpc/boot/cuboot-amigaone.c new file mode 100644 index 00000000000..d5029674030 --- /dev/null +++ b/arch/powerpc/boot/cuboot-amigaone.c @@ -0,0 +1,35 @@ +/* + * Old U-boot compatibility for AmigaOne + * + * Author: Gerhard Pircher (gerhard_pircher@gmx.net) + * + * Based on cuboot-83xx.c + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * + * 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 "ops.h" +#include "stdio.h" +#include "cuboot.h" + +#include "ppcboot.h" + +static bd_t bd; + +static void platform_fixups(void) +{ + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); + dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq); +} + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + fdt_init(_dtb_start); + serial_console_init(); + platform_ops.fixups = platform_fixups; +} diff --git a/arch/powerpc/boot/cuboot-bamboo.c b/arch/powerpc/boot/cuboot-bamboo.c new file mode 100644 index 00000000000..b5c30f766c4 --- /dev/null +++ b/arch/powerpc/boot/cuboot-bamboo.c @@ -0,0 +1,31 @@ +/* + * Old U-boot compatibility for Bamboo + * + * Author: Josh Boyer <jwboyer@linux.vnet.ibm.com> + * + * Copyright 2007 IBM Corporation + * + * Based on cuboot-ebony.c + * + * 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 "ops.h" +#include "stdio.h" +#include "44x.h" +#include "cuboot.h" + +#define TARGET_4xx +#define TARGET_44x +#include "ppcboot.h" + +static bd_t bd; + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + bamboo_init(&bd.bi_enetaddr, &bd.bi_enet1addr); +} diff --git a/arch/powerpc/boot/cuboot-c2k.c b/arch/powerpc/boot/cuboot-c2k.c new file mode 100644 index 00000000000..e43594950ba --- /dev/null +++ b/arch/powerpc/boot/cuboot-c2k.c @@ -0,0 +1,190 @@ +/* + * GEFanuc C2K platform code. + * + * Author: Remi Machet <rmachet@slac.stanford.edu> + * + * Originated from prpmc2800.c + * + * 2008 (c) Stanford University + * 2007 (c) MontaVista, Software, Inc. + * + * 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 "types.h" +#include "stdio.h" +#include "io.h" +#include "ops.h" +#include "elf.h" +#include "gunzip_util.h" +#include "mv64x60.h" +#include "cuboot.h" +#include "ppcboot.h" + +static u8 *bridge_base; + +static void c2k_bridge_setup(u32 mem_size) +{ + u32 i, v[30], enables, acc_bits; + u32 pci_base_hi, pci_base_lo, size, buf[2]; + unsigned long cpu_base; + int rc; + void *devp, *mv64x60_devp; + u8 *bridge_pbase, is_coherent; + struct mv64x60_cpu2pci_win *tbl; + int bus; + + bridge_pbase = mv64x60_get_bridge_pbase(); + is_coherent = mv64x60_is_coherent(); + + if (is_coherent) + acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_WB + | MV64x60_PCI_ACC_CNTL_SWAP_NONE + | MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES + | MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES; + else + acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_NONE + | MV64x60_PCI_ACC_CNTL_SWAP_NONE + | MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES + | MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES; + + mv64x60_config_ctlr_windows(bridge_base, bridge_pbase, is_coherent); + mv64x60_devp = find_node_by_compatible(NULL, "marvell,mv64360"); + if (mv64x60_devp == NULL) + fatal("Error: Missing marvell,mv64360 device tree node\n\r"); + + enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)); + enables |= 0x007ffe00; /* Disable all cpu->pci windows */ + out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables); + + /* Get the cpu -> pci i/o & mem mappings from the device tree */ + devp = NULL; + for (bus = 0; ; bus++) { + char name[] = "pci "; + + name[strlen(name)-1] = bus+'0'; + + devp = find_node_by_alias(name); + if (devp == NULL) + break; + + if (bus >= 2) + fatal("Error: Only 2 PCI controllers are supported at" \ + " this time.\n"); + + mv64x60_config_pci_windows(bridge_base, bridge_pbase, bus, 0, + mem_size, acc_bits); + + rc = getprop(devp, "ranges", v, sizeof(v)); + if (rc == 0) + fatal("Error: Can't find marvell,mv64360-pci ranges" + " property\n\r"); + + /* Get the cpu -> pci i/o & mem mappings from the device tree */ + + for (i = 0; i < rc; i += 6) { + switch (v[i] & 0xff000000) { + case 0x01000000: /* PCI I/O Space */ + tbl = mv64x60_cpu2pci_io; + break; + case 0x02000000: /* PCI MEM Space */ + tbl = mv64x60_cpu2pci_mem; + break; + default: + continue; + } + + pci_base_hi = v[i+1]; + pci_base_lo = v[i+2]; + cpu_base = v[i+3]; + size = v[i+5]; + + buf[0] = cpu_base; + buf[1] = size; + + if (!dt_xlate_addr(devp, buf, sizeof(buf), &cpu_base)) + fatal("Error: Can't translate PCI address " \ + "0x%x\n\r", (u32)cpu_base); + + mv64x60_config_cpu2pci_window(bridge_base, bus, + pci_base_hi, pci_base_lo, cpu_base, size, tbl); + } + + enables &= ~(3<<(9+bus*5)); /* Enable cpu->pci<bus> i/o, + cpu->pci<bus> mem0 */ + out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), + enables); + }; +} + +static void c2k_fixups(void) +{ + u32 mem_size; + + mem_size = mv64x60_get_mem_size(bridge_base); + c2k_bridge_setup(mem_size); /* Do necessary bridge setup */ +} + +#define MV64x60_MPP_CNTL_0 0xf000 +#define MV64x60_MPP_CNTL_2 0xf008 +#define MV64x60_GPP_IO_CNTL 0xf100 +#define MV64x60_GPP_LEVEL_CNTL 0xf110 +#define MV64x60_GPP_VALUE_SET 0xf118 + +static void c2k_reset(void) +{ + u32 temp; + + udelay(5000000); + + if (bridge_base != 0) { + temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0)); + temp &= 0xFFFF0FFF; + out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0), temp); + + temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL)); + temp |= 0x00000004; + out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp); + + temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL)); + temp |= 0x00000004; + out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp); + + temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2)); + temp &= 0xFFFF0FFF; + out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2), temp); + + temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL)); + temp |= 0x00080000; + out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp); + + temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL)); + temp |= 0x00080000; + out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp); + + out_le32((u32 *)(bridge_base + MV64x60_GPP_VALUE_SET), + 0x00080004); + } + + for (;;); +} + +static bd_t bd; + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + + fdt_init(_dtb_start); + + bridge_base = mv64x60_get_bridge_base(); + + platform_ops.fixups = c2k_fixups; + platform_ops.exit = c2k_reset; + + if (serial_console_init() < 0) + exit(); +} diff --git a/arch/powerpc/boot/cuboot-ebony.c b/arch/powerpc/boot/cuboot-ebony.c new file mode 100644 index 00000000000..56564ba37f6 --- /dev/null +++ b/arch/powerpc/boot/cuboot-ebony.c @@ -0,0 +1,31 @@ +/* + * Old U-boot compatibility for Ebony + * + * Author: David Gibson <david@gibson.dropbear.id.au> + * + * Copyright 2007 David Gibson, IBM Corporatio. + * Based on cuboot-83xx.c, which is: + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * + * 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 t |