/*
* Here is where the ball gets rolling as far as the kernel is concerned.
* When control is transferred to _start, the bootload has already
* loaded us to the correct address. All that's left to do here is
* to set up the kernel's global pointer and jump to the kernel
* entry point.
*
* Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* Stephane Eranian <eranian@hpl.hp.com>
* Copyright (C) 1999 VA Linux Systems
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
* Copyright (C) 1999 Intel Corp.
* Copyright (C) 1999 Asit Mallick <Asit.K.Mallick@intel.com>
* Copyright (C) 1999 Don Dugger <Don.Dugger@intel.com>
* Copyright (C) 2002 Fenghua Yu <fenghua.yu@intel.com>
* -Optimize __ia64_save_fpu() and __ia64_load_fpu() for Itanium 2.
* Copyright (C) 2004 Ashok Raj <ashok.raj@intel.com>
* Support for CPU Hotplug
*/
#include <asm/asmmacro.h>
#include <asm/fpu.h>
#include <asm/kregs.h>
#include <asm/mmu_context.h>
#include <asm/asm-offsets.h>
#include <asm/pal.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/mca_asm.h>
#ifdef CONFIG_HOTPLUG_CPU
#define SAL_PSR_BITS_TO_SET \
(IA64_PSR_AC | IA64_PSR_BN | IA64_PSR_MFH | IA64_PSR_MFL)
#define SAVE_FROM_REG(src, ptr, dest) \
mov dest=src;; \
st8 [ptr]=dest,0x08
#define RESTORE_REG(reg, ptr, _tmp) \
ld8 _tmp=[ptr],0x08;; \
mov reg=_tmp
#define SAVE_BREAK_REGS(ptr, _idx, _breg, _dest)\
mov ar.lc=IA64_NUM_DBG_REGS-1;; \
mov _idx=0;; \
1: \
SAVE_FROM_REG(_breg[_idx], ptr, _dest);; \
add _idx=1,_idx;; \
br.cloop.sptk.many 1b
#define RESTORE_BREAK_REGS(ptr, _idx, _breg, _tmp, _lbl)\
mov ar.lc=IA64_NUM_DBG_REGS-1;; \
mov _idx=0;; \
_lbl: RESTORE_REG(_breg[_idx], ptr, _tmp);; \
add _idx=1, _idx;; \
br.cloop.sptk.many _lbl
#define SAVE_ONE_RR(num, _reg, _tmp) \
movl _tmp=(num<<61);; \
mov _reg=rr[_tmp]
#define SAVE_REGION_REGS(_tmp, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) \
SAVE_ONE_RR(0,_r0, _tmp);; \
SAVE_ONE_RR(1,_r1, _tmp);; \
SAVE_ONE_RR(2,_r2, _tmp);; \
SAVE_ONE_RR(3,_r3, _tmp);; \
SAVE_ONE_RR(4,_r4, _tmp);; \
SAVE_ONE_RR(5,_r5, _tmp);; \
SAVE_ONE_RR(6,_r6, _tmp);; \
SAVE_ONE_RR(7,_r7, _tmp);;
#define STORE_REGION_REGS(ptr, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) \
st8 [ptr]=_r0, 8;; \
st8 [ptr]=_r1, 8;; \
st8 [ptr]=_r2, 8;; \
st8 [ptr]=_r3, 8;; \
st8 [ptr]=_r4, 8;; \
st8 [ptr]=_r5, 8;; \
st8 [ptr]=_r6, 8;; \
st8 [ptr]=_r7, 8;;
#define RESTORE_REGION_REGS(ptr, _idx1, _idx2, _tmp) \
mov ar.lc=0x08-1;; \
movl _idx1=0x00;; \
RestRR: \
dep.z _idx2=_idx1,61,3;; \
ld8 _tmp=[ptr],8;; \
mov rr[_idx2]=_tmp;; \
srlz.d;; \
add _idx1=1,_idx1;; \
br.cloop.sptk.few RestRR
#define SET_AREA_FOR_BOOTING_CPU(reg1, reg2) \
movl reg1=sal_state_for_booting_cpu;; \
ld8 reg2=[reg1];;
/*
* Adjust region registers saved before starting to save
* break regs and rest of the states that need to be preserved.
*/
#define SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(_reg1,_reg2,_pred) \
SAVE_FROM_REG(b0,_reg1,_reg2);; \