diff options
Diffstat (limited to 'public/sdk/inc/kxppc.h')
-rw-r--r-- | public/sdk/inc/kxppc.h | 1733 |
1 files changed, 1733 insertions, 0 deletions
diff --git a/public/sdk/inc/kxppc.h b/public/sdk/inc/kxppc.h new file mode 100644 index 000000000..af2252c71 --- /dev/null +++ b/public/sdk/inc/kxppc.h @@ -0,0 +1,1733 @@ +//++ BUILD Version: 0003 // Increment this if a change has global effects // +//*++ +// +// Copyright (c) 1990-1996 IBM Corporation +// +// Module Name: +// +// kxppc.h +// +// Abstract: +// +// This module contains the nongenerated part of the PPC assembler +// header file. In general, it contains processor architecture constant +// information, however some assembler macros are also included. +// +// Author: +// +// Chuck Bauman (chuck2) 03-Aug-1993 +// +// Revision History: +// +// Base on kxmips.h, NT product1 source (R3000 paths removed) +// Add procedure entry exit macros (Chuck Bauman) 10-Aug-1993 +// Fixed # comments so C modules compile (Chuck Bauman) 13-Aug-1993 +// Add exception entry codes and STK_SLACK_SPACE (Peter Johnston) 19-Aug-1993 +// Optimizations for NESTED ENTRY/EXIT (Chuck Bauman) 27-Aug-1993 +// New entry point linkage convention (Chuck Bauman) 01-Sep-1993 +// Added SPECIAL ENTRY/EXIT (Curt Fawcett) 22-Sep-1993 +// Deleted EXCEPTION_HANDLER and changed NESTED_ENTRY_EX +// and LEAF_ENTRY_EX to not append .scope to the Scope +// parameter (Tom Wood) 02-Nov-1993 +// Added definition for SPR #1, Fixed Point Exception +// register XER (Mark D. Johnson) 11-Mar-1994 +// Added in the macros that used to be in /private/ntos/ +// crt32/h/ppcsects.h. I then removed that file since +// we don't need it anymore. (Matt Holle) 27-Apr-1994 +// +//--*/ + +#ifndef _KXPPC_ +#define _KXPPC_ + +#ifndef _KXPPC_C_HEADER_ + +// ===================================================================== +// Begin code extracted from ppcsects.h +// ===================================================================== + +//Purpose: +// This file defines sections for the C and C++ libs. +// +// NOTE: As needed, special "CRT" sections can be added into the existing +// init/term tables. These will be for our use only -- users who put +// stuff in here do so at their own risk. +// +//Revision History: +// 03-19-92 SKS Loosely based on the 16-bit include file DEFSEGS.INC +// 08-06-92 SKS Changed these section names from X[ICPT]$[ACLUXZ] to +// .CRT$X[ICPT][ACLUXZ] to avoid creating too many sections +// Also, sections are no longer defined in groups. That was +// for use with OMF type objects where order of appearance +// is important. With COFF, sorting is done by section name. +// 10-26-93 CDB Based on MS defsects.inc +// +// beginSection - a macro for declaring and beginning a section +// +// endSection - a macro for ending a previously declared section +// +// ***** + +#define beginSection(SectName) \ +.section .CRT$##SectName, "drw2" + +#define endSection(SectName) + +// XIA Begin C Initializer Sections +// XIC Microsoft Reserved +// XIU User +// XIZ End C Initializer Sections +// +// XCA Begin C++ Constructor Sections +// XCC Compiler (MS) +// XCL Library +// XCU User +// XCZ End C++ Constructor Sections +// +// XPA Begin C Pre-Terminator Sections +// XPU User +// XPX Microsoft Reserved +// XPZ End C Pre-Terminator Sections +// +// XTA Begin C Pre-Terminator Sections +// XTU User +// XTX Microsoft Reserved +// XTZ End C Pre-Terminator Sections + +// ===================================================================== +// End code extracted from ppcsects.h +// ===================================================================== + +#endif // _KXPPC_C_HEADER_ + +// +// Define soft reset vector address for nonhandled cache parity errors. +// + +#define SOFT_RESET_VECTOR 0xbfc00300 // default parity error routine address + +// +// Define low memory transfer vector address and TB index address (temporary). +// +#define TRANSFER_VECTOR (KSEG1_BASE + 0x400) // exception handler address + +// +// Maximum Bit number (32 bit implementation) +// +#define MAX_BITS 0x1f + +// +// Macro to generate a mask using the SPR bit definitions below +// +#define MASK_SPR(shift,mask) ((mask) << (MAX_BITS-(shift))) + +// +// Define Machine State Register bit field offsets. +// +// MSR_POW 0x0d Power management enable <13> +// MSR_IMPL 0x0e Implementation dependent <14> +// MSR_ILE 0x0f Interrupt Little-Endian mode <15> +// MSR_EE 0x10 External interrupt Enable <16> +// MSR_PR 0x11 Problem state <17> +// MSR_FP 0x12 Floating Point available <18> +// MSR_ME 0x13 Machine check Enable <19> +// MSR_FE0 0x14 Floating point Exception mode 0 <20> +// MSR_SE 0x15 Single-step trace Enable <21> +// MSR_BE 0x16 Branch trace Enable <22> +// MSR_FE1 0x17 Floating point Exception mode 1 <23> +// MSR_IP 0x19 Interrupt Prefix <25> +// MSR_IR 0x1a Instruction Relocate <26> +// MSR_DR 0x1b Data Relocate <27> +// MSR_PM 0x1d Performance Monitor <29> +// MSR_RI 0x1e Recoverable Interrupt <30> +// MSR_LE 0x1f Little-Endian execution mode <31> + +#define MSR_POW 0x0d +#define MSR_IMPL 0x0e +#define MSR_ILE 0x0f +#define MSR_EE 0x10 +#define MSR_PR 0x11 +#define MSR_FP 0x12 +#define MSR_ME 0x13 +#define MSR_FE0 0x14 +#define MSR_SE 0x15 +#define MSR_BE 0x16 +#define MSR_FE1 0x17 +#define MSR_IP 0x19 +#define MSR_IR 0x1a +#define MSR_DR 0x1b +#define MSR_PM 0x1d +#define MSR_RI 0x1e +#define MSR_LE 0x1f + + +// +// Define Processor Version Register (PVR) bit fields +// +// PVR_Version 0x0 Processor Version <0:15> +// PVR_Revision 0x10 Processor Revision <16:31> +#define PVR_Version 0x0 +#define PVR_Revision 0x10 + +// +// Fixed Point Exception Register is Special Purpose Reg no. 1 +// + +#define XER 0x1 + +// +// Define Fixed Point Exception Register (XER) bit fields +// + +// XER_SO 0x0 Summary Overflow <0> +// XER_OV 0x1 Overflow <1> +// XER_CA 0x2 Carry <2> +// XER_COMP 0x10 > Carry <16:23> +// XER_COUNT 0x19 Carry <25:31> + +#define XER_SO 0x0 +#define XER_OV 0x1 +#define XER_CA 0x2 +#define XER_COMP 0x10 +#define XER_COUNT 0x19 + + +// +// Define Floating Point Status/Control Register (FPSCR) bit fields +// +// FPSCR_FX 0x0 Exception summary <0> +// FPSCR_FEX 0x1 Enabled Exception summary <1> +// FPSCR_VX 0x2 Invalid operation exception summary <2> +// FPSCR_OX 0x3 Overflow exception <3> +// FPSCR_UX 0x4 Underflow exception <4> +// FPSCR_ZX 0x5 Zero divide exception <5> +// FPSCR_XX 0x6 Inexact exception <6> +// FPSCR_VXSNAN 0x7 Invalid op exception (signalling NaN) <7> +// FPSCR_VXISI 0x8 Invalid op exception (infinity - infinity) <8> +// FPSCR_VXIDI 0x9 Invalid op exception (infinity / infinity) <9> +// FPSCR_VXZDZ 0x0a Invalid op exception (0 / 0) <10> +// FPSCR_VXIMZ 0x0b Invalid op exception (infinity * 0) <11> +// FPSCR_VXVC 0x0c Invalid op exception (compare) <12> +// FPSCR_FR 0x0d Fraction Rounded <13> +// FPSCR_FI 0x0e Fraction Inexact <14> +// FPSCR_C 0x0f Result Class descriptor <15> +// FPSCR_FL 0x10 Result Less than or negative <16> +// FPSCR_FG 0x11 Result Greater than or positive <17> +// FPSCR_FE 0x12 Result Equal or zero <18> +// FPSCR_FU 0x13 Result Unordered or NaN <19> +// FPSCR_Res1 0x14 reserved <20> +// FPSCR_VXSOFT 0x15 Invalid op exception (software request) <21> +// FPSCR_VXSQRT 0x16 Invalid op exception (square root) <22> +// FPSCR_VXCVI 0x17 Invalid op exception (integer convert) <23> +// FPSCR_VE 0x18 Invalid operation exception Enable <24> +// FPSCR_OE 0x19 Overflow exception Enable <25> +// FPSCR_UE 0x1a Underflow exception Enable <26> +// FPSCR_ZE 0x1b Zero divide exception Enable <27> +// FPSCR_XE 0x1c Inexact exception Enable <28> +// FPSCR_NI 0x1d Non-IEEE mode <29> +// FPSCR_RN 0x1e Rounding control <30:31> +#define FPSCR_FX 0x0 +#define FPSCR_FEX 0x1 +#define FPSCR_VX 0x2 +#define FPSCR_OX 0x3 +#define FPSCR_UX 0x4 +#define FPSCR_ZX 0x5 +#define FPSCR_XX 0x6 +#define FPSCR_VXSNAN 0x7 +#define FPSCR_VXISI 0x8 +#define FPSCR_VXIDI 0x9 +#define FPSCR_VXZDZ 0x0a +#define FPSCR_VXIMZ 0x0b +#define FPSCR_VXVC 0x0c +#define FPSCR_FR 0x0d +#define FPSCR_FI 0x0e +#define FPSCR_C 0x0f +#define FPSCR_FL 0x10 +#define FPSCR_FG 0x11 +#define FPSCR_FE 0x12 +#define FPSCR_FU 0x13 +#define FPSCR_Res1 0x14 +#define FPSCR_VXSOFT 0x15 +#define FPSCR_VXSQRT 0x16 +#define FPSCR_VXCVI 0x17 +#define FPSCR_VE 0x18 +#define FPSCR_OE 0x19 +#define FPSCR_UE 0x1a +#define FPSCR_ZE 0x1b +#define FPSCR_XE 0x1c +#define FPSCR_NI 0x1d +#define FPSCR_RN 0x1e + + +// +// Define exception codes. +// + +#define XCODE_INTERRUPT 0x0 // Interrupt +#define XCODE_MODIFY 0x4 // TLB modify +#define XCODE_READ_MISS 0x8 // TLB read miss +#define XCODE_WRITE_MISS 0xc // TLB write miss +#define XCODE_READ_ADDRESS_ERROR 0x10 // Read alignment error +#define XCODE_WRITE_ADDRESS_ERROR 0x14 // Write alignment error +#define XCODE_INSTRUCTION_BUS_ERROR 0x18 // Instruction bus error +#define XCODE_DATA_BUS_ERROR 0x1c // Data bus error +#define XCODE_SYSTEM_CALL 0x20 // System call +#define XCODE_BREAKPOINT 0x24 // Breakpoint +#define XCODE_ILLEGAL_INSTRUCTION 0x28 // Illegal instruction +#define XCODE_COPROCESSOR_UNUSABLE 0x2c // Coprocessor unusable +#define XCODE_INTEGER_OVERFLOW 0x30 // Arithmetic overflow + +#define XCODE_TRAP 0x34 // Trap instruction +#define XCODE_VIRTUAL_INSTRUCTION 0x38 // Virtual instruction coherency +#define XCODE_FLOATING_EXCEPTION 0x3c // Floating point exception +#define XCODE_WATCHPOINT 0x5c // Watch point +#define XCODE_PANIC 0x78 // Stack overflow (software) +#define XCODE_VIRTUAL_DATA 0x7c // Virtual data coherency + +#define R4000_XCODE_MASK (0x1f << CAUSE_XCODE) // R4000 exception code mask + +#define R4000_MISS_MASK (R4000_XCODE_MASK & \ + (~(XCODE_READ_MISS ^ XCODE_WRITE_MISS))) // + +// +// Define page mask values. +// + +#define PAGEMASK_4KB 0x0 // 4kb page +#define PAGEMASK_16KB 0x3 // 16kb page +#define PAGEMASK_64KB 0xf // 64kb page +#define PAGEMASK_256KB 0x3f // 256kb page +#define PAGEMASK_1MB 0xff // 1mb page +#define PAGEMASK_4MB 0x3ff // 4mb page +#define PAGEMASK_16MB 0xfff // 16mb page + +// +// Define primary cache states. +// + +#define PRIMARY_CACHE_INVALID 0x0 // primary cache invalid +#define PRIMARY_CACHE_SHARED 0x1 // primary cache shared (clean or dirty) +#define PRIMARY_CACHE_CLEAN_EXCLUSIVE 0x2 // primary cache clean exclusive +#define PRIMARY_CACHE_DIRTY_EXCLUSIVE 0x3 // primary cache dirty exclusive + +// +// Define cache instruction operation codes. +// + +#define INDEX_INVALIDATE_I 0x0 // invalidate primary instruction cache +#define INDEX_WRITEBACK_INVALIDATE_D 0x1 // writeback/invalidate primary data cache +#define INDEX_INVALIDATE_SI 0x2 // invalidate secondary instruction cache +#define INDEX_WRITEBACK_INVALIDATE_SD 0x3 // writeback/invalidate secondary data cache + +#define INDEX_LOAD_TAG_I 0x4 // load primary instruction tag indexed +#define INDEX_LOAD_TAG_D 0x5 // load primary data tag indexed +#define INDEX_LOAD_TAG_SI 0x6 // load secondary instruction tag indexed +#define INDEX_LOAD_TAG_SD 0x7 // load secondary data tag indexed + +#define INDEX_STORE_TAG_I 0x8 // store primary instruction tag indexed +#define INDEX_STORE_TAG_D 0x9 // store primary data tag indexed +#define INDEX_STORE_TAG_SI 0xa // store secondary instruction tag indexed +#define INDEX_STORE_TAG_SD 0xb // store secondary data tag indexed + +#define CREATE_DIRTY_EXCLUSIVE_D 0xd // create dirty exclusive primary data cache +#define CREATE_DIRTY_EXCLUSIVE_SD 0xf // create dirty exclusive secondary data cache + +#define HIT_INVALIDATE_I 0x10 // invalidate primary instruction cache +#define HIT_INVALIDATE_D 0x11 // invalidate primary data cache +#define HIT_INVALIDATE_SI 0x12 // invalidate secondary instruction cache +#define HIT_INVALIDATE_SD 0x13 // invalidate secondary data cache + +#define HIT_WRITEBACK_INVALIDATE_D 0x15 // writeback/invalidate primary data cache +#define HIT_WRITEBACK_INVALIDATE_SD 0x17 // writeback/invalidate secondary data cache + +#define HIT_WRITEBACK_D 0x19 // writeback primary data cache +#define HIT_WRITEBACK_SD 0x1b // writeback secondary data cache + +#define HIT_SET_VIRTUAL_SI 0x1e // hit set virtual secondary instruction cache +#define HIT_SET_VIRTUAL_SD 0x1f // hit set virtual secondary data cache + +#ifndef _KXPPC_C_HEADER_ + +// +// Define save and restore floating state macros. +// + +#define RESTORE_VOLATILE_FLOAT_STATE(_tf) \ + lfd f.13, TrFpscr(_tf); \ + lfd f.0, TrFpr0(_tf); \ + lfd f.1, TrFpr1(_tf); \ + lfd f.2, TrFpr2(_tf); \ + lfd f.3, TrFpr3(_tf); \ + lfd f.4, TrFpr4(_tf); \ + lfd f.5, TrFpr5(_tf); \ + lfd f.6, TrFpr6(_tf); \ + lfd f.7, TrFpr7(_tf); \ + lfd f.8, TrFpr8(_tf); \ + mtfsf 0xff, f.13; \ + lfd f.9, TrFpr9(_tf); \ + lfd f.10, TrFpr10(_tf); \ + lfd f.11, TrFpr11(_tf); \ + lfd f.12, TrFpr12(_tf); \ + lfd f.13, TrFpr13(_tf); + +#define SAVE_VOLATILE_FLOAT_STATE(_tf) \ + stfd f.0, TrFpr0(_tf); \ + stfd f.1, TrFpr1(_tf); \ + stfd f.2, TrFpr2(_tf); \ + stfd f.3, TrFpr3(_tf); \ + stfd f.4, TrFpr4(_tf); \ + stfd f.5, TrFpr5(_tf); \ + mffs f.0; \ + stfd f.6, TrFpr6(_tf); \ + stfd f.7, TrFpr7(_tf); \ + stfd f.8, TrFpr8(_tf); \ + stfd f.9, TrFpr9(_tf); \ + stfd f.10, TrFpr10(_tf); \ + stfd f.11, TrFpr11(_tf); \ + stfd f.12, TrFpr12(_tf); \ + stfd f.13, TrFpr13(_tf); \ + stfd f.0, TrFpscr(_tf); + +//#define RESTORE_NONVOLATILE_FLOAT_STATE +// ldc1 f20,ExFltF20(sp); +// jal KiRestoreNonvolatileFloatState; + +//#define SAVE_NONVOLATILE_FLOAT_STATE +// sdc1 f20,ExFltF20(sp); +// jal KiSaveNonvolatileFloatState; + +#endif // _KXPPC_C_HEADER_ + +// +// Define TB and cache parameters. +// + +#define PCR_ENTRY 0 // TB entry numbers (2) for the PCR +#define PDR_ENTRY 2 // TB entry number (1) for the PDR +#define KSTACK_ENTRY 3 // TB entry numbers (1) for kernel stack +#define DMA_ENTRY 4 // TB entry number (1) for DMA/InterruptSource + +#define TB_ENTRY_SIZE (3 * 4) // size of TB entry +#define FIXED_BASE 0 // base index of fixed TB entries +#define FIXED_ENTRIES (DMA_ENTRY + 1) // number of fixed TB entries + +// +// Define cache parameters +// + +#define DCACHE_SIZE (4 * 1024) // size of data cache in bytes +#define ICACHE_SIZE (4 * 1024) // size of instruction cache in bytes +#define MINIMUM_CACHE_SIZE (4 * 1024) // minimum size of cache +#define MAXIMUM_CACHE_SIZE (128 * 1024) // maximum size fo cache + +#ifndef _KXPPC_C_HEADER_ + +// +// Define subtitle macro +// + +#define SBTTL(x) + +// +// Define global definition macros. +// + +// +// Define load immediate macro for 32-bit values. +// +// reg - Register to load with the 32-bit immediate +// immediate - 32-bit immediate value +// +#define LWI(reg,immediate) \ + lis reg,(immediate) >> 16 ;\ + ori reg,reg,(immediate) & 0xffff + +#define END_REGION(Name) \ + .globl Name ;\ +Name: + +#define START_REGION(Name) \ + .globl Name ;\ +Name: + +// +// Define trap frame generation macro. +// + +//#define GENERATE_TRAP_FRAME +// .set noat; +// sw AT,TrIntAt(s8); +// jal KiGenerateTrapFrame; +// .set at; + +// +// Define restore volatile integer state macro. +// + +//#define RESTORE_VOLATILE_INTEGER_STATE +// .set noat; +// lw AT,TrIntAt(s8); +// jal KiRestoreVolatileIntegerState; +// .set at; + +// +// Define save volatile integer state macro. +// + +//#define SAVE_VOLATILE_INTEGER_STATE +// .set noat; +// sw AT,TrIntAt(s8); +// jal KiSaveVolatileIntegerState; +// .set at; + +// +// Define macros used by procedure entry/exit macros +// + +// +// Set register 12 to the GPR save location based on the number +// of floating point registers to be saved. +// +#define __setFramemr(Fpr) \ + mr r.12,r.sp + +#define __setFramesubi(Fpr) \ + subi r.12,r.sp,8*Fpr + +// +// Save the number of GPRs specified inline or by setting r.12 to the GPR +// save location and branching to the appropriate millicode save procedure. +// +// Changed bla to bl in __savegpr4-__savegrp19 IBMCDB +#define __savegpr0(op,Fpr) +#define __savegpr1(op,Fpr) \ + stw r.31,-(4+(8*Fpr))(r.sp) +#define __savegpr2(op,Fpr) \ + stw r.31,-(4+(8*Fpr))(r.sp) ;\ + stw r.30,-(8+(8*Fpr))(r.sp) +#define __savegpr3(op,Fpr) \ + stw r.31,-(4+(8*Fpr))(r.sp) ;\ + stw r.30,-(8+(8*Fpr))(r.sp) ;\ + stw r.29,-(12+(8*Fpr))(r.sp) +#define __savegpr4(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_28 +#define __savegpr5(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_27 +#define __savegpr6(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_26 +#define __savegpr7(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_25 +#define __savegpr8(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_24 +#define __savegpr9(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_23 +#define __savegpr10(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_22 +#define __savegpr11(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_21 +#define __savegpr12(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_20 +#define __savegpr13(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_19 + + +#define __savegpr14(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_18 +#define __savegpr15(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_17 +#define __savegpr16(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_16 +#define __savegpr17(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_15 +#define __savegpr18(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_14 +#define __savegpr19(op,Fpr) \ + __setFrame##op(Fpr) ;\ + bl .._savegpr_13 +// +// Macros for removing the stack frame established through NESTED ENTRY. +// +#define __unsetFramemov(Fsize,Fpr) \ + addi r.12,r.sp,Fsize ; \ + mtlr r.0 ; \ + mr r.sp,r.12 + +#define __unsetFrameaddi(Fsize,Fpr) \ + addi r.12,r.sp,(Fsize)-(8*Fpr) + +#define __unsetFrameblr(Fsize,Fpr) \ + mtlr r.0 ; \ + addi r.sp,r.sp,Fsize ; \ + blr + +// Change __unsetFrameba to __unsetFrameb IBMCDB +#define __unsetFrameb(Fsize,Fpr) \ + addi r.sp,r.sp,Fsize ; \ + blr + +// Change __unsetFramebla to __unsetFramebl IBMCDB +#define __unsetFramebl(Fsize,Fpr) + +#define __unsetFramenop(Fsize,Fpr) + +// Change __setLRba to __setLRb IBMCDB +#define __setLRb(Fsize,Fpr) \ + mtlr r.0 + +// Change __setLRbla to __setLRbl IBMCDB +#define __setLRbl(Fsize,Fpr) + + +// +// Restore number of GPRs specified +// setr - determines how to remove the stack frame (mov or addi) +// mov - will cause __unsetFramemov to be used +// addi - will cause __unsetFrameaddi to be used +// opret - if set to blr will cause GPR restore to return to caller +// only used for 0 GPRs and 0 FPRs +// op - specifies instruction to be used for the call to the +// restore millicode (ba, bla) - Changed to (b, bl) IBMCDB +// Fsize - stack frame size +// Fpr - number of FPRs to be restored +// +#define __restgpr0(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##opret(Fsize,Fpr) +#define __restgpr1(setr,opret,op,Fsize,Fpr) \ + __setLR##op(Fsize,Fpr) ;\ + lwz r.31,((Fsize)-(4+(8*Fpr)))(r.sp) ;\ + __unsetFrame##op(Fsize,Fpr) +#define __restgpr2(setr,opret,op,Fsize,Fpr) \ + lwz r.31,((Fsize)-(4+(8*Fpr)))(r.sp) ;\ + __setLR##op(Fsize,Fpr) ;\ + lwz r.30,((Fsize)-(8+(8*Fpr)))(r.sp) ;\ + __unsetFrame##op(Fsize,Fpr) +#define __restgpr3(setr,opret,op,Fsize,Fpr) \ + lwz r.31,((Fsize)-(4+(8*Fpr)))(r.sp) ;\ + __setLR##op(Fsize,Fpr) ;\ + lwz r.30,((Fsize)-(8+(8*Fpr)))(r.sp) ;\ + lwz r.29,((Fsize)-(12+(8*Fpr)))(r.sp) ;\ + __unsetFrame##op(Fsize,Fpr) +#define __restgpr4(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_28 +#define __restgpr5(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_27 +#define __restgpr6(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_26 +#define __restgpr7(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_25 +#define __restgpr8(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_24 +#define __restgpr9(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_23 +#define __restgpr10(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_22 +#define __restgpr11(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_21 +#define __restgpr12(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_20 +#define __restgpr13(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_19 + + +#define __restgpr14(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_18 +#define __restgpr15(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_17 +#define __restgpr16(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_16 +#define __restgpr17(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_15 +#define __restgpr18(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_14 +#define __restgpr19(setr,opret,op,Fsize,Fpr) \ + __unsetFrame##setr(Fsize,Fpr) ;\ + op .._restgpr_13 + +// +// Set r.12 to GPR save location based on number of FPRs to save. +// +#define __setGPRFrm0(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(mr,0) ;\ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __setGPRFrm1(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,1) +#define __setGPRFrm2(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,2) +#define __setGPRFrm3(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,3) +#define __setGPRFrm4(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,4) +#define __setGPRFrm5(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,5) +#define __setGPRFrm6(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,6) +#define __setGPRFrm7(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,7) +#define __setGPRFrm8(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,8) +#define __setGPRFrm9(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,9) +#define __setGPRFrm10(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,10) +#define __setGPRFrm11(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,11) +#define __setGPRFrm12(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,12) +#define __setGPRFrm13(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,13) + + +#define __setGPRFrm14(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,14) +#define __setGPRFrm15(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,15) +#define __setGPRFrm16(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,16) +#define __setGPRFrm17(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,17) +#define __setGPRFrm18(Fsize,Gpr,Fpr) \ + __savegpr##Gpr(subi,18) + +// +// Generate epilogue code for NESTED EXIT based on number of GPRs and FPRs +// to be restored. +// Fsize - stack frame size +// Gpr - number of GPRs to restore +// Fpr - number of FPRs to restore +// +// Changed 3rd argument to __restgpr##Gpr in __unsetGPRFrm1 from ba to b IBMCDB +// Changed 3rd argument to __restgpr##Gpr in __unsetGPRFrm2-18 from bla to bl IBMCDB +#define __unsetGPRFrm0(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(mov,blr,b,Fsize,Fpr) +#define __unsetGPRFrm1(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + mtlr r.0 ;\ + lfd f.31,((Fsize)-8)(r.sp) ;\ + addi r.sp,r.sp,Fsize ;\ + blr +#define __unsetGPRFrm2(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + lfd f.31,((Fsize)-8)(r.sp) ;\ + mtlr r.0 ;\ + lfd f.30,((Fsize)-16)(r.sp) ;\ + addi r.sp,r.sp,Fsize ;\ + blr +#define __unsetGPRFrm3(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + lfd f.31,((Fsize)-8)(r.sp) ;\ + mtlr r.0 ;\ + lfd f.30,((Fsize)-16)(r.sp) ;\ + lfd f.29,((Fsize)-24)(r.sp) ;\ + addi r.sp,r.sp,Fsize ;\ + blr +#define __unsetGPRFrm4(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm5(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm6(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr + + +#define __unsetGPRFrm7(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm8(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm9(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm10(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm11(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm12(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm13(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm14(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm15(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm16(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm17(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr +#define __unsetGPRFrm18(Fsize,Gpr,Fpr) \ + __restgpr##Gpr(addi,nop,bl,Fsize,Fpr) ;\ + addi r.sp,r.sp,Fsize ;\ + mtlr r.0 ;\ + __restfpr##Fpr + + +// +// Save the number of FPRs specified inline or by branching to the appropriate +// millicode procedure. +// +// Change bla to bl in __savefrp4-18 IBMCDB +#define __savefpr0(Fsize,Gpr,Fpr) +#define __savefpr1(Fsize,Gpr,Fpr) \ + stfd f.31,-8(r.sp) ;\ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr2(Fsize,Gpr,Fpr) \ + stfd f.31,-8(r.sp) ;\ + stfd f.30,-16(r.sp) ;\ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr3(Fsize,Gpr,Fpr) \ + stfd f.31,-8(r.sp) ;\ + stfd f.30,-16(r.sp) ;\ + stfd f.29,-24(r.sp) ;\ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr4(Fsize,Gpr,Fpr) \ + bl .._savefpr_28 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr5(Fsize,Gpr,Fpr) \ + bl .._savefpr_27 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr6(Fsize,Gpr,Fpr) \ + bl .._savefpr_26 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr7(Fsize,Gpr,Fpr) \ + bl .._savefpr_25 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr8(Fsize,Gpr,Fpr) \ + bl .._savefpr_24 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr9(Fsize,Gpr,Fpr) \ + bl .._savefpr_23 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr10(Fsize,Gpr,Fpr) \ + bl .._savefpr_22 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr11(Fsize,Gpr,Fpr) \ + bl .._savefpr_21 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr12(Fsize,Gpr,Fpr) \ + bl .._savefpr_20 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr13(Fsize,Gpr,Fpr) \ + bl .._savefpr_19 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr14(Fsize,Gpr,Fpr) \ + bl .._savefpr_18 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr15(Fsize,Gpr,Fpr) \ + bl .._savefpr_17 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr16(Fsize,Gpr,Fpr) \ + bl .._savefpr_16 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr17(Fsize,Gpr,Fpr) \ + bl .._savefpr_15 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) +#define __savefpr18(Fsize,Gpr,Fpr) \ + bl .._savefpr_14 ; \ + stwu r.sp,-(Fsize)(r.sp) ;\ + stw r.0,(Fsize)-(4*(Gpr+1)+(8 * Fpr))(r.sp) + + +// +// Restore the number of FPRs specified inline or by branching to the +// appropriate millicode procedure. +// +// Changed ba to b in __restfpr4-18 IBMCDB +#define __restfpr0 +#define __restfpr4 \ + b .._restfpr_28 +#define __restfpr5 \ + b .._restfpr_27 +#define __restfpr6 \ + b .._restfpr_26 +#define __restfpr7 \ + b .._restfpr_25 +#define __restfpr8 \ + b .._restfpr_24 +#define __restfpr9 \ + b .._restfpr_23 +#define __restfpr10 \ + b .._restfpr_22 +#define __restfpr11 \ + b .._restfpr_21 +#define __restfpr12 \ + b .._restfpr_20 +#define __restfpr13 \ + b .._restfpr_19 +#define __restfpr14 \ + b .._restfpr_18 +#define __restfpr15 \ + b .._restfpr_17 +#define __restfpr16 \ + b .._restfpr_16 +#define __restfpr17 \ + b .._restfpr_15 +#define __restfpr18 \ + b .._restfpr_14 + +#endif // _KXPPC_C_HEADER_ + + +//**************************************************************************/ +// +// PPC Linkage support macros +// +// +//**************************************************************************/ +// Caller's stack frame is addressed via R1, which points to +// the stack frame header. The 6 words following where R1 points +// comprise the header. The area PRECEEDING R1 is where FPRs are saved, +// and the area preceeding that is where GPRs are saved. +// +// | | +// +--------------------------------------+ +// | | +// | | +// | Saved GPRs | +// | | +// | | +// | | +// +--------------------------------------+ +// | | +// | | +// | Saved FPRs | +// | | +// | | +// | | +// R1 ------> +------------------+-------------------+ +// | Back chain | Glue saved reg | +// +------------------+-------------------+ +// | Glue saved rtoc | Reserved | +// +------------------+-------------------+ +// | Reserved | Reserved | +// +------------------+-------------------+ +// | Parameter Wd 0 | Parameter Wd 1 | +// +------------------+-------------------+ +// | Parameter Wd 2 | Parameter Wd 3 | +// +------------------+-------------------+ +// | Parameter Wd 4 | Parameter Wd 5 | +// +------------------+-------------------+ +// | Parameter Wd 6 | Parameter Wd 7 | +// +------------------+-------------------+ +// | ... | +// +// Offsets to various elements of stack frame header + +#define STK_RSP 0 +#define STK_GSR 4 +#define STK_GSRTOC 8 + +#define STK_HDR_SZ 24 +#define STK_P0 STK_HDR_SZ +#define STK_P1 (STK_P0+4) +#define STK_P2 (STK_P0+8) +#define STK_P3 (STK_P0+12) +#define STK_P4 (STK_P0+16) +#define STK_P5 (STK_P0+20) +#define STK_P6 (STK_P0+24) +#define STK_P7 (STK_P0+28) +#define STK_MIN_FRAME 56 + +#ifndef _KXPPC_C_HEADER_ + +// +// Define procedure entry/exit macros +// +// Name - Name of the nested procedure entry +// Fsize - Stack frame size +// Gprs - Number of general purpose registers to save +// Fprs - Number of floating point registers to save +// + +// +// For primary entry points (NESTED_ENTRY, LEAF_ENTRY), a function table +// entry (for debugging, exception handling) is built. +// +// For all entry points, a function descriptor is built. +// +// +// NESTED_ENTRY is used for routines that call other routines; a stack +// frame is acquired and registers are saved. +// +// LEAF_ENTRY is used for routines that do not call other routines; no stack +// frame is acquired and no registers are saved. +// +// +// NESTED_ENTRY_EX and LEAF_ENTRY_EX are used when an exception or termination +// handler is provided. +// +// +// NESTED_ENTRY always saves the LR register. Fsize must account for this. +// Fsize must be a multiple of 8 bytes. +// Minimum stack frame size is 64 bytes. +// +// +// The PROLOGUE_END macro must be coded in all routines that used NESTED_ENTRY +// or NESTED_ENTRY_EX, because the function table entry refers to the label +// that it generates. +// +// SPECIAL_ENTRY is a used for routines that function like a LEAF_ENTRY +// but require some prologue for exception handling. An example of this +// is a stack checking routine which must make a system call to get +// the TEB pointer. The efficiency of a LEAF_ENTRY is needed, but also +// parts of the NESTED_ENTRY are required for the system call. +// +// Just like the NESTED_ENTRY, SPECIAL_ENTRY requires the PROLOGUE_END +// macro. +// +// FN_TABLE, DUMMY_ENTRY, and DUMMY_EXIT are used to construct the "prologues" +// for low-level exception handling code. These prologues are never executed, +// but are present to allow unwinding through the hand-written low-level +// assembly code. See real0.s for examples. + +// +// The following macros are provided for coding by assembly language programmers +// + +#define NESTED_ENTRY(Name,Fsize,Gprs,Fprs) \ + __fntabentry(Name,0,0) ;\ + __gendescriptor(Name) ;\ + __begintext(Name) ;\ + mflr r.0 ;\ + __setGPRFrm##Fprs(Fsize,Gprs,Fprs) ;\ + __savefpr##Fprs(Fsize,Gprs,Fprs) + +#define NESTED_ENTRY_EX(Name,Fsize,Gprs,Fprs,LangHandler,Scope) \ + __fntabentry(Name,LangHandler,Scope) ;\ + __gendescriptor(Name) ;\ + __begintext(Name) ;\ + mflr r.0 ;\ + __setGPRFrm##Fprs(Fsize,Gprs,Fprs) ;\ + __savefpr##Fprs(Fsize,Gprs,Fprs) + +#define NESTED_ENTRY_S(Name,Fsize,Gprs,Fprs,Section) \ + __fntabentry(Name,0,0) ;\ + __gendescriptor(Name) ;\ + __begintext_S(Name,Section) ;\ + mflr r.0 ;\ + __setGPRFrm##Fprs(Fsize,Gprs,Fprs) ;\ + __savefpr##Fprs(Fsize,Gprs,Fprs) + +#define NESTED_ENTRY_EX_S(Name,Fsize,Gprs,Fprs,LangHandler,Scope,Section) \ + __fntabentry(Name,LangHandler,Scope) ;\ + __gendescriptor(Name) ;\ + __begintext_S(Name,Section) ;\ + mflr r.0 ;\ + __setGPRFrm##Fprs(Fsize,Gprs,Fprs) ;\ + __savefpr##Fprs(Fsize,Gprs,Fprs) + +#define NESTED_EXIT(Name,Fsize,Gprs,Fprs) \ +Name##.epi: \ + lwz r.0,((Fsize)-(4*(Gprs+1)+(8*Fprs)))(r.sp) ;\ + __unsetGPRFrm##Fprs(Fsize,Gprs,Fprs) ;\ +Name##.end: + +#define PROLOGUE_END(Name) \ +Name##.body: + +#define ALTERNATE_ENTRY(Name) \ + __gendescriptor(Name) ;\ + __begintext(Name) + +#define LEAF_ENTRY(Name) \ + __gendescriptor(Name) ;\ + __begintext(Name) ;\ +Name##.body: + +#define LEAF_ENTRY_EX(Name,LangHandler,Scope) \ + __gendescriptor(Name) ;\ + __begintext(Name) ;\ +Name##.body: + +#define SPECIAL_ENTRY(Name) \ + __fntabentry(Name,0,0) ;\ + __gendescriptor(Name) ;\ + __begintext(Name) + +#define DUMMY_ENTRY(Name) \ + __begintext(Name) + +#define ALTERNATE_ENTRY_S(Name,Section) \ + __gendescriptor(Name) ;\ + __begintext_S(Name,Section) + +#define LEAF_ENTRY_S(Name,Section) \ + __gendescriptor(Name) ;\ + __begintext_S(Name,Section) ;\ +Name##.body: + +#define LEAF_ENTRY_EX_S(Name,LangHandler,Scope,Section) \ + __gendescriptor(Name) ;\ + __begintext_S(Name,Section) ;\ +Name##.body: + +#define SPECIAL_ENTRY_S(Name,Section) \ + __fntabentry(Name,0,0) ;\ + __gendescriptor(Name) ;\ + __begintext_S(Name,Section) + +#define DUMMY_ENTRY_S(Name,Section) \ + __begintext_S(Name,Section) + +#define LEAF_EXIT(Name) \ + blr ;\ +Name##.end: + +#define ALTERNATE_EXIT(Name) \ + blr + +#define SPECIAL_EXIT(Name) \ + blr ;\ +Name##.end: + +#define DUMMY_EXIT(Name) \ +Name##.end: + +#define FN_TABLE(Name,ExHandler,Data) \ + __fntabentry(Name,ExHandler,Data) + +// +// Define special section "names" for use with the NESTED/LEAF_ENTRY_S +// macros. For the moment just define all possibilities as .text. +// + +#define _TEXT$normal .text +#define _TEXT$00 .text +#define _TEXT$01 .text + + +// +// Internal macros, used by the above (not for programmer use) +// + +#define __gendescriptor(Name) \ + .rdata ;\ + .align 2 ;\ + .globl Name ;\ +Name: ;\ + .long ..##Name, .toc + +#define __fntabentry(Name,ExHandler,Data) \ + .pdata ;\ + .align 2 ;\ + .long ..##Name ;\ + .long Name##.end ;\ + .long ExHandler ;\ + .long Data ;\ + .long Name##.body + +#define __begintext(Name) \ + .text ;\ + .align 2 ;\ + .globl ..##Name ;\ +..##Name: + +#define __begintext_S(Name,Section) \ + .section Section ;\ + .align 2 ;\ + .globl ..##Name ;\ +..##Name: + +// +// KIPCR(reg) +// +// Get address of KiPcr into reg +// + +#define KIPCR(reg) li reg, 0xffffd000 + + +// +// DISABLE_INTERRUPTS(p0,s0) +// +// Clear EXTERNAL INTERRUPT ENABLE bit in Machine State Register +// (bit MSR:EE). +// +// The cror instructions in these macros work around 603e/ev errata #15 +// by forcing the mtmsr to complete before allowing any subsequent loads +// to issue. The condition register no-op is executed in the system unit +// on the 603. This will not dispatch until the mtmsr completes and will +// halt further dispatch. On a 601 or 604 this instruction executes in +// the branch unit and will run in parallel (i.e., no performance penalty +// except for code bloat). +// +// Returns OLD value in p0 +// Destroys s0 (actually, s0 contains new value) + +#define DISABLE_INTERRUPTS(p0, s0) ; \ + mfmsr p0 ; \ + rlwinm s0,p0,0,~MASK_SPR(MSR_EE,1) ; \ + mtmsr s0 ; \ + cror 0,0,0 + +#define ENABLE_INTERRUPTS(p0) ; \ + mtmsr p0 ; \ + cror 0,0,0 + + +// +// RAISE_SOFTWARE_IRQL(p0, p1, s0) +// +// Raise Interrupt Request Level. +// Parameters +// p0 new irql +// p1 pointer to byte to receive old irql +// s0 scratch register (destroyed by this macro) +// +// LOWER_SOFTWARE_IRQL is done in a function rather than a macro. +// +// This macro should only be used to raise the IRQL if the interrupt +// mask does NOT need to be changed. +// + +#define RAISE_SOFTWARE_IRQL(p0, p1, s0) ;\ + lbz s0, KiPcr+PcCurrentIrql(r.0) ;\ + stb p0, KiPcr+PcCurrentIrql(r.0) ;\ + stb s0, 0(p1) + +// +// SOFTWARE_INTERRUPT(level, scratch) +// +// Set a flag indicating we need to process a software interrupt. +// This flag is checked when priority is lowered below dispatch level. +// +// Parameters +// level is the priority of the interrupt (either DISPATCH_LEVEL +// or APC_LEVEL). +// scratch is a register that will be destroyed by this macro. +// +// The flag is in fact a word in the PCR. There are only two levels of +// software interrupt and we need to be able to set either one atomically. +// To accomplish this we store into a different byte for either of the +// interrupts. To indicate an APC_LEVEL interrupt store a non-zero value +// at pcr->SoftwareInterrupt + 0, DISPATCH_LEVEL store at the same address +// + 1. +// + +#define SOFTWARE_INTERRUPT(level, scr) \ + li scr, 1 ;\ + stb scr, KiPcr+PcSoftwareInterrupt+(level)-APC_LEVEL(r.0) + +// +// ACQUIRE_SPIN_LOCK(_lock, _value, _scratch, _try, _spin) +// +// Acquire a spin lock. +// +// _lock is the register that holds the address of the spin lock. +// _value is the register that holds the value to be stored to the +// spin lock to lock it. +// _scratch is a scratch register. +// _try is a label to use in the generated code. +// _spin is the label at an out-of-line location where a +// SPIN_ON_SPIN_LOCK invocation occurs. +// + +#if !SPINDBG +#define ACQUIRE_SPIN_LOCK(_lock, _value, _scratch, _try, _spin) \ +_try: \ + lwarx _scratch, 0, _lock ;\ + cmpwi _scratch, 0 ;\ + bne- _spin ;\ + stwcx. _value, 0, _lock ;\ + bne- _spin ;\ + isync +#else +#define ACQUIRE_SPIN_LOCK(_lock, _value, _scratch, _try, _spin) \ + stw _lock,KiPcr+PcPcrPage2+8(0) ;\ + li _scratch,0 ;\ + stw _scratch,KiPcr+PcPcrPage2+16(0) ;\ +_try: \ + lwarx _scratch, 0, _lock ;\ + cmpwi _scratch, 0 ;\ + bne- _spin ;\ + stwcx. _value, 0, _lock ;\ + bne- _spin ;\ + isync ;\ + stw _lock,KiPcr+PcPcrPage2+16(0) ;\ + stw _scratch,KiPcr+PcPcrPage2+20(0) +#endif + +// +// SPIN_ON_SPIN_LOCK(_lock, _scratch, _try, _spin) +// +// Spin waiting for a spin lock to be released. +// +// _lock is the register that holds the address of the spin lock. +// _scratch is a scratch register. +// _try is the label on the associated ACQUIRE_SPIN_LOCK invocation. +// _spin is a label to use in the generated code. +// + +#if !SPINDBG +#define SPIN_ON_SPIN_LOCK(_lock, _scratch, _try, _spin) \ +_spin: \ + lwz _scratch, 0(_lock) ;\ + cmpwi _scratch, 0 ;\ + beq+ _try ;\ + b _spin +#else +#define SPIN_ON_SPIN_LOCK(_lock, _scratch, _try, _spin) \ +_spin: \ + stw _lock,KiPcr+PcPcrPage2+12(0) ;\ + lwz _scratch, 0(_lock) ;\ + cmpwi _scratch, 0 ;\ + bne- _spin ;\ + stw _lock,KiPcr+PcPcrPage2+24(0) ;\ + stw _scratch,KiPcr+PcPcrPage2+12(0) ;\ + b _try +#endif + +// +// SPIN_ON_SPIN_LOCK_ENABLED(_lock, _scratch, _try, _entry, _spin, _enable, _disable) +// +// Spin with interrupts enabled waiting for a spin lock to be released. +// +// _lock is the register that holds the address of the spin lock. +// _scratch is a scratch register. +// _try is the label on the associated ACQUIRE_SPIN_LOCK invocation. +// _entry is a label to use in the generated code. +// _spin is a label to use in the generated code. +// +// The cror instruction in this macro works around 603e/ev errata #15 +// by forcing the mtmsr to complete before allowing any subsequent loads +// to issue. The condition register no-op is executed in the system unit +// on the 603. This will not dispatch until the mtmsr completes and will +// halt further dispatch. On a 601 or 604 this instruction executes in +// the branch unit and will run in parallel (i.e., no performance penalty +// except for code bloat). +// + +#if !SPINDBG +#define SPIN_ON_SPIN_LOCK_ENABLED(_lock, _scratch, _try, _entry, _spin, _enable, _disable) \ +_entry: \ + ENABLE_INTERRUPTS(_enable) ;\ +_spin: \ + lwz _scratch, 0(_lock) ;\ + cmpwi _scratch, 0 ;\ + bne- _spin ;\ + mtmsr _disable ;\ + cror 0,0,0 ;\ + b _try +#else +#define SPIN_ON_SPIN_LOCK_ENABLED(_lock, _scratch, _try, _entry, _spin, _enable, _disable) \ +_entry: \ + ori _scratch,_lock,0 ;\ + ori _scratch,_scratch,1 ;\ + stw _scratch,KiPcr+PcPcrPage2+12(0) ;\ + ENABLE_INTERRUPTS(_enable) ;\ +_spin: \ + lwz _scratch, 0(_lock) ;\ + cmpwi _scratch, 0 ;\ + bne- _spin ;\ + ori _scratch,_lock,0 ;\ + ori _scratch,_scratch,1 ;\ + stw _scratch,KiPcr+PcPcrPage2+24(0) ;\ + li _scratch,0 ;\ + stw _scratch,KiPcr+PcPcrPage2+12(0) ;\ + mtmsr _disable ;\ + cror 0,0,0 ;\ + b _try +#endif + +// +// TRY_TO_ACQUIRE_SPIN_LOCK(_lock, _value, _scratch, _try, _fail) +// +// Try to acquire a spin lock. +// +// _lock is the register that holds the address of the spin lock. +// _value is the register that holds the value to be stored to the +// spin lock to lock it. +// _scratch is a scratch register. +// _try is a label to use in the generated code. +// fail_label is the label to jump to if the spin lock is already held. +// + +#if !SPINDBG +#define TRY_TO_ACQUIRE_SPIN_LOCK(_lock, _value, _scratch, _try, _fail) \ +_try: \ + lwarx _scratch, 0, _lock ;\ + cmpwi _scratch, 0 ;\ + bne- _fail ;\ + stwcx. _value, 0, _lock ;\ + bne- _try ;\ + isync +#else +#define TRY_TO_ACQUIRE_SPIN_LOCK(_lock, _value, _scratch, _try, _fail) \ + ori _scratch,_lock,0 ;\ + ori _scratch,_scratch,1 ;\ + stw _scratch,KiPcr+PcPcrPage2+8(0) ;\ + li _scratch,0 ;\ + stw _scratch,KiPcr+PcPcrPage2+16(0) ;\ +_try: \ + lwarx _scratch, 0, _lock ;\ + cmpwi _scratch, 0 ;\ + bne- _fail ;\ + stwcx. _value, 0, _lock ;\ + bne- _try ;\ + isync ;\ + ori _scratch,_lock,0 ;\ + ori _scratch,_scratch,1 ;\ + stw _scratch,KiPcr+PcPcrPage2+16(0) ;\ + li _scratch,0 ;\ + stw _scratch,KiPcr+PcPcrPage2+20(0) +#endif + +// +// RELEASE_SPIN_LOCK(_lock, _zero) +// +// Release a spin lock. +// +// _lock is the register that holds the address of the spin lock. +// _zero is a register that contains a 0. +// + +#if !SPINDBG +#define RELEASE_SPIN_LOCK(_lock, _zero) \ + eieio ;\ + stw _zero, 0(_lock) +#else +#define RELEASE_SPIN_LOCK(_lock, _zero) \ + stw _lock,KiPcr+PcPcrPage2+20(0) ;\ + eieio ;\ + stw _zero, 0(_lock) +#endif + +#endif // _KXPPC_C_HEADER_ + + +#ifndef _PPC601_ +#define _PPC601_ 601 +#endif +#define PPC60X _PPC601_ + +// +// Exception entry reasons. Passed to KiDispatchException from +// exception entry routines. +// +#define ppc_machine_check 1 +#define ppc_data_storage 2 +#define ppc_instruction_storage 3 +#define ppc_external 4 +#define ppc_alignment 5 +#define ppc_program 6 +#define ppc_fp_unavailable 7 +#define ppc_decrementer 8 +#define ppc_direct_store_error 9 +#define ppc_syscall 10 +#define ppc_trace 11 +#define ppc_fp_assist 12 +#define ppc_run_mode 13 +#define ppc_panic 256 + +#if !DBG_STORE + +#define DBGSTORE(reg,reg2,regv) +#define DBGSTORE_I(reg,reg2,val) +#define DBGSTORE_IRR(reg,reg2,val,regv2,regv3) +#define DBGSTORE_IRRR(reg,reg2,val,regv2,regv3,regv4) +#define DBGSTORE_I_R(reg,reg2,val) + +#else + +#define STORE_ADDR 0x3800 + +#if 1 +#define DCBST(reg) +#else +#define DCBST(reg) dcbst 0,reg +#endif + +#if 0 +#define DBGSTORE(reg,reg2,regv) +#else +#define DBGSTORE(reg,reg2,regv) \ + mfsprg reg,1; \ + lwz reg2,PcSpare+4(reg); \ + addi reg2,reg2,16; \ + clrlwi reg2,reg2,22; \ + stw reg2,PcSpare+4(reg); \ + lbz reg,PcNumber(reg); \ + slwi reg,reg,10; \ + add reg,reg,reg2; \ + addi reg,reg,STORE_ADDR; \ + oris reg,reg,0x8000; \ + stw regv,0(reg); \ + DCBST(reg) +#endif + +#if 0 +#define DBGSTORE_I(reg,reg2,val) +#else +#define DBGSTORE_I(reg,reg2,val) \ + mfsprg reg,1; \ + lwz reg2,PcSpare+4(reg); \ + addi reg2,reg2,16; \ + clrlwi reg2,reg2,22; \ + stw reg2,PcSpare+4(reg); \ + lbz reg,PcNumber(reg); \ + slwi reg,reg,10; \ + add reg,reg,reg2; \ + addi reg,reg,STORE_ADDR; \ + oris reg,reg,0x8000; \ + li reg2,val; \ + stw reg2,0(reg); \ + DCBST(reg) +#endif + +#if 0 +#define DBGSTORE_IRR(reg,reg2,val,regv2,regv3) +#else +#define DBGSTORE_IRR(reg,reg2,val,regv2,regv3) \ + .extern KeTickCount; \ + mfsprg reg,1; \ + lwz reg2,PcSpare+4(reg); \ + addi reg2,reg2,16; \ + clrlwi reg2,reg2,22; \ + stw reg2,PcSpare+4(reg); \ + lbz reg,PcNumber(reg); \ + slwi reg,reg,10; \ + add reg,reg,reg2; \ + addi reg,reg,STORE_ADDR; \ + oris reg,reg,0x8000; \ + li reg2,val; \ + stw reg2,0(reg); \ + stw regv2,4(reg); \ + stw regv3,8(reg); \ + lwz reg2,[toc]KeTickCount(r2); \ + lwz reg2,0(reg2); \ + stw reg2,0xc(reg); \ + DCBST(reg) +#endif + +#if 0 +#define DBGSTORE_IRRR(reg,reg2,val,regv2,regv3,regv4) +#else +#define DBGSTORE_IRRR(reg,reg2,val,regv2,regv3,regv4) \ + mfsprg reg,1; \ + lwz reg2,PcSpare+4(reg); \ + addi reg2,reg2,16; \ + clrlwi reg2,reg2,22; \ + stw reg2,PcSpare+4(reg); \ + lbz reg,PcNumber(reg); \ + slwi reg,reg,10; \ + add reg,reg,reg2; \ + addi reg,reg,STORE_ADDR; \ + oris reg,reg,0x8000; \ + li reg2,val; \ + stw reg2,0(reg); \ + stw regv2,4(reg); \ + stw regv3,8(reg); \ + stw regv4,0xc(reg); \ + DCBST(reg) +#endif + +#if 0 +#define DBGSTORE_I_R(reg,reg2,val) +#else +#define DBGSTORE_I_R(reg,reg2,val) \ + mfsprg reg,0; \ + lwz reg2,PcSpare+4(reg); \ + addi reg2,reg2,16; \ + clrlwi reg2,reg2,22; \ + stw reg2,PcSpare+4(reg); \ + lbz reg,PcNumber(reg); \ + slwi reg,reg,10; \ + add reg,reg,reg2; \ + addi reg,reg,STORE_ADDR; \ + li reg2,val; \ + stw reg2,0(reg); \ + DCBST(reg) +#endif + +#endif // DBG_STORE + +#if !SPINDBG + +#define CHKBRK(reg,label) +#define CHKLOCK(reg,regl,label) + +#else + +#if 1 +#define CHKBRK(reg,label) +#else +#define CHKBRK(reg,label) \ + mfsprg reg,1; \ + lwz reg,PcSpare+8(reg); \ + cmpwi reg,0; \ + beq label; \ + twi 31,0,0x16; \ +label: +#endif + +#if 1 +#define CHKLOCK(reg,regl,label) +#else +#define CHKLOCK(reg,regl,label) \ + .extern KiDispatcherLock; \ + lwz reg,[toc]KiDispatcherLock(r2); \ + cmpw reg,regl; \ + bne label +#endif + +#endif // SPINDBG + +#if !COLLECT_PAGING_DATA + +#define INC_CTR(ctr,rpcr,rscr) +#define INC_CTR2(ctr,rpcr,rscr) +#define INC_GRP_CTR_R(ctr,roff) +#define INC_GRP_CTR(ctr,roff,rscr1,rscr2) + +#else + +#define CTR_DTLB_MISS 0 +#define CTR_DTLB_MISS_VALID_PTE 4 +#define CTR_ITLB_MISS 8 +#define CTR_ITLB_MISS_VALID_PTE 12 +#define CTR_DSI 16 +#define CTR_DSI_HPT_MISS 20 +#define CTR_ISI 24 +#define CTR_ISI_HPT_MISS 28 +#define CTR_PCR 32 +#define CTR_PCR2 36 +#define CTR_STORAGE_ERROR 40 +#define CTR_PAGE_FAULT 44 +#define CTR_FLUSH_SINGLE 48 +#define CTR_FILL_ENTRY 52 +#define CTR_FLUSH_CURRENT 56 +#define PROC_CTR_SIZE 60 + +#define GRP_CTR_BASE PROC_CTR_SIZE + +#define GRP_CTR_DSI_VALID_PTE (GRP_CTR_BASE + 0) +#define GRP_CTR_DSI_FULL (GRP_CTR_BASE + 4) +#define GRP_CTR_DSI_FOUND (GRP_CTR_BASE + 8) +#define GRP_CTR_FLUSH_SINGLE (GRP_CTR_BASE + 12) +#define GRP_CTR_FLUSH_SINGLE_FOUND (GRP_CTR_BASE + 16) +#define GRP_CTR_FILL_ENTRY (GRP_CTR_BASE + 20) +#define GRP_CTR_FILL_ENTRY_FOUND (GRP_CTR_BASE + 24) +#define GRP_CTR_FILL_ENTRY_FULL (GRP_CTR_BASE + 28) +#define GRP_CTR_SIZE (GRP_CTR_BASE + 32) + +#define CTR_SIZE (PROC_CTR_SIZE + GRP_CTR_SIZE) + +#define PcSpare (PcPcrPage2+4) +#define PcR31 (PcSpare+4) +#define PcPagingData (PcSpare+8) + +#define INC_CTR(ctr,rpcr,rscr) \ + lwz rscr,PcPagingData+ctr(rpcr); \ + addi rscr,rscr,1; \ + stw rscr,PcPagingData+ctr(rpcr) + +#define INC_CTR2(ctr,rpcr,rscr) \ + mfsprg rpcr,1; \ + lwz rscr,PcPagingData+ctr(rpcr); \ + addi rscr,rscr,1; \ + stw rscr,PcPagingData+ctr(rpcr) + +#define INC_GRP_CTR_R(ctr,rgrp) \ + ori r0,r30,0; \ + mfsprg r30,0; \ + stw r31,PcR31(r30); \ + lwz r31,PcPagingData+ctr(r30); \ + addi r31,r31,1; \ + stw r31,PcPagingData+ctr(r30); \ + lwz r31,PcR31(r30); \ + ori r30,r0,0 + +#define INC_GRP_CTR(ctr,rgrp,rscr1,rscr2) \ + mfsprg rscr2,1; \ + lwz rscr1,PcPagingData+ctr(rscr2); \ + addi rscr1,rscr1,1; \ + stw rscr1,PcPagingData+ctr(rscr2) + +#endif // COLLECT_PAGING_DATA + +#endif // _KXPPC_ |