//
// assembly portion of the IA64 MCA handling
//
// Mods by cfleck to integrate into kernel build
// 00/03/15 davidm Added various stop bits to get a clean compile
//
// 00/03/29 cfleck Added code to save INIT handoff state in pt_regs format, switch to temp
// kstack, switch modes, jump to C INIT handler
//
// 02/01/04 J.Hall <jenna.s.hall@intel.com>
// Before entering virtual mode code:
// 1. Check for TLB CPU error
// 2. Restore current thread pointer to kr6
// 3. Move stack ptr 16 bytes to conform to C calling convention
//
// 04/11/12 Russ Anderson <rja@sgi.com>
// Added per cpu MCA/INIT stack save areas.
//
// 12/08/05 Keith Owens <kaos@sgi.com>
// Use per cpu MCA/INIT stacks for all data.
//
#include <linux/threads.h>
#include <asm/asmmacro.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/mca_asm.h>
#include <asm/mca.h>
#include "entry.h"
#define GET_IA64_MCA_DATA(reg) \
GET_THIS_PADDR(reg, ia64_mca_data) \
;; \
ld8 reg=[reg]
.global ia64_do_tlb_purge
.global ia64_os_mca_dispatch
.global ia64_os_init_dispatch_monarch
.global ia64_os_init_dispatch_slave
.text
.align 16
//StartMain////////////////////////////////////////////////////////////////////
/*
* Just the TLB purge part is moved to a separate function
* so we can re-use the code for cpu hotplug code as well
* Caller should now setup b1, so we can branch once the
* tlb flush is complete.
*/
ia64_do_tlb_purge:
#define O(member) IA64_CPUINFO_##member##_OFFSET
GET_THIS_PADDR(r2, cpu_info) // load phys addr of cpu_info into r2
;;
addl r17=O(PTCE_STRIDE),r2
addl r2=O(PTCE_BASE),r2
;;
ld8 r18=[r2],(O(PTCE_COUNT)-O(PTCE_BASE));; // r18=ptce_base
ld4 r19=[r2],4 // r19=ptce_count[0]
ld4 r21=[r17],4 // r21=ptce_stride[0]
;;
ld4 r20=[r2] // r20=ptce_count[1]
ld4 r22=[r17] // r22=ptce_stride[1]
mov r24=0
;;
adds r20=-1,r20
;;
#undef O
2:
cmp.ltu p6,p7=r24,r19
(p7) br.cond.dpnt.few 4f
mov ar.lc=r20
3:
ptc.e r18
;;
add r18=r22,r18
br.cloop.sptk.few 3b
;;
add r18=r21,r18
add r24=1,r24
;;
br.sptk.few 2b
4:
srlz.i // srlz.i implies srlz.d
;;
// Now purge addresses formerly mapped by TR registers
// 1. Purge ITR&DTR for kernel.
movl r16=KERNEL_START
mov r18=KERNEL_TR_PAGE_SHIFT<<2
;;
ptr.i r16, r18
ptr.d r16, r18
;;
srlz.i
;;
srlz.d
;;
// 3. Purge ITR for PAL code.
GET_THIS_PADDR(r2, ia64_mca_pal_base)
;;
ld8 r16=[r2]
mov r18=IA64_GRANULE_SHIFT<<2
;;