Help in Setting Up Working Interrupts 
Author Message
 Help in Setting Up Working Interrupts

Hi!
I'm a P-Mode newbie facing a problem with my interrupts.
I have loaded my IDT with descriptors of the following nature:

interrupt STRUC
 entrypoint0 dw ? ; entry point 15:0
 gdtselector dw ? ; selector
 wordcount   db ? ; word count
 inttype     db ? ; type (32-bit Ring 0 interrupt gate)
 entrypoint1 dw ? ; entry point 31:16
interrupt ENDS

Each interrupt gate entry has the following format

 INT20 interrupt <ISR20, SCODESEL, 0, 8Eh ,0>

Defined for interrupts 00h through to 20h.
ISR20 represents the offset of the (20h) interrupt handler within the code
segment whose selector is SCODESEL.

SCODESEL represents the selector of the relevant code segment in the GDT
that has already been set up. The code segment has been defined with a limit
of fffffh, byte 6 has 9A (exe/read-only ring0 present) and byte 7 as  CF
(32-bit, page granular).

All interrupts have been disabled prior to entering p-mode and all the code,
stack and data segments are at ring0.

When int 20h is issued control is transferred to the correct interrupt
handler (so the IDTR must have been set up correctly). However when it comes
to issuing the IRET interrupt 13h (General protection fault) is raised.

If I don't generate the software interrupt 20h the program proceeds to
completion as normal (so it must be safe to assume that the code segment
itself and hence the GDT has been set up correctly).

What could possibly be the problem??
I squeezed in the (TASM) code below for anyone who wanted to take a closer
look.
Thanks for your time.

..MODEL SMALL
..386P

;---------------------------------------------------------------
; Structure definitions
;---------------------------------------------------------------

descriptor STRUC
   seglimit    dw ? ; Segment limit
   segbase0    dw ? ; BITS 00..15 of base addr
   segbase1    db ? ; BITS 16..A23 of base addr
   access      db ? ; Segment access rights
   granularity db ? ; Granularity, Op-size, Limit A16..A19
   segbase2    db ? ; A24..A31 of base addr
descriptor ENDS

interrupt STRUC
 entrypoint0 dw ? ; entry point 15:0
 gdtselector dw ? ; selector
 wordcount   db ? ; word count
 inttype     db ? ; type (32-bit Ring 0 interrupt gate)
 entrypoint1 dw ? ; entry point 31:16
interrupt ENDS

CS_access equ 9ah       ; EXE/READ-only access
DS_access equ 92h       ; R/W Data segment
PG_32     equ 0cfh      ; Page granular 32 bit
IGATE_0_32 equ 8eh ;interrupt gate at ring 0 32-bit

CODE16 SEGMENT PARA 'CODE' USE16
ASSUME CS:CODE16, DS:DAT, ES:DAT, SS:STCK

BEGIN PROC NEAR

;INTIALIZING THE DS AND ES REGISTERS TO POINT TO DATA SEGMENT
  mov   eax, DAT
  mov   ds, ax
  mov   es, ax

;MAKE DATA SEGMENT ADDRESS LINEAR
  shl   eax, 4
  mov   ebx, eax

;SET THE REAL AND SYSTEM DATA DESCRIPTORS (BOTH REFER TO THE SAME LOCATION)
  mov   RDATA.segbase0, ax
  mov   SDATA.segbase0, ax
  shr   eax,16
  mov   RDATA.segbase1, al
  mov   SDATA.segbase1, al
  mov   RDATA.segbase2, ah
  mov   SDATA.segbase2, ah

;SET THE REAL 16 BIT CODE DESCRIPTOR
  mov   eax, CODE16
  shl   eax, 4
  mov   RCODE.segbase0, ax
  shr   eax,16
  mov   RCODE.segbase1, al
  mov   RCODE.segbase2, ah

;SET THE REAL MODE 16 BIT STACK DESCRIPTOR
  mov   eax, STCK
  shl   eax, 4
  mov   RSTCK.segbase0, ax
  shr   eax,16
  mov   RSTCK.segbase1, al
  mov   RSTCK.segbase2, ah

;SET THE SYSTEM CODE GDT DESRIPTOR
  mov   eax, CODE32
  shl   eax, 4
  mov   SCODE.segbase0, ax
  shr   eax,16
  mov   SCODE.segbase1, al
  mov   SCODE.segbase2, ah

;POINT THE GDTREGISTER TO THE GDT TABLE
  lea   eax, GDTSTART
  add   eax,ebx   ;ebx already contains linear address of data segment
  mov   GDTBASE,eax

;POINT THE IDTREGISTER TO THE IDT TABLE
  lea   eax,IDTSTART
  add   eax,ebx
  mov  IDTBASE,eax

  cli
;STORE VIDEO MEMORY LOCATION IN ES REGISTER
  mov   ax,0B800h
  mov   es,ax

;ENTER PROTECTED MODE
  lgdt  GDTREGISTER
  lidt  IDTREGISTER

   mov  eax,cr0
   or   al,1
   mov  cr0,eax

; EXECUTE THE JUMP INTO 32BIT MODE
  db 66h, 0eah
  dd offset protectedmode
  dd scodesel

BIT16:

;===========================================================================
;       Now BACK in 16-bit protected mode.
;===========================================================================

  mov   ax,RDATASEL
  mov   ds,ax
  mov   ax,RSTCKSEL
  mov   ss,ax

  mov   eax,cr0
  and   al,0FEh
  mov   cr0,eax

  db    0eah
  dw    offset realmode
  dw    code16

REALMODE:
;===========================================================================
;  Now in 16 bit real mode
;===========================================================================

; Before returning to DOS, put real-mode compatible values in the
; segment registers:

  mov   ax, DAT
  mov   ds,ax

  mov   ax, STCK
  mov   ss,ax

  lidt  RIDTREGISTER

; Protected mode is no more.

  sti

; Exit to DOS with errorlevel 0

  mov   ax,4C00h
  int   21h

BEGIN ENDP

CODE16 ENDS

CODE32 SEGMENT PARA 'CODE' USE32
ASSUME CS:CODE32, DS:DAT, ES:DAT, SS:STCK

PROTECTEDMODE:

;===========================================================================
; THIS IS WHERE WE ENTER PROTECTED MODE
;===========================================================================

  xor   edi,edi
  xor   esi,esi

; To enable full protected-mode addressing, we must put valid protected-
; mode selectors in the DS and SS registers:

  mov   ax,SDATASEL
  mov   ds,ax
  mov   ax,RSTCKSEL
  mov   ss,ax

; Because the descriptor referred to by LINEARSEL has a base segment
; address of zero, we can simply use the linear address 000B8000 with
; LINEAR_SEL to get at the video memory:

  mov   ax,LINEARSEL
  mov   es,ax

  lea   esi,msg                ; -> "Finally in protected mode!"

  mov   edi,0B8000h + (80 * 3 + 4) * 2        ; row 3, column 4
  mov   ecx,52
  cld
  rep   movsb

;TEST THE INTERRUPT

   int 20h
   jmp $

;RETURN TO REAL MODE
;EXECUTE A FAR JUMP BACK TO THE REAL MODE SEGMENT

   db 66h, 0eah
   dw offset BIT16
   dw rcodesel

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
; handler for INT 20H
; prints '20' on second line of screen and returns
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
ISR20:
 pusha
 push gs
  mov ax,LINEARSEL
  mov gs,ax
  mov byte ptr [gs:0B80A0h],'2'
  mov byte ptr [gs:0B80A2h],'0'
 pop gs
 jmp $
 popa
 iret
ISR1F:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'F'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $

ISR1E:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'E'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR1D:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'D'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR1C:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'C'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR1B:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'B'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR1A:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'A'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR19:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'9'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR18:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'8'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR17:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'7'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR16:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'6'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR15:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'5'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR14:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'4'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR13:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'3'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR12:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'2'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR11:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'1'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISR10:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'0'
 mov byte ptr [gs:0B809Ch],'1'
 jmp $
ISRF:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'F'
 jmp $
ISRE:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'E'
 jmp $
ISRD:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'D'
 jmp $
ISRC:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'C'
 jmp $
ISRB:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'B'
 jmp $
ISRA:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'A'

 jmp $
ISR9:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'9'
 jmp $
ISR8:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'8'
 jmp $
ISR7:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'7'
 jmp $
ISR6:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'6'
 jmp $
ISR5:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'5'
 jmp $
ISR4:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'4'
 jmp $
ISR3:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'3'
 jmp $
ISR2:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'2'
 jmp $
ISR1:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'1'
 jmp $
ISR0:
 cli
 mov ax,LINEARSEL
 mov gs,ax
 mov byte ptr [gs:0B809Eh],'0'
 jmp $

CODE32 ENDS

DAT SEGMENT PARA 'DATA' USE16
;---------------------------------------------------------------
; Global Descriptor Table & pointers
;---------------------------------------------------------------
GDTSTART LABEL QWORD

  GDT           Descriptor <0,0,0,0,0,0>
                ; NULL DESCRIPTOR

  LINEAR        Descriptor <0ffffh,0,0,DS_access,PG_32,0>
                ; LINEAR ADDRESS SELECTOR
  LINEARSEL     EQU LINEAR-GDT

  SCODE         Descriptor <0ffffh,0,0,CS_access,PG_32,0>
                ; SYSTEM CODE SEGMENT
  SCODESEL      EQU SCODE-GDT

  SDATA         Descriptor <0ffffh,0,0,DS_access,PG_32,0>
                ; SYSTEM DATA SEGMENT
  SDATASEL    
...

read more »



Wed, 07 Aug 2002 03:00:00 GMT  
 Help in Setting Up Working Interrupts


|When int 20h is issued control is transferred to the correct interrupt
|handler (so the IDTR must have been set up correctly). However when it
comes
|to issuing the IRET interrupt 13h (General protection fault) is raised.
|
|If I don't generate the software interrupt 20h the program proceeds to
|completion as normal (so it must be safe to assume that the code segment
|itself and hence the GDT has been set up correctly).

You're using IRET instead of IRETD. IRET pops FLAGS, and CS:IP, and not
EFLAGS, CS:EIP that were pushed on entry to your handler.

BTW, you don't have to CLI in your exception handlers since IF is set to 0
on entry to interrupt gates (i.e., EFLAGS.IF = EFLAGS.IF AND Gate.AR[0])



Sat, 10 Aug 2002 03:00:00 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. UPS Maxicode syntax , HELP...

2. Help with debugger UPS

3. no help on pop-ups yet

4. Interrupt Setting Problem

5. Interrupt list with register settings

6. how do i know who sets which interrupts?

7. Setting interrupts handlers under W95

8. Interrupt Setting problem!

9. Setting/Getting interrupt vectors in 32 bit

10. HELP ME: SET DEFAULT WITH SET PRINT TO LPT1

11. unix interrupts to Visual Works

12. Interrupt doesn't work after UI trouble

 

 
Powered by phpBB® Forum Software