Changes in / [b366a1bc:e950803] in mainline
- Files:
-
- 2 added
- 20 deleted
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/arch/mips32/src/Makefile
rb366a1bc re950803 32 32 .PHONY: all clean 33 33 34 all: ../../../../version ../../../../Makefile.co nfig ../../../../config.h ../../../../config.defs34 all: ../../../../version ../../../../Makefile.common ../../../../Makefile.config ../../../../config.h 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 39 43 for file in $(RD_SRVS) ; do \ 40 44 rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \ … … 43 47 rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \ 44 48 done 49 for file in $(NET_CFG) ; do \ 50 rm -f $(USPACEDIR)/dist/cfg/net/`basename $$file` ; \ 51 done 45 52 rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(OUTPUT) $(RAW) $(COMPS).h $(COMPS).c $(LINK) $(INITRD).img $(INITRD).fs 46 53 find . -name '*.o' -follow -exec rm \{\} \; -
boot/arch/mips32/src/Makefile.build
rb366a1bc re950803 32 32 33 33 include ../../../../version 34 include ../../../../Makefile.common 34 35 include ../../../../Makefile.config 35 include ../../../../config.defs36 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 79 83 for file in $(RD_SRVS) ; do \ 80 84 cp $$file $(USPACEDIR)/dist/srv/ ; \ … … 82 86 for file in $(RD_APPS) ; do \ 83 87 cp $$file $(USPACEDIR)/dist/app/ ; \ 88 done 89 for file in $(NET_CFG) ; do \ 90 cp $$file $(USPACEDIR)/dist/cfg/net/ ; \ 84 91 done 85 92 ifeq ($(RDFMT),tmpfs) -
boot/arch/mips32/src/Makefile.toolchain
rb366a1bc re950803 27 27 # 28 28 29 ## Toolchain configuration30 #31 32 ifndef CROSS_PREFIX33 CROSS_PREFIX = /usr/local34 endif35 36 29 BFD_ARCH = mips 37 TARGET = mipsel-linux-gnu38 TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32/bin39 30 40 31 JOBFILE = ../../../../tools/jobfile.py … … 48 39 BFD_NAME = elf32-tradbigmips 49 40 BFD = ecoff-bigmips 50 TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32eb/bin51 TARGET = mips-linux-gnu52 41 endif 53 42 … … 55 44 BFD_NAME = elf32-tradlittlemips 56 45 BFD = binary 57 endif58 59 ifeq ($(COMPILER),gcc_native)60 CC = gcc61 AS = as62 LD = ld63 OBJCOPY = objcopy64 OBJDUMP = objdump65 endif66 67 ifeq ($(COMPILER),gcc_cross)68 CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc69 AS = $(TOOLCHAIN_DIR)/$(TARGET)-as70 LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld71 OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy72 OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump73 46 endif 74 47 -
kernel/arch/ia32/_link.ld.in
rb366a1bc re950803 49 49 } 50 50 51 #ifdef CONFIG_LINE_DEBUG 52 .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 #endif 63 51 64 /DISCARD/ : { 52 *(.note.GNU-stack); 53 *(.comment); 65 *(*); 54 66 } 55 67 -
kernel/arch/mips32/src/mm/tlb.c
rb366a1bc re950803 557 557 entry_hi_t hi, hi_save; 558 558 tlb_index_t index; 559 560 ASSERT(asid != ASID_INVALID); 559 560 if (asid == ASID_INVALID) 561 return; 561 562 562 563 hi_save.value = cp0_entry_hi_read(); -
kernel/generic/include/mm/as.h
rb366a1bc re950803 115 115 116 116 /** 117 * Number of processors on wich is this address space active. 118 * Protected by asidlock. 117 * Number of processors on which this 118 * address space is active. Protected by 119 * asidlock. 119 120 */ 120 121 size_t cpu_refcount; 121 122 122 /** 123 * Address space identifier. 124 * Constant on architectures that do not support ASIDs. 125 * Protected by asidlock. 123 /** Address space identifier. 124 * 125 * Constant on architectures that do not 126 * support ASIDs. Protected by asidlock. 127 * 126 128 */ 127 129 asid_t asid; 128 130 129 /** Number of references (i.e tasks that reference this as). */131 /** Number of references (i.e. tasks that reference this as). */ 130 132 atomic_t refcount; 131 133 … … 199 201 typedef struct { 200 202 mutex_t lock; 203 201 204 /** Containing address space. */ 202 205 as_t *as; 203 206 204 /** 205 * Flags related to the memory represented by the address space area. 206 */ 207 /** Memory flags. */ 207 208 unsigned int flags; 208 209 209 /** A ttributes related to the address space area itself. */210 /** Address space area attributes. */ 210 211 unsigned int attributes; 211 /** Size of this area in multiples of PAGE_SIZE. */ 212 213 /** Number of pages in the area. */ 212 214 size_t pages; 215 216 /** Number of resident pages in the area. */ 217 size_t resident; 218 213 219 /** Base address of this area. */ 214 220 uintptr_t base; 221 215 222 /** Map of used space. */ 216 223 btree_t used_space; 217 224 218 225 /** 219 * If the address space area has been shared, this pointer will220 * referencethe share info structure.226 * If the address space area is shared. this is 227 * a reference to the share info structure. 221 228 */ 222 229 share_info_t *sh_info; … … 261 268 extern bool as_area_check_access(as_area_t *, pf_access_t); 262 269 extern size_t as_area_get_size(uintptr_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 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); 266 272 267 273 /* Interface to be implemented by architectures. */ -
kernel/generic/src/console/cmd.c
rb366a1bc re950803 553 553 for (i = 0; basic_commands[i]; i++) { 554 554 cmd_initialize(basic_commands[i]); 555 if (!cmd_register(basic_commands[i])) 556 printf("Cannot register command %s\n", basic_commands[i]->name); 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 } 557 562 } 558 563 } -
kernel/generic/src/lib/elf.c
rb366a1bc re950803 157 157 case PT_NULL: 158 158 case PT_PHDR: 159 case PT_NOTE: 159 160 break; 160 161 case PT_LOAD: … … 173 174 break; 174 175 case PT_SHLIB: 175 case PT_NOTE:176 176 case PT_LOPROC: 177 177 case PT_HIPROC: -
kernel/generic/src/mm/as.c
rb366a1bc re950803 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 *89 88 */ 90 89 as_operations_t *as_operations = NULL; 91 90 92 /** 93 * Slab for as_t objects. 91 /** Slab for as_t objects. 94 92 * 95 93 */ 96 94 static slab_cache_t *as_slab; 97 95 98 /** 99 * This lock serializes access to the ASID subsystem.100 * Itprotects:96 /** ASID subsystem lock. 97 * 98 * This lock protects: 101 99 * - inactive_as_with_asid_head list 102 100 * - as->asid for each as of the as_t type … … 107 105 108 106 /** 109 * This list contains address spaces that are not active on any 110 * processor and that have valid ASID. 111 * 107 * Inactive address spaces (on all processors) 108 * that have valid ASID. 112 109 */ 113 110 LIST_INITIALIZE(inactive_as_with_asid_head); … … 123 120 mutex_initialize(&as->lock, MUTEX_PASSIVE); 124 121 125 int rc = as_constructor_arch(as, flags); 126 127 return rc; 122 return as_constructor_arch(as, flags); 128 123 } 129 124 130 125 NO_TRACE static size_t as_destructor(void *obj) 131 126 { 132 as_t *as = (as_t *) obj; 133 return as_destructor_arch(as); 127 return as_destructor_arch((as_t *) obj); 134 128 } 135 129 … … 146 140 panic("Cannot create kernel address space."); 147 141 148 /* Make sure the kernel address space 142 /* 143 * Make sure the kernel address space 149 144 * reference count never drops to zero. 150 145 */ … … 195 190 { 196 191 DEADLOCK_PROBE_INIT(p_asidlock); 197 192 198 193 ASSERT(as != AS); 199 194 ASSERT(atomic_get(&as->refcount) == 0); … … 203 198 * lock its mutex. 204 199 */ 205 200 206 201 /* 207 202 * We need to avoid deadlock between TLB shootdown and asidlock. … … 210 205 * disabled to prevent nested context switches. We also depend on the 211 206 * fact that so far no spinlocks are held. 212 *213 207 */ 214 208 preemption_disable(); … … 235 229 spinlock_unlock(&asidlock); 236 230 interrupts_restore(ipl); 237 231 238 232 239 233 /* … … 241 235 * The B+tree must be walked carefully because it is 242 236 * also being destroyed. 243 *244 237 */ 245 238 bool cond = true; … … 268 261 /** Hold a reference to an address space. 269 262 * 270 * Holding a reference to an address space prevents destruction of that address271 * space.263 * Holding a reference to an address space prevents destruction 264 * of that address space. 272 265 * 273 266 * @param as Address space to be held. … … 281 274 /** Release a reference to an address space. 282 275 * 283 * The last one to release a reference to an address space destroys the address284 * space.276 * The last one to release a reference to an address space 277 * destroys the address space. 285 278 * 286 279 * @param asAddress space to be released. … … 310 303 /* 311 304 * We don't want any area to have conflicts with NULL page. 312 *313 305 */ 314 306 if (overlaps(va, size, (uintptr_t) NULL, PAGE_SIZE)) … … 321 313 * record in the left neighbour, the leftmost record in the right 322 314 * neighbour and all records in the leaf node itself. 323 *324 315 */ 325 316 btree_node_t *leaf; … … 382 373 * So far, the area does not conflict with other areas. 383 374 * Check if it doesn't conflict with kernel address space. 384 *385 375 */ 386 376 if (!KERNEL_ADDRESS_SPACE_SHADOWED) { … … 437 427 area->attributes = attrs; 438 428 area->pages = SIZE2FRAMES(size); 429 area->resident = 0; 439 430 area->base = base; 440 431 area->sh_info = NULL; … … 479 470 * to find out whether this is a miss or va belongs to an address 480 471 * space area found there. 481 *482 472 */ 483 473 … … 499 489 * Second, locate the left neighbour and test its last record. 500 490 * Because of its position in the B+tree, it must have base < va. 501 *502 491 */ 503 492 btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf); … … 534 523 /* 535 524 * Locate the area. 536 *537 525 */ 538 526 as_area_t *area = find_area_and_lock(as, address); … … 546 534 * Remapping of address space areas associated 547 535 * with memory mapped devices is not supported. 548 *549 536 */ 550 537 mutex_unlock(&area->lock); … … 557 544 * Remapping of shared address space areas 558 545 * is not supported. 559 *560 546 */ 561 547 mutex_unlock(&area->lock); … … 568 554 /* 569 555 * Zero size address space areas are not allowed. 570 *571 556 */ 572 557 mutex_unlock(&area->lock); … … 581 566 * Shrinking the area. 582 567 * No need to check for overlaps. 583 *584 568 */ 585 569 … … 588 572 /* 589 573 * Start TLB shootdown sequence. 590 *591 574 */ 592 575 ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, … … 599 582 * is also the right way to remove part of the used_space 600 583 * B+tree leaf list. 601 *602 584 */ 603 585 bool cond = true; … … 623 605 * completely in the resized 624 606 * address space area. 625 *626 607 */ 627 608 break; … … 632 613 * to b and c overlaps with the resized 633 614 * address space area. 634 *635 615 */ 636 616 … … 673 653 /* 674 654 * Finish TLB shootdown sequence. 675 *676 655 */ 677 656 … … 681 660 /* 682 661 * Invalidate software translation caches (e.g. TSB on sparc64). 683 *684 662 */ 685 663 as_invalidate_translation_cache(as, area->base + … … 692 670 * Growing the area. 693 671 * Check for overlaps with other address space areas. 694 *695 672 */ 696 673 if (!check_area_conflicts(as, address, pages * PAGE_SIZE, … … 813 790 /* 814 791 * Finish TLB shootdown sequence. 815 *816 792 */ 817 793 … … 821 797 * Invalidate potential software translation caches (e.g. TSB on 822 798 * sparc64). 823 *824 799 */ 825 800 as_invalidate_translation_cache(as, area->base, area->pages); … … 839 814 /* 840 815 * Remove the empty area from address space. 841 *842 816 */ 843 817 btree_remove(&as->as_area_btree, base, NULL); … … 881 855 /* 882 856 * Could not find the source address space area. 883 *884 857 */ 885 858 mutex_unlock(&src_as->lock); … … 891 864 * There is no backend or the backend does not 892 865 * know how to share the area. 893 *894 866 */ 895 867 mutex_unlock(&src_area->lock); … … 918 890 * First, prepare the area for sharing. 919 891 * Then it will be safe to unlock it. 920 *921 892 */ 922 893 share_info_t *sh_info = src_area->sh_info; … … 930 901 /* 931 902 * Call the backend to setup sharing. 932 *933 903 */ 934 904 src_area->backend->share(src_area); … … 949 919 * The flags of the source area are masked against dst_flags_mask 950 920 * to support sharing in less privileged mode. 951 *952 921 */ 953 922 as_area_t *dst_area = as_area_create(dst_as, dst_flags_mask, src_size, … … 966 935 * fully initialized. Clear the AS_AREA_ATTR_PARTIAL 967 936 * attribute and set the sh_info. 968 *969 937 */ 970 938 mutex_lock(&dst_as->lock); … … 989 957 NO_TRACE bool as_area_check_access(as_area_t *area, pf_access_t access) 990 958 { 959 ASSERT(mutex_locked(&area->lock)); 960 991 961 int flagmap[] = { 992 962 [PF_ACCESS_READ] = AS_AREA_READ, … … 994 964 [PF_ACCESS_EXEC] = AS_AREA_EXEC 995 965 }; 996 997 ASSERT(mutex_locked(&area->lock));998 966 999 967 if (!(area->flags & flagmap[access])) … … 1066 1034 /* 1067 1035 * Compute total number of used pages in the used_space B+tree 1068 *1069 1036 */ 1070 1037 size_t used_pages = 0; … … 1088 1055 /* 1089 1056 * Start TLB shootdown sequence. 1090 *1091 1057 */ 1092 1058 ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, … … 1096 1062 * Remove used pages from page tables and remember their frame 1097 1063 * numbers. 1098 *1099 1064 */ 1100 1065 size_t frame_idx = 0; … … 1127 1092 /* 1128 1093 * Finish TLB shootdown sequence. 1129 *1130 1094 */ 1131 1095 … … 1135 1099 * Invalidate potential software translation caches (e.g. TSB on 1136 1100 * sparc64). 1137 *1138 1101 */ 1139 1102 as_invalidate_translation_cache(as, area->base, area->pages); … … 1217 1180 * No area contained mapping for 'page'. 1218 1181 * Signal page fault to low-level handler. 1219 *1220 1182 */ 1221 1183 mutex_unlock(&AS->lock); … … 1237 1199 * The address space area is not backed by any backend 1238 1200 * or the backend cannot handle page faults. 1239 *1240 1201 */ 1241 1202 mutex_unlock(&area->lock); … … 1249 1210 * To avoid race condition between two page faults on the same address, 1250 1211 * we need to make sure the mapping has not been already inserted. 1251 *1252 1212 */ 1253 1213 pte_t *pte; … … 1267 1227 /* 1268 1228 * Resort to the backend page fault handler. 1269 *1270 1229 */ 1271 1230 if (area->backend->page_fault(area, page, access) != AS_PF_OK) { … … 1322 1281 * preemption is disabled. We should not be 1323 1282 * holding any other lock. 1324 *1325 1283 */ 1326 1284 (void) interrupts_enable(); … … 1342 1300 * list of inactive address spaces with assigned 1343 1301 * ASID. 1344 *1345 1302 */ 1346 1303 ASSERT(old_as->asid != ASID_INVALID); … … 1353 1310 * Perform architecture-specific tasks when the address space 1354 1311 * is being removed from the CPU. 1355 *1356 1312 */ 1357 1313 as_deinstall_arch(old_as); … … 1360 1316 /* 1361 1317 * Second, prepare the new address space. 1362 *1363 1318 */ 1364 1319 if ((new_as->cpu_refcount++ == 0) && (new_as != AS_KERNEL)) { … … 1376 1331 * Perform architecture-specific steps. 1377 1332 * (e.g. write ASID to hardware register etc.) 1378 *1379 1333 */ 1380 1334 as_install_arch(new_as); … … 1395 1349 { 1396 1350 ASSERT(mutex_locked(&area->lock)); 1397 1351 1398 1352 return area_flags_to_page_flags(area->flags); 1399 1353 } … … 1516 1470 * @param count Number of page to be marked. 1517 1471 * 1518 * @return Zero on failure and non-zeroon success.1519 * 1520 */ 1521 intused_space_insert(as_area_t *area, uintptr_t page, size_t count)1472 * @return False on failure or true on success. 1473 * 1474 */ 1475 bool used_space_insert(as_area_t *area, uintptr_t page, size_t count) 1522 1476 { 1523 1477 ASSERT(mutex_locked(&area->lock)); … … 1530 1484 /* 1531 1485 * We hit the beginning of some used space. 1532 * 1533 */ 1534 return 0; 1486 */ 1487 return false; 1535 1488 } 1536 1489 1537 1490 if (!leaf->keys) { 1538 1491 btree_insert(&area->used_space, page, (void *) count, leaf); 1539 return 1;1492 goto success; 1540 1493 } 1541 1494 … … 1551 1504 * somewhere between the rightmost interval of 1552 1505 * the left neigbour and the first interval of the leaf. 1553 *1554 1506 */ 1555 1507 … … 1559 1511 left_cnt * PAGE_SIZE)) { 1560 1512 /* The interval intersects with the left interval. */ 1561 return 0;1513 return false; 1562 1514 } else if (overlaps(page, count * PAGE_SIZE, right_pg, 1563 1515 right_cnt * PAGE_SIZE)) { 1564 1516 /* The interval intersects with the right interval. */ 1565 return 0;1517 return false; 1566 1518 } else if ((page == left_pg + left_cnt * PAGE_SIZE) && 1567 1519 (page + count * PAGE_SIZE == right_pg)) { … … 1569 1521 * The interval can be added by merging the two already 1570 1522 * present intervals. 1571 *1572 1523 */ 1573 1524 node->value[node->keys - 1] += count + right_cnt; 1574 1525 btree_remove(&area->used_space, right_pg, leaf); 1575 return 1;1526 goto success; 1576 1527 } else if (page == left_pg + left_cnt * PAGE_SIZE) { 1577 1528 /* 1578 1529 * The interval can be added by simply growing the left 1579 1530 * interval. 1580 *1581 1531 */ 1582 1532 node->value[node->keys - 1] += count; 1583 return 1;1533 goto success; 1584 1534 } else if (page + count * PAGE_SIZE == right_pg) { 1585 1535 /* … … 1587 1537 * the right interval down and increasing its size 1588 1538 * accordingly. 1589 *1590 1539 */ 1591 1540 leaf->value[0] += count; 1592 1541 leaf->key[0] = page; 1593 return 1;1542 goto success; 1594 1543 } else { 1595 1544 /* 1596 1545 * The interval is between both neigbouring intervals, 1597 1546 * but cannot be merged with any of them. 1598 *1599 1547 */ 1600 1548 btree_insert(&area->used_space, page, (void *) count, 1601 1549 leaf); 1602 return 1;1550 goto success; 1603 1551 } 1604 1552 } else if (page < leaf->key[0]) { … … 1609 1557 * Investigate the border case in which the left neighbour does 1610 1558 * not exist but the interval fits from the left. 1611 *1612 1559 */ 1613 1560 … … 1615 1562 right_cnt * PAGE_SIZE)) { 1616 1563 /* The interval intersects with the right interval. */ 1617 return 0;1564 return false; 1618 1565 } else if (page + count * PAGE_SIZE == right_pg) { 1619 1566 /* … … 1621 1568 * right interval down and increasing its size 1622 1569 * accordingly. 1623 *1624 1570 */ 1625 1571 leaf->key[0] = page; 1626 1572 leaf->value[0] += count; 1627 return 1;1573 goto success; 1628 1574 } else { 1629 1575 /* 1630 1576 * The interval doesn't adjoin with the right interval. 1631 1577 * It must be added individually. 1632 *1633 1578 */ 1634 1579 btree_insert(&area->used_space, page, (void *) count, 1635 1580 leaf); 1636 return 1;1581 goto success; 1637 1582 } 1638 1583 } … … 1649 1594 * somewhere between the leftmost interval of 1650 1595 * the right neigbour and the last interval of the leaf. 1651 *1652 1596 */ 1653 1597 … … 1657 1601 left_cnt * PAGE_SIZE)) { 1658 1602 /* The interval intersects with the left interval. */ 1659 return 0;1603 return false; 1660 1604 } else if (overlaps(page, count * PAGE_SIZE, right_pg, 1661 1605 right_cnt * PAGE_SIZE)) { 1662 1606 /* The interval intersects with the right interval. */ 1663 return 0;1607 return false; 1664 1608 } else if ((page == left_pg + left_cnt * PAGE_SIZE) && 1665 1609 (page + count * PAGE_SIZE == right_pg)) { … … 1667 1611 * The interval can be added by merging the two already 1668 1612 * present intervals. 1669 *1670 1613 */ 1671 1614 leaf->value[leaf->keys - 1] += count + right_cnt; 1672 1615 btree_remove(&area->used_space, right_pg, node); 1673 return 1;1616 goto success; 1674 1617 } else if (page == left_pg + left_cnt * PAGE_SIZE) { 1675 1618 /* 1676 1619 * The interval can be added by simply growing the left 1677 1620 * interval. 1678 *1679 1621 */ 1680 leaf->value[leaf->keys - 1] += 1681 return 1;1622 leaf->value[leaf->keys - 1] += count; 1623 goto success; 1682 1624 } else if (page + count * PAGE_SIZE == right_pg) { 1683 1625 /* … … 1685 1627 * the right interval down and increasing its size 1686 1628 * accordingly. 1687 *1688 1629 */ 1689 1630 node->value[0] += count; 1690 1631 node->key[0] = page; 1691 return 1;1632 goto success; 1692 1633 } else { 1693 1634 /* 1694 1635 * The interval is between both neigbouring intervals, 1695 1636 * but cannot be merged with any of them. 1696 *1697 1637 */ 1698 1638 btree_insert(&area->used_space, page, (void *) count, 1699 1639 leaf); 1700 return 1;1640 goto success; 1701 1641 } 1702 1642 } else if (page >= leaf->key[leaf->keys - 1]) { … … 1707 1647 * Investigate the border case in which the right neighbour 1708 1648 * does not exist but the interval fits from the right. 1709 *1710 1649 */ 1711 1650 … … 1713 1652 left_cnt * PAGE_SIZE)) { 1714 1653 /* The interval intersects with the left interval. */ 1715 return 0;1654 return false; 1716 1655 } else if (left_pg + left_cnt * PAGE_SIZE == page) { 1717 1656 /* 1718 1657 * The interval can be added by growing the left 1719 1658 * interval. 1720 *1721 1659 */ 1722 1660 leaf->value[leaf->keys - 1] += count; 1723 return 1;1661 goto success; 1724 1662 } else { 1725 1663 /* 1726 1664 * The interval doesn't adjoin with the left interval. 1727 1665 * It must be added individually. 1728 *1729 1666 */ 1730 1667 btree_insert(&area->used_space, page, (void *) count, 1731 1668 leaf); 1732 return 1;1669 goto success; 1733 1670 } 1734 1671 } … … 1738 1675 * only between two other intervals of the leaf. The two border cases 1739 1676 * were already resolved. 1740 *1741 1677 */ 1742 1678 btree_key_t i; … … 1750 1686 /* 1751 1687 * The interval fits between left_pg and right_pg. 1752 *1753 1688 */ 1754 1689 … … 1758 1693 * The interval intersects with the left 1759 1694 * interval. 1760 *1761 1695 */ 1762 return 0;1696 return false; 1763 1697 } else if (overlaps(page, count * PAGE_SIZE, right_pg, 1764 1698 right_cnt * PAGE_SIZE)) { … … 1766 1700 * The interval intersects with the right 1767 1701 * interval. 1768 *1769 1702 */ 1770 return 0;1703 return false; 1771 1704 } else if ((page == left_pg + left_cnt * PAGE_SIZE) && 1772 1705 (page + count * PAGE_SIZE == right_pg)) { … … 1774 1707 * The interval can be added by merging the two 1775 1708 * already present intervals. 1776 *1777 1709 */ 1778 1710 leaf->value[i - 1] += count + right_cnt; 1779 1711 btree_remove(&area->used_space, right_pg, leaf); 1780 return 1;1712 goto success; 1781 1713 } else if (page == left_pg + left_cnt * PAGE_SIZE) { 1782 1714 /* 1783 1715 * The interval can be added by simply growing 1784 1716 * the left interval. 1785 *1786 1717 */ 1787 1718 leaf->value[i - 1] += count; 1788 return 1;1719 goto success; 1789 1720 } else if (page + count * PAGE_SIZE == right_pg) { 1790 1721 /* … … 1792 1723 * base of the right interval down and 1793 1724 * increasing its size accordingly. 1794 *1795 1725 */ 1796 1726 leaf->value[i] += count; 1797 1727 leaf->key[i] = page; 1798 return 1;1728 goto success; 1799 1729 } else { 1800 1730 /* … … 1802 1732 * intervals, but cannot be merged with any of 1803 1733 * them. 1804 *1805 1734 */ 1806 1735 btree_insert(&area->used_space, page, 1807 1736 (void *) count, leaf); 1808 return 1;1737 goto success; 1809 1738 } 1810 1739 } … … 1813 1742 panic("Inconsistency detected while adding %zu pages of used " 1814 1743 "space at %p.", count, (void *) page); 1744 1745 success: 1746 area->resident += count; 1747 return true; 1815 1748 } 1816 1749 … … 1823 1756 * @param count Number of page to be marked. 1824 1757 * 1825 * @return Zero on failure and non-zeroon success.1826 * 1827 */ 1828 intused_space_remove(as_area_t *area, uintptr_t page, size_t count)1758 * @return False on failure or true on success. 1759 * 1760 */ 1761 bool used_space_remove(as_area_t *area, uintptr_t page, size_t count) 1829 1762 { 1830 1763 ASSERT(mutex_locked(&area->lock)); … … 1837 1770 /* 1838 1771 * We are lucky, page is the beginning of some interval. 1839 *1840 1772 */ 1841 1773 if (count > pages) { 1842 return 0;1774 return false; 1843 1775 } else if (count == pages) { 1844 1776 btree_remove(&area->used_space, page, leaf); 1845 return 1;1777 goto success; 1846 1778 } else { 1847 1779 /* 1848 1780 * Find the respective interval. 1849 1781 * Decrease its size and relocate its start address. 1850 *1851 1782 */ 1852 1783 btree_key_t i; … … 1855 1786 leaf->key[i] += count * PAGE_SIZE; 1856 1787 leaf->value[i] -= count; 1857 return 1;1788 goto success; 1858 1789 } 1859 1790 } 1791 1860 1792 goto error; 1861 1793 } … … 1876 1808 * removed by updating the size of the bigger 1877 1809 * interval. 1878 *1879 1810 */ 1880 1811 node->value[node->keys - 1] -= count; 1881 return 1;1812 goto success; 1882 1813 } else if (page + count * PAGE_SIZE < 1883 1814 left_pg + left_cnt*PAGE_SIZE) { … … 1888 1819 * the original interval and also inserting a 1889 1820 * new interval. 1890 *1891 1821 */ 1892 1822 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) - … … 1895 1825 btree_insert(&area->used_space, page + 1896 1826 count * PAGE_SIZE, (void *) new_cnt, leaf); 1897 return 1;1827 goto success; 1898 1828 } 1899 1829 } 1900 return 0; 1830 1831 return false; 1901 1832 } else if (page < leaf->key[0]) 1902 return 0;1833 return false; 1903 1834 1904 1835 if (page > leaf->key[leaf->keys - 1]) { … … 1914 1845 * interval of the leaf and can be removed by 1915 1846 * updating the size of the bigger interval. 1916 *1917 1847 */ 1918 1848 leaf->value[leaf->keys - 1] -= count; 1919 return 1;1849 goto success; 1920 1850 } else if (page + count * PAGE_SIZE < left_pg + 1921 1851 left_cnt * PAGE_SIZE) { … … 1926 1856 * original interval and also inserting a new 1927 1857 * interval. 1928 *1929 1858 */ 1930 1859 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) - … … 1933 1862 btree_insert(&area->used_space, page + 1934 1863 count * PAGE_SIZE, (void *) new_cnt, leaf); 1935 return 1;1864 goto success; 1936 1865 } 1937 1866 } 1938 return 0; 1867 1868 return false; 1939 1869 } 1940 1870 1941 1871 /* 1942 1872 * The border cases have been already resolved. 1943 * Now the interval can be only between intervals of the leaf. 1873 * Now the interval can be only between intervals of the leaf. 1944 1874 */ 1945 1875 btree_key_t i; … … 1962 1892 * be removed by updating the size of 1963 1893 * the bigger interval. 1964 *1965 1894 */ 1966 1895 leaf->value[i - 1] -= count; 1967 return 1;1896 goto success; 1968 1897 } else if (page + count * PAGE_SIZE < 1969 1898 left_pg + left_cnt * PAGE_SIZE) { … … 1983 1912 count * PAGE_SIZE, (void *) new_cnt, 1984 1913 leaf); 1985 return 1;1914 goto success; 1986 1915 } 1987 1916 } 1988 return 0; 1917 1918 return false; 1989 1919 } 1990 1920 } … … 1993 1923 panic("Inconsistency detected while removing %zu pages of used " 1994 1924 "space from %p.", count, (void *) page); 1925 1926 success: 1927 area->resident -= count; 1928 return true; 1995 1929 } 1996 1930 -
kernel/generic/src/sysinfo/stats.c
rb366a1bc re950803 160 160 static size_t get_task_virtmem(as_t *as) 161 161 { 162 size_t result = 0;163 164 162 /* 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. 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. 173 167 */ 174 168 175 169 if (SYNCH_FAILED(mutex_trylock(&as->lock))) 176 return result * PAGE_SIZE; 170 return 0; 171 172 size_t pages = 0; 177 173 178 174 /* 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 space202 *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 to214 * block. Only attempt to lock the address space and address space area215 * 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 space219 * management code compute these statistics as it proceeds instead of220 * 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 */227 175 link_t *cur; 228 176 for (cur = as->as_area_btree.leaf_head.next; … … 238 186 continue; 239 187 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 188 pages += area->pages; 252 189 mutex_unlock(&area->lock); 253 190 } … … 256 193 mutex_unlock(&as->lock); 257 194 258 return result * PAGE_SIZE; 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); 259 241 } 260 242 -
uspace/Makefile.common
rb366a1bc re950803 135 135 endif 136 136 137 ifeq ($(CONFIG_LINE_DEBUG),y) 138 GCC_CFLAGS += -g 139 ICC_CFLAGS += -g 140 SUNCC_CFLAGS += -g 141 CLANG_CFLAGS += -g 142 endif 143 137 144 ## Setup platform configuration 138 145 # -
uspace/drv/test2/test2.c
rb366a1bc re950803 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 } 105 109 fibril_add_ready(postpone); 106 110 } else { -
uspace/lib/c/arch/amd64/_link.ld.in
rb366a1bc re950803 5 5 text PT_LOAD FLAGS(5); 6 6 data PT_LOAD FLAGS(6); 7 debug PT_NOTE; 7 8 } 8 9 … … 13 14 *(.init); 14 15 } :text 16 15 17 .text : { 16 18 *(.text); 17 19 *(.rodata*); 18 20 } :text 19 21 20 22 . = . + 0x1000; 21 23 22 24 .data : { 23 25 *(.data); 24 26 } :data 27 25 28 .tdata : { 26 29 _tdata_start = .; … … 31 34 _tbss_end = .; 32 35 } :data 36 33 37 _tls_alignment = ALIGNOF(.tdata); 38 34 39 .bss : { 35 40 *(COMMON); 36 41 *(.bss); 37 42 } :data 38 43 39 44 . = ALIGN(0x1000); 40 45 _heap = .; 46 47 #ifdef CONFIG_LINE_DEBUG 48 .comment 0 : { *(.comment); } :debug 49 .debug_abbrev 0 : { *(.debug_abbrev); } :debug 50 .debug_aranges 0 : { *(.debug_aranges); } :debug 51 .debug_info 0 : { *(.debug_info); } :debug 52 .debug_line 0 : { *(.debug_line); } :debug 53 .debug_loc 0 : { *(.debug_loc); } :debug 54 .debug_pubnames 0 : { *(.debug_pubnames); } :debug 55 .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug 56 .debug_ranges 0 : { *(.debug_ranges); } :debug 57 .debug_str 0 : { *(.debug_str); } :debug 58 #endif 41 59 42 60 /DISCARD/ : { -
uspace/lib/c/arch/ia32/_link.ld.in
rb366a1bc re950803 5 5 text PT_LOAD FLAGS(5); 6 6 data PT_LOAD FLAGS(6); 7 debug PT_NOTE; 7 8 } 8 9 … … 43 44 44 45 . = ALIGN(0x1000); 46 _heap = .; 45 47 46 _heap = .; 48 #ifdef CONFIG_LINE_DEBUG 49 .comment 0 : { *(.comment); } :debug 50 .debug_abbrev 0 : { *(.debug_abbrev); } :debug 51 .debug_aranges 0 : { *(.debug_aranges); } :debug 52 .debug_info 0 : { *(.debug_info); } :debug 53 .debug_line 0 : { *(.debug_line); } :debug 54 .debug_loc 0 : { *(.debug_loc); } :debug 55 .debug_pubnames 0 : { *(.debug_pubnames); } :debug 56 .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug 57 .debug_ranges 0 : { *(.debug_ranges); } :debug 58 .debug_str 0 : { *(.debug_str); } :debug 59 #endif 47 60 48 61 /DISCARD/ : { -
uspace/lib/c/generic/async.c
rb366a1bc re950803 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 432 438 fibril_add_ready(fid); 433 439 … … 681 687 conn->wdata.fid = fibril_create(connection_fibril, conn); 682 688 683 if ( !conn->wdata.fid) {689 if (conn->wdata.fid == 0) { 684 690 free(conn); 691 685 692 if (callid) 686 693 ipc_answer_0(callid, ENOMEM); 694 687 695 return (uintptr_t) NULL; 688 696 } … … 853 861 { 854 862 fid_t fid = fibril_create(async_manager_fibril, NULL); 855 fibril_add_manager(fid); 863 if (fid != 0) 864 fibril_add_manager(fid); 856 865 } 857 866 -
uspace/srv/bd/ata_bd/ata_bd.c
rb366a1bc re950803 55 55 #include <as.h> 56 56 #include <fibril_synch.h> 57 #include <stdint.h> 57 58 #include <str.h> 58 59 #include <devmap.h> … … 61 62 #include <errno.h> 62 63 #include <bool.h> 64 #include <byteorder.h> 63 65 #include <task.h> 64 66 #include <macros.h> … … 73 75 #define LEGACY_CTLS 4 74 76 75 /** Physical block size. Should be always 512. */ 76 static const size_t block_size = 512; 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; 77 82 78 83 /** Size of the communication area. */ … … 105 110 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt, 106 111 const void *buf); 107 static int ata_ bd_read_block(int disk_id, uint64_t ba, size_t cnt,112 static int ata_rcmd_read(int disk_id, uint64_t ba, size_t cnt, 108 113 void *buf); 109 static int ata_ bd_write_block(int disk_id, uint64_t ba, size_t cnt,114 static int ata_rcmd_write(int disk_id, uint64_t ba, size_t cnt, 110 115 const void *buf); 111 116 static int disk_init(disk_t *d, int disk_id); 112 117 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); 113 124 static void disk_print_summary(disk_t *d); 114 125 static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc); … … 203 214 printf("%s: ", d->model); 204 215 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; 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"); 216 232 } 217 233 … … 313 329 IPC_GET_ARG2(call)); 314 330 cnt = IPC_GET_ARG3(call); 315 if (cnt * block_size > comm_size) {331 if (cnt * disk[disk_id].block_size > comm_size) { 316 332 retval = ELIMIT; 317 333 break; … … 323 339 IPC_GET_ARG2(call)); 324 340 cnt = IPC_GET_ARG3(call); 325 if (cnt * block_size > comm_size) {341 if (cnt * disk[disk_id].block_size > comm_size) { 326 342 retval = ELIMIT; 327 343 break; … … 330 346 break; 331 347 case BD_GET_BLOCK_SIZE: 332 async_answer_1(callid, EOK, block_size);348 async_answer_1(callid, EOK, disk[disk_id].block_size); 333 349 continue; 334 350 case BD_GET_NUM_BLOCKS: … … 353 369 identify_data_t idata; 354 370 uint8_t model[40]; 371 ata_inquiry_data_t inq_data; 355 372 uint16_t w; 356 373 uint8_t c; … … 359 376 unsigned i; 360 377 378 d->present = false; 379 fibril_mutex_initialize(&d->lock); 380 381 /* Try identify command. */ 361 382 rc = drive_identify(disk_id, &idata); 362 if (rc != EOK) { 363 d->present = false; 364 return rc; 365 } 366 367 if ((idata.caps & cap_lba) == 0) { 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) { 368 416 /* Device only supports CHS addressing. */ 369 417 d->amode = am_chs; … … 422 470 d->model[pos] = '\0'; 423 471 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 424 492 d->present = true; 425 fibril_mutex_initialize(&d->lock);426 427 493 return EOK; 428 494 } … … 435 501 436 502 while (cnt > 0) { 437 rc = ata_bd_read_block(disk_id, ba, 1, buf); 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 438 509 if (rc != EOK) 439 510 return rc; … … 441 512 ++ba; 442 513 --cnt; 443 buf += block_size;514 buf += disk[disk_id].block_size; 444 515 } 445 516 … … 453 524 int rc; 454 525 526 if (disk[disk_id].dev_type != ata_reg_dev) 527 return ENOTSUP; 528 455 529 while (cnt > 0) { 456 rc = ata_ bd_write_block(disk_id, ba, 1, buf);530 rc = ata_rcmd_write(disk_id, ba, 1, buf); 457 531 if (rc != EOK) 458 532 return rc; … … 460 534 ++ba; 461 535 --cnt; 462 buf += block_size;536 buf += disk[disk_id].block_size; 463 537 } 464 538 … … 473 547 * @param disk_id Device ID, 0 or 1. 474 548 * @param buf Pointer to a 512-byte buffer. 549 * 550 * @return ETIMEOUT on timeout (this can mean the device is 551 * not present). EIO if device responds with error. 475 552 */ 476 553 static int drive_identify(int disk_id, void *buf) … … 484 561 485 562 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 486 return E IO;563 return ETIMEOUT; 487 564 488 565 pio_write_8(&cmd->drive_head, drv_head); … … 493 570 */ 494 571 if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 495 return E IO;572 return ETIMEOUT; 496 573 497 574 pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE); 498 575 499 576 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) 500 return E IO;577 return ETIMEOUT; 501 578 502 579 /* Read data from the disk buffer. */ 503 580 504 581 if ((status & SR_DRQ) != 0) { 505 for (i = 0; i < block_size / 2; i++) {582 for (i = 0; i < identify_data_size / 2; i++) { 506 583 data = pio_read_16(&cmd->data_port); 507 584 ((uint16_t *) buf)[i] = data; … … 509 586 } 510 587 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 detect 598 * 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 511 635 if ((status & SR_ERR) != 0) 512 636 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 device 647 * @param obuf_size Size of obuf in bytes 648 * 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 device 736 * @param obuf_size Size of obuf in bytes 737 * 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 the 760 * function will fail. 761 * 762 * @param dev_idx Device index (0 or 1) 763 * @param ba Starting block address 764 * @param cnt Number of blocks to read 765 * @param obuf Buffer for storing inquiry data read from device 766 * @param obuf_size Size of obuf in bytes 767 * 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; 513 788 514 789 return EOK; … … 524 799 * @return EOK on success, EIO on error. 525 800 */ 526 static int ata_ bd_read_block(int disk_id, uint64_t ba, size_t blk_cnt,801 static int ata_rcmd_read(int disk_id, uint64_t ba, size_t blk_cnt, 527 802 void *buf) 528 803 { … … 579 854 /* Read data from the device buffer. */ 580 855 581 for (i = 0; i < block_size / 2; i++) {856 for (i = 0; i < disk[disk_id].block_size / 2; i++) { 582 857 data = pio_read_16(&cmd->data_port); 583 858 ((uint16_t *) buf)[i] = data; … … 601 876 * @return EOK on success, EIO on error. 602 877 */ 603 static int ata_ bd_write_block(int disk_id, uint64_t ba, size_t cnt,878 static int ata_rcmd_write(int disk_id, uint64_t ba, size_t cnt, 604 879 const void *buf) 605 880 { … … 655 930 /* Write data to the device buffer. */ 656 931 657 for (i = 0; i < block_size / 2; i++) {932 for (i = 0; i < disk[disk_id].block_size / 2; i++) { 658 933 pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]); 659 934 } -
uspace/srv/bd/ata_bd/ata_bd.h
rb366a1bc re950803 53 53 }; 54 54 55 /** Block addressing mode. */ 56 enum addr_mode { 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 { 57 62 am_chs, /**< CHS block addressing */ 58 63 am_lba28, /**< LBA-28 block addressing */ … … 62 67 /** Block coordinates */ 63 68 typedef struct { 64 /** Addressing mode used */ 65 enum addr_mode amode; 69 enum rd_addr_mode amode; 66 70 67 71 union { … … 90 94 typedef struct { 91 95 bool present; 92 enum addr_mode amode; 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; 93 102 94 103 /* … … 102 111 103 112 uint64_t blocks; 113 size_t block_size; 104 114 105 115 char model[STR_BOUNDS(40) + 1]; -
uspace/srv/bd/ata_bd/ata_hw.h
rb366a1bc re950803 134 134 CMD_WRITE_SECTORS = 0x30, 135 135 CMD_WRITE_SECTORS_EXT = 0x34, 136 CMD_PACKET = 0xA0, 137 CMD_IDENTIFY_PKT_DEV = 0xA1, 136 138 CMD_IDENTIFY_DRIVE = 0xEC 137 139 }; 138 140 139 /** Data returned from @c identifycommand. */141 /** Data returned from identify device and identify packet device command. */ 140 142 typedef struct { 141 143 uint16_t gen_conf; … … 159 161 uint16_t max_rw_multiple; 160 162 uint16_t _res48; 161 uint16_t caps; 163 uint16_t caps; /* Different meaning for packet device */ 162 164 uint16_t _res50; 163 165 uint16_t pio_timing; … … 214 216 } identify_data_t; 215 217 216 enum ata_caps { 217 cap_iordy = 0x0800, 218 cap_iordy_cbd = 0x0400, 219 cap_lba = 0x0200, 220 cap_dma = 0x0100 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 221 236 }; 222 237 … … 226 241 }; 227 242 243 /** ATA packet command codes. */ 244 enum ata_pkt_command { 245 PCMD_INQUIRY = 0x12, 246 PCMD_READ_12 = 0xa8 247 }; 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 = 0x05 293 }; 294 228 295 #endif 229 296 -
uspace/srv/loader/arch/amd64/_link.ld.in
rb366a1bc re950803 1 /* 2 * The difference from _link.ld.in for regular statically-linked apps 3 * is the base address and the special interp section. 4 */ 5 1 6 STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) 2 7 ENTRY(__entry) … … 6 11 text PT_LOAD FLAGS(5); 7 12 data PT_LOAD FLAGS(6); 13 debug PT_NOTE; 8 14 } 9 15 … … 11 17 .interp : { 12 18 *(.interp); 13 } : 14 15 /* . = 0x0000700000001000; */19 } :interp 20 21 /* . = 0x0000700000001000; */ 16 22 . = 0x70001000; 17 23 … … 19 25 *(.init); 20 26 } :text 27 21 28 .text : { 22 29 *(.text); … … 27 34 *(.data); 28 35 } :data 36 29 37 .tdata : { 30 38 _tdata_start = .; … … 32 40 _tdata_end = .; 33 41 } :data 42 34 43 .tbss : { 35 44 _tbss_start = .; … … 37 46 _tbss_end = .; 38 47 } :data 48 39 49 _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); 50 40 51 .bss : { 41 52 *(COMMON); 42 53 *(.bss); 43 54 } :data 44 55 45 56 . = ALIGN(0x1000); 46 57 _heap = .; 58 59 #ifdef CONFIG_LINE_DEBUG 60 .comment 0 : { *(.comment); } :debug 61 .debug_abbrev 0 : { *(.debug_abbrev); } :debug 62 .debug_aranges 0 : { *(.debug_aranges); } :debug 63 .debug_info 0 : { *(.debug_info); } :debug 64 .debug_line 0 : { *(.debug_line); } :debug 65 .debug_loc 0 : { *(.debug_loc); } :debug 66 .debug_pubnames 0 : { *(.debug_pubnames); } :debug 67 .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug 68 .debug_ranges 0 : { *(.debug_ranges); } :debug 69 .debug_str 0 : { *(.debug_str); } :debug 70 #endif 47 71 48 72 /DISCARD/ : { 49 73 *(*); 50 74 } 51 52 75 } -
uspace/srv/loader/arch/ia32/_link.ld.in
rb366a1bc re950803 3 3 * is the base address and the special interp section. 4 4 */ 5 5 6 STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) 6 7 ENTRY(__entry) … … 10 11 text PT_LOAD FILEHDR PHDRS FLAGS(5); 11 12 data PT_LOAD FLAGS(6); 13 debug PT_NOTE; 12 14 } 13 15 … … 53 55 54 56 . = ALIGN(0x1000); 57 _heap = .; 55 58 56 _heap = .; 59 #ifdef CONFIG_LINE_DEBUG 60 .comment 0 : { *(.comment); } :debug 61 .debug_abbrev 0 : { *(.debug_abbrev); } :debug 62 .debug_aranges 0 : { *(.debug_aranges); } :debug 63 .debug_info 0 : { *(.debug_info); } :debug 64 .debug_line 0 : { *(.debug_line); } :debug 65 .debug_loc 0 : { *(.debug_loc); } :debug 66 .debug_pubnames 0 : { *(.debug_pubnames); } :debug 67 .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug 68 .debug_ranges 0 : { *(.debug_ranges); } :debug 69 .debug_str 0 : { *(.debug_str); } :debug 70 #endif 57 71 58 72 /DISCARD/ : { -
uspace/srv/loader/elf_load.c
rb366a1bc re950803 300 300 case PT_NULL: 301 301 case PT_PHDR: 302 case PT_NOTE: 302 303 break; 303 304 case PT_LOAD: … … 310 311 case PT_DYNAMIC: 311 312 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.