flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Exception 0x11/16/#MF

Author
Thread Post new topic Reply to topic
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 11 Jun 2009, 19:33
I just added interrupt code to my loader stage so I could use the PIT for various things but as soon as I enable interrupts this exception is raised.

I have tried various flags in CR0 (NE, EM,MP) and finit but this still happens. Once captured, the FPU SW reports 0x0000 (not-busy, empty, no exceptions) and fclex does not stop this exception from being thrown; it just keeps going.

Having looked back over my code, I don't use any FPU/MMX/SSE type instructions in the initialisation. This occurs under both VirtualBox and QEMU.

Is there something I might have missed?

Thanks Cool
Post 11 Jun 2009, 19:33
View user's profile Send private message Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 314
Mac2004 12 Jun 2009, 03:54
cod3b453: Could you please post the source code? It's difficult to say without looking at it.

Regards,
Mac2004
Post 12 Jun 2009, 03:54
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 789
Location: Adelaide
sinsi 12 Jun 2009, 04:09
Do you mean 0x11/17/#AC or 0x10/16/#MF ?
Is this PM or still RM?
Post 12 Jun 2009, 04:09
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 12 Jun 2009, 11:09
This is in Protected Mode.
The exception is Vector 16 #MF.

The boot sector sets up text mode (int 0x10, mode 3), enables A20 and loads the loader and jumps to it. The loader starts off in RM and gets BIOS memory size and memory map as well as VESA modes. This all works fine. It continues as shown below in loader.asm.

Without re-enabling interrupts, this works correctly but as soon as sti is performed exception 16 #MF "x87 Floating Point Exception-Pending" is raised. Capturing the FPU SW reveals no bits set to indicate no exception. This woudl suggest flag errors or FPU instructions; I havn't got any FPU instructions in the code at all and CR0.NE = 0. Putting fclex in the handler doesn't clear the exception so my guess is rerhaps I have an error in my PIC remapping code? But looking back at documents it appears to be fine.

Below are the relevent sources:

loader.asm
Code:
  ;================================================================
   ; Boot Loader
       ; Written by COD3B453 2008
  ; tungsten/src/init/boot/loader.asm
 ;================================================================

       ; (Real Mode - previous code truncated here)

    cli

     lgdt [GDTR32]

   mov eax,cr0
 or ax,CPU_CR0_PE
    mov cr0,eax

     jmp pword 0x0008:PMode

.error:

   ; (Real Mode stuff and error handler)

   ;================================
   ; Protected Mode
    ;================================

       align 4
     use32
       include '%fasminc%/macro/proc32.inc'

PMode:

        ;================================
   ; Initialise PMode Selectors
        ;================================

       mov ax,((GDT32.Data - GDT32.Start) or GDT_RPL_RING0)
        mov ds,ax
   mov es,ax
   mov fs,ax
   mov gs,ax
   mov ss,ax
   mov esp,0x00007C00

      ;================================
   ; Initialise the Display
    ;================================

       movzx eax,word [INIT_VESATABLE+VESA_TABLE.CurrentModePtr]
   stdcall Display_Init,eax,0x00FFFFFF,0x00000000
      stdcall Display_Text_Write,msgStart

     stdcall GFX_Load

        stdcall CPU_Init
    stdcall CPU_Print

       stdcall MEM_Init

        stdcall IRQ_Disable,0xFFFF     ; Disable IRQs
       stdcall IRQ_Remap,CORE_IDT_IRQ ; Remap IRQs, CORE_IDT_IRQ equ 0x20
  stdcall IRQ_Enable,0xFFFF      ; Enable IRQs
        stdcall IRQ_PITSetFreq,20      ; Set PIT Delay

  stdcall ACPI_Init

       ; Load the IDT

  lidt [IDTR32]

   sti ; EXCEPTION HAPPENS HERE

.main:

  hlt

     jmp .main


; Creates all 256 ISRs entrypoints, normalising stack to:
; [ISR#] [ERR#] [...]
; This is passed to the idt_handler
rept 256 i
{
  align 4
idt_#i#:

 cli

if (i-1) eqtype 8 | (i-1) eqtype 10 | (i-1) eqtype 11 | (i-1) eqtype 12 | (i-1) eqtype 13 | (i-1) eqtype 14 | (i-1) eqtype 17
    ; No dummy error code
else
       pushd 0 ; Push dummy error code
end if

       pushd (i-1) ; Push the ISR number

       jmp idt_handler
}

       ; Handles:
      ;
   ; Exceptions [ 00 - 1F ] ( 32)
      ;
   ; 00 Divide By Zero
 ; 01 Debug
  ; 02 NMI
    ; 03 Breakpoint
     ; 04 INTO
   ; 05 OOB
    ; 06 Invalid Opcode
 ; 07 No Coprocessor
 ;*08 Double Fault
   ; 09 Coprocessor Segment Overrun
    ;*0A Bad TSS
        ;*0B Segment Not Present
    ;*0C Stack Fault
    ;*0D General Protection Fault
       ;*0E Page Fault
     ; 0F Unknown Interrupt
      ; 10 Coprocessor Fault
      ; 11 Alignment Check
        ; 12 Machine Check
  ; 13 (Reserved)
     ; 14 (Reserved)
     ; 15 (Reserved)
     ; 16 (Reserved)
     ; 17 (Reserved)
     ; 18 (Reserved)
     ; 19 (Reserved)
     ; 1A (Reserved)
     ; 1B (Reserved)
     ; 1C (Reserved)
     ; 1D (Reserved)
     ; 1E (Reserved)
     ; 1F (Reserved)
     ;
   ; IRQs       [ 20 - 2F ] ( 16)
      ;
   ; 20
        ; 21
        ; 22
        ; 23
        ; 24
        ; 25
        ; 26
        ; 27
        ; 28
        ; 29
        ; 2A
        ; 2B
        ; 2C
        ; 2D
        ; 2E
        ; 2F
        ;
   ; ISRs       [ 30 - FF ] (208)
      ;
   ; (None Defined)


idt_handler:; isr, err, ...

     ; Save State
        pusha            ; 8  dword

     isr equ esp+0x20
    err equ esp+0x24

        ; Process
   mov eax,[isr]

   cmp eax,32
  jae @f

  ; Exception

     inc [__idt_counter]
 stdcall Display_Text_WriteError,msgIDT_x,msgIDT_x_info

  ; THIS IS SPECIFIC TO THIS EXCEPTION
        fstsw ax
    stdcall Display_Text_WriteHex32,eax
 ; DISPLAYS 0

    jmp .done

@@:

        cmp eax,CORE_IDT_IRQ
        jb @f

   cmp eax,(CORE_IDT_IRQ + 16)
 jae @f

  ; IRQ

   sub eax,CORE_IDT_IRQ ; Convert to IRQ#

  inc [__idt_counter]
 stdcall Display_Text_WriteHex32,[__idt_counter]
     stdcall Display_Text_Write,msgIDT_q
 stdcall Display_Text_WriteHex32,eax
 stdcall Display_Text_NewLine

    cmp eax,8 ; Check for secondary
     jb .irq_lo

      mov dx,i8259_PORT_COMMAND_SECONDARY
 mov al,i8259_EOI
    out dx,al

.irq_lo:

   mov dx,i8259_PORT_COMMAND_PRIMARY
   mov al,i8259_EOI
    out dx,al 

      jmp .done

@@:

        ; ISR

   inc [__idt_counter]
 stdcall Display_Text_WriteHex32,[__idt_counter]
     stdcall Display_Text_Write,msgIDT_r
 stdcall Display_Text_WriteHex32,eax
 stdcall Display_Text_NewLine

.done:

  ; Restore state
     popa

    ; Remove params
     add esp,8

       iret

    ;================================
   ; Includes
  ;================================

       ; (Includes)

    .padding                rb (BootLoader.Start + (0x0023 * SECTOR_SIZE) - $ - (BootLoader.End - BootLoader.Footer))

       align 4

BootLoader.Footer:

   msgStart                db '================================================================',0x0A
                                                        db ' Tungsten Operating System                        Version  0.01 ',0x0A
                                                        db '================================================================',0x0A
                                                        db 0x0A,0

       msgIDT_x                db 'Exception                                               ',0
   msgIDT_x_info           db ' System Halted                                                  ',0
   msgIDT_q                db ' IRQ ',0
      msgIDT_r                db ' ISR ',0

  __idt_counter           dd 0

    ;================================
   ; Include Data
      ;================================

       ; (Includes)

    align 4
     GDTR32                  GDTRENTRY GDT32.Start,GDT32.End

 align 4
     IDTR32                  IDTRENTRY IDT32.Start,IDT32.End

 align 4

GDT32:
   .Start:
 .Null                   GDTENTRY 0x00000000,0x00000000,0x00,0x00
    .Code                   GDTENTRY 0x00000000,0x000FFFFF,(GDT_GRANULARITY_PAGES or GDT_32BIT),(GDT_PRESENT or GDT_RING0 or GDT_CODE or GDT_CODE_READ or GDT_CODE_EXECUTE)
     .Data                   GDTENTRY 0x00000000,0x000FFFFF,(GDT_GRANULARITY_PAGES or GDT_32BIT),(GDT_PRESENT or GDT_RING0 or GDT_DATA or GDT_DATA_READ or GDT_DATA_WRITE)
       .Stack                  GDTENTRY 0x00000000,0x000FFFFF,(GDT_GRANULARITY_PAGES or GDT_32BIT),(GDT_PRESENT or GDT_RING0 or GDT_STACK or GDT_STACK_READ or GDT_STACK_WRITE or GDT_STACK_EXPANDDOWN)
    .End:

       align 4

IDT32:
   .Start:
 ; Build ISR table
rept 256 i
{
   .isr#i#:
                        dw ((idt_#i#) and 0xFFFF)
                   dw ((GDT32.Code - GDT32.Start) or GDT_RPL_RING0)
                    db 0
                        db (((IDT_PRESENT or IDT_RING0) and IDT_ACCESS_MASK) or IDT_ACCESS)
                 dw ((idt_#i#) shr 16)
}
     .End:

       align 4

 IDT_TABLE               rd 256

  ; (Graphics data & font)    


irq.asm (32bit)
Code:
;================================================================ 
; IRQ
; Written by COD3B453 2007 
; tungsten/src/init/loader/irq.asm
;================================================================

proc IRQ_Enable,mask
                push eax

                mov eax,[mask]
              xor eax,0xFFFF

          out i8259_PORT_REGISTER_PRIMARY,al
          mov al,ah
           out i8259_PORT_REGISTER_SECONDARY,al

            stdcall Display_Text_Write,msgIRQEnabled
            stdcall Display_Text_WriteHex32,[mask]
              stdcall Display_Text_NewLine

            pop eax
             ret
endp

proc IRQ_Remap,base
              push eax

                ; ICW1
              mov al,(i8259_ICW1_ICW4 or i8259_ICW1_TRIGGER_EDGE or i8259_ICW1_PRIMARY_SECONDARY or i8259_ICW1_INIT)
              out i8259_PORT_COMMAND_PRIMARY,al
           out i8259_PORT_COMMAND_SECONDARY,al

             mov eax,[base]
              and eax,0x00000F8

               stdcall Display_Text_Write,msgIRQRemap
              stdcall Display_Text_WriteHex32,eax
         stdcall Display_Text_NewLine

            ; ICW2
              out i8259_PORT_REGISTER_PRIMARY,al
          add eax,8
           out i8259_PORT_REGISTER_SECONDARY,al

            ; ICW3
              mov al,4
            out i8259_PORT_REGISTER_PRIMARY,al

              mov al,2
            out i8259_PORT_REGISTER_SECONDARY,al

            ; ICW4
              mov al,(i8259_ICW4_EOI_MANUAL or i8259_ICW4_8086)
           out i8259_PORT_REGISTER_PRIMARY,al

              mov al,(i8259_ICW4_EOI_MANUAL or i8259_ICW4_8086)
           out i8259_PORT_REGISTER_SECONDARY,al

            pop eax
             ret
endp

proc IRQ_Disable,mask
            push eax

                mov eax,[mask]

          out i8259_PORT_REGISTER_PRIMARY,al
          mov al,ah
           out i8259_PORT_REGISTER_SECONDARY,al

            stdcall Display_Text_Write,msgIRQDisabled
           stdcall Display_Text_WriteHex32,[mask]
              stdcall Display_Text_NewLine

            pop eax
             ret
endp


proc IRQ_PITSetFreq,f
                push eax ebx edx

                mov al,(i8253_COMMAND_CHANNEL0 or i8253_COMMAND_LH or i8253_COMMAND_MODE_SQUARE or i8253_COMMAND_BIN)
               out i8253_PORT_COMMAND,al

               mov eax,i8253_CLOCK
         mov ebx,[f]
         xor edx,edx
         div ebx

         out i8253_PORT_CHANNEL0,al
          mov al,ah
           out i8253_PORT_CHANNEL0,al

              stdcall Display_Text_Write,msgIRQPITFreq
            stdcall Display_Text_WriteDec32,[f]
         stdcall Display_Text_Write,msgIRQPITHz
              stdcall Display_Text_NewLine

            pop edx ebx eax
             ret
endp    


i8259.ash (Header)
Code:
;================================================================
; i8259 PIC (Programmable Interrupt Controller)
; Written by COD3B453 2007
; tungsten/src/hardware/i8259.ash
;================================================================

i8259_PORT_COMMAND_PRIMARY                      equ 0x0020
i8259_PORT_COMMAND_SECONDARY                    equ 0x00A0
i8259_PORT_REGISTER_PRIMARY                     equ 0x0021
i8259_PORT_REGISTER_SECONDARY                   equ 0x00A1

i8259_EOI                                       equ 0x20

i8259_ICW1_ICW4                                 equ 0x01
i8259_ICW1_PRIMARY_ONLY                         equ 0x02
i8259_ICW1_PRIMARY_SECONDARY                     equ 0x00
i8259_ICW1_TRIGGER_LEVEL                        equ 0x08
i8259_ICW1_TRIGGER_EDGE                         equ 0x00
i8259_ICW1_INIT                                 equ 0x10

;*
; i8259_ICW2
; This is a bit map of the IRQ
;
; i8259_ICW3
; The is a bit map of IR lines connected to slave (otherwise peripheral)
;*

i8259_ICW4_8086                                 equ 0x01
i8259_ICW4_8080                                 equ 0x00
i8259_ICW4_EOI_AUTO                             equ 0x02
i8259_ICW4_EOI_MANUAL                           equ 0x00 ; Must send i8259_EOI
i8259_ICW4_SECONDARY_BUFFER                     equ 0x00
i8259_ICW4_PRIMARY_BUFFER                       equ 0x04
i8259_ICW4_BUFFERED                             equ 0x08
i8259_ICW4_NESTED                               equ 0x10    


i8253.ash (Header)
Code:
;================================================================
; i8253 PIT (Programmable Interval Timer)
; Written by COD3B453 2007
; tungsten/src/hardware/i8253.ash
;================================================================

i8253_PORT_CHANNEL0                             equ 0x0040 ; RW
i8253_PORT_CHANNEL1                             equ 0x0041 ; RW
i8253_PORT_CHANNEL2                             equ 0x0042 ; RW
i8253_PORT_COMMAND                              equ 0x0043 ; W

i8253_CLOCK                                     equ 0x001234DD

i8253_COMMAND_CHANNEL0                          equ 0x00
i8253_COMMAND_CHANNEL1                          equ 0x40
i8253_COMMAND_CHANNEL2                          equ 0x80
i8253_COMMAND_READ                              equ 0xC0

i8253_COMMAND_COUNT                             equ 0x00
i8253_COMMAND_L_ONLY                            equ 0x10
i8253_COMMAND_H_ONLY                            equ 0x20
i8253_COMMAND_LH                                equ 0x30
i8253_COMMAND_MODE_HSTROBE                      equ 0x0A
i8253_COMMAND_MODE_SSTROBE                      equ 0x08
i8253_COMMAND_MODE_SQUARE                       equ 0x06
i8253_COMMAND_MODE_RATE                         equ 0x04
i8253_COMMAND_MODE_HONESHOT                     equ 0x02
i8253_COMMAND_MODE_TCOUNT                       equ 0x00
i8253_COMMAND_BCD                               equ 0x01
i8253_COMMAND_BIN                               equ 0x00    
Post 12 Jun 2009, 11:09
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 14 Jun 2009, 18:45
Embarassed

Turns out my interrupt entry point code was wrong should have used = instead of eqtype so stack got trashed and the interrupt id was misread for the timer interrupt as the exception Confused

sorry and thanks! Cool
Post 14 Jun 2009, 18:45
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.