Fork me on GitHub

root/kernel/core386.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /*
   2  * fiwix/kernel/core386.S
   3  *
   4  * Copyright 2018, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/const.h>
   9 #include <fiwix/unistd.h>
  10 
  11 #define CR0_MP  ~(0x00000002)   /* CR0 bit-01 MP (Monitor Coprocessor) */
  12 #define CR0_EM  0x00000004      /* CR0 bit-02 EM (Emulation) */
  13 
  14 #define SS_RPL3         0x03    /* Request Privilege Level 3 */
  15 
  16 #define GS              0x00
  17 #define FS              0x04
  18 #define ES              0x08
  19 #define DS              0x0C
  20 #define EDI             0x10    /* \                            */
  21 #define ESI             0x14    /* |                            */
  22 #define EBP             0x18    /* |                            */
  23 #define ESP             0x1C    /* | saved by                   */
  24 #define EBX             0x20    /* | 'pusha'                    */
  25 #define EDX             0x24    /* |                            */
  26 #define ECX             0x28    /* |                            */
  27 #define EAX             0x2C    /* /                            */
  28 #define ERR             0x30    /*   error code or padding      */
  29 #define EIP             0x34    /* \                            */
  30 #define CS              0x38    /* | saved by processor         */
  31 #define FLAGS           0x3C    /* /                            */
  32 #define OLDESP          0x40    /* \ saved by processor on      */
  33 #define OLDSS           0x44    /* / privilege level change     */
  34 
  35 #define SAVE_ALL                                                        \
  36         pushal                                                          ;\
  37         pushl   %ds                                                     ;\
  38         pushl   %es                                                     ;\
  39         pushl   %fs                                                     ;\
  40         pushl   %gs
  41 
  42 #define EXCEPTION(exception)                                            \
  43         pushl   $exception                                              ;\
  44         call    trap_handler                                            ;\
  45         addl    $4, %esp
  46 
  47 #define IRQ(irq)                                                        \
  48         pushl   $irq                                                    ;\
  49         call    irq_handler                                             ;\
  50         addl    $4, %esp
  51 
  52 #define BOTTOM_HALVES                                                   \
  53         cmpl    $0, intr_count                                          ;\
  54         jne     2f                                                      ;\
  55         incl    intr_count                                              ;\
  56         call    do_bh                                                   ;\
  57         decl    intr_count
  58 
  59 #define CHECK_SIGNALS                                                   \
  60         call    issig                                                   ;\
  61         cmpl    $0, %eax                                                ;\
  62         je      1f                                                      ;\
  63         movl    %esp, %eax                                              ;\
  64         pushl   %eax                                                    ;\
  65         call    psig                                                    ;\
  66         addl    $4, %esp                                                ;\
  67 1:
  68 
  69 #define SCHEDULE                                                        \
  70         cmpl    $0, need_resched                                        ;\
  71         je      2f                                                      ;\
  72         call    do_sched                                                ;\
  73 2:
  74 
  75 #define RESTORE_ALL                                                     \
  76         popl    %gs                                                     ;\
  77         popl    %fs                                                     ;\
  78         popl    %es                                                     ;\
  79         popl    %ds                                                     ;\
  80         popal                                                           ;\
  81         addl    $4, %esp        /* suppress error code from stack */
  82 
  83 
  84 .text
  85 
  86 .align 4
  87 .globl except0; except0:        # DIVIDE ERROR
  88         pushl   $0              # save simulated error code to stack
  89         SAVE_ALL
  90         EXCEPTION(0x0)
  91         BOTTOM_HALVES
  92         CHECK_SIGNALS
  93         SCHEDULE
  94         RESTORE_ALL
  95         iret
  96 
  97 .align 4
  98 .globl except1; except1:        # DEBUG
  99         pushl   $0              # save simulated error code to stack
 100         SAVE_ALL
 101         EXCEPTION(0x1)
 102         BOTTOM_HALVES
 103         CHECK_SIGNALS
 104         SCHEDULE
 105         RESTORE_ALL
 106         iret
 107 
 108 .align 4
 109 .globl except2; except2:        # NMI INTERRUPT
 110         pushl   $0              # save simulated error code to stack
 111         SAVE_ALL
 112         EXCEPTION(0x2)
 113         BOTTOM_HALVES
 114         CHECK_SIGNALS
 115         SCHEDULE
 116         RESTORE_ALL
 117         iret
 118 
 119 .align 4
 120 .globl except3; except3:        # BREAKPOINT INT3
 121         pushl   $0              # save simulated error code to stack
 122         SAVE_ALL
 123         EXCEPTION(0x3)
 124         BOTTOM_HALVES
 125         CHECK_SIGNALS
 126         SCHEDULE
 127         RESTORE_ALL
 128         iret
 129 
 130 .align 4
 131 .globl except4; except4:        # OVERFLOW
 132         pushl   $0              # save simulated error code to stack
 133         SAVE_ALL
 134         EXCEPTION(0x4)
 135         BOTTOM_HALVES
 136         CHECK_SIGNALS
 137         SCHEDULE
 138         RESTORE_ALL
 139         iret
 140 
 141 .align 4
 142 .globl except5; except5:        # BOUND
 143         pushl   $0              # save simulated error code to stack
 144         SAVE_ALL
 145         EXCEPTION(0x5)
 146         BOTTOM_HALVES
 147         CHECK_SIGNALS
 148         SCHEDULE
 149         RESTORE_ALL
 150         iret
 151 
 152 .align 4
 153 .globl except6; except6:        # INVALID OPCODE
 154         pushl   $0              # save simulated error code to stack
 155         SAVE_ALL
 156         EXCEPTION(0x6)
 157         BOTTOM_HALVES
 158         CHECK_SIGNALS
 159         SCHEDULE
 160         RESTORE_ALL
 161         iret
 162 
 163 .align 4
 164 .globl except7; except7:        # NO MATH COPROCESSOR
 165         pushl   $0              # save simulated error code to stack
 166         SAVE_ALL
 167         EXCEPTION(0x7)
 168         clts                    # floating-opcode cached!
 169         BOTTOM_HALVES
 170         CHECK_SIGNALS
 171         SCHEDULE
 172         RESTORE_ALL
 173         iret
 174 
 175 .align 4
 176 .globl except8; except8:        # DOUBLE FAULT
 177         SAVE_ALL
 178         EXCEPTION(0x8)
 179         BOTTOM_HALVES
 180         CHECK_SIGNALS
 181         SCHEDULE
 182         RESTORE_ALL
 183         iret
 184 
 185 .align 4
 186 .globl except9; except9:        # COPROCESSOR SEGMENT OVERRUN
 187         pushl   $0              # save simulated error code to stack
 188         SAVE_ALL
 189         EXCEPTION(0x9)
 190         BOTTOM_HALVES
 191         CHECK_SIGNALS
 192         SCHEDULE
 193         RESTORE_ALL
 194         iret
 195 
 196 .align 4
 197 .globl exceptA; exceptA:        # INVALID TSS
 198         SAVE_ALL
 199         EXCEPTION(0xA)
 200         BOTTOM_HALVES
 201         CHECK_SIGNALS
 202         SCHEDULE
 203         RESTORE_ALL
 204         iret
 205 
 206 .align 4
 207 .globl exceptB; exceptB:        # SEGMENT NOT PRESENT
 208         SAVE_ALL
 209         EXCEPTION(0xB)
 210         BOTTOM_HALVES
 211         CHECK_SIGNALS
 212         SCHEDULE
 213         RESTORE_ALL
 214         iret
 215 
 216 .align 4
 217 .globl exceptC; exceptC:        # STACK SEGMENT FAULT
 218         SAVE_ALL
 219         EXCEPTION(0xC)
 220         BOTTOM_HALVES
 221         CHECK_SIGNALS
 222         SCHEDULE
 223         RESTORE_ALL
 224         iret
 225 
 226 .align 4
 227 .globl exceptD; exceptD:        # GENERAL PROTECTION FAULT
 228         SAVE_ALL
 229         EXCEPTION(0xD)
 230         BOTTOM_HALVES
 231         CHECK_SIGNALS
 232         SCHEDULE
 233         RESTORE_ALL
 234         iret
 235 
 236 .align 4
 237 .globl exceptE; exceptE:        # PAGE FAULT
 238         SAVE_ALL
 239         EXCEPTION(0xE)
 240         BOTTOM_HALVES
 241         CHECK_SIGNALS
 242         SCHEDULE
 243         RESTORE_ALL
 244         iret
 245 
 246 .align 4
 247 .globl exceptF; exceptF:        # INTEL RESERVED
 248         pushl   $0              # save simulated error code to stack
 249         SAVE_ALL
 250         EXCEPTION(0xF)
 251         BOTTOM_HALVES
 252         CHECK_SIGNALS
 253         SCHEDULE
 254         RESTORE_ALL
 255         iret
 256 
 257 .globl except10; except10:      # FLOATING POINT ERROR
 258         pushl   $0              # save simulated error code to stack
 259         SAVE_ALL
 260         EXCEPTION(0x10)
 261         BOTTOM_HALVES
 262         CHECK_SIGNALS
 263         SCHEDULE
 264         RESTORE_ALL
 265         iret
 266 
 267 .globl except11; except11:      # ALIGNMENT CHECK
 268         EXCEPTION(0x11)
 269         SAVE_ALL
 270         BOTTOM_HALVES
 271         CHECK_SIGNALS
 272         SCHEDULE
 273         RESTORE_ALL
 274         iret
 275 
 276 .globl except12; except12:      # MACHINE CHECK
 277         pushl   $0              # save simulated error code to stack
 278         SAVE_ALL
 279         EXCEPTION(0x12)
 280         BOTTOM_HALVES
 281         CHECK_SIGNALS
 282         SCHEDULE
 283         RESTORE_ALL
 284         iret
 285 
 286 .globl except13; except13:      # SIMD FLOATING POINT
 287         pushl   $0              # save simulated error code to stack
 288         SAVE_ALL
 289         EXCEPTION(0x13)
 290         BOTTOM_HALVES
 291         CHECK_SIGNALS
 292         SCHEDULE
 293         RESTORE_ALL
 294         iret
 295 
 296 .globl except14; except14:      # INTEL RESERVED
 297 .globl except15; except15:      # INTEL RESERVED
 298 .globl except16; except16:      # INTEL RESERVED
 299 .globl except17; except17:      # INTEL RESERVED
 300 .globl except18; except18:      # INTEL RESERVED
 301 .globl except19; except19:      # INTEL RESERVED
 302 .globl except1A; except1A:      # INTEL RESERVED
 303 .globl except1B; except1B:      # INTEL RESERVED
 304 .globl except1C; except1C:      # INTEL RESERVED
 305 .globl except1D; except1D:      # INTEL RESERVED
 306 .globl except1E; except1E:      # INTEL RESERVED
 307 .globl except1F; except1F:      # INTEL RESERVED
 308         pushl   $0              # save simulated error code to stack
 309         SAVE_ALL
 310         EXCEPTION(0x14)
 311         BOTTOM_HALVES
 312         CHECK_SIGNALS
 313         SCHEDULE
 314         RESTORE_ALL
 315         iret
 316 
 317 
 318 #define BUILD_IRQ(num, name)                                            \
 319 .align 4                                                                ;\
 320 .globl name; name:                                                      ;\
 321         pushl   $0              /* save simulated error code to stack */;\
 322         SAVE_ALL                                                        ;\
 323         IRQ(num)                                                        ;\
 324         BOTTOM_HALVES                                                   ;\
 325         CHECK_SIGNALS                                                   ;\
 326         SCHEDULE                                                        ;\
 327         RESTORE_ALL                                                     ;\
 328         iret
 329 
 330 BUILD_IRQ(0, irq0)
 331 BUILD_IRQ(1, irq1)
 332 BUILD_IRQ(2, irq2)
 333 BUILD_IRQ(3, irq3)
 334 BUILD_IRQ(4, irq4)
 335 BUILD_IRQ(5, irq5)
 336 BUILD_IRQ(6, irq6)
 337 BUILD_IRQ(7, irq7)
 338 BUILD_IRQ(8, irq8)
 339 BUILD_IRQ(9, irq9)
 340 BUILD_IRQ(10, irq10)
 341 BUILD_IRQ(11, irq11)
 342 BUILD_IRQ(12, irq12)
 343 BUILD_IRQ(13, irq13)
 344 BUILD_IRQ(14, irq14)
 345 BUILD_IRQ(15, irq15)
 346 
 347 .align 4
 348 .globl unknown_irq; unknown_irq:
 349         pushl   $0              # save simulated error code to stack
 350         SAVE_ALL
 351         IRQ(-1)
 352         RESTORE_ALL
 353         iret
 354 
 355 .align 4
 356 .globl switch_to_user_mode; switch_to_user_mode:
 357         cli
 358         xorl    %eax, %eax              # initialize %eax
 359         movl    %eax, %ebx              # initialize %ebx
 360         movl    %eax, %ecx              # initialize %ecx
 361         movl    %eax, %edx              # initialize %edx
 362         movl    %eax, %esi              # initialize %esi
 363         movl    %eax, %edi              # initialize %edi
 364         movl    %eax, %ebp              # initialize %ebp
 365         movl    $(USER_DS | SS_RPL3), %eax
 366         movw    %ax, %ds
 367         movw    %ax, %es
 368         movw    %ax, %fs
 369         movw    %ax, %gs
 370         pushl   %eax
 371         pushl   $KERNEL_BASE_ADDR - 4   # user stack address
 372         pushl   $0x202                  # initialize eflags (Linux 2.2 = 0x292)
 373         popfl
 374         pushfl
 375         movl    $(USER_CS | SS_RPL3), %eax
 376         pushl   %eax
 377         pushl   $KERNEL_BASE_ADDR - 0x1000      # go to init_trampoline() in user mode
 378         iret
 379 
 380 .align 4
 381 .globl sighandler_trampoline; sighandler_trampoline:
 382         /*
 383          * This pushes twice the %eax register in order to save the 'signum'
 384          * value from being clobbered by functions like printf(), during the
 385          * signal handler calling.
 386          * FIXME: is this a bug in Newlib or in my side?
 387          */
 388         pushl   %eax                    # save 'signum'
 389         pushl   %eax                    # 'signum' is the argument of the handler
 390         call    *%ecx
 391         addl    $4, %esp                # discard the first push
 392         popl    %ebx                    # restore 'signum'
 393 
 394         movl    $SYS_sigreturn, %eax
 395         int     $0x80
 396 
 397         # never reached, otherwise call sys_exit()
 398         movl    $SYS_exit, %eax
 399         int     $0x80
 400         ret
 401 .align 4
 402 .globl end_sighandler_trampoline; end_sighandler_trampoline:
 403         nop
 404 
 405 .align 4
 406 .globl syscall; syscall:                # SYSTEM CALL ENTRY
 407         pushl   %eax                    # save the system call number
 408         SAVE_ALL
 409 
 410         pushl   %edi                    # \ 5th argument
 411         pushl   %esi                    # | 4th argument
 412         pushl   %edx                    # | 3rd argument
 413         pushl   %ecx                    # | 2nd argument
 414         pushl   %ebx                    # / 1st argument
 415         pushl   %eax                    # system call number
 416         call    do_syscall
 417         addl    $24, %esp               # suppress all 6 pushl from the stack
 418         movl    %eax, EAX(%esp)         # save the return value
 419 
 420         BOTTOM_HALVES
 421         CHECK_SIGNALS
 422         SCHEDULE
 423 .align 4
 424 .globl return_from_syscall; return_from_syscall:
 425         RESTORE_ALL
 426         iret
 427 
 428 .align 4
 429 .globl do_switch; do_switch:
 430         movl    %esp, %ebx
 431         pushal
 432         pushfl
 433         movl    0x4(%ebx), %eax         # save ESP to 'prev->tss.esp'
 434         movl    %esp, (%eax)
 435         movl    0x8(%ebx), %eax         # save EIP to 'prev->tss.eip'
 436         movl    $1f, (%eax)
 437         movl    0xC(%ebx), %esp         # load 'next->tss.esp' into ESP
 438         pushl   0x10(%ebx)              # push 'next->tss.eip' into ESP
 439         movl    0x14(%ebx), %eax        # load 'next->tss.cr3' into CR3
 440         ltr     0x18(%ebx)              # load TSS
 441         movl    %eax, %cr3
 442         ret
 443 1:
 444         popfl
 445         popal
 446 
 447 .align 4
 448 .globl cpuid; cpuid:
 449         pushl   %ebp
 450         movl    %esp, %ebp
 451         pushl   %edi
 452         pushl   %esi
 453         pushl   %ebx
 454 
 455         pushf
 456         pop     %eax                    # put original EFLAGS in EAX
 457         mov     %eax, %ecx              # save original EFLAGS in ECX
 458         xor     $0x200000, %eax         # change bit 21 (ID) in EFLAGS
 459         push    %eax                    # save new EFLAGS on stack
 460         popf                            # replace current EFLAGS
 461         pushf
 462         pop     %eax                    # put EFLAGS in EAX
 463         cmp     %ecx, %eax              # compare if both EFLAGS are equal
 464 
 465         je      test386                 # can't toggle ID bit, no CPUID
 466         xor     %ebx, %ebx              # CPUID available, will return 0
 467         jmp     end_cpuid 
 468 
 469 test386:
 470         mov     %ecx, %eax              # get original EFLAGS
 471         xor     $0x40000, %eax          # change bit 18 (AC) in EFLAGS
 472         push    %eax                    # save new EFLAGS on stack
 473         popf                            # replace current EFLAGS
 474         pushf
 475         pop     %eax
 476         cmp     %ecx, %eax              # compare if both EFLAGS are equal
 477         movb    $3, %bl                 # looks like an i386, return 3
 478         je      end_cpuid
 479         movb    $4, %bl                 # otherwise is an old i486, return 4
 480 
 481 end_cpuid:
 482         push    %ecx                    # push original EFLAGS
 483         popf                            # restore original EFLAGS
 484         xor     %eax, %eax
 485         movb    %bl, %al                # put return value to AL
 486 
 487         popl    %ebx
 488         popl    %esi
 489         popl    %edi
 490         popl    %ebp
 491         ret
 492 
 493 .align 4
 494 .globl getfpu; getfpu:
 495         pushl   %ebp
 496         movl    %esp, %ebp
 497         pushl   %edi
 498         pushl   %esi
 499         pushl   %ebx
 500 
 501         fninit
 502         movl    $0x5a5a, _fpstatus
 503         fnstsw  _fpstatus
 504         movl    _fpstatus, %eax
 505         cmp     $0, %al
 506         movl    $0, _fpstatus
 507         jne     end_getfpu
 508 
 509 check_control_word:
 510         fnstcw  _fpstatus
 511         movl    _fpstatus, %eax
 512         andl    $0x103f, %eax
 513         cmp     $0x3f, %ax
 514         movl    $0, _fpstatus
 515         jne     end_getfpu
 516         movl    $1, _fpstatus
 517 
 518 end_getfpu:
 519         movl    _fpstatus, %eax
 520         cmp     $0, %al
 521         jne     1f                      # return if there is a coprocessor
 522         movl    %cr0, %eax              # otherwise (no math processor):
 523         orl     $CR0_EM, %eax           # - set   EM (Emulation)
 524         andl    $CR0_MP, %eax           # - clear MP (Monitor Coprocessor)
 525         movl    %eax, %cr0
 526         movl    $0, %eax
 527 1:
 528         popl    %ebx
 529         popl    %esi
 530         popl    %edi
 531         popl    %ebp
 532         ret
 533 
 534 .align 4
 535 .globl vendor_id; vendor_id:
 536         pushl   %ebp
 537         movl    %esp, %ebp
 538         pushl   %ebx
 539         pushl   %edx
 540         pushl   %ecx
 541 
 542         mov     $0, %eax
 543         cpuid
 544         movl    %ebx, _vendorid         # save the 12 bytes of vendor ID string
 545         movl    %edx, _vendorid+4
 546         movl    %ecx, _vendorid+8
 547 
 548         popl    %ecx
 549         popl    %edx
 550         popl    %ebx
 551         popl    %ebp
 552         ret                             # EAX returns the highest CPUID value
 553 
 554 .align 4
 555 .globl signature_flags; signature_flags:
 556         pushl   %ebp
 557         movl    %esp, %ebp
 558         pushl   %edi
 559         pushl   %esi
 560         pushl   %ebx
 561         pushl   %edx
 562 
 563         mov     $1, %eax
 564         cpuid
 565         movl    %eax, _cpusignature     # signature (model and stepping)
 566         movl    %ebx, _brandid          # misc. information
 567         movl    %edx, _cpuflags         # feature flags
 568         shrl    $8, %eax
 569         andl    $0xF, %eax
 570         movl    %eax, _cputype          # family
 571 
 572         popl    %edx
 573         popl    %ebx
 574         popl    %esi
 575         popl    %edi
 576         popl    %ebp
 577         ret
 578 
 579 .align 4
 580 .globl brand_str; brand_str:
 581         pushl   %ebp
 582         movl    %esp, %ebp
 583         pushl   %edi
 584         pushl   %esi
 585         pushl   %ebx
 586 
 587         movl    $0x80000000, %eax
 588         cpuid
 589         cmp     $0x80000000, %eax       # check if brand string is supported
 590         jbe     no_brand_str
 591         movl    $0x80000002, %eax       # get first 16 bytes of brand string
 592         cpuid
 593         movl    %eax, _brandstr
 594         movl    %ebx, _brandstr+4
 595         movl    %ecx, _brandstr+8
 596         movl    %edx, _brandstr+12
 597         movl    $0x80000003, %eax       # get more 16 bytes of brand string
 598         cpuid
 599         movl    %eax, _brandstr+16
 600         movl    %ebx, _brandstr+20
 601         movl    %ecx, _brandstr+24
 602         movl    %edx, _brandstr+28
 603         movl    $0x80000004, %eax       # get last 16 bytes of brand string
 604         cpuid
 605         movl    %eax, _brandstr+32
 606         movl    %ebx, _brandstr+36
 607         movl    %ecx, _brandstr+40
 608         movl    %edx, _brandstr+44
 609         jmp     end_brand_str
 610 
 611 no_brand_str:
 612         movl    $1, %eax
 613 
 614 end_brand_str:
 615         movl    $0, %eax
 616         popl    %ebx
 617         popl    %esi
 618         popl    %edi
 619         popl    %ebp
 620         ret
 621 
 622 .align 4
 623 .globl tlbinfo; tlbinfo:
 624         pushl   %edx
 625         pushl   %ecx
 626         mov     $2, %eax
 627         cpuid
 628         movl    %eax, _tlbinfo_eax      # store cache information
 629         movl    %ebx, _tlbinfo_ebx
 630         movl    %edx, _tlbinfo_ecx
 631         movl    %ecx, _tlbinfo_edx
 632         popl    %ecx
 633         popl    %edx
 634         ret
 635 
 636 .align 4
 637 .globl inport_b; inport_b:
 638         pushl   %ebp
 639         movl    %esp, %ebp
 640 
 641         movw    0x08(%ebp), %dx         # port addr
 642         inb     %dx, %al
 643 
 644         jmp     1f                      # recovery time
 645 1:      jmp     1f                      # recovery time
 646 1:      popl    %ebp
 647         ret
 648 
 649 .align 4
 650 .globl inport_w; inport_w:
 651         pushl   %ebp
 652         movl    %esp, %ebp
 653 
 654         movw    0x08(%ebp), %dx         # port addr
 655         inw     %dx, %ax
 656 
 657         jmp     1f                      # recovery time
 658 1:      jmp     1f                      # recovery time
 659 1:      popl    %ebp
 660         ret
 661 
 662 .align 4
 663 .globl inport_sw; inport_sw:
 664         pushl   %ebp
 665         movl    %esp, %ebp
 666         pushl   %edx
 667         pushl   %edi
 668         pushl   %ecx
 669 
 670         cld
 671         mov     0x8(%ebp), %edx         # port addr
 672         mov     0xC(%ebp), %edi         # dest
 673         mov     0x10(%ebp), %ecx        # count
 674         rep
 675         insw
 676 
 677         popl    %ecx
 678         popl    %edi
 679         popl    %edx
 680         popl    %ebp
 681         ret
 682 
 683 .align 4
 684 .globl outport_b; outport_b:
 685         pushl   %ebp
 686         movl    %esp, %ebp
 687 
 688         movw    0x8(%ebp), %dx          # port addr
 689         movb    0xC(%ebp), %al          # data
 690         outb    %al, %dx
 691 
 692         jmp     1f                      # recovery time
 693 1:      jmp     1f                      # recovery time
 694 1:      popl    %ebp
 695         ret
 696 
 697 .align 4
 698 .globl outport_w; outport_w:
 699         pushl   %ebp
 700         movl    %esp, %ebp
 701 
 702         movw    0x8(%ebp), %dx          # port addr
 703         movw    0xC(%ebp), %ax          # data
 704         outw    %ax, %dx
 705 
 706         jmp     1f                      # recovery time
 707 1:      jmp     1f                      # recovery time
 708 1:      popl    %ebp
 709         ret
 710 
 711 .align 4
 712 .globl outport_sw; outport_sw:
 713         pushl   %ebp
 714         movl    %esp, %ebp
 715         pushl   %edx
 716         pushl   %esi
 717         pushl   %ecx
 718 
 719         cld
 720         mov     0x8(%ebp), %edx         # port addr
 721         mov     0xC(%ebp), %esi         # src
 722         mov     0x10(%ebp), %ecx        # count
 723         rep
 724         outsw
 725 
 726         popl    %ecx
 727         popl    %esi
 728         popl    %edx
 729         popl    %ebp
 730         ret
 731 
 732 .align 4
 733 .globl load_gdt; load_gdt:
 734         movl    0x4(%esp), %eax
 735         lgdt    (%eax)
 736         movw    $KERNEL_DS, %ax
 737         movw    %ax, %ds
 738         movw    %ax, %es
 739         movw    %ax, %fs
 740         movw    %ax, %gs
 741         movw    %ax, %ss
 742         ljmp    $KERNEL_CS, $1f
 743 1:
 744         ret
 745 
 746 .align 4
 747 .globl load_idt; load_idt:
 748         movl    0x4(%esp), %eax
 749         lidt    (%eax)
 750         ret
 751 
 752 .align 4
 753 .globl activate_kpage_dir; activate_kpage_dir:
 754         movl    kpage_dir, %eax
 755         movl    %eax, %cr3
 756         ret
 757 
 758 .align 4
 759 .globl load_tr; load_tr:
 760         mov     0x4(%esp), %ax
 761         ltr     %ax
 762         ret
 763 
 764 .align 4
 765 .globl get_rdtsc; get_rdtsc:
 766         cpuid
 767         rdtsc
 768         ret
 769 
 770 .align 4
 771 .globl invalidate_tlb; invalidate_tlb:
 772         movl    %cr3, %eax
 773         movl    %eax, %cr3
 774         ret
 775 
 776 
 777 .data
 778 
 779 .globl  _cputype
 780 .globl  _cpusignature
 781 .globl  _cpuflags
 782 .globl  _fpstatus
 783 .globl  _brandid
 784 .globl  _vendorid
 785 .globl  _brandstr
 786 .globl  _tlbinfo_eax
 787 .globl  _tlbinfo_ebx
 788 .globl  _tlbinfo_ecx
 789 .globl  _tlbinfo_edx
 790 
 791 _cputype:       .int    0
 792 _cpusignature:  .int    0
 793 _cpuflags:      .int    0
 794 _fpstatus:      .int    0
 795 _brandid:       .int    0
 796 _vendorid:      .fill   13,1,0
 797 _brandstr:      .fill   49,1,0
 798 _tlbinfo_eax:   .int    0
 799 _tlbinfo_ebx:   .int    0
 800 _tlbinfo_ecx:   .int    0
 801 _tlbinfo_edx:   .int    0

/* [previous][next][first][last][top][bottom][index][help] */