| // Copyright 2010 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Manipulation of segment tables. |
| // |
| // Descriptor entry format for system call |
| // is the native machine format, ugly as it is: |
| // |
| // 2-byte limit |
| // 3-byte base |
| // 1-byte: 0x80=present, 0x60=dpl<<5, 0x1F=type |
| // 1-byte: 0x80=limit is *4k, 0x40=32-bit operand size, |
| // 0x0F=4 more bits of limit |
| // 1 byte: 8 more bits of base |
| |
| // Called to set up memory hardware. |
| // Already running in 32-bit mode thanks to boot block, |
| // but we need to install our new GDT that we can modify. |
| TEXT runtime·msetup(SB), 7, $0 |
| MOVL runtime·gdtptr(SB), GDTR |
| MOVL $(1*8+0), AX |
| MOVW AX, DS |
| MOVW AX, ES |
| MOVW AX, SS |
| MOVW $0, AX |
| MOVW AX, FS |
| MOVW AX, GS |
| |
| // long jmp to cs:mret |
| BYTE $0xEA |
| LONG $runtime·mret(SB) |
| WORD $(2*8+0) |
| |
| TEXT runtime·mret(SB), 7, $0 |
| RET |
| |
| // GDT memory |
| TEXT runtime·gdt(SB), 7, $0 |
| // null segment |
| LONG $0 |
| LONG $0 |
| |
| // 4GB data segment |
| LONG $0xFFFF |
| LONG $0x00CF9200 |
| |
| // 4GB code segment |
| LONG $0xFFFF |
| LONG $0x00CF9A00 |
| |
| // null segment (will be thread-local storage segment) |
| LONG $0 |
| LONG $0 |
| |
| // GDT pseudo-descriptor |
| TEXT runtime·gdtptr(SB), 7, $0 |
| WORD $(4*8) |
| LONG $runtime·gdt(SB) |
| |
| // Called to establish the per-thread segment. |
| // Write to gdt[3] and reload the gdt register. |
| // setldt(int entry, int address, int limit) |
| TEXT runtime·setldt(SB),7,$32 |
| MOVL address+4(FP), BX // aka base |
| MOVL limit+8(FP), CX |
| |
| // set up segment descriptor |
| LEAL gdt+(3*8)(SB), AX // gdt entry #3 |
| MOVL $0, 0(AX) |
| MOVL $0, 4(AX) |
| |
| MOVW BX, 2(AX) |
| SHRL $16, BX |
| MOVB BX, 4(AX) |
| SHRL $8, BX |
| MOVB BX, 7(AX) |
| |
| MOVW CX, 0(AX) |
| SHRL $16, CX |
| ANDL $0x0F, CX |
| ORL $0x40, CX // 32-bit operand size |
| MOVB CX, 6(AX) |
| MOVB $0xF2, 5(AX) // r/w data descriptor, dpl=3, present |
| |
| MOVL runtime·gdtptr(SB), GDTR |
| |
| // Compute segment selector - (entry*8+0) |
| MOVL $(3*8+0), AX |
| MOVW AX, GS |
| RET |
| |