This repository has been archived on 2021-03-01. You can view files and clone it, but cannot push or open issues or pull requests.
kaneton/kaneton/machine/architecture/ia32/educational/pmode.c
Mercier Pierre-Olivier fee4dd4e6d Initial snapshot
2013-02-11 22:04:30 +01:00

128 lines
2.5 KiB
C

/*
* ---------- header ----------------------------------------------------------
*
* project kaneton
*
* license kaneton
*
* file /home/mycure/kane...ne/architecture/ia32/educational/pmode.c
*
* created julien quintard [sat jan 8 19:01:44 2011]
* updated julien quintard [sun jan 16 13:42:19 2011]
*/
/*
* ---------- information -----------------------------------------------------
*
* this file contains functions for managing the ia32 protected mode.
*/
/*
* ---------- includes --------------------------------------------------------
*/
#include <kaneton.h>
/*
* ---------- globals ---------------------------------------------------------
*/
/*
* the init structure.
*/
extern s_init* _init;
/*
* ---------- functions -------------------------------------------------------
*/
/*
* this function enables the protected mode by setting the PE bit in CR0.
*/
t_error architecture_pmode_enable(void)
{
asm volatile("movl %%cr0, %%eax\n"
"orw $1, %%ax\n"
"movl %%eax, %%cr0\n"
:
:
: "%eax");
asm volatile("jmp 1f\n"
"1:"
);
MACHINE_LEAVE();
}
/*
* this function sets up the protected mode.
*
* steps:
*
* 1) build a GDT descriptor based on the GDT prepared by the boot loader.
* 2) import the descriptor in order to make it the current system's GDT.
* 3) enable the protected mode.
*/
t_error architecture_pmode_setup(void)
{
as_gdt gdt;
/*
* 1)
*/
gdt.table = (void*)_init->machine.gdt;
gdt.size = ARCHITECTURE_GDT_SIZE;
/*
* 2)
*/
if (architecture_gdt_build(_init->machine.gdt,
ARCHITECTURE_GDT_SIZE * sizeof (at_gdte),
&gdt) != ERROR_OK)
MACHINE_ESCAPE("unable to build the GDT");
if (architecture_gdt_import(&gdt) != ERROR_OK)
MACHINE_ESCAPE("unable to import the boot loader's GDT");
/*
* 3)
*/
if (architecture_pmode_enable() != ERROR_OK)
MACHINE_ESCAPE("unable to enable the protected mode");
MACHINE_LEAVE();
}
/*
* this function install the given segment registers by updating
* the processor's segment registers.
*/
t_error architecture_pmode_registers(t_uint16 code,
t_uint16 data)
{
asm volatile("pushl %0\n\t"
"pushl $1f\n\t"
"lret\n\t"
"1:\n\t"
"movw %1, %%ax\n\t"
"movw %%ax, %%ds\n\t"
"movw %%ax, %%ss\n\t"
"movw %%ax, %%es\n\t"
"movw %%ax, %%fs\n\t"
"movw %%ax, %%gs\n\t"
:
: "g" (code), "g" (data)
: "memory", "%eax"
);
MACHINE_LEAVE();
}