Rev 3624 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3624 | Rev 4377 | ||
---|---|---|---|
Line 119... | Line 119... | ||
119 | { |
119 | { |
120 | as_t *as = (as_t *) obj; |
120 | as_t *as = (as_t *) obj; |
121 | int rc; |
121 | int rc; |
122 | 122 | ||
123 | link_initialize(&as->inactive_as_with_asid_link); |
123 | link_initialize(&as->inactive_as_with_asid_link); |
124 | mutex_initialize(&as->lock, MUTEX_PASSIVE); |
124 | mutex_initialize(&as->lock, MUTEX_PASSIVE); |
125 | 125 | ||
126 | rc = as_constructor_arch(as, flags); |
126 | rc = as_constructor_arch(as, flags); |
127 | 127 | ||
128 | return rc; |
128 | return rc; |
129 | } |
129 | } |
Line 143... | Line 143... | ||
143 | as_slab = slab_cache_create("as_slab", sizeof(as_t), 0, |
143 | as_slab = slab_cache_create("as_slab", sizeof(as_t), 0, |
144 | as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED); |
144 | as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED); |
145 | 145 | ||
146 | AS_KERNEL = as_create(FLAG_AS_KERNEL); |
146 | AS_KERNEL = as_create(FLAG_AS_KERNEL); |
147 | if (!AS_KERNEL) |
147 | if (!AS_KERNEL) |
148 | panic("can't create kernel address space\n"); |
148 | panic("Cannot create kernel address space."); |
149 | 149 | ||
- | 150 | /* Make sure the kernel address space |
|
- | 151 | * reference count never drops to zero. |
|
- | 152 | */ |
|
- | 153 | atomic_set(&AS_KERNEL->refcount, 1); |
|
150 | } |
154 | } |
151 | 155 | ||
152 | /** Create address space. |
156 | /** Create address space. |
153 | * |
157 | * |
154 | * @param flags Flags that influence the way in wich the address space |
158 | * @param flags Flags that influence the way in wich the address space |
Line 173... | Line 177... | ||
173 | #ifdef AS_PAGE_TABLE |
177 | #ifdef AS_PAGE_TABLE |
174 | as->genarch.page_table = page_table_create(flags); |
178 | as->genarch.page_table = page_table_create(flags); |
175 | #else |
179 | #else |
176 | page_table_create(flags); |
180 | page_table_create(flags); |
177 | #endif |
181 | #endif |
178 | 182 | ||
179 | return as; |
183 | return as; |
180 | } |
184 | } |
181 | 185 | ||
182 | /** Destroy adress space. |
186 | /** Destroy adress space. |
183 | * |
187 | * |
Line 437... | Line 441... | ||
437 | 441 | ||
438 | cond = false; /* we are almost done */ |
442 | cond = false; /* we are almost done */ |
439 | i = (start_free - b) >> PAGE_WIDTH; |
443 | i = (start_free - b) >> PAGE_WIDTH; |
440 | if (!used_space_remove(area, start_free, |
444 | if (!used_space_remove(area, start_free, |
441 | c - i)) |
445 | c - i)) |
442 | panic("Could not remove used " |
446 | panic("Cannot remove used " |
443 | "space.\n"); |
447 | "space."); |
444 | } else { |
448 | } else { |
445 | /* |
449 | /* |
446 | * The interval of used space can be |
450 | * The interval of used space can be |
447 | * completely removed. |
451 | * completely removed. |
448 | */ |
452 | */ |
449 | if (!used_space_remove(area, b, c)) |
453 | if (!used_space_remove(area, b, c)) |
450 | panic("Could not remove used " |
454 | panic("Cannot remove used " |
451 | "space.\n"); |
455 | "space."); |
452 | } |
456 | } |
453 | 457 | ||
454 | for (; i < c; i++) { |
458 | for (; i < c; i++) { |
455 | pte_t *pte; |
459 | pte_t *pte; |
456 | 460 | ||
Line 766... | Line 770... | ||
766 | * The idea is to have the same data, but with a different access mode. |
770 | * The idea is to have the same data, but with a different access mode. |
767 | * This is needed e.g. for writing code into memory and then executing it. |
771 | * This is needed e.g. for writing code into memory and then executing it. |
768 | * In order for this to work properly, this may copy the data |
772 | * In order for this to work properly, this may copy the data |
769 | * into private anonymous memory (unless it's already there). |
773 | * into private anonymous memory (unless it's already there). |
770 | * |
774 | * |
771 | * @param as Address space. |
775 | * @param as Address space. |
772 | * @param flags Flags of the area memory. |
776 | * @param flags Flags of the area memory. |
773 | * @param address Address withing the area to be changed. |
777 | * @param address Address within the area to be changed. |
- | 778 | * |
|
- | 779 | * @return Zero on success or a value from @ref errno.h on failure. |
|
774 | * |
780 | * |
775 | * @return Zero on success or a value from @ref errno.h on failure. |
- | |
776 | */ |
781 | */ |
777 | int as_area_change_flags(as_t *as, int flags, uintptr_t address) |
782 | int as_area_change_flags(as_t *as, int flags, uintptr_t address) |
778 | { |
783 | { |
779 | as_area_t *area; |
784 | as_area_t *area; |
780 | uintptr_t base; |
785 | uintptr_t base; |
Line 782... | Line 787... | ||
782 | ipl_t ipl; |
787 | ipl_t ipl; |
783 | int page_flags; |
788 | int page_flags; |
784 | uintptr_t *old_frame; |
789 | uintptr_t *old_frame; |
785 | index_t frame_idx; |
790 | index_t frame_idx; |
786 | count_t used_pages; |
791 | count_t used_pages; |
787 | 792 | ||
788 | /* Flags for the new memory mapping */ |
793 | /* Flags for the new memory mapping */ |
789 | page_flags = area_flags_to_page_flags(flags); |
794 | page_flags = area_flags_to_page_flags(flags); |
790 | 795 | ||
791 | ipl = interrupts_disable(); |
796 | ipl = interrupts_disable(); |
792 | mutex_lock(&as->lock); |
797 | mutex_lock(&as->lock); |
Line 796... | Line 801... | ||
796 | mutex_unlock(&as->lock); |
801 | mutex_unlock(&as->lock); |
797 | interrupts_restore(ipl); |
802 | interrupts_restore(ipl); |
798 | return ENOENT; |
803 | return ENOENT; |
799 | } |
804 | } |
800 | 805 | ||
801 | if (area->sh_info || area->backend != &anon_backend) { |
806 | if ((area->sh_info) || (area->backend != &anon_backend)) { |
802 | /* Copying shared areas not supported yet */ |
807 | /* Copying shared areas not supported yet */ |
803 | /* Copying non-anonymous memory not supported yet */ |
808 | /* Copying non-anonymous memory not supported yet */ |
804 | mutex_unlock(&area->lock); |
809 | mutex_unlock(&area->lock); |
805 | mutex_unlock(&as->lock); |
810 | mutex_unlock(&as->lock); |
806 | interrupts_restore(ipl); |
811 | interrupts_restore(ipl); |
Line 867... | Line 872... | ||
867 | /* |
872 | /* |
868 | * Finish TLB shootdown sequence. |
873 | * Finish TLB shootdown sequence. |
869 | */ |
874 | */ |
870 | 875 | ||
871 | tlb_invalidate_pages(as->asid, area->base, area->pages); |
876 | tlb_invalidate_pages(as->asid, area->base, area->pages); |
- | 877 | ||
872 | /* |
878 | /* |
873 | * Invalidate potential software translation caches (e.g. TSB on |
879 | * Invalidate potential software translation caches (e.g. TSB on |
874 | * sparc64). |
880 | * sparc64). |
875 | */ |
881 | */ |
876 | as_invalidate_translation_cache(as, area->base, area->pages); |
882 | as_invalidate_translation_cache(as, area->base, area->pages); |
Line 1657... | Line 1663... | ||
1657 | } |
1663 | } |
1658 | } |
1664 | } |
1659 | } |
1665 | } |
1660 | 1666 | ||
1661 | panic("Inconsistency detected while adding %" PRIc " pages of used " |
1667 | panic("Inconsistency detected while adding %" PRIc " pages of used " |
1662 | "space at %p.\n", count, page); |
1668 | "space at %p.", count, page); |
1663 | } |
1669 | } |
1664 | 1670 | ||
1665 | /** Mark portion of address space area as unused. |
1671 | /** Mark portion of address space area as unused. |
1666 | * |
1672 | * |
1667 | * The address space area must be already locked. |
1673 | * The address space area must be already locked. |
Line 1836... | Line 1842... | ||
1836 | } |
1842 | } |
1837 | } |
1843 | } |
1838 | 1844 | ||
1839 | error: |
1845 | error: |
1840 | panic("Inconsistency detected while removing %" PRIc " pages of used " |
1846 | panic("Inconsistency detected while removing %" PRIc " pages of used " |
1841 | "space from %p.\n", count, page); |
1847 | "space from %p.", count, page); |
1842 | } |
1848 | } |
1843 | 1849 | ||
1844 | /** Remove reference to address space area share info. |
1850 | /** Remove reference to address space area share info. |
1845 | * |
1851 | * |
1846 | * If the reference count drops to 0, the sh_info is deallocated. |
1852 | * If the reference count drops to 0, the sh_info is deallocated. |