Changeset 4512d7e in mainline
- Timestamp:
- 2006-01-19T22:17:47Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6461d67c
- Parents:
- 64c44e8
- Files:
-
- 1 added
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
arch/amd64/include/mm/asid.h
-
Property mode
changed from
100644
to120000
r64c44e8 r4512d7e 1 /* 2 * Copyright (C) 2005 Jakub Jermar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * - The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef __amd64_ASID_H__ 30 #define __amd64_ASID_H__ 31 32 typedef int asid_t; 33 34 #define asid_get() 0 35 36 #endif 1 ../../../ia32/include/mm/asid.h -
Property mode
changed from
-
arch/ia32/include/mm/asid.h
r64c44e8 r4512d7e 27 27 */ 28 28 29 /* 30 * ia32 has no hardware support for address space identifiers. 31 * This file is provided to do nop-implementation of mm/asid.h 32 * interface. 33 */ 34 29 35 #ifndef __ia32_ASID_H__ 30 36 #define __ia32_ASID_H__ … … 32 38 typedef int asid_t; 33 39 34 #define asid_get() 0 40 #define ASID_MAX_ARCH 0 41 42 #define asid_install(as) 35 43 36 44 #endif -
arch/ia32/src/mm/tlb.c
r64c44e8 r4512d7e 32 32 #include <arch/types.h> 33 33 34 /** Invalidate all TLB entries35 *36 * Invalidate all TLB entries.37 *38 * @param asid This argument is ignored.39 */40 void tlb_invalidate(asid_t asid)41 {42 write_cr3(read_cr3());43 }44 45 34 /** Invalidate all entries in TLB. */ 46 35 void tlb_invalidate_all(void) … … 58 47 } 59 48 60 /** Invalidate TLB entry for specified page belongsto specified address space.49 /** Invalidate TLB entry for specified page range belonging to specified address space. 61 50 * 62 51 * @param asid This parameter is ignored as the architecture doesn't support it. 63 * @param page Address of the page whose entry is to be invalidated. 52 * @param page Address of the first page whose entry is to be invalidated. 53 * @param cnt Number of entries to invalidate. 64 54 */ 65 void tlb_invalidate_page (asid_t asid, __address page)55 void tlb_invalidate_pages(asid_t asid, __address page, count_t cnt) 66 56 { 67 invlpg(page); 57 int i; 58 59 for (i = 0; i < cnt; i++) 60 invlpg(page + i * PAGE_SIZE); 68 61 } -
arch/ia64/Makefile.inc
r64c44e8 r4512d7e 48 48 CONFIG_PAGE_HT = y 49 49 50 ## Compile with support for address space identifiers. 51 # 52 53 CONFIG_ASID = y 54 55 50 56 ARCH_SOURCES = \ 51 57 arch/$(ARCH)/src/start.S \ -
arch/ia64/include/mm/asid.h
r64c44e8 r4512d7e 30 30 #define __ia64_ASID_H__ 31 31 32 typedef int asid_t; 32 #include <arch/types.h> 33 33 34 #define asid_get() 0 34 typedef __u32 asid_t; 35 36 /* 37 * ASID_MAX can range from 2^18 - 1 to 2^24 - , 38 * depending on architecture implementation. 39 */ 40 #define ASID_MAX_ARCH 16777215 /* 2^24 - 1 */ 35 41 36 42 #endif -
arch/mips32/Makefile.inc
r64c44e8 r4512d7e 51 51 52 52 CONFIG_PAGE_PT = y 53 54 ## Compile with support for address space identifiers. 55 # 56 57 CONFIG_ASID = y 53 58 54 59 -
arch/mips32/include/mm/asid.h
r64c44e8 r4512d7e 31 31 32 32 #include <arch/types.h> 33 #include <typedefs.h>34 33 35 #define ASIDS 256 36 #define ASID_INVALID 0 37 #define ASID_START 1 34 #define ASID_MAX_ARCH 255 38 35 39 36 typedef __u8 asid_t; 40 37 41 extern asid_t asid_get(void);42 extern void asid_put(asid_t asid);43 extern bool asid_has_conflicts(asid_t asid);44 45 38 #endif -
arch/mips32/src/mm/as.c
r64c44e8 r4512d7e 36 36 /** Install address space. 37 37 * 38 * Install ASID and if necessary, purge TLB.38 * Install ASID. 39 39 * 40 40 * @param as Address space structure. … … 44 44 entry_hi_t hi; 45 45 ipl_t ipl; 46 47 /*48 * If necessary, purge TLB.49 */50 tlb_invalidate_asid(as->asid); /* TODO: do it only if necessary */51 46 52 47 /* -
arch/mips32/src/mm/asid.c
r64c44e8 r4512d7e 29 29 30 30 #include <arch/mm/asid.h> 31 #include <synch/spinlock.h>32 #include <arch.h>33 #include <debug.h>34 31 #include <typedefs.h> 35 32 36 SPINLOCK_INITIALIZE(asid_usage_lock);37 static count_t asid_usage[ASIDS]; /**< Usage tracking array for ASIDs */38 39 /** Get ASID40 *41 * Get the least used ASID.42 *43 * @return ASID44 */45 asid_t asid_get(void)46 {47 ipl_t ipl;48 int i, j;49 count_t min;50 51 min = (unsigned) -1;52 53 ipl = interrupts_disable();54 spinlock_lock(&asid_usage_lock);55 56 for (i = ASID_START, j = ASID_START; i < ASIDS; i++) {57 if (asid_usage[i] < min) {58 j = i;59 min = asid_usage[i];60 if (!min)61 break;62 }63 }64 65 asid_usage[j]++;66 67 spinlock_unlock(&asid_usage_lock);68 interrupts_restore(ipl);69 70 return i;71 }72 73 /** Release ASID74 *75 * Release ASID by decrementing its usage count.76 *77 * @param asid ASID.78 */79 void asid_put(asid_t asid)80 {81 ipl_t ipl;82 83 ipl = interrupts_disable();84 spinlock_lock(&asid_usage_lock);85 86 ASSERT(asid != ASID_INVALID);87 88 ASSERT(asid_usage[asid] > 0);89 asid_usage[asid]--;90 91 spinlock_unlock(&asid_usage_lock);92 interrupts_restore(ipl);93 }94 95 /** Find out whether ASID is used by more address spaces96 *97 * Find out whether ASID is used by more address spaces.98 *99 * @param asid ASID in question.100 *101 * @return True if 'asid' is used by more address spaces, false otherwise.102 */103 bool asid_has_conflicts(asid_t asid)104 {105 bool has_conflicts = false;106 ipl_t ipl;107 108 ASSERT(asid != ASID_INVALID);109 110 ipl = interrupts_disable();111 spinlock_lock(&asid_usage_lock);112 113 if (asid_usage[asid] > 1)114 has_conflicts = true;115 116 spinlock_unlock(&asid_usage_lock);117 interrupts_restore(ipl);118 119 return has_conflicts;120 } -
arch/mips32/src/mm/tlb.c
r64c44e8 r4512d7e 28 28 29 29 #include <arch/mm/tlb.h> 30 #include < arch/mm/asid.h>30 #include <mm/asid.h> 31 31 #include <mm/tlb.h> 32 32 #include <mm/page.h> … … 495 495 } 496 496 497 /** Invalidate TLB entr y for specified page belonging to specified address space.497 /** Invalidate TLB entries for specified page range belonging to specified address space. 498 498 * 499 499 * @param asid Address space identifier. 500 * @param page Page whose TLB entry is to be invalidated. 501 */ 502 void tlb_invalidate_page(asid_t asid, __address page) 503 { 500 * @param page First page whose TLB entry is to be invalidated. 501 * @param cnt Number of entries to invalidate. 502 */ 503 void tlb_invalidate_pages(asid_t asid, __address page, count_t cnt) 504 { 505 int i; 504 506 ipl_t ipl; 505 507 entry_lo_t lo0, lo1; … … 512 514 ipl = interrupts_disable(); 513 515 514 hi.value = 0; 515 prepare_entry_hi(&hi, asid, page); 516 cp0_entry_hi_write(hi.value); 517 518 tlbp(); 519 index.value = cp0_index_read(); 520 521 if (!index.p) { 522 /* Entry was found, index register contains valid index. */ 523 tlbr(); 524 525 lo0.value = cp0_entry_lo0_read(); 526 lo1.value = cp0_entry_lo1_read(); 527 528 lo0.v = 0; 529 lo1.v = 0; 530 531 cp0_entry_lo0_write(lo0.value); 532 cp0_entry_lo1_write(lo1.value); 533 534 tlbwi(); 516 for (i = 0; i < cnt; i++) { 517 hi.value = 0; 518 prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE); 519 cp0_entry_hi_write(hi.value); 520 521 tlbp(); 522 index.value = cp0_index_read(); 523 524 if (!index.p) { 525 /* Entry was found, index register contains valid index. */ 526 tlbr(); 527 528 lo0.value = cp0_entry_lo0_read(); 529 lo1.value = cp0_entry_lo1_read(); 530 531 lo0.v = 0; 532 lo1.v = 0; 533 534 cp0_entry_lo0_write(lo0.value); 535 cp0_entry_lo1_write(lo1.value); 536 537 tlbwi(); 538 } 535 539 } 536 540 -
arch/ppc32/include/mm/asid.h
r64c44e8 r4512d7e 32 32 typedef int asid_t; 33 33 34 #define asid_get() 0 34 #define ASID_MAX_ARCH 0 35 36 #define asid_install(as) 35 37 36 38 #endif -
arch/sparc64/Makefile.inc
r64c44e8 r4512d7e 52 52 CONFIG_PAGE_HT = y 53 53 54 ## Compile with support for address space identifiers. 55 # 56 57 CONFIG_ASID = y 58 59 54 60 ARCH_SOURCES = \ 55 61 arch/$(ARCH)/src/cpu/cpu.c \ -
arch/sparc64/include/mm/asid.h
r64c44e8 r4512d7e 37 37 typedef __u16 asid_t; 38 38 39 #define asid_get() 039 #define ASID_MAX_ARCH 0x4095 /* 2^12 - 1 */ 40 40 41 41 #endif -
arch/sparc64/src/mm/tlb.c
r64c44e8 r4512d7e 166 166 } 167 167 168 /** Invalidate all ITLB and D LTB entries for specified page in specified address space.168 /** Invalidate all ITLB and DTLB entries for specified page range in specified address space. 169 169 * 170 170 * @param asid Address Space ID. 171 * @param page Page which to sweep out from ITLB and DTLB. 171 * @param page First page which to sweep out from ITLB and DTLB. 172 * @param cnt Number of ITLB and DTLB entries to invalidate. 172 173 */ 173 void tlb_invalidate_page (asid_t asid, __address page)174 void tlb_invalidate_pages(asid_t asid, __address page, count_t cnt) 174 175 { 175 /* TODO: write asid to some Context register and encode the register in second parameter below. */ 176 itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, page); 177 dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, page); 176 int i; 177 178 for (i = 0; i < cnt; i++) { 179 /* TODO: write asid to some Context register and encode the register in second parameter below. */ 180 itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, page + i * PAGE_SIZE); 181 dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, page + i * PAGE_SIZE); 182 } 178 183 } -
genarch/Makefile.inc
r64c44e8 r4512d7e 46 46 genarch/src/mm/page_ht.c 47 47 endif 48 ifeq ($(CONFIG_ASID),y) 49 GENARCH_SOURCES += \ 50 genarch/src/mm/asid.c 51 endif -
generic/include/mm/as.h
r64c44e8 r4512d7e 49 49 #define UDATA_ADDRESS UDATA_ADDRESS_ARCH 50 50 51 #define AS_KERNEL (1<<0) /**< Kernel address space. */ 52 51 53 enum as_area_type { 52 54 AS_AREA_TEXT = 1, AS_AREA_DATA, AS_AREA_STACK … … 62 64 link_t link; 63 65 as_area_type_t type; 64 size_t size; /**< Size of this area . */66 size_t size; /**< Size of this area in multiples of PAGE_SIZE. */ 65 67 __address base; /**< Base address of this area. */ 66 68 index_t *mapping; /**< Map of physical frame numbers mapped to virtual page numbers in this area. */ … … 75 77 */ 76 78 struct as { 79 /** Protected by asidlock. Must be acquired before as-> lock. */ 80 link_t as_with_asid_link; 81 77 82 SPINLOCK_DECLARE(lock); 78 83 link_t as_area_head; … … 81 86 }; 82 87 83 extern as_t * as_create(pte_t *ptl0 );88 extern as_t * as_create(pte_t *ptl0, int flags); 84 89 extern as_area_t *as_area_create(as_t *as, as_area_type_t type, size_t size, __address base); 85 90 extern void as_area_set_mapping(as_area_t *a, index_t vpn, index_t pfn); … … 87 92 extern void as_install(as_t *m); 88 93 89 /* 90 * Each architecture should implement this function. 91 * Its main purpose is to do TLB purges according 92 * to architecture's requirements. Note that 93 * some architectures invalidate their TLB automatically 94 * on hardware address space switch (e.g. ia32 and 95 * amd64). 96 */ 94 /* Interface to be implemented by architectures. */ 97 95 #ifndef as_install_arch 98 96 extern void as_install_arch(as_t *as); -
generic/include/mm/asid.h
r64c44e8 r4512d7e 27 27 */ 28 28 29 /* 30 * This is generic interface for managing 31 * Address Space IDentifiers (ASIDs). 32 */ 33 29 34 #ifndef __ASID_H__ 30 35 #define __ASID_H__ 31 36 37 #include <arch/mm/asid.h> 38 #include <typedefs.h> 39 32 40 #define ASID_KERNEL 0 41 #define ASID_INVALID 1 42 #define ASID_START 2 43 #define ASID_MAX ASID_MAX_ARCH 44 45 #define ASIDS_ALLOCABLE ((ASID_MAX+1)-ASID_START) 46 47 extern spinlock_t asidlock; 48 extern link_t as_with_asid_head; 49 50 extern asid_t asid_get(void); 51 extern void asid_put(asid_t asid); 52 53 #ifndef asid_install 54 extern void asid_install(as_t *as); 55 #endif /* !def asid_install */ 56 57 #define asid_find_free() ASID_START 58 #define asid_put_arch(x) 33 59 34 60 #endif -
generic/include/mm/tlb.h
r64c44e8 r4512d7e 32 32 #include <arch/mm/asid.h> 33 33 #include <arch/types.h> 34 35 extern void tlb_init(void); 36 37 #ifdef CONFIG_SMP 38 extern void tlb_shootdown_start(void); 39 extern void tlb_shootdown_finalize(void); 40 extern void tlb_shootdown_ipi_recv(void); 41 #else 42 # define tlb_shootdown_start() ; 43 # define tlb_shootdown_finalize() ; 44 # define tlb_shootdown_ipi_recv() ; 45 #endif /* CONFIG_SMP */ 34 #include <typedefs.h> 46 35 47 36 /** Type of TLB shootdown message. */ … … 50 39 TLB_INVL_ALL, /**< Invalidate all entries in TLB. */ 51 40 TLB_INVL_ASID, /**< Invalidate all entries belonging to one address space. */ 52 TLB_INVL_PAGE /**< Invalidate one entry for specified page. */41 TLB_INVL_PAGES /**< Invalidate specified page range belonging to one address space. */ 53 42 }; 54 43 … … 64 53 typedef struct tlb_shootdown_msg tlb_shootdown_msg_t; 65 54 55 extern void tlb_init(void); 56 57 #ifdef CONFIG_SMP 58 extern void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, __address page, count_t cnt); 59 extern void tlb_shootdown_finalize(void); 60 extern void tlb_shootdown_ipi_recv(void); 61 #else 62 # define tlb_shootdown_start(w, x, y, z) 63 # define tlb_shootdown_finalize() 64 # define tlb_shootdown_ipi_recv() 65 #endif /* CONFIG_SMP */ 66 67 66 68 /* Export TLB interface that each architecture must implement. */ 67 69 extern void tlb_arch_init(void); 68 70 extern void tlb_print(void); 69 extern void tlb_invalidate(asid_t asid);70 71 extern void tlb_shootdown_ipi_send(void); 71 72 72 73 extern void tlb_invalidate_all(void); 73 74 extern void tlb_invalidate_asid(asid_t asid); 74 extern void tlb_invalidate_page(asid_t asid, __address page); 75 75 extern void tlb_invalidate_pages(asid_t asid, __address page, count_t cnt); 76 76 #endif -
generic/src/main/kinit.c
r64c44e8 r4512d7e 147 147 panic("config.init_addr is not frame aligned"); 148 148 149 as = as_create(NULL );149 as = as_create(NULL, 0); 150 150 if (!as) 151 151 panic("as_create\n"); -
generic/src/main/main.c
r64c44e8 r4512d7e 186 186 * Create kernel address space. 187 187 */ 188 as = as_create(GET_PTL0_ADDRESS() );188 as = as_create(GET_PTL0_ADDRESS(), AS_KERNEL); 189 189 if (!as) 190 190 panic("can't create kernel address space\n"); -
generic/src/mm/as.c
r64c44e8 r4512d7e 34 34 35 35 #include <mm/as.h> 36 #include <mm/asid.h> 36 37 #include <mm/page.h> 37 38 #include <mm/frame.h> … … 40 41 #include <arch/mm/page.h> 41 42 #include <genarch/mm/page_pt.h> 43 #include <mm/asid.h> 42 44 #include <arch/mm/asid.h> 43 45 #include <arch/mm/as.h> … … 71 73 * (Virtual Address Translation) mechanisms. 72 74 */ 73 as_t *as_create(pte_t *ptl0 )75 as_t *as_create(pte_t *ptl0, int flags) 74 76 { 75 77 as_t *as; … … 77 79 as = (as_t *) malloc(sizeof(as_t)); 78 80 if (as) { 81 list_initialize(&as->as_with_asid_link); 79 82 spinlock_initialize(&as->lock, "as_lock"); 80 83 list_initialize(&as->as_area_head); 81 84 82 as->asid = asid_get(); 85 if (flags & AS_KERNEL) 86 as->asid = ASID_KERNEL; 87 else 88 as->asid = ASID_INVALID; 83 89 84 90 as->ptl0 = ptl0; … … 290 296 ipl_t ipl; 291 297 298 asid_install(as); 299 292 300 ipl = interrupts_disable(); 293 301 spinlock_lock(&as->lock); … … 299 307 /* 300 308 * Perform architecture-specific steps. 301 * (e.g. invalidate TLB, install ASIDetc.)309 * (e.g. write ASID to hardware register etc.) 302 310 */ 303 311 as_install_arch(as); -
generic/src/mm/tlb.c
r64c44e8 r4512d7e 47 47 #ifdef CONFIG_SMP 48 48 /* must be called with interrupts disabled */ 49 void tlb_shootdown_start( void)49 void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, __address page, count_t cnt) 50 50 { 51 51 int i; … … 53 53 CPU->tlb_active = 0; 54 54 spinlock_lock(&tlblock); 55 56 /* 57 * TODO: assemble shootdown message. 58 */ 55 59 tlb_shootdown_ipi_send(); 56 tlb_invalidate(0); /* TODO: use valid ASID */ 60 61 switch (type) { 62 case TLB_INVL_ALL: 63 tlb_invalidate_all(); 64 break; 65 case TLB_INVL_ASID: 66 tlb_invalidate_asid(asid); 67 break; 68 case TLB_INVL_PAGES: 69 tlb_invalidate_pages(asid, page, cnt); 70 break; 71 default: 72 panic("unknown tlb_invalidate_type_t value: %d\n", type); 73 break; 74 } 57 75 58 76 busy_wait: … … 78 96 spinlock_lock(&tlblock); 79 97 spinlock_unlock(&tlblock); 80 tlb_invalidate (0); /* TODO: use valid ASID */98 tlb_invalidate_all(); /* TODO: use valid ASID */ 81 99 CPU->tlb_active = 1; 82 100 }
Note:
See TracChangeset
for help on using the changeset viewer.