/SPARTAN/trunk/arch/amd64/src/boot/boot.S |
---|
39,13 → 39,55 |
# switch to protected mode. |
# |
kernel_image_start: |
cli |
xorw %ax,%ax |
movw %ax,%ds |
movw %ax,%ss # initialize stack segment register |
movl $0x7c00,%esp # initialize stack pointer |
call memmap_arch_init |
mov $0x80000000, %eax |
cpuid |
cmp $0x80000000, %eax # any function > 80000000h? |
jbe no_long_mode |
mov $0x80000001, %eax # Extended function code 80000001 |
cpuid |
bt $29, %edx # Test if long mode is supported. |
jnc no_long_mode |
meeting_point: |
.code32 |
# Fill out GDTR.base, IDTR.base |
leal gdtr, %eax |
movl gdt_addr, %ebx |
movl %ebx, 2(%eax) |
movl idt_addr, %ebx |
leal idtr, %eax |
movl %ebx, 2(%eax) |
.section K_DATA_START |
# Load gdtr, idtr |
lgdt gdtr |
lidt idtr |
mov $1, %eax # Enable protected mode (CR0.PE = 1) |
mov %eax, %cr0 |
jmpl $8, $now_in_prot |
now_in_prot: |
no_long_mode: |
1: |
jmp 1b |
.section K_DATA_START |
.align 4096 |
page_directory: |
.space 4096, 0 |
gdt_addr: |
.quad gdt + 0x80000000 |
idt_addr: |
.quad idt + 0x80000000 |
/SPARTAN/trunk/arch/amd64/src/boot/memmap.S |
---|
0,0 → 1,125 |
/* |
* Copyright (C) 2005 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <arch/boot/memmapasm.h> |
E820_RECORD_SIZE = MEMMAP_E820_RECORD_SIZE |
E820_MAX_RECORDS = MEMMAP_E820_MAX_RECORDS |
E820_SMAP = 0x534d4150 |
.global memmap_arch_init |
.global e820counter |
.global e820table |
.global e801memorysize |
.code16 |
.section K_TEXT_START_2 |
memmap_arch_init: |
e820begin: |
xorl %ebx,%ebx # during first call, ebx must be 0 |
movw %bx,%ds |
movw %bx,%es |
movw $e820table,%di |
movb $E820_MAX_RECORDS,e820counter |
e820loop: |
movl $E820_SMAP,%edx # control sequence "SMAP" |
movl $0x0000e820,%eax # service |
movl $E820_RECORD_SIZE,%ecx |
int $0x15 |
jc e820err |
cmpl $E820_SMAP,%eax # verifying BIOS |
jne e820err |
cmpl $E820_RECORD_SIZE,%ecx |
jne e820err # bad record size - bug in bios |
movw %di,%ax # next record |
addw $E820_RECORD_SIZE,%ax |
movw %ax,%di |
decb e820counter # buffer is full |
jz e820end |
cmpl $0,%ebx |
jne e820loop |
e820end: |
movb $E820_MAX_RECORDS,%al |
subb e820counter,%al |
movb %al,e820counter # store # of valid entries in e820counter |
jmp e801begin |
e820err: |
movb $0,e820counter |
# method e801 - get size of memory |
e801begin: |
xorw %dx,%dx |
xorw %cx,%cx |
xorw %bx,%bx |
movw $0xe801,%ax |
stc |
int $0x15 |
jc e801end |
# fix problem with some BIOSes which use ax:bx rather than cx:dx |
testw %cx,%cx |
jnz e801cxdx |
testw %dx,%dx |
jnz e801cxdx |
movw %ax,%cx |
movw %bx,%dx |
e801cxdx: |
andl $0xffff,%edx |
shll $6,%edx |
andl $0xffff,%ecx |
addl %ecx,%edx |
addl $0x0400,%edx # add lower 1 MB - it's not included by e801 method |
movl %edx,e801memorysize |
e801end: |
ret |
#memory size in 1 kb chunks |
e801memorysize: |
.long 0 |
e820counter: |
.byte 0xff |
e820table: |
.space (32*E820_RECORD_SIZE),0xff # space for 32 records, each E820_RECORD_SIZE bytes long |
/SPARTAN/trunk/arch/amd64/src/pm.c |
---|
0,0 → 1,98 |
/* |
* Copyright (C) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <arch/pm.h> |
#include <arch/mm/page.h> |
#include <arch/types.h> |
/* |
* There is no segmentation in long mode so we set up flat mode. In this |
* mode, we use, for each privilege level, two segments spanning the |
* whole memory. One is for code and one is for data. |
*/ |
struct descriptor gdt[GDT_ITEMS] = { |
/* NULL descriptor */ |
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
/* KTEXT descriptor */ |
{ .limit_0_15 = 0xffff, |
.base_0_15 = 0, |
.base_16_23 = 0, |
.access = AR_PRESENT | AR_CODE | DPL_KERNEL, |
.limit_16_19 = 0xf, |
.available = 0, |
.longmode = 1, |
.special = 0, |
.granularity = 1, |
.base_24_31 = 0 }, |
/* KDATA descriptor */ |
{ .limit_0_15 = 0xffff, |
.base_0_15 = 0, |
.base_16_23 = 0, |
.access = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, |
.limit_16_19 = 0xf, |
.available = 0, |
.longmode = 0, |
.special = 0, |
.granularity = 0, |
.base_24_31 = 0 }, |
/* UTEXT descriptor */ |
{ .limit_0_15 = 0xffff, |
.base_0_15 = 0, |
.base_16_23 = 0, |
.access = AR_PRESENT | AR_CODE | DPL_USER, |
.limit_16_19 = 0xf, |
.available = 0, |
.longmode = 1, |
.special = 0, |
.granularity = 0, |
.base_24_31 = 0 }, |
/* UDATA descriptor */ |
{ .limit_0_15 = 0xffff, |
.base_0_15 = 0, |
.base_16_23 = 0, |
.access = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, |
.limit_16_19 = 0xf, |
.available = 0, |
.longmode = 0, |
.special = 1, |
.granularity = 1, |
.base_24_31 = 0 }, |
/* TSS descriptor - set up will be completed later */ |
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
}; |
struct idescriptor idt[IDT_ITEMS]; |
static struct tss tss; |
/* gdtr is changed by kmp before next CPU is initialized */ |
struct ptr_16_32 gdtr __attribute__ ((section ("K_DATA_START"))) = { .limit = sizeof(gdt) }; |
//struct ptr_16_32 gdtr __attribute__ ((section ("K_DATA_START"))) = { .limit = sizeof(gdt), .base = KA2PA((__address) gdt) }; |
struct ptr_16_32 idtr __attribute__ ((section ("K_DATA_START"))) = { .limit = sizeof(idt) }; |