diff --git a/.gitignore b/.gitignore index 92fc6e7..1a75fcc 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,6 @@ build-aux/ /doc/mach.toc /doc/mach.tp /doc/mach.vr +/build +Makefile.am.orig +Makefile.am.rej diff --git a/Makefrag.am b/Makefrag.am index 4625b48..8b855cb 100644 --- a/Makefrag.am +++ b/Makefrag.am @@ -139,6 +139,7 @@ libkernel_a_SOURCES += \ kern/counters.c \ kern/counters.h \ kern/cpu_number.h \ + kern/cpu_number.c \ kern/debug.c \ kern/debug.h \ kern/eventcount.c \ diff --git a/configfrag.ac b/configfrag.ac index 3d7033e..d1fe101 100644 --- a/configfrag.ac +++ b/configfrag.ac @@ -32,7 +32,7 @@ AC_DEFINE([BOOTSTRAP_SYMBOLS], [0], [BOOTSTRAP_SYMBOLS]) # Multiprocessor support is still broken. AH_TEMPLATE([MULTIPROCESSOR], [set things up for a uniprocessor]) -mach_ncpus=1 +mach_ncpus=2 AC_DEFINE_UNQUOTED([NCPUS], [$mach_ncpus], [number of CPUs]) [if [ $mach_ncpus -gt 1 ]; then] AC_DEFINE([MULTIPROCESSOR], [1], [set things up for a multiprocessor]) diff --git a/cpu_number.c b/cpu_number.c new file mode 100644 index 0000000..0b2e2f1 --- /dev/null +++ b/cpu_number.c @@ -0,0 +1,28 @@ +int apic2kernel[255]; +int cpu_number_start = 0, cpu_number_counter = 0; + +int cpu_number(void) { + int eax = 1, ebx = 0, ecx = 0, edx = 0; + unsigned int i = 0; + int apic_id = 0; + + if (!cpu_number_start) { + for (i = 0; i < 255; i++) { + apic2kernel[i] = -1; + } + cpu_number_start = 1; + } + + asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (eax)); + apic_id = (char) (ebx >> 24) & 0xff; + //printf("apic_id = %d\n", apic_id); + + if (apic2kernel[apic_id] != -1) { + return apic2kernel[apic_id]; + } else { + apic2kernel[apic_id] = cpu_number_counter; + cpu_number_counter++; + } + + return apic2kernel[apic_id]; +} diff --git a/i386/i386/cpu_number.S b/i386/i386/cpu_number.S new file mode 100644 index 0000000..95036b8 --- /dev/null +++ b/i386/i386/cpu_number.S @@ -0,0 +1,4 @@ +.macro CPU_NUMBER reg + call cpu_number + movl %eax, \reg +.endm diff --git a/i386/i386/cswitch.S b/i386/i386/cswitch.S index 718c8aa..970255a 100644 --- a/i386/i386/cswitch.S +++ b/i386/i386/cswitch.S @@ -29,6 +29,7 @@ #include #include #include +.include "i386/cpu_number.S" /* * Context switch routines for i386. @@ -39,7 +40,7 @@ ENTRY(Load_context) movl TH_KERNEL_STACK(%ecx),%ecx /* get kernel stack */ lea KERNEL_STACK_SIZE-IKS_SIZE-IEL_SIZE(%ecx),%edx /* point to stack top */ - CPU_NUMBER(%eax) + CPU_NUMBER %eax movl %ecx,CX(EXT(active_stacks),%eax) /* store stack address */ movl %edx,CX(EXT(kernel_stack),%eax) /* store stack top */ @@ -57,7 +58,7 @@ ENTRY(Load_context) */ ENTRY(Switch_context) - CPU_NUMBER(%edx) + CPU_NUMBER %edx movl CX(EXT(active_stacks),%edx),%ecx /* get old kernel stack */ movl %ebx,KSS_EBX(%ecx) /* save registers */ @@ -109,7 +110,7 @@ ENTRY(Thread_continue) * has no FPU state) */ ENTRY(switch_to_shutdown_context) - CPU_NUMBER(%edx) + CPU_NUMBER %edx movl EXT(active_stacks)(,%edx,4),%ecx /* get old kernel stack */ movl %ebx,KSS_EBX(%ecx) /* save registers */ movl %ebp,KSS_EBP(%ecx) diff --git a/i386/i386/locore.S b/i386/i386/locore.S index ddba224..265a5d1 100644 --- a/i386/i386/locore.S +++ b/i386/i386/locore.S @@ -37,6 +37,7 @@ #include #include #include +.include "i386/cpu_number.S" /* * Fault recovery. @@ -243,7 +244,7 @@ timer_normalize: * Switch to a new timer. */ ENTRY(timer_switch) - CPU_NUMBER(%edx) /* get this CPU */ + CPU_NUMBER %edx /* get this CPU */ movl VA_ETC,%ecx /* get timer */ movl CX(EXT(current_tstamp),%edx),%eax /* get old time stamp */ movl %ecx,CX(EXT(current_tstamp),%edx) /* set new time stamp */ @@ -261,7 +262,7 @@ ENTRY(timer_switch) * Initialize the first timer for a CPU. */ ENTRY(start_timer) - CPU_NUMBER(%edx) /* get this CPU */ + CPU_NUMBER %edx /* get this CPU */ movl VA_ETC,%ecx /* get timer */ movl %ecx,CX(EXT(current_tstamp),%edx) /* set initial time stamp */ movl S_ARG0,%ecx /* get timer */ @@ -479,7 +480,7 @@ trap_set_segs: jz trap_from_kernel /* kernel trap if not */ trap_from_user: - CPU_NUMBER(%edx) + CPU_NUMBER %edx TIME_TRAP_UENTRY movl CX(EXT(kernel_stack),%edx),%ebx @@ -501,7 +502,7 @@ _take_trap: */ _return_from_trap: - CPU_NUMBER(%edx) + CPU_NUMBER %edx cmpl $0,CX(EXT(need_ast),%edx) jz _return_to_user /* if we need an AST: */ @@ -547,7 +548,7 @@ trap_from_kernel: cmpl EXT(int_stack_base),%edx je 1f /* OK if so */ - CPU_NUMBER(%edx) /* get CPU number */ + CPU_NUMBER %edx /* get CPU number */ cmpl CX(EXT(kernel_stack),%edx),%esp /* already on kernel stack? */ ja 0f @@ -664,7 +665,7 @@ ENTRY(all_intrs) mov %dx,%fs mov %dx,%gs - CPU_NUMBER(%edx) + CPU_NUMBER %edx movl CX(EXT(int_stack_top),%edx),%ecx xchgl %ecx,%esp /* switch to interrupt stack */ @@ -683,7 +684,7 @@ ENTRY(all_intrs) .globl EXT(return_to_iret) LEXT(return_to_iret) /* ( label for kdb_kintr and hardclock) */ - CPU_NUMBER(%edx) + CPU_NUMBER %edx #if STAT_TIME #else TIME_INT_EXIT /* do timing */ @@ -760,7 +761,7 @@ ast_from_interrupt: mov %dx,%fs mov %dx,%gs - CPU_NUMBER(%edx) + CPU_NUMBER %edx TIME_TRAP_UENTRY movl CX(EXT(kernel_stack),%edx),%esp @@ -1025,7 +1026,7 @@ syscall_entry_2: movl %edx,R_CS(%esp) /* fix cs */ movl %ebx,R_EFLAGS(%esp) /* fix eflags */ - CPU_NUMBER(%edx) + CPU_NUMBER %edx TIME_TRAP_SENTRY movl CX(EXT(kernel_stack),%edx),%ebx diff --git a/kern/cpu_number.c b/kern/cpu_number.c new file mode 100644 index 0000000..0b2e2f1 --- /dev/null +++ b/kern/cpu_number.c @@ -0,0 +1,28 @@ +int apic2kernel[255]; +int cpu_number_start = 0, cpu_number_counter = 0; + +int cpu_number(void) { + int eax = 1, ebx = 0, ecx = 0, edx = 0; + unsigned int i = 0; + int apic_id = 0; + + if (!cpu_number_start) { + for (i = 0; i < 255; i++) { + apic2kernel[i] = -1; + } + cpu_number_start = 1; + } + + asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (eax)); + apic_id = (char) (ebx >> 24) & 0xff; + //printf("apic_id = %d\n", apic_id); + + if (apic2kernel[apic_id] != -1) { + return apic2kernel[apic_id]; + } else { + apic2kernel[apic_id] = cpu_number_counter; + cpu_number_counter++; + } + + return apic2kernel[apic_id]; +} diff --git a/kern/cpu_number.h b/kern/cpu_number.h index 5d3e4bd..2ea510e 100644 --- a/kern/cpu_number.h +++ b/kern/cpu_number.h @@ -37,7 +37,11 @@ int master_cpu; /* 'master' processor - keeps time */ /* cpu number is always 0 on a single processor system */ #define cpu_number() (0) -#endif /* NCPUS == 1 */ +#else /* NCPUS == 1 */ + +extern int cpu_number(void); + +#endif /* NCPUS != 1 */ #define CPU_L1_SIZE (1 << CPU_L1_SHIFT)