00001
00002
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _L4_L4RM_H
00018 #define _L4_L4RM_H
00019
00020
00021 #include <l4/sys/types.h>
00022 #include <l4/sys/compiler.h>
00023 #include <l4/sys/utcb.h>
00024 #include <l4/env/cdefs.h>
00025 #include <l4/dm_generic/dm_generic.h>
00026
00027
00028
00029
00033 typedef struct l4rm_region_desc
00034 {
00035
00036 l4_addr_t start;
00037 l4_addr_t end;
00038 l4_uint32_t flags;
00039
00040
00041 union
00042 {
00043
00044 struct
00045 {
00046 l4dm_dataspace_t ds;
00047 l4_offs_t offs;
00048 l4_uint32_t rights;
00050 } ds;
00051
00052
00053 struct
00054 {
00055 l4_threadid_t pager;
00056 } pager;
00057 } data;
00058
00059 void * userptr;
00060
00061 struct l4rm_region_desc * next;
00062 struct l4rm_region_desc * prev;
00063 } l4rm_region_desc_t;
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 #define REGION_FREE 0x00000000
00083 #define REGION_DATASPACE 0x10000000
00084 #define REGION_PAGER 0x20000000
00085 #define REGION_EXCEPTION 0x30000000
00086 #define REGION_BLOCKED 0x40000000
00087
00088 #define AREA_MASK 0x000FFFFF
00089 #define TYPE_MASK 0xF0000000
00090
00091 #define REGION_TYPE(r) ((r)->flags & TYPE_MASK)
00092 #define REGION_AREA(r) ((r)->flags & AREA_MASK)
00093
00094 #define IS_FREE_REGION(r) (REGION_TYPE(r)== REGION_FREE)
00095 #define IS_USED_REGION(r) (!IS_FREE_REGION(r))
00096 #define IS_DATASPACE_REGION(r) (REGION_TYPE(r)== REGION_DATASPACE)
00097 #define IS_PAGER_REGION(r) (REGION_TYPE(r)== REGION_PAGER)
00098 #define IS_EXCEPTION_REGION(r) (REGION_TYPE(r)== REGION_EXCEPTION)
00099 #define IS_BLOCKED_REGION(r) (REGION_TYPE(r)== REGION_BLOCKED)
00100
00101 #define SET_REGION_FREE(r) (r)->flags = \
00102 ((r)->flags & AREA_MASK) | REGION_FREE
00103 #define SET_REGION_DATASPACE(r) (r)->flags = \
00104 ((r)->flags & AREA_MASK) | REGION_DATASPACE
00105 #define SET_REGION_PAGER(r) (r)->flags = \
00106 ((r)->flags & AREA_MASK) | REGION_PAGER
00107 #define SET_REGION_EXCEPTION(r) (r)->flags = \
00108 ((r)->flags & AREA_MASK) | REGION_EXCEPTION
00109 #define SET_REGION_BLOCKED(r) (r)->flags = \
00110 ((r)->flags & AREA_MASK) | REGION_BLOCKED
00111 #define SET_AREA(r,a) (r)->flags = \
00112 (a & AREA_MASK) | ((r)->flags & ~AREA_MASK)
00113
00114 #define FLAGS_EQUAL(r1,r2) ((r1)->flags == (r2)->flags)
00115 #define AREA_EQUAL(r1, r2) (((r1)->flags & AREA_MASK) == \
00116 ((r2)->flags & AREA_MASK))
00117
00118 #define REGION_INITIALIZER 0
00119
00120
00121 #define L4RM_TREE_INSERT 0x80000000
00122 #define L4RM_SET_AREA 0x40000000
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 #define L4RM_MAP 0x01000000
00146 #define L4RM_LOG2_ALIGNED 0x02000000
00151 #define L4RM_LOG2_ALLOC 0x04000000
00156 #define L4RM_SUPERPAGE_ALIGNED 0x08000000
00160
00161 #define L4RM_REGION_FREE 1
00164 #define L4RM_REGION_RESERVED 2
00167 #define L4RM_REGION_DATASPACE 3
00171 #define L4RM_REGION_PAGER 4
00174 #define L4RM_REGION_EXCEPTION 5
00178 #define L4RM_REGION_BLOCKED 6
00181 #define L4RM_REGION_UNKNOWN 7
00189 #define L4RM_DEFAULT_REGION_AREA 0
00190
00191
00192 #define L4RM_REPLY_EMPTY 0
00195 #define L4RM_REPLY_EXCEPTION 1
00198 #define L4RM_REPLY_NO_REPLY 2
00201 #define L4RM_REPLY_SUCCESS 3
00205
00206
00207
00208
00213 typedef struct l4rm_vm_range
00214 {
00215 l4_addr_t addr;
00216 l4_size_t size;
00217 } l4rm_vm_range_t;
00218
00237 typedef L4_CV int (*l4rm_pf_callback_fn_t)(l4_addr_t addr, l4_addr_t eip,
00238 l4_threadid_t src);
00239
00258 typedef L4_CV int (*l4rm_unknown_fault_callback_fn_t)(l4_msgtag_t tag,
00259 l4_utcb_t *utcb,
00260 l4_threadid_t src);
00261
00262
00263
00264
00265
00270 extern const l4_addr_t l4rm_heap_start_addr;
00271
00272
00273
00274
00275
00280 #define L4RM_ADDR_FIND ~0UL
00281
00282
00287 #define L4RM_MODIFY_DIRECT 0x20000000
00288
00289
00290
00291
00292
00293 __BEGIN_DECLS;
00294
00295
00296
00297
00298
00299
00316
00317 L4_CV int
00318 l4rm_init(int have_l4env, l4rm_vm_range_t used[], int num_used);
00319
00320
00327
00328 L4_CV l4_threadid_t
00329 l4rm_region_mapper_id(void);
00330
00331
00338
00339 L4_CV void
00340 l4rm_service_loop(void) __attribute__((noreturn));
00341
00342
00343
00344
00345
00346
00379
00380 L4_CV L4_INLINE int
00381 l4rm_attach(const l4dm_dataspace_t * ds, l4_size_t size, l4_offs_t ds_offs,
00382 l4_uint32_t flags, void ** addr);
00383
00384
00408
00409 L4_CV L4_INLINE int
00410 l4rm_attach_to_region(const l4dm_dataspace_t * ds, const void * addr,
00411 l4_size_t size, l4_offs_t ds_offs, l4_uint32_t flags);
00412
00413
00447
00448 L4_CV L4_INLINE int
00449 l4rm_area_attach(const l4dm_dataspace_t * ds, l4_uint32_t area, l4_size_t size,
00450 l4_offs_t ds_offs, l4_uint32_t flags, void ** addr);
00451
00452
00477
00478 L4_CV L4_INLINE int
00479 l4rm_area_attach_to_region(const l4dm_dataspace_t * ds, l4_uint32_t area,
00480 const void * addr, l4_size_t size,
00481 l4_offs_t ds_offs, l4_uint32_t flags);
00482
00483
00497
00498 L4_CV int
00499 l4rm_detach(const void * addr);
00500
00501
00502
00503
00504
00505
00537
00538 L4_CV L4_INLINE int
00539 l4rm_area_setup(l4_size_t size, l4_uint32_t area, int type, l4_uint32_t flags,
00540 l4_threadid_t pager, l4_addr_t * addr);
00541
00542
00574
00575 L4_CV L4_INLINE int
00576 l4rm_area_setup_region(l4_addr_t addr, l4_size_t size, l4_uint32_t area,
00577 int type, l4_uint32_t flags, l4_threadid_t pager);
00578
00579
00593
00594 L4_CV int
00595 l4rm_area_clear_region(l4_addr_t addr);
00596
00597
00598
00599
00600
00601
00629
00630 L4_CV L4_INLINE int
00631 l4rm_area_reserve(l4_size_t size, l4_uint32_t flags,
00632 l4_addr_t * addr, l4_uint32_t * area);
00633
00634
00651
00652 L4_CV L4_INLINE int
00653 l4rm_area_reserve_region(l4_addr_t addr, l4_size_t size,
00654 l4_uint32_t flags, l4_uint32_t * area);
00655
00656
00668
00669 L4_CV int
00670 l4rm_area_release(l4_uint32_t area);
00671
00672
00683
00684 L4_CV int
00685 l4rm_area_release_addr(const void * ptr);
00686
00687
00698
00699 L4_CV int
00700 l4rm_set_userptr(const void * addr, void * ptr);
00701
00702
00711
00712 L4_CV void *
00713 l4rm_get_userptr(const void * addr);
00714
00715
00716
00717
00718
00719
00720
00756
00757 L4_CV int
00758 l4rm_lookup(const void * addr, l4_addr_t * map_addr, l4_size_t * map_size,
00759 l4dm_dataspace_t * ds, l4_offs_t * offset, l4_threadid_t * pager);
00760
00761
00786
00787 L4_CV int
00788 l4rm_lookup_region(const void * addr, l4_addr_t * map_addr,
00789 l4_size_t * map_size, l4dm_dataspace_t * ds,
00790 l4_offs_t * offset, l4_threadid_t * pager);
00791
00792
00793
00794
00795
00796
00803
00804 L4_CV void
00805 l4rm_set_unkown_pagefault_callback(l4rm_pf_callback_fn_t callback);
00806
00807
00814
00815 L4_CV void
00816 l4rm_set_unkown_fault_callback(l4rm_unknown_fault_callback_fn_t callback);
00817
00818
00823
00824 L4_CV void
00825 l4rm_enable_pagefault_exceptions(void);
00826
00827
00832
00833 L4_CV void
00834 l4rm_disable_pagefault_exceptions(void);
00835
00836
00837
00838
00839
00840
00845
00846 L4_CV void
00847 l4rm_show_region_list(void);
00848
00849
00854
00855 l4rm_region_desc_t *l4rm_get_region_list(void);
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00882
00883 L4_CV L4_INLINE int
00884 l4rm_direct_attach_to_region(const l4dm_dataspace_t *ds, const void *addr,
00885 l4_size_t size, l4_offs_t ds_offs,
00886 l4_uint32_t flags);
00887
00888
00907
00908 L4_CV L4_INLINE int
00909 l4rm_direct_area_attach(const l4dm_dataspace_t * ds, l4_uint32_t area,
00910 l4_size_t size, l4_offs_t ds_offs, l4_uint32_t flags,
00911 void ** addr);
00912
00913
00932
00933 L4_CV L4_INLINE int
00934 l4rm_direct_area_attach_to_region(const l4dm_dataspace_t * ds, l4_uint32_t area,
00935 const void * addr, l4_size_t size,
00936 l4_offs_t ds_offs, l4_uint32_t flags);
00937
00938
00970
00971 L4_CV L4_INLINE int
00972 l4rm_direct_area_setup(l4_size_t size, l4_uint32_t area, int type,
00973 l4_uint32_t flags, l4_threadid_t pager,
00974 l4_addr_t * addr);
00975
00976
00994
00995 L4_CV L4_INLINE int
00996 l4rm_direct_area_setup_region(l4_addr_t addr, l4_size_t size, l4_uint32_t area,
00997 int type, l4_uint32_t flags, l4_threadid_t pager);
00998
00999
01013
01014 L4_CV L4_INLINE int
01015 l4rm_direct_area_reserve(l4_size_t size, l4_uint32_t flags, l4_addr_t * addr,
01016 l4_uint32_t * area);
01017
01018
01032
01033 L4_CV L4_INLINE int
01034 l4rm_direct_area_reserve_region(l4_addr_t addr, l4_size_t size,
01035 l4_uint32_t flags, l4_uint32_t * area);
01036
01037
01038
01039
01040
01041
01046
01047 L4_CV int
01048 l4rm_do_attach(const l4dm_dataspace_t * ds, l4_uint32_t area, l4_addr_t * addr,
01049 l4_size_t size, l4_offs_t ds_offs, l4_uint32_t flags);
01050
01051
01056
01057 L4_CV int
01058 l4rm_do_area_setup(l4_addr_t * addr, l4_size_t size, l4_uint32_t area,
01059 int type, l4_uint32_t flags, l4_threadid_t pager);
01060
01061
01066
01067 L4_CV int
01068 l4rm_do_reserve(l4_addr_t * addr, l4_size_t size, l4_uint32_t flags,
01069 l4_uint32_t * area);
01070
01071 __END_DECLS;
01072
01073
01074
01075
01076
01077
01078
01079
01080 L4_CV L4_INLINE int
01081 l4rm_attach(const l4dm_dataspace_t * ds, l4_size_t size, l4_offs_t ds_offs,
01082 l4_uint32_t flags, void ** addr)
01083 {
01084
01085 *addr = (void *)L4RM_ADDR_FIND;
01086 return l4rm_do_attach(ds, L4RM_DEFAULT_REGION_AREA, (l4_addr_t *)addr,
01087 size, ds_offs, flags);
01088 }
01089
01090
01091
01092
01093 L4_CV L4_INLINE int
01094 l4rm_attach_to_region(const l4dm_dataspace_t * ds, const void * addr,
01095 l4_size_t size, l4_offs_t ds_offs, l4_uint32_t flags)
01096 {
01097
01098 l4_addr_t _addr = (l4_addr_t)addr;
01099 return l4rm_do_attach(ds, L4RM_DEFAULT_REGION_AREA, &_addr ,
01100 size, ds_offs, flags);
01101 }
01102
01103
01104
01105
01106 L4_CV L4_INLINE int
01107 l4rm_area_attach(const l4dm_dataspace_t * ds, l4_uint32_t area, l4_size_t size,
01108 l4_offs_t ds_offs, l4_uint32_t flags, void ** addr)
01109 {
01110
01111 *addr = (void *)L4RM_ADDR_FIND;
01112 return l4rm_do_attach(ds, area, (l4_addr_t *)addr, size, ds_offs, flags);
01113 }
01114
01115
01116
01117
01118 L4_CV L4_INLINE int
01119 l4rm_area_attach_to_region(const l4dm_dataspace_t * ds, l4_uint32_t area,
01120 const void * addr, l4_size_t size, l4_offs_t ds_offs,
01121 l4_uint32_t flags)
01122 {
01123
01124 l4_addr_t _addr = (l4_addr_t)addr;
01125 return l4rm_do_attach(ds, area, &_addr ,
01126 size, ds_offs, flags);
01127 }
01128
01129
01130
01131
01132 L4_CV L4_INLINE int
01133 l4rm_direct_attach_to_region(const l4dm_dataspace_t *ds, const void *addr,
01134 l4_size_t size, l4_offs_t ds_offs,
01135 l4_uint32_t flags)
01136 {
01137 l4_addr_t _addr = (l4_addr_t)addr;
01138 return l4rm_do_attach(ds, L4RM_DEFAULT_REGION_AREA, &_addr ,
01139 size, ds_offs, flags | L4RM_MODIFY_DIRECT);
01140 }
01141
01142
01143
01144
01145 L4_CV L4_INLINE int
01146 l4rm_direct_area_attach(const l4dm_dataspace_t * ds, l4_uint32_t area,
01147 l4_size_t size, l4_offs_t ds_offs, l4_uint32_t flags,
01148 void ** addr)
01149 {
01150
01151 *addr = (void *)L4RM_ADDR_FIND;
01152 return l4rm_do_attach(ds, area, (l4_addr_t *)addr, size, ds_offs,
01153 flags | L4RM_MODIFY_DIRECT);
01154 }
01155
01156
01157
01158
01159 L4_CV L4_INLINE int
01160 l4rm_direct_area_attach_to_region(const l4dm_dataspace_t * ds, l4_uint32_t area,
01161 const void * addr, l4_size_t size,
01162 l4_offs_t ds_offs, l4_uint32_t flags)
01163 {
01164
01165 l4_addr_t _addr = (l4_addr_t)addr;
01166 return l4rm_do_attach(ds, area, &_addr , size, ds_offs,
01167 flags | L4RM_MODIFY_DIRECT);
01168 }
01169
01170
01171
01172
01173 L4_CV L4_INLINE int
01174 l4rm_area_setup(l4_size_t size, l4_uint32_t area, int type, l4_uint32_t flags,
01175 l4_threadid_t pager, l4_addr_t * addr)
01176 {
01177
01178 *addr = L4RM_ADDR_FIND;
01179 return l4rm_do_area_setup(addr, size, area, type, flags, pager);
01180 }
01181
01182
01183
01184
01185 L4_CV L4_INLINE int
01186 l4rm_area_setup_region(l4_addr_t addr, l4_size_t size, l4_uint32_t area,
01187 int type, l4_uint32_t flags, l4_threadid_t pager)
01188 {
01189
01190 return l4rm_do_area_setup(&addr, size, area, type, flags, pager);
01191 }
01192
01193
01194
01195
01196 L4_CV L4_INLINE int
01197 l4rm_direct_area_setup(l4_size_t size, l4_uint32_t area, int type,
01198 l4_uint32_t flags, l4_threadid_t pager, l4_addr_t * addr)
01199 {
01200
01201 *addr = L4RM_ADDR_FIND;
01202 return l4rm_do_area_setup(addr, size, area, type, flags | L4RM_MODIFY_DIRECT,
01203 pager);
01204 }
01205
01206
01207
01208
01209 L4_CV L4_INLINE int
01210 l4rm_direct_area_setup_region(l4_addr_t addr, l4_size_t size, l4_uint32_t area,
01211 int type, l4_uint32_t flags, l4_threadid_t pager)
01212 {
01213
01214 return l4rm_do_area_setup(&addr, size, area, type,
01215 flags | L4RM_MODIFY_DIRECT, pager);
01216 }
01217
01218
01219
01220
01221 L4_CV L4_INLINE int
01222 l4rm_area_reserve(l4_size_t size, l4_uint32_t flags, l4_addr_t * addr,
01223 l4_uint32_t * area)
01224 {
01225
01226 *addr = L4RM_ADDR_FIND;
01227 return l4rm_do_reserve(addr, size, flags, area);
01228 }
01229
01230
01231
01232
01233 L4_CV L4_INLINE int
01234 l4rm_area_reserve_region(l4_addr_t addr, l4_size_t size, l4_uint32_t flags,
01235 l4_uint32_t * area)
01236 {
01237
01238 return l4rm_do_reserve(&addr, size, flags, area);
01239 }
01240
01241
01242
01243
01244 L4_CV L4_INLINE int
01245 l4rm_direct_area_reserve(l4_size_t size, l4_uint32_t flags, l4_addr_t * addr,
01246 l4_uint32_t * area)
01247 {
01248
01249 *addr = L4RM_ADDR_FIND;
01250 return l4rm_do_reserve(addr, size, flags | L4RM_MODIFY_DIRECT, area);
01251 }
01252
01253
01254
01255
01256 L4_CV L4_INLINE int
01257 l4rm_direct_area_reserve_region(l4_addr_t addr, l4_size_t size,
01258 l4_uint32_t flags, l4_uint32_t * area)
01259 {
01260
01261 return l4rm_do_reserve(&addr, size,flags | L4RM_MODIFY_DIRECT, area);
01262 }
01263
01264 #endif