Commit eb1a40d9 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://lia64.bkbits.net/to-linus-2.5

into home.osdl.org:/home/torvalds/v2.5/linux
parents 91a7d546 d93c4308
......@@ -4,7 +4,7 @@
-----------------------------------
Started: 13-Jan-2003
Last update: 11-Feb-2003
Last update: 27-Sep-2003
David Mosberger-Tang
<davidm@hpl.hp.com>
......@@ -146,6 +146,12 @@ speed comes a set of restrictions:
task pointer is not considered sensitive: it's already exposed
through ar.k6).
o Fsyscall-handlers MUST NOT access user-memory without first
validating access-permission (this can be done typically via
probe.r.fault and/or probe.w.fault) and without guarding against
memory access exceptions (this can be done with the EX() macros
defined by asmmacro.h).
The above restrictions may seem draconian, but remember that it's
possible to trade off some of the restrictions by paying a slightly
higher overhead. For example, if an fsyscall-handler could benefit
......@@ -229,3 +235,52 @@ PSR.ed Unchanged. Note: This bit could only have an effect if an fsys-mode
PSR.bn Unchanged. Note: fsys-mode handlers may clear the bit, if needed.
Doing so requires clearing PSR.i and PSR.ic as well.
PSR.ia Unchanged. Note: the ia64 linux kernel never sets this bit.
* Using fast system calls
To use fast system calls, userspace applications need simply call
__kernel_syscall_via_epc(). For example
-- example fgettimeofday() call --
-- fgettimeofday.S --
#include <asm/asmmacro.h>
GLOBAL_ENTRY(fgettimeofday)
.prologue
.save ar.pfs, r11
mov r11 = ar.pfs
.body
mov r2 = 0xa000000000020660;; // gate address
// found by inspection of System.map for the
// __kernel_syscall_via_epc() function. See
// below for how to do this for real.
mov b7 = r2
mov r15 = 1087 // gettimeofday syscall
;;
br.call.sptk.many b6 = b7
;;
.restore sp
mov ar.pfs = r11
br.ret.sptk.many rp;; // return to caller
END(fgettimeofday)
-- end fgettimeofday.S --
In reality, getting the gate address is accomplished by two extra
values passed via the ELF auxiliary vector (include/asm-ia64/elf.h)
o AT_SYSINFO : is the address of __kernel_syscall_via_epc()
o AT_SYSINFO_EHDR : is the address of the kernel gate ELF DSO
The ELF DSO is a pre-linked library that is mapped in by the kernel at
the gate page. It is a proper ELF shared object so, with a dynamic
loader that recognises the library, you should be able to make calls to
the exported functions within it as with any other shared library.
AT_SYSINFO points into the kernel DSO at the
__kernel_syscall_via_epc() function for historical reasons (it was
used before the kernel DSO) and as a convenience.
......@@ -57,6 +57,10 @@ choice
config IA64_GENERIC
bool "generic"
select NUMA
select ACPI_NUMA
select VIRTUAL_MEM_MAP
select DISCONTIGMEM
---help---
This selects the system type of your hardware. A "generic" kernel
will run on any supported IA-64 system. However, if you configure
......
......@@ -56,6 +56,7 @@ void (*pm_idle) (void);
void (*pm_power_off) (void);
unsigned char acpi_kbd_controller_present = 1;
unsigned char acpi_legacy_devices;
int acpi_disabled; /* XXX this shouldn't be needed---we can't boot without ACPI! */
......@@ -509,6 +510,9 @@ acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
acpi_kbd_controller_present = 0;
if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES)
acpi_legacy_devices = 1;
acpi_register_irq(fadt->sci_int, ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE);
return 0;
}
......
......@@ -33,16 +33,30 @@ void foo(void)
BLANK();
DEFINE(IA64_TASK_BLOCKED_OFFSET,offsetof (struct task_struct, blocked));
DEFINE(IA64_TASK_CLEAR_CHILD_TID_OFFSET,offsetof (struct task_struct, clear_child_tid));
DEFINE(IA64_TASK_GROUP_LEADER_OFFSET, offsetof (struct task_struct, group_leader));
DEFINE(IA64_TASK_PENDING_OFFSET,offsetof (struct task_struct, pending));
DEFINE(IA64_TASK_PID_OFFSET, offsetof (struct task_struct, pid));
DEFINE(IA64_TASK_REAL_PARENT_OFFSET, offsetof (struct task_struct, real_parent));
DEFINE(IA64_TASK_SIGHAND_OFFSET,offsetof (struct task_struct, sighand));
DEFINE(IA64_TASK_SIGNAL_OFFSET,offsetof (struct task_struct, signal));
DEFINE(IA64_TASK_TGID_OFFSET, offsetof (struct task_struct, tgid));
DEFINE(IA64_TASK_THREAD_KSP_OFFSET, offsetof (struct task_struct, thread.ksp));
DEFINE(IA64_TASK_THREAD_ON_USTACK_OFFSET, offsetof (struct task_struct, thread.on_ustack));
BLANK();
DEFINE(IA64_SIGHAND_SIGLOCK_OFFSET,offsetof (struct sighand_struct, siglock));
BLANK();
DEFINE(IA64_SIGNAL_GROUP_STOP_COUNT_OFFSET,offsetof (struct signal_struct,
group_stop_count));
DEFINE(IA64_SIGNAL_SHARED_PENDING_OFFSET,offsetof (struct signal_struct, shared_pending));
BLANK();
DEFINE(IA64_PT_REGS_B6_OFFSET, offsetof (struct pt_regs, b6));
DEFINE(IA64_PT_REGS_B7_OFFSET, offsetof (struct pt_regs, b7));
DEFINE(IA64_PT_REGS_AR_CSD_OFFSET, offsetof (struct pt_regs, ar_csd));
......@@ -158,6 +172,10 @@ void foo(void)
BLANK();
DEFINE(IA64_SIGPENDING_SIGNAL_OFFSET, offsetof (struct sigpending, signal));
BLANK();
DEFINE(IA64_SIGFRAME_ARG0_OFFSET, offsetof (struct sigframe, arg0));
DEFINE(IA64_SIGFRAME_ARG1_OFFSET, offsetof (struct sigframe, arg1));
DEFINE(IA64_SIGFRAME_ARG2_OFFSET, offsetof (struct sigframe, arg2));
......
......@@ -4,6 +4,7 @@
* Copyright (C) 2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*
* 25-Sep-03 davidm Implement fsys_rt_sigprocmask().
* 18-Feb-03 louisk Implement fsys_gettimeofday().
* 28-Feb-03 davidm Fixed several bugs in fsys_gettimeofday(). Tuned it some more,
* probably broke it along the way... ;-)
......@@ -15,6 +16,7 @@
#include <asm/percpu.h>
#include <asm/thread_info.h>
#include <asm/sal.h>
#include <asm/signal.h>
#include <asm/system.h>
#include <asm/unistd.h>
......@@ -48,8 +50,7 @@ ENTRY(fsys_ni_syscall)
.body
mov r8=ENOSYS
mov r10=-1
MCKINLEY_E9_WORKAROUND
br.ret.sptk.many b6
FSYS_RETURN
END(fsys_ni_syscall)
ENTRY(fsys_getpid)
......@@ -66,8 +67,7 @@ ENTRY(fsys_getpid)
;;
cmp.ne p8,p0=0,r9
(p8) br.spnt.many fsys_fallback_syscall
MCKINLEY_E9_WORKAROUND
br.ret.sptk.many b6
FSYS_RETURN
END(fsys_getpid)
ENTRY(fsys_getppid)
......@@ -114,8 +114,7 @@ ENTRY(fsys_getppid)
mov r18=0 // i must not leak kernel bits...
mov r19=0 // i must not leak kernel bits...
#endif
MCKINLEY_E9_WORKAROUND
br.ret.sptk.many b6
FSYS_RETURN
END(fsys_getppid)
ENTRY(fsys_set_tid_address)
......@@ -141,8 +140,7 @@ ENTRY(fsys_set_tid_address)
;;
mov r17=0 // i must not leak kernel bits...
mov r18=0 // i must not leak kernel bits...
MCKINLEY_E9_WORKAROUND
br.ret.sptk.many b6
FSYS_RETURN
END(fsys_set_tid_address)
/*
......@@ -199,7 +197,7 @@ ENTRY(fsys_gettimeofday)
adds r10=IA64_CPUINFO_ITM_DELTA_OFFSET, r10
(p7) tnat.nz p6,p0=r33
(p6) br.cond.spnt.few .fail
(p6) br.cond.spnt.few .fail_einval
adds r8=IA64_CPUINFO_NSEC_PER_CYC_OFFSET, r3
movl r24=2361183241434822607 // for division hack (only for / 1000)
......@@ -225,8 +223,8 @@ ENTRY(fsys_gettimeofday)
* to store the result. That's OK as long as the stores are also
* protect by EX().
*/
EX(.fail, probe.w.fault r32, 3) // this must come _after_ NaT-check
EX(.fail, probe.w.fault r10, 3) // this must come _after_ NaT-check
EX(.fail_efault, probe.w.fault r32, 3) // this must come _after_ NaT-check
EX(.fail_efault, probe.w.fault r10, 3) // this must come _after_ NaT-check
nop 0
ldf8 f10=[r8] // f10 <- local_cpu_data->nsec_per_cyc value
......@@ -311,14 +309,13 @@ EX(.fail, probe.w.fault r10, 3) // this must come _after_ NaT-check
(p7) br.spnt.many 1b
// finally: r2 = sec, r3 = usec
EX(.fail, st8 [r32]=r2)
EX(.fail_efault, st8 [r32]=r2)
adds r9=8, r32
mov r8=r0 // success
;;
EX(.fail, st8 [r9]=r3) // store them in the timeval struct
EX(.fail_efault, st8 [r9]=r3) // store them in the timeval struct
mov r10=0
MCKINLEY_E9_WORKAROUND
br.ret.sptk.many b6 // return to caller
FSYS_RETURN
/*
* Note: We are NOT clearing the scratch registers here. Since the only things
* in those registers are time-related variables and some addresses (which
......@@ -326,12 +323,183 @@ EX(.fail, st8 [r9]=r3) // store them in the timeval struct
* and we should be fine.
*/
.fail: adds r8=EINVAL, r0 // r8 = EINVAL
adds r10=-1, r0 // r10 = -1
MCKINLEY_E9_WORKAROUND
br.ret.spnt.many b6 // return with r8 set to EINVAL
.fail_einval:
mov r8=EINVAL // r8 = EINVAL
mov r10=-1 // r10 = -1
FSYS_RETURN
.fail_efault:
mov r8=EFAULT // r8 = EFAULT
mov r10=-1 // r10 = -1
FSYS_RETURN
END(fsys_gettimeofday)
/*
* long fsys_rt_sigprocmask (int how, sigset_t *set, sigset_t *oset, size_t sigsetsize).
*/
#if _NSIG_WORDS != 1
# error Sorry, fsys_rt_sigprocmask() needs to be updated for _NSIG_WORDS != 1.
#endif
ENTRY(fsys_rt_sigprocmask)
.prologue
.altrp b6
.body
mf // ensure reading of current->blocked is ordered
add r2=IA64_TASK_BLOCKED_OFFSET,r16
add r9=TI_FLAGS+IA64_TASK_SIZE,r16
;;
/*
* Since we're only reading a single word, we can do it
* atomically without acquiring current->sighand->siglock. To
* be on the safe side, we need a fully-ordered load, though:
*/
ld8.acq r3=[r2] // read/prefetch current->blocked
ld4 r9=[r9]
add r31=IA64_TASK_SIGHAND_OFFSET,r16
;;
#ifdef CONFIG_SMP
ld8 r31=[r31] // r31 <- current->sighand
#endif
and r9=TIF_ALLWORK_MASK,r9
tnat.nz p6,p0=r32
;;
cmp.ne p7,p0=0,r9
tnat.nz.or p6,p0=r35
tnat.nz p8,p0=r34
;;
cmp.ne p15,p0=r0,r34 // oset != NULL?
cmp.ne.or p6,p0=_NSIG_WORDS*8,r35
tnat.nz.or p8,p0=r33
(p6) br.spnt.few .fail_einval // fail with EINVAL
(p7) br.spnt.many fsys_fallback_syscall // got pending kernel work...
(p8) br.spnt.few .fail_efault // fail with EFAULT
;;
cmp.eq p6,p7=r0,r33 // set == NULL?
add r31=IA64_SIGHAND_SIGLOCK_OFFSET,r31 // r31 <- current->sighand->siglock
(p6) br.dpnt.many .store_mask // -> short-circuit to just reading the signal mask
/* Argh, we actually have to do some work and _update_ the signal mask: */
EX(.fail_efault, probe.r.fault r33, 3) // verify user has read-access to *set
EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set
mov r17=(1 << (SIGKILL - 1)) | (1 << (SIGSTOP - 1))
;;
rsm psr.i // mask interrupt delivery
mov ar.ccv=0
andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP
#ifdef CONFIG_SMP
mov r17=1
;;
cmpxchg4.acq r18=[r31],r17,ar.ccv // try to acquire the lock
mov r8=EINVAL // default to EINVAL
;;
ld8 r3=[r2] // re-read current->blocked now that we hold the lock
cmp4.ne p6,p0=r18,r0
(p6) br.cond.spnt.many .lock_contention
;;
#else
ld8 r3=[r2] // re-read current->blocked now that we hold the lock
mov r8=EINVAL // default to EINVAL
#endif
add r18=IA64_TASK_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r16
add r19=IA64_TASK_SIGNAL_OFFSET,r16
cmp4.eq p6,p0=SIG_BLOCK,r32
;;
ld8 r19=[r19] // r19 <- current->signal
cmp4.eq p7,p0=SIG_UNBLOCK,r32
cmp4.eq p8,p0=SIG_SETMASK,r32
;;
ld8 r18=[r18] // r18 <- current->pending.signal
.pred.rel.mutex p6,p7,p8
(p6) or r3=r3,r14 // SIG_BLOCK
(p7) andcm r3=r3,r14 // SIG_UNBLOCK
(p8) mov r3=r14 // SIG_SETMASK
(p6) mov r8=0 // clear error code
// recalc_sigpending()
add r17=IA64_SIGNAL_GROUP_STOP_COUNT_OFFSET,r19
add r19=IA64_SIGNAL_SHARED_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r19
;;
ld4 r17=[r17] // r17 <- current->signal->group_stop_count
(p7) mov r8=0 // clear error code
ld8 r19=[r19] // r19 <- current->signal->shared_pending
;;
cmp4.gt p6,p7=r17,r0 // p6/p7 <- (current->signal->group_stop_count > 0)?
(p8) mov r8=0 // clear error code
or r18=r18,r19 // r18 <- current->pending | current->signal->shared_pending
;;
// r18 <- (current->pending | current->signal->shared_pending) & ~current->blocked:
andcm r18=r18,r3
add r9=TI_FLAGS+IA64_TASK_SIZE,r16
;;
(p7) cmp.ne.or.andcm p6,p7=r18,r0 // p6/p7 <- signal pending
mov r19=0 // i must not leak kernel bits...
(p6) br.cond.dpnt.many .sig_pending
;;
1: ld4 r17=[r9] // r17 <- current->thread_info->flags
;;
mov ar.ccv=r17
and r18=~_TIF_SIGPENDING,r17 // r18 <- r17 & ~(1 << TIF_SIGPENDING)
;;
st8 [r2]=r3 // update current->blocked with new mask
cmpxchg4.acq r14=[r9],r18,ar.ccv // current->thread_info->flags <- r18
;;
cmp.ne p6,p0=r17,r14 // update failed?
(p6) br.cond.spnt.few 1b // yes -> retry
#ifdef CONFIG_SMP
st4.rel [r31]=r0 // release the lock
#endif
ssm psr.i
cmp.ne p9,p0=r8,r0 // check for bad HOW value
;;
srlz.d // ensure psr.i is set again
mov r18=0 // i must not leak kernel bits...
(p9) br.spnt.few .fail_einval // bail out for bad HOW value
.store_mask:
EX(.fail_efault, (p15) probe.w.fault r34, 3) // verify user has write-access to *oset
EX(.fail_efault, (p15) st8 [r34]=r3)
mov r2=0 // i must not leak kernel bits...
mov r3=0 // i must not leak kernel bits...
mov r8=0 // return 0
mov r9=0 // i must not leak kernel bits...
mov r14=0 // i must not leak kernel bits...
mov r17=0 // i must not leak kernel bits...
mov r31=0 // i must not leak kernel bits...
FSYS_RETURN
.sig_pending:
#ifdef CONFIG_SMP
st4.rel [r31]=r0 // release the lock
#endif
ssm psr.i
;;
srlz.d
br.sptk.many fsys_fallback_syscall // with signal pending, do the heavy-weight syscall
#ifdef CONFIG_SMP
.lock_contention:
/* Rather than spinning here, fall back on doing a heavy-weight syscall. */
ssm psr.i
;;
srlz.d
br.sptk.many fsys_fallback_syscall
#endif
END(fsys_rt_sigprocmask)
ENTRY(fsys_fallback_syscall)
.prologue
.altrp b6
......@@ -600,7 +768,7 @@ fsyscall_table:
data8 0 // sigaltstack
data8 0 // rt_sigaction
data8 0 // rt_sigpending
data8 0 // rt_sigprocmask
data8 fsys_rt_sigprocmask // rt_sigprocmask
data8 0 // rt_sigqueueinfo // 1180
data8 0 // rt_sigreturn
data8 0 // rt_sigsuspend
......
......@@ -118,8 +118,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
mov r10=-1
mov r8=ENOSYS
MCKINLEY_E9_WORKAROUND
br.ret.sptk.many b6
FSYS_RETURN
END(__kernel_syscall_via_epc)
# define ARG0_OFF (16 + IA64_SIGFRAME_ARG0_OFFSET)
......
......@@ -797,6 +797,25 @@ GLOBAL_ENTRY(ia64_switch_mode_virt)
br.ret.sptk.many rp
END(ia64_switch_mode_virt)
GLOBAL_ENTRY(ia64_delay_loop)
.prologue
{ nop 0 // work around GAS unwind info generation bug...
.save ar.lc,r2
mov r2=ar.lc
.body
;;
mov ar.lc=r32
}
;;
// force loop to be 32-byte aligned (GAS bug means we cannot use .align
// inside function body without corrupting unwind info).
{ nop 0 }
1: br.cloop.sptk.few 1b
;;
mov ar.lc=r2
br.ret.sptk.many rp
END(ia64_delay_loop)
#ifdef CONFIG_IA64_BRL_EMU
/*
......
......@@ -81,8 +81,6 @@ u64 ia64_init_stack[KERNEL_STACK_SIZE/8] __attribute__((aligned(16)));
u64 ia64_mca_sal_data_area[1356];
u64 ia64_tlb_functional;
u64 ia64_os_mca_recovery_successful;
/* TODO: need to assign min-state structure to UC memory */
u64 ia64_mca_min_state_save_info[MIN_STATE_AREA_SIZE] __attribute__((aligned(512)));
static void ia64_mca_wakeup_ipi_wait(void);
static void ia64_mca_wakeup(int cpu);
static void ia64_mca_wakeup_all(void);
......@@ -465,26 +463,6 @@ ia64_mca_register_cpev (int cpev)
#endif /* PLATFORM_MCA_HANDLERS */
/*
* routine to process and prepare to dump min_state_save
* information for debugging purposes.
*/
void
ia64_process_min_state_save (pal_min_state_area_t *pmss)
{
int i, max = MIN_STATE_AREA_SIZE;
u64 *tpmss_ptr = (u64 *)pmss;
u64 *return_min_state_ptr = ia64_mca_min_state_save_info;
for (i=0;i<max;i++) {
/* copy min-state register info for eventual return to PAL */
*return_min_state_ptr++ = *tpmss_ptr;
tpmss_ptr++; /* skip to next entry */
}
}
/*
* ia64_mca_cmc_vector_setup
*
......@@ -828,7 +806,7 @@ ia64_mca_wakeup_ipi_wait(void)
irr = ia64_getreg(_IA64_REG_CR_IRR3);
break;
}
} while (!(irr & (1 << irr_bit))) ;
} while (!(irr & (1UL << irr_bit))) ;
}
/*
......@@ -961,9 +939,8 @@ ia64_return_to_sal_check(void)
/* Default = tell SAL to return to same context */
ia64_os_to_sal_handoff_state.imots_context = IA64_MCA_SAME_CONTEXT;
/* Register pointer to new min state values */
ia64_os_to_sal_handoff_state.imots_new_min_state =
ia64_mca_min_state_save_info;
(u64 *)ia64_sal_to_os_handoff_state.pal_min_state;
}
/*
......@@ -2154,9 +2131,6 @@ ia64_log_proc_dev_err_info_print (sal_log_processor_info_t *slpi,
if (slpi->valid.psi_static_struct) {
spsi = (sal_processor_static_info_t *)p_data;
/* copy interrupted context PAL min-state info */
ia64_process_min_state_save(&spsi->min_state_area);
/* Print branch register contents if valid */
if (spsi->valid.br)
ia64_log_processor_regs_print(spsi->br, 8, "Branch", "br",
......
......@@ -77,12 +77,11 @@
(p6) movl r10=IA64_MCA_SAME_CONTEXT; \
(p6) add _tmp=0x18,_tmp;; \
(p6) ld8 r9=[_tmp],0x10; \
(p6) movl r22=ia64_mca_min_state_save_info;; \
(p6) mov r22=r0;; \
(p7) ld8 r8=[_tmp],0x08;; \
(p7) ld8 r9=[_tmp],0x08;; \
(p7) ld8 r10=[_tmp],0x08;; \
(p7) ld8 r22=[_tmp],0x08;; \
DATA_VA_TO_PA(r22)
(p7) ld8 r22=[_tmp],0x08;;
// now _tmp is pointing to SAL rtn save location
......@@ -97,7 +96,6 @@
.global ia64_init_stack
.global ia64_mca_sal_data_area
.global ia64_tlb_functional
.global ia64_mca_min_state_save_info
.text
.align 16
......
......@@ -130,9 +130,11 @@ ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
while (offp < (s32 *) end) {
wp = (u64 *) ia64_imva((char *) offp + *offp);
wp[0] = 0x0000000100000000;
wp[0] = 0x0000000100000000; /* nop.m 0; nop.i 0; nop.i 0 */
wp[1] = 0x0004000000000200;
ia64_fc(wp);
wp[2] = 0x0000000100000011; /* nop.m 0; nop.i 0; br.ret.sptk.many b6 */
wp[3] = 0x0084006880000200;
ia64_fc(wp); ia64_fc(wp + 2);
++offp;
}
ia64_sync_i();
......
This diff is collapsed.
......@@ -81,6 +81,8 @@ pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu
*/
if (cnum == 13 && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) {
DPRINT(("pmc[%d]=0x%lx has active pmc13.ta cleared, clearing ibr\n", cnum, *val));
/* don't mix debug with perfmon */
if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
......@@ -98,6 +100,8 @@ pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu
*/
if (cnum == 11 && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) {
DPRINT(("pmc[%d]=0x%lx has active pmc11.pt cleared, clearing dbr\n", cnum, *val));
/* don't mix debug with perfmon */
if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
......
......@@ -109,10 +109,20 @@ pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu
if (ctx == NULL) return -EINVAL;
/*
* we must clear the debug registers if any pmc13.ena_dbrpX bit is enabled
* before they are written (fl_using_dbreg==0) to avoid picking up stale information.
* we must clear the debug registers if pmc13 has a value which enable
* memory pipeline event constraints. In this case we need to clear the
* the debug registers if they have not yet been accessed. This is required
* to avoid picking stale state.
* PMC13 is "active" if:
* one of the pmc13.cfg_dbrpXX field is different from 0x3
* AND
* at the corresponding pmc13.ena_dbrpXX is set.
*
* For now, we just check on cfg_dbrXX != 0x3.
*/
if (cnum == 13 && (*val & (0xfUL << 45)) && ctx->ctx_fl_using_dbreg == 0) {
if (cnum == 13 && ((*val & 0x18181818UL) != 0x18181818UL) && ctx->ctx_fl_using_dbreg == 0) {
DPRINT(("pmc[%d]=0x%lx has active pmc13 settings, clearing dbr\n", cnum, *val));
/* don't mix debug with perfmon */
if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
......@@ -128,7 +138,9 @@ pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu
* we must clear the (instruction) debug registers if any pmc14.ibrpX bit is enabled
* before they are (fl_using_dbreg==0) to avoid picking up stale information.
*/
if (cnum == 14 && ((*val & 0x2222) != 0x2222) && ctx->ctx_fl_using_dbreg == 0) {
if (cnum == 14 && ((*val & 0x2222UL) != 0x2222UL) && ctx->ctx_fl_using_dbreg == 0) {
DPRINT(("pmc[%d]=0x%lx has active pmc14 settings, clearing ibr\n", cnum, *val));
/* don't mix debug with perfmon */
if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
......@@ -170,7 +182,7 @@ pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu
&& ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0)
||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0));
if (ret) printk("perfmon: failure check_case1\n");
if (ret) DPRINT((KERN_DEBUG "perfmon: failure check_case1\n"));
}
return ret ? -EINVAL : 0;
......
......@@ -30,6 +30,8 @@
#include <linux/string.h>
#include <linux/threads.h>
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/efi.h>
#include <linux/initrd.h>
......@@ -43,6 +45,7 @@
#include <asm/processor.h>
#include <asm/sal.h>
#include <asm/sections.h>
#include <asm/serial.h>
#include <asm/smp.h>
#include <asm/system.h>
#include <asm/unistd.h>
......@@ -221,6 +224,25 @@ find_initrd (void)
#endif
}
#ifdef CONFIG_SERIAL_8250_CONSOLE
static void __init
setup_serial_legacy (void)
{
struct uart_port port;
unsigned int i, iobase[] = {0x3f8, 0x2f8};
printk(KERN_INFO "Registering legacy COM ports for serial console\n");
memset(&port, 0, sizeof(port));
port.iotype = SERIAL_IO_PORT;
port.uartclk = BASE_BAUD * 16;
for (i = 0; i < ARRAY_SIZE(iobase); i++) {
port.line = i;
port.iobase = iobase[i];
early_serial_setup(&port);
}
}
#endif
void __init
setup_arch (char **cmdline_p)
{
......@@ -294,11 +316,22 @@ setup_arch (char **cmdline_p)
#ifdef CONFIG_SERIAL_8250_HCDP
if (efi.hcdp) {
void setup_serial_hcdp(void *);
/* Setup the serial ports described by HCDP */
setup_serial_hcdp(efi.hcdp);
}
#endif
#ifdef CONFIG_SERIAL_8250_CONSOLE
/*
* Without HCDP, we won't discover any serial ports until the serial driver looks
* in the ACPI namespace. If ACPI claims there are some legacy devices, register
* the legacy COM ports so serial console works earlier. This is slightly dangerous
* because we don't *really* know whether there's anything there, but we hope that
* all new boxes will implement HCDP.
*/
extern unsigned char acpi_legacy_devices;
if (!efi.hcdp && acpi_legacy_devices)
setup_serial_legacy();
#endif
#ifdef CONFIG_VT
# if defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con;
......
......@@ -65,8 +65,12 @@ itc_update (long delta_nsec)
}
/*
* Return the number of nano-seconds that elapsed since the last update to jiffy. The
* xtime_lock must be at least read-locked when calling this routine.
* Return the number of nano-seconds that elapsed since the last
* update to jiffy. It is quite possible that the timer interrupt
* will interrupt this and result in a race for any of jiffies,
* wall_jiffies or itm_next. Thus, the xtime_lock must be at least
* read synchronised when calling this routine (see do_gettimeofday()
* below for an example).
*/
unsigned long
itc_get_offset (void)
......@@ -77,11 +81,6 @@ itc_get_offset (void)
last_tick = (cpu_data(TIME_KEEPER_ID)->itm_next
- (lost + 1)*cpu_data(TIME_KEEPER_ID)->itm_delta);
if (unlikely((long) (now - last_tick) < 0)) {
printk(KERN_ERR "CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n",
smp_processor_id(), now, last_tick);
return last_nsec_offset;
}
elapsed_cycles = now - last_tick;
return (elapsed_cycles*local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT;
}
......
......@@ -11,6 +11,8 @@
#include <asm/sn/sn2/io.h>
#ifdef CONFIG_IA64_GENERIC
#undef __sn_inb
#undef __sn_inw
#undef __sn_inl
......@@ -81,3 +83,5 @@ __sn_readq (void *addr)
{
return ___sn_readq (addr);
}
#endif
......@@ -68,20 +68,25 @@
* we'll patch out the work-around bundles with NOPs, so their impact is minimal.
*/
#define DO_MCKINLEY_E9_WORKAROUND
#ifdef DO_MCKINLEY_E9_WORKAROUND
.section ".data.patch.mckinley_e9", "a"
.previous
/* workaround for Itanium 2 Errata 9: */
# define MCKINLEY_E9_WORKAROUND \
.xdata4 ".data.patch.mckinley_e9", 1f-.;\
1:{ .mib; \
nop.m 0; \
nop.i 0; \
br.call.sptk.many b7=1f;; \
}; \
1:
# define FSYS_RETURN \
.xdata4 ".data.patch.mckinley_e9", 1f-.; \
1:{ .mib; \
nop.m 0; \
mov r16=ar.pfs; \
br.call.sptk.many b7=2f;; \
}; \
2:{ .mib; \
nop.m 0; \
mov ar.pfs=r16; \
br.ret.sptk.many b6;; \
}
#else
# define MCKINLEY_E9_WORKAROUND
# define FSYS_RETURN br.ret.sptk.many b6
#endif
#endif /* _ASM_IA64_ASMMACRO_H */
......@@ -67,14 +67,15 @@ ia64_get_itc (void)
return result;
}
extern void ia64_delay_loop (unsigned long loops);
static __inline__ void
__delay (unsigned long loops)
{
if (loops < 1)
if (unlikely(loops < 1))
return;
while (loops--)
ia64_nop(0);
ia64_delay_loop (loops - 1);
}
static __inline__ void
......
......@@ -99,4 +99,6 @@ extern ia64_mv_dma_supported sn_dma_supported;
#define platform_dma_sync_sg sn_dma_sync_sg
#define platform_dma_supported sn_dma_supported
#include <asm/sn/sn2/io.h>
#endif /* _ASM_IA64_MACHVEC_SN2_H */
......@@ -108,8 +108,6 @@ enum {
IA64_MCA_NEW_CONTEXT = -1 /* SAL to return to new context */
};
#define MIN_STATE_AREA_SIZE 57
typedef struct ia64_mca_os_to_sal_state_s {
u64 imots_os_status; /* OS status to SAL as to what happened
* with the MCA handling.
......
......@@ -110,10 +110,9 @@
;; \
dep temp1 = -1, temp1, PSR_MC, 1; \
;; \
movl temp2 = start_addr; \
mov cr.ipsr = temp1; \
;; \
INST_VA_TO_PA(temp2); \
LOAD_PHYSICAL(p0, temp2, start_addr); \
;; \
mov cr.iip = temp2; \
mov cr.ifs = r0; \
......
......@@ -405,10 +405,11 @@ typedef struct pal_process_state_info_s {
* generated.
* (Trap Lost )
*/
op : 3, /* Operation that
* caused the machine
* check
mi : 1, /* More information available
* call PAL_MC_ERROR_INFO
*/
pi : 1, /* Precise instruction pointer */
pm : 1, /* Precise min-state save area */
dy : 1, /* Processor dynamic
* state valid
......@@ -450,11 +451,12 @@ typedef struct pal_process_state_info_s {
* by the processor
*/
reserved2 : 12,
reserved2 : 11,
cc : 1, /* Cache check */
tc : 1, /* TLB check */
bc : 1, /* Bus check */
uc : 1; /* Unknown check */
rc : 1, /* Register file check */
uc : 1; /* Uarch check */
} pal_processor_state_info_t;
......
......@@ -38,7 +38,6 @@
*/
#define PFM_FL_NOTIFY_BLOCK 0x01 /* block task on user level notifications */
#define PFM_FL_SYSTEM_WIDE 0x02 /* create a system wide context */
#define PFM_FL_UNSECURE 0x04 /* allow unsecure monitoring for non self-monitoring task */
#define PFM_FL_OVFL_NO_MSG 0x80 /* do not post overflow/end messages for notification */
/*
......@@ -162,8 +161,6 @@ typedef union {
*/
#define PFM_VERSION_MAJ 2U
#define PFM_VERSION_MIN 0U
#define PFM_SMPL_HDR_VERSION_MAJ 2U
#define PFM_SMPL_HDR_VERSION_MIN 0U
#define PFM_VERSION (((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff))
#define PFM_VERSION_MAJOR(x) (((x)>>16) & 0xffff)
#define PFM_VERSION_MINOR(x) ((x) & 0xffff)
......@@ -194,9 +191,8 @@ extern void pfm_handle_work(void);
/*
* Reset PMD register flags
*/
#define PFM_PMD_NO_RESET 0
#define PFM_PMD_SHORT_RESET 0
#define PFM_PMD_LONG_RESET 1
#define PFM_PMD_SHORT_RESET 2
typedef union {
unsigned int val;
......@@ -223,7 +219,7 @@ typedef struct {
} pfm_ovfl_arg_t;
typedef struct _pfm_buffer_fmt_t {
typedef struct {
char *fmt_name;
pfm_uuid_t fmt_uuid;
size_t fmt_arg_size;
......@@ -237,8 +233,7 @@ typedef struct _pfm_buffer_fmt_t {
int (*fmt_restart_active)(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs);
int (*fmt_exit)(struct task_struct *task, void *buf, struct pt_regs *regs);
struct _pfm_buffer_fmt_t *fmt_next;
struct _pfm_buffer_fmt_t *fmt_prev;
struct list_head fmt_list;
} pfm_buffer_fmt_t;
extern int pfm_register_buffer_fmt(pfm_buffer_fmt_t *fmt);
......
......@@ -10,7 +10,7 @@
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
typedef unsigned int __kernel_ino_t;
typedef unsigned long __kernel_ino_t;
typedef unsigned int __kernel_mode_t;
typedef unsigned int __kernel_nlink_t;
typedef long __kernel_off_t;
......
......@@ -4,8 +4,6 @@
* Derived from the i386 version.
*/
#include <linux/config.h>
/*
* This assumes you have a 1.8432 MHz clock for your UART.
*
......@@ -15,107 +13,7 @@
*/
#define BASE_BAUD ( 1843200 / 16 )
#define CONFIG_SERIAL_DETECT_IRQ /* on IA-64, we always want to autodetect irqs */
/* Standard COM flags (except for COM4, because of the 8514 problem) */
#ifdef CONFIG_SERIAL_DETECT_IRQ
#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
#else
#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
#endif
#ifdef CONFIG_SERIAL_MANY_PORTS
#define FOURPORT_FLAGS ASYNC_FOURPORT
#define ACCENT_FLAGS 0
#define BOCA_FLAGS 0
#define HUB6_FLAGS 0
#define RS_TABLE_SIZE 64
#else
#define RS_TABLE_SIZE
#endif
/*
* The following define the access methods for the HUB6 card. All
* access is through two ports for all 24 possible chips. The card is
* selected through the high 2 bits, the port on that card with the
* "middle" 3 bits, and the register on that port with the bottom
* 3 bits.
*
* While the access port and interrupt is configurable, the default
* port locations are 0x302 for the port control register, and 0x303
* for the data read/write register. Normally, the interrupt is at irq3
* but can be anything from 3 to 7 inclusive. Note that using 3 will
* require disabling com2.
*/
#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
#define STD_SERIAL_PORT_DEFNS \
/* UART CLK PORT IRQ FLAGS */ \
{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
#ifdef CONFIG_SERIAL_MANY_PORTS
#define EXTRA_SERIAL_PORT_DEFNS \
{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \
{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \
{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \
{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \
{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \
{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \
{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \
{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \
{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \
{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \
{ 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \
{ 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \
{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \
{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \
{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \
{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \
{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \
{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \
{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \
{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \
{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \
{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \
{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \
{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \
{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \
{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \
{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \
{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */
#else
#define EXTRA_SERIAL_PORT_DEFNS
#endif
/* You can have up to four HUB6's in the system, but I've only
* included two cards here for a total of twelve ports.
* All legacy serial ports should be enumerated via ACPI namespace, so
* we need not list them here.
*/
#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS))
#define HUB6_SERIAL_PORT_DFNS \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */
#else
#define HUB6_SERIAL_PORT_DFNS
#endif
#define SERIAL_PORT_DFNS \
STD_SERIAL_PORT_DEFNS \
EXTRA_SERIAL_PORT_DEFNS \
HUB6_SERIAL_PORT_DFNS
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