Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:41

0001 /*  cpu_asm.S
0002  *
0003  *  This file contains all assembly code for the Intel i386 IDT
0004  *  manipulation.
0005  *
0006  *  COPYRIGHT (c) 1998 valette@crf.canon.fr
0007  *
0008  *  The license and distribution terms for this file may be
0009  *  found in the file LICENSE in this distribution or at
0010  *  http://www.rtems.org/license/LICENSE.
0011  */
0012 
0013 #include <rtems/asm.h>
0014 
0015 BEGIN_CODE
0016 /*
0017  * C callable function enabling to get easilly usable info from
0018  * the actual value of IDT register.
0019  *
0020 extern void i386_get_info_from_IDTR (interrupt_gate_descriptor** table,
0021                      unsigned* limit);
0022  */
0023 PUBLIC (i386_get_info_from_IDTR)
0024 PUBLIC (i386_set_IDTR)
0025 PUBLIC (i386_get_info_from_GDTR)
0026 PUBLIC (i386_set_GDTR)
0027 
0028 SYM (i386_get_info_from_IDTR):
0029     movl    4(esp), ecx     /* get location where table address */
0030                                     /*    must be stored */
0031     movl    8(esp), edx     /* get location table size must be stored */
0032 
0033     subl    $6, esp         /* let room to prepare 48 bit IDTR */
0034 
0035     sidt    (esp)           /* get 48 bit IDTR value */
0036 
0037     movl    2(esp), eax     /* get base */
0038     movl    eax, (ecx)
0039 
0040     movzwl  (esp), eax      /* get limit */
0041     movl    eax, (edx)
0042 
0043     addl    $6, esp         /* restore %esp */
0044     ret
0045 
0046 /*
0047  * C callable function enabling to change the value of IDT register. Must be called
0048  * with inmterrupt masked at processor level!!!.
0049  *
0050 extern void i386_set_IDTR (interrupt_gate_descriptor* table,
0051                    unsigned limit);
0052  */
0053 SYM (i386_set_IDTR):
0054 
0055     leal    4(esp), edx     /* load in edx address of input */
0056                                     /*    parameter "table" */
0057 
0058     movl    (edx), eax      /* load base into eax */
0059     movl    4(edx), ecx     /* load limit into ecx */
0060 
0061     movw    cx, (edx)       /* prepare 48 bit pointer */
0062     movl    eax, 2(edx)
0063 
0064     lidt    (edx)
0065 
0066     ret
0067 /*
0068  *
0069  * C callable function enabling to get easilly usable info from
0070  * the actual value of GDT register.
0071 extern void i386_get_info_from_GDTR (segment_descriptors** table,
0072                                      uint16_t* limit);
0073  */
0074 
0075 SYM (i386_get_info_from_GDTR):
0076     movl    4(esp), ecx     /* get location where table address */
0077                                     /*    must be stored */
0078     movl    8(esp), edx     /* get location table size must be stored */
0079 
0080     subl    $6, esp         /* let room to prepare 48 bit GDTR */
0081 
0082     sgdt    (esp)           /* get 48 bit GDTR value */
0083 
0084     movl    2(esp), eax     /* get base */
0085     movl    eax, (ecx)
0086 
0087     movzwl  (esp), eax      /* get limit */
0088     movw    ax, (edx)
0089 
0090     addl    $6, esp         /* restore %esp */
0091     ret
0092 
0093 /*
0094  * C callable function enabling to change the value of GDT register.
0095  * Must be called with interrupts masked at processor level!!!.
0096  *   extern void i386_set_GDTR (segment_descriptors*, uint16_t limit);
0097  */
0098 SYM (i386_set_GDTR):
0099 
0100     leal    4(esp), edx     /* load in edx address of input */
0101                                     /*   parameter "table" */
0102 
0103     movl    (edx), eax      /* load base into eax */
0104     movl    4(edx), ecx     /* load limit into ecx */
0105 
0106     movw    cx, (edx)       /* prepare 48 bit pointer */
0107     movl    eax, 2(edx)
0108 
0109     lgdt    (edx)
0110 
0111     ret
0112 
0113 END_CODE
0114 
0115 END