1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */ 21da177e4SLinus Torvalds/* 31da177e4SLinus Torvalds * arch/ia64/kernel/ivt.S 41da177e4SLinus Torvalds * 5060561ffSDavid Mosberger-Tang * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co 61da177e4SLinus Torvalds * Stephane Eranian <eranian@hpl.hp.com> 71da177e4SLinus Torvalds * David Mosberger <davidm@hpl.hp.com> 81da177e4SLinus Torvalds * Copyright (C) 2000, 2002-2003 Intel Co 91da177e4SLinus Torvalds * Asit Mallick <asit.k.mallick@intel.com> 101da177e4SLinus Torvalds * Suresh Siddha <suresh.b.siddha@intel.com> 111da177e4SLinus Torvalds * Kenneth Chen <kenneth.w.chen@intel.com> 121da177e4SLinus Torvalds * Fenghua Yu <fenghua.yu@intel.com> 131da177e4SLinus Torvalds * 141da177e4SLinus Torvalds * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP 151da177e4SLinus Torvalds * 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB handler now uses virtual PT. 16498c5170SIsaku Yamahata * 17498c5170SIsaku Yamahata * Copyright (C) 2005 Hewlett-Packard Co 18498c5170SIsaku Yamahata * Dan Magenheimer <dan.magenheimer@hp.com> 19498c5170SIsaku Yamahata * Xen paravirtualization 20498c5170SIsaku Yamahata * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> 21498c5170SIsaku Yamahata * VA Linux Systems Japan K.K. 22498c5170SIsaku Yamahata * pv_ops. 23498c5170SIsaku Yamahata * Yaozu (Eddie) Dong <eddie.dong@intel.com> 241da177e4SLinus Torvalds */ 251da177e4SLinus Torvalds/* 261da177e4SLinus Torvalds * This file defines the interruption vector table used by the CPU. 271da177e4SLinus Torvalds * It does not include one entry per possible cause of interruption. 281da177e4SLinus Torvalds * 291da177e4SLinus Torvalds * The first 20 entries of the table contain 64 bundles each while the 301da177e4SLinus Torvalds * remaining 48 entries contain only 16 bundles each. 311da177e4SLinus Torvalds * 321da177e4SLinus Torvalds * The 64 bundles are used to allow inlining the whole handler for critical 331da177e4SLinus Torvalds * interruptions like TLB misses. 341da177e4SLinus Torvalds * 351da177e4SLinus Torvalds * For each entry, the comment is as follows: 361da177e4SLinus Torvalds * 371da177e4SLinus Torvalds * // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) 381da177e4SLinus Torvalds * entry offset ----/ / / / / 391da177e4SLinus Torvalds * entry number ---------/ / / / 401da177e4SLinus Torvalds * size of the entry -------------/ / / 411da177e4SLinus Torvalds * vector name -------------------------------------/ / 421da177e4SLinus Torvalds * interruptions triggering this vector ----------------------/ 431da177e4SLinus Torvalds * 441da177e4SLinus Torvalds * The table is 32KB in size and must be aligned on 32KB boundary. 451da177e4SLinus Torvalds * (The CPU ignores the 15 lower bits of the address) 461da177e4SLinus Torvalds * 471da177e4SLinus Torvalds * Table is based upon EAS2.6 (Oct 1999) 481da177e4SLinus Torvalds */ 491da177e4SLinus Torvalds 50*ab03e604SMasahiro Yamada#include <linux/export.h> 5165fddcfcSMike Rapoport#include <linux/pgtable.h> 521da177e4SLinus Torvalds#include <asm/asmmacro.h> 531da177e4SLinus Torvalds#include <asm/break.h> 541da177e4SLinus Torvalds#include <asm/kregs.h> 5539e01cb8SSam Ravnborg#include <asm/asm-offsets.h> 561da177e4SLinus Torvalds#include <asm/processor.h> 571da177e4SLinus Torvalds#include <asm/ptrace.h> 581da177e4SLinus Torvalds#include <asm/thread_info.h> 591da177e4SLinus Torvalds#include <asm/unistd.h> 601da177e4SLinus Torvalds#include <asm/errno.h> 611da177e4SLinus Torvalds 62c0b5a64dSTony Luck#if 0 631da177e4SLinus Torvalds# define PSR_DEFAULT_BITS psr.ac 641da177e4SLinus Torvalds#else 651da177e4SLinus Torvalds# define PSR_DEFAULT_BITS 0 661da177e4SLinus Torvalds#endif 671da177e4SLinus Torvalds 681da177e4SLinus Torvalds#if 0 691da177e4SLinus Torvalds /* 701da177e4SLinus Torvalds * This lets you track the last eight faults that occurred on the CPU. Make sure ar.k2 isn't 711da177e4SLinus Torvalds * needed for something else before enabling this... 721da177e4SLinus Torvalds */ 731da177e4SLinus Torvalds# define DBG_FAULT(i) mov r16=ar.k2;; shl r16=r16,8;; add r16=(i),r16;;mov ar.k2=r16 741da177e4SLinus Torvalds#else 751da177e4SLinus Torvalds# define DBG_FAULT(i) 761da177e4SLinus Torvalds#endif 771da177e4SLinus Torvalds 781da177e4SLinus Torvalds#include "minstate.h" 791da177e4SLinus Torvalds 801da177e4SLinus Torvalds#define FAULT(n) \ 811da177e4SLinus Torvalds mov r31=pr; \ 821da177e4SLinus Torvalds mov r19=n;; /* prepare to save predicates */ \ 831da177e4SLinus Torvalds br.sptk.many dispatch_to_fault_handler 841da177e4SLinus Torvalds 852b55f367SDenys Vlasenko .section .text..ivt,"ax" 861da177e4SLinus Torvalds 871da177e4SLinus Torvalds .align 32768 // align on 32KB boundary 881da177e4SLinus Torvalds .global ia64_ivt 897d59313fSMasahiro Yamada EXPORT_SYMBOL(ia64_ivt) 901da177e4SLinus Torvaldsia64_ivt: 911da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 921da177e4SLinus Torvalds// 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47) 931da177e4SLinus TorvaldsENTRY(vhpt_miss) 941da177e4SLinus Torvalds DBG_FAULT(0) 951da177e4SLinus Torvalds /* 961da177e4SLinus Torvalds * The VHPT vector is invoked when the TLB entry for the virtual page table 971da177e4SLinus Torvalds * is missing. This happens only as a result of a previous 981da177e4SLinus Torvalds * (the "original") TLB miss, which may either be caused by an instruction 991da177e4SLinus Torvalds * fetch or a data access (or non-access). 1001da177e4SLinus Torvalds * 101e8aabc47SChen, Kenneth W * What we do here is normal TLB miss handing for the _original_ miss, 102e8aabc47SChen, Kenneth W * followed by inserting the TLB entry for the virtual page table page 103e8aabc47SChen, Kenneth W * that the VHPT walker was attempting to access. The latter gets 104e8aabc47SChen, Kenneth W * inserted as long as page table entry above pte level have valid 105e8aabc47SChen, Kenneth W * mappings for the faulting address. The TLB entry for the original 106e8aabc47SChen, Kenneth W * miss gets inserted only if the pte entry indicates that the page is 107e8aabc47SChen, Kenneth W * present. 1081da177e4SLinus Torvalds * 1091da177e4SLinus Torvalds * do_page_fault gets invoked in the following cases: 1101da177e4SLinus Torvalds * - the faulting virtual address uses unimplemented address bits 111e8aabc47SChen, Kenneth W * - the faulting virtual address has no valid page table mapping 1121da177e4SLinus Torvalds */ 113498c5170SIsaku Yamahata MOV_FROM_IFA(r16) // get address that caused the TLB miss 1141da177e4SLinus Torvalds#ifdef CONFIG_HUGETLB_PAGE 1151da177e4SLinus Torvalds movl r18=PAGE_SHIFT 116498c5170SIsaku Yamahata MOV_FROM_ITIR(r25) 1171da177e4SLinus Torvalds#endif 1181da177e4SLinus Torvalds ;; 119498c5170SIsaku Yamahata RSM_PSR_DT // use physical addressing for data 1201da177e4SLinus Torvalds mov r31=pr // save the predicate registers 1211da177e4SLinus Torvalds mov r19=IA64_KR(PT_BASE) // get page table base address 1221da177e4SLinus Torvalds shl r21=r16,3 // shift bit 60 into sign bit 1231da177e4SLinus Torvalds shr.u r17=r16,61 // get the region number into r17 1241da177e4SLinus Torvalds ;; 125837cd0bdSRobin Holt shr.u r22=r21,3 1261da177e4SLinus Torvalds#ifdef CONFIG_HUGETLB_PAGE 1271da177e4SLinus Torvalds extr.u r26=r25,2,6 1281da177e4SLinus Torvalds ;; 1291da177e4SLinus Torvalds cmp.ne p8,p0=r18,r26 1301da177e4SLinus Torvalds sub r27=r26,r18 1311da177e4SLinus Torvalds ;; 1321da177e4SLinus Torvalds(p8) dep r25=r18,r25,2,6 1331da177e4SLinus Torvalds(p8) shr r22=r22,r27 1341da177e4SLinus Torvalds#endif 1351da177e4SLinus Torvalds ;; 1361da177e4SLinus Torvalds cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5? 137e8aabc47SChen, Kenneth W shr.u r18=r22,PGDIR_SHIFT // get bottom portion of pgd index bit 1381da177e4SLinus Torvalds ;; 1391da177e4SLinus Torvalds(p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds srlz.d 1421da177e4SLinus Torvalds LOAD_PHYSICAL(p6, r19, swapper_pg_dir) // region 5 is rooted at swapper_pg_dir 1431da177e4SLinus Torvalds 1441da177e4SLinus Torvalds .pred.rel "mutex", p6, p7 1451da177e4SLinus Torvalds(p6) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT 1461da177e4SLinus Torvalds(p7) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3 1471da177e4SLinus Torvalds ;; 148e8aabc47SChen, Kenneth W(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=pgd_offset for region 5 149e8aabc47SChen, Kenneth W(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=pgd_offset for region[0-4] 1501da177e4SLinus Torvalds cmp.eq p7,p6=0,r21 // unused address bits all zeroes? 1514d66bcc7SKirill A. Shutemov#if CONFIG_PGTABLE_LEVELS == 4 152e8aabc47SChen, Kenneth W shr.u r28=r22,PUD_SHIFT // shift pud index into position 153837cd0bdSRobin Holt#else 154e8aabc47SChen, Kenneth W shr.u r18=r22,PMD_SHIFT // shift pmd index into position 155837cd0bdSRobin Holt#endif 1561da177e4SLinus Torvalds ;; 157e8aabc47SChen, Kenneth W ld8 r17=[r17] // get *pgd (may be 0) 1581da177e4SLinus Torvalds ;; 159e8aabc47SChen, Kenneth W(p7) cmp.eq p6,p7=r17,r0 // was pgd_present(*pgd) == NULL? 1604d66bcc7SKirill A. Shutemov#if CONFIG_PGTABLE_LEVELS == 4 161e8aabc47SChen, Kenneth W dep r28=r28,r17,3,(PAGE_SHIFT-3) // r28=pud_offset(pgd,addr) 1621da177e4SLinus Torvalds ;; 163e8aabc47SChen, Kenneth W shr.u r18=r22,PMD_SHIFT // shift pmd index into position 164e8aabc47SChen, Kenneth W(p7) ld8 r29=[r28] // get *pud (may be 0) 1651da177e4SLinus Torvalds ;; 166e8aabc47SChen, Kenneth W(p7) cmp.eq.or.andcm p6,p7=r29,r0 // was pud_present(*pud) == NULL? 167e8aabc47SChen, Kenneth W dep r17=r18,r29,3,(PAGE_SHIFT-3) // r17=pmd_offset(pud,addr) 168837cd0bdSRobin Holt#else 169e8aabc47SChen, Kenneth W dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=pmd_offset(pgd,addr) 170837cd0bdSRobin Holt#endif 1711da177e4SLinus Torvalds ;; 172e8aabc47SChen, Kenneth W(p7) ld8 r20=[r17] // get *pmd (may be 0) 173e8aabc47SChen, Kenneth W shr.u r19=r22,PAGE_SHIFT // shift pte index into position 174837cd0bdSRobin Holt ;; 175e8aabc47SChen, Kenneth W(p7) cmp.eq.or.andcm p6,p7=r20,r0 // was pmd_present(*pmd) == NULL? 176e8aabc47SChen, Kenneth W dep r21=r19,r20,3,(PAGE_SHIFT-3) // r21=pte_offset(pmd,addr) 177837cd0bdSRobin Holt ;; 178e8aabc47SChen, Kenneth W(p7) ld8 r18=[r21] // read *pte 179498c5170SIsaku Yamahata MOV_FROM_ISR(r19) // cr.isr bit 32 tells us if this is an insn miss 1801da177e4SLinus Torvalds ;; 1811da177e4SLinus Torvalds(p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared? 182498c5170SIsaku Yamahata MOV_FROM_IHA(r22) // get the VHPT address that caused the TLB miss 1831da177e4SLinus Torvalds ;; // avoid RAW on p7 1841da177e4SLinus Torvalds(p7) tbit.nz.unc p10,p11=r19,32 // is it an instruction TLB miss? 1851da177e4SLinus Torvalds dep r23=0,r20,0,PAGE_SHIFT // clear low bits to get page address 1861da177e4SLinus Torvalds ;; 187498c5170SIsaku Yamahata ITC_I_AND_D(p10, p11, r18, r24) // insert the instruction TLB entry and 188498c5170SIsaku Yamahata // insert the data TLB entry 1891da177e4SLinus Torvalds(p6) br.cond.spnt.many page_fault // handle bad address/page not present (page fault) 190498c5170SIsaku Yamahata MOV_TO_IFA(r22, r24) 1911da177e4SLinus Torvalds 1921da177e4SLinus Torvalds#ifdef CONFIG_HUGETLB_PAGE 193498c5170SIsaku Yamahata MOV_TO_ITIR(p8, r25, r24) // change to default page-size for VHPT 1941da177e4SLinus Torvalds#endif 1951da177e4SLinus Torvalds 1961da177e4SLinus Torvalds /* 1971da177e4SLinus Torvalds * Now compute and insert the TLB entry for the virtual page table. We never 1981da177e4SLinus Torvalds * execute in a page table page so there is no need to set the exception deferral 1991da177e4SLinus Torvalds * bit. 2001da177e4SLinus Torvalds */ 2011da177e4SLinus Torvalds adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23 2021da177e4SLinus Torvalds ;; 203498c5170SIsaku Yamahata ITC_D(p7, r24, r25) 2041da177e4SLinus Torvalds ;; 2051da177e4SLinus Torvalds#ifdef CONFIG_SMP 2061da177e4SLinus Torvalds /* 2071da177e4SLinus Torvalds * Tell the assemblers dependency-violation checker that the above "itc" instructions 2081da177e4SLinus Torvalds * cannot possibly affect the following loads: 2091da177e4SLinus Torvalds */ 2101da177e4SLinus Torvalds dv_serialize_data 2111da177e4SLinus Torvalds 2121da177e4SLinus Torvalds /* 213e8aabc47SChen, Kenneth W * Re-check pagetable entry. If they changed, we may have received a ptc.g 2141da177e4SLinus Torvalds * between reading the pagetable and the "itc". If so, flush the entry we 215e8aabc47SChen, Kenneth W * inserted and retry. At this point, we have: 216e8aabc47SChen, Kenneth W * 217e8aabc47SChen, Kenneth W * r28 = equivalent of pud_offset(pgd, ifa) 218e8aabc47SChen, Kenneth W * r17 = equivalent of pmd_offset(pud, ifa) 219e8aabc47SChen, Kenneth W * r21 = equivalent of pte_offset(pmd, ifa) 220e8aabc47SChen, Kenneth W * 221e8aabc47SChen, Kenneth W * r29 = *pud 222e8aabc47SChen, Kenneth W * r20 = *pmd 223e8aabc47SChen, Kenneth W * r18 = *pte 2241da177e4SLinus Torvalds */ 225e8aabc47SChen, Kenneth W ld8 r25=[r21] // read *pte again 226e8aabc47SChen, Kenneth W ld8 r26=[r17] // read *pmd again 2274d66bcc7SKirill A. Shutemov#if CONFIG_PGTABLE_LEVELS == 4 228e8aabc47SChen, Kenneth W ld8 r19=[r28] // read *pud again 229837cd0bdSRobin Holt#endif 230837cd0bdSRobin Holt cmp.ne p6,p7=r0,r0 2311da177e4SLinus Torvalds ;; 232e8aabc47SChen, Kenneth W cmp.ne.or.andcm p6,p7=r26,r20 // did *pmd change 2334d66bcc7SKirill A. Shutemov#if CONFIG_PGTABLE_LEVELS == 4 234e8aabc47SChen, Kenneth W cmp.ne.or.andcm p6,p7=r19,r29 // did *pud change 235837cd0bdSRobin Holt#endif 2361da177e4SLinus Torvalds mov r27=PAGE_SHIFT<<2 2371da177e4SLinus Torvalds ;; 2381da177e4SLinus Torvalds(p6) ptc.l r22,r27 // purge PTE page translation 239e8aabc47SChen, Kenneth W(p7) cmp.ne.or.andcm p6,p7=r25,r18 // did *pte change 2401da177e4SLinus Torvalds ;; 2411da177e4SLinus Torvalds(p6) ptc.l r16,r27 // purge translation 2421da177e4SLinus Torvalds#endif 2431da177e4SLinus Torvalds 2441da177e4SLinus Torvalds mov pr=r31,-1 // restore predicate registers 245498c5170SIsaku Yamahata RFI 2461da177e4SLinus TorvaldsEND(vhpt_miss) 2471da177e4SLinus Torvalds 2481da177e4SLinus Torvalds .org ia64_ivt+0x400 2491da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 2501da177e4SLinus Torvalds// 0x0400 Entry 1 (size 64 bundles) ITLB (21) 2511da177e4SLinus TorvaldsENTRY(itlb_miss) 2521da177e4SLinus Torvalds DBG_FAULT(1) 2531da177e4SLinus Torvalds /* 254e8aabc47SChen, Kenneth W * The ITLB handler accesses the PTE via the virtually mapped linear 2551da177e4SLinus Torvalds * page table. If a nested TLB miss occurs, we switch into physical 256e8aabc47SChen, Kenneth W * mode, walk the page table, and then re-execute the PTE read and 257e8aabc47SChen, Kenneth W * go on normally after that. 2581da177e4SLinus Torvalds */ 259498c5170SIsaku Yamahata MOV_FROM_IFA(r16) // get virtual address 2601da177e4SLinus Torvalds mov r29=b0 // save b0 2611da177e4SLinus Torvalds mov r31=pr // save predicates 2621da177e4SLinus Torvalds.itlb_fault: 263498c5170SIsaku Yamahata MOV_FROM_IHA(r17) // get virtual address of PTE 2641da177e4SLinus Torvalds movl r30=1f // load nested fault continuation point 2651da177e4SLinus Torvalds ;; 266e8aabc47SChen, Kenneth W1: ld8 r18=[r17] // read *pte 2671da177e4SLinus Torvalds ;; 2681da177e4SLinus Torvalds mov b0=r29 2691da177e4SLinus Torvalds tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared? 2701da177e4SLinus Torvalds(p6) br.cond.spnt page_fault 2711da177e4SLinus Torvalds ;; 272498c5170SIsaku Yamahata ITC_I(p0, r18, r19) 2731da177e4SLinus Torvalds ;; 2741da177e4SLinus Torvalds#ifdef CONFIG_SMP 2751da177e4SLinus Torvalds /* 2761da177e4SLinus Torvalds * Tell the assemblers dependency-violation checker that the above "itc" instructions 2771da177e4SLinus Torvalds * cannot possibly affect the following loads: 2781da177e4SLinus Torvalds */ 2791da177e4SLinus Torvalds dv_serialize_data 2801da177e4SLinus Torvalds 281e8aabc47SChen, Kenneth W ld8 r19=[r17] // read *pte again and see if same 2821da177e4SLinus Torvalds mov r20=PAGE_SHIFT<<2 // setup page size for purge 2831da177e4SLinus Torvalds ;; 2841da177e4SLinus Torvalds cmp.ne p7,p0=r18,r19 2851da177e4SLinus Torvalds ;; 2861da177e4SLinus Torvalds(p7) ptc.l r16,r20 2871da177e4SLinus Torvalds#endif 2881da177e4SLinus Torvalds mov pr=r31,-1 289498c5170SIsaku Yamahata RFI 2901da177e4SLinus TorvaldsEND(itlb_miss) 2911da177e4SLinus Torvalds 2921da177e4SLinus Torvalds .org ia64_ivt+0x0800 2931da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 2941da177e4SLinus Torvalds// 0x0800 Entry 2 (size 64 bundles) DTLB (9,48) 2951da177e4SLinus TorvaldsENTRY(dtlb_miss) 2961da177e4SLinus Torvalds DBG_FAULT(2) 2971da177e4SLinus Torvalds /* 298e8aabc47SChen, Kenneth W * The DTLB handler accesses the PTE via the virtually mapped linear 2991da177e4SLinus Torvalds * page table. If a nested TLB miss occurs, we switch into physical 300e8aabc47SChen, Kenneth W * mode, walk the page table, and then re-execute the PTE read and 301e8aabc47SChen, Kenneth W * go on normally after that. 3021da177e4SLinus Torvalds */ 303498c5170SIsaku Yamahata MOV_FROM_IFA(r16) // get virtual address 3041da177e4SLinus Torvalds mov r29=b0 // save b0 3051da177e4SLinus Torvalds mov r31=pr // save predicates 3061da177e4SLinus Torvaldsdtlb_fault: 307498c5170SIsaku Yamahata MOV_FROM_IHA(r17) // get virtual address of PTE 3081da177e4SLinus Torvalds movl r30=1f // load nested fault continuation point 3091da177e4SLinus Torvalds ;; 310e8aabc47SChen, Kenneth W1: ld8 r18=[r17] // read *pte 3111da177e4SLinus Torvalds ;; 3121da177e4SLinus Torvalds mov b0=r29 3131da177e4SLinus Torvalds tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared? 3141da177e4SLinus Torvalds(p6) br.cond.spnt page_fault 3151da177e4SLinus Torvalds ;; 316498c5170SIsaku Yamahata ITC_D(p0, r18, r19) 3171da177e4SLinus Torvalds ;; 3181da177e4SLinus Torvalds#ifdef CONFIG_SMP 3191da177e4SLinus Torvalds /* 3201da177e4SLinus Torvalds * Tell the assemblers dependency-violation checker that the above "itc" instructions 3211da177e4SLinus Torvalds * cannot possibly affect the following loads: 3221da177e4SLinus Torvalds */ 3231da177e4SLinus Torvalds dv_serialize_data 3241da177e4SLinus Torvalds 325e8aabc47SChen, Kenneth W ld8 r19=[r17] // read *pte again and see if same 3261da177e4SLinus Torvalds mov r20=PAGE_SHIFT<<2 // setup page size for purge 3271da177e4SLinus Torvalds ;; 3281da177e4SLinus Torvalds cmp.ne p7,p0=r18,r19 3291da177e4SLinus Torvalds ;; 3301da177e4SLinus Torvalds(p7) ptc.l r16,r20 3311da177e4SLinus Torvalds#endif 3321da177e4SLinus Torvalds mov pr=r31,-1 333498c5170SIsaku Yamahata RFI 3341da177e4SLinus TorvaldsEND(dtlb_miss) 3351da177e4SLinus Torvalds 3361da177e4SLinus Torvalds .org ia64_ivt+0x0c00 3371da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 3381da177e4SLinus Torvalds// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19) 3391da177e4SLinus TorvaldsENTRY(alt_itlb_miss) 3401da177e4SLinus Torvalds DBG_FAULT(3) 341498c5170SIsaku Yamahata MOV_FROM_IFA(r16) // get address that caused the TLB miss 3421da177e4SLinus Torvalds movl r17=PAGE_KERNEL 343498c5170SIsaku Yamahata MOV_FROM_IPSR(p0, r21) 3441da177e4SLinus Torvalds movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) 3451da177e4SLinus Torvalds mov r31=pr 3461da177e4SLinus Torvalds ;; 3471da177e4SLinus Torvalds#ifdef CONFIG_DISABLE_VHPT 3481da177e4SLinus Torvalds shr.u r22=r16,61 // get the region number into r21 3491da177e4SLinus Torvalds ;; 3501da177e4SLinus Torvalds cmp.gt p8,p0=6,r22 // user mode 3511da177e4SLinus Torvalds ;; 352498c5170SIsaku Yamahata THASH(p8, r17, r16, r23) 3531da177e4SLinus Torvalds ;; 354498c5170SIsaku Yamahata MOV_TO_IHA(p8, r17, r23) 3551da177e4SLinus Torvalds(p8) mov r29=b0 // save b0 3561da177e4SLinus Torvalds(p8) br.cond.dptk .itlb_fault 3571da177e4SLinus Torvalds#endif 3581da177e4SLinus Torvalds extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl 3591da177e4SLinus Torvalds and r19=r19,r16 // clear ed, reserved bits, and PTE control bits 3601da177e4SLinus Torvalds shr.u r18=r16,57 // move address bit 61 to bit 4 3611da177e4SLinus Torvalds ;; 3621da177e4SLinus Torvalds andcm r18=0x10,r18 // bit 4=~address-bit(61) 3631da177e4SLinus Torvalds cmp.ne p8,p0=r0,r23 // psr.cpl != 0? 3641da177e4SLinus Torvalds or r19=r17,r19 // insert PTE control bits into r19 3651da177e4SLinus Torvalds ;; 3661da177e4SLinus Torvalds or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6 3671da177e4SLinus Torvalds(p8) br.cond.spnt page_fault 3681da177e4SLinus Torvalds ;; 369498c5170SIsaku Yamahata ITC_I(p0, r19, r18) // insert the TLB entry 3701da177e4SLinus Torvalds mov pr=r31,-1 371498c5170SIsaku Yamahata RFI 3721da177e4SLinus TorvaldsEND(alt_itlb_miss) 3731da177e4SLinus Torvalds 3741da177e4SLinus Torvalds .org ia64_ivt+0x1000 3751da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 3761da177e4SLinus Torvalds// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46) 3771da177e4SLinus TorvaldsENTRY(alt_dtlb_miss) 3781da177e4SLinus Torvalds DBG_FAULT(4) 379498c5170SIsaku Yamahata MOV_FROM_IFA(r16) // get address that caused the TLB miss 3801da177e4SLinus Torvalds movl r17=PAGE_KERNEL 381498c5170SIsaku Yamahata MOV_FROM_ISR(r20) 3821da177e4SLinus Torvalds movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) 383498c5170SIsaku Yamahata MOV_FROM_IPSR(p0, r21) 3841da177e4SLinus Torvalds mov r31=pr 38500b65985SChen, Kenneth W mov r24=PERCPU_ADDR 3861da177e4SLinus Torvalds ;; 3871da177e4SLinus Torvalds#ifdef CONFIG_DISABLE_VHPT 3881da177e4SLinus Torvalds shr.u r22=r16,61 // get the region number into r21 3891da177e4SLinus Torvalds ;; 3901da177e4SLinus Torvalds cmp.gt p8,p0=6,r22 // access to region 0-5 3911da177e4SLinus Torvalds ;; 392498c5170SIsaku Yamahata THASH(p8, r17, r16, r25) 3931da177e4SLinus Torvalds ;; 394498c5170SIsaku Yamahata MOV_TO_IHA(p8, r17, r25) 3951da177e4SLinus Torvalds(p8) mov r29=b0 // save b0 3961da177e4SLinus Torvalds(p8) br.cond.dptk dtlb_fault 3971da177e4SLinus Torvalds#endif 39800b65985SChen, Kenneth W cmp.ge p10,p11=r16,r24 // access to per_cpu_data? 39900b65985SChen, Kenneth W tbit.z p12,p0=r16,61 // access to region 6? 40000b65985SChen, Kenneth W mov r25=PERCPU_PAGE_SHIFT << 2 40100b65985SChen, Kenneth W mov r26=PERCPU_PAGE_SIZE 40200b65985SChen, Kenneth W nop.m 0 40300b65985SChen, Kenneth W nop.b 0 40400b65985SChen, Kenneth W ;; 40500b65985SChen, Kenneth W(p10) mov r19=IA64_KR(PER_CPU_DATA) 40600b65985SChen, Kenneth W(p11) and r19=r19,r16 // clear non-ppn fields 4071da177e4SLinus Torvalds extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl 4081da177e4SLinus Torvalds and r22=IA64_ISR_CODE_MASK,r20 // get the isr.code field 4091da177e4SLinus Torvalds tbit.nz p6,p7=r20,IA64_ISR_SP_BIT // is speculation bit on? 4101da177e4SLinus Torvalds tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on? 4111da177e4SLinus Torvalds ;; 41200b65985SChen, Kenneth W(p10) sub r19=r19,r26 413498c5170SIsaku Yamahata MOV_TO_ITIR(p10, r25, r24) 4141da177e4SLinus Torvalds cmp.ne p8,p0=r0,r23 4151da177e4SLinus Torvalds(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field 41600b65985SChen, Kenneth W(p12) dep r17=-1,r17,4,1 // set ma=UC for region 6 addr 4171da177e4SLinus Torvalds(p8) br.cond.spnt page_fault 4181da177e4SLinus Torvalds 4191da177e4SLinus Torvalds dep r21=-1,r21,IA64_PSR_ED_BIT,1 4201da177e4SLinus Torvalds ;; 42100b65985SChen, Kenneth W or r19=r19,r17 // insert PTE control bits into r19 422498c5170SIsaku Yamahata MOV_TO_IPSR(p6, r21, r24) 4231da177e4SLinus Torvalds ;; 424498c5170SIsaku Yamahata ITC_D(p7, r19, r18) // insert the TLB entry 4251da177e4SLinus Torvalds mov pr=r31,-1 426498c5170SIsaku Yamahata RFI 4271da177e4SLinus TorvaldsEND(alt_dtlb_miss) 4281da177e4SLinus Torvalds 4291da177e4SLinus Torvalds .org ia64_ivt+0x1400 4301da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 4311da177e4SLinus Torvalds// 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45) 4321da177e4SLinus TorvaldsENTRY(nested_dtlb_miss) 4331da177e4SLinus Torvalds /* 4341da177e4SLinus Torvalds * In the absence of kernel bugs, we get here when the virtually mapped linear 4351da177e4SLinus Torvalds * page table is accessed non-speculatively (e.g., in the Dirty-bit, Instruction 4361da177e4SLinus Torvalds * Access-bit, or Data Access-bit faults). If the DTLB entry for the virtual page 4371da177e4SLinus Torvalds * table is missing, a nested TLB miss fault is triggered and control is 4381da177e4SLinus Torvalds * transferred to this point. When this happens, we lookup the pte for the 4391da177e4SLinus Torvalds * faulting address by walking the page table in physical mode and return to the 4401da177e4SLinus Torvalds * continuation point passed in register r30 (or call page_fault if the address is 4411da177e4SLinus Torvalds * not mapped). 4421da177e4SLinus Torvalds * 4431da177e4SLinus Torvalds * Input: r16: faulting address 4441da177e4SLinus Torvalds * r29: saved b0 4451da177e4SLinus Torvalds * r30: continuation address 4461da177e4SLinus Torvalds * r31: saved pr 4471da177e4SLinus Torvalds * 448e8aabc47SChen, Kenneth W * Output: r17: physical address of PTE of faulting address 4491da177e4SLinus Torvalds * r29: saved b0 4501da177e4SLinus Torvalds * r30: continuation address 4511da177e4SLinus Torvalds * r31: saved pr 4521da177e4SLinus Torvalds * 4530393eed5SKen Chen * Clobbered: b0, r18, r19, r21, r22, psr.dt (cleared) 4541da177e4SLinus Torvalds */ 455498c5170SIsaku Yamahata RSM_PSR_DT // switch to using physical data addressing 4561da177e4SLinus Torvalds mov r19=IA64_KR(PT_BASE) // get the page table base address 4571da177e4SLinus Torvalds shl r21=r16,3 // shift bit 60 into sign bit 458498c5170SIsaku Yamahata MOV_FROM_ITIR(r18) 4591da177e4SLinus Torvalds ;; 4601da177e4SLinus Torvalds shr.u r17=r16,61 // get the region number into r17 4610393eed5SKen Chen extr.u r18=r18,2,6 // get the faulting page size 4621da177e4SLinus Torvalds ;; 4631da177e4SLinus Torvalds cmp.eq p6,p7=5,r17 // is faulting address in region 5? 4640393eed5SKen Chen add r22=-PAGE_SHIFT,r18 // adjustment for hugetlb address 4650393eed5SKen Chen add r18=PGDIR_SHIFT-PAGE_SHIFT,r18 4661da177e4SLinus Torvalds ;; 4670393eed5SKen Chen shr.u r22=r16,r22 4680393eed5SKen Chen shr.u r18=r16,r18 4691da177e4SLinus Torvalds(p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place 4701da177e4SLinus Torvalds 4711da177e4SLinus Torvalds srlz.d 4721da177e4SLinus Torvalds LOAD_PHYSICAL(p6, r19, swapper_pg_dir) // region 5 is rooted at swapper_pg_dir 4731da177e4SLinus Torvalds 4741da177e4SLinus Torvalds .pred.rel "mutex", p6, p7 4751da177e4SLinus Torvalds(p6) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT 4761da177e4SLinus Torvalds(p7) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3 4771da177e4SLinus Torvalds ;; 478e8aabc47SChen, Kenneth W(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=pgd_offset for region 5 479e8aabc47SChen, Kenneth W(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=pgd_offset for region[0-4] 4801da177e4SLinus Torvalds cmp.eq p7,p6=0,r21 // unused address bits all zeroes? 4814d66bcc7SKirill A. Shutemov#if CONFIG_PGTABLE_LEVELS == 4 482e8aabc47SChen, Kenneth W shr.u r18=r22,PUD_SHIFT // shift pud index into position 483837cd0bdSRobin Holt#else 484e8aabc47SChen, Kenneth W shr.u r18=r22,PMD_SHIFT // shift pmd index into position 485837cd0bdSRobin Holt#endif 4861da177e4SLinus Torvalds ;; 487e8aabc47SChen, Kenneth W ld8 r17=[r17] // get *pgd (may be 0) 4881da177e4SLinus Torvalds ;; 489e8aabc47SChen, Kenneth W(p7) cmp.eq p6,p7=r17,r0 // was pgd_present(*pgd) == NULL? 490e8aabc47SChen, Kenneth W dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=p[u|m]d_offset(pgd,addr) 4911da177e4SLinus Torvalds ;; 4924d66bcc7SKirill A. Shutemov#if CONFIG_PGTABLE_LEVELS == 4 493e8aabc47SChen, Kenneth W(p7) ld8 r17=[r17] // get *pud (may be 0) 494e8aabc47SChen, Kenneth W shr.u r18=r22,PMD_SHIFT // shift pmd index into position 4951da177e4SLinus Torvalds ;; 496e8aabc47SChen, Kenneth W(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was pud_present(*pud) == NULL? 497e8aabc47SChen, Kenneth W dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=pmd_offset(pud,addr) 498837cd0bdSRobin Holt ;; 499837cd0bdSRobin Holt#endif 500e8aabc47SChen, Kenneth W(p7) ld8 r17=[r17] // get *pmd (may be 0) 501e8aabc47SChen, Kenneth W shr.u r19=r22,PAGE_SHIFT // shift pte index into position 502837cd0bdSRobin Holt ;; 503e8aabc47SChen, Kenneth W(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was pmd_present(*pmd) == NULL? 504e8aabc47SChen, Kenneth W dep r17=r19,r17,3,(PAGE_SHIFT-3) // r17=pte_offset(pmd,addr); 5051da177e4SLinus Torvalds(p6) br.cond.spnt page_fault 5061da177e4SLinus Torvalds mov b0=r30 5071da177e4SLinus Torvalds br.sptk.many b0 // return to continuation point 5081da177e4SLinus TorvaldsEND(nested_dtlb_miss) 5091da177e4SLinus Torvalds 5101da177e4SLinus Torvalds .org ia64_ivt+0x1800 5111da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 5121da177e4SLinus Torvalds// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24) 5131da177e4SLinus TorvaldsENTRY(ikey_miss) 5141da177e4SLinus Torvalds DBG_FAULT(6) 5151da177e4SLinus Torvalds FAULT(6) 5161da177e4SLinus TorvaldsEND(ikey_miss) 5171da177e4SLinus Torvalds 5181da177e4SLinus Torvalds .org ia64_ivt+0x1c00 5191da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 5201da177e4SLinus Torvalds// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) 5211da177e4SLinus TorvaldsENTRY(dkey_miss) 5221da177e4SLinus Torvalds DBG_FAULT(7) 5231da177e4SLinus Torvalds FAULT(7) 5241da177e4SLinus TorvaldsEND(dkey_miss) 5251da177e4SLinus Torvalds 5261da177e4SLinus Torvalds .org ia64_ivt+0x2000 5271da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 5281da177e4SLinus Torvalds// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54) 5291da177e4SLinus TorvaldsENTRY(dirty_bit) 5301da177e4SLinus Torvalds DBG_FAULT(8) 5311da177e4SLinus Torvalds /* 5321da177e4SLinus Torvalds * What we do here is to simply turn on the dirty bit in the PTE. We need to 5331da177e4SLinus Torvalds * update both the page-table and the TLB entry. To efficiently access the PTE, 5341da177e4SLinus Torvalds * we address it through the virtual page table. Most likely, the TLB entry for 5351da177e4SLinus Torvalds * the relevant virtual page table page is still present in the TLB so we can 5361da177e4SLinus Torvalds * normally do this without additional TLB misses. In case the necessary virtual 5371da177e4SLinus Torvalds * page table TLB entry isn't present, we take a nested TLB miss hit where we look 5381da177e4SLinus Torvalds * up the physical address of the L3 PTE and then continue at label 1 below. 5391da177e4SLinus Torvalds */ 540498c5170SIsaku Yamahata MOV_FROM_IFA(r16) // get the address that caused the fault 5411da177e4SLinus Torvalds movl r30=1f // load continuation point in case of nested fault 5421da177e4SLinus Torvalds ;; 543498c5170SIsaku Yamahata THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE 5441da177e4SLinus Torvalds mov r29=b0 // save b0 in case of nested fault 5451da177e4SLinus Torvalds mov r31=pr // save pr 5461da177e4SLinus Torvalds#ifdef CONFIG_SMP 5471da177e4SLinus Torvalds mov r28=ar.ccv // save ar.ccv 5481da177e4SLinus Torvalds ;; 5491da177e4SLinus Torvalds1: ld8 r18=[r17] 5501da177e4SLinus Torvalds ;; // avoid RAW on r18 5511da177e4SLinus Torvalds mov ar.ccv=r18 // set compare value for cmpxchg 5521da177e4SLinus Torvalds or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits 553d8117ce5SChristoph Lameter tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit 5541da177e4SLinus Torvalds ;; 555d8117ce5SChristoph Lameter(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only update if page is present 5561da177e4SLinus Torvalds mov r24=PAGE_SHIFT<<2 5571da177e4SLinus Torvalds ;; 558d8117ce5SChristoph Lameter(p6) cmp.eq p6,p7=r26,r18 // Only compare if page is present 5591da177e4SLinus Torvalds ;; 560498c5170SIsaku Yamahata ITC_D(p6, r25, r18) // install updated PTE 5611da177e4SLinus Torvalds ;; 5621da177e4SLinus Torvalds /* 5631da177e4SLinus Torvalds * Tell the assemblers dependency-violation checker that the above "itc" instructions 5641da177e4SLinus Torvalds * cannot possibly affect the following loads: 5651da177e4SLinus Torvalds */ 5661da177e4SLinus Torvalds dv_serialize_data 5671da177e4SLinus Torvalds 5681da177e4SLinus Torvalds ld8 r18=[r17] // read PTE again 5691da177e4SLinus Torvalds ;; 5701da177e4SLinus Torvalds cmp.eq p6,p7=r18,r25 // is it same as the newly installed 5711da177e4SLinus Torvalds ;; 5721da177e4SLinus Torvalds(p7) ptc.l r16,r24 5731da177e4SLinus Torvalds mov b0=r29 // restore b0 5741da177e4SLinus Torvalds mov ar.ccv=r28 5751da177e4SLinus Torvalds#else 5761da177e4SLinus Torvalds ;; 5771da177e4SLinus Torvalds1: ld8 r18=[r17] 5781da177e4SLinus Torvalds ;; // avoid RAW on r18 5791da177e4SLinus Torvalds or r18=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits 5801da177e4SLinus Torvalds mov b0=r29 // restore b0 5811da177e4SLinus Torvalds ;; 5821da177e4SLinus Torvalds st8 [r17]=r18 // store back updated PTE 583749da791SIsaku Yamahata ITC_D(p0, r18, r16) // install updated PTE 5841da177e4SLinus Torvalds#endif 5851da177e4SLinus Torvalds mov pr=r31,-1 // restore pr 586498c5170SIsaku Yamahata RFI 5871da177e4SLinus TorvaldsEND(dirty_bit) 5881da177e4SLinus Torvalds 5891da177e4SLinus Torvalds .org ia64_ivt+0x2400 5901da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 5911da177e4SLinus Torvalds// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27) 5921da177e4SLinus TorvaldsENTRY(iaccess_bit) 5931da177e4SLinus Torvalds DBG_FAULT(9) 5941da177e4SLinus Torvalds // Like Entry 8, except for instruction access 595498c5170SIsaku Yamahata MOV_FROM_IFA(r16) // get the address that caused the fault 5961da177e4SLinus Torvalds movl r30=1f // load continuation point in case of nested fault 5971da177e4SLinus Torvalds mov r31=pr // save predicates 5981da177e4SLinus Torvalds#ifdef CONFIG_ITANIUM 5991da177e4SLinus Torvalds /* 6001da177e4SLinus Torvalds * Erratum 10 (IFA may contain incorrect address) has "NoFix" status. 6011da177e4SLinus Torvalds */ 602498c5170SIsaku Yamahata MOV_FROM_IPSR(p0, r17) 6031da177e4SLinus Torvalds ;; 604498c5170SIsaku Yamahata MOV_FROM_IIP(r18) 6051da177e4SLinus Torvalds tbit.z p6,p0=r17,IA64_PSR_IS_BIT // IA64 instruction set? 6061da177e4SLinus Torvalds ;; 6071da177e4SLinus Torvalds(p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa 6081da177e4SLinus Torvalds#endif /* CONFIG_ITANIUM */ 6091da177e4SLinus Torvalds ;; 610498c5170SIsaku Yamahata THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE 6111da177e4SLinus Torvalds mov r29=b0 // save b0 in case of nested fault) 6121da177e4SLinus Torvalds#ifdef CONFIG_SMP 6131da177e4SLinus Torvalds mov r28=ar.ccv // save ar.ccv 6141da177e4SLinus Torvalds ;; 6151da177e4SLinus Torvalds1: ld8 r18=[r17] 6161da177e4SLinus Torvalds ;; 6171da177e4SLinus Torvalds mov ar.ccv=r18 // set compare value for cmpxchg 6181da177e4SLinus Torvalds or r25=_PAGE_A,r18 // set the accessed bit 619d8117ce5SChristoph Lameter tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit 6201da177e4SLinus Torvalds ;; 621d8117ce5SChristoph Lameter(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page present 6221da177e4SLinus Torvalds mov r24=PAGE_SHIFT<<2 6231da177e4SLinus Torvalds ;; 624d8117ce5SChristoph Lameter(p6) cmp.eq p6,p7=r26,r18 // Only if page present 6251da177e4SLinus Torvalds ;; 626498c5170SIsaku Yamahata ITC_I(p6, r25, r26) // install updated PTE 6271da177e4SLinus Torvalds ;; 6281da177e4SLinus Torvalds /* 6291da177e4SLinus Torvalds * Tell the assemblers dependency-violation checker that the above "itc" instructions 6301da177e4SLinus Torvalds * cannot possibly affect the following loads: 6311da177e4SLinus Torvalds */ 6321da177e4SLinus Torvalds dv_serialize_data 6331da177e4SLinus Torvalds 6341da177e4SLinus Torvalds ld8 r18=[r17] // read PTE again 6351da177e4SLinus Torvalds ;; 6361da177e4SLinus Torvalds cmp.eq p6,p7=r18,r25 // is it same as the newly installed 6371da177e4SLinus Torvalds ;; 6381da177e4SLinus Torvalds(p7) ptc.l r16,r24 6391da177e4SLinus Torvalds mov b0=r29 // restore b0 6401da177e4SLinus Torvalds mov ar.ccv=r28 6411da177e4SLinus Torvalds#else /* !CONFIG_SMP */ 6421da177e4SLinus Torvalds ;; 6431da177e4SLinus Torvalds1: ld8 r18=[r17] 6441da177e4SLinus Torvalds ;; 6451da177e4SLinus Torvalds or r18=_PAGE_A,r18 // set the accessed bit 6461da177e4SLinus Torvalds mov b0=r29 // restore b0 6471da177e4SLinus Torvalds ;; 6481da177e4SLinus Torvalds st8 [r17]=r18 // store back updated PTE 649749da791SIsaku Yamahata ITC_I(p0, r18, r16) // install updated PTE 6501da177e4SLinus Torvalds#endif /* !CONFIG_SMP */ 6511da177e4SLinus Torvalds mov pr=r31,-1 652498c5170SIsaku Yamahata RFI 6531da177e4SLinus TorvaldsEND(iaccess_bit) 6541da177e4SLinus Torvalds 6551da177e4SLinus Torvalds .org ia64_ivt+0x2800 6561da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 6571da177e4SLinus Torvalds// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55) 6581da177e4SLinus TorvaldsENTRY(daccess_bit) 6591da177e4SLinus Torvalds DBG_FAULT(10) 6601da177e4SLinus Torvalds // Like Entry 8, except for data access 661498c5170SIsaku Yamahata MOV_FROM_IFA(r16) // get the address that caused the fault 6621da177e4SLinus Torvalds movl r30=1f // load continuation point in case of nested fault 6631da177e4SLinus Torvalds ;; 664498c5170SIsaku Yamahata THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE 6651da177e4SLinus Torvalds mov r31=pr 6661da177e4SLinus Torvalds mov r29=b0 // save b0 in case of nested fault) 6671da177e4SLinus Torvalds#ifdef CONFIG_SMP 6681da177e4SLinus Torvalds mov r28=ar.ccv // save ar.ccv 6691da177e4SLinus Torvalds ;; 6701da177e4SLinus Torvalds1: ld8 r18=[r17] 6711da177e4SLinus Torvalds ;; // avoid RAW on r18 6721da177e4SLinus Torvalds mov ar.ccv=r18 // set compare value for cmpxchg 6731da177e4SLinus Torvalds or r25=_PAGE_A,r18 // set the dirty bit 674d8117ce5SChristoph Lameter tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit 6751da177e4SLinus Torvalds ;; 676d8117ce5SChristoph Lameter(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page is present 6771da177e4SLinus Torvalds mov r24=PAGE_SHIFT<<2 6781da177e4SLinus Torvalds ;; 679d8117ce5SChristoph Lameter(p6) cmp.eq p6,p7=r26,r18 // Only if page is present 6801da177e4SLinus Torvalds ;; 681498c5170SIsaku Yamahata ITC_D(p6, r25, r26) // install updated PTE 6821da177e4SLinus Torvalds /* 6831da177e4SLinus Torvalds * Tell the assemblers dependency-violation checker that the above "itc" instructions 6841da177e4SLinus Torvalds * cannot possibly affect the following loads: 6851da177e4SLinus Torvalds */ 6861da177e4SLinus Torvalds dv_serialize_data 6871da177e4SLinus Torvalds ;; 6881da177e4SLinus Torvalds ld8 r18=[r17] // read PTE again 6891da177e4SLinus Torvalds ;; 6901da177e4SLinus Torvalds cmp.eq p6,p7=r18,r25 // is it same as the newly installed 6911da177e4SLinus Torvalds ;; 6921da177e4SLinus Torvalds(p7) ptc.l r16,r24 6931da177e4SLinus Torvalds mov ar.ccv=r28 6941da177e4SLinus Torvalds#else 6951da177e4SLinus Torvalds ;; 6961da177e4SLinus Torvalds1: ld8 r18=[r17] 6971da177e4SLinus Torvalds ;; // avoid RAW on r18 6981da177e4SLinus Torvalds or r18=_PAGE_A,r18 // set the accessed bit 6991da177e4SLinus Torvalds ;; 7001da177e4SLinus Torvalds st8 [r17]=r18 // store back updated PTE 701749da791SIsaku Yamahata ITC_D(p0, r18, r16) // install updated PTE 7021da177e4SLinus Torvalds#endif 7031da177e4SLinus Torvalds mov b0=r29 // restore b0 7041da177e4SLinus Torvalds mov pr=r31,-1 705498c5170SIsaku Yamahata RFI 7061da177e4SLinus TorvaldsEND(daccess_bit) 7071da177e4SLinus Torvalds 7081da177e4SLinus Torvalds .org ia64_ivt+0x2c00 7091da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 7101da177e4SLinus Torvalds// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33) 7111da177e4SLinus TorvaldsENTRY(break_fault) 7121da177e4SLinus Torvalds /* 7131da177e4SLinus Torvalds * The streamlined system call entry/exit paths only save/restore the initial part 7141da177e4SLinus Torvalds * of pt_regs. This implies that the callers of system-calls must adhere to the 7151da177e4SLinus Torvalds * normal procedure calling conventions. 7161da177e4SLinus Torvalds * 7171da177e4SLinus Torvalds * Registers to be saved & restored: 7181da177e4SLinus Torvalds * CR registers: cr.ipsr, cr.iip, cr.ifs 7191da177e4SLinus Torvalds * AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr 7201da177e4SLinus Torvalds * others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15 7211da177e4SLinus Torvalds * Registers to be restored only: 7221da177e4SLinus Torvalds * r8-r11: output value from the system call. 7231da177e4SLinus Torvalds * 7241da177e4SLinus Torvalds * During system call exit, scratch registers (including r15) are modified/cleared 7251da177e4SLinus Torvalds * to prevent leaking bits from kernel to user level. 7261da177e4SLinus Torvalds */ 7271da177e4SLinus Torvalds DBG_FAULT(11) 728f8fa5448SDavid Mosberger-Tang mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc) 729498c5170SIsaku Yamahata MOV_FROM_IPSR(p0, r29) // M2 (12 cyc) 730f8fa5448SDavid Mosberger-Tang mov r31=pr // I0 (2 cyc) 731f8fa5448SDavid Mosberger-Tang 732498c5170SIsaku Yamahata MOV_FROM_IIM(r17) // M2 (2 cyc) 733f8fa5448SDavid Mosberger-Tang mov.m r27=ar.rsc // M2 (12 cyc) 734f8fa5448SDavid Mosberger-Tang mov r18=__IA64_BREAK_SYSCALL // A 735f8fa5448SDavid Mosberger-Tang 736f8fa5448SDavid Mosberger-Tang mov.m ar.rsc=0 // M2 737f8fa5448SDavid Mosberger-Tang mov.m r21=ar.fpsr // M2 (12 cyc) 738f8fa5448SDavid Mosberger-Tang mov r19=b6 // I0 (2 cyc) 7391da177e4SLinus Torvalds ;; 740f8fa5448SDavid Mosberger-Tang mov.m r23=ar.bspstore // M2 (12 cyc) 741f8fa5448SDavid Mosberger-Tang mov.m r24=ar.rnat // M2 (5 cyc) 742f8fa5448SDavid Mosberger-Tang mov.i r26=ar.pfs // I0 (2 cyc) 743f8fa5448SDavid Mosberger-Tang 744f8fa5448SDavid Mosberger-Tang invala // M0|1 745f8fa5448SDavid Mosberger-Tang nop.m 0 // M 746f8fa5448SDavid Mosberger-Tang mov r20=r1 // A save r1 747f8fa5448SDavid Mosberger-Tang 748f8fa5448SDavid Mosberger-Tang nop.m 0 749f8fa5448SDavid Mosberger-Tang movl r30=sys_call_table // X 750f8fa5448SDavid Mosberger-Tang 751498c5170SIsaku Yamahata MOV_FROM_IIP(r28) // M2 (2 cyc) 752f8fa5448SDavid Mosberger-Tang cmp.eq p0,p7=r18,r17 // I0 is this a system call? 753f8fa5448SDavid Mosberger-Tang(p7) br.cond.spnt non_syscall // B no -> 754f8fa5448SDavid Mosberger-Tang // 755f8fa5448SDavid Mosberger-Tang // From this point on, we are definitely on the syscall-path 756f8fa5448SDavid Mosberger-Tang // and we can use (non-banked) scratch registers. 757f8fa5448SDavid Mosberger-Tang // 758f8fa5448SDavid Mosberger-Tang/////////////////////////////////////////////////////////////////////// 759f8fa5448SDavid Mosberger-Tang mov r1=r16 // A move task-pointer to "addl"-addressable reg 760f8fa5448SDavid Mosberger-Tang mov r2=r16 // A setup r2 for ia64_syscall_setup 761f8fa5448SDavid Mosberger-Tang add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = ¤t_thread_info()->flags 762f8fa5448SDavid Mosberger-Tang 7631da177e4SLinus Torvalds adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 764f8fa5448SDavid Mosberger-Tang adds r15=-1024,r15 // A subtract 1024 from syscall number 7651da177e4SLinus Torvalds mov r3=NR_syscalls - 1 7661da177e4SLinus Torvalds ;; 767f8fa5448SDavid Mosberger-Tang ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag 768f8fa5448SDavid Mosberger-Tang ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags 769f8fa5448SDavid Mosberger-Tang extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr 7701da177e4SLinus Torvalds 771f8fa5448SDavid Mosberger-Tang shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024) 772f8fa5448SDavid Mosberger-Tang addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS 773f8fa5448SDavid Mosberger-Tang cmp.leu p6,p7=r15,r3 // A syscall number in range? 7741da177e4SLinus Torvalds ;; 7751da177e4SLinus Torvalds 776f8fa5448SDavid Mosberger-Tang lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS 777f8fa5448SDavid Mosberger-Tang(p6) ld8 r30=[r30] // M0|1 load address of syscall entry point 778f8fa5448SDavid Mosberger-Tang tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT? 779f8fa5448SDavid Mosberger-Tang 780f8fa5448SDavid Mosberger-Tang mov.m ar.bspstore=r22 // M2 switch to kernel RBS 781f8fa5448SDavid Mosberger-Tang cmp.eq p8,p9=2,r8 // A isr.ei==2? 7821da177e4SLinus Torvalds ;; 783f8fa5448SDavid Mosberger-Tang 784f8fa5448SDavid Mosberger-Tang(p8) mov r8=0 // A clear ei to 0 785f8fa5448SDavid Mosberger-Tang(p7) movl r30=sys_ni_syscall // X 786f8fa5448SDavid Mosberger-Tang 787f8fa5448SDavid Mosberger-Tang(p8) adds r28=16,r28 // A switch cr.iip to next bundle 788f8fa5448SDavid Mosberger-Tang(p9) adds r8=1,r8 // A increment ei to next slot 789abf917cdSFrederic Weisbecker#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 790b64f34cdSHidetoshi Seto ;; 791b64f34cdSHidetoshi Seto mov b6=r30 // I0 setup syscall handler branch reg early 792b64f34cdSHidetoshi Seto#else 793f8fa5448SDavid Mosberger-Tang nop.i 0 7941da177e4SLinus Torvalds ;; 795b64f34cdSHidetoshi Seto#endif 796f8fa5448SDavid Mosberger-Tang 797f8fa5448SDavid Mosberger-Tang mov.m r25=ar.unat // M2 (5 cyc) 798f8fa5448SDavid Mosberger-Tang dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr 799f8fa5448SDavid Mosberger-Tang adds r15=1024,r15 // A restore original syscall number 800f8fa5448SDavid Mosberger-Tang // 801f8fa5448SDavid Mosberger-Tang // If any of the above loads miss in L1D, we'll stall here until 802f8fa5448SDavid Mosberger-Tang // the data arrives. 803f8fa5448SDavid Mosberger-Tang // 804f8fa5448SDavid Mosberger-Tang/////////////////////////////////////////////////////////////////////// 805f8fa5448SDavid Mosberger-Tang st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag 806abf917cdSFrederic Weisbecker#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 80794752a79SIsaku Yamahata MOV_FROM_ITC(p0, p14, r30, r18) // M get cycle for accounting 808b64f34cdSHidetoshi Seto#else 809f8fa5448SDavid Mosberger-Tang mov b6=r30 // I0 setup syscall handler branch reg early 810b64f34cdSHidetoshi Seto#endif 811f8fa5448SDavid Mosberger-Tang cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already? 812f8fa5448SDavid Mosberger-Tang 813f8fa5448SDavid Mosberger-Tang and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit 814f8fa5448SDavid Mosberger-Tang mov r18=ar.bsp // M2 (12 cyc) 815f8fa5448SDavid Mosberger-Tang(pKStk) br.cond.spnt .break_fixup // B we're already in kernel-mode -- fix up RBS 8161da177e4SLinus Torvalds ;; 817f8fa5448SDavid Mosberger-Tang.back_from_break_fixup: 818f8fa5448SDavid Mosberger-Tang(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack 819f8fa5448SDavid Mosberger-Tang cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? 820f8fa5448SDavid Mosberger-Tang br.call.sptk.many b7=ia64_syscall_setup // B 821f8fa5448SDavid Mosberger-Tang1: 822abf917cdSFrederic Weisbecker#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 823b64f34cdSHidetoshi Seto // mov.m r30=ar.itc is called in advance, and r13 is current 824b64f34cdSHidetoshi Seto add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13 // A 825b64f34cdSHidetoshi Seto add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13 // A 826b64f34cdSHidetoshi Seto(pKStk) br.cond.spnt .skip_accounting // B unlikely skip 827b64f34cdSHidetoshi Seto ;; 828b64f34cdSHidetoshi Seto ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP // M get last stamp 829b64f34cdSHidetoshi Seto ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE // M time at leave 830b64f34cdSHidetoshi Seto ;; 831b64f34cdSHidetoshi Seto ld8 r20=[r16],TI_AC_STAMP-TI_AC_STIME // M cumulated stime 832b64f34cdSHidetoshi Seto ld8 r21=[r17] // M cumulated utime 833b64f34cdSHidetoshi Seto sub r22=r19,r18 // A stime before leave 834b64f34cdSHidetoshi Seto ;; 835b64f34cdSHidetoshi Seto st8 [r16]=r30,TI_AC_STIME-TI_AC_STAMP // M update stamp 836b64f34cdSHidetoshi Seto sub r18=r30,r19 // A elapsed time in user 837b64f34cdSHidetoshi Seto ;; 838b64f34cdSHidetoshi Seto add r20=r20,r22 // A sum stime 839b64f34cdSHidetoshi Seto add r21=r21,r18 // A sum utime 840b64f34cdSHidetoshi Seto ;; 841b64f34cdSHidetoshi Seto st8 [r16]=r20 // M update stime 842b64f34cdSHidetoshi Seto st8 [r17]=r21 // M update utime 843b64f34cdSHidetoshi Seto ;; 844b64f34cdSHidetoshi Seto.skip_accounting: 845b64f34cdSHidetoshi Seto#endif 846f8fa5448SDavid Mosberger-Tang mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 847f8fa5448SDavid Mosberger-Tang nop 0 848498c5170SIsaku Yamahata BSW_1(r2, r14) // B (6 cyc) regs are saved, switch to bank 1 8491da177e4SLinus Torvalds ;; 850f8fa5448SDavid Mosberger-Tang 851498c5170SIsaku Yamahata SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r16) // M2 now it's safe to re-enable intr.-collection 852498c5170SIsaku Yamahata // M0 ensure interruption collection is on 853f8fa5448SDavid Mosberger-Tang movl r3=ia64_ret_from_syscall // X 854f8fa5448SDavid Mosberger-Tang ;; 855f8fa5448SDavid Mosberger-Tang mov rp=r3 // I0 set the real return addr 856f8fa5448SDavid Mosberger-Tang(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT 857f8fa5448SDavid Mosberger-Tang 858498c5170SIsaku Yamahata SSM_PSR_I(p15, p15, r16) // M2 restore psr.i 859f8fa5448SDavid Mosberger-Tang(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) 860f8fa5448SDavid Mosberger-Tang br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic 8611da177e4SLinus Torvalds // NOT REACHED 862f8fa5448SDavid Mosberger-Tang/////////////////////////////////////////////////////////////////////// 863f8fa5448SDavid Mosberger-Tang // On entry, we optimistically assumed that we're coming from user-space. 864f8fa5448SDavid Mosberger-Tang // For the rare cases where a system-call is done from within the kernel, 865f8fa5448SDavid Mosberger-Tang // we fix things up at this point: 866f8fa5448SDavid Mosberger-Tang.break_fixup: 867f8fa5448SDavid Mosberger-Tang add r1=-IA64_PT_REGS_SIZE,sp // A allocate space for pt_regs structure 868f8fa5448SDavid Mosberger-Tang mov ar.rnat=r24 // M2 restore kernel's AR.RNAT 869f8fa5448SDavid Mosberger-Tang ;; 870f8fa5448SDavid Mosberger-Tang mov ar.bspstore=r23 // M2 restore kernel's AR.BSPSTORE 871f8fa5448SDavid Mosberger-Tang br.cond.sptk .back_from_break_fixup 8721da177e4SLinus TorvaldsEND(break_fault) 8731da177e4SLinus Torvalds 8741da177e4SLinus Torvalds .org ia64_ivt+0x3000 8751da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 8761da177e4SLinus Torvalds// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4) 8771da177e4SLinus TorvaldsENTRY(interrupt) 8784d58bbccSIsaku Yamahata /* interrupt handler has become too big to fit this area. */ 8794d58bbccSIsaku Yamahata br.sptk.many __interrupt 8801da177e4SLinus TorvaldsEND(interrupt) 8811da177e4SLinus Torvalds 8821da177e4SLinus Torvalds .org ia64_ivt+0x3400 8831da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 8841da177e4SLinus Torvalds// 0x3400 Entry 13 (size 64 bundles) Reserved 8851da177e4SLinus Torvalds DBG_FAULT(13) 8861da177e4SLinus Torvalds FAULT(13) 8871da177e4SLinus Torvalds 8881da177e4SLinus Torvalds .org ia64_ivt+0x3800 8891da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 8901da177e4SLinus Torvalds// 0x3800 Entry 14 (size 64 bundles) Reserved 8911da177e4SLinus Torvalds DBG_FAULT(14) 8921da177e4SLinus Torvalds FAULT(14) 8931da177e4SLinus Torvalds 8941da177e4SLinus Torvalds /* 8951da177e4SLinus Torvalds * There is no particular reason for this code to be here, other than that 8961da177e4SLinus Torvalds * there happens to be space here that would go unused otherwise. If this 8971da177e4SLinus Torvalds * fault ever gets "unreserved", simply moved the following code to a more 8981da177e4SLinus Torvalds * suitable spot... 8991da177e4SLinus Torvalds * 9001da177e4SLinus Torvalds * ia64_syscall_setup() is a separate subroutine so that it can 9011da177e4SLinus Torvalds * allocate stacked registers so it can safely demine any 9021da177e4SLinus Torvalds * potential NaT values from the input registers. 9031da177e4SLinus Torvalds * 9041da177e4SLinus Torvalds * On entry: 9051da177e4SLinus Torvalds * - executing on bank 0 or bank 1 register set (doesn't matter) 9061da177e4SLinus Torvalds * - r1: stack pointer 9071da177e4SLinus Torvalds * - r2: current task pointer 9081da177e4SLinus Torvalds * - r3: preserved 9091da177e4SLinus Torvalds * - r11: original contents (saved ar.pfs to be saved) 9101da177e4SLinus Torvalds * - r12: original contents (sp to be saved) 9111da177e4SLinus Torvalds * - r13: original contents (tp to be saved) 9121da177e4SLinus Torvalds * - r15: original contents (syscall # to be saved) 9131da177e4SLinus Torvalds * - r18: saved bsp (after switching to kernel stack) 9141da177e4SLinus Torvalds * - r19: saved b6 9151da177e4SLinus Torvalds * - r20: saved r1 (gp) 9161da177e4SLinus Torvalds * - r21: saved ar.fpsr 9171da177e4SLinus Torvalds * - r22: kernel's register backing store base (krbs_base) 9181da177e4SLinus Torvalds * - r23: saved ar.bspstore 9191da177e4SLinus Torvalds * - r24: saved ar.rnat 9201da177e4SLinus Torvalds * - r25: saved ar.unat 9211da177e4SLinus Torvalds * - r26: saved ar.pfs 9221da177e4SLinus Torvalds * - r27: saved ar.rsc 9231da177e4SLinus Torvalds * - r28: saved cr.iip 9241da177e4SLinus Torvalds * - r29: saved cr.ipsr 925b64f34cdSHidetoshi Seto * - r30: ar.itc for accounting (don't touch) 9261da177e4SLinus Torvalds * - r31: saved pr 9271da177e4SLinus Torvalds * - b0: original contents (to be saved) 9281da177e4SLinus Torvalds * On exit: 9291da177e4SLinus Torvalds * - p10: TRUE if syscall is invoked with more than 8 out 9301da177e4SLinus Torvalds * registers or r15's Nat is true 9311da177e4SLinus Torvalds * - r1: kernel's gp 9321da177e4SLinus Torvalds * - r3: preserved (same as on entry) 9331da177e4SLinus Torvalds * - r8: -EINVAL if p10 is true 9341da177e4SLinus Torvalds * - r12: points to kernel stack 9351da177e4SLinus Torvalds * - r13: points to current task 936f8fa5448SDavid Mosberger-Tang * - r14: preserved (same as on entry) 937f8fa5448SDavid Mosberger-Tang * - p13: preserved 9381da177e4SLinus Torvalds * - p15: TRUE if interrupts need to be re-enabled 9391da177e4SLinus Torvalds * - ar.fpsr: set to kernel settings 940f8fa5448SDavid Mosberger-Tang * - b6: preserved (same as on entry) 9411da177e4SLinus Torvalds */ 9421da177e4SLinus TorvaldsGLOBAL_ENTRY(ia64_syscall_setup) 9431da177e4SLinus Torvalds#if PT(B6) != 0 9441da177e4SLinus Torvalds# error This code assumes that b6 is the first field in pt_regs. 9451da177e4SLinus Torvalds#endif 9461da177e4SLinus Torvalds st8 [r1]=r19 // save b6 9471da177e4SLinus Torvalds add r16=PT(CR_IPSR),r1 // initialize first base pointer 9481da177e4SLinus Torvalds add r17=PT(R11),r1 // initialize second base pointer 9491da177e4SLinus Torvalds ;; 9501da177e4SLinus Torvalds alloc r19=ar.pfs,8,0,0,0 // ensure in0-in7 are writable 9511da177e4SLinus Torvalds st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR) // save cr.ipsr 9521da177e4SLinus Torvalds tnat.nz p8,p0=in0 9531da177e4SLinus Torvalds 9541da177e4SLinus Torvalds st8.spill [r17]=r11,PT(CR_IIP)-PT(R11) // save r11 9551da177e4SLinus Torvalds tnat.nz p9,p0=in1 9561da177e4SLinus Torvalds(pKStk) mov r18=r0 // make sure r18 isn't NaT 9571da177e4SLinus Torvalds ;; 9581da177e4SLinus Torvalds 9591da177e4SLinus Torvalds st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS) // save ar.pfs 9601da177e4SLinus Torvalds st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP) // save cr.iip 9611da177e4SLinus Torvalds mov r28=b0 // save b0 (2 cyc) 9621da177e4SLinus Torvalds ;; 9631da177e4SLinus Torvalds 9641da177e4SLinus Torvalds st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT) // save ar.unat 9651da177e4SLinus Torvalds dep r19=0,r19,38,26 // clear all bits but 0..37 [I0] 9661da177e4SLinus Torvalds(p8) mov in0=-1 9671da177e4SLinus Torvalds ;; 9681da177e4SLinus Torvalds 9691da177e4SLinus Torvalds st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS) // store ar.pfs.pfm in cr.ifs 9701da177e4SLinus Torvalds extr.u r11=r19,7,7 // I0 // get sol of ar.pfs 9711da177e4SLinus Torvalds and r8=0x7f,r19 // A // get sof of ar.pfs 9721da177e4SLinus Torvalds 9731da177e4SLinus Torvalds st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc 9741da177e4SLinus Torvalds tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0 9751da177e4SLinus Torvalds(p9) mov in1=-1 9761da177e4SLinus Torvalds ;; 9771da177e4SLinus Torvalds 9781da177e4SLinus Torvalds(pUStk) sub r18=r18,r22 // r18=RSE.ndirty*8 9791da177e4SLinus Torvalds tnat.nz p10,p0=in2 9801da177e4SLinus Torvalds add r11=8,r11 9811da177e4SLinus Torvalds ;; 9821da177e4SLinus Torvalds(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16 // skip over ar_rnat field 9831da177e4SLinus Torvalds(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17 // skip over ar_bspstore field 9841da177e4SLinus Torvalds tnat.nz p11,p0=in3 9851da177e4SLinus Torvalds ;; 9861da177e4SLinus Torvalds(p10) mov in2=-1 9871da177e4SLinus Torvalds tnat.nz p12,p0=in4 // [I0] 9881da177e4SLinus Torvalds(p11) mov in3=-1 9891da177e4SLinus Torvalds ;; 9901da177e4SLinus Torvalds(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT) // save ar.rnat 9911da177e4SLinus Torvalds(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE) // save ar.bspstore 9921da177e4SLinus Torvalds shl r18=r18,16 // compute ar.rsc to be used for "loadrs" 9931da177e4SLinus Torvalds ;; 9941da177e4SLinus Torvalds st8 [r16]=r31,PT(LOADRS)-PT(PR) // save predicates 9951da177e4SLinus Torvalds st8 [r17]=r28,PT(R1)-PT(B0) // save b0 9961da177e4SLinus Torvalds tnat.nz p13,p0=in5 // [I0] 9971da177e4SLinus Torvalds ;; 9981da177e4SLinus Torvalds st8 [r16]=r18,PT(R12)-PT(LOADRS) // save ar.rsc value for "loadrs" 9991da177e4SLinus Torvalds st8.spill [r17]=r20,PT(R13)-PT(R1) // save original r1 10001da177e4SLinus Torvalds(p12) mov in4=-1 10011da177e4SLinus Torvalds ;; 10021da177e4SLinus Torvalds 10031da177e4SLinus Torvalds.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12) // save r12 10041da177e4SLinus Torvalds.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13) // save r13 10051da177e4SLinus Torvalds(p13) mov in5=-1 10061da177e4SLinus Torvalds ;; 10071da177e4SLinus Torvalds st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr 1008f8fa5448SDavid Mosberger-Tang tnat.nz p13,p0=in6 10091da177e4SLinus Torvalds cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8 10101da177e4SLinus Torvalds ;; 1011060561ffSDavid Mosberger-Tang mov r8=1 10121da177e4SLinus Torvalds(p9) tnat.nz p10,p0=r15 10131da177e4SLinus Torvalds adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch) 10141da177e4SLinus Torvalds 10151da177e4SLinus Torvalds st8.spill [r17]=r15 // save r15 10161da177e4SLinus Torvalds tnat.nz p8,p0=in7 10171da177e4SLinus Torvalds nop.i 0 10181da177e4SLinus Torvalds 10191da177e4SLinus Torvalds mov r13=r2 // establish `current' 10201da177e4SLinus Torvalds movl r1=__gp // establish kernel global pointer 10211da177e4SLinus Torvalds ;; 1022060561ffSDavid Mosberger-Tang st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error) 1023f8fa5448SDavid Mosberger-Tang(p13) mov in6=-1 10241da177e4SLinus Torvalds(p8) mov in7=-1 10251da177e4SLinus Torvalds 10261da177e4SLinus Torvalds cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 10271da177e4SLinus Torvalds movl r17=FPSR_DEFAULT 10281da177e4SLinus Torvalds ;; 10291da177e4SLinus Torvalds mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value 10301da177e4SLinus Torvalds(p10) mov r8=-EINVAL 10311da177e4SLinus Torvalds br.ret.sptk.many b7 10321da177e4SLinus TorvaldsEND(ia64_syscall_setup) 10331da177e4SLinus Torvalds 10341da177e4SLinus Torvalds .org ia64_ivt+0x3c00 10351da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 10361da177e4SLinus Torvalds// 0x3c00 Entry 15 (size 64 bundles) Reserved 10371da177e4SLinus Torvalds DBG_FAULT(15) 10381da177e4SLinus Torvalds FAULT(15) 10391da177e4SLinus Torvalds 10401da177e4SLinus Torvalds .org ia64_ivt+0x4000 10411da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 10421da177e4SLinus Torvalds// 0x4000 Entry 16 (size 64 bundles) Reserved 10431da177e4SLinus Torvalds DBG_FAULT(16) 10441da177e4SLinus Torvalds FAULT(16) 10451da177e4SLinus Torvalds 1046e55645ecSLuis R. Rodriguez#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) 1047b64f34cdSHidetoshi Seto /* 1048b64f34cdSHidetoshi Seto * There is no particular reason for this code to be here, other than 1049b64f34cdSHidetoshi Seto * that there happens to be space here that would go unused otherwise. 1050b64f34cdSHidetoshi Seto * If this fault ever gets "unreserved", simply moved the following 1051b64f34cdSHidetoshi Seto * code to a more suitable spot... 1052b64f34cdSHidetoshi Seto * 1053b64f34cdSHidetoshi Seto * account_sys_enter is called from SAVE_MIN* macros if accounting is 1054b64f34cdSHidetoshi Seto * enabled and if the macro is entered from user mode. 1055b64f34cdSHidetoshi Seto */ 1056498c5170SIsaku YamahataGLOBAL_ENTRY(account_sys_enter) 1057b64f34cdSHidetoshi Seto // mov.m r20=ar.itc is called in advance, and r13 is current 1058b64f34cdSHidetoshi Seto add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13 1059b64f34cdSHidetoshi Seto add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13 1060b64f34cdSHidetoshi Seto ;; 1061b64f34cdSHidetoshi Seto ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP // time at last check in kernel 1062b64f34cdSHidetoshi Seto ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE // time at left from kernel 1063b64f34cdSHidetoshi Seto ;; 1064b64f34cdSHidetoshi Seto ld8 r23=[r16],TI_AC_STAMP-TI_AC_STIME // cumulated stime 1065b64f34cdSHidetoshi Seto ld8 r21=[r17] // cumulated utime 1066b64f34cdSHidetoshi Seto sub r22=r19,r18 // stime before leave kernel 1067b64f34cdSHidetoshi Seto ;; 1068b64f34cdSHidetoshi Seto st8 [r16]=r20,TI_AC_STIME-TI_AC_STAMP // update stamp 1069b64f34cdSHidetoshi Seto sub r18=r20,r19 // elapsed time in user mode 1070b64f34cdSHidetoshi Seto ;; 1071b64f34cdSHidetoshi Seto add r23=r23,r22 // sum stime 1072b64f34cdSHidetoshi Seto add r21=r21,r18 // sum utime 1073b64f34cdSHidetoshi Seto ;; 1074b64f34cdSHidetoshi Seto st8 [r16]=r23 // update stime 1075b64f34cdSHidetoshi Seto st8 [r17]=r21 // update utime 1076b64f34cdSHidetoshi Seto ;; 1077b64f34cdSHidetoshi Seto br.ret.sptk.many rp 1078b64f34cdSHidetoshi SetoEND(account_sys_enter) 1079b64f34cdSHidetoshi Seto#endif 1080b64f34cdSHidetoshi Seto 10811da177e4SLinus Torvalds .org ia64_ivt+0x4400 10821da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 10831da177e4SLinus Torvalds// 0x4400 Entry 17 (size 64 bundles) Reserved 10841da177e4SLinus Torvalds DBG_FAULT(17) 10851da177e4SLinus Torvalds FAULT(17) 10861da177e4SLinus Torvalds 10871da177e4SLinus Torvalds .org ia64_ivt+0x4800 10881da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 10891da177e4SLinus Torvalds// 0x4800 Entry 18 (size 64 bundles) Reserved 10901da177e4SLinus Torvalds DBG_FAULT(18) 10911da177e4SLinus Torvalds FAULT(18) 10921da177e4SLinus Torvalds 10931da177e4SLinus Torvalds .org ia64_ivt+0x4c00 10941da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 10951da177e4SLinus Torvalds// 0x4c00 Entry 19 (size 64 bundles) Reserved 10961da177e4SLinus Torvalds DBG_FAULT(19) 10971da177e4SLinus Torvalds FAULT(19) 10981da177e4SLinus Torvalds 10991da177e4SLinus Torvalds// 11001da177e4SLinus Torvalds// --- End of long entries, Beginning of short entries 11011da177e4SLinus Torvalds// 11021da177e4SLinus Torvalds 11031da177e4SLinus Torvalds .org ia64_ivt+0x5000 11041da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 11051da177e4SLinus Torvalds// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49) 11061da177e4SLinus TorvaldsENTRY(page_not_present) 11071da177e4SLinus Torvalds DBG_FAULT(20) 1108498c5170SIsaku Yamahata MOV_FROM_IFA(r16) 1109498c5170SIsaku Yamahata RSM_PSR_DT 11101da177e4SLinus Torvalds /* 11111da177e4SLinus Torvalds * The Linux page fault handler doesn't expect non-present pages to be in 11121da177e4SLinus Torvalds * the TLB. Flush the existing entry now, so we meet that expectation. 11131da177e4SLinus Torvalds */ 11141da177e4SLinus Torvalds mov r17=PAGE_SHIFT<<2 11151da177e4SLinus Torvalds ;; 11161da177e4SLinus Torvalds ptc.l r16,r17 11171da177e4SLinus Torvalds ;; 11181da177e4SLinus Torvalds mov r31=pr 11191da177e4SLinus Torvalds srlz.d 11201da177e4SLinus Torvalds br.sptk.many page_fault 11211da177e4SLinus TorvaldsEND(page_not_present) 11221da177e4SLinus Torvalds 11231da177e4SLinus Torvalds .org ia64_ivt+0x5100 11241da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 11251da177e4SLinus Torvalds// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52) 11261da177e4SLinus TorvaldsENTRY(key_permission) 11271da177e4SLinus Torvalds DBG_FAULT(21) 1128498c5170SIsaku Yamahata MOV_FROM_IFA(r16) 1129498c5170SIsaku Yamahata RSM_PSR_DT 11301da177e4SLinus Torvalds mov r31=pr 11311da177e4SLinus Torvalds ;; 11321da177e4SLinus Torvalds srlz.d 11331da177e4SLinus Torvalds br.sptk.many page_fault 11341da177e4SLinus TorvaldsEND(key_permission) 11351da177e4SLinus Torvalds 11361da177e4SLinus Torvalds .org ia64_ivt+0x5200 11371da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 11381da177e4SLinus Torvalds// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26) 11391da177e4SLinus TorvaldsENTRY(iaccess_rights) 11401da177e4SLinus Torvalds DBG_FAULT(22) 1141498c5170SIsaku Yamahata MOV_FROM_IFA(r16) 1142498c5170SIsaku Yamahata RSM_PSR_DT 11431da177e4SLinus Torvalds mov r31=pr 11441da177e4SLinus Torvalds ;; 11451da177e4SLinus Torvalds srlz.d 11461da177e4SLinus Torvalds br.sptk.many page_fault 11471da177e4SLinus TorvaldsEND(iaccess_rights) 11481da177e4SLinus Torvalds 11491da177e4SLinus Torvalds .org ia64_ivt+0x5300 11501da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 11511da177e4SLinus Torvalds// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53) 11521da177e4SLinus TorvaldsENTRY(daccess_rights) 11531da177e4SLinus Torvalds DBG_FAULT(23) 1154498c5170SIsaku Yamahata MOV_FROM_IFA(r16) 1155498c5170SIsaku Yamahata RSM_PSR_DT 11561da177e4SLinus Torvalds mov r31=pr 11571da177e4SLinus Torvalds ;; 11581da177e4SLinus Torvalds srlz.d 11591da177e4SLinus Torvalds br.sptk.many page_fault 11601da177e4SLinus TorvaldsEND(daccess_rights) 11611da177e4SLinus Torvalds 11621da177e4SLinus Torvalds .org ia64_ivt+0x5400 11631da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 11641da177e4SLinus Torvalds// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39) 11651da177e4SLinus TorvaldsENTRY(general_exception) 11661da177e4SLinus Torvalds DBG_FAULT(24) 1167498c5170SIsaku Yamahata MOV_FROM_ISR(r16) 11681da177e4SLinus Torvalds mov r31=pr 11691da177e4SLinus Torvalds ;; 11701da177e4SLinus Torvalds cmp4.eq p6,p0=0,r16 11711da177e4SLinus Torvalds(p6) br.sptk.many dispatch_illegal_op_fault 11721da177e4SLinus Torvalds ;; 11731da177e4SLinus Torvalds mov r19=24 // fault number 11741da177e4SLinus Torvalds br.sptk.many dispatch_to_fault_handler 11751da177e4SLinus TorvaldsEND(general_exception) 11761da177e4SLinus Torvalds 11771da177e4SLinus Torvalds .org ia64_ivt+0x5500 11781da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 11791da177e4SLinus Torvalds// 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35) 11801da177e4SLinus TorvaldsENTRY(disabled_fp_reg) 11811da177e4SLinus Torvalds DBG_FAULT(25) 11821da177e4SLinus Torvalds rsm psr.dfh // ensure we can access fph 11831da177e4SLinus Torvalds ;; 11841da177e4SLinus Torvalds srlz.d 11851da177e4SLinus Torvalds mov r31=pr 11861da177e4SLinus Torvalds mov r19=25 11871da177e4SLinus Torvalds br.sptk.many dispatch_to_fault_handler 11881da177e4SLinus TorvaldsEND(disabled_fp_reg) 11891da177e4SLinus Torvalds 11901da177e4SLinus Torvalds .org ia64_ivt+0x5600 11911da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 11921da177e4SLinus Torvalds// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50) 11931da177e4SLinus TorvaldsENTRY(nat_consumption) 11941da177e4SLinus Torvalds DBG_FAULT(26) 1195458f9355SDavid Mosberger-Tang 1196498c5170SIsaku Yamahata MOV_FROM_IPSR(p0, r16) 1197498c5170SIsaku Yamahata MOV_FROM_ISR(r17) 1198458f9355SDavid Mosberger-Tang mov r31=pr // save PR 1199458f9355SDavid Mosberger-Tang ;; 1200458f9355SDavid Mosberger-Tang and r18=0xf,r17 // r18 = cr.ipsr.code{3:0} 1201458f9355SDavid Mosberger-Tang tbit.z p6,p0=r17,IA64_ISR_NA_BIT 1202458f9355SDavid Mosberger-Tang ;; 1203458f9355SDavid Mosberger-Tang cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18 1204458f9355SDavid Mosberger-Tang dep r16=-1,r16,IA64_PSR_ED_BIT,1 1205458f9355SDavid Mosberger-Tang(p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH) 1206458f9355SDavid Mosberger-Tang ;; 1207498c5170SIsaku Yamahata MOV_TO_IPSR(p0, r16, r18) 1208458f9355SDavid Mosberger-Tang mov pr=r31,-1 1209458f9355SDavid Mosberger-Tang ;; 1210498c5170SIsaku Yamahata RFI 1211458f9355SDavid Mosberger-Tang 1212458f9355SDavid Mosberger-Tang1: mov pr=r31,-1 1213458f9355SDavid Mosberger-Tang ;; 12141da177e4SLinus Torvalds FAULT(26) 12151da177e4SLinus TorvaldsEND(nat_consumption) 12161da177e4SLinus Torvalds 12171da177e4SLinus Torvalds .org ia64_ivt+0x5700 12181da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 12191da177e4SLinus Torvalds// 0x5700 Entry 27 (size 16 bundles) Speculation (40) 12201da177e4SLinus TorvaldsENTRY(speculation_vector) 12211da177e4SLinus Torvalds DBG_FAULT(27) 12221da177e4SLinus Torvalds /* 12231da177e4SLinus Torvalds * A [f]chk.[as] instruction needs to take the branch to the recovery code but 12241da177e4SLinus Torvalds * this part of the architecture is not implemented in hardware on some CPUs, such 12251da177e4SLinus Torvalds * as Itanium. Thus, in general we need to emulate the behavior. IIM contains 12261da177e4SLinus Torvalds * the relative target (not yet sign extended). So after sign extending it we 12271da177e4SLinus Torvalds * simply add it to IIP. We also need to reset the EI field of the IPSR to zero, 12281da177e4SLinus Torvalds * i.e., the slot to restart into. 12291da177e4SLinus Torvalds * 12301da177e4SLinus Torvalds * cr.imm contains zero_ext(imm21) 12311da177e4SLinus Torvalds */ 1232498c5170SIsaku Yamahata MOV_FROM_IIM(r18) 12331da177e4SLinus Torvalds ;; 1234498c5170SIsaku Yamahata MOV_FROM_IIP(r17) 12351da177e4SLinus Torvalds shl r18=r18,43 // put sign bit in position (43=64-21) 12361da177e4SLinus Torvalds ;; 12371da177e4SLinus Torvalds 1238498c5170SIsaku Yamahata MOV_FROM_IPSR(p0, r16) 12391da177e4SLinus Torvalds shr r18=r18,39 // sign extend (39=43-4) 12401da177e4SLinus Torvalds ;; 12411da177e4SLinus Torvalds 12421da177e4SLinus Torvalds add r17=r17,r18 // now add the offset 12431da177e4SLinus Torvalds ;; 12449b3cbf72SIsaku Yamahata MOV_TO_IIP(r17, r19) 12451da177e4SLinus Torvalds dep r16=0,r16,41,2 // clear EI 12461da177e4SLinus Torvalds ;; 12471da177e4SLinus Torvalds 12489b3cbf72SIsaku Yamahata MOV_TO_IPSR(p0, r16, r19) 12491da177e4SLinus Torvalds ;; 12501da177e4SLinus Torvalds 1251498c5170SIsaku Yamahata RFI 12521da177e4SLinus TorvaldsEND(speculation_vector) 12531da177e4SLinus Torvalds 12541da177e4SLinus Torvalds .org ia64_ivt+0x5800 12551da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 12561da177e4SLinus Torvalds// 0x5800 Entry 28 (size 16 bundles) Reserved 12571da177e4SLinus Torvalds DBG_FAULT(28) 12581da177e4SLinus Torvalds FAULT(28) 12591da177e4SLinus Torvalds 12601da177e4SLinus Torvalds .org ia64_ivt+0x5900 12611da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 12621da177e4SLinus Torvalds// 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56) 12631da177e4SLinus TorvaldsENTRY(debug_vector) 12641da177e4SLinus Torvalds DBG_FAULT(29) 12651da177e4SLinus Torvalds FAULT(29) 12661da177e4SLinus TorvaldsEND(debug_vector) 12671da177e4SLinus Torvalds 12681da177e4SLinus Torvalds .org ia64_ivt+0x5a00 12691da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 12701da177e4SLinus Torvalds// 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57) 12711da177e4SLinus TorvaldsENTRY(unaligned_access) 12721da177e4SLinus Torvalds DBG_FAULT(30) 12731da177e4SLinus Torvalds mov r31=pr // prepare to save predicates 12741da177e4SLinus Torvalds ;; 12751da177e4SLinus Torvalds br.sptk.many dispatch_unaligned_handler 12761da177e4SLinus TorvaldsEND(unaligned_access) 12771da177e4SLinus Torvalds 12781da177e4SLinus Torvalds .org ia64_ivt+0x5b00 12791da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 12801da177e4SLinus Torvalds// 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57) 12811da177e4SLinus TorvaldsENTRY(unsupported_data_reference) 12821da177e4SLinus Torvalds DBG_FAULT(31) 12831da177e4SLinus Torvalds FAULT(31) 12841da177e4SLinus TorvaldsEND(unsupported_data_reference) 12851da177e4SLinus Torvalds 12861da177e4SLinus Torvalds .org ia64_ivt+0x5c00 12871da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 12881da177e4SLinus Torvalds// 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64) 12891da177e4SLinus TorvaldsENTRY(floating_point_fault) 12901da177e4SLinus Torvalds DBG_FAULT(32) 12911da177e4SLinus Torvalds FAULT(32) 12921da177e4SLinus TorvaldsEND(floating_point_fault) 12931da177e4SLinus Torvalds 12941da177e4SLinus Torvalds .org ia64_ivt+0x5d00 12951da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 12961da177e4SLinus Torvalds// 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66) 12971da177e4SLinus TorvaldsENTRY(floating_point_trap) 12981da177e4SLinus Torvalds DBG_FAULT(33) 12991da177e4SLinus Torvalds FAULT(33) 13001da177e4SLinus TorvaldsEND(floating_point_trap) 13011da177e4SLinus Torvalds 13021da177e4SLinus Torvalds .org ia64_ivt+0x5e00 13031da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13041da177e4SLinus Torvalds// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66) 13051da177e4SLinus TorvaldsENTRY(lower_privilege_trap) 13061da177e4SLinus Torvalds DBG_FAULT(34) 13071da177e4SLinus Torvalds FAULT(34) 13081da177e4SLinus TorvaldsEND(lower_privilege_trap) 13091da177e4SLinus Torvalds 13101da177e4SLinus Torvalds .org ia64_ivt+0x5f00 13111da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13121da177e4SLinus Torvalds// 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68) 13131da177e4SLinus TorvaldsENTRY(taken_branch_trap) 13141da177e4SLinus Torvalds DBG_FAULT(35) 13151da177e4SLinus Torvalds FAULT(35) 13161da177e4SLinus TorvaldsEND(taken_branch_trap) 13171da177e4SLinus Torvalds 13181da177e4SLinus Torvalds .org ia64_ivt+0x6000 13191da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13201da177e4SLinus Torvalds// 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69) 13211da177e4SLinus TorvaldsENTRY(single_step_trap) 13221da177e4SLinus Torvalds DBG_FAULT(36) 13231da177e4SLinus Torvalds FAULT(36) 13241da177e4SLinus TorvaldsEND(single_step_trap) 13251da177e4SLinus Torvalds 13261da177e4SLinus Torvalds .org ia64_ivt+0x6100 13271da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13281da177e4SLinus Torvalds// 0x6100 Entry 37 (size 16 bundles) Reserved 13291da177e4SLinus Torvalds DBG_FAULT(37) 13301da177e4SLinus Torvalds FAULT(37) 13311da177e4SLinus Torvalds 13321da177e4SLinus Torvalds .org ia64_ivt+0x6200 13331da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13341da177e4SLinus Torvalds// 0x6200 Entry 38 (size 16 bundles) Reserved 13351da177e4SLinus Torvalds DBG_FAULT(38) 13361da177e4SLinus Torvalds FAULT(38) 13371da177e4SLinus Torvalds 13381da177e4SLinus Torvalds .org ia64_ivt+0x6300 13391da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13401da177e4SLinus Torvalds// 0x6300 Entry 39 (size 16 bundles) Reserved 13411da177e4SLinus Torvalds DBG_FAULT(39) 13421da177e4SLinus Torvalds FAULT(39) 13431da177e4SLinus Torvalds 13441da177e4SLinus Torvalds .org ia64_ivt+0x6400 13451da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13461da177e4SLinus Torvalds// 0x6400 Entry 40 (size 16 bundles) Reserved 13471da177e4SLinus Torvalds DBG_FAULT(40) 13481da177e4SLinus Torvalds FAULT(40) 13491da177e4SLinus Torvalds 13501da177e4SLinus Torvalds .org ia64_ivt+0x6500 13511da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13521da177e4SLinus Torvalds// 0x6500 Entry 41 (size 16 bundles) Reserved 13531da177e4SLinus Torvalds DBG_FAULT(41) 13541da177e4SLinus Torvalds FAULT(41) 13551da177e4SLinus Torvalds 13561da177e4SLinus Torvalds .org ia64_ivt+0x6600 13571da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13581da177e4SLinus Torvalds// 0x6600 Entry 42 (size 16 bundles) Reserved 13591da177e4SLinus Torvalds DBG_FAULT(42) 13601da177e4SLinus Torvalds FAULT(42) 13611da177e4SLinus Torvalds 13621da177e4SLinus Torvalds .org ia64_ivt+0x6700 13631da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13641da177e4SLinus Torvalds// 0x6700 Entry 43 (size 16 bundles) Reserved 13651da177e4SLinus Torvalds DBG_FAULT(43) 13661da177e4SLinus Torvalds FAULT(43) 13671da177e4SLinus Torvalds 13681da177e4SLinus Torvalds .org ia64_ivt+0x6800 13691da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13701da177e4SLinus Torvalds// 0x6800 Entry 44 (size 16 bundles) Reserved 13711da177e4SLinus Torvalds DBG_FAULT(44) 13721da177e4SLinus Torvalds FAULT(44) 13731da177e4SLinus Torvalds 13741da177e4SLinus Torvalds .org ia64_ivt+0x6900 13751da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13761da177e4SLinus Torvalds// 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77) 13771da177e4SLinus TorvaldsENTRY(ia32_exception) 13781da177e4SLinus Torvalds DBG_FAULT(45) 13791da177e4SLinus Torvalds FAULT(45) 13801da177e4SLinus TorvaldsEND(ia32_exception) 13811da177e4SLinus Torvalds 13821da177e4SLinus Torvalds .org ia64_ivt+0x6a00 13831da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13841da177e4SLinus Torvalds// 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept (30,31,59,70,71) 13851da177e4SLinus TorvaldsENTRY(ia32_intercept) 13861da177e4SLinus Torvalds DBG_FAULT(46) 13871da177e4SLinus Torvalds FAULT(46) 13881da177e4SLinus TorvaldsEND(ia32_intercept) 13891da177e4SLinus Torvalds 13901da177e4SLinus Torvalds .org ia64_ivt+0x6b00 13911da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 13921da177e4SLinus Torvalds// 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt (74) 13931da177e4SLinus TorvaldsENTRY(ia32_interrupt) 13941da177e4SLinus Torvalds DBG_FAULT(47) 13951da177e4SLinus Torvalds FAULT(47) 13961da177e4SLinus TorvaldsEND(ia32_interrupt) 13971da177e4SLinus Torvalds 13981da177e4SLinus Torvalds .org ia64_ivt+0x6c00 13991da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14001da177e4SLinus Torvalds// 0x6c00 Entry 48 (size 16 bundles) Reserved 14011da177e4SLinus Torvalds DBG_FAULT(48) 14021da177e4SLinus Torvalds FAULT(48) 14031da177e4SLinus Torvalds 14041da177e4SLinus Torvalds .org ia64_ivt+0x6d00 14051da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14061da177e4SLinus Torvalds// 0x6d00 Entry 49 (size 16 bundles) Reserved 14071da177e4SLinus Torvalds DBG_FAULT(49) 14081da177e4SLinus Torvalds FAULT(49) 14091da177e4SLinus Torvalds 14101da177e4SLinus Torvalds .org ia64_ivt+0x6e00 14111da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14121da177e4SLinus Torvalds// 0x6e00 Entry 50 (size 16 bundles) Reserved 14131da177e4SLinus Torvalds DBG_FAULT(50) 14141da177e4SLinus Torvalds FAULT(50) 14151da177e4SLinus Torvalds 14161da177e4SLinus Torvalds .org ia64_ivt+0x6f00 14171da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14181da177e4SLinus Torvalds// 0x6f00 Entry 51 (size 16 bundles) Reserved 14191da177e4SLinus Torvalds DBG_FAULT(51) 14201da177e4SLinus Torvalds FAULT(51) 14211da177e4SLinus Torvalds 14221da177e4SLinus Torvalds .org ia64_ivt+0x7000 14231da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14241da177e4SLinus Torvalds// 0x7000 Entry 52 (size 16 bundles) Reserved 14251da177e4SLinus Torvalds DBG_FAULT(52) 14261da177e4SLinus Torvalds FAULT(52) 14271da177e4SLinus Torvalds 14281da177e4SLinus Torvalds .org ia64_ivt+0x7100 14291da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14301da177e4SLinus Torvalds// 0x7100 Entry 53 (size 16 bundles) Reserved 14311da177e4SLinus Torvalds DBG_FAULT(53) 14321da177e4SLinus Torvalds FAULT(53) 14331da177e4SLinus Torvalds 14341da177e4SLinus Torvalds .org ia64_ivt+0x7200 14351da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14361da177e4SLinus Torvalds// 0x7200 Entry 54 (size 16 bundles) Reserved 14371da177e4SLinus Torvalds DBG_FAULT(54) 14381da177e4SLinus Torvalds FAULT(54) 14391da177e4SLinus Torvalds 14401da177e4SLinus Torvalds .org ia64_ivt+0x7300 14411da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14421da177e4SLinus Torvalds// 0x7300 Entry 55 (size 16 bundles) Reserved 14431da177e4SLinus Torvalds DBG_FAULT(55) 14441da177e4SLinus Torvalds FAULT(55) 14451da177e4SLinus Torvalds 14461da177e4SLinus Torvalds .org ia64_ivt+0x7400 14471da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14481da177e4SLinus Torvalds// 0x7400 Entry 56 (size 16 bundles) Reserved 14491da177e4SLinus Torvalds DBG_FAULT(56) 14501da177e4SLinus Torvalds FAULT(56) 14511da177e4SLinus Torvalds 14521da177e4SLinus Torvalds .org ia64_ivt+0x7500 14531da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14541da177e4SLinus Torvalds// 0x7500 Entry 57 (size 16 bundles) Reserved 14551da177e4SLinus Torvalds DBG_FAULT(57) 14561da177e4SLinus Torvalds FAULT(57) 14571da177e4SLinus Torvalds 14581da177e4SLinus Torvalds .org ia64_ivt+0x7600 14591da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14601da177e4SLinus Torvalds// 0x7600 Entry 58 (size 16 bundles) Reserved 14611da177e4SLinus Torvalds DBG_FAULT(58) 14621da177e4SLinus Torvalds FAULT(58) 14631da177e4SLinus Torvalds 14641da177e4SLinus Torvalds .org ia64_ivt+0x7700 14651da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14661da177e4SLinus Torvalds// 0x7700 Entry 59 (size 16 bundles) Reserved 14671da177e4SLinus Torvalds DBG_FAULT(59) 14681da177e4SLinus Torvalds FAULT(59) 14691da177e4SLinus Torvalds 14701da177e4SLinus Torvalds .org ia64_ivt+0x7800 14711da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14721da177e4SLinus Torvalds// 0x7800 Entry 60 (size 16 bundles) Reserved 14731da177e4SLinus Torvalds DBG_FAULT(60) 14741da177e4SLinus Torvalds FAULT(60) 14751da177e4SLinus Torvalds 14761da177e4SLinus Torvalds .org ia64_ivt+0x7900 14771da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14781da177e4SLinus Torvalds// 0x7900 Entry 61 (size 16 bundles) Reserved 14791da177e4SLinus Torvalds DBG_FAULT(61) 14801da177e4SLinus Torvalds FAULT(61) 14811da177e4SLinus Torvalds 14821da177e4SLinus Torvalds .org ia64_ivt+0x7a00 14831da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14841da177e4SLinus Torvalds// 0x7a00 Entry 62 (size 16 bundles) Reserved 14851da177e4SLinus Torvalds DBG_FAULT(62) 14861da177e4SLinus Torvalds FAULT(62) 14871da177e4SLinus Torvalds 14881da177e4SLinus Torvalds .org ia64_ivt+0x7b00 14891da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14901da177e4SLinus Torvalds// 0x7b00 Entry 63 (size 16 bundles) Reserved 14911da177e4SLinus Torvalds DBG_FAULT(63) 14921da177e4SLinus Torvalds FAULT(63) 14931da177e4SLinus Torvalds 14941da177e4SLinus Torvalds .org ia64_ivt+0x7c00 14951da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 14961da177e4SLinus Torvalds// 0x7c00 Entry 64 (size 16 bundles) Reserved 14971da177e4SLinus Torvalds DBG_FAULT(64) 14981da177e4SLinus Torvalds FAULT(64) 14991da177e4SLinus Torvalds 15001da177e4SLinus Torvalds .org ia64_ivt+0x7d00 15011da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 15021da177e4SLinus Torvalds// 0x7d00 Entry 65 (size 16 bundles) Reserved 15031da177e4SLinus Torvalds DBG_FAULT(65) 15041da177e4SLinus Torvalds FAULT(65) 15051da177e4SLinus Torvalds 15061da177e4SLinus Torvalds .org ia64_ivt+0x7e00 15071da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 15081da177e4SLinus Torvalds// 0x7e00 Entry 66 (size 16 bundles) Reserved 15091da177e4SLinus Torvalds DBG_FAULT(66) 15101da177e4SLinus Torvalds FAULT(66) 15111da177e4SLinus Torvalds 15121da177e4SLinus Torvalds .org ia64_ivt+0x7f00 15131da177e4SLinus Torvalds///////////////////////////////////////////////////////////////////////////////////////// 15141da177e4SLinus Torvalds// 0x7f00 Entry 67 (size 16 bundles) Reserved 15151da177e4SLinus Torvalds DBG_FAULT(67) 15161da177e4SLinus Torvalds FAULT(67) 15171da177e4SLinus Torvalds 15184d58bbccSIsaku Yamahata //----------------------------------------------------------------------------------- 15194d58bbccSIsaku Yamahata // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address) 15204d58bbccSIsaku YamahataENTRY(page_fault) 15214d58bbccSIsaku Yamahata SSM_PSR_DT_AND_SRLZ_I 15224d58bbccSIsaku Yamahata ;; 15234d58bbccSIsaku Yamahata SAVE_MIN_WITH_COVER 15244d58bbccSIsaku Yamahata alloc r15=ar.pfs,0,0,3,0 15254d58bbccSIsaku Yamahata MOV_FROM_IFA(out0) 15264d58bbccSIsaku Yamahata MOV_FROM_ISR(out1) 15274d58bbccSIsaku Yamahata SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r14, r3) 15284d58bbccSIsaku Yamahata adds r3=8,r2 // set up second base pointer 15294d58bbccSIsaku Yamahata SSM_PSR_I(p15, p15, r14) // restore psr.i 15304d58bbccSIsaku Yamahata movl r14=ia64_leave_kernel 15314d58bbccSIsaku Yamahata ;; 15324d58bbccSIsaku Yamahata SAVE_REST 15334d58bbccSIsaku Yamahata mov rp=r14 15344d58bbccSIsaku Yamahata ;; 15354d58bbccSIsaku Yamahata adds out2=16,r12 // out2 = pointer to pt_regs 15364d58bbccSIsaku Yamahata br.call.sptk.many b6=ia64_do_page_fault // ignore return address 15374d58bbccSIsaku YamahataEND(page_fault) 15384d58bbccSIsaku Yamahata 15394d58bbccSIsaku YamahataENTRY(non_syscall) 15404d58bbccSIsaku Yamahata mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER 15414d58bbccSIsaku Yamahata ;; 15424d58bbccSIsaku Yamahata SAVE_MIN_WITH_COVER 15434d58bbccSIsaku Yamahata 15444d58bbccSIsaku Yamahata // There is no particular reason for this code to be here, other than that 15454d58bbccSIsaku Yamahata // there happens to be space here that would go unused otherwise. If this 15464d58bbccSIsaku Yamahata // fault ever gets "unreserved", simply moved the following code to a more 15474d58bbccSIsaku Yamahata // suitable spot... 15484d58bbccSIsaku Yamahata 15494d58bbccSIsaku Yamahata alloc r14=ar.pfs,0,0,2,0 15504d58bbccSIsaku Yamahata MOV_FROM_IIM(out0) 15514d58bbccSIsaku Yamahata add out1=16,sp 15524d58bbccSIsaku Yamahata adds r3=8,r2 // set up second base pointer for SAVE_REST 15534d58bbccSIsaku Yamahata 15544d58bbccSIsaku Yamahata SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r15, r24) 15554d58bbccSIsaku Yamahata // guarantee that interruption collection is on 15564d58bbccSIsaku Yamahata SSM_PSR_I(p15, p15, r15) // restore psr.i 15574d58bbccSIsaku Yamahata movl r15=ia64_leave_kernel 15584d58bbccSIsaku Yamahata ;; 15594d58bbccSIsaku Yamahata SAVE_REST 15604d58bbccSIsaku Yamahata mov rp=r15 15614d58bbccSIsaku Yamahata ;; 15624d58bbccSIsaku Yamahata br.call.sptk.many b6=ia64_bad_break // avoid WAW on CFM and ignore return addr 15634d58bbccSIsaku YamahataEND(non_syscall) 15644d58bbccSIsaku Yamahata 15654d58bbccSIsaku YamahataENTRY(__interrupt) 15664d58bbccSIsaku Yamahata DBG_FAULT(12) 15674d58bbccSIsaku Yamahata mov r31=pr // prepare to save predicates 15684d58bbccSIsaku Yamahata ;; 15694d58bbccSIsaku Yamahata SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3 15704d58bbccSIsaku Yamahata SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r14) 15714d58bbccSIsaku Yamahata // ensure everybody knows psr.ic is back on 15724d58bbccSIsaku Yamahata adds r3=8,r2 // set up second base pointer for SAVE_REST 15734d58bbccSIsaku Yamahata ;; 15744d58bbccSIsaku Yamahata SAVE_REST 15754d58bbccSIsaku Yamahata ;; 15764d58bbccSIsaku Yamahata MCA_RECOVER_RANGE(interrupt) 15774d58bbccSIsaku Yamahata alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group 15784d58bbccSIsaku Yamahata MOV_FROM_IVR(out0, r8) // pass cr.ivr as first arg 15794d58bbccSIsaku Yamahata add out1=16,sp // pass pointer to pt_regs as second arg 15804d58bbccSIsaku Yamahata ;; 15814d58bbccSIsaku Yamahata srlz.d // make sure we see the effect of cr.ivr 15824d58bbccSIsaku Yamahata movl r14=ia64_leave_kernel 15834d58bbccSIsaku Yamahata ;; 15844d58bbccSIsaku Yamahata mov rp=r14 15854d58bbccSIsaku Yamahata br.call.sptk.many b6=ia64_handle_irq 15864d58bbccSIsaku YamahataEND(__interrupt) 15874d58bbccSIsaku Yamahata 15884d58bbccSIsaku Yamahata /* 15894d58bbccSIsaku Yamahata * There is no particular reason for this code to be here, other than that 15904d58bbccSIsaku Yamahata * there happens to be space here that would go unused otherwise. If this 15914d58bbccSIsaku Yamahata * fault ever gets "unreserved", simply moved the following code to a more 15924d58bbccSIsaku Yamahata * suitable spot... 15934d58bbccSIsaku Yamahata */ 15944d58bbccSIsaku Yamahata 15954d58bbccSIsaku YamahataENTRY(dispatch_unaligned_handler) 15964d58bbccSIsaku Yamahata SAVE_MIN_WITH_COVER 15974d58bbccSIsaku Yamahata ;; 15984d58bbccSIsaku Yamahata alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!) 15994d58bbccSIsaku Yamahata MOV_FROM_IFA(out0) 16004d58bbccSIsaku Yamahata adds out1=16,sp 16014d58bbccSIsaku Yamahata 16024d58bbccSIsaku Yamahata SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24) 16034d58bbccSIsaku Yamahata // guarantee that interruption collection is on 16044d58bbccSIsaku Yamahata SSM_PSR_I(p15, p15, r3) // restore psr.i 16054d58bbccSIsaku Yamahata adds r3=8,r2 // set up second base pointer 16064d58bbccSIsaku Yamahata ;; 16074d58bbccSIsaku Yamahata SAVE_REST 16084d58bbccSIsaku Yamahata movl r14=ia64_leave_kernel 16094d58bbccSIsaku Yamahata ;; 16104d58bbccSIsaku Yamahata mov rp=r14 16114d58bbccSIsaku Yamahata br.sptk.many ia64_prepare_handle_unaligned 16124d58bbccSIsaku YamahataEND(dispatch_unaligned_handler) 16134d58bbccSIsaku Yamahata 16144d58bbccSIsaku Yamahata /* 16154d58bbccSIsaku Yamahata * There is no particular reason for this code to be here, other than that 16164d58bbccSIsaku Yamahata * there happens to be space here that would go unused otherwise. If this 16174d58bbccSIsaku Yamahata * fault ever gets "unreserved", simply moved the following code to a more 16184d58bbccSIsaku Yamahata * suitable spot... 16194d58bbccSIsaku Yamahata */ 16204d58bbccSIsaku Yamahata 16214d58bbccSIsaku YamahataENTRY(dispatch_to_fault_handler) 16224d58bbccSIsaku Yamahata /* 16234d58bbccSIsaku Yamahata * Input: 16244d58bbccSIsaku Yamahata * psr.ic: off 16254d58bbccSIsaku Yamahata * r19: fault vector number (e.g., 24 for General Exception) 16264d58bbccSIsaku Yamahata * r31: contains saved predicates (pr) 16274d58bbccSIsaku Yamahata */ 16284d58bbccSIsaku Yamahata SAVE_MIN_WITH_COVER_R19 16294d58bbccSIsaku Yamahata alloc r14=ar.pfs,0,0,5,0 16304d58bbccSIsaku Yamahata MOV_FROM_ISR(out1) 16314d58bbccSIsaku Yamahata MOV_FROM_IFA(out2) 16324d58bbccSIsaku Yamahata MOV_FROM_IIM(out3) 16334d58bbccSIsaku Yamahata MOV_FROM_ITIR(out4) 16344d58bbccSIsaku Yamahata ;; 16354d58bbccSIsaku Yamahata SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, out0) 16364d58bbccSIsaku Yamahata // guarantee that interruption collection is on 16374d58bbccSIsaku Yamahata mov out0=r15 16384d58bbccSIsaku Yamahata ;; 16394d58bbccSIsaku Yamahata SSM_PSR_I(p15, p15, r3) // restore psr.i 16404d58bbccSIsaku Yamahata adds r3=8,r2 // set up second base pointer for SAVE_REST 16414d58bbccSIsaku Yamahata ;; 16424d58bbccSIsaku Yamahata SAVE_REST 16434d58bbccSIsaku Yamahata movl r14=ia64_leave_kernel 16444d58bbccSIsaku Yamahata ;; 16454d58bbccSIsaku Yamahata mov rp=r14 16464d58bbccSIsaku Yamahata br.call.sptk.many b6=ia64_fault 16474d58bbccSIsaku YamahataEND(dispatch_to_fault_handler) 16484d58bbccSIsaku Yamahata 16494dcc29e1STony Luck /* 16504dcc29e1STony Luck * Squatting in this space ... 16514dcc29e1STony Luck * 16524dcc29e1STony Luck * This special case dispatcher for illegal operation faults allows preserved 16534dcc29e1STony Luck * registers to be modified through a callback function (asm only) that is handed 16544dcc29e1STony Luck * back from the fault handler in r8. Up to three arguments can be passed to the 16554dcc29e1STony Luck * callback function by returning an aggregate with the callback as its first 16564dcc29e1STony Luck * element, followed by the arguments. 16574dcc29e1STony Luck */ 16584dcc29e1STony LuckENTRY(dispatch_illegal_op_fault) 16594dcc29e1STony Luck .prologue 16604dcc29e1STony Luck .body 16614dcc29e1STony Luck SAVE_MIN_WITH_COVER 1662498c5170SIsaku Yamahata SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24) 1663498c5170SIsaku Yamahata // guarantee that interruption collection is on 16644dcc29e1STony Luck ;; 1665498c5170SIsaku Yamahata SSM_PSR_I(p15, p15, r3) // restore psr.i 16664dcc29e1STony Luck adds r3=8,r2 // set up second base pointer for SAVE_REST 16674dcc29e1STony Luck ;; 16684dcc29e1STony Luck alloc r14=ar.pfs,0,0,1,0 // must be first in insn group 16694dcc29e1STony Luck mov out0=ar.ec 16704dcc29e1STony Luck ;; 16714dcc29e1STony Luck SAVE_REST 16724dcc29e1STony Luck PT_REGS_UNWIND_INFO(0) 16734dcc29e1STony Luck ;; 16744dcc29e1STony Luck br.call.sptk.many rp=ia64_illegal_op_fault 16754dcc29e1STony Luck.ret0: ;; 16764dcc29e1STony Luck alloc r14=ar.pfs,0,0,3,0 // must be first in insn group 16774dcc29e1STony Luck mov out0=r9 16784dcc29e1STony Luck mov out1=r10 16794dcc29e1STony Luck mov out2=r11 16804dcc29e1STony Luck movl r15=ia64_leave_kernel 16814dcc29e1STony Luck ;; 16824dcc29e1STony Luck mov rp=r15 16834dcc29e1STony Luck mov b6=r8 16844dcc29e1STony Luck ;; 16854dcc29e1STony Luck cmp.ne p6,p0=0,r8 16864dcc29e1STony Luck(p6) br.call.dpnt.many b6=b6 // call returns to ia64_leave_kernel 16874dcc29e1STony Luck br.sptk.many ia64_leave_kernel 16884dcc29e1STony LuckEND(dispatch_illegal_op_fault) 1689