Commit 06b402d7 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.99pre6-4

parent 5aa2eae5
......@@ -1788,6 +1788,13 @@ S: Matlock
S: Derbyshire DE4 3RL
S: United Kingdom
N: Ian S. Nelson
E: ian.nelson@echostar.com
D: Minor mmap and ide hacks
S: 1370 Atlantis Ave.
S: Lafayette CO, 80026
S: USA
N: Russell Nelson
E: nelson@crynwr.com
W: http://www.crynwr.com/~nelson
......
This diff is collapsed.
EFI Real Time Clock driver
-------------------------------
S. Eranian <eranian@hpl.hp.com>
March 2000
I/ Introduction
This document describes the efirtc.c driver has provided for
the IA-64 platform.
The purpose of this driver is to supply an API for kernel and user applications
to get access to the Time Service offered by EFI version 0.92.
EFI provides 4 calls one can make once the OS is booted: GetTime(),
SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this driver.
We describes those calls as well the the design of the driver in the following
sections.
II/ Design Decisions
The original ideas was to provide a very simple driver to get access to,
at first, the time of day service. This is required in order to access, in a
portable way, the CMOS clock. A program like /sbin/hwclock uses such a clock
to initialize the system view of the time during boot.
Because we wanted to minimize the impact on existing user-level apps using
the CMOS clock, we decided to expose an API that was very similar to the one
used today with the legacy RTC driver (driver/char/rtc.c). However, because
EFI provides a simpler services, not all all ioctl() are available. Also
new ioctl()s have been introduced for things that EFI provides but not the
legacy.
EFI uses a slightly different way of representing the time, noticeably
the reference date is different. Year is the using the full 4-digit format.
The Epoch is January 1st 1998. For backward compatibility reasons we don't
expose this new way of representing time. Instead we use something very
similar to the struct tm, i.e. struct rtc_time, as used by hwclock.
One of the reasons for doing it this way is to allow for EFI to still evolve
without necessarily impatcing any of the user applications. The decoupling
enables flexibility and permits writing wrapper code is ncase things change.
The driver exposes two interfaces, one via the device file and a set of ioctl()s.
The other is read-only via the /proc filesystem.
As of today we don't offer a /proc/sys interface.
To allow for a uniform interface between the legacy RTC and EFI time service,
we have created the include/linux/rtc.h header file to contain only the
"public" API of the two drivers. The specifics of the legacy RTC are still
in include/linux/mc146818rtc.h.
III/ Time of day service
The part of the driver gives access to the time of day service of EFI.
Two ioctl()s, compatible with the legacy RTC calls:
Read the CMOS clock: ioctl(d, RTC_RD_TIME, &rtc);
Write the CMOS clock: ioctl(d, RTC_SET_TIME, &rtc);
The rtc is a pointer to a data structure defined in rtc.h which is close
to a struct tm:
struct rtc_time {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
The driver takes care of converting back an forth between the EFI time and
this format.
Those two ioctl()s can be exercised with the hwclock command:
For reading:
# /sbin/hwclock --show
Mon Mar 6 15:32:32 2000 -0.910248 seconds
For setting:
# /sbin/hwclock --systohc
Root privileges are required to be able to set the time of day.
IV/ Wakeup Alarm service
EFI provides an API by which one can program when a machine should wakeup,
i.e. reboot. This is very different from the alarm provided by the legacy
RTC which is some kind of interval timer alarm. For this reason we don't use
the same ioctl()s to get access to the service. Instead we have
introduced 2 news ioctl()s to the interface of an RTC.
We have added 2 new ioctl()s that are specific to the EFI driver:
Read the current state of the alarm
ioctl(d, RTC_WKLAM_RD, &wkt)
Set the alarm or change its status
ioctl(d, RTC_WKALM_SET, &wkt)
The wkt structure encapsulates a struct rtc_time + 2 extra fields to get
status information:
struct rtc_wkalrm {
unsigned char enabled; /* =1 if alarm is enabled */
unsigned char pending; /* =1 if alarm is pending */
struct rtc_time time;
}
As of today, none of the existing user-level apps supports this feature.
However writing such a program should be hard by simply using those two
ioctl().
Root privileges are required to be able to set the alarm.
V/ References.
Checkout the following Web site for more information on EFI:
http://developer.intel.com/technology/efi/
19 January 2000
14 April 2000
david-b@pacbell.net
This is an overview of how to use the "dc2xx" USB driver with certain
......@@ -17,30 +17,22 @@ to Kodak DC-240 and DC-280 cameras over USB.
In addition the DC-220, DC-260, DC-265, and DC-290 are also recognized.
However, like other cameras using the "Digita OS" (from www.flashpoint.com)
there is no gPhoto support for this camera. At this writing the best
known support for these cameras is a Python script that supports image
downloading from those cameras. (See archives of the linux-usb mailing
list.) When it becomes available, the HP PhotoSmart C500 should also
work ... it's another Digita OS camera with USB support.
there is no gPhoto support for this camera. There is a python script
for accessing these cameras (see archives of the linux-usb mailing list)
and a "Digita Services" library that can also use this driver.
It's likely that other digital still cameras can also use this USB driver,
even if they're not from Kodak and don't use Digita. The reason is that
most currently known USB still camera protocols treat USB like a faster
packet-carrying connection than a serial line, which is exactly how this
driver looks to an application.
The HP PhotoSmart C500 should also work, since it's another Digita camera
with USB support.
USB HARDWARE
This has been shown to work on x86 OHCI and UHCI (Intel) chipsets. OHCI has
been trouble free; not so with UHCI, which was first seen to be happy with
2.3.24 kernels, and has not been as fast as OHCI. Users on the PowerMac
platform have had success, although the stock kernel doesn't yet support
that platform.
Recent kernels have had no particular problems using this driver with
either OHCI or UHCI chipsets, and have worked on the PowerMac platform.
Note that in some cases changes in BIOS settings may be needed before
your USB works. At least one user has reported a need for SMP-related
settings as well.
settings as well, and some old hardware may not handle USB correctly.
SETUP
......@@ -50,15 +42,18 @@ as a module, or compiled in directly.
Create at least one device, perhaps like this (both read and write):
# mknod -m 0666 /dev/kodak00 c 180 80
# mknod -m 0666 /dev/kodak01 c 180 81
# mknod -m 0660 /dev/usb/dc2xx0 c 180 80
# mknod -m 0660 /dev/usb/dc2xx1 c 180 81
...
NOTE: you would normally configure PAM so that the user logged in at
the console is granted ownership of these devices. console.perms(5)
explains how to do this.
The driver supports multiple device nodes. The USB framework supports
a maximum of sixteen device nodes (up to minor device number 96), though
by default fewer devices are available.
a maximum of sixteen device nodes (up to minor device number 96).
When you plug in one camera, it will use the first device node (kodak00
When you plug in one camera, it will use the first device node (dc2xx0
in the example above). A second camera will use the second device node,
and so on.
......@@ -69,18 +64,22 @@ First: if you've got /proc support, make sure that the driver has hooked
itself up correctly.
- You should see an entry in /proc/bus/usb/drivers for "dc2xx",
if you enabled USB /proc support.
if you enabled USB /proc support and correctly mounted the
usbdevfs on /proc/bus/usb.
Second: when you connect your camera to the computer, does it get recognized
by the driver? (Make sure the camera is powered on!)
- if you've got /proc/bus/usb/devices, you should see an entry
something like this. The "ProdID" may be different if you didn't
plug in a DC-240, but the "Driver=dc2xx" had better be there.
plug in a DC-240, as may the strings presented, but "Driver=dc2xx"
had better be there.
T: Lev=01 Prnt=00 Port=00 Cnt=01 Dev#= 1 Spd=12 MxCh= 0
D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=040a ProdID=0120 Rev= 1.08
S: Manufacturer=Eastman Kodak Company
S: Product=KODAK DC240 Zoom Digital Camera
C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=00(>ifc ) Sub=00 Prot=00 Driver=dc2xx
E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl= 0ms
......@@ -90,13 +89,12 @@ by the driver? (Make sure the camera is powered on!)
Manufacturer: Eastman Kodak Company
Product: KODAK DC240 Zoom Digital Camera
Serial Number: ?
dc2xx.c: USB Camera #0 connected
Third: (optional) can you use gPhoto to talk to the camera?
- When you configure your camera, tell it to use "/dev/kodak00" (or
whatever name you used). Right now, gPhoto emits a diagnostic
- When you configure your camera, tell it to use "/dev/usb/dc2xx0"
(or whatever name you used). Right now, gPhoto emits a diagnostic
message (non-GUI) saying that it since it didn't act like a TTY,
it's assuming it's got a USB connection.
......
......@@ -215,6 +215,7 @@ CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_VIA82CXXX_TUNING is not set
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_IDEDMA_AUTO is not set
CONFIG_BLK_DEV_IDE_MODES=y
......
......@@ -29,7 +29,7 @@ static struct irq_routing_table *pirq_table;
* Avoid using: 13, 14 and 15 (FP error and IDE).
* Penalize: 3, 4, 7, 12 (known ISA uses: serial, parallel and mouse)
*/
unsigned int pcibios_irq_mask = ~0;
unsigned int pcibios_irq_mask = 0xfff8;
static unsigned pirq_penalty[16] = {
10000, 10000, 10000, 100, 100, 0, 0, 100,
......@@ -305,10 +305,7 @@ int pcibios_lookup_irq(struct pci_dev *dev, int assign)
return 0;
}
DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
if (pcibios_irq_mask != ~0)
mask &= pcibios_irq_mask;
else
mask &= pirq_table->exclusive_irqs;
mask &= pcibios_irq_mask;
/* Find the best IRQ to assign */
newirq = 0;
......
......@@ -9,6 +9,7 @@
#
NM := $(CROSS_COMPILE)nm -B
AWK := awk
LINKFLAGS = -static -T arch/$(ARCH)/vmlinux.lds
# next line is for HP compiler backend:
......@@ -16,10 +17,10 @@ LINKFLAGS = -static -T arch/$(ARCH)/vmlinux.lds
# The next line is needed when compiling with the July snapshot of the Cygnus compiler:
#EXTRA = -D__GCC_DOESNT_KNOW_IN_REGS__
# next two lines are for the September snapshot of the Cygnus compiler:
AFLAGS += -D__GCC_MULTIREG_RETVALS__
AFLAGS += -D__GCC_MULTIREG_RETVALS__ -Wa,-x
EXTRA = -D__GCC_MULTIREG_RETVALS__
CFLAGS := $(CFLAGS) -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f10-f15,f32-f127
CFLAGS := $(CFLAGS) -pipe $(EXTRA) -Wa,-x -ffixed-r13 -mfixed-range=f10-f15,f32-f127
ifdef CONFIG_IA64_GENERIC
CORE_FILES := arch/$(ARCH)/hp/hp.a \
......@@ -34,14 +35,14 @@ ifdef CONFIG_IA64_GENERIC
else # !GENERIC
ifeq ($(CONFIG_IA64_HP_SIM),y)
ifdef CONFIG_IA64_HP_SIM
SUBDIRS := arch/$(ARCH)/hp \
$(SUBDIRS)
CORE_FILES := arch/$(ARCH)/hp/hp.a \
$(CORE_FILES)
endif
ifeq ($(CONFIG_IA64_SGI_SN1_SIM),y)
ifdef CONFIG_IA64_SGI_SN1_SIM
SUBDIRS := arch/$(ARCH)/sn/sn1 \
arch/$(ARCH)/sn \
$(SUBDIRS)
......@@ -49,14 +50,14 @@ ifeq ($(CONFIG_IA64_SGI_SN1_SIM),y)
$(CORE_FILES)
endif
ifeq ($(CONFIG_IA64_SOFTSDV),y)
ifdef CONFIG_IA64_SOFTSDV
SUBDIRS := arch/$(ARCH)/dig \
$(SUBDIRS)
CORE_FILES := arch/$(ARCH)/dig/dig.a \
$(CORE_FILES)
endif
ifeq ($(CONFIG_IA64_DIG),y)
ifdef CONFIG_IA64_DIG
SUBDIRS := arch/$(ARCH)/dig \
$(SUBDIRS)
CORE_FILES := arch/$(ARCH)/dig/dig.a \
......@@ -65,16 +66,11 @@ endif
endif # !GENERIC
ifeq ($(CONFIG_IA32_SUPPORT),y)
ifdef CONFIG_IA32_SUPPORT
SUBDIRS := arch/$(ARCH)/ia32 $(SUBDIRS)
CORE_FILES := arch/$(ARCH)/ia32/ia32.o $(CORE_FILES)
endif
ifdef CONFIG_KDB
LIBS := $(LIBS) $(TOPDIR)/arch/$(ARCH)/kdb/kdb.a
SUBDIRS := $(SUBDIRS) arch/$(ARCH)/kdb
endif
HEAD := arch/$(ARCH)/kernel/head.o arch/ia64/kernel/init_task.o
SUBDIRS := arch/$(ARCH)/tools arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib $(SUBDIRS)
......
......@@ -4,6 +4,8 @@ mainmenu_option next_comment
comment 'General setup'
define_bool CONFIG_IA64 y
define_bool CONFIG_ITANIUM y # easy choice for now... ;-)
define_bool CONFIG_ISA n
define_bool CONFIG_SBUS n
......@@ -25,7 +27,7 @@ if [ "$CONFIG_IA64_DIG" = "y" ]; then
bool ' Enable BigSur hacks' CONFIG_IA64_BIGSUR_HACKS
bool ' Enable Lion hacks' CONFIG_IA64_LION_HACKS
bool ' Emulate PAL/SAL/EFI firmware' CONFIG_IA64_FW_EMU
bool ' Get PCI IRQ routing from firmware/ACPI' CONFIG_IA64_IRQ_ACPI
bool ' Enable IA64 Machine Check Abort' CONFIG_IA64_MCA
fi
if [ "$CONFIG_IA64_GENERIC" = "y" ]; then
......@@ -185,10 +187,5 @@ bool 'Early printk support (requires VGA!)' CONFIG_IA64_EARLY_PRINTK
bool 'Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXCHG
bool 'Turn on irq debug checks (slow!)' CONFIG_IA64_DEBUG_IRQ
bool 'Print possible IA64 hazards to console' CONFIG_IA64_PRINT_HAZARDS
bool 'Built-in Kernel Debugger support' CONFIG_KDB
if [ "$CONFIG_KDB" = "y" ]; then
bool 'Compile the kernel with frame pointers' CONFIG_KDB_FRAMEPTR
int 'KDB Kernel Symbol Table size?' CONFIG_KDB_STBSIZE 10000
fi
endmenu
......@@ -15,7 +15,7 @@ all: dig.a
O_TARGET = dig.a
O_OBJS = iosapic.o setup.o
ifeq ($(CONFIG_IA64_GENERIC),y)
ifdef CONFIG_IA64_GENERIC
O_OBJS += machvec.o
endif
......
This diff is collapsed.
......@@ -47,17 +47,11 @@ dig_setup (char **cmdline_p)
unsigned int orig_x, orig_y, num_cols, num_rows, font_height;
/*
* This assumes that the EFI partition is physical disk 1
* partition 1 and the Linux root disk is physical disk 1
* partition 2.
* Default to /dev/sda2. This assumes that the EFI partition
* is physical disk 1 partition 1 and the Linux root disk is
* physical disk 1 partition 2.
*/
#ifdef CONFIG_IA64_LION_HACKS
/* default to /dev/sda2 on Lion... */
ROOT_DEV = to_kdev_t(0x0802); /* default to second partition on first drive */
#else
/* default to /dev/dha2 on BigSur... */
ROOT_DEV = to_kdev_t(0x0302); /* default to second partition on first drive */
#endif
#ifdef CONFIG_SMP
init_smp_config();
......
......@@ -10,7 +10,7 @@ all: hp.a
O_TARGET = hp.a
O_OBJS = hpsim_console.o hpsim_irq.o hpsim_setup.o
ifeq ($(CONFIG_IA64_GENERIC),y)
ifdef CONFIG_IA64_GENERIC
O_OBJS += hpsim_machvec.o
endif
......
......@@ -10,7 +10,7 @@
all: ia32.o
O_TARGET := ia32.o
O_OBJS := ia32_entry.o ia32_signal.o sys_ia32.o ia32_support.o binfmt_elf32.o
O_OBJS := ia32_entry.o sys_ia32.o ia32_signal.o ia32_support.o ia32_traps.o binfmt_elf32.o
clean::
......
......@@ -134,6 +134,19 @@ void ia64_elf32_init(struct pt_regs *regs)
regs->cr_ipsr &= ~IA64_PSR_AC;
regs->loadrs = 0;
/*
* According to the ABI %edx points to an `atexit' handler.
* Since we don't have one we'll set it to 0 and initialize
* all the other registers just to make things more deterministic,
* ala the i386 implementation.
*/
regs->r8 = 0; /* %eax */
regs->r11 = 0; /* %ebx */
regs->r9 = 0; /* %ecx */
regs->r10 = 0; /* %edx */
regs->r13 = 0; /* %ebp */
regs->r14 = 0; /* %esi */
regs->r15 = 0; /* %edi */
}
#undef STACK_TOP
......
#include <asm/offsets.h>
#include <asm/signal.h>
//
// Get possibly unaligned sigmask argument into an aligned
// kernel buffer
.text
.proc ia32_rt_sigsuspend
.global ia32_rt_sigsuspend
ia32_rt_sigsuspend:
// We'll cheat and not do an alloc here since we are ultimately
// going to do a simple branch to the IA64 sys_rt_sigsuspend.
// r32 is still the first argument which is the signal mask.
// We copy this 4-byte aligned value to an 8-byte aligned buffer
// in the task structure and then jump to the IA64 code.
mov r8=r0 // no memory access errors yet
add r10=4,r32
;;
1:
ld4 r2=[r32] // get first half of sigmask
ld4 r3=[r10] // get second half of sigmask
2:
cmp.lt p6,p0=r8,r0 // check memory access
;;
(p6) br.ret.sptk.many rp // it failed
adds r32=IA64_TASK_THREAD_SIGMASK_OFFSET,r13
adds r10=IA64_TASK_THREAD_SIGMASK_OFFSET+4,r13
;;
st4 [r32]=r2
st4 [r10]=r3
br.cond.sptk.many sys_rt_sigsuspend
.section __ex_table,"a"
data4 @gprel(1b)
data4 (2b-1b)|1
.previous
.endp ia32_rt_sigsuspend
.global ia32_ret_from_syscall
.proc ia64_ret_from_syscall
.proc ia32_ret_from_syscall
ia32_ret_from_syscall:
cmp.ge p6,p7=r8,r0 // syscall executed successfully?
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
;;
st8 [r2]=r8 // store return value in slot for r8
br.cond.sptk.few ia64_leave_kernel
.endp ia32_ret_from_syscall
//
// Invoke a system call, but do some tracing before and after the call.
......@@ -34,11 +75,22 @@ ia32_trace_syscall:
.endp ia32_trace_syscall
.align 16
.global sys32_vfork
.proc sys32_vfork
sys32_vfork:
alloc r16=ar.pfs,2,2,3,0;;
mov out0=IA64_CLONE_VFORK|IA64_CLONE_VM|SIGCHLD // out0 = clone_flags
br.cond.sptk.few .fork1 // do the work
.endp sys32_vfork
.align 16
.global sys32_fork
.proc sys32_fork
sys32_fork:
alloc r16=ar.pfs,2,2,3,0;;
mov out0=SIGCHLD // out0 = clone_flags
.fork1:
movl r28=1f
mov loc1=rp
br.cond.sptk.many save_switch_stack
......@@ -46,7 +98,6 @@ sys32_fork:
mov loc0=r16 // save ar.pfs across do_fork
adds out2=IA64_SWITCH_STACK_SIZE+16,sp
adds r2=IA64_SWITCH_STACK_SIZE+IA64_PT_REGS_R12_OFFSET+16,sp
mov out0=SIGCHLD // out0 = clone_flags
;;
ld8 out1=[r2] // fetch usp from pt_regs.r12
br.call.sptk.few rp=do_fork
......@@ -88,7 +139,7 @@ ia32_syscall_table:
data8 sys_setuid
data8 sys_getuid
data8 sys_ni_syscall /* sys_stime is not supported on IA64 */ /* 25 */
data8 sys_ptrace
data8 sys32_ptrace
data8 sys32_alarm
data8 sys_ni_syscall
data8 sys_ni_syscall
......@@ -105,7 +156,7 @@ ia32_syscall_table:
data8 sys_rmdir /* 40 */
data8 sys_dup
data8 sys32_pipe
data8 sys_times
data8 sys32_times
data8 sys_ni_syscall /* old prof syscall holder */
data8 sys_brk /* 45 */
data8 sys_setgid
......@@ -139,7 +190,7 @@ ia32_syscall_table:
data8 sys_sethostname
data8 sys32_setrlimit /* 75 */
data8 sys32_getrlimit
data8 sys_getrusage
data8 sys32_getrusage
data8 sys32_gettimeofday
data8 sys32_settimeofday
data8 sys_getgroups /* 80 */
......@@ -241,7 +292,7 @@ ia32_syscall_table:
data8 sys_rt_sigpending
data8 sys_rt_sigtimedwait
data8 sys_rt_sigqueueinfo
data8 sys_rt_sigsuspend
data8 ia32_rt_sigsuspend
data8 sys_pread /* 180 */
data8 sys_pwrite
data8 sys_chown
......
......@@ -94,7 +94,9 @@ setup_sigcontext_ia32(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
/* non-iBCS2 extensions.. */
#endif
err |= __put_user(mask, &sc->oldmask);
#if 0
err |= __put_user(current->tss.cr2, &sc->cr2);
#endif
......@@ -196,7 +198,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
return (void *)((esp - frame_size) & -8ul);
}
static void
static int
setup_frame_ia32(int sig, struct k_sigaction *ka, sigset_t *set,
struct pt_regs * regs)
{
......@@ -247,20 +249,21 @@ setup_frame_ia32(int sig, struct k_sigaction *ka, sigset_t *set,
regs->eflags &= ~TF_MASK;
#endif
#if 1
printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n",
current->comm, current->pid, frame, regs->cr_iip, frame->pretcode);
#if 0
printk("SIG deliver (%s:%d): sig=%d sp=%p pc=%lx ra=%x\n",
current->comm, current->pid, sig, frame, regs->cr_iip, frame->pretcode);
#endif
return;
return 1;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
return 0;
}
static void
static int
setup_rt_frame_ia32(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs * regs)
{
......@@ -316,29 +319,29 @@ setup_rt_frame_ia32(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->eflags &= ~TF_MASK;
#endif
#if 1
#if 0
printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n",
current->comm, current->pid, frame, regs->cr_iip, frame->pretcode);
#endif
return;
return 1;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
return 0;
}
long
int
ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs)
{
/* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame_ia32(sig, ka, info, set, regs);
return(setup_rt_frame_ia32(sig, ka, info, set, regs));
else
setup_frame_ia32(sig, ka, set, regs);
return(setup_frame_ia32(sig, ka, set, regs));
}
asmlinkage int
......
#include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/ia32.h>
#include <asm/ptrace.h>
int
ia32_exception (struct pt_regs *regs, unsigned long isr)
{
struct siginfo siginfo;
switch ((isr >> 16) & 0xff) {
case 1:
case 2:
if (isr == 0)
siginfo.si_code = TRAP_TRACE;
else if (isr & 0x4)
siginfo.si_code = TRAP_BRANCH;
else
siginfo.si_code = TRAP_BRKPT;
break;
case 3:
siginfo.si_code = TRAP_BRKPT;
break;
case 0: /* Divide fault */
case 4: /* Overflow */
case 5: /* Bounds fault */
case 6: /* Invalid Op-code */
case 7: /* FP DNA */
case 8: /* Double Fault */
case 9: /* Invalid TSS */
case 11: /* Segment not present */
case 12: /* Stack fault */
case 13: /* General Protection Fault */
case 16: /* Pending FP error */
case 17: /* Alignment check */
case 19: /* SSE Numeric error */
default:
return -1;
}
siginfo.si_signo = SIGTRAP;
siginfo.si_errno = 0;
send_sig_info(SIGTRAP, &siginfo, current);
return 0;
}
This diff is collapsed.
#
# Makefile for ia64-specific kdb files..
#
# Copyright 1999, Silicon Graphics Inc.
#
# Written March 1999 by Scott Lurndal at Silicon Graphics, Inc.
# Code for IA64 written by Goutham Rao <goutham.rao@intel.com> and
# Sreenivas Subramoney <sreenivas.subramoney@intel.com>
#
SUB_DIRS :=
MOD_SUB_DIRS := $(SUB_DIRS)
ALL_SUB_DIRS := $(SUB_DIRS)
.S.o:
$(CC) $(AFLAGS) -traditional -c $< -o $*.o
L_TARGET = kdb.a
L_OBJS = kdbsupport.o kdb_io.o kdb_bt.o kdb_traps.o
include $(TOPDIR)/Rules.make
/**
* Minimalist Kernel Debugger
* Machine dependent stack traceback code for IA-64.
*
* Copyright (C) 1999 Goutham Rao <goutham.rao@intel.com>
* Copyright (C) 1999 Sreenivas Subramoney <sreenivas.subramoney@intel.com>
* Intel Corporation, August 1999.
* Copyright (C) 1999 Hewlett-Packard Co
* Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
*
* 99/12/03 D. Mosberger Reimplemented based on <asm-ia64/unwind.h> API.
* 99/12/06 D. Mosberger Added support for backtracing other processes.
*/
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/kdb.h>
#include <asm/system.h>
#include <asm/current.h>
#include <asm/kdbsupport.h>
/*
* Minimal stack back trace functionality.
*/
int
kdb_bt (int argc, const char **argv, const char **envp, struct pt_regs *regs)
{
struct task_struct *task = current;
struct ia64_frame_info info;
char *name;
int diag;
if (strcmp(argv[0], "btp") == 0) {
unsigned long pid;
diag = kdbgetularg(argv[1], &pid);
if (diag)
return diag;
task = find_task_by_pid(pid);
if (!task) {
kdb_printf("No process with pid == %d found\n", pid);
return 0;
}
regs = ia64_task_regs(task);
} else if (argc) {
kdb_printf("bt <address> is unsupported for IA-64\n");
return 0;
}
if (task == current) {
/*
* Upon entering kdb, the stack frame looks like this:
*
* +---------------------+
* | struct pt_regs |
* +---------------------+
* | |
* | kernel stack |
* | |
* +=====================+ <--- top of stack upon entering kdb
* | struct pt_regs |
* +---------------------+
* | struct switch_stack |
* +---------------------+
*/
if (user_mode(regs)) {
/* We are not implementing stack backtrace from user mode code */
kdb_printf ("Not in Kernel\n");
return 0;
}
ia64_unwind_init_from_current(&info, regs);
} else {
/*
* For a blocked task, the stack frame looks like this:
*
* +---------------------+
* | struct pt_regs |
* +---------------------+
* | |
* | kernel stack |
* | |
* +---------------------+
* | struct switch_stack |
* +=====================+ <--- task->thread.ksp
*/
ia64_unwind_init_from_blocked_task(&info, task);
}
kdb_printf("Ret Address Reg Stack base Name\n\n") ;
do {
unsigned long ip = ia64_unwind_get_ip(&info);
name = kdbnearsym(ip);
if (!name) {
kdb_printf("Interrupt\n");
return 0;
}
kdb_printf("0x%016lx: [0x%016lx] %s\n", ip, ia64_unwind_get_bsp(&info), name);
} while (ia64_unwind_to_previous_frame(&info) >= 0);
return 0;
}
/*
* Kernel Debugger Console I/O handler
*
* Copyright (C) 1999 Silicon Graphics, Inc.
* Copyright (C) Scott Lurndal (slurn@engr.sgi.com)
* Copyright (C) Scott Foehner (sfoehner@engr.sgi.com)
* Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
*
* Written March 1999 by Scott Lurndal at Silicon Graphics, Inc.
*
* Modifications from:
* Chuck Fleckenstein 1999/07/20
* Move kdb_info struct declaration to this file
* for cases where serial support is not compiled into
* the kernel.
*
* Masahiro Adegawa 1999/07/20
* Handle some peculiarities of japanese 86/106
* keyboards.
*
* marc@mucom.co.il 1999/07/20
* Catch buffer overflow for serial input.
*
* Scott Foehner
* Port to ia64
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/console.h>
#include <linux/serial_reg.h>
#include <linux/spinlock.h>
#include <asm/io.h>
#include "pc_keyb.h"
int kdb_port = 0;
/*
* This module contains code to read characters from the keyboard or a serial
* port.
*
* It is used by the kernel debugger, and is polled, not interrupt driven.
*
*/
/*
* send: Send a byte to the keyboard controller. Used primarily to
* alter LED settings.
*/
static void
kdb_kbdsend(unsigned char byte)
{
while (inb(KBD_STATUS_REG) & KBD_STAT_IBF)
;
outb(KBD_DATA_REG, byte);
}
static void
kdb_kbdsetled(int leds)
{
kdb_kbdsend(KBD_CMD_SET_LEDS);
kdb_kbdsend((unsigned char)leds);
}
static void
console_read (char *buffer, size_t bufsize)
{
struct console *in;
struct console *out;
char *cp, ch;
for (in = console_drivers; in; in = in->next) {
if ((in->flags & CON_ENABLED) && (in->read || in->wait_key))
break;
}
for (out = console_drivers; out; out = out->next) {
if ((out->flags & CON_ENABLED) && out->write)
break;
}
if ((!in->read && !in->wait_key) || !out->write) {
panic("kdb_io: can't do console i/o!");
}
if (in->read) {
/* this is untested... */
(*in->read)(in, buffer, bufsize);
return;
}
bufsize -= 2; /* leave room for CR & NUL terminator */
cp = buffer;
while (1) {
ch = (*in->wait_key)(in);
switch (ch) {
case '\b':
if (cp > buffer) {
--cp, ++bufsize;
(*out->write)(out, "\b \b", 3);
}
break;
case '\025':
while (cp > buffer) {
--cp, ++bufsize;
(*out->write)(out, "\b \b", 3);
}
break;
case '\r':
case '\n':
(*out->write)(out, "\r\n", 2);
*cp++ = '\n';
*cp++ = '\0';
return;
default:
if (bufsize > 0) {
(*out->write)(out, &ch, 1);
--bufsize;
*cp++ = ch;
}
break;
}
}
}
char *
kdb_getscancode(char *buffer, size_t bufsize)
{
/*
* XXX Shouldn't kdb _always_ use console based I/O? That's what the console
* abstraction is for, after all... ---davidm
*/
#ifdef CONFIG_IA64_HP_SIM
extern spinlock_t console_lock;
unsigned long flags;
spin_lock_irqsave(&console_lock, flags);
console_read(buffer, bufsize);
spin_unlock_irqrestore(&console_lock, flags);
return buffer;
#else /* !CONFIG_IA64_HP_SIM */
char *cp = buffer;
int scancode, scanstatus;
static int shift_lock = 0; /* CAPS LOCK state (0-off, 1-on) */
static int shift_key = 0; /* Shift next keypress */
static int ctrl_key = 0;
static int leds = 2; /* Num lock */
u_short keychar;
extern u_short plain_map[], shift_map[], ctrl_map[];
bufsize -= 2; /* Reserve space for newline and null byte */
/*
* If we came in via a serial console, we allow that to
* be the input window for kdb.
*/
if (kdb_port != 0) {
char ch;
int status;
#define serial_inp(info, offset) inb((info) + (offset))
#define serial_out(info, offset, v) outb((v), (info) + (offset))
while(1) {
while ((status = serial_inp(kdb_port, UART_LSR))
& UART_LSR_DR) {
readchar:
ch = serial_inp(kdb_port, UART_RX);
if (ch == 8) { /* BS */
if (cp > buffer) {
--cp, bufsize++;
printk("%c %c", 0x08, 0x08);
}
continue;
}
serial_out(kdb_port, UART_TX, ch);
if (ch == 13) { /* CR */
*cp++ = '\n';
*cp++ = '\0';
serial_out(kdb_port, UART_TX, 10);
return(buffer);
}
/*
* Discard excess characters
*/
if (bufsize > 0) {
*cp++ = ch;
bufsize--;
}
}
while (((status = serial_inp(kdb_port, UART_LSR))
& UART_LSR_DR) == 0);
}
}
while (1) {
/*
* Wait for a valid scancode
*/
while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
;
/*
* Fetch the scancode
*/
scancode = inb(KBD_DATA_REG);
scanstatus = inb(KBD_STATUS_REG);
/*
* Ignore mouse events.
*/
if (scanstatus & KBD_STAT_MOUSE_OBF)
continue;
/*
* Ignore release, trigger on make
* (except for shift keys, where we want to
* keep the shift state so long as the key is
* held down).
*/
if (((scancode&0x7f) == 0x2a)
|| ((scancode&0x7f) == 0x36)) {
/*
* Next key may use shift table
*/
if ((scancode & 0x80) == 0) {
shift_key=1;
} else {
shift_key=0;
}
continue;
}
if ((scancode&0x7f) == 0x1d) {
/*
* Left ctrl key
*/
if ((scancode & 0x80) == 0) {
ctrl_key = 1;
} else {
ctrl_key = 0;
}
continue;
}
if ((scancode & 0x80) != 0)
continue;
scancode &= 0x7f;
/*
* Translate scancode
*/
if (scancode == 0x3a) {
/*
* Toggle caps lock
*/
shift_lock ^= 1;
leds ^= 0x4; /* toggle caps lock led */
kdb_kbdsetled(leds);
continue;
}
if (scancode == 0x0e) {
/*
* Backspace
*/
if (cp > buffer) {
--cp, bufsize++;
/*
* XXX - erase character on screen
*/
printk("%c %c", 0x08, 0x08);
}
continue;
}
if (scancode == 0xe0) {
continue;
}
/*
* For Japanese 86/106 keyboards
* See comment in drivers/char/pc_keyb.c.
* - Masahiro Adegawa
*/
if (scancode == 0x73) {
scancode = 0x59;
} else if (scancode == 0x7d) {
scancode = 0x7c;
}
if (!shift_lock && !shift_key) {
keychar = plain_map[scancode];
} else if (shift_lock || shift_key) {
keychar = shift_map[scancode];
} else if (ctrl_key) {
keychar = ctrl_map[scancode];
} else {
keychar = 0x0020;
printk("Unknown state/scancode (%d)\n", scancode);
}
if ((scancode & 0x7f) == 0x1c) {
/*
* enter key. All done.
*/
printk("\n");
break;
}
/*
* echo the character.
*/
printk("%c", keychar&0xff);
if (bufsize) {
--bufsize;
*cp++ = keychar&0xff;
} else {
printk("buffer overflow\n");
break;
}
}
*cp++ = '\n'; /* White space for parser */
*cp++ = '\0'; /* String termination */
#if defined(NOTNOW)
cp = buffer;
while (*cp) {
printk("char 0x%x\n", *cp++);
}
#endif
return buffer;
#endif /* !CONFIG_IA64_HP_SIM */
}
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/kdb.h>
static struct kdb_bp_support {
unsigned long addr ;
int slot ;
} kdb_bp_info[NR_CPUS] ;
extern void kdb_bp_install (void);
/*
* This gets invoked right before a call to ia64_fault().
* Returns zero the normal fault handler should be invoked.
*/
long
ia64_kdb_fault_handler (unsigned long vector, unsigned long isr, unsigned long ifa,
unsigned long iim, unsigned long itir, unsigned long arg5,
unsigned long arg6, unsigned long arg7, unsigned long stack)
{
struct switch_stack *sw = (struct switch_stack *) &stack;
struct pt_regs *regs = (struct pt_regs *) (sw + 1);
int bundle_slot;
/*
* TBD
* If KDB is configured, enter KDB for any fault.
*/
if ((vector == 29) || (vector == 35) || (vector == 36)) {
if (!user_mode(regs)) {
bundle_slot = ia64_psr(regs)->ri;
if (vector == 29) {
if (bundle_slot == 0) {
kdb_bp_info[0].addr = regs->cr_iip;
kdb_bp_info[0].slot = bundle_slot;
kdb(KDB_REASON_FLTDBG, 0, regs);
} else {
if ((bundle_slot < 3) &&
(kdb_bp_info[0].addr == regs->cr_iip))
{
ia64_psr(regs)->id = 1;
ia64_psr(regs)->db = 1;
kdb_bp_install() ;
} else /* some error ?? */
kdb(KDB_REASON_FLTDBG, 0, regs);
}
} else /* single step or taken branch */
kdb(KDB_REASON_DEBUG, 0, regs);
return 1;
}
}
return 0;
}
This diff is collapsed.
/*
* linux/drivers/char/pc_keyb.h
*
* PC Keyboard And Keyboard Controller
*
* (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*/
/*
* Configuration Switches
*/
#undef KBD_REPORT_ERR /* Report keyboard errors */
#define KBD_REPORT_UNKN /* Report unknown scan codes */
#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
/*
* Internal variables of the driver
*/
extern unsigned char pckbd_read_mask;
extern unsigned char aux_device_present;
/*
* Keyboard Controller Registers
*/
#define KBD_STATUS_REG 0x64 /* Status register (R) */
#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
/*
* Keyboard Controller Commands
*/
#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
initiated by the auxiliary device */
#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
/*
* Keyboard Commands
*/
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
#define KBD_CMD_RESET 0xFF /* Reset */
/*
* Keyboard Replies
*/
#define KBD_REPLY_POR 0xAA /* Power on reset */
#define KBD_REPLY_ACK 0xFA /* Command ACK */
#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
/*
* Status Register Bits
*/
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
#define KBD_STAT_PERR 0x80 /* Parity error */
#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
/*
* Controller Mode Register Bits
*/
#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
#define KBD_MODE_SYS 0x04 /* The system flag (?) */
#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
#define KBD_MODE_RFU 0x80
/*
* Mouse Commands
*/
#define AUX_SET_RES 0xE8 /* Set resolution */
#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
#define AUX_SET_STREAM 0xEA /* Set stream mode */
#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
#define AUX_RESET 0xFF /* Reset aux device */
#define AUX_BUF_SIZE 2048
struct aux_queue {
unsigned long head;
unsigned long tail;
struct wait_queue *proc_list;
struct fasync_struct *fasync;
unsigned char buf[AUX_BUF_SIZE];
};
......@@ -15,13 +15,13 @@
all: kernel.o head.o init_task.o
O_TARGET := kernel.o
O_OBJS := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_internal.o ivt.o \
pal.o pci-dma.o process.o perfmon.o ptrace.o sal.o sal_stub.o semaphore.o setup.o signal.o \
sys_ia64.o traps.o time.o unaligned.o unwind.o
O_OBJS := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_sapic.o ivt.o \
pal.o pci-dma.o process.o perfmon.o ptrace.o sal.o sal_stub.o semaphore.o setup.o \
signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
#O_OBJS := fpreg.o
#OX_OBJS := ia64_ksyms.o
ifeq ($(CONFIG_IA64_GENERIC),y)
ifdef CONFIG_IA64_GENERIC
O_OBJS += machvec.o
endif
......@@ -30,10 +30,10 @@ O_OBJS += pci.o
endif
ifdef CONFIG_SMP
O_OBJS += smp.o irq_lock.o
O_OBJS += smp.o
endif
ifeq ($(CONFIG_MCA),y)
ifdef CONFIG_IA64_MCA
O_OBJS += mca.o mca_asm.o
endif
......
......@@ -11,12 +11,12 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/irq.h>
#include <asm/acpi-ext.h>
#include <asm/page.h>
......@@ -27,13 +27,12 @@
#undef ACPI_DEBUG /* Guess what this does? */
#ifdef CONFIG_SMP
extern unsigned long ipi_base_addr;
extern struct smp_boot_data smp;
#endif
/* These are ugly but will be reclaimed by the kernel */
int __initdata acpi_cpus = 0;
int __initdata acpi_apic_map[32];
int __initdata cpu_cnt = 0;
int __initdata available_cpus = 0;
int __initdata total_cpus = 0;
void (*pm_idle) (void);
......@@ -50,7 +49,7 @@ acpi_lsapic(char *p)
if ((lsapic->flags & LSAPIC_PRESENT) == 0)
return;
printk(" CPU %d (%.04x:%.04x): ", cpu_cnt, lsapic->eid, lsapic->id);
printk(" CPU %d (%.04x:%.04x): ", total_cpus, lsapic->eid, lsapic->id);
if ((lsapic->flags & LSAPIC_ENABLED) == 0) {
printk("Disabled.\n");
......@@ -62,11 +61,17 @@ acpi_lsapic(char *p)
if (add) {
printk("Available.\n");
acpi_cpus++;
acpi_apic_map[cpu_cnt] = (lsapic->id << 8) | lsapic->eid;
available_cpus++;
#ifdef CONFIG_SMP
# if LARGE_CPU_ID_OK
smp.cpu_map[total_cpus] = (lsapic->id << 8) | lsapic->eid;
# else
smp.cpu_map[total_cpus] = lsapic->id;
# endif
#endif
}
cpu_cnt++;
total_cpus++;
}
/*
......@@ -174,7 +179,7 @@ acpi_legacy_irq(char *p)
break;
}
#ifdef ACPI_DEBUG
#if 1/*def ACPI_DEBUG*/
printk("Legacy ISA IRQ %x -> IA64 Vector %x IOSAPIC Pin %x Active %s %s Trigger\n",
legacy->isa_irq, vector, iosapic_pin(vector),
((iosapic_polarity(vector) == IO_SAPIC_POL_LOW) ? "Low" : "High"),
......@@ -204,11 +209,11 @@ acpi_parse_msapic(acpi_sapic_t *msapic)
{
char *p, *end;
memset(&acpi_apic_map, -1, sizeof(acpi_apic_map));
/* Base address of IPI Message Block */
ipi_base_addr = (unsigned long) ioremap(msapic->interrupt_block, 0);
#ifdef CONFIG_SMP
/* Base address of IPI Message Block */
ipi_base_addr = ioremap(msapic->interrupt_block, 0);
memset(&smp, -1, sizeof(smp));
#endif
p = (char *) (msapic + 1);
......@@ -238,11 +243,22 @@ acpi_parse_msapic(acpi_sapic_t *msapic)
}
/* Move to next table entry. */
p += *(p + 1);
#define BAD_ACPI_TABLE
#ifdef BAD_ACPI_TABLE
/*
* Some prototype Lion's have a bad ACPI table
* requiring this fix. Without this fix, those
* machines crash during bootup.
*/
if (p[1] == 0)
p = end;
else
#endif
p += p[1];
}
/* Make bootup pretty */
printk(" %d CPUs available, %d CPUs total\n", acpi_cpus, cpu_cnt);
printk(" %d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
}
int __init
......@@ -281,12 +297,15 @@ acpi_parse(acpi_rsdp_t *rsdp)
continue;
acpi_parse_msapic((acpi_sapic_t *) hdrp);
} /* while() */
}
if (acpi_cpus == 0) {
#ifdef CONFIG_SMP
if (available_cpus == 0) {
printk("ACPI: Found 0 CPUS; assuming 1\n");
acpi_cpus = 1; /* We've got at least one of these, no? */
available_cpus = 1; /* We've got at least one of these, no? */
}
smp.cpu_count = available_cpus;
#endif
return 1;
}
......
......@@ -24,7 +24,7 @@
#include <asm/io.h>
#include <asm/processor.h>
#define EFI_DEBUG
#define EFI_DEBUG 0
extern efi_status_t efi_call_phys (void *, ...);
......@@ -210,9 +210,8 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
void __init
efi_init (void)
{
void *efi_map_start, *efi_map_end, *p;
void *efi_map_start, *efi_map_end;
efi_config_table_t *config_tables;
efi_memory_desc_t *md;
efi_char16_t *c16;
u64 efi_desc_size;
char vendor[100] = "unknown";
......@@ -278,13 +277,18 @@ efi_init (void)
efi_map_end = efi_map_start + ia64_boot_param.efi_memmap_size;
efi_desc_size = ia64_boot_param.efi_memdesc_size;
#ifdef EFI_DEBUG
#if EFI_DEBUG
/* print EFI memory map: */
for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
md = p;
printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
i, md->type, md->attribute,
md->phys_addr, md->phys_addr + (md->num_pages<<12) - 1, md->num_pages >> 8);
{
efi_memory_desc_t *md = p;
void *p;
for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
md = p;
printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
i, md->type, md->attribute, md->phys_addr,
md->phys_addr + (md->num_pages<<12) - 1, md->num_pages >> 8);
}
}
#endif
}
......
......@@ -25,6 +25,7 @@
#include <linux/config.h>
#include <asm/cache.h>
#include <asm/errno.h>
#include <asm/offsets.h>
#include <asm/processor.h>
......@@ -228,11 +229,11 @@ save_switch_stack:
stf.spill [r2]=f30,32
stf.spill [r3]=f31,24
;;
st8.spill [r2]=r4,16
st8.spill [r3]=r5,16
.mem.offset 0,0; st8.spill [r2]=r4,16
.mem.offset 8,0; st8.spill [r3]=r5,16
;;
st8.spill [r2]=r6,16
st8.spill [r3]=r7,16
.mem.offset 0,0; st8.spill [r2]=r6,16
.mem.offset 8,0; st8.spill [r3]=r7,16
;;
st8 [r2]=r21,16 // save b0
st8 [r3]=r22,16 // save b1
......@@ -437,8 +438,8 @@ strace_check_retval:
(p6) br.cond.sptk.few strace_error // syscall failed ->
;; // avoid RAW on r10
strace_save_retval:
st8.spill [r2]=r8 // store return value in slot for r8
st8.spill [r3]=r10 // clear error indication in slot for r10
.mem.offset 0,0; st8.spill [r2]=r8 // store return value in slot for r8
.mem.offset 8,0; st8.spill [r3]=r10 // clear error indication in slot for r10
ia64_strace_leave_kernel:
br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch return value
.ret6: br.cond.sptk.many ia64_leave_kernel
......@@ -491,7 +492,9 @@ ia64_ret_from_syscall:
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
adds r3=IA64_PT_REGS_R8_OFFSET+32,sp // r3 = &pt_regs.r10
;;
.mem.offset 0,0
(p6) st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit
.mem.offset 8,0
(p6) st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit
(p7) br.cond.spnt.few handle_syscall_error // handle potential syscall failure
......@@ -504,7 +507,9 @@ ia64_leave_kernel:
;;
ld4 r2=[r2]
;;
shladd r3=r2,3,r3
shl r2=r2,SMP_LOG_CACHE_BYTES // can't use shladd here...
;;
add r3=r2,r3
#else
movl r3=softirq_state
#endif
......@@ -550,6 +555,16 @@ back_from_resched:
2:
// check & deliver pending signals:
(p2) br.call.spnt.few rp=handle_signal_delivery
#if defined(CONFIG_SMP) || defined(CONFIG_IA64_SOFTSDV_HACKS)
// Check for lost ticks
mov r2 = ar.itc
mov r3 = cr.itm
;;
sub r2 = r2, r3
;;
cmp.ge p6,p7 = r2, r0
(p6) br.call.spnt.few rp=invoke_ia64_reset_itm
#endif
restore_all:
// start restoring the state saved on the kernel stack (struct pt_regs):
......@@ -735,8 +750,8 @@ handle_syscall_error:
(p6) mov r9=r8
(p6) mov r10=0
;;
st8.spill [r2]=r9 // store errno in pt_regs.r8 and set unat bit
st8.spill [r3]=r10 // store error indication in pt_regs.r10 and set unat bit
.mem.offset 0,0; st8.spill [r2]=r9 // store errno in pt_regs.r8 and set unat bit
.mem.offset 8,0; st8.spill [r3]=r10 // store error indication in pt_regs.r10 and set unat bit
br.cond.sptk.many ia64_leave_kernel
.endp handle_syscall_error
......@@ -757,6 +772,19 @@ invoke_schedule_tail:
mov rp=loc1
br.ret.sptk.many rp
.endp invoke_schedule_tail
.proc invoke_ia64_reset_itm
invoke_ia64_reset_itm:
alloc loc0=ar.pfs,8,2,0,0
mov loc1=rp
;;
br.call.sptk.many rp=ia64_reset_itm
;;
mov ar.pfs=loc0
mov rp=loc1
br.ret.sptk.many rp
.endp invoke_ia64_reset_itm
#endif /* CONFIG_SMP */
/*
......@@ -855,26 +883,22 @@ setup_switch_stack:
.global sys_rt_sigsuspend
sys_rt_sigsuspend:
alloc loc0=ar.pfs,2,2,3,0
mov r9=ar.unat
// If the process is being ptraced, the signal may not actually be delivered to
// the process. Instead, SIGCHLD will be sent to the parent. We need to
// setup a switch_stack so ptrace can inspect the processes state if necessary.
adds r2=IA64_TASK_FLAGS_OFFSET,r13
;;
ld8 r2=[r2]
// Also, the process might not ptraced until stopped in sigsuspend, so this
// isn't something that we can do conditionally based upon the value of
// PF_PTRACED_BIT.
mov out0=in0 // mask
mov out1=in1 // sigsetsize
;;
adds out2=16,sp // out1=&pt_regs
tbit.nz p16,p17=r2,PF_PTRACED_BIT
(p16) br.cond.spnt.many sigsuspend_setup_switch_stack
movl r28=back_from_sigsuspend_setup_switch_stack
mov r16=loc0
br.cond.sptk.many save_switch_stack
;;
back_from_sigsuspend_setup_switch_stack:
adds r3=-IA64_SWITCH_STACK_SIZE+IA64_SWITCH_STACK_CALLER_UNAT_OFFSET+16,sp
(p17) adds sp=-IA64_SWITCH_STACK_SIZE,sp // make space for (dummy) switch_stack
;;
(p17) st8 [r3]=r9 // save ar.unat in sw->caller_unat
mov loc1=rp // save return address
br.call.sptk.many rp=ia64_rt_sigsuspend
.ret12:
......@@ -883,32 +907,22 @@ back_from_sigsuspend_setup_switch_stack:
ld8 r9=[r3] // load new unat from sw->caller_unat
mov rp=loc1
;;
(p17) adds sp=IA64_SWITCH_STACK_SIZE,sp // drop (dummy) switch_stack
(p17) mov ar.unat=r9
(p17) mov ar.pfs=loc0
(p17) br.ret.sptk.many rp
// restore the switch stack (ptrace may have modified it):
movl r28=1f
br.cond.sptk.many load_switch_stack
1: br.ret.sptk.many rp
// NOT REACHED
sigsuspend_setup_switch_stack:
movl r28=back_from_sigsuspend_setup_switch_stack
mov r16=loc0
br.cond.sptk.many save_switch_stack
// NOT REACHED
.endp sys_rt_sigsuspend
.align 16
.proc sys_rt_sigreturn
sys_rt_sigreturn:
alloc loc0=ar.pfs,8,1,1,0 // preserve all eight input regs in case of syscall restart!
.regstk 0,0,3,0 // inherited from gate.s:invoke_sighandler()
adds out0=16,sp // out0 = &pt_regs
;;
adds sp=-IA64_SWITCH_STACK_SIZE,sp // make space for unat and padding
;;
cmp.eq pNonSys,p0=r0,r0 // sigreturn isn't a normal syscall...
br.call.sptk.few rp=ia64_rt_sigreturn
.ret13:
adds r3=IA64_SWITCH_STACK_CALLER_UNAT_OFFSET+16,sp
......@@ -918,8 +932,7 @@ sys_rt_sigreturn:
;;
adds sp=IA64_SWITCH_STACK_SIZE,sp // drop (dummy) switch-stack frame
mov ar.unat=r9
mov ar.pfs=loc0
br.ret.sptk.many rp
br rp
.endp sys_rt_sigreturn
.align 16
......@@ -940,76 +953,6 @@ ia64_prepare_handle_unaligned:
2: br.cond.sptk.many rp // goes to ia64_leave_kernel
.endp ia64_prepare_handle_unaligned
#ifdef CONFIG_KDB
//
// This gets called from ivt.S with:
// SAVE MIN with cover done
// SAVE REST done
// no parameters
// r15 has return value = ia64_leave_kernel
//
.align 16
.global ia64_invoke_kdb
.proc ia64_invoke_kdb
ia64_invoke_kdb:
alloc r16=ar.pfs,0,0,4,0
movl r28=1f // save_switch_stack protocol
;; // avoid WAW on CFM
br.cond.sptk.many save_switch_stack // to flushrs
1: mov out0=4 // kdb entry reason
mov out1=0 // err number
adds out2=IA64_SWITCH_STACK_SIZE+16,sp // pt_regs
add out3=16,sp // switch_stack
br.call.sptk.few rp=kdb
.ret15:
movl r28=1f // load_switch_stack proto
br.cond.sptk.many load_switch_stack
1: br.ret.sptk.many rp
.endp ia64_invoke_kdb
//
// When KDB is compiled in, we intercept each fault and give
// kdb a chance to run before calling the normal fault handler.
//
.align 16
.global ia64_invoke_kdb_fault_handler
.proc ia64_invoke_kdb_fault_handler
ia64_invoke_kdb_fault_handler:
alloc r16=ar.pfs,5,1,5,0
movl r28=1f
mov loc0=rp // save this
br.cond.sptk.many save_switch_stack // to flushrs
;; // avoid WAW on CFM
1: mov out0=in0 // vector number
mov out1=in1 // cr.isr
mov out2=in2 // cr.ifa
mov out3=in3 // cr.iim
mov out4=in4 // cr.itir
br.call.sptk.few rp=ia64_kdb_fault_handler
.ret16:
movl r28=1f
br.cond.sptk.many load_switch_stack
1: cmp.ne p6,p0=r8,r0 // did ia64_kdb_fault_handler return 0?
mov rp=loc0
(p6) br.ret.spnt.many rp // no, we're done
;; // avoid WAW on rp
mov out0=in0 // vector number
mov out1=in1 // cr.isr
mov out2=in2 // cr.ifa
mov out3=in3 // cr.iim
mov out4=in4 // cr.itir
mov in0=ar.pfs // preserve ar.pfs returned by load_switch_stack
br.call.sptk.few rp=ia64_fault // yup -> we need to invoke normal fault handler now
.ret17:
mov ar.pfs=in0
mov rp=loc0
br.ret.sptk.many rp
.endp ia64_invoke_kdb_fault_handler
#endif /* CONFIG_KDB */
.rodata
.align 8
.globl sys_call_table
......@@ -1198,8 +1141,8 @@ sys_call_table:
data8 sys_sendmsg // 1205
data8 sys_recvmsg
data8 sys_pivot_root
data8 ia64_ni_syscall
data8 ia64_ni_syscall
data8 sys_mincore
data8 sys_madvise
data8 ia64_ni_syscall // 1210
data8 ia64_ni_syscall
data8 ia64_ni_syscall
......
......@@ -80,8 +80,6 @@
ia64_sigtramp:
ld8 r10=[r3],8 // get signal handler entry point
br.call.sptk.many rp=invoke_sighandler
.ret0: mov r15=__NR_rt_sigreturn
break __BREAK_SYSCALL
.endp ia64_sigtramp
.proc invoke_sighandler
......@@ -90,10 +88,9 @@ invoke_sighandler:
mov b6=r10
cover // push args in interrupted frame onto backing store
;;
alloc r8=ar.pfs,0,1,3,0 // get CFM0, EC0, and CPL0 into r8
mov r17=ar.bsp // fetch ar.bsp
mov loc0=rp // save return pointer
alloc r8=ar.pfs,0,0,3,0 // get CFM0, EC0, and CPL0 into r8
;;
mov r17=ar.bsp // fetch ar.bsp
cmp.ne p8,p0=r15,r0 // do we need to switch the rbs?
mov out0=r2 // signal number
(p8) br.cond.spnt.few setup_rbs // yup -> (clobbers r14 and r16)
......@@ -101,10 +98,11 @@ back_from_setup_rbs:
adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
;;
st8 [base0]=r17,(CFM_OFF-BSP_OFF) // save sc_ar_bsp
dep r8=0,r8,38,26 // clear EC0, CPL0 and reserved bits
adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
;;
st8 [base0]=r8 // save CFM0, EC0, and CPL0
st8 [base0]=r8 // save CFM0
adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
;;
stf.spill [base0]=f6,32
......@@ -124,7 +122,8 @@ back_from_setup_rbs:
stf.spill [base0]=f14,32
stf.spill [base1]=f15,32
br.call.sptk.few rp=b6 // call the signal handler
.ret2: adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
.ret2:
adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
;;
ld8 r15=[base0],(CFM_OFF-BSP_OFF) // fetch sc_ar_bsp and advance to CFM_OFF
mov r14=ar.bsp
......@@ -134,23 +133,11 @@ back_from_setup_rbs:
(p8) br.cond.spnt.few restore_rbs // yup -> (clobbers r14 and r16)
;;
back_from_restore_rbs:
{
and r9=0x7f,r8 // r9 <- CFM0.sof
extr.u r10=r8,7,7 // r10 <- CFM0.sol
mov r11=ip
}
;;
adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
adds r11=(cont-back_from_restore_rbs),r11
sub r9=r9,r10 // r9 <- CFM0.sof - CFM0.sol == CFM0.nout
;;
adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
dep r9=r9,r9,7,7 // r9.sol = r9.sof
mov b6=r11
;;
ldf.fill f6=[base0],32
ldf.fill f7=[base1],32
mov rp=loc0 // copy return pointer out of stacked register
;;
ldf.fill f8=[base0],32
ldf.fill f9=[base1],32
......@@ -160,26 +147,23 @@ back_from_restore_rbs:
;;
ldf.fill f12=[base0],32
ldf.fill f13=[base1],32
mov ar.pfs=r9
;;
ldf.fill f14=[base0],32
ldf.fill f15=[base1],32
br.ret.sptk.few b6
cont: mov ar.pfs=r8 // ar.pfs = CFM0
br.ret.sptk.few rp // re-establish CFM0
mov r15=__NR_rt_sigreturn
break __BREAK_SYSCALL
.endp invoke_sighandler
.proc setup_rbs
setup_rbs:
flushrs // must be first in insn
;;
mov ar.rsc=r0 // put RSE into enforced lazy mode
adds r16=(RNAT_OFF+SIGCONTEXT_OFF),sp
mov r14=ar.rnat // get rnat as updated by flushrs
;;
mov r14=ar.rnat // get rnat as updated by flushrs
mov ar.bspstore=r15 // set new register backing store area
st8 [r16]=r14 // save sc_ar_rnat
;;
st8 [r16]=r14 // save sc_ar_rnat
mov ar.rsc=0xf // set RSE into eager mode, pl 3
invala // invalidate ALAT
br.cond.sptk.many back_from_setup_rbs
......
......@@ -66,7 +66,7 @@ irq_cpustat_t irq_stat [NR_CPUS];
* Controller mappings for all interrupt sources:
*/
irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
{ [0 ... NR_IRQS-1] = { IRQ_DISABLED, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
static void register_irq_proc (unsigned int irq);
......@@ -164,7 +164,7 @@ int get_irq_list(char *buf)
p += sprintf(p, "%10u ",
atomic_read(&nmi_counter(cpu_logical_map(j))));
p += sprintf(p, "\n");
#if CONFIG_SMP
#if defined(CONFIG_SMP) && defined(__i386__)
p += sprintf(p, "LOC: ");
for (j = 0; j < smp_num_cpus; j++)
p += sprintf(p, "%10u ",
......@@ -182,8 +182,8 @@ int get_irq_list(char *buf)
*/
#ifdef CONFIG_SMP
unsigned char global_irq_holder = NO_PROC_ID;
unsigned volatile int global_irq_lock;
unsigned int global_irq_holder = NO_PROC_ID;
volatile unsigned int global_irq_lock;
extern void show_stack(unsigned long* esp);
......@@ -201,6 +201,10 @@ static void show(char * str)
printk(" %d",local_bh_count(i));
printk(" ]\nStack dumps:");
#ifdef __ia64__
printk(" ]\nStack dumps: <unimplemented on IA-64---please fix me>");
/* for now we don't have stack dumping support... */
#elif __i386__
for(i=0;i< smp_num_cpus;i++) {
unsigned long esp;
if(i==cpu)
......@@ -219,8 +223,13 @@ static void show(char * str)
esp += sizeof(struct task_struct);
show_stack((void*)esp);
}
#else
You lose...
#endif
printk("\nCPU %d:",cpu);
#ifdef __i386__
show_stack(NULL);
#endif
printk("\n");
}
......@@ -250,7 +259,11 @@ static void show(char * str)
/*
* We have to allow irqs to arrive between __sti and __cli
*/
# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
# ifdef __ia64__
# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop 0")
# else
# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
# endif
#endif
static inline void wait_on_irq(int cpu)
......@@ -311,7 +324,7 @@ static inline void get_irqlock(int cpu)
{
if (test_and_set_bit(0,&global_irq_lock)) {
/* do we already hold the lock? */
if ((unsigned char) cpu == global_irq_holder)
if (cpu == global_irq_holder)
return;
/* Uhhuh.. Somebody else got it. Wait.. */
do {
......@@ -349,6 +362,15 @@ void __global_cli(void)
{
unsigned int flags;
#ifdef __ia64__
__save_flags(flags);
if (flags & IA64_PSR_I) {
int cpu = smp_processor_id();
__cli();
if (!local_irq_count(cpu))
get_irqlock(cpu);
}
#else
__save_flags(flags);
if (flags & (1 << EFLAGS_IF_SHIFT)) {
int cpu = smp_processor_id();
......@@ -356,6 +378,7 @@ void __global_cli(void)
if (!local_irq_count(cpu))
get_irqlock(cpu);
}
#endif
}
void __global_sti(void)
......@@ -382,7 +405,11 @@ unsigned long __global_save_flags(void)
int cpu = smp_processor_id();
__save_flags(flags);
#ifdef __ia64__
local_enabled = (flags & IA64_PSR_I) != 0;
#else
local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
#endif
/* default to local */
retval = 2 + local_enabled;
......@@ -479,11 +506,13 @@ void disable_irq(unsigned int irq)
{
disable_irq_nosync(irq);
#ifdef CONFIG_SMP
if (!local_irq_count(smp_processor_id())) {
do {
barrier();
} while (irq_desc[irq].status & IRQ_INPROGRESS);
}
#endif
}
void enable_irq(unsigned int irq)
......@@ -559,15 +588,12 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
/*
* If there is no IRQ handler or it was disabled, exit early.
Since we set PENDING, if another processor is handling
a different instance of this same irq, the other processor
will take care of it.
* Since we set PENDING, if another processor is handling
* a different instance of this same irq, the other processor
* will take care of it.
*/
if (!action)
{
desc->status = status & ~IRQ_INPROGRESS;
goto out;
}
/*
* Edge triggered interrupts need to remember
......@@ -597,15 +623,6 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
desc->handler->end(irq);
spin_unlock(&desc->lock);
#if 0
/*
* let kernel exit path take care of this; we want to do the
* CPU EOI before doing softirq() so a new interrupt can come
* through
*/
if (softirq_state[cpu].active & softirq_state[cpu].mask)
do_softirq();
#endif
return 1;
}
......
This diff is collapsed.
This diff is collapsed.
/*
* Internal Interrupt Vectors
* SAPIC Interrupt Controller
*
* This takes care of interrupts that are generated by the CPU
* internally, such as the ITC and IPI interrupts.
* This takes care of interrupts that are generated by the CPU's
* internal Streamlined Advanced Programmable Interrupt Controller
* (SAPIC), such as the ITC and IPI interrupts.
*
* Copyright (C) 1999 VA Linux Systems
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
......@@ -10,27 +11,28 @@
* Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <linux/sched.h>
#include <linux/irq.h>
static unsigned int
internal_noop_startup (unsigned int irq)
sapic_noop_startup (unsigned int irq)
{
return 0;
}
static void
internal_noop (unsigned int irq)
sapic_noop (unsigned int irq)
{
/* nuthing to do... */
}
struct hw_interrupt_type irq_type_ia64_internal = {
typename: "IA64-internal",
startup: internal_noop_startup,
shutdown: internal_noop,
enable: internal_noop,
disable: internal_noop,
ack: internal_noop,
end: internal_noop,
set_affinity: (void (*)(unsigned int, unsigned long)) internal_noop
struct hw_interrupt_type irq_type_ia64_sapic = {
typename: "SAPIC",
startup: sapic_noop_startup,
shutdown: sapic_noop,
enable: sapic_noop,
disable: sapic_noop,
ack: sapic_noop,
end: sapic_noop,
set_affinity: (void (*)(unsigned int, unsigned long)) sapic_noop
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -139,7 +139,7 @@ ia64_sal_init (struct ia64_sal_systab *systab)
case IA64_SAL_AP_EXTERNAL_INT:
ap_wakeup_vector = ap->vector;
# ifdef SAL_DEBUG
printk("SAL: AP wakeup using external interrupt; "
printk("SAL: AP wakeup using external interrupt "
"vector 0x%lx\n", ap_wakeup_vector);
# endif
break;
......@@ -151,6 +151,36 @@ ia64_sal_init (struct ia64_sal_systab *systab)
break;
}
#endif
case SAL_DESC_PLATFORM_FEATURE:
{
struct ia64_sal_desc_platform_feature *pf = (void *) p;
printk("SAL: Platform features ");
if (pf->feature_mask & (1 << 0))
printk("BusLock ");
if (pf->feature_mask & (1 << 1)) {
printk("IRQ_Redirection ");
#ifdef CONFIG_SMP
if (no_int_routing)
smp_int_redirect &= ~SMP_IRQ_REDIRECTION;
else
smp_int_redirect |= SMP_IRQ_REDIRECTION;
#endif
}
if (pf->feature_mask & (1 << 2)) {
printk("IPI_Redirection ");
#ifdef CONFIG_SMP
if (no_int_routing)
smp_int_redirect &= ~SMP_IPI_REDIRECTION;
else
smp_int_redirect |= SMP_IPI_REDIRECTION;
#endif
}
printk("\n");
break;
}
}
p += SAL_DESC_SIZE(*p);
}
......
This diff is collapsed.
......@@ -310,7 +310,7 @@ __down_write_failed (struct rw_semaphore *sem, long count)
do {
old_count = sem->count;
count = old_count - RW_LOCK_BIAS;
} while (cmpxchg(&sem->count, old_count, count) != old_count);
} while (cmpxchg_acq(&sem->count, old_count, count) != old_count);
if (count == 0)
return;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
unsigned long cpu_online_map;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -210,6 +210,7 @@ long_do_clear:
// if p7 -> coming from st4 or st1 : len3 contains what's left
// We must restore lc/pr even though might not have been used.
.Lexit2:
.pred.rel "mutex", p6, p7
(p6) mov len=len2
(p7) mov len=len3
;;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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