Changeset 24f27bb in mainline
- Timestamp:
- 2009-08-09T14:35:32Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 75a2dc08
- Parents:
- cb0ea39 (diff), 330965c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/include/cpu.h
rcb0ea39 r24f27bb 36 36 #define KERN_amd64_CPU_H_ 37 37 38 #define RFLAGS_IF (1 << 9) 39 #define RFLAGS_DF (1 << 10) 40 #define RFLAGS_RF (1 << 16) 38 #define RFLAGS_CF (1 << 0) 39 #define RFLAGS_PF (1 << 2) 40 #define RFLAGS_AF (1 << 4) 41 #define RFLAGS_ZF (1 << 6) 42 #define RFLAGS_SF (1 << 7) 43 #define RFLAGS_TF (1 << 8) 44 #define RFLAGS_IF (1 << 9) 45 #define RFLAGS_DF (1 << 10) 46 #define RFLAGS_OF (1 << 11) 47 #define RFLAGS_RF (1 << 16) 41 48 42 49 #define EFER_MSR_NUM 0xc0000080 -
kernel/arch/amd64/src/userspace.c
rcb0ea39 r24f27bb 34 34 35 35 #include <userspace.h> 36 #include <arch/cpu.h> 36 37 #include <arch/pm.h> 37 38 #include <arch/types.h> … … 50 51 ipl_t ipl = interrupts_disable(); 51 52 52 /* Clear CF, PF, AF, ZF, SF, DF, OF */53 ipl &= ~(0xcd4);53 ipl &= ~(RFLAGS_CF | RFLAGS_PF | RFLAGS_AF | RFLAGS_ZF | RFLAGS_SF | 54 RFLAGS_DF | RFLAGS_OF); 54 55 55 56 asm volatile ( 56 57 58 59 60 61 57 "pushq %[udata_des]\n" 58 "pushq %[stack_size]\n" 59 "pushq %[ipl]\n" 60 "pushq %[utext_des]\n" 61 "pushq %[entry]\n" 62 "movq %[uarg], %%rax\n" 62 63 63 64 65 66 67 68 69 70 71 72 73 64 /* %rdi is defined to hold pcb_ptr - set it to 0 */ 65 "xorq %%rdi, %%rdi\n" 66 "iretq\n" 67 :: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER), 68 [stack_size] "r" (kernel_uarg->uspace_stack + THREAD_STACK_SIZE), 69 [ipl] "r" (ipl), 70 [utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER), 71 [entry] "r" (kernel_uarg->uspace_entry), 72 [uarg] "r" (kernel_uarg->uspace_uarg) 73 : "rax" 74 ); 74 75 75 76 /* Unreachable */ 76 while (1); 77 while (1) 78 ; 77 79 } 78 80 -
kernel/arch/sparc64/src/sparc64.c
rcb0ea39 r24f27bb 135 135 void userspace(uspace_arg_t *kernel_uarg) 136 136 { 137 (void) interrupts_disable(); 137 138 switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry, 138 139 ((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE -
kernel/generic/src/ipc/event.c
rcb0ea39 r24f27bb 45 45 #include <arch.h> 46 46 47 /** 48 * The events array. 49 * Arranging the events in this two-dimensional array should decrease the 50 * likelyhood of cacheline ping-pong. 51 */ 47 /** The events array. */ 52 48 static event_t events[EVENT_END]; 53 49 -
kernel/generic/src/main/uinit.c
rcb0ea39 r24f27bb 81 81 free((uspace_arg_t *) arg); 82 82 83 /*84 * Disable interrupts so that the execution of userspace() is not85 * disturbed by any interrupts as some of the userspace()86 * implementations will switch to the userspace stack before switching87 * the mode.88 */89 (void) interrupts_disable();90 83 userspace(&uarg); 91 84 } -
kernel/generic/src/printf/printf_core.c
rcb0ea39 r24f27bb 491 491 counter += retval; 492 492 493 /* Print t ailing spaces */493 /* Print trailing spaces */ 494 494 495 495 while (width-- > 0) { -
kernel/generic/src/printf/vsnprintf.c
rcb0ea39 r24f27bb 100 100 } 101 101 102 /* Buffer is big enough tto print the whole string */102 /* Buffer is big enough to print the whole string */ 103 103 memcpy((void *)(data->dst + data->len), (void *) str, size); 104 104 data->len += size; -
kernel/generic/src/proc/task.c
rcb0ea39 r24f27bb 75 75 static task_id_t task_counter = 0; 76 76 77 /* Forward declarations. */ 78 static void task_kill_internal(task_t *); 79 77 80 /** Initialize kernel tasks support. */ 78 81 void task_init(void) … … 83 86 84 87 /* 85 * The idea behind this walker is to remember a single taskdifferent from88 * The idea behind this walker is to kill and count all tasks different from 86 89 * TASK. 87 90 */ … … 89 92 { 90 93 task_t *t = avltree_get_instance(node, task_t, tasks_tree_node); 91 task_t **tp = (task_t **) arg; 92 93 if (t != TASK) { 94 *tp = t; 95 return false; /* stop walking */ 94 unsigned *cnt = (unsigned *) arg; 95 96 if (t != TASK) { 97 (*cnt)++; 98 #ifdef CONFIG_DEBUG 99 printf("[%"PRIu64"] ", t->taskid); 100 #endif 101 task_kill_internal(t); 96 102 } 97 103 … … 102 108 void task_done(void) 103 109 { 104 task_t *t; 110 unsigned tasks_left; 111 105 112 do { /* Repeat until there are any tasks except TASK */ 106 107 113 /* Messing with task structures, avoid deadlock */ 114 #ifdef CONFIG_DEBUG 115 printf("Killing tasks... "); 116 #endif 108 117 ipl_t ipl = interrupts_disable(); 109 118 spinlock_lock(&tasks_lock); 110 111 t = NULL; 112 avltree_walk(&tasks_tree, task_done_walker, &t); 113 114 if (t != NULL) { 115 task_id_t id = t->taskid; 116 117 spinlock_unlock(&tasks_lock); 118 interrupts_restore(ipl); 119 119 tasks_left = 0; 120 avltree_walk(&tasks_tree, task_done_walker, &tasks_left); 121 spinlock_unlock(&tasks_lock); 122 interrupts_restore(ipl); 123 thread_sleep(1); 120 124 #ifdef CONFIG_DEBUG 121 printf("Killing task %" PRIu64 "\n", id); 122 #endif 123 task_kill(id); 124 thread_usleep(10000); 125 } else { 126 spinlock_unlock(&tasks_lock); 127 interrupts_restore(ipl); 128 } 129 130 } while (t != NULL); 125 printf("\n"); 126 #endif 127 } while (tasks_left); 131 128 } 132 129 … … 350 347 } 351 348 352 /** Kill task. 353 * 354 * This function is idempotent. 355 * It signals all the task's threads to bail it out. 356 * 357 * @param id ID of the task to be killed. 358 * 359 * @return Zero on success or an error code from errno.h. 360 */ 361 int task_kill(task_id_t id) 362 { 363 ipl_t ipl; 364 task_t *ta; 349 static void task_kill_internal(task_t *ta) 350 { 365 351 link_t *cur; 366 352 367 if (id == 1)368 return EPERM;369 370 ipl = interrupts_disable();371 spinlock_lock(&tasks_lock);372 if (!(ta = task_find_by_id(id))) {373 spinlock_unlock(&tasks_lock);374 interrupts_restore(ipl);375 return ENOENT;376 }377 spinlock_unlock(&tasks_lock);378 379 353 /* 380 354 * Interrupt all threads. … … 397 371 } 398 372 spinlock_unlock(&ta->lock); 373 } 374 375 /** Kill task. 376 * 377 * This function is idempotent. 378 * It signals all the task's threads to bail it out. 379 * 380 * @param id ID of the task to be killed. 381 * 382 * @return Zero on success or an error code from errno.h. 383 */ 384 int task_kill(task_id_t id) 385 { 386 ipl_t ipl; 387 task_t *ta; 388 389 if (id == 1) 390 return EPERM; 391 392 ipl = interrupts_disable(); 393 spinlock_lock(&tasks_lock); 394 if (!(ta = task_find_by_id(id))) { 395 spinlock_unlock(&tasks_lock); 396 interrupts_restore(ipl); 397 return ENOENT; 398 } 399 task_kill_internal(ta); 400 spinlock_unlock(&tasks_lock); 399 401 interrupts_restore(ipl); 400 401 402 return 0; 402 403 } -
tools/config.py
rcb0ea39 r24f27bb 225 225 "Create output configuration" 226 226 227 revision = commands.getoutput(' svnversion .2> /dev/null')227 revision = commands.getoutput('bzr version-info --custom --template="{revision_id}" 2> /dev/null') 228 228 timestamp = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"') 229 229 -
uspace/lib/libc/generic/io/printf_core.c
rcb0ea39 r24f27bb 490 490 counter += retval; 491 491 492 /* Print t ailing spaces */492 /* Print trailing spaces */ 493 493 494 494 while (width-- > 0) { -
uspace/lib/libc/generic/io/vsnprintf.c
rcb0ea39 r24f27bb 100 100 } 101 101 102 /* Buffer is big enough tto print the whole string */102 /* Buffer is big enough to print the whole string */ 103 103 memcpy((void *)(data->dst + data->len), (void *) str, size); 104 104 data->len += size; -
uspace/lib/libc/generic/malloc.c
rcb0ea39 r24f27bb 392 392 if (orig_size - real_size >= STRUCT_OVERHEAD) { 393 393 /* Split the original block to a full block 394 and a t ailing free block */394 and a trailing free block */ 395 395 block_init((void *) head, real_size, false); 396 396 block_init((void *) head + real_size, -
uspace/srv/bd/ata_bd/ata_bd.c
rcb0ea39 r24f27bb 36 36 * 37 37 * This driver currently works only with CHS addressing and uses PIO. 38 * Currently based on the (now obsolete) ANSI X3.221-1994 (ATA-1) standard. 39 * At this point only reading is possible, not writing. 38 * Currently based on the (now obsolete) ATA-1, ATA-2 standards. 40 39 * 41 40 * The driver services a single controller which can have up to two disks … … 61 60 #define NAME "ata_bd" 62 61 62 /** Physical block size. Should be always 512. */ 63 63 static const size_t block_size = 512; 64 65 /** Size of the communication area. */ 64 66 static size_t comm_size; 65 67 68 /** I/O base address of the command registers. */ 66 69 static uintptr_t cmd_physical = 0x1f0; 70 /** I/O base address of the control registers. */ 67 71 static uintptr_t ctl_physical = 0x170; 72 68 73 static ata_cmd_t *cmd; 69 74 static ata_ctl_t *ctl; … … 81 86 const void *buf); 82 87 static int drive_identify(int drive_id, disk_t *d); 88 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus, 89 unsigned timeout); 83 90 84 91 int main(int argc, char **argv) 85 92 { 86 uint8_t status;87 93 char name[16]; 88 94 int i, rc; … … 96 102 return -1; 97 103 98 /* Put drives to reset, disable interrupts. */ 99 printf("Reset drives... "); 100 fflush(stdout); 101 102 pio_write_8(&ctl->device_control, DCR_SRST); 103 /* FIXME: Find out how to do this properly. */ 104 async_usleep(100); 105 pio_write_8(&ctl->device_control, 0); 106 107 do { 108 status = pio_read_8(&cmd->status); 109 } while ((status & SR_BSY) != 0); 110 printf("Done\n"); 111 112 (void) drive_identify(0, &disk[0]); 113 (void) drive_identify(1, &disk[1]); 104 for (i = 0; i < MAX_DISKS; i++) { 105 printf("Identify drive %d... ", i); 106 fflush(stdout); 107 108 rc = drive_identify(i, &disk[i]); 109 110 if (rc == EOK) { 111 printf("%u cylinders, %u heads, %u sectors\n", 112 disk[i].cylinders, disk[i].heads, disk[i].sectors); 113 } else { 114 printf("Not found.\n"); 115 } 116 } 114 117 115 118 n_disks = 0; … … 144 147 } 145 148 146 static int drive_identify(int disk_id, disk_t *d) 147 { 148 uint16_t data; 149 uint8_t status; 150 size_t i; 151 152 printf("Identify drive %d... ", disk_id); 153 fflush(stdout); 154 155 pio_write_8(&cmd->drive_head, ((disk_id != 0) ? DHR_DRV : 0)); 156 async_usleep(100); 157 pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE); 158 159 status = pio_read_8(&cmd->status); 160 161 d->present = false; 162 163 /* 164 * Detect if drive is present. This is Qemu only! Need to 165 * do the right thing to work with real drives. 166 */ 167 if ((status & SR_DRDY) == 0) { 168 printf("None attached.\n"); 169 return ENOENT; 170 } 171 172 for (i = 0; i < block_size / 2; i++) { 173 do { 174 status = pio_read_8(&cmd->status); 175 } while ((status & SR_DRDY) == 0); 176 177 data = pio_read_16(&cmd->data_port); 178 179 switch (i) { 180 case 1: d->cylinders = data; break; 181 case 3: d->heads = data; break; 182 case 6: d->sectors = data; break; 183 } 184 } 185 186 d->blocks = d->cylinders * d->heads * d->sectors; 187 188 printf("Geometry: %u cylinders, %u heads, %u sectors\n", 189 d->cylinders, d->heads, d->sectors); 190 191 d->present = true; 192 fibril_mutex_initialize(&d->lock); 193 194 return EOK; 195 } 196 149 150 /** Register driver and enable device I/O. */ 197 151 static int ata_bd_init(void) 198 152 { … … 226 180 } 227 181 182 /** Block device connection handler */ 228 183 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall) 229 184 { … … 296 251 } 297 252 253 /** Transfer a logical block from/to the device. 254 * 255 * @param disk_id Device index (0 or 1) 256 * @param method @c BD_READ_BLOCK or @c BD_WRITE_BLOCK 257 * @param blk_idx Index of the first block. 258 * @param size Size of the logical block. 259 * @param buf Data buffer. 260 * 261 * @return EOK on success, EIO on error. 262 */ 298 263 static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t blk_idx, size_t size, 299 264 void *buf) … … 327 292 } 328 293 329 294 /** Issue IDENTIFY command. 295 * 296 * This is used to detect whether an ATA device is present and if so, 297 * to determine its parameters. The parameters are written to @a d. 298 * 299 * @param disk_id Device ID, 0 or 1. 300 * @param d Device structure to store parameters in. 301 */ 302 static int drive_identify(int disk_id, disk_t *d) 303 { 304 uint16_t data; 305 uint8_t status; 306 uint8_t drv_head; 307 size_t i; 308 309 drv_head = ((disk_id != 0) ? DHR_DRV : 0); 310 d->present = false; 311 312 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 313 return EIO; 314 315 pio_write_8(&cmd->drive_head, drv_head); 316 317 /* 318 * This is where we would most likely expect a non-existing device to 319 * show up by not setting SR_DRDY. 320 */ 321 if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 322 return EIO; 323 324 pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE); 325 326 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) 327 return EIO; 328 329 /* Read data from the disk buffer. */ 330 331 if ((status & SR_DRQ) != 0) { 332 // for (i = 0; i < block_size / 2; i++) { 333 // data = pio_read_16(&cmd->data_port); 334 // ((uint16_t *) buf)[i] = data; 335 // } 336 337 for (i = 0; i < block_size / 2; i++) { 338 data = pio_read_16(&cmd->data_port); 339 340 switch (i) { 341 case 1: d->cylinders = data; break; 342 case 3: d->heads = data; break; 343 case 6: d->sectors = data; break; 344 } 345 } 346 } 347 348 if ((status & SR_ERR) != 0) 349 return EIO; 350 351 d->blocks = d->cylinders * d->heads * d->sectors; 352 353 d->present = true; 354 fibril_mutex_initialize(&d->lock); 355 356 return EOK; 357 } 358 359 /** Read a physical from the device. 360 * 361 * @param disk_id Device index (0 or 1) 362 * @param blk_idx Index of the first block. 363 * @param blk_cnt Number of blocks to transfer. 364 * @param buf Buffer for holding the data. 365 * 366 * @return EOK on success, EIO on error. 367 */ 330 368 static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt, 331 369 void *buf) … … 361 399 /* Program a Read Sectors operation. */ 362 400 401 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 402 fibril_mutex_unlock(&d->lock); 403 return EIO; 404 } 405 363 406 pio_write_8(&cmd->drive_head, drv_head); 407 408 if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 409 fibril_mutex_unlock(&d->lock); 410 return EIO; 411 } 412 364 413 pio_write_8(&cmd->sector_count, 1); 365 414 pio_write_8(&cmd->sector_number, s); 366 415 pio_write_8(&cmd->cylinder_low, c & 0xff); 367 416 pio_write_8(&cmd->cylinder_high, c >> 16); 417 368 418 pio_write_8(&cmd->command, CMD_READ_SECTORS); 369 419 370 /* Read data from the disk buffer. */ 371 372 for (i = 0; i < block_size / 2; i++) { 373 do { 374 status = pio_read_8(&cmd->status); 375 } while ((status & SR_DRDY) == 0); 376 377 data = pio_read_16(&cmd->data_port); 378 ((uint16_t *) buf)[i] = data; 379 } 420 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 421 fibril_mutex_unlock(&d->lock); 422 return EIO; 423 } 424 425 if ((status & SR_DRQ) != 0) { 426 /* Read data from the device buffer. */ 427 428 for (i = 0; i < block_size / 2; i++) { 429 data = pio_read_16(&cmd->data_port); 430 ((uint16_t *) buf)[i] = data; 431 } 432 } 433 434 if ((status & SR_ERR) != 0) 435 return EIO; 380 436 381 437 fibril_mutex_unlock(&d->lock); … … 383 439 } 384 440 441 /** Write a physical block to the device. 442 * 443 * @param disk_id Device index (0 or 1) 444 * @param blk_idx Index of the first block. 445 * @param blk_cnt Number of blocks to transfer. 446 * @param buf Buffer holding the data to write. 447 * 448 * @return EOK on success, EIO on error. 449 */ 385 450 static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt, 386 451 const void *buf) … … 413 478 fibril_mutex_lock(&d->lock); 414 479 415 /* Program a Read Sectors operation. */ 480 /* Program a Write Sectors operation. */ 481 482 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 483 fibril_mutex_unlock(&d->lock); 484 return EIO; 485 } 416 486 417 487 pio_write_8(&cmd->drive_head, drv_head); 488 489 if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 490 fibril_mutex_unlock(&d->lock); 491 return EIO; 492 } 493 418 494 pio_write_8(&cmd->sector_count, 1); 419 495 pio_write_8(&cmd->sector_number, s); 420 496 pio_write_8(&cmd->cylinder_low, c & 0xff); 421 497 pio_write_8(&cmd->cylinder_high, c >> 16); 498 422 499 pio_write_8(&cmd->command, CMD_WRITE_SECTORS); 423 500 424 /* Write data to the disk buffer. */ 425 426 for (i = 0; i < block_size / 2; i++) { 427 do { 428 status = pio_read_8(&cmd->status); 429 } while ((status & SR_DRDY) == 0); 430 431 pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]); 501 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 502 fibril_mutex_unlock(&d->lock); 503 return EIO; 504 } 505 506 if ((status & SR_DRQ) != 0) { 507 /* Write data to the device buffer. */ 508 509 for (i = 0; i < block_size / 2; i++) { 510 pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]); 511 } 432 512 } 433 513 434 514 fibril_mutex_unlock(&d->lock); 515 516 if (status & SR_ERR) 517 return EIO; 518 435 519 return EOK; 436 520 } 437 521 522 /** Wait until some status bits are set and some are reset. 523 * 524 * Example: wait_status(SR_DRDY, ~SR_BSY) waits for SR_DRDY to become 525 * set and SR_BSY to become reset. 526 * 527 * @param set Combination if bits which must be all set. 528 * @param n_reset Negated combination of bits which must be all reset. 529 * @param pstatus Pointer where to store last read status or NULL. 530 * @param timeout Timeout in 10ms units. 531 * 532 * @return EOK on success, EIO on timeout. 533 */ 534 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus, 535 unsigned timeout) 536 { 537 uint8_t status; 538 int cnt; 539 540 status = pio_read_8(&cmd->status); 541 542 /* 543 * This is crude, yet simple. First try with 1us delays 544 * (most likely the device will respond very fast). If not, 545 * start trying every 10 ms. 546 */ 547 548 cnt = 100; 549 while ((status & ~n_reset) != 0 || (status & set) != set) { 550 async_usleep(1); 551 --cnt; 552 if (cnt <= 0) break; 553 554 status = pio_read_8(&cmd->status); 555 } 556 557 cnt = timeout; 558 while ((status & ~n_reset) != 0 || (status & set) != set) { 559 async_usleep(10000); 560 --cnt; 561 if (cnt <= 0) break; 562 563 status = pio_read_8(&cmd->status); 564 } 565 566 if (pstatus) 567 *pstatus = status; 568 569 if (cnt == 0) 570 return EIO; 571 572 return EOK; 573 } 438 574 439 575 /** -
uspace/srv/bd/ata_bd/ata_bd.h
rcb0ea39 r24f27bb 135 135 }; 136 136 137 /** Timeout definitions. Unit is 10 ms. */ 138 enum ata_timeout { 139 TIMEOUT_PROBE = 100, /* 1 s */ 140 TIMEOUT_BSY = 100, /* 1 s */ 141 TIMEOUT_DRDY = 1000 /* 10 s */ 142 }; 143 137 144 typedef struct { 138 145 bool present;
Note:
See TracChangeset
for help on using the changeset viewer.