.\" This manpage has been automatically generated by docbook2man
.\" from a DocBook document. This tool can be found at:
.\"
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng .
.TH "SET_MTRR" "9" "09 October 2005" "" ""
.SH NAME
set_mtrr \- update mtrrs on all processors
.SH SYNOPSIS
"SYNOPSIS"
.sp
\fB
.sp
void set_mtrr (unsigned int \fIreg\fB, unsigned long \fIbase\fB, unsigned long \fIsize\fB, mtrr_type \fItype\fB);
\fR
.SH "ARGUMENTS"
.TP
\fB\fIreg\fB\fR
mtrr in question
.TP
\fB\fIbase\fB\fR
mtrr base
.TP
\fB\fIsize\fB\fR
mtrr size
.TP
\fB\fItype\fB\fR
mtrr type
.SH "DESCRIPTION"
.PP
This is kinda tricky, but fortunately, Intel spelled it out for us cleanly:
.PP
1. Send IPI to do the following:
2. Disable Interrupts
3. Wait for all procs to do so
4. Enter no-fill cache mode
5. Flush caches
6. Clear PGE bit
7. Flush all TLBs
8. Disable all range registers
9. Update the MTRRs
10. Enable all range registers
11. Flush all TLBs and caches again
12. Enter normal cache mode and reenable caching
13. Set PGE
14. Wait for buddies to catch up
15. Enable interrupts.
.PP
What does that mean for us? Well, first we set data.count to the number
of CPUs. As each CPU disables interrupts, it'll decrement it once. We wait
until it hits 0 and proceed. We set the data.gate flag and reset data.count.
Meanwhile, they are waiting for that flag to be set. Once it's set, each
CPU goes through the transition of updating MTRRs. The CPU vendors may each do it
differently, so we call mtrr_if->\fBset\fR callback and let them take care of it.
When they're done, they again decrement data->count and wait for data.gate to
be reset.
When we finish, we wait for data.count to hit 0 and toggle the data.gate flag.
Everyone then enables interrupts and we all continue on.
.PP
Note that the mechanism is the same for UP systems, too; all the SMP stuff
becomes nops.