summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2001-01-06 17:40:04 +0000
committerjake <jake@FreeBSD.org>2001-01-06 17:40:04 +0000
commit56e99b7d35d909eaef84dafc091867116a08e54f (patch)
tree20d39cad65f882504f37dd6b22616271e30bec7b /sys/i386
parentc269c9fb36040d129558f61fa26bf3745100a4ff (diff)
downloadFreeBSD-src-56e99b7d35d909eaef84dafc091867116a08e54f.zip
FreeBSD-src-56e99b7d35d909eaef84dafc091867116a08e54f.tar.gz
Use %fs to access per-cpu variables in uni-processor kernels the same
as multi-processor kernels. The old way made it difficult for kernel modules to be portable between uni-processor and multi-processor kernels. It is no longer necessary to jump through hoops. - always load %fs with the private segment on entry to the kernel - change the type of the self referntial pointer from struct privatespace to struct globaldata - make the globaldata symbol have value 0 in all cases, so the symbols in globals.s are always offsets, not aliases for fields in globaldata - define the globaldata space used for uniprocessor kernels in C, rather than assembler - change the assmebly language accessors to use %fs, add a macro PCPU_ADDR(member, reg), which loads the register reg with the address of the per-cpu variable member
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/exception.s16
-rw-r--r--sys/i386/i386/genassym.c4
-rw-r--r--sys/i386/i386/globals.s12
-rw-r--r--sys/i386/i386/machdep.c13
-rw-r--r--sys/i386/i386/support.s2
-rw-r--r--sys/i386/i386/swtch.s7
-rw-r--r--sys/i386/include/asmacros.h6
-rw-r--r--sys/i386/include/globaldata.h4
-rw-r--r--sys/i386/include/globals.h7
-rw-r--r--sys/i386/include/pcpu.h4
-rw-r--r--sys/i386/isa/atpic_vector.s2
-rw-r--r--sys/i386/isa/icu_vector.s2
12 files changed, 29 insertions, 50 deletions
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index 6ba916f..07f4a29 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -47,11 +47,6 @@
#include "assym.s"
-#ifdef SMP
-#define MOVL_KPSEL_EAX movl $KPSEL,%eax
-#else
-#define MOVL_KPSEL_EAX
-#endif
#define SEL_RPL_MASK 0x0003
.text
@@ -172,7 +167,7 @@ IDTVEC(fpu)
mov $KDSEL,%ax
mov %ax,%ds
mov %ax,%es
- MOVL_KPSEL_EAX
+ mov $KPSEL,%ax
mov %ax,%fs
FAKE_MCOUNT(13*4(%esp))
@@ -213,7 +208,7 @@ alltraps_with_regs_pushed:
mov $KDSEL,%ax
mov %ax,%ds
mov %ax,%es
- MOVL_KPSEL_EAX
+ mov $KPSEL,%ax
mov %ax,%fs
FAKE_MCOUNT(13*4(%esp))
calltrap:
@@ -253,7 +248,7 @@ IDTVEC(syscall)
mov $KDSEL,%ax /* switch to kernel segments */
mov %ax,%ds
mov %ax,%es
- MOVL_KPSEL_EAX
+ mov $KPSEL,%ax
mov %ax,%fs
movl TF_ERR(%esp),%eax /* copy saved eflags to final spot */
movl %eax,TF_EFLAGS(%esp)
@@ -287,7 +282,7 @@ IDTVEC(int0x80_syscall)
mov $KDSEL,%ax /* switch to kernel segments */
mov %ax,%ds
mov %ax,%es
- MOVL_KPSEL_EAX
+ mov $KPSEL,%ax
mov %ax,%fs
movl $2,TF_ERR(%esp) /* sizeof "int 0x80" */
FAKE_MCOUNT(13*4(%esp))
@@ -308,8 +303,7 @@ ENTRY(fork_trampoline)
#ifdef SMP
cmpl $0,PCPU(SWITCHTIME)
jne 1f
- movl $GD_SWITCHTIME,%eax
- addl %fs:0,%eax
+ PCPU_ADDR(SWITCHTIME, %eax)
pushl %eax
call _microuptime
popl %edx
diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c
index 6f04558..233f2f7 100644
--- a/sys/i386/i386/genassym.c
+++ b/sys/i386/i386/genassym.c
@@ -169,6 +169,7 @@ ASSYM(BI_SYMTAB, offsetof(struct bootinfo, bi_symtab));
ASSYM(BI_ESYMTAB, offsetof(struct bootinfo, bi_esymtab));
ASSYM(BI_KERNEND, offsetof(struct bootinfo, bi_kernend));
ASSYM(GD_SIZEOF, sizeof(struct globaldata));
+ASSYM(GD_PRVSPACE, offsetof(struct globaldata, gd_prvspace));
ASSYM(GD_CURPROC, offsetof(struct globaldata, gd_curproc));
ASSYM(GD_NPXPROC, offsetof(struct globaldata, gd_npxproc));
ASSYM(GD_IDLEPROC, offsetof(struct globaldata, gd_idleproc));
@@ -223,10 +224,7 @@ ASSYM(LA_ICR_HI, offsetof(struct LAPIC, icr_hi));
ASSYM(KCSEL, GSEL(GCODE_SEL, SEL_KPL));
ASSYM(KDSEL, GSEL(GDATA_SEL, SEL_KPL));
-
-#ifdef SMP
ASSYM(KPSEL, GSEL(GPRIV_SEL, SEL_KPL));
-#endif
ASSYM(BC32SEL, GSEL(GBIOSCODE32_SEL, SEL_KPL));
ASSYM(GPROC0_SEL, GPROC0_SEL);
diff --git a/sys/i386/i386/globals.s b/sys/i386/i386/globals.s
index aaa6f81..fcc4cdd 100644
--- a/sys/i386/i386/globals.s
+++ b/sys/i386/i386/globals.s
@@ -48,19 +48,9 @@
.set gd_idlestack_top,PS_IDLESTACK_TOP
#endif
- /*
- * Define layout of the global data. On SMP this lives in
- * the per-cpu address space, otherwise it's in the data segment.
- */
.globl globaldata
-#ifndef SMP
- .data
- ALIGN_DATA
-globaldata:
- .space GD_SIZEOF /* in data segment */
-#else
.set globaldata,0
-#endif
+
.globl gd_curproc, gd_curpcb, gd_npxproc, gd_idleproc
.globl gd_astpending, gd_common_tss, gd_switchtime, gd_switchticks
.globl gd_intr_nesting_level
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 7b537ff..c1c6f29 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -244,6 +244,9 @@ static vm_offset_t buffer_sva, buffer_eva;
vm_offset_t clean_sva, clean_eva;
static vm_offset_t pager_sva, pager_eva;
static struct trapframe proc0_tf;
+#ifndef SMP
+static struct globaldata __globaldata;
+#endif
struct cpuhead cpuhead;
@@ -1850,10 +1853,14 @@ init386(first)
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[0];
gdt_segs[GPROC0_SEL].ssd_base =
(int) &SMP_prvspace[0].globaldata.gd_common_tss;
- SMP_prvspace[0].globaldata.gd_prvspace = &SMP_prvspace[0];
+ SMP_prvspace[0].globaldata.gd_prvspace = &SMP_prvspace[0].globaldata;
#else
- gdt_segs[GPRIV_SEL].ssd_limit = i386_btop(0) - 1;
- gdt_segs[GPROC0_SEL].ssd_base = (int) &common_tss;
+ gdt_segs[GPRIV_SEL].ssd_limit =
+ i386_btop(sizeof(struct globaldata)) - 1;
+ gdt_segs[GPRIV_SEL].ssd_base = (int) &__globaldata;
+ gdt_segs[GPROC0_SEL].ssd_base =
+ (int) &__globaldata.gd_common_tss;
+ __globaldata.gd_prvspace = &__globaldata;
#endif
for (x = 0; x < NGDT; x++) {
diff --git a/sys/i386/i386/support.s b/sys/i386/i386/support.s
index e240de4..3f0f51f 100644
--- a/sys/i386/i386/support.s
+++ b/sys/i386/i386/support.s
@@ -1516,9 +1516,7 @@ ENTRY(lgdt)
mov %ax,%es
mov %ax,%gs
mov %ax,%ss
-#ifdef SMP
movl $KPSEL,%eax
-#endif
mov %ax,%fs
/* reload code selector by turning return into intersegmental return */
diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s
index 6d2e30d..8d5cade 100644
--- a/sys/i386/i386/swtch.s
+++ b/sys/i386/i386/swtch.s
@@ -224,12 +224,7 @@ sw1b:
btrl %esi, _private_tss
jae 3f
-#ifdef SMP
- movl $GD_COMMON_TSSD, %edi
- addl %fs:0, %edi
-#else
- movl $PCPU(COMMON_TSSD), %edi
-#endif
+ PCPU_ADDR(COMMON_TSSD, %edi)
2:
/* move correct tss descriptor into GDT slot, then reload tr */
movl PCPU(TSS_GDT), %ebx /* entry in GDT */
diff --git a/sys/i386/include/asmacros.h b/sys/i386/include/asmacros.h
index c2d89b8..0931404 100644
--- a/sys/i386/include/asmacros.h
+++ b/sys/i386/include/asmacros.h
@@ -69,10 +69,10 @@
#define NON_GPROF_ENTRY(name) GEN_ENTRY(name)
#define NON_GPROF_RET .byte 0xc3 /* opcode for `ret' */
-#ifdef SMP
+#ifdef LOCORE
#define PCPU(member) %fs:GD_ ## member
-#else
-#define PCPU(member) CNAME(globaldata) + GD_ ## member
+#define PCPU_ADDR(member, reg) movl %fs:GD_PRVSPACE,reg; \
+ addl $GD_ ## member,reg
#endif
#ifdef GPROF
diff --git a/sys/i386/include/globaldata.h b/sys/i386/include/globaldata.h
index 2788499..90c3bd7 100644
--- a/sys/i386/include/globaldata.h
+++ b/sys/i386/include/globaldata.h
@@ -53,7 +53,7 @@
* other processors"
*/
struct globaldata {
- struct privatespace *gd_prvspace; /* self-reference */
+ struct globaldata *gd_prvspace; /* self-reference */
struct proc *gd_curproc;
struct proc *gd_npxproc;
struct pcb *gd_curpcb;
@@ -92,8 +92,6 @@ struct globaldata {
#endif
};
-extern struct globaldata globaldata;
-
SLIST_HEAD(cpuhead, globaldata);
extern struct cpuhead cpuhead;
diff --git a/sys/i386/include/globals.h b/sys/i386/include/globals.h
index a20d83b..386810c 100644
--- a/sys/i386/include/globals.h
+++ b/sys/i386/include/globals.h
@@ -82,7 +82,8 @@ _global_globaldata(void)
return (val);
}
-#if defined(SMP) || defined(KLD_MODULE)
+/* #if defined(SMP) || defined(KLD_MODULE) */
+#if 1
/*
* The following set of macros works for UP kernel as well, but for maximum
* performance we allow the global variables to be accessed directly. On the
@@ -179,11 +180,7 @@ GLOBAL_FUNC(prv_PADDR1)
GLOBAL_FUNC(witness_spin_check)
-#ifdef SMP
#define GLOBALDATA GLOBAL_RVALUE(globaldata, struct globaldata *)
-#else
-#define GLOBALDATA (&globaldata)
-#endif
#define CURTHD curproc
#define CURPROC curproc
diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h
index 2788499..90c3bd7 100644
--- a/sys/i386/include/pcpu.h
+++ b/sys/i386/include/pcpu.h
@@ -53,7 +53,7 @@
* other processors"
*/
struct globaldata {
- struct privatespace *gd_prvspace; /* self-reference */
+ struct globaldata *gd_prvspace; /* self-reference */
struct proc *gd_curproc;
struct proc *gd_npxproc;
struct pcb *gd_curpcb;
@@ -92,8 +92,6 @@ struct globaldata {
#endif
};
-extern struct globaldata globaldata;
-
SLIST_HEAD(cpuhead, globaldata);
extern struct cpuhead cpuhead;
diff --git a/sys/i386/isa/atpic_vector.s b/sys/i386/isa/atpic_vector.s
index e28c375..635d2ad 100644
--- a/sys/i386/isa/atpic_vector.s
+++ b/sys/i386/isa/atpic_vector.s
@@ -58,6 +58,7 @@ IDTVEC(vec_name) ; \
mov $KDSEL,%ax ; \
mov %ax,%ds ; \
mov %ax,%es ; \
+ mov $KPSEL,%ax ; \
mov %ax,%fs ; \
FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \
incb PCPU(INTR_NESTING_LEVEL) ; \
@@ -93,6 +94,7 @@ IDTVEC(vec_name) ; \
mov $KDSEL,%ax ; /* load kernel ds, es and fs */ \
mov %ax,%ds ; \
mov %ax,%es ; \
+ mov $KPSEL,%ax ; \
mov %ax,%fs ; \
maybe_extra_ipending ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
diff --git a/sys/i386/isa/icu_vector.s b/sys/i386/isa/icu_vector.s
index e28c375..635d2ad 100644
--- a/sys/i386/isa/icu_vector.s
+++ b/sys/i386/isa/icu_vector.s
@@ -58,6 +58,7 @@ IDTVEC(vec_name) ; \
mov $KDSEL,%ax ; \
mov %ax,%ds ; \
mov %ax,%es ; \
+ mov $KPSEL,%ax ; \
mov %ax,%fs ; \
FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \
incb PCPU(INTR_NESTING_LEVEL) ; \
@@ -93,6 +94,7 @@ IDTVEC(vec_name) ; \
mov $KDSEL,%ax ; /* load kernel ds, es and fs */ \
mov %ax,%ds ; \
mov %ax,%es ; \
+ mov $KPSEL,%ax ; \
mov %ax,%fs ; \
maybe_extra_ipending ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
OpenPOWER on IntegriCloud