Changes in / [e950803:b366a1bc] in mainline
- Files:
-
- 20 added
- 2 deleted
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/arch/mips32/src/Makefile
re950803 rb366a1bc 32 32 .PHONY: all clean 33 33 34 all: ../../../../version ../../../../Makefile.co mmon ../../../../Makefile.config ../../../../config.h34 all: ../../../../version ../../../../Makefile.config ../../../../config.h ../../../../config.defs 35 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 36 $(MAKE) -f Makefile.build PRECHECK=$(PRECHECK) 37 37 38 38 clean: 39 rm -f $(USPACEDIR)/dist/srv/*40 rm -f $(USPACEDIR)/dist/app/*41 rm -f $(USPACEDIR)/dist/cfg/net/*42 43 39 for file in $(RD_SRVS) ; do \ 44 40 rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \ … … 47 43 rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \ 48 44 done 49 for file in $(NET_CFG) ; do \50 rm -f $(USPACEDIR)/dist/cfg/net/`basename $$file` ; \51 done52 45 rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(OUTPUT) $(RAW) $(COMPS).h $(COMPS).c $(LINK) $(INITRD).img $(INITRD).fs 53 46 find . -name '*.o' -follow -exec rm \{\} \; -
boot/arch/mips32/src/Makefile.build
re950803 rb366a1bc 32 32 33 33 include ../../../../version 34 include ../../../../Makefile.common35 34 include ../../../../Makefile.config 35 include ../../../../config.defs 36 36 include Makefile.common 37 37 include Makefile.toolchain … … 77 77 78 78 $(DEPEND): 79 rm -f $(USPACEDIR)/dist/srv/*80 rm -f $(USPACEDIR)/dist/app/*81 rm -f $(USPACEDIR)/dist/cfg/net/*82 83 79 for file in $(RD_SRVS) ; do \ 84 80 cp $$file $(USPACEDIR)/dist/srv/ ; \ … … 86 82 for file in $(RD_APPS) ; do \ 87 83 cp $$file $(USPACEDIR)/dist/app/ ; \ 88 done89 for file in $(NET_CFG) ; do \90 cp $$file $(USPACEDIR)/dist/cfg/net/ ; \91 84 done 92 85 ifeq ($(RDFMT),tmpfs) -
boot/arch/mips32/src/Makefile.toolchain
re950803 rb366a1bc 27 27 # 28 28 29 ## Toolchain configuration 30 # 31 32 ifndef CROSS_PREFIX 33 CROSS_PREFIX = /usr/local 34 endif 35 29 36 BFD_ARCH = mips 37 TARGET = mipsel-linux-gnu 38 TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32/bin 30 39 31 40 JOBFILE = ../../../../tools/jobfile.py … … 39 48 BFD_NAME = elf32-tradbigmips 40 49 BFD = ecoff-bigmips 50 TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32eb/bin 51 TARGET = mips-linux-gnu 41 52 endif 42 53 … … 44 55 BFD_NAME = elf32-tradlittlemips 45 56 BFD = binary 57 endif 58 59 ifeq ($(COMPILER),gcc_native) 60 CC = gcc 61 AS = as 62 LD = ld 63 OBJCOPY = objcopy 64 OBJDUMP = objdump 65 endif 66 67 ifeq ($(COMPILER),gcc_cross) 68 CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc 69 AS = $(TOOLCHAIN_DIR)/$(TARGET)-as 70 LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld 71 OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy 72 OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump 46 73 endif 47 74 -
kernel/arch/ia32/_link.ld.in
re950803 rb366a1bc 49 49 } 50 50 51 #ifdef CONFIG_LINE_DEBUG52 .comment 0 : { *(.comment); }53 .debug_abbrev 0 : { *(.debug_abbrev); }54 .debug_aranges 0 : { *(.debug_aranges); }55 .debug_info 0 : { *(.debug_info); }56 .debug_line 0 : { *(.debug_line); }57 .debug_loc 0 : { *(.debug_loc); }58 .debug_pubnames 0 : { *(.debug_pubnames); }59 .debug_pubtypes 0 : { *(.debug_pubtypes); }60 .debug_ranges 0 : { *(.debug_ranges); }61 .debug_str 0 : { *(.debug_str); }62 #endif63 64 51 /DISCARD/ : { 65 *(*); 52 *(.note.GNU-stack); 53 *(.comment); 66 54 } 67 55 -
kernel/arch/mips32/src/mm/tlb.c
re950803 rb366a1bc 557 557 entry_hi_t hi, hi_save; 558 558 tlb_index_t index; 559 560 if (asid == ASID_INVALID) 561 return; 559 560 ASSERT(asid != ASID_INVALID); 562 561 563 562 hi_save.value = cp0_entry_hi_read(); -
kernel/generic/include/mm/as.h
re950803 rb366a1bc 115 115 116 116 /** 117 * Number of processors on which this 118 * address space is active. Protected by 119 * asidlock. 117 * Number of processors on wich is this address space active. 118 * Protected by asidlock. 120 119 */ 121 120 size_t cpu_refcount; 122 121 123 /** Address space identifier. 124 * 125 * Constant on architectures that do not 126 * support ASIDs. Protected by asidlock. 127 * 122 /** 123 * Address space identifier. 124 * Constant on architectures that do not support ASIDs. 125 * Protected by asidlock. 128 126 */ 129 127 asid_t asid; 130 128 131 /** Number of references (i.e .tasks that reference this as). */129 /** Number of references (i.e tasks that reference this as). */ 132 130 atomic_t refcount; 133 131 … … 201 199 typedef struct { 202 200 mutex_t lock; 203 204 201 /** Containing address space. */ 205 202 as_t *as; 206 203 207 /** Memory flags. */ 204 /** 205 * Flags related to the memory represented by the address space area. 206 */ 208 207 unsigned int flags; 209 208 210 /** A ddress space area attributes. */209 /** Attributes related to the address space area itself. */ 211 210 unsigned int attributes; 212 213 /** Number of pages in the area. */ 211 /** Size of this area in multiples of PAGE_SIZE. */ 214 212 size_t pages; 215 216 /** Number of resident pages in the area. */217 size_t resident;218 219 213 /** Base address of this area. */ 220 214 uintptr_t base; 221 222 215 /** Map of used space. */ 223 216 btree_t used_space; 224 217 225 218 /** 226 * If the address space area is shared. this is227 * a reference tothe share info structure.219 * If the address space area has been shared, this pointer will 220 * reference the share info structure. 228 221 */ 229 222 share_info_t *sh_info; … … 268 261 extern bool as_area_check_access(as_area_t *, pf_access_t); 269 262 extern size_t as_area_get_size(uintptr_t); 270 extern bool used_space_insert(as_area_t *, uintptr_t, size_t); 271 extern bool used_space_remove(as_area_t *, uintptr_t, size_t); 263 extern int used_space_insert(as_area_t *, uintptr_t, size_t); 264 extern int used_space_remove(as_area_t *, uintptr_t, size_t); 265 272 266 273 267 /* Interface to be implemented by architectures. */ -
kernel/generic/src/console/cmd.c
re950803 rb366a1bc 553 553 for (i = 0; basic_commands[i]; i++) { 554 554 cmd_initialize(basic_commands[i]); 555 } 556 557 for (i = 0; basic_commands[i]; i++) { 558 if (!cmd_register(basic_commands[i])) { 559 printf("Cannot register command %s\n", 560 basic_commands[i]->name); 561 } 555 if (!cmd_register(basic_commands[i])) 556 printf("Cannot register command %s\n", basic_commands[i]->name); 562 557 } 563 558 } -
kernel/generic/src/lib/elf.c
re950803 rb366a1bc 157 157 case PT_NULL: 158 158 case PT_PHDR: 159 case PT_NOTE:160 159 break; 161 160 case PT_LOAD: … … 174 173 break; 175 174 case PT_SHLIB: 175 case PT_NOTE: 176 176 case PT_LOPROC: 177 177 case PT_HIPROC: -
kernel/generic/src/mm/as.c
re950803 rb366a1bc 86 86 * Each architecture decides what functions will be used to carry out 87 87 * address space operations such as creating or locking page tables. 88 * 88 89 */ 89 90 as_operations_t *as_operations = NULL; 90 91 91 /** Slab for as_t objects. 92 /** 93 * Slab for as_t objects. 92 94 * 93 95 */ 94 96 static slab_cache_t *as_slab; 95 97 96 /** ASID subsystem lock.97 * 98 * This lockprotects:98 /** 99 * This lock serializes access to the ASID subsystem. 100 * It protects: 99 101 * - inactive_as_with_asid_head list 100 102 * - as->asid for each as of the as_t type … … 105 107 106 108 /** 107 * Inactive address spaces (on all processors) 108 * that have valid ASID. 109 * This list contains address spaces that are not active on any 110 * processor and that have valid ASID. 111 * 109 112 */ 110 113 LIST_INITIALIZE(inactive_as_with_asid_head); … … 120 123 mutex_initialize(&as->lock, MUTEX_PASSIVE); 121 124 122 return as_constructor_arch(as, flags); 125 int rc = as_constructor_arch(as, flags); 126 127 return rc; 123 128 } 124 129 125 130 NO_TRACE static size_t as_destructor(void *obj) 126 131 { 127 return as_destructor_arch((as_t *) obj); 132 as_t *as = (as_t *) obj; 133 return as_destructor_arch(as); 128 134 } 129 135 … … 140 146 panic("Cannot create kernel address space."); 141 147 142 /* 143 * Make sure the kernel address space 148 /* Make sure the kernel address space 144 149 * reference count never drops to zero. 145 150 */ … … 190 195 { 191 196 DEADLOCK_PROBE_INIT(p_asidlock); 192 197 193 198 ASSERT(as != AS); 194 199 ASSERT(atomic_get(&as->refcount) == 0); … … 198 203 * lock its mutex. 199 204 */ 200 205 201 206 /* 202 207 * We need to avoid deadlock between TLB shootdown and asidlock. … … 205 210 * disabled to prevent nested context switches. We also depend on the 206 211 * fact that so far no spinlocks are held. 212 * 207 213 */ 208 214 preemption_disable(); … … 229 235 spinlock_unlock(&asidlock); 230 236 interrupts_restore(ipl); 231 237 232 238 233 239 /* … … 235 241 * The B+tree must be walked carefully because it is 236 242 * also being destroyed. 243 * 237 244 */ 238 245 bool cond = true; … … 261 268 /** Hold a reference to an address space. 262 269 * 263 * Holding a reference to an address space prevents destruction 264 * of that addressspace.270 * Holding a reference to an address space prevents destruction of that address 271 * space. 265 272 * 266 273 * @param as Address space to be held. … … 274 281 /** Release a reference to an address space. 275 282 * 276 * The last one to release a reference to an address space 277 * destroys the addressspace.283 * The last one to release a reference to an address space destroys the address 284 * space. 278 285 * 279 286 * @param asAddress space to be released. … … 303 310 /* 304 311 * We don't want any area to have conflicts with NULL page. 312 * 305 313 */ 306 314 if (overlaps(va, size, (uintptr_t) NULL, PAGE_SIZE)) … … 313 321 * record in the left neighbour, the leftmost record in the right 314 322 * neighbour and all records in the leaf node itself. 323 * 315 324 */ 316 325 btree_node_t *leaf; … … 373 382 * So far, the area does not conflict with other areas. 374 383 * Check if it doesn't conflict with kernel address space. 384 * 375 385 */ 376 386 if (!KERNEL_ADDRESS_SPACE_SHADOWED) { … … 427 437 area->attributes = attrs; 428 438 area->pages = SIZE2FRAMES(size); 429 area->resident = 0;430 439 area->base = base; 431 440 area->sh_info = NULL; … … 470 479 * to find out whether this is a miss or va belongs to an address 471 480 * space area found there. 481 * 472 482 */ 473 483 … … 489 499 * Second, locate the left neighbour and test its last record. 490 500 * Because of its position in the B+tree, it must have base < va. 501 * 491 502 */ 492 503 btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf); … … 523 534 /* 524 535 * Locate the area. 536 * 525 537 */ 526 538 as_area_t *area = find_area_and_lock(as, address); … … 534 546 * Remapping of address space areas associated 535 547 * with memory mapped devices is not supported. 548 * 536 549 */ 537 550 mutex_unlock(&area->lock); … … 544 557 * Remapping of shared address space areas 545 558 * is not supported. 559 * 546 560 */ 547 561 mutex_unlock(&area->lock); … … 554 568 /* 555 569 * Zero size address space areas are not allowed. 570 * 556 571 */ 557 572 mutex_unlock(&area->lock); … … 566 581 * Shrinking the area. 567 582 * No need to check for overlaps. 583 * 568 584 */ 569 585 … … 572 588 /* 573 589 * Start TLB shootdown sequence. 590 * 574 591 */ 575 592 ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, … … 582 599 * is also the right way to remove part of the used_space 583 600 * B+tree leaf list. 601 * 584 602 */ 585 603 bool cond = true; … … 605 623 * completely in the resized 606 624 * address space area. 625 * 607 626 */ 608 627 break; … … 613 632 * to b and c overlaps with the resized 614 633 * address space area. 634 * 615 635 */ 616 636 … … 653 673 /* 654 674 * Finish TLB shootdown sequence. 675 * 655 676 */ 656 677 … … 660 681 /* 661 682 * Invalidate software translation caches (e.g. TSB on sparc64). 683 * 662 684 */ 663 685 as_invalidate_translation_cache(as, area->base + … … 670 692 * Growing the area. 671 693 * Check for overlaps with other address space areas. 694 * 672 695 */ 673 696 if (!check_area_conflicts(as, address, pages * PAGE_SIZE, … … 790 813 /* 791 814 * Finish TLB shootdown sequence. 815 * 792 816 */ 793 817 … … 797 821 * Invalidate potential software translation caches (e.g. TSB on 798 822 * sparc64). 823 * 799 824 */ 800 825 as_invalidate_translation_cache(as, area->base, area->pages); … … 814 839 /* 815 840 * Remove the empty area from address space. 841 * 816 842 */ 817 843 btree_remove(&as->as_area_btree, base, NULL); … … 855 881 /* 856 882 * Could not find the source address space area. 883 * 857 884 */ 858 885 mutex_unlock(&src_as->lock); … … 864 891 * There is no backend or the backend does not 865 892 * know how to share the area. 893 * 866 894 */ 867 895 mutex_unlock(&src_area->lock); … … 890 918 * First, prepare the area for sharing. 891 919 * Then it will be safe to unlock it. 920 * 892 921 */ 893 922 share_info_t *sh_info = src_area->sh_info; … … 901 930 /* 902 931 * Call the backend to setup sharing. 932 * 903 933 */ 904 934 src_area->backend->share(src_area); … … 919 949 * The flags of the source area are masked against dst_flags_mask 920 950 * to support sharing in less privileged mode. 951 * 921 952 */ 922 953 as_area_t *dst_area = as_area_create(dst_as, dst_flags_mask, src_size, … … 935 966 * fully initialized. Clear the AS_AREA_ATTR_PARTIAL 936 967 * attribute and set the sh_info. 968 * 937 969 */ 938 970 mutex_lock(&dst_as->lock); … … 957 989 NO_TRACE bool as_area_check_access(as_area_t *area, pf_access_t access) 958 990 { 959 ASSERT(mutex_locked(&area->lock));960 961 991 int flagmap[] = { 962 992 [PF_ACCESS_READ] = AS_AREA_READ, … … 964 994 [PF_ACCESS_EXEC] = AS_AREA_EXEC 965 995 }; 996 997 ASSERT(mutex_locked(&area->lock)); 966 998 967 999 if (!(area->flags & flagmap[access])) … … 1034 1066 /* 1035 1067 * Compute total number of used pages in the used_space B+tree 1068 * 1036 1069 */ 1037 1070 size_t used_pages = 0; … … 1055 1088 /* 1056 1089 * Start TLB shootdown sequence. 1090 * 1057 1091 */ 1058 1092 ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, … … 1062 1096 * Remove used pages from page tables and remember their frame 1063 1097 * numbers. 1098 * 1064 1099 */ 1065 1100 size_t frame_idx = 0; … … 1092 1127 /* 1093 1128 * Finish TLB shootdown sequence. 1129 * 1094 1130 */ 1095 1131 … … 1099 1135 * Invalidate potential software translation caches (e.g. TSB on 1100 1136 * sparc64). 1137 * 1101 1138 */ 1102 1139 as_invalidate_translation_cache(as, area->base, area->pages); … … 1180 1217 * No area contained mapping for 'page'. 1181 1218 * Signal page fault to low-level handler. 1219 * 1182 1220 */ 1183 1221 mutex_unlock(&AS->lock); … … 1199 1237 * The address space area is not backed by any backend 1200 1238 * or the backend cannot handle page faults. 1239 * 1201 1240 */ 1202 1241 mutex_unlock(&area->lock); … … 1210 1249 * To avoid race condition between two page faults on the same address, 1211 1250 * we need to make sure the mapping has not been already inserted. 1251 * 1212 1252 */ 1213 1253 pte_t *pte; … … 1227 1267 /* 1228 1268 * Resort to the backend page fault handler. 1269 * 1229 1270 */ 1230 1271 if (area->backend->page_fault(area, page, access) != AS_PF_OK) { … … 1281 1322 * preemption is disabled. We should not be 1282 1323 * holding any other lock. 1324 * 1283 1325 */ 1284 1326 (void) interrupts_enable(); … … 1300 1342 * list of inactive address spaces with assigned 1301 1343 * ASID. 1344 * 1302 1345 */ 1303 1346 ASSERT(old_as->asid != ASID_INVALID); … … 1310 1353 * Perform architecture-specific tasks when the address space 1311 1354 * is being removed from the CPU. 1355 * 1312 1356 */ 1313 1357 as_deinstall_arch(old_as); … … 1316 1360 /* 1317 1361 * Second, prepare the new address space. 1362 * 1318 1363 */ 1319 1364 if ((new_as->cpu_refcount++ == 0) && (new_as != AS_KERNEL)) { … … 1331 1376 * Perform architecture-specific steps. 1332 1377 * (e.g. write ASID to hardware register etc.) 1378 * 1333 1379 */ 1334 1380 as_install_arch(new_as); … … 1349 1395 { 1350 1396 ASSERT(mutex_locked(&area->lock)); 1351 1397 1352 1398 return area_flags_to_page_flags(area->flags); 1353 1399 } … … 1470 1516 * @param count Number of page to be marked. 1471 1517 * 1472 * @return False on failure or trueon success.1473 * 1474 */ 1475 boolused_space_insert(as_area_t *area, uintptr_t page, size_t count)1518 * @return Zero on failure and non-zero on success. 1519 * 1520 */ 1521 int used_space_insert(as_area_t *area, uintptr_t page, size_t count) 1476 1522 { 1477 1523 ASSERT(mutex_locked(&area->lock)); … … 1484 1530 /* 1485 1531 * We hit the beginning of some used space. 1486 */ 1487 return false; 1532 * 1533 */ 1534 return 0; 1488 1535 } 1489 1536 1490 1537 if (!leaf->keys) { 1491 1538 btree_insert(&area->used_space, page, (void *) count, leaf); 1492 goto success;1539 return 1; 1493 1540 } 1494 1541 … … 1504 1551 * somewhere between the rightmost interval of 1505 1552 * the left neigbour and the first interval of the leaf. 1553 * 1506 1554 */ 1507 1555 … … 1511 1559 left_cnt * PAGE_SIZE)) { 1512 1560 /* The interval intersects with the left interval. */ 1513 return false;1561 return 0; 1514 1562 } else if (overlaps(page, count * PAGE_SIZE, right_pg, 1515 1563 right_cnt * PAGE_SIZE)) { 1516 1564 /* The interval intersects with the right interval. */ 1517 return false;1565 return 0; 1518 1566 } else if ((page == left_pg + left_cnt * PAGE_SIZE) && 1519 1567 (page + count * PAGE_SIZE == right_pg)) { … … 1521 1569 * The interval can be added by merging the two already 1522 1570 * present intervals. 1571 * 1523 1572 */ 1524 1573 node->value[node->keys - 1] += count + right_cnt; 1525 1574 btree_remove(&area->used_space, right_pg, leaf); 1526 goto success;1575 return 1; 1527 1576 } else if (page == left_pg + left_cnt * PAGE_SIZE) { 1528 1577 /* 1529 1578 * The interval can be added by simply growing the left 1530 1579 * interval. 1580 * 1531 1581 */ 1532 1582 node->value[node->keys - 1] += count; 1533 goto success;1583 return 1; 1534 1584 } else if (page + count * PAGE_SIZE == right_pg) { 1535 1585 /* … … 1537 1587 * the right interval down and increasing its size 1538 1588 * accordingly. 1589 * 1539 1590 */ 1540 1591 leaf->value[0] += count; 1541 1592 leaf->key[0] = page; 1542 goto success;1593 return 1; 1543 1594 } else { 1544 1595 /* 1545 1596 * The interval is between both neigbouring intervals, 1546 1597 * but cannot be merged with any of them. 1598 * 1547 1599 */ 1548 1600 btree_insert(&area->used_space, page, (void *) count, 1549 1601 leaf); 1550 goto success;1602 return 1; 1551 1603 } 1552 1604 } else if (page < leaf->key[0]) { … … 1557 1609 * Investigate the border case in which the left neighbour does 1558 1610 * not exist but the interval fits from the left. 1611 * 1559 1612 */ 1560 1613 … … 1562 1615 right_cnt * PAGE_SIZE)) { 1563 1616 /* The interval intersects with the right interval. */ 1564 return false;1617 return 0; 1565 1618 } else if (page + count * PAGE_SIZE == right_pg) { 1566 1619 /* … … 1568 1621 * right interval down and increasing its size 1569 1622 * accordingly. 1623 * 1570 1624 */ 1571 1625 leaf->key[0] = page; 1572 1626 leaf->value[0] += count; 1573 goto success;1627 return 1; 1574 1628 } else { 1575 1629 /* 1576 1630 * The interval doesn't adjoin with the right interval. 1577 1631 * It must be added individually. 1632 * 1578 1633 */ 1579 1634 btree_insert(&area->used_space, page, (void *) count, 1580 1635 leaf); 1581 goto success;1636 return 1; 1582 1637 } 1583 1638 } … … 1594 1649 * somewhere between the leftmost interval of 1595 1650 * the right neigbour and the last interval of the leaf. 1651 * 1596 1652 */ 1597 1653 … … 1601 1657 left_cnt * PAGE_SIZE)) { 1602 1658 /* The interval intersects with the left interval. */ 1603 return false;1659 return 0; 1604 1660 } else if (overlaps(page, count * PAGE_SIZE, right_pg, 1605 1661 right_cnt * PAGE_SIZE)) { 1606 1662 /* The interval intersects with the right interval. */ 1607 return false;1663 return 0; 1608 1664 } else if ((page == left_pg + left_cnt * PAGE_SIZE) && 1609 1665 (page + count * PAGE_SIZE == right_pg)) { … … 1611 1667 * The interval can be added by merging the two already 1612 1668 * present intervals. 1669 * 1613 1670 */ 1614 1671 leaf->value[leaf->keys - 1] += count + right_cnt; 1615 1672 btree_remove(&area->used_space, right_pg, node); 1616 goto success;1673 return 1; 1617 1674 } else if (page == left_pg + left_cnt * PAGE_SIZE) { 1618 1675 /* 1619 1676 * The interval can be added by simply growing the left 1620 1677 * interval. 1678 * 1621 1679 */ 1622 leaf->value[leaf->keys - 1] += count;1623 goto success;1680 leaf->value[leaf->keys - 1] += count; 1681 return 1; 1624 1682 } else if (page + count * PAGE_SIZE == right_pg) { 1625 1683 /* … … 1627 1685 * the right interval down and increasing its size 1628 1686 * accordingly. 1687 * 1629 1688 */ 1630 1689 node->value[0] += count; 1631 1690 node->key[0] = page; 1632 goto success;1691 return 1; 1633 1692 } else { 1634 1693 /* 1635 1694 * The interval is between both neigbouring intervals, 1636 1695 * but cannot be merged with any of them. 1696 * 1637 1697 */ 1638 1698 btree_insert(&area->used_space, page, (void *) count, 1639 1699 leaf); 1640 goto success;1700 return 1; 1641 1701 } 1642 1702 } else if (page >= leaf->key[leaf->keys - 1]) { … … 1647 1707 * Investigate the border case in which the right neighbour 1648 1708 * does not exist but the interval fits from the right. 1709 * 1649 1710 */ 1650 1711 … … 1652 1713 left_cnt * PAGE_SIZE)) { 1653 1714 /* The interval intersects with the left interval. */ 1654 return false;1715 return 0; 1655 1716 } else if (left_pg + left_cnt * PAGE_SIZE == page) { 1656 1717 /* 1657 1718 * The interval can be added by growing the left 1658 1719 * interval. 1720 * 1659 1721 */ 1660 1722 leaf->value[leaf->keys - 1] += count; 1661 goto success;1723 return 1; 1662 1724 } else { 1663 1725 /* 1664 1726 * The interval doesn't adjoin with the left interval. 1665 1727 * It must be added individually. 1728 * 1666 1729 */ 1667 1730 btree_insert(&area->used_space, page, (void *) count, 1668 1731 leaf); 1669 goto success;1732 return 1; 1670 1733 } 1671 1734 } … … 1675 1738 * only between two other intervals of the leaf. The two border cases 1676 1739 * were already resolved. 1740 * 1677 1741 */ 1678 1742 btree_key_t i; … … 1686 1750 /* 1687 1751 * The interval fits between left_pg and right_pg. 1752 * 1688 1753 */ 1689 1754 … … 1693 1758 * The interval intersects with the left 1694 1759 * interval. 1760 * 1695 1761 */ 1696 return false;1762 return 0; 1697 1763 } else if (overlaps(page, count * PAGE_SIZE, right_pg, 1698 1764 right_cnt * PAGE_SIZE)) { … … 1700 1766 * The interval intersects with the right 1701 1767 * interval. 1768 * 1702 1769 */ 1703 return false;1770 return 0; 1704 1771 } else if ((page == left_pg + left_cnt * PAGE_SIZE) && 1705 1772 (page + count * PAGE_SIZE == right_pg)) { … … 1707 1774 * The interval can be added by merging the two 1708 1775 * already present intervals. 1776 * 1709 1777 */ 1710 1778 leaf->value[i - 1] += count + right_cnt; 1711 1779 btree_remove(&area->used_space, right_pg, leaf); 1712 goto success;1780 return 1; 1713 1781 } else if (page == left_pg + left_cnt * PAGE_SIZE) { 1714 1782 /* 1715 1783 * The interval can be added by simply growing 1716 1784 * the left interval. 1785 * 1717 1786 */ 1718 1787 leaf->value[i - 1] += count; 1719 goto success;1788 return 1; 1720 1789 } else if (page + count * PAGE_SIZE == right_pg) { 1721 1790 /* … … 1723 1792 * base of the right interval down and 1724 1793 * increasing its size accordingly. 1794 * 1725 1795 */ 1726 1796 leaf->value[i] += count; 1727 1797 leaf->key[i] = page; 1728 goto success;1798 return 1; 1729 1799 } else { 1730 1800 /* … … 1732 1802 * intervals, but cannot be merged with any of 1733 1803 * them. 1804 * 1734 1805 */ 1735 1806 btree_insert(&area->used_space, page, 1736 1807 (void *) count, leaf); 1737 goto success;1808 return 1; 1738 1809 } 1739 1810 } … … 1742 1813 panic("Inconsistency detected while adding %zu pages of used " 1743 1814 "space at %p.", count, (void *) page); 1744 1745 success:1746 area->resident += count;1747 return true;1748 1815 } 1749 1816 … … 1756 1823 * @param count Number of page to be marked. 1757 1824 * 1758 * @return False on failure or trueon success.1759 * 1760 */ 1761 boolused_space_remove(as_area_t *area, uintptr_t page, size_t count)1825 * @return Zero on failure and non-zero on success. 1826 * 1827 */ 1828 int used_space_remove(as_area_t *area, uintptr_t page, size_t count) 1762 1829 { 1763 1830 ASSERT(mutex_locked(&area->lock)); … … 1770 1837 /* 1771 1838 * We are lucky, page is the beginning of some interval. 1839 * 1772 1840 */ 1773 1841 if (count > pages) { 1774 return false;1842 return 0; 1775 1843 } else if (count == pages) { 1776 1844 btree_remove(&area->used_space, page, leaf); 1777 goto success;1845 return 1; 1778 1846 } else { 1779 1847 /* 1780 1848 * Find the respective interval. 1781 1849 * Decrease its size and relocate its start address. 1850 * 1782 1851 */ 1783 1852 btree_key_t i; … … 1786 1855 leaf->key[i] += count * PAGE_SIZE; 1787 1856 leaf->value[i] -= count; 1788 goto success;1857 return 1; 1789 1858 } 1790 1859 } 1791 1792 1860 goto error; 1793 1861 } … … 1808 1876 * removed by updating the size of the bigger 1809 1877 * interval. 1878 * 1810 1879 */ 1811 1880 node->value[node->keys - 1] -= count; 1812 goto success;1881 return 1; 1813 1882 } else if (page + count * PAGE_SIZE < 1814 1883 left_pg + left_cnt*PAGE_SIZE) { … … 1819 1888 * the original interval and also inserting a 1820 1889 * new interval. 1890 * 1821 1891 */ 1822 1892 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) - … … 1825 1895 btree_insert(&area->used_space, page + 1826 1896 count * PAGE_SIZE, (void *) new_cnt, leaf); 1827 goto success;1897 return 1; 1828 1898 } 1829 1899 } 1830 1831 return false; 1900 return 0; 1832 1901 } else if (page < leaf->key[0]) 1833 return false;1902 return 0; 1834 1903 1835 1904 if (page > leaf->key[leaf->keys - 1]) { … … 1845 1914 * interval of the leaf and can be removed by 1846 1915 * updating the size of the bigger interval. 1916 * 1847 1917 */ 1848 1918 leaf->value[leaf->keys - 1] -= count; 1849 goto success;1919 return 1; 1850 1920 } else if (page + count * PAGE_SIZE < left_pg + 1851 1921 left_cnt * PAGE_SIZE) { … … 1856 1926 * original interval and also inserting a new 1857 1927 * interval. 1928 * 1858 1929 */ 1859 1930 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) - … … 1862 1933 btree_insert(&area->used_space, page + 1863 1934 count * PAGE_SIZE, (void *) new_cnt, leaf); 1864 goto success;1935 return 1; 1865 1936 } 1866 1937 } 1867 1868 return false; 1938 return 0; 1869 1939 } 1870 1940 1871 1941 /* 1872 1942 * The border cases have been already resolved. 1873 * Now the interval can be only between intervals of the leaf. 1943 * Now the interval can be only between intervals of the leaf. 1874 1944 */ 1875 1945 btree_key_t i; … … 1892 1962 * be removed by updating the size of 1893 1963 * the bigger interval. 1964 * 1894 1965 */ 1895 1966 leaf->value[i - 1] -= count; 1896 goto success;1967 return 1; 1897 1968 } else if (page + count * PAGE_SIZE < 1898 1969 left_pg + left_cnt * PAGE_SIZE) { … … 1912 1983 count * PAGE_SIZE, (void *) new_cnt, 1913 1984 leaf); 1914 goto success;1985 return 1; 1915 1986 } 1916 1987 } 1917 1918 return false; 1988 return 0; 1919 1989 } 1920 1990 } … … 1923 1993 panic("Inconsistency detected while removing %zu pages of used " 1924 1994 "space from %p.", count, (void *) page); 1925 1926 success:1927 area->resident -= count;1928 return true;1929 1995 } 1930 1996 -
kernel/generic/src/sysinfo/stats.c
re950803 rb366a1bc 160 160 static size_t get_task_virtmem(as_t *as) 161 161 { 162 size_t result = 0; 163 162 164 /* 163 * We are holding spinlocks here and therefore are not allowed to 164 * block. Only attempt to lock the address space and address space 165 * area mutexes conditionally. If it is not possible to lock either 166 * object, return inexact statistics by skipping the respective object. 165 * We are holding some spinlocks here and therefore are not allowed to 166 * block. Only attempt to lock the address space and address space area 167 * mutexes conditionally. If it is not possible to lock either object, 168 * allow the statistics to be inexact by skipping the respective object. 169 * 170 * Note that it may be infinitely better to let the address space 171 * management code compute these statistics as it proceeds instead of 172 * having them calculated over and over again here. 167 173 */ 168 174 169 175 if (SYNCH_FAILED(mutex_trylock(&as->lock))) 170 return 0; 171 172 size_t pages = 0; 176 return result * PAGE_SIZE; 173 177 174 178 /* Walk the B+ tree and count pages */ 179 link_t *cur; 180 for (cur = as->as_area_btree.leaf_head.next; 181 cur != &as->as_area_btree.leaf_head; cur = cur->next) { 182 btree_node_t *node = 183 list_get_instance(cur, btree_node_t, leaf_link); 184 185 unsigned int i; 186 for (i = 0; i < node->keys; i++) { 187 as_area_t *area = node->value[i]; 188 189 if (SYNCH_FAILED(mutex_trylock(&area->lock))) 190 continue; 191 result += area->pages; 192 mutex_unlock(&area->lock); 193 } 194 } 195 196 mutex_unlock(&as->lock); 197 198 return result * PAGE_SIZE; 199 } 200 201 /** Get the resident (used) size of a virtual address space 202 * 203 * @param as Address space. 204 * 205 * @return Size of the resident (used) virtual address space (bytes). 206 * 207 */ 208 static size_t get_task_resmem(as_t *as) 209 { 210 size_t result = 0; 211 212 /* 213 * We are holding some spinlocks here and therefore are not allowed to 214 * block. Only attempt to lock the address space and address space area 215 * mutexes conditionally. If it is not possible to lock either object, 216 * allow the statistics to be inexact by skipping the respective object. 217 * 218 * Note that it may be infinitely better to let the address space 219 * management code compute these statistics as it proceeds instead of 220 * having them calculated over and over again here. 221 */ 222 223 if (SYNCH_FAILED(mutex_trylock(&as->lock))) 224 return result * PAGE_SIZE; 225 226 /* Walk the B+ tree of AS areas */ 175 227 link_t *cur; 176 228 for (cur = as->as_area_btree.leaf_head.next; … … 186 238 continue; 187 239 188 pages += area->pages; 240 /* Walk the B+ tree of resident pages */ 241 link_t *rcur; 242 for (rcur = area->used_space.leaf_head.next; 243 rcur != &area->used_space.leaf_head; rcur = rcur->next) { 244 btree_node_t *rnode = 245 list_get_instance(rcur, btree_node_t, leaf_link); 246 247 unsigned int j; 248 for (j = 0; j < rnode->keys; j++) 249 result += (size_t) rnode->value[i]; 250 } 251 189 252 mutex_unlock(&area->lock); 190 253 } … … 193 256 mutex_unlock(&as->lock); 194 257 195 return (pages << PAGE_WIDTH); 196 } 197 198 /** Get the resident (used) size of a virtual address space 199 * 200 * @param as Address space. 201 * 202 * @return Size of the resident (used) virtual address space (bytes). 203 * 204 */ 205 static size_t get_task_resmem(as_t *as) 206 { 207 /* 208 * We are holding spinlocks here and therefore are not allowed to 209 * block. Only attempt to lock the address space and address space 210 * area mutexes conditionally. If it is not possible to lock either 211 * object, return inexact statistics by skipping the respective object. 212 */ 213 214 if (SYNCH_FAILED(mutex_trylock(&as->lock))) 215 return 0; 216 217 size_t pages = 0; 218 219 /* Walk the B+ tree and count pages */ 220 link_t *cur; 221 for (cur = as->as_area_btree.leaf_head.next; 222 cur != &as->as_area_btree.leaf_head; cur = cur->next) { 223 btree_node_t *node = 224 list_get_instance(cur, btree_node_t, leaf_link); 225 226 unsigned int i; 227 for (i = 0; i < node->keys; i++) { 228 as_area_t *area = node->value[i]; 229 230 if (SYNCH_FAILED(mutex_trylock(&area->lock))) 231 continue; 232 233 pages += area->resident; 234 mutex_unlock(&area->lock); 235 } 236 } 237 238 mutex_unlock(&as->lock); 239 240 return (pages << PAGE_WIDTH); 258 return result * PAGE_SIZE; 241 259 } 242 260 -
uspace/Makefile.common
re950803 rb366a1bc 135 135 endif 136 136 137 ifeq ($(CONFIG_LINE_DEBUG),y)138 GCC_CFLAGS += -g139 ICC_CFLAGS += -g140 SUNCC_CFLAGS += -g141 CLANG_CFLAGS += -g142 endif143 144 137 ## Setup platform configuration 145 138 # -
uspace/drv/test2/test2.c
re950803 rb366a1bc 103 103 if (dev->parent == NULL) { 104 104 fid_t postpone = fibril_create(postponed_birth, dev); 105 if (postpone == 0) {106 printf(NAME ": fibril_create() error\n");107 return ENOMEM;108 }109 105 fibril_add_ready(postpone); 110 106 } else { -
uspace/lib/c/arch/amd64/_link.ld.in
re950803 rb366a1bc 5 5 text PT_LOAD FLAGS(5); 6 6 data PT_LOAD FLAGS(6); 7 debug PT_NOTE;8 7 } 9 8 … … 14 13 *(.init); 15 14 } :text 16 17 15 .text : { 18 16 *(.text); 19 17 *(.rodata*); 20 18 } :text 21 19 22 20 . = . + 0x1000; 23 21 24 22 .data : { 25 23 *(.data); 26 24 } :data 27 28 25 .tdata : { 29 26 _tdata_start = .; … … 34 31 _tbss_end = .; 35 32 } :data 36 37 33 _tls_alignment = ALIGNOF(.tdata); 38 39 34 .bss : { 40 35 *(COMMON); 41 36 *(.bss); 42 37 } :data 43 38 44 39 . = ALIGN(0x1000); 45 40 _heap = .; 46 47 #ifdef CONFIG_LINE_DEBUG48 .comment 0 : { *(.comment); } :debug49 .debug_abbrev 0 : { *(.debug_abbrev); } :debug50 .debug_aranges 0 : { *(.debug_aranges); } :debug51 .debug_info 0 : { *(.debug_info); } :debug52 .debug_line 0 : { *(.debug_line); } :debug53 .debug_loc 0 : { *(.debug_loc); } :debug54 .debug_pubnames 0 : { *(.debug_pubnames); } :debug55 .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug56 .debug_ranges 0 : { *(.debug_ranges); } :debug57 .debug_str 0 : { *(.debug_str); } :debug58 #endif59 41 60 42 /DISCARD/ : { -
uspace/lib/c/arch/ia32/_link.ld.in
re950803 rb366a1bc 5 5 text PT_LOAD FLAGS(5); 6 6 data PT_LOAD FLAGS(6); 7 debug PT_NOTE;8 7 } 9 8 … … 44 43 45 44 . = ALIGN(0x1000); 45 46 46 _heap = .; 47 48 #ifdef CONFIG_LINE_DEBUG49 .comment 0 : { *(.comment); } :debug50 .debug_abbrev 0 : { *(.debug_abbrev); } :debug51 .debug_aranges 0 : { *(.debug_aranges); } :debug52 .debug_info 0 : { *(.debug_info); } :debug53 .debug_line 0 : { *(.debug_line); } :debug54 .debug_loc 0 : { *(.debug_loc); } :debug55 .debug_pubnames 0 : { *(.debug_pubnames); } :debug56 .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug57 .debug_ranges 0 : { *(.debug_ranges); } :debug58 .debug_str 0 : { *(.debug_str); } :debug59 #endif60 47 61 48 /DISCARD/ : { -
uspace/lib/c/generic/async.c
re950803 rb366a1bc 430 430 431 431 fid_t fid = fibril_create(notification_fibril, msg); 432 if (fid == 0) {433 free(msg);434 futex_up(&async_futex);435 return false;436 }437 438 432 fibril_add_ready(fid); 439 433 … … 687 681 conn->wdata.fid = fibril_create(connection_fibril, conn); 688 682 689 if ( conn->wdata.fid == 0) {683 if (!conn->wdata.fid) { 690 684 free(conn); 691 692 685 if (callid) 693 686 ipc_answer_0(callid, ENOMEM); 694 695 687 return (uintptr_t) NULL; 696 688 } … … 861 853 { 862 854 fid_t fid = fibril_create(async_manager_fibril, NULL); 863 if (fid != 0) 864 fibril_add_manager(fid); 855 fibril_add_manager(fid); 865 856 } 866 857 -
uspace/srv/bd/ata_bd/ata_bd.c
re950803 rb366a1bc 55 55 #include <as.h> 56 56 #include <fibril_synch.h> 57 #include <stdint.h>58 57 #include <str.h> 59 58 #include <devmap.h> … … 62 61 #include <errno.h> 63 62 #include <bool.h> 64 #include <byteorder.h>65 63 #include <task.h> 66 64 #include <macros.h> … … 75 73 #define LEGACY_CTLS 4 76 74 77 /** 78 * Size of data returned from Identify Device or Identify Packet Device 79 * command. 80 */ 81 static const size_t identify_data_size = 512; 75 /** Physical block size. Should be always 512. */ 76 static const size_t block_size = 512; 82 77 83 78 /** Size of the communication area. */ … … 110 105 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt, 111 106 const void *buf); 112 static int ata_ rcmd_read(int disk_id, uint64_t ba, size_t cnt,107 static int ata_bd_read_block(int disk_id, uint64_t ba, size_t cnt, 113 108 void *buf); 114 static int ata_ rcmd_write(int disk_id, uint64_t ba, size_t cnt,109 static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt, 115 110 const void *buf); 116 111 static int disk_init(disk_t *d, int disk_id); 117 112 static int drive_identify(int drive_id, void *buf); 118 static int identify_pkt_dev(int dev_idx, void *buf);119 static int ata_cmd_packet(int dev_idx, const void *cpkt, size_t cpkt_size,120 void *obuf, size_t obuf_size);121 static int ata_pcmd_inquiry(int dev_idx, void *obuf, size_t obuf_size);122 static int ata_pcmd_read_12(int dev_idx, uint64_t ba, size_t cnt,123 void *obuf, size_t obuf_size);124 113 static void disk_print_summary(disk_t *d); 125 114 static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc); … … 214 203 printf("%s: ", d->model); 215 204 216 if (d->dev_type == ata_reg_dev) { 217 switch (d->amode) { 218 case am_chs: 219 printf("CHS %u cylinders, %u heads, %u sectors", 220 disk->geom.cylinders, disk->geom.heads, 221 disk->geom.sectors); 222 break; 223 case am_lba28: 224 printf("LBA-28"); 225 break; 226 case am_lba48: 227 printf("LBA-48"); 228 break; 229 } 230 } else { 231 printf("PACKET"); 205 switch (d->amode) { 206 case am_chs: 207 printf("CHS %u cylinders, %u heads, %u sectors", 208 disk->geom.cylinders, disk->geom.heads, disk->geom.sectors); 209 break; 210 case am_lba28: 211 printf("LBA-28"); 212 break; 213 case am_lba48: 214 printf("LBA-48"); 215 break; 232 216 } 233 217 … … 329 313 IPC_GET_ARG2(call)); 330 314 cnt = IPC_GET_ARG3(call); 331 if (cnt * disk[disk_id].block_size > comm_size) {315 if (cnt * block_size > comm_size) { 332 316 retval = ELIMIT; 333 317 break; … … 339 323 IPC_GET_ARG2(call)); 340 324 cnt = IPC_GET_ARG3(call); 341 if (cnt * disk[disk_id].block_size > comm_size) {325 if (cnt * block_size > comm_size) { 342 326 retval = ELIMIT; 343 327 break; … … 346 330 break; 347 331 case BD_GET_BLOCK_SIZE: 348 async_answer_1(callid, EOK, disk[disk_id].block_size);332 async_answer_1(callid, EOK, block_size); 349 333 continue; 350 334 case BD_GET_NUM_BLOCKS: … … 369 353 identify_data_t idata; 370 354 uint8_t model[40]; 371 ata_inquiry_data_t inq_data;372 355 uint16_t w; 373 356 uint8_t c; … … 376 359 unsigned i; 377 360 378 d->present = false;379 fibril_mutex_initialize(&d->lock);380 381 /* Try identify command. */382 361 rc = drive_identify(disk_id, &idata); 383 if (rc == EOK) { 384 /* Success. It's a register (non-packet) device. */ 385 printf("ATA register-only device found.\n"); 386 d->dev_type = ata_reg_dev; 387 } else if (rc == EIO) { 388 /* 389 * There is something, but not a register device. 390 * It could be a packet device. 391 */ 392 rc = identify_pkt_dev(disk_id, &idata); 393 if (rc == EOK) { 394 /* We have a packet device. */ 395 d->dev_type = ata_pkt_dev; 396 } else { 397 /* Nope. Something's there, but not recognized. */ 398 return EIO; 399 } 400 } else { 401 /* Operation timed out. That means there is no device there. */ 402 return EIO; 403 } 404 405 printf("device caps: 0x%04x\n", idata.caps); 406 if (d->dev_type == ata_pkt_dev) { 407 /* Packet device */ 408 d->amode = 0; 409 410 d->geom.cylinders = 0; 411 d->geom.heads = 0; 412 d->geom.sectors = 0; 413 414 d->blocks = 0; 415 } else if ((idata.caps & rd_cap_lba) == 0) { 362 if (rc != EOK) { 363 d->present = false; 364 return rc; 365 } 366 367 if ((idata.caps & cap_lba) == 0) { 416 368 /* Device only supports CHS addressing. */ 417 369 d->amode = am_chs; … … 470 422 d->model[pos] = '\0'; 471 423 472 if (d->dev_type == ata_pkt_dev) {473 /* Send inquiry. */474 rc = ata_pcmd_inquiry(0, &inq_data, sizeof(inq_data));475 if (rc != EOK) {476 printf("Device inquiry failed.\n");477 d->present = false;478 return EIO;479 }480 481 /* Check device type. */482 if (INQUIRY_PDEV_TYPE(inq_data.pdev_type) != PDEV_TYPE_CDROM)483 printf("Warning: Peripheral device type is not CD-ROM.\n");484 485 /* Assume 2k block size for now. */486 d->block_size = 2048;487 } else {488 /* Assume register Read always uses 512-byte blocks. */489 d->block_size = 512;490 }491 492 424 d->present = true; 425 fibril_mutex_initialize(&d->lock); 426 493 427 return EOK; 494 428 } … … 501 435 502 436 while (cnt > 0) { 503 if (disk[disk_id].dev_type == ata_reg_dev) 504 rc = ata_rcmd_read(disk_id, ba, 1, buf); 505 else 506 rc = ata_pcmd_read_12(disk_id, ba, 1, buf, 507 disk[disk_id].block_size); 508 437 rc = ata_bd_read_block(disk_id, ba, 1, buf); 509 438 if (rc != EOK) 510 439 return rc; … … 512 441 ++ba; 513 442 --cnt; 514 buf += disk[disk_id].block_size;443 buf += block_size; 515 444 } 516 445 … … 524 453 int rc; 525 454 526 if (disk[disk_id].dev_type != ata_reg_dev)527 return ENOTSUP;528 529 455 while (cnt > 0) { 530 rc = ata_ rcmd_write(disk_id, ba, 1, buf);456 rc = ata_bd_write_block(disk_id, ba, 1, buf); 531 457 if (rc != EOK) 532 458 return rc; … … 534 460 ++ba; 535 461 --cnt; 536 buf += disk[disk_id].block_size;462 buf += block_size; 537 463 } 538 464 … … 547 473 * @param disk_id Device ID, 0 or 1. 548 474 * @param buf Pointer to a 512-byte buffer. 549 *550 * @return ETIMEOUT on timeout (this can mean the device is551 * not present). EIO if device responds with error.552 475 */ 553 476 static int drive_identify(int disk_id, void *buf) … … 561 484 562 485 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 563 return E TIMEOUT;486 return EIO; 564 487 565 488 pio_write_8(&cmd->drive_head, drv_head); … … 570 493 */ 571 494 if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 572 return E TIMEOUT;495 return EIO; 573 496 574 497 pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE); 575 498 576 499 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) 577 return E TIMEOUT;500 return EIO; 578 501 579 502 /* Read data from the disk buffer. */ 580 503 581 504 if ((status & SR_DRQ) != 0) { 582 for (i = 0; i < identify_data_size / 2; i++) {505 for (i = 0; i < block_size / 2; i++) { 583 506 data = pio_read_16(&cmd->data_port); 584 507 ((uint16_t *) buf)[i] = data; … … 586 509 } 587 510 588 if ((status & SR_ERR) != 0) {589 return EIO;590 }591 592 return EOK;593 }594 595 /** Issue Identify Packet Device command.596 *597 * Reads @c identify data into the provided buffer. This is used to detect598 * whether an ATAPI device is present and if so, to determine its parameters.599 *600 * @param dev_idx Device index, 0 or 1.601 * @param buf Pointer to a 512-byte buffer.602 */603 static int identify_pkt_dev(int dev_idx, void *buf)604 {605 uint16_t data;606 uint8_t status;607 uint8_t drv_head;608 size_t i;609 610 drv_head = ((dev_idx != 0) ? DHR_DRV : 0);611 612 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)613 return EIO;614 615 pio_write_8(&cmd->drive_head, drv_head);616 617 /* For ATAPI commands we do not need to wait for DRDY. */618 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)619 return EIO;620 621 pio_write_8(&cmd->command, CMD_IDENTIFY_PKT_DEV);622 623 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)624 return EIO;625 626 /* Read data from the device buffer. */627 628 if ((status & SR_DRQ) != 0) {629 for (i = 0; i < identify_data_size / 2; i++) {630 data = pio_read_16(&cmd->data_port);631 ((uint16_t *) buf)[i] = data;632 }633 }634 635 511 if ((status & SR_ERR) != 0) 636 512 return EIO; 637 638 return EOK;639 }640 641 /** Issue packet command (i. e. write a command packet to the device).642 *643 * Only data-in commands are supported (e.g. inquiry, read).644 *645 * @param dev_idx Device index (0 or 1)646 * @param obuf Buffer for storing data read from device647 * @param obuf_size Size of obuf in bytes648 *649 * @return EOK on success, EIO on error.650 */651 static int ata_cmd_packet(int dev_idx, const void *cpkt, size_t cpkt_size,652 void *obuf, size_t obuf_size)653 {654 size_t i;655 uint8_t status;656 uint8_t drv_head;657 disk_t *d;658 size_t data_size;659 uint16_t val;660 661 d = &disk[dev_idx];662 fibril_mutex_lock(&d->lock);663 664 /* New value for Drive/Head register */665 drv_head =666 ((dev_idx != 0) ? DHR_DRV : 0);667 668 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {669 fibril_mutex_unlock(&d->lock);670 return EIO;671 }672 673 pio_write_8(&cmd->drive_head, drv_head);674 675 if (wait_status(0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {676 fibril_mutex_unlock(&d->lock);677 return EIO;678 }679 680 /* Byte count <- max. number of bytes we can read in one transfer. */681 pio_write_8(&cmd->cylinder_low, 0xfe);682 pio_write_8(&cmd->cylinder_high, 0xff);683 684 pio_write_8(&cmd->command, CMD_PACKET);685 686 if (wait_status(SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {687 fibril_mutex_unlock(&d->lock);688 return EIO;689 }690 691 /* Write command packet. */692 for (i = 0; i < (cpkt_size + 1) / 2; i++)693 pio_write_16(&cmd->data_port, ((uint16_t *) cpkt)[i]);694 695 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {696 fibril_mutex_unlock(&d->lock);697 return EIO;698 }699 700 if ((status & SR_DRQ) == 0) {701 fibril_mutex_unlock(&d->lock);702 return EIO;703 }704 705 /* Read byte count. */706 data_size = (uint16_t) pio_read_8(&cmd->cylinder_low) +707 ((uint16_t) pio_read_8(&cmd->cylinder_high) << 8);708 709 /* Check whether data fits into output buffer. */710 if (data_size > obuf_size) {711 /* Output buffer is too small to store data. */712 fibril_mutex_unlock(&d->lock);713 return EIO;714 }715 716 /* Read data from the device buffer. */717 for (i = 0; i < (data_size + 1) / 2; i++) {718 val = pio_read_16(&cmd->data_port);719 ((uint16_t *) obuf)[i] = val;720 }721 722 if (status & SR_ERR) {723 fibril_mutex_unlock(&d->lock);724 return EIO;725 }726 727 fibril_mutex_unlock(&d->lock);728 729 return EOK;730 }731 732 /** Issue ATAPI Inquiry.733 *734 * @param dev_idx Device index (0 or 1)735 * @param obuf Buffer for storing inquiry data read from device736 * @param obuf_size Size of obuf in bytes737 *738 * @return EOK on success, EIO on error.739 */740 static int ata_pcmd_inquiry(int dev_idx, void *obuf, size_t obuf_size)741 {742 ata_pcmd_inquiry_t cp;743 int rc;744 745 memset(&cp, 0, sizeof(cp));746 747 cp.opcode = PCMD_INQUIRY;748 cp.alloc_len = min(obuf_size, 0xff); /* Allocation length */749 750 rc = ata_cmd_packet(0, &cp, sizeof(cp), obuf, obuf_size);751 if (rc != EOK)752 return rc;753 754 return EOK;755 }756 757 /** Issue ATAPI read(12) command.758 *759 * Output buffer must be large enough to hold the data, otherwise the760 * function will fail.761 *762 * @param dev_idx Device index (0 or 1)763 * @param ba Starting block address764 * @param cnt Number of blocks to read765 * @param obuf Buffer for storing inquiry data read from device766 * @param obuf_size Size of obuf in bytes767 *768 * @return EOK on success, EIO on error.769 */770 static int ata_pcmd_read_12(int dev_idx, uint64_t ba, size_t cnt,771 void *obuf, size_t obuf_size)772 {773 ata_pcmd_read_12_t cp;774 int rc;775 776 if (ba > UINT32_MAX)777 return EINVAL;778 779 memset(&cp, 0, sizeof(cp));780 781 cp.opcode = PCMD_READ_12;782 cp.ba = host2uint32_t_be(ba);783 cp.nblocks = host2uint32_t_be(cnt);784 785 rc = ata_cmd_packet(0, &cp, sizeof(cp), obuf, obuf_size);786 if (rc != EOK)787 return rc;788 513 789 514 return EOK; … … 799 524 * @return EOK on success, EIO on error. 800 525 */ 801 static int ata_ rcmd_read(int disk_id, uint64_t ba, size_t blk_cnt,526 static int ata_bd_read_block(int disk_id, uint64_t ba, size_t blk_cnt, 802 527 void *buf) 803 528 { … … 854 579 /* Read data from the device buffer. */ 855 580 856 for (i = 0; i < disk[disk_id].block_size / 2; i++) {581 for (i = 0; i < block_size / 2; i++) { 857 582 data = pio_read_16(&cmd->data_port); 858 583 ((uint16_t *) buf)[i] = data; … … 876 601 * @return EOK on success, EIO on error. 877 602 */ 878 static int ata_ rcmd_write(int disk_id, uint64_t ba, size_t cnt,603 static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt, 879 604 const void *buf) 880 605 { … … 930 655 /* Write data to the device buffer. */ 931 656 932 for (i = 0; i < disk[disk_id].block_size / 2; i++) {657 for (i = 0; i < block_size / 2; i++) { 933 658 pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]); 934 659 } -
uspace/srv/bd/ata_bd/ata_bd.h
re950803 rb366a1bc 53 53 }; 54 54 55 enum ata_dev_type { 56 ata_reg_dev, /* Register device (no packet feature set support) */ 57 ata_pkt_dev /* Packet device (supports packet feature set). */ 58 }; 59 60 /** Register device block addressing mode. */ 61 enum rd_addr_mode { 55 /** Block addressing mode. */ 56 enum addr_mode { 62 57 am_chs, /**< CHS block addressing */ 63 58 am_lba28, /**< LBA-28 block addressing */ … … 67 62 /** Block coordinates */ 68 63 typedef struct { 69 enum rd_addr_mode amode; 64 /** Addressing mode used */ 65 enum addr_mode amode; 70 66 71 67 union { … … 94 90 typedef struct { 95 91 bool present; 96 97 /** Device type */ 98 enum ata_dev_type dev_type; 99 100 /** Addressing mode to use (if register device) */ 101 enum rd_addr_mode amode; 92 enum addr_mode amode; 102 93 103 94 /* … … 111 102 112 103 uint64_t blocks; 113 size_t block_size;114 104 115 105 char model[STR_BOUNDS(40) + 1]; -
uspace/srv/bd/ata_bd/ata_hw.h
re950803 rb366a1bc 134 134 CMD_WRITE_SECTORS = 0x30, 135 135 CMD_WRITE_SECTORS_EXT = 0x34, 136 CMD_PACKET = 0xA0,137 CMD_IDENTIFY_PKT_DEV = 0xA1,138 136 CMD_IDENTIFY_DRIVE = 0xEC 139 137 }; 140 138 141 /** Data returned from identify device and identify packet devicecommand. */139 /** Data returned from @c identify command. */ 142 140 typedef struct { 143 141 uint16_t gen_conf; … … 161 159 uint16_t max_rw_multiple; 162 160 uint16_t _res48; 163 uint16_t caps; /* Different meaning for packet device */161 uint16_t caps; 164 162 uint16_t _res50; 165 163 uint16_t pio_timing; … … 216 214 } identify_data_t; 217 215 218 /** Capability bits for register device. */ 219 enum ata_regdev_caps { 220 rd_cap_iordy = 0x0800, 221 rd_cap_iordy_cbd = 0x0400, 222 rd_cap_lba = 0x0200, 223 rd_cap_dma = 0x0100 224 }; 225 226 /** Capability bits for packet device. */ 227 enum ata_pktdev_caps { 228 pd_cap_ildma = 0x8000, 229 pd_cap_cmdqueue = 0x4000, 230 pd_cap_overlap = 0x2000, 231 pd_cap_need_softreset = 0x1000, /* Obsolete (ATAPI-6) */ 232 pd_cap_iordy = 0x0800, 233 pd_cap_iordy_dis = 0x0400, 234 pd_cap_lba = 0x0200, /* Must be on */ 235 pd_cap_dma = 0x0100 216 enum ata_caps { 217 cap_iordy = 0x0800, 218 cap_iordy_cbd = 0x0400, 219 cap_lba = 0x0200, 220 cap_dma = 0x0100 236 221 }; 237 222 … … 241 226 }; 242 227 243 /** ATA packet command codes. */244 enum ata_pkt_command {245 PCMD_INQUIRY = 0x12,246 PCMD_READ_12 = 0xa8247 };248 249 /** ATAPI Inquiry command */250 typedef struct {251 uint8_t opcode; /**< Operation code (PCMD_INQUIRY) */252 uint8_t _res0;253 uint8_t _res1;254 uint8_t _res2;255 uint8_t alloc_len; /**< Allocation length */256 uint8_t _res3;257 uint8_t _res4;258 uint8_t _res5;259 uint32_t _res6;260 } __attribute__ ((packed)) ata_pcmd_inquiry_t;261 262 /** ATAPI Read(12) command */263 typedef struct {264 uint8_t opcode; /**< Operation code (PCMD_READ_12) */265 uint8_t _res0;266 uint32_t ba; /**< Starting block address */267 uint32_t nblocks; /**< Number of blocks to transfer */268 uint8_t _res1;269 uint8_t _res2;270 } __attribute__ ((packed)) ata_pcmd_read_12_t;271 272 /** Data returned from Inquiry command (mandatory part) */273 typedef struct {274 uint8_t pdev_type; /** Reserved, Peripheral device type */275 uint8_t rmb; /** RMB, Reserved */276 uint8_t std_version; /** ISO version, ECMA version, ANSI version */277 uint8_t atapi_ver_rdf; /** ATAPI version, Response data format */278 uint8_t additional_len; /** Additional length */279 uint8_t _res0;280 uint8_t _res1;281 uint8_t _res2;282 uint8_t vendor_id[8]; /** Vendor ID */283 uint8_t product_id[8]; /** Product ID */284 uint8_t product_rev[4]; /** Product revision level */285 } ata_inquiry_data_t;286 287 /** Extract value of ata_inquiry_data_t.pdev_type */288 #define INQUIRY_PDEV_TYPE(val) ((val) & 0x1f)289 290 /** Values for ata_inquiry_data_t.pdev_type */291 enum ata_pdev_type {292 PDEV_TYPE_CDROM = 0x05293 };294 295 228 #endif 296 229 -
uspace/srv/loader/arch/amd64/_link.ld.in
re950803 rb366a1bc 1 /*2 * The difference from _link.ld.in for regular statically-linked apps3 * is the base address and the special interp section.4 */5 6 1 STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) 7 2 ENTRY(__entry) … … 11 6 text PT_LOAD FLAGS(5); 12 7 data PT_LOAD FLAGS(6); 13 debug PT_NOTE;14 8 } 15 9 … … 17 11 .interp : { 18 12 *(.interp); 19 } : interp20 21 /* . = 0x0000700000001000; 13 } : interp 14 15 /* . = 0x0000700000001000;*/ 22 16 . = 0x70001000; 23 17 … … 25 19 *(.init); 26 20 } :text 27 28 21 .text : { 29 22 *(.text); … … 34 27 *(.data); 35 28 } :data 36 37 29 .tdata : { 38 30 _tdata_start = .; … … 40 32 _tdata_end = .; 41 33 } :data 42 43 34 .tbss : { 44 35 _tbss_start = .; … … 46 37 _tbss_end = .; 47 38 } :data 48 49 39 _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); 50 51 40 .bss : { 52 41 *(COMMON); 53 42 *(.bss); 54 43 } :data 55 44 56 45 . = ALIGN(0x1000); 57 46 _heap = .; 58 59 #ifdef CONFIG_LINE_DEBUG60 .comment 0 : { *(.comment); } :debug61 .debug_abbrev 0 : { *(.debug_abbrev); } :debug62 .debug_aranges 0 : { *(.debug_aranges); } :debug63 .debug_info 0 : { *(.debug_info); } :debug64 .debug_line 0 : { *(.debug_line); } :debug65 .debug_loc 0 : { *(.debug_loc); } :debug66 .debug_pubnames 0 : { *(.debug_pubnames); } :debug67 .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug68 .debug_ranges 0 : { *(.debug_ranges); } :debug69 .debug_str 0 : { *(.debug_str); } :debug70 #endif71 47 72 48 /DISCARD/ : { 73 49 *(*); 74 50 } 51 75 52 } -
uspace/srv/loader/arch/ia32/_link.ld.in
re950803 rb366a1bc 3 3 * is the base address and the special interp section. 4 4 */ 5 6 5 STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) 7 6 ENTRY(__entry) … … 11 10 text PT_LOAD FILEHDR PHDRS FLAGS(5); 12 11 data PT_LOAD FLAGS(6); 13 debug PT_NOTE;14 12 } 15 13 … … 55 53 56 54 . = ALIGN(0x1000); 55 57 56 _heap = .; 58 59 #ifdef CONFIG_LINE_DEBUG60 .comment 0 : { *(.comment); } :debug61 .debug_abbrev 0 : { *(.debug_abbrev); } :debug62 .debug_aranges 0 : { *(.debug_aranges); } :debug63 .debug_info 0 : { *(.debug_info); } :debug64 .debug_line 0 : { *(.debug_line); } :debug65 .debug_loc 0 : { *(.debug_loc); } :debug66 .debug_pubnames 0 : { *(.debug_pubnames); } :debug67 .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug68 .debug_ranges 0 : { *(.debug_ranges); } :debug69 .debug_str 0 : { *(.debug_str); } :debug70 #endif71 57 72 58 /DISCARD/ : { -
uspace/srv/loader/elf_load.c
re950803 rb366a1bc 300 300 case PT_NULL: 301 301 case PT_PHDR: 302 case PT_NOTE:303 302 break; 304 303 case PT_LOAD: … … 311 310 case PT_DYNAMIC: 312 311 case PT_SHLIB: 312 case PT_NOTE: 313 313 case PT_LOPROC: 314 314 case PT_HIPROC:
Note:
See TracChangeset
for help on using the changeset viewer.