[movitz-cvs] CVS update: movitz/losp/x86-pc/interrupt.lisp

Frode Vatvedt Fjeld ffjeld at common-lisp.net
Wed Apr 7 00:12:28 UTC 2004


Update of /project/movitz/cvsroot/movitz/losp/x86-pc
In directory common-lisp.net:/tmp/cvs-serv737

Modified Files:
	interrupt.lisp 
Log Message:
Moved much stuff from :x86-pc/interrupt to :muerte/interrupt, because
it's really a required part of Muerte.

Date: Tue Apr  6 20:12:28 2004
Author: ffjeld

Index: movitz/losp/x86-pc/interrupt.lisp
diff -u movitz/losp/x86-pc/interrupt.lisp:1.8 movitz/losp/x86-pc/interrupt.lisp:1.9
--- movitz/losp/x86-pc/interrupt.lisp:1.8	Tue Apr  6 10:42:11 2004
+++ movitz/losp/x86-pc/interrupt.lisp	Tue Apr  6 20:12:28 2004
@@ -10,12 +10,11 @@
 ;;;; Author:        Frode Vatvedt Fjeld <frodef at acm.org>
 ;;;; Created at:    Fri May  4 18:08:50 2001
 ;;;;                
-;;;; $Id: interrupt.lisp,v 1.8 2004/04/06 14:42:11 ffjeld Exp $
+;;;; $Id: interrupt.lisp,v 1.9 2004/04/07 00:12:28 ffjeld Exp $
 ;;;;                
 ;;;;------------------------------------------------------------------
 
 (require :x86-pc/pic8259)
-(require :x86-pc/debugger)
 (provide :x86-pc/interrupt)
 
 (in-package muerte.x86-pc)
@@ -25,250 +24,6 @@
     (:movb #x20 :al)
     (:outb :al #x20)))
 
-(defmacro stack-word (offset)
-  `(with-inline-assembly (:returns :eax)
-     (:movl (:esp ,(* 4 offset)) :eax)))
-
-(define-compiler-macro int-frame-index (&whole form name &environment env)
-  (let ((name (and (movitz:movitz-constantp name env)
-		   (movitz:movitz-eval name env))))
-    (if (not name)
-	form
-      (- 5 (position name
-		      '(:eip :eflags nil :error-code :exception :ebp nil
-			:ecx :eax :edx :ebx :esi :edi)
-		      #+ignore '(:edi :esi :ebp :esp :ebx :edx :ecx :eax
-				 :exception :error-code
-				 :eip :cs :eflags))))))
-
-(defun int-frame-index (name)
-  (- 5 (position name
-		  '(:eip :eflags nil :error-code :exception :ebp nil
-		    :ecx :eax :edx :ebx :esi :edi))))
-
-(define-compiler-macro int-frame-ref (&whole form frame reg type &optional (offset 0) &environment env)
-  `(memref ,frame (+ (* 4 (int-frame-index ,reg)) ,offset) 0 ,type))
-
-(defun int-frame-ref (frame reg type &optional (offset 0))
-  (int-frame-ref frame reg type offset))
-
-(defun (setf int-frame-ref) (x frame reg type)
-  (setf (memref frame (* 4 (int-frame-index reg)) 0 type) x))
-
-(define-primitive-function muerte::default-interrupt-trampoline ()
-  "Default first-stage interrupt handler."
-  #.(cl:list* 'with-inline-assembly '(:returns :nothing)
-	      (cl:loop :for i :from 0 :to movitz::+idt-size+
-		:append (cl:if (cl:member i '(8 10 11 12 13 14 17))
-			    `(((5) :pushl ,i)
-			      ((5) :jmp 'ok))
-			  `(((2) :pushl 0) ; replace Error Code
-			    ((2) :pushl ,i)
-			    ((1) :nop)
-			    ((5) :jmp 'ok)))))
-  (with-inline-assembly (:returns :multiple-values)
-   ok
-    ;; Stack:
-    ;; 20: Interruptee EFLAGS (later EIP)
-    ;; 16: Interruptee CS     (later EFLAGS)
-    ;; 12: Interruptee EIP
-    ;;  8: Error code
-    ;;  4: Exception number
-    ;;  0: EBP
-    (:pushl :ebp)
-    (:movl :esp :ebp)
-    (:pushl 0)				; 0 means default-interrupt-trampoline frame
-    (:pushl :ecx)			; -8
-    (:pushl :eax)			; -12
-    (:pushl :edx)			; -16
-    (:pushl :ebx)			; -20
-    (:pushl :esi)			; -24
-    (:pushl :edi)			; -28
-
-    ;; rearrange stack for return
-    (:movl (:ebp 12) :eax)		; load return address
-    (:movl (:ebp 20) :ebx)		; load EFLAGS
-    (:movl :ebx (:ebp 16))		; EFLAGS at next-to-bottom of stack
-    (:movl :eax (:ebp 20))		; return address at bottom of stack
-
-    (:xorl :eax :eax)			; Ensure safe value
-    (:xorl :edx :edx)			; Ensure safe value
-
-    (:movl ':nil-value :edi)		; We want NIL!
-    
-    (:pushl (:ebp 16))			; EFLAGS
-    (:pushl :cs)			; push CS
-    (:call (:pc+ 0))			; push EIP.
-    ;; Now add a few bytes to the on-stack EIP so the iret goes to
-    ;; *DEST* below.
-    ((4) :addl 5 (:esp))		; 4 bytes
-    ((1) :iretd)			; 1 byte
-    
-    ;; *DEST* iret branches to here.
-    ;; we're now in the context of the interruptee.
-
-;;;    (:pushl :eax)			; fake stack-frame return address
-;;;    (:pushl :ebp)			; set up fake stack-frame
-;;;    (:movl :esp :ebp)			; (GIVES EBP OFFSET 8 RELATIVE TO NUMBERS ABOVE!!)
-;;;    (:pushl :edi)			; A fake "funobj" for the fake stack-frame..
-;;;					; ..the int-frame will be put here shortly.
-    
-    ;; Save/push thread-local values
-    (:locally (:movl (:edi (:edi-offset num-values)) :ecx))
-    (:jecxz 'push-values-done)
-    (:leal (:edi #.(movitz::global-constant-offset 'values)) :eax)
-   push-values-loop
-    (:locally (:pushl (:eax)))
-    (:addl 4 :eax)
-    (:subl 1 :ecx)
-    (:jnz 'push-values-loop)
-   push-values-done
-    (:locally (:pushl (:edi (:edi-offset num-values))))
-    
-    ;; call handler
-    (:movl (:ebp 4) :ebx)		; interrupt number into EBX
-    (:locally (:movl (:edi (:edi-offset interrupt-handlers)) :eax))
-    (:movl (:eax 2 (:ebx 4)) :eax)	; symbol at (aref EBX interrupt-handlers) into :esi
-    (:leal (:eax -7) :ecx)
-    (:testb 7 :cl)
-    (:jnz 'skip-interrupt-handler)	; if it's not a symbol, never mind.
-    (:movl (:eax #.(movitz::slot-offset 'movitz::movitz-symbol 'movitz::function-value))
-	   :esi)			; load new funobj from symbol into ESI
-    (:movl :ebp :ebx)			; pass INT-frame as arg1
-    ;; (:movl :ebx (:ebp -4))		; put INT-frame as our fake stack-frame's funobj.
-    (:movl (:ebp 4) :eax)		; pass interrupt number as arg 0.
-    (:shll #.movitz::+movitz-fixnum-shift+ :eax)
-    (:call (:esi #.(movitz::slot-offset 'movitz::movitz-funobj 'movitz::code-vector%2op)))
-
-   skip-interrupt-handler
-    ;; Restore thread-local values
-    (:popl :ecx)
-    (:locally (:movl :ecx (:edi (:edi-offset num-values))))
-    (:jecxz 'pop-values-done)
-   pop-values-loop
-    ;; ((:fs-override) :popl (:edi #.(movitz::global-constant-offset 'values) (:ecx 4) -4))
-    (:locally (:popl (:edi (:edi-offset values) (:ecx 4) -4)))
-    (:subl 1 :ecx)
-    (:jnz 'pop-values-loop)
-   pop-values-done
-
-    (:movl (:ebp -28) :edi)
-    (:movl (:ebp -24) :esi)
-    (:movl (:ebp -20) :ebx)
-    (:movl (:ebp -16) :edx)
-    (:movl (:ebp -12) :eax)
-    (:movl (:ebp -8)  :ecx)
-
-    (:leave)
-    (:addl 12 :esp)
-     
-;;;    (:leal (:ebp 8) :esp)
-;;;    (:popal)				; pop interruptee's registers
-;;;    (:addl 12 :esp)			; skip stack-hole
-    (:popfl)				; pop EFLAGS
-    (:ret)))				; pop EIP
-
-(defvar *last-interrupt-frame* nil)
-
-(defun muerte::interrupt-default-handler (number int-frame)
-  (declare (muerte::without-check-stack-limit))
-  (macrolet ((@ (fixnum-address &optional (type :lisp))
-	       "Dereference the fixnum-address."
-	       `(memref ,fixnum-address 0 0 ,type)))
-    (let (($eip (+ int-frame (int-frame-index :eip)))
-	  ($eax (+ int-frame (int-frame-index :eax)))
-	  ($ebx (+ int-frame (int-frame-index :ebx)))
-	  ($ecx (+ int-frame (int-frame-index :ecx)))
-	  ($edx (+ int-frame (int-frame-index :edx)))
-	  ($esi (+ int-frame (int-frame-index :esi)))
-	  (*last-interrupt-frame* int-frame))
-      (block nil
-	(case number
-	  (0 (error "Division by zero."))
-	  (3 (break "Break instruction at ~@Z." $eip))
-	  (6 (error "Illegal instruction at ~@Z." $eip))
-	  (13 (error "General protection error. EIP=~@Z, error-code: #x~X, EAX: ~@Z, EBX: ~@Z, ECX: ~@Z"
-		     $eip
-		     (int-frame-ref int-frame :error-code :unsigned-byte32)
-		     $eax $ebx $ecx))
-	  (68 (warn "EIP: ~@Z EAX: ~@Z EBX: ~@Z  ECX: ~@Z EDX: ~@Z"
-		    $eip $eax $ebx $ecx $edx)
-	      (dotimes (i 100000)
-		(with-inline-assembly (:returns :nothing) (:nop))))
-	  (67 (muerte.debug:backtrace :fresh-lines nil :length 6)
-	      (dotimes (i 100000)
-		(with-inline-assembly (:returns :nothing) (:nop))))
-	  (66 (error "Unspecified type error at ~@Z in ~S with EAX=~@Z, ECX=~@Z."
-		     $eip (@ (+ int-frame (int-frame-index :esi)))
-		     $eax $ecx))
-	  (62 (error "Trying to save too many values: ~@Z." $ecx))
-	  ((5 55)
-	   (let* ((stack (muerte::%run-time-context-slot 'movitz::stack-vector))
-		  (old-bottom (muerte::stack-bottom))
-		  (real-bottom (- (object-location stack) 2))
-		  (stack-left (- old-bottom real-bottom))
-		  (new-bottom (cond
-			       ((< stack-left 10)
-				(princ "Halting CPU due to stack exhaustion.")
-				(muerte::halt-cpu))
-			       ((<= stack-left 256)
-				(format *debug-io*
-					"~&This is your LAST chance to pop off stack.~%")
-				real-bottom)
-			       (t (+ real-bottom (truncate stack-left 2)))))) ; Cushion the fall..
-	     (unwind-protect
-		 (progn
-		   (setf (muerte::stack-bottom) new-bottom)
-		   (format *debug-io* "~&Stack-warning: Bumped stack-bottom by ~D to #x~X.~%"
-			   (- old-bottom new-bottom)
-			   new-bottom)
-		   (break "Stack overload exception ~D at ESP=~@Z with bottom #x~X."
-			  number
-			  (+ int-frame (int-frame-index :ebp))
-			  old-bottom))
-	       (format *debug-io* "~&Stack-warning: Resetting stack-bottom to #x~X.~%"
-		       old-bottom)
-	       (setf (muerte::stack-bottom) old-bottom))))
-	  (69
-	   (error "Not a function: ~S" (@ $edx)))
-	  (70
-	   (error "[EIP=~@Z] Index ~@Z out of bounds ~@Z for ~S." $eip $ecx $ebx (@ $eax)))
-	  (98
-	   (let ((name (@ $ecx)))
-	     (when (symbolp name)
-	       (error 'undefined-function :name name))))
-	  (99
-	   (let ((name (@ $edx)))
-	     (when (symbolp name)
-	       (error 'unbound-variable :name name))))
-	  ((100);; 101 102 103 104 105)
-	   (let ((funobj (@ (+ int-frame (int-frame-index :esi))))
-		 (code (int-frame-ref int-frame :ecx :unsigned-byte8)))
-	     (error 'muerte:wrong-argument-count
-		    :function funobj
-		    :argument-count (if (logbitp 7 code)
-					(ash (int-frame-ref int-frame :ecx :unsigned-byte32)
-					     -24)
-				      code))))
-	  (108
-	   (error 'throw-error :tag (@ $eax)))
-	  (110
-	   ;; (print-dynamic-context); what's this?
-	   (throw :debugger nil))
-	  (112
-	   (setf (%run-time-context-slot 'nursery-space)
-	     (memref (%run-time-context-slot 'nursery-space) -6 3 :lisp))
-	   (error "Out of memory. Please take out the garbage."))
-	  (t (funcall (if (< 16 number 50) #'warn #'error)
-		      "Exception occurred: ~D, EIP: ~@Z, EAX: ~@Z, ECX: ~@Z, ESI: ~@Z"
-		      number $eip $eax $ecx $esi)))
-	nil))))
-
-
-;;;  (with-inline-assembly (:returns :nothing) (:movb #x47 (#xb8045))
-;;;  (:addb #x01 (#xb8044))))
-
-
 (defun idt-init ()
   (init-pic8259 32 40)
   (setf (pic8259-irq-mask) #xffff)
@@ -284,24 +39,6 @@
   (setf (pic8259-irq-mask) #xfffe)
   (with-inline-assembly (:returns :nothing) (:sti)))
 
-(defun cli ()
-  (with-inline-assembly (:returns :nothing)
-    (:cli)))
-
-(defun sti ()
-  (with-inline-assembly (:returns :nothing)
-    (:sti)))
-
-(defun interrupt-handler (n)
-  (let ((vector (load-global-constant interrupt-handlers)))
-    (svref vector n)))
-
-(defun (setf interrupt-handler) (handler n)
-  (check-type handler symbol)
-  (assert (fboundp handler))
-  (let ((vector (load-global-constant interrupt-handlers)))
-    (setf (svref vector n) handler)))
-
 (defparameter *timer-counter* 0)
 
 (defun timer-handler (number int-frame)
@@ -312,31 +49,3 @@
   (pic8259-end-of-interrupt 0))
 
 
-(define-primitive-function primitive-software-interrupt ()
-  "A primitive code-vector that generates software interrupts."
-  (macrolet ((make-software-interrupt-code ()
-	       (cons 'progn
-		     (loop for vector from 0 to 255
-			 collect `(with-inline-assembly (:returns :nothing)
-				    ;; Each code-entry is 2+1+1=4 bytes.
-				    ((2) :int ,vector)
-				    ((1) :ret)
-				    ((1) :nop))))))
-    (make-software-interrupt-code)))
-
-(defun software-interrupt (interrupt-vector &optional (eax 0) (ebx 0))
-  "Generate software-interrupt number <interrupt-vector>."
-  ;; The problem now is that the x86 INT instruction only takes an
-  ;; immediate argument.
-  ;; Hence the primitive-function primitive-software-interrupt.
-  (check-type interrupt-vector (unsigned-byte 8))
-  (let ((code-vector (symbol-value 'primitive-software-interrupt)))
-    (check-type code-vector vector)
-    (with-inline-assembly-case ()
-      (do-case (t :nothing)
-	(:compile-two-forms (:ecx :edx) interrupt-vector code-vector)
-	(:leal (:edx :ecx 2) :ecx)
-	(:compile-two-forms (:eax :ebx) eax ebx)
-	(:shrl 2 :eax)
-	(:shrl 2 :ebx)
-	(:call :ecx)))))





More information about the Movitz-cvs mailing list