summaryrefslogtreecommitdiffstats
path: root/sys/pc98
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2011-04-06 23:59:59 +0000
committerjkim <jkim@FreeBSD.org>2011-04-06 23:59:59 +0000
commit0c7a0c810c13b5c1ceadfb651f3c089fe41feccb (patch)
tree2c512de0f88eb1927d24901d2d83e577f2f21731 /sys/pc98
parentc94af9f0eb95d5b4e7a0c20a349481ae824b0222 (diff)
downloadFreeBSD-src-0c7a0c810c13b5c1ceadfb651f3c089fe41feccb.zip
FreeBSD-src-0c7a0c810c13b5c1ceadfb651f3c089fe41feccb.tar.gz
Implement atomic_load_acq_64(9) and atomic_store_rel_64(9) for i386. These
functions are implemented with CMPXCHG8B instruction where it is available, i. e., all Pentium-class and later processors. Note this instruction is also used for atomic_store_rel_64() because a simple XCHG-like instruction for 64-bit memory access does not exist, unfortunately. If the processor lacks the instruction, i. e., 80486-class CPUs, two 32-bit load/store are performed with interrupt temporarily disabled, assuming it does not support SMP. Although this assumption may be little naive, it is true in reality. This implementation is inspired by Linux.
Diffstat (limited to 'sys/pc98')
-rw-r--r--sys/pc98/pc98/machdep.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index d778de5..5e7215e 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -1330,6 +1330,21 @@ idle_sysctl(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_machdep, OID_AUTO, idle, CTLTYPE_STRING | CTLFLAG_RW, 0, 0,
idle_sysctl, "A", "currently selected idle function");
+uint64_t (*atomic_load_acq_64)(volatile uint64_t *) =
+ atomic_load_acq_64_i386;
+void (*atomic_store_rel_64)(volatile uint64_t *, uint64_t) =
+ atomic_store_rel_64_i386;
+
+static void
+cpu_probe_cmpxchg8b(void)
+{
+
+ if ((cpu_feature & CPUID_CX8) != 0) {
+ atomic_load_acq_64 = atomic_load_acq_64_i586;
+ atomic_store_rel_64 = atomic_store_rel_64_i586;
+ }
+}
+
/*
* Reset registers to default values on exec.
*/
@@ -2344,6 +2359,8 @@ init386(first)
thread0.td_pcb->pcb_cr3 = (int)IdlePTD;
thread0.td_pcb->pcb_ext = 0;
thread0.td_frame = &proc0_tf;
+
+ cpu_probe_cmpxchg8b();
}
void
OpenPOWER on IntegriCloud