pt[pte_idx] = pte_create_kernel (vaddr, true);
}
+ /* 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. */
asm volatile ("movl %0,%%cr3" :: "r" (vtop (base_page_dir)));
}
intr_get_level (void)
{
uint32_t flags;
-
+
+ /* 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. */
asm volatile ("pushfl; popl %0" : "=g" (flags));
return flags & FLAG_IF ? INTR_ON : INTR_OFF;
{
enum intr_level old_level = intr_get_level ();
ASSERT (!intr_context ());
+
+ /* Enable interrupts by setting the interrupt flag.
+ See [IA32-v2b] "STI" and [IA32-v3] 5.8.1. */
asm volatile ("sti");
+
return old_level;
}
intr_disable (void)
{
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. */
asm volatile ("cli");
+
return old_level;
}
\f
for (i = 0; i < INTR_CNT; i++)
idt[i] = make_intr_gate (intr_stubs[i], 0);
- /* Load IDT register. */
+ /* Load IDT register.
+ See [IA32-v2a] "LIDT" and [IA32-v3] 5.10. */
idtr_operand = make_idtr_operand (sizeof idt - 1, idt);
asm volatile ("lidt %0" :: "m" (idtr_operand));
void
intr_dump_frame (const struct intr_frame *f)
{
- uint32_t cr2, ss;
+ uint32_t cr2;
+
+ /* 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
+ (#PF)". */
asm ("movl %%cr2, %0" : "=r" (cr2));
- asm ("movl %%ss, %0" : "=r" (ss));
printf ("Interrupt %#04x (%s) at eip=%p\n",
f->vec_no, intr_names[f->vec_no], f->eip);
printf (" esi=%08"PRIx32" edi=%08"PRIx32" esp=%08"PRIx32" ebp=%08"PRIx32"\n",
f->esi, f->edi, (uint32_t) f->esp, f->ebp);
printf (" cs=%04"PRIx16" ds=%04"PRIx16" es=%04"PRIx16" ss=%04"PRIx16"\n",
- f->cs, f->ds, f->es, f->cs != SEL_KCSEG ? f->ss : ss);
+ f->cs, f->ds, f->es, f->ss);
}
/* Returns the name of interrupt VEC. */
static inline uint8_t
inb (uint16_t port)
{
+ /* See [IA32-v2a] "IN". */
uint8_t data;
asm volatile ("inb %w1,%0" : "=a" (data) : "d" (port));
return data;
static inline void
insb (uint16_t port, void *addr, size_t cnt)
{
+ /* See [IA32-v2a] "INS". */
asm volatile ("cld; repne; insb"
: "=D" (addr), "=c" (cnt)
: "d" (port), "0" (addr), "1" (cnt)
inw (uint16_t port)
{
uint16_t data;
+ /* See [IA32-v2a] "IN". */
asm volatile ("inw %w1,%0" : "=a" (data) : "d" (port));
return data;
}
static inline void
insw (uint16_t port, void *addr, size_t cnt)
{
+ /* See [IA32-v2a] "INS". */
asm volatile ("cld; repne; insw"
: "=D" (addr), "=c" (cnt)
: "d" (port), "0" (addr), "1" (cnt)
static inline uint32_t
inl (uint16_t port)
{
+ /* See [IA32-v2a] "IN". */
uint32_t data;
asm volatile ("inl %w1,%0" : "=a" (data) : "d" (port));
return data;
static inline void
insl (uint16_t port, void *addr, size_t cnt)
{
+ /* See [IA32-v2a] "INS". */
asm volatile ("cld; repne; insl"
: "=D" (addr), "=c" (cnt)
: "d" (port), "0" (addr), "1" (cnt)
static inline void
outb (uint16_t port, uint8_t data)
{
+ /* See [IA32-v2b] "OUT". */
asm volatile ("outb %0,%w1" : : "a" (data), "d" (port));
}
static inline void
outsb (uint16_t port, const void *addr, size_t cnt)
{
+ /* See [IA32-v2b] "OUTS". */
asm volatile ("cld; repne; outsb"
: "=S" (addr), "=c" (cnt)
: "d" (port), "0" (addr), "1" (cnt)
static inline void
outw (uint16_t port, uint16_t data)
{
+ /* See [IA32-v2b] "OUT". */
asm volatile ("outw %0,%w1" : : "a" (data), "d" (port));
}
static inline void
outsw (uint16_t port, const void *addr, size_t cnt)
{
+ /* See [IA32-v2b] "OUTS". */
asm volatile ("cld; repne; outsw"
: "=S" (addr), "=c" (cnt)
: "d" (port), "0" (addr), "1" (cnt)
static inline void
outl (uint16_t port, uint32_t data)
{
+ /* See [IA32-v2b] "OUT". */
asm volatile ("outl %0,%w1" : : "a" (data), "d" (port));
}
static inline void
outsl (uint16_t port, const void *addr, size_t cnt)
{
+ /* See [IA32-v2b] "OUTS". */
asm volatile ("cld; repne; outsl"
: "=S" (addr), "=c" (cnt)
: "d" (port), "0" (addr), "1" (cnt)
thread_block ();
intr_enable ();
- /* Use CPU `hlt' instruction to wait for interrupt. */
+ /* Use CPU `hlt' instruction to wait for interrupt.
+ See [IA32-v2a] "HLT" and [IA32-v3] 7.7. */
asm ("hlt");
}
}
/* Obtain faulting address, the virtual address that was
accessed to cause the fault. It may point to code or to
data. It is not necessarily the address of the instruction
- that caused the fault (that's f->eip). */
+ 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
+ (#PF)". */
asm ("movl %%cr2, %0" : "=r" (fault_addr));
/* Turn interrupts back on (they were only off so that we could
{
if (pd == NULL)
pd = base_page_dir;
+
+ /* 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. */
asm volatile ("movl %0,%%cr3" :: "r" (vtop (pd)));
}
{
uint32_t *pd;
+ /* Copy CR3, the page directory base register (PDBR), into `pd'
+ for us to exmaine. See [IA32-v2a] "MOV--Move to/from
+ Control Registers" and [IA32-v3] 3.7.5. */
asm ("movl %%cr3,%0" : "=r" (pd));
return pd;
}