diff options
Diffstat (limited to 'arch/sparc/kernel/entry.S')
-rw-r--r-- | arch/sparc/kernel/entry.S | 206 |
1 files changed, 11 insertions, 195 deletions
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index c2eed8f71516..135644f8add7 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
@@ -1186,36 +1186,6 @@ srmmu_fault: | |||
1186 | 1186 | ||
1187 | RESTORE_ALL | 1187 | RESTORE_ALL |
1188 | 1188 | ||
1189 | #ifdef CONFIG_SUNOS_EMUL | ||
1190 | /* SunOS uses syscall zero as the 'indirect syscall' it looks | ||
1191 | * like indir_syscall(scall_num, arg0, arg1, arg2...); etc. | ||
1192 | * This is complete brain damage. | ||
1193 | */ | ||
1194 | .globl sunos_indir | ||
1195 | sunos_indir: | ||
1196 | mov %o7, %l4 | ||
1197 | cmp %o0, NR_SYSCALLS | ||
1198 | blu,a 1f | ||
1199 | sll %o0, 0x2, %o0 | ||
1200 | |||
1201 | sethi %hi(sunos_nosys), %l6 | ||
1202 | b 2f | ||
1203 | or %l6, %lo(sunos_nosys), %l6 | ||
1204 | |||
1205 | 1: | ||
1206 | set sunos_sys_table, %l7 | ||
1207 | ld [%l7 + %o0], %l6 | ||
1208 | |||
1209 | 2: | ||
1210 | mov %o1, %o0 | ||
1211 | mov %o2, %o1 | ||
1212 | mov %o3, %o2 | ||
1213 | mov %o4, %o3 | ||
1214 | mov %o5, %o4 | ||
1215 | call %l6 | ||
1216 | mov %l4, %o7 | ||
1217 | #endif | ||
1218 | |||
1219 | .align 4 | 1189 | .align 4 |
1220 | .globl sys_nis_syscall | 1190 | .globl sys_nis_syscall |
1221 | sys_nis_syscall: | 1191 | sys_nis_syscall: |
@@ -1232,6 +1202,16 @@ sys_execve: | |||
1232 | call sparc_execve | 1202 | call sparc_execve |
1233 | mov %l5, %o7 | 1203 | mov %l5, %o7 |
1234 | 1204 | ||
1205 | .globl sunos_execv | ||
1206 | sunos_execv: | ||
1207 | st %g0, [%sp + STACKFRAME_SZ + PT_I2] | ||
1208 | |||
1209 | call sparc_execve | ||
1210 | add %sp, STACKFRAME_SZ, %o0 | ||
1211 | |||
1212 | b ret_sys_call | ||
1213 | ld [%sp + STACKFRAME_SZ + PT_I0], %o0 | ||
1214 | |||
1235 | .align 4 | 1215 | .align 4 |
1236 | .globl sys_pipe | 1216 | .globl sys_pipe |
1237 | sys_pipe: | 1217 | sys_pipe: |
@@ -1394,7 +1374,7 @@ ret_from_fork: | |||
1394 | b ret_sys_call | 1374 | b ret_sys_call |
1395 | ld [%sp + STACKFRAME_SZ + PT_I0], %o0 | 1375 | ld [%sp + STACKFRAME_SZ + PT_I0], %o0 |
1396 | 1376 | ||
1397 | /* Linux native and SunOS system calls enter here... */ | 1377 | /* Linux native system calls enter here... */ |
1398 | .align 4 | 1378 | .align 4 |
1399 | .globl linux_sparc_syscall | 1379 | .globl linux_sparc_syscall |
1400 | linux_sparc_syscall: | 1380 | linux_sparc_syscall: |
@@ -1472,170 +1452,6 @@ linux_syscall_trace2: | |||
1472 | st %l2, [%sp + STACKFRAME_SZ + PT_NPC] | 1452 | st %l2, [%sp + STACKFRAME_SZ + PT_NPC] |
1473 | 1453 | ||
1474 | 1454 | ||
1475 | /* | ||
1476 | * Solaris system calls and indirect system calls enter here. | ||
1477 | * | ||
1478 | * I have named the solaris indirect syscalls like that because | ||
1479 | * it seems like Solaris has some fast path syscalls that can | ||
1480 | * be handled as indirect system calls. - mig | ||
1481 | */ | ||
1482 | |||
1483 | linux_syscall_for_solaris: | ||
1484 | sethi %hi(sys_call_table), %l7 | ||
1485 | b linux_sparc_syscall | ||
1486 | or %l7, %lo(sys_call_table), %l7 | ||
1487 | |||
1488 | .align 4 | ||
1489 | .globl solaris_syscall | ||
1490 | solaris_syscall: | ||
1491 | cmp %g1,59 | ||
1492 | be linux_syscall_for_solaris | ||
1493 | cmp %g1,2 | ||
1494 | be linux_syscall_for_solaris | ||
1495 | cmp %g1,42 | ||
1496 | be linux_syscall_for_solaris | ||
1497 | cmp %g1,119 | ||
1498 | be,a linux_syscall_for_solaris | ||
1499 | mov 2, %g1 | ||
1500 | 1: | ||
1501 | SAVE_ALL_HEAD | ||
1502 | rd %wim, %l3 | ||
1503 | |||
1504 | wr %l0, PSR_ET, %psr | ||
1505 | nop | ||
1506 | nop | ||
1507 | mov %i0, %l5 | ||
1508 | |||
1509 | call do_solaris_syscall | ||
1510 | add %sp, STACKFRAME_SZ, %o0 | ||
1511 | |||
1512 | st %o0, [%sp + STACKFRAME_SZ + PT_I0] | ||
1513 | set PSR_C, %g2 | ||
1514 | cmp %o0, -ERESTART_RESTARTBLOCK | ||
1515 | bgeu 1f | ||
1516 | ld [%sp + STACKFRAME_SZ + PT_PSR], %g3 | ||
1517 | |||
1518 | /* System call success, clear Carry condition code. */ | ||
1519 | andn %g3, %g2, %g3 | ||
1520 | clr %l6 | ||
1521 | b 2f | ||
1522 | st %g3, [%sp + STACKFRAME_SZ + PT_PSR] | ||
1523 | |||
1524 | 1: | ||
1525 | /* System call failure, set Carry condition code. | ||
1526 | * Also, get abs(errno) to return to the process. | ||
1527 | */ | ||
1528 | sub %g0, %o0, %o0 | ||
1529 | mov 1, %l6 | ||
1530 | st %o0, [%sp + STACKFRAME_SZ + PT_I0] | ||
1531 | or %g3, %g2, %g3 | ||
1532 | st %g3, [%sp + STACKFRAME_SZ + PT_PSR] | ||
1533 | |||
1534 | /* Advance the pc and npc over the trap instruction. | ||
1535 | * If the npc is unaligned (has a 1 in the lower byte), it means | ||
1536 | * the kernel does not want us to play magic (ie, skipping over | ||
1537 | * traps). Mainly when the Solaris code wants to set some PC and | ||
1538 | * nPC (setcontext). | ||
1539 | */ | ||
1540 | 2: | ||
1541 | ld [%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */ | ||
1542 | andcc %l1, 1, %g0 | ||
1543 | bne 1f | ||
1544 | add %l1, 0x4, %l2 /* npc = npc+4 */ | ||
1545 | st %l1, [%sp + STACKFRAME_SZ + PT_PC] | ||
1546 | b ret_trap_entry | ||
1547 | st %l2, [%sp + STACKFRAME_SZ + PT_NPC] | ||
1548 | |||
1549 | /* kernel knows what it is doing, fixup npc and continue */ | ||
1550 | 1: | ||
1551 | sub %l1, 1, %l1 | ||
1552 | b ret_trap_entry | ||
1553 | st %l1, [%sp + STACKFRAME_SZ + PT_NPC] | ||
1554 | |||
1555 | #ifndef CONFIG_SUNOS_EMUL | ||
1556 | .align 4 | ||
1557 | .globl sunos_syscall | ||
1558 | sunos_syscall: | ||
1559 | SAVE_ALL_HEAD | ||
1560 | rd %wim, %l3 | ||
1561 | wr %l0, PSR_ET, %psr | ||
1562 | nop | ||
1563 | nop | ||
1564 | mov %i0, %l5 | ||
1565 | call do_sunos_syscall | ||
1566 | add %sp, STACKFRAME_SZ, %o0 | ||
1567 | #endif | ||
1568 | |||
1569 | /* {net, open}bsd system calls enter here... */ | ||
1570 | .align 4 | ||
1571 | .globl bsd_syscall | ||
1572 | bsd_syscall: | ||
1573 | /* Direct access to user regs, must faster. */ | ||
1574 | cmp %g1, NR_SYSCALLS | ||
1575 | blu,a 1f | ||
1576 | sll %g1, 2, %l4 | ||
1577 | |||
1578 | set sys_ni_syscall, %l7 | ||
1579 | b bsd_is_too_hard | ||
1580 | nop | ||
1581 | |||
1582 | 1: | ||
1583 | ld [%l7 + %l4], %l7 | ||
1584 | |||
1585 | .globl bsd_is_too_hard | ||
1586 | bsd_is_too_hard: | ||
1587 | rd %wim, %l3 | ||
1588 | SAVE_ALL | ||
1589 | |||
1590 | wr %l0, PSR_ET, %psr | ||
1591 | WRITE_PAUSE | ||
1592 | |||
1593 | 2: | ||
1594 | mov %i0, %o0 | ||
1595 | mov %i1, %o1 | ||
1596 | mov %i2, %o2 | ||
1597 | mov %i0, %l5 | ||
1598 | mov %i3, %o3 | ||
1599 | mov %i4, %o4 | ||
1600 | call %l7 | ||
1601 | mov %i5, %o5 | ||
1602 | |||
1603 | st %o0, [%sp + STACKFRAME_SZ + PT_I0] | ||
1604 | set PSR_C, %g2 | ||
1605 | cmp %o0, -ERESTART_RESTARTBLOCK | ||
1606 | bgeu 1f | ||
1607 | ld [%sp + STACKFRAME_SZ + PT_PSR], %g3 | ||
1608 | |||
1609 | /* System call success, clear Carry condition code. */ | ||
1610 | andn %g3, %g2, %g3 | ||
1611 | clr %l6 | ||
1612 | b 2f | ||
1613 | st %g3, [%sp + STACKFRAME_SZ + PT_PSR] | ||
1614 | |||
1615 | 1: | ||
1616 | /* System call failure, set Carry condition code. | ||
1617 | * Also, get abs(errno) to return to the process. | ||
1618 | */ | ||
1619 | sub %g0, %o0, %o0 | ||
1620 | #if 0 /* XXX todo XXX */ | ||
1621 | sethi %hi(bsd_xlatb_rorl), %o3 | ||
1622 | or %o3, %lo(bsd_xlatb_rorl), %o3 | ||
1623 | sll %o0, 2, %o0 | ||
1624 | ld [%o3 + %o0], %o0 | ||
1625 | #endif | ||
1626 | mov 1, %l6 | ||
1627 | st %o0, [%sp + STACKFRAME_SZ + PT_I0] | ||
1628 | or %g3, %g2, %g3 | ||
1629 | st %g3, [%sp + STACKFRAME_SZ + PT_PSR] | ||
1630 | |||
1631 | /* Advance the pc and npc over the trap instruction. */ | ||
1632 | 2: | ||
1633 | ld [%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */ | ||
1634 | add %l1, 0x4, %l2 /* npc = npc+4 */ | ||
1635 | st %l1, [%sp + STACKFRAME_SZ + PT_PC] | ||
1636 | b ret_trap_entry | ||
1637 | st %l2, [%sp + STACKFRAME_SZ + PT_NPC] | ||
1638 | |||
1639 | /* Saving and restoring the FPU state is best done from lowlevel code. | 1455 | /* Saving and restoring the FPU state is best done from lowlevel code. |
1640 | * | 1456 | * |
1641 | * void fpsave(unsigned long *fpregs, unsigned long *fsr, | 1457 | * void fpsave(unsigned long *fpregs, unsigned long *fsr, |