_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
This commit is contained in:
Axel Dörfler 2003-01-06 08:33:59 +00:00
parent 39c5004d20
commit f143877df9
2 changed files with 75 additions and 41 deletions

View File

@ -2,6 +2,8 @@
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <stage2.h>
#include <arch/x86/stage2_priv.h>
@ -18,7 +20,9 @@ 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));
@ -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,7 +196,9 @@ 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;
@ -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;
@ -438,7 +463,9 @@ static int smp_boot_all_cpus(kernel_args *ka)
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,7 +494,9 @@ 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");
@ -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)
return 0;
else
return ka->arch_args.cpu_os_id[(apic_read(APIC_ID) & 0xffffffff) >> 24];
}

View File

@ -6,6 +6,7 @@
#include <bootdir.h>
#include <stage2.h>
#include "arch/x86/stage2_priv.h"
#include "arch/x86/descriptors.h"
#include "vesa.h"
#include <string.h>
@ -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);