home *** CD-ROM | disk | FTP | other *** search
- #define TRUE 1
- #define FALSE 0
-
- #define _SVDC_ db 36h, 0fh, 78h, 1fh
-
- int old_off;
- int old_seg;
- extern ill_op();
-
- /*****************************************************************************
- * Function: isb()
- *
- * Purpose: Determine if 486SLC/DLC is rev. A or B
- *
- * Technique: A step devices do not support SMM. By executing an SMM
- * instruction without an invalid opcode exception the device
- * is a B step device or later. To execute the SMM instruction
- * this routine must be operating at CPL 0 or REAL mode. V86
- * mode, CPL 1,2, and 3 are NOT permissable. A check for V86
- * should be done before calling this routine.
- *
- * Parameters: Nothing
- *
- * Returns: 0 if A step
- * 1 if B step device
- *
- * Calls: DOS via int 21 function 35,25
- * - To load new invalid opcode handler
- *****************************************************************************/
- isb ()
- {
- int i, b_step;
- char mem[10];
- char save_ccr1, save_cf, save_ce, save_cd;
-
- for (i=0; i<10; mem[i++]=0);
-
- asm {
-
- .386
- extrn _ill_op:near
-
- ;***** save flag and turn off interrupts *****
- pushf
- cli
-
- ;*********************************************
- ;****** get present invalid opcode handler
- ;*********************************************
-
- push es
- mov ax, 3506h
- int 21h
- mov old_seg, es
- mov old_off, bx
- pop es
-
- ;*********************************************
- ;****** install new invalid opcode handler
- ;*********************************************
- push ds
- mov ax, 2506h
- mov dx, OFFSET _ill_op
- mov bx, cs
- mov ds, bx
- int 21h
- pop ds
-
- ;*************************************************************
- ;****** Set SM4 and SMAC and SMI bit to allow SMM instructions
- ;*************************************************************
- mov al, 0c1h
- out 22h, al
- in al, 23h
- mov byte ptr [save_ccr1], al
- or al, 86h
- mov ah, al
- mov al, 0c1h
- out 22h, al
- mov al, ah
- out 23h, al
-
- ;************************************************************
- ;***** Setup non-zero SMM region
- ;************************************************************
- mov al, 0cfh
- out 22h, al
- in al, 23h
- mov byte ptr [save_cf], al
-
- mov al, 0cfh
- out 22h, al
- mov al, 1
- out 23h, al
-
- ;********************************************
- ;**** Set SMM region to the top of memory to
- ;**** avoid overlapping with this program.
- ;********************************************
- mov al, 0cdh
- out 22h, al
- in al, 23h
- mov byte ptr [save_cd], al
-
- mov al, 0ceh
- out 22h, al
- in al, 23h
- mov byte ptr [save_ce], al
-
- mov al, 0cdh
- out 22h, al
- mov al, 0ffh
- out 23h, al
-
- mov al, 0ceh
- out 22h, al
- mov al, 0h
- out 23h, al
-
- mov al, 0cfh
- out 22h, al
- in al, 23h
- and al, 0fh
- out 23h, al
- ;********************* flush instruction cache **************
- jmp $+2
-
- ;*********************************************
- ;****** Execute SMM instruction svdc
- ;*********************************************
- ;svdc word ptr mem, ds
- ; word ptr mem == ss:[bx]
- lea bx, mem
- _SVDC_
-
- ;**********************************************
- ;***** restore configuration registers
- ;**********************************************
- mov al, 0cdh
- out 22h, al
- mov al, byte ptr save_cd
- out 23h, al
-
- mov al, 0ceh
- out 22h, al
- mov al, byte ptr save_ce
- out 23h, al
-
- mov al, 0cfh
- out 22h, al
- mov al, byte ptr save_cf
- out 23h, al
-
- mov al, 0c1h
- out 22h, al
- mov al, byte ptr save_ccr1
- out 23h, al
-
- ;*********************************************
- ;****** restore old invalid opcode handler
- ;*********************************************
- push ds
- mov ax, 2506h
- mov dx, [old_off]
- mov bx, [old_seg]
- mov ds, bx
- int 21h
- pop ds
-
- ;****** restore flags ******
- popf
-
- } // isb asm region
-
- for (i=0,b_step=FALSE; i<10; ++i)
- if (mem[i] != 0)
- {
- b_step = TRUE;
- break;
- }
-
- return (b_step);
- } // isb ()
-