Ignore:
Timestamp:
May 24, 2010, 7:49:19 PM (9 years ago)
Author:
gb
Message:

Get the kernel to compile/link/run on ARM Linux; remove some PPC-isms and
add some ARM-isms, though there's likely more of the latter to be done
to support exceptions/GC.

Raise subprim addresses to start at #x9000, since some distributions
set vm.mmap_min_addr to #x8000 and others act as if they do. This means
that some subprims (whose addresses are above #x10000) will be spaced 1K
apart; maybe not so bad for keyword handling/FFI/some other things.

Re-partition UUOs, so that those that require direct action from a kernel
handler are easier to distinguish from lisp-level errors.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/arm/lisp-kernel/arm-exceptions.h

    r13716 r13737  
    11/*
    2    Copyright (C) 2009 Clozure Associates
    3    Copyright (C) 1994-2001 Digitool, Inc
     2   Copyright (C) 2010 Clozure Associates
    43   This file is part of Clozure CL. 
    54
     
    1514   http://opensource.franz.com/preamble.html
    1615*/
    17 #define UUO_MASK 0xfc00000f
     16#define UUO_MASK 0x0ff000f0
    1817
    19 #define IS_UUO(i) (((i) & UUO_MASK) == 0xb)
    20 /* If an instruction is a UUO, the minor opcode is in bits 21:27 */
    21 #define UUO_MINOR(u) (((u) >> 4) & 0x7f)
     18#define IS_UUO(i) (((i) & UUO_MASK) == 0x07f000f0)
     19/* If an instruction is a UUO its format is determined by the low 4 bits */
     20#define UUO_FORMAT(i) ((i)&0xf)
     21
     22#define UUO_UNARY_field(uuo) (((uuo)>>12)&0xff)
     23#define UUOA_field(uuo)      (((uuo)>>8) &0x0f)
     24
     25#define uuo_format_nullary          0 /* 12 bits of code */
     26#define uuo_format_unary            1 /* 8 bits of info - NOT type info - 4-bit reg */
     27#define uuo_format_error_lisptag    2 /* 2 bits of lisptag info, 4-bit reg */
     28#define uuo_format_error_fulltag    3 /* 3 bits of fulltag info, 4 bit reg */
     29
     30#define uuo_format_error_xtype      4 /* 8 bits of extended type/subtag info, 4 bit reg */
     31#define uuo_format_binary           7 /* 4 bits of code, r1, r0 */
     32#define uuo_format_nullary_error    8 /* nullary, call out to lisp */
     33#define uuo_format_unary_error      9 /* like unary, but call out to lisp */
     34#define uuo_format_cerror_lisptag  10 /* continuable, lisptag, reg */
     35#define uuo_format_cerror_fulltag  11 /* continuable, fulltag, reg */
     36#define uuo_format_cerror_xtype    12 /* continuable, xtype, reg */ 
     37#define uuo_format_kernel_service  13 /* 8 bits of info */     
     38#define uuo_format_binary_error    15 /* binary format, call out to lisp */
     39
     40
     41
    2242
    2343typedef u_int32_t opcode, *pc;
    2444
    2545OSStatus
    26 handle_uuo(ExceptionInformation *, opcode, pc);
     46handle_uuo(ExceptionInformation *, opcode);
    2747
    2848
    2949
    30 /*
    31   Unconditional traps (tw, twi instructions) are used by the
    32   operating system.  We use conditional traps.
    33   */
    34 
    3550int
    36 is_conditional_trap(opcode);
    37 
    38 #define kNameBufLen 256
    39 #define TRAP_LOOKUP_TRIES 5   /* # instrs to scan before trap instr */
    40 
    41 void
    42 callback_for_trap (LispObj, ExceptionInformation *, pc, natural, natural, natural);
     51callback_for_trap (LispObj, ExceptionInformation *, natural, natural);
    4352
    4453natural
    4554register_codevector_contains_pc (natural, pc);
    4655
    47 void
    48 callback_to_lisp (LispObj, ExceptionInformation *, natural, natural, natural, natural, natural);
     56int
     57callback_to_lisp (LispObj, ExceptionInformation *, natural, natural);
    4958
    5059OSStatus
    5160handle_trap(ExceptionInformation *, opcode, pc, siginfo_t *);
    5261
    53 unsigned
    54 scan_for_instr( unsigned, unsigned, pc );
     62
     63/* */
     64
     65#define RN_field(i) (((i)>>16)&0xf)
     66#define RD_field(i) (((i)>>12)&0xf)
     67#define RM_field(i) ((i)&0xf)
     68
     69#define IS_SUB_RM_FROM_ALLOCPTR(i)   (((i)&0x0ffff000) == 0x004cc000)
     70#define IS_SUB_FROM_ALLOCPTR(i)      (((i)&0x0fffff00) == 0x024cc000)
     71#define IS_SUB_LO_FROM_ALLOCPTR(i)   (((i)&0x0fffff00) == 0x024cc000)
     72#define IS_SUB_HI_FROM_ALLOCPTR(i)   (IS_SUB_FROM_ALLOCPTR(i) && \
     73                                     !(IS_SUB_LOW_FROM_ALLOCPTR(i)))
     74#define IS_LOAD_RD_FROM_ALLOCBASE(i) (((i)&0x0fff0fff) == \
     75                                      ( 0x05930000 | offsetof(tcr,allocbase)))
     76#define IS_COMPARE_ALLOCPTR_TO_RM(i) (((i)&0x0fffff0) == 0x0140c000)
     77#define IS_ALLOC_TRAP(i) (((i)&0x0fffffff) == 0x07f000f0)
     78#define IS_SET_ALLOCPTR_HEADER_RD(i) (((i)&0x0fff0fff) == \
     79                                      (0x050c0000 | (- misc_header_offset)))
     80/* The 1 here - and the 3 in the following definition - are based on
     81   the tagged offsets of cars and cdrs.  Fix these definitions of that ever
     82   changes ... */
     83#define IS_SET_ALLOCPTR_CDR_RD(i)    (((i)&0x0fff0fff) == 0x050c0001)
     84#define IS_SET_ALLOCPTR_CAR_RD(i)    (((i)&0x0fff0fff) == 0x058c0003)
     85#define IS_SET_ALLOCPTR_RESULT_RD(i) (((i)&0x0fff0fff) == 0x01a0000c)
     86#define IS_CLR_ALLOCPTR_TAG(i)       (((i)&0x0fffffff) == 0x03ccc007)
    5587
    5688
    57 
    58 #define UUO_INTERR (11)
    59 #define UUO_INTCERR (12)
    60 #define UUO_INTERR2 (13)
    61 #define UUO_INTCERR2 (14)
    62 
    63 #define UUO_FPUX_BINOP (22)
    64 #define UUO_ZERO_FPSCR (25)
     89#define IS_GC_TRAP(i)                (((i)*0x0fffffff) == 0x07f001f0)
     90#define IS_DEBUG_TRAP(i)             (((i)*0x0fffffff) == 0x07f002f0)
     91#define IS_DEFERRED_INTERRUPT(i)     (((i)*0x0fffffff) == 0x07f004f0)
     92#define IS_DEFERRED_SUSPEND(i)       (((i)*0x0fffffff) == 0x07f005f0)
    6593
    6694
    67 /* PPC instructions */
    68 #define match_instr(instr, mask, target)   (((instr) & (mask)) == (target))
    69 #define RS_field(instr)  (((instr) >> 21) & 0x1f)
    70 #define RT_field(instr)  (RS_field(instr))
    71 #define TO_field(instr)  (RT_field(instr))
    72 #define RA_field(instr)  (((instr) >> 16) & 0x1f)
    73 #define RB_field(instr)  (((instr) >> 11) & 0x1f)
    74 #define D_field(instr)   ((instr) & 0xffff)
    75 #define DS_field(instr)  ((instr) & 0xfffc)
    76 #define DS_VARIANT_FIELD(instr) ((instr) & 3)
    77 
    78 #define RT(val) ((val & 0x1f) << 21)
    79 #define RS(val) (RT(val))
    80 #define RA(val) ((val & 0x1f) << 16)
    81 #define RB(val) ((val & 0x1f) << 11)
    82 #define D(val) (val & 0xffff)
    83 
    84 #define RS_MASK RS(-1)
    85 #define RT_MASK RS_MASK
    86 #define TO_MASK RS_MASK
    87 #define RA_MASK RA(-1)
    88 #define RB_MASK RB(-1)
    89 #define D_MASK  D(-1)
    90 
    91 
    92 
    93 #define OP(x) (((x) & 0x3f) << 26)
    94 #define OP_MASK OP (0x3f)
    95 
    96 /* Main opcode + TO field of a D form instruction */
    97 #define OPTO(x,to) (OP(x) | (((to) & 0x1f) << 21))
    98 #define OPTO_MASK (OP_MASK | TO_MASK)
    99 #define OPTORA(x,to,ra) (OPTO(x,to) | RA(ra))
    100 #define OPTORA_MASK (OP_TO_MASK | RA_MASK)
    101 
    102 
    103 
    104 
    105 /* An X form instruction.  */
    106 #define X(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
    107 
    108 /* An X form instruction with the RC bit specified.  */
    109 #define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1))
    110 
    111 /* The mask for an X form instruction.  */
    112 #define X_MASK XRC(0x3f, 0x3ff, 1)
    113 
    114 /* An XO form instruction */
    115 #define XO(op, xop, oe, rc) \
    116   (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1) | ((((unsigned long)(oe)) & 1) << 10) | (((unsigned long)(rc)) & 1))
    117 #define XO_MASK XO (0x3f, 0x1ff, 1, 1)
    118 
    119 
    120 
    121 /* The bits in the TO field of a TW or TWI instruction */
    122 #define TO_LT (1<<4)            /* signed < */
    123 #define TO_GT (1<<3)            /* signed > */
    124 #define TO_EQ (1<<2)            /* = */
    125 #define TO_LO (1<<1)            /* unsigned < */
    126 #define TO_HI (1<<0)            /* unsigned > */
    127 #define TO_NE (TO_LT|TO_GT)
    128 
    129 /* True if major opcode of "instr" is "op" */
    130 #define major_opcode_p(instr, op) match_instr((instr),OP_MASK,OP(op))
    131 
    132 /* True if "instr" is an X form instruction with major opcode "major"
    133    and minor opcode "minor" */
    134 #define X_opcode_p(instr,major,minor) match_instr((instr),X_MASK,X(major,minor))
    135 
    136 #define major_opcode_TDI 2
    137 #define major_opcode_TWI 3
    138 #ifdef PPC64
    139 #define major_opcode_TRI major_opcode_TDI
    140 #else
    141 #define major_opcode_TRI major_opcode_TWI
    142 #endif
    143 #define major_opcode_ADDI 14
    144 #define major_opcode_RLWINM 21
    145 #define major_opcode_X31 31             /* an "X" form instruction; see minor opcode */
    146 #define major_opcode_LWZ 32
    147 #define major_opcode_LBZ 34
    148 #define major_opcode_STW 36
    149 #define major_opcode_STWU 37
    150 #define major_opcode_LD_LDU_LWA 58
    151 #define major_opcode_FPU_SINGLE 59
    152 #define major_opcode_FPU_DOUBLE 63
    153 
    154 #define minor_opcode_TW 4
    155 #define minor_opcode_TD 68
    156 #ifdef PPC64
    157 #define minor_opcode_TR minor_opcode_TD
    158 #else
    159 #define minor_opcode_TR minor_opcode_TW
    160 #endif
    161 #define minor_opcode_SUBF 40
    162 #define minor_opcode_STWX 151
    163 #define minor_opcode_STWUX 183
    164 
    165 #define major_opcode_DS_LOAD64 58
    166 #define DS_LOAD64_VARIANT_LD 0
    167 
    168 #define major_opcode_DS_STORE64 62
    169 #define DS_STORE64_VARIANT_STD 0
    170 
    171 
    172 
    173 #define D_instruction(major,rt,ra,imm) (OP(major)|((rt)<<21)|((ra)<<16)|((imm)&D_MASK))
    174 #define DS_instruction(major,rt,ra,imm,minor) (OP(major)|((rt)<<21)|((ra)<<16)|(((imm)&D_MASK)&~3)|((minor)&3))
    175 #define TRI_instruction(rt,ra,imm)     D_instruction(major_opcode_TRI,rt,ra,imm)
    176 #define LBZ_instruction(rt,ra,imm)     D_instruction(major_opcode_LBZ,rt,ra,imm)
    177 #define LWZ_instruction(rt,ra,imm)     D_instruction(major_opcode_LWZ,rt,ra,imm)
    178 #define LD_instruction(rt,ra,imm)      DS_instruction(58,rt,ra,imm,0)
    179 
    180 #define D_RT_IMM_MASK                  (OP_MASK|RT_MASK|D_MASK)
    181 #define D_RA_IMM_MASK                  (OP_MASK|RA_MASK|D_MASK)
    182 
    183 #define X_instruction(major,minor,rt,ra,rb) (X(major,minor)|((rt)<<21)|((ra)<<16)|((rb)<<11))
    184 
    185 #define unmasked_register              0
    186 
    187 #define LISP_BREAK_INSTRUCTION 0x7f810808
    188 #define QUIET_LISP_BREAK_INSTRUCTION 0x7c800008
    189 
    190 #ifdef PPC64
    191 /* Have to use signed comparisons on PPC64; if we decrememt
    192    allocptr and it "wraps around" address 0, that's an
    193    attempt to allocate a large object.  Note that this
    194    means that valid heap addresses can't have the high
    195    bit set. */
    196 /* tdlt allocptr,allocbase */
    197 #define ALLOC_TRAP_INSTRUCTION 0x7e095088
    198 #else
    199 /* On PPC32, we can use an unsigned comparison, as long
    200    as  HEAP_IMAGE_BASE+PURESPACE_RESERVE is greater than
    201    the maximum possible allocation (around 27 bits).
    202    Decrementing allocptr may cause it to wrap around
    203    #x80000000, but it should never wrap around 0. */
    204 /* twllt allocptr,allocbase */
    205 #define ALLOC_TRAP_INSTRUCTION 0x7c495008
    206 #endif
    207 
    208 #ifdef PPC64
    209 /* tdlgei allocptr,0 */
    210 #define GC_TRAP_INSTRUCTION 0x08a90000
    211 #else
    212 /* twlgei allocptr,0 */
    213 #define GC_TRAP_INSTRUCTION 0x0ca90000
    214 #endif
    215 
    216 #ifdef PPC64
    217 /* clrrdi allocptr,allocptr,4 */
    218 #define UNTAG_ALLOCPTR_INSTRUCTION 0x792906e4
    219 #else
    220 /* clrrwi allocptr,allocptr,3 */
    221 #define UNTAG_ALLOCPTR_INSTRUCTION 0x55290038
    222 #endif
    223 
    224 #ifdef PPC64
    225 /* std rX,misc_header_offset(allocptr) */
    226 #define STORE_HEADER_ALLOCPTR_INSTRUCTION 0xf809fff4
    227 #else
    228 /* stw rX,misc_header_offset(allocptr) */
    229 #define STORE_HEADER_ALLOCPTR_INSTRUCTION 0x9009fffa
    230 #endif
    231 #define STORE_HEADER_ALLOCPTR_MASK D_RA_IMM_MASK
    232 
    233 #ifdef PPC64
    234 /* std rX,cons.cXr(allocptr) */
    235 #define STORE_CAR_ALLOCPTR_INSTRUCTION 0xf8090004
    236 #define STORE_CDR_ALLOCPTR_INSTRUCTION 0xf809fffc
    237 #else
    238 /* stw rX,cons.cXr(allocptr) */
    239 #define STORE_CAR_ALLOCPTR_INSTRUCTION 0x90090003
    240 #define STORE_CDR_ALLOCPTR_INSTRUCTION 0x9009ffff
    241 #endif
    242 #define STORE_CXR_ALLOCPTR_MASK D_RA_IMM_MASK
    243 
    244 
    245 #ifdef PPC64
    246 /* stdu sp,-32(sp) */
    247 #define CREATE_LISP_FRAME_INSTRUCTION 0xf821ffe1
    248 #else
    249 /* stwu sp,-16(sp) */
    250 #define CREATE_LISP_FRAME_INSTRUCTION 0x9421fff0
    251 #endif
    252 
    253 #ifdef PPC64
    254 /* std tsp,tsp_frame.type(tsp) */
    255 #define MARK_TSP_FRAME_INSTRUCTION 0xf98c0008
    256 #else
    257 /* stw tsp,tsp_frame.type(tsp) */
    258 #define MARK_TSP_FRAME_INSTRUCTION 0x918c0004
    259 #endif
    260 
    261 #ifdef PPC64
    262 #define INIT_CATCH_FRAME_INSTRUCTION (0xf8000000 | RA(nargs))
    263 #define INIT_CATCH_FRAME_MASK (OP_MASK | RA_MASK)
    264 #else
    265 #define INIT_CATCH_FRAME_INSTRUCTION (0x90000000 | RA(nargs))
    266 #define INIT_CATCH_FRAME_MASK (OP_MASK | RA_MASK)
    267 #endif
    268 
    26995OSStatus
    270 handle_error(ExceptionInformation *, unsigned, unsigned, unsigned, pc);
     96handle_error(ExceptionInformation *, unsigned, unsigned);
    27197
    27298typedef char* vector_buf;
     
    286112#endif
    287113
    288 /* Yet another way to look at a branch instruction ... */
    289 typedef union {
    290   struct {unsigned op:6, li:24, aa:1, lk:1;} b;
    291   unsigned opcode;
    292 } branch_instruction;
    293 
    294 
    295 
    296   /* Enable exceptions (at least, enable another thread's attempts to
    297      suspend this one) by restoring the signal mask.
    298   */
    299 
    300114
    301115
     
    308122
    309123
    310 #ifdef LINUX
    311 register void *current_r2 __asm__("r2");
    312 #endif
    313124
    314125Boolean
    315 extend_tcr_tlb(TCR *, ExceptionInformation *, unsigned, unsigned);
     126extend_tcr_tlb(TCR *, ExceptionInformation *, unsigned);
    316127
    317128void
    318129pc_luser_xp(ExceptionInformation *, TCR *, signed_natural *);
    319130
     131#define codevec_hdr_p(value) ((value) == 0)
    320132
    321 #ifdef PPC64
    322 #define codevec_hdr_p(value) ((value) == (('C'<<24)|('O'<<16)|('D'<<8)|'E'))
     133#ifdef __GNUC__
     134static __inline__ natural
     135ror(natural val, natural count) __attribute__((always_inline));
     136
     137static __inline__ natural
     138ror(natural val,natural count)
     139{
     140  natural result;
     141  __asm__ __volatile__("ror %[result],%[val],%[count]"
     142                       :[result] "=r" (result)
     143                       :[val] "r" (val),
     144                        [count] "r" (count));
     145  return result;
     146}
    323147#else
    324 /* top 6 bits will be zero, subtag will be subtag_code_vector */
    325 #define CV_HDR_MASK     (OP_MASK | subtagmask)
    326 #define CV_HDR_VALUE    subtag_code_vector
    327 #define codevec_hdr_p(value)    (((value) & CV_HDR_MASK) == CV_HDR_VALUE)
     148extern natural ror(natural, natural);
    328149#endif
    329 
    330 
Note: See TracChangeset for help on using the changeset viewer.