_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:
parent
39c5004d20
commit
f143877df9
@ -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,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];
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user