Minix1.5/kernel/protect1.c

Compare this file to the similar file:
Show the results in this format:

/* This file contains routines to initialize code and data segment
 * descriptors, and to initialize global descriptors for local descriptors
 * in the process table.
 * It is separate from protect.c for the 386 32-bit kernel.
 * There it must be compiled into 32-bit code (for use by the kernel) and
 * (apart from the LDT initialization) into static 16-bit code (for use by
 * the routines in protect.c), while protect.c must be compiled into 16-bit
 * code to initialize 32-bit mode.
 */

#ifdef _SYSTEM			/* this is being included by protect.c */
#define MAYBE_PUBLIC PRIVATE
#define NEED_LDT_INIT 0
#define init_codeseg linit_codeseg
#define init_dataseg linit_dataseg
#define sdesc lsdesc
#else				/* native version */
#include "kernel.h"
#include "proc.h"
#include "protect.h"
#define MAYBE_PUBLIC PUBLIC
#define NEED_LDT_INIT 1
#endif

FORWARD void sdesc();

/*=========================================================================*
 *				init_codeseg				   *
 *=========================================================================*/
MAYBE_PUBLIC void init_codeseg(segdp, base, size, privilege)
register struct segdesc_s *segdp;
phys_bytes base;
phys_bytes size;
int privilege;
{
/* Build descriptor for a code segment. */

  sdesc(segdp, base, size);
  segdp->access = (privilege << DPL_SHIFT)
	        | (PRESENT | SEGMENT | EXECUTABLE | READABLE);
		/* CONFORMING = 0, ACCESSED = 0 */
}

/*=========================================================================*
 *				init_dataseg				   *
 *=========================================================================*/
MAYBE_PUBLIC void init_dataseg(segdp, base, size, privilege)
register struct segdesc_s *segdp;
phys_bytes base;
phys_bytes size;
int privilege;
{
/* Build descriptor for a data segment. */

  sdesc(segdp, base, size);
  segdp->access = (privilege << DPL_SHIFT) | (PRESENT | SEGMENT | WRITEABLE);
		/* EXECUTABLE = 0, EXPAND_DOWN = 0, ACCESSED = 0 */
}

#if NEED_LDT_INIT
/*=========================================================================*
 *				ldt_init				   *
 *=========================================================================*/
PUBLIC void ldt_init()
{
/* Build local descriptors in GDT for LDT's in process table.
 * The LDT's are allocated at compile time in the process table, and
 * initialized whenever a process' map is initialized or changed.
 */

  unsigned ldt_selector;
  register struct proc *rp;

  for (rp = BEG_PROC_ADDR, ldt_selector = FIRST_LDT_INDEX * DESC_SIZE;
       rp < END_PROC_ADDR; ++rp, ldt_selector += DESC_SIZE) {
	init_dataseg(&gdt[ldt_selector / DESC_SIZE],
		     data_base + (phys_bytes) (vir_bytes) rp->p_ldt,
		     (phys_bytes) sizeof rp->p_ldt, INTR_PRIVILEGE);
	gdt[ldt_selector / DESC_SIZE].access = PRESENT | LDT;
	rp->p_ldt_sel = ldt_selector;
  }
}
#endif				/* NEED_LDT_INIT */

/*=========================================================================*
 *				sdesc					   *
 *=========================================================================*/
PRIVATE void sdesc(segdp, base, size)
register struct segdesc_s *segdp;
phys_bytes base;
phys_bytes size;
{
/* Fill in the size fields (base, limit and granularity) of a descriptor. */

  segdp->base_low = base;
  segdp->base_middle = base >> BASE_MIDDLE_SHIFT;
#if INTEL_32BITS
  segdp->base_high = base >> BASE_HIGH_SHIFT;
  --size;			/* convert to a limit, 0 size means 4G */
  if (size > BYTE_GRAN_MAX) {
	segdp->limit_low = size >> PAGE_GRAN_SHIFT;
	segdp->granularity = GRANULAR | (size >>
				     (PAGE_GRAN_SHIFT + GRANULARITY_SHIFT));
  } else {
	segdp->limit_low = size;
	segdp->granularity = size >> GRANULARITY_SHIFT;
  }
  segdp->granularity |= DEFAULT;	/* means BIG for data seg */
#else
  segdp->limit_low = size - 1;
#endif
}