//----------------------------------------------------------------- // smidemo.s // // This is our code for an SMI interrupt service routine for // the purposes of a classroom demonstration in our Advanced // Microcomputer Programming course. (To display its output // properly, you need first to switch to a text-mode console // using a --Fn keystroke-combination and execute // the 'setfont' command, then use our 'issuesmi' program to // trigger a System Management Interrupt for one of the CPUs // in our Core-2 Quad workstation.) The physical address of // our machine's graphics frame-buffer, and its organization // of display-data while in text-mode, were discovered using // our 'vram.c' device-driver. Our 'smram.ko' kernel-module // has to be installed beforehand. // // to assemble: $ as smidemo.s -o smidemo.o // and to link: $ ld smidemo.o -T ldscript -o smidemo.b // // preparation: $ /sbin/insmod smram.ko // and install: $ ./smiload smidemo.b // and execute: $ ./issuesmi // // NOTE: You must perform a cold reboot of your workstation // after finishing this experiment (in order to restore the // manufacturer's SMI interrupt-handlers for proper machine // functioning). And keep in mind that the code below will // begin execution with CS:EIP = SMSEGMENT_BASE:0x00008000. // // programmer: ALLAN CRUSE // written on: 09 DEC 2008 //----------------------------------------------------------------- .equ APIC_BASE, 0xFEE00000 # address for Local-APIC .equ VRAM_BASE, 0xE0000000 # graphics frame-buffer .equ CRTC_ADDR, 0x03D4 # I/O-port for CRTC Addr .equ CRTC_DATA, 0x03D5 # I/O-port for CRTC Data .equ CRTC_START_HI, 0x0C # CRTC Start-Address MSB .equ CRTC_START_LO, 0x0D # CRTC Start-Address LSB .section .text #------------------------------------------------------------------ isrSMI: .code16 # for execution in System Management Mode # turn the text screen blue (to confirm execution) xor %ax, %ax mov %ax, %ds mov $VRAM_BASE, %ebx xor %edi, %edi cld mov $0x4000, %ecx nxpel: movb $0x17, 1(%ebx, %edi, 8) inc %edi loop nxpel # insert processor's Local-APIC ID-number into message text mov $APIC_BASE, %ebx # processor's Local-APIC mov 0x20(%ebx), %eax # read Local-ID register shr $24, %eax # shift ID-number to LSB and $0x7, %al # insure value is [7..0] or $'0', %al # convert to ascii-numeral mov $0x8000, %esi # label-offsets from CS-base mov %al, %cs:buf(%esi) # store numeral in message # get current CRTC Start-Address into register EDI mov $CRTC_ADDR, %dx # i/o-port for CRTC mov $CRTC_START_HI, %al # specify register out %al, %dx # for Start-Address MSB mov $CRTC_DATA, %dx # i/o-port for DATA in %dx, %al # read current value mov %al, %ah # and copy into AH mov $CRTC_ADDR, %dx # i/o-port for CTRC mov $CRTC_START_LO, %al # specify register out %al, %dx # for Start-Address LSB mov $CRTC_DATA, %dx # i/o-port for DATA in %dx, %al # read current value movzxw %ax, %edi # Start-Address to EDI # advance to row 12, column 10 mov $12, %eax # setup row-number imul $80, %eax # times row's width add $10, %eax # plus column-number add %eax, %edi # add to Start-Address # draw our message to the text-mode screen mov $VRAM_BASE, %ebx # frame-buffer address mov $0x8000, %esi # label-offsets from CS mov %cs:len(%esi), %ecx # message-length in ECX mov %cs:att(%esi), %ah # text-attributes in AH nxchr: mov %cs:msg(%esi), %al # get message character mov %ax, (%ebx, %edi, 8) # write char and color inc %esi # advance source-index inc %edi # advance dest'n-index loop nxchr # again if more chars rsm # resume interrupted task #------------------------------------------------------------------ msg: .ascii " Hello from processor number " buf: .ascii "x in System Management Mode " len: .long . - msg # length of message-string att: .byte 0x4F # bright white against red #------------------------------------------------------------------ # include this ascii-text so we can easily see our installed code .align 16 # align for easy viewing .ascii " smidemo " # name of this program #------------------------------------------------------------------ .end