kern

diff src/segm.c @ 55:88a6c4e192f9

Fixed most important task switching bugs. Now it seems that I can switch in and out of user space reliably.
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 15 Aug 2011 04:03:39 +0300
parents 4eaecb14fe31
children
line diff
     1.1 --- a/src/segm.c	Sun Aug 14 16:57:23 2011 +0300
     1.2 +++ b/src/segm.c	Mon Aug 15 04:03:39 2011 +0300
     1.3 @@ -1,6 +1,7 @@
     1.4  #include <string.h>
     1.5  #include "segm.h"
     1.6  #include "desc.h"
     1.7 +#include "tss.h"
     1.8  
     1.9  /* bits for the 3rd 16bt part of the descriptor */
    1.10  #define BIT_ACCESSED	(1 << 8)
    1.11 @@ -21,10 +22,11 @@
    1.12  
    1.13  enum {TYPE_DATA, TYPE_CODE};
    1.14  
    1.15 -#define TSS_TYPE_BITS	(BIT_ACCESSED | BIT_CODE)
    1.16 +/* we need the following bit pattern at the 8th bit excluding the busy bit: 1001 */
    1.17 +#define TSS_TYPE_BITS	(9 << 8)
    1.18  
    1.19  static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type);
    1.20 -static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, unsigned int busy);
    1.21 +static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl);
    1.22  
    1.23  /* these functions are implemented in segm-asm.S */
    1.24  void setup_selectors(uint16_t code, uint16_t data);
    1.25 @@ -57,7 +59,7 @@
    1.26  
    1.27  void set_tss(uint32_t addr)
    1.28  {
    1.29 -	task_desc(gdt + SEGM_TASK, 0, sizeof(struct tss) - 1, 3, TSS_BUSY);
    1.30 +	task_desc(gdt + SEGM_TASK, addr, sizeof(struct task_state) - 1, 3);
    1.31  	set_task_reg(selector(SEGM_TASK, 0));
    1.32  }
    1.33  
    1.34 @@ -79,12 +81,44 @@
    1.35  	desc->d[3] = ((limit >> 16) & 0xf) | ((base >> 16) & 0xff00) | BIT_GRAN | BIT_BIG;
    1.36  }
    1.37  
    1.38 -static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, unsigned int busy)
    1.39 +static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl)
    1.40  {
    1.41  	desc->d[0] = limit & 0xffff;
    1.42  	desc->d[1] = base & 0xffff;
    1.43  
    1.44  	desc->d[2] = ((base >> 16) & 0xff) | ((dpl & 3) << 13) | BIT_PRESENT |
    1.45 -		TSS_TYPE_BITS | busy;
    1.46 +		TSS_TYPE_BITS; /* XXX busy ? */
    1.47  	desc->d[3] = ((limit >> 16) & 0xf) | ((base >> 16) & 0xff00) | BIT_GRAN;
    1.48  }
    1.49 +/*
    1.50 +static void dbg_print_gdt(void)
    1.51 +{
    1.52 +	int i;
    1.53 +
    1.54 +	printf("Global Descriptor Table\n");
    1.55 +	printf("-----------------------\n");
    1.56 +
    1.57 +	for(i=0; i<6; i++) {
    1.58 +		print_desc(gdt + i);
    1.59 +	}
    1.60 +}
    1.61 +
    1.62 +static void print_desc(desc_t *desc)
    1.63 +{
    1.64 +	uint32_t base, limit;
    1.65 +	int dpl, g, db, l, avl, p, s, type;
    1.66 +	char *type_str;
    1.67 +
    1.68 +	base = (uint32_t)desc->d[1] | ((uint32_t)(desc->d[2] & 0xff) << 16) | ((uint32_t)(desc->d[3] >> 8) << 24);
    1.69 +	limit = (uint32_t)desc->d[0] | ((uint32_t)(desc->d[3] & 0xf) << 16);
    1.70 +	dpl = (desc->d[2] >> 13) & 3;
    1.71 +	type = (desc->d[2] >> 8) & 0xf;
    1.72 +	g = (desc->d[3] >> 23) & 1;
    1.73 +	db = (desc->d[3] >> 22) & 1;
    1.74 +	l = (desc->d[3] >> 21) & 1;
    1.75 +	avl = (desc->d[3] >> 20) & 1;
    1.76 +
    1.77 +	p = (desc->d[2] >> 15) & 1;
    1.78 +	s = (desc->d[2] >> 12) & 1;
    1.79 +}
    1.80 +*/