Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Jul 2011 16:55:45 +0000 (09:55 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Jul 2011 16:55:45 +0000 (09:55 -0700)
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (21 commits)
  [S390] use siginfo for sigtrap signals
  [S390] dasd: add enhanced DASD statistics interface
  [S390] kvm: make sigp emerg smp capable
  [S390] disable cpu measurement alerts on a dying cpu
  [S390] initial cr0 bits
  [S390] iucv cr0 enablement bit
  [S390] race safe external interrupt registration
  [S390] remove tape block docu
  [S390] ap: toleration support for ap device type 10
  [S390] cleanup program check handler prototypes
  [S390] remove kvm mmu reload on s390
  [S390] Use gmap translation for accessing guest memory
  [S390] use gmap address spaces for kvm guest images
  [S390] kvm guest address space mapping
  [S390] fix s390 assembler code alignments
  [S390] move sie code to entry.S
  [S390] kvm: handle tprot intercepts
  [S390] qdio: clear shared DSCI before scheduling the queue handler
  [S390] reference bit testing for unmapped pages
  [S390] irqs: Do not trace arch_local_{*,irq_*} functions
  ...

255 files changed:
Documentation/kernel-parameters.txt
Documentation/virtual/kvm/api.txt
Documentation/virtual/kvm/mmu.txt
Documentation/virtual/kvm/msr.txt
Documentation/virtual/kvm/nested-vmx.txt [new file with mode: 0644]
Documentation/virtual/kvm/ppc-pv.txt
MAINTAINERS
arch/alpha/kernel/module.c
arch/arm/kernel/module.c
arch/avr32/include/asm/delay.h
arch/avr32/kernel/module.c
arch/blackfin/kernel/module.c
arch/cris/kernel/module.c
arch/frv/kernel/module.c
arch/h8300/kernel/module.c
arch/ia64/include/asm/paravirt.h
arch/ia64/kernel/module.c
arch/ia64/kernel/paravirt.c
arch/m32r/include/asm/delay.h
arch/m32r/kernel/module.c
arch/m68k/kernel/module_mm.c
arch/m68k/kernel/module_no.c
arch/microblaze/kernel/module.c
arch/mips/kernel/module.c
arch/mn10300/kernel/module.c
arch/openrisc/Kconfig [new file with mode: 0644]
arch/openrisc/Makefile [new file with mode: 0644]
arch/openrisc/README.openrisc [new file with mode: 0644]
arch/openrisc/TODO.openrisc [new file with mode: 0644]
arch/openrisc/boot/Makefile [new file with mode: 0644]
arch/openrisc/boot/dts/or1ksim.dts [new file with mode: 0644]
arch/openrisc/configs/or1ksim_defconfig [new file with mode: 0644]
arch/openrisc/include/asm/Kbuild [new file with mode: 0644]
arch/openrisc/include/asm/asm-offsets.h [new file with mode: 0644]
arch/openrisc/include/asm/bitops.h [new file with mode: 0644]
arch/openrisc/include/asm/bitops/__ffs.h [new file with mode: 0644]
arch/openrisc/include/asm/bitops/__fls.h [new file with mode: 0644]
arch/openrisc/include/asm/bitops/ffs.h [new file with mode: 0644]
arch/openrisc/include/asm/bitops/fls.h [new file with mode: 0644]
arch/openrisc/include/asm/byteorder.h [new file with mode: 0644]
arch/openrisc/include/asm/cache.h [new file with mode: 0644]
arch/openrisc/include/asm/cpuinfo.h [new file with mode: 0644]
arch/openrisc/include/asm/delay.h [new file with mode: 0644]
arch/openrisc/include/asm/dma-mapping.h [new file with mode: 0644]
arch/openrisc/include/asm/elf.h [new file with mode: 0644]
arch/openrisc/include/asm/fixmap.h [new file with mode: 0644]
arch/openrisc/include/asm/gpio.h [new file with mode: 0644]
arch/openrisc/include/asm/io.h [new file with mode: 0644]
arch/openrisc/include/asm/irq.h [new file with mode: 0644]
arch/openrisc/include/asm/irqflags.h [new file with mode: 0644]
arch/openrisc/include/asm/linkage.h [new file with mode: 0644]
arch/openrisc/include/asm/memblock.h [new file with mode: 0644]
arch/openrisc/include/asm/mmu.h [new file with mode: 0644]
arch/openrisc/include/asm/mmu_context.h [new file with mode: 0644]
arch/openrisc/include/asm/mutex.h [new file with mode: 0644]
arch/openrisc/include/asm/page.h [new file with mode: 0644]
arch/openrisc/include/asm/param.h [new file with mode: 0644]
arch/openrisc/include/asm/pgalloc.h [new file with mode: 0644]
arch/openrisc/include/asm/pgtable.h [new file with mode: 0644]
arch/openrisc/include/asm/processor.h [new file with mode: 0644]
arch/openrisc/include/asm/prom.h [new file with mode: 0644]
arch/openrisc/include/asm/ptrace.h [new file with mode: 0644]
arch/openrisc/include/asm/serial.h [new file with mode: 0644]
arch/openrisc/include/asm/sigcontext.h [new file with mode: 0644]
arch/openrisc/include/asm/spinlock.h [new file with mode: 0644]
arch/openrisc/include/asm/spr.h [new file with mode: 0644]
arch/openrisc/include/asm/spr_defs.h [new file with mode: 0644]
arch/openrisc/include/asm/syscall.h [new file with mode: 0644]
arch/openrisc/include/asm/syscalls.h [new file with mode: 0644]
arch/openrisc/include/asm/system.h [new file with mode: 0644]
arch/openrisc/include/asm/thread_info.h [new file with mode: 0644]
arch/openrisc/include/asm/timex.h [new file with mode: 0644]
arch/openrisc/include/asm/tlb.h [new file with mode: 0644]
arch/openrisc/include/asm/tlbflush.h [new file with mode: 0644]
arch/openrisc/include/asm/uaccess.h [new file with mode: 0644]
arch/openrisc/include/asm/unaligned.h [new file with mode: 0644]
arch/openrisc/include/asm/unistd.h [new file with mode: 0644]
arch/openrisc/kernel/Makefile [new file with mode: 0644]
arch/openrisc/kernel/asm-offsets.c [new file with mode: 0644]
arch/openrisc/kernel/dma.c [new file with mode: 0644]
arch/openrisc/kernel/entry.S [new file with mode: 0644]
arch/openrisc/kernel/head.S [new file with mode: 0644]
arch/openrisc/kernel/idle.c [new file with mode: 0644]
arch/openrisc/kernel/init_task.c [new file with mode: 0644]
arch/openrisc/kernel/irq.c [new file with mode: 0644]
arch/openrisc/kernel/module.c [new file with mode: 0644]
arch/openrisc/kernel/or32_ksyms.c [new file with mode: 0644]
arch/openrisc/kernel/process.c [new file with mode: 0644]
arch/openrisc/kernel/prom.c [new file with mode: 0644]
arch/openrisc/kernel/ptrace.c [new file with mode: 0644]
arch/openrisc/kernel/setup.c [new file with mode: 0644]
arch/openrisc/kernel/signal.c [new file with mode: 0644]
arch/openrisc/kernel/sys_call_table.c [new file with mode: 0644]
arch/openrisc/kernel/sys_or32.c [new file with mode: 0644]
arch/openrisc/kernel/time.c [new file with mode: 0644]
arch/openrisc/kernel/traps.c [new file with mode: 0644]
arch/openrisc/kernel/vmlinux.h [new file with mode: 0644]
arch/openrisc/kernel/vmlinux.lds.S [new file with mode: 0644]
arch/openrisc/lib/Makefile [new file with mode: 0644]
arch/openrisc/lib/delay.c [new file with mode: 0644]
arch/openrisc/lib/string.S [new file with mode: 0644]
arch/openrisc/mm/Makefile [new file with mode: 0644]
arch/openrisc/mm/fault.c [new file with mode: 0644]
arch/openrisc/mm/init.c [new file with mode: 0644]
arch/openrisc/mm/ioremap.c [new file with mode: 0644]
arch/openrisc/mm/tlb.c [new file with mode: 0644]
arch/parisc/kernel/module.c
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/exception-64s.h
arch/powerpc/include/asm/hvcall.h
arch/powerpc/include/asm/kvm.h
arch/powerpc/include/asm/kvm_asm.h
arch/powerpc/include/asm/kvm_book3s.h
arch/powerpc/include/asm/kvm_book3s_64.h
arch/powerpc/include/asm/kvm_book3s_asm.h
arch/powerpc/include/asm/kvm_booke.h
arch/powerpc/include/asm/kvm_e500.h
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/asm/kvm_ppc.h
arch/powerpc/include/asm/mmu-hash64.h
arch/powerpc/include/asm/paca.h
arch/powerpc/include/asm/ppc_asm.h
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/reg_booke.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/cpu_setup_power7.S
arch/powerpc/kernel/cpu_setup_ppc970.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/idle_power7.S
arch/powerpc/kernel/module.c
arch/powerpc/kernel/module_32.c
arch/powerpc/kernel/module_64.c
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/traps.c
arch/powerpc/kvm/44x_tlb.c
arch/powerpc/kvm/Kconfig
arch/powerpc/kvm/Makefile
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/book3s_64_mmu.c
arch/powerpc/kvm/book3s_64_mmu_hv.c [new file with mode: 0644]
arch/powerpc/kvm/book3s_64_vio_hv.c [new file with mode: 0644]
arch/powerpc/kvm/book3s_exports.c
arch/powerpc/kvm/book3s_hv.c [new file with mode: 0644]
arch/powerpc/kvm/book3s_hv_builtin.c [new file with mode: 0644]
arch/powerpc/kvm/book3s_hv_interrupts.S [new file with mode: 0644]
arch/powerpc/kvm/book3s_hv_rm_mmu.c [new file with mode: 0644]
arch/powerpc/kvm/book3s_hv_rmhandlers.S [new file with mode: 0644]
arch/powerpc/kvm/book3s_interrupts.S
arch/powerpc/kvm/book3s_mmu_hpte.c
arch/powerpc/kvm/book3s_pr.c [new file with mode: 0644]
arch/powerpc/kvm/book3s_rmhandlers.S
arch/powerpc/kvm/book3s_segment.S
arch/powerpc/kvm/booke.c
arch/powerpc/kvm/booke.h
arch/powerpc/kvm/booke_interrupts.S
arch/powerpc/kvm/e500.c
arch/powerpc/kvm/e500_emulate.c
arch/powerpc/kvm/e500_tlb.c
arch/powerpc/kvm/e500_tlb.h
arch/powerpc/kvm/powerpc.c
arch/powerpc/kvm/timing.c
arch/powerpc/kvm/trace.h
arch/powerpc/mm/hash_native_64.c
arch/powerpc/platforms/iseries/exception.S
arch/powerpc/platforms/iseries/exception.h
arch/powerpc/sysdev/xics/icp-native.c
arch/s390/crypto/sha256_s390.c
arch/s390/kernel/module.c
arch/score/kernel/module.c
arch/sh/include/asm/delay.h
arch/sh/kernel/module.c
arch/sparc/kernel/module.c
arch/tile/kernel/module.c
arch/unicore32/kernel/module.c
arch/x86/Kconfig
arch/x86/crypto/ghash-clmulni-intel_glue.c
arch/x86/include/asm/delay.h
arch/x86/include/asm/kvm_emulate.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/kvm_para.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/paravirt.h
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/processor-flags.h
arch/x86/include/asm/vmx.h
arch/x86/include/asm/xen/hypercall.h
arch/x86/include/asm/xen/trace_types.h [new file with mode: 0644]
arch/x86/kernel/kvm.c
arch/x86/kernel/kvmclock.c
arch/x86/kernel/module.c
arch/x86/kernel/paravirt.c
arch/x86/kvm/Kconfig
arch/x86/kvm/emulate.c
arch/x86/kvm/mmu.c
arch/x86/kvm/mmu.h
arch/x86/kvm/mmu_audit.c
arch/x86/kvm/mmutrace.h
arch/x86/kvm/paging_tmpl.h
arch/x86/kvm/svm.c
arch/x86/kvm/trace.h
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h
arch/x86/xen/Makefile
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
arch/x86/xen/multicalls.c
arch/x86/xen/multicalls.h
arch/x86/xen/trace.c [new file with mode: 0644]
arch/xtensa/kernel/module.c
crypto/Kconfig
crypto/algif_hash.c
crypto/arc4.c
crypto/crc32c.c
crypto/gf128mul.c
crypto/sha1_generic.c
crypto/testmgr.h
drivers/char/hw_random/Kconfig
drivers/char/hw_random/Makefile
drivers/char/hw_random/nomadik-rng.c
drivers/char/hw_random/omap-rng.c
drivers/char/hw_random/ppc4xx-rng.c [new file with mode: 0644]
drivers/char/hw_random/timeriomem-rng.c
drivers/crypto/amcc/crypto4xx_core.c
drivers/crypto/caam/caamalg.c
drivers/crypto/caam/compat.h
drivers/crypto/caam/ctrl.c
drivers/crypto/caam/desc_constr.h
drivers/crypto/omap-sham.c
drivers/crypto/talitos.c
drivers/of/of_pci.c
include/asm-generic/delay.h
include/asm-generic/io.h
include/asm-generic/iomap.h
include/linux/kvm.h
include/linux/kvm_host.h
include/linux/module.h
include/linux/moduleloader.h
include/trace/events/xen.h [new file with mode: 0644]
kernel/compat.c
kernel/delayacct.c
kernel/module.c
kernel/params.c
kernel/sched.c
kernel/sched_features.h
lib/iomap.c
scripts/mod/modpost.c
virt/kvm/assigned-dev.c
virt/kvm/iommu.c
virt/kvm/kvm_main.c

index aa47be7..40cc653 100644 (file)
@@ -1159,10 +1159,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        for all guests.
                        Default is 1 (enabled) if in 64bit or 32bit-PAE mode
 
-       kvm-intel.bypass_guest_pf=
-                       [KVM,Intel] Disables bypassing of guest page faults
-                       on Intel chips. Default is 1 (enabled)
-
        kvm-intel.ept=  [KVM,Intel] Disable extended page tables
                        (virtualized MMU) support on capable Intel chips.
                        Default is 1 (enabled)
@@ -1737,6 +1733,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
        no-kvmapf       [X86,KVM] Disable paravirtualized asynchronous page
                        fault handling.
 
+       no-steal-acc    [X86,KVM] Disable paravirtualized steal time accounting.
+                       steal time is computed, but won't influence scheduler
+                       behaviour
+
        nolapic         [X86-32,APIC] Do not enable or use the local APIC.
 
        nolapic_timer   [X86-32,APIC] Do not use the local APIC timer.
index 42542eb..b0e4b9c 100644 (file)
@@ -180,6 +180,19 @@ KVM_CHECK_EXTENSION ioctl() to determine the value for max_vcpus at run-time.
 If the KVM_CAP_NR_VCPUS does not exist, you should assume that max_vcpus is 4
 cpus max.
 
+On powerpc using book3s_hv mode, the vcpus are mapped onto virtual
+threads in one or more virtual CPU cores.  (This is because the
+hardware requires all the hardware threads in a CPU core to be in the
+same partition.)  The KVM_CAP_PPC_SMT capability indicates the number
+of vcpus per virtual core (vcore).  The vcore id is obtained by
+dividing the vcpu id by the number of vcpus per vcore.  The vcpus in a
+given vcore will always be in the same physical core as each other
+(though that might be a different physical core from time to time).
+Userspace can control the threading (SMT) mode of the guest by its
+allocation of vcpu ids.  For example, if userspace wants
+single-threaded guest vcpus, it should make all vcpu ids be a multiple
+of the number of vcpus per vcore.
+
 4.8 KVM_GET_DIRTY_LOG (vm ioctl)
 
 Capability: basic
@@ -1143,15 +1156,10 @@ Assigns an IRQ to a passed-through device.
 
 struct kvm_assigned_irq {
        __u32 assigned_dev_id;
-       __u32 host_irq;
+       __u32 host_irq; /* ignored (legacy field) */
        __u32 guest_irq;
        __u32 flags;
        union {
-               struct {
-                       __u32 addr_lo;
-                       __u32 addr_hi;
-                       __u32 data;
-               } guest_msi;
                __u32 reserved[12];
        };
 };
@@ -1239,8 +1247,10 @@ Type: vm ioctl
 Parameters: struct kvm_assigned_msix_nr (in)
 Returns: 0 on success, -1 on error
 
-Set the number of MSI-X interrupts for an assigned device. This service can
-only be called once in the lifetime of an assigned device.
+Set the number of MSI-X interrupts for an assigned device. The number is
+reset again by terminating the MSI-X assignment of the device via
+KVM_DEASSIGN_DEV_IRQ. Calling this service more than once at any earlier
+point will fail.
 
 struct kvm_assigned_msix_nr {
        __u32 assigned_dev_id;
@@ -1291,6 +1301,135 @@ Returns the tsc frequency of the guest. The unit of the return value is
 KHz. If the host has unstable tsc this ioctl returns -EIO instead as an
 error.
 
+4.56 KVM_GET_LAPIC
+
+Capability: KVM_CAP_IRQCHIP
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_lapic_state (out)
+Returns: 0 on success, -1 on error
+
+#define KVM_APIC_REG_SIZE 0x400
+struct kvm_lapic_state {
+       char regs[KVM_APIC_REG_SIZE];
+};
+
+Reads the Local APIC registers and copies them into the input argument.  The
+data format and layout are the same as documented in the architecture manual.
+
+4.57 KVM_SET_LAPIC
+
+Capability: KVM_CAP_IRQCHIP
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_lapic_state (in)
+Returns: 0 on success, -1 on error
+
+#define KVM_APIC_REG_SIZE 0x400
+struct kvm_lapic_state {
+       char regs[KVM_APIC_REG_SIZE];
+};
+
+Copies the input argument into the the Local APIC registers.  The data format
+and layout are the same as documented in the architecture manual.
+
+4.58 KVM_IOEVENTFD
+
+Capability: KVM_CAP_IOEVENTFD
+Architectures: all
+Type: vm ioctl
+Parameters: struct kvm_ioeventfd (in)
+Returns: 0 on success, !0 on error
+
+This ioctl attaches or detaches an ioeventfd to a legal pio/mmio address
+within the guest.  A guest write in the registered address will signal the
+provided event instead of triggering an exit.
+
+struct kvm_ioeventfd {
+       __u64 datamatch;
+       __u64 addr;        /* legal pio/mmio address */
+       __u32 len;         /* 1, 2, 4, or 8 bytes    */
+       __s32 fd;
+       __u32 flags;
+       __u8  pad[36];
+};
+
+The following flags are defined:
+
+#define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch)
+#define KVM_IOEVENTFD_FLAG_PIO       (1 << kvm_ioeventfd_flag_nr_pio)
+#define KVM_IOEVENTFD_FLAG_DEASSIGN  (1 << kvm_ioeventfd_flag_nr_deassign)
+
+If datamatch flag is set, the event will be signaled only if the written value
+to the registered address is equal to datamatch in struct kvm_ioeventfd.
+
+4.62 KVM_CREATE_SPAPR_TCE
+
+Capability: KVM_CAP_SPAPR_TCE
+Architectures: powerpc
+Type: vm ioctl
+Parameters: struct kvm_create_spapr_tce (in)
+Returns: file descriptor for manipulating the created TCE table
+
+This creates a virtual TCE (translation control entry) table, which
+is an IOMMU for PAPR-style virtual I/O.  It is used to translate
+logical addresses used in virtual I/O into guest physical addresses,
+and provides a scatter/gather capability for PAPR virtual I/O.
+
+/* for KVM_CAP_SPAPR_TCE */
+struct kvm_create_spapr_tce {
+       __u64 liobn;
+       __u32 window_size;
+};
+
+The liobn field gives the logical IO bus number for which to create a
+TCE table.  The window_size field specifies the size of the DMA window
+which this TCE table will translate - the table will contain one 64
+bit TCE entry for every 4kiB of the DMA window.
+
+When the guest issues an H_PUT_TCE hcall on a liobn for which a TCE
+table has been created using this ioctl(), the kernel will handle it
+in real mode, updating the TCE table.  H_PUT_TCE calls for other
+liobns will cause a vm exit and must be handled by userspace.
+
+The return value is a file descriptor which can be passed to mmap(2)
+to map the created TCE table into userspace.  This lets userspace read
+the entries written by kernel-handled H_PUT_TCE calls, and also lets
+userspace update the TCE table directly which is useful in some
+circumstances.
+
+4.63 KVM_ALLOCATE_RMA
+
+Capability: KVM_CAP_PPC_RMA
+Architectures: powerpc
+Type: vm ioctl
+Parameters: struct kvm_allocate_rma (out)
+Returns: file descriptor for mapping the allocated RMA
+
+This allocates a Real Mode Area (RMA) from the pool allocated at boot
+time by the kernel.  An RMA is a physically-contiguous, aligned region
+of memory used on older POWER processors to provide the memory which
+will be accessed by real-mode (MMU off) accesses in a KVM guest.
+POWER processors support a set of sizes for the RMA that usually
+includes 64MB, 128MB, 256MB and some larger powers of two.
+
+/* for KVM_ALLOCATE_RMA */
+struct kvm_allocate_rma {
+       __u64 rma_size;
+};
+
+The return value is a file descriptor which can be passed to mmap(2)
+to map the allocated RMA into userspace.  The mapped area can then be
+passed to the KVM_SET_USER_MEMORY_REGION ioctl to establish it as the
+RMA for a virtual machine.  The size of the RMA in bytes (which is
+fixed at host kernel boot time) is returned in the rma_size field of
+the argument structure.
+
+The KVM_CAP_PPC_RMA capability is 1 or 2 if the KVM_ALLOCATE_RMA ioctl
+is supported; 2 if the processor requires all virtual machines to have
+an RMA, or 1 if the processor can use an RMA but doesn't require it,
+because it supports the Virtual RMA (VRMA) facility.
+
 5. The kvm_run structure
 
 Application code obtains a pointer to the kvm_run structure by
@@ -1473,6 +1612,23 @@ Userspace can now handle the hypercall and when it's done modify the gprs as
 necessary. Upon guest entry all guest GPRs will then be replaced by the values
 in this struct.
 
+               /* KVM_EXIT_PAPR_HCALL */
+               struct {
+                       __u64 nr;
+                       __u64 ret;
+                       __u64 args[9];
+               } papr_hcall;
+
+This is used on 64-bit PowerPC when emulating a pSeries partition,
+e.g. with the 'pseries' machine type in qemu.  It occurs when the
+guest does a hypercall using the 'sc 1' instruction.  The 'nr' field
+contains the hypercall number (from the guest R3), and 'args' contains
+the arguments (from the guest R4 - R12).  Userspace should put the
+return code in 'ret' and any extra returned values in args[].
+The possible hypercalls are defined in the Power Architecture Platform
+Requirements (PAPR) document available from www.power.org (free
+developer registration required to access it).
+
                /* Fix the size of the union. */
                char padding[256];
        };
index f46aa58..5dc972c 100644 (file)
@@ -165,6 +165,10 @@ Shadow pages contain the following information:
     Contains the value of efer.nxe for which the page is valid.
   role.cr0_wp:
     Contains the value of cr0.wp for which the page is valid.
+  role.smep_andnot_wp:
+    Contains the value of cr4.smep && !cr0.wp for which the page is valid
+    (pages for which this is true are different from other pages; see the
+    treatment of cr0.wp=0 below).
   gfn:
     Either the guest page table containing the translations shadowed by this
     page, or the base page frame for linear translations.  See role.direct.
@@ -317,6 +321,20 @@ on fault type:
 
 (user write faults generate a #PF)
 
+In the first case there is an additional complication if CR4.SMEP is
+enabled: since we've turned the page into a kernel page, the kernel may now
+execute it.  We handle this by also setting spte.nx.  If we get a user
+fetch or read fault, we'll change spte.u=1 and spte.nx=gpte.nx back.
+
+To prevent an spte that was converted into a kernel page with cr0.wp=0
+from being written by the kernel after cr0.wp has changed to 1, we make
+the value of cr0.wp part of the page role.  This means that an spte created
+with one value of cr0.wp cannot be used when cr0.wp has a different value -
+it will simply be missed by the shadow page lookup code.  A similar issue
+exists when an spte created with cr0.wp=0 and cr4.smep=0 is used after
+changing cr4.smep to 1.  To avoid this, the value of !cr0.wp && cr4.smep
+is also made a part of the page role.
+
 Large pages
 ===========
 
index d079aed..5031780 100644 (file)
@@ -185,3 +185,37 @@ MSR_KVM_ASYNC_PF_EN: 0x4b564d02
 
        Currently type 2 APF will be always delivered on the same vcpu as
        type 1 was, but guest should not rely on that.
+
+MSR_KVM_STEAL_TIME: 0x4b564d03
+
+       data: 64-byte alignment physical address of a memory area which must be
+       in guest RAM, plus an enable bit in bit 0. This memory is expected to
+       hold a copy of the following structure:
+
+       struct kvm_steal_time {
+               __u64 steal;
+               __u32 version;
+               __u32 flags;
+               __u32 pad[12];
+       }
+
+       whose data will be filled in by the hypervisor periodically. Only one
+       write, or registration, is needed for each VCPU. The interval between
+       updates of this structure is arbitrary and implementation-dependent.
+       The hypervisor may update this structure at any time it sees fit until
+       anything with bit0 == 0 is written to it. Guest is required to make sure
+       this structure is initialized to zero.
+
+       Fields have the following meanings:
+
+               version: a sequence counter. In other words, guest has to check
+               this field before and after grabbing time information and make
+               sure they are both equal and even. An odd version indicates an
+               in-progress update.
+
+               flags: At this point, always zero. May be used to indicate
+               changes in this structure in the future.
+
+               steal: the amount of time in which this vCPU did not run, in
+               nanoseconds. Time during which the vcpu is idle, will not be
+               reported as steal time.
diff --git a/Documentation/virtual/kvm/nested-vmx.txt b/Documentation/virtual/kvm/nested-vmx.txt
new file mode 100644 (file)
index 0000000..8ed937d
--- /dev/null
@@ -0,0 +1,251 @@
+Nested VMX
+==========
+
+Overview
+---------
+
+On Intel processors, KVM uses Intel's VMX (Virtual-Machine eXtensions)
+to easily and efficiently run guest operating systems. Normally, these guests
+*cannot* themselves be hypervisors running their own guests, because in VMX,
+guests cannot use VMX instructions.
+
+The "Nested VMX" feature adds this missing capability - of running guest
+hypervisors (which use VMX) with their own nested guests. It does so by
+allowing a guest to use VMX instructions, and correctly and efficiently
+emulating them using the single level of VMX available in the hardware.
+
+We describe in much greater detail the theory behind the nested VMX feature,
+its implementation and its performance characteristics, in the OSDI 2010 paper
+"The Turtles Project: Design and Implementation of Nested Virtualization",
+available at:
+
+       http://www.usenix.org/events/osdi10/tech/full_papers/Ben-Yehuda.pdf
+
+
+Terminology
+-----------
+
+Single-level virtualization has two levels - the host (KVM) and the guests.
+In nested virtualization, we have three levels: The host (KVM), which we call
+L0, the guest hypervisor, which we call L1, and its nested guest, which we
+call L2.
+
+
+Known limitations
+-----------------
+
+The current code supports running Linux guests under KVM guests.
+Only 64-bit guest hypervisors are supported.
+
+Additional patches for running Windows under guest KVM, and Linux under
+guest VMware server, and support for nested EPT, are currently running in
+the lab, and will be sent as follow-on patchsets.
+
+
+Running nested VMX
+------------------
+
+The nested VMX feature is disabled by default. It can be enabled by giving
+the "nested=1" option to the kvm-intel module.
+
+No modifications are required to user space (qemu). However, qemu's default
+emulated CPU type (qemu64) does not list the "VMX" CPU feature, so it must be
+explicitly enabled, by giving qemu one of the following options:
+
+     -cpu host              (emulated CPU has all features of the real CPU)
+
+     -cpu qemu64,+vmx       (add just the vmx feature to a named CPU type)
+
+
+ABIs
+----
+
+Nested VMX aims to present a standard and (eventually) fully-functional VMX
+implementation for the a guest hypervisor to use. As such, the official
+specification of the ABI that it provides is Intel's VMX specification,
+namely volume 3B of their "Intel 64 and IA-32 Architectures Software
+Developer's Manual". Not all of VMX's features are currently fully supported,
+but the goal is to eventually support them all, starting with the VMX features
+which are used in practice by popular hypervisors (KVM and others).
+
+As a VMX implementation, nested VMX presents a VMCS structure to L1.
+As mandated by the spec, other than the two fields revision_id and abort,
+this structure is *opaque* to its user, who is not supposed to know or care
+about its internal structure. Rather, the structure is accessed through the
+VMREAD and VMWRITE instructions.
+Still, for debugging purposes, KVM developers might be interested to know the
+internals of this structure; This is struct vmcs12 from arch/x86/kvm/vmx.c.
+
+The name "vmcs12" refers to the VMCS that L1 builds for L2. In the code we
+also have "vmcs01", the VMCS that L0 built for L1, and "vmcs02" is the VMCS
+which L0 builds to actually run L2 - how this is done is explained in the
+aforementioned paper.
+
+For convenience, we repeat the content of struct vmcs12 here. If the internals
+of this structure changes, this can break live migration across KVM versions.
+VMCS12_REVISION (from vmx.c) should be changed if struct vmcs12 or its inner
+struct shadow_vmcs is ever changed.
+
+       typedef u64 natural_width;
+       struct __packed vmcs12 {
+               /* According to the Intel spec, a VMCS region must start with
+                * these two user-visible fields */
+               u32 revision_id;
+               u32 abort;
+
+               u32 launch_state; /* set to 0 by VMCLEAR, to 1 by VMLAUNCH */
+               u32 padding[7]; /* room for future expansion */
+
+               u64 io_bitmap_a;
+               u64 io_bitmap_b;
+               u64 msr_bitmap;
+               u64 vm_exit_msr_store_addr;
+               u64 vm_exit_msr_load_addr;
+               u64 vm_entry_msr_load_addr;
+               u64 tsc_offset;
+               u64 virtual_apic_page_addr;
+               u64 apic_access_addr;
+               u64 ept_pointer;
+               u64 guest_physical_address;
+               u64 vmcs_link_pointer;
+               u64 guest_ia32_debugctl;
+               u64 guest_ia32_pat;
+               u64 guest_ia32_efer;
+               u64 guest_pdptr0;
+               u64 guest_pdptr1;
+               u64 guest_pdptr2;
+               u64 guest_pdptr3;
+               u64 host_ia32_pat;
+               u64 host_ia32_efer;
+               u64 padding64[8]; /* room for future expansion */
+               natural_width cr0_guest_host_mask;
+               natural_width cr4_guest_host_mask;
+               natural_width cr0_read_shadow;
+               natural_width cr4_read_shadow;
+               natural_width cr3_target_value0;
+               natural_width cr3_target_value1;
+               natural_width cr3_target_value2;
+               natural_width cr3_target_value3;
+               natural_width exit_qualification;
+               natural_width guest_linear_address;
+               natural_width guest_cr0;
+               natural_width guest_cr3;
+               natural_width guest_cr4;
+               natural_width guest_es_base;
+               natural_width guest_cs_base;
+               natural_width guest_ss_base;
+               natural_width guest_ds_base;
+               natural_width guest_fs_base;
+               natural_width guest_gs_base;
+               natural_width guest_ldtr_base;
+               natural_width guest_tr_base;
+               natural_width guest_gdtr_base;
+               natural_width guest_idtr_base;
+               natural_width guest_dr7;
+               natural_width guest_rsp;
+               natural_width guest_rip;
+               natural_width guest_rflags;
+               natural_width guest_pending_dbg_exceptions;
+               natural_width guest_sysenter_esp;
+               natural_width guest_sysenter_eip;
+               natural_width host_cr0;
+               natural_width host_cr3;
+               natural_width host_cr4;
+               natural_width host_fs_base;
+               natural_width host_gs_base;
+               natural_width host_tr_base;
+               natural_width host_gdtr_base;
+               natural_width host_idtr_base;
+               natural_width host_ia32_sysenter_esp;
+               natural_width host_ia32_sysenter_eip;
+               natural_width host_rsp;
+               natural_width host_rip;
+               natural_width paddingl[8]; /* room for future expansion */
+               u32 pin_based_vm_exec_control;
+               u32 cpu_based_vm_exec_control;
+               u32 exception_bitmap;
+               u32 page_fault_error_code_mask;
+               u32 page_fault_error_code_match;
+               u32 cr3_target_count;
+               u32 vm_exit_controls;
+               u32 vm_exit_msr_store_count;
+               u32 vm_exit_msr_load_count;
+               u32 vm_entry_controls;
+               u32 vm_entry_msr_load_count;
+               u32 vm_entry_intr_info_field;
+               u32 vm_entry_exception_error_code;
+               u32 vm_entry_instruction_len;
+               u32 tpr_threshold;
+               u32 secondary_vm_exec_control;
+               u32 vm_instruction_error;
+               u32 vm_exit_reason;
+               u32 vm_exit_intr_info;
+               u32 vm_exit_intr_error_code;
+               u32 idt_vectoring_info_field;
+               u32 idt_vectoring_error_code;
+               u32 vm_exit_instruction_len;
+               u32 vmx_instruction_info;
+               u32 guest_es_limit;
+               u32 guest_cs_limit;
+               u32 guest_ss_limit;
+               u32 guest_ds_limit;
+               u32 guest_fs_limit;
+               u32 guest_gs_limit;
+               u32 guest_ldtr_limit;
+               u32 guest_tr_limit;
+               u32 guest_gdtr_limit;
+               u32 guest_idtr_limit;
+               u32 guest_es_ar_bytes;
+               u32 guest_cs_ar_bytes;
+               u32 guest_ss_ar_bytes;
+               u32 guest_ds_ar_bytes;
+               u32 guest_fs_ar_bytes;
+               u32 guest_gs_ar_bytes;
+               u32 guest_ldtr_ar_bytes;
+               u32 guest_tr_ar_bytes;
+               u32 guest_interruptibility_info;
+               u32 guest_activity_state;
+               u32 guest_sysenter_cs;
+               u32 host_ia32_sysenter_cs;
+               u32 padding32[8]; /* room for future expansion */
+               u16 virtual_processor_id;
+               u16 guest_es_selector;
+               u16 guest_cs_selector;
+               u16 guest_ss_selector;
+               u16 guest_ds_selector;
+               u16 guest_fs_selector;
+               u16 guest_gs_selector;
+               u16 guest_ldtr_selector;
+               u16 guest_tr_selector;
+               u16 host_es_selector;
+               u16 host_cs_selector;
+               u16 host_ss_selector;
+               u16 host_ds_selector;
+               u16 host_fs_selector;
+               u16 host_gs_selector;
+               u16 host_tr_selector;
+       };
+
+
+Authors
+-------
+
+These patches were written by:
+     Abel Gordon, abelg <at> il.ibm.com
+     Nadav Har'El, nyh <at> il.ibm.com
+     Orit Wasserman, oritw <at> il.ibm.com
+     Ben-Ami Yassor, benami <at> il.ibm.com
+     Muli Ben-Yehuda, muli <at> il.ibm.com
+
+With contributions by:
+     Anthony Liguori, aliguori <at> us.ibm.com
+     Mike Day, mdday <at> us.ibm.com
+     Michael Factor, factor <at> il.ibm.com
+     Zvi Dubitzky, dubi <at> il.ibm.com
+
+And valuable reviews by:
+     Avi Kivity, avi <at> redhat.com
+     Gleb Natapov, gleb <at> redhat.com
+     Marcelo Tosatti, mtosatti <at> redhat.com
+     Kevin Tian, kevin.tian <at> intel.com
+     and others.
index 3ab969c..2b7ce19 100644 (file)
@@ -68,9 +68,11 @@ page that contains parts of supervisor visible register state. The guest can
 map this shared page using the KVM hypercall KVM_HC_PPC_MAP_MAGIC_PAGE.
 
 With this hypercall issued the guest always gets the magic page mapped at the
-desired location in effective and physical address space. For now, we always
-map the page to -4096. This way we can access it using absolute load and store
-functions. The following instruction reads the first field of the magic page:
+desired location. The first parameter indicates the effective address when the
+MMU is enabled. The second parameter indicates the address in real mode, if
+applicable to the target. For now, we always map the page to -4096. This way we
+can access it using absolute load and store functions. The following
+instruction reads the first field of the magic page:
 
        ld      rX, -4096(0)
 
index 63524a0..43392c9 100644 (file)
@@ -4688,6 +4688,14 @@ F:       drivers/of
 F:     include/linux/of*.h
 K:     of_get_property
 
+OPENRISC ARCHITECTURE
+M:     Jonas Bonn <jonas@southpole.se>
+W:     http://openrisc.net
+L:     linux@lists.openrisc.net
+S:     Maintained
+T:     git git://openrisc.net/~jonas/linux
+F:     arch/openrisc
+
 OPL4 DRIVER
 M:     Clemens Ladisch <clemens@ladisch.de>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
index ebc3c89..2fd00b7 100644 (file)
 #define DEBUGP(fmt...)
 #endif
 
-void *
-module_alloc(unsigned long size)
-{
-       if (size == 0)
-               return NULL;
-       return vmalloc(size);
-}
-
-void
-module_free(struct module *mod, void *module_region)
-{
-       vfree(module_region);
-}
-
 /* Allocate the GOT at the end of the core sections.  */
 
 struct got_entry {
@@ -155,14 +141,6 @@ module_frob_arch_sections(Elf64_Ehdr *hdr, Elf64_Shdr *sechdrs,
        return 0;
 }
 
-int
-apply_relocate(Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
-              unsigned int relsec, struct module *me)
-{
-       printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name);
-       return -ENOEXEC;
-}
-
 int
 apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
                   unsigned int symindex, unsigned int relsec,
@@ -302,15 +280,3 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
 
        return 0;
 }
-
-int
-module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
-               struct module *me)
-{
-       return 0;
-}
-
-void
-module_arch_cleanup(struct module *mod)
-{
-}
index 016d6a0..05b3776 100644 (file)
@@ -43,25 +43,7 @@ void *module_alloc(unsigned long size)
                                GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
                                __builtin_return_address(0));
 }
-#else /* CONFIG_MMU */
-void *module_alloc(unsigned long size)
-{
-       return size == 0 ? NULL : vmalloc(size);
-}
-#endif /* !CONFIG_MMU */
-
-void module_free(struct module *module, void *region)
-{
-       vfree(region);
-}
-
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-                             Elf_Shdr *sechdrs,
-                             char *secstrings,
-                             struct module *mod)
-{
-       return 0;
-}
+#endif
 
 int
 apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
@@ -265,15 +247,6 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
        return 0;
 }
 
-int
-apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
-                  unsigned int symindex, unsigned int relsec, struct module *module)
-{
-       printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
-              module->name);
-       return -ENOEXEC;
-}
-
 struct mod_unwind_map {
        const Elf_Shdr *unw_sec;
        const Elf_Shdr *txt_sec;
index a0ed9a9..9670e12 100644 (file)
@@ -1,26 +1 @@
-#ifndef __ASM_AVR32_DELAY_H
-#define __ASM_AVR32_DELAY_H
-
-/*
- * Copyright (C) 1993 Linus Torvalds
- *
- * Delay routines calling functions in arch/avr32/lib/delay.c
- */
-
-extern void __bad_udelay(void);
-extern void __bad_ndelay(void);
-
-extern void __udelay(unsigned long usecs);
-extern void __ndelay(unsigned long nsecs);
-extern void __const_udelay(unsigned long xloops);
-extern void __delay(unsigned long loops);
-
-#define udelay(n) (__builtin_constant_p(n) ? \
-       ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \
-       __udelay(n))
-
-#define ndelay(n) (__builtin_constant_p(n) ? \
-       ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
-       __ndelay(n))
-
-#endif /* __ASM_AVR32_DELAY_H */
+#include <asm-generic/delay.h>
index a727f54..596f730 100644 (file)
 #include <linux/moduleloader.h>
 #include <linux/vmalloc.h>
 
-void *module_alloc(unsigned long size)
-{
-       if (size == 0)
-               return NULL;
-       return vmalloc(size);
-}
-
 void module_free(struct module *mod, void *module_region)
 {
        vfree(mod->arch.syminfo);
@@ -299,15 +292,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
        return ret;
 }
 
-int apply_relocate(Elf32_Shdr *sechdrs, const char *strtab,
-                  unsigned int symindex, unsigned int relindex,
-                  struct module *module)
-{
-       printk(KERN_ERR "module %s: REL relocations are not supported\n",
-               module->name);
-       return -ENOEXEC;
-}
-
 int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
                    struct module *module)
 {
@@ -316,7 +300,3 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
 
        return 0;
 }
-
-void module_arch_cleanup(struct module *module)
-{
-}
index 35e350c..4489efc 100644 (file)
 #include <asm/cacheflush.h>
 #include <asm/uaccess.h>
 
-void *module_alloc(unsigned long size)
-{
-       if (size == 0)
-               return NULL;
-       return vmalloc(size);
-}
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-       vfree(module_region);
-}
-
 /* Transfer the section to the L1 memory */
 int
 module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
@@ -150,14 +137,6 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
        return 0;
 }
 
-int
-apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
-              unsigned int symindex, unsigned int relsec, struct module *mod)
-{
-       pr_err(".rel unsupported\n");
-       return -ENOEXEC;
-}
-
 /*************************************************************************/
 /* FUNCTION : apply_relocate_add                                         */
 /* ABSTRACT : Blackfin specific relocation handling for the loadable     */
index bcd502f..37400f5 100644 (file)
 #endif
 
 #ifdef CONFIG_ETRAX_KMALLOCED_MODULES
-#define MALLOC_MODULE(size) kmalloc(size, GFP_KERNEL)
-#define FREE_MODULE(region) kfree(region)
-#else
-#define MALLOC_MODULE(size) vmalloc_exec(size)
-#define FREE_MODULE(region) vfree(region)
-#endif
-
 void *module_alloc(unsigned long size)
 {
        if (size == 0)
                return NULL;
-       return MALLOC_MODULE(size);
+       return kmalloc(size, GFP_KERNEL);
 }
 
-
 /* Free memory returned from module_alloc */
 void module_free(struct module *mod, void *module_region)
 {
-       FREE_MODULE(module_region);
-}
-
-/* We don't need anything special. */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-                             Elf_Shdr *sechdrs,
-                             char *secstrings,
-                             struct module *mod)
-{
-       return 0;
-}
-
-int apply_relocate(Elf32_Shdr *sechdrs,
-                  const char *strtab,
-                  unsigned int symindex,
-                  unsigned int relsec,
-                  struct module *me)
-{
-       printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name);
-       return -ENOEXEC;
+       kfree(module_region);
 }
+#endif
 
 int apply_relocate_add(Elf32_Shdr *sechdrs,
                       const char *strtab,
@@ -108,14 +82,3 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
 
        return 0;
 }
-
-int module_finalize(const Elf_Ehdr *hdr,
-                   const Elf_Shdr *sechdrs,
-                   struct module *me)
-{
-       return 0;
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-}
index 711763c..9d9835f 100644 (file)
 #define DEBUGP(fmt...)
 #endif
 
-void *module_alloc(unsigned long size)
-{
-       if (size == 0)
-               return NULL;
-
-       return vmalloc_exec(size);
-}
-
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-       vfree(module_region);
-}
-
-/* We don't need anything special. */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-                             Elf_Shdr *sechdrs,
-                             char *secstrings,
-                             struct module *mod)
-{
-       return 0;
-}
-
-int apply_relocate(Elf32_Shdr *sechdrs,
-                  const char *strtab,
-                  unsigned int symindex,
-                  unsigned int relsec,
-                  struct module *me)
-{
-       printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name);
-       return -ENOEXEC;
-}
-
-int apply_relocate_add(Elf32_Shdr *sechdrs,
-                      const char *strtab,
-                      unsigned int symindex,
-                      unsigned int relsec,
-                      struct module *me)
-{
-       printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name);
-       return -ENOEXEC;
-}
-
-int module_finalize(const Elf_Ehdr *hdr,
-                   const Elf_Shdr *sechdrs,
-                   struct module *me)
-{
-       return 0;
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-}
+/* TODO: At least one of apply_relocate or apply_relocate_add must be
+ * implemented in order to get working module support.
+ */
index db4953d..1d526e0 100644 (file)
 #define DEBUGP(fmt...)
 #endif
 
-void *module_alloc(unsigned long size)
-{
-       if (size == 0)
-               return NULL;
-       return vmalloc(size);
-}
-
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-       vfree(module_region);
-}
-
-/* We don't need anything special. */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-                             Elf_Shdr *sechdrs,
-                             char *secstrings,
-                             struct module *mod)
-{
-       return 0;
-}
-
-int apply_relocate(Elf32_Shdr *sechdrs,
-                  const char *strtab,
-                  unsigned int symindex,
-                  unsigned int relsec,
-                  struct module *me)
-{
-       printk(KERN_ERR "module %s: RELOCATION unsupported\n",
-              me->name);
-       return -ENOEXEC;
-}
-
 int apply_relocate_add(Elf32_Shdr *sechdrs,
                       const char *strtab,
                       unsigned int symindex,
@@ -107,14 +73,3 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
               me->name, rela[i].r_offset);
        return -ENOEXEC;
 }
-
-int module_finalize(const Elf_Ehdr *hdr,
-                   const Elf_Shdr *sechdrs,
-                   struct module *me)
-{
-       return 0;
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-}
index 2eb0a98..32551d3 100644 (file)
@@ -281,6 +281,10 @@ paravirt_init_missing_ticks_accounting(int cpu)
                pv_time_ops.init_missing_ticks_accounting(cpu);
 }
 
+struct jump_label_key;
+extern struct jump_label_key paravirt_steal_enabled;
+extern struct jump_label_key paravirt_steal_rq_enabled;
+
 static inline int
 paravirt_do_steal_accounting(unsigned long *new_itm)
 {
index 1481b0a..24603be 100644 (file)
@@ -304,14 +304,6 @@ plt_target (struct plt_entry *plt)
 
 #endif /* !USE_BRL */
 
-void *
-module_alloc (unsigned long size)
-{
-       if (!size)
-               return NULL;
-       return vmalloc(size);
-}
-
 void
 module_free (struct module *mod, void *module_region)
 {
@@ -853,14 +845,6 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind
        return 0;
 }
 
-int
-apply_relocate (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
-               unsigned int relsec, struct module *mod)
-{
-       printk(KERN_ERR "module %s: REL relocs in section %u unsupported\n", mod->name, relsec);
-       return -ENOEXEC;
-}
-
 /*
  * Modules contain a single unwind table which covers both the core and the init text
  * sections but since the two are not contiguous, we need to split this table up such that
index a21d7bb..1008682 100644 (file)
@@ -634,6 +634,8 @@ struct pv_irq_ops pv_irq_ops = {
  * pv_time_ops
  * time operations
  */
+struct jump_label_key paravirt_steal_enabled;
+struct jump_label_key paravirt_steal_rq_enabled;
 
 static int
 ia64_native_do_steal_accounting(unsigned long *new_itm)
index 9dd9e99..9670e12 100644 (file)
@@ -1,26 +1 @@
-#ifndef _ASM_M32R_DELAY_H
-#define _ASM_M32R_DELAY_H
-
-/*
- * Copyright (C) 1993 Linus Torvalds
- *
- * Delay routines calling functions in arch/m32r/lib/delay.c
- */
-
-extern void __bad_udelay(void);
-extern void __bad_ndelay(void);
-
-extern void __udelay(unsigned long usecs);
-extern void __ndelay(unsigned long nsecs);
-extern void __const_udelay(unsigned long xloops);
-extern void __delay(unsigned long loops);
-
-#define udelay(n) (__builtin_constant_p(n) ? \
-       ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
-       __udelay(n))
-
-#define ndelay(n) (__builtin_constant_p(n) ? \
-       ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
-       __ndelay(n))
-
-#endif /* _ASM_M32R_DELAY_H */
+#include <asm-generic/delay.h>
index cb5f37d..3071fe8 100644 (file)
 #define DEBUGP(fmt...)
 #endif
 
-void *module_alloc(unsigned long size)
-{
-       if (size == 0)
-               return NULL;
-#ifdef CONFIG_MMU
-       return vmalloc_exec(size);
-#else
-       return vmalloc(size);
-#endif
-}
-
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-       vfree(module_region);
-}
-
-/* We don't need anything special. */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-                             Elf_Shdr *sechdrs,
-                             char *secstrings,
-                             struct module *mod)
-{
-       return 0;
-}
-
 #define COPY_UNALIGNED_WORD(sw, tw, align) \
 { \
        void *__s = &(sw), *__t = &(tw); \
@@ -243,14 +216,3 @@ int apply_relocate(Elf32_Shdr *sechdrs,
        return 0;
 
 }
-
-int module_finalize(const Elf_Ehdr *hdr,
-                   const Elf_Shdr *sechdrs,
-                   struct module *me)
-{
-       return 0;
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-}
index cd6bcb1..ceafc47 100644 (file)
 
 #ifdef CONFIG_MODULES
 
-void *module_alloc(unsigned long size)
-{
-       if (size == 0)
-               return NULL;
-       return vmalloc(size);
-}
-
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-       vfree(module_region);
-}
-
-/* We don't need anything special. */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-                             Elf_Shdr *sechdrs,
-                             char *secstrings,
-                             struct module *mod)
-{
-       return 0;
-}
-
 int apply_relocate(Elf32_Shdr *sechdrs,
                   const char *strtab,
                   unsigned int symindex,
@@ -131,10 +108,6 @@ int module_finalize(const Elf_Ehdr *hdr,
        return 0;
 }
 
-void module_arch_cleanup(struct module *mod)
-{
-}
-
 #endif /* CONFIG_MODULES */
 
 void module_fixup(struct module *mod, struct m68k_fixup_info *start,
index d11ffae..5a097c6 100644 (file)
 #define DEBUGP(fmt...)
 #endif
 
-void *module_alloc(unsigned long size)
-{
-       if (size == 0)
-               return NULL;
-       return vmalloc(size);
-}
-
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-       vfree(module_region);
-}
-
-/* We don't need anything special. */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-                             Elf_Shdr *sechdrs,
-                             char *secstrings,
-                             struct module *mod)
-{
-       return 0;
-}
-
 int apply_relocate(Elf32_Shdr *sechdrs,
                   const char *strtab,
                   unsigned int symindex,
@@ -113,14 +90,3 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
        }
        return 0;
 }
-
-int module_finalize(const Elf_Ehdr *hdr,
-                   const Elf_Shdr *sechdrs,
-                   struct module *me)
-{
-       return 0;
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-}
index 0e73f66..142426f 100644 (file)
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
 
-void *module_alloc(unsigned long size)
-{
-       void *ret;
-       ret = (size == 0) ? NULL : vmalloc(size);
-       pr_debug("module_alloc (%08lx@%08lx)\n", size, (unsigned long int)ret);
-       return ret;
-}
-
-void module_free(struct module *module, void *region)
-{
-       pr_debug("module_free(%s,%08lx)\n", module->name,
-                                       (unsigned long)region);
-       vfree(region);
-}
-
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-                               Elf_Shdr *sechdrs,
-                               char *secstrings,
-                               struct module *mod)
-{
-       return 0;
-}
-
-int apply_relocate(Elf32_Shdr *sechdrs, const char *strtab,
-       unsigned int symindex, unsigned int relsec, struct module *module)
-{
-       printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
-               module->name);
-       return -ENOEXEC;
-}
-
 int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
        unsigned int symindex, unsigned int relsec, struct module *module)
 {
@@ -155,7 +124,3 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
        flush_dcache();
        return 0;
 }
-
-void module_arch_cleanup(struct module *mod)
-{
-}
index dd940b7..4b930ac 100644 (file)
@@ -45,30 +45,14 @@ static struct mips_hi16 *mips_hi16_list;
 static LIST_HEAD(dbe_list);
 static DEFINE_SPINLOCK(dbe_lock);
 
+#ifdef MODULE_START
 void *module_alloc(unsigned long size)
 {
-#ifdef MODULE_START
        return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
                                GFP_KERNEL, PAGE_KERNEL, -1,
                                __builtin_return_address(0));
-#else
-       if (size == 0)
-               return NULL;
-       return vmalloc(size);
-#endif
-}
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-       vfree(module_region);
-}
-
-int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
-                             char *secstrings, struct module *mod)
-{
-       return 0;
 }
+#endif
 
 static int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v)
 {
index 196a111..216ad23 100644 (file)
 #define DEBUGP(fmt, ...)
 #endif
 
-/*
- * allocate storage for a module
- */
-void *module_alloc(unsigned long size)
-{
-       if (size == 0)
-               return NULL;
-       return vmalloc_exec(size);
-}
-
-/*
- * free memory returned from module_alloc()
- */
-void module_free(struct module *mod, void *module_region)
-{
-       vfree(module_region);
-}
-
-/*
- * allow the arch to fix up the section table
- * - we don't need anything special
- */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-                             Elf_Shdr *sechdrs,
-                             char *secstrings,
-                             struct module *mod)
-{
-       return 0;
-}
-
 static void reloc_put16(uint8_t *p, uint32_t val)
 {
        p[0] = val & 0xff;
@@ -80,20 +50,6 @@ static void reloc_put32(uint8_t *p, uint32_t val)
        reloc_put16(p+2, val >> 16);
 }
 
-/*
- * apply a REL relocation
- */
-int apply_relocate(Elf32_Shdr *sechdrs,
-                  const char *strtab,
-                  unsigned int symindex,
-                  unsigned int relsec,
-                  struct module *me)
-{
-       printk(KERN_ERR "module %s: RELOCATION unsupported\n",
-              me->name);
-       return -ENOEXEC;
-}
-
 /*
  * apply a RELA relocation
  */
@@ -198,20 +154,3 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
        }
        return 0;
 }
-
-/*
- * finish loading the module
- */
-int module_finalize(const Elf_Ehdr *hdr,
-                   const Elf_Shdr *sechdrs,
-                   struct module *me)
-{
-       return 0;
-}
-
-/*
- * finish clearing the module
- */
-void module_arch_cleanup(struct module *mod)
-{
-}
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
new file mode 100644 (file)
index 0000000..4558baf
--- /dev/null
@@ -0,0 +1,207 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+
+config OPENRISC
+       def_bool y
+       select OF
+       select OF_EARLY_FLATTREE
+       select HAVE_MEMBLOCK
+       select ARCH_WANT_OPTIONAL_GPIOLIB
+        select HAVE_ARCH_TRACEHOOK
+       select HAVE_GENERIC_HARDIRQS
+       select GENERIC_IRQ_CHIP
+       select GENERIC_IRQ_PROBE
+       select GENERIC_IRQ_SHOW
+       select GENERIC_IOMAP
+
+config MMU
+       def_bool y
+
+config WISHBONE_BUS_BIG_ENDIAN
+       def_bool y
+
+config SYMBOL_PREFIX
+        string
+        default ""
+
+config HAVE_DMA_ATTRS
+       def_bool y
+
+config UID16
+       def_bool y
+
+config RWSEM_GENERIC_SPINLOCK
+       def_bool y
+
+config RWSEM_XCHGADD_ALGORITHM
+       def_bool n
+
+config GENERIC_HWEIGHT
+       def_bool y
+
+config GENERIC_IOMAP
+       def_bool y
+
+config NO_IOPORT
+       def_bool y
+
+config GENERIC_GPIO
+       def_bool y
+
+config GENERIC_CLOCKEVENTS
+       def_bool y
+
+config TRACE_IRQFLAGS_SUPPORT
+        def_bool y
+
+# For now, use generic checksum functions
+#These can be reimplemented in assembly later if so inclined
+config GENERIC_CSUM
+        def_bool y
+
+config GENERIC_FIND_NEXT_BIT
+       def_bool y
+
+source "init/Kconfig"
+
+
+menu "Processor type and features"
+
+choice
+       prompt "Subarchitecture"
+       default OR1K_1200
+
+config OR1K_1200
+       bool "OR1200"
+       help
+         Generic OpenRISC 1200 architecture
+
+endchoice
+
+config OPENRISC_BUILTIN_DTB
+        string "Builtin DTB"
+        default ""
+
+menu "Class II Instructions"
+
+config OPENRISC_HAVE_INST_FF1
+       bool "Have instruction l.ff1"
+       default y
+       help
+         Select this if your implementation has the Class II instruction l.ff1
+
+config OPENRISC_HAVE_INST_FL1
+       bool "Have instruction l.fl1"
+       default y
+       help
+         Select this if your implementation has the Class II instruction l.fl1
+
+config OPENRISC_HAVE_INST_MUL
+       bool "Have instruction l.mul for hardware multiply"
+       default y
+       help
+         Select this if your implementation has a hardware multiply instruction
+
+config OPENRISC_HAVE_INST_DIV
+       bool "Have instruction l.div for hardware divide"
+       default y
+       help
+         Select this if your implementation has a hardware divide instruction
+endmenu
+
+
+source "kernel/time/Kconfig"
+source kernel/Kconfig.hz
+source kernel/Kconfig.preempt
+source "mm/Kconfig"
+
+config OPENRISC_NO_SPR_SR_DSX
+       bool "use SPR_SR_DSX software emulation" if OR1K_1200
+       default y
+       help
+         SPR_SR_DSX bit is status register bit indicating whether
+         the last exception has happened in delay slot.
+
+         OpenRISC architecture makes it optional to have it implemented
+         in hardware and the OR1200 does not have it.
+
+         Say N here if you know that your OpenRISC processor has
+         SPR_SR_DSX bit implemented. Say Y if you are unsure.
+
+config CMDLINE
+        string "Default kernel command string"
+        default ""
+        help
+          On some architectures there is currently no way for the boot loader
+          to pass arguments to the kernel. For these architectures, you should
+          supply some command-line options at build time by entering them
+          here.
+
+menu "Debugging options"
+
+config DEBUG_STACKOVERFLOW
+       bool "Check for kernel stack overflow"
+       default y
+       help
+         Make extra checks for space avaliable on stack in some
+          critical functions. This will cause kernel to run a bit slower,
+         but will catch most of kernel stack overruns and exit gracefuly.
+
+         Say Y if you are unsure.
+
+config JUMP_UPON_UNHANDLED_EXCEPTION
+       bool "Try to die gracefully"
+       default y
+       help
+         Now this puts kernel into infinite loop after first oops. Till
+         your kernel crashes this doesn't have any influence.
+
+         Say Y if you are unsure.
+
+config OPENRISC_EXCEPTION_DEBUG
+       bool "Print processor state at each exception"
+       default n
+       help
+         This option will make your kernel unusable for all but kernel
+         debugging.
+
+         Say N if you are unsure.
+
+config OPENRISC_ESR_EXCEPTION_BUG_CHECK
+       bool "Check for possible ESR exception bug"
+       default n
+       help
+         This option enables some checks that might expose some problems
+          in kernel.
+
+         Say N if you are unsure.
+
+endmenu
+
+endmenu
+
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
+
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+endmenu
diff --git a/arch/openrisc/Makefile b/arch/openrisc/Makefile
new file mode 100644 (file)
index 0000000..158ae4c
--- /dev/null
@@ -0,0 +1,55 @@
+# BK Id: %F% %I% %G% %U% %#%
+#
+# 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
+# Modifications for the OpenRISC architecture:
+# Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+# Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+#
+# Based on:
+# arch/i386/Makefile
+
+KBUILD_DEFCONFIG := or1ksim_defconfig
+
+LDFLAGS         :=
+OBJCOPYFLAGS    := -O binary -R .note -R .comment -S
+LDFLAGS_vmlinux :=
+LIBGCC                 := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
+
+KBUILD_CFLAGS  += -pipe -ffixed-r10
+
+ifeq ($(CONFIG_OPENRISC_HAVE_INST_MUL),y)
+       KBUILD_CFLAGS += $(call cc-option,-mhard-mul)
+else
+       KBUILD_CFLAGS += $(call cc-option,-msoft-mul)
+endif
+
+ifeq ($(CONFIG_OPENRISC_HAVE_INST_DIV),y)
+       KBUILD_CFLAGS += $(call cc-option,-mhard-div)
+else
+       KBUILD_CFLAGS += $(call cc-option,-msoft-div)
+endif
+
+head-y                 := arch/openrisc/kernel/head.o arch/openrisc/kernel/init_task.o
+
+core-y         += arch/openrisc/lib/ \
+                  arch/openrisc/kernel/ \
+                  arch/openrisc/mm/
+libs-y         += $(LIBGCC)
+
+ifneq '$(CONFIG_OPENRISC_BUILTIN_DTB)' '""'
+BUILTIN_DTB := y
+else
+BUILTIN_DTB := n
+endif
+core-$(BUILTIN_DTB) += arch/openrisc/boot/
+
+all: vmlinux
diff --git a/arch/openrisc/README.openrisc b/arch/openrisc/README.openrisc
new file mode 100644 (file)
index 0000000..c9f7edf
--- /dev/null
@@ -0,0 +1,99 @@
+OpenRISC Linux
+==============
+
+This is a port of Linux to the OpenRISC class of microprocessors; the initial
+target architecture, specifically, is the 32-bit OpenRISC 1000 family (or1k).
+
+For information about OpenRISC processors and ongoing development:
+
+       website         http://openrisc.net
+
+For more information about Linux on OpenRISC, please contact South Pole AB.
+
+       email:          info@southpole.se
+
+       website:        http://southpole.se
+                       http://southpoleconsulting.com
+
+---------------------------------------------------------------------
+
+Build instructions for OpenRISC toolchain and Linux
+===================================================
+
+In order to build and run Linux for OpenRISC, you'll need at least a basic
+toolchain and, perhaps, the architectural simulator.  Steps to get these bits
+in place are outlined here.
+
+1)  The toolchain can be obtained from openrisc.net.  Instructions for building
+a toolchain can be found at:
+
+http://openrisc.net/toolchain-build.html
+
+2) or1ksim (optional)
+
+or1ksim is the architectural simulator which will allow you to actually run
+your OpenRISC Linux kernel if you don't have an OpenRISC processor at hand.
+
+       git clone git://openrisc.net/jonas/or1ksim-svn
+
+       cd or1ksim
+       ./configure --prefix=$OPENRISC_PREFIX
+       make
+       make install
+
+3)  Linux kernel
+
+Build the kernel as usual
+
+       make ARCH=openrisc defconfig
+       make ARCH=openrisc
+
+4)  Run in architectural simulator
+
+Grab the or1ksim platform configuration file (from the or1ksim source) and
+together with your freshly built vmlinux, run your kernel with the following
+incantation:
+
+       sim -f arch/openrisc/or1ksim.cfg vmlinux
+
+---------------------------------------------------------------------
+
+Terminology
+===========
+
+In the code, the following particles are used on symbols to limit the scope
+to more or less specific processor implementations:
+
+openrisc: the OpenRISC class of processors
+or1k:     the OpenRISC 1000 family of processors
+or1200:   the OpenRISC 1200 processor
+
+---------------------------------------------------------------------
+
+History
+========
+
+18. 11. 2003   Matjaz Breskvar (phoenix@bsemi.com)
+       initial port of linux to OpenRISC/or32 architecture.
+        all the core stuff is implemented and seams usable.
+
+08. 12. 2003   Matjaz Breskvar (phoenix@bsemi.com)
+       complete change of TLB miss handling.
+       rewrite of exceptions handling.
+       fully functional sash-3.6 in default initrd.
+       a much improved version with changes all around.
+
+10. 04. 2004   Matjaz Breskvar (phoenix@bsemi.com)
+       alot of bugfixes all over.
+       ethernet support, functional http and telnet servers.
+       running many standard linux apps.
+
+26. 06. 2004   Matjaz Breskvar (phoenix@bsemi.com)
+       port to 2.6.x
+
+30. 11. 2004   Matjaz Breskvar (phoenix@bsemi.com)
+       lots of bugfixes and enhancments.
+       added opencores framebuffer driver.
+
+09. 10. 2010    Jonas Bonn (jonas@southpole.se)
+       major rewrite to bring up to par with upstream Linux 2.6.36
diff --git a/arch/openrisc/TODO.openrisc b/arch/openrisc/TODO.openrisc
new file mode 100644 (file)
index 0000000..acfeef9
--- /dev/null
@@ -0,0 +1,16 @@
+The OpenRISC Linux port is fully functional and has been tracking upstream
+since 2.6.35.  There are, however, remaining items to be completed within
+the coming months.  Here's a list of known-to-be-less-than-stellar items
+that are due for investigation shortly, i.e. our TODO list:
+
+-- Implement the rest of the DMA API... dma_map_sg, etc.
+
+-- Consolidate usage of memblock and bootmem... move everything over to
+   memblock.
+
+-- Finish the renaming cleanup... there are references to or32 in the code
+   which was an older name for the architecture.  The name we've settled on is
+   or1k and this change is slowly trickling through the stack.  For the time
+   being, or32 is equivalent to or1k.
+
+-- Implement optimized version of memcpy and memset
diff --git a/arch/openrisc/boot/Makefile b/arch/openrisc/boot/Makefile
new file mode 100644 (file)
index 0000000..98ca185
--- /dev/null
@@ -0,0 +1,15 @@
+
+
+ifneq '$(CONFIG_OPENRISC_BUILTIN_DTB)' '""'
+BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_OPENRISC_BUILTIN_DTB)).dtb.o
+else
+BUILTIN_DTB :=
+endif
+obj-y += $(BUILTIN_DTB)
+
+clean-files := *.dtb.S
+
+#DTC_FLAGS ?= -p 1024
+
+$(obj)/%.dtb: $(src)/dts/%.dts
+       $(call cmd,dtc)
diff --git a/arch/openrisc/boot/dts/or1ksim.dts b/arch/openrisc/boot/dts/or1ksim.dts
new file mode 100644 (file)
index 0000000..5d4f902
--- /dev/null
@@ -0,0 +1,50 @@
+/dts-v1/;
+/ {
+       compatible = "opencores,or1ksim";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       interrupt-parent = <&pic>;
+
+       chosen {
+               bootargs = "console=uart,mmio,0x90000000,115200";
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x02000000>;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu@0 {
+                       compatible = "opencores,or1200-rtlsvn481";
+                       reg = <0>;
+                       clock-frequency = <20000000>;
+               };
+       };
+
+       /*
+        * OR1K PIC is built into CPU and accessed via special purpose
+        * registers.  It is not addressable and, hence, has no 'reg'
+        * property.
+        */
+       pic: pic {
+               compatible = "opencores,or1k-pic";
+               #interrupt-cells = <1>;
+               interrupt-controller;
+       };
+
+       serial0: serial@90000000 {
+               compatible = "opencores,uart16550-rtlsvn105", "ns16550a";
+               reg = <0x90000000 0x100>;
+               interrupts = <2>;
+               clock-frequency = <20000000>;
+       };
+
+       enet0: ethoc@92000000 {
+               compatible = "opencores,ethmac-rtlsvn338";
+               reg = <0x92000000 0x100>;
+               interrupts = <4>;
+       };
+};
diff --git a/arch/openrisc/configs/or1ksim_defconfig b/arch/openrisc/configs/or1ksim_defconfig
new file mode 100644 (file)
index 0000000..ea172bd
--- /dev/null
@@ -0,0 +1,65 @@
+CONFIG_CROSS_COMPILE="or32-linux-"
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_GZIP is not set
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_EPOLL is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+CONFIG_MODULES=y
+# CONFIG_BLOCK is not set
+CONFIG_OPENRISC_BUILTIN_DTB="or1ksim"
+CONFIG_NO_HZ=y
+CONFIG_HZ_100=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_TCP_CONG_ADVANCED=y
+# CONFIG_TCP_CONG_BIC is not set
+# CONFIG_TCP_CONG_CUBIC is not set
+# CONFIG_TCP_CONG_WESTWOOD is not set
+# CONFIG_TCP_CONG_HTCP is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_PROC_DEVICETREE=y
+CONFIG_NETDEVICES=y
+CONFIG_MICREL_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_ETHOC=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_MFD_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
new file mode 100644 (file)
index 0000000..11162e6
--- /dev/null
@@ -0,0 +1,64 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += spr_defs.h
+
+generic-y += atomic.h
+generic-y += auxvec.h
+generic-y += bitsperlong.h
+generic-y += bug.h
+generic-y += bugs.h
+generic-y += cacheflush.h
+generic-y += checksum.h
+generic-y += cmpxchg.h
+generic-y += cmpxchg-local.h
+generic-y += cpumask.h
+generic-y += cputime.h
+generic-y += current.h
+generic-y += device.h
+generic-y += div64.h
+generic-y += dma.h
+generic-y += emergency-restart.h
+generic-y += errno.h
+generic-y += fb.h
+generic-y += fcntl.h
+generic-y += ftrace.h
+generic-y += futex.h
+generic-y += hardirq.h
+generic-y += hw_irq.h
+generic-y += ioctl.h
+generic-y += ioctls.h
+generic-y += ipcbuf.h
+generic-y += irq_regs.h
+generic-y += kdebug.h
+generic-y += kmap_types.h
+generic-y += local.h
+generic-y += mman.h
+generic-y += module.h
+generic-y += msgbuf.h
+generic-y += pci.h
+generic-y += percpu.h
+generic-y += poll.h
+generic-y += posix_types.h
+generic-y += resource.h
+generic-y += rmap.h
+generic-y += scatterlist.h
+generic-y += sections.h
+generic-y += segment.h
+generic-y += sembuf.h
+generic-y += setup.h
+generic-y += shmbuf.h
+generic-y += shmparam.h
+generic-y += siginfo.h
+generic-y += signal.h
+generic-y += socket.h
+generic-y += sockios.h
+generic-y += statfs.h
+generic-y += stat.h
+generic-y += string.h
+generic-y += swab.h
+generic-y += termbits.h
+generic-y += termios.h
+generic-y += topology.h
+generic-y += types.h
+generic-y += ucontext.h
+generic-y += user.h
diff --git a/arch/openrisc/include/asm/asm-offsets.h b/arch/openrisc/include/asm/asm-offsets.h
new file mode 100644 (file)
index 0000000..d370ee3
--- /dev/null
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/openrisc/include/asm/bitops.h b/arch/openrisc/include/asm/bitops.h
new file mode 100644 (file)
index 0000000..a9e11ef
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_BITOPS_H
+#define __ASM_OPENRISC_BITOPS_H
+
+/*
+ * Where we haven't written assembly versions yet, we fall back to the
+ * generic implementations.  Otherwise, we pull in our (hopefully)
+ * optimized versions.
+ */
+
+#include <linux/irqflags.h>
+#include <linux/compiler.h>
+
+/*
+ * clear_bit may not imply a memory barrier
+ */
+#ifndef smp_mb__before_clear_bit
+#define smp_mb__before_clear_bit()     smp_mb()
+#define smp_mb__after_clear_bit()      smp_mb()
+#endif
+
+#include <asm/bitops/__ffs.h>
+#include <asm-generic/bitops/ffz.h>
+#include <asm/bitops/fls.h>
+#include <asm/bitops/__fls.h>
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/find.h>
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+#include <asm-generic/bitops/sched.h>
+#include <asm/bitops/ffs.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
+
+#include <asm-generic/bitops/atomic.h>
+#include <asm-generic/bitops/non-atomic.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+
+#endif /* __ASM_GENERIC_BITOPS_H */
diff --git a/arch/openrisc/include/asm/bitops/__ffs.h b/arch/openrisc/include/asm/bitops/__ffs.h
new file mode 100644 (file)
index 0000000..6c8368a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * OpenRISC Linux
+ *
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC___FFS_H
+#define __ASM_OPENRISC___FFS_H
+
+
+#ifdef CONFIG_OPENRISC_HAVE_INST_FF1
+
+static inline unsigned long __ffs(unsigned long x)
+{
+       int ret;
+
+       __asm__ ("l.ff1 %0,%1"
+                : "=r" (ret)
+                : "r" (x));
+
+       return ret-1;
+}
+
+#else
+#include <asm-generic/bitops/__ffs.h>
+#endif
+
+#endif /* __ASM_OPENRISC___FFS_H */
diff --git a/arch/openrisc/include/asm/bitops/__fls.h b/arch/openrisc/include/asm/bitops/__fls.h
new file mode 100644 (file)
index 0000000..c4ecdb4
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * OpenRISC Linux
+ *
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC___FLS_H
+#define __ASM_OPENRISC___FLS_H
+
+
+#ifdef CONFIG_OPENRISC_HAVE_INST_FL1
+
+static inline unsigned long __fls(unsigned long x)
+{
+       int ret;
+
+       __asm__ ("l.fl1 %0,%1"
+                : "=r" (ret)
+                : "r" (x));
+
+       return ret-1;
+}
+
+#else
+#include <asm-generic/bitops/__fls.h>
+#endif
+
+#endif /* __ASM_OPENRISC___FLS_H */
diff --git a/arch/openrisc/include/asm/bitops/ffs.h b/arch/openrisc/include/asm/bitops/ffs.h
new file mode 100644 (file)
index 0000000..9de4624
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * OpenRISC Linux
+ *
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_FFS_H
+#define __ASM_OPENRISC_FFS_H
+
+#ifdef CONFIG_OPENRISC_HAVE_INST_FF1
+
+static inline int ffs(int x)
+{
+       int ret;
+
+       __asm__ ("l.ff1 %0,%1"
+                : "=r" (ret)
+                : "r" (x));
+
+       return ret;
+}
+
+#else
+#include <asm-generic/bitops/ffs.h>
+#endif
+
+#endif /* __ASM_OPENRISC_FFS_H */
diff --git a/arch/openrisc/include/asm/bitops/fls.h b/arch/openrisc/include/asm/bitops/fls.h
new file mode 100644 (file)
index 0000000..9efbf9a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * OpenRISC Linux
+ *
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_FLS_H
+#define __ASM_OPENRISC_FLS_H
+
+
+#ifdef CONFIG_OPENRISC_HAVE_INST_FL1
+
+static inline int fls(int x)
+{
+       int ret;
+
+       __asm__ ("l.fl1 %0,%1"
+                : "=r" (ret)
+                : "r" (x));
+
+       return ret;
+}
+
+#else
+#include <asm-generic/bitops/fls.h>
+#endif
+
+#endif /* __ASM_OPENRISC_FLS_H */
diff --git a/arch/openrisc/include/asm/byteorder.h b/arch/openrisc/include/asm/byteorder.h
new file mode 100644 (file)
index 0000000..60d14f7
--- /dev/null
@@ -0,0 +1 @@
+#include <linux/byteorder/big_endian.h>
diff --git a/arch/openrisc/include/asm/cache.h b/arch/openrisc/include/asm/cache.h
new file mode 100644 (file)
index 0000000..4ce7a01
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_CACHE_H
+#define __ASM_OPENRISC_CACHE_H
+
+/* FIXME: How can we replace these with values from the CPU...
+ * they shouldn't be hard-coded!
+ */
+
+#define L1_CACHE_BYTES 16
+#define L1_CACHE_SHIFT 4
+
+#endif /* __ASM_OPENRISC_CACHE_H */
diff --git a/arch/openrisc/include/asm/cpuinfo.h b/arch/openrisc/include/asm/cpuinfo.h
new file mode 100644 (file)
index 0000000..917318b
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_CPUINFO_H
+#define __ASM_OPENRISC_CPUINFO_H
+
+struct cpuinfo {
+       u32 clock_frequency;
+
+       u32 icache_size;
+       u32 icache_block_size;
+
+       u32 dcache_size;
+       u32 dcache_block_size;
+};
+
+extern struct cpuinfo cpuinfo;
+
+#endif /* __ASM_OPENRISC_CPUINFO_H */
diff --git a/arch/openrisc/include/asm/delay.h b/arch/openrisc/include/asm/delay.h
new file mode 100644 (file)
index 0000000..17f8bf5
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_DELAY_H
+#define __ASM_OPENRISC_DELAY_H
+
+#include <asm-generic/delay.h>
+
+extern unsigned long loops_per_jiffy;
+
+#endif
diff --git a/arch/openrisc/include/asm/dma-mapping.h b/arch/openrisc/include/asm/dma-mapping.h
new file mode 100644 (file)
index 0000000..052f877
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_DMA_MAPPING_H
+#define __ASM_OPENRISC_DMA_MAPPING_H
+
+/*
+ * See Documentation/PCI/PCI-DMA-mapping.txt and
+ * Documentation/DMA-API.txt for documentation.
+ *
+ * This file is written with the intention of eventually moving over
+ * to largely using asm-generic/dma-mapping-common.h in its place.
+ */
+
+#include <linux/dma-debug.h>
+#include <asm-generic/dma-coherent.h>
+#include <linux/kmemcheck.h>
+
+#define DMA_ERROR_CODE         (~(dma_addr_t)0x0)
+
+int dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+void *or1k_dma_alloc_coherent(struct device *dev, size_t size,
+                             dma_addr_t *dma_handle, gfp_t flag);
+void or1k_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+                           dma_addr_t dma_handle);
+dma_addr_t or1k_map_page(struct device *dev, struct page *page,
+                        unsigned long offset, size_t size,
+                        enum dma_data_direction dir,
+                        struct dma_attrs *attrs);
+void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
+                    size_t size, enum dma_data_direction dir,
+                    struct dma_attrs *attrs);
+void or1k_sync_single_for_cpu(struct device *dev,
+                             dma_addr_t dma_handle, size_t size,
+                             enum dma_data_direction dir);
+void or1k_sync_single_for_device(struct device *dev,
+                                dma_addr_t dma_handle, size_t size,
+                                enum dma_data_direction dir);
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+                                       dma_addr_t *dma_handle, gfp_t flag)
+{
+       void *memory;
+
+       memory = or1k_dma_alloc_coherent(dev, size, dma_handle, flag);
+
+       debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
+       return memory;
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+                                    void *cpu_addr, dma_addr_t dma_handle)
+{
+       debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
+       or1k_dma_free_coherent(dev, size, cpu_addr, dma_handle);
+}
+
+static inline dma_addr_t dma_map_single(struct device *dev, void *ptr,
+                                       size_t size,
+                                       enum dma_data_direction dir)
+{
+       dma_addr_t addr;
+
+       kmemcheck_mark_initialized(ptr, size);
+       BUG_ON(!valid_dma_direction(dir));
+       addr = or1k_map_page(dev, virt_to_page(ptr),
+                            (unsigned long)ptr & ~PAGE_MASK, size,
+                            dir, NULL);
+       debug_dma_map_page(dev, virt_to_page(ptr),
+                          (unsigned long)ptr & ~PAGE_MASK, size,
+                          dir, addr, true);
+       return addr;
+}
+
+static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
+                                         size_t size,
+                                         enum dma_data_direction dir)
+{
+       BUG_ON(!valid_dma_direction(dir));
+       or1k_unmap_page(dev, addr, size, dir, NULL);
+       debug_dma_unmap_page(dev, addr, size, dir, true);
+}
+
+static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
+                                          size_t size,
+                                          enum dma_data_direction dir)
+{
+       BUG_ON(!valid_dma_direction(dir));
+       or1k_sync_single_for_cpu(dev, addr, size, dir);
+       debug_dma_sync_single_for_cpu(dev, addr, size, dir);
+}
+
+static inline void dma_sync_single_for_device(struct device *dev,
+                                             dma_addr_t addr, size_t size,
+                                             enum dma_data_direction dir)
+{
+       BUG_ON(!valid_dma_direction(dir));
+       or1k_sync_single_for_device(dev, addr, size, dir);
+       debug_dma_sync_single_for_device(dev, addr, size, dir);
+}
+
+static inline int dma_supported(struct device *dev, u64 dma_mask)
+{
+       /* Support 32 bit DMA mask exclusively */
+       return dma_mask == 0xffffffffULL;
+}
+
+static inline int dma_set_mask(struct device *dev, u64 dma_mask)
+{
+       if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+               return -EIO;
+
+       *dev->dma_mask = dma_mask;
+
+       return 0;
+}
+#endif /* __ASM_OPENRISC_DMA_MAPPING_H */
diff --git a/arch/openrisc/include/asm/elf.h b/arch/openrisc/include/asm/elf.h
new file mode 100644 (file)
index 0000000..2ce603b
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_ELF_H
+#define __ASM_OPENRISC_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+
+/* The OR1K relocation types... not all relevant for module loader */
+#define R_OR32_NONE    0
+#define R_OR32_32      1
+#define R_OR32_16      2
+#define R_OR32_8       3
+#define R_OR32_CONST   4
+#define R_OR32_CONSTH  5
+#define R_OR32_JUMPTARG        6
+#define R_OR32_VTINHERIT 7
+#define R_OR32_VTENTRY 8
+
+typedef unsigned long elf_greg_t;
+
+/*
+ * Note that NGREG is defined to ELF_NGREG in include/linux/elfcore.h, and is
+ * thus exposed to user-space.
+ */
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* A placeholder; OR32 does not have fp support yes, so no fp regs for now.  */
+typedef unsigned long elf_fpregset_t;
+
+/* This should be moved to include/linux/elf.h */
+#define EM_OR32         0x8472
+#define EM_OPENRISC     92     /* OpenRISC 32-bit embedded processor */
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_ARCH       EM_OR32
+#define ELF_CLASS      ELFCLASS32
+#define ELF_DATA       ELFDATA2MSB
+
+#ifdef __KERNEL__
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+
+#define elf_check_arch(x) \
+       (((x)->e_machine == EM_OR32) || ((x)->e_machine == EM_OPENRISC))
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE         (0x08000000)
+
+/*
+ * Enable dump using regset.
+ * This covers all of general/DSP/FPU regs.
+ */
+#define CORE_DUMP_USE_REGSET
+
+#define ELF_EXEC_PAGESIZE      8192
+
+extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt);
+#define ELF_CORE_COPY_REGS(dest, regs) dump_elf_thread(dest, regs);
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  This could be done in userspace,
+   but it's not easy, and we've already done it here.  */
+
+#define ELF_HWCAP      (0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.
+
+   For the moment, we have only optimizations for the Intel generations,
+   but that could change... */
+
+#define ELF_PLATFORM   (NULL)
+
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+
+#endif /* __KERNEL__ */
+#endif
diff --git a/arch/openrisc/include/asm/fixmap.h b/arch/openrisc/include/asm/fixmap.h
new file mode 100644 (file)
index 0000000..5273341
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_FIXMAP_H
+#define __ASM_OPENRISC_FIXMAP_H
+
+/* Why exactly do we need 2 empty pages between the top of the fixed
+ * addresses and the top of virtual memory?  Something is using that
+ * memory space but not sure what right now... If you find it, leave
+ * a comment here.
+ */
+#define FIXADDR_TOP    ((unsigned long) (-2*PAGE_SIZE))
+
+#include <linux/kernel.h>
+#include <asm/page.h>
+
+/*
+ * On OpenRISC we use these special fixed_addresses for doing ioremap
+ * early in the boot process before memory initialization is complete.
+ * This is used, in particular, by the early serial console code.
+ *
+ * It's not really 'fixmap', per se, but fits loosely into the same
+ * paradigm.
+ */
+enum fixed_addresses {
+       /*
+        * FIX_IOREMAP entries are useful for mapping physical address
+        * space before ioremap() is useable, e.g. really early in boot
+        * before kmalloc() is working.
+        */
+#define FIX_N_IOREMAPS  32
+       FIX_IOREMAP_BEGIN,
+       FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS - 1,
+       __end_of_fixed_addresses
+};
+
+#define FIXADDR_SIZE           (__end_of_fixed_addresses << PAGE_SHIFT)
+/* FIXADDR_BOTTOM might be a better name here... */
+#define FIXADDR_START          (FIXADDR_TOP - FIXADDR_SIZE)
+
+#define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x)       ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+
+/*
+ * 'index to address' translation. If anyone tries to use the idx
+ * directly without tranlation, we catch the bug with a NULL-deference
+ * kernel oops. Illegal ranges of incoming indices are caught too.
+ */
+static __always_inline unsigned long fix_to_virt(const unsigned int idx)
+{
+       /*
+        * this branch gets completely eliminated after inlining,
+        * except when someone tries to use fixaddr indices in an
+        * illegal way. (such as mixing up address types or using
+        * out-of-range indices).
+        *
+        * If it doesn't get removed, the linker will complain
+        * loudly with a reasonably clear error message..
+        */
+       if (idx >= __end_of_fixed_addresses)
+               BUG();
+
+       return __fix_to_virt(idx);
+}
+
+static inline unsigned long virt_to_fix(const unsigned long vaddr)
+{
+       BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+       return __virt_to_fix(vaddr);
+}
+
+#endif
diff --git a/arch/openrisc/include/asm/gpio.h b/arch/openrisc/include/asm/gpio.h
new file mode 100644 (file)
index 0000000..0b0d174
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_GPIO_H
+#define __ASM_OPENRISC_GPIO_H
+
+#include <linux/errno.h>
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_GPIOLIB
+
+/*
+ * OpenRISC (or1k) does not have on-chip GPIO's so there is not really
+ * any standardized implementation that makes sense here.  If passing
+ * through gpiolib becomes a bottleneck then it may make sense, on a
+ * case-by-case basis, to implement these inlined/rapid versions.
+ *
+ * Just call gpiolib.
+ */
+static inline int gpio_get_value(unsigned int gpio)
+{
+       return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned int gpio, int value)
+{
+       __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned int gpio)
+{
+       return __gpio_cansleep(gpio);
+}
+
+/*
+ * Not implemented, yet.
+ */
+static inline int gpio_to_irq(unsigned int gpio)
+{
+       return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+       return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* __ASM_OPENRISC_GPIO_H */
diff --git a/arch/openrisc/include/asm/io.h b/arch/openrisc/include/asm/io.h
new file mode 100644 (file)
index 0000000..07f5299
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_IO_H
+#define __ASM_OPENRISC_IO_H
+
+/*
+ * PCI: can we really do 0 here if we have no port IO?
+ */
+#define IO_SPACE_LIMIT         0
+
+/* OpenRISC has no port IO */
+#define HAVE_ARCH_PIO_SIZE     1
+#define PIO_RESERVED           0X0UL
+#define PIO_OFFSET             0
+#define PIO_MASK               0
+
+#include <asm-generic/io.h>
+
+extern void __iomem *__ioremap(phys_addr_t offset, unsigned long size,
+                               pgprot_t prot);
+
+static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
+{
+       return __ioremap(offset, size, PAGE_KERNEL);
+}
+
+/* #define _PAGE_CI       0x002 */
+static inline void __iomem *ioremap_nocache(phys_addr_t offset,
+                                            unsigned long size)
+{
+       return __ioremap(offset, size,
+                        __pgprot(pgprot_val(PAGE_KERNEL) | _PAGE_CI));
+}
+
+extern void iounmap(void *addr);
+#endif
diff --git a/arch/openrisc/include/asm/irq.h b/arch/openrisc/include/asm/irq.h
new file mode 100644 (file)
index 0000000..eb612b1
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_IRQ_H__
+#define __ASM_OPENRISC_IRQ_H__
+
+#define        NR_IRQS         32
+#include <asm-generic/irq.h>
+
+#define NO_IRQ         (-1)
+
+#endif /* __ASM_OPENRISC_IRQ_H__ */
diff --git a/arch/openrisc/include/asm/irqflags.h b/arch/openrisc/include/asm/irqflags.h
new file mode 100644 (file)
index 0000000..dc86c65
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef ___ASM_OPENRISC_IRQFLAGS_H
+#define ___ASM_OPENRISC_IRQFLAGS_H
+
+#include <asm/spr_defs.h>
+
+#define ARCH_IRQ_DISABLED        0x00
+#define ARCH_IRQ_ENABLED         (SPR_SR_IEE|SPR_SR_TEE)
+
+#include <asm-generic/irqflags.h>
+
+#endif /* ___ASM_OPENRISC_IRQFLAGS_H */
diff --git a/arch/openrisc/include/asm/linkage.h b/arch/openrisc/include/asm/linkage.h
new file mode 100644 (file)
index 0000000..e263875
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_LINKAGE_H
+#define __ASM_OPENRISC_LINKAGE_H
+
+#define __ALIGN      .align 0
+#define __ALIGN_STR ".align 0"
+
+#endif /* __ASM_OPENRISC_LINKAGE_H */
diff --git a/arch/openrisc/include/asm/memblock.h b/arch/openrisc/include/asm/memblock.h
new file mode 100644 (file)
index 0000000..bbe5a1c
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_MEMBLOCK_H
+#define __ASM_OPENRISC_MEMBLOCK_H
+
+/* empty */
+
+#endif /* __ASM_OPENRISC_MEMBLOCK_H */
diff --git a/arch/openrisc/include/asm/mmu.h b/arch/openrisc/include/asm/mmu.h
new file mode 100644 (file)
index 0000000..d069bc2
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_MMU_H
+#define __ASM_OPENRISC_MMU_H
+
+#ifndef __ASSEMBLY__
+typedef unsigned long mm_context_t;
+#endif
+
+#endif
diff --git a/arch/openrisc/include/asm/mmu_context.h b/arch/openrisc/include/asm/mmu_context.h
new file mode 100644 (file)
index 0000000..e94b814
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_MMU_CONTEXT_H
+#define __ASM_OPENRISC_MMU_CONTEXT_H
+
+#include <asm-generic/mm_hooks.h>
+
+extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+extern void destroy_context(struct mm_struct *mm);
+extern void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+                     struct task_struct *tsk);
+
+#define deactivate_mm(tsk, mm) do { } while (0)
+
+#define activate_mm(prev, next) switch_mm((prev), (next), NULL)
+
+/* current active pgd - this is similar to other processors pgd
+ * registers like cr3 on the i386
+ */
+
+extern volatile pgd_t *current_pgd;   /* defined in arch/openrisc/mm/fault.c */
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+#endif
diff --git a/arch/openrisc/include/asm/mutex.h b/arch/openrisc/include/asm/mutex.h
new file mode 100644 (file)
index 0000000..b85a0cf
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/arch/openrisc/include/asm/page.h b/arch/openrisc/include/asm/page.h
new file mode 100644 (file)
index 0000000..b041b34
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_PAGE_H
+#define __ASM_OPENRISC_PAGE_H
+
+
+/* PAGE_SHIFT determines the page size */
+
+#define PAGE_SHIFT      13
+#ifdef __ASSEMBLY__
+#define PAGE_SIZE       (1 << PAGE_SHIFT)
+#else
+#define PAGE_SIZE       (1UL << PAGE_SHIFT)
+#endif
+#define PAGE_MASK       (~(PAGE_SIZE-1))
+
+#define PAGE_OFFSET    0xc0000000
+#define KERNELBASE     PAGE_OFFSET
+
+/* This is not necessarily the right place for this, but it's needed by
+ * drivers/of/fdt.c
+ */
+#include <asm/setup.h>
+
+#ifndef __ASSEMBLY__
+
+#define get_user_page(vaddr)            __get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)      free_page(addr)
+
+#define clear_page(page)       memset((page), 0, PAGE_SIZE)
+#define copy_page(to, from)    memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr, pg)        clear_page(page)
+#define copy_user_page(to, from, vaddr, pg)     copy_page(to, from)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct {
+       unsigned long pte;
+} pte_t;
+typedef struct {
+       unsigned long pgd;
+} pgd_t;
+typedef struct {
+       unsigned long pgprot;
+} pgprot_t;
+typedef struct page *pgtable_t;
+
+#define pte_val(x)     ((x).pte)
+#define pgd_val(x)     ((x).pgd)
+#define pgprot_val(x)  ((x).pgprot)
+
+#define __pte(x)       ((pte_t) { (x) })
+#define __pgd(x)       ((pgd_t) { (x) })
+#define __pgprot(x)    ((pgprot_t) { (x) })
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+#endif /* !__ASSEMBLY__ */
+
+
+#ifndef __ASSEMBLY__
+
+#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET))
+#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
+
+#define virt_to_pfn(kaddr)      (__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_to_virt(pfn)        __va((pfn) << PAGE_SHIFT)
+
+#define virt_to_page(addr) \
+       (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define page_to_virt(page) \
+       ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
+
+#define page_to_phys(page)      ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
+
+#define pfn_valid(pfn)          ((pfn) < max_mapnr)
+
+#define virt_addr_valid(kaddr)  (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
+                               ((void *)(kaddr) < (void *)memory_end))
+
+#endif /* __ASSEMBLY__ */
+
+
+#define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
+                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/getorder.h>
+
+#endif /* __ASM_OPENRISC_PAGE_H */
diff --git a/arch/openrisc/include/asm/param.h b/arch/openrisc/include/asm/param.h
new file mode 100644 (file)
index 0000000..c39a336
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_PARAM_H
+#define __ASM_OPENRISC_PARAM_H
+
+#define EXEC_PAGESIZE  8192
+
+#include <asm-generic/param.h>
+
+#endif /* __ASM_OPENRISC_PARAM_H */
diff --git a/arch/openrisc/include/asm/pgalloc.h b/arch/openrisc/include/asm/pgalloc.h
new file mode 100644 (file)
index 0000000..05c39ec
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_PGALLOC_H
+#define __ASM_OPENRISC_PGALLOC_H
+
+#include <asm/page.h>
+#include <linux/threads.h>
+#include <linux/mm.h>
+#include <linux/memblock.h>
+#include <linux/bootmem.h>
+
+extern int mem_init_done;
+
+#define pmd_populate_kernel(mm, pmd, pte) \
+       set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
+
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
+                               struct page *pte)
+{
+       set_pmd(pmd, __pmd(_KERNPG_TABLE +
+                    ((unsigned long)page_to_pfn(pte) <<
+                    (unsigned long) PAGE_SHIFT)));
+}
+
+/*
+ * Allocate and free page tables.
+ */
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+       pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL);
+
+       if (ret) {
+               memset(ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+               memcpy(ret + USER_PTRS_PER_PGD,
+                      swapper_pg_dir + USER_PTRS_PER_PGD,
+                      (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+
+       }
+       return ret;
+}
+
+#if 0
+/* FIXME: This seems to be the preferred style, but we are using
+ * current_pgd (from mm->pgd) to load kernel pages so we need it
+ * initialized.  This needs to be looked into.
+ */
+extern inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+       return (pgd_t *)get_zeroed_page(GFP_KERNEL);
+}
+#endif
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+       free_page((unsigned long)pgd);
+}
+
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address);
+
+static inline struct page *pte_alloc_one(struct mm_struct *mm,
+                                        unsigned long address)
+{
+       struct page *pte;
+       pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
+       if (pte)
+               clear_page(page_address(pte));
+       return pte;
+}
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+       free_page((unsigned long)pte);
+}
+
+static inline void pte_free(struct mm_struct *mm, struct page *pte)
+{
+       __free_page(pte);
+}
+
+
+#define __pte_free_tlb(tlb, pte, addr) tlb_remove_page((tlb), (pte))
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+#define check_pgt_cache()          do { } while (0)
+
+#endif
diff --git a/arch/openrisc/include/asm/pgtable.h b/arch/openrisc/include/asm/pgtable.h
new file mode 100644 (file)
index 0000000..043505d
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+/* or32 pgtable.h - macros and functions to manipulate page tables
+ *
+ * Based on:
+ * include/asm-cris/pgtable.h
+ */
+
+#ifndef __ASM_OPENRISC_PGTABLE_H
+#define __ASM_OPENRISC_PGTABLE_H
+
+#include <asm-generic/pgtable-nopmd.h>
+
+#ifndef __ASSEMBLY__
+#include <asm/mmu.h>
+#include <asm/fixmap.h>
+
+/*
+ * The Linux memory management assumes a three-level page table setup. On
+ * or32, we use that, but "fold" the mid level into the top-level page
+ * table. Since the MMU TLB is software loaded through an interrupt, it
+ * supports any page table structure, so we could have used a three-level
+ * setup, but for the amounts of memory we normally use, a two-level is
+ * probably more efficient.
+ *
+ * This file contains the functions and defines necessary to modify and use
+ * the or32 page table tree.
+ */
+
+extern void paging_init(void);
+
+/* Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
+#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
+/*
+ * (pmds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
+
+#define PGDIR_SHIFT    (PAGE_SHIFT + (PAGE_SHIFT-2))
+#define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK     (~(PGDIR_SIZE-1))
+
+/*
+ * entries per page directory level: we use a two-level, so
+ * we don't really have any PMD directory physically.
+ * pointers are 4 bytes so we can use the page size and
+ * divide it by 4 (shift by 2).
+ */
+#define PTRS_PER_PTE   (1UL << (PAGE_SHIFT-2))
+
+#define PTRS_PER_PGD   (1UL << (PAGE_SHIFT-2))
+
+/* calculate how many PGD entries a user-level program can use
+ * the first mappable virtual address is 0
+ * (TASK_SIZE is the maximum virtual address space)
+ */
+
+#define USER_PTRS_PER_PGD       (TASK_SIZE/PGDIR_SIZE)
+#define FIRST_USER_ADDRESS      0
+
+/*
+ * Kernels own virtual memory area.
+ */
+
+/*
+ * The size and location of the vmalloc area are chosen so that modules
+ * placed in this area aren't more than a 28-bit signed offset from any
+ * kernel functions that they may need.  This greatly simplifies handling
+ * of the relocations for l.j and l.jal instructions as we don't need to
+ * introduce any trampolines for reaching "distant" code.
+ *
+ * 64 MB of vmalloc area is comparable to what's available on other arches.
+ */
+
+#define VMALLOC_START  (PAGE_OFFSET-0x04000000)
+#define VMALLOC_END    (PAGE_OFFSET)
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+
+/* Define some higher level generic page attributes.
+ *
+ * If you change _PAGE_CI definition be sure to change it in
+ * io.h for ioremap_nocache() too.
+ */
+
+/*
+ * An OR32 PTE looks like this:
+ *
+ * |  31 ... 10 |  9  |  8 ... 6  |  5  |  4  |  3  |  2  |  1  |  0  |
+ *  Phys pg.num    L     PP Index    D     A    WOM   WBC   CI    CC
+ *
+ *  L  : link
+ *  PPI: Page protection index
+ *  D  : Dirty
+ *  A  : Accessed
+ *  WOM: Weakly ordered memory
+ *  WBC: Write-back cache
+ *  CI : Cache inhibit
+ *  CC : Cache coherent
+ *
+ * The protection bits below should correspond to the layout of the actual
+ * PTE as per above
+ */
+
+#define _PAGE_CC       0x001 /* software: pte contains a translation */
+#define _PAGE_CI       0x002 /* cache inhibit          */
+#define _PAGE_WBC      0x004 /* write back cache       */
+#define _PAGE_FILE     0x004 /* set: pagecache, unset: swap (when !PRESENT) */
+#define _PAGE_WOM      0x008 /* weakly ordered memory  */
+
+#define _PAGE_A        0x010 /* accessed               */
+#define _PAGE_D        0x020 /* dirty                  */
+#define _PAGE_URE      0x040 /* user read enable       */
+#define _PAGE_UWE      0x080 /* user write enable      */
+
+#define _PAGE_SRE      0x100 /* superuser read enable  */
+#define _PAGE_SWE      0x200 /* superuser write enable */
+#define _PAGE_EXEC     0x400 /* software: page is executable */
+#define _PAGE_U_SHARED 0x800 /* software: page is shared in user space */
+
+/* 0x001 is cache coherency bit, which should always be set to
+ *       1 - for SMP (when we support it)
+ *       0 - otherwise
+ *
+ * we just reuse this bit in software for _PAGE_PRESENT and
+ * force it to 0 when loading it into TLB.
+ */
+#define _PAGE_PRESENT  _PAGE_CC
+#define _PAGE_USER     _PAGE_URE
+#define _PAGE_WRITE    (_PAGE_UWE | _PAGE_SWE)
+#define _PAGE_DIRTY    _PAGE_D
+#define _PAGE_ACCESSED _PAGE_A
+#define _PAGE_NO_CACHE _PAGE_CI
+#define _PAGE_SHARED   _PAGE_U_SHARED
+#define _PAGE_READ     (_PAGE_URE | _PAGE_SRE)
+
+#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_BASE     (_PAGE_PRESENT | _PAGE_ACCESSED)
+#define _PAGE_ALL      (_PAGE_PRESENT | _PAGE_ACCESSED)
+#define _KERNPG_TABLE \
+       (_PAGE_BASE | _PAGE_SRE | _PAGE_SWE | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+#define PAGE_NONE       __pgprot(_PAGE_ALL)
+#define PAGE_READONLY   __pgprot(_PAGE_ALL | _PAGE_URE | _PAGE_SRE)
+#define PAGE_READONLY_X __pgprot(_PAGE_ALL | _PAGE_URE | _PAGE_SRE | _PAGE_EXEC)
+#define PAGE_SHARED \
+       __pgprot(_PAGE_ALL | _PAGE_URE | _PAGE_SRE | _PAGE_UWE | _PAGE_SWE \
+                | _PAGE_SHARED)
+#define PAGE_SHARED_X \
+       __pgprot(_PAGE_ALL | _PAGE_URE | _PAGE_SRE | _PAGE_UWE | _PAGE_SWE \
+                | _PAGE_SHARED | _PAGE_EXEC)
+#define PAGE_COPY       __pgprot(_PAGE_ALL | _PAGE_URE | _PAGE_SRE)
+#define PAGE_COPY_X     __pgprot(_PAGE_ALL | _PAGE_URE | _PAGE_SRE | _PAGE_EXEC)
+
+#define PAGE_KERNEL \
+       __pgprot(_PAGE_ALL | _PAGE_SRE | _PAGE_SWE \
+                | _PAGE_SHARED | _PAGE_DIRTY | _PAGE_EXEC)
+#define PAGE_KERNEL_RO \
+       __pgprot(_PAGE_ALL | _PAGE_SRE \
+                | _PAGE_SHARED | _PAGE_DIRTY | _PAGE_EXEC)
+#define PAGE_KERNEL_NOCACHE \
+       __pgprot(_PAGE_ALL | _PAGE_SRE | _PAGE_SWE \
+                | _PAGE_SHARED | _PAGE_DIRTY | _PAGE_EXEC | _PAGE_CI)
+
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY_X
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY_X
+#define __P100 PAGE_READONLY
+#define __P101 PAGE_READONLY_X
+#define __P110 PAGE_COPY
+#define __P111 PAGE_COPY_X
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY_X
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED_X
+#define __S100 PAGE_READONLY
+#define __S101 PAGE_READONLY_X
+#define __S110 PAGE_SHARED
+#define __S111 PAGE_SHARED_X
+
+/* zero page used for uninitialized stuff */
+extern unsigned long empty_zero_page[2048];
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+
+/* number of bits that fit into a memory pointer */
+#define BITS_PER_PTR                   (8*sizeof(unsigned long))
+
+/* to align the pointer to a pointer address */
+#define PTR_MASK                       (~(sizeof(void *)-1))
+
+/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
+/* 64-bit machines, beware!  SRB. */
+#define SIZEOF_PTR_LOG2                        2
+
+/* to find an entry in a page-table */
+#define PAGE_PTR(address) \
+((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
+
+/* to set the page-dir */
+#define SET_PAGE_DIR(tsk, pgdir)
+
+#define pte_none(x)    (!pte_val(x))
+#define pte_present(x) (pte_val(x) & _PAGE_PRESENT)
+#define pte_clear(mm, addr, xp)        do { pte_val(*(xp)) = 0; } while (0)
+
+#define pmd_none(x)    (!pmd_val(x))
+#define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK)) != _KERNPG_TABLE)
+#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
+#define pmd_clear(xp)  do { pmd_val(*(xp)) = 0; } while (0)
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+
+static inline int pte_read(pte_t pte)  { return pte_val(pte) & _PAGE_READ; }
+static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
+static inline int pte_exec(pte_t pte)  { return pte_val(pte) & _PAGE_EXEC; }
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte)  { return pte_val(pte) & _PAGE_FILE; }
+static inline int pte_special(pte_t pte) { return 0; }
+static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+       pte_val(pte) &= ~(_PAGE_WRITE);
+       return pte;
+}
+
+static inline pte_t pte_rdprotect(pte_t pte)
+{
+       pte_val(pte) &= ~(_PAGE_READ);
+       return pte;
+}
+
+static inline pte_t pte_exprotect(pte_t pte)
+{
+       pte_val(pte) &= ~(_PAGE_EXEC);
+       return pte;
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+       pte_val(pte) &= ~(_PAGE_DIRTY);
+       return pte;
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+       pte_val(pte) &= ~(_PAGE_ACCESSED);
+       return pte;
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+       pte_val(pte) |= _PAGE_WRITE;
+       return pte;
+}
+
+static inline pte_t pte_mkread(pte_t pte)
+{
+       pte_val(pte) |= _PAGE_READ;
+       return pte;
+}
+
+static inline pte_t pte_mkexec(pte_t pte)
+{
+       pte_val(pte) |= _PAGE_EXEC;
+       return pte;
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+       pte_val(pte) |= _PAGE_DIRTY;
+       return pte;
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+       pte_val(pte) |= _PAGE_ACCESSED;
+       return pte;
+}
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+
+/* What actually goes as arguments to the various functions is less than
+ * obvious, but a rule of thumb is that struct page's goes as struct page *,
+ * really physical DRAM addresses are unsigned long's, and DRAM "virtual"
+ * addresses (the 0xc0xxxxxx's) goes as void *'s.
+ */
+
+static inline pte_t __mk_pte(void *page, pgprot_t pgprot)
+{
+       pte_t pte;
+       /* the PTE needs a physical address */
+       pte_val(pte) = __pa(page) | pgprot_val(pgprot);
+       return pte;
+}
+
+#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot))
+
+#define mk_pte_phys(physpage, pgprot) \
+({                                                                      \
+       pte_t __pte;                                                    \
+                                                                       \
+       pte_val(__pte) = (physpage) + pgprot_val(pgprot);               \
+       __pte;                                                          \
+})
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+       pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
+       return pte;
+}
+
+
+/*
+ * pte_val refers to a page in the 0x0xxxxxxx physical DRAM interval
+ * __pte_page(pte_val) refers to the "virtual" DRAM interval
+ * pte_pagenr refers to the page-number counted starting from the virtual
+ * DRAM start
+ */
+
+static inline unsigned long __pte_page(pte_t pte)
+{
+       /* the PTE contains a physical address */
+       return (unsigned long)__va(pte_val(pte) & PAGE_MASK);
+}
+
+#define pte_pagenr(pte)         ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
+
+/* permanent address of a page */
+
+#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define pte_page(pte)          (mem_map+pte_pagenr(pte))
+
+/*
+ * only the pte's themselves need to point to physical DRAM (see above)
+ * the pagetable links are purely handled within the kernel SW and thus
+ * don't need the __pa and __va transformations.
+ */
+static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
+{
+       pmd_val(*pmdp) = _KERNPG_TABLE | (unsigned long) ptep;
+}
+
+#define pmd_page(pmd)          (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+#define pmd_page_kernel(pmd)    ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
+/* to find an entry in a page-table-directory. */
+#define pgd_index(address)      ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+
+#define __pgd_offset(address)   pgd_index(address)
+
+#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+#define __pmd_offset(address) \
+       (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
+/*
+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
+ *
+ * this macro returns the index of the entry in the pte page which would
+ * control the given virtual address
+ */
+#define __pte_offset(address)                   \
+       (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir, address)         \
+       ((pte_t *) pmd_page_kernel(*(dir)) +  __pte_offset(address))
+#define pte_offset_map(dir, address)           \
+       ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
+#define pte_offset_map_nested(dir, address)     \
+       pte_offset_map(dir, address)
+
+#define pte_unmap(pte)          do { } while (0)
+#define pte_unmap_nested(pte)   do { } while (0)
+#define pte_pfn(x)             ((unsigned long)(((x).pte)) >> PAGE_SHIFT)
+#define pfn_pte(pfn, prot)  __pte((((pfn) << PAGE_SHIFT)) | pgprot_val(prot))
+
+#define pte_ERROR(e) \
+       printk(KERN_ERR "%s:%d: bad pte %p(%08lx).\n", \
+              __FILE__, __LINE__, &(e), pte_val(e))
+#define pgd_ERROR(e) \
+       printk(KERN_ERR "%s:%d: bad pgd %p(%08lx).\n", \
+              __FILE__, __LINE__, &(e), pgd_val(e))
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */
+
+/*
+ * or32 doesn't have any external MMU info: the kernel page
+ * tables contain all the necessary information.
+ *
+ * Actually I am not sure on what this could be used for.
+ */
+static inline void update_mmu_cache(struct vm_area_struct *vma,
+       unsigned long address, pte_t *pte)
+{
+}
+
+/* __PHX__ FIXME, SWAP, this probably doesn't work */
+
+/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */
+/* Since the PAGE_PRESENT bit is bit 4, we can use the bits above */
+
+#define __swp_type(x)                  (((x).val >> 5) & 0x7f)
+#define __swp_offset(x)                        ((x).val >> 12)
+#define __swp_entry(type, offset) \
+       ((swp_entry_t) { ((type) << 5) | ((offset) << 12) })
+#define __pte_to_swp_entry(pte)                ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)          ((pte_t) { (x).val })
+
+/* Encode and decode a nonlinear file mapping entry */
+
+#define PTE_FILE_MAX_BITS               26
+#define pte_to_pgoff(x)                        (pte_val(x) >> 6)
+#define pgoff_to_pte(x)                        __pte(((x) << 6) | _PAGE_FILE)
+
+#define kern_addr_valid(addr)           (1)
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)         \
+       remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#include <asm-generic/pgtable.h>
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()           do { } while (0)
+#define io_remap_page_range            remap_page_range
+
+typedef pte_t *pte_addr_t;
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_OPENRISC_PGTABLE_H */
diff --git a/arch/openrisc/include/asm/processor.h b/arch/openrisc/include/asm/processor.h
new file mode 100644 (file)
index 0000000..bb54c97
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_PROCESSOR_H
+#define __ASM_OPENRISC_PROCESSOR_H
+
+#include <asm/spr_defs.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+
+#define STACK_TOP       TASK_SIZE
+#define STACK_TOP_MAX  STACK_TOP
+/* Kernel and user SR register setting */
+#define KERNEL_SR (SPR_SR_DME | SPR_SR_IME | SPR_SR_ICE \
+                  | SPR_SR_DCE | SPR_SR_SM)
+#define USER_SR   (SPR_SR_DME | SPR_SR_IME | SPR_SR_ICE \
+                  | SPR_SR_DCE | SPR_SR_IEE | SPR_SR_TEE)
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l; })
+
+/*
+ * User space process size. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+
+#define TASK_SIZE       (0x80000000UL)
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE      (TASK_SIZE / 8 * 3)
+
+#ifndef __ASSEMBLY__
+
+struct task_struct;
+
+struct thread_struct {
+};
+
+/*
+ * At user->kernel entry, the pt_regs struct is stacked on the top of the
+ * kernel-stack.  This macro allows us to find those regs for a task.
+ * Notice that subsequent pt_regs stackings, like recursive interrupts
+ * occurring while we're in the kernel, won't affect this - only the first
+ * user->kernel transition registers are reached by this (i.e. not regs
+ * for running signal handler)
+ */
+#define user_regs(thread_info)  (((struct pt_regs *)((unsigned long)(thread_info) + THREAD_SIZE - STACK_FRAME_OVERHEAD)) - 1)
+
+/*
+ * Dito but for the currently running task
+ */
+
+#define task_pt_regs(task) user_regs(task_thread_info(task))
+#define current_regs() user_regs(current_thread_info())
+
+extern inline void prepare_to_copy(struct task_struct *tsk)
+{
+}
+
+#define INIT_SP         (sizeof(init_stack) + (unsigned long) &init_stack)
+
+#define INIT_THREAD  { }
+
+
+#define KSTK_EIP(tsk)   (task_pt_regs(tsk)->pc);
+#define KSTK_ESP(tsk)   (task_pt_regs(tsk)->sp);
+
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
+void release_thread(struct task_struct *);
+unsigned long get_wchan(struct task_struct *p);
+
+/*
+ * Free current thread data structures etc..
+ */
+
+extern inline void exit_thread(void)
+{
+       /* Nothing needs to be done.  */
+}
+
+/*
+ * Return saved PC of a blocked thread. For now, this is the "user" PC
+ */
+extern unsigned long thread_saved_pc(struct task_struct *t);
+
+#define init_stack      (init_thread_union.stack)
+
+#define cpu_relax()     do { } while (0)
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_OPENRISC_PROCESSOR_H */
diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h
new file mode 100644 (file)
index 0000000..e1f3fe2
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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 <linux/of.h>  /* linux/of.h gets to determine #include ordering */
+
+#ifndef _ASM_OPENRISC_PROM_H
+#define _ASM_OPENRISC_PROM_H
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <asm/irq.h>
+#include <linux/atomic.h>
+#include <linux/of_irq.h>
+#include <linux/of_fdt.h>
+#include <linux/of_address.h>
+#include <linux/proc_fs.h>
+#include <linux/platform_device.h>
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
+/* Other Prototypes */
+extern int early_uartlite_console(void);
+
+/* Parse the ibm,dma-window property of an OF node into the busno, phys and
+ * size parameters.
+ */
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
+               unsigned long *busno, unsigned long *phys, unsigned long *size);
+
+extern void kdump_move_device_tree(void);
+
+/* CPU OF node matching */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
+
+/* Get the MAC address */
+extern const void *of_get_mac_address(struct device_node *np);
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev:      the device whose interrupt is to be resolved
+ * @out_irq:   structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+
+/* This routine is here to provide compatibility with how powerpc
+ * handles IRQ mapping for OF device nodes.  We precompute and permanently
+ * register them in the platform_device objects, whereas powerpc computes them
+ * on request.
+ */
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_OPENRISC_PROM_H */
diff --git a/arch/openrisc/include/asm/ptrace.h b/arch/openrisc/include/asm/ptrace.h
new file mode 100644 (file)
index 0000000..054537c
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_PTRACE_H
+#define __ASM_OPENRISC_PTRACE_H
+
+#include <asm/spr_defs.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * This is the layout of the regset returned by the GETREGSET ptrace call
+ */
+struct user_regs_struct {
+       /* GPR R0-R31... */
+       unsigned long gpr[32];
+       unsigned long pc;
+       unsigned long sr;
+       unsigned long pad1;
+       unsigned long pad2;
+};
+#endif
+
+#ifdef __KERNEL__
+
+/*
+ * Make kernel PTrace/register structures opaque to userspace... userspace can
+ * access thread state via the regset mechanism.  This allows us a bit of
+ * flexibility in how we order the registers on the stack, permitting some
+ * optimizations like packing call-clobbered registers together so that
+ * they share a cacheline (not done yet, though... future optimization).
+ */
+
+#ifndef __ASSEMBLY__
+/*
+ * This struct describes how the registers are laid out on the kernel stack
+ * during a syscall or other kernel entry.
+ *
+ * This structure should always be cacheline aligned on the stack.
+ * FIXME: I don't think that's the case right now.  The alignment is
+ * taken care of elsewhere... head.S, process.c, etc.
+ */
+
+struct pt_regs {
+       union {
+               struct {
+                       /* Named registers */
+                       long  sr;       /* Stored in place of r0 */
+                       long  sp;       /* r1 */
+               };
+               struct {
+                       /* Old style */
+                       long offset[2];
+                       long gprs[30];
+               };
+               struct {
+                       /* New style */
+                       long gpr[32];
+               };
+       };
+       long  pc;
+       long  orig_gpr11;       /* For restarting system calls */
+       long  syscallno;        /* Syscall number (used by strace) */
+       long dummy;             /* Cheap alignment fix */
+};
+#endif /* __ASSEMBLY__ */
+
+/* TODO: Rename this to REDZONE because that's what it is */
+#define STACK_FRAME_OVERHEAD  128  /* size of minimum stack frame */
+
+#define instruction_pointer(regs)      ((regs)->pc)
+#define user_mode(regs)                        (((regs)->sr & SPR_SR_SM) == 0)
+#define user_stack_pointer(regs)       ((unsigned long)(regs)->sp)
+#define profile_pc(regs)               instruction_pointer(regs)
+
+/*
+ * Offsets used by 'ptrace' system call interface.
+ */
+#define PT_SR         0
+#define PT_SP         4
+#define PT_GPR2       8
+#define PT_GPR3       12
+#define PT_GPR4       16
+#define PT_GPR5       20
+#define PT_GPR6       24
+#define PT_GPR7       28
+#define PT_GPR8       32
+#define PT_GPR9       36
+#define PT_GPR10      40
+#define PT_GPR11      44
+#define PT_GPR12      48
+#define PT_GPR13      52
+#define PT_GPR14      56
+#define PT_GPR15      60
+#define PT_GPR16      64
+#define PT_GPR17      68
+#define PT_GPR18      72
+#define PT_GPR19      76
+#define PT_GPR20      80
+#define PT_GPR21      84
+#define PT_GPR22      88
+#define PT_GPR23      92
+#define PT_GPR24      96
+#define PT_GPR25      100
+#define PT_GPR26      104
+#define PT_GPR27      108
+#define PT_GPR28      112
+#define PT_GPR29      116
+#define PT_GPR30      120
+#define PT_GPR31      124
+#define PT_PC        128
+#define PT_ORIG_GPR11 132
+#define PT_SYSCALLNO  136
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_OPENRISC_PTRACE_H */
diff --git a/arch/openrisc/include/asm/serial.h b/arch/openrisc/include/asm/serial.h
new file mode 100644 (file)
index 0000000..270a452
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_SERIAL_H
+#define __ASM_OPENRISC_SERIAL_H
+
+#ifdef __KERNEL__
+
+#include <asm/cpuinfo.h>
+
+/* There's a generic version of this file, but it assumes a 1.8MHz UART clk...
+ * this, on the other hand, assumes the UART clock is tied to the system
+ * clock... 8250_early.c (early 8250 serial console) actually uses this, so
+ * it needs to be correct to get the early console working.
+ */
+
+#define BASE_BAUD (cpuinfo.clock_frequency/16)
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_OPENRISC_SERIAL_H */
diff --git a/arch/openrisc/include/asm/sigcontext.h b/arch/openrisc/include/asm/sigcontext.h
new file mode 100644 (file)
index 0000000..54a5c50
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_SIGCONTEXT_H
+#define __ASM_OPENRISC_SIGCONTEXT_H
+
+#include <asm/ptrace.h>
+
+/* This struct is saved by setup_frame in signal.c, to keep the current
+   context while a signal handler is executed. It's restored by sys_sigreturn.
+
+   To keep things simple, we use pt_regs here even though normally you just
+   specify the list of regs to save. Then we can use copy_from_user on the
+   entire regs instead of a bunch of get_user's as well...
+*/
+
+struct sigcontext {
+       struct pt_regs regs;  /* needs to be first */
+       unsigned long oldmask;
+       unsigned long usp;    /* usp before stacking this gunk on it */
+};
+
+#endif /* __ASM_OPENRISC_SIGCONTEXT_H */
diff --git a/arch/openrisc/include/asm/spinlock.h b/arch/openrisc/include/asm/spinlock.h
new file mode 100644 (file)
index 0000000..fd00a3a
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_SPINLOCK_H
+#define __ASM_OPENRISC_SPINLOCK_H
+
+#error "or32 doesn't do SMP yet"
+
+#endif
diff --git a/arch/openrisc/include/asm/spr.h b/arch/openrisc/include/asm/spr.h
new file mode 100644 (file)
index 0000000..1cccb42
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_SPR_H
+#define __ASM_OPENRISC_SPR_H
+
+#define mtspr(_spr, _val) __asm__ __volatile__ (               \
+       "l.mtspr r0,%1,%0"                                      \
+       : : "K" (_spr), "r" (_val))
+#define mtspr_off(_spr, _off, _val) __asm__ __volatile__ (     \
+       "l.mtspr %0,%1,%2"                                      \
+       : : "r" (_off), "r" (_val), "K" (_spr))
+
+static inline unsigned long mfspr(unsigned long add)
+{
+       unsigned long ret;
+       __asm__ __volatile__ ("l.mfspr %0,r0,%1" : "=r" (ret) : "K" (add));
+       return ret;
+}
+
+static inline unsigned long mfspr_off(unsigned long add, unsigned long offset)
+{
+       unsigned long ret;
+       __asm__ __volatile__ ("l.mfspr %0,%1,%2" : "=r" (ret)
+                                                : "r" (offset), "K" (add));
+       return ret;
+}
+
+#endif
diff --git a/arch/openrisc/include/asm/spr_defs.h b/arch/openrisc/include/asm/spr_defs.h
new file mode 100644 (file)
index 0000000..5dbc668
--- /dev/null
@@ -0,0 +1,604 @@
+/*
+ * OpenRISC Linux
+ *
+ * SPR Definitions
+ *
+ * Copyright (C) 2000 Damjan Lampret
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2008, 2010 Embecosm Limited
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is part of OpenRISC 1000 Architectural Simulator.
+ */
+
+#ifndef SPR_DEFS__H
+#define SPR_DEFS__H
+
+/* Definition of special-purpose registers (SPRs). */
+
+#define MAX_GRPS (32)
+#define MAX_SPRS_PER_GRP_BITS (11)
+#define MAX_SPRS_PER_GRP (1 << MAX_SPRS_PER_GRP_BITS)
+#define MAX_SPRS (0x10000)
+
+/* Base addresses for the groups */
+#define SPRGROUP_SYS   (0 << MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_DMMU  (1 << MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_IMMU  (2 << MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_DC    (3 << MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_IC    (4 << MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_MAC   (5 << MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_D     (6 << MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_PC    (7 << MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_PM    (8 << MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_PIC   (9 << MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_TT    (10 << MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_FP    (11 << MAX_SPRS_PER_GRP_BITS)
+
+/* System control and status group */
+#define SPR_VR         (SPRGROUP_SYS + 0)
+#define SPR_UPR                (SPRGROUP_SYS + 1)
+#define SPR_CPUCFGR    (SPRGROUP_SYS + 2)
+#define SPR_DMMUCFGR   (SPRGROUP_SYS + 3)
+#define SPR_IMMUCFGR   (SPRGROUP_SYS + 4)
+#define SPR_DCCFGR     (SPRGROUP_SYS + 5)
+#define SPR_ICCFGR     (SPRGROUP_SYS + 6)
+#define SPR_DCFGR      (SPRGROUP_SYS + 7)
+#define SPR_PCCFGR     (SPRGROUP_SYS + 8)
+#define SPR_NPC         (SPRGROUP_SYS + 16)  /* CZ 21/06/01 */
+#define SPR_SR         (SPRGROUP_SYS + 17)  /* CZ 21/06/01 */
+#define SPR_PPC         (SPRGROUP_SYS + 18)  /* CZ 21/06/01 */
+#define SPR_FPCSR       (SPRGROUP_SYS + 20)  /* CZ 21/06/01 */
+#define SPR_EPCR_BASE  (SPRGROUP_SYS + 32)  /* CZ 21/06/01 */
+#define SPR_EPCR_LAST  (SPRGROUP_SYS + 47)  /* CZ 21/06/01 */
+#define SPR_EEAR_BASE  (SPRGROUP_SYS + 48)
+#define SPR_EEAR_LAST  (SPRGROUP_SYS + 63)
+#define SPR_ESR_BASE   (SPRGROUP_SYS + 64)
+#define SPR_ESR_LAST   (SPRGROUP_SYS + 79)
+#define SPR_GPR_BASE   (SPRGROUP_SYS + 1024)
+
+/* Data MMU group */
+#define SPR_DMMUCR     (SPRGROUP_DMMU + 0)
+#define SPR_DTLBEIR    (SPRGROUP_DMMU + 2)
+#define SPR_DTLBMR_BASE(WAY)   (SPRGROUP_DMMU + 0x200 + (WAY) * 0x100)
+#define SPR_DTLBMR_LAST(WAY)   (SPRGROUP_DMMU + 0x27f + (WAY) * 0x100)
+#define SPR_DTLBTR_BASE(WAY)   (SPRGROUP_DMMU + 0x280 + (WAY) * 0x100)
+#define SPR_DTLBTR_LAST(WAY)   (SPRGROUP_DMMU + 0x2ff + (WAY) * 0x100)
+
+/* Instruction MMU group */
+#define SPR_IMMUCR     (SPRGROUP_IMMU + 0)
+#define SPR_ITLBEIR    (SPRGROUP_IMMU + 2)
+#define SPR_ITLBMR_BASE(WAY)   (SPRGROUP_IMMU + 0x200 + (WAY) * 0x100)
+#define SPR_ITLBMR_LAST(WAY)   (SPRGROUP_IMMU + 0x27f + (WAY) * 0x100)
+#define SPR_ITLBTR_BASE(WAY)   (SPRGROUP_IMMU + 0x280 + (WAY) * 0x100)
+#define SPR_ITLBTR_LAST(WAY)   (SPRGROUP_IMMU + 0x2ff + (WAY) * 0x100)
+
+/* Data cache group */
+#define SPR_DCCR       (SPRGROUP_DC + 0)
+#define SPR_DCBPR      (SPRGROUP_DC + 1)
+#define SPR_DCBFR      (SPRGROUP_DC + 2)
+#define SPR_DCBIR      (SPRGROUP_DC + 3)
+#define SPR_DCBWR      (SPRGROUP_DC + 4)
+#define SPR_DCBLR      (SPRGROUP_DC + 5)
+#define SPR_DCR_BASE(WAY)      (SPRGROUP_DC + 0x200 + (WAY) * 0x200)
+#define SPR_DCR_LAST(WAY)      (SPRGROUP_DC + 0x3ff + (WAY) * 0x200)
+
+/* Instruction cache group */
+#define SPR_ICCR       (SPRGROUP_IC + 0)
+#define SPR_ICBPR      (SPRGROUP_IC + 1)
+#define SPR_ICBIR      (SPRGROUP_IC + 2)
+#define SPR_ICBLR      (SPRGROUP_IC + 3)
+#define SPR_ICR_BASE(WAY)      (SPRGROUP_IC + 0x200 + (WAY) * 0x200)
+#define SPR_ICR_LAST(WAY)      (SPRGROUP_IC + 0x3ff + (WAY) * 0x200)
+
+/* MAC group */
+#define SPR_MACLO      (SPRGROUP_MAC + 1)
+#define SPR_MACHI      (SPRGROUP_MAC + 2)
+
+/* Debug group */
+#define SPR_DVR(N)     (SPRGROUP_D + (N))
+#define SPR_DCR(N)     (SPRGROUP_D + 8 + (N))
+#define SPR_DMR1       (SPRGROUP_D + 16)
+#define SPR_DMR2       (SPRGROUP_D + 17)
+#define SPR_DWCR0      (SPRGROUP_D + 18)
+#define SPR_DWCR1      (SPRGROUP_D + 19)
+#define SPR_DSR                (SPRGROUP_D + 20)
+#define SPR_DRR                (SPRGROUP_D + 21)
+
+/* Performance counters group */
+#define SPR_PCCR(N)    (SPRGROUP_PC + (N))
+#define SPR_PCMR(N)    (SPRGROUP_PC + 8 + (N))
+
+/* Power management group */
+#define SPR_PMR (SPRGROUP_PM + 0)
+
+/* PIC group */
+#define SPR_PICMR (SPRGROUP_PIC + 0)
+#define SPR_PICPR (SPRGROUP_PIC + 1)
+#define SPR_PICSR (SPRGROUP_PIC + 2)
+
+/* Tick Timer group */
+#define SPR_TTMR (SPRGROUP_TT + 0)
+#define SPR_TTCR (SPRGROUP_TT + 1)
+
+/*
+ * Bit definitions for the Version Register
+ *
+ */
+#define SPR_VR_VER     0xff000000  /* Processor version */
+#define SPR_VR_CFG     0x00ff0000  /* Processor configuration */
+#define SPR_VR_RES     0x0000ffc0  /* Reserved */
+#define SPR_VR_REV     0x0000003f  /* Processor revision */
+
+#define SPR_VR_VER_OFF 24
+#define SPR_VR_CFG_OFF 16
+#define SPR_VR_REV_OFF 0
+
+/*
+ * Bit definitions for the Unit Present Register
+ *
+ */
+#define SPR_UPR_UP        0x00000001  /* UPR present */
+#define SPR_UPR_DCP       0x00000002  /* Data cache present */
+#define SPR_UPR_ICP       0x00000004  /* Instruction cache present */
+#define SPR_UPR_DMP       0x00000008  /* Data MMU present */
+#define SPR_UPR_IMP       0x00000010  /* Instruction MMU present */
+#define SPR_UPR_MP        0x00000020  /* MAC present */
+#define SPR_UPR_DUP       0x00000040  /* Debug unit present */
+#define SPR_UPR_PCUP      0x00000080  /* Performance counters unit present */
+#define SPR_UPR_PMP       0x00000100  /* Power management present */
+#define SPR_UPR_PICP      0x00000200  /* PIC present */
+#define SPR_UPR_TTP       0x00000400  /* Tick timer present */
+#define SPR_UPR_RES       0x00fe0000  /* Reserved */
+#define SPR_UPR_CUP       0xff000000  /* Context units present */
+
+/*
+ * JPB: Bit definitions for the CPU configuration register
+ *
+ */
+#define SPR_CPUCFGR_NSGF   0x0000000f  /* Number of shadow GPR files */
+#define SPR_CPUCFGR_CGF           0x00000010  /* Custom GPR file */
+#define SPR_CPUCFGR_OB32S  0x00000020  /* ORBIS32 supported */
+#define SPR_CPUCFGR_OB64S  0x00000040  /* ORBIS64 supported */
+#define SPR_CPUCFGR_OF32S  0x00000080  /* ORFPX32 supported */
+#define SPR_CPUCFGR_OF64S  0x00000100  /* ORFPX64 supported */
+#define SPR_CPUCFGR_OV64S  0x00000200  /* ORVDX64 supported */
+#define SPR_CPUCFGR_RES           0xfffffc00  /* Reserved */
+
+/*
+ * JPB: Bit definitions for the Debug configuration register and other
+ * constants.
+ *
+ */
+
+#define SPR_DCFGR_NDP      0x00000007  /* Number of matchpoints mask */
+#define SPR_DCFGR_NDP1     0x00000000  /* One matchpoint supported */
+#define SPR_DCFGR_NDP2     0x00000001  /* Two matchpoints supported */
+#define SPR_DCFGR_NDP3     0x00000002  /* Three matchpoints supported */
+#define SPR_DCFGR_NDP4     0x00000003  /* Four matchpoints supported */
+#define SPR_DCFGR_NDP5     0x00000004  /* Five matchpoints supported */
+#define SPR_DCFGR_NDP6     0x00000005  /* Six matchpoints supported */
+#define SPR_DCFGR_NDP7     0x00000006  /* Seven matchpoints supported */
+#define SPR_DCFGR_NDP8     0x00000007  /* Eight matchpoints supported */
+#define SPR_DCFGR_WPCI     0x00000008  /* Watchpoint counters implemented */
+
+#define MATCHPOINTS_TO_NDP(n) (1 == n ? SPR_DCFGR_NDP1 : \
+                               2 == n ? SPR_DCFGR_NDP2 : \
+                               3 == n ? SPR_DCFGR_NDP3 : \
+                               4 == n ? SPR_DCFGR_NDP4 : \
+                               5 == n ? SPR_DCFGR_NDP5 : \
+                               6 == n ? SPR_DCFGR_NDP6 : \
+                               7 == n ? SPR_DCFGR_NDP7 : SPR_DCFGR_NDP8)
+#define MAX_MATCHPOINTS  8
+#define MAX_WATCHPOINTS  (MAX_MATCHPOINTS + 2)
+
+/*
+ * Bit definitions for the Supervision Register
+ *
+ */
+#define SPR_SR_SM          0x00000001  /* Supervisor Mode */
+#define SPR_SR_TEE         0x00000002  /* Tick timer Exception Enable */
+#define SPR_SR_IEE         0x00000004  /* Interrupt Exception Enable */
+#define SPR_SR_DCE         0x00000008  /* Data Cache Enable */
+#define SPR_SR_ICE         0x00000010  /* Instruction Cache Enable */
+#define SPR_SR_DME         0x00000020  /* Data MMU Enable */
+#define SPR_SR_IME         0x00000040  /* Instruction MMU Enable */
+#define SPR_SR_LEE         0x00000080  /* Little Endian Enable */
+#define SPR_SR_CE          0x00000100  /* CID Enable */
+#define SPR_SR_F           0x00000200  /* Condition Flag */
+#define SPR_SR_CY          0x00000400  /* Carry flag */
+#define SPR_SR_OV          0x00000800  /* Overflow flag */
+#define SPR_SR_OVE         0x00001000  /* Overflow flag Exception */
+#define SPR_SR_DSX         0x00002000  /* Delay Slot Exception */
+#define SPR_SR_EPH         0x00004000  /* Exception Prefix High */
+#define SPR_SR_FO          0x00008000  /* Fixed one */
+#define SPR_SR_SUMRA       0x00010000  /* Supervisor SPR read access */
+#define SPR_SR_RES         0x0ffe0000  /* Reserved */
+#define SPR_SR_CID         0xf0000000  /* Context ID */
+
+/*
+ * Bit definitions for the Data MMU Control Register
+ *
+ */
+#define SPR_DMMUCR_P2S    0x0000003e  /* Level 2 Page Size */
+#define SPR_DMMUCR_P1S    0x000007c0  /* Level 1 Page Size */
+#define SPR_DMMUCR_VADDR_WIDTH 0x0000f800  /* Virtual ADDR Width */
+#define SPR_DMMUCR_PADDR_WIDTH 0x000f0000  /* Physical ADDR Width */
+
+/*
+ * Bit definitions for the Instruction MMU Control Register
+ *
+ */
+#define SPR_IMMUCR_P2S    0x0000003e  /* Level 2 Page Size */
+#define SPR_IMMUCR_P1S    0x000007c0  /* Level 1 Page Size */
+#define SPR_IMMUCR_VADDR_WIDTH 0x0000f800  /* Virtual ADDR Width */
+#define SPR_IMMUCR_PADDR_WIDTH 0x000f0000  /* Physical ADDR Width */
+
+/*
+ * Bit definitions for the Data TLB Match Register
+ *
+ */
+#define SPR_DTLBMR_V      0x00000001  /* Valid */
+#define SPR_DTLBMR_PL1    0x00000002  /* Page Level 1 (if 0 then PL2) */
+#define SPR_DTLBMR_CID    0x0000003c  /* Context ID */
+#define SPR_DTLBMR_LRU    0x000000c0  /* Least Recently Used */
+#define SPR_DTLBMR_VPN    0xfffff000  /* Virtual Page Number */
+
+/*
+ * Bit definitions for the Data TLB Translate Register
+ *
+ */
+#define SPR_DTLBTR_CC     0x00000001  /* Cache Coherency */
+#define SPR_DTLBTR_CI     0x00000002  /* Cache Inhibit */
+#define SPR_DTLBTR_WBC    0x00000004  /* Write-Back Cache */
+#define SPR_DTLBTR_WOM    0x00000008  /* Weakly-Ordered Memory */
+#define SPR_DTLBTR_A      0x00000010  /* Accessed */
+#define SPR_DTLBTR_D      0x00000020  /* Dirty */
+#define SPR_DTLBTR_URE    0x00000040  /* User Read Enable */
+#define SPR_DTLBTR_UWE    0x00000080  /* User Write Enable */
+#define SPR_DTLBTR_SRE    0x00000100  /* Supervisor Read Enable */
+#define SPR_DTLBTR_SWE    0x00000200  /* Supervisor Write Enable */
+#define SPR_DTLBTR_PPN    0xfffff000  /* Physical Page Number */
+
+/*
+ * Bit definitions for the Instruction TLB Match Register
+ *
+ */
+#define SPR_ITLBMR_V      0x00000001  /* Valid */
+#define SPR_ITLBMR_PL1    0x00000002  /* Page Level 1 (if 0 then PL2) */
+#define SPR_ITLBMR_CID    0x0000003c  /* Context ID */
+#define SPR_ITLBMR_LRU    0x000000c0  /* Least Recently Used */
+#define SPR_ITLBMR_VPN    0xfffff000  /* Virtual Page Number */
+
+/*
+ * Bit definitions for the Instruction TLB Translate Register
+ *
+ */
+#define SPR_ITLBTR_CC     0x00000001  /* Cache Coherency */
+#define SPR_ITLBTR_CI     0x00000002  /* Cache Inhibit */
+#define SPR_ITLBTR_WBC    0x00000004  /* Write-Back Cache */
+#define SPR_ITLBTR_WOM    0x00000008  /* Weakly-Ordered Memory */
+#define SPR_ITLBTR_A      0x00000010  /* Accessed */
+#define SPR_ITLBTR_D      0x00000020  /* Dirty */
+#define SPR_ITLBTR_SXE    0x00000040  /* User Read Enable */
+#define SPR_ITLBTR_UXE    0x00000080  /* User Write Enable */
+#define SPR_ITLBTR_PPN    0xfffff000  /* Physical Page Number */
+
+/*
+ * Bit definitions for Data Cache Control register
+ *
+ */
+#define SPR_DCCR_EW       0x000000ff  /* Enable ways */
+
+/*
+ * Bit definitions for Insn Cache Control register
+ *
+ */
+#define SPR_ICCR_EW       0x000000ff  /* Enable ways */
+
+/*
+ * Bit definitions for Data Cache Configuration Register
+ *
+ */
+
+#define SPR_DCCFGR_NCW         0x00000007
+#define SPR_DCCFGR_NCS         0x00000078
+#define SPR_DCCFGR_CBS         0x00000080
+#define SPR_DCCFGR_CWS         0x00000100
+#define SPR_DCCFGR_CCRI                0x00000200
+#define SPR_DCCFGR_CBIRI       0x00000400
+#define SPR_DCCFGR_CBPRI       0x00000800
+#define SPR_DCCFGR_CBLRI       0x00001000
+#define SPR_DCCFGR_CBFRI       0x00002000
+#define SPR_DCCFGR_CBWBRI      0x00004000
+
+#define SPR_DCCFGR_NCW_OFF      0
+#define SPR_DCCFGR_NCS_OFF      3
+#define SPR_DCCFGR_CBS_OFF     7
+
+/*
+ * Bit definitions for Instruction Cache Configuration Register
+ *
+ */
+#define SPR_ICCFGR_NCW         0x00000007
+#define SPR_ICCFGR_NCS         0x00000078
+#define SPR_ICCFGR_CBS         0x00000080
+#define SPR_ICCFGR_CCRI                0x00000200
+#define SPR_ICCFGR_CBIRI       0x00000400
+#define SPR_ICCFGR_CBPRI       0x00000800
+#define SPR_ICCFGR_CBLRI       0x00001000
+
+#define SPR_ICCFGR_NCW_OFF      0
+#define SPR_ICCFGR_NCS_OFF      3
+#define SPR_ICCFGR_CBS_OFF     7
+
+/*
+ * Bit definitions for Data MMU Configuration Register
+ *
+ */
+
+#define SPR_DMMUCFGR_NTW       0x00000003
+#define SPR_DMMUCFGR_NTS       0x0000001C
+#define SPR_DMMUCFGR_NAE       0x000000E0
+#define SPR_DMMUCFGR_CRI       0x00000100
+#define SPR_DMMUCFGR_PRI        0x00000200
+#define SPR_DMMUCFGR_TEIRI     0x00000400
+#define SPR_DMMUCFGR_HTR       0x00000800
+
+#define SPR_DMMUCFGR_NTW_OFF   0
+#define SPR_DMMUCFGR_NTS_OFF   2
+
+/*
+ * Bit definitions for Instruction MMU Configuration Register
+ *
+ */
+
+#define SPR_IMMUCFGR_NTW       0x00000003
+#define SPR_IMMUCFGR_NTS       0x0000001C
+#define SPR_IMMUCFGR_NAE       0x000000E0
+#define SPR_IMMUCFGR_CRI       0x00000100
+#define SPR_IMMUCFGR_PRI       0x00000200
+#define SPR_IMMUCFGR_TEIRI     0x00000400
+#define SPR_IMMUCFGR_HTR       0x00000800
+
+#define SPR_IMMUCFGR_NTW_OFF   0
+#define SPR_IMMUCFGR_NTS_OFF   2
+
+/*
+ * Bit definitions for Debug Control registers
+ *
+ */
+#define SPR_DCR_DP     0x00000001  /* DVR/DCR present */
+#define SPR_DCR_CC     0x0000000e  /* Compare condition */
+#define SPR_DCR_SC     0x00000010  /* Signed compare */
+#define SPR_DCR_CT     0x000000e0  /* Compare to */
+
+/* Bit results with SPR_DCR_CC mask */
+#define SPR_DCR_CC_MASKED 0x00000000
+#define SPR_DCR_CC_EQUAL  0x00000002
+#define SPR_DCR_CC_LESS   0x00000004
+#define SPR_DCR_CC_LESSE  0x00000006
+#define SPR_DCR_CC_GREAT  0x00000008
+#define SPR_DCR_CC_GREATE 0x0000000a
+#define SPR_DCR_CC_NEQUAL 0x0000000c
+
+/* Bit results with SPR_DCR_CT mask */
+#define SPR_DCR_CT_DISABLED 0x00000000
+#define SPR_DCR_CT_IFEA     0x00000020
+#define SPR_DCR_CT_LEA      0x00000040
+#define SPR_DCR_CT_SEA      0x00000060
+#define SPR_DCR_CT_LD       0x00000080
+#define SPR_DCR_CT_SD       0x000000a0
+#define SPR_DCR_CT_LSEA     0x000000c0
+#define SPR_DCR_CT_LSD     0x000000e0
+/* SPR_DCR_CT_LSD doesn't seem to be implemented anywhere in or1ksim. 2004-1-30 HP */
+
+/*
+ * Bit definitions for Debug Mode 1 register
+ *
+ */
+#define SPR_DMR1_CW       0x000fffff  /* Chain register pair data */
+#define SPR_DMR1_CW0_AND  0x00000001
+#define SPR_DMR1_CW0_OR   0x00000002
+#define SPR_DMR1_CW0      (SPR_DMR1_CW0_AND | SPR_DMR1_CW0_OR)
+#define SPR_DMR1_CW1_AND  0x00000004
+#define SPR_DMR1_CW1_OR   0x00000008
+#define SPR_DMR1_CW1      (SPR_DMR1_CW1_AND | SPR_DMR1_CW1_OR)
+#define SPR_DMR1_CW2_AND  0x00000010
+#define SPR_DMR1_CW2_OR   0x00000020
+#define SPR_DMR1_CW2      (SPR_DMR1_CW2_AND | SPR_DMR1_CW2_OR)
+#define SPR_DMR1_CW3_AND  0x00000040
+#define SPR_DMR1_CW3_OR   0x00000080
+#define SPR_DMR1_CW3      (SPR_DMR1_CW3_AND | SPR_DMR1_CW3_OR)
+#define SPR_DMR1_CW4_AND  0x00000100
+#define SPR_DMR1_CW4_OR   0x00000200
+#define SPR_DMR1_CW4      (SPR_DMR1_CW4_AND | SPR_DMR1_CW4_OR)
+#define SPR_DMR1_CW5_AND  0x00000400
+#define SPR_DMR1_CW5_OR   0x00000800
+#define SPR_DMR1_CW5      (SPR_DMR1_CW5_AND | SPR_DMR1_CW5_OR)
+#define SPR_DMR1_CW6_AND  0x00001000
+#define SPR_DMR1_CW6_OR   0x00002000
+#define SPR_DMR1_CW6      (SPR_DMR1_CW6_AND | SPR_DMR1_CW6_OR)
+#define SPR_DMR1_CW7_AND  0x00004000
+#define SPR_DMR1_CW7_OR   0x00008000
+#define SPR_DMR1_CW7      (SPR_DMR1_CW7_AND | SPR_DMR1_CW7_OR)
+#define SPR_DMR1_CW8_AND  0x00010000
+#define SPR_DMR1_CW8_OR   0x00020000
+#define SPR_DMR1_CW8      (SPR_DMR1_CW8_AND | SPR_DMR1_CW8_OR)
+#define SPR_DMR1_CW9_AND  0x00040000
+#define SPR_DMR1_CW9_OR   0x00080000
+#define SPR_DMR1_CW9      (SPR_DMR1_CW9_AND | SPR_DMR1_CW9_OR)
+#define SPR_DMR1_RES1      0x00300000  /* Reserved */
+#define SPR_DMR1_ST      0x00400000  /* Single-step trace*/
+#define SPR_DMR1_BT      0x00800000  /* Branch trace */
+#define SPR_DMR1_RES2    0xff000000  /* Reserved */
+
+/*
+ * Bit definitions for Debug Mode 2 register. AWTC and WGB corrected by JPB
+ *
+ */
+#define SPR_DMR2_WCE0     0x00000001  /* Watchpoint counter 0 enable */
+#define SPR_DMR2_WCE1     0x00000002  /* Watchpoint counter 0 enable */
+#define SPR_DMR2_AWTC     0x00000ffc  /* Assign watchpoints to counters */
+#define SPR_DMR2_AWTC_OFF           2  /* Bit offset to AWTC field */
+#define SPR_DMR2_WGB      0x003ff000  /* Watchpoints generating breakpoint */
+#define SPR_DMR2_WGB_OFF           12  /* Bit offset to WGB field */
+#define SPR_DMR2_WBS      0xffc00000  /* JPB: Watchpoint status */
+#define SPR_DMR2_WBS_OFF           22  /* Bit offset to WBS field */
+
+/*
+ * Bit definitions for Debug watchpoint counter registers
+ *
+ */
+#define SPR_DWCR_COUNT     0x0000ffff  /* Count */
+#define SPR_DWCR_MATCH     0xffff0000  /* Match */
+#define SPR_DWCR_MATCH_OFF          16  /* Match bit offset */
+
+/*
+ * Bit definitions for Debug stop register
+ *
+ */
+#define SPR_DSR_RSTE   0x00000001  /* Reset exception */
+#define SPR_DSR_BUSEE  0x00000002  /* Bus error exception */
+#define SPR_DSR_DPFE   0x00000004  /* Data Page Fault exception */
+#define SPR_DSR_IPFE   0x00000008  /* Insn Page Fault exception */
+#define SPR_DSR_TTE    0x00000010  /* Tick Timer exception */
+#define SPR_DSR_AE     0x00000020  /* Alignment exception */
+#define SPR_DSR_IIE    0x00000040  /* Illegal Instruction exception */
+#define SPR_DSR_IE     0x00000080  /* Interrupt exception */
+#define SPR_DSR_DME    0x00000100  /* DTLB miss exception */
+#define SPR_DSR_IME    0x00000200  /* ITLB miss exception */
+#define SPR_DSR_RE     0x00000400  /* Range exception */
+#define SPR_DSR_SCE    0x00000800  /* System call exception */
+#define SPR_DSR_FPE     0x00001000  /* Floating Point Exception */
+#define SPR_DSR_TE     0x00002000  /* Trap exception */
+
+/*
+ * Bit definitions for Debug reason register
+ *
+ */
+#define SPR_DRR_RSTE   0x00000001  /* Reset exception */
+#define SPR_DRR_BUSEE  0x00000002  /* Bus error exception */
+#define SPR_DRR_DPFE   0x00000004  /* Data Page Fault exception */
+#define SPR_DRR_IPFE   0x00000008  /* Insn Page Fault exception */
+#define SPR_DRR_TTE    0x00000010  /* Tick Timer exception */
+#define SPR_DRR_AE     0x00000020  /* Alignment exception */
+#define SPR_DRR_IIE    0x00000040  /* Illegal Instruction exception */
+#define SPR_DRR_IE     0x00000080  /* Interrupt exception */
+#define SPR_DRR_DME    0x00000100  /* DTLB miss exception */
+#define SPR_DRR_IME    0x00000200  /* ITLB miss exception */
+#define SPR_DRR_RE     0x00000400  /* Range exception */
+#define SPR_DRR_SCE    0x00000800  /* System call exception */
+#define SPR_DRR_FPE     0x00001000  /* Floating Point Exception */
+#define SPR_DRR_TE     0x00002000  /* Trap exception */
+
+/*
+ * Bit definitions for Performance counters mode registers
+ *
+ */
+#define SPR_PCMR_CP    0x00000001  /* Counter present */
+#define SPR_PCMR_UMRA  0x00000002  /* User mode read access */
+#define SPR_PCMR_CISM  0x00000004  /* Count in supervisor mode */
+#define SPR_PCMR_CIUM  0x00000008  /* Count in user mode */
+#define SPR_PCMR_LA    0x00000010  /* Load access event */
+#define SPR_PCMR_SA    0x00000020  /* Store access event */
+#define SPR_PCMR_IF    0x00000040  /* Instruction fetch event*/
+#define SPR_PCMR_DCM   0x00000080  /* Data cache miss event */
+#define SPR_PCMR_ICM   0x00000100  /* Insn cache miss event */
+#define SPR_PCMR_IFS   0x00000200  /* Insn fetch stall event */
+#define SPR_PCMR_LSUS  0x00000400  /* LSU stall event */
+#define SPR_PCMR_BS    0x00000800  /* Branch stall event */
+#define SPR_PCMR_DTLBM 0x00001000  /* DTLB miss event */
+#define SPR_PCMR_ITLBM 0x00002000  /* ITLB miss event */
+#define SPR_PCMR_DDS   0x00004000  /* Data dependency stall event */
+#define SPR_PCMR_WPE   0x03ff8000  /* Watchpoint events */
+
+/*
+ * Bit definitions for the Power management register
+ *
+ */
+#define SPR_PMR_SDF    0x0000000f  /* Slow down factor */
+#define SPR_PMR_DME    0x00000010  /* Doze mode enable */
+#define SPR_PMR_SME    0x00000020  /* Sleep mode enable */
+#define SPR_PMR_DCGE   0x00000040  /* Dynamic clock gating enable */
+#define SPR_PMR_SUME   0x00000080  /* Suspend mode enable */
+
+/*
+ * Bit definitions for PICMR
+ *
+ */
+#define SPR_PICMR_IUM  0xfffffffc  /* Interrupt unmask */
+
+/*
+ * Bit definitions for PICPR
+ *
+ */
+#define SPR_PICPR_IPRIO        0xfffffffc  /* Interrupt priority */
+
+/*
+ * Bit definitions for PICSR
+ *
+ */
+#define SPR_PICSR_IS   0xffffffff  /* Interrupt status */
+
+/*
+ * Bit definitions for Tick Timer Control Register
+ *
+ */
+
+#define SPR_TTCR_CNT   0xffffffff  /* Count, time period */
+#define SPR_TTMR_TP    0x0fffffff  /* Time period */
+#define SPR_TTMR_IP    0x10000000  /* Interrupt Pending */
+#define SPR_TTMR_IE    0x20000000  /* Interrupt Enable */
+#define SPR_TTMR_DI    0x00000000  /* Disabled */
+#define SPR_TTMR_RT    0x40000000  /* Restart tick */
+#define SPR_TTMR_SR     0x80000000  /* Single run */
+#define SPR_TTMR_CR     0xc0000000  /* Continuous run */
+#define SPR_TTMR_M      0xc0000000  /* Tick mode */
+
+/*
+ * Bit definitions for the FP Control Status Register
+ *
+ */
+#define SPR_FPCSR_FPEE  0x00000001  /* Floating Point Exception Enable */
+#define SPR_FPCSR_RM    0x00000006  /* Rounding Mode */
+#define SPR_FPCSR_OVF   0x00000008  /* Overflow Flag */
+#define SPR_FPCSR_UNF   0x00000010  /* Underflow Flag */
+#define SPR_FPCSR_SNF   0x00000020  /* SNAN Flag */
+#define SPR_FPCSR_QNF   0x00000040  /* QNAN Flag */
+#define SPR_FPCSR_ZF    0x00000080  /* Zero Flag */
+#define SPR_FPCSR_IXF   0x00000100  /* Inexact Flag */
+#define SPR_FPCSR_IVF   0x00000200  /* Invalid Flag */
+#define SPR_FPCSR_INF   0x00000400  /* Infinity Flag */
+#define SPR_FPCSR_DZF   0x00000800  /* Divide By Zero Flag */
+#define SPR_FPCSR_ALLF (SPR_FPCSR_OVF | SPR_FPCSR_UNF | SPR_FPCSR_SNF | \
+                       SPR_FPCSR_QNF | SPR_FPCSR_ZF | SPR_FPCSR_IXF |  \
+                       SPR_FPCSR_IVF | SPR_FPCSR_INF | SPR_FPCSR_DZF)
+
+#define FPCSR_RM_RN (0<<1)
+#define FPCSR_RM_RZ (1<<1)
+#define FPCSR_RM_RIP (2<<1)
+#define FPCSR_RM_RIN (3<<1)
+
+/*
+ * l.nop constants
+ *
+ */
+#define NOP_NOP          0x0000      /* Normal nop instruction */
+#define NOP_EXIT         0x0001      /* End of simulation */
+#define NOP_REPORT       0x0002      /* Simple report */
+/*#define NOP_PRINTF       0x0003       Simprintf instruction (obsolete)*/
+#define NOP_PUTC         0x0004      /* JPB: Simputc instruction */
+#define NOP_CNT_RESET    0x0005             /* Reset statistics counters */
+#define NOP_GET_TICKS    0x0006             /* JPB: Get # ticks running */
+#define NOP_GET_PS       0x0007      /* JPB: Get picosecs/cycle */
+#define NOP_REPORT_FIRST 0x0400      /* Report with number */
+#define NOP_REPORT_LAST  0x03ff      /* Report with number */
+
+#endif /* SPR_DEFS__H */
diff --git a/arch/openrisc/include/asm/syscall.h b/arch/openrisc/include/asm/syscall.h
new file mode 100644 (file)
index 0000000..9f03370
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_SYSCALL_H__
+#define __ASM_OPENRISC_SYSCALL_H__
+
+#include <linux/err.h>
+#include <linux/sched.h>
+
+static inline int
+syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+       return regs->syscallno ? regs->syscallno : -1;
+}
+
+static inline void
+syscall_rollback(struct task_struct *task, struct pt_regs *regs)
+{
+       regs->gpr[11] = regs->orig_gpr11;
+}
+
+static inline long
+syscall_get_error(struct task_struct *task, struct pt_regs *regs)
+{
+       return IS_ERR_VALUE(regs->gpr[11]) ? regs->gpr[11] : 0;
+}
+
+static inline long
+syscall_get_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+       return regs->gpr[11];
+}
+
+static inline void
+syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
+                        int error, long val)
+{
+       if (error)
+               regs->gpr[11] = -error;
+       else
+               regs->gpr[11] = val;
+}
+
+static inline void
+syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
+                     unsigned int i, unsigned int n, unsigned long *args)
+{
+       BUG_ON(i + n > 6);
+
+       memcpy(args, &regs->gpr[3 + i], n * sizeof(args[0]));
+}
+
+static inline void
+syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
+                     unsigned int i, unsigned int n, const unsigned long *args)
+{
+       BUG_ON(i + n > 6);
+
+       memcpy(&regs->gpr[3 + i], args, n * sizeof(args[0]));
+}
+
+#endif
diff --git a/arch/openrisc/include/asm/syscalls.h b/arch/openrisc/include/asm/syscalls.h
new file mode 100644 (file)
index 0000000..84a978a
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_SYSCALLS_H
+#define __ASM_OPENRISC_SYSCALLS_H
+
+asmlinkage long sys_or1k_atomic(unsigned long type, unsigned long *v1,
+                               unsigned long *v2);
+
+#include <asm-generic/syscalls.h>
+
+#endif /* __ASM_OPENRISC_SYSCALLS_H */
diff --git a/arch/openrisc/include/asm/system.h b/arch/openrisc/include/asm/system.h
new file mode 100644 (file)
index 0000000..cf65888
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_SYSTEM_H
+#define __ASM_OPENRISC_SYSTEM_H
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#include <asm/spr.h>
+#include <asm-generic/system.h>
+
+/* We probably need this definition, but the generic system.h provides it
+ * and it's not used on our arch anyway...
+ */
+/*#define nop() __asm__ __volatile__ ("l.nop"::)*/
+
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* __ASM_OPENRISC_SYSTEM_H */
diff --git a/arch/openrisc/include/asm/thread_info.h b/arch/openrisc/include/asm/thread_info.h
new file mode 100644 (file)
index 0000000..07a8bc0
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+#include <asm/types.h>
+#include <asm/processor.h>
+#endif
+
+
+/* THREAD_SIZE is the size of the task_struct/kernel_stack combo.
+ * normally, the stack is found by doing something like p + THREAD_SIZE
+ * in or32, a page is 8192 bytes, which seems like a sane size
+ */
+
+#define THREAD_SIZE_ORDER 0
+#define THREAD_SIZE       (PAGE_SIZE << THREAD_SIZE_ORDER)
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants
+ *   must also be changed
+ */
+#ifndef __ASSEMBLY__
+
+typedef unsigned long mm_segment_t;
+
+struct thread_info {
+       struct task_struct      *task;          /* main task structure */
+       struct exec_domain      *exec_domain;   /* execution domain */
+       unsigned long           flags;          /* low level flags */
+       __u32                   cpu;            /* current CPU */
+       __s32                   preempt_count; /* 0 => preemptable, <0 => BUG */
+
+       mm_segment_t            addr_limit; /* thread address space:
+                                              0-0x7FFFFFFF for user-thead
+                                              0-0xFFFFFFFF for kernel-thread
+                                            */
+       struct restart_block    restart_block;
+       __u8                    supervisor_stack[0];
+
+       /* saved context data */
+       unsigned long           ksp;
+};
+#endif
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#ifndef __ASSEMBLY__
+#define INIT_THREAD_INFO(tsk)                          \
+{                                                      \
+       .task           = &tsk,                         \
+       .exec_domain    = &default_exec_domain,         \
+       .flags          = 0,                            \
+       .cpu            = 0,                            \
+       .preempt_count  = 1,                            \
+       .addr_limit     = KERNEL_DS,                    \
+       .restart_block  = {                             \
+                         .fn = do_no_restart_syscall,  \
+       },                                              \
+       .ksp            = 0,                            \
+}
+
+#define init_thread_info       (init_thread_union.thread_info)
+
+/* how to get the thread information struct from C */
+register struct thread_info *current_thread_info_reg asm("r10");
+#define current_thread_info()   (current_thread_info_reg)
+
+#define get_thread_info(ti) get_task_struct((ti)->task)
+#define put_thread_info(ti) put_task_struct((ti)->task)
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * thread information flags
+ *   these are process state flags that various assembly files may need to
+ *   access
+ *   - pending work-to-be-done flags are in LSW
+ *   - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE      0       /* syscall trace active */
+#define TIF_NOTIFY_RESUME      1       /* resumption notification requested */
+#define TIF_SIGPENDING         2       /* signal pending */
+#define TIF_NEED_RESCHED       3       /* rescheduling necessary */
+#define TIF_SINGLESTEP         4       /* restore singlestep on return to user
+                                        * mode
+                                        */
+#define TIF_SYSCALL_TRACEPOINT  8       /* for ftrace syscall instrumentation */
+#define TIF_RESTORE_SIGMASK     9
+#define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling                                                * TIF_NEED_RESCHED
+                                        */
+#define TIF_MEMDIE              17
+
+#define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
+#define _TIF_RESTORE_SIGMASK     (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
+
+
+/* Work to do when returning from interrupt/exception */
+/* For OpenRISC, this is anything in the LSW other than syscall trace */
+#define _TIF_WORK_MASK (0xff & ~(_TIF_SYSCALL_TRACE|_TIF_SINGLESTEP))
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/openrisc/include/asm/timex.h b/arch/openrisc/include/asm/timex.h
new file mode 100644 (file)
index 0000000..9935cad
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_TIMEX_H
+#define __ASM_OPENRISC_TIMEX_H
+
+#define get_cycles get_cycles
+
+#include <asm-generic/timex.h>
+#include <asm/spr.h>
+#include <asm/spr_defs.h>
+
+static inline cycles_t get_cycles(void)
+{
+       return mfspr(SPR_TTCR);
+}
+
+/* This isn't really used any more */
+#define CLOCK_TICK_RATE 1000
+
+#define ARCH_HAS_READ_CURRENT_TIMER
+
+#endif
diff --git a/arch/openrisc/include/asm/tlb.h b/arch/openrisc/include/asm/tlb.h
new file mode 100644 (file)
index 0000000..fa4376a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_TLB_H__
+#define __ASM_OPENRISC_TLB_H__
+
+/*
+ * or32 doesn't need any special per-pte or
+ * per-vma handling..
+ */
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
+
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+#include <linux/pagemap.h>
+#include <asm-generic/tlb.h>
+
+#endif /* __ASM_OPENRISC_TLB_H__ */
diff --git a/arch/openrisc/include/asm/tlbflush.h b/arch/openrisc/include/asm/tlbflush.h
new file mode 100644 (file)
index 0000000..6a2accd
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_TLBFLUSH_H
+#define __ASM_OPENRISC_TLBFLUSH_H
+
+#include <linux/mm.h>
+#include <asm/processor.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/current.h>
+#include <linux/sched.h>
+
+/*
+ *  - flush_tlb() flushes the current mm struct TLBs
+ *  - flush_tlb_all() flushes all processes TLBs
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_range(mm, start, end) flushes a range of pages
+ */
+
+void flush_tlb_all(void);
+void flush_tlb_mm(struct mm_struct *mm);
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
+void flush_tlb_range(struct vm_area_struct *vma,
+                    unsigned long start,
+                    unsigned long end);
+
+static inline void flush_tlb(void)
+{
+       flush_tlb_mm(current->mm);
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start,
+                                         unsigned long end)
+{
+       flush_tlb_range(NULL, start, end);
+}
+
+#endif /* __ASM_OPENRISC_TLBFLUSH_H */
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h
new file mode 100644 (file)
index 0000000..c310e45
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_UACCESS_H
+#define __ASM_OPENRISC_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/errno.h>
+#include <linux/thread_info.h>
+#include <linux/prefetch.h>
+#include <linux/string.h>
+#include <linux/thread_info.h>
+#include <asm/page.h>
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not.  If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ */
+
+/* addr_limit is the maximum accessible address for the task. we misuse
+ * the KERNEL_DS and USER_DS values to both assign and compare the
+ * addr_limit values through the equally misnamed get/set_fs macros.
+ * (see above)
+ */
+
+#define KERNEL_DS      (~0UL)
+#define get_ds()       (KERNEL_DS)
+
+#define USER_DS                (TASK_SIZE)
+#define get_fs()       (current_thread_info()->addr_limit)
+#define set_fs(x)      (current_thread_info()->addr_limit = (x))
+
+#define segment_eq(a, b)       ((a) == (b))
+
+/* Ensure that the range from addr to addr+size is all within the process'
+ * address space
+ */
+#define __range_ok(addr, size) (size <= get_fs() && addr <= (get_fs()-size))
+
+/* Ensure that addr is below task's addr_limit */
+#define __addr_ok(addr) ((unsigned long) addr < get_fs())
+
+#define access_ok(type, addr, size) \
+       __range_ok((unsigned long)addr, (unsigned long)size)
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry {
+       unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+extern void sort_exception_table(void);
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the uglyness from the user.
+ *
+ * The "__xxx" versions of the user access functions are versions that
+ * do not verify the address space, that must have been done previously
+ * with a separate "access_ok()" call (this is used when we do multiple
+ * accesses to the same area of user memory).
+ *
+ * As we use the same address space for kernel and user data on the
+ * PowerPC, we can just do these as direct assignments.  (Of course, the
+ * exception handling means that it's no longer "just"...)
+ */
+#define get_user(x, ptr) \
+       __get_user_check((x), (ptr), sizeof(*(ptr)))
+#define put_user(x, ptr) \
+       __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
+
+#define __get_user(x, ptr) \
+       __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+#define __put_user(x, ptr) \
+       __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
+
+extern long __put_user_bad(void);
+
+#define __put_user_nocheck(x, ptr, size)               \
+({                                                     \
+       long __pu_err;                                  \
+       __put_user_size((x), (ptr), (size), __pu_err);  \
+       __pu_err;                                       \
+})
+
+#define __put_user_check(x, ptr, size)                                 \
+({                                                                     \
+       long __pu_err = -EFAULT;                                        \
+       __typeof__(*(ptr)) *__pu_addr = (ptr);                          \
+       if (access_ok(VERIFY_WRITE, __pu_addr, size))                   \
+               __put_user_size((x), __pu_addr, (size), __pu_err);      \
+       __pu_err;                                                       \
+})
+
+#define __put_user_size(x, ptr, size, retval)                          \
+do {                                                                   \
+       retval = 0;                                                     \
+       switch (size) {                                                 \
+       case 1: __put_user_asm(x, ptr, retval, "l.sb"); break;          \
+       case 2: __put_user_asm(x, ptr, retval, "l.sh"); break;          \
+       case 4: __put_user_asm(x, ptr, retval, "l.sw"); break;          \
+       case 8: __put_user_asm2(x, ptr, retval); break;                 \
+       default: __put_user_bad();                                      \
+       }                                                               \
+} while (0)
+
+struct __large_struct {
+       unsigned long buf[100];
+};
+#define __m(x) (*(struct __large_struct *)(x))
+
+/*
+ * We don't tell gcc that we are accessing memory, but this is OK
+ * because we do not write to any memory gcc knows about, so there
+ * are no aliasing issues.
+ */
+#define __put_user_asm(x, addr, err, op)                       \
+       __asm__ __volatile__(                                   \
+               "1:     "op" 0(%2),%1\n"                        \
+               "2:\n"                                          \
+               ".section .fixup,\"ax\"\n"                      \
+               "3:     l.addi %0,r0,%3\n"                      \
+               "       l.j 2b\n"                               \
+               "       l.nop\n"                                \
+               ".previous\n"                                   \
+               ".section __ex_table,\"a\"\n"                   \
+               "       .align 2\n"                             \
+               "       .long 1b,3b\n"                          \
+               ".previous"                                     \
+               : "=r"(err)                                     \
+               : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err))
+
+#define __put_user_asm2(x, addr, err)                          \
+       __asm__ __volatile__(                                   \
+               "1:     l.sw 0(%2),%1\n"                        \
+               "2:     l.sw 4(%2),%H1\n"                       \
+               "3:\n"                                          \
+               ".section .fixup,\"ax\"\n"                      \
+               "4:     l.addi %0,r0,%3\n"                      \
+               "       l.j 3b\n"                               \
+               "       l.nop\n"                                \
+               ".previous\n"                                   \
+               ".section __ex_table,\"a\"\n"                   \
+               "       .align 2\n"                             \
+               "       .long 1b,4b\n"                          \
+               "       .long 2b,4b\n"                          \
+               ".previous"                                     \
+               : "=r"(err)                                     \
+               : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err))
+
+#define __get_user_nocheck(x, ptr, size)                       \
+({                                                             \
+       long __gu_err, __gu_val;                                \
+       __get_user_size(__gu_val, (ptr), (size), __gu_err);     \
+       (x) = (__typeof__(*(ptr)))__gu_val;                     \
+       __gu_err;                                               \
+})
+
+#define __get_user_check(x, ptr, size)                                 \
+({                                                                     \
+       long __gu_err = -EFAULT, __gu_val = 0;                          \
+       const __typeof__(*(ptr)) * __gu_addr = (ptr);                   \
+       if (access_ok(VERIFY_READ, __gu_addr, size))                    \
+               __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
+       (x) = (__typeof__(*(ptr)))__gu_val;                             \
+       __gu_err;                                                       \
+})
+
+extern long __get_user_bad(void);
+
+#define __get_user_size(x, ptr, size, retval)                          \
+do {                                                                   \
+       retval = 0;                                                     \
+       switch (size) {                                                 \
+       case 1: __get_user_asm(x, ptr, retval, "l.lbz"); break;         \
+       case 2: __get_user_asm(x, ptr, retval, "l.lhz"); break;         \
+       case 4: __get_user_asm(x, ptr, retval, "l.lwz"); break;         \
+       case 8: __get_user_asm2(x, ptr, retval);                        \
+       default: (x) = __get_user_bad();                                \
+       }                                                               \
+} while (0)
+
+#define __get_user_asm(x, addr, err, op)               \
+       __asm__ __volatile__(                           \
+               "1:     "op" %1,0(%2)\n"                \
+               "2:\n"                                  \
+               ".section .fixup,\"ax\"\n"              \
+               "3:     l.addi %0,r0,%3\n"              \
+               "       l.addi %1,r0,0\n"               \
+               "       l.j 2b\n"                       \
+               "       l.nop\n"                        \
+               ".previous\n"                           \
+               ".section __ex_table,\"a\"\n"           \
+               "       .align 2\n"                     \
+               "       .long 1b,3b\n"                  \
+               ".previous"                             \
+               : "=r"(err), "=r"(x)                    \
+               : "r"(addr), "i"(-EFAULT), "0"(err))
+
+#define __get_user_asm2(x, addr, err)                  \
+       __asm__ __volatile__(                           \
+               "1:     l.lwz %1,0(%2)\n"               \
+               "2:     l.lwz %H1,4(%2)\n"              \
+               "3:\n"                                  \
+               ".section .fixup,\"ax\"\n"              \
+               "4:     l.addi %0,r0,%3\n"              \
+               "       l.addi %1,r0,0\n"               \
+               "       l.addi %H1,r0,0\n"              \
+               "       l.j 3b\n"                       \
+               "       l.nop\n"                        \
+               ".previous\n"                           \
+               ".section __ex_table,\"a\"\n"           \
+               "       .align 2\n"                     \
+               "       .long 1b,4b\n"                  \
+               "       .long 2b,4b\n"                  \
+               ".previous"                             \
+               : "=r"(err), "=&r"(x)                   \
+               : "r"(addr), "i"(-EFAULT), "0"(err))
+
+/* more complex routines */
+
+extern unsigned long __must_check
+__copy_tofrom_user(void *to, const void *from, unsigned long size);
+
+#define __copy_from_user(to, from, size) \
+       __copy_tofrom_user(to, from, size)
+#define __copy_to_user(to, from, size) \
+       __copy_tofrom_user(to, from, size)
+
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
+static inline unsigned long
+copy_from_user(void *to, const void *from, unsigned long n)
+{
+       unsigned long over;
+
+       if (access_ok(VERIFY_READ, from, n))
+               return __copy_tofrom_user(to, from, n);
+       if ((unsigned long)from < TASK_SIZE) {
+               over = (unsigned long)from + n - TASK_SIZE;
+               return __copy_tofrom_user(to, from, n - over) + over;
+       }
+       return n;
+}
+
+static inline unsigned long
+copy_to_user(void *to, const void *from, unsigned long n)
+{
+       unsigned long over;
+
+       if (access_ok(VERIFY_WRITE, to, n))
+               return __copy_tofrom_user(to, from, n);
+       if ((unsigned long)to < TASK_SIZE) {
+               over = (unsigned long)to + n - TASK_SIZE;
+               return __copy_tofrom_user(to, from, n - over) + over;
+       }
+       return n;
+}
+
+extern unsigned long __clear_user(void *addr, unsigned long size);
+
+static inline __must_check unsigned long
+clear_user(void *addr, unsigned long size)
+{
+
+       if (access_ok(VERIFY_WRITE, addr, size))
+               return __clear_user(addr, size);
+       if ((unsigned long)addr < TASK_SIZE) {
+               unsigned long over = (unsigned long)addr + size - TASK_SIZE;
+               return __clear_user(addr, size - over) + over;
+       }
+       return size;
+}
+
+extern int __strncpy_from_user(char *dst, const char *src, long count);
+
+static inline long strncpy_from_user(char *dst, const char *src, long count)
+{
+       if (access_ok(VERIFY_READ, src, 1))
+               return __strncpy_from_user(dst, src, count);
+       return -EFAULT;
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+
+extern int __strnlen_user(const char *str, long len, unsigned long top);
+
+/*
+ * Returns the length of the string at str (including the null byte),
+ * or 0 if we hit a page we can't access,
+ * or something > len if we didn't find a null byte.
+ *
+ * The `top' parameter to __strnlen_user is to make sure that
+ * we can never overflow from the user area into kernel space.
+ */
+static inline long strnlen_user(const char __user *str, long len)
+{
+       unsigned long top = (unsigned long)get_fs();
+       unsigned long res = 0;
+
+       if (__addr_ok(str))
+               res = __strnlen_user(str, len, top);
+
+       return res;
+}
+
+#define strlen_user(str) strnlen_user(str, TASK_SIZE-1)
+
+#endif /* __ASM_OPENRISC_UACCESS_H */
diff --git a/arch/openrisc/include/asm/unaligned.h b/arch/openrisc/include/asm/unaligned.h
new file mode 100644 (file)
index 0000000..1141cbd
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_OPENRISC_UNALIGNED_H
+#define __ASM_OPENRISC_UNALIGNED_H
+
+/*
+ * This is copied from the generic implementation and the C-struct
+ * variant replaced with the memmove variant.  The GCC compiler
+ * for the OR32 arch optimizes too aggressively for the C-struct
+ * variant to work, so use the memmove variant instead.
+ *
+ * It may be worth considering implementing the unaligned access
+ * exception handler and allowing unaligned accesses (access_ok.h)...
+ * not sure if it would be much of a performance win without further
+ * investigation.
+ */
+#include <asm/byteorder.h>
+
+#if defined(__LITTLE_ENDIAN)
+# include <linux/unaligned/le_memmove.h>
+# include <linux/unaligned/be_byteshift.h>
+# include <linux/unaligned/generic.h>
+# define get_unaligned __get_unaligned_le
+# define put_unaligned __put_unaligned_le
+#elif defined(__BIG_ENDIAN)
+# include <linux/unaligned/be_memmove.h>
+# include <linux/unaligned/le_byteshift.h>
+# include <linux/unaligned/generic.h>
+# define get_unaligned __get_unaligned_be
+# define put_unaligned __put_unaligned_be
+#else
+# error need to define endianess
+#endif
+
+#endif /* __ASM_OPENRISC_UNALIGNED_H */
diff --git a/arch/openrisc/include/asm/unistd.h b/arch/openrisc/include/asm/unistd.h
new file mode 100644 (file)
index 0000000..89af3ab
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * 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.
+ */
+
+#if !defined(__ASM_OPENRISC_UNISTD_H) || defined(__SYSCALL)
+#define __ASM_OPENRISC_UNISTD_H
+
+#define __ARCH_HAVE_MMU
+
+#define sys_mmap2 sys_mmap_pgoff
+
+#include <asm-generic/unistd.h>
+
+#define __NR_or1k_atomic __NR_arch_specific_syscall
+__SYSCALL(__NR_or1k_atomic, sys_or1k_atomic)
+
+#endif /* __ASM_OPENRISC_UNISTD_H */
diff --git a/arch/openrisc/kernel/Makefile b/arch/openrisc/kernel/Makefile
new file mode 100644 (file)
index 0000000..9a4c270
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+
+extra-y        := head.o vmlinux.lds init_task.o
+
+obj-y  := setup.o idle.o or32_ksyms.o process.o dma.o \
+          traps.o time.o irq.o entry.o ptrace.o signal.o sys_or32.o \
+          sys_call_table.o
+
+obj-$(CONFIG_MODULES)          += module.o
+obj-$(CONFIG_OF)               += prom.o
+
+clean:
diff --git a/arch/openrisc/kernel/asm-offsets.c b/arch/openrisc/kernel/asm-offsets.c
new file mode 100644 (file)
index 0000000..1a242a0
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * OpenRISC asm-offsets.c
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * Modifications for the OpenRISC architecture:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ *
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/thread_info.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+
+#define DEFINE(sym, val) \
+               asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+       /* offsets into the task_struct */
+       DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+       DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+       DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+       DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+       DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+       DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+
+       /* offsets into thread_info */
+       DEFINE(TI_TASK, offsetof(struct thread_info, task));
+       DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+       DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
+       DEFINE(TI_KSP, offsetof(struct thread_info, ksp));
+
+       DEFINE(PT_SIZE, sizeof(struct pt_regs));
+
+       /* Interrupt register frame */
+       DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
+       DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
+
+       DEFINE(NUM_USER_SEGMENTS, TASK_SIZE >> 28);
+       return 0;
+}
diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
new file mode 100644 (file)
index 0000000..968d3ee
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * Modifications for the OpenRISC architecture:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ *      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.
+ *
+ * DMA mapping callbacks...
+ * As alloc_coherent is the only DMA callback being used currently, that's
+ * the only thing implemented properly.  The rest need looking into...
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/dma-debug.h>
+
+#include <asm/cpuinfo.h>
+#include <asm/spr_defs.h>
+#include <asm/tlbflush.h>
+
+static int page_set_nocache(pte_t *pte, unsigned long addr,
+                           unsigned long next, struct mm_walk *walk)
+{
+       unsigned long cl;
+
+       pte_val(*pte) |= _PAGE_CI;
+
+       /*
+        * Flush the page out of the TLB so that the new page flags get
+        * picked up next time there's an access
+        */
+       flush_tlb_page(NULL, addr);
+
+       /* Flush page out of dcache */
+       for (cl = __pa(addr); cl < __pa(next); cl += cpuinfo.dcache_block_size)
+               mtspr(SPR_DCBFR, cl);
+
+       return 0;
+}
+
+static int page_clear_nocache(pte_t *pte, unsigned long addr,
+                             unsigned long next, struct mm_walk *walk)
+{
+       pte_val(*pte) &= ~_PAGE_CI;
+
+       /*
+        * Flush the page out of the TLB so that the new page flags get
+        * picked up next time there's an access
+        */
+       flush_tlb_page(NULL, addr);
+
+       return 0;
+}
+
+/*
+ * Alloc "coherent" memory, which for OpenRISC means simply uncached.
+ *
+ * This function effectively just calls __get_free_pages, sets the
+ * cache-inhibit bit on those pages, and makes sure that the pages are
+ * flushed out of the cache before they are used.
+ *
+ */
+void *or1k_dma_alloc_coherent(struct device *dev, size_t size,
+                             dma_addr_t *dma_handle, gfp_t gfp)
+{
+       unsigned long va;
+       void *page;
+       struct mm_walk walk = {
+               .pte_entry = page_set_nocache,
+               .mm = &init_mm
+       };
+
+       page = alloc_pages_exact(size, gfp);
+       if (!page)
+               return NULL;
+
+       /* This gives us the real physical address of the first page. */
+       *dma_handle = __pa(page);
+
+       va = (unsigned long)page;
+
+       /*
+        * We need to iterate through the pages, clearing the dcache for
+        * them and setting the cache-inhibit bit.
+        */
+       if (walk_page_range(va, va + size, &walk)) {
+               free_pages_exact(page, size);
+               return NULL;
+       }
+
+       return (void *)va;
+}
+
+void or1k_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+                           dma_addr_t dma_handle)
+{
+       unsigned long va = (unsigned long)vaddr;
+       struct mm_walk walk = {
+               .pte_entry = page_clear_nocache,
+               .mm = &init_mm
+       };
+
+       /* walk_page_range shouldn't be able to fail here */
+       WARN_ON(walk_page_range(va, va + size, &walk));
+
+       free_pages_exact(vaddr, size);
+}
+
+dma_addr_t or1k_map_page(struct device *dev, struct page *page,
+                        unsigned long offset, size_t size,
+                        enum dma_data_direction dir,
+                        struct dma_attrs *attrs)
+{
+       unsigned long cl;
+       dma_addr_t addr = page_to_phys(page) + offset;
+
+       switch (dir) {
+       case DMA_TO_DEVICE:
+               /* Flush the dcache for the requested range */
+               for (cl = addr; cl < addr + size;
+                    cl += cpuinfo.dcache_block_size)
+                       mtspr(SPR_DCBFR, cl);
+               break;
+       case DMA_FROM_DEVICE:
+               /* Invalidate the dcache for the requested range */
+               for (cl = addr; cl < addr + size;
+                    cl += cpuinfo.dcache_block_size)
+                       mtspr(SPR_DCBIR, cl);
+               break;
+       default:
+               /*
+                * NOTE: If dir == DMA_BIDIRECTIONAL then there's no need to
+                * flush nor invalidate the cache here as the area will need
+                * to be manually synced anyway.
+                */
+               break;
+       }
+
+       return addr;
+}
+
+void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
+                    size_t size, enum dma_data_direction dir,
+                    struct dma_attrs *attrs)
+{
+       /* Nothing special to do here... */
+}
+
+void or1k_sync_single_for_cpu(struct device *dev,
+                             dma_addr_t dma_handle, size_t size,
+                             enum dma_data_direction dir)
+{
+       unsigned long cl;
+       dma_addr_t addr = dma_handle;
+
+       /* Invalidate the dcache for the requested range */
+       for (cl = addr; cl < addr + size; cl += cpuinfo.dcache_block_size)
+               mtspr(SPR_DCBIR, cl);
+}
+
+void or1k_sync_single_for_device(struct device *dev,
+                                dma_addr_t dma_handle, size_t size,
+                                enum dma_data_direction dir)
+{
+       unsigned long cl;
+       dma_addr_t addr = dma_handle;
+
+       /* Flush the dcache for the requested range */
+       for (cl = addr; cl < addr + size; cl += cpuinfo.dcache_block_size)
+               mtspr(SPR_DCBFR, cl);
+}
+
+/* Number of entries preallocated for DMA-API debugging */
+#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
+
+static int __init dma_init(void)
+{
+       dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+
+       return 0;
+}
+
+fs_initcall(dma_init);
diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S
new file mode 100644 (file)
index 0000000..d5f9c35
--- /dev/null
@@ -0,0 +1,1128 @@
+/*
+ * OpenRISC entry.S
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * Modifications for the OpenRISC architecture:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2005 Gyorgy Jeney <nog@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ *      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 <linux/linkage.h>
+
+#include <asm/processor.h>
+#include <asm/unistd.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/spr_defs.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/asm-offsets.h>
+
+#define DISABLE_INTERRUPTS(t1,t2)                      \
+       l.mfspr t2,r0,SPR_SR                            ;\
+       l.movhi t1,hi(~(SPR_SR_IEE|SPR_SR_TEE))         ;\
+       l.ori   t1,t1,lo(~(SPR_SR_IEE|SPR_SR_TEE))      ;\
+       l.and   t2,t2,t1                                ;\
+       l.mtspr r0,t2,SPR_SR
+
+#define ENABLE_INTERRUPTS(t1)                          \
+       l.mfspr t1,r0,SPR_SR                            ;\
+       l.ori   t1,t1,lo(SPR_SR_IEE|SPR_SR_TEE)         ;\
+       l.mtspr r0,t1,SPR_SR
+
+/* =========================================================[ macros ]=== */
+
+/*
+ * We need to disable interrupts at beginning of RESTORE_ALL
+ * since interrupt might come in after we've loaded EPC return address
+ * and overwrite EPC with address somewhere in RESTORE_ALL
+ * which is of course wrong!
+ */
+
+#define RESTORE_ALL                                            \
+       DISABLE_INTERRUPTS(r3,r4)                               ;\
+       l.lwz   r3,PT_PC(r1)                                    ;\
+       l.mtspr r0,r3,SPR_EPCR_BASE                             ;\
+       l.lwz   r3,PT_SR(r1)                                    ;\
+       l.mtspr r0,r3,SPR_ESR_BASE                              ;\
+       l.lwz   r2,PT_GPR2(r1)                                  ;\
+       l.lwz   r3,PT_GPR3(r1)                                  ;\
+       l.lwz   r4,PT_GPR4(r1)                                  ;\
+       l.lwz   r5,PT_GPR5(r1)                                  ;\
+       l.lwz   r6,PT_GPR6(r1)                                  ;\
+       l.lwz   r7,PT_GPR7(r1)                                  ;\
+       l.lwz   r8,PT_GPR8(r1)                                  ;\
+       l.lwz   r9,PT_GPR9(r1)                                  ;\
+       l.lwz   r10,PT_GPR10(r1)                                        ;\
+       l.lwz   r11,PT_GPR11(r1)                                        ;\
+       l.lwz   r12,PT_GPR12(r1)                                        ;\
+       l.lwz   r13,PT_GPR13(r1)                                        ;\
+       l.lwz   r14,PT_GPR14(r1)                                        ;\
+       l.lwz   r15,PT_GPR15(r1)                                        ;\
+       l.lwz   r16,PT_GPR16(r1)                                        ;\
+       l.lwz   r17,PT_GPR17(r1)                                        ;\
+       l.lwz   r18,PT_GPR18(r1)                                        ;\
+       l.lwz   r19,PT_GPR19(r1)                                        ;\
+       l.lwz   r20,PT_GPR20(r1)                                        ;\
+       l.lwz   r21,PT_GPR21(r1)                                        ;\
+       l.lwz   r22,PT_GPR22(r1)                                        ;\
+       l.lwz   r23,PT_GPR23(r1)                                        ;\
+       l.lwz   r24,PT_GPR24(r1)                                        ;\
+       l.lwz   r25,PT_GPR25(r1)                                        ;\
+       l.lwz   r26,PT_GPR26(r1)                                        ;\
+       l.lwz   r27,PT_GPR27(r1)                                        ;\
+       l.lwz   r28,PT_GPR28(r1)                                        ;\
+       l.lwz   r29,PT_GPR29(r1)                                        ;\
+       l.lwz   r30,PT_GPR30(r1)                                        ;\
+       l.lwz   r31,PT_GPR31(r1)                                        ;\
+       l.lwz   r1,PT_SP(r1)                                    ;\
+       l.rfe
+
+
+#define EXCEPTION_ENTRY(handler)                               \
+       .global handler                                         ;\
+handler:                                                       ;\
+       /* r1, EPCR, ESR a already saved */                     ;\
+       l.sw    PT_GPR2(r1),r2                                  ;\
+       l.sw    PT_GPR3(r1),r3                                  ;\
+       l.sw    PT_ORIG_GPR11(r1),r11                           ;\
+       /* r4 already save */                                   ;\
+       l.sw    PT_GPR5(r1),r5                                  ;\
+       l.sw    PT_GPR6(r1),r6                                  ;\
+       l.sw    PT_GPR7(r1),r7                                  ;\
+       l.sw    PT_GPR8(r1),r8                                  ;\
+       l.sw    PT_GPR9(r1),r9                                  ;\
+       /* r10 already saved */                                 ;\
+       l.sw    PT_GPR11(r1),r11                                        ;\
+       /* r12 already saved */                                 ;\
+       l.sw    PT_GPR13(r1),r13                                        ;\
+       l.sw    PT_GPR14(r1),r14                                        ;\
+       l.sw    PT_GPR15(r1),r15                                        ;\
+       l.sw    PT_GPR16(r1),r16                                        ;\
+       l.sw    PT_GPR17(r1),r17                                        ;\
+       l.sw    PT_GPR18(r1),r18                                        ;\
+       l.sw    PT_GPR19(r1),r19                                        ;\
+       l.sw    PT_GPR20(r1),r20                                        ;\
+       l.sw    PT_GPR21(r1),r21                                        ;\
+       l.sw    PT_GPR22(r1),r22                                        ;\
+       l.sw    PT_GPR23(r1),r23                                        ;\
+       l.sw    PT_GPR24(r1),r24                                        ;\
+       l.sw    PT_GPR25(r1),r25                                        ;\
+       l.sw    PT_GPR26(r1),r26                                        ;\
+       l.sw    PT_GPR27(r1),r27                                        ;\
+       l.sw    PT_GPR28(r1),r28                                        ;\
+       l.sw    PT_GPR29(r1),r29                                        ;\
+       /* r30 already save */                                  ;\
+/*        l.sw    PT_GPR30(r1),r30*/                                   ;\
+       l.sw    PT_GPR31(r1),r31                                        ;\
+       l.sw    PT_SYSCALLNO(r1),r0
+
+#define UNHANDLED_EXCEPTION(handler,vector)                    \
+       .global handler                                         ;\
+handler:                                                       ;\
+       /* r1, EPCR, ESR already saved */                       ;\
+       l.sw    PT_GPR2(r1),r2                                  ;\
+       l.sw    PT_GPR3(r1),r3                                  ;\
+       l.sw    PT_ORIG_GPR11(r1),r11                           ;\
+       l.sw    PT_GPR5(r1),r5                                  ;\
+       l.sw    PT_GPR6(r1),r6                                  ;\
+       l.sw    PT_GPR7(r1),r7                                  ;\
+       l.sw    PT_GPR8(r1),r8                                  ;\
+       l.sw    PT_GPR9(r1),r9                                  ;\
+       /* r10 already saved */                                 ;\
+       l.sw    PT_GPR11(r1),r11                                        ;\
+       /* r12 already saved */                                 ;\
+       l.sw    PT_GPR13(r1),r13                                        ;\
+       l.sw    PT_GPR14(r1),r14                                        ;\
+       l.sw    PT_GPR15(r1),r15                                        ;\
+       l.sw    PT_GPR16(r1),r16                                        ;\
+       l.sw    PT_GPR17(r1),r17                                        ;\
+       l.sw    PT_GPR18(r1),r18                                        ;\
+       l.sw    PT_GPR19(r1),r19                                        ;\
+       l.sw    PT_GPR20(r1),r20                                        ;\
+       l.sw    PT_GPR21(r1),r21                                        ;\
+       l.sw    PT_GPR22(r1),r22                                        ;\
+       l.sw    PT_GPR23(r1),r23                                        ;\
+       l.sw    PT_GPR24(r1),r24                                        ;\
+       l.sw    PT_GPR25(r1),r25                                        ;\
+       l.sw    PT_GPR26(r1),r26                                        ;\
+       l.sw    PT_GPR27(r1),r27                                        ;\
+       l.sw    PT_GPR28(r1),r28                                        ;\
+       l.sw    PT_GPR29(r1),r29                                        ;\
+       /* r31 already saved */                                 ;\
+       l.sw    PT_GPR30(r1),r30                                        ;\
+/*        l.sw    PT_GPR31(r1),r31     */                              ;\
+       l.sw    PT_SYSCALLNO(r1),r0                             ;\
+       l.addi  r3,r1,0                                         ;\
+       /* r4 is exception EA */                                ;\
+       l.addi  r5,r0,vector                                    ;\
+       l.jal   unhandled_exception                             ;\
+        l.nop                                                  ;\
+       l.j     _ret_from_exception                             ;\
+        l.nop
+
+/*
+ * NOTE: one should never assume that SPR_EPC, SPR_ESR, SPR_EEAR
+ *       contain the same values as when exception we're handling
+ *      occured. in fact they never do. if you need them use
+ *      values saved on stack (for SPR_EPC, SPR_ESR) or content
+ *       of r4 (for SPR_EEAR). for details look at EXCEPTION_HANDLE()
+ *       in 'arch/or32/kernel/head.S'
+ */
+
+/* =====================================================[ exceptions] === */
+
+/* ---[ 0x100: RESET exception ]----------------------------------------- */
+
+EXCEPTION_ENTRY(_tng_kernel_start)
+       l.jal   _start
+        l.andi r0,r0,0
+
+/* ---[ 0x200: BUS exception ]------------------------------------------- */
+
+EXCEPTION_ENTRY(_bus_fault_handler)
+       /* r4: EA of fault (set by EXCEPTION_HANDLE) */
+       l.jal   do_bus_fault
+        l.addi  r3,r1,0 /* pt_regs */
+
+       l.j     _ret_from_exception
+        l.nop
+
+/* ---[ 0x300: Data Page Fault exception ]------------------------------- */
+
+EXCEPTION_ENTRY(_data_page_fault_handler)
+       /* set up parameters for do_page_fault */
+       l.addi  r3,r1,0                    // pt_regs
+       /* r4 set be EXCEPTION_HANDLE */   // effective address of fault
+       l.ori   r5,r0,0x300                // exception vector
+
+       /*
+        * __PHX__: TODO
+        *
+        * all this can be written much simpler. look at
+        * DTLB miss handler in the CONFIG_GUARD_PROTECTED_CORE part
+        */
+#ifdef CONFIG_OPENRISC_NO_SPR_SR_DSX
+       l.lwz   r6,PT_PC(r3)                  // address of an offending insn
+       l.lwz   r6,0(r6)                   // instruction that caused pf
+
+       l.srli  r6,r6,26                   // check opcode for jump insn
+       l.sfeqi r6,0                       // l.j
+       l.bf    8f
+       l.sfeqi r6,1                       // l.jal
+       l.bf    8f
+       l.sfeqi r6,3                       // l.bnf
+       l.bf    8f
+       l.sfeqi r6,4                       // l.bf
+       l.bf    8f
+       l.sfeqi r6,0x11                    // l.jr
+       l.bf    8f
+       l.sfeqi r6,0x12                    // l.jalr
+       l.bf    8f
+
+       l.nop
+
+       l.j     9f
+       l.nop
+8:
+
+       l.lwz   r6,PT_PC(r3)                  // address of an offending insn
+       l.addi  r6,r6,4
+       l.lwz   r6,0(r6)                   // instruction that caused pf
+       l.srli  r6,r6,26                   // get opcode
+9:
+
+#else
+
+       l.mfspr r6,r0,SPR_SR               // SR
+//     l.lwz   r6,PT_SR(r3)               // ESR
+       l.andi  r6,r6,SPR_SR_DSX           // check for delay slot exception
+       l.sfeqi r6,0x1                     // exception happened in delay slot
+       l.bnf   7f
+       l.lwz   r6,PT_PC(r3)               // address of an offending insn
+
+       l.addi  r6,r6,4                    // offending insn is in delay slot
+7:
+       l.lwz   r6,0(r6)                   // instruction that caused pf
+       l.srli  r6,r6,26                   // check opcode for write access
+#endif
+
+       l.sfgeui r6,0x34                   // check opcode for write access
+       l.bnf   1f
+       l.sfleui r6,0x37
+       l.bnf   1f
+       l.ori   r6,r0,0x1                  // write access
+       l.j     2f
+       l.nop
+1:     l.ori   r6,r0,0x0                  // !write access
+2:
+
+       /* call fault.c handler in or32/mm/fault.c */
+       l.jal   do_page_fault
+       l.nop
+       l.j     _ret_from_exception
+       l.nop
+
+/* ---[ 0x400: Insn Page Fault exception ]------------------------------- */
+
+EXCEPTION_ENTRY(_insn_page_fault_handler)
+       /* set up parameters for do_page_fault */
+       l.addi  r3,r1,0                    // pt_regs
+       /* r4 set be EXCEPTION_HANDLE */   // effective address of fault
+       l.ori   r5,r0,0x400                // exception vector
+       l.ori   r6,r0,0x0                  // !write access
+
+       /* call fault.c handler in or32/mm/fault.c */
+       l.jal   do_page_fault
+       l.nop
+       l.j     _ret_from_exception
+       l.nop
+
+
+/* ---[ 0x500: Timer exception ]----------------------------------------- */
+
+EXCEPTION_ENTRY(_timer_handler)
+       l.jal   timer_interrupt
+        l.addi r3,r1,0 /* pt_regs */
+
+       l.j    _ret_from_intr
+        l.nop
+
+/* ---[ 0x600: Aligment exception ]-------------------------------------- */
+
+EXCEPTION_ENTRY(_alignment_handler)
+       /* r4: EA of fault (set by EXCEPTION_HANDLE) */
+       l.jal   do_unaligned_access
+        l.addi  r3,r1,0 /* pt_regs */
+
+       l.j     _ret_from_exception
+        l.nop
+
+#if 0
+EXCEPTION_ENTRY(_aligment_handler)
+//        l.mfspr r2,r0,SPR_EEAR_BASE     /* Load the efective addres */
+       l.addi  r2,r4,0
+//        l.mfspr r5,r0,SPR_EPCR_BASE     /* Load the insn address */
+       l.lwz   r5,PT_PC(r1)
+
+       l.lwz   r3,0(r5)                /* Load insn */
+       l.srli  r4,r3,26                /* Shift left to get the insn opcode */
+
+       l.sfeqi r4,0x00                 /* Check if the load/store insn is in delay slot */
+       l.bf    jmp
+       l.sfeqi r4,0x01
+       l.bf    jmp
+       l.sfeqi r4,0x03
+       l.bf    jmp
+       l.sfeqi r4,0x04
+       l.bf    jmp
+       l.sfeqi r4,0x11
+       l.bf    jr
+       l.sfeqi r4,0x12
+       l.bf    jr
+       l.nop
+       l.j     1f
+       l.addi  r5,r5,4                 /* Increment PC to get return insn address */
+
+jmp:
+       l.slli  r4,r3,6                 /* Get the signed extended jump length */
+       l.srai  r4,r4,4
+
+       l.lwz   r3,4(r5)                /* Load the real load/store insn */
+
+       l.add   r5,r5,r4                /* Calculate jump target address */
+
+       l.j     1f
+       l.srli  r4,r3,26                /* Shift left to get the insn opcode */
+
+jr:
+       l.slli  r4,r3,9                 /* Shift to get the reg nb */
+       l.andi  r4,r4,0x7c
+
+       l.lwz   r3,4(r5)                /* Load the real load/store insn */
+
+       l.add   r4,r4,r1                /* Load the jump register value from the stack */
+       l.lwz   r5,0(r4)
+
+       l.srli  r4,r3,26                /* Shift left to get the insn opcode */
+
+
+1:
+//       l.mtspr r0,r5,SPR_EPCR_BASE
+       l.sw    PT_PC(r1),r5
+
+       l.sfeqi r4,0x26
+       l.bf    lhs
+       l.sfeqi r4,0x25
+       l.bf    lhz
+       l.sfeqi r4,0x22
+       l.bf    lws
+       l.sfeqi r4,0x21
+       l.bf    lwz
+       l.sfeqi r4,0x37
+       l.bf    sh
+       l.sfeqi r4,0x35
+       l.bf    sw
+       l.nop
+
+1:      l.j     1b                      /* I don't know what to do */
+       l.nop
+
+lhs:    l.lbs   r5,0(r2)
+       l.slli  r5,r5,8
+       l.lbz   r6,1(r2)
+       l.or    r5,r5,r6
+       l.srli  r4,r3,19
+       l.andi  r4,r4,0x7c
+       l.add   r4,r4,r1
+       l.j     align_end
+       l.sw    0(r4),r5
+
+lhz:    l.lbz   r5,0(r2)
+       l.slli  r5,r5,8
+       l.lbz   r6,1(r2)
+       l.or    r5,r5,r6
+       l.srli  r4,r3,19
+       l.andi  r4,r4,0x7c
+       l.add   r4,r4,r1
+       l.j     align_end
+       l.sw    0(r4),r5
+
+lws:    l.lbs   r5,0(r2)
+       l.slli  r5,r5,24
+       l.lbz   r6,1(r2)
+       l.slli  r6,r6,16
+       l.or    r5,r5,r6
+       l.lbz   r6,2(r2)
+       l.slli  r6,r6,8
+       l.or    r5,r5,r6
+       l.lbz   r6,3(r2)
+       l.or    r5,r5,r6
+       l.srli  r4,r3,19
+       l.andi  r4,r4,0x7c
+       l.add   r4,r4,r1
+       l.j     align_end
+       l.sw    0(r4),r5
+
+lwz:    l.lbz   r5,0(r2)
+       l.slli  r5,r5,24
+       l.lbz   r6,1(r2)
+       l.slli  r6,r6,16
+       l.or    r5,r5,r6
+       l.lbz   r6,2(r2)
+       l.slli  r6,r6,8
+       l.or    r5,r5,r6
+       l.lbz   r6,3(r2)
+       l.or    r5,r5,r6
+       l.srli  r4,r3,19
+       l.andi  r4,r4,0x7c
+       l.add   r4,r4,r1
+       l.j     align_end
+       l.sw    0(r4),r5
+
+sh:
+       l.srli  r4,r3,9
+       l.andi  r4,r4,0x7c
+       l.add   r4,r4,r1
+       l.lwz   r5,0(r4)
+       l.sb    1(r2),r5
+       l.srli  r5,r5,8
+       l.j     align_end
+       l.sb    0(r2),r5
+
+sw:
+       l.srli  r4,r3,9
+       l.andi  r4,r4,0x7c
+       l.add   r4,r4,r1
+       l.lwz   r5,0(r4)
+       l.sb    3(r2),r5
+       l.srli  r5,r5,8
+       l.sb    2(r2),r5
+       l.srli  r5,r5,8
+       l.sb    1(r2),r5
+       l.srli  r5,r5,8
+       l.j     align_end
+       l.sb    0(r2),r5
+
+align_end:
+       l.j    _ret_from_intr
+       l.nop
+#endif
+
+/* ---[ 0x700: Illegal insn exception ]---------------------------------- */
+
+EXCEPTION_ENTRY(_illegal_instruction_handler)
+       /* r4: EA of fault (set by EXCEPTION_HANDLE) */
+       l.jal   do_illegal_instruction
+        l.addi  r3,r1,0 /* pt_regs */
+
+       l.j     _ret_from_exception
+        l.nop
+
+/* ---[ 0x800: External interrupt exception ]---------------------------- */
+
+EXCEPTION_ENTRY(_external_irq_handler)
+#ifdef CONFIG_OPENRISC_ESR_EXCEPTION_BUG_CHECK
+       l.lwz   r4,PT_SR(r1)            // were interrupts enabled ?
+       l.andi  r4,r4,SPR_SR_IEE
+       l.sfeqi r4,0
+       l.bnf   1f                      // ext irq enabled, all ok.
+       l.nop
+
+       l.addi  r1,r1,-0x8
+       l.movhi r3,hi(42f)
+       l.ori   r3,r3,lo(42f)
+       l.sw    0x0(r1),r3
+       l.jal   printk
+       l.sw    0x4(r1),r4
+       l.addi  r1,r1,0x8
+
+       .section .rodata, "a"
+42:
+               .string "\n\rESR interrupt bug: in _external_irq_handler (ESR %x)\n\r"
+               .align 4
+       .previous
+
+       l.ori   r4,r4,SPR_SR_IEE        // fix the bug
+//     l.sw    PT_SR(r1),r4
+1:
+#endif
+       l.addi  r3,r1,0
+       l.movhi r8,hi(do_IRQ)
+       l.ori   r8,r8,lo(do_IRQ)
+       l.jalr r8
+       l.nop
+       l.j    _ret_from_intr
+       l.nop
+
+/* ---[ 0x900: DTLB miss exception ]------------------------------------- */
+
+
+/* ---[ 0xa00: ITLB miss exception ]------------------------------------- */
+
+
+/* ---[ 0xb00: Range exception ]----------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0xb00,0xb00)
+
+/* ---[ 0xc00: Syscall exception ]--------------------------------------- */
+
+/*
+ * Syscalls are a special type of exception in that they are
+ * _explicitly_ invoked by userspace and can therefore be
+ * held to conform to the same ABI as normal functions with
+ * respect to whether registers are preserved across the call
+ * or not.
+ */
+
+/* Upon syscall entry we just save the callee-saved registers
+ * and not the call-clobbered ones.
+ */
+
+_string_syscall_return:
+       .string "syscall return %ld \n\r\0"
+       .align 4
+
+ENTRY(_sys_call_handler)
+       /* syscalls run with interrupts enabled */
+       ENABLE_INTERRUPTS(r29)          // enable interrupts, r29 is temp
+
+       /* r1, EPCR, ESR a already saved */
+       l.sw    PT_GPR2(r1),r2
+       /* r3-r8 must be saved because syscall restart relies
+        * on us being able to restart the syscall args... technically
+        * they should be clobbered, otherwise
+        */
+       l.sw    PT_GPR3(r1),r3
+       /* r4 already saved */
+       /* r4 holds the EEAR address of the fault, load the original r4 */
+       l.lwz   r4,PT_GPR4(r1)
+       l.sw    PT_GPR5(r1),r5
+       l.sw    PT_GPR6(r1),r6
+       l.sw    PT_GPR7(r1),r7
+       l.sw    PT_GPR8(r1),r8
+       l.sw    PT_GPR9(r1),r9
+       /* r10 already saved */
+       l.sw    PT_GPR11(r1),r11
+       l.sw    PT_ORIG_GPR11(r1),r11
+       /* r12,r13 already saved */
+
+       /* r14-r28 (even) aren't touched by the syscall fast path below
+        * so we don't need to save them.  However, the functions that return
+        * to userspace via a call to switch() DO need to save these because
+        * switch() effectively clobbers them... saving these registers for
+        * such functions is handled in their syscall wrappers (see fork, vfork,
+        * and clone, below).
+
+       /* r30 is the only register we clobber in the fast path */
+       /* r30 already saved */
+/*     l.sw    PT_GPR30(r1),r30 */
+       /* This is used by do_signal to determine whether to check for
+        * syscall restart or not */
+       l.sw    PT_SYSCALLNO(r1),r11
+
+_syscall_check_trace_enter:
+       /* If TIF_SYSCALL_TRACE is set, then we want to do syscall tracing */
+       l.lwz   r30,TI_FLAGS(r10)
+       l.andi  r30,r30,_TIF_SYSCALL_TRACE
+       l.sfne  r30,r0
+       l.bf    _syscall_trace_enter
+        l.nop
+
+_syscall_check:
+       /* Ensure that the syscall number is reasonable */
+       l.sfgeui r11,__NR_syscalls
+       l.bf    _syscall_badsys
+        l.nop
+
+_syscall_call:
+       l.movhi r29,hi(sys_call_table)
+       l.ori   r29,r29,lo(sys_call_table)
+       l.slli  r11,r11,2
+       l.add   r29,r29,r11
+       l.lwz   r29,0(r29)
+
+       l.jalr  r29
+        l.nop
+
+_syscall_return:
+       /* All syscalls return here... just pay attention to ret_from_fork
+        * which does it in a round-about way.
+        */
+       l.sw    PT_GPR11(r1),r11           // save return value
+
+#if 0
+_syscall_debug:
+       l.movhi r3,hi(_string_syscall_return)
+       l.ori   r3,r3,lo(_string_syscall_return)
+       l.ori   r27,r0,1
+       l.sw    -4(r1),r27
+       l.sw    -8(r1),r11
+       l.addi  r1,r1,-8
+       l.movhi r27,hi(printk)
+       l.ori   r27,r27,lo(printk)
+       l.jalr  r27
+        l.nop
+       l.addi  r1,r1,8
+#endif
+
+_syscall_check_trace_leave:
+       /* r30 is a callee-saved register so this should still hold the
+        * _TIF_SYSCALL_TRACE flag from _syscall_check_trace_enter above...
+        * _syscall_trace_leave expects syscall result to be in pt_regs->r11.
+        */
+       l.sfne  r30,r0
+       l.bf    _syscall_trace_leave
+        l.nop
+
+/* This is where the exception-return code begins... interrupts need to be
+ * disabled the rest of the way here because we can't afford to miss any
+ * interrupts that set NEED_RESCHED or SIGNALPENDING... really true? */
+
+_syscall_check_work:
+       /* Here we need to disable interrupts */
+       DISABLE_INTERRUPTS(r27,r29)
+       l.lwz   r30,TI_FLAGS(r10)
+       l.andi  r30,r30,_TIF_WORK_MASK
+       l.sfne  r30,r0
+
+       l.bnf   _syscall_resume_userspace
+        l.nop
+
+       /* Work pending follows a different return path, so we need to
+        * make sure that all the call-saved registers get into pt_regs
+        * before branching...
+        */
+       l.sw    PT_GPR14(r1),r14
+       l.sw    PT_GPR16(r1),r16
+       l.sw    PT_GPR18(r1),r18
+       l.sw    PT_GPR20(r1),r20
+       l.sw    PT_GPR22(r1),r22
+       l.sw    PT_GPR24(r1),r24
+       l.sw    PT_GPR26(r1),r26
+       l.sw    PT_GPR28(r1),r28
+
+       /* _work_pending needs to be called with interrupts disabled */
+       l.j     _work_pending
+        l.nop
+
+_syscall_resume_userspace:
+//     ENABLE_INTERRUPTS(r29)
+
+
+/* This is the hot path for returning to userspace from a syscall.  If there's
+ * work to be done and the branch to _work_pending was taken above, then the
+ * return to userspace will be done via the normal exception return path...
+ * that path restores _all_ registers and will overwrite the "clobbered"
+ * registers with whatever garbage is in pt_regs -- that's OK because those
+ * registers are clobbered anyway and because the extra work is insignificant
+ * in the context of the extra work that _work_pending is doing.
+
+/* Once again, syscalls are special and only guarantee to preserve the
+ * same registers as a normal function call */
+
+/* The assumption here is that the registers r14-r28 (even) are untouched and
+ * don't need to be restored... be sure that that's really the case!
+ */
+
+/* This is still too much... we should only be restoring what we actually
+ * clobbered... we should even be using 'scratch' (odd) regs above so that
+ * we don't need to restore anything, hardly...
+ */
+
+       l.lwz   r2,PT_GPR2(r1)
+
+       /* Restore args */
+       /* r3-r8 are technically clobbered, but syscall restart needs these
+        * to be restored...
+        */
+       l.lwz   r3,PT_GPR3(r1)
+       l.lwz   r4,PT_GPR4(r1)
+       l.lwz   r5,PT_GPR5(r1)
+       l.lwz   r6,PT_GPR6(r1)
+       l.lwz   r7,PT_GPR7(r1)
+       l.lwz   r8,PT_GPR8(r1)
+
+       l.lwz   r9,PT_GPR9(r1)
+       l.lwz   r10,PT_GPR10(r1)
+       l.lwz   r11,PT_GPR11(r1)
+
+       /* r30 is the only register we clobber in the fast path */
+       l.lwz   r30,PT_GPR30(r1)
+
+       /* Here we use r13-r19 (odd) as scratch regs */
+       l.lwz   r13,PT_PC(r1)
+       l.lwz   r15,PT_SR(r1)
+       l.lwz   r1,PT_SP(r1)
+       /* Interrupts need to be disabled for setting EPCR and ESR
+        * so that another interrupt doesn't come in here and clobber
+        * them before we can use them for our l.rfe */
+       DISABLE_INTERRUPTS(r17,r19)
+       l.mtspr r0,r13,SPR_EPCR_BASE
+       l.mtspr r0,r15,SPR_ESR_BASE
+       l.rfe
+
+/* End of hot path!
+ * Keep the below tracing and error handling out of the hot path...
+*/
+
+_syscall_trace_enter:
+       /* Here we pass pt_regs to do_syscall_trace_enter.  Make sure
+        * that function is really getting all the info it needs as
+        * pt_regs isn't a complete set of userspace regs, just the
+        * ones relevant to the syscall...
+        *
+        * Note use of delay slot for setting argument.
+        */
+       l.jal   do_syscall_trace_enter
+        l.addi r3,r1,0
+
+       /* Restore arguments (not preserved across do_syscall_trace_enter)
+        * so that we can do the syscall for real and return to the syscall
+        * hot path.
+        */
+       l.lwz   r11,PT_SYSCALLNO(r1)
+       l.lwz   r3,PT_GPR3(r1)
+       l.lwz   r4,PT_GPR4(r1)
+       l.lwz   r5,PT_GPR5(r1)
+       l.lwz   r6,PT_GPR6(r1)
+       l.lwz   r7,PT_GPR7(r1)
+
+       l.j     _syscall_check
+        l.lwz  r8,PT_GPR8(r1)
+
+_syscall_trace_leave:
+       l.jal   do_syscall_trace_leave
+        l.addi r3,r1,0
+
+       l.j     _syscall_check_work
+        l.nop
+
+_syscall_badsys:
+       /* Here we effectively pretend to have executed an imaginary
+        * syscall that returns -ENOSYS and then return to the regular
+        * syscall hot path.
+        * Note that "return value" is set in the delay slot...
+        */
+       l.j     _syscall_return
+        l.addi r11,r0,-ENOSYS
+
+/******* END SYSCALL HANDLING *******/
+
+/* ---[ 0xd00: Trap exception ]------------------------------------------ */
+
+UNHANDLED_EXCEPTION(_vector_0xd00,0xd00)
+
+/* ---[ 0xe00: Trap exception ]------------------------------------------ */
+
+EXCEPTION_ENTRY(_trap_handler)
+       /* r4: EA of fault (set by EXCEPTION_HANDLE) */
+       l.jal   do_trap
+        l.addi  r3,r1,0 /* pt_regs */
+
+       l.j     _ret_from_exception
+        l.nop
+
+/* ---[ 0xf00: Reserved exception ]-------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0xf00,0xf00)
+
+/* ---[ 0x1000: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1000,0x1000)
+
+/* ---[ 0x1100: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1100,0x1100)
+
+/* ---[ 0x1200: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1200,0x1200)
+
+/* ---[ 0x1300: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1300,0x1300)
+
+/* ---[ 0x1400: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1400,0x1400)
+
+/* ---[ 0x1500: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1500,0x1500)
+
+/* ---[ 0x1600: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1600,0x1600)
+
+/* ---[ 0x1700: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1700,0x1700)
+
+/* ---[ 0x1800: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1800,0x1800)
+
+/* ---[ 0x1900: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1900,0x1900)
+
+/* ---[ 0x1a00: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1a00,0x1a00)
+
+/* ---[ 0x1b00: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1b00,0x1b00)
+
+/* ---[ 0x1c00: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1c00,0x1c00)
+
+/* ---[ 0x1d00: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1d00,0x1d00)
+
+/* ---[ 0x1e00: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1e00,0x1e00)
+
+/* ---[ 0x1f00: Reserved exception ]------------------------------------- */
+
+UNHANDLED_EXCEPTION(_vector_0x1f00,0x1f00)
+
+/* ========================================================[ return ] === */
+
+_work_pending:
+       /*
+        * if (current_thread_info->flags & _TIF_NEED_RESCHED)
+        *     schedule();
+        */
+       l.lwz   r5,TI_FLAGS(r10)
+       l.andi  r3,r5,_TIF_NEED_RESCHED
+       l.sfnei r3,0
+       l.bnf   _work_notifysig
+        l.nop
+       l.jal   schedule
+        l.nop
+       l.j     _resume_userspace
+        l.nop
+
+/* Handle pending signals and notify-resume requests.
+ * do_notify_resume must be passed the latest pushed pt_regs, not
+ * necessarily the "userspace" ones.  Also, pt_regs->syscallno
+ * must be set so that the syscall restart functionality works.
+ */
+_work_notifysig:
+       l.jal   do_notify_resume
+        l.ori  r3,r1,0           /* pt_regs */
+
+_resume_userspace:
+       DISABLE_INTERRUPTS(r3,r4)
+       l.lwz   r3,TI_FLAGS(r10)
+       l.andi  r3,r3,_TIF_WORK_MASK
+       l.sfnei r3,0
+       l.bf    _work_pending
+        l.nop
+
+_restore_all:
+       RESTORE_ALL
+       /* This returns to userspace code */
+
+
+ENTRY(_ret_from_intr)
+ENTRY(_ret_from_exception)
+       l.lwz   r4,PT_SR(r1)
+       l.andi  r3,r4,SPR_SR_SM
+       l.sfeqi r3,0
+       l.bnf   _restore_all
+        l.nop
+       l.j     _resume_userspace
+        l.nop
+
+ENTRY(ret_from_fork)
+       l.jal   schedule_tail
+        l.nop
+
+       /* _syscall_returns expect r11 to contain return value */
+       l.lwz   r11,PT_GPR11(r1)
+
+       /* The syscall fast path return expects call-saved registers
+        * r12-r28 to be untouched, so we restore them here as they
+        * will have been effectively clobbered when arriving here
+        * via the call to switch()
+        */
+       l.lwz   r12,PT_GPR12(r1)
+       l.lwz   r14,PT_GPR14(r1)
+       l.lwz   r16,PT_GPR16(r1)
+       l.lwz   r18,PT_GPR18(r1)
+       l.lwz   r20,PT_GPR20(r1)
+       l.lwz   r22,PT_GPR22(r1)
+       l.lwz   r24,PT_GPR24(r1)
+       l.lwz   r26,PT_GPR26(r1)
+       l.lwz   r28,PT_GPR28(r1)
+
+       l.j     _syscall_return
+        l.nop
+
+/* Since syscalls don't save call-clobbered registers, the args to
+ * kernel_thread_helper will need to be passed through callee-saved
+ * registers and copied to the parameter registers when the thread
+ * begins running.
+ *
+ * See arch/openrisc/kernel/process.c:
+ * The args are passed as follows:
+ *   arg1 (r3) : passed in r20
+ *   arg2 (r4) : passed in r22
+ */
+
+ENTRY(_kernel_thread_helper)
+       l.or    r3,r20,r0
+       l.or    r4,r22,r0
+       l.movhi r31,hi(kernel_thread_helper)
+       l.ori   r31,r31,lo(kernel_thread_helper)
+       l.jr    r31
+        l.nop
+
+
+/* ========================================================[ switch ] === */
+
+/*
+ * This routine switches between two different tasks.  The process
+ * state of one is saved on its kernel stack.  Then the state
+ * of the other is restored from its kernel stack.  The memory
+ * management hardware is updated to the second process's state.
+ * Finally, we can return to the second process, via the 'return'.
+ *
+ * Note: there are two ways to get to the "going out" portion
+ * of this code; either by coming in via the entry (_switch)
+ * or via "fork" which must set up an environment equivalent
+ * to the "_switch" path.  If you change this (or in particular, the
+ * SAVE_REGS macro), you'll have to change the fork code also.
+ */
+
+
+/* _switch MUST never lay on page boundry, cause it runs from
+ * effective addresses and beeing interrupted by iTLB miss would kill it.
+ * dTLB miss seams to never accour in the bad place since data accesses
+ * are from task structures which are always page aligned.
+ *
+ * The problem happens in RESTORE_ALL_NO_R11 where we first set the EPCR
+ * register, then load the previous register values and only at the end call
+ * the l.rfe instruction. If get TLB miss in beetwen the EPCR register gets
+ * garbled and we end up calling l.rfe with the wrong EPCR. (same probably
+ * holds for ESR)
+ *
+ * To avoid this problems it is sufficient to align _switch to
+ * some nice round number smaller than it's size...
+ */
+
+/* ABI rules apply here... we either enter _switch via schedule() or via
+ * an imaginary call to which we shall return at return_from_fork.  Either
+ * way, we are a function call and only need to preserve the callee-saved
+ * registers when we return.  As such, we don't need to save the registers
+ * on the stack that we won't be returning as they were...
+ */
+
+       .align 0x400
+ENTRY(_switch)
+       /* We don't store SR as _switch only gets called in a context where
+        * the SR will be the same going in and coming out... */
+
+       /* Set up new pt_regs struct for saving task state */
+       l.addi  r1,r1,-(INT_FRAME_SIZE)
+
+       /* No need to store r1/PT_SP as it goes into KSP below */
+       l.sw    PT_GPR2(r1),r2
+       l.sw    PT_GPR9(r1),r9
+       /* This is wrong, r12 shouldn't be here... but GCC is broken for the time being
+        * and expects r12 to be callee-saved... */
+       l.sw    PT_GPR12(r1),r12
+       l.sw    PT_GPR14(r1),r14
+       l.sw    PT_GPR16(r1),r16
+       l.sw    PT_GPR18(r1),r18
+       l.sw    PT_GPR20(r1),r20
+       l.sw    PT_GPR22(r1),r22
+       l.sw    PT_GPR24(r1),r24
+       l.sw    PT_GPR26(r1),r26
+       l.sw    PT_GPR28(r1),r28
+       l.sw    PT_GPR30(r1),r30
+
+       l.addi  r11,r10,0                       /* Save old 'current' to 'last' return value*/
+
+       /* We use thread_info->ksp for storing the address of the above
+        * structure so that we can get back to it later... we don't want
+        * to lose the value of thread_info->ksp, though, so store it as
+        * pt_regs->sp so that we can easily restore it when we are made
+        * live again...
+        */
+
+       /* Save the old value of thread_info->ksp as pt_regs->sp */
+       l.lwz   r29,TI_KSP(r10)
+       l.sw    PT_SP(r1),r29
+
+       /* Swap kernel stack pointers */
+       l.sw    TI_KSP(r10),r1                  /* Save old stack pointer */
+       l.or    r10,r4,r0                       /* Set up new current_thread_info */
+       l.lwz   r1,TI_KSP(r10)                  /* Load new stack pointer */
+
+       /* Restore the old value of thread_info->ksp */
+       l.lwz   r29,PT_SP(r1)
+       l.sw    TI_KSP(r10),r29
+
+       /* ...and restore the registers, except r11 because the return value
+        * has already been set above.
+        */
+       l.lwz   r2,PT_GPR2(r1)
+       l.lwz   r9,PT_GPR9(r1)
+       /* No need to restore r10 */
+       /* ...and do not restore r11 */
+
+       /* This is wrong, r12 shouldn't be here... but GCC is broken for the time being
+        * and expects r12 to be callee-saved... */
+       l.lwz   r12,PT_GPR12(r1)
+       l.lwz   r14,PT_GPR14(r1)
+       l.lwz   r16,PT_GPR16(r1)
+       l.lwz   r18,PT_GPR18(r1)
+       l.lwz   r20,PT_GPR20(r1)
+       l.lwz   r22,PT_GPR22(r1)
+       l.lwz   r24,PT_GPR24(r1)
+       l.lwz   r26,PT_GPR26(r1)
+       l.lwz   r28,PT_GPR28(r1)
+       l.lwz   r30,PT_GPR30(r1)
+
+       /* Unwind stack to pre-switch state */
+       l.addi  r1,r1,(INT_FRAME_SIZE)
+
+       /* Return via the link-register back to where we 'came from', where that can be
+        * either schedule() or return_from_fork()... */
+       l.jr    r9
+        l.nop
+
+/* ==================================================================== */
+
+/* These all use the delay slot for setting the argument register, so the
+ * jump is always happening after the l.addi instruction.
+ *
+ * These are all just wrappers that don't touch the link-register r9, so the
+ * return from the "real" syscall function will return back to the syscall
+ * code that did the l.jal that brought us here.
+ */
+
+/* fork requires that we save all the callee-saved registers because they
+ * are all effectively clobbered by the call to _switch.  Here we store
+ * all the registers that aren't touched by the syscall fast path and thus
+ * weren't saved there.
+ */
+
+_fork_save_extra_regs_and_call:
+       l.sw    PT_GPR14(r1),r14
+       l.sw    PT_GPR16(r1),r16
+       l.sw    PT_GPR18(r1),r18
+       l.sw    PT_GPR20(r1),r20
+       l.sw    PT_GPR22(r1),r22
+       l.sw    PT_GPR24(r1),r24
+       l.sw    PT_GPR26(r1),r26
+       l.jr    r29
+        l.sw    PT_GPR28(r1),r28
+
+ENTRY(sys_clone)
+       l.movhi r29,hi(_sys_clone)
+       l.ori   r29,r29,lo(_sys_clone)
+       l.j     _fork_save_extra_regs_and_call
+        l.addi r7,r1,0
+
+ENTRY(sys_fork)
+       l.movhi r29,hi(_sys_fork)
+       l.ori   r29,r29,lo(_sys_fork)
+       l.j     _fork_save_extra_regs_and_call
+        l.addi r3,r1,0
+
+ENTRY(sys_execve)
+       l.j     _sys_execve
+        l.addi r6,r1,0
+
+ENTRY(sys_sigaltstack)
+       l.j     _sys_sigaltstack
+        l.addi r5,r1,0
+
+ENTRY(sys_rt_sigreturn)
+       l.j     _sys_rt_sigreturn
+        l.addi r3,r1,0
+
+/* This is a catch-all syscall for atomic instructions for the OpenRISC 1000.
+ * The functions takes a variable number of parameters depending on which
+ * particular flavour of atomic you want... parameter 1 is a flag identifying
+ * the atomic in question.  Currently, this function implements the
+ * following variants:
+ *
+ * XCHG:
+ *  @flag: 1
+ *  @ptr1:
+ *  @ptr2:
+ * Atomically exchange the values in pointers 1 and 2.
+ *
+ */
+
+ENTRY(sys_or1k_atomic)
+       /* FIXME: This ignores r3 and always does an XCHG */
+       DISABLE_INTERRUPTS(r17,r19)
+       l.lwz   r30,0(r4)
+       l.lwz   r28,0(r5)
+       l.sw    0(r4),r28
+       l.sw    0(r5),r30
+       ENABLE_INTERRUPTS(r17)
+       l.jr    r9
+        l.or   r11,r0,r0
+
+/* ============================================================[ EOF ]=== */
diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S
new file mode 100644 (file)
index 0000000..c75018d
--- /dev/null
@@ -0,0 +1,1607 @@
+/*
+ * OpenRISC head.S
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others.  All original copyrights apply as per the original source
+ * declaration.
+ *
+ * Modifications for the OpenRISC architecture:
+ * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ *      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 <linux/linkage.h>
+#include <linux/threads.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/cache.h>
+#include <asm/spr_defs.h>
+#include <asm/asm-offsets.h>
+
+#define tophys(rd,rs)                          \
+       l.movhi rd,hi(-KERNELBASE)              ;\
+       l.add   rd,rd,rs
+
+#define CLEAR_GPR(gpr)                         \
+       l.or    gpr,r0,r0
+
+#define LOAD_SYMBOL_2_GPR(gpr,symbol)          \
+       l.movhi gpr,hi(symbol)                  ;\
+       l.ori   gpr,gpr,lo(symbol)
+
+
+#define UART_BASE_ADD      0x90000000
+
+#define EXCEPTION_SR  (SPR_SR_DME | SPR_SR_IME | SPR_SR_DCE | SPR_SR_ICE | SPR_SR_SM)
+#define SYSCALL_SR  (SPR_SR_DME | SPR_SR_IME | SPR_SR_DCE | SPR_SR_ICE | SPR_SR_IEE | SPR_SR_TEE | SPR_SR_SM)
+
+/* ============================================[ tmp store locations ]=== */
+
+/*
+ * emergency_print temporary stores
+ */
+#define EMERGENCY_PRINT_STORE_GPR4     l.sw    0x20(r0),r4
+#define EMERGENCY_PRINT_LOAD_GPR4      l.lwz   r4,0x20(r0)
+
+#define EMERGENCY_PRINT_STORE_GPR5     l.sw    0x24(r0),r5
+#define EMERGENCY_PRINT_LOAD_GPR5      l.lwz   r5,0x24(r0)
+
+#define EMERGENCY_PRINT_STORE_GPR6     l.sw    0x28(r0),r6
+#define EMERGENCY_PRINT_LOAD_GPR6      l.lwz   r6,0x28(r0)
+
+#define EMERGENCY_PRINT_STORE_GPR7     l.sw    0x2c(r0),r7
+#define EMERGENCY_PRINT_LOAD_GPR7      l.lwz   r7,0x2c(r0)
+
+#define EMERGENCY_PRINT_STORE_GPR8     l.sw    0x30(r0),r8
+#define EMERGENCY_PRINT_LOAD_GPR8      l.lwz   r8,0x30(r0)
+
+#define EMERGENCY_PRINT_STORE_GPR9     l.sw    0x34(r0),r9
+#define EMERGENCY_PRINT_LOAD_GPR9      l.lwz   r9,0x34(r0)
+
+
+/*
+ * TLB miss handlers temorary stores
+ */
+#define EXCEPTION_STORE_GPR9           l.sw    0x10(r0),r9
+#define EXCEPTION_LOAD_GPR9            l.lwz   r9,0x10(r0)
+
+#define EXCEPTION_STORE_GPR2           l.sw    0x64(r0),r2
+#define EXCEPTION_LOAD_GPR2            l.lwz   r2,0x64(r0)
+
+#define EXCEPTION_STORE_GPR3           l.sw    0x68(r0),r3
+#define EXCEPTION_LOAD_GPR3            l.lwz   r3,0x68(r0)
+
+#define EXCEPTION_STORE_GPR4           l.sw    0x6c(r0),r4
+#define EXCEPTION_LOAD_GPR4            l.lwz   r4,0x6c(r0)
+
+#define EXCEPTION_STORE_GPR5           l.sw    0x70(r0),r5
+#define EXCEPTION_LOAD_GPR5            l.lwz   r5,0x70(r0)
+
+#define EXCEPTION_STORE_GPR6           l.sw    0x74(r0),r6
+#define EXCEPTION_LOAD_GPR6            l.lwz   r6,0x74(r0)
+
+
+/*
+ * EXCEPTION_HANDLE temporary stores
+ */
+
+#define EXCEPTION_T_STORE_GPR30                l.sw    0x78(r0),r30
+#define EXCEPTION_T_LOAD_GPR30(reg)    l.lwz   reg,0x78(r0)
+
+#define EXCEPTION_T_STORE_GPR10                l.sw    0x7c(r0),r10
+#define EXCEPTION_T_LOAD_GPR10(reg)    l.lwz   reg,0x7c(r0)
+
+#define EXCEPTION_T_STORE_SP           l.sw    0x80(r0),r1
+#define EXCEPTION_T_LOAD_SP(reg)       l.lwz   reg,0x80(r0)
+
+/*
+ * For UNHANLDED_EXCEPTION
+ */
+
+#define EXCEPTION_T_STORE_GPR31                l.sw    0x84(r0),r31
+#define EXCEPTION_T_LOAD_GPR31(reg)    l.lwz   reg,0x84(r0)
+
+/* =========================================================[ macros ]=== */
+
+
+#define GET_CURRENT_PGD(reg,t1)                                        \
+       LOAD_SYMBOL_2_GPR(reg,current_pgd)                      ;\
+       tophys  (t1,reg)                                        ;\
+       l.lwz   reg,0(t1)
+
+
+/*
+ * DSCR: this is a common hook for handling exceptions. it will save
+ *       the needed registers, set up stack and pointer to current
+ *      then jump to the handler while enabling MMU
+ *
+ * PRMS: handler       - a function to jump to. it has to save the
+ *                     remaining registers to kernel stack, call
+ *                     appropriate arch-independant exception handler
+ *                     and finaly jump to ret_from_except
+ *
+ * PREQ: unchanged state from the time exception happened
+ *</