OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [ufs/] [util.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  linux/fs/ufs/util.h
3
 *
4
 * Copyright (C) 1998
5
 * Daniel Pirkl <daniel.pirkl@email.cz>
6
 * Charles University, Faculty of Mathematics and Physics
7
 */
8
 
9
#include <linux/fs.h>
10
#include "swab.h"
11
 
12
 
13
/*
14
 * some useful macros
15
 */
16
#define in_range(b,first,len)   ((b)>=(first)&&(b)<(first)+(len))
17
 
18
/*
19
 * macros used for retyping
20
 */
21
#define UCPI_UBH ((struct ufs_buffer_head *)ucpi)
22
#define USPI_UBH ((struct ufs_buffer_head *)uspi)
23
 
24
 
25
 
26
/*
27
 * macros used for accesing structures
28
 */
29
static inline s32
30
ufs_get_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1,
31
                 struct ufs_super_block_third *usb3)
32
{
33
        switch (sb->u.ufs_sb.s_flags & UFS_ST_MASK) {
34
        case UFS_ST_SUN:
35
                return fs32_to_cpu(sb, usb3->fs_u2.fs_sun.fs_state);
36
        case UFS_ST_SUNx86:
37
                return fs32_to_cpu(sb, usb1->fs_u1.fs_sunx86.fs_state);
38
        case UFS_ST_44BSD:
39
        default:
40
                return fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_state);
41
        }
42
}
43
 
44
static inline void
45
ufs_set_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1,
46
                 struct ufs_super_block_third *usb3, s32 value)
47
{
48
        switch (sb->u.ufs_sb.s_flags & UFS_ST_MASK) {
49
        case UFS_ST_SUN:
50
                usb3->fs_u2.fs_sun.fs_state = cpu_to_fs32(sb, value);
51
                break;
52
        case UFS_ST_SUNx86:
53
                usb1->fs_u1.fs_sunx86.fs_state = cpu_to_fs32(sb, value);
54
                break;
55
        case UFS_ST_44BSD:
56
                usb3->fs_u2.fs_44.fs_state = cpu_to_fs32(sb, value);
57
                break;
58
        }
59
}
60
 
61
static inline u32
62
ufs_get_fs_npsect(struct super_block *sb, struct ufs_super_block_first *usb1,
63
                  struct ufs_super_block_third *usb3)
64
{
65
        if ((sb->u.ufs_sb.s_flags & UFS_ST_MASK) == UFS_ST_SUNx86)
66
                return fs32_to_cpu(sb, usb3->fs_u2.fs_sunx86.fs_npsect);
67
        else
68
                return fs32_to_cpu(sb, usb1->fs_u1.fs_sun.fs_npsect);
69
}
70
 
71
static inline u64
72
ufs_get_fs_qbmask(struct super_block *sb, struct ufs_super_block_third *usb3)
73
{
74
        u64 tmp;
75
 
76
        switch (sb->u.ufs_sb.s_flags & UFS_ST_MASK) {
77
        case UFS_ST_SUN:
78
                ((u32 *)&tmp)[0] = usb3->fs_u2.fs_sun.fs_qbmask[0];
79
                ((u32 *)&tmp)[1] = usb3->fs_u2.fs_sun.fs_qbmask[1];
80
                break;
81
        case UFS_ST_SUNx86:
82
                ((u32 *)&tmp)[0] = usb3->fs_u2.fs_sunx86.fs_qbmask[0];
83
                ((u32 *)&tmp)[1] = usb3->fs_u2.fs_sunx86.fs_qbmask[1];
84
                break;
85
        case UFS_ST_44BSD:
86
                ((u32 *)&tmp)[0] = usb3->fs_u2.fs_44.fs_qbmask[0];
87
                ((u32 *)&tmp)[1] = usb3->fs_u2.fs_44.fs_qbmask[1];
88
                break;
89
        }
90
 
91
        return fs64_to_cpu(sb, tmp);
92
}
93
 
94
static inline u64
95
ufs_get_fs_qfmask(struct super_block *sb, struct ufs_super_block_third *usb3)
96
{
97
        u64 tmp;
98
 
99
        switch (sb->u.ufs_sb.s_flags & UFS_ST_MASK) {
100
        case UFS_ST_SUN:
101
                ((u32 *)&tmp)[0] = usb3->fs_u2.fs_sun.fs_qfmask[0];
102
                ((u32 *)&tmp)[1] = usb3->fs_u2.fs_sun.fs_qfmask[1];
103
                break;
104
        case UFS_ST_SUNx86:
105
                ((u32 *)&tmp)[0] = usb3->fs_u2.fs_sunx86.fs_qfmask[0];
106
                ((u32 *)&tmp)[1] = usb3->fs_u2.fs_sunx86.fs_qfmask[1];
107
                break;
108
        case UFS_ST_44BSD:
109
                ((u32 *)&tmp)[0] = usb3->fs_u2.fs_44.fs_qfmask[0];
110
                ((u32 *)&tmp)[1] = usb3->fs_u2.fs_44.fs_qfmask[1];
111
                break;
112
        }
113
 
114
        return fs64_to_cpu(sb, tmp);
115
}
116
 
117
static inline u16
118
ufs_get_de_namlen(struct super_block *sb, struct ufs_dir_entry *de)
119
{
120
        if ((sb->u.ufs_sb.s_flags & UFS_DE_MASK) == UFS_DE_OLD)
121
                return fs16_to_cpu(sb, de->d_u.d_namlen);
122
        else
123
                return de->d_u.d_44.d_namlen; /* XXX this seems wrong */
124
}
125
 
126
static inline void
127
ufs_set_de_namlen(struct super_block *sb, struct ufs_dir_entry *de, u16 value)
128
{
129
        if ((sb->u.ufs_sb.s_flags & UFS_DE_MASK) == UFS_DE_OLD)
130
                de->d_u.d_namlen = cpu_to_fs16(sb, value);
131
        else
132
                de->d_u.d_44.d_namlen = value; /* XXX this seems wrong */
133
}
134
 
135
static inline void
136
ufs_set_de_type(struct super_block *sb, struct ufs_dir_entry *de, int mode)
137
{
138
        if ((sb->u.ufs_sb.s_flags & UFS_DE_MASK) != UFS_DE_44BSD)
139
                return;
140
 
141
        /*
142
         * TODO turn this into a table lookup
143
         */
144
        switch (mode & S_IFMT) {
145
        case S_IFSOCK:
146
                de->d_u.d_44.d_type = DT_SOCK;
147
                break;
148
        case S_IFLNK:
149
                de->d_u.d_44.d_type = DT_LNK;
150
                break;
151
        case S_IFREG:
152
                de->d_u.d_44.d_type = DT_REG;
153
                break;
154
        case S_IFBLK:
155
                de->d_u.d_44.d_type = DT_BLK;
156
                break;
157
        case S_IFDIR:
158
                de->d_u.d_44.d_type = DT_DIR;
159
                break;
160
        case S_IFCHR:
161
                de->d_u.d_44.d_type = DT_CHR;
162
                break;
163
        case S_IFIFO:
164
                de->d_u.d_44.d_type = DT_FIFO;
165
                break;
166
        default:
167
                de->d_u.d_44.d_type = DT_UNKNOWN;
168
        }
169
}
170
 
171
static inline u32
172
ufs_get_inode_uid(struct super_block *sb, struct ufs_inode *inode)
173
{
174
        switch (sb->u.ufs_sb.s_flags & UFS_UID_MASK) {
175
        case UFS_UID_EFT:
176
                return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_uid);
177
        case UFS_UID_44BSD:
178
                return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_uid);
179
        default:
180
                return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_suid);
181
        }
182
}
183
 
184
static inline void
185
ufs_set_inode_uid(struct super_block *sb, struct ufs_inode *inode, u32 value)
186
{
187
        switch (sb->u.ufs_sb.s_flags & UFS_UID_MASK) {
188
        case UFS_UID_EFT:
189
                inode->ui_u3.ui_sun.ui_uid = cpu_to_fs32(sb, value);
190
                break;
191
        case UFS_UID_44BSD:
192
                inode->ui_u3.ui_44.ui_uid = cpu_to_fs32(sb, value);
193
                break;
194
        }
195
        inode->ui_u1.oldids.ui_suid = cpu_to_fs16(sb, value);
196
}
197
 
198
static inline u32
199
ufs_get_inode_gid(struct super_block *sb, struct ufs_inode *inode)
200
{
201
        switch (sb->u.ufs_sb.s_flags & UFS_UID_MASK) {
202
        case UFS_UID_EFT:
203
                return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid);
204
        case UFS_UID_44BSD:
205
                return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_gid);
206
        default:
207
                return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_sgid);
208
        }
209
}
210
 
211
static inline void
212
ufs_set_inode_gid(struct super_block *sb, struct ufs_inode *inode, u32 value)
213
{
214
        switch (sb->u.ufs_sb.s_flags & UFS_UID_MASK) {
215
        case UFS_UID_EFT:
216
                inode->ui_u3.ui_sun.ui_gid = cpu_to_fs32(sb, value);
217
                break;
218
        case UFS_UID_44BSD:
219
                inode->ui_u3.ui_44.ui_gid = cpu_to_fs32(sb, value);
220
                break;
221
        }
222
        inode->ui_u1.oldids.ui_sgid =  cpu_to_fs16(sb, value);
223
}
224
 
225
 
226
/*
227
 * These functions manipulate ufs buffers
228
 */
229
#define ubh_bread(sb,fragment,size) _ubh_bread_(uspi,sb,fragment,size)  
230
extern struct ufs_buffer_head * _ubh_bread_(struct ufs_sb_private_info *, struct super_block *, unsigned, unsigned);
231
extern struct ufs_buffer_head * ubh_bread_uspi(struct ufs_sb_private_info *, struct super_block *, unsigned, unsigned);
232
extern void ubh_brelse (struct ufs_buffer_head *);
233
extern void ubh_brelse_uspi (struct ufs_sb_private_info *);
234
extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *);
235
extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int);
236
extern void ubh_ll_rw_block (int, unsigned, struct ufs_buffer_head **);
237
extern void ubh_wait_on_buffer (struct ufs_buffer_head *);
238
extern unsigned ubh_max_bcount (struct ufs_buffer_head *);
239
extern void ubh_bforget (struct ufs_buffer_head *);
240
extern int  ubh_buffer_dirty (struct ufs_buffer_head *);
241
#define ubh_ubhcpymem(mem,ubh,size) _ubh_ubhcpymem_(uspi,mem,ubh,size)
242
extern void _ubh_ubhcpymem_(struct ufs_sb_private_info *, unsigned char *, struct ufs_buffer_head *, unsigned);
243
#define ubh_memcpyubh(ubh,mem,size) _ubh_memcpyubh_(uspi,ubh,mem,size)
244
extern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head *, unsigned char *, unsigned);
245
 
246
 
247
 
248
/*
249
 * macros to get important structures from ufs_buffer_head
250
 */
251
#define ubh_get_usb_first(ubh) \
252
        ((struct ufs_super_block_first *)((ubh)->bh[0]->b_data))
253
 
254
#define ubh_get_usb_second(ubh) \
255
        ((struct ufs_super_block_second *)(ubh)-> \
256
        bh[UFS_SECTOR_SIZE >> uspi->s_fshift]->b_data + (UFS_SECTOR_SIZE & ~uspi->s_fmask))
257
 
258
#define ubh_get_usb_third(ubh) \
259
        ((struct ufs_super_block_third *)((ubh)-> \
260
        bh[UFS_SECTOR_SIZE*2 >> uspi->s_fshift]->b_data + (UFS_SECTOR_SIZE*2 & ~uspi->s_fmask)))
261
 
262
#define ubh_get_ucg(ubh) \
263
        ((struct ufs_cylinder_group *)((ubh)->bh[0]->b_data))
264
 
265
 
266
/*
267
 * Extract byte from ufs_buffer_head
268
 * Extract the bits for a block from a map inside ufs_buffer_head
269
 */
270
#define ubh_get_addr8(ubh,begin) \
271
        ((u8*)(ubh)->bh[(begin) >> uspi->s_fshift]->b_data + \
272
        ((begin) & ~uspi->s_fmask))
273
 
274
#define ubh_get_addr16(ubh,begin) \
275
        (((u16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + \
276
        ((begin) & (uspi->fsize>>1) - 1)))
277
 
278
#define ubh_get_addr32(ubh,begin) \
279
        (((u32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \
280
        ((begin) & ((uspi->s_fsize>>2) - 1)))
281
 
282
#define ubh_get_addr ubh_get_addr8
283
 
284
#define ubh_blkmap(ubh,begin,bit) \
285
        ((*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) >> ((bit) & 7)) & (0xff >> (UFS_MAXFRAG - uspi->s_fpb)))
286
 
287
 
288
/*
289
 * Macros for access to superblock array structures
290
 */
291
#define ubh_postbl(ubh,cylno,i) \
292
        ((uspi->s_postblformat != UFS_DYNAMICPOSTBLFMT) \
293
        ? (*(__s16*)(ubh_get_addr(ubh, \
294
        (unsigned)(&((struct ufs_super_block *)0)->fs_opostbl) \
295
        + (((cylno) * 16 + (i)) << 1) ) )) \
296
        : (*(__s16*)(ubh_get_addr(ubh, \
297
        uspi->s_postbloff + (((cylno) * uspi->s_nrpos + (i)) << 1) ))))
298
 
299
#define ubh_rotbl(ubh,i) \
300
        ((uspi->s_postblformat != UFS_DYNAMICPOSTBLFMT) \
301
        ? (*(__u8*)(ubh_get_addr(ubh, \
302
        (unsigned)(&((struct ufs_super_block *)0)->fs_space) + (i)))) \
303
        : (*(__u8*)(ubh_get_addr(ubh, uspi->s_rotbloff + (i)))))
304
 
305
/*
306
 * Determine the number of available frags given a
307
 * percentage to hold in reserve.
308
 */
309
#define ufs_freespace(usb, percentreserved) \
310
        (ufs_blkstofrags(fs32_to_cpu(sb, (usb)->fs_cstotal.cs_nbfree)) + \
311
        fs32_to_cpu(sb, (usb)->fs_cstotal.cs_nffree) - (uspi->s_dsize * (percentreserved) / 100))
312
 
313
/*
314
 * Macros to access cylinder group array structures
315
 */
316
#define ubh_cg_blktot(ucpi,cylno) \
317
        (*((__u32*)ubh_get_addr(UCPI_UBH, (ucpi)->c_btotoff + ((cylno) << 2))))
318
 
319
#define ubh_cg_blks(ucpi,cylno,rpos) \
320
        (*((__u16*)ubh_get_addr(UCPI_UBH, \
321
        (ucpi)->c_boff + (((cylno) * uspi->s_nrpos + (rpos)) << 1 ))))
322
 
323
/*
324
 * Bitmap operations
325
 * These functions work like classical bitmap operations.
326
 * The difference is that we don't have the whole bitmap
327
 * in one contiguous chunk of memory, but in several buffers.
328
 * The parameters of each function are super_block, ufs_buffer_head and
329
 * position of the beginning of the bitmap.
330
 */
331
#define ubh_setbit(ubh,begin,bit) \
332
        (*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) |= (1 << ((bit) & 7)))
333
 
334
#define ubh_clrbit(ubh,begin,bit) \
335
        (*ubh_get_addr (ubh, (begin) + ((bit) >> 3)) &= ~(1 << ((bit) & 7)))
336
 
337
#define ubh_isset(ubh,begin,bit) \
338
        (*ubh_get_addr (ubh, (begin) + ((bit) >> 3)) & (1 << ((bit) & 7)))
339
 
340
#define ubh_isclr(ubh,begin,bit) (!ubh_isset(ubh,begin,bit))
341
 
342
#define ubh_find_first_zero_bit(ubh,begin,size) _ubh_find_next_zero_bit_(uspi,ubh,begin,size,0)
343
 
344
#define ubh_find_next_zero_bit(ubh,begin,size,offset) _ubh_find_next_zero_bit_(uspi,ubh,begin,size,offset)
345
static inline unsigned _ubh_find_next_zero_bit_(
346
        struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh,
347
        unsigned begin, unsigned size, unsigned offset)
348
{
349
        unsigned base, count, pos;
350
 
351
        size -= offset;
352
        begin <<= 3;
353
        offset += begin;
354
        base = offset >> uspi->s_bpfshift;
355
        offset &= uspi->s_bpfmask;
356
        for (;;) {
357
                count = min_t(unsigned int, size + offset, uspi->s_bpf);
358
                size -= count - offset;
359
                pos = ext2_find_next_zero_bit (ubh->bh[base]->b_data, count, offset);
360
                if (pos < count || !size)
361
                        break;
362
                base++;
363
                offset = 0;
364
        }
365
        return (base << uspi->s_bpfshift) + pos - begin;
366
}
367
 
368
static inline unsigned find_last_zero_bit (unsigned char * bitmap,
369
        unsigned size, unsigned offset)
370
{
371
        unsigned bit, i;
372
        unsigned char * mapp;
373
        unsigned char map;
374
 
375
        mapp = bitmap + (size >> 3);
376
        map = *mapp--;
377
        bit = 1 << (size & 7);
378
        for (i = size; i > offset; i--) {
379
                if ((map & bit) == 0)
380
                        break;
381
                if ((i & 7) != 0) {
382
                        bit >>= 1;
383
                } else {
384
                        map = *mapp--;
385
                        bit = 1 << 7;
386
                }
387
        }
388
        return i;
389
}
390
 
391
#define ubh_find_last_zero_bit(ubh,begin,size,offset) _ubh_find_last_zero_bit_(uspi,ubh,begin,size,offset)
392
static inline unsigned _ubh_find_last_zero_bit_(
393
        struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh,
394
        unsigned begin, unsigned start, unsigned end)
395
{
396
        unsigned base, count, pos, size;
397
 
398
        size = start - end;
399
        begin <<= 3;
400
        start += begin;
401
        base = start >> uspi->s_bpfshift;
402
        start &= uspi->s_bpfmask;
403
        for (;;) {
404
                count = min_t(unsigned int,
405
                            size + (uspi->s_bpf - start), uspi->s_bpf)
406
                        - (uspi->s_bpf - start);
407
                size -= count;
408
                pos = find_last_zero_bit (ubh->bh[base]->b_data,
409
                        start, start - count);
410
                if (pos > start - count || !size)
411
                        break;
412
                base--;
413
                start = uspi->s_bpf;
414
        }
415
        return (base << uspi->s_bpfshift) + pos - begin;
416
}
417
 
418
#define ubh_isblockclear(ubh,begin,block) (!_ubh_isblockset_(uspi,ubh,begin,block))
419
 
420
#define ubh_isblockset(ubh,begin,block) _ubh_isblockset_(uspi,ubh,begin,block)
421
static inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi,
422
        struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
423
{
424
        switch (uspi->s_fpb) {
425
        case 8:
426
                return (*ubh_get_addr (ubh, begin + block) == 0xff);
427
        case 4:
428
                return (*ubh_get_addr (ubh, begin + (block >> 1)) == (0x0f << ((block & 0x01) << 2)));
429
        case 2:
430
                return (*ubh_get_addr (ubh, begin + (block >> 2)) == (0x03 << ((block & 0x03) << 1)));
431
        case 1:
432
                return (*ubh_get_addr (ubh, begin + (block >> 3)) == (0x01 << (block & 0x07)));
433
        }
434
        return 0;
435
}
436
 
437
#define ubh_clrblock(ubh,begin,block) _ubh_clrblock_(uspi,ubh,begin,block)
438
static inline void _ubh_clrblock_(struct ufs_sb_private_info * uspi,
439
        struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
440
{
441
        switch (uspi->s_fpb) {
442
        case 8:
443
                *ubh_get_addr (ubh, begin + block) = 0x00;
444
                return;
445
        case 4:
446
                *ubh_get_addr (ubh, begin + (block >> 1)) &= ~(0x0f << ((block & 0x01) << 2));
447
                return;
448
        case 2:
449
                *ubh_get_addr (ubh, begin + (block >> 2)) &= ~(0x03 << ((block & 0x03) << 1));
450
                return;
451
        case 1:
452
                *ubh_get_addr (ubh, begin + (block >> 3)) &= ~(0x01 << ((block & 0x07)));
453
                return;
454
        }
455
}
456
 
457
#define ubh_setblock(ubh,begin,block) _ubh_setblock_(uspi,ubh,begin,block)
458
static inline void _ubh_setblock_(struct ufs_sb_private_info * uspi,
459
        struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
460
{
461
        switch (uspi->s_fpb) {
462
        case 8:
463
                *ubh_get_addr(ubh, begin + block) = 0xff;
464
                return;
465
        case 4:
466
                *ubh_get_addr(ubh, begin + (block >> 1)) |= (0x0f << ((block & 0x01) << 2));
467
                return;
468
        case 2:
469
                *ubh_get_addr(ubh, begin + (block >> 2)) |= (0x03 << ((block & 0x03) << 1));
470
                return;
471
        case 1:
472
                *ubh_get_addr(ubh, begin + (block >> 3)) |= (0x01 << ((block & 0x07)));
473
                return;
474
        }
475
}
476
 
477
static inline void ufs_fragacct (struct super_block * sb, unsigned blockmap,
478
        unsigned * fraglist, int cnt)
479
{
480
        struct ufs_sb_private_info * uspi;
481
        unsigned fragsize, pos;
482
 
483
        uspi = sb->u.ufs_sb.s_uspi;
484
 
485
        fragsize = 0;
486
        for (pos = 0; pos < uspi->s_fpb; pos++) {
487
                if (blockmap & (1 << pos)) {
488
                        fragsize++;
489
                }
490
                else if (fragsize > 0) {
491
                        fs32_add(sb, &fraglist[fragsize], cnt);
492
                        fragsize = 0;
493
                }
494
        }
495
        if (fragsize > 0 && fragsize < uspi->s_fpb)
496
                fs32_add(sb, &fraglist[fragsize], cnt);
497
}
498
 
499
#define ubh_scanc(ubh,begin,size,table,mask) _ubh_scanc_(uspi,ubh,begin,size,table,mask)
500
static inline unsigned _ubh_scanc_(struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh,
501
        unsigned begin, unsigned size, unsigned char * table, unsigned char mask)
502
{
503
        unsigned rest, offset;
504
        unsigned char * cp;
505
 
506
 
507
        offset = begin & ~uspi->s_fmask;
508
        begin >>= uspi->s_fshift;
509
        for (;;) {
510
                if ((offset + size) < uspi->s_fsize)
511
                        rest = size;
512
                else
513
                        rest = uspi->s_fsize - offset;
514
                size -= rest;
515
                cp = ubh->bh[begin]->b_data + offset;
516
                while ((table[*cp++] & mask) == 0 && --rest);
517
                if (rest || !size)
518
                        break;
519
                begin++;
520
                offset = 0;
521
        }
522
        return (size + rest);
523
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.