Commit 3cf71b17 authored by David Mosberger's avatar David Mosberger

ia64: Fixes for the inline-asm cleanup patch so the tree builds and

	works again on the simulator (besides the real hw, of course).
	Also, clean up simulator bootloader code so it's all in
	a single place (arch/ia64/hp/sim/bootloader/).
parent 708df1b0
...@@ -66,7 +66,7 @@ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ ...@@ -66,7 +66,7 @@ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/
drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/
boot := arch/ia64/boot boot := arch/ia64/hp/sim/boot
.PHONY: boot compressed check .PHONY: boot compressed check
......
/*
* Copyright (C) 1998-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <asm/asmmacro.h>
.bss
.align 16
stack_mem:
.skip 16834
.text
/* This needs to be defined because lib/string.c:strlcat() calls it in case of error... */
GLOBAL_ENTRY(printk)
break 0
END(printk)
GLOBAL_ENTRY(_start)
.prologue
.save rp, r0
.body
movl gp = __gp
movl sp = stack_mem
bsw.1
br.call.sptk.many rp=start_bootloader
END(_start)
GLOBAL_ENTRY(ssc)
.regstk 5,0,0,0
mov r15=in4
break 0x80001
br.ret.sptk.many b0
END(ssc)
GLOBAL_ENTRY(jmp_to_kernel)
.regstk 2,0,0,0
mov r28=in0
mov b7=in1
br.sptk.few b7
END(jmp_to_kernel)
GLOBAL_ENTRY(pal_emulator_static)
mov r8=-1
mov r9=256
;;
cmp.gtu p6,p7=r9,r28 /* r28 <= 255? */
(p6) br.cond.sptk.few static
;;
mov r9=512
;;
cmp.gtu p6,p7=r9,r28
(p6) br.cond.sptk.few stacked
;;
static: cmp.eq p6,p7=6,r28 /* PAL_PTCE_INFO */
(p7) br.cond.sptk.few 1f
;;
mov r8=0 /* status = 0 */
movl r9=0x100000000 /* tc.base */
movl r10=0x0000000200000003 /* count[0], count[1] */
movl r11=0x1000000000002000 /* stride[0], stride[1] */
br.cond.sptk.few rp
1: cmp.eq p6,p7=14,r28 /* PAL_FREQ_RATIOS */
(p7) br.cond.sptk.few 1f
mov r8=0 /* status = 0 */
movl r9 =0x100000064 /* proc_ratio (1/100) */
movl r10=0x100000100 /* bus_ratio<<32 (1/256) */
movl r11=0x100000064 /* itc_ratio<<32 (1/100) */
;;
1: cmp.eq p6,p7=19,r28 /* PAL_RSE_INFO */
(p7) br.cond.sptk.few 1f
mov r8=0 /* status = 0 */
mov r9=96 /* num phys stacked */
mov r10=0 /* hints */
mov r11=0
br.cond.sptk.few rp
1: cmp.eq p6,p7=1,r28 /* PAL_CACHE_FLUSH */
(p7) br.cond.sptk.few 1f
mov r9=ar.lc
movl r8=524288 /* flush 512k million cache lines (16MB) */
;;
mov ar.lc=r8
movl r8=0xe000000000000000
;;
.loop: fc r8
add r8=32,r8
br.cloop.sptk.few .loop
sync.i
;;
srlz.i
;;
mov ar.lc=r9
mov r8=r0
;;
1: cmp.eq p6,p7=15,r28 /* PAL_PERF_MON_INFO */
(p7) br.cond.sptk.few 1f
mov r8=0 /* status = 0 */
movl r9 =0x12082004 /* generic=4 width=32 retired=8 cycles=18 */
mov r10=0 /* reserved */
mov r11=0 /* reserved */
mov r16=0xffff /* implemented PMC */
mov r17=0xffff /* implemented PMD */
add r18=8,r29 /* second index */
;;
st8 [r29]=r16,16 /* store implemented PMC */
st8 [r18]=r0,16 /* clear remaining bits */
;;
st8 [r29]=r0,16 /* store implemented PMC */
st8 [r18]=r0,16 /* clear remaining bits */
;;
st8 [r29]=r17,16 /* store implemented PMD */
st8 [r18]=r0,16 /* clear remaining bits */
mov r16=0xf0 /* cycles count capable PMC */
;;
st8 [r29]=r0,16 /* store implemented PMC */
st8 [r18]=r0,16 /* clear remaining bits */
mov r17=0x10 /* retired bundles capable PMC */
;;
st8 [r29]=r16,16 /* store cycles capable */
st8 [r18]=r0,16 /* clear remaining bits */
;;
st8 [r29]=r0,16 /* store implemented PMC */
st8 [r18]=r0,16 /* clear remaining bits */
;;
st8 [r29]=r17,16 /* store retired bundle capable */
st8 [r18]=r0,16 /* clear remaining bits */
;;
st8 [r29]=r0,16 /* store implemented PMC */
st8 [r18]=r0,16 /* clear remaining bits */
;;
1: br.cond.sptk.few rp
stacked:
br.ret.sptk.few rp
END(pal_emulator_static)
...@@ -3,9 +3,6 @@ ...@@ -3,9 +3,6 @@
* *
* Copyright (C) 1998-2001 Hewlett-Packard Co * Copyright (C) 1998-2001 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
*
* For the HP simulator, this file gets include in boot/bootloader.c.
* For SoftSDV, this file gets included in sys_softsdv.c.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -18,6 +15,8 @@ ...@@ -18,6 +15,8 @@
#include <asm/pal.h> #include <asm/pal.h>
#include <asm/sal.h> #include <asm/sal.h>
#include "ssc.h"
#define MB (1024*1024UL) #define MB (1024*1024UL)
#define SIMPLE_MEMMAP 1 #define SIMPLE_MEMMAP 1
...@@ -37,17 +36,6 @@ static char fw_mem[( sizeof(struct ia64_boot_param) ...@@ -37,17 +36,6 @@ static char fw_mem[( sizeof(struct ia64_boot_param)
+ NUM_MEM_DESCS*(sizeof(efi_memory_desc_t)) + NUM_MEM_DESCS*(sizeof(efi_memory_desc_t))
+ 1024)] __attribute__ ((aligned (8))); + 1024)] __attribute__ ((aligned (8)));
#if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC)
/* Simulator system calls: */
#define SSC_EXIT 66
/*
* Simulator system call.
*/
extern long ssc (long arg0, long arg1, long arg2, long arg3, int nr);
#define SECS_PER_HOUR (60 * 60) #define SECS_PER_HOUR (60 * 60)
#define SECS_PER_DAY (SECS_PER_HOUR * 24) #define SECS_PER_DAY (SECS_PER_HOUR * 24)
...@@ -109,12 +97,6 @@ offtime (unsigned long t, efi_time_t *tp) ...@@ -109,12 +97,6 @@ offtime (unsigned long t, efi_time_t *tp)
return 1; return 1;
} }
#endif /* CONFIG_IA64_HP_SIM */
/*
* Very ugly, but we need this in the simulator only. Once we run on
* real hw, this can all go away.
*/
extern void pal_emulator_static (void); extern void pal_emulator_static (void);
/* Macro to emulate SAL call using legacy IN and OUT calls to CF8, CFC etc.. */ /* Macro to emulate SAL call using legacy IN and OUT calls to CF8, CFC etc.. */
...@@ -321,7 +303,7 @@ sys_fw_init (const char *args, int arglen) ...@@ -321,7 +303,7 @@ sys_fw_init (const char *args, int arglen)
efi_systab->hdr.headersize = sizeof(efi_systab->hdr); efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
efi_systab->fw_vendor = __pa("H\0e\0w\0l\0e\0t\0t\0-\0P\0a\0c\0k\0a\0r\0d\0\0"); efi_systab->fw_vendor = __pa("H\0e\0w\0l\0e\0t\0t\0-\0P\0a\0c\0k\0a\0r\0d\0\0");
efi_systab->fw_revision = 1; efi_systab->fw_revision = 1;
efi_systab->runtime = __pa(efi_runtime); efi_systab->runtime = (void *) __pa(efi_runtime);
efi_systab->nr_tables = 1; efi_systab->nr_tables = 1;
efi_systab->tables = __pa(efi_tables); efi_systab->tables = __pa(efi_tables);
......
/*
* Copyright (C) 1998-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* Stephane Eranian <eranian@hpl.hp.com>
*/
#ifndef ssc_h
#define ssc_h
/* Simulator system calls: */
#define SSC_CONSOLE_INIT 20
#define SSC_GETCHAR 21
#define SSC_PUTCHAR 31
#define SSC_OPEN 50
#define SSC_CLOSE 51
#define SSC_READ 52
#define SSC_WRITE 53
#define SSC_GET_COMPLETION 54
#define SSC_WAIT_COMPLETION 55
#define SSC_CONNECT_INTERRUPT 58
#define SSC_GENERATE_INTERRUPT 59
#define SSC_SET_PERIODIC_INTERRUPT 60
#define SSC_GET_RTC 65
#define SSC_EXIT 66
#define SSC_LOAD_SYMBOLS 69
#define SSC_GET_TOD 74
#define SSC_GET_ARGS 75
/*
* Simulator system call.
*/
extern long ssc (long arg0, long arg1, long arg2, long arg3, int nr);
#endif /* ssc_h */
...@@ -8,4 +8,3 @@ GLOBAL_ENTRY(ia64_ssc) ...@@ -8,4 +8,3 @@ GLOBAL_ENTRY(ia64_ssc)
break 0x80001 break 0x80001
br.ret.sptk.many rp br.ret.sptk.many rp
END(ia64_ssc) END(ia64_ssc)
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <asm/intrinsics.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/rse.h> #include <asm/rse.h>
#include <asm/sigcontext.h> #include <asm/sigcontext.h>
...@@ -41,8 +42,11 @@ ...@@ -41,8 +42,11 @@
#define __IA32_NR_sigreturn 119 #define __IA32_NR_sigreturn 119
#define __IA32_NR_rt_sigreturn 173 #define __IA32_NR_rt_sigreturn 173
#include <asm/intrinsics.h>
#ifdef ASM_SUPPORTED #ifdef ASM_SUPPORTED
/*
* Don't let GCC uses f16-f31 so that save_ia32_fpstate_live() and
* restore_ia32_fpstate_live() can be sure the live register contain user-level state.
*/
register double f16 asm ("f16"); register double f17 asm ("f17"); register double f16 asm ("f16"); register double f17 asm ("f17");
register double f18 asm ("f18"); register double f19 asm ("f19"); register double f18 asm ("f18"); register double f19 asm ("f19");
register double f20 asm ("f20"); register double f21 asm ("f21"); register double f20 asm ("f20"); register double f21 asm ("f21");
...@@ -217,7 +221,7 @@ save_ia32_fpstate_live (struct _fpstate_ia32 *save) ...@@ -217,7 +221,7 @@ save_ia32_fpstate_live (struct _fpstate_ia32 *save)
if (!access_ok(VERIFY_WRITE, save, sizeof(*save))) if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
return -EFAULT; return -EFAULT;
/* Readin fsr, fcr, fir, fdr and copy onto fpstate */ /* Read in fsr, fcr, fir, fdr and copy onto fpstate */
fsr = ia64_getreg(_IA64_REG_AR_FSR); fsr = ia64_getreg(_IA64_REG_AR_FSR);
fcr = ia64_getreg(_IA64_REG_AR_FCR); fcr = ia64_getreg(_IA64_REG_AR_FCR);
fir = ia64_getreg(_IA64_REG_AR_FIR); fir = ia64_getreg(_IA64_REG_AR_FIR);
......
...@@ -18,11 +18,11 @@ ...@@ -18,11 +18,11 @@
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <asm/intrinsics.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/intrinsics.h>
#include "ia32priv.h" #include "ia32priv.h"
......
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
#include "ia32priv.h" #include "ia32priv.h"
#include <asm/ptrace.h>
#include <asm/intrinsics.h> #include <asm/intrinsics.h>
#include <asm/ptrace.h>
int int
ia32_intercept (struct pt_regs *regs, unsigned long isr) ia32_intercept (struct pt_regs *regs, unsigned long isr)
......
...@@ -446,8 +446,8 @@ extern unsigned long ia32_do_mmap (struct file *, unsigned long, unsigned long, ...@@ -446,8 +446,8 @@ extern unsigned long ia32_do_mmap (struct file *, unsigned long, unsigned long,
extern void ia32_load_segment_descriptors (struct task_struct *task); extern void ia32_load_segment_descriptors (struct task_struct *task);
#define ia32f2ia64f(dst,src) \ #define ia32f2ia64f(dst,src) \
do { \ do { \
ia64_ldfe(6,src); \ ia64_ldfe(6,src); \
ia64_stop(); \ ia64_stop(); \
ia64_stf_spill(dst, 6); \ ia64_stf_spill(dst, 6); \
} while(0) } while(0)
...@@ -456,7 +456,7 @@ do { \ ...@@ -456,7 +456,7 @@ do { \
do { \ do { \
ia64_ldf_fill(6, src); \ ia64_ldf_fill(6, src); \
ia64_stop(); \ ia64_stop(); \
ia64_stfe(dst, 6); \ ia64_stfe(dst, 6); \
} while(0) } while(0)
struct user_regs_struct32 { struct user_regs_struct32 {
...@@ -470,11 +470,8 @@ struct user_regs_struct32 { ...@@ -470,11 +470,8 @@ struct user_regs_struct32 {
}; };
/* Prototypes for use in elfcore32.h */ /* Prototypes for use in elfcore32.h */
int save_ia32_fpstate (struct task_struct *tsk, extern int save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct *save);
struct ia32_user_i387_struct *save); extern int save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct *save);
int save_ia32_fpxstate (struct task_struct *tsk,
struct ia32_user_fxsr_struct *save);
#endif /* !CONFIG_IA32_SUPPORT */ #endif /* !CONFIG_IA32_SUPPORT */
......
...@@ -51,10 +51,10 @@ ...@@ -51,10 +51,10 @@
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include <asm/intrinsics.h>
#include <asm/semaphore.h>
#include <asm/types.h> #include <asm/types.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <asm/intrinsics.h>
#include "ia32priv.h" #include "ia32priv.h"
......
...@@ -30,12 +30,12 @@ ...@@ -30,12 +30,12 @@
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/intrinsics.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
#include <asm/machvec.h> #include <asm/machvec.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/intrinsics.h>
#ifdef CONFIG_PERFMON #ifdef CONFIG_PERFMON
# include <asm/perfmon.h> # include <asm/perfmon.h>
......
...@@ -531,7 +531,7 @@ void ...@@ -531,7 +531,7 @@ void
ia64_mca_cmc_vector_disable (void *dummy) ia64_mca_cmc_vector_disable (void *dummy)
{ {
cmcv_reg_t cmcv; cmcv_reg_t cmcv;
cmcv = (cmcv_reg_t)ia64_getreg(_IA64_REG_CR_CMCV); cmcv = (cmcv_reg_t)ia64_getreg(_IA64_REG_CR_CMCV);
cmcv.cmcv_mask = 1; /* Mask/disable interrupt */ cmcv.cmcv_mask = 1; /* Mask/disable interrupt */
...@@ -558,7 +558,7 @@ void ...@@ -558,7 +558,7 @@ void
ia64_mca_cmc_vector_enable (void *dummy) ia64_mca_cmc_vector_enable (void *dummy)
{ {
cmcv_reg_t cmcv; cmcv_reg_t cmcv;
cmcv = (cmcv_reg_t)ia64_getreg(_IA64_REG_CR_CMCV); cmcv = (cmcv_reg_t)ia64_getreg(_IA64_REG_CR_CMCV);
cmcv.cmcv_mask = 0; /* Unmask/enable interrupt */ cmcv.cmcv_mask = 0; /* Unmask/enable interrupt */
...@@ -1146,7 +1146,7 @@ ia64_mca_cmc_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs) ...@@ -1146,7 +1146,7 @@ ia64_mca_cmc_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
ia64_mca_cmc_int_handler(cpe_irq, arg, ptregs); ia64_mca_cmc_int_handler(cpe_irq, arg, ptregs);
for (++cpuid ; !cpu_online(cpuid) && cpuid < NR_CPUS ; cpuid++); for (++cpuid ; !cpu_online(cpuid) && cpuid < NR_CPUS ; cpuid++);
if (cpuid < NR_CPUS) { if (cpuid < NR_CPUS) {
platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0); platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
} else { } else {
...@@ -1176,7 +1176,7 @@ ia64_mca_cmc_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs) ...@@ -1176,7 +1176,7 @@ ia64_mca_cmc_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
start_count = -1; start_count = -1;
} }
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/errno.h> #include <asm/errno.h>
#include <asm/intrinsics.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/perfmon.h> #include <asm/perfmon.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -46,7 +47,6 @@ ...@@ -46,7 +47,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/intrinsics.h>
#ifdef CONFIG_PERFMON #ifdef CONFIG_PERFMON
/* /*
...@@ -680,28 +680,28 @@ static int pfm_end_notify_user(pfm_context_t *ctx); ...@@ -680,28 +680,28 @@ static int pfm_end_notify_user(pfm_context_t *ctx);
static inline void static inline void
pfm_clear_psr_pp(void) pfm_clear_psr_pp(void)
{ {
ia64_rsm(IA64_PSR_PP) ia64_rsm(IA64_PSR_PP);
ia64_srlz_i(); ia64_srlz_i();
} }
static inline void static inline void
pfm_set_psr_pp(void) pfm_set_psr_pp(void)
{ {
ia64_ssm(IA64_PSR_PP) ia64_ssm(IA64_PSR_PP);
ia64_srlz_i(); ia64_srlz_i();
} }
static inline void static inline void
pfm_clear_psr_up(void) pfm_clear_psr_up(void)
{ {
ia64_rsm(IA64_PSR_UP) ia64_rsm(IA64_PSR_UP);
ia64_srlz_i(); ia64_srlz_i();
} }
static inline void static inline void
pfm_set_psr_up(void) pfm_set_psr_up(void)
{ {
ia64_ssm(IA64_PSR_UP) ia64_ssm(IA64_PSR_UP);
ia64_srlz_i(); ia64_srlz_i();
} }
...@@ -985,8 +985,7 @@ pfm_restore_monitoring(struct task_struct *task) ...@@ -985,8 +985,7 @@ pfm_restore_monitoring(struct task_struct *task)
*/ */
if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) { if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
/* disable dcr pp */ /* disable dcr pp */
ia64_setreg(_IA64_REG_CR_DCR, ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP);
ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP);
pfm_clear_psr_pp(); pfm_clear_psr_pp();
} else { } else {
pfm_clear_psr_up(); pfm_clear_psr_up();
...@@ -1033,8 +1032,7 @@ pfm_restore_monitoring(struct task_struct *task) ...@@ -1033,8 +1032,7 @@ pfm_restore_monitoring(struct task_struct *task)
*/ */
if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) { if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
/* enable dcr pp */ /* enable dcr pp */
ia64_setreg(_IA64_REG_CR_DCR, ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) | IA64_DCR_PP);
ia64_getreg(_IA64_REG_CR_DCR) | IA64_DCR_PP);
ia64_srlz_i(); ia64_srlz_i();
} }
pfm_set_psr_l(psr); pfm_set_psr_l(psr);
...@@ -1790,8 +1788,7 @@ pfm_syswide_force_stop(void *info) ...@@ -1790,8 +1788,7 @@ pfm_syswide_force_stop(void *info)
/* /*
* Update local PMU * Update local PMU
*/ */
ia64_setreg(_IA64_REG_CR_DCR, ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP);
ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP);
ia64_srlz_i(); ia64_srlz_i();
/* /*
* update local cpuinfo * update local cpuinfo
...@@ -3962,8 +3959,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) ...@@ -3962,8 +3959,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* *
* disable dcr pp * disable dcr pp
*/ */
ia64_setreg(_IA64_REG_CR_DCR, ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP);
ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP);
ia64_srlz_i(); ia64_srlz_i();
/* /*
...@@ -4053,8 +4049,7 @@ pfm_start(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) ...@@ -4053,8 +4049,7 @@ pfm_start(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
pfm_set_psr_pp(); pfm_set_psr_pp();
/* enable dcr pp */ /* enable dcr pp */
ia64_setreg(_IA64_REG_CR_DCR, ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) | IA64_DCR_PP);
ia64_getreg(_IA64_REG_CR_DCR) | IA64_DCR_PP);
ia64_srlz_i(); ia64_srlz_i();
return 0; return 0;
......
...@@ -741,8 +741,8 @@ cpu_init (void) ...@@ -741,8 +741,8 @@ cpu_init (void)
* shouldn't be affected by this (moral: keep your ia32 locks aligned and you'll * shouldn't be affected by this (moral: keep your ia32 locks aligned and you'll
* be fine). * be fine).
*/ */
ia64_setreg(_IA64_REG_CR_DCR, IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX ia64_setreg(_IA64_REG_CR_DCR, ( IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR
| IA64_DCR_DR | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC); | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC));
atomic_inc(&init_mm.mm_count); atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm; current->active_mm = &init_mm;
if (current->mm) if (current->mm)
......
/* /*
* Architecture-specific signal handling support. * Architecture-specific signal handling support.
* *
* Copyright (C) 1999-2002 Hewlett-Packard Co * Copyright (C) 1999-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
* *
* Derived from i386 and Alpha versions. * Derived from i386 and Alpha versions.
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <asm/ia32.h> #include <asm/ia32.h>
#include <asm/intrinsics.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/rse.h> #include <asm/rse.h>
#include <asm/sigcontext.h> #include <asm/sigcontext.h>
...@@ -41,8 +42,12 @@ ...@@ -41,8 +42,12 @@
# define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0]) # define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0])
#endif #endif
#include <asm/intrinsics.h>
#ifdef ASM_SUPPORTED #ifdef ASM_SUPPORTED
/*
* Don't let GCC uses f16-f31 so that when we setup/restore the registers in the signal
* context in __kernel_sigtramp(), we can be sure that registers f16-f31 contain user-level
* values.
*/
register double f16 asm ("f16"); register double f17 asm ("f17"); register double f16 asm ("f16"); register double f17 asm ("f17");
register double f18 asm ("f18"); register double f19 asm ("f19"); register double f18 asm ("f18"); register double f19 asm ("f19");
register double f20 asm ("f20"); register double f21 asm ("f21"); register double f20 asm ("f20"); register double f21 asm ("f21");
...@@ -195,7 +200,7 @@ copy_siginfo_to_user (siginfo_t *to, siginfo_t *from) ...@@ -195,7 +200,7 @@ copy_siginfo_to_user (siginfo_t *to, siginfo_t *from)
case __SI_TIMER >> 16: case __SI_TIMER >> 16:
err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_tid, &to->si_tid);
err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_overrun, &to->si_overrun);
err |= __put_user(from->si_value.sival_ptr, &to->si_value.sival_ptr); err |= __put_user(from->si_ptr, &to->si_ptr);
break; break;
case __SI_CHLD >> 16: case __SI_CHLD >> 16:
err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_utime, &to->si_utime);
......
...@@ -14,12 +14,13 @@ ...@@ -14,12 +14,13 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */ #include <linux/vt_kern.h> /* For unblank_screen() */
#include <asm/fpswa.h>
#include <asm/hardirq.h> #include <asm/hardirq.h>
#include <asm/ia32.h> #include <asm/ia32.h>
#include <asm/intrinsics.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/fpswa.h>
/* /*
* fp_emulate() needs to be able to access and update all floating point registers. Those * fp_emulate() needs to be able to access and update all floating point registers. Those
* saved in pt_regs can be accessed through that structure, but those not saved, will be * saved in pt_regs can be accessed through that structure, but those not saved, will be
...@@ -28,7 +29,6 @@ ...@@ -28,7 +29,6 @@
* by declaring preserved registers that are not marked as "fixed" as global register * by declaring preserved registers that are not marked as "fixed" as global register
* variables. * variables.
*/ */
#include <asm/intrinsics.h>
#ifdef ASM_SUPPORTED #ifdef ASM_SUPPORTED
register double f2 asm ("f2"); register double f3 asm ("f3"); register double f2 asm ("f2"); register double f3 asm ("f3");
register double f4 asm ("f4"); register double f5 asm ("f5"); register double f4 asm ("f4"); register double f5 asm ("f5");
......
...@@ -18,11 +18,11 @@ ...@@ -18,11 +18,11 @@
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <asm/uaccess.h> #include <asm/intrinsics.h>
#include <asm/rse.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/rse.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <asm/intrinsics.h>
extern void die_if_kernel(char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn)); extern void die_if_kernel(char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn));
......
...@@ -292,7 +292,7 @@ ffz (unsigned long x) ...@@ -292,7 +292,7 @@ ffz (unsigned long x)
{ {
unsigned long result; unsigned long result;
result = ia64_popcnt((x & (~x - 1))); result = ia64_popcnt(x & (~x - 1));
return result; return result;
} }
......
...@@ -7,8 +7,11 @@ ...@@ -7,8 +7,11 @@
*/ */
#include <asm/intrinsics.h> #include <asm/intrinsics.h>
/* In kernel mode, thread pointer (r13) is used to point to the
current task structure. */ /*
#define current ((struct task_struct *) ia64_getreg(_IA64_REG_TP)) * In kernel mode, thread pointer (r13) is used to point to the current task
* structure.
*/
#define current ((struct task_struct *) ia64_getreg(_IA64_REG_TP))
#endif /* _ASM_IA64_CURRENT_H */ #endif /* _ASM_IA64_CURRENT_H */
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Delay routines using a pre-computed "cycles/usec" value. * Delay routines using a pre-computed "cycles/usec" value.
* *
* Copyright (C) 1998, 1999 Hewlett-Packard Co * Copyright (C) 1998, 1999 Hewlett-Packard Co
* Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999 VA Linux Systems
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com> * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
* Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com> * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <asm/processor.h>
#include <asm/intrinsics.h> #include <asm/intrinsics.h>
#include <asm/processor.h>
static __inline__ void static __inline__ void
ia64_set_itm (unsigned long val) ia64_set_itm (unsigned long val)
...@@ -73,7 +73,7 @@ __delay (unsigned long loops) ...@@ -73,7 +73,7 @@ __delay (unsigned long loops)
if (loops < 1) if (loops < 1)
return; return;
for (;loops--;) while (loops--)
ia64_nop(0); ia64_nop(0);
} }
......
This diff is collapsed.
...@@ -8,8 +8,11 @@ ...@@ -8,8 +8,11 @@
#define _ASM_IA64_IA64REGS_H #define _ASM_IA64_IA64REGS_H
/* /*
** Register Names for getreg() and setreg() * Register Names for getreg() and setreg().
*/ *
* The "magic" numbers happen to match the values used by the Intel compiler's
* getreg()/setreg() intrinsics.
*/
/* Special Registers */ /* Special Registers */
...@@ -17,15 +20,15 @@ ...@@ -17,15 +20,15 @@
#define _IA64_REG_PSR 1019 #define _IA64_REG_PSR 1019
#define _IA64_REG_PSR_L 1019 #define _IA64_REG_PSR_L 1019
// General Integer Registers /* General Integer Registers */
#define _IA64_REG_GP 1025 /* R1 */ #define _IA64_REG_GP 1025 /* R1 */
#define _IA64_REG_R8 1032 /* R8 */ #define _IA64_REG_R8 1032 /* R8 */
#define _IA64_REG_R9 1033 /* R9 */ #define _IA64_REG_R9 1033 /* R9 */
#define _IA64_REG_SP 1036 /* R12 */ #define _IA64_REG_SP 1036 /* R12 */
#define _IA64_REG_TP 1037 /* R13 */ #define _IA64_REG_TP 1037 /* R13 */
/* Application Registers */ /* Application Registers */
#define _IA64_REG_AR_KR0 3072 #define _IA64_REG_AR_KR0 3072
#define _IA64_REG_AR_KR1 3073 #define _IA64_REG_AR_KR1 3073
...@@ -55,7 +58,7 @@ ...@@ -55,7 +58,7 @@
#define _IA64_REG_AR_LC 3137 #define _IA64_REG_AR_LC 3137
#define _IA64_REG_AR_EC 3138 #define _IA64_REG_AR_EC 3138
/* Control Registers */ /* Control Registers */
#define _IA64_REG_CR_DCR 4096 #define _IA64_REG_CR_DCR 4096
#define _IA64_REG_CR_ITM 4097 #define _IA64_REG_CR_ITM 4097
...@@ -84,7 +87,7 @@ ...@@ -84,7 +87,7 @@
#define _IA64_REG_CR_LRR0 4176 #define _IA64_REG_CR_LRR0 4176
#define _IA64_REG_CR_LRR1 4177 #define _IA64_REG_CR_LRR1 4177
/* Indirect Registers for getindreg() and setindreg() */ /* Indirect Registers for getindreg() and setindreg() */
#define _IA64_REG_INDR_CPUID 9000 /* getindreg only */ #define _IA64_REG_INDR_CPUID 9000 /* getindreg only */
#define _IA64_REG_INDR_DBR 9001 #define _IA64_REG_INDR_DBR 9001
...@@ -94,5 +97,4 @@ ...@@ -94,5 +97,4 @@
#define _IA64_REG_INDR_PMD 9005 #define _IA64_REG_INDR_PMD 9005
#define _IA64_REG_INDR_RR 9006 #define _IA64_REG_INDR_RR 9006
#endif /* _ASM_IA64_IA64REGS_H */ #endif /* _ASM_IA64_IA64REGS_H */
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
/* include compiler specific intrinsics */ /* include compiler specific intrinsics */
#include <asm/ia64regs.h> #include <asm/ia64regs.h>
#ifdef __INTEL_COMPILER #ifdef __INTEL_COMPILER
#include <asm/intel_intrin.h> # include <asm/intel_intrin.h>
#else #else
#include <asm/gcc_intrin.h> # include <asm/gcc_intrin.h>
#endif #endif
/* /*
...@@ -117,7 +117,7 @@ extern void ia64_xchg_called_with_bad_pointer (void); ...@@ -117,7 +117,7 @@ extern void ia64_xchg_called_with_bad_pointer (void);
* This function doesn't exist, so you'll get a linker error * This function doesn't exist, so you'll get a linker error
* if something tries to do an invalid cmpxchg(). * if something tries to do an invalid cmpxchg().
*/ */
extern long ia64_cmpxchg_called_with_bad_pointer(void); extern long ia64_cmpxchg_called_with_bad_pointer (void);
#define ia64_cmpxchg(sem,ptr,old,new,size) \ #define ia64_cmpxchg(sem,ptr,old,new,size) \
({ \ ({ \
......
...@@ -52,10 +52,10 @@ extern unsigned int num_io_spaces; ...@@ -52,10 +52,10 @@ extern unsigned int num_io_spaces;
# ifdef __KERNEL__ # ifdef __KERNEL__
#include <asm/intrinsics.h>
#include <asm/machvec.h> #include <asm/machvec.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/intrinsics.h>
/* /*
* Change virtual addresses to physical addresses and vv. * Change virtual addresses to physical addresses and vv.
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
#include <linux/config.h> #include <linux/config.h>
#include <asm/types.h>
#include <asm/intrinsics.h> #include <asm/intrinsics.h>
#include <asm/types.h>
/* /*
* PAGE_SHIFT determines the actual kernel page size. * PAGE_SHIFT determines the actual kernel page size.
......
...@@ -15,10 +15,10 @@ ...@@ -15,10 +15,10 @@
#include <linux/config.h> #include <linux/config.h>
#include <asm/ptrace.h> #include <asm/intrinsics.h>
#include <asm/kregs.h> #include <asm/kregs.h>
#include <asm/ptrace.h>
#include <asm/ustack.h> #include <asm/ustack.h>
#include <asm/intrinsics.h>
#define IA64_NUM_DBG_REGS 8 #define IA64_NUM_DBG_REGS 8
/* /*
...@@ -357,13 +357,12 @@ extern unsigned long get_wchan (struct task_struct *p); ...@@ -357,13 +357,12 @@ extern unsigned long get_wchan (struct task_struct *p);
/* Return stack pointer of blocked task TSK. */ /* Return stack pointer of blocked task TSK. */
#define KSTK_ESP(tsk) ((tsk)->thread.ksp) #define KSTK_ESP(tsk) ((tsk)->thread.ksp)
extern void ia64_getreg_unknown_kr(void); extern void ia64_getreg_unknown_kr (void);
extern void ia64_setreg_unknown_kr(void); extern void ia64_setreg_unknown_kr (void);
#define ia64_get_kr(regnum) \ #define ia64_get_kr(regnum) \
({ \ ({ \
unsigned long r=0; \ unsigned long r = 0; \
\ \
switch (regnum) { \ switch (regnum) { \
case 0: r = ia64_getreg(_IA64_REG_AR_KR0); break; \ case 0: r = ia64_getreg(_IA64_REG_AR_KR0); break; \
...@@ -646,18 +645,18 @@ ia64_get_dbr (__u64 regnum) ...@@ -646,18 +645,18 @@ ia64_get_dbr (__u64 regnum)
/* XXX remove the handcoded version once we have a sufficiently clever compiler... */ /* XXX remove the handcoded version once we have a sufficiently clever compiler... */
#ifdef SMART_COMPILER #ifdef SMART_COMPILER
# define ia64_rotr(w,n) \ # define ia64_rotr(w,n) \
({ \ ({ \
__u64 _w = (w), _n = (n); \ __u64 __ia64_rotr_w = (w), _n = (n); \
\ \
(_w >> _n) | (_w << (64 - _n)); \ (__ia64_rotr_w >> _n) | (__ia64_rotr_w << (64 - _n)); \
}) })
#else #else
# define ia64_rotr(w,n) \ # define ia64_rotr(w,n) \
({ \ ({ \
__u64 result; \ __u64 __ia64_rotr_w; \
result = ia64_shrp((w), (w), (n)); \ __ia64_rotr_w = ia64_shrp((w), (w), (n)); \
result; \ __ia64_rotr_w; \
}) })
#endif #endif
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <asm/intrinsics.h> #include <asm/intrinsics.h>
/* /*
...@@ -82,9 +83,7 @@ init_rwsem (struct rw_semaphore *sem) ...@@ -82,9 +83,7 @@ init_rwsem (struct rw_semaphore *sem)
static inline void static inline void
__down_read (struct rw_semaphore *sem) __down_read (struct rw_semaphore *sem)
{ {
int result; int result = ia64_fetchadd4_acq((unsigned int *)&sem->count, 1);
result = ia64_fetchadd4_acq((unsigned int *)&sem->count, 1);
if (result < 0) if (result < 0)
rwsem_down_read_failed(sem); rwsem_down_read_failed(sem);
...@@ -113,9 +112,7 @@ __down_write (struct rw_semaphore *sem) ...@@ -113,9 +112,7 @@ __down_write (struct rw_semaphore *sem)
static inline void static inline void
__up_read (struct rw_semaphore *sem) __up_read (struct rw_semaphore *sem)
{ {
int result; int result = ia64_fetchadd4_rel((unsigned int *)&sem->count, -1);
result = ia64_fetchadd4_rel((unsigned int *)&sem->count, -1);
if (result < 0 && (--result & RWSEM_ACTIVE_MASK) == 0) if (result < 0 && (--result & RWSEM_ACTIVE_MASK) == 0)
rwsem_wake(sem); rwsem_wake(sem);
......
...@@ -79,7 +79,6 @@ typedef struct siginfo { ...@@ -79,7 +79,6 @@ typedef struct siginfo {
* si_code is non-zero and __ISR_VALID is set in si_flags. * si_code is non-zero and __ISR_VALID is set in si_flags.
*/ */
#define si_isr _sifields._sigfault._isr #define si_isr _sifields._sigfault._isr
#define si_pfm_ovfl _sifields._sigprof._pfm_ovfl_counters
/* /*
* Flag values for si_flags: * Flag values for si_flags:
......
...@@ -120,7 +120,7 @@ hard_smp_processor_id (void) ...@@ -120,7 +120,7 @@ hard_smp_processor_id (void)
unsigned long bits; unsigned long bits;
} lid; } lid;
lid.bits = ia64_getreg(_IA64_REG_CR_LID); lid.bits = ia64_getreg(_IA64_REG_CR_LID);
return lid.f.id << 8 | lid.f.eid; return lid.f.id << 8 | lid.f.eid;
} }
......
...@@ -9,13 +9,13 @@ ...@@ -9,13 +9,13 @@
* This file is used for SMP configurations only. * This file is used for SMP configurations only.
*/ */
#include <linux/kernel.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/kernel.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/bitops.h>
#include <asm/intrinsics.h> #include <asm/intrinsics.h>
#include <asm/system.h>
typedef struct { typedef struct {
volatile unsigned int lock; volatile unsigned int lock;
......
...@@ -113,19 +113,17 @@ extern struct ia64_boot_param { ...@@ -113,19 +113,17 @@ extern struct ia64_boot_param {
/* clearing psr.i is implicitly serialized (visible by next insn) */ /* clearing psr.i is implicitly serialized (visible by next insn) */
/* setting psr.i requires data serialization */ /* setting psr.i requires data serialization */
#define __local_irq_save(x) \ #define __local_irq_save(x) \
do { \ do { \
unsigned long psr; \ (x) = ia64_getreg(_IA64_REG_PSR); \
psr = ia64_getreg(_IA64_REG_PSR); \ ia64_stop(); \
ia64_stop(); \ ia64_rsm(IA64_PSR_I); \
ia64_rsm(IA64_PSR_I); \
(x) = psr; \
} while (0) } while (0)
#define __local_irq_disable() \ #define __local_irq_disable() \
do { \ do { \
ia64_stop(); \ ia64_stop(); \
ia64_rsm(IA64_PSR_I); \ ia64_rsm(IA64_PSR_I); \
} while (0) } while (0)
#define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I) #define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I)
...@@ -165,13 +163,13 @@ do { \ ...@@ -165,13 +163,13 @@ do { \
#endif /* !CONFIG_IA64_DEBUG_IRQ */ #endif /* !CONFIG_IA64_DEBUG_IRQ */
#define local_irq_enable() ({ ia64_ssm(IA64_PSR_I); ia64_srlz_d(); }) #define local_irq_enable() ({ ia64_ssm(IA64_PSR_I); ia64_srlz_d(); })
#define local_save_flags(flags) ({ (flags) = ia64_getreg(_IA64_REG_PSR); }) #define local_save_flags(flags) ((flags) = ia64_getreg(_IA64_REG_PSR))
#define irqs_disabled() \ #define irqs_disabled() \
({ \ ({ \
unsigned long flags; \ unsigned long __ia64_id_flags; \
local_save_flags(flags); \ local_save_flags(__ia64_id_flags); \
(flags & IA64_PSR_I) == 0; \ (__ia64_id_flags & IA64_PSR_I) == 0; \
}) })
#ifdef __KERNEL__ #ifdef __KERNEL__
......
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
* Also removed cacheflush_time as it's entirely unused. * Also removed cacheflush_time as it's entirely unused.
*/ */
#include <asm/processor.h>
#include <asm/intrinsics.h> #include <asm/intrinsics.h>
#include <asm/processor.h>
typedef unsigned long cycles_t; typedef unsigned long cycles_t;
......
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <asm/intrinsics.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/intrinsics.h>
/* /*
* Now for some TLB flushing routines. This is the kind of stuff that * Now for some TLB flushing routines. This is the kind of stuff that
......
...@@ -342,8 +342,10 @@ extern pid_t clone (unsigned long flags, void *sp); ...@@ -342,8 +342,10 @@ extern pid_t clone (unsigned long flags, void *sp);
/* /*
* "Conditional" syscalls * "Conditional" syscalls
* *
* Note, this macro can only be used in the * Note, this macro can only be used in the file which defines sys_ni_syscall, i.e., in
* file which defines sys_ni_syscall, i.e., in kernel/sys.c. * kernel/sys.c. This version causes warnings because the declaration isn't a
* proper prototype, but we can't use __typeof__ either, because not all cond_syscall()
* declarations have prototypes at the moment.
*/ */
#define cond_syscall(x) asmlinkage long x() __attribute__((weak,alias("sys_ni_syscall"))); #define cond_syscall(x) asmlinkage long x() __attribute__((weak,alias("sys_ni_syscall")));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment