Changeset 92778f2 in mainline


Ignore:
Timestamp:
2006-12-04T21:14:07Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4b43f86
Parents:
3d76996
Message:

Initial support for handling illegal virtual aliases on sparc64.

Location:
kernel
Files:
1 added
16 edited
1 moved

Legend:

Unmodified
Added
Removed
  • kernel/Makefile

    r3d76996 r92778f2  
    9292endif
    9393
    94 ifeq ($(CONFIG_VIRT_IDX_CACHE),y)
    95         DEFS += -DCONFIG_VIRT_IDX_CACHE
     94ifeq ($(CONFIG_VIRT_IDX_DCACHE),y)
     95        DEFS += -DCONFIG_VIRT_IDX_DCACHE
    9696endif
    9797
  • kernel/arch/sparc64/Makefile.inc

    r3d76996 r92778f2  
    8585        arch/$(ARCH)/src/mm/as.c \
    8686        arch/$(ARCH)/src/mm/cache.c \
     87        arch/$(ARCH)/src/mm/cache_asm.S \
    8788        arch/$(ARCH)/src/mm/frame.c \
    8889        arch/$(ARCH)/src/mm/page.c \
  • kernel/arch/sparc64/include/cpu.h

    r3d76996 r92778f2  
    5656        ver_reg_t ver;
    5757        uint32_t clock_frequency;       /**< Processor frequency in MHz. */
     58        int dcache_active;              /**< When non-zero, the D-cache is not being shot down. */
    5859};
    5960       
  • kernel/arch/sparc64/include/interrupt.h

    r3d76996 r92778f2  
    4444#define IVT_FIRST       1
    4545
     46/* This needs to be defined for inter-architecture API portability. */
    4647#define VECTOR_TLB_SHOOTDOWN_IPI        0
    47 #define IPI_TLB_SHOOTDOWN               VECTOR_TLB_SHOOTDOWN_IPI
     48
     49enum {
     50        IPI_TLB_SHOOTDOWN = VECTOR_TLB_SHOOTDOWN_IPI,
     51        IPI_DCACHE_SHOOTDOWN
     52};             
    4853
    4954struct istate {
  • kernel/arch/sparc64/include/mm/as.h

    r3d76996 r92778f2  
    5353        tsb_entry_t *itsb;
    5454        tsb_entry_t *dtsb;
    55 #endif
     55#endif /* CONFIG_TSB */
    5656} as_arch_t;
    5757
  • kernel/arch/sparc64/include/mm/cache.h

    r3d76996 r92778f2  
    3636#define KERN_sparc64_CACHE_H_
    3737
     38#ifdef CONFIG_SMP
     39extern void dcache_shootdown_start(void);
     40extern void dcache_shootdown_finalize(void);
     41extern void dcache_shootdown_ipi_recv(void);
     42#else /* CONFIG_SMP */
     43#define dcache_shootdown_start();
     44#define dcache_shootdown_finalize();
     45#define dcache_shootdown_ipi_recv();
     46#endif /* CONFIG_SMP */
     47
    3848extern void dcache_flush(void);
    3949
  • kernel/arch/sparc64/src/cpu/cpu.c

    r3d76996 r92778f2  
    9393        }
    9494
     95        /*
     96         * Set the D-cache active flag.
     97         * Needed for the D-cache to work.
     98         */
     99        CPU->arch.dcache_active = 1;
    95100}
    96101
  • kernel/arch/sparc64/src/mm/as.c

    r3d76996 r92778f2  
    4848#include <bitops.h>
    4949#include <macros.h>
    50 #endif
     50#endif /* CONFIG_TSB */
     51
     52#ifdef CONFIG_VIRT_IDX_DCACHE
     53#include <arch/mm/cache.h>
     54#endif /* CONFIG_VIRT_IDX_DCACHE */
    5155
    5256/** Architecture dependent address space init. */
     
    159163        dtsb_base_write(tsb_base.value);
    160164#endif
     165#ifdef CONFIG_VIRT_IDX_DCACHE
     166        if (as->dcache_flush_on_install) {
     167                /*
     168                 * Some mappings in this address space are illegal address
     169                 * aliases. Upon their creation, the flush_dcache_on_install
     170                 * flag was set.
     171                 *
     172                 * We are now obliged to flush the D-cache in order to guarantee
     173                 * that there will be at most one cache line for each address
     174                 * alias.
     175                 *
     176                 * This flush performs a cleanup after another address space in
     177                 * which the alias might have existed.
     178                 */
     179                dcache_flush();
     180        }
     181#endif /* CONFIG_VIRT_IDX_DCACHE */
    161182}
    162183
     
    193214        }
    194215#endif
     216#ifdef CONFIG_VIRT_IDX_DCACHE
     217        if (as->dcache_flush_on_deinstall) {
     218                /*
     219                 * Some mappings in this address space are illegal address
     220                 * aliases. Upon their creation, the flush_dcache_on_deinstall
     221                 * flag was set.
     222                 *
     223                 * We are now obliged to flush the D-cache in order to guarantee
     224                 * that there will be at most one cache line for each address
     225                 * alias.
     226                 *
     227                 * This flush performs a cleanup after this address space. It is
     228                 * necessary because other address spaces that contain the same
     229                 * alias are not necessarily aware of the need to carry out the
     230                 * cache flush. The only address spaces that are aware of it are
     231                 * those that created the illegal alias.
     232                 */
     233                dcache_flush();
     234        }
     235#endif /* CONFIG_VIRT_IDX_DCACHE */
    195236}
    196237
  • kernel/arch/sparc64/src/mm/tlb.c

    r3d76996 r92778f2  
    112112        data.l = locked;
    113113        data.cp = cacheable;
    114 #ifdef CONFIG_VIRT_IDX_CACHE
     114#ifdef CONFIG_VIRT_IDX_DCACHE
    115115        data.cv = cacheable;
    116 #endif /* CONFIG_VIRT_IDX_CACHE */
     116#endif /* CONFIG_VIRT_IDX_DCACHE */
    117117        data.p = true;
    118118        data.w = true;
     
    149149        data.l = false;
    150150        data.cp = t->c;
    151 #ifdef CONFIG_VIRT_IDX_CACHE
     151#ifdef CONFIG_VIRT_IDX_DCACHE
    152152        data.cv = t->c;
    153 #endif /* CONFIG_VIRT_IDX_CACHE */
     153#endif /* CONFIG_VIRT_IDX_DCACHE */
    154154        data.p = t->k;          /* p like privileged */
    155155        data.w = ro ? false : t->w;
     
    185185        data.l = false;
    186186        data.cp = t->c;
    187 #ifdef CONFIG_VIRT_IDX_CACHE
    188         data.cv = t->c;
    189 #endif /* CONFIG_VIRT_IDX_CACHE */
    190187        data.p = t->k;          /* p like privileged */
    191188        data.w = false;
  • kernel/arch/sparc64/src/mm/tsb.c

    r3d76996 r92778f2  
    101101        tsb->data.pfn = t->frame >> FRAME_WIDTH;
    102102        tsb->data.cp = t->c;
    103 #ifdef CONFIG_VIRT_IDX_CACHE
    104         tsb->data.cv = t->c;
    105 #endif /* CONFIG_VIRT_IDX_CACHE */
    106103        tsb->data.p = t->k;             /* p as privileged */
    107104        tsb->data.v = t->p;
     
    143140        tsb->data.pfn = t->frame >> FRAME_WIDTH;
    144141        tsb->data.cp = t->c;
    145 #ifdef CONFIG_VIRT_IDX_CACHE
     142#ifdef CONFIG_VIRT_IDX_DCACHE
    146143        tsb->data.cv = t->c;
    147 #endif /* CONFIG_VIRT_IDX_CACHE */
     144#endif /* CONFIG_VIRT_IDX_DCACHE */
    148145        tsb->data.p = t->k;             /* p as privileged */
    149146        tsb->data.w = ro ? false : t->w;
  • kernel/arch/sparc64/src/smp/ipi.c

    r3d76996 r92778f2  
    3939#include <config.h>
    4040#include <mm/tlb.h>
     41#include <arch/mm/cache.h>
    4142#include <arch/interrupt.h>
    4243#include <arch/trap/interrupt.h>
     
    121122                func = tlb_shootdown_ipi_recv;
    122123                break;
     124        case IPI_DCACHE_SHOOTDOWN:
     125                func = dcache_shootdown_ipi_recv;
     126                break;
    123127        default:
    124128                panic("Unknown IPI (%d).\n", ipi);
  • kernel/arch/sparc64/src/start.S

    r3d76996 r92778f2  
    123123        membar #Sync
    124124
    125 #ifdef CONFIG_VIRT_IDX_CACHE
     125#ifdef CONFIG_VIRT_IDX_DCACHE
    126126#define TTE_LOW_DATA(imm)       (TTE_CP | TTE_CV | TTE_P | LMA | (imm))
    127 #else /* CONFIG_VIRT_IDX_CACHE */
     127#else /* CONFIG_VIRT_IDX_DCACHE */
    128128#define TTE_LOW_DATA(imm)       (TTE_CP | TTE_P | LMA | (imm))
    129 #endif /* CONFIG_VIRT_IDX_CACHE */
     129#endif /* CONFIG_VIRT_IDX_DCACHE */
    130130
    131131#define SET_TLB_DATA(r1, r2, imm) \
     
    361361.global kernel_8k_tlb_data_template
    362362kernel_8k_tlb_data_template:
    363 #ifdef CONFIG_VIRT_IDX_CACHE
     363#ifdef CONFIG_VIRT_IDX_DCACHE
    364364        .quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | TTE_CV | TTE_P | TTE_W)
    365 #else /* CONFIG_VIRT_IDX_CACHE */
     365#else /* CONFIG_VIRT_IDX_DCACHE */
    366366        .quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | TTE_P | TTE_W)
    367 #endif /* CONFIG_VIRT_IDX_CACHE */
     367#endif /* CONFIG_VIRT_IDX_DCACHE */
  • kernel/arch/sparc64/src/trap/interrupt.c

    r3d76996 r92778f2  
    4545#include <arch.h>
    4646#include <mm/tlb.h>
     47#include <arch/mm/cache.h>
    4748#include <config.h>
    4849#include <synch/spinlock.h>
     
    9192                if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) {
    9293                        tlb_shootdown_ipi_recv();
     94                } else if (data0 == (uintptr_t) dcache_shootdown_ipi_recv) {
     95                        dcache_shootdown_ipi_recv();
    9396                }
    9497#endif
  • kernel/generic/include/mm/as.h

    r3d76996 r92778f2  
    9595        asid_t asid;
    9696       
     97#ifdef CONFIG_VIRT_IDX_DCACHE
     98        bool dcache_flush_on_install;
     99        bool dcache_flush_on_deinstall;
     100#endif /* CONFIG_VIRT_IDX_DCACHE */
     101
    97102        /** Architecture specific content. */
    98103        as_arch_t arch;
     
    161166        /** Data to be used by the backend. */
    162167        mem_backend_data_t backend_data;
     168
     169        /**
     170         * Virtual color of the original address space area that was at the beginning
     171         * of the share chain.
     172         */
     173        int orig_color;
    163174};
    164175
  • kernel/generic/src/mm/as.c

    r3d76996 r92778f2  
    7979#include <arch/interrupt.h>
    8080
     81#ifdef CONFIG_VIRT_IDX_DCACHE
     82#include <arch/mm/cache.h>
     83#endif /* CONFIG_VIRT_IDX_DCACHE */
     84
    8185/**
    8286 * Each architecture decides what functions will be used to carry out
     
    162166        as->cpu_refcount = 0;
    163167        as->page_table = page_table_create(flags);
     168
     169#ifdef CONFIG_VIRT_IDX_DCACHE
     170        as->dcache_flush_on_install = false;
     171        as->dcache_flush_on_deinstall = false;
     172#endif  /* CONFIG_VIRT_IDX_DCACHE */
    164173
    165174        return as;
     
    269278        else
    270279                memsetb((uintptr_t) &a->backend_data, sizeof(a->backend_data), 0);
     280
     281#ifdef CONFIG_VIRT_IDX_DCACHE
     282        /*
     283         * When the area is being created with the AS_AREA_ATTR_PARTIAL flag, the
     284         * orig_color is probably wrong until the flag is reset. In other words, it is
     285         * initialized with the color of the area being created and not with the color
     286         * of the original address space area at the beginning of the share chain. Of
     287         * course, the correct color is set by as_area_share() before the flag is
     288         * reset.
     289         */
     290        a->orig_color = PAGE_COLOR(base);
     291#endif /* CONFIG_VIRT_IDX_DCACHE */
    271292
    272293        btree_create(&a->used_space);
     
    555576 * or ENOMEM if there was a problem in allocating destination address space
    556577 * area. ENOTSUP is returned if the address space area backend does not support
    557  * sharing. It can be also returned if the architecture uses virtually indexed
    558  * caches and the source and destination areas start at pages with different
    559  * page colors.
     578 * sharing.
    560579 */
    561580int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
     
    565584        int src_flags;
    566585        size_t src_size;
     586        int src_orig_color;
    567587        as_area_t *src_area, *dst_area;
    568588        share_info_t *sh_info;
     
    582602        }
    583603       
    584 #if 0   /* disable the check for now */
    585 #ifdef CONFIG_VIRT_IDX_CACHE
    586         if (PAGE_COLOR(src_area->base) != PAGE_COLOR(dst_base)) {
    587                 /*
    588                  * Refuse to create illegal address alias.
     604
     605        if (!src_area->backend || !src_area->backend->share) {
     606                /*
     607                 * There is no backend or the backend does not
     608                 * know how to share the area.
    589609                 */
    590610                mutex_unlock(&src_area->lock);
     
    593613                return ENOTSUP;
    594614        }
    595 #endif /* CONFIG_VIRT_IDX_CACHE */
    596 #endif
    597 
    598         if (!src_area->backend || !src_area->backend->share) {
    599                 /*
    600                  * There is no backend or the backend does not
    601                  * know how to share the area.
    602                  */
    603                 mutex_unlock(&src_area->lock);
    604                 mutex_unlock(&src_as->lock);
    605                 interrupts_restore(ipl);
    606                 return ENOTSUP;
    607         }
    608615       
    609616        src_size = src_area->pages * PAGE_SIZE;
     
    611618        src_backend = src_area->backend;
    612619        src_backend_data = src_area->backend_data;
     620        src_orig_color = src_area->orig_color;
    613621
    614622        /* Share the cacheable flag from the original mapping */
     
    665673                return ENOMEM;
    666674        }
    667        
     675
    668676        /*
    669677         * Now the destination address space area has been
     
    671679         * attribute and set the sh_info.
    672680         */     
     681        mutex_lock(&dst_as->lock);     
    673682        mutex_lock(&dst_area->lock);
    674683        dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
    675684        dst_area->sh_info = sh_info;
     685        dst_area->orig_color = src_orig_color;
     686#ifdef CONFIG_VIRT_IDX_DCACHE
     687        if (src_orig_color != PAGE_COLOR(dst_base)) {
     688                /*
     689                 * We have just detected an attempt to create an invalid address
     690                 * alias. We allow this and set a special flag that tells the
     691                 * architecture specific code to flush the D-cache when the
     692                 * offending address space is installed and deinstalled
     693                 * (cleanup).
     694                 *
     695                 * In order for the flags to take effect immediately, we also
     696                 * perform a global D-cache shootdown.
     697                 */
     698                dcache_shootdown_start();
     699                dst_as->dcache_flush_on_install = true;
     700                dst_as->dcache_flush_on_deinstall = true;
     701                dcache_flush();
     702                dcache_shootdown_finalize();
     703        }
     704#endif /* CONFIG_VIRT_IDX_DCACHE */
    676705        mutex_unlock(&dst_area->lock);
    677        
     706        mutex_unlock(&dst_as->lock);   
     707
    678708        interrupts_restore(ipl);
    679709       
  • kernel/kernel.config

    r3d76996 r92778f2  
    9898! [ARCH=sparc64] CONFIG_NS16550 (y/n)
    9999
    100 # Virtually indexed cache support
    101 ! [ARCH=sparc64] CONFIG_VIRT_IDX_CACHE (n/y)
     100# Virtually indexed D-cache support
     101! [ARCH=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n)
    102102
    103103
Note: See TracChangeset for help on using the changeset viewer.