X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fsegm.c;h=c6baffd091b88fef430b4a1e2853b7d148338a6a;hb=0a37e241149d011e038aceb3faac568b405f8ecd;hp=d2f940a6ad235daf4b4c6272a9edb54e1421a5be;hpb=a2f94f569a4c99204de02814a20098a71527e913;p=bootcensus diff --git a/src/segm.c b/src/segm.c index d2f940a..c6baffd 100644 --- a/src/segm.c +++ b/src/segm.c @@ -1,3 +1,20 @@ +/* +pcboot - bootable PC demo/game kernel +Copyright (C) 2018 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY, without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ #include #include "segm.h" #include "desc.h" @@ -26,6 +43,7 @@ enum {TYPE_DATA, TYPE_CODE}; #define TSS_TYPE_BITS (9 << 8) static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type); +static void segm_desc16(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type); static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl); /* these functions are implemented in segm-asm.S */ @@ -35,7 +53,7 @@ void set_task_reg(uint16_t tss_selector); /* our global descriptor table */ -static desc_t gdt[6] __attribute__((aligned(8))); +static desc_t gdt[NUM_SEGMENTS] __attribute__((aligned(8))); void init_segm(void) @@ -45,6 +63,7 @@ void init_segm(void) segm_desc(gdt + SEGM_KDATA, 0, 0xffffffff, 0, TYPE_DATA); segm_desc(gdt + SEGM_UCODE, 0, 0xffffffff, 3, TYPE_CODE); segm_desc(gdt + SEGM_UDATA, 0, 0xffffffff, 3, TYPE_DATA); + segm_desc16(gdt + SEGM_CODE16, 0, 0xffff, 0, TYPE_CODE); set_gdt((uint32_t)gdt, sizeof gdt - 1); @@ -81,6 +100,22 @@ static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int desc->d[3] = ((limit >> 16) & 0xf) | ((base >> 16) & 0xff00) | BIT_GRAN | BIT_BIG; } +static void segm_desc16(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type) +{ + desc->d[0] = limit & 0xffff; /* low order 16bits of limit */ + desc->d[1] = base & 0xffff; /* low order 16bits of base */ + + /* third 16bit part contains the last 8 bits of base, the 2 priviledge + * level bits starting on bit 13, present flag on bit 15, and type bits + * starting from bit 8 + */ + desc->d[2] = ((base >> 16) & 0xff) | ((dpl & 3) << 13) | BIT_PRESENT | + BIT_NOSYS | (type == TYPE_DATA ? BIT_WR : (BIT_RD | BIT_CODE)); + + /* 16bit descriptors have the upper word 0 */ + desc->d[3] = 0; +} + static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl) { desc->d[0] = limit & 0xffff;