Changeset 2382d09 in mainline for arch/ia32


Ignore:
Timestamp:
2006-04-29T15:01:41Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
407862e
Parents:
69a5600
Message:

Improve SYS_IOSPACE_ENABLE support.
The general protection fault handler now contains
code to service early I/O Permission bitmap faults.

Location:
arch/ia32
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • arch/ia32/include/cpu.h

    r69a5600 r2382d09  
    4343        int stepping;
    4444        struct tss *tss;
     45       
     46        count_t iomapver_copy;  /** Copy of TASK's I/O Permission bitmap generation count. */
    4547};
    4648
  • arch/ia32/include/proc/task.h

    r69a5600 r2382d09  
    3535
    3636typedef struct {
    37         bitmap_t iomap;
     37        count_t iomapver;       /**< I/O Permission bitmap Generation counter. */
     38        bitmap_t iomap;         /**< I/O Permission bitmap. */
    3839} task_arch_t;
    3940
  • arch/ia32/src/ddi/ddi.c

    r69a5600 r2382d09  
    2828
    2929#include <ddi/ddi.h>
     30#include <arch/ddi/ddi.h>
    3031#include <proc/task.h>
    3132#include <arch/types.h>
     
    3637#include <errno.h>
    3738#include <arch/cpu.h>
     39#include <cpu.h>
     40#include <arch.h>
    3841
    3942/** Enable I/O space range for task.
     
    9093        bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
    9194
     95        /*
     96         * Increment I/O Permission bitmap generation counter.
     97         */
     98        task->arch.iomapver++;
     99
    92100        return 0;
    93101}
     
    106114        return 0;
    107115}
     116
     117/** Install I/O Permission bitmap.
     118 *
     119 * Current task's I/O permission bitmap, if any, is installed
     120 * in the current CPU's TSS.
     121 *
     122 * Interrupts must be disabled prior this call.
     123 */
     124void io_perm_bitmap_install(void)
     125{
     126        count_t bits;
     127        ptr_16_32_t cpugdtr;
     128        descriptor_t *gdt_p;
     129        count_t ver;
     130
     131        /* First, copy the I/O Permission Bitmap. */
     132        spinlock_lock(&TASK->lock);
     133        ver = TASK->arch.iomapver;
     134        if ((bits = TASK->arch.iomap.bits)) {
     135                bitmap_t iomap;
     136       
     137                ASSERT(TASK->arch.iomap.map);
     138                bitmap_initialize(&iomap, CPU->arch.tss->iomap, TSS_IOMAP_SIZE * 8);
     139                bitmap_copy(&iomap, &TASK->arch.iomap, TASK->arch.iomap.bits);
     140                /*
     141                 * It is safe to set the trailing eight bits because of the extra
     142                 * convenience byte in TSS_IOMAP_SIZE.
     143                 */
     144                bitmap_set_range(&iomap, TASK->arch.iomap.bits, 8);
     145        }
     146        spinlock_unlock(&TASK->lock);
     147
     148        /* Second, adjust TSS segment limit. */
     149        gdtr_store(&cpugdtr);
     150        gdt_p = (descriptor_t *) cpugdtr.base;
     151        gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits) - 1);
     152        gdtr_load(&cpugdtr);
     153
     154        /*
     155         * Before we load new TSS limit, the current TSS descriptor
     156         * type must be changed to describe inactive TSS.
     157         */
     158        gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
     159        tr_load(selector(TSS_DES));
     160       
     161        /*
     162         * Update the generation count so that faults caused by
     163         * early accesses can be serviced.
     164         */
     165        CPU->arch.iomapver_copy = ver;
     166}
  • arch/ia32/src/interrupt.c

    r69a5600 r2382d09  
    4141#include <symtab.h>
    4242#include <proc/thread.h>
     43#include <proc/task.h>
     44#include <synch/spinlock.h>
     45#include <arch/ddi/ddi.h>
    4346
    4447/*
     
    7982}
    8083
     84/** General Protection Fault. */
    8185void gp_fault(int n, istate_t *istate)
    8286{
     87        if (TASK) {
     88                count_t ver;
     89               
     90                spinlock_lock(&TASK->lock);
     91                ver = TASK->arch.iomapver;
     92                spinlock_unlock(&TASK->lock);
     93       
     94                if (CPU->arch.iomapver_copy != ver) {
     95                        /*
     96                         * This fault can be caused by an early access
     97                         * to I/O port because of an out-dated
     98                         * I/O Permission bitmap installed on CPU.
     99                         * Install the fresh copy and restart
     100                         * the instruction.
     101                         */
     102                        io_perm_bitmap_install();
     103                        return;
     104                }
     105        }
     106
    83107        PRINT_INFO_ERRCODE(istate);
    84108        panic("general protection fault\n");
  • arch/ia32/src/proc/scheduler.c

    r69a5600 r2382d09  
    3636#include <arch/pm.h>
    3737#include <arch/asm.h>
    38 #include <adt/bitmap.h>
    39 #include <print.h>
     38#include <arch/ddi/ddi.h>
    4039
    4140/** Perform ia32 specific tasks needed before the new task is run.
     
    4544void before_task_runs_arch(void)
    4645{
    47         count_t bits;
    48         ptr_16_32_t cpugdtr;
    49         descriptor_t *gdt_p;
    50 
    51         /*
    52          * Switch the I/O Permission Bitmap, if necessary.
    53          */
    54 
    55         /* First, copy the I/O Permission Bitmap. */
    56         spinlock_lock(&TASK->lock);
    57         if ((bits = TASK->arch.iomap.bits)) {
    58                 bitmap_t iomap;
    59        
    60                 ASSERT(TASK->arch.iomap.map);
    61                 bitmap_initialize(&iomap, CPU->arch.tss->iomap, TSS_IOMAP_SIZE * 8);
    62                 bitmap_copy(&iomap, &TASK->arch.iomap, TASK->arch.iomap.bits);
    63                 /*
    64                  * It is safe to set the trailing eight bits because of the extra
    65                  * convenience byte in TSS_IOMAP_SIZE.
    66                  */
    67                 bitmap_set_range(&iomap, TASK->arch.iomap.bits, 8);
    68         }
    69         spinlock_unlock(&TASK->lock);
    70 
    71         /* Second, adjust TSS segment limit. */
    72         gdtr_store(&cpugdtr);
    73         gdt_p = (descriptor_t *) cpugdtr.base;
    74         gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits) - 1);
    75         gdtr_load(&cpugdtr);
    76 
    77         /*
    78          * Before we load new TSS limit, the current TSS descriptor
    79          * type must be changed to describe inactive TSS.
    80          */
    81         gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
    82         tr_load(selector(TSS_DES));
     46        io_perm_bitmap_install();
    8347}
    8448
Note: See TracChangeset for help on using the changeset viewer.