Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia32/src/asm.S

    rb5382d4f rb8230b9  
    1 /*
    2  * Copyright (c) 2001 Jakub Jermar
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  *
    9  * - Redistributions of source code must retain the above copyright
    10  *   notice, this list of conditions and the following disclaimer.
    11  * - Redistributions in binary form must reproduce the above copyright
    12  *   notice, this list of conditions and the following disclaimer in the
    13  *   documentation and/or other materials provided with the distribution.
    14  * - The name of the author may not be used to endorse or promote products
    15  *   derived from this software without specific prior written permission.
    16  *
    17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    27  */
    28 
    29 /** Very low and hardware-level functions
    30  *
    31  */
    32 
    33 /**
    34  * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int
    35  * has no error word  and 1 means interrupt with error word
    36  *
    37  */
    38 #define ERROR_WORD_INTERRUPT_LIST  0x00027d00
    39 
    40 #include <arch/pm.h>
    41 #include <arch/mm/page.h>
     1#
     2# Copyright (c) 2001-2004 Jakub Jermar
     3# All rights reserved.
     4#
     5# Redistribution and use in source and binary forms, with or without
     6# modification, are permitted provided that the following conditions
     7# are met:
     8#
     9# - Redistributions of source code must retain the above copyright
     10#   notice, this list of conditions and the following disclaimer.
     11# - Redistributions in binary form must reproduce the above copyright
     12#   notice, this list of conditions and the following disclaimer in the
     13#   documentation and/or other materials provided with the distribution.
     14# - The name of the author may not be used to endorse or promote products
     15#   derived from this software without specific prior written permission.
     16#
     17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27#
     28
     29## very low and hardware-level functions
     30
     31# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error
     32# word and 1 means interrupt with error word
     33#define ERROR_WORD_INTERRUPT_LIST 0x00027d00
    4234
    4335.text
     36
    4437.global paging_on
    4538.global enable_l_apic_in_msr
     
    5245.global memcpy_to_uspace
    5346.global memcpy_to_uspace_failover_address
    54 .global early_putchar
    55 
    56 /* Wrapper for generic memsetb */
     47
     48
     49# Wrapper for generic memsetb
    5750memsetb:
    5851        jmp _memsetb
    5952
    60 /* Wrapper for generic memsetw */
     53# Wrapper for generic memsetw
    6154memsetw:
    6255        jmp _memsetw
    6356
    64 #define MEMCPY_DST   4
    65 #define MEMCPY_SRC   8
    66 #define MEMCPY_SIZE  12
     57
     58#define MEMCPY_DST      4
     59#define MEMCPY_SRC      8
     60#define MEMCPY_SIZE     12
    6761
    6862/** Copy memory to/from userspace.
     
    7468 * or copy_to_uspace().
    7569 *
    76  * @param MEMCPY_DST(%esp)  Destination address.
    77  * @param MEMCPY_SRC(%esp)  Source address.
    78  * @param MEMCPY_SIZE(%esp) Size.
     70 * @param MEMCPY_DST(%esp)      Destination address.
     71 * @param MEMCPY_SRC(%esp)      Source address.
     72 * @param MEMCPY_SIZE(%esp)     Size.
    7973 *
    8074 * @return MEMCPY_DST(%esp) on success and 0 on failure.
    81  *
    8275 */
    8376memcpy:
    8477memcpy_from_uspace:
    8578memcpy_to_uspace:
    86         movl %edi, %edx  /* save %edi */
    87         movl %esi, %eax  /* save %esi */
     79        movl %edi, %edx                 /* save %edi */
     80        movl %esi, %eax                 /* save %esi */
    8881       
    8982        movl MEMCPY_SIZE(%esp), %ecx
    90         shrl $2, %ecx  /* size / 4 */
     83        shrl $2, %ecx                   /* size / 4 */
    9184       
    9285        movl MEMCPY_DST(%esp), %edi
    9386        movl MEMCPY_SRC(%esp), %esi
    9487       
    95         /* Copy whole words */
    96         rep movsl
    97        
     88        rep movsl                       /* copy whole words */
     89
    9890        movl MEMCPY_SIZE(%esp), %ecx
    99         andl $3, %ecx  /* size % 4 */
     91        andl $3, %ecx                   /* size % 4 */
    10092        jz 0f
    10193       
    102         /* Copy the rest byte by byte */
    103         rep movsb
    104        
    105         0:
    106        
    107                 movl %edx, %edi
    108                 movl %eax, %esi
    109                
    110                 /* MEMCPY_DST(%esp), success */
    111                 movl MEMCPY_DST(%esp), %eax
    112                 ret
    113 
     94        rep movsb                       /* copy the rest byte by byte */
     95
     960:
     97        movl %edx, %edi
     98        movl %eax, %esi
     99        movl MEMCPY_DST(%esp), %eax     /* MEMCPY_DST(%esp), success */
     100        ret
     101       
    114102/*
    115103 * We got here from as_page_fault() after the memory operations
     
    120108        movl %edx, %edi
    121109        movl %eax, %esi
    122        
    123         /* Return 0, failure */
    124         xorl %eax, %eax
     110        xorl %eax, %eax                 /* return 0, failure */
    125111        ret
    126112
    127 /** Turn paging on
    128  *
    129  * Enable paging and write-back caching in CR0.
    130  *
    131  */
     113## Turn paging on
     114#
     115# Enable paging and write-back caching in CR0.
     116#
    132117paging_on:
    133118        movl %cr0, %edx
    134         orl $(1 << 31), %edx  /* paging on */
    135        
    136         /* Clear Cache Disable and not Write Though */
     119        orl $(1 << 31), %edx            # paging on
     120        # clear Cache Disable and not Write Though
    137121        andl $~((1 << 30) | (1 << 29)), %edx
    138         movl %edx, %cr0
     122        movl %edx,%cr0
    139123        jmp 0f
    140        
    141         0:
    142                 ret
    143 
    144 /** Enable local APIC
    145  *
    146  * Enable local APIC in MSR.
    147  *
    148  */
     1240:
     125        ret
     126
     127
     128## Enable local APIC
     129#
     130# Enable local APIC in MSR.
     131#
    149132enable_l_apic_in_msr:
    150133        movl $0x1b, %ecx
     
    155138        ret
    156139
    157 /** Clear nested flag
    158  *
    159  */
     140# Clear nested flag
     141# overwrites %ecx
    160142.macro CLEAR_NT_FLAG
    161143        pushfl
    162         andl $0xffffbfff, (%esp)
     144        pop %ecx
     145        and $0xffffbfff, %ecx
     146        push %ecx
    163147        popfl
    164 .endm
     148.endm   
    165149
    166150/*
     
    176160sysenter_handler:
    177161        sti
    178         pushl %ebp  /* remember user stack */
    179         pushl %edi  /* remember return user address */
    180        
    181         xorl %ebp, %ebp  /* stop stack traces here */
    182        
    183         pushl %gs  /* remember TLS */
    184        
    185         pushl %eax     /* syscall number */
    186         subl $8, %esp  /* unused sixth and fifth argument */
    187         pushl %esi     /* fourth argument */
    188         pushl %ebx     /* third argument */
    189         pushl %ecx     /* second argument */
    190         pushl %edx     /* first argument */
    191        
     162        pushl %ebp      # remember user stack
     163        pushl %edi      # remember return user address
     164
     165        pushl %gs       # remember TLS
     166
     167        pushl %eax      # syscall number
     168        subl $8, %esp   # unused sixth and fifth argument
     169        pushl %esi      # fourth argument
     170        pushl %ebx      # third argument
     171        pushl %ecx      # second argument
     172        pushl %edx      # first argument
     173
    192174        movw $16, %ax
    193175        movw %ax, %ds
    194176        movw %ax, %es
    195        
     177
    196178        cld
    197179        call syscall_handler
    198         addl $28, %esp  /* remove arguments from stack */
    199        
    200         pop %gs  /* restore TLS */
    201        
    202         pop %edx  /* prepare return EIP for SYSEXIT */
    203         pop %ecx  /* prepare userspace ESP for SYSEXIT */
    204        
    205         sysexit   /* return to userspace */
    206 
    207 #define ISTATE_OFFSET_EAX         0
    208 #define ISTATE_OFFSET_EBX         4
    209 #define ISTATE_OFFSET_ECX         8
    210 #define ISTATE_OFFSET_EDX         12
    211 #define ISTATE_OFFSET_EDI         16
    212 #define ISTATE_OFFSET_ESI         20
    213 #define ISTATE_OFFSET_EBP         24
    214 #define ISTATE_OFFSET_EBP_FRAME   28
    215 #define ISTATE_OFFSET_EIP_FRAME   32
    216 #define ISTATE_OFFSET_GS          36
    217 #define ISTATE_OFFSET_FS          40
    218 #define ISTATE_OFFSET_ES          44
    219 #define ISTATE_OFFSET_DS          48
    220 #define ISTATE_OFFSET_ERROR_WORD  52
    221 #define ISTATE_OFFSET_EIP         56
    222 #define ISTATE_OFFSET_CS          60
    223 #define ISTATE_OFFSET_EFLAGS      64
    224 #define ISTATE_OFFSET_ESP         68
    225 #define ISTATE_OFFSET_SS          72
    226 
    227 /*
    228  * Size of the istate structure without the hardware-saved part
    229  * and without the error word.
    230  */
    231 #define ISTATE_SOFT_SIZE  52
    232 
    233 /** Declare interrupt handlers
    234  *
    235  * Declare interrupt handlers for n interrupt
    236  * vectors starting at vector i.
    237  *
    238  * The handlers setup data segment registers
    239  * and call exc_dispatch().
    240  *
    241  */
    242 #define INTERRUPT_ALIGN  256
    243 
     180        addl $28, %esp  # remove arguments from stack
     181
     182        pop %gs         # restore TLS
     183
     184        pop %edx        # prepare return EIP for SYSEXIT
     185        pop %ecx        # prepare userspace ESP for SYSEXIT
     186
     187        sysexit         # return to userspace
     188
     189
     190## Declare interrupt handlers
     191#
     192# Declare interrupt handlers for n interrupt
     193# vectors starting at vector i.
     194#
     195# The handlers setup data segment registers
     196# and call exc_dispatch().
     197#
     198#define INTERRUPT_ALIGN 64
    244199.macro handler i n
    245         .ifeq \i - 0x30
    246                 /* Syscall handler */
     200       
     201        .ifeq \i - 0x30     # Syscall handler
    247202                pushl %ds
    248203                pushl %es
     
    250205                pushl %gs
    251206               
    252                 /*
    253                  * Push syscall arguments onto the stack
    254                  *
    255                  * NOTE: The idea behind the order of arguments passed
    256                  *       in registers is to use all scratch registers
    257                  *       first and preserved registers next. An optimized
    258                  *       libc syscall wrapper can make use of this setup.
    259                  *
    260                  */
     207                #
     208                # Push syscall arguments onto the stack
     209                #
     210                # NOTE: The idea behind the order of arguments passed in registers is to
     211                #       use all scratch registers first and preserved registers next.
     212                #       An optimized libc syscall wrapper can make use of this setup.
     213                #
    261214                pushl %eax
    262215                pushl %ebp
     
    267220                pushl %edx
    268221               
    269                 /* We must fill the data segment registers */
     222                # we must fill the data segment registers
    270223                movw $16, %ax
    271224                movw %ax, %ds
    272225                movw %ax, %es
    273226               
    274                 xorl %ebp, %ebp
    275                
    276227                cld
    277228                sti
    278                
    279                 /* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */
     229                # syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax)
    280230                call syscall_handler
    281231                cli
    282                
    283                 movl 20(%esp), %ebp  /* restore EBP */
    284                 addl $28, %esp       /* clean-up of parameters */
     232                addl $28, %esp         # clean-up of parameters
    285233               
    286234                popl %gs
     
    293241        .else
    294242                /*
    295                  * This macro distinguishes between two versions of ia32
    296                  * exceptions. One version has error word and the other
    297                  * does not have it. The latter version fakes the error
    298                  * word on the stack so that the handlers and istate_t
    299                  * can be the same for both types.
     243                 * This macro distinguishes between two versions of ia32 exceptions.
     244                 * One version has error word and the other does not have it.
     245                 * The latter version fakes the error word on the stack so that the
     246                 * handlers and istate_t can be the same for both types.
    300247                 */
    301248                .iflt \i - 32
    302249                        .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
    303250                                /*
    304                                  * Exception with error word: do nothing
     251                                 * With error word, do nothing
    305252                                 */
    306253                        .else
    307254                                /*
    308                                  * Exception without error word: fake up one
     255                                 * Version without error word
    309256                                 */
    310                                 pushl $0
     257                                subl $4, %esp
    311258                        .endif
    312259                .else
    313260                        /*
    314                          * Interrupt: fake up one
     261                         * Version without error word
    315262                         */
    316                         pushl $0
     263                        subl $4, %esp
    317264                .endif
    318265               
    319                 subl $ISTATE_SOFT_SIZE, %esp
    320                
    321                 /*
    322                  * Save the general purpose registers.
    323                  */
    324                 movl %eax, ISTATE_OFFSET_EAX(%esp)
    325                 movl %ebx, ISTATE_OFFSET_EBX(%esp)
    326                 movl %ecx, ISTATE_OFFSET_ECX(%esp)
    327                 movl %edx, ISTATE_OFFSET_EDX(%esp)
    328                 movl %edi, ISTATE_OFFSET_EDI(%esp)
    329                 movl %esi, ISTATE_OFFSET_ESI(%esp)
    330                 movl %ebp, ISTATE_OFFSET_EBP(%esp)
    331                
    332                 /*
    333                  * Save the selector registers.
    334                  */
    335                 movl %gs, %eax
    336                 movl %fs, %ebx
    337                 movl %es, %ecx
    338                 movl %ds, %edx
    339                
    340                 movl %eax, ISTATE_OFFSET_GS(%esp)
    341                 movl %ebx, ISTATE_OFFSET_FS(%esp)
    342                 movl %ecx, ISTATE_OFFSET_ES(%esp)
    343                 movl %edx, ISTATE_OFFSET_DS(%esp)
    344                
    345                 /*
    346                  * Switch to kernel selectors.
    347                  */
    348                 movl $16, %eax
    349                 movl %eax, %ds
    350                 movl %eax, %es
    351                
    352                 /*
    353                  * Imitate a regular stack frame linkage.
    354                  * Stop stack traces here if we came from userspace.
    355                  */
    356                 cmpl $8, ISTATE_OFFSET_CS(%esp)
    357                 jz 0f
     266                pushl %ds
     267                pushl %es
     268                pushl %fs
     269                pushl %gs
     270               
     271                pushl %ebp
     272                pushl %edx
     273                pushl %ecx
     274                pushl %eax
     275               
     276                # we must fill the data segment registers
     277               
     278                movw $16, %ax
     279                movw %ax, %ds
     280                movw %ax, %es
     281               
     282                # stop stack traces here
    358283                xorl %ebp, %ebp
    359284               
    360                 0:
    361                
    362                         movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp)
    363                         movl ISTATE_OFFSET_EIP(%esp), %eax
    364                         movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp)
    365                         leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp
    366                        
    367                         cld
    368                        
    369                         pushl %esp   /* pass istate address */
    370                         pushl $(\i)  /* pass intnum */
    371                        
    372                         /* Call exc_dispatch(intnum, istate) */
    373                         call exc_dispatch
    374                        
    375                         addl $8, %esp  /* clear arguments from the stack */
    376                        
    377                         CLEAR_NT_FLAG
    378                        
    379                         /*
    380                          * Restore the selector registers.
    381                          */
    382                         movl ISTATE_OFFSET_GS(%esp), %eax
    383                         movl ISTATE_OFFSET_FS(%esp), %ebx
    384                         movl ISTATE_OFFSET_ES(%esp), %ecx
    385                         movl ISTATE_OFFSET_DS(%esp), %edx
    386                        
    387                         movl %eax, %gs
    388                         movl %ebx, %fs
    389                         movl %ecx, %es
    390                         movl %edx, %ds
    391                        
    392                         /*
    393                          * Restore the scratch registers and the preserved
    394                          * registers the handler cloberred itself
    395                          * (i.e. EBX and EBP).
    396                          */
    397                         movl ISTATE_OFFSET_EAX(%esp), %eax
    398                         movl ISTATE_OFFSET_EBX(%esp), %ebx
    399                         movl ISTATE_OFFSET_ECX(%esp), %ecx
    400                         movl ISTATE_OFFSET_EDX(%esp), %edx
    401                         movl ISTATE_OFFSET_EBP(%esp), %ebp
    402                        
    403                         addl $(ISTATE_SOFT_SIZE + 4), %esp
    404                         iret
    405                
     285                pushl %esp          # *istate
     286                pushl $(\i)         # intnum
     287                call exc_dispatch   # exc_dispatch(intnum, *istate)
     288                addl $8, %esp       # Clear arguments from stack
     289               
     290                CLEAR_NT_FLAG # Modifies %ecx
     291               
     292                popl %eax
     293                popl %ecx
     294                popl %edx
     295                popl %ebp
     296               
     297                popl %gs
     298                popl %fs
     299                popl %es
     300                popl %ds
     301               
     302                # skip error word, no matter whether real or fake
     303                addl $4, %esp
     304                iret
    406305        .endif
    407306       
    408307        .align INTERRUPT_ALIGN
    409         .if (\n - \i) - 1
     308        .if (\n- \i) - 1
    410309                handler "(\i + 1)", \n
    411310        .endif
    412311.endm
    413312
    414 /* Keep in sync with pm.h! */
    415 #define IDT_ITEMS  64
    416 
     313# keep in sync with pm.h !!!
     314IDT_ITEMS = 64
    417315.align INTERRUPT_ALIGN
    418316interrupt_handlers:
    419         h_start:
    420                 handler 0 IDT_ITEMS
    421         h_end:
    422 
    423 /** Print Unicode character to EGA display.
    424  *
    425  * If CONFIG_EGA is undefined or CONFIG_FB is defined
    426  * then this function does nothing.
    427  *
    428  * Since the EGA can only display Extended ASCII (usually
    429  * ISO Latin 1) characters, some of the Unicode characters
    430  * can be displayed in a wrong way. Only the newline character
    431  * is interpreted, all other characters (even unprintable) are
    432  * printed verbatim.
    433  *
    434  * @param %ebp+0x08 Unicode character to be printed.
    435  *
    436  */
    437 early_putchar:
    438        
    439 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
    440        
    441         /* Prologue, save preserved registers */
    442         pushl %ebp
    443         movl %esp, %ebp
    444         pushl %ebx
    445         pushl %esi
    446         pushl %edi
    447        
    448         movl $(PA2KA(0xb8000)), %edi  /* base of EGA text mode memory */
    449         xorl %eax, %eax
    450        
    451         /* Read bits 8 - 15 of the cursor address */
    452         movw $0x3d4, %dx
    453         movb $0xe, %al
    454         outb %al, %dx
    455        
    456         movw $0x3d5, %dx
    457         inb %dx, %al
    458         shl $8, %ax
    459        
    460         /* Read bits 0 - 7 of the cursor address */
    461         movw $0x3d4, %dx
    462         movb $0xf, %al
    463         outb %al, %dx
    464        
    465         movw $0x3d5, %dx
    466         inb %dx, %al
    467        
    468         /* Sanity check for the cursor on screen */
    469         cmp $2000, %ax
    470         jb early_putchar_cursor_ok
    471        
    472                 movw $1998, %ax
    473        
    474         early_putchar_cursor_ok:
    475        
    476         movw %ax, %bx
    477         shl $1, %eax
    478         addl %eax, %edi
    479        
    480         movl 0x08(%ebp), %eax
    481        
    482         cmp $0x0a, %al
    483         jne early_putchar_print
    484        
    485                 /* Interpret newline */
    486                
    487                 movw %bx, %ax  /* %bx -> %dx:%ax */
    488                 xorw %dx, %dx
    489                
    490                 movw $80, %cx
    491                 idivw %cx, %ax  /* %dx = %bx % 80 */
    492                
    493                 /* %bx <- %bx + 80 - (%bx % 80) */
    494                 addw %cx, %bx
    495                 subw %dx, %bx
    496                
    497                 jmp early_putchar_newline
    498        
    499         early_putchar_print:
    500        
    501                 /* Print character */
    502                
    503                 movb $0x0e, %ah  /* black background, yellow foreground */
    504                 stosw
    505                 inc %bx
    506        
    507         early_putchar_newline:
    508        
    509         /* Sanity check for the cursor on the last line */
    510         cmp $2000, %bx
    511         jb early_putchar_no_scroll
    512        
    513                 /* Scroll the screen (24 rows) */
    514                 movl $(PA2KA(0xb80a0)), %esi
    515                 movl $(PA2KA(0xb8000)), %edi
    516                 movl $1920, %ecx
    517                 rep movsw
    518                
    519                 /* Clear the 24th row */
    520                 xorl %eax, %eax
    521                 movl $80, %ecx
    522                 rep stosw
    523                
    524                 /* Go to row 24 */
    525                 movw $1920, %bx
    526        
    527         early_putchar_no_scroll:
    528        
    529         /* Write bits 8 - 15 of the cursor address */
    530         movw $0x3d4, %dx
    531         movb $0xe, %al
    532         outb %al, %dx
    533        
    534         movw $0x3d5, %dx
    535         movb %bh, %al
    536         outb %al, %dx
    537        
    538         /* Write bits 0 - 7 of the cursor address */
    539         movw $0x3d4, %dx
    540         movb $0xf, %al
    541         outb %al, %dx
    542        
    543         movw $0x3d5, %dx
    544         movb %bl, %al
    545         outb %al, %dx
    546        
    547         /* Epilogue, restore preserved registers */
    548         popl %edi
    549         popl %esi
    550         popl %ebx
    551         leave
    552        
    553 #endif
    554        
    555         ret
     317h_start:
     318        handler 0 IDT_ITEMS
     319h_end:
    556320
    557321.data
Note: See TracChangeset for help on using the changeset viewer.