Changeset 8e0eb63 in mainline


Ignore:
Timestamp:
2006-03-15T18:01:43Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9e1c942
Parents:
2f7342d
Message:

Hopefully final version of interrupt handlers for amd64 and ia32.
amd64 has been especially tricky to debug.
Error code detection is now done in compile time.

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • arch/amd64/include/context_offset.h

    r2f7342d r8e0eb63  
    99#define OFFSET_R15 0x38
    1010#define OFFSET_IPL 0x40
    11 
    12 #define IOFFSET_RAX 0x0
    13 #define IOFFSET_RBX 0x8
    14 #define IOFFSET_RCX 0x10
    15 #define IOFFSET_RDX 0x18
    16 #define IOFFSET_RSI 0x20
    17 #define IOFFSET_RDI 0x28
    18 #define IOFFSET_R8 0x30
    19 #define IOFFSET_R9 0x38
    20 #define IOFFSET_R10 0x40
    21 #define IOFFSET_R11 0x48
    22 #define IOFFSET_R12 0x50
    23 #define IOFFSET_R13 0x58
    24 #define IOFFSET_R14 0x60
    25 #define IOFFSET_R15 0x68
    26 #define IOFFSET_RBP 0x70
    27 #define IREGISTER_SPACE 120
  • arch/amd64/include/interrupt.h

    r2f7342d r8e0eb63  
    7777        __u64 r14;
    7878        __u64 r15;
    79         /* These 2 items MUST be last parts of the structure */
    8079        __u64 rbp;
    81         __u64 stack[0]; /* Additional data on stack */
    82 } __attribute__ ((packed));
     80        __u64 error_word;
     81        __u64 rip;
     82        __u64 cs;
     83        __u64 rflags;
     84        __u64 stack[]; /* Additional data on stack */
     85};
    8386
    8487extern void (* disable_irqs_function)(__u16 irqmask);
  • arch/amd64/src/asm_utils.S

    r2f7342d r8e0eb63  
    2727#
    2828
     29#define IREGISTER_SPACE 120
     30
     31#define IOFFSET_RAX 0x0
     32#define IOFFSET_RBX 0x8
     33#define IOFFSET_RCX 0x10
     34#define IOFFSET_RDX 0x18
     35#define IOFFSET_RSI 0x20
     36#define IOFFSET_RDI 0x28
     37#define IOFFSET_R8 0x30
     38#define IOFFSET_R9 0x38
     39#define IOFFSET_R10 0x40
     40#define IOFFSET_R11 0x48
     41#define IOFFSET_R12 0x50
     42#define IOFFSET_R13 0x58
     43#define IOFFSET_R14 0x60
     44#define IOFFSET_R15 0x68
     45#define IOFFSET_RBP 0x70
    2946
    3047#  Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
    3148# and 1 means interrupt with error word
    32 
    33        
    3449#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
    3550
    3651#include <arch/pm.h>
    37 #include <arch/context_offset.h>
    3852#include <arch/mm/page.h>
    3953       
     
    142156        movq IOFFSET_R15(%rsp), %r15
    143157.endm
    144        
     158
    145159## Declare interrupt handlers
    146160#
     
    148162# vectors starting at vector i.
    149163#
    150 # The handlers setup data segment registers
    151 # and call exc_dispatch().
     164# The handlers call exc_dispatch().
    152165#
    153166.macro handler i n
    154         subq $IREGISTER_SPACE, %rsp
     167
     168        /*
     169         * Choose between version with error code and version without error code.
     170         * Both versions have to be of the same size. amd64 assembly is, however,
     171         * a little bit tricky. For instance, subq $0x80, %rsp and subq $0x78, %rsp
     172         * can result in two instructions with different op-code lengths.
     173         * Therefore, pay special attention to the extra NOP's that serve as
     174         * a necessary fill.
     175         */
     176
     177        .iflt \i-32
     178                .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
     179                        /*
     180                         * Version with error word.
     181                         */
     182                        subq $IREGISTER_SPACE, %rsp
     183                        nop
     184                        nop
     185                        nop
     186                .else
     187                        /*
     188                         * Version without error word,
     189                         */
     190                        subq $(IREGISTER_SPACE+8), %rsp
     191                .endif
     192        .else
     193                /*
     194                 * Version without error word,
     195                 */
     196                subq $(IREGISTER_SPACE+8), %rsp
     197        .endif 
     198
    155199        save_all_gpr
    156200
    157         movq $(\i),%rdi   # %rdi - first parameter
    158         movq %rsp, %rsi   # %rsi - pointer to interrupt_context
    159         call exc_dispatch       # exc_dispatch(i, stack)
    160 
    161 # Test if this is interrupt with error word or not
    162         mov $\i,%cl;
    163         movl $1,%eax;
    164         test $0xe0,%cl;
    165         jnz 0f;
    166         and $0x1f,%cl;
    167         shl %cl,%eax;
    168         and $ERROR_WORD_INTERRUPT_LIST,%eax;
    169         jz 0f;
    170 
    171 
    172 # Return with error word
     201        movq $(\i), %rdi        # %rdi - first parameter
     202        movq %rsp, %rsi         # %rsi - pointer to istate
     203        call exc_dispatch       # exc_dispatch(i, istate)
     204       
    173205        restore_all_gpr
    174206        # $8 = Skip error word
    175         addq $IREGISTER_SPACE + 0x8, %rsp
    176         iretq
    177 
    178 0:
    179 # Return with no error word
    180         restore_all_gpr
    181         addq $IREGISTER_SPACE, %rsp
     207        addq $(IREGISTER_SPACE+8), %rsp
    182208        iretq
    183209
  • arch/amd64/src/interrupt.c

    r2f7342d r8e0eb63  
    4848        __u64 *x = &istate->stack[0];
    4949
    50         if (!(symbol=get_symtab_entry(x[1])))
     50        if (!(symbol=get_symtab_entry(istate->rip)))
    5151                symbol = "";
    5252
    53         printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n",n,__FUNCTION__);
    54         printf("%%rip: %Q (%s)\n",istate->stack[1],symbol);
    55         printf("ERROR_WORD=%Q\n", istate->stack[0]);
    56         printf("%%rcs=%Q,flags=%Q, %%cr0=%Q\n", istate->stack[2],
    57                istate->stack[3],read_cr0());
     53        printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n",n, __FUNCTION__);
     54        printf("%%rip: %Q (%s)\n",istate->rip, symbol);
     55        printf("ERROR_WORD=%Q\n", istate->error_word);
     56        printf("%%rcs=%Q, flags=%Q, %%cr0=%Q\n", istate->cs, istate->rflags,read_cr0());
    5857        printf("%%rax=%Q, %%rbx=%Q, %%rcx=%Q\n",istate->rax,istate->rbx,istate->rcx);
    5958        printf("%%rdx=%Q, %%rsi=%Q, %%rdi=%Q\n",istate->rdx,istate->rsi,istate->rdi);
     
    7877void null_interrupt(int n, istate_t *istate)
    7978{
    80         printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n",n,__FUNCTION__); \
    81         printf("stack: %X, %X, %X, %X\n", istate->stack[0], istate->stack[1],
    82                istate->stack[2], istate->stack[3]);
     79        print_info_errcode(n, istate);
    8380        panic("unserviced interrupt\n");
    8481}
  • arch/ia32/src/asm.S

    r2f7342d r8e0eb63  
    7979#
    8080.macro handler i n
    81         push %eax
    8281
    8382        /*
    84          * Test if this is interrupt with error word or not.
    85          * Be careful about width of the shift.
     83         * This macro distinguishes between two versions of ia32 exceptions.
     84         * One version has error word and the other does not have it.
     85         * The latter version fakes the error word on the stack so that the
     86         * handlers and istate_t can be the same for both types.
    8687         */
     88
    8789        .iflt \i-32
    88                 movl $(1<<\i), %eax
    89         .else
    90                 movl $0, %eax
    91         .endif
    92         andl $ERROR_WORD_INTERRUPT_LIST, %eax
    93         movl (%esp), %eax
     90                .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
     91                        /*
     92                         * Version with error word.
     93                         * Just take space equal to subl $4, %esp.
     94                         */
     95                        nop
     96                        nop
     97                        nop
     98                .else
     99                        /*
     100                         * Version without error word,
     101                         */
     102                        subl $4, %esp
     103                .endif
     104        .else
     105                /*
     106                 * Version without error word,
     107                 */
     108                subl $4, %esp
     109        .endif
    94110
    95         /*
    96          * If this interrupt/exception stores error word,
    97          * we need to pop EAX.
    98          * If this interrupt doesn't store error word, we emulate it
    99          * for the sake of consistent istate structure. In that case
    100          * we merely leave the EAX on the stack.
    101          */
    102         jz 0f
    103 
    104         /*
    105          * This exception stores error word.
    106          * Remove EAX from the stack.
    107          */
    108         addl $4, %esp
    109 
    110 0:
    111111        pusha
    112112        movl %esp, %ebp
     
    139139       
    140140        popa
    141         addl $4,%esp    # Skip error word, whether real or fake.
     141        addl $4,%esp    # Skip error word, no matter whether real or fake.
    142142        iret
    143143
  • tools/amd64/gencontext.c

    r2f7342d r8e0eb63  
    3838        fprintf(f,"#define OFFSET_IPL 0x%x\n", ((int) &pctx->ipl) - (int) pctx);
    3939
    40         fprintf(f, "\n");
    41 
    42 #define ifpr(big, nm) fprintf(f, "#define IOFFSET_" #big " 0x%x\n", ((int) &ipctx->nm) - (int) ipctx)
    43        
    44         ifpr(RAX, rax);
    45         ifpr(RBX, rbx);
    46         ifpr(RCX, rcx);
    47         ifpr(RDX, rdx);
    48         ifpr(RSI, rsi);
    49         ifpr(RDI, rdi);
    50         ifpr(R8, r8);
    51         ifpr(R9, r9);
    52         ifpr(R10, r10);
    53         ifpr(R11, r11);
    54         ifpr(R12, r12);
    55         ifpr(R13, r13);
    56         ifpr(R14, r14);
    57         ifpr(R15, r15);
    58         ifpr(RBP, rbp);
    59 
    60         fprintf(f, "#define IREGISTER_SPACE %d\n", sizeof(ictx));
    61 
    6240        fclose(f);
    6341
Note: See TracChangeset for help on using the changeset viewer.