Merge branch 'parisc-4.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Nov 2017 22:26:14 +0000 (14:26 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Nov 2017 22:26:14 +0000 (14:26 -0800)
Pull parisc updates from Helge Deller:
 "Highlights:

   - one important fix from Dave to prevent kernel crash when userspace
     hands over invalid values to our in-kernel CAS implementation.

   - added CPU topology support, including multi-core scheduler support
     on PA8900 CPUs

  Minor changes:

   - minor fixes for sparse (from Luc)

   - drop duplicates for CPU_BIG_ENDIAN from parisc and sparc top
     Kconfig files (from Babu)

   - reorganized parisc PDC (firmware-access) header files for usage
     from userspace. Required for upcoming qemu parisc emulator and
     SeaBIOS fork to support parisc"

* 'parisc-4.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  arch: Fix duplicates in Kconfig for parisc and sparc
  parisc: Make some PDC structures accessible in uapi headers
  parisc: Pass endianness info to sparse
  parisc: Add CPU topology support
  parisc: Fix validity check of pointer size argument in new CAS implementation

arch/parisc/Kconfig
arch/parisc/Makefile
arch/parisc/include/asm/pdc.h
arch/parisc/include/asm/topology.h [new file with mode: 0644]
arch/parisc/include/uapi/asm/pdc.h
arch/parisc/kernel/Makefile
arch/parisc/kernel/processor.c
arch/parisc/kernel/setup.c
arch/parisc/kernel/syscall.S
arch/parisc/kernel/topology.c
arch/sparc/Kconfig

index 1fd3eb5b66c6c6586c028b9002dcb185f6d54e56..9792d8cf4f565660ab5dbe83b4eb6ab3aa1af888 100644 (file)
@@ -32,6 +32,7 @@ config PARISC
        select GENERIC_PCI_IOMAP
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select GENERIC_SMP_IDLE_THREAD
+       select GENERIC_CPU_DEVICES
        select GENERIC_STRNCPY_FROM_USER
        select SYSCTL_ARCH_UNALIGN_ALLOW
        select SYSCTL_EXCEPTION_TRACE
@@ -60,9 +61,6 @@ config PARISC
 config CPU_BIG_ENDIAN
        def_bool y
 
-config CPU_BIG_ENDIAN
-       def_bool y
-
 config MMU
        def_bool y
 
@@ -288,6 +286,21 @@ config SMP
 
          If you don't know what to do here, say N.
 
+config PARISC_CPU_TOPOLOGY
+       bool "Support cpu topology definition"
+       depends on SMP
+       default y
+       help
+         Support PARISC cpu topology definition.
+
+config SCHED_MC
+       bool "Multi-core scheduler support"
+       depends on PARISC_CPU_TOPOLOGY && PA8X00
+       help
+         Multi-core scheduler support improves the CPU scheduler's decision
+         making when dealing with multi-core CPU chips at a cost of slightly
+         increased overhead in some places. If unsure say N here.
+
 config IRQSTACKS
        bool "Use separate kernel stacks when processing interrupts"
        default y
index 01946ebaff72814435cf6128665bd778eb217fb1..e2364ff591809287a227ba32e6533a911b48032a 100644 (file)
@@ -22,7 +22,7 @@ KBUILD_IMAGE := vmlinuz
 KBUILD_DEFCONFIG := default_defconfig
 
 NM             = sh $(srctree)/arch/parisc/nm
-CHECKFLAGS     += -D__hppa__=1
+CHECKFLAGS     += -D__hppa__=1 -mbig-endian
 LIBGCC         = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 export LIBGCC
 
index efee44a5e0633d5760c12552acc6fa9adabe163d..339e83ddb39e464c1d4dee57ea1d87d4c6ef570b 100644 (file)
@@ -18,261 +18,6 @@ extern unsigned long parisc_cell_loc; /* cell location of CPU (PAT)    */
 #define PDC_TYPE_SYSTEM_MAP     1 /* 32-bit, but supports PDC_SYSTEM_MAP */
 #define PDC_TYPE_SNAKE          2 /* Doesn't support SYSTEM_MAP */
 
-struct pdc_chassis_info {       /* for PDC_CHASSIS_INFO */
-       unsigned long actcnt;   /* actual number of bytes returned */
-       unsigned long maxcnt;   /* maximum number of bytes that could be returned */
-};
-
-struct pdc_coproc_cfg {         /* for PDC_COPROC_CFG */
-        unsigned long ccr_functional;
-        unsigned long ccr_present;
-        unsigned long revision;
-        unsigned long model;
-};
-
-struct pdc_model {             /* for PDC_MODEL */
-       unsigned long hversion;
-       unsigned long sversion;
-       unsigned long hw_id;
-       unsigned long boot_id;
-       unsigned long sw_id;
-       unsigned long sw_cap;
-       unsigned long arch_rev;
-       unsigned long pot_key;
-       unsigned long curr_key;
-};
-
-struct pdc_cache_cf {          /* for PDC_CACHE  (I/D-caches) */
-    unsigned long
-#ifdef CONFIG_64BIT
-               cc_padW:32,
-#endif
-               cc_alias: 4,    /* alias boundaries for virtual addresses   */
-               cc_block: 4,    /* to determine most efficient stride */
-               cc_line : 3,    /* maximum amount written back as a result of store (multiple of 16 bytes) */
-               cc_shift: 2,    /* how much to shift cc_block left */
-               cc_wt   : 1,    /* 0 = WT-Dcache, 1 = WB-Dcache */
-               cc_sh   : 2,    /* 0 = separate I/D-cache, else shared I/D-cache */
-               cc_cst  : 3,    /* 0 = incoherent D-cache, 1=coherent D-cache */
-               cc_pad1 : 10,   /* reserved */
-               cc_hv   : 3;    /* hversion dependent */
-};
-
-struct pdc_tlb_cf {            /* for PDC_CACHE (I/D-TLB's) */
-    unsigned long tc_pad0:12,  /* reserved */
-#ifdef CONFIG_64BIT
-               tc_padW:32,
-#endif
-               tc_sh   : 2,    /* 0 = separate I/D-TLB, else shared I/D-TLB */
-               tc_hv   : 1,    /* HV */
-               tc_page : 1,    /* 0 = 2K page-size-machine, 1 = 4k page size */
-               tc_cst  : 3,    /* 0 = incoherent operations, else coherent operations */
-               tc_aid  : 5,    /* ITLB: width of access ids of processor (encoded!) */
-               tc_sr   : 8;    /* ITLB: width of space-registers (encoded) */
-};
-
-struct pdc_cache_info {                /* main-PDC_CACHE-structure (caches & TLB's) */
-       /* I-cache */
-       unsigned long   ic_size;        /* size in bytes */
-       struct pdc_cache_cf ic_conf;    /* configuration */
-       unsigned long   ic_base;        /* base-addr */
-       unsigned long   ic_stride;
-       unsigned long   ic_count;
-       unsigned long   ic_loop;
-       /* D-cache */
-       unsigned long   dc_size;        /* size in bytes */
-       struct pdc_cache_cf dc_conf;    /* configuration */
-       unsigned long   dc_base;        /* base-addr */
-       unsigned long   dc_stride;
-       unsigned long   dc_count;
-       unsigned long   dc_loop;
-       /* Instruction-TLB */
-       unsigned long   it_size;        /* number of entries in I-TLB */
-       struct pdc_tlb_cf it_conf;      /* I-TLB-configuration */
-       unsigned long   it_sp_base;
-       unsigned long   it_sp_stride;
-       unsigned long   it_sp_count;
-       unsigned long   it_off_base;
-       unsigned long   it_off_stride;
-       unsigned long   it_off_count;
-       unsigned long   it_loop;
-       /* data-TLB */
-       unsigned long   dt_size;        /* number of entries in D-TLB */
-       struct pdc_tlb_cf dt_conf;      /* D-TLB-configuration */
-       unsigned long   dt_sp_base;
-       unsigned long   dt_sp_stride;
-       unsigned long   dt_sp_count;
-       unsigned long   dt_off_base;
-       unsigned long   dt_off_stride;
-       unsigned long   dt_off_count;
-       unsigned long   dt_loop;
-};
-
-#if 0
-/* If you start using the next struct, you'll have to adjust it to
- * work with 64-bit firmware I think -PB
- */
-struct pdc_iodc {     /* PDC_IODC */
-       unsigned char   hversion_model;
-       unsigned char   hversion;
-       unsigned char   spa;
-       unsigned char   type;
-       unsigned int    sversion_rev:4;
-       unsigned int    sversion_model:19;
-       unsigned int    sversion_opt:8;
-       unsigned char   rev;
-       unsigned char   dep;
-       unsigned char   features;
-       unsigned char   pad1;
-       unsigned int    checksum:16;
-       unsigned int    length:16;
-       unsigned int    pad[15];
-} __attribute__((aligned(8))) ;
-#endif
-
-#ifndef CONFIG_PA20
-/* no BLTBs in pa2.0 processors */
-struct pdc_btlb_info_range {
-       __u8 res00;
-       __u8 num_i;
-       __u8 num_d;
-       __u8 num_comb;
-};
-
-struct pdc_btlb_info { /* PDC_BLOCK_TLB, return of PDC_BTLB_INFO */
-       unsigned int min_size;  /* minimum size of BTLB in pages */
-       unsigned int max_size;  /* maximum size of BTLB in pages */
-       struct pdc_btlb_info_range fixed_range_info;
-       struct pdc_btlb_info_range variable_range_info;
-};
-
-#endif /* !CONFIG_PA20 */
-
-struct pdc_mem_retinfo { /* PDC_MEM/PDC_MEM_MEMINFO (return info) */
-       unsigned long pdt_size;
-       unsigned long pdt_entries;
-       unsigned long pdt_status;
-       unsigned long first_dbe_loc;
-       unsigned long good_mem;
-};
-
-struct pdc_mem_read_pdt { /* PDC_MEM/PDC_MEM_READ_PDT (return info) */
-       unsigned long pdt_entries;
-};
-
-#ifdef CONFIG_64BIT
-struct pdc_memory_table_raddr { /* PDC_MEM/PDC_MEM_TABLE (return info) */
-       unsigned long entries_returned;
-       unsigned long entries_total;
-};
-
-struct pdc_memory_table {       /* PDC_MEM/PDC_MEM_TABLE (arguments) */
-       unsigned long paddr;
-       unsigned int  pages;
-       unsigned int  reserved;
-};
-#endif /* CONFIG_64BIT */
-
-struct pdc_system_map_mod_info { /* PDC_SYSTEM_MAP/FIND_MODULE */
-       unsigned long mod_addr;
-       unsigned long mod_pgs;
-       unsigned long add_addrs;
-};
-
-struct pdc_system_map_addr_info { /* PDC_SYSTEM_MAP/FIND_ADDRESS */
-       unsigned long mod_addr;
-       unsigned long mod_pgs;
-};
-
-struct pdc_initiator { /* PDC_INITIATOR */
-       int host_id;
-       int factor;
-       int width;
-       int mode;
-};
-
-struct hardware_path {
-       char  flags;    /* see bit definitions below */
-       char  bc[6];    /* Bus Converter routing info to a specific */
-                       /* I/O adaptor (< 0 means none, > 63 resvd) */
-       char  mod;      /* fixed field of specified module */
-};
-
-/*
- * Device path specifications used by PDC.
- */
-struct pdc_module_path {
-       struct hardware_path path;
-       unsigned int layers[6]; /* device-specific info (ctlr #, unit # ...) */
-};
-
-#ifndef CONFIG_PA20
-/* Only used on some pre-PA2.0 boxes */
-struct pdc_memory_map {                /* PDC_MEMORY_MAP */
-       unsigned long hpa;      /* mod's register set address */
-       unsigned long more_pgs; /* number of additional I/O pgs */
-};
-#endif
-
-struct pdc_tod {
-       unsigned long tod_sec; 
-       unsigned long tod_usec;
-};
-
-/* architected results from PDC_PIM/transfer hpmc on a PA1.1 machine */
-
-struct pdc_hpmc_pim_11 { /* PDC_PIM */
-       __u32 gr[32];
-       __u32 cr[32];
-       __u32 sr[8];
-       __u32 iasq_back;
-       __u32 iaoq_back;
-       __u32 check_type;
-       __u32 cpu_state;
-       __u32 rsvd1;
-       __u32 cache_check;
-       __u32 tlb_check;
-       __u32 bus_check;
-       __u32 assists_check;
-       __u32 rsvd2;
-       __u32 assist_state;
-       __u32 responder_addr;
-       __u32 requestor_addr;
-       __u32 path_info;
-       __u64 fr[32];
-};
-
-/*
- * architected results from PDC_PIM/transfer hpmc on a PA2.0 machine
- *
- * Note that PDC_PIM doesn't care whether or not wide mode was enabled
- * so the results are different on  PA1.1 vs. PA2.0 when in narrow mode.
- *
- * Note also that there are unarchitected results available, which
- * are hversion dependent. Do a "ser pim 0 hpmc" after rebooting, since
- * the firmware is probably the best way of printing hversion dependent
- * data.
- */
-
-struct pdc_hpmc_pim_20 { /* PDC_PIM */
-       __u64 gr[32];
-       __u64 cr[32];
-       __u64 sr[8];
-       __u64 iasq_back;
-       __u64 iaoq_back;
-       __u32 check_type;
-       __u32 cpu_state;
-       __u32 cache_check;
-       __u32 tlb_check;
-       __u32 bus_check;
-       __u32 assists_check;
-       __u32 assist_state;
-       __u32 path_info;
-       __u64 responder_addr;
-       __u64 requestor_addr;
-       __u64 fr[32];
-};
-
 void pdc_console_init(void);   /* in pdc_console.c */
 void pdc_console_restart(void);
 
diff --git a/arch/parisc/include/asm/topology.h b/arch/parisc/include/asm/topology.h
new file mode 100644 (file)
index 0000000..6f0750c
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _ASM_PARISC_TOPOLOGY_H
+#define _ASM_PARISC_TOPOLOGY_H
+
+#ifdef CONFIG_PARISC_CPU_TOPOLOGY
+
+#include <linux/cpumask.h>
+
+struct cputopo_parisc {
+       int thread_id;
+       int core_id;
+       int socket_id;
+       cpumask_t thread_sibling;
+       cpumask_t core_sibling;
+};
+
+extern struct cputopo_parisc cpu_topology[NR_CPUS];
+
+#define topology_physical_package_id(cpu)      (cpu_topology[cpu].socket_id)
+#define topology_core_id(cpu)          (cpu_topology[cpu].core_id)
+#define topology_core_cpumask(cpu)     (&cpu_topology[cpu].core_sibling)
+#define topology_sibling_cpumask(cpu)  (&cpu_topology[cpu].thread_sibling)
+
+void init_cpu_topology(void);
+void store_cpu_topology(unsigned int cpuid);
+const struct cpumask *cpu_coregroup_mask(int cpu);
+
+#else
+
+static inline void init_cpu_topology(void) { }
+static inline void store_cpu_topology(unsigned int cpuid) { }
+
+#endif
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_ARM_TOPOLOGY_H */
index 0ad117617f1a27d488ab60a26ad182add51a6ea0..593eeb573138709aafa855343730a1f7e393a874 100644 (file)
@@ -16,6 +16,7 @@
 #define PDC_ERROR               -3     /* Call could not complete without an error */
 #define PDC_NE_MOD              -5     /* Module not found             */
 #define PDC_NE_CELL_MOD                 -7     /* Cell module not found        */
+#define PDC_NE_BOOTDEV          -9     /* Cannot locate a console device or boot device */
 #define PDC_INVALID_ARG                -10     /* Called with an invalid argument */
 #define PDC_BUS_POW_WARN       -12     /* Call could not complete in allowed power budget */
 #define PDC_NOT_NARROW         -17     /* Narrow mode not supported    */
 
 #if !defined(__ASSEMBLY__)
 
-#include <linux/types.h>
-
-
 /* flags of the device_path */
 #define        PF_AUTOBOOT     0x80
 #define        PF_AUTOSEARCH   0x40
@@ -418,9 +416,255 @@ struct zeropage {
        int     pad430[116];
 
        /* [0x600] processor dependent */
-       __u32   pad600[1];
-       __u32   proc_sti;               /* pointer to STI ROM */
-       __u32   pad608[126];
+       unsigned int pad600[1];
+       unsigned int proc_sti;          /* pointer to STI ROM */
+       unsigned int pad608[126];
+};
+
+struct pdc_chassis_info {       /* for PDC_CHASSIS_INFO */
+       unsigned long actcnt;   /* actual number of bytes returned */
+       unsigned long maxcnt;   /* maximum number of bytes that could be returned */
+};
+
+struct pdc_coproc_cfg {         /* for PDC_COPROC_CFG */
+        unsigned long ccr_functional;
+        unsigned long ccr_present;
+        unsigned long revision;
+        unsigned long model;
+};
+
+struct pdc_model {             /* for PDC_MODEL */
+       unsigned long hversion;
+       unsigned long sversion;
+       unsigned long hw_id;
+       unsigned long boot_id;
+       unsigned long sw_id;
+       unsigned long sw_cap;
+       unsigned long arch_rev;
+       unsigned long pot_key;
+       unsigned long curr_key;
+};
+
+struct pdc_cache_cf {          /* for PDC_CACHE  (I/D-caches) */
+    unsigned long
+#ifdef __LP64__
+               cc_padW:32,
+#endif
+               cc_alias: 4,    /* alias boundaries for virtual addresses   */
+               cc_block: 4,    /* to determine most efficient stride */
+               cc_line : 3,    /* maximum amount written back as a result of store (multiple of 16 bytes) */
+               cc_shift: 2,    /* how much to shift cc_block left */
+               cc_wt   : 1,    /* 0 = WT-Dcache, 1 = WB-Dcache */
+               cc_sh   : 2,    /* 0 = separate I/D-cache, else shared I/D-cache */
+               cc_cst  : 3,    /* 0 = incoherent D-cache, 1=coherent D-cache */
+               cc_pad1 : 10,   /* reserved */
+               cc_hv   : 3;    /* hversion dependent */
+};
+
+struct pdc_tlb_cf {            /* for PDC_CACHE (I/D-TLB's) */
+    unsigned long tc_pad0:12,  /* reserved */
+#ifdef __LP64__
+               tc_padW:32,
+#endif
+               tc_sh   : 2,    /* 0 = separate I/D-TLB, else shared I/D-TLB */
+               tc_hv   : 1,    /* HV */
+               tc_page : 1,    /* 0 = 2K page-size-machine, 1 = 4k page size */
+               tc_cst  : 3,    /* 0 = incoherent operations, else coherent operations */
+               tc_aid  : 5,    /* ITLB: width of access ids of processor (encoded!) */
+               tc_sr   : 8;    /* ITLB: width of space-registers (encoded) */
+};
+
+struct pdc_cache_info {                /* main-PDC_CACHE-structure (caches & TLB's) */
+       /* I-cache */
+       unsigned long   ic_size;        /* size in bytes */
+       struct pdc_cache_cf ic_conf;    /* configuration */
+       unsigned long   ic_base;        /* base-addr */
+       unsigned long   ic_stride;
+       unsigned long   ic_count;
+       unsigned long   ic_loop;
+       /* D-cache */
+       unsigned long   dc_size;        /* size in bytes */
+       struct pdc_cache_cf dc_conf;    /* configuration */
+       unsigned long   dc_base;        /* base-addr */
+       unsigned long   dc_stride;
+       unsigned long   dc_count;
+       unsigned long   dc_loop;
+       /* Instruction-TLB */
+       unsigned long   it_size;        /* number of entries in I-TLB */
+       struct pdc_tlb_cf it_conf;      /* I-TLB-configuration */
+       unsigned long   it_sp_base;
+       unsigned long   it_sp_stride;
+       unsigned long   it_sp_count;
+       unsigned long   it_off_base;
+       unsigned long   it_off_stride;
+       unsigned long   it_off_count;
+       unsigned long   it_loop;
+       /* data-TLB */
+       unsigned long   dt_size;        /* number of entries in D-TLB */
+       struct pdc_tlb_cf dt_conf;      /* D-TLB-configuration */
+       unsigned long   dt_sp_base;
+       unsigned long   dt_sp_stride;
+       unsigned long   dt_sp_count;
+       unsigned long   dt_off_base;
+       unsigned long   dt_off_stride;
+       unsigned long   dt_off_count;
+       unsigned long   dt_loop;
+};
+
+/* Might need adjustment to work with 64-bit firmware */
+struct pdc_iodc {     /* PDC_IODC */
+       unsigned char   hversion_model;
+       unsigned char   hversion;
+       unsigned char   spa;
+       unsigned char   type;
+       unsigned int    sversion_rev:4;
+       unsigned int    sversion_model:19;
+       unsigned int    sversion_opt:8;
+       unsigned char   rev;
+       unsigned char   dep;
+       unsigned char   features;
+       unsigned char   pad1;
+       unsigned int    checksum:16;
+       unsigned int    length:16;
+       unsigned int    pad[15];
+} __attribute__((aligned(8))) ;
+
+/* no BLTBs in pa2.0 processors */
+struct pdc_btlb_info_range {
+       unsigned char res00;
+       unsigned char num_i;
+       unsigned char num_d;
+       unsigned char num_comb;
+};
+
+struct pdc_btlb_info { /* PDC_BLOCK_TLB, return of PDC_BTLB_INFO */
+       unsigned int min_size;  /* minimum size of BTLB in pages */
+       unsigned int max_size;  /* maximum size of BTLB in pages */
+       struct pdc_btlb_info_range fixed_range_info;
+       struct pdc_btlb_info_range variable_range_info;
+};
+
+struct pdc_mem_retinfo { /* PDC_MEM/PDC_MEM_MEMINFO (return info) */
+       unsigned long pdt_size;
+       unsigned long pdt_entries;
+       unsigned long pdt_status;
+       unsigned long first_dbe_loc;
+       unsigned long good_mem;
+};
+
+struct pdc_mem_read_pdt { /* PDC_MEM/PDC_MEM_READ_PDT (return info) */
+       unsigned long pdt_entries;
+};
+
+#ifdef __LP64__
+struct pdc_memory_table_raddr { /* PDC_MEM/PDC_MEM_TABLE (return info) */
+       unsigned long entries_returned;
+       unsigned long entries_total;
+};
+
+struct pdc_memory_table {       /* PDC_MEM/PDC_MEM_TABLE (arguments) */
+       unsigned long paddr;
+       unsigned int  pages;
+       unsigned int  reserved;
+};
+#endif /* __LP64__ */
+
+struct pdc_system_map_mod_info { /* PDC_SYSTEM_MAP/FIND_MODULE */
+       unsigned long mod_addr;
+       unsigned long mod_pgs;
+       unsigned long add_addrs;
+};
+
+struct pdc_system_map_addr_info { /* PDC_SYSTEM_MAP/FIND_ADDRESS */
+       unsigned long mod_addr;
+       unsigned long mod_pgs;
+};
+
+struct pdc_initiator { /* PDC_INITIATOR */
+       int host_id;
+       int factor;
+       int width;
+       int mode;
+};
+
+struct hardware_path {
+       char  flags;    /* see bit definitions below */
+       char  bc[6];    /* Bus Converter routing info to a specific */
+                       /* I/O adaptor (< 0 means none, > 63 resvd) */
+       char  mod;      /* fixed field of specified module */
+};
+
+/*
+ * Device path specifications used by PDC.
+ */
+struct pdc_module_path {
+       struct hardware_path path;
+       unsigned int layers[6]; /* device-specific info (ctlr #, unit # ...) */
+};
+
+/* Only used on some pre-PA2.0 boxes */
+struct pdc_memory_map {                /* PDC_MEMORY_MAP */
+       unsigned long hpa;      /* mod's register set address */
+       unsigned long more_pgs; /* number of additional I/O pgs */
+};
+
+struct pdc_tod {
+       unsigned long tod_sec;
+       unsigned long tod_usec;
+};
+
+/* architected results from PDC_PIM/transfer hpmc on a PA1.1 machine */
+
+struct pdc_hpmc_pim_11 { /* PDC_PIM */
+       unsigned int gr[32];
+       unsigned int cr[32];
+       unsigned int sr[8];
+       unsigned int iasq_back;
+       unsigned int iaoq_back;
+       unsigned int check_type;
+       unsigned int cpu_state;
+       unsigned int rsvd1;
+       unsigned int cache_check;
+       unsigned int tlb_check;
+       unsigned int bus_check;
+       unsigned int assists_check;
+       unsigned int rsvd2;
+       unsigned int assist_state;
+       unsigned int responder_addr;
+       unsigned int requestor_addr;
+       unsigned int path_info;
+       unsigned long long fr[32];
+};
+
+/*
+ * architected results from PDC_PIM/transfer hpmc on a PA2.0 machine
+ *
+ * Note that PDC_PIM doesn't care whether or not wide mode was enabled
+ * so the results are different on  PA1.1 vs. PA2.0 when in narrow mode.
+ *
+ * Note also that there are unarchitected results available, which
+ * are hversion dependent. Do a "ser pim 0 hpmc" after rebooting, since
+ * the firmware is probably the best way of printing hversion dependent
+ * data.
+ */
+
+struct pdc_hpmc_pim_20 { /* PDC_PIM */
+       unsigned long long gr[32];
+       unsigned long long cr[32];
+       unsigned long long sr[8];
+       unsigned long long iasq_back;
+       unsigned long long iaoq_back;
+       unsigned int check_type;
+       unsigned int cpu_state;
+       unsigned int cache_check;
+       unsigned int tlb_check;
+       unsigned int bus_check;
+       unsigned int assists_check;
+       unsigned int assist_state;
+       unsigned int path_info;
+       unsigned long long responder_addr;
+       unsigned long long requestor_addr;
+       unsigned long long fr[32];
 };
 
 #endif /* !defined(__ASSEMBLY__) */
index 649dc3eda4488205346c19912b9dc2baae4b2863..eafd06ab59ef8db3b21aabccc5021a05877e38f7 100644 (file)
@@ -9,8 +9,7 @@ obj-y           := cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \
                   pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
                   ptrace.o hardware.o inventory.o drivers.o \
                   signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \
-                  process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \
-                  topology.o
+                  process.o processor.o pdc_cons.o pdc_chassis.o unwind.o
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not profile debug and lowlevel utilities
@@ -30,5 +29,6 @@ obj-$(CONFIG_AUDIT)   += audit.o
 obj64-$(CONFIG_AUDIT)  += compat_audit.o
 # only supported for PCX-W/U in 64-bit mode at the moment
 obj-$(CONFIG_64BIT)    += perf.o perf_asm.o $(obj64-y)
+obj-$(CONFIG_PARISC_CPU_TOPOLOGY)      += topology.o
 obj-$(CONFIG_FUNCTION_TRACER)          += ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)    += ftrace.o
index e120d63c1b285ad545c2281de0abbbcc2dde6e08..45cc65902fcebb88edc6f98d96241d4a1dbf7617 100644 (file)
@@ -184,6 +184,9 @@ static int __init processor_probe(struct parisc_device *dev)
        p->txn_addr = txn_addr; /* save CPU IRQ address */
        p->cpu_num = cpu_info.cpu_num;
        p->cpu_loc = cpu_info.cpu_loc;
+
+       store_cpu_topology(cpuid);
+
 #ifdef CONFIG_SMP
        /*
        ** FIXME: review if any other initialization is clobbered
@@ -325,6 +328,8 @@ int __init init_per_cpu(int cpunum)
        set_firmware_width();
        ret = pdc_coproc_cfg(&coproc_cfg);
 
+       store_cpu_topology(cpunum);
+
        if(ret >= 0 && coproc_cfg.ccr_functional) {
                mtctl(coproc_cfg.ccr_functional, 10);  /* 10 == Coprocessor Control Reg */
 
@@ -388,6 +393,14 @@ show_cpuinfo (struct seq_file *m, void *v)
                                 boot_cpu_data.cpu_hz / 1000000,
                                 boot_cpu_data.cpu_hz % 1000000  );
 
+#ifdef CONFIG_PARISC_CPU_TOPOLOGY
+               seq_printf(m, "physical id\t: %d\n",
+                               topology_physical_package_id(cpu));
+               seq_printf(m, "siblings\t: %d\n",
+                               cpumask_weight(topology_core_cpumask(cpu)));
+               seq_printf(m, "core id\t\t: %d\n", topology_core_id(cpu));
+#endif
+
                seq_printf(m, "capabilities\t:");
                if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS32)
                        seq_puts(m, " os32");
index f7d0c3b33d70a53b5350729f1e3d59b2e803749b..0e9675f857a5ca910769b8de1335cd318d0e2c9d 100644 (file)
@@ -408,6 +408,8 @@ void __init start_parisc(void)
 
        cpunum = smp_processor_id();
 
+       init_cpu_topology();
+
        set_firmware_width_unlocked();
 
        ret = pdc_coproc_cfg_unlocked(&coproc_cfg);
index 41e60a9c7db23b8384b18bf8ddd45f188ef4a0c3..e775f80ae28c5ab8d7fac7456235fa4f415c7215 100644 (file)
@@ -690,15 +690,15 @@ cas_action:
        /* ELF32 Process entry path */
 lws_compare_and_swap_2:
 #ifdef CONFIG_64BIT
-       /* Clip the input registers */
+       /* Clip the input registers. We don't need to clip %r23 as we
+          only use it for word operations */
        depdi   0, 31, 32, %r26
        depdi   0, 31, 32, %r25
        depdi   0, 31, 32, %r24
-       depdi   0, 31, 32, %r23
 #endif
 
        /* Check the validity of the size pointer */
-       subi,>>= 4, %r23, %r0
+       subi,>>= 3, %r23, %r0
        b,n     lws_exit_nosys
 
        /* Jump to the functions which will load the old and new values into
index f5159381fdd6f04be4679a0dd66ab474bb78f490..0a10e4ddc528f76f40364a3e3b49ece350d91519 100644 (file)
 /*
- * arch/parisc/kernel/topology.c - Populate sysfs with topology information
+ * arch/parisc/kernel/topology.c
  *
- * 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.
+ * Copyright (C) 2017 Helge Deller <deller@gmx.de>
  *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
+ * based on arch/arm/kernel/topology.c
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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.
  */
 
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/cpu.h>
-#include <linux/cache.h>
+#include <linux/percpu.h>
+#include <linux/sched.h>
+#include <linux/sched/topology.h>
 
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
+#include <asm/topology.h>
 
-static int __init topology_init(void)
+ /*
+  * cpu topology table
+  */
+struct cputopo_parisc cpu_topology[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL_GPL(cpu_topology);
+
+const struct cpumask *cpu_coregroup_mask(int cpu)
 {
-       int num;
+       return &cpu_topology[cpu].core_sibling;
+}
+
+static void update_siblings_masks(unsigned int cpuid)
+{
+       struct cputopo_parisc *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
+       int cpu;
+
+       /* update core and thread sibling masks */
+       for_each_possible_cpu(cpu) {
+               cpu_topo = &cpu_topology[cpu];
+
+               if (cpuid_topo->socket_id != cpu_topo->socket_id)
+                       continue;
+
+               cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
+               if (cpu != cpuid)
+                       cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
+
+               if (cpuid_topo->core_id != cpu_topo->core_id)
+                       continue;
+
+               cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
+               if (cpu != cpuid)
+                       cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
+       }
+       smp_wmb();
+}
+
+static int dualcores_found __initdata;
+
+/*
+ * store_cpu_topology is called at boot when only one cpu is running
+ * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
+ * which prevents simultaneous write access to cpu_topology array
+ */
+void __init store_cpu_topology(unsigned int cpuid)
+{
+       struct cputopo_parisc *cpuid_topo = &cpu_topology[cpuid];
+       struct cpuinfo_parisc *p;
+       int max_socket = -1;
+       unsigned long cpu;
+
+       /* If the cpu topology has been already set, just return */
+       if (cpuid_topo->core_id != -1)
+               return;
 
-       for_each_present_cpu(num) {
-               register_cpu(&per_cpu(cpu_devices, num), num);
+       /* create cpu topology mapping */
+       cpuid_topo->thread_id = -1;
+       cpuid_topo->core_id = 0;
+
+       p = &per_cpu(cpu_data, cpuid);
+       for_each_online_cpu(cpu) {
+               const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
+
+               if (cpu == cpuid) /* ignore current cpu */
+                       continue;
+
+               if (cpuinfo->cpu_loc == p->cpu_loc) {
+                       cpuid_topo->core_id = cpu_topology[cpu].core_id;
+                       if (p->cpu_loc) {
+                               cpuid_topo->core_id++;
+                               cpuid_topo->socket_id = cpu_topology[cpu].socket_id;
+                               dualcores_found = 1;
+                               continue;
+                       }
+               }
+
+               if (cpuid_topo->socket_id == -1)
+                       max_socket = max(max_socket, cpu_topology[cpu].socket_id);
        }
-       return 0;
+
+       if (cpuid_topo->socket_id == -1)
+               cpuid_topo->socket_id = max_socket + 1;
+
+       update_siblings_masks(cpuid);
+
+       pr_info("CPU%u: thread %d, cpu %d, socket %d\n",
+               cpuid, cpu_topology[cpuid].thread_id,
+               cpu_topology[cpuid].core_id,
+               cpu_topology[cpuid].socket_id);
 }
 
-subsys_initcall(topology_init);
+static struct sched_domain_topology_level parisc_mc_topology[] = {
+#ifdef CONFIG_SCHED_MC
+       { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) },
+#endif
+
+       { cpu_cpu_mask, SD_INIT_NAME(DIE) },
+       { NULL, },
+};
+
+/*
+ * init_cpu_topology is called at boot when only one cpu is running
+ * which prevent simultaneous write access to cpu_topology array
+ */
+void __init init_cpu_topology(void)
+{
+       unsigned int cpu;
+
+       /* init core mask and capacity */
+       for_each_possible_cpu(cpu) {
+               struct cputopo_parisc *cpu_topo = &(cpu_topology[cpu]);
+
+               cpu_topo->thread_id = -1;
+               cpu_topo->core_id =  -1;
+               cpu_topo->socket_id = -1;
+               cpumask_clear(&cpu_topo->core_sibling);
+               cpumask_clear(&cpu_topo->thread_sibling);
+       }
+       smp_wmb();
+
+       /* Set scheduler topology descriptor */
+       if (dualcores_found)
+               set_sched_topology(parisc_mc_topology);
+}
index 4e83f950713e9f9837da01406586613a9c07cb3f..987a57502909b4eb81bc86afa286f1140955ade0 100644 (file)
@@ -96,9 +96,6 @@ config ARCH_PROC_KCORE_TEXT
 config CPU_BIG_ENDIAN
        def_bool y
 
-config CPU_BIG_ENDIAN
-       def_bool y
-
 config ARCH_ATU
        bool
        default y if SPARC64