@section Hardware References
@bibdfn{IA32-v1}
-@uref{ftp://download.intel.com/design/Pentium4/manuals/25366515.pdf, ,
IA-32 Intel Architecture Software Developer's Manual Volume 1: Basic
-Architecture}. Basic 80@var{x}86 architecture and programming
-environment.
+Architecture. Basic 80@var{x}86 architecture and programming
+environment. Available via @uref{developer.intel.com}. Section numbers
+in this document refer to revision 18.
-@bibdfn{IA32-v2a}
-@uref{ftp://download.intel.com/design/Pentium4/manuals/25366615.pdf, ,
-IA-32 Intel Architecture Software Developer's Manual Volume 2A:
-Instruction Set Reference A-M}. 80@var{x}86 instructions whose names
-begin with A through M.
+@bibdfn{IA32-v2a}
+IA-32 Intel Architecture Software Developer's Manual
+Volume 2A: Instruction Set Reference A-M. 80@var{x}86 instructions
+whose names begin with A through M. Available via
+@uref{developer.intel.com}. Section numbers in this document refer to
+revision 18.
@bibdfn{IA32-v2b}
-@uref{ftp://download.intel.com/design/Pentium4/manuals/25366715.pdf, ,
IA-32 Intel Architecture Software Developer's Manual Volume 2B:
-Instruction Set Reference N-Z}. 80@var{x}86 instructions whose names
-begin with N through Z.
-
-@bibdfn{IA32-v3}
-@uref{ftp://download.intel.com/design/Pentium4/manuals/25366815.pdf, ,
-IA-32 Intel Architecture Software Developer's Manual Volume 3: System
-Programming Guide}. Operating system support, including segmentation,
-paging, tasks, interrupt and exception handling.
+Instruction Set Reference N-Z. 80@var{x}86 instructions whose names
+begin with N through Z. Available via @uref{developer.intel.com}.
+Section numbers in this document refer to revision 18.
+
+@bibdfn{IA32-v3a}
+IA-32 Intel Architecture Software Developer's Manual Volume 3A: System
+Programming Guide. Operating system support, including segmentation,
+paging, tasks, interrupt and exception handling. Available via
+@uref{developer.intel.com}. Section numbers in this document refer to
+revision 18.
@bibdfn{FreeVGA}
@uref{specs/freevga/home.htm, , FreeVGA Project}. Documents the VGA video
Pintos comments sometimes refer to external standards or
specifications by writing a name inside square brackets, like this:
-@code{[IA32-v3]}. These names refer to the reference names used in
+@code{[IA32-v3a]}. These names refer to the reference names used in
this documentation (@pxref{References}).
If you remove existing Pintos code, please delete it from your source
@item flags.h
Macros that define a few bits in the 80@var{x}86 ``flags'' register.
-Probably of no interest. See @bibref{IA32-v1}, section 3.4.3, for more
-information.
+Probably of no interest. See @bibref{IA32-v1}, section 3.4.3, ``EFLAGS
+Register,'' for more information.
@end table
@menu
not important to understand exactly what the loader does, but if
you're interested, read on. You should probably read along with the
loader's source. You should also understand the basics of the
-80@var{x}86 architecture as described by chapter 3 of
-@bibref{IA32-v1}.
+80@var{x}86 architecture as described by chapter 3, ``Basic Execution
+Environment,'' of @bibref{IA32-v1}.
Because the PC BIOS loads the loader, the loader has to play by the
BIOS's rules. In particular, the BIOS only loads 512 bytes (one disk
common infrastructure, and sections after that give the specifics of
external and internal interrupts.
-If you haven't already read chapter 3 in @bibref{IA32-v1}, it is
-recommended that you do so now. You might also want to skim chapter 5
-in @bibref{IA32-v3}.
+If you haven't already read chapter 3, ``Basic Execution Environment,''
+in @bibref{IA32-v1}, it is recommended that you do so now. You might
+also want to skim chapter 5, ``Interrupt and Exception Handling,'' in
+@bibref{IA32-v3a}.
@menu
* Interrupt Infrastructure::
translate virtual page frames to physical page frames. It is possible
to do this translation without adding a new data structure, by modifying
the code in @file{userprog/pagedir.c}. However, if you do that you'll
-need to carefully study and understand section 3.7 in @bibref{IA32-v3},
-and in practice it is probably easier to add a new data structure. You
-may find other uses for hash tables as well.
+need to carefully study and understand section 3.7, ``Page Translation
+Using 32-Bit Physical Addressing,'' in @bibref{IA32-v3a}, and in practice
+it is probably easier to add a new data structure. You may find other
+uses for hash tables as well.
Pintos provides a hash table data structure in @file{lib/kernel/hash.c}.
To use it you will need to manually include its header file,
It is possible to do this translation without adding a new data
structure, by modifying the code in @file{userprog/pagedir.c}. However,
-if you do that you'll need to carefully study and understand section 3.7
-in @bibref{IA32-v3}, and in practice it is probably easier to add a new
+if you do that you'll need to carefully study and understand section
+3.7, ``Page Translation Using 32-Bit Physical Addressing,'' in
+@bibref{IA32-v3a}, and in practice it is probably easier to add a new
data structure.
@item
/* Store the physical address of the page directory into CR3
aka PDBR (page directory base register). This activates our
new page tables immediately. See [IA32-v2a] "MOV--Move
- to/from Control Registers" and [IA32-v3] 3.7.5. */
+ to/from Control Registers" and [IA32-v3a] 3.7.5 "Base Address
+ of the Page Directory". */
asm volatile ("movl %0, %%cr3" :: "r" (vtop (base_page_dir)));
}
#define INTR_CNT 256
/* The Interrupt Descriptor Table (IDT). The format is fixed by
- the CPU. See [IA32-v3] sections 5.10, 5.11, 5.12.1.2. */
+ the CPU. See [IA32-v3a] sections 5.10 "Interrupt Descriptor
+ Table (IDT)", 5.11 "IDT Descriptors", 5.12.1.2 "Flag Usage By
+ Exception- or Interrupt-Handler Procedure". */
static uint64_t idt[INTR_CNT];
/* Interrupt handler functions for each interrupt. */
/* Push the flags register on the processor stack, then pop the
value off the stack into `flags'. See [IA32-v2b] "PUSHF"
- and "POP" and [IA32-v3] 5.8.1. */
+ and "POP" and [IA32-v3a] 5.8.1 "Masking Maskable Hardware
+ Interrupts". */
asm volatile ("pushfl; popl %0" : "=g" (flags));
return flags & FLAG_IF ? INTR_ON : INTR_OFF;
ASSERT (!intr_context ());
/* Enable interrupts by setting the interrupt flag.
- See [IA32-v2b] "STI" and [IA32-v3] 5.8.1. */
+
+ See [IA32-v2b] "STI" and [IA32-v3a] 5.8.1 "Masking Maskable
+ Hardware Interrupts". */
asm volatile ("sti");
return old_level;
enum intr_level old_level = intr_get_level ();
/* Disable interrupts by clearing the interrupt flag.
- See [IA32-v2b] "CLI" and [IA32-v3] 5.8.1. */
+ See [IA32-v2b] "CLI" and [IA32-v3a] 5.8.1 "Masking Maskable
+ Hardware Interrupts". */
asm volatile ("cli");
return old_level;
idt[i] = make_intr_gate (intr_stubs[i], 0);
/* Load IDT register.
- See [IA32-v2a] "LIDT" and [IA32-v3] 5.10. */
+ See [IA32-v2a] "LIDT" and [IA32-v3a] 5.10 "Interrupt
+ Descriptor Table (IDT)". */
idtr_operand = make_idtr_operand (sizeof idt - 1, idt);
asm volatile ("lidt %0" :: "m" (idtr_operand));
user mode to invoke the interrupts and DPL==0 prevents such
invocation. Faults and exceptions that occur in user mode
still cause interrupts with DPL==0 to be invoked. See
- [IA32-v3] sections 4.5 and 4.8.1.1 for further discussion. */
+ [IA32-v3a] sections 4.5 "Privilege Levels" and 4.8.1.1
+ "Accessing Nonconforming Code Segments" for further
+ discussion. */
void
intr_register_int (uint8_t vec_no, int dpl, enum intr_level level,
intr_handler_func *handler, const char *name)
or lower-numbered ring. In practice, DPL==3 allows user mode
to call into the gate and DPL==0 prevents such calls. Faults
and exceptions that occur in user mode still cause gates with
- DPL==0 to be invoked. See [IA32-v3] sections 4.5 and 4.8.1.1
+ DPL==0 to be invoked. See [IA32-v3a] sections 4.5 "Privilege
+ Levels" and 4.8.1.1 "Accessing Nonconforming Code Segments"
for further discussion.
TYPE must be either 14 (for an interrupt gate) or 15 (for a
trap gate). The difference is that entering an interrupt gate
disables interrupts, but entering a trap gate does not. See
- [IA32-v3] section 5.12.1.2 for discussion. */
+ [IA32-v3a] section 5.12.1.2 "Flag Usage By Exception- or
+ Interrupt-Handler Procedure" for discussion. */
static uint64_t
make_gate (void (*function) (void), int dpl, int type)
{
/* Store current value of CR2 into `cr2'.
CR2 is the linear address of the last page fault.
See [IA32-v2a] "MOV--Move to/from Control Registers" and
- [IA32-v3] 5.14 "Interrupt 14--Page Fault Exception
+ [IA32-v3a] 5.14 "Interrupt 14--Page Fault Exception
(#PF)". */
asm ("movl %%cr2, %0" : "=r" (cr2));
# Add PDEs to point to PTEs for the first 64 MB of RAM.
# Also add identical PDEs starting at LOADER_PHYS_BASE.
-# See [IA32-v3] section 3.7.6 for a description of the bits in %eax.
+# See [IA32-v3a] section 3.7.6 "Page-Directory and Page-Table Entries"
+# for a description of the bits in %eax.
+
movl $0x11007, %eax
movl $0x11, %ecx
loop 1b
# Set up one-to-map linear to physical map for the first 64 MB of RAM.
-# See [IA32-v3] section 3.7.6 for a description of the bits in %eax.
+# See [IA32-v3a] section 3.7.6 "Page-Directory and Page-Table Entries"
+# for a description of the bits in %eax.
movw $0x1100, %ax
movw %ax, %es
\f
/* Page directories and page tables.
- For more information see [IA32-v3] pages 3-23 to 3-28.
+ For more information see [IA32-v3a] 3.7.6 "Page-Directory and
+ Page-Table Entries".
PDEs and PTEs share a common format:
one to occur, wasting as much as one clock tick worth of
time.
- See [IA32-v2a] "HLT", [IA32-v2b] "STI", and [IA32-v3] 7.7. */
+ See [IA32-v2a] "HLT", [IA32-v2b] "STI", and [IA32-v3a]
+ 7.11.1 "HLT Instruction". */
asm ("sti; hlt");
}
}
way as other exceptions, but this will need to change to
implement virtual memory.
- Refer to [IA32-v3] section 5.14 for a description of each of
- these exceptions. */
+ Refer to [IA32-v3a] section 5.15 "Exception and Interrupt
+ Reference" for a description of each of these exceptions. */
void
exception_init (void)
{
example code here shows how to parse that information. You
can find more information about both of these in the
description of "Interrupt 14--Page Fault Exception (#PF)" in
- [IA32-v3] section 5.14, which is pages 5-46 to 5-49. */
+ [IA32-v3a] section 5.15 "Exception and Interrupt Reference". */
static void
page_fault (struct intr_frame *f)
{
data. It is not necessarily the address of the instruction
that caused the fault (that's f->eip).
See [IA32-v2a] "MOV--Move to/from Control Registers" and
- [IA32-v3] 5.14 "Interrupt 14--Page Fault Exception
+ [IA32-v3a] 5.15 "Interrupt 14--Page Fault Exception
(#PF)". */
asm ("movl %%cr2, %0" : "=r" (fault_addr));
stack switching on interrupts.
For more information on the GDT as used here, refer to
- [IA32-v3] sections 3.2 through 3.5. */
+ [IA32-v3a] 3.2 "Using Segments" through 3.5 "System Descriptor
+ Types". */
static uint64_t gdt[SEL_CNT];
/* GDT helpers. */
gdt[SEL_UDSEG / sizeof *gdt] = make_data_desc (3);
gdt[SEL_TSS / sizeof *gdt] = make_tss_desc (tss_get ());
- /* Load GDTR, TR. See [IA32-v3] 2.4.1, 2.4.4, 6.2.3. */
+ /* Load GDTR, TR. See [IA32-v3a] 2.4.1 "Global Descriptor
+ Table Register (GDTR)", 2.4.4 "Task Register (TR)", and
+ 6.2.4 "Task Register". */
gdtr_operand = make_gdtr_operand (sizeof gdt - 1, gdt);
asm volatile ("lgdt %0" :: "m" (gdtr_operand));
asm volatile ("ltr %w0" :: "r" (SEL_TSS));
it can be used in rings numbered DPL or lower. In practice,
DPL==3 means that user processes can use the segment and
DPL==0 means that only the kernel can use the segment. See
- [IA32-v3] section 4.5 for further discussion. */
+ [IA32-v3a] 4.5 "Privilege Levels" for further discussion. */
static uint64_t
make_seg_desc (uint32_t base,
uint32_t limit,
/* Returns a descriptor for an "available" 32-bit Task-State
Segment with its base at the given linear address, a limit of
0x67 bytes (the size of a 32-bit TSS), and a DPL of 0.
- See [IA32-v3] 6.2.2. */
+ See [IA32-v3a] 6.2.2 "TSS Descriptor". */
static uint64_t
make_tss_desc (void *laddr)
{
/* Store the physical address of the page directory into CR3
aka PDBR (page directory base register). This activates our
new page tables immediately. See [IA32-v2a] "MOV--Move
- to/from Control Registers" and [IA32-v3] 3.7.5. */
+ to/from Control Registers" and [IA32-v3a] 3.7.5 "Base
+ Address of the Page Directory". */
asm volatile ("movl %0, %%cr3" :: "r" (vtop (pd)));
}
/* Copy CR3, the page directory base register (PDBR), into
`pd'.
See [IA32-v2a] "MOV--Move to/from Control Registers" and
- [IA32-v3] 3.7.5. */
+ [IA32-v3a] 3.7.5 "Base Address of the Page Directory". */
uintptr_t pd;
asm volatile ("movl %%cr3, %0" : "=r" (pd));
return ptov (pd);
{
if (active_pd () == pd)
{
- /* We cleared a page-table entry in the active page
- table, so we have to invalidate the TLB. See
- [IA32-v3], section 3.11. */
+ /* We cleared a page-table entry in the active page table,
+ so we have to invalidate the TLB. See [IA32-v3a] 3.12
+ "Translation Lookaside Buffers (TLBs)". */
pagedir_activate (pd);
}
}
stack pointer to point to the new thread's kernel stack.
(The call is in schedule_tail() in thread.c.)
- See [IA32-v3] 6.2.1 for a description of the TSS and 5.12.1
- for a description of when and how stack switching occurs
- during an interrupt. */
+ See [IA32-v3a] 6.2.1 "Task-State Segment (TSS)" for a
+ description of the TSS. See [IA32-v3a] 5.12.1 "Exception- or
+ Interrupt-Handler Procedures" for a description of when and
+ how stack switching occurs during an interrupt. */
struct tss
{
uint16_t back_link, :16;