From f143877df95029ae4da9ec6e97af6afa07206edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 6 Jan 2003 08:33:59 +0000 Subject: [PATCH] _start() now uses set_segment_descriptor() to initialize the GDT instead of the direct values. Some cleanups. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2369 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/boot/arch/x86/smp_boot.c | 85 ++++++++++++++++++++--------- src/kernel/boot/arch/x86/stage2.c | 31 ++++++----- 2 files changed, 75 insertions(+), 41 deletions(-) diff --git a/src/kernel/boot/arch/x86/smp_boot.c b/src/kernel/boot/arch/x86/smp_boot.c index 9abd7e4302..6e6603d63e 100644 --- a/src/kernel/boot/arch/x86/smp_boot.c +++ b/src/kernel/boot/arch/x86/smp_boot.c @@ -2,6 +2,8 @@ ** Copyright 2001, Travis Geiselbrecht. All rights reserved. ** Distributed under the terms of the NewOS License. */ + + #include #include @@ -18,13 +20,15 @@ static unsigned int kernel_entry_point = 0; static int smp_get_current_cpu(kernel_args *ka); -static unsigned int map_page(kernel_args *ka, unsigned int paddr, unsigned int vaddr) + +static unsigned int +map_page(kernel_args *ka, unsigned int paddr, unsigned int vaddr) { unsigned int *pentry; unsigned int *pgdir = (unsigned int *)(ka->arch_args.page_hole + (4*1024*1024-PAGE_SIZE)); // check to see if a page table exists for this range - if(pgdir[vaddr / PAGE_SIZE / 1024] == 0) { + if (pgdir[vaddr / PAGE_SIZE / 1024] == 0) { unsigned int pgtable; // we need to allocate a pgtable pgtable = ka->phys_alloc_range[0].start + ka->phys_alloc_range[0].size; @@ -47,28 +51,37 @@ static unsigned int map_page(kernel_args *ka, unsigned int paddr, unsigned int v return 0; } -static unsigned int apic_read(unsigned int *addr) + +static unsigned int +apic_read(unsigned int *addr) { return *addr; } -static void apic_write(unsigned int *addr, unsigned int data) + +static void +apic_write(unsigned int *addr, unsigned int data) { *addr = data; } /* -static void *mp_virt_to_phys(void *ptr) +static void * +mp_virt_to_phys(void *ptr) { return ((void *)(((unsigned int)ptr - mp_mem_virt) + mp_mem_phys)); } */ -static void *mp_phys_to_virt(void *ptr) + +static void * +mp_phys_to_virt(void *ptr) { return ((void *)(((unsigned int)ptr - mp_mem_phys) + mp_mem_virt)); } -static unsigned int *smp_probe(unsigned int base, unsigned int limit) + +static unsigned int * +smp_probe(unsigned int base, unsigned int limit) { unsigned int *ptr; @@ -83,7 +96,9 @@ static unsigned int *smp_probe(unsigned int base, unsigned int limit) return NULL; } -static void smp_do_config(kernel_args *ka) + +static void +smp_do_config(kernel_args *ka) { char *ptr; int i; @@ -168,6 +183,7 @@ static void smp_do_config(kernel_args *ka) } } + struct smp_scan_spots_struct { unsigned int start; unsigned int stop; @@ -180,21 +196,23 @@ static struct smp_scan_spots_struct smp_scan_spots[] = { { 0, 0, 0 } }; -static int smp_find_mp_config(kernel_args *ka) + +static int +smp_find_mp_config(kernel_args *ka) { int i; // XXX for now, assume the memory is identity mapped by the 1st stage - for(i=0; smp_scan_spots[i].len > 0; i++) { + for (i = 0; smp_scan_spots[i].len > 0; i++) { mp_flt_ptr = (struct mp_flt_struct *)smp_probe(smp_scan_spots[i].start, smp_scan_spots[i].stop); if(mp_flt_ptr != NULL) break; } #if NO_SMP - if(0) { + if (0) { #else - if(mp_flt_ptr != NULL) { + if (mp_flt_ptr != NULL) { #endif mp_mem_phys = smp_scan_spots[i].start; mp_mem_virt = smp_scan_spots[i].start; @@ -231,7 +249,9 @@ static int smp_find_mp_config(kernel_args *ka) } } -static int smp_setup_apic(kernel_args *ka) + +static int +smp_setup_apic(kernel_args *ka) { unsigned int config; // dprintf("setting up the apic..."); @@ -278,12 +298,15 @@ static int smp_setup_apic(kernel_args *ka) return 0; } + // target function of the trampoline code // The trampoline code should have the pgdir and a gdt set up for us, // along with us being on the final stack for this processor. We need // to set up the local APIC and load the global idt and gdt. When we're // done, we'll jump into the kernel with the cpu number as an argument. -static int smp_cpu_ready(void) + +static int +smp_cpu_ready(void) { kernel_args *ka = saved_ka; unsigned int curr_cpu = smp_get_current_cpu(ka); @@ -324,7 +347,9 @@ static int smp_cpu_ready(void) return 0; } -static int smp_boot_all_cpus(kernel_args *ka) + +static int +smp_boot_all_cpus(kernel_args *ka) { unsigned int trampoline_code; unsigned int trampoline_stack; @@ -345,7 +370,7 @@ static int smp_boot_all_cpus(kernel_args *ka) (unsigned int)&smp_trampoline_end - (unsigned int)&smp_trampoline); // boot the cpus - for(i = 1; i < ka->num_cpus; i++) { + for (i = 1; i < ka->num_cpus; i++) { unsigned int *final_stack; unsigned int *final_stack_ptr; unsigned int *tramp_stack_ptr; @@ -387,7 +412,7 @@ static int smp_boot_all_cpus(kernel_args *ka) memcpy(&((unsigned int *)trampoline_stack)[2], (void *)ka->arch_args.vir_gdt, 6*4); /* clear apic errors */ - if(ka->arch_args.cpu_apic_version[i] & 0xf0) { + if (ka->arch_args.cpu_apic_version[i] & 0xf0) { apic_write(APIC_ESR, 0); apic_read(APIC_ESR); } @@ -399,7 +424,7 @@ static int smp_boot_all_cpus(kernel_args *ka) apic_write(APIC_ICR1, config); // wait for pending to end - while((apic_read(APIC_ICR1) & 0x00001000) == 0x00001000); + while ((apic_read(APIC_ICR1) & 0x00001000) == 0x00001000); /* deassert INIT */ config = (apic_read(APIC_ICR2) & 0x00ffffff) | (ka->arch_args.cpu_apic_id[i] << 24); @@ -407,7 +432,7 @@ static int smp_boot_all_cpus(kernel_args *ka) config = (apic_read(APIC_ICR1) & 0xfff00000) | 0x00008500; // wait for pending to end - while((apic_read(APIC_ICR1) & 0x00001000) == 0x00001000); + while ((apic_read(APIC_ICR1) & 0x00001000) == 0x00001000); // dprintf("0x%x\n", apic_read(APIC_ICR1)); /* wait 10ms */ @@ -431,14 +456,16 @@ static int smp_boot_all_cpus(kernel_args *ka) /* wait */ sleep(200); - while((apic_read(APIC_ICR1)& 0x00001000) == 0x00001000); + while ((apic_read(APIC_ICR1)& 0x00001000) == 0x00001000); } } return 0; } -static void calculate_apic_timer_conversion_factor(kernel_args *ka) + +static void +calculate_apic_timer_conversion_factor(kernel_args *ka) { long long t1, t2; unsigned int config; @@ -467,14 +494,16 @@ static void calculate_apic_timer_conversion_factor(kernel_args *ka) dprintf("APIC ticks/sec = %d\n", ka->arch_args.apic_time_cv_factor); } -int smp_boot(kernel_args *ka, unsigned int kernel_entry) + +int +smp_boot(kernel_args *ka, unsigned int kernel_entry) { // dprintf("smp_boot: entry\n"); kernel_entry_point = kernel_entry; saved_ka = ka; - if(smp_find_mp_config(ka) > 1) { + if (smp_find_mp_config(ka) > 1) { // dprintf("smp_boot: had found > 1 cpus\n"); // dprintf("post config:\n"); // dprintf("num_cpus = 0x%p\n", ka->num_cpus); @@ -509,10 +538,12 @@ int smp_boot(kernel_args *ka, unsigned int kernel_entry) return 0; } -static int smp_get_current_cpu(kernel_args *ka) + +static int +smp_get_current_cpu(kernel_args *ka) { - if(ka->arch_args.apic == NULL) + if (ka->arch_args.apic == NULL) return 0; - else - return ka->arch_args.cpu_os_id[(apic_read(APIC_ID) & 0xffffffff) >> 24]; + + return ka->arch_args.cpu_os_id[(apic_read(APIC_ID) & 0xffffffff) >> 24]; } diff --git a/src/kernel/boot/arch/x86/stage2.c b/src/kernel/boot/arch/x86/stage2.c index c6ec684545..f1ba26f597 100644 --- a/src/kernel/boot/arch/x86/stage2.c +++ b/src/kernel/boot/arch/x86/stage2.c @@ -6,6 +6,7 @@ #include #include #include "arch/x86/stage2_priv.h" +#include "arch/x86/descriptors.h" #include "vesa.h" #include @@ -69,7 +70,7 @@ void _start(unsigned int mem, int in_vesa, unsigned int vesa_ptr) { unsigned int *idt; - unsigned int *gdt; + segment_descriptor *gdt; unsigned int next_vaddr; unsigned int next_paddr; unsigned int i; @@ -186,24 +187,26 @@ _start(unsigned int mem, int in_vesa, unsigned int vesa_ptr) struct gdt_idt_descr gdt_descr; // find a new gdt - gdt = (unsigned int *)next_paddr; + gdt = (segment_descriptor *)next_paddr; ka->arch_args.phys_gdt = (unsigned int)gdt; next_paddr += PAGE_SIZE; MESSAGE(("gdt at ", (unsigned int)gdt, "\n")); - // put segment descriptors in it - gdt[0] = 0; - gdt[1] = 0; - gdt[2] = 0x0000ffff; // seg 0x8 -- kernel 4GB code - gdt[3] = 0x00cf9a00; - gdt[4] = 0x0000ffff; // seg 0x10 -- kernel 4GB data - gdt[5] = 0x00cf9200; - gdt[6] = 0x0000ffff; // seg 0x1b -- ring 3 4GB code - gdt[7] = 0x00cffa00; - gdt[8] = 0x0000ffff; // seg 0x23 -- ring 3 4GB data - gdt[9] = 0x00cff200; - // gdt[10] & gdt[11] will be filled later by the kernel + // put standard segment descriptors in it + clear_segment_descriptor(&gdt[0]); + set_segment_descriptor(&gdt[1], 0, 0xfffff, DT_CODE_READABLE, DPL_KERNEL); + // seg 0x10 - kernel 4GB code + set_segment_descriptor(&gdt[2], 0, 0xfffff, DT_DATA_WRITEABLE, DPL_KERNEL); + // seg 0x10 - kernel 4GB data + + set_segment_descriptor(&gdt[3], 0, 0xfffff, DT_CODE_READABLE, DPL_USER); + // seg 0x1b - ring 3 user 4GB code + set_segment_descriptor(&gdt[4], 0, 0xfffff, DT_DATA_WRITEABLE, DPL_USER); + // seg 0x23 - ring 3 user 4GB data + + // gdt[5] and above will be filled later by the kernel + // to contain the TSS descriptors, and for TLS (one for every CPU) // map the gdt into virtual space mmu_map_page(next_vaddr, (unsigned int)gdt);