From e5b0e0b5e3568a70e543bb5632b50fb02a825738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 4 Apr 2005 14:34:18 +0000 Subject: [PATCH] Changed the set_segment_descriptor()'s usage of the limit/granularity flag. Now, it will choose how to set the granularity by evaluating the limit. This call was actually already used this way in the kernel, so that the TLS and TSS segments were much too large (harmless but incorrect). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12231 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/arch/x86/descriptors.h | 15 ++++++++++++--- src/kernel/boot/platform/bios_ia32/mmu.cpp | 8 ++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/headers/private/kernel/arch/x86/descriptors.h b/headers/private/kernel/arch/x86/descriptors.h index 20db3e053a..8615027a16 100644 --- a/headers/private/kernel/arch/x86/descriptors.h +++ b/headers/private/kernel/arch/x86/descriptors.h @@ -86,15 +86,24 @@ set_segment_descriptor(struct segment_descriptor *desc, addr_t base, uint32 limi { set_segment_descriptor_base(desc, base); - desc->limit_00_15 = (addr_t)limit & 0x0ffff; // limit is 20 bits long - desc->limit_19_16 = ((addr_t)limit >> 16) & 0xf; + // limit is 20 bits long + if (limit & 0xfff00000) { + desc->limit_00_15 = ((addr_t)limit >> 12) & 0x0ffff; + desc->limit_19_16 = ((addr_t)limit >> 28) & 0xf; + desc->granularity = 1; // 4 KB granularity + } else { + desc->limit_00_15 = (addr_t)limit & 0x0ffff; + desc->limit_19_16 = ((addr_t)limit >> 16) & 0xf; + desc->granularity = 0; // 1 byte granularity + } + limit >>= 12; + desc->type = type; desc->desc_type = DT_CODE_DATA_SEGMENT; desc->privilege_level = privilegeLevel; desc->present = 1; - desc->granularity = 1; // 4 GB size (in page size steps) desc->available = 0; // system available bit is currently not used desc->d_b = 1; // 32-bit code diff --git a/src/kernel/boot/platform/bios_ia32/mmu.cpp b/src/kernel/boot/platform/bios_ia32/mmu.cpp index 05a3654b5e..47cb8d1394 100644 --- a/src/kernel/boot/platform/bios_ia32/mmu.cpp +++ b/src/kernel/boot/platform/bios_ia32/mmu.cpp @@ -379,14 +379,14 @@ mmu_init_for_kernel(void) // put standard segment descriptors in it clear_segment_descriptor(&gdt[0]); - set_segment_descriptor(&gdt[1], 0, 0xfffff, DT_CODE_READABLE, DPL_KERNEL); + set_segment_descriptor(&gdt[1], 0, 0xffffffff, DT_CODE_READABLE, DPL_KERNEL); // seg 0x08 - kernel 4GB code - set_segment_descriptor(&gdt[2], 0, 0xfffff, DT_DATA_WRITEABLE, DPL_KERNEL); + set_segment_descriptor(&gdt[2], 0, 0xffffffff, DT_DATA_WRITEABLE, DPL_KERNEL); // seg 0x10 - kernel 4GB data - set_segment_descriptor(&gdt[3], 0, 0xfffff, DT_CODE_READABLE, DPL_USER); + set_segment_descriptor(&gdt[3], 0, 0xffffffff, DT_CODE_READABLE, DPL_USER); // seg 0x1b - ring 3 user 4GB code - set_segment_descriptor(&gdt[4], 0, 0xfffff, DT_DATA_WRITEABLE, DPL_USER); + set_segment_descriptor(&gdt[4], 0, 0xffffffff, DT_DATA_WRITEABLE, DPL_USER); // seg 0x23 - ring 3 user 4GB data // gdt[5] and above will be filled later by the kernel