summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2015-07-21 19:34:47 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-07-21 19:34:47 +0200
commita2952398e5de8746a761a59686619d08d376bce3 (patch)
treedf2373bb1119468873c667624769455c36dc3786
parentba1b3afd50913473f3036a63b4a82d7ba5c42009 (diff)
parent92e98a7f4d4fa75b286a067e1d1caef514fccb0d (diff)
Merge branch 'master' into master-gdb_stubs
-rw-r--r--Makefile.am39
-rw-r--r--Makefrag.am59
-rw-r--r--Makerules.mig.am10
-rw-r--r--NEWS37
-rw-r--r--README52
-rw-r--r--chips/busses.c26
-rw-r--r--chips/busses.h8
-rw-r--r--configfrag.ac2
-rw-r--r--configure.ac5
-rw-r--r--ddb/db_access.c50
-rw-r--r--ddb/db_access.h6
-rw-r--r--ddb/db_aout.c118
-rw-r--r--ddb/db_aout.h52
-rw-r--r--ddb/db_break.c124
-rw-r--r--ddb/db_break.h22
-rw-r--r--ddb/db_command.c118
-rw-r--r--ddb/db_command.h15
-rw-r--r--ddb/db_cond.c22
-rw-r--r--ddb/db_cond.h2
-rw-r--r--ddb/db_elf.c232
-rw-r--r--ddb/db_elf.h52
-rw-r--r--ddb/db_examine.c71
-rw-r--r--ddb/db_examine.h42
-rw-r--r--ddb/db_expr.c36
-rw-r--r--ddb/db_expr.h2
-rw-r--r--ddb/db_ext_symtab.c13
-rw-r--r--ddb/db_input.c44
-rw-r--r--ddb/db_input.h2
-rw-r--r--ddb/db_lex.c31
-rw-r--r--ddb/db_lex.h9
-rw-r--r--ddb/db_macro.c40
-rw-r--r--ddb/db_macro.h4
-rw-r--r--ddb/db_mp.c37
-rw-r--r--ddb/db_mp.h30
-rw-r--r--ddb/db_output.c30
-rw-r--r--ddb/db_output.h10
-rw-r--r--ddb/db_print.c120
-rw-r--r--ddb/db_print.h75
-rw-r--r--ddb/db_run.c77
-rw-r--r--ddb/db_run.h48
-rw-r--r--ddb/db_sym.c137
-rw-r--r--ddb/db_sym.h42
-rw-r--r--ddb/db_task_thread.c88
-rw-r--r--ddb/db_task_thread.h24
-rw-r--r--ddb/db_trap.c23
-rw-r--r--ddb/db_variables.c46
-rw-r--r--ddb/db_variables.h9
-rw-r--r--ddb/db_watch.c56
-rw-r--r--ddb/db_watch.h20
-rw-r--r--ddb/db_write_cmd.c8
-rw-r--r--ddb/db_write_cmd.h34
-rw-r--r--ddb/stab.h4
-rw-r--r--device/blkio.c144
-rw-r--r--device/blkio.h24
-rw-r--r--device/buf.h10
-rw-r--r--device/chario.c108
-rw-r--r--device/chario.h37
-rw-r--r--device/cirbuf.c54
-rw-r--r--device/cirbuf.h3
-rw-r--r--device/conf.h48
-rw-r--r--device/cons.c30
-rw-r--r--device/cons.h14
-rw-r--r--device/dev_hdr.h10
-rw-r--r--device/dev_lookup.c63
-rw-r--r--device/dev_master.h7
-rw-r--r--device/dev_name.c98
-rw-r--r--device/dev_pager.c167
-rw-r--r--device/dev_pager.h28
-rw-r--r--device/device_init.c13
-rw-r--r--device/device_init.h24
-rw-r--r--device/device_types_kernel.h1
-rw-r--r--device/dk_label.c99
-rw-r--r--device/ds_routines.c280
-rw-r--r--device/ds_routines.h27
-rw-r--r--device/if_ether.h7
-rw-r--r--device/io_req.h2
-rw-r--r--device/kmsg.c17
-rw-r--r--device/kmsg.h2
-rw-r--r--device/net_io.c271
-rw-r--r--device/net_io.h70
-rw-r--r--device/subrs.c36
-rw-r--r--device/tty.h12
-rw-r--r--doc/gpl.texi9
-rw-r--r--doc/mach.texi266
-rwxr-xr-xgitlog-to-changelog432
-rw-r--r--i386/Makefrag.am27
-rw-r--r--i386/configfrag.ac4
-rw-r--r--i386/grub/acpi.h220
-rw-r--r--i386/grub/compiler.h51
-rw-r--r--i386/grub/cpu/io.h72
-rw-r--r--i386/grub/cpu/time.h29
-rw-r--r--i386/grub/cpu/types.h33
-rw-r--r--i386/grub/err.h96
-rw-r--r--i386/grub/glue.h33
-rw-r--r--i386/grub/i18n.h25
-rw-r--r--i386/grub/misc.h517
-rw-r--r--i386/grub/mm.h77
-rw-r--r--i386/grub/symbol.h72
-rw-r--r--i386/grub/time.h46
-rw-r--r--i386/grub/types.h325
-rw-r--r--i386/i386/ast_check.c14
-rw-r--r--i386/i386/db_disasm.c10
-rw-r--r--i386/i386/db_interface.c264
-rw-r--r--i386/i386/db_interface.h65
-rw-r--r--i386/i386/db_machdep.h2
-rw-r--r--i386/i386/db_trace.c83
-rw-r--r--i386/i386/db_trace.h32
-rw-r--r--i386/i386/debug.h2
-rw-r--r--i386/i386/debug_i386.c7
-rw-r--r--i386/i386/fpu.c82
-rw-r--r--i386/i386/fpu.h2
-rw-r--r--i386/i386/gdt.c2
-rw-r--r--i386/i386/hardclock.c10
-rw-r--r--i386/i386/hardclock.h29
-rw-r--r--i386/i386/idt.c2
-rw-r--r--i386/i386/io_map.c38
-rw-r--r--i386/i386/io_perm.c10
-rw-r--r--i386/i386/io_perm.h2
-rw-r--r--i386/i386/ipl.h4
-rw-r--r--i386/i386/ktss.c2
-rw-r--r--i386/i386/kttd_interface.c2
-rw-r--r--i386/i386/ldt.c5
-rw-r--r--i386/i386/lock.h2
-rw-r--r--i386/i386/locore.S216
-rw-r--r--i386/i386/locore.h2
-rw-r--r--i386/i386/loose_ends.c10
-rw-r--r--i386/i386/machine_routines.h3
-rw-r--r--i386/i386/machine_task.c2
-rw-r--r--i386/i386/model_dep.h8
-rw-r--r--i386/i386/mp_desc.c17
-rw-r--r--i386/i386/mp_desc.h2
-rw-r--r--i386/i386/pcb.c157
-rw-r--r--i386/i386/pcb.h14
-rw-r--r--i386/i386/phys.c109
-rw-r--r--i386/i386/pic.c11
-rw-r--r--i386/i386/pic.h2
-rw-r--r--i386/i386/pit.c4
-rw-r--r--i386/i386/proc_reg.h126
-rw-r--r--i386/i386/setjmp.h4
-rw-r--r--i386/i386/spl.S36
-rw-r--r--i386/i386/thread.h4
-rw-r--r--i386/i386/trap.c91
-rw-r--r--i386/i386/trap.h9
-rw-r--r--i386/i386/user_ldt.c72
-rw-r--r--i386/i386/user_ldt.h12
-rw-r--r--i386/i386/vm_tuning.h35
-rw-r--r--i386/i386/xen.h4
-rw-r--r--i386/i386at/acpi.c82
-rw-r--r--i386/i386at/acpihalt.c409
-rw-r--r--i386/i386at/acpihalt.h23
-rw-r--r--i386/i386at/autoconf.c14
-rw-r--r--i386/i386at/com.c107
-rw-r--r--i386/i386at/com.h33
-rw-r--r--i386/i386at/conf.c62
-rw-r--r--i386/i386at/cons_conf.c7
-rw-r--r--i386/i386at/cram.h4
-rw-r--r--i386/i386at/disk.h4
-rw-r--r--i386/i386at/grub_glue.c67
-rw-r--r--i386/i386at/i8250.h5
-rw-r--r--i386/i386at/idt.h2
-rw-r--r--i386/i386at/immc.c78
-rw-r--r--i386/i386at/immc.h31
-rw-r--r--i386/i386at/int_init.c2
-rw-r--r--i386/i386at/int_init.h2
-rw-r--r--i386/i386at/kd.c470
-rw-r--r--i386/i386at/kd.h65
-rw-r--r--i386/i386at/kd_event.c98
-rw-r--r--i386/i386at/kd_event.h29
-rw-r--r--i386/i386at/kd_mouse.c107
-rw-r--r--i386/i386at/kd_mouse.h13
-rw-r--r--i386/i386at/kd_queue.c10
-rw-r--r--i386/i386at/kd_queue.h9
-rw-r--r--i386/i386at/kdsoft.h5
-rw-r--r--i386/i386at/lpr.c49
-rw-r--r--i386/i386at/lpr.h (renamed from i386/i386at/lprreg.h)33
-rw-r--r--i386/i386at/mem.c2
-rw-r--r--i386/i386at/mem.h24
-rw-r--r--i386/i386at/model_dep.c190
-rw-r--r--i386/i386at/model_dep.h30
-rw-r--r--i386/i386at/pic_isa.c2
-rw-r--r--i386/i386at/rtc.c33
-rw-r--r--i386/i386at/rtc.h9
-rw-r--r--i386/include/mach/i386/asm.h4
-rw-r--r--i386/include/mach/i386/cthreads.h2
-rw-r--r--i386/include/mach/i386/disk.h4
-rw-r--r--i386/include/mach/i386/mach_i386_types.h4
-rw-r--r--i386/include/mach/i386/multiboot.h10
-rw-r--r--i386/include/mach/i386/rpc.h9
-rw-r--r--i386/include/mach/i386/thread_status.h7
-rw-r--r--i386/include/mach/i386/vm_param.h2
-rw-r--r--i386/intel/pmap.c359
-rw-r--r--i386/intel/pmap.h32
-rw-r--r--i386/intel/read_fault.c10
-rw-r--r--include/cache.h25
-rw-r--r--include/device/device.defs19
-rw-r--r--include/device/device_reply.defs8
-rw-r--r--include/device/device_request.defs8
-rw-r--r--include/device/device_types.defs17
-rw-r--r--include/device/device_types.h2
-rw-r--r--include/device/tape_status.h2
-rw-r--r--include/device/tty_status.h5
-rw-r--r--include/mach/alert.h2
-rw-r--r--include/mach/boot.h4
-rw-r--r--include/mach/default_pager_types.defs2
-rw-r--r--include/mach/default_pager_types.h2
-rw-r--r--include/mach/gnumach.defs47
-rw-r--r--include/mach/mach.defs4
-rw-r--r--include/mach/mach_host.defs6
-rw-r--r--include/mach/mach_port.defs32
-rw-r--r--include/mach/mach_types.defs15
-rw-r--r--include/mach/memory_object.defs53
-rw-r--r--include/mach/memory_object_default.defs4
-rw-r--r--include/mach/message.h9
-rw-r--r--include/mach/multiboot.h2
-rw-r--r--include/mach/notify.defs35
-rw-r--r--include/mach/port.h2
-rw-r--r--include/mach/profil.h2
-rw-r--r--include/mach/rpc.h1
-rw-r--r--include/mach/std_types.defs8
-rw-r--r--include/mach/task_notify.defs36
-rw-r--r--include/mach/version.h5
-rw-r--r--include/mach/vm_param.h2
-rw-r--r--include/mach_debug/ipc_info.h23
-rw-r--r--include/mach_debug/mach_debug.defs33
-rw-r--r--include/mach_debug/mach_debug_types.defs9
-rw-r--r--include/mach_debug/mach_debug_types.h11
-rw-r--r--include/mach_debug/pc_info.h2
-rw-r--r--include/string.h8
-rw-r--r--ipc/ipc_entry.c795
-rw-r--r--ipc/ipc_entry.h72
-rw-r--r--ipc/ipc_hash.c620
-rw-r--r--ipc/ipc_hash.h96
-rw-r--r--ipc/ipc_init.c10
-rw-r--r--ipc/ipc_kmsg.c345
-rw-r--r--ipc/ipc_kmsg.h29
-rw-r--r--ipc/ipc_kmsg_queue.h2
-rwxr-xr-xipc/ipc_machdep.h4
-rw-r--r--ipc/ipc_marequest.c34
-rw-r--r--ipc/ipc_mqueue.c14
-rw-r--r--ipc/ipc_mqueue.h3
-rw-r--r--ipc/ipc_notify.c42
-rw-r--r--ipc/ipc_object.c58
-rw-r--r--ipc/ipc_object.h6
-rw-r--r--ipc/ipc_port.c88
-rw-r--r--ipc/ipc_port.h30
-rw-r--r--ipc/ipc_print.h39
-rw-r--r--ipc/ipc_pset.c5
-rw-r--r--ipc/ipc_pset.h3
-rw-r--r--ipc/ipc_right.c91
-rw-r--r--ipc/ipc_space.c104
-rw-r--r--ipc/ipc_space.h228
-rw-r--r--ipc/ipc_splay.c920
-rw-r--r--ipc/ipc_splay.h114
-rw-r--r--ipc/ipc_table.c70
-rw-r--r--ipc/ipc_table.h59
-rw-r--r--ipc/ipc_thread.h8
-rw-r--r--ipc/mach_debug.c339
-rw-r--r--ipc/mach_msg.c299
-rw-r--r--ipc/mach_port.c263
-rw-r--r--ipc/mach_port.h11
-rw-r--r--ipc/mach_rpc.c9
-rw-r--r--ipc/notify.defs22
-rw-r--r--ipc/port.h7
-rw-r--r--kern/act.c34
-rw-r--r--kern/act.h5
-rw-r--r--kern/assert.h17
-rw-r--r--kern/ast.c22
-rw-r--r--kern/ast.h2
-rw-r--r--kern/boot_script.c6
-rw-r--r--kern/boot_script.h4
-rw-r--r--kern/bootstrap.c52
-rw-r--r--kern/bootstrap.h24
-rw-r--r--kern/counters.c6
-rw-r--r--kern/counters.h6
-rw-r--r--kern/debug.c21
-rw-r--r--kern/debug.h4
-rw-r--r--kern/elf-load.c2
-rw-r--r--kern/eventcount.c21
-rw-r--r--kern/eventcount.h7
-rw-r--r--kern/exception.c114
-rw-r--r--kern/exception.h66
-rw-r--r--kern/host.c26
-rw-r--r--kern/ipc_host.c2
-rw-r--r--kern/ipc_kobject.c30
-rw-r--r--kern/ipc_kobject.h5
-rw-r--r--kern/ipc_mig.c236
-rw-r--r--kern/ipc_mig.h79
-rw-r--r--kern/ipc_sched.c12
-rw-r--r--kern/ipc_tt.c68
-rw-r--r--kern/list.h6
-rw-r--r--kern/lock.c36
-rw-r--r--kern/lock.h8
-rw-r--r--kern/lock_mon.c51
-rw-r--r--kern/mach_clock.c79
-rw-r--r--kern/mach_clock.h9
-rw-r--r--kern/mach_factor.c16
-rw-r--r--kern/machine.c102
-rw-r--r--kern/machine.h2
-rw-r--r--kern/macro_help.h55
-rw-r--r--kern/macros.h72
-rw-r--r--kern/pc_sample.c42
-rw-r--r--kern/pc_sample.h2
-rw-r--r--kern/printf.c112
-rw-r--r--kern/printf.h16
-rw-r--r--kern/priority.c18
-rw-r--r--kern/priority.h28
-rw-r--r--kern/processor.c49
-rw-r--r--kern/processor.h6
-rw-r--r--kern/profile.c2
-rw-r--r--kern/queue.c24
-rw-r--r--kern/queue.h41
-rw-r--r--kern/rbtree.h10
-rw-r--r--kern/rdxtree.c830
-rw-r--r--kern/rdxtree.h209
-rw-r--r--kern/rdxtree_i.h66
-rw-r--r--kern/refcount.h8
-rw-r--r--kern/sched.h8
-rw-r--r--kern/sched_prim.c236
-rw-r--r--kern/sched_prim.h29
-rw-r--r--kern/server_loop.ch104
-rw-r--r--kern/shuttle.h2
-rw-r--r--kern/slab.c143
-rw-r--r--kern/slab.h32
-rw-r--r--kern/startup.c53
-rw-r--r--kern/startup.h28
-rw-r--r--kern/strings.c40
-rw-r--r--kern/syscall_emulation.c54
-rw-r--r--kern/syscall_emulation.h6
-rw-r--r--kern/syscall_subr.c58
-rw-r--r--kern/syscall_subr.h1
-rw-r--r--kern/syscall_sw.c29
-rw-r--r--kern/task.c181
-rw-r--r--kern/task.h22
-rw-r--r--kern/task_notify.cli7
-rw-r--r--kern/thread.c181
-rw-r--r--kern/thread.h43
-rw-r--r--kern/thread_swap.c27
-rw-r--r--kern/thread_swap.h5
-rw-r--r--kern/time_stamp.c24
-rw-r--r--kern/timer.c89
-rw-r--r--kern/timer.h6
-rw-r--r--kern/xpr.c29
-rw-r--r--kern/xpr.h2
-rw-r--r--linux/Makefrag.am13
-rw-r--r--linux/dev/arch/i386/kernel/irq.c2
-rw-r--r--linux/dev/drivers/block/ahci.c1009
-rw-r--r--linux/dev/drivers/block/floppy.c2
-rw-r--r--linux/dev/drivers/block/genhd.c26
-rw-r--r--linux/dev/glue/block.c20
-rw-r--r--linux/dev/glue/kmem.c6
-rw-r--r--linux/dev/include/ahci.h268
-rw-r--r--linux/dev/include/asm-i386/string.h36
-rw-r--r--linux/dev/include/linux/blk.h5
-rw-r--r--linux/dev/include/linux/blkdev.h1
-rw-r--r--linux/dev/include/linux/fs.h4
-rw-r--r--linux/dev/include/linux/mm.h1
-rw-r--r--linux/dev/include/linux/types.h9
-rw-r--r--linux/pcmcia-cs/clients/axnet_cs.c2
-rw-r--r--linux/src/drivers/block/ide-cd.c51
-rw-r--r--linux/src/drivers/block/ide.c26
-rw-r--r--linux/src/drivers/block/ide.h1
-rw-r--r--linux/src/drivers/net/3c507.c4
-rw-r--r--linux/src/drivers/net/3c509.c2
-rw-r--r--linux/src/drivers/net/3c515.c4
-rw-r--r--linux/src/drivers/net/ac3200.c2
-rw-r--r--linux/src/drivers/net/apricot.c2
-rw-r--r--linux/src/drivers/net/at1700.c2
-rw-r--r--linux/src/drivers/net/de4x5.c2
-rw-r--r--linux/src/drivers/net/de600.c2
-rw-r--r--linux/src/drivers/net/de620.c2
-rw-r--r--linux/src/drivers/net/depca.c2
-rw-r--r--linux/src/drivers/net/e2100.c2
-rw-r--r--linux/src/drivers/net/eepro.c2
-rw-r--r--linux/src/drivers/net/eepro100.c2
-rw-r--r--linux/src/drivers/net/eexpress.c2
-rw-r--r--linux/src/drivers/net/ewrk3.c2
-rw-r--r--linux/src/drivers/net/fmv18x.c2
-rw-r--r--linux/src/drivers/net/hp-plus.c2
-rw-r--r--linux/src/drivers/net/hp.c2
-rw-r--r--linux/src/drivers/net/lance.c2
-rw-r--r--linux/src/drivers/net/ne.c2
-rw-r--r--linux/src/drivers/net/pci-scan.c2
-rw-r--r--linux/src/drivers/net/pcnet32.c2
-rw-r--r--linux/src/drivers/net/seeq8005.c2
-rw-r--r--linux/src/drivers/net/smc-ultra.c2
-rw-r--r--linux/src/drivers/net/smc-ultra32.c2
-rw-r--r--linux/src/drivers/net/sundance.c2
-rw-r--r--linux/src/drivers/net/tlan.c4
-rw-r--r--linux/src/drivers/net/wd.c2
-rw-r--r--linux/src/drivers/scsi/AM53C974.c2
-rw-r--r--linux/src/drivers/scsi/FlashPoint.c14
-rw-r--r--linux/src/drivers/scsi/NCR5380.c4
-rw-r--r--linux/src/drivers/scsi/t128.c4
-rw-r--r--linux/src/include/asm-i386/bitops.h28
-rw-r--r--linux/src/include/asm-i386/io.h12
-rw-r--r--linux/src/include/asm-i386/segment.h8
-rw-r--r--linux/src/include/asm-i386/semaphore.h30
-rw-r--r--linux/src/include/linux/compiler-gcc5.h67
-rw-r--r--linux/src/include/linux/hdreg.h9
-rw-r--r--linux/src/include/linux/pci.h2
-rw-r--r--linux/src/include/linux/string.h8
-rw-r--r--util/atoi.c8
-rw-r--r--util/atoi.h2
-rw-r--r--version.m42
-rw-r--r--vm/memory_object.c161
-rw-r--r--vm/memory_object_proxy.c8
-rw-r--r--vm/memory_object_proxy.h15
-rw-r--r--vm/pmap.h24
-rw-r--r--vm/vm_debug.c35
-rw-r--r--vm/vm_external.c18
-rw-r--r--vm/vm_fault.c152
-rw-r--r--vm/vm_fault.h6
-rw-r--r--vm/vm_init.c4
-rw-r--r--vm/vm_init.h25
-rw-r--r--vm/vm_kern.c319
-rw-r--r--vm/vm_kern.h16
-rw-r--r--vm/vm_map.c502
-rw-r--r--vm/vm_map.h37
-rw-r--r--vm/vm_object.c140
-rw-r--r--vm/vm_object.h14
-rw-r--r--vm/vm_page.h24
-rw-r--r--vm/vm_pageout.c65
-rw-r--r--vm/vm_pageout.h6
-rw-r--r--vm/vm_print.h40
-rw-r--r--vm/vm_resident.c101
-rw-r--r--vm/vm_resident.h6
-rw-r--r--vm/vm_user.c150
-rw-r--r--xen/block.c15
-rw-r--r--xen/console.c2
-rw-r--r--xen/console.h10
-rw-r--r--xen/grant.c2
-rw-r--r--xen/net.c9
-rw-r--r--xen/time.c7
433 files changed, 13902 insertions, 9725 deletions
diff --git a/Makefile.am b/Makefile.am
index 319b7e80..76a192ba 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
# Makefile for GNU Mach.
-# Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2006, 2007, 2008, 2009, 2013 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
@@ -59,9 +59,9 @@ AM_CFLAGS += \
AM_CFLAGS += \
-Wall
-# See <http://lists.gnu.org/archive/html/bug-hurd/2006-01/msg00148.html>.
+# We need the GNU-style inline
AM_CFLAGS += \
- -fno-strict-aliasing
+ -fgnu89-inline
# The smashing stack protector might be enabled by default, but might emit
# unsuitable code.
@@ -104,8 +104,8 @@ CPP = @CPP@ -x c
# Other Tools' Configuration.
#
-# Don't needlessly overwrite files that whose contents haven't changed. This
-# helps for avoinding unneccessary recompilation cycles when keeping
+# Don't needlessly overwrite files whose contents haven't changed.
+# This helps avoiding unnecessary recompilation cycles when keeping
# cross-compilation toolchains up-to-date. Thus, unconditionally use the
# `install-sh' that is supplied by GNU Automake 1.10.1, as the GNU Coreutils
# one doesn't provide this functionality yet (TODO: change that). TODO:
@@ -159,8 +159,9 @@ noinst_PROGRAMS += \
clib_routines := memcmp memcpy memmove \
strchr strstr strsep strtok \
htonl htons ntohl ntohs \
- udivdi3 __udivdi3 \
+ udivdi3 __udivdi3 __umoddi3 \
__rel_iplt_start __rel_iplt_end \
+ __ffsdi2 \
_START _start etext _edata end _end # actually ld magic, not libc.
gnumach-undef: gnumach.$(OBJEXT)
$(NM_V) $(NM) -u $< | sed 's/ *U *//' | sort -u > $@
@@ -173,6 +174,9 @@ clib-routines.o: gnumach-undef gnumach-undef-bad
then cat gnumach-undef-bad; exit 2; else true; fi
$(AM_V_CCLD) $(CCLD) -nostdlib -nostartfiles -r -static \
-o $@ `sed 's/^/-Wl,-u,/' < $<` -x c /dev/null -lc -lgcc
+ @if nm $@ | grep __init_cpu_features; \
+ then echo "Please install a 32bit libc without multiarch support (on Debian systems, the libc6-dev:i386 package containing /usr/lib/i386-linux-gnu/libc.a)". ; \
+ false ; fi
gnumach_LINK = $(LD) $(LINKFLAGS) $(gnumach_LINKFLAGS) -o $@
gnumach_LDADD = gnumach.o clib-routines.o
@@ -196,7 +200,10 @@ EXTRA_DIST += \
EXTRA_DIST += \
DEVELOPMENT
-dist-hook:
+dist-hook: dist-rm-CVS gen-ChangeLog
+
+.PHONY: dist-rm-CVS
+dist-rm-CVS:
# Try to be very safe with respect to spuriously removing various directories
# in case of an error.
find $(distdir)/ -type d -name CVS | while read d; do \
@@ -204,6 +211,24 @@ dist-hook:
rmdir "$$d"; \
done
+gen_start_commit = e227045b06d62ee7d2fbab9d5ade9030ff43170b
+ChangeLog_files = ChangeLog ChangeLog.0 ChangeLog.00
+.PHONY: gen-ChangeLog
+gen-ChangeLog:
+ $(AM_V_GEN)if test -d $(top_srcdir)/.git; then \
+ (cd $(top_srcdir)/ && \
+ ./gitlog-to-changelog --strip-tab \
+ $(gen_start_commit).. && \
+ echo) >> $(distdir)/cl-t && \
+ for f in $(ChangeLog_files); do \
+ (cd $(top_srcdir)/ && \
+ git show $(gen_start_commit):$$f) >> $(distdir)/cl-t && \
+ rm -f $(distdir)/$$f && \
+ mv $(distdir)/cl-t $(distdir)/$$f \
+ || exit $$?; \
+ done; \
+ fi
+
DISTCLEANFILES += \
Makefile.orig \
config.status.orig
diff --git a/Makefrag.am b/Makefrag.am
index 42026f33..5393513f 100644
--- a/Makefrag.am
+++ b/Makefrag.am
@@ -24,6 +24,9 @@ libkernel_a_SOURCES += \
ddb/db_access.c \
ddb/db_access.h \
ddb/db_aout.c \
+ ddb/db_aout.h \
+ ddb/db_elf.c \
+ ddb/db_elf.h \
ddb/db_break.c \
ddb/db_break.h \
ddb/db_command.c \
@@ -42,6 +45,7 @@ libkernel_a_SOURCES += \
ddb/db_macro.c \
ddb/db_macro.h \
ddb/db_mp.c \
+ ddb/db_mp.h \
ddb/db_output.c \
ddb/db_output.h \
ddb/db_print.c \
@@ -59,12 +63,13 @@ libkernel_a_SOURCES += \
ddb/db_watch.c \
ddb/db_watch.h \
ddb/db_write_cmd.c \
+ ddb/db_write_cmd.h \
ddb/nlist.h \
ddb/stab.h \
ddb/tr.h
# We need frame pointers for trace to work properly.
-AM_CFLAGS += -fno-omit-frame-pointer
+AM_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
endif
#
@@ -83,8 +88,6 @@ endif
libkernel_a_SOURCES += \
ipc/ipc_entry.c \
ipc/ipc_entry.h \
- ipc/ipc_hash.c \
- ipc/ipc_hash.h \
ipc/ipc_init.c \
ipc/ipc_init.h \
ipc/ipc_kmsg.c \
@@ -101,14 +104,13 @@ libkernel_a_SOURCES += \
ipc/ipc_object.h \
ipc/ipc_port.c \
ipc/ipc_port.h \
+ ipc/ipc_print.h \
ipc/ipc_pset.c \
ipc/ipc_pset.h \
ipc/ipc_right.c \
ipc/ipc_right.h \
ipc/ipc_space.c \
ipc/ipc_space.h \
- ipc/ipc_splay.c \
- ipc/ipc_splay.h \
ipc/ipc_table.c \
ipc/ipc_table.h \
ipc/ipc_target.c \
@@ -124,7 +126,8 @@ libkernel_a_SOURCES += \
ipc/mach_debug.c \
ipc/port.h
EXTRA_DIST += \
- ipc/mach_port.srv
+ ipc/mach_port.srv \
+ ipc/notify.defs
#
@@ -139,6 +142,7 @@ libkernel_a_SOURCES += \
kern/ast.h \
kern/boot_script.h \
kern/bootstrap.c \
+ kern/bootstrap.h \
kern/counters.c \
kern/counters.h \
kern/cpu_number.h \
@@ -147,6 +151,7 @@ libkernel_a_SOURCES += \
kern/eventcount.c \
kern/eventcount.h \
kern/exception.c \
+ kern/exception.h \
kern/host.c \
kern/host.h \
kern/ipc_host.c \
@@ -171,12 +176,13 @@ libkernel_a_SOURCES += \
kern/mach_factor.h \
kern/machine.c \
kern/machine.h \
- kern/macro_help.h \
+ kern/macros.h \
kern/pc_sample.c \
kern/pc_sample.h \
kern/printf.c \
kern/printf.h \
kern/priority.c \
+ kern/priority.h \
kern/processor.c \
kern/processor.h \
kern/profile.c \
@@ -185,6 +191,9 @@ libkernel_a_SOURCES += \
kern/rbtree.c \
kern/rbtree.h \
kern/rbtree_i.h \
+ kern/rdxtree.c \
+ kern/rdxtree.h \
+ kern/rdxtree_i.h \
kern/refcount.h \
kern/slab.c \
kern/slab.h \
@@ -193,6 +202,7 @@ libkernel_a_SOURCES += \
kern/sched_prim.h \
kern/shuttle.h \
kern/startup.c \
+ kern/startup.h \
kern/strings.c \
kern/syscall_emulation.c \
kern/syscall_emulation.h \
@@ -219,7 +229,8 @@ EXTRA_DIST += \
kern/mach4.srv \
kern/gnumach.srv \
kern/mach_debug.srv \
- kern/mach_host.srv
+ kern/mach_host.srv \
+ kern/task_notify.cli
#
@@ -249,6 +260,7 @@ libkernel_a_SOURCES += \
vm/vm_fault.c \
vm/vm_fault.h \
vm/vm_init.c \
+ vm/vm_init.h \
vm/vm_kern.c \
vm/vm_kern.h \
vm/vm_map.c \
@@ -258,6 +270,7 @@ libkernel_a_SOURCES += \
vm/vm_page.h \
vm/vm_pageout.c \
vm/vm_pageout.h \
+ vm/vm_print.h \
vm/vm_resident.c \
vm/vm_resident.h \
vm/vm_types.h \
@@ -277,8 +290,10 @@ EXTRA_DIST += \
# TODO. Functions in device/subrs.c should each be moved elsewhere.
libkernel_a_SOURCES += \
device/blkio.c \
+ device/blkio.h \
device/buf.h \
device/chario.c \
+ device/chario.h \
device/cirbuf.h \
device/conf.h \
device/cons.c \
@@ -289,7 +304,9 @@ libkernel_a_SOURCES += \
device/dev_master.h \
device/dev_name.c \
device/dev_pager.c \
+ device/dev_pager.h \
device/device_init.c \
+ device/device_init.h \
device/device_port.h \
device/device_types_kernel.h \
device/ds_routines.c \
@@ -355,6 +372,7 @@ include_mach_HEADERS = \
include/mach/mach.defs \
include/mach/mach4.defs \
include/mach/gnumach.defs \
+ include/mach/task_notify.defs \
include/mach/mach_host.defs \
include/mach/mach_port.defs \
include/mach/mach_types.defs \
@@ -412,9 +430,18 @@ include_mach_eXec_HEADERS = \
include/mach/exec/elf.h \
include/mach/exec/exec.h
-# mach-debug-headers:= $(addprefix mach_debug/, hash_info.h ipc_info.h \
-# mach_debug.defs mach_debug_types.defs mach_debug_types.h \
-# pc_info.h vm_info.h slab_info.h)
+include_mach_debugdir = $(includedir)/mach_debug
+include_mach_debug_HEADERS = \
+ $(addprefix include/mach_debug/, \
+ hash_info.h \
+ ipc_info.h \
+ mach_debug.defs \
+ mach_debug_types.defs \
+ mach_debug_types.h \
+ pc_info.h \
+ vm_info.h \
+ slab_info.h \
+ )
# Other headers for the distribution. We don't install these, because the
# GNU C library has correct versions for users to use.
@@ -470,6 +497,13 @@ nodist_libkernel_a_SOURCES += \
# device/device_reply.user.defs
# device/memory_object_reply.user.defs
+nodist_lib_dep_tr_for_defs_a_SOURCES += \
+ kern/task_notify.user.defs.c
+nodist_libkernel_a_SOURCES += \
+ kern/task_notify.user.h \
+ kern/task_notify.user.c \
+ kern/task_notify.user.msgids
+
# Server stubs.
nodist_lib_dep_tr_for_defs_a_SOURCES += \
device/device.server.defs.c \
@@ -521,7 +555,8 @@ nodist_libkernel_a_SOURCES += \
# rpctrace can make use of that.
MOSTLYCLEANFILES += \
gnumach.msgids
-gnumach.msgids: $(filter %.msgids,$(nodist_libkernel_a_SOURCES))
+gnumach.msgids: $(filter %.msgids,$(nodist_libkernel_a_SOURCES)) \
+ ipc/notify.msgids
$(AM_V_at) cat $^ > $@.new
$(AM_V_GEN) mv $@.new $@
# `exec_' prefix, so that we don't try to build that file during when running
diff --git a/Makerules.mig.am b/Makerules.mig.am
index 30609846..085b247a 100644
--- a/Makerules.mig.am
+++ b/Makerules.mig.am
@@ -88,6 +88,16 @@ lib_dep_tr_for_defs_a_CPPFLAGS = $(AM_CPPFLAGS) \
-list $*.user.msgids \
< $<
+vpath %.defs $(top_srcdir)
+
+# Stand-alone rule to generate the list of message ids when neither
+# the client nor the server stubs are required.
+%.msgids: %.defs
+ $(MIGCOM_V) $(CPP) $(AM_CPPFLAGS) $(CPPFLAGS) -E $< \
+ | $(MIGCOM) $(MIGCOMFLAGS) $(MIGCOMSFLAGS) \
+ -sheader /dev/null -server /dev/null \
+ -list "$*.msgids"
+
# This is how it should be done, but this is not integrated into GNU Automake
# and is missing automatic inter-file dependency management because of that.
diff --git a/NEWS b/NEWS
index 98eae891..5d220fab 100644
--- a/NEWS
+++ b/NEWS
@@ -1,17 +1,32 @@
--*- Text -*-
+Version 1.5 (2015-04-10)
-Changes between version 1.3 and unreleased
+Numerous cleanups and stylistic fixes of the code base. Several
+problems have been identified using static analysis tools and
+subsequently been fixed.
-The calculation of the number of blocks for the floppy drives has been
-fixed.
+A protected payload can now be associated with capabilities. This
+payload is attached by the kernel to delivered messages and can be
+used to speed up the object lookup in the receiving task.
-The check for BSD labels in impossible situations has been removed.
-This removes a spurious warning at boot time for extended partitions.
+The kernel debugger can now parse ELF symbol tables, can be invoked
+over serial lines, gained two new commands and has received usability
+improvements.
-The keyboard LEDs can be set.
+The vm pageout policy has been tuned to accommodate modern hardware.
+The kernel gained partial ACPI support on x86, enough to power down
+the system.
-Changes between version 1.2 and version 1.3
+Version 1.4 (2013-09-27)
+
+Really too many to list them individually. Highlight include numerous bug and
+stability fixes, a Xen port for 32-bit x86 including basic support for Physical
+Address Extension (PAE), an initial AHCI driver (SATA hard disks), a new SLAB
+memory allocator to replace the previous zone allocator, support for memory
+object proxies, access restrictions for x86 I/O ports, support for some PCMCIA
+devices based on the pcmcia-cs package.
+
+Version 1.3
The kernel now directly supports "boot scripts" in the form of multiboot
module names with the same syntax as the Hurd's `serverboot' program.
@@ -31,9 +46,8 @@ it perform better on today's machines.
The console supports ANSI escape sequences for colors and attributes.
Support for the terminal speeds B57600 and B115200 has been added.
-
-Changes between version 1.1 and version 1.2
+Version 1.2
Many bug fixes.
@@ -57,9 +71,8 @@ former will install only the kernel, and the latter will install only
the header files.
Print out Mach device names instead of Linux ones.
-
-Changes between versions 1.0 and 1.1:
+Version 1.1
Cross-compilation support is much improved. Any of various popular
libc's is now sufficient for building clib-routines.o.
diff --git a/README b/README
index dcedb7ee..6c0ea5b3 100644
--- a/README
+++ b/README
@@ -1,41 +1,47 @@
--*- Text -*-
-This is the GNU Mach 1.2 distribution.
+This is GNU Mach, the GNU distribution of the Mach microkernel,
+<http://www.gnu.org/software/hurd/microkernel/mach/gnumach.html>. Welcome.
-This kernel is derived from the Utah kernel source. We use it to run
-the Hurd on. It is being distributed by us so that we can more easily
-modify the source, and so that it will work with the normal GNU coding
-standards and Makefile conventions.
+GNU Mach is the microkernel upon which a GNU Hurd system is based. It
+provides an Inter Process Communication (IPC) mechanism that the Hurd
+uses to define interfaces for implementing in a distributed multi-server
+fashion the services a traditional operating system kernel provides.
+
+GNU Mach runs on 32-bit x86 machines. A version running on 64-bit x86
+(x86_64) machines is in progress. Volunteers interested in ports to
+other architectures are sought; please contact us (see below) if you'd
+like to help.
libmach, bootloaders, default pagers, and the like are not part of
-this distribution. For libraries, we refer you to the GNU C library,
+this distribution. For libraries, we refer you to the GNU C Library,
which has Mach support. For bootloaders, we refer you to GRUB. (This
kernel can be loaded by any bootloader that uses the multiboot
standard.) For default pagers, we refer you to your particular system
that you will run on top of Mach.
-The interface generator `MiG' is no longer part of this distribution.
+The Mach Interface Generator (MIG) is no longer part of this distribution, and
+instead is packaged separately: GNU MIG.
Generic installation instructions may be found in the file INSTALL.
-By default, you get a kernel with no device drivers for disks and
-network devices. This is not what you want! Examine the file
-`README-Drivers' in the directory for the machine type your kernel is
-on (e.g., `i386/README-Drivers') for a list of configure --enable
-switches. Give the appropriate set for your hardware. It is
-generally safe to specify switches for hardware you don't have; in
-this way you can build kernels that work on different physical machine
-set ups.
+By default, most drivers for network boards are included, as well as
+drivers for IDE, SCSI and AHCI disks.
If you want the in-kernel debugger compiled in, specify --enable-kdb
to configure. This is only useful if you actually anticipate
-debugging the kernel, of course. We don't turn it on be default
+debugging the kernel, of course. We don't turn it on by default
because it adds considerably to the unpageable memory footprint of the
kernel.
-The specific switches you give to configure are always recorded in the
-file `config.status'. So you can always tell what options you used to
-build a particular kernel.
+GNU Mach can be cross-built. No specific options need to be given when
+building on a 32-bit x86 ELF userland such as GNU/Linux. Manually switch the
+compiler to 32-bit mode when using a 64-bit x86 (x86_64) ELF toolchain:
+
+ $ [...]/configure --host=i686-gnu CC='gcc -m32' LD='ld -melf_i386'
+
-Bug reports relating to this distribution should be sent to
-bug-hurd@gnu.org. Requests for assistance should be made on
-help-hurd@gnu.org.
+Please read the FAQ at <http://www.gnu.org/software/hurd/faq.html>.
+Bug reports should be sent to <bug-hurd@gnu.org> or filed on
+<http://savannah.gnu.org/bugs/?group=hurd>. Requests for assistance
+should be sent to <help-hurd@gnu.org> or filed on
+<http://savannah.gnu.org/support/?group=hurd>. You can also find us on
+the Freenode IRC network in the #hurd channel.
diff --git a/chips/busses.c b/chips/busses.c
index 89afa973..3811d0c6 100644
--- a/chips/busses.c
+++ b/chips/busses.c
@@ -59,17 +59,17 @@
*
*/
boolean_t configure_bus_master(
- char *name,
+ const char *name,
vm_offset_t virt,
vm_offset_t phys,
int adpt_no,
- char *bus_name)
+ const char *bus_name)
{
- register struct bus_device *device;
- register struct bus_ctlr *master;
- register struct bus_driver *driver;
+ struct bus_device *device;
+ struct bus_ctlr *master;
+ struct bus_driver *driver;
- int found = 0;
+ boolean_t found = FALSE;
/*
* Match the name in the table, then pick the entry that has the
@@ -81,7 +81,7 @@ boolean_t configure_bus_master(
continue;
if (((master->adaptor == adpt_no) || (master->adaptor == '?')) &&
(strcmp(master->name, name) == 0)) {
- found = 1;
+ found = TRUE;
break;
}
}
@@ -171,16 +171,16 @@ boolean_t configure_bus_master(
*
*/
boolean_t configure_bus_device(
- char *name,
+ const char *name,
vm_offset_t virt,
vm_offset_t phys,
int adpt_no,
- char *bus_name)
+ const char *bus_name)
{
- register struct bus_device *device;
- register struct bus_driver *driver;
+ struct bus_device *device;
+ struct bus_driver *driver;
- int found = 0;
+ boolean_t found = FALSE;
/*
* Walk all devices to find one with the right name
@@ -196,7 +196,7 @@ boolean_t configure_bus_device(
((!device->phys_address) ||
((device->phys_address == phys) && (device->address == virt))) &&
(strcmp(device->name, name) == 0)) {
- found = 1;
+ found = TRUE;
break;
}
}
diff --git a/chips/busses.h b/chips/busses.h
index 49c0e44f..f728add0 100644
--- a/chips/busses.h
+++ b/chips/busses.h
@@ -144,10 +144,10 @@ struct bus_driver {
extern struct bus_ctlr bus_master_init[];
extern struct bus_device bus_device_init[];
-extern boolean_t configure_bus_master(char *, vm_offset_t, vm_offset_t,
- int, char * );
-extern boolean_t configure_bus_device(char *, vm_offset_t, vm_offset_t,
- int, char * );
+extern boolean_t configure_bus_master(const char *, vm_offset_t, vm_offset_t,
+ int, const char * );
+extern boolean_t configure_bus_device(const char *, vm_offset_t, vm_offset_t,
+ int, const char * );
#endif /* KERNEL */
diff --git a/configfrag.ac b/configfrag.ac
index 57146c93..3e5fea3f 100644
--- a/configfrag.ac
+++ b/configfrag.ac
@@ -153,7 +153,7 @@ AC_ARG_ENABLE([gdb-stub],
# `${file}' and `$file' have different meanings here with respect to having the
# files in the referenced directory considered for `make dist' or not. See
# <http://lists.gnu.org/archive/html/bug-automake/2006-11/msg00027.html>.
-AC_CONFIG_LINKS([machine:$systype/$systype
+AC_CONFIG_LINKS([machine:$srcdir/$systype/$systype
mach/machine:$systype/include/mach/$systype])
dnl Local Variables:
diff --git a/configure.ac b/configure.ac
index 3a7d3be6..40e78a04 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
dnl Configure script for GNU Mach.
-dnl Copyright (C) 1997, 1998, 1999, 2004, 2006, 2007, 2008, 2010 Free Software
-dnl Foundation, Inc.
+dnl Copyright (C) 1997, 1998, 1999, 2004, 2006, 2007, 2008, 2010, 2013 Free
+dnl Software Foundation, Inc.
dnl Permission to use, copy, modify and distribute this software and its
dnl documentation is hereby granted, provided that both the copyright
@@ -25,6 +25,7 @@ AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE(
[1.10.2]
+ [dist-bzip2]
dnl Don't define `PACKAGE' and `VERSION'.
[no-define]
dnl Do not clutter the main build directory.
diff --git a/ddb/db_access.c b/ddb/db_access.c
index f06f9502..16d4d3ef 100644
--- a/ddb/db_access.c
+++ b/ddb/db_access.c
@@ -32,6 +32,7 @@
#include <mach/boolean.h>
#include <machine/db_machdep.h> /* type definitions */
+#include <machine/db_interface.h> /* function definitions */
#include <machine/setjmp.h>
#include <kern/task.h>
#include <ddb/db_access.h>
@@ -43,9 +44,6 @@
* boundaries.
*/
-extern void db_read_bytes(); /* machine-dependent */
-extern void db_write_bytes(); /* machine-dependent */
-
int db_access_level = DB_ACCESS_LEVEL;
/*
@@ -64,17 +62,17 @@ static int db_extend[sizeof(int)+1] = { /* table for sign-extending */
};
db_expr_t
-db_get_task_value(addr, size, is_signed, task)
- db_addr_t addr;
- register int size;
- boolean_t is_signed;
- task_t task;
+db_get_task_value(
+ db_addr_t addr,
+ int size,
+ boolean_t is_signed,
+ task_t task)
{
char data[sizeof(db_expr_t)];
- register db_expr_t value;
- register int i;
+ db_expr_t value;
+ int i;
- db_read_bytes((void*)addr, size, data, task);
+ db_read_bytes(addr, size, data, task);
value = 0;
#if BYTE_MSF
@@ -94,14 +92,14 @@ db_get_task_value(addr, size, is_signed, task)
}
void
-db_put_task_value(addr, size, value, task)
- db_addr_t addr;
- register int size;
- register db_expr_t value;
- task_t task;
+db_put_task_value(
+ db_addr_t addr,
+ int size,
+ db_expr_t value,
+ task_t task)
{
char data[sizeof(db_expr_t)];
- register int i;
+ int i;
#if BYTE_MSF
for (i = size - 1; i >= 0; i--)
@@ -113,23 +111,23 @@ db_put_task_value(addr, size, value, task)
value >>= 8;
}
- db_write_bytes((void*)addr, size, data, task);
+ db_write_bytes(addr, size, data, task);
}
db_expr_t
-db_get_value(addr, size, is_signed)
- db_addr_t addr;
- int size;
- boolean_t is_signed;
+db_get_value(
+ db_addr_t addr,
+ int size,
+ boolean_t is_signed)
{
return(db_get_task_value(addr, size, is_signed, TASK_NULL));
}
void
-db_put_value(addr, size, value)
- db_addr_t addr;
- int size;
- db_expr_t value;
+db_put_value(
+ db_addr_t addr,
+ int size,
+ db_expr_t value)
{
db_put_task_value(addr, size, value, TASK_NULL);
}
diff --git a/ddb/db_access.h b/ddb/db_access.h
index 6cedf29f..3bda5a4a 100644
--- a/ddb/db_access.h
+++ b/ddb/db_access.h
@@ -30,6 +30,10 @@
/*
* Data access functions for debugger.
*/
+
+#ifndef _DDB_DB_ACCESS_H_
+#define _DDB_DB_ACCESS_H_
+
#include <mach/boolean.h>
#include <machine/db_machdep.h>
#include <ddb/db_task_thread.h>
@@ -71,3 +75,5 @@ extern void db_put_task_value( db_addr_t addr,
int size,
db_expr_t value,
task_t task );
+
+#endif /* _DDB_DB_ACCESS_H_ */
diff --git a/ddb/db_aout.c b/ddb/db_aout.c
index 42fa6f75..d3f2e31e 100644
--- a/ddb/db_aout.c
+++ b/ddb/db_aout.c
@@ -39,6 +39,7 @@
#include <machine/db_machdep.h> /* data types */
#include <ddb/db_output.h>
#include <ddb/db_sym.h>
+#include <ddb/db_aout.h>
#ifndef DB_NO_AOUT
@@ -69,18 +70,18 @@
ep = (struct nlist *)((char *)sp + *((int*)symtab)))
boolean_t
-aout_db_sym_init(symtab, esymtab, name, task_addr)
- char * symtab; /* pointer to start of symbol table */
- char * esymtab; /* pointer to end of string table,
+aout_db_sym_init(
+ char * symtab, /* pointer to start of symbol table */
+ char * esymtab, /* pointer to end of string table,
for checking - may be rounded up to
integer boundary */
- char * name;
- char * task_addr; /* use for this task only */
+ char * name,
+ char * task_addr) /* use for this task only */
{
- register struct nlist *sym_start, *sym_end;
- register struct nlist *sp;
- register char * strtab;
- register int strlen;
+ struct nlist *sym_start, *sym_end;
+ struct nlist *sp;
+ char * strtab;
+ int strlen;
char * estrtab;
db_get_aout_symtab(symtab, sym_start, sym_end);
@@ -100,7 +101,7 @@ aout_db_sym_init(symtab, esymtab, name, task_addr)
#undef round_to_size
for (sp = sym_start; sp < sym_end; sp++) {
- register long strx;
+ long strx;
strx = sp->n_un.n_strx;
if (strx != 0) {
if (strx > strlen) {
@@ -131,9 +132,9 @@ aout_db_sym_init(symtab, esymtab, name, task_addr)
/*
* check file name or not (check xxxx.x pattern)
*/
-private boolean_t
+private boolean_t __attribute__ ((pure))
aout_db_is_filename(name)
- register char *name;
+ const char *name;
{
while (*name) {
if (*name == '.') {
@@ -148,12 +149,12 @@ aout_db_is_filename(name)
/*
* special name comparison routine with a name in the symbol table entry
*/
-private boolean_t
+private boolean_t __attribute__ ((pure))
aout_db_eq_name(sp, name)
- struct nlist *sp;
- char *name;
+ const struct nlist *sp;
+ const char *name;
{
- register char *s1, *s2;
+ const char *s1, *s2;
s1 = sp->n_un.n_name;
s2 = name;
@@ -185,11 +186,11 @@ aout_db_eq_name(sp, name)
*/
private struct nlist *
aout_db_search_name(sp, ep, name, type, fp)
- register struct nlist *sp;
- struct nlist *ep;
- char *name;
- int type;
- struct nlist **fp;
+ struct nlist *sp;
+ const struct nlist *ep;
+ const char *name;
+ int type;
+ struct nlist **fp;
{
struct nlist *file_sp = *fp;
struct nlist *found_sp = 0;
@@ -232,11 +233,11 @@ aout_db_search_name(sp, ep, name, type, fp)
private db_sym_t
aout_db_qualified_search(stab, file, sym, line)
db_symtab_t *stab;
- char *file;
- char *sym;
+ const char *file;
+ const char *sym;
int line;
{
- register struct nlist *sp = (struct nlist *)stab->start;
+ struct nlist *sp = (struct nlist *)stab->start;
struct nlist *ep = (struct nlist *)stab->end;
struct nlist *fp = 0;
struct nlist *found_sp;
@@ -244,19 +245,19 @@ aout_db_qualified_search(stab, file, sym, line)
boolean_t in_file;
if (file == 0 && sym == 0)
- return(0);
+ return(DB_SYM_NULL);
if (file) {
if ((sp = aout_db_search_name(sp, ep, file, N_TEXT, &fp)) == 0)
- return(0);
+ return(DB_SYM_NULL);
}
if (sym) {
sp = aout_db_search_name(sp, ep, sym, (line > 0)? N_FUN: 0, &fp);
if (sp == 0)
- return(0);
+ return(DB_SYM_NULL);
}
if (line > 0) {
if (file && !aout_db_eq_name(fp, file))
- return(0);
+ return(DB_SYM_NULL);
found_sp = 0;
if (sp->n_type == N_FUN) {
/*
@@ -278,7 +279,7 @@ aout_db_qualified_search(stab, file, sym, line)
}
}
if (sp->n_type != N_SLINE || sp->n_value < func_top)
- return(0);
+ return(DB_SYM_NULL);
} else {
/*
* qualified by only file name
@@ -312,26 +313,23 @@ aout_db_qualified_search(stab, file, sym, line)
* lookup symbol by name
*/
db_sym_t
-aout_db_lookup(stab, symstr)
- db_symtab_t *stab;
- char * symstr;
+aout_db_lookup(
+ db_symtab_t *stab,
+ char * symstr)
{
- db_sym_t db_sym_parse_and_lookup();
-
return(db_sym_parse_and_lookup(aout_db_qualified_search, stab, symstr));
}
db_sym_t
-aout_db_search_symbol(symtab, off, strategy, diffp)
- db_symtab_t * symtab;
- register
- db_addr_t off;
- db_strategy_t strategy;
- db_expr_t *diffp; /* in/out */
+aout_db_search_symbol(
+ db_symtab_t * symtab,
+ db_addr_t off,
+ db_strategy_t strategy,
+ db_expr_t *diffp) /* in/out */
{
- register unsigned long diff = *diffp;
- register struct nlist *symp = 0;
- register struct nlist *sp, *ep;
+ unsigned long diff = *diffp;
+ struct nlist *symp = 0;
+ struct nlist *sp, *ep;
sp = (struct nlist *)symtab->start;
ep = (struct nlist *)symtab->end;
@@ -376,13 +374,13 @@ aout_db_search_symbol(symtab, off, strategy, diffp)
* Return the name and value for a symbol.
*/
void
-aout_db_symbol_values(stab, sym, namep, valuep)
- db_symtab_t *stab;
- db_sym_t sym;
- char **namep;
- db_expr_t *valuep;
+aout_db_symbol_values(
+ db_symtab_t *stab,
+ db_sym_t sym,
+ char **namep,
+ db_expr_t *valuep)
{
- register struct nlist *sp;
+ struct nlist *sp;
sp = (struct nlist *)sym;
if (namep)
@@ -398,16 +396,16 @@ aout_db_symbol_values(stab, sym, namep, valuep)
*/
private boolean_t
aout_db_search_by_addr(stab, addr, file, func, line, diff)
- db_symtab_t *stab;
- register vm_offset_t addr;
- char **file;
- char **func;
- int *line;
- unsigned long *diff;
+ const db_symtab_t *stab;
+ vm_offset_t addr;
+ char **file;
+ char **func;
+ int *line;
+ unsigned long *diff;
{
- register struct nlist *sp;
- register struct nlist *line_sp, *func_sp, *file_sp, *line_func;
- register vm_size_t func_diff, line_diff;
+ struct nlist *sp;
+ struct nlist *line_sp, *func_sp, *file_sp, *line_func;
+ vm_size_t func_diff, line_diff;
boolean_t found_line = FALSE;
struct nlist *ep = (struct nlist *)stab->end;
@@ -495,13 +493,13 @@ aout_db_line_at_pc(stab, sym, file, line, pc)
db_sym_t sym;
char **file;
int *line;
- db_expr_t pc;
+ db_addr_t pc;
{
char *func;
unsigned long diff;
boolean_t found;
- found = aout_db_search_by_addr(stab,(vm_offset_t)pc,file,&func,line,&diff);
+ found = aout_db_search_by_addr(stab, pc, file, &func, line, &diff);
return(found && func && *file);
}
diff --git a/ddb/db_aout.h b/ddb/db_aout.h
new file mode 100644
index 00000000..7c03d36d
--- /dev/null
+++ b/ddb/db_aout.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _DDB_DB_AOUT_H_
+#define _DDB_DB_AOUT_H_
+
+#include <ddb/db_sym.h>
+#include <machine/db_machdep.h>
+
+extern boolean_t
+aout_db_line_at_pc(
+ db_symtab_t *stab,
+ db_sym_t sym,
+ char **file,
+ int *line,
+ db_addr_t pc);
+
+extern db_sym_t
+aout_db_lookup(
+ db_symtab_t *stab,
+ char * symstr);
+
+extern db_sym_t
+aout_db_search_symbol(
+ db_symtab_t * symtab,
+ db_addr_t off,
+ db_strategy_t strategy,
+ db_expr_t *diffp);
+
+extern void
+aout_db_symbol_values(
+ db_symtab_t *stab,
+ db_sym_t sym,
+ char **namep,
+ db_expr_t *valuep);
+
+#endif /* _DDB_DB_AOUT_H_ */
diff --git a/ddb/db_break.c b/ddb/db_break.c
index 9b1d6049..c3a9e181 100644
--- a/ddb/db_break.c
+++ b/ddb/db_break.c
@@ -36,6 +36,7 @@
*/
#include <mach/boolean.h>
#include <machine/db_machdep.h>
+#include <machine/db_interface.h>
#include <ddb/db_lex.h>
#include <ddb/db_break.h>
#include <ddb/db_access.h>
@@ -63,7 +64,7 @@ static int db_breakpoint_number = 0;
db_breakpoint_t
db_breakpoint_alloc()
{
- register db_breakpoint_t bkpt;
+ db_breakpoint_t bkpt;
if ((bkpt = db_free_breakpoints) != 0) {
db_free_breakpoints = bkpt->link;
@@ -81,7 +82,7 @@ db_breakpoint_alloc()
void
db_breakpoint_free(bkpt)
- register db_breakpoint_t bkpt;
+ db_breakpoint_t bkpt;
{
bkpt->link = db_free_breakpoints;
db_free_breakpoints = bkpt;
@@ -89,11 +90,12 @@ db_breakpoint_free(bkpt)
static int
db_add_thread_breakpoint(bkpt, task_thd, count, task_bpt)
- register db_breakpoint_t bkpt;
+ const db_breakpoint_t bkpt;
vm_offset_t task_thd;
+ int count;
boolean_t task_bpt;
{
- register db_thread_breakpoint_t tp;
+ db_thread_breakpoint_t tp;
if (db_thread_break_init == FALSE) {
for (tp = db_thread_break_list;
@@ -119,12 +121,12 @@ db_add_thread_breakpoint(bkpt, task_thd, count, task_bpt)
}
static int
-db_delete_thread_breakpoint(bkpt, task_thd)
- register db_breakpoint_t bkpt;
- vm_offset_t task_thd;
+db_delete_thread_breakpoint(
+ db_breakpoint_t bkpt,
+ vm_offset_t task_thd)
{
- register db_thread_breakpoint_t tp;
- register db_thread_breakpoint_t *tpp;
+ db_thread_breakpoint_t tp;
+ db_thread_breakpoint_t *tpp;
if (task_thd == 0) {
/* delete all the thread-breakpoints */
@@ -152,13 +154,13 @@ db_delete_thread_breakpoint(bkpt, task_thd)
}
}
-static db_thread_breakpoint_t
+static db_thread_breakpoint_t __attribute__ ((pure))
db_find_thread_breakpoint(bkpt, thread)
- db_breakpoint_t bkpt;
- thread_t thread;
+ const db_breakpoint_t bkpt;
+ const thread_t thread;
{
- register db_thread_breakpoint_t tp;
- register task_t task = (thread == THREAD_NULL)? TASK_NULL: thread->task;
+ db_thread_breakpoint_t tp;
+ task_t task = (thread == THREAD_NULL)? TASK_NULL: thread->task;
for (tp = bkpt->threads; tp; tp = tp->tb_next) {
if (tp->tb_is_task) {
@@ -174,24 +176,24 @@ db_find_thread_breakpoint(bkpt, thread)
db_thread_breakpoint_t
db_find_thread_breakpoint_here(task, addr)
- task_t task;
+ const task_t task;
db_addr_t addr;
{
db_breakpoint_t bkpt;
- bkpt = db_find_breakpoint(task, (db_addr_t)addr);
+ bkpt = db_find_breakpoint(task, addr);
if (bkpt == 0)
return(0);
return(db_find_thread_breakpoint(bkpt, current_thread()));
}
db_thread_breakpoint_t
-db_find_breakpoint_number(num, bkptp)
- int num;
- db_breakpoint_t *bkptp;
+db_find_breakpoint_number(
+ int num,
+ db_breakpoint_t *bkptp)
{
- register db_thread_breakpoint_t tp;
- register db_breakpoint_t bkpt;
+ db_thread_breakpoint_t tp;
+ db_breakpoint_t bkpt;
for (bkpt = db_breakpoint_list; bkpt != 0; bkpt = bkpt->link) {
for (tp = bkpt->threads; tp; tp = tp->tb_next) {
@@ -206,10 +208,10 @@ db_find_breakpoint_number(num, bkptp)
}
static void
-db_force_delete_breakpoint(bkpt, task_thd, is_task)
- db_breakpoint_t bkpt;
- vm_offset_t task_thd;
- boolean_t is_task;
+db_force_delete_breakpoint(
+ db_breakpoint_t bkpt,
+ vm_offset_t task_thd,
+ boolean_t is_task)
{
db_printf("deleted a stale breakpoint at ");
if (bkpt->task == TASK_NULL || db_lookup_task(bkpt->task) >= 0)
@@ -225,10 +227,10 @@ db_force_delete_breakpoint(bkpt, task_thd, is_task)
}
void
-db_check_breakpoint_valid()
+db_check_breakpoint_valid(void)
{
- register db_thread_breakpoint_t tbp, tbp_next;
- register db_breakpoint_t bkpt, *bkptp;
+ db_thread_breakpoint_t tbp, tbp_next;
+ db_breakpoint_t bkpt, *bkptp;
bkptp = &db_breakpoint_list;
for (bkpt = *bkptp; bkpt; bkpt = *bkptp) {
@@ -266,13 +268,13 @@ db_check_breakpoint_valid()
db_breakpoint_t
db_set_breakpoint(task, addr, count, thread, task_bpt)
- task_t task;
+ const task_t task;
db_addr_t addr;
int count;
- thread_t thread;
+ const thread_t thread;
boolean_t task_bpt;
{
- register db_breakpoint_t bkpt;
+ db_breakpoint_t bkpt;
db_breakpoint_t alloc_bkpt = 0;
vm_offset_t task_thd;
@@ -319,12 +321,12 @@ db_set_breakpoint(task, addr, count, thread, task_bpt)
void
db_delete_breakpoint(task, addr, task_thd)
- task_t task;
+ const task_t task;
db_addr_t addr;
vm_offset_t task_thd;
{
- register db_breakpoint_t bkpt;
- register db_breakpoint_t *prev;
+ db_breakpoint_t bkpt;
+ db_breakpoint_t *prev;
for (prev = &db_breakpoint_list; (bkpt = *prev) != 0;
prev = &bkpt->link) {
@@ -348,12 +350,12 @@ db_delete_breakpoint(task, addr, task_thd)
}
}
-db_breakpoint_t
+db_breakpoint_t __attribute__ ((pure))
db_find_breakpoint(task, addr)
- task_t task;
+ const task_t task;
db_addr_t addr;
{
- register db_breakpoint_t bkpt;
+ db_breakpoint_t bkpt;
for (bkpt = db_breakpoint_list; bkpt != 0; bkpt = bkpt->link) {
if ((bkpt->task == task
@@ -366,10 +368,10 @@ db_find_breakpoint(task, addr)
boolean_t
db_find_breakpoint_here(task, addr)
- task_t task;
+ const task_t task;
db_addr_t addr;
{
- register db_breakpoint_t bkpt;
+ db_breakpoint_t bkpt;
for (bkpt = db_breakpoint_list; bkpt != 0; bkpt = bkpt->link) {
if ((bkpt->task == task
@@ -377,7 +379,7 @@ db_find_breakpoint_here(task, addr)
&& bkpt->address == addr)
return(TRUE);
if ((bkpt->flags & BKPT_USR_GLOBAL) == 0 &&
- DB_PHYS_EQ(task, (vm_offset_t)addr, bkpt->task, (vm_offset_t)bkpt->address))
+ DB_PHYS_EQ(task, addr, bkpt->task, bkpt->address))
return (TRUE);
}
return(FALSE);
@@ -388,8 +390,8 @@ boolean_t db_breakpoints_inserted = TRUE;
void
db_set_breakpoints(void)
{
- register db_breakpoint_t bkpt;
- register task_t task;
+ db_breakpoint_t bkpt;
+ task_t task;
db_expr_t inst;
task_t cur_task;
@@ -433,8 +435,8 @@ db_set_breakpoints(void)
void
db_clear_breakpoints(void)
{
- register db_breakpoint_t bkpt, *bkptp;
- register task_t task;
+ db_breakpoint_t bkpt, *bkptp;
+ task_t task;
task_t cur_task;
db_expr_t inst;
@@ -480,11 +482,11 @@ db_clear_breakpoints(void)
* so the breakpoint does not have to be on the breakpoint list.
*/
db_breakpoint_t
-db_set_temp_breakpoint(task, addr)
- task_t task;
- db_addr_t addr;
+db_set_temp_breakpoint(
+ task_t task,
+ db_addr_t addr)
{
- register db_breakpoint_t bkpt;
+ db_breakpoint_t bkpt;
bkpt = db_breakpoint_alloc();
if (bkpt == 0) {
@@ -509,9 +511,9 @@ db_set_temp_breakpoint(task, addr)
}
void
-db_delete_temp_breakpoint(task, bkpt)
- task_t task;
- db_breakpoint_t bkpt;
+db_delete_temp_breakpoint(
+ task_t task,
+ db_breakpoint_t bkpt)
{
db_put_task_value(bkpt->address, BKPT_SIZE, bkpt->bkpt_inst, task);
db_delete_thread_breakpoint(bkpt, 0);
@@ -522,9 +524,9 @@ db_delete_temp_breakpoint(task, bkpt)
* List breakpoints.
*/
void
-db_list_breakpoints()
+db_list_breakpoints(void)
{
- register db_breakpoint_t bkpt;
+ db_breakpoint_t bkpt;
if (db_breakpoint_list == 0) {
db_printf("No breakpoints set\n");
@@ -536,9 +538,9 @@ db_list_breakpoints()
bkpt != 0;
bkpt = bkpt->link)
{
- register db_thread_breakpoint_t tp;
- int task_id;
- int thread_id;
+ db_thread_breakpoint_t tp;
+ int task_id;
+ int thread_id;
if (bkpt->threads) {
for (tp = bkpt->threads; tp; tp = tp->tb_next) {
@@ -596,9 +598,9 @@ db_list_breakpoints()
/* Delete breakpoint */
/*ARGSUSED*/
void
-db_delete_cmd()
+db_delete_cmd(void)
{
- register int n;
+ int n;
thread_t thread;
vm_offset_t task_thd;
boolean_t user_global = FALSE;
@@ -679,9 +681,9 @@ db_breakpoint_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
- register int n;
+ int n;
thread_t thread;
boolean_t user_global = db_option(modif, 'U');
boolean_t task_bpt = db_option(modif, 'T');
@@ -729,7 +731,7 @@ db_breakpoint_cmd(addr, have_addr, count, modif)
/* list breakpoints */
void
-db_listbreak_cmd()
+db_listbreak_cmd(void)
{
db_list_breakpoints();
}
diff --git a/ddb/db_break.h b/ddb/db_break.h
index 20d74d26..610af2f8 100644
--- a/ddb/db_break.h
+++ b/ddb/db_break.h
@@ -71,12 +71,12 @@ struct db_breakpoint {
typedef struct db_breakpoint *db_breakpoint_t;
-extern db_breakpoint_t db_find_breakpoint( task_t task, db_addr_t addr);
-extern boolean_t db_find_breakpoint_here( task_t task, db_addr_t addr);
+extern db_breakpoint_t db_find_breakpoint( const task_t task, db_addr_t addr) __attribute__ ((pure));
+extern boolean_t db_find_breakpoint_here( const task_t task, db_addr_t addr);
extern void db_set_breakpoints(void);
extern void db_clear_breakpoints(void);
extern db_thread_breakpoint_t db_find_thread_breakpoint_here
- ( task_t task, db_addr_t addr );
+ ( const task_t task, db_addr_t addr );
extern db_thread_breakpoint_t db_find_breakpoint_number
( int num, db_breakpoint_t *bkptp);
@@ -84,8 +84,20 @@ extern db_breakpoint_t db_set_temp_breakpoint( task_t task, db_addr_t addr);
extern void db_delete_temp_breakpoint
( task_t task, db_breakpoint_t bkpt);
-extern db_breakpoint_t db_set_breakpoint(task_t task, db_addr_t addr,
- int count, thread_t thread,
+extern db_breakpoint_t db_set_breakpoint(const task_t task, db_addr_t addr,
+ int count, const thread_t thread,
boolean_t task_bpt);
+void db_listbreak_cmd(void);
+
+void db_delete_cmd(void);
+
+void db_breakpoint_cmd(
+ db_expr_t addr,
+ int have_addr,
+ db_expr_t count,
+ const char * modif);
+
+extern void db_check_breakpoint_valid(void);
+
#endif /* _DDB_DB_BREAK_H_ */
diff --git a/ddb/db_command.c b/ddb/db_command.c
index 1593e866..56516672 100644
--- a/ddb/db_command.c
+++ b/ddb/db_command.c
@@ -45,14 +45,24 @@
#include <ddb/db_macro.h>
#include <ddb/db_expr.h>
#include <ddb/db_examine.h>
+#include <ddb/db_print.h>
+#include <ddb/db_break.h>
+#include <ddb/db_watch.h>
+#include <ddb/db_variables.h>
+#include <ddb/db_write_cmd.h>
+#include <ddb/db_run.h>
+#include <ddb/db_cond.h>
#include <machine/setjmp.h>
+#include <machine/db_interface.h>
#include <kern/debug.h>
#include <kern/thread.h>
#include <ipc/ipc_pset.h> /* 4proto */
#include <ipc/ipc_port.h> /* 4proto */
-
+#include <vm/vm_print.h>
+#include <ipc/ipc_print.h>
+#include <kern/lock.h>
/*
* Exported global variables
@@ -85,17 +95,17 @@ boolean_t db_ed_style = TRUE;
*/
int
db_cmd_search(name, table, cmdp)
- char * name;
- struct db_command *table;
- struct db_command **cmdp; /* out */
+ const char * name;
+ const struct db_command *table;
+ const struct db_command **cmdp; /* out */
{
- struct db_command *cmd;
+ const struct db_command *cmd;
int result = CMD_NONE;
for (cmd = table; cmd->name != 0; cmd++) {
- register char *lp;
- register char *rp;
- register int c;
+ const char *lp;
+ char *rp;
+ int c;
lp = name;
rp = cmd->name;
@@ -132,9 +142,9 @@ db_cmd_search(name, table, cmdp)
void
db_cmd_list(table)
- struct db_command *table;
+ const struct db_command *table;
{
- register struct db_command *cmd;
+ const struct db_command *cmd;
for (cmd = table; cmd->name != 0; cmd++) {
db_printf("%-12s", cmd->name);
@@ -143,9 +153,9 @@ db_cmd_list(table)
}
void
-db_command(last_cmdp, cmd_table)
- struct db_command **last_cmdp; /* IN_OUT */
- struct db_command *cmd_table;
+db_command(
+ struct db_command **last_cmdp, /* IN_OUT */
+ struct db_command *cmd_table)
{
struct db_command *cmd;
int t;
@@ -166,7 +176,6 @@ db_command(last_cmdp, cmd_table)
db_unread_token(t);
}
else if (t == tEXCL) {
- void db_fncall();
db_fncall();
return;
}
@@ -284,34 +293,18 @@ db_command(last_cmdp, cmd_table)
}
void
-db_command_list(last_cmdp, cmd_table)
- struct db_command **last_cmdp; /* IN_OUT */
- struct db_command *cmd_table;
+db_command_list(
+ struct db_command **last_cmdp, /* IN_OUT */
+ struct db_command *cmd_table)
{
- void db_skip_to_eol();
-
do {
db_command(last_cmdp, cmd_table);
db_skip_to_eol();
- } while (db_read_token() == tSEMI_COLON && db_cmd_loop_done == 0);
+ } while (db_read_token() == tSEMI_COLON && db_cmd_loop_done == FALSE);
}
-/*
- * 'show' commands
- */
-extern void db_listbreak_cmd();
-extern void db_listwatch_cmd();
-extern void db_show_regs(), db_show_one_thread(), db_show_one_task();
-extern void db_show_all_threads();
-extern void db_show_macro();
-extern void vm_map_print(), vm_object_print(), vm_page_print();
-extern void vm_map_copy_print();
-extern void ipc_port_print(), ipc_pset_print(), db_show_all_slocks();
-extern void ipc_kmsg_print(), ipc_msg_print();
-extern void db_show_port_id();
-void db_show_help();
-
struct db_command db_show_all_cmds[] = {
+ { "tasks", db_show_all_tasks, 0, 0 },
{ "threads", db_show_all_threads, 0, 0 },
{ "slocks", db_show_all_slocks, 0, 0 },
{ (char *)0 }
@@ -337,20 +330,6 @@ struct db_command db_show_cmds[] = {
{ (char *)0, }
};
-extern void db_print_cmd(), db_examine_cmd(), db_set_cmd();
-extern void db_examine_forward(), db_examine_backward();
-extern void db_search_cmd();
-extern void db_write_cmd();
-extern void db_delete_cmd(), db_breakpoint_cmd();
-extern void db_deletewatch_cmd(), db_watchpoint_cmd();
-extern void db_single_step_cmd(), db_trace_until_call_cmd(),
- db_trace_until_matching_cmd(), db_continue_cmd();
-extern void db_stack_trace_cmd(), db_cond_cmd();
-void db_help_cmd();
-void db_def_macro_cmd(), db_del_macro_cmd();
-void db_fncall();
-extern void db_reset_cpu();
-
struct db_command db_command_table[] = {
#ifdef DB_MACHINE_COMMANDS
/* this must be the first entry, if it exists */
@@ -385,6 +364,7 @@ struct db_command db_command_table[] = {
{ "show", 0, 0, db_show_cmds },
{ "reset", db_reset_cpu, 0, 0 },
{ "reboot", db_reset_cpu, 0, 0 },
+ { "halt", db_halt_cpu, 0, 0 },
{ (char *)0, }
};
@@ -392,20 +372,19 @@ struct db_command db_command_table[] = {
/* this function should be called to install the machine dependent
commands. It should be called before the debugger is enabled */
-void db_machine_commands_install(ptr)
-struct db_command *ptr;
+void db_machine_commands_install(struct db_command *ptr)
{
db_command_table[0].more = ptr;
return;
}
-#endif
+#endif /* DB_MACHINE_COMMANDS */
struct db_command *db_last_command = 0;
void
-db_help_cmd()
+db_help_cmd(void)
{
struct db_command *cmd = db_command_table;
@@ -416,8 +395,6 @@ db_help_cmd()
}
}
-int (*ddb_display)();
-
void
db_command_loop(void)
{
@@ -432,10 +409,7 @@ db_command_loop(void)
db_prev = db_dot;
db_next = db_dot;
- if (ddb_display)
- (*ddb_display)();
-
- db_cmd_loop_done = 0;
+ db_cmd_loop_done = FALSE;
while (!db_cmd_loop_done) {
(void) _setjmp(db_recover = &db_jmpbuf);
db_macro_level = 0;
@@ -456,13 +430,13 @@ db_command_loop(void)
}
boolean_t
-db_exec_cmd_nest(cmd, size)
- char *cmd;
- int size;
+db_exec_cmd_nest(
+ char *cmd,
+ int size)
{
struct db_lex_context lex_context;
- db_cmd_loop_done = 0;
+ db_cmd_loop_done = FALSE;
if (cmd) {
db_save_lex_context(&lex_context);
db_switch_input(cmd, size /**OLD, &lex_context OLD**/);
@@ -470,15 +444,11 @@ db_exec_cmd_nest(cmd, size)
db_command_list(&db_last_command, db_command_table);
if (cmd)
db_restore_lex_context(&lex_context);
- return(db_cmd_loop_done == 0);
+ return(db_cmd_loop_done == FALSE);
}
-#ifdef __GNUC__
-extern __volatile__ void _longjmp();
-#endif
-
void db_error(s)
- char *s;
+ const char *s;
{
extern int db_macro_level;
@@ -502,7 +472,7 @@ void db_error(s)
* !expr(arg,arg,arg)
*/
void
-db_fncall()
+db_fncall(void)
{
db_expr_t fn_addr;
#define MAXARGS 11
@@ -553,12 +523,12 @@ db_fncall()
db_printf(" %#N\n", retval);
}
-boolean_t
+boolean_t __attribute__ ((pure))
db_option(modif, option)
- char *modif;
- int option;
+ const char *modif;
+ int option;
{
- register char *p;
+ const char *p;
for (p = modif; *p; p++)
if (*p == option)
diff --git a/ddb/db_command.h b/ddb/db_command.h
index 1c0d106f..4208bda8 100644
--- a/ddb/db_command.h
+++ b/ddb/db_command.h
@@ -28,6 +28,9 @@
* Date: 7/90
*/
+#ifndef _DDB_DB_COMMAND_H_
+#define _DDB_DB_COMMAND_H_
+
#if MACH_KDB
/*
@@ -38,9 +41,9 @@
#include <machine/setjmp.h>
extern void db_command_loop(void);
-extern boolean_t db_option(char *, int);
+extern boolean_t db_option(const char *, int) __attribute__ ((pure));
-extern void db_error(char *); /* report error */
+extern void db_error(const char *) __attribute__ ((noreturn)); /* report error */
extern db_addr_t db_dot; /* current location */
extern db_addr_t db_last_addr; /* last explicit address typed */
@@ -50,8 +53,6 @@ extern db_addr_t db_next; /* next address to be examined
or written */
extern jmp_buf_t * db_recover; /* error recovery */
-extern jmp_buf_t * db_recover; /* error recovery */
-
/*
* Command table
*/
@@ -68,4 +69,10 @@ struct db_command {
extern boolean_t db_exec_cmd_nest(char *cmd, int size);
+void db_fncall(void);
+
+void db_help_cmd(void);
+
#endif /* MACH_KDB */
+
+#endif /* _DDB_DB_COMMAND_H_ */
diff --git a/ddb/db_cond.c b/ddb/db_cond.c
index 60ea4735..31e1d241 100644
--- a/ddb/db_cond.c
+++ b/ddb/db_cond.c
@@ -48,8 +48,7 @@ struct db_cond {
} db_cond[DB_MAX_COND];
void
-db_cond_free(bkpt)
- db_thread_breakpoint_t bkpt;
+db_cond_free(db_thread_breakpoint_t bkpt)
{
if (bkpt->tb_cond > 0) {
db_cond[bkpt->tb_cond-1].c_size = 0;
@@ -59,10 +58,9 @@ db_cond_free(bkpt)
}
boolean_t
-db_cond_check(bkpt)
- db_thread_breakpoint_t bkpt;
+db_cond_check(db_thread_breakpoint_t bkpt)
{
- register struct db_cond *cp;
+ struct db_cond *cp;
db_expr_t value;
int t;
jmp_buf_t db_jmpbuf;
@@ -105,10 +103,10 @@ db_cond_check(bkpt)
void
db_cond_print(bkpt)
- db_thread_breakpoint_t bkpt;
+ const db_thread_breakpoint_t bkpt;
{
- register char *p, *ep;
- register struct db_cond *cp;
+ char *p, *ep;
+ struct db_cond *cp;
if (bkpt->tb_cond <= 0)
return;
@@ -123,11 +121,11 @@ db_cond_print(bkpt)
}
void
-db_cond_cmd()
+db_cond_cmd(void)
{
- register int c;
- register struct db_cond *cp;
- register char *p;
+ int c;
+ struct db_cond *cp;
+ char *p;
db_expr_t value;
db_thread_breakpoint_t bkpt;
diff --git a/ddb/db_cond.h b/ddb/db_cond.h
index dec4967d..6b9c3a5b 100644
--- a/ddb/db_cond.h
+++ b/ddb/db_cond.h
@@ -24,7 +24,7 @@
#include <sys/types.h>
#include <machine/db_machdep.h>
-extern void db_cond_free (db_thread_breakpoint_t bkpt);
+extern void db_cond_free (const db_thread_breakpoint_t bkpt);
extern boolean_t db_cond_check (db_thread_breakpoint_t bkpt);
diff --git a/ddb/db_elf.c b/ddb/db_elf.c
new file mode 100644
index 00000000..10e71621
--- /dev/null
+++ b/ddb/db_elf.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2014 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Author: David B. Golub, Carnegie Mellon University
+ * Date: 7/90
+ */
+
+#if MACH_KDB
+
+/*
+ * Symbol table routines for ELF format files.
+ */
+
+#include <string.h>
+#include <mach/std_types.h>
+#include <mach/exec/elf.h>
+#include <machine/db_machdep.h> /* data types */
+#include <machine/vm_param.h>
+#include <ddb/db_output.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_elf.h>
+
+#ifndef DB_NO_ELF
+
+struct db_symtab_elf {
+ int type;
+ Elf32_Sym *start;
+ Elf32_Sym *end;
+ char *strings;
+ char *map_pointer; /* symbols are for this map only,
+ if not null */
+ char name[SYMTAB_NAME_LEN];
+ /* symtab name */
+};
+
+boolean_t
+elf_db_sym_init (unsigned shdr_num,
+ vm_size_t shdr_size,
+ vm_offset_t shdr_addr,
+ unsigned shdr_shndx,
+ char *name,
+ char *task_addr)
+{
+ Elf32_Shdr *shdr, *symtab, *strtab;
+ const char *shstrtab;
+ int i;
+
+ if (shdr_num == 0)
+ return FALSE;
+
+ if (shdr_size != sizeof *shdr)
+ return FALSE;
+
+ shdr = (Elf32_Shdr *) shdr_addr;
+
+ if (shdr[shdr_shndx].sh_type != SHT_STRTAB)
+ return FALSE;
+
+ shstrtab = (const char *) phystokv (shdr[shdr_shndx].sh_addr);
+
+ symtab = strtab = NULL;
+ for (i = 0; i < shdr_num; i++)
+ switch (shdr[i].sh_type) {
+ case SHT_SYMTAB:
+ if (symtab)
+ db_printf ("Ignoring additional ELF symbol table at %d\n", i);
+ else
+ symtab = &shdr[i];
+ break;
+
+ case SHT_STRTAB:
+ if (strcmp (&shstrtab[shdr[i].sh_name], ".strtab") == 0) {
+ if (strtab)
+ db_printf ("Ignoring additional ELF string table at %d\n", i);
+ else
+ strtab = &shdr[i];
+ }
+ break;
+ }
+
+ if (symtab == NULL || strtab == NULL)
+ return FALSE;
+
+ if (db_add_symbol_table (SYMTAB_ELF,
+ (char *) phystokv (symtab->sh_addr),
+ (char *) phystokv (symtab->sh_addr)+symtab->sh_size,
+ name,
+ (char *) phystokv (strtab->sh_addr),
+ task_addr)) {
+ db_printf ("Loaded ELF symbol table for %s (%d symbols)\n",
+ name, symtab->sh_size / sizeof (Elf32_Sym));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * lookup symbol by name
+ */
+db_sym_t
+elf_db_lookup (db_symtab_t *stab,
+ char *symstr)
+{
+ struct db_symtab_elf *self = (struct db_symtab_elf *) stab;
+ Elf32_Sym *s;
+
+ for (s = self->start; s < self->end; s++)
+ if (strcmp (symstr, &self->strings[s->st_name]) == 0)
+ return (db_sym_t) s;
+
+ return NULL;
+}
+
+db_sym_t
+elf_db_search_symbol (db_symtab_t *stab,
+ db_addr_t off,
+ db_strategy_t strategy,
+ db_expr_t *diffp) /* in/out */
+{
+ struct db_symtab_elf *self = (struct db_symtab_elf *) stab;
+ unsigned long diff = *diffp;
+ Elf32_Sym *s, *symp = NULL;
+
+ for (s = self->start; s < self->end; s++) {
+ if (s->st_name == 0)
+ continue;
+
+ if (strategy == DB_STGY_XTRN && (s->st_info & STB_GLOBAL) == 0)
+ continue;
+
+ if (off >= s->st_value) {
+ if (s->st_info == STT_FUNC)
+ continue;
+
+ if (off - s->st_value < diff) {
+ diff = off - s->st_value;
+ symp = s;
+ if (diff == 0 && (s->st_info & STB_GLOBAL))
+ break;
+ } else if (off - s->st_value == diff) {
+ if (symp == NULL)
+ symp = s;
+ else if ((symp->st_info & STB_GLOBAL) == 0
+ && (s->st_info & STB_GLOBAL) != 0)
+ symp = s; /* pick the external symbol */
+ }
+ }
+ }
+
+ if (symp == NULL)
+ *diffp = off;
+ else
+ *diffp = diff;
+
+ return (db_sym_t) symp;
+}
+
+/*
+ * Return the name and value for a symbol.
+ */
+void
+elf_db_symbol_values (db_symtab_t *stab,
+ db_sym_t sym,
+ char **namep,
+ db_expr_t *valuep)
+{
+ struct db_symtab_elf *self = (struct db_symtab_elf *) stab;
+ Elf32_Sym *s = (Elf32_Sym *) sym;
+
+ if (namep)
+ *namep = &self->strings[s->st_name];
+ if (valuep)
+ *valuep = s->st_value;
+}
+
+/*
+ * Find filename and lineno within, given the current pc.
+ */
+boolean_t
+elf_db_line_at_pc (db_symtab_t *stab,
+ db_sym_t sym,
+ char **file,
+ int *line,
+ db_addr_t pc)
+{
+ /* XXX Parse DWARF information. */
+ return FALSE;
+}
+
+#endif /* DB_NO_ELF */
+
+#endif /* MACH_KDB */
diff --git a/ddb/db_elf.h b/ddb/db_elf.h
new file mode 100644
index 00000000..12b82868
--- /dev/null
+++ b/ddb/db_elf.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _DDB_DB_ELF_H_
+#define _DDB_DB_ELF_H_
+
+#include <ddb/db_sym.h>
+#include <machine/db_machdep.h>
+
+extern boolean_t
+elf_db_line_at_pc(
+ db_symtab_t *stab,
+ db_sym_t sym,
+ char **file,
+ int *line,
+ db_addr_t pc);
+
+extern db_sym_t
+elf_db_lookup(
+ db_symtab_t *stab,
+ char * symstr);
+
+extern db_sym_t
+elf_db_search_symbol(
+ db_symtab_t * symtab,
+ db_addr_t off,
+ db_strategy_t strategy,
+ db_expr_t *diffp);
+
+extern void
+elf_db_symbol_values(
+ db_symtab_t *stab,
+ db_sym_t sym,
+ char **namep,
+ db_expr_t *valuep);
+
+#endif /* _DDB_DB_ELF_H_ */
diff --git a/ddb/db_examine.c b/ddb/db_examine.c
index 96c5eee1..836b0e89 100644
--- a/ddb/db_examine.c
+++ b/ddb/db_examine.c
@@ -53,9 +53,6 @@ int db_examine_count = 1;
db_addr_t db_examine_prev_addr = 0;
thread_t db_examine_thread = THREAD_NULL;
-extern db_addr_t db_disasm(db_addr_t pc, boolean_t altform, task_t task);
- /* instruction disassembler */
-
/*
* Examine (print) data.
*/
@@ -65,10 +62,9 @@ db_examine_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
thread_t thread;
- boolean_t db_option();
if (modif[0] != '\0')
db_strcpy(db_examine_format, modif);
@@ -82,7 +78,7 @@ db_examine_cmd(addr, have_addr, count, modif)
return;
}
else
- if (db_option(modif,'u'))
+ if (db_option(modif, 'u'))
thread = current_thread();
else
thread = THREAD_NULL;
@@ -98,7 +94,7 @@ db_examine_forward(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
db_examine(db_next, db_examine_format, db_examine_count,
db_thread_to_task(db_examine_thread));
@@ -110,7 +106,7 @@ db_examine_backward(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
db_examine(db_examine_prev_addr - (db_next - db_examine_prev_addr),
@@ -120,9 +116,8 @@ db_examine_backward(addr, have_addr, count, modif)
void
db_examine(addr, fmt, count, task)
- register
db_addr_t addr;
- char * fmt; /* format string */
+ const char * fmt; /* format string */
int count; /* repeat count */
task_t task;
{
@@ -130,7 +125,7 @@ db_examine(addr, fmt, count, task)
db_expr_t value;
int size; /* in bytes */
int width;
- char * fp;
+ const char * fp;
db_examine_prev_addr = addr;
while (--count >= 0) {
@@ -163,7 +158,7 @@ db_examine(addr, fmt, count, task)
db_printf(":\t");
break;
case 'm':
- db_next = db_xcdump(addr, size, count+1, task);
+ db_next = db_xcdump(addr, size, count + 1, task);
return;
default:
if (db_print_position() == 0) {
@@ -171,7 +166,7 @@ db_examine(addr, fmt, count, task)
char * name;
db_addr_t off;
- db_find_task_sym_and_offset(addr,&name,&off,task);
+ db_find_task_sym_and_offset(addr, &name, &off, task);
if (off == 0)
db_printf("%s:\t", name);
else
@@ -260,7 +255,7 @@ char db_print_format = 'x';
/*ARGSUSED*/
void
-db_print_cmd()
+db_print_cmd(void)
{
db_expr_t value;
int t;
@@ -326,9 +321,9 @@ db_print_cmd()
}
void
-db_print_loc_and_inst(loc, task)
- db_addr_t loc;
- task_t task;
+db_print_loc_and_inst(
+ db_addr_t loc,
+ task_t task)
{
db_task_printsym(loc, DB_STGY_PROC, task);
db_printf(":\t");
@@ -337,20 +332,19 @@ db_print_loc_and_inst(loc, task)
void
db_strcpy(dst, src)
- register char *dst;
- register char *src;
+ char *dst;
+ const char *src;
{
while ((*dst++ = *src++))
;
}
-void db_search(); /*forward*/
/*
* Search for a value in memory.
* Syntax: search [/bhl] addr value [mask] [,count] [thread]
*/
void
-db_search_cmd()
+db_search_cmd(void)
{
int t;
db_addr_t addr;
@@ -360,7 +354,7 @@ db_search_cmd()
db_addr_t count;
thread_t thread;
boolean_t thread_flag = FALSE;
- register char *p;
+ char *p;
t = db_read_token();
if (t == tSLASH) {
@@ -395,7 +389,7 @@ db_search_cmd()
size = sizeof(int);
}
- if (!db_expression(&addr)) {
+ if (!db_expression((db_expr_t *)&addr)) {
db_printf("Address missing\n");
db_flush_lex();
return;
@@ -412,7 +406,7 @@ db_search_cmd()
t = db_read_token();
if (t == tCOMMA) {
- if (!db_expression(&count)) {
+ if (!db_expression((db_expr_t *)&count)) {
db_printf("Count missing\n");
db_flush_lex();
return;
@@ -431,18 +425,17 @@ db_search_cmd()
}
void
-db_search(addr, size, value, mask, count, task)
- register
- db_addr_t addr;
- int size;
- db_expr_t value;
- db_expr_t mask;
- unsigned int count;
- task_t task;
+db_search(
+ db_addr_t addr,
+ int size,
+ db_expr_t value,
+ db_expr_t mask,
+ unsigned int count,
+ task_t task)
{
while (count-- != 0) {
db_prev = addr;
- if ((db_get_task_value(addr,size,FALSE,task) & mask) == value)
+ if ((db_get_task_value(addr, size, FALSE, task) & mask) == value)
break;
addr += size;
}
@@ -452,13 +445,13 @@ db_search(addr, size, value, mask, count, task)
#define DB_XCDUMP_NC 16
int
-db_xcdump(addr, size, count, task)
- db_addr_t addr;
- int size;
- int count;
- task_t task;
+db_xcdump(
+ db_addr_t addr,
+ int size,
+ int count,
+ task_t task)
{
- register int i, n;
+ int i, n;
db_expr_t value;
int bcount;
db_addr_t off;
diff --git a/ddb/db_examine.h b/ddb/db_examine.h
index 96ad7194..df578a02 100644
--- a/ddb/db_examine.h
+++ b/ddb/db_examine.h
@@ -29,18 +29,54 @@ extern void db_examine_cmd (
db_expr_t addr,
int have_addr,
db_expr_t count,
- char *modif);
+ const char *modif);
-extern void db_strcpy (char *dst, char *src);
+extern void db_strcpy (char *dst, const char *src);
extern void db_examine (
db_addr_t addr,
- char *fmt,
+ const char *fmt,
int count,
task_t task);
+void db_examine_forward(
+ db_expr_t addr,
+ int have_addr,
+ db_expr_t count,
+ const char * modif);
+
+void db_examine_backward(
+ db_expr_t addr,
+ int have_addr,
+ db_expr_t count,
+ const char * modif);
+
extern void db_print_loc_and_inst (
db_addr_t loc,
task_t task);
+int db_xcdump(
+ db_addr_t addr,
+ int size,
+ int count,
+ task_t task);
+
+void db_print_cmd(void);
+
+void db_search_cmd(void);
+
+void db_search(
+ db_addr_t addr,
+ int size,
+ db_expr_t value,
+ db_expr_t mask,
+ unsigned int count,
+ task_t task);
+
+/* instruction disassembler */
+extern db_addr_t db_disasm(
+ db_addr_t pc,
+ boolean_t altform,
+ task_t task);
+
#endif /* _DDB_DB_EXAMINE_H_ */
diff --git a/ddb/db_expr.c b/ddb/db_expr.c
index 611baa09..c9e6752a 100644
--- a/ddb/db_expr.c
+++ b/ddb/db_expr.c
@@ -41,10 +41,8 @@
#include <ddb/db_variables.h>
#include <kern/task.h>
-
boolean_t
-db_term(valuep)
- db_expr_t *valuep;
+db_term(db_expr_t *valuep)
{
int t;
@@ -95,12 +93,12 @@ db_term(valuep)
int
db_size_option(modif, u_option, t_option)
- char *modif;
+ const char *modif;
boolean_t *u_option;
boolean_t *t_option;
{
- register char *p;
- int size = sizeof(int);
+ const char *p;
+ int size = sizeof(int);
*u_option = FALSE;
*t_option = FALSE;
@@ -127,8 +125,7 @@ db_size_option(modif, u_option, t_option)
}
boolean_t
-db_unary(valuep)
- db_expr_t *valuep;
+db_unary(db_expr_t *valuep)
{
int t;
int size;
@@ -177,10 +174,9 @@ db_unary(valuep)
}
boolean_t
-db_mult_expr(valuep)
- db_expr_t *valuep;
+db_mult_expr(db_expr_t *valuep)
{
- db_expr_t lhs, rhs;
+ db_expr_t lhs = 0, rhs;
int t;
char c;
@@ -223,8 +219,7 @@ db_mult_expr(valuep)
}
boolean_t
-db_add_expr(valuep)
- db_expr_t *valuep;
+db_add_expr(db_expr_t *valuep)
{
db_expr_t lhs, rhs;
int t;
@@ -255,8 +250,7 @@ db_add_expr(valuep)
}
boolean_t
-db_shift_expr(valuep)
- db_expr_t *valuep;
+db_shift_expr(db_expr_t *valuep)
{
db_expr_t lhs, rhs;
int t;
@@ -290,8 +284,7 @@ db_shift_expr(valuep)
}
boolean_t
-db_logical_relation_expr(valuep)
- db_expr_t *valuep;
+db_logical_relation_expr(db_expr_t *valuep)
{
db_expr_t lhs, rhs;
int t;
@@ -340,8 +333,7 @@ db_logical_relation_expr(valuep)
}
boolean_t
-db_logical_and_expr(valuep)
- db_expr_t *valuep;
+db_logical_and_expr(db_expr_t *valuep)
{
db_expr_t lhs, rhs;
int t;
@@ -363,8 +355,7 @@ db_logical_and_expr(valuep)
}
boolean_t
-db_logical_or_expr(valuep)
- db_expr_t *valuep;
+db_logical_or_expr(db_expr_t *valuep)
{
db_expr_t lhs, rhs;
int t;
@@ -386,8 +377,7 @@ db_logical_or_expr(valuep)
}
int
-db_expression(valuep)
- db_expr_t *valuep;
+db_expression(db_expr_t *valuep)
{
return (db_logical_or_expr(valuep));
}
diff --git a/ddb/db_expr.h b/ddb/db_expr.h
index 989b66be..9c304e69 100644
--- a/ddb/db_expr.h
+++ b/ddb/db_expr.h
@@ -17,7 +17,7 @@
*/
int db_size_option(
- char *modif,
+ const char *modif,
boolean_t *u_option,
boolean_t *t_option);
diff --git a/ddb/db_ext_symtab.c b/ddb/db_ext_symtab.c
index 24342971..cafb0c4c 100644
--- a/ddb/db_ext_symtab.c
+++ b/ddb/db_ext_symtab.c
@@ -33,6 +33,7 @@
#include <mach/vm_param.h>
#include <vm/vm_map.h>
#include <vm/vm_kern.h>
+#include <vm/vm_user.h>
#include <kern/host.h>
#include <kern/task.h>
#include <ddb/db_sym.h>
@@ -45,12 +46,12 @@
* the caller and the kernel debugger agree on its format.
*/
kern_return_t
-host_load_symbol_table(host, task, name, symtab, symtab_count)
- host_t host;
- task_t task;
- char * name;
- pointer_t symtab;
- unsigned int symtab_count;
+host_load_symbol_table(
+ host_t host,
+ task_t task,
+ char * name,
+ pointer_t symtab,
+ unsigned int symtab_count)
{
kern_return_t result;
vm_offset_t symtab_start;
diff --git a/ddb/db_input.c b/ddb/db_input.c
index ce6a3103..6b6db764 100644
--- a/ddb/db_input.c
+++ b/ddb/db_input.c
@@ -32,6 +32,7 @@
#include <mach/boolean.h>
#include <machine/db_machdep.h>
+#include <device/cons.h>
#include <ddb/db_command.h>
#include <ddb/db_input.h>
#include <ddb/db_output.h>
@@ -68,8 +69,8 @@ char * db_history_prev = (char *) 0; /* start of previous line */
void
db_putstring(s, count)
- char *s;
- int count;
+ const char *s;
+ int count;
{
while (--count >= 0)
cnputc(*s++);
@@ -90,11 +91,11 @@ db_putnchars(c, count)
#define DEL_FWD 0
#define DEL_BWD 1
void
-db_delete(n, bwd)
- int n;
- int bwd;
+db_delete(
+ int n,
+ int bwd)
{
- register char *p;
+ char *p;
if (bwd) {
db_lc -= n;
@@ -110,7 +111,7 @@ db_delete(n, bwd)
}
void
-db_delete_line()
+db_delete_line(void)
{
db_delete(db_le - db_lc, DEL_FWD);
db_delete(db_lc - db_lbuf_start, DEL_BWD);
@@ -132,12 +133,11 @@ db_delete_line()
db_history_curr = db_history + \
db_history_size - 1; \
} while (0)
-#endif
+#endif /* DB_HISTORY_SIZE */
/* returns TRUE at end-of-line */
boolean_t
-db_inputchar(c)
- int c;
+db_inputchar(int c)
{
switch (c) {
case CTRL('b'):
@@ -213,7 +213,7 @@ db_inputchar(c)
INC_DB_CURR();
db_le = db_lc = db_lbuf_start;
} else {
- register char *p;
+ char *p;
INC_DB_CURR();
for (p = db_history_curr, db_le = db_lbuf_start;
*p; ) {
@@ -236,7 +236,7 @@ db_inputchar(c)
INC_DB_CURR();
db_delete_line();
if (db_history_curr != db_history_last) {
- register char *p;
+ char *p;
for (p = db_history_curr,
db_le = db_lbuf_start; *p;) {
*db_le++ = *p++;
@@ -250,7 +250,7 @@ db_inputchar(c)
db_putstring(db_lbuf_start, db_le - db_lbuf_start);
}
break;
-#endif
+#endif /* DB_HISTORY_SIZE */
case CTRL('r'):
db_putstring("^R\n", 3);
if (db_le > db_lbuf_start) {
@@ -267,7 +267,7 @@ db_inputchar(c)
* save it.
*/
if (db_history_curr == db_history_prev) {
- register char *pp, *pc;
+ char *pp, *pc;
/*
* Is it the same?
@@ -291,7 +291,7 @@ db_inputchar(c)
}
}
if (db_le != db_lbuf_start) {
- register char *p;
+ char *p;
db_history_prev = db_history_last;
for (p = db_lbuf_start; p != db_le; p++) {
*db_history_last++ = *p;
@@ -303,7 +303,7 @@ db_inputchar(c)
*db_history_last++ = '\0';
}
db_history_curr = db_history_last;
-#endif
+#endif /* DB_HISTORY_SIZE */
*db_le++ = c;
return (TRUE);
default:
@@ -311,7 +311,7 @@ db_inputchar(c)
cnputc('\007');
}
else if (c >= ' ' && c <= '~') {
- register char *p;
+ char *p;
for (p = db_le; p > db_lc; p--)
*p = *(p-1);
@@ -327,9 +327,9 @@ db_inputchar(c)
}
int
-db_readline(lstart, lsize)
- char * lstart;
- int lsize;
+db_readline(
+ char * lstart,
+ int lsize)
{
db_force_whitespace(); /* synch output position */
@@ -348,9 +348,9 @@ db_readline(lstart, lsize)
}
void
-db_check_interrupt()
+db_check_interrupt(void)
{
- register int c;
+ int c;
c = cnmaygetc();
switch (c) {
diff --git a/ddb/db_input.h b/ddb/db_input.h
index 316e3268..77f07bb6 100644
--- a/ddb/db_input.h
+++ b/ddb/db_input.h
@@ -25,4 +25,6 @@
extern int db_readline (char *lstart, int lsize);
+extern void db_check_interrupt(void);
+
#endif /* _DDB_DB_INPUT_H_ */
diff --git a/ddb/db_lex.c b/ddb/db_lex.c
index ebffe062..8ab69106 100644
--- a/ddb/db_lex.c
+++ b/ddb/db_lex.c
@@ -50,7 +50,7 @@ db_expr_t db_look_token = 0;
int
db_read_line(repeat_last)
- char *repeat_last;
+ const char *repeat_last;
{
int i;
@@ -82,9 +82,9 @@ db_flush_line(void)
}
void
-db_switch_input(buffer, size)
- char *buffer;
- int size;
+db_switch_input(
+ char *buffer,
+ int size)
{
db_lp = buffer;
db_last_lp = db_lp;
@@ -94,8 +94,7 @@ db_switch_input(buffer, size)
}
void
-db_save_lex_context(lp)
- register struct db_lex_context *lp;
+db_save_lex_context(struct db_lex_context *lp)
{
lp->l_ptr = db_lp;
lp->l_eptr = db_endlp;
@@ -105,7 +104,7 @@ db_save_lex_context(lp)
void
db_restore_lex_context(lp)
- register struct db_lex_context *lp;
+ const struct db_lex_context *lp;
{
db_lp = lp->l_ptr;
db_last_lp = db_lp;
@@ -131,15 +130,13 @@ db_read_char(void)
}
void
-db_unread_char(c)
- int c;
+db_unread_char(int c)
{
db_look_char = c;
}
void
-db_unread_token(t)
- int t;
+db_unread_token(int t)
{
db_look_token = t;
}
@@ -179,10 +176,10 @@ db_flush_lex(void)
void
db_skip_to_eol(void)
{
- register int skip;
- register int t;
- register int n;
- register char *p;
+ int skip;
+ int t;
+ int n;
+ char *p;
t = db_read_token();
p = db_last_lp;
@@ -205,8 +202,8 @@ db_skip_to_eol(void)
int
db_lex(void)
{
- register char *cp;
- register int c;
+ char *cp;
+ int c;
c = db_read_char();
while (c <= ' ' || c > '~') {
diff --git a/ddb/db_lex.h b/ddb/db_lex.h
index dc9da0a9..f7677df8 100644
--- a/ddb/db_lex.h
+++ b/ddb/db_lex.h
@@ -31,6 +31,9 @@
* Lexical analyzer.
*/
+#ifndef _DDB_DB_LEX_H_
+#define _DDB_DB_LEX_H_
+
#define TOK_STRING_SIZE 64
#define DB_LEX_LINE_SIZE 256
@@ -42,7 +45,7 @@ struct db_lex_context {
};
extern int db_lex(void);
-extern int db_read_line(char *rep_str);
+extern int db_read_line(const char *rep_str);
extern void db_flush_line(void);
extern int db_read_char(void);
extern void db_unread_char(int c);
@@ -51,7 +54,7 @@ extern void db_unread_token(int t);
extern void db_flush_lex(void);
extern void db_switch_input(char *, int);
extern void db_save_lex_context(struct db_lex_context *);
-extern void db_restore_lex_context(struct db_lex_context *);
+extern void db_restore_lex_context(const struct db_lex_context *);
extern void db_skip_to_eol(void);
extern db_expr_t db_tok_number;
@@ -92,3 +95,5 @@ extern db_expr_t db_radix;
#define tLOG_OR 31
#define tSTRING 32
#define tQUESTION 33
+
+#endif /* _DDB_DB_LEX_H_ */
diff --git a/ddb/db_macro.c b/ddb/db_macro.c
index 43bb5837..307b7c59 100644
--- a/ddb/db_macro.c
+++ b/ddb/db_macro.c
@@ -59,9 +59,9 @@ db_expr_t db_macro_args[DB_MACRO_LEVEL][DB_NARGS];
static struct db_user_macro *
db_lookup_macro(name)
- char *name;
+ const char *name;
{
- register struct db_user_macro *mp;
+ struct db_user_macro *mp;
for (mp = db_user_macro; mp < &db_user_macro[DB_NUSER_MACRO]; mp++) {
if (mp->m_name[0] == 0)
@@ -73,11 +73,11 @@ db_lookup_macro(name)
}
void
-db_def_macro_cmd()
+db_def_macro_cmd(void)
{
- register char *p;
- register int c;
- register struct db_user_macro *mp, *ep;
+ char *p;
+ int c;
+ struct db_user_macro *mp, *ep;
if (db_read_token() != tIDENT) {
db_printf("Bad macro name \"%s\"\n", db_tok_string);
@@ -104,9 +104,9 @@ db_def_macro_cmd()
}
void
-db_del_macro_cmd()
+db_del_macro_cmd(void)
{
- register struct db_user_macro *mp;
+ struct db_user_macro *mp;
if (db_read_token() != tIDENT
|| (mp = db_lookup_macro(db_tok_string)) == 0) {
@@ -120,9 +120,9 @@ db_del_macro_cmd()
}
void
-db_show_macro()
+db_show_macro(void)
{
- register struct db_user_macro *mp;
+ struct db_user_macro *mp;
int t;
char *name = 0;
@@ -141,10 +141,10 @@ db_show_macro()
int
db_exec_macro(name)
- char *name;
+ const char *name;
{
- register struct db_user_macro *mp;
- register int n;
+ struct db_user_macro *mp;
+ int n;
if ((mp = db_lookup_macro(name)) == 0)
return(-1);
@@ -165,13 +165,13 @@ db_exec_macro(name)
return(0);
}
-long
+void
/* ARGSUSED */
-db_arg_variable(vp, valuep, flag, ap)
- struct db_variable *vp;
- db_expr_t *valuep;
- int flag;
- db_var_aux_param_t ap;
+db_arg_variable(
+ struct db_variable *vp,
+ db_expr_t *valuep,
+ int flag,
+ db_var_aux_param_t ap)
{
if (ap->level != 1 || ap->suffix[0] < 1 || ap->suffix[0] > DB_NARGS) {
db_error("Bad $arg variable\n");
@@ -181,7 +181,7 @@ db_arg_variable(vp, valuep, flag, ap)
*valuep = db_macro_args[db_macro_level][ap->suffix[0]-1];
else
db_macro_args[db_macro_level][ap->suffix[0]-1] = *valuep;
- return(0);
+ return;
}
#endif /* MACH_KDB */
diff --git a/ddb/db_macro.h b/ddb/db_macro.h
index da5626f9..2c0a599b 100644
--- a/ddb/db_macro.h
+++ b/ddb/db_macro.h
@@ -30,9 +30,9 @@ extern void db_del_macro_cmd (void);
extern void db_show_macro (void);
-extern int db_exec_macro (char *name);
+extern int db_exec_macro (const char *name);
-extern long db_arg_variable (
+extern void db_arg_variable (
struct db_variable *vp,
db_expr_t *valuep,
int flag,
diff --git a/ddb/db_mp.c b/ddb/db_mp.c
index cc14aea2..8d1a5605 100644
--- a/ddb/db_mp.c
+++ b/ddb/db_mp.c
@@ -38,6 +38,7 @@
#include <ddb/db_command.h>
#include <ddb/db_run.h>
+#include <ddb/db_mp.h>
/*
* Routines to interlock access to the kernel debugger on
@@ -52,12 +53,7 @@ int db_active[NCPUS] = { 0 }; /* count recursive entries
int db_slave[NCPUS] = { 0 }; /* nonzero if cpu interrupted
by another cpu in debugger */
-int db_enter_debug = 0;
-
-void remote_db(); /* forward */
-void lock_db();
-void unlock_db();
-
+boolean_t db_enter_debug = FALSE;
/*
* Called when entering kernel debugger.
@@ -67,7 +63,7 @@ void unlock_db();
*/
boolean_t
-db_enter()
+db_enter(void)
{
int mycpu = cpu_number();
@@ -112,7 +108,7 @@ db_enter()
* Leave debugger.
*/
void
-db_leave()
+db_leave(void)
{
int mycpu = cpu_number();
@@ -147,9 +143,9 @@ db_leave()
*/
void
-remote_db() {
+remote_db(void) {
int my_cpu = cpu_number();
- register int i;
+ int i;
for (i = 0; i < NCPUS; i++) {
if (i != my_cpu &&
@@ -214,8 +210,7 @@ remote_db() {
* switch to another cpu
*/
void
-db_on(cpu)
- int cpu;
+db_on(int cpu)
{
/*
* Save ddb global variables
@@ -254,7 +249,7 @@ db_on(cpu)
* in kernel debugger and wants to stop other CPUs
*/
void
-remote_db_enter()
+remote_db_enter(void)
{
db_slave[cpu_number()]++;
kdb_kintr();
@@ -271,7 +266,7 @@ remote_db_enter()
* is active on another cpu.
*/
void
-lock_db()
+lock_db(void)
{
int my_cpu = cpu_number();
@@ -280,7 +275,7 @@ lock_db()
if (my_cpu == master_cpu) {
db_console();
}
-#endif
+#endif /* CONSOLE_ON_MASTER */
if (db_cpu != -1 && db_cpu != my_cpu)
continue;
@@ -292,9 +287,9 @@ lock_db()
else {
simple_lock(&db_lock);
}
-#else
+#else /* CONSOLE_ON_MASTER */
simple_lock(&db_lock);
-#endif
+#endif /* CONSOLE_ON_MASTER */
if (db_cpu == -1 || db_cpu == my_cpu)
break;
simple_unlock(&db_lock);
@@ -302,14 +297,14 @@ lock_db()
}
void
-unlock_db()
+unlock_db(void)
{
simple_unlock(&db_lock);
}
-#ifdef sketch
+#if CONSOLE_ON_MASTER
void
-db_console()
+db_console(void)
{
if (i_bit(CBUS_PUT_CHAR, my_word)) {
volatile u_char c = cbus_ochar;
@@ -330,7 +325,7 @@ db_console()
db_cpu = my_cpu;
}
}
-#endif /* sketch */
+#endif /* CONSOLE_ON_MASTER */
#endif /* NCPUS > 1 */
diff --git a/ddb/db_mp.h b/ddb/db_mp.h
new file mode 100644
index 00000000..722f28c7
--- /dev/null
+++ b/ddb/db_mp.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _DDB_DB_MP_H_
+#define _DDB_DB_MP_H_
+
+void remote_db(void);
+void lock_db(void);
+void unlock_db(void);
+
+#if CONSOLE_ON_MASTER
+void db_console(void);
+#endif /* CONSOLE_ON_MASTER */
+
+#endif /* _DDB_DB_MP_H_ */
diff --git a/ddb/db_output.c b/ddb/db_output.c
index 3ea2caac..be5319d2 100644
--- a/ddb/db_output.c
+++ b/ddb/db_output.c
@@ -38,9 +38,11 @@
#include <stdarg.h>
#include <mach/boolean.h>
#include <machine/db_machdep.h>
+#include <device/cons.h>
#include <ddb/db_command.h>
#include <ddb/db_lex.h>
#include <ddb/db_output.h>
+#include <ddb/db_input.h>
/*
* Character output - tracks position in line.
@@ -73,15 +75,13 @@ int db_tab_stop_width = 8; /* how wide are tab stops? */
int db_max_line = DB_MAX_LINE; /* output max lines */
int db_max_width = DB_MAX_WIDTH; /* output line width */
-extern void db_check_interrupt();
-
/*
* Force pending whitespace.
*/
void
db_force_whitespace(void)
{
- register int last_print, next_tab;
+ int last_print, next_tab;
last_print = db_last_non_space;
while (last_print < db_output_position) {
@@ -99,9 +99,9 @@ db_force_whitespace(void)
}
static void
-db_more()
+db_more(void)
{
- register char *p;
+ char *p;
boolean_t quit_output = FALSE;
for (p = "--db_more--"; *p; p++)
@@ -132,8 +132,7 @@ db_more()
* Output character. Buffer whitespace.
*/
void
-db_putchar(c)
- int c; /* character to output */
+db_putchar(int c) /* character to output */
{
if (db_max_line >= DB_MIN_MAX_LINE && db_output_line >= db_max_line-1)
db_more();
@@ -188,7 +187,7 @@ db_id_putc(char c, vm_offset_t dummy)
/*
* Return output position
*/
-int
+int __attribute__ ((pure))
db_print_position(void)
{
return (db_output_position);
@@ -209,21 +208,6 @@ db_printf(const char *fmt, ...)
{
va_list listp;
-#ifdef db_printf_enter
- db_printf_enter(); /* optional multiP serialization */
-#endif
- va_start(listp, fmt);
- _doprnt(fmt, listp, db_id_putc, db_radix, 0);
- va_end(listp);
-}
-
-/* alternate name */
-
-/*VARARGS1*/
-void
-kdbprintf(const char *fmt, ...)
-{
- va_list listp;
va_start(listp, fmt);
_doprnt(fmt, listp, db_id_putc, db_radix, 0);
va_end(listp);
diff --git a/ddb/db_output.h b/ddb/db_output.h
index 1159c6ba..497ae430 100644
--- a/ddb/db_output.h
+++ b/ddb/db_output.h
@@ -32,9 +32,15 @@
* Printing routines for kernel debugger.
*/
+#ifndef _DDB_DB_OUTPUT_H_
+#define _DDB_DB_OUTPUT_H_
+
extern void db_force_whitespace(void);
-extern int db_print_position(void);
+extern int db_print_position(void) __attribute__ ((pure));
extern void db_end_line(void);
extern void db_printf(const char *fmt, ...);
+/* alternate name */
+#define kdbprintf db_printf
extern void db_putchar(int c);
-extern void kdbprintf(const char *fmt, ...);
+
+#endif /* _DDB_DB_OUTPUT_H_ */
diff --git a/ddb/db_print.c b/ddb/db_print.c
index 5d0f150b..fb4efaad 100644
--- a/ddb/db_print.c
+++ b/ddb/db_print.c
@@ -51,22 +51,23 @@
#include <ddb/db_variables.h>
#include <ddb/db_sym.h>
#include <ddb/db_task_thread.h>
+#include <ddb/db_print.h>
-extern unsigned int db_maxoff;
+extern unsigned long db_maxoff;
/* ARGSUSED */
void
-db_show_regs(addr, have_addr, count, modif)
- db_expr_t addr;
- boolean_t have_addr;
- db_expr_t count;
- char *modif;
+db_show_regs(
+ db_expr_t addr,
+ boolean_t have_addr,
+ db_expr_t count,
+ char *modif)
{
- register struct db_variable *regp;
+ struct db_variable *regp;
db_expr_t value;
db_addr_t offset;
char * name;
- register int i;
+ int i;
struct db_var_aux_param aux_param;
task_t task = TASK_NULL;
@@ -126,10 +127,10 @@ db_show_regs(addr, have_addr, count, modif)
char *
db_thread_stat(thread, status)
- register thread_t thread;
- char *status;
+ const thread_t thread;
+ char *status;
{
- register char *p = status;
+ char *p = status;
*p++ = (thread->state & TH_RUN) ? 'R' : '.';
*p++ = (thread->state & TH_WAIT) ? 'W' : '.';
@@ -143,10 +144,10 @@ db_thread_stat(thread, status)
}
void
-db_print_thread(thread, thread_id, flag)
- thread_t thread;
- int thread_id;
- int flag;
+db_print_thread(
+ thread_t thread,
+ int thread_id,
+ int flag)
{
if (flag & OPTION_USER) {
char status[8];
@@ -193,12 +194,8 @@ db_print_thread(thread, thread_id, flag)
2*sizeof(vm_offset_t), thread);
else
db_printf("(%0*X) ", 2*sizeof(vm_offset_t), thread);
- db_printf("%c%c%c%c%c",
- (thread->state & TH_RUN) ? 'R' : ' ',
- (thread->state & TH_WAIT) ? 'W' : ' ',
- (thread->state & TH_SUSP) ? 'S' : ' ',
- (thread->state & TH_UNINT)? 'N' : ' ',
- db_thread_fp_used(thread) ? 'F' : ' ');
+ char status[8];
+ db_printf("%s", db_thread_stat(thread, status));
if (thread->state & TH_SWAPPED) {
if (thread->swap_func) {
db_printf("(");
@@ -219,10 +216,10 @@ db_print_thread(thread, thread_id, flag)
}
void
-db_print_task(task, task_id, flag)
- task_t task;
- int task_id;
- int flag;
+db_print_task(
+ task_t task,
+ int task_id,
+ int flag)
{
thread_t thread;
int thread_id;
@@ -257,7 +254,12 @@ db_print_task(task, task_id, flag)
} else {
if (flag & OPTION_TASK_TITLE)
db_printf(" TASK THREADS\n");
- db_printf("%3d (%0*X): ", task_id, 2*sizeof(vm_offset_t), task);
+ if (task->name[0])
+ db_printf("%3d %s (%0*X): ", task_id, task->name,
+ 2*sizeof(vm_offset_t), task);
+ else
+ db_printf("%3d (%0*X): ", task_id,
+ 2*sizeof(vm_offset_t), task);
if (task->thread_count == 0) {
db_printf("no threads\n");
} else {
@@ -274,13 +276,37 @@ db_print_task(task, task_id, flag)
}
}
+void
+db_show_all_tasks(db_expr_t addr,
+ boolean_t have_addr,
+ db_expr_t count,
+ const char *modif)
+{
+ task_t task;
+ int task_id = 0;
+ processor_set_t pset;
+
+ db_printf(" ID %-*s NAME [THREADS]\n", 2*sizeof(vm_offset_t), "TASK");
+
+ queue_iterate(&all_psets, pset, processor_set_t, all_psets)
+ queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
+ db_printf("%3d %0*X %s [%d]\n",
+ task_id,
+ 2*sizeof(vm_offset_t),
+ task,
+ task->name,
+ task->thread_count);
+ task_id++;
+ }
+}
+
/*ARGSUSED*/
void
db_show_all_threads(addr, have_addr, count, modif)
db_expr_t addr;
boolean_t have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
task_t task;
int task_id;
@@ -331,7 +357,7 @@ db_show_one_thread(addr, have_addr, count, modif)
db_expr_t addr;
boolean_t have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
int flag;
int thread_id;
@@ -377,7 +403,7 @@ db_show_one_task(addr, have_addr, count, modif)
db_expr_t addr;
boolean_t have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
int flag;
int task_id;
@@ -409,41 +435,33 @@ db_show_one_task(addr, have_addr, count, modif)
int
db_port_iterate(thread, func)
- thread_t thread;
+ const thread_t thread;
void (*func)();
{
ipc_entry_t entry;
- int index;
int n = 0;
- int size;
- ipc_space_t space;
-
- space = thread->task->itk_space;
- entry = space->is_table;
- size = space->is_table_size;
- for (index = 0; index < size; index++, entry++) {
+ struct rdxtree_iter iter;
+ rdxtree_for_each(&thread->task->itk_space->is_map, &iter, entry) {
if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
- (*func)(index, (ipc_port_t) entry->ie_object,
+ (*func)(entry->ie_name, (ipc_port_t) entry->ie_object,
entry->ie_bits, n++);
}
return(n);
}
ipc_port_t
-db_lookup_port(thread, id)
- thread_t thread;
- int id;
+db_lookup_port(
+ thread_t thread,
+ int id)
{
- register ipc_space_t space;
- register ipc_entry_t entry;
+ ipc_entry_t entry;
if (thread == THREAD_NULL)
return(0);
- space = thread->task->itk_space;
- if (id < 0 || id >= space->is_table_size)
+ if (id < 0)
return(0);
- entry = &space->is_table[id];
- if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
+ entry = ipc_entry_lookup(thread->task->itk_space, (mach_port_t) id);
+ if (entry && entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
return((ipc_port_t)entry->ie_object);
return(0);
}
@@ -451,7 +469,7 @@ db_lookup_port(thread, id)
static void
db_print_port_id(id, port, bits, n)
int id;
- ipc_port_t port;
+ const ipc_port_t port;
unsigned bits;
int n;
{
@@ -465,7 +483,7 @@ db_print_port_id(id, port, bits, n)
static void
db_print_port_id_long(
int id,
- ipc_port_t port,
+ const ipc_port_t port,
unsigned bits,
int n)
{
@@ -483,7 +501,7 @@ db_show_port_id(addr, have_addr, count, modif)
db_expr_t addr;
boolean_t have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
thread_t thread;
diff --git a/ddb/db_print.h b/ddb/db_print.h
index 634c5be4..87db97be 100644
--- a/ddb/db_print.h
+++ b/ddb/db_print.h
@@ -20,91 +20,38 @@ void db_show_regs(
db_expr_t count,
char *modif);
-void db_show_all_acts(
- db_expr_t addr,
- boolean_t have_addr,
- db_expr_t count,
- char * modif);
-
-void db_show_one_act(
- db_expr_t addr,
- boolean_t have_addr,
- db_expr_t count,
- char * modif);
-
void db_show_one_task(
db_expr_t addr,
boolean_t have_addr,
db_expr_t count,
- char * modif);
-
-void db_show_shuttle(
- db_expr_t addr,
- boolean_t have_addr,
- db_expr_t count,
- char * modif);
+ const char * modif);
void db_show_port_id(
db_expr_t addr,
boolean_t have_addr,
db_expr_t count,
- char * modif);
+ const char * modif);
-void db_show_one_task_vm(
+void db_show_one_thread(
db_expr_t addr,
- boolean_t have_addr,
+ int have_addr,
db_expr_t count,
- char *modif);
+ const char * modif);
-void db_show_all_task_vm(
+void db_show_all_tasks(
db_expr_t addr,
- boolean_t have_addr,
+ int have_addr,
db_expr_t count,
- char *modif);
+ const char * modif);
-void db_show_one_space(
+void db_show_all_threads(
db_expr_t addr,
- boolean_t have_addr,
+ int have_addr,
db_expr_t count,
- char * modif);
-
-void db_show_all_spaces(
- db_expr_t addr,
- boolean_t have_addr,
- db_expr_t count,
- char * modif);
-
-void db_sys(void);
-
-int db_port_kmsg_count(
- ipc_port_t port);
+ const char * modif);
db_addr_t db_task_from_space(
ipc_space_t space,
int *task_id);
-void db_show_one_simple_lock(
- db_expr_t addr,
- boolean_t have_addr,
- db_expr_t count,
- char * modif);
-
-void db_show_one_mutex(
- db_expr_t addr,
- boolean_t have_addr,
- db_expr_t count,
- char * modif);
-
-void db_show_subsystem(
- db_expr_t addr,
- boolean_t have_addr,
- db_expr_t count,
- char * modif);
-
-void db_show_runq(
- db_expr_t addr,
- boolean_t have_addr,
- db_expr_t count,
- char * modif);
-
#endif /* !_DDB_DB_PRINT_H_ */
diff --git a/ddb/db_run.c b/ddb/db_run.c
index 53a02ce1..9b467fc4 100644
--- a/ddb/db_run.c
+++ b/ddb/db_run.c
@@ -59,24 +59,13 @@ int db_last_inst_count;
int db_load_count;
int db_store_count;
-#ifndef db_set_single_step
-void db_set_task_single_step(/* db_regs_t *, task_t */);/* forward */
-#else
-#define db_set_task_single_step(regs,task) db_set_single_step(regs)
-#endif
-#ifndef db_clear_single_step
-void db_clear_task_single_step(/* db_regs_t *, task_t */);
-#else
-#define db_clear_task_single_step(regs,task) db_clear_single_step(regs)
-#endif
-
boolean_t
-db_stop_at_pc(is_breakpoint, task)
- boolean_t *is_breakpoint;
- task_t task;
+db_stop_at_pc(
+ boolean_t *is_breakpoint,
+ task_t task)
{
- register db_addr_t pc;
- register db_thread_breakpoint_t bkpt;
+ db_addr_t pc;
+ db_thread_breakpoint_t bkpt;
db_clear_task_single_step(DDB_REGS, task);
db_clear_breakpoints();
@@ -92,7 +81,7 @@ db_stop_at_pc(is_breakpoint, task)
FIXUP_PC_AFTER_BREAK
pc = PC_REGS(DDB_REGS);
}
-#endif
+#endif /* FIXUP_PC_AFTER_BREAK */
/*
* Now check for a breakpoint at this address.
@@ -131,7 +120,7 @@ db_stop_at_pc(is_breakpoint, task)
(!inst_return(ins) || --db_call_depth != 0)) {
if (db_sstep_print) {
if (inst_call(ins) || inst_return(ins)) {
- register int i;
+ int i;
db_printf("[after %6d /%4d] ",
db_inst_count,
@@ -167,32 +156,32 @@ db_stop_at_pc(is_breakpoint, task)
}
void
-db_restart_at_pc(watchpt, task)
- boolean_t watchpt;
- task_t task;
+db_restart_at_pc(
+ boolean_t watchpt,
+ task_t task)
{
- register db_addr_t pc = PC_REGS(DDB_REGS), brpc;
+ db_addr_t pc = PC_REGS(DDB_REGS);
if ((db_run_mode == STEP_COUNT) ||
(db_run_mode == STEP_RETURN) ||
(db_run_mode == STEP_CALLT)) {
- db_expr_t ins;
/*
* We are about to execute this instruction,
* so count it now.
*/
- ins = db_get_task_value(pc, sizeof(int), FALSE, task);
+ db_get_task_value(pc, sizeof(int), FALSE, task);
db_inst_count++;
db_load_count += inst_load(ins);
db_store_count += inst_store(ins);
#ifdef SOFTWARE_SSTEP
+ db_addr_t brpc;
/* Account for instructions in delay slots */
- brpc = next_instr_address(pc,1,task);
+ brpc = next_instr_address(pc, 1, task);
if ((brpc != pc) && (inst_branch(ins) || inst_call(ins))) {
/* Note: this ~assumes an instruction <= sizeof(int) */
- ins = db_get_task_value(brpc, sizeof(int), FALSE, task);
+ db_get_task_value(brpc, sizeof(int), FALSE, task);
db_inst_count++;
db_load_count += inst_load(ins);
db_store_count += inst_store(ins);
@@ -217,9 +206,9 @@ db_restart_at_pc(watchpt, task)
}
void
-db_single_step(regs, task)
- db_regs_t *regs;
- task_t task;
+db_single_step(
+ db_regs_t *regs,
+ task_t task)
{
if (db_run_mode == STEP_CONTINUE) {
db_run_mode = STEP_INVISIBLE;
@@ -260,10 +249,10 @@ db_single_step(regs, task)
db_breakpoint_t db_not_taken_bkpt = 0;
db_breakpoint_t db_taken_bkpt = 0;
-db_breakpoint_t
+db_breakpoint_t __attribute__ ((pure))
db_find_temp_breakpoint(task, addr)
- task_t task;
- db_addr_t addr;
+ const task_t task;
+ db_addr_t addr;
{
if (db_taken_bkpt && (db_taken_bkpt->address == addr) &&
db_taken_bkpt->task == task)
@@ -275,13 +264,13 @@ db_find_temp_breakpoint(task, addr)
}
void
-db_set_task_single_step(regs, task)
- register db_regs_t *regs;
- task_t task;
+db_set_task_single_step(
+ db_regs_t *regs,
+ task_t task)
{
db_addr_t pc = PC_REGS(regs), brpc;
- register unsigned int inst;
- register boolean_t unconditional;
+ unsigned int inst;
+ boolean_t unconditional;
/*
* User was stopped at pc, e.g. the instruction
@@ -321,8 +310,8 @@ db_set_task_single_step(regs, task)
void
db_clear_task_single_step(regs, task)
- db_regs_t *regs;
- task_t task;
+ const db_regs_t *regs;
+ task_t task;
{
if (db_taken_bkpt != 0) {
db_delete_temp_breakpoint(task, db_taken_bkpt);
@@ -346,7 +335,7 @@ db_single_step_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
boolean_t print = FALSE;
@@ -374,7 +363,7 @@ db_trace_until_call_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
boolean_t print = FALSE;
@@ -397,7 +386,7 @@ db_trace_until_matching_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
boolean_t print = FALSE;
@@ -422,7 +411,7 @@ db_continue_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
if (modif[0] == 'c')
db_run_mode = STEP_COUNT;
@@ -437,7 +426,7 @@ db_continue_cmd(addr, have_addr, count, modif)
}
boolean_t
-db_in_single_step()
+db_in_single_step(void)
{
return(db_run_mode != STEP_NONE && db_run_mode != STEP_CONTINUE);
}
diff --git a/ddb/db_run.h b/ddb/db_run.h
index 31c0e376..c042d4ca 100644
--- a/ddb/db_run.h
+++ b/ddb/db_run.h
@@ -24,6 +24,9 @@
* the rights to redistribute these changes.
*/
+#ifndef _DDB_DB_RUN_H_
+#define _DDB_DB_RUN_H_
+
#include <kern/task.h>
#include <machine/db_machdep.h>
@@ -43,8 +46,49 @@ extern void db_single_step(db_regs_t *regs, task_t task);
extern void db_single_step_cmd(
db_expr_t addr,
- int have_addr,
+ int have_addr,
+ db_expr_t count,
+ const char *modif);
+
+void db_trace_until_call_cmd(
+ db_expr_t addr,
+ int have_addr,
+ db_expr_t count,
+ const char * modif);
+
+void db_trace_until_matching_cmd(
+ db_expr_t addr,
+ int have_addr,
db_expr_t count,
- char *modif);
+ const char * modif);
+
+void db_continue_cmd(
+ db_expr_t addr,
+ int have_addr,
+ db_expr_t count,
+ const char * modif);
+
+#ifndef db_set_single_step
+void db_set_task_single_step(db_regs_t *, task_t);
+#else
+#define db_set_task_single_step(regs, task) db_set_single_step(regs)
+#endif
+#ifndef db_clear_single_step
+void db_clear_task_single_step(const db_regs_t *, task_t);
+#else
+#define db_clear_task_single_step(regs, task) db_clear_single_step(regs)
+#endif
extern boolean_t db_in_single_step(void);
+
+extern void
+db_restart_at_pc(
+ boolean_t watchpt,
+ task_t task);
+
+extern boolean_t
+db_stop_at_pc(
+ boolean_t *is_breakpoint,
+ task_t task);
+
+#endif /* _DDB_DB_RUN_H_ */
diff --git a/ddb/db_sym.c b/ddb/db_sym.c
index 5c5f7006..2abd5746 100644
--- a/ddb/db_sym.c
+++ b/ddb/db_sym.c
@@ -37,6 +37,8 @@
#include <ddb/db_output.h>
#include <ddb/db_sym.h>
#include <ddb/db_task_thread.h>
+#include <ddb/db_aout.h>
+#include <ddb/db_elf.h>
#include <vm/vm_map.h> /* vm_map_t */
@@ -50,21 +52,19 @@ int db_nsymtab = 0;
db_symtab_t *db_last_symtab;
-db_sym_t db_lookup(); /* forward */
-
/*
* Add symbol table, with given name, to list of symbol tables.
*/
boolean_t
-db_add_symbol_table(type, start, end, name, ref, map_pointer)
- int type;
- char *start;
- char *end;
- char *name;
- char *ref;
- char *map_pointer;
+db_add_symbol_table(
+ int type,
+ char *start,
+ char *end,
+ char *name,
+ char *ref,
+ char *map_pointer)
{
- register db_symtab_t *st;
+ db_symtab_t *st;
extern vm_map_t kernel_map;
if (db_nsymtab >= MAXNOSYMTABS)
@@ -76,7 +76,8 @@ db_add_symbol_table(type, start, end, name, ref, map_pointer)
st->end = end;
st->private = ref;
st->map_pointer = (map_pointer == (char *)kernel_map)? 0: map_pointer;
- strcpy(st->name, name);
+ strncpy(st->name, name, sizeof st->name - 1);
+ st->name[sizeof st->name - 1] = '\0';
db_nsymtab++;
@@ -89,13 +90,13 @@ db_add_symbol_table(type, start, end, name, ref, map_pointer)
* Note: return value points to static data whose content is
* overwritten by each call... but in practice this seems okay.
*/
-static char *
+static char * __attribute__ ((pure))
db_qualify(symname, symtabname)
- char *symname;
- register char *symtabname;
+ const char *symname;
+ const char *symtabname;
{
static char tmp[256];
- register char *s;
+ char *s;
s = tmp;
while ((*s++ = *symtabname++)) {
@@ -109,7 +110,7 @@ db_qualify(symname, symtabname)
boolean_t
-db_eqname( char* src, char* dst, char c )
+db_eqname( const char* src, const char* dst, char c )
{
if (!strcmp(src, dst))
return (TRUE);
@@ -119,9 +120,9 @@ db_eqname( char* src, char* dst, char c )
}
boolean_t
-db_value_of_name(name, valuep)
- char *name;
- db_expr_t *valuep;
+db_value_of_name(
+ char *name,
+ db_expr_t *valuep)
{
db_sym_t sym;
@@ -141,14 +142,13 @@ db_value_of_name(name, valuep)
* otherwise, all symbol tables will be searched.
*/
db_sym_t
-db_lookup(symstr)
- char *symstr;
+db_lookup(char *symstr)
{
db_sym_t sp;
- register int i;
+ int i;
int symtab_start = 0;
int symtab_end = db_nsymtab;
- register char *cp;
+ char *cp;
/*
* Look for, remove, and remember any symbol table specifier.
@@ -193,13 +193,13 @@ db_lookup(symstr)
* with parsed file name, symbol name and line number.
*/
db_sym_t
-db_sym_parse_and_lookup(func, symtab, symstr)
- db_sym_t (*func)();
- db_symtab_t *symtab;
- char *symstr;
+db_sym_parse_and_lookup(
+ db_sym_t (*func)(),
+ db_symtab_t *symtab,
+ char *symstr)
{
- register char *p;
- register int n;
+ char *p;
+ int n;
int n_name;
int line_number;
char *file_name = 0;
@@ -265,19 +265,17 @@ out:
boolean_t db_qualify_ambiguous_names = FALSE;
boolean_t
-db_name_is_ambiguous(sym_name)
- char *sym_name;
+db_name_is_ambiguous(char *sym_name)
{
- register int i;
- register
+ int i;
boolean_t found_once = FALSE;
if (!db_qualify_ambiguous_names)
return FALSE;
for (i = 0; i < db_nsymtab; i++) {
- db_sym_t sp;
- if (sp = X_db_lookup(&db_symtabs[i], sym_name)) {
+ db_sym_t sp = X_db_lookup(&db_symtabs[i], sym_name);
+ if (sp) {
if (found_once)
{
db_free_symbol(sp);
@@ -290,26 +288,23 @@ db_name_is_ambiguous(sym_name)
return FALSE;
}
-
-db_sym_t db_search_in_task_symbol();
-
/*
* Find the closest symbol to val, and return its name
* and the difference between val and the symbol found.
*
* Logic change. If the task argument is non NULL and a
- * matching symbol is found in a symbol table which explictly
+ * matching symbol is found in a symbol table which explicitly
* specifies its map to be task->map, that symbol will have
* precedence over any symbol from a symbol table will a null
* map. This allows overlapping kernel/user maps to work correctly.
*
*/
db_sym_t
-db_search_task_symbol(val, strategy, offp, task)
- register db_addr_t val;
- db_strategy_t strategy;
- db_addr_t *offp; /* better be unsigned */
- task_t task;
+db_search_task_symbol(
+ db_addr_t val,
+ db_strategy_t strategy,
+ db_addr_t *offp, /* better be unsigned */
+ task_t task)
{
db_sym_t ret;
@@ -334,15 +329,15 @@ db_search_task_symbol(val, strategy, offp, task)
}
db_sym_t
-db_search_in_task_symbol(val, strategy, offp, task)
- register db_addr_t val;
- db_strategy_t strategy;
- db_addr_t *offp;
- task_t task;
+db_search_in_task_symbol(
+ db_addr_t val,
+ db_strategy_t strategy,
+ db_addr_t *offp,
+ task_t task)
{
- register vm_size_t diff;
+ vm_size_t diff;
vm_size_t newdiff;
- register int i;
+ int i;
db_symtab_t *sp;
db_sym_t ret = DB_SYM_NULL, sym;
vm_map_t map_for_val;
@@ -402,11 +397,11 @@ db_search_in_task_symbol(val, strategy, offp, task)
* Return name and value of a symbol
*/
void
-db_symbol_values(stab, sym, namep, valuep)
- db_symtab_t *stab;
- db_sym_t sym;
- char **namep;
- db_expr_t *valuep;
+db_symbol_values(
+ db_symtab_t *stab,
+ db_sym_t sym,
+ char **namep,
+ db_expr_t *valuep)
{
db_expr_t value;
char *name;
@@ -449,7 +444,7 @@ unsigned long db_maxoff = 0x4000;
void
db_task_printsym(off, strategy, task)
- db_expr_t off;
+ db_addr_t off;
db_strategy_t strategy;
task_t task;
{
@@ -494,7 +489,7 @@ db_line_at_pc( sym, filename, linenum, pc)
db_sym_t sym;
char **filename;
int *linenum;
- db_expr_t pc;
+ db_addr_t pc;
{
return (db_last_symtab) ?
X_db_line_at_pc( db_last_symtab, sym, filename, linenum, pc) :
@@ -512,15 +507,11 @@ void db_free_symbol(db_sym_t s)
* Switch into symbol-table specific routines
*/
-extern boolean_t aout_db_sym_init(), aout_db_line_at_pc();
-extern db_sym_t aout_db_lookup(), aout_db_search_symbol();
-extern void aout_db_symbol_values();
-
-extern boolean_t coff_db_sym_init(), coff_db_line_at_pc();
-extern db_sym_t coff_db_lookup(), coff_db_search_symbol();
-extern void coff_db_symbol_values();
+void dummy_db_free_symbol(db_sym_t symbol) { }
+boolean_t dummy_db_sym_init(char *a, char *b, char *c, char *d) {
+ return FALSE;
+}
-void dummy_db_free_symbol(sym_t) { }
struct db_sym_switch x_db[] = {
@@ -532,15 +523,17 @@ struct db_sym_switch x_db[] = {
aout_db_line_at_pc, aout_db_symbol_values, dummy_db_free_symbol },
#endif /* DB_NO_AOUT */
-#ifdef DB_NO_COFF
{ 0,},
-#else /* DB_NO_COFF */
- { coff_db_sym_init, coff_db_lookup, coff_db_search_symbol,
- coff_db_line_at_pc, coff_db_symbol_values, dummy_db_free_symbol },
-#endif /* DB_NO_COFF */
/* Machdep, not inited here */
- { 0,}
+ { 0,},
+
+#ifdef DB_NO_ELF
+ { 0,},
+#else /* DB_NO_ELF */
+ { dummy_db_sym_init, elf_db_lookup, elf_db_search_symbol,
+ elf_db_line_at_pc, elf_db_symbol_values, dummy_db_free_symbol },
+#endif /* DB_NO_ELF */
};
diff --git a/ddb/db_sym.h b/ddb/db_sym.h
index e40264ab..d8f33874 100644
--- a/ddb/db_sym.h
+++ b/ddb/db_sym.h
@@ -46,6 +46,7 @@ typedef struct {
#define SYMTAB_AOUT 0
#define SYMTAB_COFF 1
#define SYMTAB_MACHDEP 2
+#define SYMTAB_ELF 3
char *start; /* symtab location */
char *end;
char *private; /* optional machdep pointer */
@@ -161,10 +162,10 @@ extern void db_symbol_values( db_symtab_t *stab,
db_search_task_symbol(val,strgy,offp,0)
/* strcmp, modulo leading char */
-extern boolean_t db_eqname( char* src, char* dst, char c );
+extern boolean_t db_eqname( const char* src, const char* dst, char c );
/* print closest symbol to a value */
-extern void db_task_printsym( db_expr_t off,
+extern void db_task_printsym( db_addr_t off,
db_strategy_t strategy,
task_t task);
@@ -205,7 +206,7 @@ extern struct db_sym_switch {
db_sym_t sym,
char **file,
int *line,
- db_expr_t pc
+ db_addr_t pc
);
void (*symbol_values)(
@@ -235,6 +236,35 @@ extern boolean_t db_line_at_pc(
db_sym_t sym,
char **filename,
int *linenum,
- db_expr_t pc);
-
-#endif
+ db_addr_t pc);
+
+extern boolean_t aout_db_sym_init(
+ char *symtab,
+ char *esymtab,
+ char *name,
+ char *task_addr);
+
+extern boolean_t elf_db_sym_init (
+ unsigned shdr_num,
+ vm_size_t shdr_size,
+ vm_offset_t shdr_addr,
+ unsigned shdr_shndx,
+ char *name,
+ char *task_addr);
+
+db_sym_t db_lookup(char *);
+
+db_sym_t
+db_search_in_task_symbol(
+ db_addr_t val,
+ db_strategy_t strategy,
+ db_addr_t *offp,
+ task_t task);
+
+extern db_sym_t
+db_sym_parse_and_lookup(
+ db_sym_t (*func)(),
+ db_symtab_t *symtab,
+ char *symstr);
+
+#endif /* _DDB_DB_SYM_H_ */
diff --git a/ddb/db_task_thread.c b/ddb/db_task_thread.c
index 1146223b..7927e674 100644
--- a/ddb/db_task_thread.c
+++ b/ddb/db_task_thread.c
@@ -52,12 +52,12 @@ thread_t db_default_thread; /* default target thread */
*/
int
db_lookup_task(target_task)
- task_t target_task;
+ const task_t target_task;
{
- register task_t task;
- register int task_id;
- register processor_set_t pset;
- register int npset = 0;
+ task_t task;
+ int task_id;
+ processor_set_t pset;
+ int npset = 0;
task_id = 0;
if (queue_first(&all_psets) == 0)
@@ -82,11 +82,11 @@ db_lookup_task(target_task)
*/
int
db_lookup_task_thread(task, target_thread)
- task_t task;
- thread_t target_thread;
+ const task_t task;
+ const thread_t target_thread;
{
- register thread_t thread;
- register int thread_id;
+ thread_t thread;
+ int thread_id;
thread_id = 0;
if (queue_first(&task->thread_list) == 0)
@@ -106,13 +106,13 @@ db_lookup_task_thread(task, target_thread)
*/
int
db_lookup_thread(target_thread)
- thread_t target_thread;
+ const thread_t target_thread;
{
- register int thread_id;
- register task_t task;
- register processor_set_t pset;
- register int ntask = 0;
- register int npset = 0;
+ int thread_id;
+ task_t task;
+ processor_set_t pset;
+ int ntask = 0;
+ int npset = 0;
if (queue_first(&all_psets) == 0)
return(-1);
@@ -139,7 +139,7 @@ db_lookup_thread(target_thread)
*/
boolean_t
db_check_thread_address_valid(thread)
- thread_t thread;
+ const thread_t thread;
{
if (db_lookup_thread(thread) < 0) {
db_printf("Bad thread address 0x%x\n", thread);
@@ -150,15 +150,14 @@ db_check_thread_address_valid(thread)
}
/*
- * convert task_id(queue postion) to task address
+ * convert task_id(queue position) to task address
*/
task_t
-db_lookup_task_id(task_id)
- register int task_id;
+db_lookup_task_id(int task_id)
{
- register task_t task;
- register processor_set_t pset;
- register int npset = 0;
+ task_t task;
+ processor_set_t pset;
+ int npset = 0;
if (task_id > DB_MAX_TASKID)
return(TASK_NULL);
@@ -181,11 +180,11 @@ db_lookup_task_id(task_id)
* convert (task_id, thread_id) pair to thread address
*/
static thread_t
-db_lookup_thread_id(task, thread_id)
- task_t task;
- register int thread_id;
+db_lookup_thread_id(
+ task_t task,
+ int thread_id)
{
- register thread_t thread;
+ thread_t thread;
if (thread_id > DB_MAX_THREADID)
@@ -204,9 +203,9 @@ db_lookup_thread_id(task, thread_id)
* thread address
*/
boolean_t
-db_get_next_thread(threadp, position)
- thread_t *threadp;
- int position;
+db_get_next_thread(
+ thread_t *threadp,
+ int position)
{
db_expr_t value;
thread_t thread;
@@ -245,17 +244,18 @@ db_init_default_thread(void)
* in the command line
*/
/* ARGSUSED */
-long
-db_set_default_thread(vp, valuep, flag)
- struct db_variable *vp;
- db_expr_t *valuep;
- int flag;
+void
+db_set_default_thread(vp, valuep, flag, ap)
+ struct db_variable *vp;
+ db_expr_t *valuep;
+ int flag;
+ db_var_aux_param_t ap;
{
thread_t thread;
if (flag != DB_VAR_SET) {
*valuep = (db_expr_t) db_default_thread;
- return(0);
+ return;
}
thread = (thread_t) *valuep;
if (thread != THREAD_NULL && !db_check_thread_address_valid(thread))
@@ -264,18 +264,18 @@ db_set_default_thread(vp, valuep, flag)
db_default_thread = thread;
if (thread)
db_default_task = thread->task;
- return(0);
+ return;
}
/*
* convert $taskXXX[.YYY] type DDB variable to task or thread address
*/
-long
-db_get_task_thread(vp, valuep, flag, ap)
- struct db_variable *vp;
- db_expr_t *valuep;
- int flag;
- db_var_aux_param_t ap;
+void
+db_get_task_thread(
+ struct db_variable *vp,
+ db_expr_t *valuep,
+ int flag,
+ db_var_aux_param_t ap)
{
task_t task;
thread_t thread;
@@ -291,7 +291,7 @@ db_get_task_thread(vp, valuep, flag, ap)
}
if (ap->level <= 1) {
*valuep = (db_expr_t) task;
- return(0);
+ return;
}
if ((thread = db_lookup_thread_id(task, ap->suffix[1])) == THREAD_NULL){
db_printf("no such thread($task%d.%d)\n",
@@ -300,7 +300,7 @@ db_get_task_thread(vp, valuep, flag, ap)
/* NOTREACHED */
}
*valuep = (db_expr_t) thread;
- return(0);
+ return;
}
#endif /* MACH_KDB */
diff --git a/ddb/db_task_thread.h b/ddb/db_task_thread.h
index ebf99d8d..cbb36802 100644
--- a/ddb/db_task_thread.h
+++ b/ddb/db_task_thread.h
@@ -27,6 +27,8 @@
#ifndef _DDB_DB_TASK_THREAD_H_
#define _DDB_DB_TASK_THREAD_H_
+#include <ddb/db_variables.h>
+
#include <kern/task.h>
#include <kern/thread.h>
@@ -41,11 +43,25 @@
extern task_t db_default_task; /* default target task */
extern thread_t db_default_thread; /* default target thread */
-extern int db_lookup_task(task_t);
-extern int db_lookup_thread(thread_t);
-extern int db_lookup_task_thread(task_t, thread_t);
-extern boolean_t db_check_thread_address_valid(thread_t);
+extern int db_lookup_task(const task_t);
+extern int db_lookup_thread(const thread_t);
+extern int db_lookup_task_thread(const task_t, const thread_t);
+extern boolean_t db_check_thread_address_valid(const thread_t);
extern boolean_t db_get_next_thread(thread_t *, int);
extern void db_init_default_thread(void);
+extern void
+db_set_default_thread(
+ struct db_variable *vp,
+ db_expr_t *valuep,
+ int flag,
+ db_var_aux_param_t ap);
+
+extern void
+db_get_task_thread(
+ struct db_variable *vp,
+ db_expr_t *valuep,
+ int flag,
+ db_var_aux_param_t ap);
+
#endif /* _DDB_DB_TASK_THREAD_H_ */
diff --git a/ddb/db_trap.c b/ddb/db_trap.c
index 395a9b51..7e107319 100644
--- a/ddb/db_trap.c
+++ b/ddb/db_trap.c
@@ -35,6 +35,7 @@
*/
#include <mach/boolean.h>
#include <machine/db_machdep.h>
+#include <machine/setjmp.h>
#include <ddb/db_command.h>
#include <ddb/db_access.h>
#include <ddb/db_break.h>
@@ -42,28 +43,26 @@
#include <ddb/db_output.h>
#include <ddb/db_task_thread.h>
#include <ddb/db_trap.h>
+#include <ddb/db_run.h>
+#include <machine/db_interface.h>
extern jmp_buf_t *db_recover;
-extern void db_restart_at_pc();
-extern boolean_t db_stop_at_pc();
-
extern int db_inst_count;
extern int db_load_count;
extern int db_store_count;
void
-db_task_trap(type, code, user_space)
- int type, code;
- boolean_t user_space;
+db_task_trap(
+ int type,
+ int code,
+ boolean_t user_space)
{
jmp_buf_t db_jmpbuf;
jmp_buf_t *prev;
boolean_t bkpt;
boolean_t watchpt;
- void db_init_default_thread();
- void db_check_breakpoint_valid();
task_t task_space;
task_space = db_target_space(current_thread(), user_space);
@@ -90,6 +89,9 @@ db_task_trap(type, code, user_space)
db_print_loc_and_inst(db_dot, task_space);
else
db_printf("Trouble printing location %#X.\n", db_dot);
+
+ if (!bkpt && !watchpt && _setjmp(db_recover = &db_jmpbuf) == 0)
+ db_stack_trace_cmd(0, 0, -1, "");
db_recover = prev;
db_command_loop();
@@ -99,8 +101,9 @@ db_task_trap(type, code, user_space)
}
void
-db_trap(type, code)
- int type, code;
+db_trap(
+ int type,
+ int code)
{
db_task_trap(type, code, !DB_VALID_KERN_ADDR(PC_REGS(DDB_REGS)));
}
diff --git a/ddb/db_variables.c b/ddb/db_variables.c
index 55b87422..4442ccbc 100644
--- a/ddb/db_variables.c
+++ b/ddb/db_variables.c
@@ -39,6 +39,7 @@
#include <ddb/db_output.h>
#include <ddb/db_variables.h>
#include <ddb/db_task_thread.h>
+#include <ddb/db_macro.h>
extern unsigned long db_maxoff;
@@ -46,9 +47,6 @@ extern db_expr_t db_radix;
extern db_expr_t db_max_width;
extern db_expr_t db_tab_stop_width;
extern db_expr_t db_max_line;
-extern int db_set_default_thread();
-extern int db_get_task_thread();
-extern int db_arg_variable();
#define DB_NWORK 32 /* number of work variable */
@@ -70,12 +68,12 @@ struct db_variable db_vars[] = {
};
struct db_variable *db_evars = db_vars + sizeof(db_vars)/sizeof(db_vars[0]);
-char *
+const char *
db_get_suffix(suffix, suffix_value)
- register char *suffix;
+ const char *suffix;
short *suffix_value;
{
- register int value;
+ int value;
for (value = 0; *suffix && *suffix != '.' && *suffix != ':'; suffix++) {
if (*suffix < '0' || *suffix > '9')
@@ -92,10 +90,11 @@ static boolean_t
db_cmp_variable_name(vp, name, ap)
struct db_variable *vp;
char *name;
- register db_var_aux_param_t ap;
+ const db_var_aux_param_t ap;
{
- register char *var_np, *np;
- register int level;
+ char *var_np;
+ const char *np;
+ int level;
for (np = name, var_np = vp->name; *var_np; ) {
if (*np++ != *var_np++)
@@ -116,9 +115,9 @@ db_cmp_variable_name(vp, name, ap)
}
int
-db_find_variable(varp, ap)
- struct db_variable **varp;
- db_var_aux_param_t ap;
+db_find_variable(
+ struct db_variable **varp,
+ db_var_aux_param_t ap)
{
int t;
struct db_variable *vp;
@@ -143,12 +142,8 @@ db_find_variable(varp, ap)
return (0);
}
-
-void db_read_write_variable(); /* forward */
-
int
-db_get_variable(valuep)
- db_expr_t *valuep;
+db_get_variable(db_expr_t *valuep)
{
struct db_variable *vp;
struct db_var_aux_param aux_param;
@@ -164,8 +159,7 @@ db_get_variable(valuep)
}
int
-db_set_variable(value)
- db_expr_t value;
+db_set_variable(db_expr_t value)
{
struct db_variable *vp;
struct db_var_aux_param aux_param;
@@ -181,13 +175,13 @@ db_set_variable(value)
}
void
-db_read_write_variable(vp, valuep, rw_flag, ap)
- struct db_variable *vp;
- db_expr_t *valuep;
- int rw_flag;
- db_var_aux_param_t ap;
+db_read_write_variable(
+ struct db_variable *vp,
+ db_expr_t *valuep,
+ int rw_flag,
+ db_var_aux_param_t ap)
{
- int (*func)() = vp->fcn;
+ void (*func)() = vp->fcn;
struct db_var_aux_param aux_param;
if (ap == 0) {
@@ -206,7 +200,7 @@ db_read_write_variable(vp, valuep, rw_flag, ap)
}
void
-db_set_cmd()
+db_set_cmd(void)
{
db_expr_t value;
int t;
diff --git a/ddb/db_variables.h b/ddb/db_variables.h
index 5249d18c..9880d50f 100644
--- a/ddb/db_variables.h
+++ b/ddb/db_variables.h
@@ -32,6 +32,7 @@
#define _DB_VARIABLES_H_
#include <kern/thread.h>
+#include <machine/db_machdep.h>
/*
* Debugger variables.
@@ -42,7 +43,7 @@ struct db_variable {
char *name; /* Name of variable */
db_expr_t *valuep; /* pointer to value of variable */
/* function to call when reading/writing */
- long (*fcn)(struct db_variable *, db_expr_t *, int, db_var_aux_param_t);
+ void (*fcn)(struct db_variable *, db_expr_t *, int, db_var_aux_param_t);
short min_level; /* number of minimum suffix levels */
short max_level; /* number of maximum suffix levels */
short low; /* low value of level 1 suffix */
@@ -50,7 +51,7 @@ struct db_variable {
#define DB_VAR_GET 0
#define DB_VAR_SET 1
};
-#define FCN_NULL ((long (*)())0)
+#define FCN_NULL ((void (*)())0)
#define DB_VAR_LEVEL 3 /* maximum number of suffix level */
@@ -80,4 +81,8 @@ extern struct db_variable *db_eregs;
extern int db_get_variable(db_expr_t *valuep);
+void db_set_cmd(void);
+
+void db_read_write_variable(struct db_variable *, db_expr_t *, int, struct db_var_aux_param *);
+
#endif /* _DB_VARIABLES_H_ */
diff --git a/ddb/db_watch.c b/ddb/db_watch.c
index 072f474a..f0d0443f 100644
--- a/ddb/db_watch.c
+++ b/ddb/db_watch.c
@@ -37,6 +37,7 @@
#include <vm/vm_map.h>
#include <machine/db_machdep.h>
+#include <machine/db_interface.h>
#include <ddb/db_command.h>
#include <ddb/db_lex.h>
#include <ddb/db_watch.h>
@@ -64,9 +65,9 @@ db_watchpoint_t db_watchpoint_list = 0;
extern vm_map_t kernel_map;
db_watchpoint_t
-db_watchpoint_alloc()
+db_watchpoint_alloc(void)
{
- register db_watchpoint_t watch;
+ db_watchpoint_t watch;
if ((watch = db_free_watchpoints) != 0) {
db_free_watchpoints = watch->link;
@@ -84,7 +85,7 @@ db_watchpoint_alloc()
void
db_watchpoint_free(watch)
- register db_watchpoint_t watch;
+ db_watchpoint_t watch;
{
watch->link = db_free_watchpoints;
db_free_watchpoints = watch;
@@ -92,11 +93,11 @@ db_watchpoint_free(watch)
void
db_set_watchpoint(task, addr, size)
- task_t task;
+ const task_t task;
db_addr_t addr;
vm_size_t size;
{
- register db_watchpoint_t watch;
+ db_watchpoint_t watch;
/*
* Should we do anything fancy with overlapping regions?
@@ -129,11 +130,11 @@ db_set_watchpoint(task, addr, size)
void
db_delete_watchpoint(task, addr)
- task_t task;
+ const task_t task;
db_addr_t addr;
{
- register db_watchpoint_t watch;
- register db_watchpoint_t *prev;
+ db_watchpoint_t watch;
+ db_watchpoint_t *prev;
for (prev = &db_watchpoint_list; (watch = *prev) != 0;
prev = &watch->link) {
@@ -152,8 +153,8 @@ db_delete_watchpoint(task, addr)
void
db_list_watchpoints(void)
{
- register db_watchpoint_t watch;
- int task_id;
+ db_watchpoint_t watch;
+ int task_id;
if (db_watchpoint_list == 0) {
db_printf("No watchpoints set\n");
@@ -178,7 +179,7 @@ db_list_watchpoints(void)
static int
db_get_task(modif, taskp, addr)
- char *modif;
+ const char *modif;
task_t *taskp;
db_addr_t addr;
{
@@ -220,7 +221,7 @@ db_deletewatch_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
task_t task;
@@ -236,12 +237,11 @@ db_watchpoint_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
vm_size_t size;
db_expr_t value;
task_t task;
- boolean_t db_option();
if (db_get_task(modif, &task, addr) < 0)
return;
@@ -254,7 +254,7 @@ db_watchpoint_cmd(addr, have_addr, count, modif)
/* list watchpoints */
void
-db_listwatch_cmd()
+db_listwatch_cmd(void)
{
db_list_watchpoints();
}
@@ -262,11 +262,16 @@ db_listwatch_cmd()
void
db_set_watchpoints(void)
{
- register db_watchpoint_t watch;
- vm_map_t map;
+ db_watchpoint_t watch;
+ vm_map_t map;
+ unsigned hw_idx = 0;
if (!db_watchpoints_inserted) {
for (watch = db_watchpoint_list; watch != 0; watch = watch->link) {
+ if (db_set_hw_watchpoint(watch, hw_idx)) {
+ hw_idx++;
+ continue;
+ }
map = (watch->task)? watch->task->map: kernel_map;
pmap_protect(map->pmap,
trunc_page(watch->loaddr),
@@ -280,18 +285,23 @@ db_set_watchpoints(void)
void
db_clear_watchpoints(void)
{
+ unsigned hw_idx = 0;
+
+ while (db_clear_hw_watchpoint(hw_idx))
+ hw_idx++;
+
db_watchpoints_inserted = FALSE;
}
boolean_t
-db_find_watchpoint(map, addr, regs)
- vm_map_t map;
- db_addr_t addr;
- db_regs_t *regs;
+db_find_watchpoint(
+ vm_map_t map,
+ db_addr_t addr,
+ db_regs_t *regs)
{
- register db_watchpoint_t watch;
+ db_watchpoint_t watch;
db_watchpoint_t found = 0;
- register task_t task_space;
+ task_t task_space;
task_space = (map == kernel_map)? TASK_NULL: db_current_task();
for (watch = db_watchpoint_list; watch != 0; watch = watch->link) {
diff --git a/ddb/db_watch.h b/ddb/db_watch.h
index a7acb39e..7ef1a207 100644
--- a/ddb/db_watch.h
+++ b/ddb/db_watch.h
@@ -49,14 +49,28 @@ typedef struct db_watchpoint {
} *db_watchpoint_t;
extern boolean_t db_find_watchpoint(vm_map_t map, db_addr_t addr,
- db_regs_t *regs);
+ db_regs_t *regs);
extern void db_set_watchpoints(void);
extern void db_clear_watchpoints(void);
-extern void db_set_watchpoint(task_t task, db_addr_t addr, vm_size_t size);
-extern void db_delete_watchpoint(task_t task, db_addr_t addr);
+extern void db_set_watchpoint(const task_t task, db_addr_t addr, vm_size_t size);
+extern void db_delete_watchpoint(const task_t task, db_addr_t addr);
extern void db_list_watchpoints(void);
+void db_listwatch_cmd(void);
+
+void db_deletewatch_cmd(
+ db_expr_t addr,
+ int have_addr,
+ db_expr_t count,
+ const char * modif);
+
+void db_watchpoint_cmd(
+ db_expr_t addr,
+ int have_addr,
+ db_expr_t count,
+ const char * modif);
+
#endif /* _DDB_DB_WATCH_ */
#endif /* MACH_KDB */
diff --git a/ddb/db_write_cmd.c b/ddb/db_write_cmd.c
index eacf53b4..46a2ee32 100644
--- a/ddb/db_write_cmd.c
+++ b/ddb/db_write_cmd.c
@@ -55,12 +55,12 @@ db_write_cmd(address, have_addr, count, modif)
db_expr_t address;
boolean_t have_addr;
db_expr_t count;
- char * modif;
+ const char * modif;
{
- register db_addr_t addr;
- register db_expr_t old_value;
+ db_addr_t addr;
+ db_expr_t old_value;
db_expr_t new_value;
- register int size;
+ int size;
boolean_t wrote_one = FALSE;
boolean_t t_opt, u_opt;
thread_t thread;
diff --git a/ddb/db_write_cmd.h b/ddb/db_write_cmd.h
new file mode 100644
index 00000000..3a1d0575
--- /dev/null
+++ b/ddb/db_write_cmd.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _DDB_DB_WRITE_CMD_H_
+#define _DDB_DB_WRITE_CMD_H_
+
+#include <mach/boolean.h>
+#include <machine/db_machdep.h>
+
+/* Prototypes for functions exported by this module.
+ */
+
+void db_write_cmd(
+ db_expr_t address,
+ boolean_t have_addr,
+ db_expr_t count,
+ const char * modif);
+
+#endif /* !_DDB_DB_WRITE_CMD_H_ */
diff --git a/ddb/stab.h b/ddb/stab.h
index 3ebc1af8..55e9d452 100644
--- a/ddb/stab.h
+++ b/ddb/stab.h
@@ -33,6 +33,8 @@
* @(#)stab.h 5.2 (Berkeley) 4/4/91
*/
+#ifndef _DDB_STAB_H_
+#define _DDB_STAB_H_
/*
* The following are symbols used by various debuggers and by the Pascal
@@ -67,3 +69,5 @@
#define N_ECOMM 0xe4 /* end common */
#define N_ECOML 0xe8 /* end common (local name) */
#define N_LENG 0xfe /* length of preceding entry */
+
+#endif /* _DDB_STAB_H_ */
diff --git a/device/blkio.c b/device/blkio.c
index 26d4a75a..e5b4d09f 100644
--- a/device/blkio.c
+++ b/device/blkio.c
@@ -38,12 +38,12 @@
-io_return_t block_io(strat, max_count, ior)
- void (*strat)();
- void (*max_count)();
- register io_req_t ior;
+io_return_t block_io(
+ void (*strat)(),
+ void (*max_count)(),
+ io_req_t ior)
{
- register kern_return_t rc;
+ kern_return_t rc;
boolean_t wait = FALSE;
/*
@@ -88,8 +88,7 @@ io_return_t block_io(strat, max_count, ior)
*/
#define MAX_PHYS (256 * 1024)
-void minphys(ior)
- register io_req_t ior;
+void minphys(io_req_t ior)
{
if ((ior->io_op & (IO_WRITE | IO_READ | IO_OPEN)) == IO_WRITE)
return;
@@ -102,137 +101,8 @@ void minphys(ior)
* Dummy routine placed in device switch entries to indicate that
* block device may be mapped.
*/
-vm_offset_t block_io_mmap()
+int block_io_mmap(dev_t dev, vm_offset_t off, int prot)
{
return (0);
}
-/*
- * Disk sort routine.
- *
- * We order the disk request chain so that the disk head will sweep
- * back and forth across the disk. The chain is divided into two
- * pieces, with requests ordered in opposite directions. Assume that
- * the first part of the chain holds increasing cylinder numbers.
- * If a new request has a higher cylinder number than the head of
- * the chain, the disk head has not yet reached it; the new request
- * can go in the first part of the chain. If the new request has
- * a lower cylinder number, the disk head has already passed it and
- * must catch it on the way back; so the new request goes in the
- * second (descending) part of the chain.
- * When all of the requests in the ascending portion are filled,
- * the descending chain becomes the first chain, and requests above
- * the first now go in the second part of the chain (ascending).
- */
-
-#define io_cylinder io_residual
- /* Disk drivers put cylinder here */
-#define h_head io_next
-#define h_tail io_prev
- /* IORs are chained here */
-
-void disksort(head, ior)
- io_req_t head; /* (sort of) */
- io_req_t ior;
-{
- register int cylinder = ior->io_cylinder;
- register io_req_t next, prev;
-
- next = head->h_head;
- if (next == 0) {
- head->h_head = ior;
- head->h_tail = ior;
- ior->io_next = 0;
- return;
- }
-
- do {
- prev = next;
- next = prev->io_next;
- } while (next != 0 && prev->io_cylinder == next->io_cylinder);
-
- if (next == 0) {
- prev->io_next = ior;
- head->h_tail = ior;
- ior->io_next = 0;
- return;
- }
-
- if (prev->io_cylinder < next->io_cylinder) {
- /*
- * Ascending list first.
- */
- if (prev->io_cylinder <= cylinder) {
- /*
- * Insert in ascending list.
- */
- while (next != 0 &&
- next->io_cylinder <= cylinder &&
- prev->io_cylinder <= next->io_cylinder)
- {
- prev = next;
- next = prev->io_next;
- }
- }
- else {
- /*
- * Insert in descending list
- */
- do {
- prev = next;
- next = prev->io_next;
- } while (next != 0 &&
- prev->io_cylinder <= next->io_cylinder);
-
- while (next != 0 &&
- next->io_cylinder >= cylinder)
- {
- prev = next;
- next = prev->io_next;
- }
- }
- }
- else {
- /*
- * Descending first.
- */
- if (prev->io_cylinder >= cylinder) {
- /*
- * Insert in descending list.
- */
- while (next != 0 &&
- next->io_cylinder >= cylinder &&
- prev->io_cylinder >= next->io_cylinder)
- {
- prev = next;
- next = prev->io_next;
- }
- }
- else {
- /*
- * Insert in ascending list
- */
- do {
- prev = next;
- next = prev->io_next;
- } while (next != 0 &&
- prev->io_cylinder >= next->io_cylinder);
- while (next != 0 &&
- next->io_cylinder <= cylinder)
- {
- prev = next;
- next = prev->io_next;
- }
- }
- }
- /*
- * Insert between prev and next.
- */
- prev->io_next = ior;
- ior->io_next = next;
- if (next == 0) {
- /* At tail of list. */
- head->h_tail = ior;
- }
-}
-
diff --git a/device/blkio.h b/device/blkio.h
new file mode 100644
index 00000000..77eb105a
--- /dev/null
+++ b/device/blkio.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _DEVICE_BLKIO_H_
+#define _DEVICE_BLKIO_H_
+
+extern int block_io_mmap(dev_t dev, vm_offset_t off, int prot);
+
+#endif /* _DEVICE_BLKIO_H_ */
diff --git a/device/buf.h b/device/buf.h
index 80466c8d..a79ed8e4 100644
--- a/device/buf.h
+++ b/device/buf.h
@@ -30,6 +30,9 @@
* Definitions to make new IO structures look like old ones
*/
+#ifndef _DEVICE_BUF_H_
+#define _DEVICE_BUF_H_
+
/*
* io_req and fields
*/
@@ -80,11 +83,6 @@
#define B_MD1 IO_SPARE_START
/*
- * Redefine uio structure
- */
-#define uio io_req
-
-/*
* Redefine physio routine
*/
#define physio(strat, xbuf, dev, ops, minphys, ior) \
@@ -100,3 +98,5 @@ extern void minphys(io_req_t);
*/
#define biodone iodone
#define biowait iowait
+
+#endif /* _DEVICE_BUF_H_ */
diff --git a/device/chario.c b/device/chario.c
index d7c092e9..0e9dd70b 100644
--- a/device/chario.c
+++ b/device/chario.c
@@ -49,6 +49,7 @@
#include <device/io_req.h>
#include <device/ds_routines.h>
#include <device/device_reply.user.h>
+#include <device/chario.h>
#include <device/tty.h>
@@ -63,18 +64,6 @@ short ttlowat[NSPEEDS] =
125,125 };
/*
- * forward declarations
- */
-void queue_delayed_reply(
- queue_t, io_req_t, boolean_t (*)(io_req_t));
-void tty_output(struct tty *);
-void tty_flush(struct tty *, int);
-boolean_t char_open_done(io_req_t);
-boolean_t char_read_done(io_req_t);
-boolean_t char_write_done(io_req_t);
-void ttstart(struct tty *tp);
-
-/*
* Fake 'line discipline' switch for the benefit of old code
* that wants to call through it.
*/
@@ -91,9 +80,9 @@ struct ldisc_switch linesw[] = {
/*
* Sizes for input and output circular buffers.
*/
-int tty_inq_size = 4096; /* big nuf */
-int tty_outq_size = 2048; /* Must be bigger that tthiwat */
-int pdma_default = 1; /* turn pseudo dma on by default */
+const unsigned int tty_inq_size = 4096; /* big nuf */
+const unsigned int tty_outq_size = 2048; /* Must be bigger that tthiwat */
+boolean_t pdma_default = TRUE; /* turn pseudo dma on by default */
/*
* compute pseudo-dma tables
@@ -216,7 +205,7 @@ out:
boolean_t char_open_done(
io_req_t ior)
{
- register struct tty *tp = (struct tty *)ior->io_dev_ptr;
+ struct tty *tp = (struct tty *)ior->io_dev_ptr;
spl_t s = spltty();
simple_lock(&tp->t_lock);
@@ -256,13 +245,13 @@ boolean_t tty_close_open_reply(
* device needs to run on master.
*/
io_return_t char_write(
- register struct tty * tp,
- register io_req_t ior)
+ struct tty * tp,
+ io_req_t ior)
{
spl_t s;
- register int count;
- register char *data;
- vm_offset_t addr;
+ int count;
+ char *data;
+ vm_offset_t addr = 0;
io_return_t rc = D_SUCCESS;
data = ior->io_data;
@@ -347,10 +336,10 @@ out:
* May run on any CPU.
*/
boolean_t char_write_done(
- register io_req_t ior)
+ io_req_t ior)
{
- register struct tty *tp = (struct tty *)ior->io_dev_ptr;
- register spl_t s = spltty();
+ struct tty *tp = (struct tty *)ior->io_dev_ptr;
+ spl_t s = spltty();
simple_lock(&tp->t_lock);
if (tp->t_outq.c_cc > TTHIWAT(tp) ||
@@ -378,7 +367,7 @@ boolean_t char_write_done(
}
boolean_t tty_close_write_reply(
- register io_req_t ior)
+ io_req_t ior)
{
ior->io_residual = ior->io_count;
ior->io_error = D_DEVICE_DOWN;
@@ -392,8 +381,8 @@ boolean_t tty_close_write_reply(
* May run on any CPU - does not talk to device driver.
*/
io_return_t char_read(
- register struct tty *tp,
- register io_req_t ior)
+ struct tty *tp,
+ io_req_t ior)
{
spl_t s;
kern_return_t rc;
@@ -453,10 +442,10 @@ io_return_t char_read(
* May run on any CPU - does not talk to device driver.
*/
boolean_t char_read_done(
- register io_req_t ior)
+ io_req_t ior)
{
- register struct tty *tp = (struct tty *)ior->io_dev_ptr;
- register spl_t s = spltty();
+ struct tty *tp = (struct tty *)ior->io_dev_ptr;
+ spl_t s = spltty();
simple_lock(&tp->t_lock);
@@ -485,7 +474,7 @@ boolean_t char_read_done(
}
boolean_t tty_close_read_reply(
- register io_req_t ior)
+ io_req_t ior)
{
ior->io_residual = ior->io_count;
ior->io_error = D_DEVICE_DOWN;
@@ -499,9 +488,9 @@ boolean_t tty_close_read_reply(
* Iff modem control should run on master.
*/
void ttyclose(
- register struct tty *tp)
+ struct tty *tp)
{
- register io_req_t ior;
+ io_req_t ior;
/*
* Flush the read and write queues. Signal
@@ -537,11 +526,11 @@ void ttyclose(
*/
boolean_t
tty_queue_clean(
- queue_t q,
- ipc_port_t port,
- boolean_t (*routine)(io_req_t) )
+ queue_t q,
+ const ipc_port_t port,
+ boolean_t (*routine)(io_req_t) )
{
- register io_req_t ior;
+ io_req_t ior;
ior = (io_req_t)queue_first(q);
while (!queue_end(q, (queue_entry_t)ior)) {
@@ -563,11 +552,11 @@ tty_queue_clean(
*/
boolean_t
tty_portdeath(
- struct tty * tp,
- ipc_port_t port)
+ struct tty * tp,
+ const ipc_port_t port)
{
- register spl_t spl = spltty();
- register boolean_t result;
+ spl_t spl = spltty();
+ boolean_t result;
simple_lock(&tp->t_lock);
@@ -598,7 +587,7 @@ tty_portdeath(
* May run on any CPU.
*/
io_return_t tty_get_status(
- register struct tty *tp,
+ struct tty *tp,
dev_flavor_t flavor,
int * data, /* pointer to OUT array */
natural_t *count) /* out */
@@ -608,7 +597,7 @@ io_return_t tty_get_status(
switch (flavor) {
case TTY_STATUS:
{
- register struct tty_status *tsp =
+ struct tty_status *tsp =
(struct tty_status *) data;
if (*count < TTY_STATUS_COUNT)
@@ -644,7 +633,7 @@ io_return_t tty_get_status(
* device needs to run on master.
*/
io_return_t tty_set_status(
- register struct tty *tp,
+ struct tty *tp,
dev_flavor_t flavor,
int * data,
natural_t count)
@@ -654,7 +643,7 @@ io_return_t tty_set_status(
switch (flavor) {
case TTY_FLUSH:
{
- register int flags;
+ int flags;
if (count < TTY_FLUSH_COUNT)
return D_INVALID_OPERATION;
@@ -697,7 +686,7 @@ io_return_t tty_set_status(
case TTY_STATUS:
/* set special characters and speed */
{
- register struct tty_status *tsp;
+ struct tty_status *tsp;
if (count < TTY_STATUS_COUNT)
return D_INVALID_OPERATION;
@@ -752,9 +741,9 @@ void queue_delayed_reply(
* TTY containing queue must be locked (at spltty).
*/
void tty_queue_completion(
- register queue_t qh)
+ queue_t qh)
{
- register io_req_t ior;
+ io_req_t ior;
while ((ior = (io_req_t)dequeue_head(qh)) != 0) {
iodone(ior);
@@ -767,7 +756,7 @@ void tty_queue_completion(
* we can initialize the queues here.
*/
void ttychars(
- register struct tty *tp)
+ struct tty *tp)
{
if ((tp->t_flags & TS_INIT) == 0) {
/*
@@ -804,7 +793,7 @@ void ttychars(
* device needs to run on master.
*/
void tty_flush(
- register struct tty *tp,
+ struct tty *tp,
int rw)
{
if (rw & D_READ) {
@@ -827,9 +816,9 @@ void tty_flush(
* What if device runs on a different CPU?
*/
void ttrstrt(
- register struct tty *tp)
+ struct tty *tp)
{
- register spl_t s;
+ spl_t s;
s = spltty();
simple_lock(&tp->t_lock);
@@ -850,8 +839,7 @@ void ttrstrt(
* Called at spltty, tty already locked.
* Must be on master CPU if device runs on master.
*/
-void ttstart(tp)
- register struct tty *tp;
+void ttstart(struct tty *tp)
{
if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0) {
/*
@@ -875,7 +863,7 @@ void ttstart(tp)
* Must be on master CPU if device runs on master.
*/
void tty_output(
- register struct tty *tp)
+ struct tty *tp)
{
if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0) {
/*
@@ -897,9 +885,9 @@ void tty_output(
void ttypush(
void * _tp)
{
- register struct tty *tp = _tp;
+ struct tty *tp = _tp;
spl_t s = spltty();
- register int state;
+ int state;
simple_lock(&tp->t_lock);
@@ -918,7 +906,7 @@ void ttypush(
if (state & TS_MIN_TO_RCV)
{ /* a character was received */
tp->t_state = state & ~TS_MIN_TO_RCV;
- timeout(ttypush,tp,pdma_timeouts[tp->t_ispeed]);
+ timeout(ttypush, tp, pdma_timeouts[tp->t_ispeed]);
}
else
{
@@ -985,7 +973,7 @@ void ttyinput(
* into the future, but this involves making a timeout/untimeout
* call on every character.
*/
- register int ptime = pdma_timeouts[tp->t_ispeed];
+ int ptime = pdma_timeouts[tp->t_ispeed];
if (ptime > 0)
{
if ((tp->t_state & TS_MIN_TO) == 0)
@@ -1015,7 +1003,7 @@ void ttyinput_many(
* Do not want to overflow input queue
*/
if (tp->t_inq.c_cc < tp->t_inq.c_hog)
- count -= b_to_q( chars, count, &tp->t_inq);
+ count -= b_to_q(chars, count, &tp->t_inq);
tty_queue_completion(&tp->t_delayed_read);
}
diff --git a/device/chario.h b/device/chario.h
new file mode 100644
index 00000000..52105a20
--- /dev/null
+++ b/device/chario.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _DEVICE_CHARIO_H_
+#define _DEVICE_CHARIO_H_
+
+#include <device/tty.h>
+
+extern void chario_init(void);
+
+void queue_delayed_reply(
+ queue_t qh,
+ io_req_t ior,
+ boolean_t (*io_done)(io_req_t));
+
+void tty_output(struct tty *tp);
+
+boolean_t char_open_done(io_req_t);
+boolean_t char_read_done(io_req_t);
+boolean_t char_write_done(io_req_t);
+
+#endif /* _DEVICE_CHARIO_H_ */
diff --git a/device/cirbuf.c b/device/cirbuf.c
index 4fe2d896..dfb06df1 100644
--- a/device/cirbuf.c
+++ b/device/cirbuf.c
@@ -42,11 +42,11 @@
/* if c_cl == c_cf - 1, buffer is full */
#if DEBUG
-int cb_check_enable = 0;
+boolean_t cb_check_enable = FALSE;
#define CB_CHECK(cb) if (cb_check_enable) cb_check(cb)
void
-cb_check(register struct cirbuf *cb)
+cb_check(struct cirbuf *cb)
{
if (!(cb->c_cf >= cb->c_start && cb->c_cf < cb->c_end))
panic("cf %x out of range [%x..%x)",
@@ -78,9 +78,9 @@ cb_check(register struct cirbuf *cb)
*/
int putc(
int c,
- register struct cirbuf *cb)
+ struct cirbuf *cb)
{
- register char *ow, *nw;
+ char *ow, *nw;
ow = cb->c_cl;
nw = ow+1;
@@ -101,10 +101,10 @@ int putc(
/*
* Get one character from circular buffer.
*/
-int getc(register struct cirbuf *cb)
+int getc(struct cirbuf *cb)
{
- register unsigned char *nr;
- register int c;
+ unsigned char *nr;
+ int c;
nr = (unsigned char *)cb->c_cf;
if (nr == (unsigned char *)cb->c_cl) {
@@ -129,12 +129,12 @@ int getc(register struct cirbuf *cb)
* Return number moved.
*/
int
-q_to_b( register struct cirbuf *cb,
- register char *cp,
- register int count)
+q_to_b( struct cirbuf *cb,
+ char *cp,
+ int count)
{
- char * ocp = cp;
- register int i;
+ char *ocp = cp;
+ int i;
while (count != 0) {
if (cb->c_cl == cb->c_cf)
@@ -165,12 +165,12 @@ q_to_b( register struct cirbuf *cb,
* NOT entered.
*/
int
-b_to_q( register char * cp,
+b_to_q( char *cp,
int count,
- register struct cirbuf *cb)
+ struct cirbuf *cb)
{
- register int i;
- register char *lim;
+ int i;
+ char *lim;
while (count != 0) {
lim = cb->c_cf - 1;
@@ -205,10 +205,10 @@ b_to_q( register char * cp,
* that matches the mask.
*/
int
-ndqb( register struct cirbuf *cb,
- register int mask)
+ndqb( struct cirbuf *cb,
+ int mask)
{
- register char *cp, *lim;
+ char *cp, *lim;
if (cb->c_cl < cb->c_cf)
lim = cb->c_end;
@@ -229,10 +229,10 @@ ndqb( register struct cirbuf *cb,
* Flush characters from circular buffer.
*/
void
-ndflush(register struct cirbuf *cb,
- register int count)
+ndflush(struct cirbuf *cb,
+ int count)
{
- register int i;
+ int i;
while (count != 0) {
if (cb->c_cl == cb->c_cf)
@@ -269,10 +269,10 @@ void cb_clear(struct cirbuf *cb)
*/
void
cb_alloc(
- register struct cirbuf *cb,
- int buf_size)
+ struct cirbuf *cb,
+ vm_size_t buf_size)
{
- register char *buf;
+ char *buf;
buf = (char *)kalloc(buf_size);
@@ -290,9 +290,9 @@ cb_alloc(
* Free character space for a circular buffer.
*/
void
-cb_free(register struct cirbuf *cb)
+cb_free(struct cirbuf *cb)
{
- int size;
+ vm_size_t size;
size = cb->c_end - cb->c_start;
kfree((vm_offset_t)cb->c_start, size);
diff --git a/device/cirbuf.h b/device/cirbuf.h
index a3f50ce5..64771ce1 100644
--- a/device/cirbuf.h
+++ b/device/cirbuf.h
@@ -52,11 +52,10 @@ extern int putc(int, struct cirbuf *);
extern int getc(struct cirbuf *);
extern int q_to_b(struct cirbuf *, char *, int);
extern int b_to_q(char *, int, struct cirbuf *);
-extern int nqdb(struct cirbuf *, int);
extern void ndflush(struct cirbuf *, int);
extern void cb_clear(struct cirbuf *);
-extern void cb_alloc(struct cirbuf *, int);
+extern void cb_alloc(struct cirbuf *, vm_size_t);
extern void cb_free(struct cirbuf *);
#endif /* _DEVICE_CIRBUF_H_ */
diff --git a/device/conf.h b/device/conf.h
index e91e0996..fea18223 100644
--- a/device/conf.h
+++ b/device/conf.h
@@ -32,22 +32,30 @@
#define _DEVICE_CONF_H_
#include <mach/machine/vm_types.h>
+#include <sys/types.h>
+#include <mach/port.h>
+#include <mach/vm_prot.h>
+
+struct io_req;
+typedef struct io_req *io_req_t;
+
+typedef int io_return_t;
/*
* Operations list for major device types.
*/
struct dev_ops {
- char * d_name; /* name for major device */
- int (*d_open)(); /* open device */
- int (*d_close)(); /* close device */
- int (*d_read)(); /* read */
- int (*d_write)(); /* write */
- int (*d_getstat)(); /* get status/control */
- int (*d_setstat)(); /* set status/control */
- vm_offset_t (*d_mmap)(); /* map memory */
- int (*d_async_in)();/* asynchronous input setup */
- int (*d_reset)(); /* reset device */
- int (*d_port_death)();
+ char * d_name; /* name for major device */
+ int (*d_open)(dev_t, int, io_req_t);/* open device */
+ void (*d_close)(dev_t, int); /* close device */
+ int (*d_read)(dev_t, io_req_t); /* read */
+ int (*d_write)(dev_t, io_req_t); /* write */
+ int (*d_getstat)(dev_t, int, int *, natural_t *); /* get status/control */
+ int (*d_setstat)(dev_t, int, int *, natural_t); /* set status/control */
+ int (*d_mmap)(dev_t, vm_offset_t, vm_prot_t); /* map memory */
+ int (*d_async_in)(); /* asynchronous input setup */
+ int (*d_reset)(); /* reset device */
+ int (*d_port_death)(dev_t, mach_port_t);
/* clean up reply ports */
int d_subdev; /* number of sub-devices per
unit */
@@ -58,9 +66,16 @@ typedef struct dev_ops *dev_ops_t;
/*
* Routines for null entries.
*/
-extern int nulldev(); /* no operation - OK */
-extern int nodev(); /* no operation - error */
-extern vm_offset_t nomap(); /* no operation - error */
+extern int nulldev(void); /* no operation - OK */
+extern int nulldev_open(dev_t dev, int flag, io_req_t ior);
+extern void nulldev_close(dev_t dev, int flags);
+extern int nulldev_read(dev_t dev, io_req_t ior);
+extern int nulldev_write(dev_t dev, io_req_t ior);
+extern io_return_t nulldev_getstat(dev_t dev, int flavor, int *data, natural_t *count);
+extern io_return_t nulldev_setstat(dev_t dev, int flavor, int *data, natural_t count);
+extern io_return_t nulldev_portdeath(dev_t dev, mach_port_t port);
+extern int nodev(void); /* no operation - error */
+extern int nomap(dev_t dev, vm_offset_t off, int prot); /* no operation - error */
/*
* Flavor constants for d_dev_info routine
@@ -105,10 +120,5 @@ extern int dev_indirect_count;
di < &dev_indirect_list[dev_indirect_count]; \
di++)
-/*
- * Exported routine to set indirection.
- */
-extern void dev_set_indirect(char *, dev_ops_t, int);
-
#endif /* _DEVICE_CONF_H_ */
diff --git a/device/cons.c b/device/cons.c
index f26f22c5..b04621ae 100644
--- a/device/cons.c
+++ b/device/cons.c
@@ -30,9 +30,9 @@
#ifdef MACH_KMSG
#include <device/io_req.h>
#include <device/kmsg.h>
-#endif
+#endif /* MACH_KMSG */
-static int cn_inited = 0;
+static boolean_t cn_inited = FALSE;
static struct consdev *cn_tab = 0; /* physical console device info */
/*
@@ -42,8 +42,8 @@ static struct consdev *cn_tab = 0; /* physical console device info */
* is enabled. This can be useful to debug (or catch panics from) code early
* in the bootstrap procedure.
*/
-int (*romgetc)() = 0;
-void (*romputc)() = 0;
+int (*romgetc)(char c) = 0;
+void (*romputc)(char c) = 0;
#if CONSBUFSIZE > 0
/*
@@ -54,11 +54,11 @@ void (*romputc)() = 0;
*/
static char consbuf[CONSBUFSIZE] = { 0 };
static char *consbp = consbuf;
-static int consbufused = 0;
-#endif
+static boolean_t consbufused = FALSE;
+#endif /* CONSBUFSIZE > 0 */
void
-cninit()
+cninit(void)
{
struct consdev *cp;
dev_ops_t cn_ops;
@@ -106,10 +106,10 @@ cninit()
if (++cbp == &consbuf[CONSBUFSIZE])
cbp = consbuf;
} while (cbp != consbp);
- consbufused = 0;
+ consbufused = FALSE;
}
-#endif
- cn_inited = 1;
+#endif /* CONSBUFSIZE > 0 */
+ cn_inited = TRUE;
return;
}
/*
@@ -120,7 +120,7 @@ cninit()
int
-cngetc()
+cngetc(void)
{
if (cn_tab)
return ((*cn_tab->cn_getc)(cn_tab->cn_dev, 1));
@@ -130,7 +130,7 @@ cngetc()
}
int
-cnmaygetc()
+cnmaygetc(void)
{
if (cn_tab)
return((*cn_tab->cn_getc)(cn_tab->cn_dev, 0));
@@ -171,14 +171,14 @@ cnputc(c)
}
#if CONSBUFSIZE > 0
else {
- if (consbufused == 0) {
+ if (consbufused == FALSE) {
consbp = consbuf;
- consbufused = 1;
+ consbufused = TRUE;
memset(consbuf, 0, CONSBUFSIZE);
}
*consbp++ = c;
if (consbp >= &consbuf[CONSBUFSIZE])
consbp = consbuf;
}
-#endif
+#endif /* CONSBUFSIZE > 0 */
}
diff --git a/device/cons.h b/device/cons.h
index 6a0ae850..34f3bc56 100644
--- a/device/cons.h
+++ b/device/cons.h
@@ -41,9 +41,6 @@ struct consdev {
#define CN_INTERNAL 2 /* "internal" bit-mapped display */
#define CN_REMOTE 3 /* serial interface with remote bit set */
-/* XXX */
-#define CONSMAJOR 0
-
#define CONSBUFSIZE 1024
#ifdef KERNEL
@@ -57,4 +54,15 @@ extern int cngetc(void);
extern int cnmaygetc(void);
extern void cnputc(char);
+
+/*
+ * ROM getc/putc primitives.
+ * On some architectures, the boot ROM provides basic character input/output
+ * routines that can be used before devices are configured or virtual memory
+ * is enabled. This can be useful to debug (or catch panics from) code early
+ * in the bootstrap procedure.
+ */
+extern int (*romgetc)(char c);
+extern void (*romputc)(char c);
+
#endif /* _DEVICE_CONS_H */
diff --git a/device/dev_hdr.h b/device/dev_hdr.h
index 340a2db1..ff7d2ef5 100644
--- a/device/dev_hdr.h
+++ b/device/dev_hdr.h
@@ -134,16 +134,16 @@ boolean_t dev_map(boolean_t (*)(), mach_port_t);
* device name lookup
*/
extern boolean_t dev_name_lookup(
- char * name,
- dev_ops_t *ops, /* out */
- int *unit); /* out */
+ char * name,
+ dev_ops_t *ops, /* out */
+ int *unit); /* out */
/*
* Change an entry in the indirection list.
*/
extern void dev_set_indirection(
- char *name,
+ const char *name,
dev_ops_t ops,
- int unit);
+ int unit);
#endif /* _DEVICE_DEV_HDR_H_ */
diff --git a/device/dev_lookup.c b/device/dev_lookup.c
index 98a2d02c..a80830c2 100644
--- a/device/dev_lookup.c
+++ b/device/dev_lookup.c
@@ -43,6 +43,7 @@
#include <kern/ipc_kobject.h>
#include <device/device_emul.h>
+#include <device/ds_routines.h>
/*
* Device structure routines: reference counting, port->device.
@@ -70,9 +71,9 @@ struct kmem_cache dev_hdr_cache;
*/
void
dev_number_enter(device)
- register mach_device_t device;
+ const mach_device_t device;
{
- register queue_t q;
+ queue_t q;
q = &dev_number_hash_table[DEV_NUMBER_HASH(device->dev_number)];
queue_enter(q, device, mach_device_t, number_chain);
@@ -84,9 +85,9 @@ dev_number_enter(device)
*/
void
dev_number_remove(device)
- register mach_device_t device;
+ const mach_device_t device;
{
- register queue_t q;
+ queue_t q;
q = &dev_number_hash_table[DEV_NUMBER_HASH(device->dev_number)];
queue_remove(q, device, mach_device_t, number_chain);
@@ -98,11 +99,11 @@ dev_number_remove(device)
*/
mach_device_t
dev_number_lookup(ops, devnum)
- dev_ops_t ops;
+ const dev_ops_t ops;
int devnum;
{
- register queue_t q;
- register mach_device_t device;
+ queue_t q;
+ mach_device_t device;
q = &dev_number_hash_table[DEV_NUMBER_HASH(devnum)];
queue_iterate(q, device, mach_device_t, number_chain) {
@@ -119,13 +120,12 @@ dev_number_lookup(ops, devnum)
* table.
*/
mach_device_t
-device_lookup(name)
- char * name;
+device_lookup(char *name)
{
dev_ops_t dev_ops;
int dev_minor;
- register mach_device_t device;
- register mach_device_t new_device;
+ mach_device_t device;
+ mach_device_t new_device;
/*
* Get the device and unit number from the name.
@@ -197,8 +197,7 @@ device_lookup(name)
* Add a reference to the device.
*/
void
-mach_device_reference(device)
- register mach_device_t device;
+mach_device_reference(mach_device_t device)
{
simple_lock(&device->ref_lock);
device->ref_count++;
@@ -210,8 +209,7 @@ mach_device_reference(device)
* structure if no references are left.
*/
void
-mach_device_deallocate(device)
- register mach_device_t device;
+mach_device_deallocate(mach_device_t device)
{
simple_lock(&device->ref_lock);
if (--device->ref_count > 0) {
@@ -242,15 +240,12 @@ mach_device_deallocate(device)
/*
* port-to-device lookup routines.
*/
-decl_simple_lock_data(,
- dev_port_lock)
/*
* Enter a port-to-device mapping.
*/
void
-dev_port_enter(device)
- register mach_device_t device;
+dev_port_enter(mach_device_t device)
{
mach_device_reference(device);
@@ -268,8 +263,7 @@ dev_port_enter(device)
* Remove a port-to-device mapping.
*/
void
-dev_port_remove(device)
- register mach_device_t device;
+dev_port_remove(mach_device_t device)
{
ipc_kobject_set(device->port, IKO_NULL, IKOT_NONE);
mach_device_deallocate(device);
@@ -280,10 +274,9 @@ dev_port_remove(device)
* Doesn't consume the naked send right; produces a device reference.
*/
device_t
-dev_port_lookup(port)
- ipc_port_t port;
+dev_port_lookup(ipc_port_t port)
{
- register device_t device;
+ device_t device;
if (!IP_VALID(port))
return (DEVICE_NULL);
@@ -307,7 +300,7 @@ dev_port_lookup(port)
*/
ipc_port_t
convert_device_to_port(device)
- register device_t device;
+ const device_t device;
{
if (device == DEVICE_NULL)
return IP_NULL;
@@ -322,13 +315,13 @@ convert_device_to_port(device)
* return FALSE.
*/
boolean_t
-dev_map(routine, port)
- boolean_t (*routine)();
- mach_port_t port;
+dev_map(
+ boolean_t (*routine)(),
+ mach_port_t port)
{
- register int i;
- register queue_t q;
- register mach_device_t dev, prev_dev;
+ int i;
+ queue_t q;
+ mach_device_t dev, prev_dev;
for (i = 0, q = &dev_number_hash_table[0];
i < NDEVHASH;
@@ -362,20 +355,16 @@ dev_map(routine, port)
/*
* Initialization
*/
-#define NDEVICES 256
-
void
-dev_lookup_init()
+dev_lookup_init(void)
{
- register int i;
+ int i;
simple_lock_init(&dev_number_lock);
for (i = 0; i < NDEVHASH; i++)
queue_init(&dev_number_hash_table[i]);
- simple_lock_init(&dev_port_lock);
-
kmem_cache_init(&dev_hdr_cache, "mach_device",
sizeof(struct mach_device), 0, NULL, NULL, NULL, 0);
}
diff --git a/device/dev_master.h b/device/dev_master.h
index 964ae828..70d4c63f 100644
--- a/device/dev_master.h
+++ b/device/dev_master.h
@@ -30,11 +30,14 @@
* Bind an IO operation to the master CPU.
*/
+#ifndef _DEVICE_DEV_MASTER_H_
+#define _DEVICE_DEV_MASTER_H_
+
#include <cpus.h>
#if NCPUS > 1
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/cpu_number.h>
#include <kern/sched_prim.h>
#include <kern/thread.h>
@@ -58,3 +61,5 @@
#define io_release_master()
#endif NCPUS > 1
+
+#endif /* _DEVICE_DEV_MASTER_H_ */
diff --git a/device/dev_name.c b/device/dev_name.c
index cef1efd5..175e3890 100644
--- a/device/dev_name.c
+++ b/device/dev_name.c
@@ -39,18 +39,52 @@
/*
* Routines placed in empty entries in the device tables
*/
-int nulldev()
+int nulldev(void)
{
return (D_SUCCESS);
}
-int nodev()
+int nulldev_open(dev_t dev, int flags, io_req_t ior)
+{
+ return (D_SUCCESS);
+}
+
+void nulldev_close(dev_t dev, int flags)
+{
+}
+
+int nulldev_read(dev_t dev, io_req_t ior)
+{
+ return (D_SUCCESS);
+}
+
+int nulldev_write(dev_t dev, io_req_t ior)
+{
+ return (D_SUCCESS);
+}
+
+io_return_t nulldev_getstat(dev_t dev, int flavor, int *data, natural_t *count)
+{
+ return (D_SUCCESS);
+}
+
+io_return_t nulldev_setstat(dev_t dev, int flavor, int *data, natural_t count)
+{
+ return (D_SUCCESS);
+}
+
+int nulldev_portdeath(dev_t dev, mach_port_t port)
+{
+ return (D_SUCCESS);
+}
+
+int nodev(void)
{
return (D_INVALID_OPERATION);
}
-vm_offset_t
-nomap()
+int
+nomap(dev_t dev, vm_offset_t off, int prot)
{
return (D_INVALID_OPERATION);
}
@@ -63,11 +97,11 @@ nomap()
* src and target are equal in first 'len' characters
* next character of target is 0 (end of string).
*/
-boolean_t
+boolean_t __attribute__ ((pure))
name_equal(src, len, target)
- register char * src;
- register int len;
- register char * target;
+ const char *src;
+ int len;
+ const char *target;
{
while (--len >= 0)
if (*src++ != *target++)
@@ -78,10 +112,10 @@ name_equal(src, len, target)
/*
* device name lookup
*/
-boolean_t dev_name_lookup(name, ops, unit)
- char * name;
- dev_ops_t *ops; /* out */
- int *unit; /* out */
+boolean_t dev_name_lookup(
+ char *name,
+ dev_ops_t *ops, /* out */
+ int *unit) /* out */
{
/*
* Assume that block device names are of the form
@@ -95,18 +129,14 @@ boolean_t dev_name_lookup(name, ops, unit)
* <partition> is a letter in [a-h] (disks only?)
*/
- register char * cp = name;
+ char *cp = name;
int len;
- register int j = 0;
- register int c;
+ int j = 0;
+ int c;
dev_ops_t dev;
- register boolean_t found;
-
- int slice_num=0;
+ boolean_t found;
-#if 0
- printf("lookup on name %s\n",name);
-#endif /* 0 */
+ int slice_num = 0;
/*
* Find device type name (characters before digit)
@@ -136,7 +166,7 @@ boolean_t dev_name_lookup(name, ops, unit)
}
if (!found) {
/* name not found - try indirection list */
- register dev_indirect_t di;
+ dev_indirect_t di;
dev_indirect_search(di) {
if (name_equal(name, len, di->d_name)) {
@@ -167,7 +197,7 @@ boolean_t dev_name_lookup(name, ops, unit)
*unit *= j;
/* find slice ? */
- if (c=='s') {
+ if (c == 's') {
cp++;
while ((c = *cp) != '\0' &&
c >= '0' && c <= '9') {
@@ -176,17 +206,14 @@ boolean_t dev_name_lookup(name, ops, unit)
}
}
- *unit += (slice_num <<4);
- /* if slice==0, it is either compatability or whole device */
+ *unit += (slice_num << 4);
+ /* if slice==0, it is either compatibility or whole device */
if (c >= 'a' && c < 'a' + j) { /* note: w/o this -> whole slice */
/*
* Minor number is <subdev_count>*unit + letter.
* NOW it is slice result + letter
*/
-#if 0
- *unit = *unit * j + (c - 'a' +1); /* +1 to start 'a' at 1 */
-#endif /* 0 */
*unit += (c - 'a' +1);
}
}
@@ -198,11 +225,11 @@ boolean_t dev_name_lookup(name, ops, unit)
*/
void
dev_set_indirection(name, ops, unit)
- char *name;
+ const char *name;
dev_ops_t ops;
int unit;
{
- register dev_indirect_t di;
+ dev_indirect_t di;
dev_indirect_search(di) {
if (!strcmp(di->d_name, name)) {
@@ -214,22 +241,23 @@ dev_set_indirection(name, ops, unit)
}
boolean_t dev_change_indirect(iname, dname, unit)
-char *iname,*dname;
-int unit;
+ const char *iname;
+ const char *dname;
+ int unit;
{
struct dev_ops *dp;
struct dev_indirect *di;
- int found = FALSE;
+ boolean_t found = FALSE;
dev_search(dp) {
- if (!strcmp(dp->d_name,dname)) {
+ if (!strcmp(dp->d_name, dname)) {
found = TRUE;
break;
}
}
if (!found) return FALSE;
dev_indirect_search(di) {
- if (!strcmp(di->d_name,iname)) {
+ if (!strcmp(di->d_name, iname)) {
di->d_ops = dp;
di->d_unit = unit;
return TRUE;
diff --git a/device/dev_pager.c b/device/dev_pager.c
index e0ca2c76..815473a9 100644
--- a/device/dev_pager.c
+++ b/device/dev_pager.c
@@ -55,9 +55,8 @@
#include <device/dev_hdr.h>
#include <device/io_req.h>
#include <device/memory_object_reply.user.h>
-
-extern vm_offset_t block_io_mmap(); /* dummy routine to allow
- mmap for block devices */
+#include <device/dev_pager.h>
+#include <device/blkio.h>
/*
* The device pager routines are called directly from the message
@@ -127,14 +126,14 @@ typedef struct dev_pager *dev_pager_t;
struct kmem_cache dev_pager_cache;
-void dev_pager_reference(register dev_pager_t ds)
+void dev_pager_reference(dev_pager_t ds)
{
simple_lock(&ds->lock);
ds->ref_count++;
simple_unlock(&ds->lock);
}
-void dev_pager_deallocate(register dev_pager_t ds)
+void dev_pager_deallocate(dev_pager_t ds)
{
simple_lock(&ds->lock);
if (--ds->ref_count > 0) {
@@ -169,8 +168,8 @@ decl_simple_lock_data(,
void dev_pager_hash_init(void)
{
- register int i;
- register vm_size_t size;
+ int i;
+ vm_size_t size;
size = sizeof(struct dev_pager_entry);
kmem_cache_init(&dev_pager_hash_cache, "dev_pager_entry", size, 0,
@@ -181,10 +180,10 @@ void dev_pager_hash_init(void)
}
void dev_pager_hash_insert(
- ipc_port_t name_port,
- dev_pager_t rec)
+ const ipc_port_t name_port,
+ const dev_pager_t rec)
{
- register dev_pager_entry_t new_entry;
+ dev_pager_entry_t new_entry;
new_entry = (dev_pager_entry_t) kmem_cache_alloc(&dev_pager_hash_cache);
new_entry->name = name_port;
@@ -196,10 +195,10 @@ void dev_pager_hash_insert(
simple_unlock(&dev_pager_hash_lock);
}
-void dev_pager_hash_delete(ipc_port_t name_port)
+void dev_pager_hash_delete(const ipc_port_t name_port)
{
- register queue_t bucket;
- register dev_pager_entry_t entry;
+ queue_t bucket;
+ dev_pager_entry_t entry;
bucket = &dev_pager_hashtable[dev_pager_hash(name_port)];
@@ -217,11 +216,11 @@ void dev_pager_hash_delete(ipc_port_t name_port)
kmem_cache_free(&dev_pager_hash_cache, (vm_offset_t)entry);
}
-dev_pager_t dev_pager_hash_lookup(ipc_port_t name_port)
+dev_pager_t dev_pager_hash_lookup(const ipc_port_t name_port)
{
- register queue_t bucket;
- register dev_pager_entry_t entry;
- register dev_pager_t pager;
+ queue_t bucket;
+ dev_pager_entry_t entry;
+ dev_pager_t pager;
bucket = &dev_pager_hashtable[dev_pager_hash(name_port)];
@@ -241,13 +240,13 @@ dev_pager_t dev_pager_hash_lookup(ipc_port_t name_port)
}
kern_return_t device_pager_setup(
- mach_device_t device,
- int prot,
- vm_offset_t offset,
- vm_size_t size,
- mach_port_t *pager)
+ const mach_device_t device,
+ int prot,
+ vm_offset_t offset,
+ vm_size_t size,
+ mach_port_t *pager)
{
- register dev_pager_t d;
+ dev_pager_t d;
/*
* Verify the device is indeed mappable
@@ -318,28 +317,20 @@ void device_pager_release(memory_object_t object)
boolean_t device_pager_debug = FALSE;
-boolean_t device_pager_data_request_done(); /* forward */
-boolean_t device_pager_data_write_done(); /* forward */
-
-
kern_return_t device_pager_data_request(
- ipc_port_t pager,
- ipc_port_t pager_request,
- vm_offset_t offset,
- vm_size_t length,
- vm_prot_t protection_required)
+ const ipc_port_t pager,
+ const ipc_port_t pager_request,
+ vm_offset_t offset,
+ vm_size_t length,
+ vm_prot_t protection_required)
{
- register dev_pager_t ds;
-
-#ifdef lint
- protection_required++;
-#endif /* lint */
+ dev_pager_t ds;
if (device_pager_debug)
printf("(device_pager)data_request: pager=%p, offset=0x%lx, length=0x%x\n",
pager, offset, length);
- ds = dev_pager_hash_lookup((ipc_port_t)pager);
+ ds = dev_pager_hash_lookup(pager);
if (ds == DEV_PAGER_NULL)
panic("(device_pager)data_request: lookup failed");
@@ -347,8 +338,7 @@ kern_return_t device_pager_data_request(
panic("(device_pager)data_request: bad pager_request");
if (ds->type == CHAR_PAGER_TYPE) {
- register vm_object_t object;
- vm_offset_t device_map_page(void *,vm_offset_t);
+ vm_object_t object;
object = vm_object_lookup(pager_request);
if (object == VM_OBJECT_NULL) {
@@ -361,13 +351,13 @@ kern_return_t device_pager_data_request(
vm_object_page_map(object,
offset, length,
- device_map_page, (char *)ds);
+ device_map_page, (void *)ds);
vm_object_deallocate(object);
}
else {
- register io_req_t ior;
- register mach_device_t device;
+ io_req_t ior;
+ mach_device_t device;
io_return_t result;
panic("(device_pager)data_request: dev pager");
@@ -415,7 +405,7 @@ kern_return_t device_pager_data_request(
/*
* Always called by io_done thread.
*/
-boolean_t device_pager_data_request_done(register io_req_t ior)
+boolean_t device_pager_data_request_done(io_req_t ior)
{
vm_offset_t start_alloc, end_alloc;
vm_size_t size_read;
@@ -424,15 +414,15 @@ boolean_t device_pager_data_request_done(register io_req_t ior)
size_read = ior->io_count;
if (ior->io_residual) {
if (device_pager_debug)
- printf("(device_pager)data_request_done: r: 0x%lx\n",ior->io_residual);
+ printf("(device_pager)data_request_done: r: 0x%lx\n", ior->io_residual);
memset((&ior->io_data[ior->io_count - ior->io_residual]), 0,
- (unsigned) ior->io_residual);
+ (size_t) ior->io_residual);
}
} else {
size_read = ior->io_count - ior->io_residual;
}
- start_alloc = trunc_page((vm_offset_t)ior->io_data);
+ start_alloc = trunc_page(ior->io_data);
end_alloc = start_alloc + round_page(ior->io_alloc_size);
if (ior->io_error == D_SUCCESS) {
@@ -467,20 +457,20 @@ boolean_t device_pager_data_request_done(register io_req_t ior)
}
kern_return_t device_pager_data_write(
- ipc_port_t pager,
- ipc_port_t pager_request,
- register vm_offset_t offset,
- register pointer_t addr,
+ const ipc_port_t pager,
+ const ipc_port_t pager_request,
+ vm_offset_t offset,
+ pointer_t addr,
vm_size_t data_count)
{
- register dev_pager_t ds;
- register mach_device_t device;
- register io_req_t ior;
+ dev_pager_t ds;
+ mach_device_t device;
+ io_req_t ior;
kern_return_t result;
panic("(device_pager)data_write: called");
- ds = dev_pager_hash_lookup((ipc_port_t)pager);
+ ds = dev_pager_hash_lookup(pager);
if (ds == DEV_PAGER_NULL)
panic("(device_pager)data_write: lookup failed");
@@ -523,8 +513,7 @@ kern_return_t device_pager_data_write(
return (KERN_SUCCESS);
}
-boolean_t device_pager_data_write_done(ior)
- register io_req_t ior;
+boolean_t device_pager_data_write_done(io_req_t ior)
{
device_write_dealloc(ior);
mach_device_deallocate(ior->io_device);
@@ -533,19 +522,19 @@ boolean_t device_pager_data_write_done(ior)
}
kern_return_t device_pager_copy(
- ipc_port_t pager,
- ipc_port_t pager_request,
- register vm_offset_t offset,
- register vm_size_t length,
- ipc_port_t new_pager)
+ const ipc_port_t pager,
+ const ipc_port_t pager_request,
+ vm_offset_t offset,
+ vm_size_t length,
+ const ipc_port_t new_pager)
{
panic("(device_pager)copy: called");
}
kern_return_t
device_pager_supply_completed(
- ipc_port_t pager,
- ipc_port_t pager_request,
+ const ipc_port_t pager,
+ const ipc_port_t pager_request,
vm_offset_t offset,
vm_size_t length,
kern_return_t result,
@@ -556,10 +545,10 @@ device_pager_supply_completed(
kern_return_t
device_pager_data_return(
- ipc_port_t pager,
- ipc_port_t pager_request,
+ const ipc_port_t pager,
+ const ipc_port_t pager_request,
vm_offset_t offset,
- register pointer_t addr,
+ pointer_t addr,
vm_size_t data_cnt,
boolean_t dirty,
boolean_t kernel_copy)
@@ -569,7 +558,7 @@ device_pager_data_return(
kern_return_t
device_pager_change_completed(
- ipc_port_t pager,
+ const ipc_port_t pager,
boolean_t may_cache,
memory_object_copy_strategy_t copy_strategy)
{
@@ -586,7 +575,7 @@ vm_offset_t device_map_page(
void *dsp,
vm_offset_t offset)
{
- register dev_pager_t ds = (dev_pager_t) dsp;
+ dev_pager_t ds = (dev_pager_t) dsp;
return pmap_phys_address(
(*(ds->device->dev_ops->d_mmap))
@@ -594,12 +583,12 @@ vm_offset_t device_map_page(
}
kern_return_t device_pager_init_pager(
- ipc_port_t pager,
- ipc_port_t pager_request,
- ipc_port_t pager_name,
- vm_size_t pager_page_size)
+ const ipc_port_t pager,
+ const ipc_port_t pager_request,
+ const ipc_port_t pager_name,
+ vm_size_t pager_page_size)
{
- register dev_pager_t ds;
+ dev_pager_t ds;
if (device_pager_debug)
printf("(device_pager)init: pager=%p, request=%p, name=%p\n",
@@ -645,11 +634,11 @@ kern_return_t device_pager_init_pager(
}
kern_return_t device_pager_terminate(
- ipc_port_t pager,
- ipc_port_t pager_request,
- ipc_port_t pager_name)
+ const ipc_port_t pager,
+ const ipc_port_t pager_request,
+ const ipc_port_t pager_name)
{
- register dev_pager_t ds;
+ dev_pager_t ds;
assert(IP_VALID(pager_request));
assert(IP_VALID(pager_name));
@@ -687,37 +676,29 @@ kern_return_t device_pager_terminate(
}
kern_return_t device_pager_data_unlock(
- ipc_port_t memory_object,
- ipc_port_t memory_control_port,
+ const ipc_port_t memory_object,
+ const ipc_port_t memory_control_port,
vm_offset_t offset,
vm_size_t length,
vm_prot_t desired_access)
{
-#ifdef lint
- memory_object++; memory_control_port++; offset++; length++; desired_access++;
-#endif /* lint */
-
panic("(device_pager)data_unlock: called");
return (KERN_FAILURE);
}
kern_return_t device_pager_lock_completed(
- ipc_port_t memory_object,
- ipc_port_t pager_request_port,
- vm_offset_t offset,
- vm_size_t length)
+ const ipc_port_t memory_object,
+ const ipc_port_t pager_request_port,
+ vm_offset_t offset,
+ vm_size_t length)
{
-#ifdef lint
- memory_object++; pager_request_port++; offset++; length++;
-#endif /* lint */
-
panic("(device_pager)lock_completed: called");
return (KERN_FAILURE);
}
void device_pager_init(void)
{
- register vm_size_t size;
+ vm_size_t size;
/*
* Initialize cache of paging structures.
diff --git a/device/dev_pager.h b/device/dev_pager.h
new file mode 100644
index 00000000..7f97ee7e
--- /dev/null
+++ b/device/dev_pager.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _DEVICE_DEV_PAGER_H_
+#define _DEVICE_DEV_PAGER_H_
+
+vm_offset_t device_map_page(void *dsp, vm_offset_t offset);
+
+boolean_t device_pager_data_request_done(io_req_t ior);
+
+boolean_t device_pager_data_write_done(io_req_t ior);
+
+#endif /* _DEVICE_DEV_PAGER_H_ */
diff --git a/device/device_init.c b/device/device_init.c
index e43a2a95..794186ee 100644
--- a/device/device_init.c
+++ b/device/device_init.c
@@ -38,20 +38,15 @@
#include <device/device_types.h>
#include <device/device_port.h>
#include <device/tty.h>
+#include <device/ds_routines.h>
+#include <device/net_io.h>
+#include <device/chario.h>
-extern void mach_device_init();
-extern void dev_lookup_init();
-extern void net_io_init();
-extern void device_pager_init();
-
-extern void io_done_thread();
-extern void net_thread();
-
ipc_port_t master_device_port;
void
-device_service_create()
+device_service_create(void)
{
master_device_port = ipc_port_alloc_kernel();
if (master_device_port == IP_NULL)
diff --git a/device/device_init.h b/device/device_init.h
new file mode 100644
index 00000000..175b34d7
--- /dev/null
+++ b/device/device_init.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _DEVICE_DEVICE_INIT_H_
+#define _DEVICE_DEVICE_INIT_H_
+
+extern void device_service_create(void);
+
+#endif /* _DEVICE_DEVICE_INIT_H_ */
diff --git a/device/device_types_kernel.h b/device/device_types_kernel.h
index 87ce00f5..e17055c1 100644
--- a/device/device_types_kernel.h
+++ b/device/device_types_kernel.h
@@ -38,7 +38,6 @@
#include <mach/port.h>
#include <device/dev_hdr.h>
-extern device_t dev_port_lookup(ipc_port_t);
extern ipc_port_t convert_device_to_port(device_t);
#endif /* _DEVICE_DEVICE_TYPES_KERNEL_H_ */
diff --git a/device/dk_label.c b/device/dk_label.c
deleted file mode 100644
index c7d459bd..00000000
--- a/device/dk_label.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993,1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: rz_disk.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- */
-
-#include <sys/types.h>
-#include <kern/printf.h>
-#include <sys/ioctl.h>
-#include <device/device_types.h>
-#include <device/disk_status.h>
-
-/* Checksum a disk label */
-unsigned
-dkcksum(lp)
- struct disklabel *lp;
-{
- register unsigned short *start, *end, sum = 0;
-
- start = (unsigned short *)lp;
- end = (unsigned short*)&lp->d_partitions[lp->d_npartitions];
- while (start < end) sum ^= *start++;
- return sum;
-}
-
-/* Perform some checks and then copy a disk label */
-setdisklabel(lp, nlp)
- struct disklabel *lp, *nlp;
-{
- if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
- (dkcksum(nlp) != 0))
- return D_INVALID_OPERATION;
- *lp = *nlp;
- return D_SUCCESS;
-}
-
-dkgetlabel(lp, flavor, data, count)
- struct disklabel *lp;
- int flavor;
- int * data; /* pointer to OUT array */
- unsigned int *count; /* OUT */
-{
-
- switch (flavor) {
- /* get */
- case DIOCGDINFO:
- *(struct disklabel *)data = *lp;
- *count = sizeof(struct disklabel)/sizeof(int);
- break;
- case DIOCGDINFO - (0x10<<16):
- *(struct disklabel *)data = *lp;
- *count = sizeof(struct disklabel)/sizeof(int) - 4;
- break;
- }
-}
-
-print_bsd_label(lp, str)
-struct disklabel *lp;
-char *str;
-{
-int i;
- printf("%s sectors %d, tracks %d, cylinders %d\n",
- str, lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders);
- printf("%s secpercyl %d, secperunit %d, npartitions %d\n",
- str, lp->d_secpercyl, lp->d_secperunit, lp->d_npartitions);
-
- for (i = 0; i < lp->d_npartitions; i++) {
- printf("%s %c: size = %d, offset = %d\n",
- str, 'a'+i,
- lp->d_partitions[i].p_size,
- lp->d_partitions[i].p_offset);
- }
-}
diff --git a/device/ds_routines.c b/device/ds_routines.c
index 68589dee..43ed5b5d 100644
--- a/device/ds_routines.c
+++ b/device/ds_routines.c
@@ -99,16 +99,16 @@
extern struct device_emulation_ops linux_block_emulation_ops;
#ifdef CONFIG_INET
extern struct device_emulation_ops linux_net_emulation_ops;
-extern void free_skbuffs ();
+extern void free_skbuffs (void);
#ifdef CONFIG_PCMCIA
extern struct device_emulation_ops linux_pcmcia_emulation_ops;
-#endif
-#endif
-#endif
+#endif /* CONFIG_PCMCIA */
+#endif /* CONFIG_INET */
+#endif /* LINUX_DEV */
#ifdef MACH_HYP
extern struct device_emulation_ops hyp_block_emulation_ops;
extern struct device_emulation_ops hyp_net_emulation_ops;
-#endif
+#endif /* MACH_HYP */
extern struct device_emulation_ops mach_device_emulation_ops;
/* List of emulations. */
@@ -120,13 +120,13 @@ static struct device_emulation_ops *emulation_list[] =
&linux_net_emulation_ops,
#ifdef CONFIG_PCMCIA
&linux_pcmcia_emulation_ops,
-#endif
-#endif
-#endif
+#endif /* CONFIG_PCMCIA */
+#endif /* CONFIG_INET */
+#endif /* LINUX_DEV */
#ifdef MACH_HYP
&hyp_block_emulation_ops,
&hyp_net_emulation_ops,
-#endif
+#endif /* MACH_HYP */
&mach_device_emulation_ops,
};
@@ -417,16 +417,15 @@ mach_convert_device_to_port (mach_device_t device)
}
static io_return_t
-device_open(reply_port, reply_port_type, mode, name, device_p)
- ipc_port_t reply_port;
- mach_msg_type_name_t reply_port_type;
- dev_mode_t mode;
- char * name;
- device_t *device_p; /* out */
+device_open(const ipc_port_t reply_port,
+ mach_msg_type_name_t reply_port_type,
+ dev_mode_t mode,
+ char * name,
+ device_t *device_p)
{
- register mach_device_t device;
- register kern_return_t result;
- register io_req_t ior;
+ mach_device_t device;
+ kern_return_t result;
+ io_req_t ior;
ipc_port_t notify;
/*
@@ -537,11 +536,10 @@ device_open(reply_port, reply_port_type, mode, name, device_p)
}
boolean_t
-ds_open_done(ior)
- register io_req_t ior;
+ds_open_done(const io_req_t ior)
{
kern_return_t result;
- register mach_device_t device;
+ mach_device_t device;
device = ior->io_device;
result = ior->io_error;
@@ -597,9 +595,10 @@ ds_open_done(ior)
}
static io_return_t
-device_close(device)
- register mach_device_t device;
+device_close(void *dev)
{
+ mach_device_t device = dev;
+
device_lock(device);
/*
@@ -639,7 +638,7 @@ device_close(device)
/*
* Close the device
*/
- (*device->dev_ops->d_close)(device->dev_number);
+ (*device->dev_ops->d_close)(device->dev_number, 0);
/*
* Finally mark it closed. If someone else is trying
@@ -660,19 +659,18 @@ device_close(device)
* Write to a device.
*/
static io_return_t
-device_write(device, reply_port, reply_port_type, mode, recnum,
- data, data_count, bytes_written)
- mach_device_t device;
- ipc_port_t reply_port;
- mach_msg_type_name_t reply_port_type;
- dev_mode_t mode;
- recnum_t recnum;
- io_buf_ptr_t data;
- unsigned int data_count;
- int *bytes_written; /* out */
+device_write(void *dev,
+ const ipc_port_t reply_port,
+ mach_msg_type_name_t reply_port_type,
+ dev_mode_t mode,
+ recnum_t recnum,
+ const io_buf_ptr_t data,
+ unsigned int data_count,
+ int *bytes_written)
{
- register io_req_t ior;
- register io_return_t result;
+ mach_device_t device = dev;
+ io_req_t ior;
+ io_return_t result;
if (device->state != DEV_STATE_OPEN)
return (D_NO_SUCH_DEVICE);
@@ -751,19 +749,18 @@ device_write(device, reply_port, reply_port_type, mode, recnum,
* Write to a device, but memory is in message.
*/
static io_return_t
-device_write_inband(device, reply_port, reply_port_type, mode, recnum,
- data, data_count, bytes_written)
- mach_device_t device;
- ipc_port_t reply_port;
- mach_msg_type_name_t reply_port_type;
- dev_mode_t mode;
- recnum_t recnum;
- io_buf_ptr_inband_t data;
- unsigned int data_count;
- int *bytes_written; /* out */
+device_write_inband(void *dev,
+ const ipc_port_t reply_port,
+ mach_msg_type_name_t reply_port_type,
+ dev_mode_t mode,
+ recnum_t recnum,
+ io_buf_ptr_inband_t data,
+ unsigned int data_count,
+ int *bytes_written)
{
- register io_req_t ior;
- register io_return_t result;
+ mach_device_t device = dev;
+ io_req_t ior;
+ io_return_t result;
if (device->state != DEV_STATE_OPEN)
return (D_NO_SUCH_DEVICE);
@@ -824,13 +821,13 @@ device_write_inband(device, reply_port, reply_port_type, mode, recnum,
* Wire down incoming memory to give to device.
*/
kern_return_t
-device_write_get(ior, wait)
- register io_req_t ior;
- boolean_t *wait;
+device_write_get(
+ io_req_t ior,
+ boolean_t *wait)
{
vm_map_copy_t io_copy;
vm_offset_t new_addr;
- register kern_return_t result;
+ kern_return_t result;
int bsize;
vm_size_t min_size;
@@ -919,11 +916,9 @@ device_write_get(ior, wait)
* Clean up memory allocated for IO.
*/
boolean_t
-device_write_dealloc(ior)
- register io_req_t ior;
+device_write_dealloc(io_req_t ior)
{
vm_map_copy_t new_copy = VM_MAP_COPY_NULL;
- register
vm_map_copy_t io_copy;
kern_return_t result;
vm_offset_t size_to_do;
@@ -971,7 +966,7 @@ device_write_dealloc(ior)
}
if (result == KERN_SUCCESS && new_copy != VM_MAP_COPY_NULL) {
- register int res;
+ int res;
/*
* We have a new continuation, reset the ior to
@@ -1021,16 +1016,15 @@ device_write_dealloc(ior)
* Send write completion message to client, and discard the data.
*/
boolean_t
-ds_write_done(ior)
- register io_req_t ior;
+ds_write_done(const io_req_t ior)
{
/*
* device_write_dealloc discards the data that has been
* written, but may decide that there is more to write.
*/
while (!device_write_dealloc(ior)) {
- register io_return_t result;
- register mach_device_t device;
+ io_return_t result;
+ mach_device_t device;
/*
* More IO to do -- invoke it.
@@ -1067,24 +1061,18 @@ ds_write_done(ior)
* Read from a device.
*/
static io_return_t
-device_read(device, reply_port, reply_port_type, mode, recnum,
- bytes_wanted, data, data_count)
- mach_device_t device;
- ipc_port_t reply_port;
- mach_msg_type_name_t reply_port_type;
- dev_mode_t mode;
- recnum_t recnum;
- int bytes_wanted;
- io_buf_ptr_t *data; /* out */
- unsigned int *data_count; /* out */
+device_read(void *dev,
+ const ipc_port_t reply_port,
+ mach_msg_type_name_t reply_port_type,
+ dev_mode_t mode,
+ recnum_t recnum,
+ int bytes_wanted,
+ io_buf_ptr_t *data,
+ unsigned int *data_count)
{
- register io_req_t ior;
- register io_return_t result;
-
-#ifdef lint
- *data = *data;
- *data_count = *data_count;
-#endif /* lint */
+ mach_device_t device = dev;
+ io_req_t ior;
+ io_return_t result;
if (device->state != DEV_STATE_OPEN)
return (D_NO_SUCH_DEVICE);
@@ -1149,24 +1137,18 @@ device_read(device, reply_port, reply_port_type, mode, recnum,
* Read from a device, but return the data 'inband.'
*/
static io_return_t
-device_read_inband(device, reply_port, reply_port_type, mode, recnum,
- bytes_wanted, data, data_count)
- mach_device_t device;
- ipc_port_t reply_port;
- mach_msg_type_name_t reply_port_type;
- dev_mode_t mode;
- recnum_t recnum;
- int bytes_wanted;
- char *data; /* pointer to OUT array */
- unsigned int *data_count; /* out */
+device_read_inband(void *dev,
+ const ipc_port_t reply_port,
+ mach_msg_type_name_t reply_port_type,
+ dev_mode_t mode,
+ recnum_t recnum,
+ int bytes_wanted,
+ char *data,
+ unsigned int *data_count)
{
- register io_req_t ior;
- register io_return_t result;
-
-#ifdef lint
- *data = *data;
- *data_count = *data_count;
-#endif /* lint */
+ mach_device_t device = dev;
+ io_req_t ior;
+ io_return_t result;
if (device->state != DEV_STATE_OPEN)
return (D_NO_SUCH_DEVICE);
@@ -1232,9 +1214,9 @@ device_read_inband(device, reply_port, reply_port_type, mode, recnum,
/*
* Allocate wired-down memory for device read.
*/
-kern_return_t device_read_alloc(ior, size)
- register io_req_t ior;
- register vm_size_t size;
+kern_return_t device_read_alloc(
+ io_req_t ior,
+ vm_size_t size)
{
vm_offset_t addr;
kern_return_t kr;
@@ -1261,12 +1243,11 @@ kern_return_t device_read_alloc(ior, size)
return (KERN_SUCCESS);
}
-boolean_t ds_read_done(ior)
- io_req_t ior;
+boolean_t ds_read_done(const io_req_t ior)
{
vm_offset_t start_data, end_data;
vm_offset_t start_sent, end_sent;
- register vm_size_t size_read;
+ vm_size_t size_read;
if (ior->io_error)
size_read = 0;
@@ -1285,9 +1266,9 @@ boolean_t ds_read_done(ior)
* Zero memory that the device did not fill.
*/
if (start_sent < start_data)
- memset((char *)start_sent, 0, start_data - start_sent);
+ memset((void *)start_sent, 0, start_data - start_sent);
if (end_sent > end_data)
- memset((char *)end_data, 0, end_sent - end_data);
+ memset((void *)end_data, 0, end_sent - end_data);
/*
@@ -1296,8 +1277,8 @@ boolean_t ds_read_done(ior)
* may think that they are clean.
*/
{
- register vm_offset_t touch;
- register int c;
+ vm_offset_t touch;
+ int c;
for (touch = start_sent; touch < end_sent; touch += PAGE_SIZE) {
c = *(volatile char *)touch;
@@ -1341,7 +1322,7 @@ boolean_t ds_read_done(ior)
if (ior->io_alloc_size > 0)
kmem_cache_free(&io_inband_cache, (vm_offset_t)ior->io_data);
} else {
- register vm_offset_t end_alloc;
+ vm_offset_t end_alloc;
end_alloc = start_sent + round_page(ior->io_alloc_size);
if (end_alloc > end_sent)
@@ -1357,12 +1338,13 @@ boolean_t ds_read_done(ior)
}
static io_return_t
-device_set_status(device, flavor, status, status_count)
- mach_device_t device;
- dev_flavor_t flavor;
- dev_status_t status;
- mach_msg_type_number_t status_count;
+device_set_status(
+ void *dev,
+ dev_flavor_t flavor,
+ dev_status_t status,
+ mach_msg_type_number_t status_count)
{
+ mach_device_t device = dev;
if (device->state != DEV_STATE_OPEN)
return (D_NO_SUCH_DEVICE);
@@ -1375,12 +1357,13 @@ device_set_status(device, flavor, status, status_count)
}
io_return_t
-mach_device_get_status(device, flavor, status, status_count)
- mach_device_t device;
- dev_flavor_t flavor;
- dev_status_t status; /* pointer to OUT array */
- mach_msg_type_number_t *status_count; /* out */
+mach_device_get_status(
+ void *dev,
+ dev_flavor_t flavor,
+ dev_status_t status, /* pointer to OUT array */
+ mach_msg_type_number_t *status_count) /* out */
{
+ mach_device_t device = dev;
if (device->state != DEV_STATE_OPEN)
return (D_NO_SUCH_DEVICE);
@@ -1393,13 +1376,13 @@ mach_device_get_status(device, flavor, status, status_count)
}
static io_return_t
-device_set_filter(device, receive_port, priority, filter, filter_count)
- mach_device_t device;
- ipc_port_t receive_port;
- int priority;
- filter_t filter[]; /* pointer to IN array */
- unsigned int filter_count;
+device_set_filter(void *dev,
+ const ipc_port_t receive_port,
+ int priority,
+ filter_t filter[],
+ unsigned int filter_count)
{
+ mach_device_t device = dev;
if (device->state != DEV_STATE_OPEN)
return (D_NO_SUCH_DEVICE);
@@ -1419,17 +1402,15 @@ device_set_filter(device, receive_port, priority, filter, filter_count)
}
static io_return_t
-device_map(device, protection, offset, size, pager, unmap)
- mach_device_t device;
- vm_prot_t protection;
- vm_offset_t offset;
- vm_size_t size;
- ipc_port_t *pager; /* out */
- boolean_t unmap; /* ? */
+device_map(
+ void *dev,
+ vm_prot_t protection,
+ vm_offset_t offset,
+ vm_size_t size,
+ ipc_port_t *pager, /* out */
+ boolean_t unmap) /* ? */
{
-#ifdef lint
- unmap = unmap;
-#endif /* lint */
+ mach_device_t device = dev;
if (protection & ~VM_PROT_ALL)
return (KERN_INVALID_ARGUMENT);
@@ -1446,8 +1427,7 @@ device_map(device, protection, offset, size, pager, unmap)
* Doesn't do anything (yet).
*/
static void
-ds_no_senders(notification)
- mach_no_senders_notification_t *notification;
+ds_no_senders(mach_no_senders_notification_t *notification)
{
printf("ds_no_senders called! device_port=0x%lx count=%d\n",
notification->not_header.msgh_remote_port,
@@ -1459,10 +1439,9 @@ decl_simple_lock_data(, io_done_list_lock)
#define splio splsched /* XXX must block ALL io devices */
-void iodone(ior)
- register io_req_t ior;
+void iodone(io_req_t ior)
{
- register spl_t s;
+ spl_t s;
/*
* If this ior was loaned to us, return it directly.
@@ -1493,11 +1472,11 @@ void iodone(ior)
splx(s);
}
-void io_done_thread_continue()
+void __attribute__ ((noreturn)) io_done_thread_continue(void)
{
for (;;) {
- register spl_t s;
- register io_req_t ior;
+ spl_t s;
+ io_req_t ior;
#if defined (LINUX_DEV) && defined (CONFIG_INET)
free_skbuffs ();
@@ -1528,7 +1507,7 @@ void io_done_thread_continue()
}
}
-void io_done_thread()
+void io_done_thread(void)
{
/*
* Set thread privileges and highest priority.
@@ -1545,7 +1524,7 @@ void io_done_thread()
static void mach_device_trap_init(void); /* forward */
-void mach_device_init()
+void mach_device_init(void)
{
vm_offset_t device_io_min, device_io_max;
@@ -1580,8 +1559,7 @@ void mach_device_init()
mach_device_trap_init();
}
-void iowait(ior)
- io_req_t ior;
+void iowait(io_req_t ior)
{
spl_t s;
@@ -1631,7 +1609,7 @@ mach_device_trap_init(void)
* Could call a device-specific routine.
*/
io_req_t
-ds_trap_req_alloc(mach_device_t device, vm_size_t data_size)
+ds_trap_req_alloc(const mach_device_t device, vm_size_t data_size)
{
return (io_req_t) kmem_cache_alloc(&io_trap_cache);
}
@@ -1640,9 +1618,9 @@ ds_trap_req_alloc(mach_device_t device, vm_size_t data_size)
* Called by iodone to release ior.
*/
boolean_t
-ds_trap_write_done(io_req_t ior)
+ds_trap_write_done(const io_req_t ior)
{
- register mach_device_t dev;
+ mach_device_t dev;
dev = ior->io_device;
@@ -1702,7 +1680,7 @@ device_write_trap (mach_device_t device, dev_mode_t mode,
* Copy the data from user space.
*/
if (data_count > 0)
- copyin((char *)data, (char *)ior->io_data, data_count);
+ copyin((void *)data, ior->io_data, data_count);
/*
* The ior keeps an extra reference for the device.
@@ -1749,8 +1727,8 @@ device_writev_trap (mach_device_t device, dev_mode_t mode,
*/
if (iocount > 16)
return KERN_INVALID_VALUE; /* lame */
- copyin((char *)iovec,
- (char *)stack_iovec,
+ copyin(iovec,
+ stack_iovec,
iocount * sizeof(io_buf_vec_t));
for (data_count = 0, i = 0; i < iocount; i++)
data_count += stack_iovec[i].count;
@@ -1788,8 +1766,8 @@ device_writev_trap (mach_device_t device, dev_mode_t mode,
p = (vm_offset_t) ior->io_data;
for (i = 0; i < iocount; i++) {
- copyin((char *) stack_iovec[i].data,
- (char *) p,
+ copyin((void *) stack_iovec[i].data,
+ (void *) p,
stack_iovec[i].count);
p += stack_iovec[i].count;
}
diff --git a/device/ds_routines.h b/device/ds_routines.h
index a00a12d5..c0543cbc 100644
--- a/device/ds_routines.h
+++ b/device/ds_routines.h
@@ -49,7 +49,6 @@ kern_return_t device_read_alloc(io_req_t, vm_size_t);
kern_return_t device_write_get(io_req_t, boolean_t *);
boolean_t device_write_dealloc(io_req_t);
void device_reference(device_t);
-void device_deallocate(device_t);
boolean_t ds_notify(mach_msg_header_t *msg);
boolean_t ds_open_done(io_req_t);
@@ -58,4 +57,30 @@ boolean_t ds_write_done(io_req_t);
void iowait (io_req_t ior);
+kern_return_t device_pager_setup(
+ const mach_device_t device,
+ int prot,
+ vm_offset_t offset,
+ vm_size_t size,
+ mach_port_t *pager);
+
+extern void mach_device_init(void);
+extern void dev_lookup_init(void);
+extern void device_pager_init(void);
+extern void io_done_thread(void) __attribute__ ((noreturn));
+
+io_return_t ds_device_write_trap(
+ device_t dev,
+ dev_mode_t mode,
+ recnum_t recnum,
+ vm_offset_t data,
+ vm_size_t count);
+
+io_return_t ds_device_writev_trap(
+ device_t dev,
+ dev_mode_t mode,
+ recnum_t recnum,
+ io_buf_vec_t *iovec,
+ vm_size_t count);
+
#endif /* DS_ROUTINES_H */
diff --git a/device/if_ether.h b/device/if_ether.h
index 2ac938e2..91d4d9a6 100644
--- a/device/if_ether.h
+++ b/device/if_ether.h
@@ -45,13 +45,8 @@ struct ether_header {
u_short ether_type;
};
-#define ETHERMTU 1500
-#define ETHERMIN (60-14)
-
#ifdef KERNEL
-u_char etherbroadcastaddr[6];
-
-extern char * ether_sprintf(u_char *);
+extern char * ether_sprintf(const u_char *);
#endif /* KERNEL */
#endif /*_DEVICE_IF_ETHER_H_*/
diff --git a/device/io_req.h b/device/io_req.h
index 65e23e60..1ad46801 100644
--- a/device/io_req.h
+++ b/device/io_req.h
@@ -42,7 +42,7 @@
#include <device/device_types.h>
#include <device/dev_hdr.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
/*
* IO request element, queued on device for delayed replies.
diff --git a/device/kmsg.c b/device/kmsg.c
index c8bd897a..c80775d9 100644
--- a/device/kmsg.c
+++ b/device/kmsg.c
@@ -42,11 +42,11 @@ static int kmsg_read_offset;
/* I/O request queue for blocking read */
static queue_head_t kmsg_read_queue;
/* Used for exclusive access to the device */
-static int kmsg_in_use;
+static boolean_t kmsg_in_use;
/* Used for exclusive access to the routines */
decl_simple_lock_data (static, kmsg_lock);
/* If already initialized or not */
-static int kmsg_init_done = 0;
+static boolean_t kmsg_init_done = FALSE;
/* Kernel Message Initializer */
static void
@@ -55,13 +55,13 @@ kmsginit (void)
kmsg_write_offset = 0;
kmsg_read_offset = 0;
queue_init (&kmsg_read_queue);
- kmsg_in_use = 0;
+ kmsg_in_use = FALSE;
simple_lock_init (&kmsg_lock);
}
/* Kernel Message Open Handler */
io_return_t
-kmsgopen (dev_t dev, int flag, io_req_t ior)
+kmsgopen (dev_t dev, int flag, const io_req_t ior)
{
simple_lock (&kmsg_lock);
if (kmsg_in_use)
@@ -70,21 +70,20 @@ kmsgopen (dev_t dev, int flag, io_req_t ior)
return D_ALREADY_OPEN;
}
- kmsg_in_use = 1;
+ kmsg_in_use = TRUE;
simple_unlock (&kmsg_lock);
return D_SUCCESS;
}
/* Kernel Message Close Handler */
-io_return_t
+void
kmsgclose (dev_t dev, int flag)
{
simple_lock (&kmsg_lock);
- kmsg_in_use = 0;
+ kmsg_in_use = FALSE;
simple_unlock (&kmsg_lock);
- return D_SUCCESS;
}
static boolean_t kmsg_read_done (io_req_t ior);
@@ -225,7 +224,7 @@ kmsg_putchar (int c)
if (!kmsg_init_done)
{
kmsginit ();
- kmsg_init_done = 1;
+ kmsg_init_done = TRUE;
}
simple_lock (&kmsg_lock);
diff --git a/device/kmsg.h b/device/kmsg.h
index b8c1f366..8d907f1b 100644
--- a/device/kmsg.h
+++ b/device/kmsg.h
@@ -8,7 +8,7 @@
#include <device/io_req.h>
io_return_t kmsgopen (dev_t dev, int flag, io_req_t ior);
-io_return_t kmsgclose (dev_t dev, int flag);
+void kmsgclose (dev_t dev, int flag);
io_return_t kmsgread (dev_t dev, io_req_t ior);
io_return_t kmsggetstat (dev_t dev, int flavor,
int *data, unsigned int *count);
diff --git a/device/net_io.c b/device/net_io.c
index 4ebf9964..47ef2ea8 100644
--- a/device/net_io.c
+++ b/device/net_io.c
@@ -144,7 +144,7 @@ vm_size_t net_kmsg_size; /* initialized below */
ipc_kmsg_t
net_kmsg_get(void)
{
- register ipc_kmsg_t kmsg;
+ ipc_kmsg_t kmsg;
spl_t s;
/*
@@ -196,7 +196,7 @@ net_kmsg_get(void)
}
void
-net_kmsg_put(register ipc_kmsg_t kmsg)
+net_kmsg_put(const ipc_kmsg_t kmsg)
{
spl_t s;
@@ -212,7 +212,7 @@ net_kmsg_put(register ipc_kmsg_t kmsg)
void
net_kmsg_collect(void)
{
- register ipc_kmsg_t kmsg;
+ ipc_kmsg_t kmsg;
spl_t s;
s = splimp();
@@ -238,7 +238,7 @@ net_kmsg_collect(void)
void
net_kmsg_more(void)
{
- register ipc_kmsg_t kmsg;
+ ipc_kmsg_t kmsg;
/*
* Replenish net kmsg pool if low. We don't have the locks
@@ -301,17 +301,13 @@ struct net_rcv_port {
filter_t filter[NET_MAX_FILTER];
/* filter operations */
};
-typedef struct net_rcv_port *net_rcv_port_t;
struct kmem_cache net_rcv_cache; /* cache of net_rcv_port structs */
-
#define NET_HASH_SIZE 256
#define N_NET_HASH 4
#define N_NET_HASH_KEYS 4
-unsigned int bpf_hash (int, unsigned int *);
-
/*
* A single hash entry.
*/
@@ -323,7 +319,6 @@ struct net_hash_entry {
int rcv_qlimit; /* qlimit for the port */
unsigned int keys[N_NET_HASH_KEYS];
};
-typedef struct net_hash_entry *net_hash_entry_t;
struct kmem_cache net_hash_entry_cache;
@@ -342,8 +337,6 @@ struct net_hash_header {
net_hash_entry_t table[NET_HASH_SIZE];
} filter_hash_header[N_NET_HASH];
-typedef struct net_hash_header *net_hash_header_t;
-
decl_simple_lock_data(,net_hash_header_lock)
#define HASH_ITERATE(head, elt) (elt) = (net_hash_entry_t) (head); do {
@@ -351,7 +344,6 @@ decl_simple_lock_data(,net_hash_header_lock)
(elt) = (net_hash_entry_t) queue_next((queue_entry_t) (elt)); \
} while ((elt) != (head));
-
#define FILTER_ITERATE(if_port_list, fp, nextfp, chain) \
for ((fp) = (net_rcv_port_t) queue_first(if_port_list); \
!queue_end(if_port_list, (queue_entry_t)(fp)); \
@@ -361,44 +353,10 @@ decl_simple_lock_data(,net_hash_header_lock)
/* entry_p must be net_rcv_port_t or net_hash_entry_t */
#define ENQUEUE_DEAD(dead, entry_p, chain) { \
- queue_next(&(entry_p)->chain) = (queue_entry_t) (dead); \
+ (entry_p)->chain.next = (queue_entry_t) (dead); \
(dead) = (queue_entry_t)(entry_p); \
}
-extern boolean_t net_do_filter(); /* CSPF */
-extern int bpf_do_filter(); /* BPF */
-
-int hash_ent_remove (
- struct ifnet *ifp,
- net_hash_header_t hp,
- int used,
- net_hash_entry_t *head,
- net_hash_entry_t entp,
- queue_entry_t *dead_p);
-
-void net_free_dead_infp (queue_entry_t dead_infp);
-void net_free_dead_entp (queue_entry_t dead_entp);
-
-int bpf_validate(
- bpf_insn_t f,
- int bytes,
- bpf_insn_t *match);
-
-int bpf_eq (
- bpf_insn_t f1,
- bpf_insn_t f2,
- register int bytes);
-
-int net_add_q_info (ipc_port_t rcv_port);
-
-int bpf_match (
- net_hash_header_t hash,
- int n_keys,
- unsigned long *keys,
- net_hash_entry_t **hash_headpp,
- net_hash_entry_t *entpp);
-
-
/*
* ethernet_priority:
*
@@ -411,9 +369,9 @@ int bpf_match (
*/
boolean_t ethernet_priority(kmsg)
- ipc_kmsg_t kmsg;
+ const ipc_kmsg_t kmsg;
{
- register unsigned char *addr =
+ unsigned char *addr =
(unsigned char *) net_kmsg(kmsg)->header;
/*
@@ -454,10 +412,9 @@ mach_msg_type_t packet_type = {
* Dequeues a message and delivers it at spl0.
* Returns FALSE if no messages.
*/
-boolean_t net_deliver(nonblocking)
- boolean_t nonblocking;
+boolean_t net_deliver(boolean_t nonblocking)
{
- register ipc_kmsg_t kmsg;
+ ipc_kmsg_t kmsg;
boolean_t high_priority;
struct ipc_kmsg_queue send_list;
@@ -510,6 +467,7 @@ boolean_t net_deliver(nonblocking)
/* remember message sizes must be rounded up */
kmsg->ikm_header.msgh_size =
(((mach_msg_size_t) (sizeof(struct net_rcv_msg)
+ - sizeof net_kmsg(kmsg)->sent
- NET_RCV_MAX + count)) + 3) &~ 3;
kmsg->ikm_header.msgh_local_port = MACH_PORT_NULL;
kmsg->ikm_header.msgh_kind = MACH_MSGH_KIND_NORMAL;
@@ -562,7 +520,7 @@ boolean_t net_deliver(nonblocking)
* net_kmsg_get will do a wakeup.
*/
-void net_ast()
+void net_ast(void)
{
spl_t s;
@@ -591,7 +549,7 @@ void net_ast()
(void) splx(s);
}
-void net_thread_continue()
+void __attribute__ ((noreturn)) net_thread_continue(void)
{
for (;;) {
spl_t s;
@@ -617,7 +575,7 @@ void net_thread_continue()
}
}
-void net_thread()
+void net_thread(void)
{
spl_t s;
@@ -645,10 +603,11 @@ void net_thread()
}
void
-reorder_queue(first, last)
- register queue_t first, last;
+reorder_queue(
+ queue_t first,
+ queue_t last)
{
- register queue_entry_t prev, next;
+ queue_entry_t prev, next;
prev = first->prev;
next = last->next;
@@ -668,11 +627,11 @@ reorder_queue(first, last)
* We are already at splimp.
*/
void
-net_packet(ifp, kmsg, count, priority)
- register struct ifnet *ifp;
- register ipc_kmsg_t kmsg;
- unsigned int count;
- boolean_t priority;
+net_packet(
+ struct ifnet *ifp,
+ ipc_kmsg_t kmsg,
+ unsigned int count,
+ boolean_t priority)
{
boolean_t awake;
@@ -681,7 +640,7 @@ net_packet(ifp, kmsg, count, priority)
* Do a quick check to see if it is a kernel TTD packet.
*
* Only check if KernelTTD is enabled, ie. the current
- * device driver supports TTD, and the bootp succeded.
+ * device driver supports TTD, and the bootp succeeded.
*/
if (kttd_enabled && kttd_handle_async(kmsg)) {
/*
@@ -732,12 +691,12 @@ int net_filter_queue_reorder = 0; /* non-zero to enable reordering */
*/
void
net_filter(kmsg, send_list)
- register ipc_kmsg_t kmsg;
+ const ipc_kmsg_t kmsg;
ipc_kmsg_queue_t send_list;
{
- register struct ifnet *ifp;
- register net_rcv_port_t infp, nextfp;
- register ipc_kmsg_t new_kmsg;
+ struct ifnet *ifp;
+ net_rcv_port_t infp, nextfp;
+ ipc_kmsg_t new_kmsg;
net_hash_entry_t entp, *hash_headp;
ipc_port_t dest;
@@ -857,7 +816,7 @@ net_filter(kmsg, send_list)
ipc_kmsg_enqueue(send_list, new_kmsg);
{
- register net_rcv_port_t prevfp;
+ net_rcv_port_t prevfp;
int rcount = ++infp->rcv_count;
/*
@@ -914,14 +873,14 @@ net_filter(kmsg, send_list)
boolean_t
net_do_filter(infp, data, data_count, header)
net_rcv_port_t infp;
- char * data;
+ const char * data;
unsigned int data_count;
- char * header;
+ const char * header;
{
int stack[NET_FILTER_STACK_DEPTH+1];
- register int *sp;
- register filter_t *fp, *fpe;
- register unsigned int op, arg;
+ int *sp;
+ filter_t *fp, *fpe;
+ unsigned int op, arg;
/*
* The filter accesses the header and data
@@ -1052,13 +1011,13 @@ net_do_filter(infp, data, data_count, header)
* Check filter for invalid operations or stack over/under-flow.
*/
boolean_t
-parse_net_filter(filter, count)
- register filter_t *filter;
- unsigned int count;
+parse_net_filter(
+ filter_t *filter,
+ unsigned int count)
{
- register int sp;
- register filter_t *fpe = &filter[count];
- register filter_t op, arg;
+ int sp;
+ filter_t *fpe = &filter[count];
+ filter_t op, arg;
/*
* count is at least 1, and filter[0] is used for flags.
@@ -1146,19 +1105,19 @@ parse_net_filter(filter, count)
* If we are successful, we must consume that right.
*/
io_return_t
-net_set_filter(ifp, rcv_port, priority, filter, filter_count)
- struct ifnet *ifp;
- ipc_port_t rcv_port;
- int priority;
- filter_t *filter;
- unsigned int filter_count;
+net_set_filter(
+ struct ifnet *ifp,
+ ipc_port_t rcv_port,
+ int priority,
+ filter_t *filter,
+ unsigned int filter_count)
{
int filter_bytes;
bpf_insn_t match;
- register net_rcv_port_t infp, my_infp;
+ net_rcv_port_t infp, my_infp;
net_rcv_port_t nextfp;
net_hash_header_t hhp;
- register net_hash_entry_t entp, hash_entp;
+ net_hash_entry_t entp;
net_hash_entry_t *head, nextentp;
queue_entry_t dead_infp, dead_entp;
int i;
@@ -1166,6 +1125,13 @@ net_set_filter(ifp, rcv_port, priority, filter, filter_count)
io_return_t rval;
boolean_t in, out;
+ /* Initialize hash_entp to NULL to quiet GCC
+ * warning about uninitialized variable. hash_entp is only
+ * used when match != 0; in that case it is properly initialized
+ * by kmem_cache_alloc().
+ */
+ net_hash_entry_t hash_entp = NULL;
+
/*
* Check the filter syntax.
*/
@@ -1404,16 +1370,16 @@ clean_and_return:
* Other network operations
*/
io_return_t
-net_getstat(ifp, flavor, status, count)
- struct ifnet *ifp;
- dev_flavor_t flavor;
- dev_status_t status; /* pointer to OUT array */
- natural_t *count; /* OUT */
+net_getstat(
+ struct ifnet *ifp,
+ dev_flavor_t flavor,
+ dev_status_t status, /* pointer to OUT array */
+ natural_t *count) /* OUT */
{
switch (flavor) {
case NET_STATUS:
{
- register struct net_status *ns = (struct net_status *)status;
+ struct net_status *ns = (struct net_status *)status;
if (*count < NET_STATUS_COUNT)
return (D_INVALID_OPERATION);
@@ -1431,9 +1397,9 @@ net_getstat(ifp, flavor, status, count)
}
case NET_ADDRESS:
{
- register int addr_byte_count;
- register int addr_int_count;
- register int i;
+ int addr_byte_count;
+ int addr_int_count;
+ int i;
addr_byte_count = ifp->if_address_size;
addr_int_count = (addr_byte_count + (sizeof(int)-1))
@@ -1454,7 +1420,7 @@ printf ("net_getstat: count: %d, addr_int_count: %d\n",
- addr_byte_count));
for (i = 0; i < addr_int_count; i++) {
- register int word;
+ int word;
word = status[i];
status[i] = htonl(word);
@@ -1469,10 +1435,10 @@ printf ("net_getstat: count: %d, addr_int_count: %d\n",
}
io_return_t
-net_write(ifp, start, ior)
- register struct ifnet *ifp;
- int (*start)();
- io_req_t ior;
+net_write(
+ struct ifnet *ifp,
+ int (*start)(),
+ io_req_t ior)
{
spl_t s;
kern_return_t rc;
@@ -1523,9 +1489,9 @@ net_write(ifp, start, ior)
* Initialize the whole package.
*/
void
-net_io_init()
+net_io_init(void)
{
- register vm_size_t size;
+ vm_size_t size;
size = sizeof(struct net_rcv_port);
kmem_cache_init(&net_rcv_cache, "net_rcv_port", size, 0,
@@ -1625,20 +1591,21 @@ net_io_init()
*/
int
-bpf_do_filter(infp, p, wirelen, header, hlen, hash_headpp, entpp)
- net_rcv_port_t infp;
- char * p; /* packet data */
- unsigned int wirelen; /* data_count (in bytes) */
- char * header;
- unsigned int hlen; /* header len (in bytes) */
- net_hash_entry_t **hash_headpp, *entpp; /* out */
+bpf_do_filter(
+ net_rcv_port_t infp,
+ char * p, /* packet data */
+ unsigned int wirelen, /* data_count (in bytes) */
+ char * header,
+ unsigned int hlen, /* header len (in bytes) */
+ net_hash_entry_t **hash_headpp,
+ net_hash_entry_t *entpp) /* out */
{
- register bpf_insn_t pc, pc_end;
- register unsigned int buflen;
+ bpf_insn_t pc, pc_end;
+ unsigned int buflen;
- register unsigned long A, X;
- register int k;
- unsigned long mem[BPF_MEMWORDS];
+ unsigned int A, X;
+ int k;
+ unsigned int mem[BPF_MEMWORDS];
/* Generic pointer to either HEADER or P according to the specified offset. */
char *data = NULL;
@@ -1689,9 +1656,9 @@ bpf_do_filter(infp, p, wirelen, header, hlen, hash_headpp, entpp)
k = pc->k;
load_word:
- if ((u_int)k + sizeof(long) <= hlen)
+ if ((u_int)k + sizeof(int) <= hlen)
data = header;
- else if ((u_int)k + sizeof(long) <= buflen) {
+ else if ((u_int)k + sizeof(int) <= buflen) {
k -= hlen;
data = p;
} else
@@ -1702,7 +1669,7 @@ bpf_do_filter(infp, p, wirelen, header, hlen, hash_headpp, entpp)
A = EXTRACT_LONG(&data[k]);
else
#endif
- A = ntohl(*(long *)(data + k));
+ A = ntohl(*(int *)(data + k));
continue;
case BPF_LD|BPF_H|BPF_ABS:
@@ -1924,13 +1891,13 @@ bpf_do_filter(infp, p, wirelen, header, hlen, hash_headpp, entpp)
* Otherwise, a bogus program could easily crash the system.
*/
int
-bpf_validate(f, bytes, match)
- bpf_insn_t f;
- int bytes;
- bpf_insn_t *match;
+bpf_validate(
+ bpf_insn_t f,
+ int bytes,
+ bpf_insn_t *match)
{
- register int i, j, len;
- register bpf_insn_t p;
+ int i, j, len;
+ bpf_insn_t p;
len = BPF_BYTES2LEN(bytes);
@@ -1946,7 +1913,7 @@ bpf_validate(f, bytes, match)
*/
p = &f[i];
if (BPF_CLASS(p->code) == BPF_JMP) {
- register int from = i + 1;
+ int from = i + 1;
if (BPF_OP(p->code) == BPF_JA) {
if (from + p->k >= len)
@@ -1996,11 +1963,12 @@ bpf_validate(f, bytes, match)
}
int
-bpf_eq (f1, f2, bytes)
- register bpf_insn_t f1, f2;
- register int bytes;
+bpf_eq(
+ bpf_insn_t f1,
+ bpf_insn_t f2,
+ int bytes)
{
- register int count;
+ int count;
count = BPF_BYTES2LEN(bytes);
for (; count--; f1++, f2++) {
@@ -2016,10 +1984,10 @@ bpf_eq (f1, f2, bytes)
unsigned int
bpf_hash (n, keys)
- register int n;
- register unsigned int *keys;
+ int n;
+ const unsigned int *keys;
{
- register unsigned int hval = 0;
+ unsigned int hval = 0;
while (n--) {
hval += *keys++;
@@ -2031,12 +1999,12 @@ bpf_hash (n, keys)
int
bpf_match (hash, n_keys, keys, hash_headpp, entpp)
net_hash_header_t hash;
- register int n_keys;
- register unsigned long *keys;
+ int n_keys;
+ const unsigned int *keys;
net_hash_entry_t **hash_headpp, *entpp;
{
- register net_hash_entry_t head, entp;
- register int i;
+ net_hash_entry_t head, entp;
+ int i;
if (n_keys != hash->n_keys)
return FALSE;
@@ -2070,12 +2038,13 @@ bpf_match (hash, n_keys, keys, hash_headpp, entpp)
*/
int
-hash_ent_remove (ifp, hp, used, head, entp, dead_p)
- struct ifnet *ifp;
- net_hash_header_t hp;
- int used;
- net_hash_entry_t *head, entp;
- queue_entry_t *dead_p;
+hash_ent_remove(
+ struct ifnet *ifp,
+ net_hash_header_t hp,
+ int used,
+ net_hash_entry_t *head,
+ net_hash_entry_t entp,
+ queue_entry_t *dead_p)
{
hp->ref_count--;
@@ -2107,8 +2076,7 @@ hash_ent_remove (ifp, hp, used, head, entp, dead_p)
}
int
-net_add_q_info (rcv_port)
- ipc_port_t rcv_port;
+net_add_q_info(ipc_port_t rcv_port)
{
mach_port_msgcount_t qlimit = 0;
@@ -2133,8 +2101,7 @@ net_add_q_info (rcv_port)
}
void
-net_del_q_info (qlimit)
- int qlimit;
+net_del_q_info(int qlimit)
{
simple_lock(&net_kmsg_total_lock);
net_queue_free_min--;
@@ -2151,10 +2118,9 @@ net_del_q_info (qlimit)
* No locks should be held when called.
*/
void
-net_free_dead_infp (dead_infp)
- queue_entry_t dead_infp;
+net_free_dead_infp(queue_entry_t dead_infp)
{
- register net_rcv_port_t infp, nextfp;
+ net_rcv_port_t infp, nextfp;
for (infp = (net_rcv_port_t) dead_infp; infp != 0; infp = nextfp)
{
@@ -2173,10 +2139,9 @@ net_free_dead_infp (dead_infp)
* No locks should be held when called.
*/
void
-net_free_dead_entp (dead_entp)
- queue_entry_t dead_entp;
+net_free_dead_entp(queue_entry_t dead_entp)
{
- register net_hash_entry_t entp, nextentp;
+ net_hash_entry_t entp, nextentp;
for (entp = (net_hash_entry_t)dead_entp; entp != 0; entp = nextentp)
{
diff --git a/device/net_io.h b/device/net_io.h
index 073bdca7..d4e24d41 100644
--- a/device/net_io.h
+++ b/device/net_io.h
@@ -38,7 +38,7 @@
#include <mach/machine/vm_types.h>
#include <ipc/ipc_kmsg.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/lock.h>
#include <kern/kalloc.h>
@@ -46,6 +46,15 @@
#include <device/io_req.h>
#include <device/net_status.h>
+struct net_rcv_port;
+typedef struct net_rcv_port *net_rcv_port_t;
+
+struct net_hash_entry;
+typedef struct net_hash_entry *net_hash_entry_t;
+
+struct net_hash_header;
+typedef struct net_hash_header *net_hash_header_t;
+
/*
* A network packet is wrapped in a kernel message while in
* the kernel.
@@ -65,7 +74,7 @@ extern void net_kmsg_put(ipc_kmsg_t);
* Network utility routines.
*/
-extern void net_ast();
+extern void net_ast(void);
extern void net_packet(struct ifnet *, ipc_kmsg_t, unsigned int, boolean_t);
extern void net_filter(ipc_kmsg_t, ipc_kmsg_queue_t);
extern io_return_t net_getstat(struct ifnet *, dev_flavor_t, dev_status_t,
@@ -80,7 +89,64 @@ extern vm_size_t net_kmsg_size;
extern void net_kmsg_collect (void);
+extern void net_io_init(void);
+extern void net_thread(void) __attribute__ ((noreturn));
+
#define net_kmsg_alloc() ((ipc_kmsg_t) kalloc(net_kmsg_size))
#define net_kmsg_free(kmsg) kfree((vm_offset_t) (kmsg), net_kmsg_size)
+extern unsigned int ntohl(unsigned int);
+extern unsigned short int ntohs(unsigned short int);
+extern unsigned int htonl(unsigned int);
+extern unsigned short int htons(unsigned short int);
+
+unsigned int bpf_hash(int n, const unsigned int *keys);
+
+extern boolean_t
+net_do_filter(
+ net_rcv_port_t infp,
+ const char * data,
+ unsigned int data_count,
+ const char * header); /* CSPF */
+
+extern int
+bpf_do_filter(
+ net_rcv_port_t infp,
+ char * p,
+ unsigned int wirelen,
+ char * header,
+ unsigned int hlen,
+ net_hash_entry_t **hash_headpp,
+ net_hash_entry_t *entpp); /* BPF */
+
+int hash_ent_remove(
+ struct ifnet *ifp,
+ net_hash_header_t hp,
+ int used,
+ net_hash_entry_t *head,
+ net_hash_entry_t entp,
+ queue_entry_t *dead_p);
+
+void net_free_dead_infp(queue_entry_t dead_infp);
+void net_free_dead_entp (queue_entry_t dead_entp);
+
+int bpf_validate(
+ bpf_insn_t f,
+ int bytes,
+ bpf_insn_t *match);
+
+int bpf_eq(
+ bpf_insn_t f1,
+ bpf_insn_t f2,
+ int bytes);
+
+int net_add_q_info(ipc_port_t rcv_port);
+
+int bpf_match (
+ net_hash_header_t hash,
+ int n_keys,
+ const unsigned int *keys,
+ net_hash_entry_t **hash_headpp,
+ net_hash_entry_t *entpp);
+
#endif /* _DEVICE_NET_IO_H_ */
diff --git a/device/subrs.c b/device/subrs.c
index a82bae38..a10b72d7 100644
--- a/device/subrs.c
+++ b/device/subrs.c
@@ -40,32 +40,27 @@
/*
* Print out disk name and block number for hard disk errors.
*/
-void harderr(bp, cp)
- struct buf *bp;
- char * cp;
+void harderr(ior, cp)
+ const io_req_t ior;
+ const char * cp;
{
printf("%s%d%c: hard error sn%d ",
cp,
- minor(bp->b_dev) >> 3,
- 'a' + (minor(bp->b_dev) & 0x7),
- bp->b_blkno);
+ minor(ior->io_unit) >> 3,
+ 'a' + (minor(ior->io_unit) & 0x7),
+ ior->io_recnum);
}
/*
- * Ethernet support routines.
- */
-u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-/*
* Convert Ethernet address to printable (loggable) representation.
*/
char *
ether_sprintf(ap)
- register u_char *ap;
+ const u_char *ap;
{
- register int i;
+ int i;
static char etherbuf[18];
- register char *cp = etherbuf;
+ char *cp = etherbuf;
static char digits[] = "0123456789abcdef";
for (i = 0; i < 6; i++) {
@@ -80,8 +75,7 @@ ether_sprintf(ap)
/*
* Initialize send and receive queues on an interface.
*/
-void if_init_queues(ifp)
- register struct ifnet *ifp;
+void if_init_queues(struct ifnet *ifp)
{
IFQ_INIT(&ifp->if_snd);
queue_init(&ifp->if_rcv_port_list);
@@ -108,11 +102,11 @@ void wakeup(channel)
thread_wakeup((event_t) channel);
}
-struct buf *
+io_req_t
geteblk(size)
int size;
{
- register io_req_t ior;
+ io_req_t ior;
io_req_alloc(ior, 0);
ior->io_device = (mach_device_t)0;
@@ -133,11 +127,9 @@ geteblk(size)
return (ior);
}
-void brelse(bp)
- struct buf *bp;
+void brelse(ior)
+ io_req_t ior;
{
- register io_req_t ior = bp;
-
(void) vm_deallocate(kernel_map,
(vm_offset_t) ior->io_data,
ior->io_alloc_size);
diff --git a/device/tty.h b/device/tty.h
index be287083..d7aa2add 100644
--- a/device/tty.h
+++ b/device/tty.h
@@ -42,10 +42,6 @@
#include <device/cirbuf.h>
#include <device/io_req.h>
-#ifdef luna88k
-#include <luna88k/jtermio.h>
-#endif
-
struct tty {
decl_simple_lock_data(,t_lock)
struct cirbuf t_inq; /* input buffer */
@@ -76,8 +72,8 @@ struct tty {
* Items beyond this point should be removed to device-specific
* extension structures.
*/
- int (*t_getstat)(); /* routine to get status */
- int (*t_setstat)(); /* routine to set status */
+ io_return_t (*t_getstat)(dev_t, int, int *, natural_t *); /* routine to get status */
+ io_return_t (*t_setstat)(dev_t, int, int *, natural_t); /* routine to set status */
dev_ops_t t_tops; /* another device to possibly
push through */
};
@@ -188,7 +184,7 @@ extern boolean_t tty_portdeath(
#define TS_TRANSLATE 0x00100000 /* translation device enabled */
#define TS_KDB 0x00200000 /* should enter kdb on ALT */
-#define TS_MIN_TO_RCV 0x00400000 /* character recived during
+#define TS_MIN_TO_RCV 0x00400000 /* character received during
receive timeout interval */
/* flags - old names defined in terms of new ones */
@@ -238,6 +234,4 @@ struct ldisc_switch {
extern struct ldisc_switch linesw[];
-extern void chario_init(void);
-
#endif /* _DEVICE_TTY_H_ */
diff --git a/doc/gpl.texi b/doc/gpl.texi
index 1a4dfcb3..c1f025e7 100644
--- a/doc/gpl.texi
+++ b/doc/gpl.texi
@@ -283,15 +283,8 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
-@iftex
-@heading NO WARRANTY
-@end iftex
-@ifinfo
-@center NO WARRANTY
+@item NO WARRANTY
-@end ifinfo
-
-@item
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
diff --git a/doc/mach.texi b/doc/mach.texi
index e93fdb8b..6fc79f70 100644
--- a/doc/mach.texi
+++ b/doc/mach.texi
@@ -38,22 +38,10 @@ Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
-any later version published by the Free Software Foundation; with the
-Invariant Sections being ``Free Software Needs Free Documentation'' and
-``GNU Lesser General Public License'', the Front-Cover texts being (a)
-(see below), and with the Back-Cover Texts being (b) (see below). A
-copy of the license is included in the section entitled ``GNU Free
-Documentation License''.
-
-(a) The FSF's Front-Cover Text is:
-
- A GNU Manual
-
-(b) The FSF's Back-Cover Text is:
-
- You have freedom to copy and modify this GNU Manual, like GNU
- software. Copies published by the Free Software Foundation raise
- funds for GNU development.
+any later version published by the Free Software Foundation; with no
+Invariant Section, with no Front-Cover Texts, and with no Back-Cover
+Texts. A copy of the license is included in the section entitled
+``GNU Free Documentation License''.
This work is based on manual pages under the following copyright and license:
@@ -205,7 +193,7 @@ Port Manipulation Interface
* Receive Rights:: How to work with receive rights.
* Port Sets:: How to work with port sets.
* Request Notifications:: How to request notifications for events.
-@c * Inherited Ports:: How to work with the inherited system ports.
+* Inherited Ports:: How to work with the inherited system ports.
Virtual Memory Interface
@@ -842,7 +830,7 @@ AT-LAN-TEC/RealTek pocket adaptor network card device driver for the
AMD LANCE and PCnet (AT1500 and NE2100) network card device driver. On
@samp{ix86-at} enabled by @samp{default}.
-@itemx --enable-tulip
+@item --enable-tulip
DECchip Tulip (dc21x4x) PCI network card device driver. On @samp{ix86-at}
enabled by @samp{default}.
@@ -870,7 +858,7 @@ Packet Engines Yellowfin Gigabit-NIC network card device driver. On
RealTek 8129/8139 (not 8019/8029!) network card device driver. On
@samp{ix86-at} enabled by @samp{default}.
-@itemx --enable-epic100
+@item --enable-epic100
SMC 83c170/175 EPIC/100 (EtherPower II) network card device driver. On
@samp{ix86-at} enabled by @samp{default}.
@@ -1342,6 +1330,15 @@ which is conventionally used as a reply port by the recipient of the
message. The field must carry a send right, a send-once right,
@code{MACH_PORT_NULL}, or @code{MACH_PORT_DEAD}.
+@item unsigned long msgh_protected_payload
+The @code{msgh_protected_payload} field carries a payload that is set
+by the kernel during message delivery. The payload is an opaque
+identifier that can be used by the receiver to lookup the associated
+data structure.
+
+It is only valid in received messages. See @ref{Message Receive} for
+further information.
+
@item mach_port_seqno_t msgh_seqno
The @code{msgh_seqno} field provides a sequence number for the message.
It is only valid in received messages; its value in sent messages is
@@ -1429,6 +1426,7 @@ types are predefined:
@item MACH_MSG_TYPE_STRING
@item MACH_MSG_TYPE_STRING_C
@item MACH_MSG_TYPE_PORT_NAME
+@item MACH_MSG_TYPE_PROTECTED_PAYLOAD
@end table
The following predefined types specify port rights, and receive special
@@ -1447,6 +1445,11 @@ should be used in preference to @code{MACH_MSG_TYPE_INTEGER_32}.
@item MACH_MSG_TYPE_MAKE_SEND_ONCE
@end table
+The type @code{MACH_MSG_TYPE_PROTECTED_PAYLOAD} is used by the kernel
+to indicate that a delivered message carries a payload in the
+@code{msgh_protected_payload} field. See @ref{Message Receive} for
+more information.
+
@item msgt_size : 8
The @code{msgt_size} field specifies the size of each datum, in bits. For
example, the msgt_size of @code{MACH_MSG_TYPE_INTEGER_32} data is 32.
@@ -1946,6 +1949,25 @@ loses the receive right after the message was dequeued from it, then
right still exists, but isn't held by the caller, then
@code{msgh_local_port} specifies @code{MACH_PORT_NULL}.
+Servers usually associate some state with a receive right. To that
+end, they might use a hash table to look up the state for the port a
+message was sent to. To optimize this, a task may associate an opaque
+@var{payload} with a receive right using the
+@code{mach_port_set_protected_payload} function. Once this is done,
+the kernel will set the @code{msgh_protected_payload} field to
+@var{payload} when delivering a message to this right and indicate
+this by setting the local part of @code{msgh_bits} to
+@code{MACH_MSG_TYPE_PROTECTED_PAYLOAD}.
+
+The support for protected payloads was added to GNU Mach. To preserve
+binary compatibility, the @code{msgh_local_port} and
+@code{msgh_local_port} share the same location. This makes it
+possible to add the payload information without increasing the size of
+@code{mach_msg_header_t}. This is an implementation detail. Which
+field is valid is determined by the local part of the
+@code{msgh_bits}. Existing software is not affected. When a receive
+right is transferred to another task, its payload is cleared.
+
Received messages are stamped with a sequence number, taken from the
port from which the message was received. (Messages received from a
port set are stamped with a sequence number from the appropriate member
@@ -2176,7 +2198,7 @@ the kernel.
* Receive Rights:: How to work with receive rights.
* Port Sets:: How to work with port sets.
* Request Notifications:: How to request notifications for events.
-@c * Inherited Ports:: How to work with the inherited system ports.
+* Inherited Ports:: How to work with the inherited system ports.
@end menu
@@ -2727,6 +2749,41 @@ In addition to the normal diagnostic return codes from the call's server
(normally the kernel), the call may return @code{mach_msg} return codes.
@end deftypefun
+@deftypefun kern_return_t mach_port_set_protected_payload (@w{ipc_space_t @var{task}}, @w{mach_port_t @var{name}}, @w{unsigned long @var{payload}})
+The function @code{mach_port_set_protected_payload} sets the protected
+payload associated with the right @var{name} to @var{payload}.
+Section @ref{Message Receive} describes how setting a protected
+payload affects the messages delivered to @var{name}.
+
+The function returns @code{KERN_SUCCESS} if the call succeeded,
+@code{KERN_INVALID_TASK} if @var{task} was invalid,
+@code{KERN_INVALID_NAME} if @var{name} did not denote a right and
+@code{KERN_INVALID_RIGHT} if @var{name} denoted a right, but not a
+receive right.
+
+The @code{mach_port_set_protected_payload} call is actually an RPC to
+@var{task}, normally a send right for a task port, but potentially any
+send right. In addition to the normal diagnostic return codes from
+the call's server (normally the kernel), the call may return
+@code{mach_msg} return codes.
+@end deftypefun
+
+@deftypefun kern_return_t mach_port_clear_protected_payload (@w{ipc_space_t @var{task}}, @w{mach_port_t @var{name}}, @w{unsigned long @var{payload}})
+The function @code{mach_port_clear_protected_payload} clears the
+protected payload associated with the right @var{name}.
+
+The function returns @code{KERN_SUCCESS} if the call succeeded,
+@code{KERN_INVALID_TASK} if @var{task} was invalid,
+@code{KERN_INVALID_NAME} if @var{name} did not denote a right and
+@code{KERN_INVALID_RIGHT} if @var{name} denoted a right, but not a
+receive right.
+
+The @code{mach_port_clear_protected_payload} call is actually an RPC
+to @var{task}, normally a send right for a task port, but potentially
+any send right. In addition to the normal diagnostic return codes
+from the call's server (normally the kernel), the call may return
+@code{mach_msg} return codes.
+@end deftypefun
@node Port Sets
@subsection Port Sets
@@ -2860,66 +2917,69 @@ call's server (normally the kernel), the call may return @code{mach_msg}
return codes.
@end deftypefun
-@c The inherited ports concept is not used in the Hurd,
-@c and so the _SLOT macros are not defined in GNU Mach.
-
-@c @node Inherited Ports
-@c @subsection Inherited Ports
-
-@c @deftypefun kern_return_t mach_ports_register (@w{task_t @var{target_task}, @w{port_array_t @var{init_port_set}}, @w{int @var{init_port_array_count}})
-@c @deftypefunx kern_return_t mach_ports_lookup (@w{task_t @var{target_task}, @w{port_array_t *@var{init_port_set}}, @w{int *@var{init_port_array_count}})
-@c @code{mach_ports_register} manipulates the inherited ports array,
-@c @code{mach_ports_lookup} is used to acquire specific parent ports.
-@c @var{target_task} is the task to be affected. @var{init_port_set} is an
-@c array of system ports to be registered, or returned. Although the array
-@c size is given as variable, the kernel will only accept a limited number
-@c of ports. @var{init_port_array_count} is the number of ports returned
-@c in @var{init_port_set}.
-
-@c @code{mach_ports_register} registers an array of well-known system ports
-@c with the kernel on behalf of a specific task. Currently the ports to be
-@c registered are: the port to the Network Name Server, the port to the
-@c Environment Manager, and a port to the Service server. These port
-@c values must be placed in specific slots in the init_port_set. The slot
-@c numbers are given by the global constants defined in @file{mach_init.h}:
-@c @code{NAME_SERVER_SLOT}, @code{ENVIRONMENT_SLOT}, and
-@c @code{SERVICE_SLOT}. These ports may later be retrieved with
-@c @code{mach_ports_lookup}.
-
-@c When a new task is created (see @code{task_create}), the child task will
-@c be given access to these ports. Only port send rights may be
-@c registered. Furthermore, the number of ports which may be registered is
-@c fixed and given by the global constant @code{MACH_PORT_SLOTS_USED}
-@c Attempts to register too many ports will fail.
-
-@c It is intended that this mechanism be used only for task initialization,
-@c and then only by runtime support modules. A parent task has three
-@c choices in passing these system ports to a child task. Most commonly it
-@c can do nothing and its child will inherit access to the same
-@c @var{init_port_set} that the parent has; or a parent task may register a
-@c set of ports it wishes to have passed to all of its children by calling
-@c @code{mach_ports_register} using its task port; or it may make necessary
-@c modifications to the set of ports it wishes its child to see, and then
-@c register those ports using the child's task port prior to starting the
-@c child's thread(s). The @code{mach_ports_lookup} call which is done by
-@c @code{mach_init} in the child task will acquire these initial ports for
-@c the child.
-
-@c Tasks other than the Network Name Server and the Environment Manager
-@c should not need access to the Service port. The Network Name Server port
-@c is the same for all tasks on a given machine. The Environment port is
-@c the only port likely to have different values for different tasks.
-
-@c Since the number of ports which may be registered is limited, ports
-@c other than those used by the runtime system to initialize a task should
-@c be passed to children either through an initial message, or through the
-@c Network Name Server for public ports, or the Environment Manager for
-@c private ports.
-
-@c The function returns @code{KERN_SUCCESS} if the memory was allocated,
-@c and @code{KERN_INVALID_ARGUMENT} if an attempt was made to register more
-@c ports than the current kernel implementation allows.
-@c @end deftypefun
+@node Inherited Ports
+@subsection Inherited Ports
+
+The inherited ports concept is not used in the Hurd, and so the _SLOT
+macros are not defined in GNU Mach.
+
+The following section documents how @code{mach_ports_register} and
+@code{mach_ports_lookup} were originally intended to be used.
+
+@deftypefun kern_return_t mach_ports_register (@w{task_t @var{target_task}}, @w{port_array_t @var{init_port_set}}, @w{int @var{init_port_array_count}})
+@deftypefunx kern_return_t mach_ports_lookup (@w{task_t @var{target_task}}, @w{port_array_t *@var{init_port_set}}, @w{int *@var{init_port_array_count}})
+@code{mach_ports_register} manipulates the inherited ports array,
+@code{mach_ports_lookup} is used to acquire specific parent ports.
+@var{target_task} is the task to be affected. @var{init_port_set} is an
+array of system ports to be registered, or returned. Although the array
+size is given as variable, the kernel will only accept a limited number
+of ports. @var{init_port_array_count} is the number of ports returned
+in @var{init_port_set}.
+
+@code{mach_ports_register} registers an array of well-known system ports
+with the kernel on behalf of a specific task. Currently the ports to be
+registered are: the port to the Network Name Server, the port to the
+Environment Manager, and a port to the Service server. These port
+values must be placed in specific slots in the init_port_set. The slot
+numbers are given by the global constants defined in @file{mach_init.h}:
+@code{NAME_SERVER_SLOT}, @code{ENVIRONMENT_SLOT}, and
+@code{SERVICE_SLOT}. These ports may later be retrieved with
+@code{mach_ports_lookup}.
+
+When a new task is created (see @code{task_create}), the child task will
+be given access to these ports. Only port send rights may be
+registered. Furthermore, the number of ports which may be registered is
+fixed and given by the global constant @code{MACH_PORT_SLOTS_USED}
+Attempts to register too many ports will fail.
+
+It is intended that this mechanism be used only for task initialization,
+and then only by runtime support modules. A parent task has three
+choices in passing these system ports to a child task. Most commonly it
+can do nothing and its child will inherit access to the same
+@var{init_port_set} that the parent has; or a parent task may register a
+set of ports it wishes to have passed to all of its children by calling
+@code{mach_ports_register} using its task port; or it may make necessary
+modifications to the set of ports it wishes its child to see, and then
+register those ports using the child's task port prior to starting the
+child's thread(s). The @code{mach_ports_lookup} call which is done by
+@code{mach_init} in the child task will acquire these initial ports for
+the child.
+
+Tasks other than the Network Name Server and the Environment Manager
+should not need access to the Service port. The Network Name Server port
+is the same for all tasks on a given machine. The Environment port is
+the only port likely to have different values for different tasks.
+
+Since the number of ports which may be registered is limited, ports
+other than those used by the runtime system to initialize a task should
+be passed to children either through an initial message, or through the
+Network Name Server for public ports, or the Environment Manager for
+private ports.
+
+The function returns @code{KERN_SUCCESS} if the memory was allocated,
+and @code{KERN_INVALID_ARGUMENT} if an attempt was made to register more
+ports than the current kernel implementation allows.
+@end deftypefun
@node Virtual Memory Interface
@@ -3181,14 +3241,15 @@ successfully set and @code{KERN_INVALID_ADDRESS} if an invalid or
non-allocated address was specified.
@end deftypefun
-@deftypefun kern_return_t vm_wire (@w{host_priv_t @var{host_priv}}, @w{vm_task_t @var{target_task}}, @w{vm_address_t @var{address}}, @w{vm_size_t @var{size}}, @w{vm_prot_t @var{access}})
-The function @code{vm_wire} allows privileged applications to control
-memory pageability. @var{host_priv} is the privileged host port for the
+@deftypefun kern_return_t vm_wire (@w{host_t @var{host}}, @w{vm_task_t @var{target_task}}, @w{vm_address_t @var{address}}, @w{vm_size_t @var{size}}, @w{vm_prot_t @var{access}})
+The function @code{vm_wire} allows applications to control
+memory pageability. @var{host} is the host port for the
host on which @var{target_task} resides. @var{address} is the starting
address, which will be rounded down to a page boundary. @var{size} is
the size in bytes of the region for which protection is to change, and
will be rounded up to give a page boundary. @var{access} specifies the
-types of accesses that must not cause page faults.
+types of accesses that must not cause page faults. If the host port is
+not privileged, the amount of memory is limited per task.
The semantics of a successful @code{vm_wire} operation are that memory
in the specified range will not cause page faults for any accesses
@@ -3197,7 +3258,7 @@ access argument of @code{VM_PROT_READ | VM_PROT_WRITE}. A special case
is that @code{VM_PROT_NONE} makes the memory pageable.
The function returns @code{KERN_SUCCESS} if the call succeeded,
-@code{KERN_INVALID_HOST} if @var{host_priv} was not the privileged host
+@code{KERN_INVALID_HOST} if @var{host} was not a valid host
port, @code{KERN_INVALID_TASK} if @var{task} was not a valid task,
@code{KERN_INVALID_VALUE} if @var{access} specified an invalid access
mode, @code{KERN_FAILURE} if some memory in the specified range is not
@@ -3205,7 +3266,7 @@ present or has an inappropriate protection value, and
@code{KERN_INVALID_ARGUMENT} if unwiring (@var{access} is
@code{VM_PROT_NONE}) and the memory is not already wired.
-The @code{vm_wire} call is actually an RPC to @var{host_priv}, normally
+The @code{vm_wire} call is actually an RPC to @var{host}, normally
a send right for a privileged host port, but potentially any send right.
In addition to the normal diagnostic return codes from the call's server
(normally the kernel), the call may return @code{mach_msg} return codes.
@@ -3306,7 +3367,7 @@ exception.
@var{target_task} is the task to be affected. The starting address is
@var{address}. If the @var{anywhere} option is used, this address is
-ignored. The address actually allocated will be returned in
+used as a starting hint. The address actually allocated will be returned in
@var{address}. @var{size} is the number of bytes to allocate (rounded by
the system in a machine dependent way). The alignment restriction is
specified by @var{mask}. Bits asserted in this mask must not be
@@ -4569,7 +4630,7 @@ their priority from their task and their max priority from the thread.
@deftypefun kern_return_t thread_priority (@w{thread_t @var{thread}}, @w{int @var{prority}}, @w{boolean_t @var{set_max}})
The function @code{thread_priority} changes the priority and optionally
-the maximum priority of @var{thread}. Priorities range from 0 to 31,
+the maximum priority of @var{thread}. Priorities range from 0 to 49,
where lower numbers denote higher priorities. If the new priority is
higher than the priority of the current thread, preemption may occur as
a result of this call. The maximum priority of the thread is also set
@@ -4580,7 +4641,7 @@ priority.
The functions returns @code{KERN_SUCCESS} if the operation completed
successfully, @code{KERN_INVALID_ARGUMENT} if @var{thread} is not a
-thread or @var{priority} is out of range (not in 0..31), and
+thread or @var{priority} is out of range (not in 0..49), and
@code{KERN_FAILURE} if the requested operation would violate the
thread's maximum priority (thread_priority).
@end deftypefun
@@ -4594,7 +4655,7 @@ legal value.
The functions returns @code{KERN_SUCCESS} if the operation completed
successfully, @code{KERN_INVALID_ARGUMENT} if @var{thread} is not a
thread or @var{processor_set} is not a control port for a processor set
-or @var{priority} is out of range (not in 0..31), and
+or @var{priority} is out of range (not in 0..49), and
@code{KERN_FAILURE} if the thread is not assigned to the processor set
whose control port was presented.
@end deftypefun
@@ -5049,6 +5110,17 @@ total system run time for live threads
This is a pointer to a @code{struct task_thread_times_info}.
@end deftp
+@deftypefun kern_return_t task_set_name (@w{task_t @var{target_task}}, @w{kernel_debug_name_t @var{name}})
+
+The function @code{task_set_name} sets the name of @var{target_task}
+to @var{name}, truncating it if necessary.
+
+This is a debugging aid. The name is used in diagnostic messages
+printed by the kernel.
+
+The function returns @code{KERN_SUCCESS} if the call succeeded.
+@end deftypefun
+
@node Task Execution
@subsection Task Execution
@@ -7030,8 +7102,9 @@ session. If the execution is resumed again, the numbers may change.
The current thread can be distinguished from others by a @code{#} after
the thread id instead of @code{:}. Without @code{l} option, it only
shows thread id, thread structure address and the status for each
-thread. The status consists of 5 letters, R(run), W(wait), S(suspended),
-O(swapped out) and N(interruptible), and if corresponding
+thread. The status consists of 6 letters, R(run), W(wait), S(suspended),
+O(swapped out), N(interruptible), and F(loating) point arithmetic used (if
+supported by the platform). If the corresponding
status bit is off, @code{.} is printed instead. If @code{l} option is
specified, more detail information is printed for each thread.
@@ -7088,6 +7161,15 @@ rejected with an error message.
Warning: Attempts to watch wired kernel memory may cause unrecoverable
error in some systems such as i386. Watchpoints on user addresses work
best.
+
+@item dwatch[/T] @var{addr} [ @var{task} ]
+Clears a watchpoint previously set for a region.
+Without @code{T} option, @var{addr} is assumed to be a kernel address.
+If you want to clear a watch point in user space, specify @code{T} and
+@var{task} parameter where the address belongs to. If the @var{task}
+parameter is omitted, a task of the default target thread or a current
+task is assumed. If you specify a wrong space address, the request is
+rejected with an error message.
@end table
diff --git a/gitlog-to-changelog b/gitlog-to-changelog
new file mode 100755
index 00000000..e02d34c2
--- /dev/null
+++ b/gitlog-to-changelog
@@ -0,0 +1,432 @@
+eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
+ & eval 'exec perl -wS "$0" $argv:q'
+ if 0;
+# Convert git log output to ChangeLog format.
+
+my $VERSION = '2012-07-29 06:11'; # UTC
+# The definition above must lie within the first 8 lines in order
+# for the Emacs time-stamp write hook (at end) to update it.
+# If you change this file with Emacs, please let the write hook
+# do its job. Otherwise, update this string manually.
+
+# Copyright (C) 2008-2013 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Written by Jim Meyering
+
+use strict;
+use warnings;
+use Getopt::Long;
+use POSIX qw(strftime);
+
+(my $ME = $0) =~ s|.*/||;
+
+# use File::Coda; # http://meyering.net/code/Coda/
+END {
+ defined fileno STDOUT or return;
+ close STDOUT and return;
+ warn "$ME: failed to close standard output: $!\n";
+ $? ||= 1;
+}
+
+sub usage ($)
+{
+ my ($exit_code) = @_;
+ my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
+ if ($exit_code != 0)
+ {
+ print $STREAM "Try '$ME --help' for more information.\n";
+ }
+ else
+ {
+ print $STREAM <<EOF;
+Usage: $ME [OPTIONS] [ARGS]
+
+Convert git log output to ChangeLog format. If present, any ARGS
+are passed to "git log". To avoid ARGS being parsed as options to
+$ME, they may be preceded by '--'.
+
+OPTIONS:
+
+ --amend=FILE FILE maps from an SHA1 to perl code (i.e., s/old/new/) that
+ makes a change to SHA1's commit log text or metadata.
+ --append-dot append a dot to the first line of each commit message if
+ there is no other punctuation or blank at the end.
+ --no-cluster never cluster commit messages under the same date/author
+ header; the default is to cluster adjacent commit messages
+ if their headers are the same and neither commit message
+ contains multiple paragraphs.
+ --srcdir=DIR the root of the source tree, from which the .git/
+ directory can be derived.
+ --since=DATE convert only the logs since DATE;
+ the default is to convert all log entries.
+ --format=FMT set format string for commit subject and body;
+ see 'man git-log' for the list of format metacharacters;
+ the default is '%s%n%b%n'
+ --strip-tab remove one additional leading TAB from commit message lines.
+ --strip-cherry-pick remove data inserted by "git cherry-pick";
+ this includes the "cherry picked from commit ..." line,
+ and the possible final "Conflicts:" paragraph.
+ --help display this help and exit
+ --version output version information and exit
+
+EXAMPLE:
+
+ $ME --since=2008-01-01 > ChangeLog
+ $ME -- -n 5 foo > last-5-commits-to-branch-foo
+
+SPECIAL SYNTAX:
+
+The following types of strings are interpreted specially when they appear
+at the beginning of a log message line. They are not copied to the output.
+
+ Copyright-paperwork-exempt: Yes
+ Append the "(tiny change)" notation to the usual "date name email"
+ ChangeLog header to mark a change that does not require a copyright
+ assignment.
+ Co-authored-by: Joe User <user\@example.com>
+ List the specified name and email address on a second
+ ChangeLog header, denoting a co-author.
+ Signed-off-by: Joe User <user\@example.com>
+ These lines are simply elided.
+
+In a FILE specified via --amend, comment lines (starting with "#") are ignored.
+FILE must consist of <SHA,CODE+> pairs where SHA is a 40-byte SHA1 (alone on
+a line) referring to a commit in the current project, and CODE refers to one
+or more consecutive lines of Perl code. Pairs must be separated by one or
+more blank line.
+
+Here is sample input for use with --amend=FILE, from coreutils:
+
+3a169f4c5d9159283548178668d2fae6fced3030
+# fix typo in title:
+s/all tile types/all file types/
+
+1379ed974f1fa39b12e2ffab18b3f7a607082202
+# Due to a bug in vc-dwim, I mis-attributed a patch by Paul to myself.
+# Change the author to be Paul. Note the escaped "@":
+s,Jim .*>,Paul Eggert <eggert\\\@cs.ucla.edu>,
+
+EOF
+ }
+ exit $exit_code;
+}
+
+# If the string $S is a well-behaved file name, simply return it.
+# If it contains white space, quotes, etc., quote it, and return the new string.
+sub shell_quote($)
+{
+ my ($s) = @_;
+ if ($s =~ m![^\w+/.,-]!)
+ {
+ # Convert each single quote to '\''
+ $s =~ s/\'/\'\\\'\'/g;
+ # Then single quote the string.
+ $s = "'$s'";
+ }
+ return $s;
+}
+
+sub quoted_cmd(@)
+{
+ return join (' ', map {shell_quote $_} @_);
+}
+
+# Parse file F.
+# Comment lines (starting with "#") are ignored.
+# F must consist of <SHA,CODE+> pairs where SHA is a 40-byte SHA1
+# (alone on a line) referring to a commit in the current project, and
+# CODE refers to one or more consecutive lines of Perl code.
+# Pairs must be separated by one or more blank line.
+sub parse_amend_file($)
+{
+ my ($f) = @_;
+
+ open F, '<', $f
+ or die "$ME: $f: failed to open for reading: $!\n";
+
+ my $fail;
+ my $h = {};
+ my $in_code = 0;
+ my $sha;
+ while (defined (my $line = <F>))
+ {
+ $line =~ /^\#/
+ and next;
+ chomp $line;
+ $line eq ''
+ and $in_code = 0, next;
+
+ if (!$in_code)
+ {
+ $line =~ /^([0-9a-fA-F]{40})$/
+ or (warn "$ME: $f:$.: invalid line; expected an SHA1\n"),
+ $fail = 1, next;
+ $sha = lc $1;
+ $in_code = 1;
+ exists $h->{$sha}
+ and (warn "$ME: $f:$.: duplicate SHA1\n"),
+ $fail = 1, next;
+ }
+ else
+ {
+ $h->{$sha} ||= '';
+ $h->{$sha} .= "$line\n";
+ }
+ }
+ close F;
+
+ $fail
+ and exit 1;
+
+ return $h;
+}
+
+# git_dir_option $SRCDIR
+#
+# From $SRCDIR, the --git-dir option to pass to git (none if $SRCDIR
+# is undef). Return as a list (0 or 1 element).
+sub git_dir_option($)
+{
+ my ($srcdir) = @_;
+ my @res = ();
+ if (defined $srcdir)
+ {
+ my $qdir = shell_quote $srcdir;
+ my $cmd = "cd $qdir && git rev-parse --show-toplevel";
+ my $qcmd = shell_quote $cmd;
+ my $git_dir = qx($cmd);
+ defined $git_dir
+ or die "$ME: cannot run $qcmd: $!\n";
+ $? == 0
+ or die "$ME: $qcmd had unexpected exit code or signal ($?)\n";
+ chomp $git_dir;
+ push @res, "--git-dir=$git_dir/.git";
+ }
+ @res;
+}
+
+{
+ my $since_date;
+ my $format_string = '%s%n%b%n';
+ my $amend_file;
+ my $append_dot = 0;
+ my $cluster = 1;
+ my $strip_tab = 0;
+ my $strip_cherry_pick = 0;
+ my $srcdir;
+ GetOptions
+ (
+ help => sub { usage 0 },
+ version => sub { print "$ME version $VERSION\n"; exit },
+ 'since=s' => \$since_date,
+ 'format=s' => \$format_string,
+ 'amend=s' => \$amend_file,
+ 'append-dot' => \$append_dot,
+ 'cluster!' => \$cluster,
+ 'strip-tab' => \$strip_tab,
+ 'strip-cherry-pick' => \$strip_cherry_pick,
+ 'srcdir=s' => \$srcdir,
+ ) or usage 1;
+
+ defined $since_date
+ and unshift @ARGV, "--since=$since_date";
+
+ # This is a hash that maps an SHA1 to perl code (i.e., s/old/new/)
+ # that makes a correction in the log or attribution of that commit.
+ my $amend_code = defined $amend_file ? parse_amend_file $amend_file : {};
+
+ my @cmd = ('git',
+ git_dir_option $srcdir,
+ qw(log --log-size),
+ '--pretty=format:%H:%ct %an <%ae>%n%n'.$format_string, @ARGV);
+ open PIPE, '-|', @cmd
+ or die ("$ME: failed to run '". quoted_cmd (@cmd) ."': $!\n"
+ . "(Is your Git too old? Version 1.5.1 or later is required.)\n");
+
+ my $prev_multi_paragraph;
+ my $prev_date_line = '';
+ my @prev_coauthors = ();
+ while (1)
+ {
+ defined (my $in = <PIPE>)
+ or last;
+ $in =~ /^log size (\d+)$/
+ or die "$ME:$.: Invalid line (expected log size):\n$in";
+ my $log_nbytes = $1;
+
+ my $log;
+ my $n_read = read PIPE, $log, $log_nbytes;
+ $n_read == $log_nbytes
+ or die "$ME:$.: unexpected EOF\n";
+
+ # Extract leading hash.
+ my ($sha, $rest) = split ':', $log, 2;
+ defined $sha
+ or die "$ME:$.: malformed log entry\n";
+ $sha =~ /^[0-9a-fA-F]{40}$/
+ or die "$ME:$.: invalid SHA1: $sha\n";
+
+ # If this commit's log requires any transformation, do it now.
+ my $code = $amend_code->{$sha};
+ if (defined $code)
+ {
+ eval 'use Safe';
+ my $s = new Safe;
+ # Put the unpreprocessed entry into "$_".
+ $_ = $rest;
+
+ # Let $code operate on it, safely.
+ my $r = $s->reval("$code")
+ or die "$ME:$.:$sha: failed to eval \"$code\":\n$@\n";
+
+ # Note that we've used this entry.
+ delete $amend_code->{$sha};
+
+ # Update $rest upon success.
+ $rest = $_;
+ }
+
+ # Remove lines inserted by "git cherry-pick".
+ if ($strip_cherry_pick)
+ {
+ $rest =~ s/^\s*Conflicts:\n.*//sm;
+ $rest =~ s/^\s*\(cherry picked from commit [\da-f]+\)\n//m;
+ }
+
+ my @line = split "\n", $rest;
+ my $author_line = shift @line;
+ defined $author_line
+ or die "$ME:$.: unexpected EOF\n";
+ $author_line =~ /^(\d+) (.*>)$/
+ or die "$ME:$.: Invalid line "
+ . "(expected date/author/email):\n$author_line\n";
+
+ # Format 'Copyright-paperwork-exempt: Yes' as a standard ChangeLog
+ # `(tiny change)' annotation.
+ my $tiny = (grep (/^Copyright-paperwork-exempt:\s+[Yy]es$/, @line)
+ ? ' (tiny change)' : '');
+
+ my $date_line = sprintf "%s %s$tiny\n",
+ strftime ("%F", localtime ($1)), $2;
+
+ my @coauthors = grep /^Co-authored-by:.*$/, @line;
+ # Omit meta-data lines we've already interpreted.
+ @line = grep !/^(?:Signed-off-by:[ ].*>$
+ |Co-authored-by:[ ]
+ |Copyright-paperwork-exempt:[ ]
+ )/x, @line;
+
+ # Remove leading and trailing blank lines.
+ if (@line)
+ {
+ while ($line[0] =~ /^\s*$/) { shift @line; }
+ while ($line[$#line] =~ /^\s*$/) { pop @line; }
+ }
+
+ # Record whether there are two or more paragraphs.
+ my $multi_paragraph = grep /^\s*$/, @line;
+
+ # Format 'Co-authored-by: A U Thor <email@example.com>' lines in
+ # standard multi-author ChangeLog format.
+ for (@coauthors)
+ {
+ s/^Co-authored-by:\s*/\t /;
+ s/\s*</ </;
+
+ /<.*?@.*\..*>/
+ or warn "$ME: warning: missing email address for "
+ . substr ($_, 5) . "\n";
+ }
+
+ # If clustering of commit messages has been disabled, if this header
+ # would be different from the previous date/name/email/coauthors header,
+ # or if this or the previous entry consists of two or more paragraphs,
+ # then print the header.
+ if ( ! $cluster
+ || $date_line ne $prev_date_line
+ || "@coauthors" ne "@prev_coauthors"
+ || $multi_paragraph
+ || $prev_multi_paragraph)
+ {
+ $prev_date_line eq ''
+ or print "\n";
+ print $date_line;
+ @coauthors
+ and print join ("\n", @coauthors), "\n";
+ }
+ $prev_date_line = $date_line;
+ @prev_coauthors = @coauthors;
+ $prev_multi_paragraph = $multi_paragraph;
+
+ # If there were any lines
+ if (@line == 0)
+ {
+ warn "$ME: warning: empty commit message:\n $date_line\n";
+ }
+ else
+ {
+ if ($append_dot)
+ {
+ # If the first line of the message has enough room, then
+ if (length $line[0] < 72)
+ {
+ # append a dot if there is no other punctuation or blank
+ # at the end.
+ $line[0] =~ /[[:punct:]\s]$/
+ or $line[0] .= '.';
+ }
+ }
+
+ # Remove one additional leading TAB from each line.
+ $strip_tab
+ and map { s/^\t// } @line;
+
+ # Prefix each non-empty line with a TAB.
+ @line = map { length $_ ? "\t$_" : '' } @line;
+
+ print "\n", join ("\n", @line), "\n";
+ }
+
+ defined ($in = <PIPE>)
+ or last;
+ $in ne "\n"
+ and die "$ME:$.: unexpected line:\n$in";
+ }
+
+ close PIPE
+ or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n";
+ # FIXME-someday: include $PROCESS_STATUS in the diagnostic
+
+ # Complain about any unused entry in the --amend=F specified file.
+ my $fail = 0;
+ foreach my $sha (keys %$amend_code)
+ {
+ warn "$ME:$amend_file: unused entry: $sha\n";
+ $fail = 1;
+ }
+
+ exit $fail;
+}
+
+# Local Variables:
+# mode: perl
+# indent-tabs-mode: nil
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "my $VERSION = '"
+# time-stamp-format: "%:y-%02m-%02d %02H:%02M"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "'; # UTC"
+# End:
diff --git a/i386/Makefrag.am b/i386/Makefrag.am
index 3338e6e6..05fe4adf 100644
--- a/i386/Makefrag.am
+++ b/i386/Makefrag.am
@@ -24,6 +24,7 @@ libkernel_a_SOURCES += \
i386/i386at/cons_conf.c \
i386/i386at/idt.h \
i386/i386at/model_dep.c \
+ i386/i386at/model_dep.h \
i386/include/mach/sa/stdarg.h
if PLATFORM_at
@@ -50,9 +51,29 @@ libkernel_a_SOURCES += \
i386/i386at/kdasm.S \
i386/i386at/kdsoft.h \
i386/i386at/mem.c \
+ i386/i386at/mem.h \
i386/i386at/pic_isa.c \
i386/i386at/rtc.c \
i386/i386at/rtc.h
+
+libkernel_a_SOURCES += \
+ i386/i386at/acpihalt.c \
+ i386/i386at/acpihalt.h \
+ i386/i386at/acpi.c \
+ i386/i386at/grub_glue.c \
+ i386/grub/err.h \
+ i386/grub/cpu/io.h \
+ i386/grub/cpu/types.h \
+ i386/grub/cpu/time.h \
+ i386/grub/mm.h \
+ i386/grub/acpi.h \
+ i386/grub/symbol.h \
+ i386/grub/misc.h \
+ i386/grub/types.h \
+ i386/grub/time.h \
+ i386/grub/i18n.h \
+ i386/grub/compiler.h \
+ i386/grub/glue.h
endif
#
@@ -62,7 +83,7 @@ endif
if enable_lpr
libkernel_a_SOURCES += \
i386/i386at/lpr.c \
- i386/i386at/lprreg.h
+ i386/i386at/lpr.h
endif
@@ -81,6 +102,7 @@ libkernel_a_SOURCES += \
i386/i386/db_interface.h \
i386/i386/db_machdep.h \
i386/i386/db_trace.c \
+ i386/i386/db_trace.h \
i386/i386/debug.h \
i386/i386/debug_i386.c \
i386/i386/debug_trace.S \
@@ -134,7 +156,6 @@ libkernel_a_SOURCES += \
i386/i386/user_ldt.c \
i386/i386/user_ldt.h \
i386/i386/vm_param.h \
- i386/i386/vm_tuning.h \
i386/i386/xpr.h \
i386/intel/pmap.c \
i386/intel/pmap.h \
@@ -146,6 +167,7 @@ EXTRA_DIST += \
if PLATFORM_at
libkernel_a_SOURCES += \
i386/i386/hardclock.c \
+ i386/i386/hardclock.h \
i386/i386/io_map.c \
i386/i386/pic.c \
i386/i386/pic.h \
@@ -234,7 +256,6 @@ include_mach_i386_HEADERS = \
i386/include/mach/i386/mach_i386_types.h \
i386/include/mach/i386/machine_types.defs \
i386/include/mach/i386/multiboot.h \
- i386/include/mach/i386/rpc.h \
i386/include/mach/i386/syscall_sw.h \
i386/include/mach/i386/thread_status.h \
i386/include/mach/i386/trap.h \
diff --git a/i386/configfrag.ac b/i386/configfrag.ac
index 1eaabcad..48744b12 100644
--- a/i386/configfrag.ac
+++ b/i386/configfrag.ac
@@ -73,6 +73,10 @@ AC_DEFINE_UNQUOTED([NLPR], [$nlpr], [NLPR])
# Options.
#
+# The immediate console, useful for debugging early system
+# initialization. Disabled by default.
+AC_DEFINE([ENABLE_IMMEDIATE_CONSOLE], [0], [ENABLE_IMMEDIATE_CONSOLE])
+
AC_ARG_ENABLE([lpr],
AS_HELP_STRING([--enable-lpr], [lpr device; on ix86-at enabled by default]))
[case $host_platform:$host_cpu in
diff --git a/i386/grub/acpi.h b/i386/grub/acpi.h
new file mode 100644
index 00000000..2ac2bd6f
--- /dev/null
+++ b/i386/grub/acpi.h
@@ -0,0 +1,220 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ACPI_HEADER
+#define GRUB_ACPI_HEADER 1
+
+#ifndef GRUB_DSDT_TEST
+#include <grub/types.h>
+#include <grub/err.h>
+#endif
+
+#define GRUB_RSDP_SIGNATURE "RSD PTR "
+#define GRUB_RSDP_SIGNATURE_SIZE 8
+
+struct grub_acpi_rsdp_v10
+{
+ grub_uint8_t signature[GRUB_RSDP_SIGNATURE_SIZE];
+ grub_uint8_t checksum;
+ grub_uint8_t oemid[6];
+ grub_uint8_t revision;
+ grub_uint32_t rsdt_addr;
+} GRUB_PACKED;
+
+struct grub_acpi_rsdp_v20
+{
+ struct grub_acpi_rsdp_v10 rsdpv1;
+ grub_uint32_t length;
+ grub_uint64_t xsdt_addr;
+ grub_uint8_t checksum;
+ grub_uint8_t reserved[3];
+} GRUB_PACKED;
+
+struct grub_acpi_table_header
+{
+ grub_uint8_t signature[4];
+ grub_uint32_t length;
+ grub_uint8_t revision;
+ grub_uint8_t checksum;
+ grub_uint8_t oemid[6];
+ grub_uint8_t oemtable[8];
+ grub_uint32_t oemrev;
+ grub_uint8_t creator_id[4];
+ grub_uint32_t creator_rev;
+} GRUB_PACKED;
+
+#define GRUB_ACPI_FADT_SIGNATURE "FACP"
+
+struct grub_acpi_fadt
+{
+ struct grub_acpi_table_header hdr;
+ grub_uint32_t facs_addr;
+ grub_uint32_t dsdt_addr;
+ grub_uint8_t somefields1[20];
+ grub_uint32_t pm1a;
+ grub_uint8_t somefields2[64];
+ grub_uint64_t facs_xaddr;
+ grub_uint64_t dsdt_xaddr;
+ grub_uint8_t somefields3[96];
+} GRUB_PACKED;
+
+#define GRUB_ACPI_MADT_SIGNATURE "APIC"
+
+struct grub_acpi_madt_entry_header
+{
+ grub_uint8_t type;
+ grub_uint8_t len;
+};
+
+struct grub_acpi_madt
+{
+ struct grub_acpi_table_header hdr;
+ grub_uint32_t lapic_addr;
+ grub_uint32_t flags;
+ struct grub_acpi_madt_entry_header entries[0];
+};
+
+enum
+ {
+ GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC = 0,
+ GRUB_ACPI_MADT_ENTRY_TYPE_IOAPIC = 1,
+ GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE = 2,
+ GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC_NMI = 4,
+ GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC = 6,
+ GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC = 7,
+ GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE = 8
+ };
+
+struct grub_acpi_madt_entry_lapic
+{
+ struct grub_acpi_madt_entry_header hdr;
+ grub_uint8_t acpiid;
+ grub_uint8_t apicid;
+ grub_uint32_t flags;
+};
+
+struct grub_acpi_madt_entry_ioapic
+{
+ struct grub_acpi_madt_entry_header hdr;
+ grub_uint8_t id;
+ grub_uint8_t pad;
+ grub_uint32_t address;
+ grub_uint32_t global_sys_interrupt;
+};
+
+struct grub_acpi_madt_entry_interrupt_override
+{
+ struct grub_acpi_madt_entry_header hdr;
+ grub_uint8_t bus;
+ grub_uint8_t source;
+ grub_uint32_t global_sys_interrupt;
+ grub_uint16_t flags;
+} GRUB_PACKED;
+
+
+struct grub_acpi_madt_entry_lapic_nmi
+{
+ struct grub_acpi_madt_entry_header hdr;
+ grub_uint8_t acpiid;
+ grub_uint16_t flags;
+ grub_uint8_t lint;
+} GRUB_PACKED;
+
+struct grub_acpi_madt_entry_sapic
+{
+ struct grub_acpi_madt_entry_header hdr;
+ grub_uint8_t id;
+ grub_uint8_t pad;
+ grub_uint32_t global_sys_interrupt_base;
+ grub_uint64_t addr;
+};
+
+struct grub_acpi_madt_entry_lsapic
+{
+ struct grub_acpi_madt_entry_header hdr;
+ grub_uint8_t cpu_id;
+ grub_uint8_t id;
+ grub_uint8_t eid;
+ grub_uint8_t pad[3];
+ grub_uint32_t flags;
+ grub_uint32_t cpu_uid;
+ grub_uint8_t cpu_uid_str[0];
+};
+
+struct grub_acpi_madt_entry_platform_int_source
+{
+ struct grub_acpi_madt_entry_header hdr;
+ grub_uint16_t flags;
+ grub_uint8_t inttype;
+ grub_uint8_t cpu_id;
+ grub_uint8_t cpu_eid;
+ grub_uint8_t sapic_vector;
+ grub_uint32_t global_sys_int;
+ grub_uint32_t src_flags;
+};
+
+enum
+ {
+ GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED = 1
+ };
+
+#ifndef GRUB_DSDT_TEST
+struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (void);
+struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (void);
+struct grub_acpi_rsdp_v10 *grub_machine_acpi_get_rsdpv1 (void);
+struct grub_acpi_rsdp_v20 *grub_machine_acpi_get_rsdpv2 (void);
+grub_uint8_t grub_byte_checksum (void *base, grub_size_t size);
+
+grub_err_t grub_acpi_create_ebda (void);
+
+void grub_acpi_halt (void);
+#endif
+
+#define GRUB_ACPI_SLP_EN (1 << 13)
+#define GRUB_ACPI_SLP_TYP_OFFSET 10
+
+enum
+ {
+ GRUB_ACPI_OPCODE_ZERO = 0, GRUB_ACPI_OPCODE_ONE = 1,
+ GRUB_ACPI_OPCODE_NAME = 8, GRUB_ACPI_OPCODE_BYTE_CONST = 0x0a,
+ GRUB_ACPI_OPCODE_WORD_CONST = 0x0b,
+ GRUB_ACPI_OPCODE_DWORD_CONST = 0x0c,
+ GRUB_ACPI_OPCODE_STRING_CONST = 0x0d,
+ GRUB_ACPI_OPCODE_SCOPE = 0x10,
+ GRUB_ACPI_OPCODE_BUFFER = 0x11,
+ GRUB_ACPI_OPCODE_PACKAGE = 0x12,
+ GRUB_ACPI_OPCODE_METHOD = 0x14, GRUB_ACPI_OPCODE_EXTOP = 0x5b,
+ GRUB_ACPI_OPCODE_CREATE_WORD_FIELD = 0x8b,
+ GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD = 0x8c,
+ GRUB_ACPI_OPCODE_IF = 0xa0, GRUB_ACPI_OPCODE_ONES = 0xff
+ };
+enum
+ {
+ GRUB_ACPI_EXTOPCODE_MUTEX = 0x01,
+ GRUB_ACPI_EXTOPCODE_EVENT_OP = 0x02,
+ GRUB_ACPI_EXTOPCODE_OPERATION_REGION = 0x80,
+ GRUB_ACPI_EXTOPCODE_FIELD_OP = 0x81,
+ GRUB_ACPI_EXTOPCODE_DEVICE_OP = 0x82,
+ GRUB_ACPI_EXTOPCODE_PROCESSOR_OP = 0x83,
+ GRUB_ACPI_EXTOPCODE_POWER_RES_OP = 0x84,
+ GRUB_ACPI_EXTOPCODE_THERMAL_ZONE_OP = 0x85,
+ GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP = 0x86,
+ GRUB_ACPI_EXTOPCODE_BANK_FIELD_OP = 0x87,
+ };
+
+#endif /* ! GRUB_ACPI_HEADER */
diff --git a/i386/grub/compiler.h b/i386/grub/compiler.h
new file mode 100644
index 00000000..c9e1d7a7
--- /dev/null
+++ b/i386/grub/compiler.h
@@ -0,0 +1,51 @@
+/* compiler.h - macros for various compiler features */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010,2014 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_COMPILER_HEADER
+#define GRUB_COMPILER_HEADER 1
+
+/* GCC version checking borrowed from glibc. */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define GNUC_PREREQ(maj,min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+# define GNUC_PREREQ(maj,min) 0
+#endif
+
+/* Does this compiler support compile-time error attributes? */
+#if GNUC_PREREQ(4,3)
+# define ATTRIBUTE_ERROR(msg) \
+ __attribute__ ((__error__ (msg)))
+#else
+# define ATTRIBUTE_ERROR(msg) __attribute__ ((noreturn))
+#endif
+
+#if GNUC_PREREQ(4,4)
+# define GNU_PRINTF gnu_printf
+#else
+# define GNU_PRINTF printf
+#endif
+
+#if GNUC_PREREQ(3,4)
+# define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
+#else
+# define WARN_UNUSED_RESULT
+#endif
+
+#endif /* ! GRUB_COMPILER_HEADER */
diff --git a/i386/grub/cpu/io.h b/i386/grub/cpu/io.h
new file mode 100644
index 00000000..ae12a3e3
--- /dev/null
+++ b/i386/grub/cpu/io.h
@@ -0,0 +1,72 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1996,2000,2002,2007 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Based on sys/io.h from GNU libc. */
+
+#ifndef GRUB_IO_H
+#define GRUB_IO_H 1
+
+typedef unsigned short int grub_port_t;
+
+static __inline unsigned char
+grub_inb (unsigned short int port)
+{
+ unsigned char _v;
+
+ __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned short int
+grub_inw (unsigned short int port)
+{
+ unsigned short _v;
+
+ __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned int
+grub_inl (unsigned short int port)
+{
+ unsigned int _v;
+
+ __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline void
+grub_outb (unsigned char value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
+}
+
+static __inline void
+grub_outw (unsigned short int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port));
+
+}
+
+static __inline void
+grub_outl (unsigned int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port));
+}
+
+#endif /* _SYS_IO_H */
diff --git a/i386/grub/cpu/time.h b/i386/grub/cpu/time.h
new file mode 100644
index 00000000..842882cf
--- /dev/null
+++ b/i386/grub/cpu/time.h
@@ -0,0 +1,29 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER 1
+
+static __inline void
+grub_cpu_idle (void)
+{
+ /* FIXME: this can't work until we handle interrupts. */
+/* __asm__ __volatile__ ("hlt"); */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/i386/grub/cpu/types.h b/i386/grub/cpu/types.h
new file mode 100644
index 00000000..c20063f3
--- /dev/null
+++ b/i386/grub/cpu/types.h
@@ -0,0 +1,33 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2006,2007 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER 1
+
+/* The size of void *. */
+#define GRUB_TARGET_SIZEOF_VOID_P 4
+
+/* The size of long. */
+#define GRUB_TARGET_SIZEOF_LONG 4
+
+/* i386 is little-endian. */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+
+#define GRUB_HAVE_UNALIGNED_ACCESS 1
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/i386/grub/err.h b/i386/grub/err.h
new file mode 100644
index 00000000..1590c688
--- /dev/null
+++ b/i386/grub/err.h
@@ -0,0 +1,96 @@
+/* err.h - error numbers and prototypes */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ERR_HEADER
+#define GRUB_ERR_HEADER 1
+
+#include <grub/symbol.h>
+
+#define GRUB_MAX_ERRMSG 256
+
+typedef enum
+ {
+ GRUB_ERR_NONE = 0,
+ GRUB_ERR_TEST_FAILURE,
+ GRUB_ERR_BAD_MODULE,
+ GRUB_ERR_OUT_OF_MEMORY,
+ GRUB_ERR_BAD_FILE_TYPE,
+ GRUB_ERR_FILE_NOT_FOUND,
+ GRUB_ERR_FILE_READ_ERROR,
+ GRUB_ERR_BAD_FILENAME,
+ GRUB_ERR_UNKNOWN_FS,
+ GRUB_ERR_BAD_FS,
+ GRUB_ERR_BAD_NUMBER,
+ GRUB_ERR_OUT_OF_RANGE,
+ GRUB_ERR_UNKNOWN_DEVICE,
+ GRUB_ERR_BAD_DEVICE,
+ GRUB_ERR_READ_ERROR,
+ GRUB_ERR_WRITE_ERROR,
+ GRUB_ERR_UNKNOWN_COMMAND,
+ GRUB_ERR_INVALID_COMMAND,
+ GRUB_ERR_BAD_ARGUMENT,
+ GRUB_ERR_BAD_PART_TABLE,
+ GRUB_ERR_UNKNOWN_OS,
+ GRUB_ERR_BAD_OS,
+ GRUB_ERR_NO_KERNEL,
+ GRUB_ERR_BAD_FONT,
+ GRUB_ERR_NOT_IMPLEMENTED_YET,
+ GRUB_ERR_SYMLINK_LOOP,
+ GRUB_ERR_BAD_COMPRESSED_DATA,
+ GRUB_ERR_MENU,
+ GRUB_ERR_TIMEOUT,
+ GRUB_ERR_IO,
+ GRUB_ERR_ACCESS_DENIED,
+ GRUB_ERR_EXTRACTOR,
+ GRUB_ERR_NET_BAD_ADDRESS,
+ GRUB_ERR_NET_ROUTE_LOOP,
+ GRUB_ERR_NET_NO_ROUTE,
+ GRUB_ERR_NET_NO_ANSWER,
+ GRUB_ERR_NET_NO_CARD,
+ GRUB_ERR_WAIT,
+ GRUB_ERR_BUG,
+ GRUB_ERR_NET_PORT_CLOSED,
+ GRUB_ERR_NET_INVALID_RESPONSE,
+ GRUB_ERR_NET_UNKNOWN_ERROR,
+ GRUB_ERR_NET_PACKET_TOO_BIG,
+ GRUB_ERR_NET_NO_DOMAIN,
+ GRUB_ERR_EOF,
+ GRUB_ERR_BAD_SIGNATURE
+ }
+grub_err_t;
+
+struct grub_error_saved
+{
+ grub_err_t grub_errno;
+ char errmsg[GRUB_MAX_ERRMSG];
+};
+
+extern grub_err_t EXPORT_VAR(grub_errno);
+extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG];
+
+grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...);
+void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn));
+void EXPORT_FUNC(grub_error_push) (void);
+int EXPORT_FUNC(grub_error_pop) (void);
+void EXPORT_FUNC(grub_print_error) (void);
+extern int EXPORT_VAR(grub_err_printed_errors);
+int grub_err_printf (const char *fmt, ...)
+ __attribute__ ((format (__printf__, 1, 2)));
+
+#endif /* ! GRUB_ERR_HEADER */
diff --git a/i386/grub/glue.h b/i386/grub/glue.h
new file mode 100644
index 00000000..ae41014d
--- /dev/null
+++ b/i386/grub/glue.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GRUB_GLUE_H
+#define _GRUB_GLUE_H
+
+#define GRUB_FILE __FILE__
+#define grub_memcmp memcmp
+#define grub_printf printf
+#define grub_puts_ puts
+
+#include <mach/mach_types.h>
+#include <i386/vm_param.h>
+
+/* Warning: this leaks memory maps for now, do not use it yet for something
+ * else than Mach shutdown. */
+vm_offset_t io_map_cached(vm_offset_t phys_addr, vm_size_t size);
+
+#endif /* _GRUB_GLUE_H */
diff --git a/i386/grub/i18n.h b/i386/grub/i18n.h
new file mode 100644
index 00000000..8b533571
--- /dev/null
+++ b/i386/grub/i18n.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GRUB_I18N_H
+#define _GRUB_I18N_H
+
+/* No i18n please. */
+#define _(x) x
+#define N_(x) x
+
+#endif /* _GRUB_I18N_H */
diff --git a/i386/grub/misc.h b/i386/grub/misc.h
new file mode 100644
index 00000000..b71140a5
--- /dev/null
+++ b/i386/grub/misc.h
@@ -0,0 +1,517 @@
+/* misc.h - prototypes for misc functions */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MISC_HEADER
+#define GRUB_MISC_HEADER 1
+
+#include <stdarg.h>
+#include <kern/macros.h>
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/i18n.h>
+#include <grub/compiler.h>
+
+#define ALIGN_UP(addr, align) \
+ ((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1))
+#define ALIGN_UP_OVERHEAD(addr, align) ((-(addr)) & ((typeof (addr)) (align) - 1))
+#define ALIGN_DOWN(addr, align) \
+ ((addr) & ~((typeof (addr)) align - 1))
+#define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; }
+
+#define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__)
+
+void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
+char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src);
+
+static inline char *
+grub_strncpy (char *dest, const char *src, int c)
+{
+ char *p = dest;
+
+ while ((*p++ = *src++) != '\0' && --c)
+ ;
+
+ return dest;
+}
+
+static inline char *
+grub_stpcpy (char *dest, const char *src)
+{
+ char *d = dest;
+ const char *s = src;
+
+ do
+ *d++ = *s;
+ while (*s++ != '\0');
+
+ return d - 1;
+}
+
+/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */
+static inline void *
+grub_memcpy (void *dest, const void *src, grub_size_t n)
+{
+ return grub_memmove (dest, src, n);
+}
+
+#if defined (__APPLE__) && defined(__i386__) && !defined (GRUB_UTIL)
+#define GRUB_BUILTIN_ATTR __attribute__ ((regparm(0)))
+#else
+#define GRUB_BUILTIN_ATTR
+#endif
+
+#if defined(__x86_64__) && !defined (GRUB_UTIL)
+#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (__MINGW64__)
+#define GRUB_ASM_ATTR __attribute__ ((sysv_abi))
+#else
+#define GRUB_ASM_ATTR
+#endif
+#endif
+
+/* Prototypes for aliases. */
+#ifndef GRUB_UTIL
+int GRUB_BUILTIN_ATTR EXPORT_FUNC(memcmp) (const void *s1, const void *s2, grub_size_t n);
+void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memmove) (void *dest, const void *src, grub_size_t n);
+void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memcpy) (void *dest, const void *src, grub_size_t n);
+void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memset) (void *s, int c, grub_size_t n);
+
+#ifdef __APPLE__
+void GRUB_BUILTIN_ATTR EXPORT_FUNC (__bzero) (void *s, grub_size_t n);
+#endif
+
+#endif
+
+int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n);
+int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2);
+int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n);
+
+char *EXPORT_FUNC(grub_strchr) (const char *s, int c);
+char *EXPORT_FUNC(grub_strrchr) (const char *s, int c);
+int EXPORT_FUNC(grub_strword) (const char *s, const char *w);
+
+/* Copied from gnulib.
+ Written by Bruno Haible <bruno@clisp.org>, 2005. */
+static inline char *
+grub_strstr (const char *haystack, const char *needle)
+{
+ /* Be careful not to look at the entire extent of haystack or needle
+ until needed. This is useful because of these two cases:
+ - haystack may be very long, and a match of needle found early,
+ - needle may be very long, and not even a short initial segment of
+ needle may be found in haystack. */
+ if (*needle != '\0')
+ {
+ /* Speed up the following searches of needle by caching its first
+ character. */
+ char b = *needle++;
+
+ for (;; haystack++)
+ {
+ if (*haystack == '\0')
+ /* No match. */
+ return 0;
+ if (*haystack == b)
+ /* The first character matches. */
+ {
+ const char *rhaystack = haystack + 1;
+ const char *rneedle = needle;
+
+ for (;; rhaystack++, rneedle++)
+ {
+ if (*rneedle == '\0')
+ /* Found a match. */
+ return (char *) haystack;
+ if (*rhaystack == '\0')
+ /* No match. */
+ return 0;
+ if (*rhaystack != *rneedle)
+ /* Nothing in this round. */
+ break;
+ }
+ }
+ }
+ }
+ else
+ return (char *) haystack;
+}
+
+int EXPORT_FUNC(grub_isspace) (int c);
+
+static inline int
+grub_isprint (int c)
+{
+ return (c >= ' ' && c <= '~');
+}
+
+static inline int
+grub_iscntrl (int c)
+{
+ return (c >= 0x00 && c <= 0x1F) || c == 0x7F;
+}
+
+static inline int
+grub_isalpha (int c)
+{
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+
+static inline int
+grub_islower (int c)
+{
+ return (c >= 'a' && c <= 'z');
+}
+
+static inline int
+grub_isupper (int c)
+{
+ return (c >= 'A' && c <= 'Z');
+}
+
+static inline int
+grub_isgraph (int c)
+{
+ return (c >= '!' && c <= '~');
+}
+
+static inline int
+grub_isdigit (int c)
+{
+ return (c >= '0' && c <= '9');
+}
+
+static inline int
+grub_isxdigit (int c)
+{
+ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
+}
+
+static inline int
+grub_isalnum (int c)
+{
+ return grub_isalpha (c) || grub_isdigit (c);
+}
+
+static inline int
+grub_tolower (int c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return c - 'A' + 'a';
+
+ return c;
+}
+
+static inline int
+grub_toupper (int c)
+{
+ if (c >= 'a' && c <= 'z')
+ return c - 'a' + 'A';
+
+ return c;
+}
+
+static inline int
+grub_strcasecmp (const char *s1, const char *s2)
+{
+ while (*s1 && *s2)
+ {
+ if (grub_tolower ((grub_uint8_t) *s1)
+ != grub_tolower ((grub_uint8_t) *s2))
+ break;
+
+ s1++;
+ s2++;
+ }
+
+ return (int) grub_tolower ((grub_uint8_t) *s1)
+ - (int) grub_tolower ((grub_uint8_t) *s2);
+}
+
+static inline int
+grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
+{
+ if (n == 0)
+ return 0;
+
+ while (*s1 && *s2 && --n)
+ {
+ if (grub_tolower (*s1) != grub_tolower (*s2))
+ break;
+
+ s1++;
+ s2++;
+ }
+
+ return (int) grub_tolower ((grub_uint8_t) *s1)
+ - (int) grub_tolower ((grub_uint8_t) *s2);
+}
+
+unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base);
+unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base);
+
+static inline long
+grub_strtol (const char *str, char **end, int base)
+{
+ int negative = 0;
+ unsigned long long magnitude;
+
+ while (*str && grub_isspace (*str))
+ str++;
+
+ if (*str == '-')
+ {
+ negative = 1;
+ str++;
+ }
+
+ magnitude = grub_strtoull (str, end, base);
+ if (negative)
+ {
+ if (magnitude > (unsigned long) GRUB_LONG_MAX + 1)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+ return GRUB_LONG_MIN;
+ }
+ return -((long) magnitude);
+ }
+ else
+ {
+ if (magnitude > GRUB_LONG_MAX)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+ return GRUB_LONG_MAX;
+ }
+ return (long) magnitude;
+ }
+}
+
+char *EXPORT_FUNC(grub_strdup) (const char *s) WARN_UNUSED_RESULT;
+char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n) WARN_UNUSED_RESULT;
+void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
+grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) WARN_UNUSED_RESULT;
+int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2)));
+int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2)));
+
+/* Replace all `ch' characters of `input' with `with' and copy the
+ result into `output'; return EOS address of `output'. */
+static inline char *
+grub_strchrsub (char *output, const char *input, char ch, const char *with)
+{
+ while (*input)
+ {
+ if (*input == ch)
+ {
+ grub_strcpy (output, with);
+ output += grub_strlen (with);
+ input++;
+ continue;
+ }
+ *output++ = *input++;
+ }
+ *output = '\0';
+ return output;
+}
+
+extern void (*EXPORT_VAR (grub_xputs)) (const char *str);
+
+static inline int
+grub_puts (const char *s)
+{
+ const char nl[2] = "\n";
+ grub_xputs (s);
+ grub_xputs (nl);
+
+ return 1; /* Cannot fail. */
+}
+
+int EXPORT_FUNC(grub_puts_) (const char *s);
+void EXPORT_FUNC(grub_real_dprintf) (const char *file,
+ const int line,
+ const char *condition,
+ const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 4, 5)));
+int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args);
+int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...)
+ __attribute__ ((format (GNU_PRINTF, 3, 4)));
+int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt,
+ va_list args);
+char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...)
+ __attribute__ ((format (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT;
+char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) WARN_UNUSED_RESULT;
+void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
+grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
+ grub_uint64_t d,
+ grub_uint64_t *r);
+
+#if (defined (__MINGW32__) || defined (__CYGWIN__)) && !defined(GRUB_UTIL)
+void EXPORT_FUNC (__register_frame_info) (void);
+void EXPORT_FUNC (__deregister_frame_info) (void);
+void EXPORT_FUNC (___chkstk_ms) (void);
+void EXPORT_FUNC (__chkstk_ms) (void);
+#endif
+
+/* Inline functions. */
+
+static inline char *
+grub_memchr (const void *p, int c, grub_size_t len)
+{
+ const char *s = (const char *) p;
+ const char *e = s + len;
+
+ for (; s < e; s++)
+ if (*s == c)
+ return (char *) s;
+
+ return 0;
+}
+
+
+static inline unsigned int
+grub_abs (int x)
+{
+ if (x < 0)
+ return (unsigned int) (-x);
+ else
+ return (unsigned int) x;
+}
+
+/* Rounded-up division */
+static inline unsigned int
+grub_div_roundup (unsigned int x, unsigned int y)
+{
+ return (x + y - 1) / y;
+}
+
+/* Reboot the machine. */
+#if defined (GRUB_MACHINE_EMU) || defined (GRUB_MACHINE_QEMU_MIPS)
+void EXPORT_FUNC(grub_reboot) (void) __attribute__ ((noreturn));
+#else
+void grub_reboot (void) __attribute__ ((noreturn));
+#endif
+
+#if defined (__clang__) && !defined (GRUB_UTIL)
+void __attribute__ ((noreturn)) EXPORT_FUNC (abort) (void);
+#endif
+
+#ifdef GRUB_MACHINE_PCBIOS
+/* Halt the system, using APM if possible. If NO_APM is true, don't
+ * use APM even if it is available. */
+void grub_halt (int no_apm) __attribute__ ((noreturn));
+#elif defined (__mips__) && !defined (GRUB_MACHINE_EMU)
+void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn));
+#else
+void grub_halt (void) __attribute__ ((noreturn));
+#endif
+
+#ifdef GRUB_MACHINE_EMU
+/* Flag to check if module loading is available. */
+extern const int EXPORT_VAR(grub_no_modules);
+#else
+#define grub_no_modules 0
+#endif
+
+static inline void
+grub_error_save (struct grub_error_saved *save)
+{
+ grub_memcpy (save->errmsg, grub_errmsg, sizeof (save->errmsg));
+ save->grub_errno = grub_errno;
+ grub_errno = GRUB_ERR_NONE;
+}
+
+static inline void
+grub_error_load (const struct grub_error_saved *save)
+{
+ grub_memcpy (grub_errmsg, save->errmsg, sizeof (grub_errmsg));
+ grub_errno = save->grub_errno;
+}
+
+#ifndef GRUB_UTIL
+
+#if defined (__arm__)
+
+grub_uint32_t
+EXPORT_FUNC (__udivsi3) (grub_uint32_t a, grub_uint32_t b);
+
+grub_uint32_t
+EXPORT_FUNC (__umodsi3) (grub_uint32_t a, grub_uint32_t b);
+
+#endif
+
+#if defined (__sparc__) || defined (__powerpc__)
+unsigned
+EXPORT_FUNC (__ctzdi2) (grub_uint64_t x);
+#define NEED_CTZDI2 1
+#endif
+
+#if defined (__mips__) || defined (__arm__)
+unsigned
+EXPORT_FUNC (__ctzsi2) (grub_uint32_t x);
+#define NEED_CTZSI2 1
+#endif
+
+#ifdef __arm__
+grub_uint32_t
+EXPORT_FUNC (__aeabi_uidiv) (grub_uint32_t a, grub_uint32_t b);
+grub_uint32_t
+EXPORT_FUNC (__aeabi_uidivmod) (grub_uint32_t a, grub_uint32_t b);
+
+/* Needed for allowing modules to be compiled as thumb. */
+grub_uint64_t
+EXPORT_FUNC (__muldi3) (grub_uint64_t a, grub_uint64_t b);
+grub_uint64_t
+EXPORT_FUNC (__aeabi_lmul) (grub_uint64_t a, grub_uint64_t b);
+
+#endif
+
+#if defined (__ia64__)
+
+grub_uint64_t
+EXPORT_FUNC (__udivdi3) (grub_uint64_t a, grub_uint64_t b);
+
+grub_uint64_t
+EXPORT_FUNC (__umoddi3) (grub_uint64_t a, grub_uint64_t b);
+
+#endif
+
+#endif /* GRUB_UTIL */
+
+
+#if BOOT_TIME_STATS
+struct grub_boot_time
+{
+ struct grub_boot_time *next;
+ grub_uint64_t tp;
+ const char *file;
+ int line;
+ char *msg;
+};
+
+extern struct grub_boot_time *EXPORT_VAR(grub_boot_time_head);
+
+void EXPORT_FUNC(grub_real_boot_time) (const char *file,
+ const int line,
+ const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 3, 4)));
+#define grub_boot_time(...) grub_real_boot_time(GRUB_FILE, __LINE__, __VA_ARGS__)
+#else
+#define grub_boot_time(...)
+#endif
+
+#define grub_max(a, b) (((a) > (b)) ? (a) : (b))
+#define grub_min(a, b) (((a) < (b)) ? (a) : (b))
+
+#endif /* ! GRUB_MISC_HEADER */
diff --git a/i386/grub/mm.h b/i386/grub/mm.h
new file mode 100644
index 00000000..28e2e53e
--- /dev/null
+++ b/i386/grub/mm.h
@@ -0,0 +1,77 @@
+/* mm.h - prototypes and declarations for memory manager */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2007 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MM_H
+#define GRUB_MM_H 1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <config.h>
+
+#ifndef NULL
+# define NULL ((void *) 0)
+#endif
+
+void grub_mm_init_region (void *addr, grub_size_t size);
+void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
+void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);
+void EXPORT_FUNC(grub_free) (void *ptr);
+void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size);
+#ifndef GRUB_MACHINE_EMU
+void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size);
+#endif
+
+void grub_mm_check_real (const char *file, int line);
+#define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__);
+
+/* For debugging. */
+#if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU)
+/* Set this variable to 1 when you want to trace all memory function calls. */
+extern int EXPORT_VAR(grub_mm_debug);
+
+void grub_mm_dump_free (void);
+void grub_mm_dump (unsigned lineno);
+
+#define grub_malloc(size) \
+ grub_debug_malloc (GRUB_FILE, __LINE__, size)
+
+#define grub_zalloc(size) \
+ grub_debug_zalloc (GRUB_FILE, __LINE__, size)
+
+#define grub_realloc(ptr,size) \
+ grub_debug_realloc (GRUB_FILE, __LINE__, ptr, size)
+
+#define grub_memalign(align,size) \
+ grub_debug_memalign (GRUB_FILE, __LINE__, align, size)
+
+#define grub_free(ptr) \
+ grub_debug_free (GRUB_FILE, __LINE__, ptr)
+
+void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line,
+ grub_size_t size);
+void *EXPORT_FUNC(grub_debug_zalloc) (const char *file, int line,
+ grub_size_t size);
+void EXPORT_FUNC(grub_debug_free) (const char *file, int line, void *ptr);
+void *EXPORT_FUNC(grub_debug_realloc) (const char *file, int line, void *ptr,
+ grub_size_t size);
+void *EXPORT_FUNC(grub_debug_memalign) (const char *file, int line,
+ grub_size_t align, grub_size_t size);
+#endif /* MM_DEBUG && ! GRUB_UTIL */
+
+#endif /* ! GRUB_MM_H */
diff --git a/i386/grub/symbol.h b/i386/grub/symbol.h
new file mode 100644
index 00000000..ed19f70d
--- /dev/null
+++ b/i386/grub/symbol.h
@@ -0,0 +1,72 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SYMBOL_HEADER
+#define GRUB_SYMBOL_HEADER 1
+
+#include <config.h>
+
+/* Apple assembler requires local labels to start with a capital L */
+#define LOCAL(sym) L_ ## sym
+
+/* Add an underscore to a C symbol in assembler code if needed. */
+#ifndef GRUB_UTIL
+
+#ifdef __APPLE__
+#define MACRO_DOLLAR(x) $$ ## x
+#else
+#define MACRO_DOLLAR(x) $ ## x
+#endif
+
+#if HAVE_ASM_USCORE
+#ifdef ASM_FILE
+# define EXT_C(sym) _ ## sym
+#else
+# define EXT_C(sym) "_" sym
+#endif
+#else
+# define EXT_C(sym) sym
+#endif
+
+#ifdef __arm__
+#define END .end
+#endif
+
+#if defined (__APPLE__)
+#define FUNCTION(x) .globl EXT_C(x) ; EXT_C(x):
+#define VARIABLE(x) .globl EXT_C(x) ; EXT_C(x):
+#elif defined (__CYGWIN__) || defined (__MINGW32__)
+/* .type not supported for non-ELF targets. XXX: Check this in configure? */
+#define FUNCTION(x) .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 32; .endef; EXT_C(x):
+#define VARIABLE(x) .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 0; .endef; EXT_C(x):
+#elif defined (__arm__)
+#define FUNCTION(x) .globl EXT_C(x) ; .type EXT_C(x), %function ; EXT_C(x):
+#define VARIABLE(x) .globl EXT_C(x) ; .type EXT_C(x), %object ; EXT_C(x):
+#else
+#define FUNCTION(x) .globl EXT_C(x) ; .type EXT_C(x), @function ; EXT_C(x):
+#define VARIABLE(x) .globl EXT_C(x) ; .type EXT_C(x), @object ; EXT_C(x):
+#endif
+#endif
+
+/* Mark an exported symbol. */
+#ifndef GRUB_SYMBOL_GENERATOR
+# define EXPORT_FUNC(x) x
+# define EXPORT_VAR(x) x
+#endif /* ! GRUB_SYMBOL_GENERATOR */
+
+#endif /* ! GRUB_SYMBOL_HEADER */
diff --git a/i386/grub/time.h b/i386/grub/time.h
new file mode 100644
index 00000000..64ac99a1
--- /dev/null
+++ b/i386/grub/time.h
@@ -0,0 +1,46 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_TIME_HEADER
+#define KERNEL_TIME_HEADER 1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#ifndef GRUB_MACHINE_EMU
+#include <grub/cpu/time.h>
+#else
+static inline void
+grub_cpu_idle(void)
+{
+}
+#endif
+
+void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms);
+grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void);
+
+grub_uint64_t grub_rtc_get_time_ms (void);
+
+static __inline void
+grub_sleep (grub_uint32_t s)
+{
+ grub_millisleep (1000 * s);
+}
+
+void grub_install_get_time_ms (grub_uint64_t (*get_time_ms_func) (void));
+
+#endif /* ! KERNEL_TIME_HEADER */
diff --git a/i386/grub/types.h b/i386/grub/types.h
new file mode 100644
index 00000000..79f765c6
--- /dev/null
+++ b/i386/grub/types.h
@@ -0,0 +1,325 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_HEADER
+#define GRUB_TYPES_HEADER 1
+
+#include <config.h>
+#ifndef GRUB_UTIL
+#include <grub/cpu/types.h>
+#endif
+
+#ifdef __MINGW32__
+#define GRUB_PACKED __attribute__ ((packed,gcc_struct))
+#else
+#define GRUB_PACKED __attribute__ ((packed))
+#endif
+
+#ifdef GRUB_BUILD
+# define GRUB_CPU_SIZEOF_VOID_P BUILD_SIZEOF_VOID_P
+# define GRUB_CPU_SIZEOF_LONG BUILD_SIZEOF_LONG
+# if BUILD_WORDS_BIGENDIAN
+# define GRUB_CPU_WORDS_BIGENDIAN 1
+# else
+# undef GRUB_CPU_WORDS_BIGENDIAN
+# endif
+#elif defined (GRUB_UTIL)
+# define GRUB_CPU_SIZEOF_VOID_P SIZEOF_VOID_P
+# define GRUB_CPU_SIZEOF_LONG SIZEOF_LONG
+# ifdef WORDS_BIGENDIAN
+# define GRUB_CPU_WORDS_BIGENDIAN 1
+# else
+# undef GRUB_CPU_WORDS_BIGENDIAN
+# endif
+#else /* ! GRUB_UTIL */
+# define GRUB_CPU_SIZEOF_VOID_P GRUB_TARGET_SIZEOF_VOID_P
+# define GRUB_CPU_SIZEOF_LONG GRUB_TARGET_SIZEOF_LONG
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+# define GRUB_CPU_WORDS_BIGENDIAN 1
+# else
+# undef GRUB_CPU_WORDS_BIGENDIAN
+# endif
+#endif /* ! GRUB_UTIL */
+
+#if GRUB_CPU_SIZEOF_VOID_P != 4 && GRUB_CPU_SIZEOF_VOID_P != 8
+# error "This architecture is not supported because sizeof(void *) != 4 and sizeof(void *) != 8"
+#endif
+
+#if GRUB_CPU_SIZEOF_LONG != 4 && GRUB_CPU_SIZEOF_LONG != 8
+# error "This architecture is not supported because sizeof(long) != 4 and sizeof(long) != 8"
+#endif
+
+#if !defined (GRUB_UTIL) && !defined (GRUB_TARGET_WORDSIZE)
+# if GRUB_TARGET_SIZEOF_VOID_P == 4
+# define GRUB_TARGET_WORDSIZE 32
+# elif GRUB_TARGET_SIZEOF_VOID_P == 8
+# define GRUB_TARGET_WORDSIZE 64
+# endif
+#endif
+
+/* Define various wide integers. */
+typedef signed char grub_int8_t;
+typedef short grub_int16_t;
+typedef int grub_int32_t;
+#if GRUB_CPU_SIZEOF_LONG == 8
+typedef long grub_int64_t;
+#else
+typedef long long grub_int64_t;
+#endif
+
+typedef unsigned char grub_uint8_t;
+typedef unsigned short grub_uint16_t;
+typedef unsigned grub_uint32_t;
+# define PRIxGRUB_UINT32_T "x"
+# define PRIuGRUB_UINT32_T "u"
+#if GRUB_CPU_SIZEOF_LONG == 8
+typedef unsigned long grub_uint64_t;
+# define PRIxGRUB_UINT64_T "lx"
+# define PRIuGRUB_UINT64_T "lu"
+#else
+typedef unsigned long long grub_uint64_t;
+# define PRIxGRUB_UINT64_T "llx"
+# define PRIuGRUB_UINT64_T "llu"
+#endif
+
+/* Misc types. */
+
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+typedef grub_uint64_t grub_addr_t;
+typedef grub_uint64_t grub_size_t;
+typedef grub_int64_t grub_ssize_t;
+
+# define GRUB_SIZE_MAX 18446744073709551615UL
+
+# if GRUB_CPU_SIZEOF_LONG == 8
+# define PRIxGRUB_SIZE "lx"
+# define PRIxGRUB_ADDR "lx"
+# define PRIuGRUB_SIZE "lu"
+# define PRIdGRUB_SSIZE "ld"
+# else
+# define PRIxGRUB_SIZE "llx"
+# define PRIxGRUB_ADDR "llx"
+# define PRIuGRUB_SIZE "llu"
+# define PRIdGRUB_SSIZE "lld"
+# endif
+#else
+typedef grub_uint32_t grub_addr_t;
+typedef grub_uint32_t grub_size_t;
+typedef grub_int32_t grub_ssize_t;
+
+# define GRUB_SIZE_MAX 4294967295UL
+
+# define PRIxGRUB_SIZE "x"
+# define PRIxGRUB_ADDR "x"
+# define PRIuGRUB_SIZE "u"
+# define PRIdGRUB_SSIZE "d"
+#endif
+
+#define GRUB_UCHAR_MAX 0xFF
+#define GRUB_USHRT_MAX 65535
+#define GRUB_SHRT_MAX 0x7fff
+#define GRUB_UINT_MAX 4294967295U
+#define GRUB_INT_MAX 0x7fffffff
+#define GRUB_INT32_MIN (-2147483647 - 1)
+#define GRUB_INT32_MAX 2147483647
+
+#if GRUB_CPU_SIZEOF_LONG == 8
+# define GRUB_ULONG_MAX 18446744073709551615UL
+# define GRUB_LONG_MAX 9223372036854775807L
+# define GRUB_LONG_MIN (-9223372036854775807L - 1)
+#else
+# define GRUB_ULONG_MAX 4294967295UL
+# define GRUB_LONG_MAX 2147483647L
+# define GRUB_LONG_MIN (-2147483647L - 1)
+#endif
+
+typedef grub_uint64_t grub_properly_aligned_t;
+
+#define GRUB_PROPERLY_ALIGNED_ARRAY(name, size) grub_properly_aligned_t name[((size) + sizeof (grub_properly_aligned_t) - 1) / sizeof (grub_properly_aligned_t)]
+
+/* The type for representing a file offset. */
+typedef grub_uint64_t grub_off_t;
+
+/* The type for representing a disk block address. */
+typedef grub_uint64_t grub_disk_addr_t;
+
+/* Byte-orders. */
+static inline grub_uint16_t grub_swap_bytes16(grub_uint16_t _x)
+{
+ return (grub_uint16_t) ((_x << 8) | (_x >> 8));
+}
+
+#define grub_swap_bytes16_compile_time(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+#define grub_swap_bytes32_compile_time(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000UL) >> 24))
+#define grub_swap_bytes64_compile_time(x) \
+({ \
+ grub_uint64_t _x = (x); \
+ (grub_uint64_t) ((_x << 56) \
+ | ((_x & (grub_uint64_t) 0xFF00ULL) << 40) \
+ | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24) \
+ | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) \
+ | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8) \
+ | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24) \
+ | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40) \
+ | (_x >> 56)); \
+})
+
+#if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
+static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t x)
+{
+ return __builtin_bswap32(x);
+}
+
+static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x)
+{
+ return __builtin_bswap64(x);
+}
+#else /* not gcc 4.3 or newer */
+static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t _x)
+{
+ return ((_x << 24)
+ | ((_x & (grub_uint32_t) 0xFF00UL) << 8)
+ | ((_x & (grub_uint32_t) 0xFF0000UL) >> 8)
+ | (_x >> 24));
+}
+
+static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t _x)
+{
+ return ((_x << 56)
+ | ((_x & (grub_uint64_t) 0xFF00ULL) << 40)
+ | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24)
+ | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8)
+ | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8)
+ | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24)
+ | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40)
+ | (_x >> 56));
+}
+#endif /* not gcc 4.3 or newer */
+
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+# define grub_cpu_to_le16(x) grub_swap_bytes16(x)
+# define grub_cpu_to_le32(x) grub_swap_bytes32(x)
+# define grub_cpu_to_le64(x) grub_swap_bytes64(x)
+# define grub_le_to_cpu16(x) grub_swap_bytes16(x)
+# define grub_le_to_cpu32(x) grub_swap_bytes32(x)
+# define grub_le_to_cpu64(x) grub_swap_bytes64(x)
+# define grub_cpu_to_be16(x) ((grub_uint16_t) (x))
+# define grub_cpu_to_be32(x) ((grub_uint32_t) (x))
+# define grub_cpu_to_be64(x) ((grub_uint64_t) (x))
+# define grub_be_to_cpu16(x) ((grub_uint16_t) (x))
+# define grub_be_to_cpu32(x) ((grub_uint32_t) (x))
+# define grub_be_to_cpu64(x) ((grub_uint64_t) (x))
+# define grub_cpu_to_be16_compile_time(x) ((grub_uint16_t) (x))
+# define grub_cpu_to_be32_compile_time(x) ((grub_uint32_t) (x))
+# define grub_cpu_to_be64_compile_time(x) ((grub_uint64_t) (x))
+# define grub_be_to_cpu64_compile_time(x) ((grub_uint64_t) (x))
+# define grub_cpu_to_le32_compile_time(x) grub_swap_bytes32_compile_time(x)
+# define grub_cpu_to_le64_compile_time(x) grub_swap_bytes64_compile_time(x)
+# define grub_cpu_to_le16_compile_time(x) grub_swap_bytes16_compile_time(x)
+#else /* ! WORDS_BIGENDIAN */
+# define grub_cpu_to_le16(x) ((grub_uint16_t) (x))
+# define grub_cpu_to_le32(x) ((grub_uint32_t) (x))
+# define grub_cpu_to_le64(x) ((grub_uint64_t) (x))
+# define grub_le_to_cpu16(x) ((grub_uint16_t) (x))
+# define grub_le_to_cpu32(x) ((grub_uint32_t) (x))
+# define grub_le_to_cpu64(x) ((grub_uint64_t) (x))
+# define grub_cpu_to_be16(x) grub_swap_bytes16(x)
+# define grub_cpu_to_be32(x) grub_swap_bytes32(x)
+# define grub_cpu_to_be64(x) grub_swap_bytes64(x)
+# define grub_be_to_cpu16(x) grub_swap_bytes16(x)
+# define grub_be_to_cpu32(x) grub_swap_bytes32(x)
+# define grub_be_to_cpu64(x) grub_swap_bytes64(x)
+# define grub_cpu_to_be16_compile_time(x) grub_swap_bytes16_compile_time(x)
+# define grub_cpu_to_be32_compile_time(x) grub_swap_bytes32_compile_time(x)
+# define grub_cpu_to_be64_compile_time(x) grub_swap_bytes64_compile_time(x)
+# define grub_be_to_cpu64_compile_time(x) grub_swap_bytes64_compile_time(x)
+# define grub_cpu_to_le16_compile_time(x) ((grub_uint16_t) (x))
+# define grub_cpu_to_le32_compile_time(x) ((grub_uint32_t) (x))
+# define grub_cpu_to_le64_compile_time(x) ((grub_uint64_t) (x))
+
+#endif /* ! WORDS_BIGENDIAN */
+
+static inline grub_uint16_t grub_get_unaligned16 (const void *ptr)
+{
+ struct grub_unaligned_uint16_t
+ {
+ grub_uint16_t d;
+ } GRUB_PACKED;
+ const struct grub_unaligned_uint16_t *dd
+ = (const struct grub_unaligned_uint16_t *) ptr;
+ return dd->d;
+}
+
+static inline void grub_set_unaligned16 (void *ptr, grub_uint16_t val)
+{
+ struct grub_unaligned_uint16_t
+ {
+ grub_uint16_t d;
+ } GRUB_PACKED;
+ struct grub_unaligned_uint16_t *dd = (struct grub_unaligned_uint16_t *) ptr;
+ dd->d = val;
+}
+
+static inline grub_uint32_t grub_get_unaligned32 (const void *ptr)
+{
+ struct grub_unaligned_uint32_t
+ {
+ grub_uint32_t d;
+ } GRUB_PACKED;
+ const struct grub_unaligned_uint32_t *dd
+ = (const struct grub_unaligned_uint32_t *) ptr;
+ return dd->d;
+}
+
+static inline void grub_set_unaligned32 (void *ptr, grub_uint32_t val)
+{
+ struct grub_unaligned_uint32_t
+ {
+ grub_uint32_t d;
+ } GRUB_PACKED;
+ struct grub_unaligned_uint32_t *dd = (struct grub_unaligned_uint32_t *) ptr;
+ dd->d = val;
+}
+
+struct grub_unaligned_uint64
+{
+ grub_uint64_t val;
+} GRUB_PACKED;
+
+typedef struct grub_unaligned_uint64 grub_unaligned_uint64_t;
+
+static inline grub_uint64_t grub_get_unaligned64 (const void *ptr)
+{
+ const struct grub_unaligned_uint64 *dd
+ = (const struct grub_unaligned_uint64 *) ptr;
+ return dd->val;
+}
+
+static inline void grub_set_unaligned64 (void *ptr, grub_uint64_t val)
+{
+ struct grub_unaligned_uint64_t
+ {
+ grub_uint64_t d;
+ } GRUB_PACKED;
+ struct grub_unaligned_uint64_t *dd = (struct grub_unaligned_uint64_t *) ptr;
+ dd->d = val;
+}
+
+#define GRUB_CHAR_BIT 8
+
+#endif /* ! GRUB_TYPES_HEADER */
diff --git a/i386/i386/ast_check.c b/i386/i386/ast_check.c
index 982c7053..f3e1c350 100644
--- a/i386/i386/ast_check.c
+++ b/i386/i386/ast_check.c
@@ -37,23 +37,17 @@
/*
* Initialize for remote invocation of ast_check.
*/
-init_ast_check(processor)
- processor_t processor;
+void init_ast_check(processor)
+ const processor_t processor;
{
-#ifdef lint
- processor++;
-#endif /* lint */
}
/*
* Cause remote invocation of ast_check. Caller is at splsched().
*/
-cause_ast_check(processor)
- processor_t processor;
+void cause_ast_check(processor)
+ const processor_t processor;
{
-#ifdef lint
- processor++;
-#endif /* lint */
}
#endif /* NCPUS > 1 */
diff --git a/i386/i386/db_disasm.c b/i386/i386/db_disasm.c
index e15293b0..4afbcf3e 100644
--- a/i386/i386/db_disasm.c
+++ b/i386/i386/db_disasm.c
@@ -950,10 +950,10 @@ db_read_address(
void
db_print_address(
- char * seg,
- int size,
- struct i_addr *addrp,
- task_t task)
+ const char * seg,
+ int size,
+ const struct i_addr *addrp,
+ task_t task)
{
if (addrp->is_reg) {
db_printf("%s", db_reg[size][addrp->disp]);
@@ -986,7 +986,7 @@ db_disasm_esc(
int inst,
int short_addr,
int size,
- char * seg,
+ const char * seg,
task_t task)
{
int regmodrm;
diff --git a/i386/i386/db_interface.c b/i386/i386/db_interface.c
index 66cc8b59..b3fac0bb 100644
--- a/i386/i386/db_interface.c
+++ b/i386/i386/db_interface.c
@@ -27,8 +27,7 @@
* Interface to new debugger.
*/
-#if MACH_KDB
-
+#include <string.h>
#include <sys/reboot.h>
#include <vm/pmap.h>
@@ -45,6 +44,7 @@
#include "vm_param.h"
#include <vm/vm_map.h>
+#include <vm/vm_fault.h>
#include <kern/cpu_number.h>
#include <kern/printf.h>
#include <kern/thread.h>
@@ -55,21 +55,181 @@
#include <ddb/db_run.h>
#include <ddb/db_task_thread.h>
#include <ddb/db_trap.h>
+#include <ddb/db_watch.h>
#include <machine/db_interface.h>
#include <machine/machspl.h>
+#if MACH_KDB
+/* Whether the kernel uses any debugging register. */
+static boolean_t kernel_dr;
+#endif
+/* Whether the current debug registers are zero. */
+static boolean_t zero_dr;
+
+void db_load_context(pcb_t pcb)
+{
+#if MACH_KDB
+ int s = splhigh();
+
+ if (kernel_dr) {
+ splx(s);
+ return;
+ }
+#endif
+ /* Else set user debug registers, if any */
+ unsigned int *dr = pcb->ims.ids.dr;
+ boolean_t will_zero_dr = !dr[0] && !dr[1] && !dr[2] && !dr[3] && !dr[7];
+
+ if (!(zero_dr && will_zero_dr))
+ {
+ set_dr0(dr[0]);
+ set_dr1(dr[1]);
+ set_dr2(dr[2]);
+ set_dr3(dr[3]);
+ set_dr7(dr[7]);
+ zero_dr = will_zero_dr;
+ }
+
+#if MACH_KDB
+ splx(s);
+#endif
+}
+
+void db_get_debug_state(
+ pcb_t pcb,
+ struct i386_debug_state *state)
+{
+ *state = pcb->ims.ids;
+}
+
+kern_return_t db_set_debug_state(
+ pcb_t pcb,
+ const struct i386_debug_state *state)
+{
+ int i;
+
+ for (i = 0; i <= 3; i++)
+ if (state->dr[i] < VM_MIN_ADDRESS
+ || state->dr[i] >= VM_MAX_ADDRESS)
+ return KERN_INVALID_ARGUMENT;
+
+ pcb->ims.ids = *state;
+
+ if (pcb == current_thread()->pcb)
+ db_load_context(pcb);
+
+ return KERN_SUCCESS;
+}
+
+#if MACH_KDB
+
struct i386_saved_state *i386_last_saved_statep;
struct i386_saved_state i386_nested_saved_state;
unsigned i386_last_kdb_sp;
extern thread_t db_default_thread;
+static struct i386_debug_state ids;
+
+void db_dr (
+ int num,
+ vm_offset_t linear_addr,
+ int type,
+ int len,
+ int persistence)
+{
+ int s = splhigh();
+ unsigned long dr7;
+
+ if (!kernel_dr) {
+ if (!linear_addr) {
+ splx(s);
+ return;
+ }
+ kernel_dr = TRUE;
+ /* Clear user debugging registers */
+ set_dr7(0);
+ set_dr0(0);
+ set_dr1(0);
+ set_dr2(0);
+ set_dr3(0);
+ }
+
+ ids.dr[num] = linear_addr;
+ switch (num) {
+ case 0: set_dr0(linear_addr); break;
+ case 1: set_dr1(linear_addr); break;
+ case 2: set_dr2(linear_addr); break;
+ case 3: set_dr3(linear_addr); break;
+ }
+
+ /* Replace type/len/persistence for DRnum in dr7 */
+ dr7 = get_dr7 ();
+ dr7 &= ~(0xfUL << (4*num+16)) & ~(0x3UL << (2*num));
+ dr7 |= (((len << 2) | type) << (4*num+16)) | (persistence << (2*num));
+ set_dr7 (dr7);
+
+ if (kernel_dr) {
+ if (!ids.dr[0] && !ids.dr[1] && !ids.dr[2] && !ids.dr[3]) {
+ /* Not used any more, switch back to user debugging registers */
+ set_dr7 (0);
+ kernel_dr = FALSE;
+ zero_dr = TRUE;
+ db_load_context(current_thread()->pcb);
+ }
+ }
+ splx(s);
+}
+
+boolean_t
+db_set_hw_watchpoint(
+ const db_watchpoint_t watch,
+ unsigned num)
+{
+ vm_size_t size = watch->hiaddr - watch->loaddr;
+ db_addr_t addr = watch->loaddr;
+ vm_offset_t kern_addr;
+
+ if (num >= 4)
+ return FALSE;
+ if (size != 1 && size != 2 && size != 4)
+ return FALSE;
+
+ if (addr & (size-1))
+ /* Unaligned */
+ return FALSE;
+
+ if (watch->task) {
+ if (db_user_to_kernel_address(watch->task, addr, &kern_addr, 1) < 0)
+ return FALSE;
+ addr = kern_addr;
+ }
+ addr = kvtolin(addr);
+
+ db_dr (num, addr, I386_DB_TYPE_W, size-1, I386_DB_LOCAL|I386_DB_GLOBAL);
+
+ db_printf("Hardware watchpoint %d set for %x\n", num, addr);
+ return TRUE;
+}
+
+boolean_t
+db_clear_hw_watchpoint(
+ unsigned num)
+{
+ if (num >= 4)
+ return FALSE;
+
+ db_dr (num, 0, 0, 0, 0);
+ return TRUE;
+}
+
/*
* Print trap reason.
*/
void
-kdbprinttrap(type, code)
- int type, code;
+kdbprinttrap(
+ int type,
+ int code)
{
printf("kernel: %s (%d), code=%x\n",
trap_name(type), type, code);
@@ -86,7 +246,7 @@ boolean_t
kdb_trap(
int type,
int code,
- register struct i386_saved_state *regs)
+ struct i386_saved_state *regs)
{
spl_t s;
@@ -96,15 +256,14 @@ kdb_trap(
switch (type) {
case T_DEBUG: /* single_step */
{
- extern int dr_addr[];
int addr;
- int status = dr6();
+ int status = get_dr6();
if (status & 0xf) { /* hmm hdw break */
- addr = status & 0x8 ? dr_addr[3] :
- status & 0x4 ? dr_addr[2] :
- status & 0x2 ? dr_addr[1] :
- dr_addr[0];
+ addr = status & 0x8 ? get_dr3() :
+ status & 0x4 ? get_dr2() :
+ status & 0x2 ? get_dr1() :
+ get_dr0();
regs->efl |= EFL_RF;
db_single_step_cmd(addr, 0, 1, "p");
}
@@ -263,12 +422,12 @@ boolean_t db_no_vm_fault = TRUE;
int
db_user_to_kernel_address(
- task_t task,
+ const task_t task,
vm_offset_t addr,
- unsigned int *kaddr,
+ vm_offset_t *kaddr,
int flag)
{
- register pt_entry_t *ptp;
+ pt_entry_t *ptp;
boolean_t faulted = FALSE;
retry:
@@ -292,7 +451,7 @@ db_user_to_kernel_address(
}
return(-1);
}
- *kaddr = (unsigned)ptetokv(*ptp) + (addr & (INTEL_PGBYTES-1));
+ *kaddr = ptetokv(*ptp) + (addr & (INTEL_PGBYTES-1));
return(0);
}
@@ -303,13 +462,13 @@ db_user_to_kernel_address(
void
db_read_bytes(
vm_offset_t addr,
- register int size,
- register char *data,
+ int size,
+ char *data,
task_t task)
{
- register char *src;
- register int n;
- unsigned kern_addr;
+ char *src;
+ int n;
+ vm_offset_t kern_addr;
src = (char *)addr;
if ((addr >= VM_MIN_KERNEL_ADDRESS && addr < VM_MAX_KERNEL_ADDRESS) || task == TASK_NULL) {
@@ -346,19 +505,18 @@ db_read_bytes(
void
db_write_bytes(
vm_offset_t addr,
- register int size,
- register char *data,
+ int size,
+ char *data,
task_t task)
{
- register char *dst;
+ char *dst;
- register pt_entry_t *ptep0 = 0;
+ pt_entry_t *ptep0 = 0;
pt_entry_t oldmap0 = 0;
vm_offset_t addr1;
- register pt_entry_t *ptep1 = 0;
+ pt_entry_t *ptep1 = 0;
pt_entry_t oldmap1 = 0;
extern char etext;
- void db_write_bytes_user_space();
if ((addr < VM_MIN_KERNEL_ADDRESS) ^
((addr + size) <= VM_MIN_KERNEL_ADDRESS)) {
@@ -415,13 +573,13 @@ db_write_bytes(
void
db_write_bytes_user_space(
vm_offset_t addr,
- register int size,
- register char *data,
+ int size,
+ char *data,
task_t task)
{
- register char *dst;
- register int n;
- unsigned kern_addr;
+ char *dst;
+ int n;
+ vm_offset_t kern_addr;
while (size > 0) {
if (db_user_to_kernel_address(task, addr, &kern_addr, 1) < 0)
@@ -440,10 +598,10 @@ db_write_bytes_user_space(
boolean_t
db_check_access(
vm_offset_t addr,
- register int size,
+ int size,
task_t task)
{
- register n;
+ int n;
vm_offset_t kern_addr;
if (addr >= VM_MIN_KERNEL_ADDRESS) {
@@ -471,7 +629,7 @@ boolean_t
db_phys_eq(
task_t task1,
vm_offset_t addr1,
- task_t task2,
+ const task_t task2,
vm_offset_t addr2)
{
vm_offset_t kern_addr1, kern_addr2;
@@ -494,16 +652,19 @@ db_phys_eq(
#define DB_USER_STACK_ADDR (VM_MIN_KERNEL_ADDRESS)
#define DB_NAME_SEARCH_LIMIT (DB_USER_STACK_ADDR-(INTEL_PGBYTES*3))
+#define GNU
+
+#ifndef GNU
static boolean_t
db_search_null(
- task_t task,
+ const task_t task,
vm_offset_t *svaddr,
vm_offset_t evaddr,
vm_offset_t *skaddr,
int flag)
{
- register unsigned vaddr;
- register unsigned *kaddr;
+ unsigned vaddr;
+ unsigned *kaddr;
kaddr = (unsigned *)*skaddr;
for (vaddr = *svaddr; vaddr > evaddr; ) {
@@ -524,13 +685,12 @@ db_search_null(
}
return FALSE;
}
-
-#define GNU
+#endif /* GNU */
#ifdef GNU
static boolean_t
looks_like_command(
- task_t task,
+ const task_t task,
char* kaddr)
{
char *c;
@@ -570,19 +730,19 @@ looks_like_command(
return TRUE;
}
-#endif
+#endif /* GNU */
void
db_task_name(
- task_t task)
+ const task_t task)
{
- register char *p;
- register int n;
- unsigned vaddr, kaddr;
+ char *p;
+ int n;
+ vm_offset_t vaddr, kaddr;
unsigned sp;
- if (task->map->pmap == kernel_pmap) {
- db_printf(DB_GNUMACH_TASK_NAME);
+ if (task->name[0]) {
+ db_printf("%s", task->name);
return;
}
@@ -613,12 +773,12 @@ db_task_name(
vaddr = (sp & ~(INTEL_PGBYTES - 1)) + INTEL_PGBYTES;
while (1) {
if (db_user_to_kernel_address(task, vaddr, &kaddr, 0) < 0)
- return FALSE;
+ return;
if (looks_like_command(task, (char*) kaddr))
break;
vaddr += INTEL_PGBYTES;
}
-#else
+#else /* GNU */
vaddr = DB_USER_STACK_ADDR;
kaddr = 0;
@@ -636,18 +796,18 @@ db_task_name(
db_printf(DB_NULL_TASK_NAME);
return;
}
-#endif
+#endif /* GNU */
ok:
n = DB_TASK_NAME_LEN-1;
#ifdef GNU
p = (char *)kaddr;
for (; n > 0; vaddr++, p++, n--) {
-#else
+#else /* GNU */
p = (char *)kaddr + sizeof(unsigned);
for (vaddr += sizeof(int); vaddr < DB_USER_STACK_ADDR && n > 0;
vaddr++, p++, n--) {
-#endif
+#endif /* GNU */
if (vaddr % INTEL_PGBYTES == 0) {
(void)db_user_to_kernel_address(task, vaddr, &kaddr, 0);
p = (char*)kaddr;
diff --git a/i386/i386/db_interface.h b/i386/i386/db_interface.h
index 10a02e2b..8d7daeae 100644
--- a/i386/i386/db_interface.h
+++ b/i386/i386/db_interface.h
@@ -24,6 +24,8 @@
#include <sys/types.h>
#include <kern/task.h>
#include <machine/thread.h>
+#include <ddb/db_watch.h>
+#include <ddb/db_variables.h>
extern boolean_t kdb_trap (
int type,
@@ -53,6 +55,12 @@ extern boolean_t db_phys_eq (
task_t task2,
vm_offset_t addr2);
+extern int db_user_to_kernel_address(
+ task_t task,
+ vm_offset_t addr,
+ vm_offset_t *kaddr,
+ int flag);
+
extern void db_task_name (task_t task);
#define I386_DB_TYPE_X 0
@@ -67,9 +75,58 @@ extern void db_task_name (task_t task);
#define I386_DB_LOCAL 1
#define I386_DB_GLOBAL 2
-extern unsigned long dr0 (vm_offset_t linear_addr, int type, int len, int persistence);
-extern unsigned long dr1 (vm_offset_t linear_addr, int type, int len, int persistence);
-extern unsigned long dr2 (vm_offset_t linear_addr, int type, int len, int persistence);
-extern unsigned long dr3 (vm_offset_t linear_addr, int type, int len, int persistence);
+#if MACH_KDB
+extern boolean_t db_set_hw_watchpoint(
+ db_watchpoint_t watch,
+ unsigned num);
+
+extern boolean_t db_clear_hw_watchpoint(
+ unsigned num);
+
+extern void db_dr (
+ int num,
+ vm_offset_t linear_addr,
+ int type,
+ int len,
+ int persistence);
+
+extern void
+db_stack_trace_cmd(
+ db_expr_t addr,
+ boolean_t have_addr,
+ db_expr_t count,
+ const char *modif);
+
+extern void
+db_halt_cpu(void);
+extern void
+db_reset_cpu(void);
+
+void
+db_i386_reg_value(
+ struct db_variable *vp,
+ db_expr_t *valuep,
+ int flag,
+ struct db_var_aux_param *ap);
+
+#endif
+
+extern void db_get_debug_state(
+ pcb_t pcb,
+ struct i386_debug_state *state);
+extern kern_return_t db_set_debug_state(
+ pcb_t pcb,
+ const struct i386_debug_state *state);
+
+extern void db_load_context(pcb_t pcb);
+
+extern void cnpollc(boolean_t on);
+
+void
+db_write_bytes_user_space(
+ vm_offset_t addr,
+ int size,
+ char *data,
+ task_t task);
#endif /* _I386_DB_INTERFACE_H_ */
diff --git a/i386/i386/db_machdep.h b/i386/i386/db_machdep.h
index 1dba2cd8..ae1f9c09 100644
--- a/i386/i386/db_machdep.h
+++ b/i386/i386/db_machdep.h
@@ -34,7 +34,6 @@
#include <mach/machine/vm_types.h>
#include <mach/machine/vm_param.h>
#include <mach/machine/eflags.h>
-#include <machine/db_interface.h>
#include <i386/thread.h> /* for thread_status */
#include <i386/trap.h>
@@ -94,7 +93,6 @@ db_regs_t ddb_regs; /* register state */
#define DB_TASK_NAME_TITLE "COMMAND "
#define DB_TASK_NAME_LEN 23
#define DB_NULL_TASK_NAME "? "
-#define DB_GNUMACH_TASK_NAME "gnumach "
/* macro for checking if a thread has used floating-point */
diff --git a/i386/i386/db_trace.c b/i386/i386/db_trace.c
index 4e3bea39..ec338591 100644
--- a/i386/i386/db_trace.c
+++ b/i386/i386/db_trace.c
@@ -35,6 +35,8 @@
#include <machine/db_machdep.h>
#include <machine/machspl.h>
+#include <machine/db_interface.h>
+#include <machine/db_trace.h>
#include <ddb/db_access.h>
#include <ddb/db_command.h>
@@ -45,13 +47,6 @@
#include "trap.h"
-long
-db_i386_reg_value(
- struct db_variable *vp,
- db_expr_t *valuep,
- int flag,
- struct db_var_aux_param *ap); /* forward */
-
/*
* Machine register set.
*/
@@ -112,10 +107,10 @@ struct i386_kregs {
long *
db_lookup_i386_kreg(
- char *name,
- int *kregp)
+ const char *name,
+ const long *kregp)
{
- register struct i386_kregs *kp;
+ struct i386_kregs *kp;
for (kp = i386_kregs; kp->name; kp++) {
if (strcmp(name, kp->name) == 0)
@@ -124,7 +119,7 @@ db_lookup_i386_kreg(
return 0;
}
-long
+void
db_i386_reg_value(
struct db_variable *vp,
db_expr_t *valuep,
@@ -133,7 +128,7 @@ db_i386_reg_value(
{
long *dp = 0;
db_expr_t null_reg = 0;
- register thread_t thread = ap->thread;
+ thread_t thread = ap->thread;
extern unsigned int_stack_high;
if (db_option(ap->modif, 'u')) {
@@ -205,7 +200,7 @@ db_find_trace_symbols(void)
/*
* Figure out how many arguments were passed into the frame at "fp".
*/
-int db_numargs_default = 5;
+const int db_numargs_default = 5;
int
db_numargs(
@@ -264,7 +259,7 @@ db_nextframe(
struct i386_frame **fp, /* in/out */
db_addr_t *ip, /* out */
long frame_type, /* in */
- thread_t thread) /* in */
+ const thread_t thread) /* in */
{
struct i386_saved_state *saved_regs;
struct interrupt_frame *ifp;
@@ -318,14 +313,6 @@ db_nextframe(
}
}
-void
-db_i386_stack_trace(
- thread_t th,
- struct i386_frame *frame,
- db_addr_t callpc,
- db_expr_t count,
- int flags); /* forward */
-
#define F_USER_TRACE 1
#define F_TRACE_THREAD 2
@@ -334,7 +321,7 @@ db_stack_trace_cmd(
db_expr_t addr,
boolean_t have_addr,
db_expr_t count,
- char *modif)
+ const char *modif)
{
boolean_t trace_thread = FALSE;
struct i386_frame *frame;
@@ -343,8 +330,8 @@ db_stack_trace_cmd(
thread_t th;
{
- register char *cp = modif;
- register char c;
+ const char *cp = modif;
+ char c;
while ((c = *cp++) != 0) {
if (c == 't')
@@ -361,7 +348,7 @@ db_stack_trace_cmd(
} else if (trace_thread) {
if (have_addr) {
th = (thread_t) addr;
- if (!db_check_thread_address_valid((db_addr_t)th))
+ if (!db_check_thread_address_valid(th))
return;
} else {
th = db_default_thread;
@@ -381,10 +368,10 @@ db_stack_trace_cmd(
return;
}
if ((th->state & TH_SWAPPED) || th->kernel_stack == 0) {
- register struct i386_saved_state *iss = &th->pcb->iss;
+ struct i386_saved_state *iss = &th->pcb->iss;
db_printf("Continuation ");
- db_task_printsym((db_expr_t)th->swap_func,
+ db_task_printsym((db_addr_t)th->swap_func,
DB_STGY_PROC,
th->task);
db_printf("\n");
@@ -392,7 +379,7 @@ db_stack_trace_cmd(
frame = (struct i386_frame *) (iss->ebp);
callpc = (db_addr_t) (iss->eip);
} else {
- register struct i386_kernel_state *iks;
+ struct i386_kernel_state *iks;
iks = STACK_IKS(th->kernel_stack);
frame = (struct i386_frame *) (iks->k_ebp);
callpc = (db_addr_t) (iks->k_eip);
@@ -412,7 +399,7 @@ db_stack_trace_cmd(
void
db_i386_stack_trace(
- thread_t th,
+ const thread_t th,
struct i386_frame *frame,
db_addr_t callpc,
db_expr_t count,
@@ -438,18 +425,18 @@ db_i386_stack_trace(
if (!db_trace_symbols_found)
db_find_trace_symbols();
- if (!INKERNEL((unsigned long)callpc) && !INKERNEL((unsigned long)frame)) {
+ if (!INKERNEL(callpc) && !INKERNEL(frame)) {
db_printf(">>>>> user space <<<<<\n");
user_frame++;
}
lastframe = 0;
while (count-- && frame != 0) {
- register int narg;
+ int narg;
char * name;
db_expr_t offset;
- if (INKERNEL((unsigned long)callpc) && user_frame == 0) {
+ if (INKERNEL(callpc) && user_frame == 0) {
db_addr_t call_func = 0;
db_sym_t sym_tmp;
@@ -474,7 +461,7 @@ db_i386_stack_trace(
frame_type = 0;
narg = db_numargs(frame, task);
}
- } else if (INKERNEL((unsigned long)callpc) ^ INKERNEL((unsigned long)frame)) {
+ } else if (INKERNEL(callpc) ^ INKERNEL(frame)) {
frame_type = 0;
narg = -1;
} else {
@@ -501,7 +488,7 @@ db_i386_stack_trace(
db_printf("...");
db_printf(")");
if (offset) {
- db_printf("+%x", offset);
+ db_printf("+0x%x", offset);
}
if (db_line_at_pc(0, &filename, &linenum, callpc)) {
db_printf(" [%s", filename);
@@ -519,7 +506,7 @@ db_i386_stack_trace(
break;
}
if (!INKERNEL(lastframe) ||
- (!INKERNEL((unsigned long)callpc) && !INKERNEL((unsigned long)frame)))
+ (!INKERNEL(callpc) && !INKERNEL(frame)))
user_frame++;
if (user_frame == 1) {
db_printf(">>>>> user space <<<<<\n");
@@ -546,6 +533,8 @@ db_find_kthread(
task_t task)
{
thread_t thread;
+ if (task == TASK_NULL)
+ task = db_current_task();
queue_iterate(&task->thread_list, thread, thread_t, thread_list) {
vm_offset_t usp = thread->pcb->iss.uesp/*ebp works*/;
@@ -571,18 +560,18 @@ static void db_cproc_state(
/* offsets in a cproc structure */
/* TODO: longs? */
-int db_cproc_next_offset = 0 * 4;
-int db_cproc_incarnation_offset = 1 * 4;
-int db_cproc_list_offset = 2 * 4;
-int db_cproc_wait_offset = 3 * 4;
-int db_cproc_context_offset = 5 * 4;
-int db_cproc_state_offset = 7 * 4;
-int db_cproc_stack_base_offset = 10 * 4 + sizeof(mach_msg_header_t);
-int db_cproc_stack_size_offset = 11 * 4 + sizeof(mach_msg_header_t);
+const int db_cproc_next_offset = 0 * 4;
+const int db_cproc_incarnation_offset = 1 * 4;
+const int db_cproc_list_offset = 2 * 4;
+const int db_cproc_wait_offset = 3 * 4;
+const int db_cproc_context_offset = 5 * 4;
+const int db_cproc_state_offset = 7 * 4;
+const int db_cproc_stack_base_offset = 10 * 4 + sizeof(mach_msg_header_t);
+const int db_cproc_stack_size_offset = 11 * 4 + sizeof(mach_msg_header_t);
/* offsets in a cproc_switch context structure */
-int db_cprocsw_framep_offset = 3 * 4;
-int db_cprocsw_pc_offset = 4 * 4;
+const int db_cprocsw_framep_offset = 3 * 4;
+const int db_cprocsw_pc_offset = 4 * 4;
#include <machine/setjmp.h>
@@ -646,7 +635,7 @@ void db_trace_cproc(
}
void db_all_cprocs(
- task_t task,
+ const task_t task,
db_expr_t cproc_list)
{
jmp_buf_t db_jmpbuf;
diff --git a/i386/i386/db_trace.h b/i386/i386/db_trace.h
new file mode 100644
index 00000000..604654c5
--- /dev/null
+++ b/i386/i386/db_trace.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _I386_DB_TRACE_H_
+#define _I386_DB_TRACE_H_
+
+struct i386_frame;
+
+void
+db_i386_stack_trace(
+ thread_t th,
+ struct i386_frame *frame,
+ db_addr_t callpc,
+ db_expr_t count,
+ int flags);
+
+#endif /* _I386_DB_TRACE_H_ */
diff --git a/i386/i386/debug.h b/i386/i386/debug.h
index f87b95bb..e94649bb 100644
--- a/i386/i386/debug.h
+++ b/i386/i386/debug.h
@@ -26,7 +26,7 @@
/* Dump a saved state.
Probably a good idea to have this around
even when DEBUG isn't turned on. */
-void dump_ss(struct i386_saved_state *st);
+void dump_ss(const struct i386_saved_state *st);
#ifdef DEBUG
diff --git a/i386/i386/debug_i386.c b/i386/i386/debug_i386.c
index 937d7b4b..76578081 100644
--- a/i386/i386/debug_i386.c
+++ b/i386/i386/debug_i386.c
@@ -27,7 +27,7 @@
#include "trap.h"
#include "debug.h"
-void dump_ss(struct i386_saved_state *st)
+void dump_ss(const struct i386_saved_state *st)
{
printf("Dump of i386_saved_state %p:\n", st);
printf("EAX %08lx EBX %08lx ECX %08lx EDX %08lx\n",
@@ -59,9 +59,8 @@ struct debug_trace_entry
struct debug_trace_entry debug_trace_buf[DEBUG_TRACE_LEN];
int debug_trace_pos;
-
void
-debug_trace_reset()
+debug_trace_reset(void)
{
int s = splhigh();
debug_trace_pos = 0;
@@ -89,7 +88,7 @@ print_entry(int i, int *col)
}
void
-debug_trace_dump()
+debug_trace_dump(void)
{
int s = splhigh();
int i;
diff --git a/i386/i386/fpu.c b/i386/i386/fpu.c
index 8efe9e80..0f34833e 100644
--- a/i386/i386/fpu.c
+++ b/i386/i386/fpu.c
@@ -53,6 +53,7 @@
#include <i386/pio.h>
#include <i386/pic.h>
#include <i386/locore.h>
+#include <i386/trap.h>
#include "cpu_number.h"
#if 0
@@ -68,15 +69,10 @@
#define ASSERT_IPL(L)
#endif
-extern void i386_exception();
-
int fp_kind = FP_387; /* 80387 present */
struct kmem_cache ifps_cache; /* cache for FPU save area */
static unsigned long mxcsr_feature_mask = 0xffffffff; /* Always AND user-provided mxcsr with this security mask */
-void fp_save(thread_t thread);
-void fp_load(thread_t thread);
-
#if NCPUS == 1
volatile thread_t fp_thread = THREAD_NULL;
/* thread whose state is in FPU */
@@ -105,7 +101,7 @@ volatile thread_t fp_intr_thread = THREAD_NULL;
* Called on each CPU.
*/
void
-init_fpu()
+init_fpu(void)
{
unsigned short status, control;
@@ -158,7 +154,6 @@ init_fpu()
unsigned long mask;
fp_kind = FP_387X;
#ifndef MACH_RING1
- printf("Enabling FXSR\n");
set_cr4(get_cr4() | CR4_OSFXSR);
#endif /* MACH_RING1 */
fxsave(&save);
@@ -190,7 +185,7 @@ init_fpu()
* Initialize FP handling.
*/
void
-fpu_module_init()
+fpu_module_init(void)
{
kmem_cache_init(&ifps_cache, "i386_fpsave_state",
sizeof(struct i386_fpsave_state), 16,
@@ -202,8 +197,7 @@ fpu_module_init()
* Called only when thread terminating - no locking necessary.
*/
void
-fp_free(fps)
- struct i386_fpsave_state *fps;
+fp_free(struct i386_fpsave_state *fps)
{
ASSERT_IPL(SPL0);
#if NCPUS == 1
@@ -297,12 +291,12 @@ twd_fxsr_to_i387 (struct i386_xfp_save *fxsave)
*/
kern_return_t
fpu_set_state(thread, state)
- thread_t thread;
+ const thread_t thread;
struct i386_float_state *state;
{
- register pcb_t pcb = thread->pcb;
- register struct i386_fpsave_state *ifps;
- register struct i386_fpsave_state *new_ifps;
+ pcb_t pcb = thread->pcb;
+ struct i386_fpsave_state *ifps;
+ struct i386_fpsave_state *new_ifps;
ASSERT_IPL(SPL0);
if (fp_kind == FP_NO)
@@ -340,8 +334,8 @@ ASSERT_IPL(SPL0);
/*
* Valid state. Allocate the fp state if there is none.
*/
- register struct i386_fp_save *user_fp_state;
- register struct i386_fp_regs *user_fp_regs;
+ struct i386_fp_save *user_fp_state;
+ struct i386_fp_regs *user_fp_regs;
user_fp_state = (struct i386_fp_save *) &state->hw_state[0];
user_fp_regs = (struct i386_fp_regs *)
@@ -379,7 +373,7 @@ ASSERT_IPL(SPL0);
ifps->xfp_save_state.fp_dp = user_fp_state->fp_dp;
ifps->xfp_save_state.fp_ds = user_fp_state->fp_ds;
for (i=0; i<8; i++)
- memcpy(&ifps->xfp_save_state.fp_reg_word[i], &user_fp_regs[i], sizeof(user_fp_regs[i]));
+ memcpy(&ifps->xfp_save_state.fp_reg_word[i], &user_fp_regs->fp_reg_word[i], sizeof(user_fp_regs->fp_reg_word[i]));
} else {
ifps->fp_save_state.fp_control = user_fp_state->fp_control;
ifps->fp_save_state.fp_status = user_fp_state->fp_status;
@@ -408,11 +402,11 @@ ASSERT_IPL(SPL0);
*/
kern_return_t
fpu_get_state(thread, state)
- thread_t thread;
- register struct i386_float_state *state;
+ const thread_t thread;
+ struct i386_float_state *state;
{
- register pcb_t pcb = thread->pcb;
- register struct i386_fpsave_state *ifps;
+ pcb_t pcb = thread->pcb;
+ struct i386_fpsave_state *ifps;
ASSERT_IPL(SPL0);
if (fp_kind == FP_NO)
@@ -446,8 +440,8 @@ ASSERT_IPL(SPL0);
state->exc_status = 0;
{
- register struct i386_fp_save *user_fp_state;
- register struct i386_fp_regs *user_fp_regs;
+ struct i386_fp_save *user_fp_state;
+ struct i386_fp_regs *user_fp_regs;
state->initialized = ifps->fp_valid;
@@ -472,7 +466,7 @@ ASSERT_IPL(SPL0);
user_fp_state->fp_dp = ifps->xfp_save_state.fp_dp;
user_fp_state->fp_ds = ifps->xfp_save_state.fp_ds;
for (i=0; i<8; i++)
- memcpy(&user_fp_regs[i], &ifps->xfp_save_state.fp_reg_word[i], sizeof(user_fp_regs[i]));
+ memcpy(&user_fp_regs->fp_reg_word[i], &ifps->xfp_save_state.fp_reg_word[i], sizeof(user_fp_regs->fp_reg_word[i]));
} else {
user_fp_state->fp_control = ifps->fp_save_state.fp_control;
user_fp_state->fp_status = ifps->fp_save_state.fp_status;
@@ -500,7 +494,7 @@ ASSERT_IPL(SPL0);
*
* Use 53-bit precision.
*/
-void fpinit()
+void fpinit(void)
{
unsigned short control;
@@ -524,7 +518,7 @@ ASSERT_IPL(SPL0);
* Coprocessor not present.
*/
void
-fpnoextflt()
+fpnoextflt(void)
{
/*
* Enable FPU use.
@@ -568,11 +562,11 @@ ASSERT_IPL(SPL0);
* Re-initialize FPU. Floating point state is not valid.
*/
void
-fpextovrflt()
+fpextovrflt(void)
{
- register thread_t thread = current_thread();
- register pcb_t pcb;
- register struct i386_fpsave_state *ifps;
+ thread_t thread = current_thread();
+ pcb_t pcb;
+ struct i386_fpsave_state *ifps;
#if NCPUS == 1
@@ -617,9 +611,9 @@ fpextovrflt()
}
static int
-fphandleerr()
+fphandleerr(void)
{
- register thread_t thread = current_thread();
+ thread_t thread = current_thread();
/*
* Save the FPU context to the thread using it.
@@ -664,9 +658,9 @@ fphandleerr()
* FPU error. Called by exception handler.
*/
void
-fpexterrflt()
+fpexterrflt(void)
{
- register thread_t thread = current_thread();
+ thread_t thread = current_thread();
if (fphandleerr())
return;
@@ -689,9 +683,9 @@ fpexterrflt()
* FPU error. Called by AST.
*/
void
-fpastintr()
+fpastintr(void)
{
- register thread_t thread = current_thread();
+ thread_t thread = current_thread();
ASSERT_IPL(SPL0);
#if NCPUS == 1
@@ -752,11 +746,10 @@ ASSERT_IPL(SPL0);
* . otherwise, thread is running.
*/
void
-fp_save(thread)
- register thread_t thread;
+fp_save(thread_t thread)
{
- register pcb_t pcb = thread->pcb;
- register struct i386_fpsave_state *ifps = pcb->ims.ifps;
+ pcb_t pcb = thread->pcb;
+ struct i386_fpsave_state *ifps = pcb->ims.ifps;
if (ifps != 0 && !ifps->fp_valid) {
/* registers are in FPU */
@@ -774,11 +767,10 @@ fp_save(thread)
* Locking not needed; always called on the current thread.
*/
void
-fp_load(thread)
- register thread_t thread;
+fp_load(thread_t thread)
{
- register pcb_t pcb = thread->pcb;
- register struct i386_fpsave_state *ifps;
+ pcb_t pcb = thread->pcb;
+ struct i386_fpsave_state *ifps;
ASSERT_IPL(SPL0);
ifps = pcb->ims.ifps;
@@ -829,7 +821,7 @@ ASSERT_IPL(SPL0);
* Locking not needed; always called on the current thread.
*/
void
-fp_state_alloc()
+fp_state_alloc(void)
{
pcb_t pcb = current_thread()->pcb;
struct i386_fpsave_state *ifps;
diff --git a/i386/i386/fpu.h b/i386/i386/fpu.h
index 21561875..7bc64388 100644
--- a/i386/i386/fpu.h
+++ b/i386/i386/fpu.h
@@ -87,7 +87,7 @@
#if NCPUS > 1
#define fpu_save_context(thread) \
{ \
- register struct i386_fpsave_state *ifps; \
+ struct i386_fpsave_state *ifps; \
ifps = (thread)->pcb->ims.ifps; \
if (ifps != 0 && !ifps->fp_valid) { \
/* registers are in FPU - save to memory */ \
diff --git a/i386/i386/gdt.c b/i386/i386/gdt.c
index 5523fea3..c895eb3a 100644
--- a/i386/i386/gdt.c
+++ b/i386/i386/gdt.c
@@ -46,7 +46,7 @@ extern
struct real_descriptor gdt[GDTSZ];
void
-gdt_init()
+gdt_init(void)
{
/* Initialize the kernel code and data segment descriptors. */
fill_gdt_descriptor(KERNEL_CS,
diff --git a/i386/i386/hardclock.c b/i386/i386/hardclock.c
index 66150332..49ea82cd 100644
--- a/i386/i386/hardclock.c
+++ b/i386/i386/hardclock.c
@@ -47,10 +47,10 @@ extern char return_to_iret[];
void
hardclock(iunit, old_ipl, irq, ret_addr, regs)
- int iunit; /* 'unit' number */
- int old_ipl; /* old interrupt level */
- int irq; /* irq number */
- char * ret_addr; /* return address in interrupt handler */
+ int iunit; /* 'unit' number */
+ int old_ipl; /* old interrupt level */
+ int irq; /* irq number */
+ const char * ret_addr; /* return address in interrupt handler */
struct i386_interrupt_state *regs;
/* saved registers */
{
@@ -77,5 +77,5 @@ hardclock(iunit, old_ipl, irq, ret_addr, regs)
#ifdef LINUX_DEV
linux_timer_intr();
-#endif
+#endif /* LINUX_DEV */
}
diff --git a/i386/i386/hardclock.h b/i386/i386/hardclock.h
new file mode 100644
index 00000000..38c51ea6
--- /dev/null
+++ b/i386/i386/hardclock.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _I386_HARDCLOCK_H_
+#define _I386_HARDCLOCK_H_
+
+void hardclock(
+ int iunit,
+ int old_ipl,
+ int irq,
+ char *ret_addr,
+ struct i386_interrupt_state *regs);
+
+#endif /* _I386_HARDCLOCK_H_ */
diff --git a/i386/i386/idt.c b/i386/i386/idt.c
index 882764f4..d304ec3e 100644
--- a/i386/i386/idt.c
+++ b/i386/i386/idt.c
@@ -36,7 +36,7 @@ struct idt_init_entry
};
extern struct idt_init_entry idt_inittab[];
-void idt_init()
+void idt_init(void)
{
#ifdef MACH_PV_DESCRIPTORS
if (hyp_set_trap_table(kvtolin(idt_inittab)))
diff --git a/i386/i386/io_map.c b/i386/i386/io_map.c
index b095f224..2c2aa720 100644
--- a/i386/i386/io_map.c
+++ b/i386/i386/io_map.c
@@ -37,9 +37,9 @@ extern vm_offset_t kernel_virtual_start;
* Mach VM is running.
*/
vm_offset_t
-io_map(phys_addr, size)
- vm_offset_t phys_addr;
- vm_size_t size;
+io_map(
+ vm_offset_t phys_addr,
+ vm_size_t size)
{
vm_offset_t start;
@@ -58,3 +58,35 @@ io_map(phys_addr, size)
VM_PROT_READ|VM_PROT_WRITE);
return (start);
}
+
+/*
+ * Allocate and map memory for devices that may need to be mapped before
+ * Mach VM is running.
+ *
+ * This maps the all pages containing [PHYS_ADDR:PHYS_ADDR + SIZE].
+ * For contiguous requests to those pages will reuse the previously
+ * established mapping.
+ *
+ * Warning: this leaks memory maps for now, do not use it yet for something
+ * else than Mach shutdown.
+ */
+vm_offset_t
+io_map_cached(
+ vm_offset_t phys_addr,
+ vm_size_t size)
+{
+ static vm_offset_t base;
+ static vm_size_t length;
+ static vm_offset_t map;
+
+ if (! map
+ || (phys_addr < base)
+ || (base + length < phys_addr + size))
+ {
+ base = trunc_page(phys_addr);
+ length = round_page(phys_addr - base + size);
+ map = io_map(base, length);
+ }
+
+ return map + (phys_addr - base);
+}
diff --git a/i386/i386/io_perm.c b/i386/i386/io_perm.c
index 8bacb8d5..d5c71035 100644
--- a/i386/i386/io_perm.c
+++ b/i386/i386/io_perm.c
@@ -66,6 +66,7 @@
#include "io_perm.h"
#include "gdt.h"
+#include "pcb.h"
/* Our device emulation ops. See below, at the bottom of this file. */
static struct device_emulation_ops io_perm_device_emulation_ops;
@@ -174,7 +175,7 @@ io_bitmap_clear (unsigned char *iopb, io_port_t from, io_port_t to)
The function is exported. */
kern_return_t
-i386_io_perm_create (ipc_port_t master_port, io_port_t from, io_port_t to,
+i386_io_perm_create (const ipc_port_t master_port, io_port_t from, io_port_t to,
io_perm_t *new)
{
if (master_port != master_device_port)
@@ -219,13 +220,8 @@ i386_io_perm_create (ipc_port_t master_port, io_port_t from, io_port_t to,
return KERN_SUCCESS;
}
-
-/* From pcb.c. */
-extern void update_ktss_iopb (unsigned char *new_iopb, int last);
-
-
/* Modify the I/O permissions for TARGET_TASK. If ENABLE is TRUE, the
- permission to acces the I/O ports specified by IO_PERM is granted,
+ permission to access the I/O ports specified by IO_PERM is granted,
otherwise it is withdrawn.
The function returns KERN_INVALID_ARGUMENT if TARGET_TASK is not a valid
diff --git a/i386/i386/io_perm.h b/i386/i386/io_perm.h
index a68e1038..a7f1f6fe 100644
--- a/i386/i386/io_perm.h
+++ b/i386/i386/io_perm.h
@@ -62,4 +62,4 @@ extern ipc_port_t convert_io_perm_to_port (io_perm_t);
extern void io_perm_deallocate (io_perm_t);
#endif
-#endif
+#endif /* _I386_IO_PERM_H_ */
diff --git a/i386/i386/ipl.h b/i386/i386/ipl.h
index 8f729e1d..2da2e89f 100644
--- a/i386/i386/ipl.h
+++ b/i386/i386/ipl.h
@@ -49,6 +49,8 @@ OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifndef _I386_IPL_H_
+#define _I386_IPL_H_
#define SPL0 0
#define SPL1 1
@@ -76,3 +78,5 @@ extern int intpri[];
extern spl_t curr_ipl;
#endif /* __ASSEMBLER__ */
#endif /* KERNEL */
+
+#endif /* _I386_IPL_H_ */
diff --git a/i386/i386/ktss.c b/i386/i386/ktss.c
index 1b2938a0..21d00300 100644
--- a/i386/i386/ktss.c
+++ b/i386/i386/ktss.c
@@ -40,7 +40,7 @@
struct task_tss ktss;
void
-ktss_init()
+ktss_init(void)
{
/* XXX temporary exception stack */
static int exception_stack[1024];
diff --git a/i386/i386/kttd_interface.c b/i386/i386/kttd_interface.c
index b9e0624b..c6caa76d 100644
--- a/i386/i386/kttd_interface.c
+++ b/i386/i386/kttd_interface.c
@@ -240,7 +240,7 @@ boolean_t kttd_mem_access(vm_offset_t offset, vm_prot_t access)
trunc_page(offset), access);
code = vm_fault(kernel_map, trunc_page(offset), access, FALSE,
FALSE, (void (*)()) 0);
- }else{
+ } else {
/*
* Check for user thread
*/
diff --git a/i386/i386/ldt.c b/i386/i386/ldt.c
index 43b9efb5..0250ee26 100644
--- a/i386/i386/ldt.c
+++ b/i386/i386/ldt.c
@@ -36,8 +36,7 @@
#include "seg.h"
#include "gdt.h"
#include "ldt.h"
-
-extern int syscall();
+#include "locore.h"
#ifdef MACH_PV_DESCRIPTORS
/* It is actually defined in xen_boothdr.S */
@@ -46,7 +45,7 @@ extern
struct real_descriptor ldt[LDTSZ];
void
-ldt_init()
+ldt_init(void)
{
#ifdef MACH_PV_DESCRIPTORS
#ifdef MACH_PV_PAGETABLES
diff --git a/i386/i386/lock.h b/i386/i386/lock.h
index 38a66c87..b989927b 100644
--- a/i386/i386/lock.h
+++ b/i386/i386/lock.h
@@ -44,7 +44,7 @@
*/
#define _simple_lock_xchg_(lock, new_val) \
- ({ register int _old_val_; \
+ ({ int _old_val_; \
asm volatile("xchgl %0, %2" \
: "=r" (_old_val_) \
: "0" (new_val), "m" (*(lock) : "memory") \
diff --git a/i386/i386/locore.S b/i386/i386/locore.S
index eeef09d7..a44be04d 100644
--- a/i386/i386/locore.S
+++ b/i386/i386/locore.S
@@ -119,6 +119,7 @@ LEXT(retry_table_end) ;\
* Uses %eax, %ebx, %ecx.
*/
#define TIME_TRAP_UENTRY \
+ pushf /* Save flags */ ;\
cli /* block interrupts */ ;\
movl VA_ETC,%ebx /* get timer value */ ;\
movl CX(EXT(current_tstamp),%edx),%ecx /* get old time stamp */;\
@@ -131,7 +132,7 @@ LEXT(retry_table_end) ;\
0: addl $(TH_SYSTEM_TIMER-TH_USER_TIMER),%ecx ;\
/* switch to sys timer */;\
movl %ecx,CX(EXT(current_timer),%edx) /* make it current */ ;\
- sti /* allow interrupts */
+ popf /* allow interrupts */
/*
* Update time on system call entry.
@@ -141,6 +142,7 @@ LEXT(retry_table_end) ;\
* Same as TIME_TRAP_UENTRY, but preserves %eax.
*/
#define TIME_TRAP_SENTRY \
+ pushf /* Save flags */ ;\
cli /* block interrupts */ ;\
movl VA_ETC,%ebx /* get timer value */ ;\
movl CX(EXT(current_tstamp),%edx),%ecx /* get old time stamp */;\
@@ -155,7 +157,7 @@ LEXT(retry_table_end) ;\
0: addl $(TH_SYSTEM_TIMER-TH_USER_TIMER),%ecx ;\
/* switch to sys timer */;\
movl %ecx,CX(EXT(current_timer),%edx) /* make it current */ ;\
- sti /* allow interrupts */
+ popf /* allow interrupts */
/*
* update time on user trap exit.
@@ -1241,13 +1243,12 @@ ENTRY(discover_x86_cpu_type)
*/
/*
- * Copy from user address space.
+ * Copy from user address space - generic version.
* arg0: user address
* arg1: kernel address
* arg2: byte count
*/
ENTRY(copyin)
-Entry(copyinmsg)
pushl %esi
pushl %edi /* save registers */
@@ -1284,13 +1285,48 @@ copyin_fail:
jmp copyin_ret /* pop frame and return */
/*
- * Copy to user address space.
+ * Copy from user address space - version for copying messages.
+ * arg0: user address
+ * arg1: kernel address
+ * arg2: byte count - must be a multiple of four
+ */
+ENTRY(copyinmsg)
+ pushl %esi
+ pushl %edi /* save registers */
+
+ movl 8+S_ARG0,%esi /* get user start address */
+ movl 8+S_ARG1,%edi /* get kernel destination address */
+ movl 8+S_ARG2,%ecx /* get count */
+
+ movl $USER_DS,%eax /* use user data segment for accesses */
+ mov %ax,%ds
+
+ /*cld*/ /* count up: default mode in all GCC code */
+ shrl $2,%ecx
+ RECOVER(copyinmsg_fail)
+ rep
+ movsl /* move longwords */
+ xorl %eax,%eax /* return 0 for success */
+
+copyinmsg_ret:
+ mov %ss,%di /* restore DS to kernel segment */
+ mov %di,%ds
+
+ popl %edi /* restore registers */
+ popl %esi
+ ret /* and return */
+
+copyinmsg_fail:
+ movl $1,%eax /* return 1 for failure */
+ jmp copyinmsg_ret /* pop frame and return */
+
+/*
+ * Copy to user address space - generic version.
* arg0: kernel address
* arg1: user address
* arg2: byte count
*/
ENTRY(copyout)
-Entry(copyoutmsg)
pushl %esi
pushl %edi /* save registers */
@@ -1306,14 +1342,13 @@ Entry(copyoutmsg)
jbe copyout_retry /* Use slow version on i386 */
#endif /* !defined(MACH_HYP) && !PAE */
- movl %edx,%eax /* use count */
/*cld*/ /* count up: always this way in GCC code */
- movl %eax,%ecx /* move by longwords first */
+ movl %edx,%ecx /* move by longwords first */
shrl $2,%ecx
RECOVER(copyout_fail)
rep
movsl
- movl %eax,%ecx /* now move remaining bytes */
+ movl %edx,%ecx /* now move remaining bytes */
andl $3,%ecx
RECOVER(copyout_fail)
rep
@@ -1332,6 +1367,47 @@ copyout_fail:
movl $1,%eax /* return 1 for failure */
jmp copyout_ret /* pop frame and return */
+/*
+ * Copy to user address space - version for copying messages.
+ * arg0: kernel address
+ * arg1: user address
+ * arg2: byte count - must be a multiple of four
+ */
+ENTRY(copyoutmsg)
+ pushl %esi
+ pushl %edi /* save registers */
+
+ movl 8+S_ARG0,%esi /* get kernel start address */
+ movl 8+S_ARG1,%edi /* get user start address */
+ movl 8+S_ARG2,%ecx /* get count */
+
+ movl $USER_DS,%eax /* use user data segment for accesses */
+ mov %ax,%es
+
+#if !defined(MACH_HYP) && !PAE
+ movl 8+S_ARG2,%edx /* copyout_retry expects count here */
+ cmpl $3,machine_slot+SUB_TYPE_CPU_TYPE
+ jbe copyout_retry /* Use slow version on i386 */
+#endif /* !defined(MACH_HYP) && !PAE */
+
+ shrl $2,%ecx /* move by longwords */
+ RECOVER(copyoutmsg_fail)
+ rep
+ movsl
+ xorl %eax,%eax /* return 0 for success */
+
+copyoutmsg_ret:
+ mov %ss,%di /* restore ES to kernel segment */
+ mov %di,%es
+
+ popl %edi /* restore registers */
+ popl %esi
+ ret /* and return */
+
+copyoutmsg_fail:
+ movl $1,%eax /* return 1 for failure */
+ jmp copyoutmsg_ret /* pop frame and return */
+
#if !defined(MACH_HYP) && !PAE
/*
* Check whether user address space is writable
@@ -1422,128 +1498,6 @@ _inst_fetch_fault:
-ENTRY(dr6)
-#ifdef MACH_RING1
- pushl %ebx
- movl $6, %ebx
- call __hyp_get_debugreg
- popl %ebx
-#else /* MACH_RING1 */
- movl %db6, %eax
-#endif /* MACH_RING1 */
- ret
-
-/* dr<i>(address, type, len, persistence)
- */
-ENTRY(dr0)
- movl S_ARG0, %eax
- movl %eax,EXT(dr_addr)
-#ifdef MACH_RING1
- pushl %ebx
- movl $0,%ebx
- movl %eax,%ecx
- call __hyp_set_debugreg
-#else /* MACH_RING1 */
- movl %eax, %db0
-#endif /* MACH_RING1 */
- movl $0, %ecx
- jmp 0f
-ENTRY(dr1)
- movl S_ARG0, %eax
- movl %eax,EXT(dr_addr)+1*4
-#ifdef MACH_RING1
- pushl %ebx
- movl $1,%ebx
- movl %eax,%ecx
- call __hyp_set_debugreg
-#else /* MACH_RING1 */
- movl %eax, %db1
-#endif /* MACH_RING1 */
- movl $2, %ecx
- jmp 0f
-ENTRY(dr2)
- movl S_ARG0, %eax
- movl %eax,EXT(dr_addr)+2*4
-#ifdef MACH_RING1
- pushl %ebx
- movl $2,%ebx
- movl %eax,%ecx
- call __hyp_set_debugreg
-#else /* MACH_RING1 */
- movl %eax, %db2
-#endif /* MACH_RING1 */
- movl $4, %ecx
- jmp 0f
-
-ENTRY(dr3)
- movl S_ARG0, %eax
- movl %eax,EXT(dr_addr)+3*4
-#ifdef MACH_RING1
- pushl %ebx
- movl $3,%ebx
- movl %eax,%ecx
- call __hyp_set_debugreg
-#else /* MACH_RING1 */
- movl %eax, %db3
-#endif /* MACH_RING1 */
- movl $6, %ecx
-
-0:
- pushl %ebp
- movl %esp, %ebp
-
-#ifdef MACH_RING1
- movl $7,%ebx
- call __hyp_get_debugreg
- movl %eax, %edx
-#else /* MACH_RING1 */
- movl %db7, %edx
-#endif /* MACH_RING1 */
- movl %edx,EXT(dr_addr)+4*4
- andl dr_msk(,%ecx,2),%edx /* clear out new entry */
- movl %edx,EXT(dr_addr)+5*4
- movzbl B_ARG3, %eax
- andb $3, %al
- shll %cl, %eax
- orl %eax, %edx
-
- movzbl B_ARG1, %eax
- andb $3, %al
- addb %cl, %cl
- addb $0x10, %cl
- shll %cl, %eax
- orl %eax, %edx
-
- movzbl B_ARG2, %eax
- andb $3, %al
- addb $0x2, %cl
- shll %cl, %eax
- orl %eax, %edx
-
-#ifdef MACH_RING1
- movl $7,%ebx
- movl %edx, %ecx
- call __hyp_set_debugreg
- popl %ebx
-#else /* MACH_RING1 */
- movl %edx, %db7
-#endif /* MACH_RING1 */
- movl %edx,EXT(dr_addr)+7*4
- movl %edx, %eax
- leave
- ret
-
- .data
-dr_msk:
- .long ~0x000f0003
- .long ~0x00f0000c
- .long ~0x0f000030
- .long ~0xf00000c0
-ENTRY(dr_addr)
- .long 0,0,0,0
- .long 0,0,0,0
- .text
-
/*
* cpu_shutdown()
* Force reboot
diff --git a/i386/i386/locore.h b/i386/i386/locore.h
index bfd13177..6948f72d 100644
--- a/i386/i386/locore.h
+++ b/i386/i386/locore.h
@@ -56,6 +56,8 @@ extern int inst_fetch (int eip, int cs);
extern void cpu_shutdown (void);
+extern int syscall (void);
+
extern unsigned int cpu_features[1];
#define CPU_FEATURE_FPU 0
diff --git a/i386/i386/loose_ends.c b/i386/i386/loose_ends.c
index d3108fdb..64b53b71 100644
--- a/i386/i386/loose_ends.c
+++ b/i386/i386/loose_ends.c
@@ -30,20 +30,18 @@
#define MACH_ASSERT 1
#else
#define MACH_ASSERT 0
-#endif
+#endif /* NDEBUG */
/*
* For now we will always go to single user mode, since there is
* no way pass this request through the boot.
*/
-int boothowto = 0;
/* Someone with time should write code to set cpuspeed automagically */
int cpuspeed = 4;
#define DELAY(n) { volatile int N = cpuspeed * (n); while (--N > 0); }
void
-delay(n)
- int n;
+delay(int n)
{
DELAY(n);
}
@@ -55,8 +53,8 @@ delay(n)
* levels of return pc information.
*/
void machine_callstack(
- unsigned long *buf,
- int callstack_max)
+ const unsigned long *buf,
+ int callstack_max)
{
}
diff --git a/i386/i386/machine_routines.h b/i386/i386/machine_routines.h
index a1fb489e..d9dd94be 100644
--- a/i386/i386/machine_routines.h
+++ b/i386/i386/machine_routines.h
@@ -31,7 +31,8 @@
* The i386 has a set of machine-dependent interfaces.
*/
#define MACHINE_SERVER mach_i386_server
+#define MACHINE_SERVER_HEADER "i386/i386/mach_i386.server.h"
#define MACHINE_SERVER_ROUTINE mach_i386_server_routine
-#endif
+#endif /* _I386_MACHINE_ROUTINES_H_ */
diff --git a/i386/i386/machine_task.c b/i386/i386/machine_task.c
index 62b22e3a..490b1022 100644
--- a/i386/i386/machine_task.c
+++ b/i386/i386/machine_task.c
@@ -55,7 +55,7 @@ machine_task_init (task_t task)
/* Destroy the machine specific part of task TASK and release all
associated resources. */
void
-machine_task_terminate (task_t task)
+machine_task_terminate (const task_t task)
{
if (task->machine.iopb)
kmem_cache_free (&machine_task_iopb_cache,
diff --git a/i386/i386/model_dep.h b/i386/i386/model_dep.h
index a41c474d..ab2738f8 100644
--- a/i386/i386/model_dep.h
+++ b/i386/i386/model_dep.h
@@ -36,6 +36,10 @@ extern void machine_init (void);
/* Conserve power on processor CPU. */
extern void machine_idle (int cpu);
+extern void resettodr (void);
+
+extern void startrtclock (void);
+
/*
* Halt a cpu.
*/
@@ -46,10 +50,6 @@ extern void halt_cpu (void) __attribute__ ((noreturn));
*/
extern void halt_all_cpus (boolean_t reboot) __attribute__ ((noreturn));
-extern void resettodr (void);
-
-extern void startrtclock (void);
-
/*
* More-specific code provides these;
* they indicate the total extent of physical memory
diff --git a/i386/i386/mp_desc.c b/i386/i386/mp_desc.c
index 95f55af2..6aa8e664 100644
--- a/i386/i386/mp_desc.c
+++ b/i386/i386/mp_desc.c
@@ -65,12 +65,6 @@ char intstack[]; /* bottom */
char eintstack[]; /* top */
/*
- * We allocate interrupt stacks from physical memory.
- */
-extern
-vm_offset_t avail_start;
-
-/*
* Multiprocessor i386/i486 systems use a separate copy of the
* GDT, IDT, LDT, and kernel TSS per processor. The first three
* are separate to avoid lock contention: the i386 uses locked
@@ -106,10 +100,9 @@ extern struct real_descriptor ldt[LDTSZ];
*/
struct mp_desc_table *
-mp_desc_init(mycpu)
- register int mycpu;
+mp_desc_init(int mycpu)
{
- register struct mp_desc_table *mpt;
+ struct mp_desc_table *mpt;
if (mycpu == master_cpu) {
/*
@@ -177,9 +170,9 @@ mp_desc_init(mycpu)
* is running. The machine array must show which CPUs exist.
*/
void
-interrupt_stack_alloc()
+interrupt_stack_alloc(void)
{
- register int i;
+ int i;
int cpu_count;
vm_offset_t stack_start;
@@ -244,7 +237,7 @@ simple_lock_pause(void)
}
kern_return_t
-cpu_control(int cpu, int *info, unsigned int count)
+cpu_control(int cpu, const int *info, unsigned int count)
{
printf("cpu_control(%d, %p, %d) not implemented\n",
cpu, info, count);
diff --git a/i386/i386/mp_desc.h b/i386/i386/mp_desc.h
index 03d7194d..9f963123 100644
--- a/i386/i386/mp_desc.h
+++ b/i386/i386/mp_desc.h
@@ -79,4 +79,6 @@ extern struct mp_desc_table * mp_desc_init(int);
#endif /* MULTIPROCESSOR */
+extern void start_other_cpus(void);
+
#endif /* _I386_MP_DESC_H_ */
diff --git a/i386/i386/pcb.c b/i386/i386/pcb.c
index 7d632a6b..3a0eba0f 100644
--- a/i386/i386/pcb.c
+++ b/i386/i386/pcb.c
@@ -46,6 +46,7 @@
#include <i386/proc_reg.h>
#include <i386/seg.h>
#include <i386/user_ldt.h>
+#include <i386/db_interface.h>
#include <i386/fpu.h>
#include "eflags.h"
#include "gdt.h"
@@ -59,12 +60,6 @@
#include <i386/mp_desc.h>
#endif
-extern thread_t Load_context();
-extern thread_t Switch_context();
-extern void Thread_continue();
-
-extern void user_ldt_free();
-
struct kmem_cache pcb_cache;
vm_offset_t kernel_stack[NCPUS]; /* top of active_stack */
@@ -75,10 +70,10 @@ vm_offset_t kernel_stack[NCPUS]; /* top of active_stack */
* Attach a kernel stack to a thread.
*/
-void stack_attach(thread, stack, continuation)
- register thread_t thread;
- register vm_offset_t stack;
- void (*continuation)(thread_t);
+void stack_attach(
+ thread_t thread,
+ vm_offset_t stack,
+ void (*continuation)(thread_t))
{
counter(if (++c_stacks_current > c_stacks_max)
c_stacks_max = c_stacks_current);
@@ -101,7 +96,7 @@ void stack_attach(thread, stack, continuation)
/*
* Point top of kernel stack to user`s registers.
*/
- STACK_IEL(stack)->saved_state = &thread->pcb->iss;
+ STACK_IEL(stack)->saved_state = USER_REGS(thread);
}
/*
@@ -110,10 +105,9 @@ void stack_attach(thread, stack, continuation)
* Detaches a kernel stack from a thread, returning the old stack.
*/
-vm_offset_t stack_detach(thread)
- register thread_t thread;
+vm_offset_t stack_detach(thread_t thread)
{
- register vm_offset_t stack;
+ vm_offset_t stack;
counter(if (--c_stacks_current < c_stacks_min)
c_stacks_min = c_stacks_current);
@@ -135,8 +129,7 @@ vm_offset_t stack_detach(thread)
#define gdt_desc_p(mycpu,sel) \
((struct real_descriptor *)&curr_gdt(mycpu)[sel_idx(sel)])
-void switch_ktss(pcb)
- register pcb_t pcb;
+void switch_ktss(pcb_t pcb)
{
int mycpu = cpu_number();
{
@@ -165,7 +158,7 @@ void switch_ktss(pcb)
}
{
- register user_ldt_t tldt = pcb->ims.ldt;
+ user_ldt_t tldt = pcb->ims.ldt;
/*
* Set the thread`s LDT.
*/
@@ -200,8 +193,14 @@ void switch_ktss(pcb)
for (i=0; i < USER_GDT_SLOTS; i++) {
if (memcmp(gdt_desc_p (mycpu, USER_GDT + (i << 3)),
&pcb->ims.user_gdt[i], sizeof pcb->ims.user_gdt[i])) {
+ union {
+ struct real_descriptor real_descriptor;
+ uint64_t descriptor;
+ } user_gdt;
+ user_gdt.real_descriptor = pcb->ims.user_gdt[i];
+
if (hyp_do_update_descriptor(kv_to_ma(gdt_desc_p (mycpu, USER_GDT + (i << 3))),
- *(uint64_t *) &pcb->ims.user_gdt[i]))
+ user_gdt.descriptor))
panic("couldn't set user gdt %d\n",i);
}
}
@@ -215,6 +214,8 @@ void switch_ktss(pcb)
pcb->ims.user_gdt, sizeof pcb->ims.user_gdt);
#endif /* MACH_PV_DESCRIPTORS */
+ db_load_context(pcb);
+
/*
* Load the floating-point context, if necessary.
*/
@@ -246,12 +247,12 @@ update_ktss_iopb (unsigned char *new_iopb, io_port_t size)
* Move the current thread's kernel stack to the new thread.
*/
-void stack_handoff(old, new)
- register thread_t old;
- register thread_t new;
+void stack_handoff(
+ thread_t old,
+ thread_t new)
{
- register int mycpu = cpu_number();
- register vm_offset_t stack;
+ int mycpu = cpu_number();
+ vm_offset_t stack;
/*
* Save FP registers if in use.
@@ -303,15 +304,14 @@ void stack_handoff(old, new)
* user registers.
*/
- STACK_IEL(stack)->saved_state = &new->pcb->iss;
+ STACK_IEL(stack)->saved_state = USER_REGS(new);
}
/*
* Switch to the first thread on a CPU.
*/
-void load_context(new)
- register thread_t new;
+void load_context(thread_t new)
{
switch_ktss(new->pcb);
Load_context(new);
@@ -322,10 +322,10 @@ void load_context(new)
* Save the old thread`s kernel state or continuation,
* and return it.
*/
-thread_t switch_context(old, continuation, new)
- register thread_t old;
- void (*continuation)();
- register thread_t new;
+thread_t switch_context(
+ thread_t old,
+ void (*continuation)(),
+ thread_t new)
{
/*
* Save FP registers if in use.
@@ -368,7 +368,7 @@ thread_t switch_context(old, continuation, new)
return Switch_context(old, continuation, new);
}
-void pcb_module_init()
+void pcb_module_init(void)
{
kmem_cache_init(&pcb_cache, "pcb", sizeof(struct pcb), 0,
NULL, NULL, NULL, 0);
@@ -376,10 +376,9 @@ void pcb_module_init()
fpu_module_init();
}
-void pcb_init(thread)
- register thread_t thread;
+void pcb_init(thread_t thread)
{
- register pcb_t pcb;
+ pcb_t pcb;
pcb = (pcb_t) kmem_cache_alloc(&pcb_cache);
if (pcb == 0)
@@ -409,10 +408,9 @@ void pcb_init(thread)
thread->pcb = pcb;
}
-void pcb_terminate(thread)
- register thread_t thread;
+void pcb_terminate(thread_t thread)
{
- register pcb_t pcb = thread->pcb;
+ pcb_t pcb = thread->pcb;
counter(if (--c_threads_current < c_threads_min)
c_threads_min = c_threads_current);
@@ -432,7 +430,7 @@ void pcb_terminate(thread)
*/
void pcb_collect(thread)
- thread_t thread;
+ const thread_t thread;
{
}
@@ -443,18 +441,18 @@ void pcb_collect(thread)
* Set the status of the specified thread.
*/
-kern_return_t thread_setstatus(thread, flavor, tstate, count)
- thread_t thread;
- int flavor;
- thread_state_t tstate;
- unsigned int count;
+kern_return_t thread_setstatus(
+ thread_t thread,
+ int flavor,
+ thread_state_t tstate,
+ unsigned int count)
{
switch (flavor) {
case i386_THREAD_STATE:
case i386_REGS_SEGS_STATE:
{
- register struct i386_thread_state *state;
- register struct i386_saved_state *saved_state;
+ struct i386_thread_state *state;
+ struct i386_saved_state *saved_state;
if (count < i386_THREAD_STATE_COUNT) {
return(KERN_INVALID_ARGUMENT);
@@ -596,7 +594,7 @@ kern_return_t thread_setstatus(thread, flavor, tstate, count)
case i386_V86_ASSIST_STATE:
{
- register struct i386_v86_assist_state *state;
+ struct i386_v86_assist_state *state;
vm_offset_t int_table;
int int_count;
@@ -621,6 +619,21 @@ kern_return_t thread_setstatus(thread, flavor, tstate, count)
break;
}
+ case i386_DEBUG_STATE:
+ {
+ struct i386_debug_state *state;
+ kern_return_t ret;
+
+ if (count < i386_DEBUG_STATE_COUNT)
+ return KERN_INVALID_ARGUMENT;
+
+ state = (struct i386_debug_state *) tstate;
+ ret = db_set_debug_state(thread->pcb, state);
+ if (ret)
+ return ret;
+ break;
+ }
+
default:
return(KERN_INVALID_ARGUMENT);
}
@@ -634,11 +647,11 @@ kern_return_t thread_setstatus(thread, flavor, tstate, count)
* Get the status of the specified thread.
*/
-kern_return_t thread_getstatus(thread, flavor, tstate, count)
- register thread_t thread;
- int flavor;
- thread_state_t tstate; /* pointer to OUT array */
- unsigned int *count; /* IN/OUT */
+kern_return_t thread_getstatus(
+ thread_t thread,
+ int flavor,
+ thread_state_t tstate, /* pointer to OUT array */
+ unsigned int *count) /* IN/OUT */
{
switch (flavor) {
case THREAD_STATE_FLAVOR_LIST:
@@ -654,8 +667,8 @@ kern_return_t thread_getstatus(thread, flavor, tstate, count)
case i386_THREAD_STATE:
case i386_REGS_SEGS_STATE:
{
- register struct i386_thread_state *state;
- register struct i386_saved_state *saved_state;
+ struct i386_thread_state *state;
+ struct i386_saved_state *saved_state;
if (*count < i386_THREAD_STATE_COUNT)
return(KERN_INVALID_ARGUMENT);
@@ -725,7 +738,7 @@ kern_return_t thread_getstatus(thread, flavor, tstate, count)
* Temporary - replace by i386_io_map
*/
case i386_ISA_PORT_MAP_STATE: {
- register struct i386_isa_port_map_state *state;
+ struct i386_isa_port_map_state *state;
if (*count < i386_ISA_PORT_MAP_STATE_COUNT)
return(KERN_INVALID_ARGUMENT);
@@ -736,8 +749,8 @@ kern_return_t thread_getstatus(thread, flavor, tstate, count)
if (thread->task->machine.iopb == 0)
memset (state->pm, 0xff, sizeof state->pm);
else
- memcpy((char *) state->pm,
- (char *) thread->task->machine.iopb,
+ memcpy(state->pm,
+ thread->task->machine.iopb,
sizeof state->pm);
simple_unlock (&thread->task->machine.iopb_lock);
@@ -747,7 +760,7 @@ kern_return_t thread_getstatus(thread, flavor, tstate, count)
case i386_V86_ASSIST_STATE:
{
- register struct i386_v86_assist_state *state;
+ struct i386_v86_assist_state *state;
if (*count < i386_V86_ASSIST_STATE_COUNT)
return KERN_INVALID_ARGUMENT;
@@ -760,6 +773,20 @@ kern_return_t thread_getstatus(thread, flavor, tstate, count)
break;
}
+ case i386_DEBUG_STATE:
+ {
+ struct i386_debug_state *state;
+
+ if (*count < i386_DEBUG_STATE_COUNT)
+ return KERN_INVALID_ARGUMENT;
+
+ state = (struct i386_debug_state *) tstate;
+ db_get_debug_state(thread->pcb, state);
+
+ *count = i386_DEBUG_STATE_COUNT;
+ break;
+ }
+
default:
return(KERN_INVALID_ARGUMENT);
}
@@ -772,24 +799,22 @@ kern_return_t thread_getstatus(thread, flavor, tstate, count)
* will make the thread return 'retval' from a syscall.
*/
void
-thread_set_syscall_return(thread, retval)
- thread_t thread;
- kern_return_t retval;
+thread_set_syscall_return(
+ thread_t thread,
+ kern_return_t retval)
{
thread->pcb->iss.eax = retval;
}
-
/*
- * Return prefered address of user stack.
+ * Return preferred address of user stack.
* Always returns low address. If stack grows up,
* the stack grows away from this address;
* if stack grows down, the stack grows towards this
* address.
*/
vm_offset_t
-user_stack_low(stack_size)
- vm_size_t stack_size;
+user_stack_low(vm_size_t stack_size)
{
return (VM_MAX_ADDRESS - stack_size);
}
@@ -801,11 +826,11 @@ vm_offset_t
set_user_regs(stack_base, stack_size, exec_info, arg_size)
vm_offset_t stack_base; /* low address */
vm_offset_t stack_size;
- struct exec_info *exec_info;
+ const struct exec_info *exec_info;
vm_size_t arg_size;
{
vm_offset_t arg_addr;
- register struct i386_saved_state *saved_state;
+ struct i386_saved_state *saved_state;
arg_size = (arg_size + sizeof(int) - 1) & ~(sizeof(int)-1);
arg_addr = stack_base + stack_size - arg_size;
diff --git a/i386/i386/pcb.h b/i386/i386/pcb.h
index 21bdfd9c..708f30d8 100644
--- a/i386/i386/pcb.h
+++ b/i386/i386/pcb.h
@@ -28,6 +28,8 @@
#include <sys/types.h>
#include <mach/exec/exec.h>
+#include <mach/thread_status.h>
+#include <machine/thread.h>
extern void pcb_init (thread_t thread);
@@ -56,7 +58,7 @@ extern vm_offset_t user_stack_low (vm_size_t stack_size);
extern vm_offset_t set_user_regs (
vm_offset_t stack_base,
vm_offset_t stack_size,
- struct exec_info *exec_info,
+ const struct exec_info *exec_info,
vm_size_t arg_size);
extern void load_context (thread_t new);
@@ -70,4 +72,14 @@ extern vm_offset_t stack_detach (thread_t thread);
extern void switch_ktss (pcb_t pcb);
+extern void update_ktss_iopb (unsigned char *new_iopb, io_port_t size);
+
+extern thread_t Load_context (thread_t new);
+
+extern thread_t Switch_context (thread_t old, void (*continuation)(), thread_t new);
+
+extern void Thread_continue (void);
+
+extern void pcb_module_init (void);
+
#endif /* _I386_PCB_H_ */
diff --git a/i386/i386/phys.c b/i386/i386/phys.c
index ed4a309a..d55bdd9d 100644
--- a/i386/i386/phys.c
+++ b/i386/i386/phys.c
@@ -37,30 +37,74 @@
#include <vm/vm_page.h>
#include <i386/pmap.h>
+#include <i386/model_dep.h>
#include <mach/machine/vm_param.h>
+#define INTEL_PTE_W(p) (INTEL_PTE_VALID | INTEL_PTE_WRITE | INTEL_PTE_REF | INTEL_PTE_MOD | pa_to_pte(p))
+#define INTEL_PTE_R(p) (INTEL_PTE_VALID | INTEL_PTE_REF | pa_to_pte(p))
+
/*
* pmap_zero_page zeros the specified (machine independent) page.
*/
void
-pmap_zero_page(p)
- vm_offset_t p;
+pmap_zero_page(vm_offset_t p)
{
assert(p != vm_page_fictitious_addr);
- memset((void *)phystokv(p), 0, PAGE_SIZE);
+ vm_offset_t v;
+ pmap_mapwindow_t *map;
+ boolean_t mapped = p >= phys_last_addr;
+
+ if (mapped)
+ {
+ map = pmap_get_mapwindow(INTEL_PTE_W(p));
+ v = map->vaddr;
+ }
+ else
+ v = phystokv(p);
+
+ memset((void*) v, 0, PAGE_SIZE);
+
+ if (mapped)
+ pmap_put_mapwindow(map);
}
/*
* pmap_copy_page copies the specified (machine independent) pages.
*/
void
-pmap_copy_page(src, dst)
- vm_offset_t src, dst;
+pmap_copy_page(
+ vm_offset_t src,
+ vm_offset_t dst)
{
+ vm_offset_t src_addr_v, dst_addr_v;
+ pmap_mapwindow_t *src_map, *dst_map;
+ boolean_t src_mapped = src >= phys_last_addr;
+ boolean_t dst_mapped = dst >= phys_last_addr;
assert(src != vm_page_fictitious_addr);
assert(dst != vm_page_fictitious_addr);
- memcpy((void *)phystokv(dst), (void *)phystokv(src), PAGE_SIZE);
+ if (src_mapped)
+ {
+ src_map = pmap_get_mapwindow(INTEL_PTE_R(src));
+ src_addr_v = src_map->vaddr;
+ }
+ else
+ src_addr_v = phystokv(src);
+
+ if (dst_mapped)
+ {
+ dst_map = pmap_get_mapwindow(INTEL_PTE_W(dst));
+ dst_addr_v = dst_map->vaddr;
+ }
+ else
+ dst_addr_v = phystokv(dst);
+
+ memcpy((void *) dst_addr_v, (void *) src_addr_v, PAGE_SIZE);
+
+ if (src_mapped)
+ pmap_put_mapwindow(src_map);
+ if (dst_mapped)
+ pmap_put_mapwindow(dst_map);
}
/*
@@ -69,12 +113,29 @@ pmap_copy_page(src, dst)
* Copy virtual memory to physical memory
*/
void
-copy_to_phys(src_addr_v, dst_addr_p, count)
- vm_offset_t src_addr_v, dst_addr_p;
- int count;
+copy_to_phys(
+ vm_offset_t src_addr_v,
+ vm_offset_t dst_addr_p,
+ int count)
{
+ vm_offset_t dst_addr_v;
+ pmap_mapwindow_t *dst_map;
+ boolean_t mapped = dst_addr_p >= phys_last_addr;
assert(dst_addr_p != vm_page_fictitious_addr);
- memcpy((void *)phystokv(dst_addr_p), (void *)src_addr_v, count);
+ assert(pa_to_pte(dst_addr_p + count-1) == pa_to_pte(dst_addr_p));
+
+ if (mapped)
+ {
+ dst_map = pmap_get_mapwindow(INTEL_PTE_W(dst_addr_p));
+ dst_addr_v = dst_map->vaddr;
+ }
+ else
+ dst_addr_v = phystokv(dst_addr_p);
+
+ memcpy((void *)dst_addr_v, (void *)src_addr_v, count);
+
+ if (mapped)
+ pmap_put_mapwindow(dst_map);
}
/*
@@ -84,12 +145,29 @@ copy_to_phys(src_addr_v, dst_addr_p, count)
* is assumed to be present (e.g. the buffer pool).
*/
void
-copy_from_phys(src_addr_p, dst_addr_v, count)
- vm_offset_t src_addr_p, dst_addr_v;
- int count;
+copy_from_phys(
+ vm_offset_t src_addr_p,
+ vm_offset_t dst_addr_v,
+ int count)
{
+ vm_offset_t src_addr_v;
+ pmap_mapwindow_t *src_map;
+ boolean_t mapped = src_addr_p >= phys_last_addr;
assert(src_addr_p != vm_page_fictitious_addr);
- memcpy((void *)dst_addr_v, (void *)phystokv(src_addr_p), count);
+ assert(pa_to_pte(src_addr_p + count-1) == pa_to_pte(src_addr_p));
+
+ if (mapped)
+ {
+ src_map = pmap_get_mapwindow(INTEL_PTE_R(src_addr_p));
+ src_addr_v = src_map->vaddr;
+ }
+ else
+ src_addr_v = phystokv(src_addr_p);
+
+ memcpy((void *)dst_addr_v, (void *)src_addr_v, count);
+
+ if (mapped)
+ pmap_put_mapwindow(src_map);
}
/*
@@ -98,8 +176,7 @@ copy_from_phys(src_addr_p, dst_addr_v, count)
* Convert a kernel virtual address to a physical address
*/
vm_offset_t
-kvtophys(addr)
-vm_offset_t addr;
+kvtophys(vm_offset_t addr)
{
pt_entry_t *pte;
diff --git a/i386/i386/pic.c b/i386/i386/pic.c
index 50ca1509..e8c881af 100644
--- a/i386/i386/pic.c
+++ b/i386/i386/pic.c
@@ -62,9 +62,6 @@ int curr_pic_mask;
int iunit[NINTR] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
-int nintr = NINTR;
-int npics = NPICS;
-
unsigned short master_icw, master_ocw, slaves_icw, slaves_ocw;
u_short PICM_ICW1, PICM_OCW1, PICS_ICW1, PICS_OCW1 ;
@@ -105,7 +102,7 @@ u_short PICM_ICW4, PICS_ICW4 ;
*/
void
-picinit()
+picinit(void)
{
asm("cli");
@@ -223,7 +220,7 @@ picinit()
#define SLAVEACTV 0xFF00
void
-form_pic_mask()
+form_pic_mask(void)
{
unsigned int i, j, bit, mask;
@@ -240,7 +237,7 @@ form_pic_mask()
}
void
-intnull(unit_dev)
+intnull(int unit_dev)
{
printf("intnull(%d)\n", unit_dev);
}
@@ -248,7 +245,7 @@ intnull(unit_dev)
int prtnull_count = 0;
void
-prtnull(unit)
+prtnull(int unit)
{
++prtnull_count;
}
diff --git a/i386/i386/pic.h b/i386/i386/pic.h
index 52f6ec16..80bf65d6 100644
--- a/i386/i386/pic.h
+++ b/i386/i386/pic.h
@@ -183,6 +183,6 @@ extern int curr_pic_mask;
extern int pic_mask[];
extern void prtnull(int unit);
extern void intnull(int unit);
-#endif
+#endif /* __ASSEMBLER__ */
#endif /* _I386_PIC_H_ */
diff --git a/i386/i386/pit.c b/i386/i386/pit.c
index 4f156d87..da683308 100644
--- a/i386/i386/pit.c
+++ b/i386/i386/pit.c
@@ -57,8 +57,6 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
int pitctl_port = PITCTL_PORT; /* For 386/20 Board */
int pitctr0_port = PITCTR0_PORT; /* For 386/20 Board */
-int pitctr1_port = PITCTR1_PORT; /* For 386/20 Board */
-int pitctr2_port = PITCTR2_PORT; /* For 386/20 Board */
/* We want PIT 0 in square wave mode */
int pit0_mode = PIT_C0|PIT_SQUAREMODE|PIT_READMODE ;
@@ -67,7 +65,7 @@ int pit0_mode = PIT_C0|PIT_SQUAREMODE|PIT_READMODE ;
unsigned int clknumb = CLKNUM; /* interrupt interval for timer 0 */
void
-clkstart()
+clkstart(void)
{
unsigned char byte;
unsigned long s;
diff --git a/i386/i386/proc_reg.h b/i386/i386/proc_reg.h
index f1b2c89f..80835361 100644
--- a/i386/i386/proc_reg.h
+++ b/i386/i386/proc_reg.h
@@ -234,6 +234,132 @@ extern unsigned long cr3;
asm("jmp 0f\n" \
"0:\n")
+#ifdef MACH_RING1
+#define get_dr0() hyp_get_debugreg(0)
+#else
+#define get_dr0() \
+ ({ \
+ register unsigned long _temp__; \
+ asm volatile("movl %%dr0, %0" : "=r" (_temp__)); \
+ _temp__; \
+ })
+#endif
+
+#ifdef MACH_RING1
+#define set_dr0(value) hyp_set_debugreg(0, value)
+#else
+#define set_dr0(value) \
+ ({ \
+ register unsigned long _temp__ = (value); \
+ asm volatile("movl %0,%%dr0" : : "r" (_temp__)); \
+ })
+#endif
+
+#ifdef MACH_RING1
+#define get_dr1() hyp_get_debugreg(1)
+#else
+#define get_dr1() \
+ ({ \
+ register unsigned long _temp__; \
+ asm volatile("movl %%dr1, %0" : "=r" (_temp__)); \
+ _temp__; \
+ })
+#endif
+
+#ifdef MACH_RING1
+#define set_dr1(value) hyp_set_debugreg(1, value)
+#else
+#define set_dr1(value) \
+ ({ \
+ register unsigned long _temp__ = (value); \
+ asm volatile("movl %0,%%dr1" : : "r" (_temp__)); \
+ })
+#endif
+
+#ifdef MACH_RING1
+#define get_dr2() hyp_get_debugreg(2)
+#else
+#define get_dr2() \
+ ({ \
+ register unsigned long _temp__; \
+ asm volatile("movl %%dr2, %0" : "=r" (_temp__)); \
+ _temp__; \
+ })
+#endif
+
+#ifdef MACH_RING1
+#define set_dr2(value) hyp_set_debugreg(2, value)
+#else
+#define set_dr2(value) \
+ ({ \
+ register unsigned long _temp__ = (value); \
+ asm volatile("movl %0,%%dr2" : : "r" (_temp__)); \
+ })
+#endif
+
+#ifdef MACH_RING1
+#define get_dr3() hyp_get_debugreg(3)
+#else
+#define get_dr3() \
+ ({ \
+ register unsigned long _temp__; \
+ asm volatile("movl %%dr3, %0" : "=r" (_temp__)); \
+ _temp__; \
+ })
+#endif
+
+#ifdef MACH_RING1
+#define set_dr3(value) hyp_set_debugreg(3, value)
+#else
+#define set_dr3(value) \
+ ({ \
+ register unsigned long _temp__ = (value); \
+ asm volatile("movl %0,%%dr3" : : "r" (_temp__)); \
+ })
+#endif
+
+#ifdef MACH_RING1
+#define get_dr6() hyp_get_debugreg(6)
+#else
+#define get_dr6() \
+ ({ \
+ register unsigned long _temp__; \
+ asm volatile("movl %%dr6, %0" : "=r" (_temp__)); \
+ _temp__; \
+ })
+#endif
+
+#ifdef MACH_RING1
+#define set_dr6(value) hyp_set_debugreg(6, value)
+#else
+#define set_dr6(value) \
+ ({ \
+ register unsigned long _temp__ = (value); \
+ asm volatile("movl %0,%%dr6" : : "r" (_temp__)); \
+ })
+#endif
+
+#ifdef MACH_RING1
+#define get_dr7() hyp_get_debugreg(7)
+#else
+#define get_dr7() \
+ ({ \
+ register unsigned long _temp__; \
+ asm volatile("movl %%dr7, %0" : "=r" (_temp__)); \
+ _temp__; \
+ })
+#endif
+
+#ifdef MACH_RING1
+#define set_dr7(value) hyp_set_debugreg(7, value)
+#else
+#define set_dr7(value) \
+ ({ \
+ register unsigned long _temp__ = (value); \
+ asm volatile("movl %0,%%dr7" : : "r" (_temp__)); \
+ })
+#endif
+
#endif /* __GNUC__ */
#endif /* __ASSEMBLER__ */
diff --git a/i386/i386/setjmp.h b/i386/i386/setjmp.h
index 21c856dc..930a9dd5 100644
--- a/i386/i386/setjmp.h
+++ b/i386/i386/setjmp.h
@@ -33,4 +33,8 @@ typedef struct jmp_buf {
int jmp_buf[6]; /* ebx, esi, edi, ebp, esp, eip */
} jmp_buf_t;
+extern int _setjmp(jmp_buf_t*);
+
+extern void _longjmp(jmp_buf_t*, int) __attribute__ ((noreturn));
+
#endif /* _I386_SETJMP_H_ */
diff --git a/i386/i386/spl.S b/i386/i386/spl.S
index 3c075092..1dce991d 100644
--- a/i386/i386/spl.S
+++ b/i386/i386/spl.S
@@ -140,15 +140,35 @@ Entry(splsched)
Entry(splhigh)
Entry(splhi)
ENTRY(spl7)
- SETIPL(SPL7)
+ /* ipl7 just clears IF */
+ movl $SPL7,%eax
+ xchgl EXT(curr_ipl),%eax
+ cli
+ ret
ENTRY(splx)
movl S_ARG0,%edx /* get ipl */
+
+#if (MACH_KDB || MACH_TTD) && !defined(MACH_XEN)
+ /* First make sure that if we're exitting from ipl7, IF is still cleared */
+ cmpl $SPL7,EXT(curr_ipl) /* from ipl7? */
+ jne 0f
+ pushfl
+ popl %eax
+ testl $0x200,%eax /* IF? */
+ jz 0f
+ int3 /* Oops, interrupts got enabled?! */
+
+0:
+#endif /* (MACH_KDB || MACH_TTD) && !MACH_XEN */
testl %edx,%edx /* spl0? */
jz EXT(spl0) /* yes, handle specially */
cmpl EXT(curr_ipl),%edx /* same ipl as current? */
jne spl /* no */
+ cmpl $SPL7,%edx /* spl7? */
+ je 1f /* to ipl7, don't enable interrupts */
sti /* ensure interrupts are enabled */
+1:
movl %edx,%eax /* return previous ipl */
ret
@@ -207,6 +227,20 @@ splx_cli:
.align TEXT_ALIGN
.globl spl
spl:
+#if (MACH_KDB || MACH_TTD) && !defined(MACH_XEN)
+ /* First make sure that if we're exitting from ipl7, IF is still cleared */
+ cmpl $SPL7,EXT(curr_ipl) /* from ipl7? */
+ jne 0f
+ pushfl
+ popl %eax
+ testl $0x200,%eax /* IF? */
+ jz 0f
+ int3 /* Oops, interrupts got enabled?! */
+
+0:
+#endif /* (MACH_KDB || MACH_TTD) && !MACH_XEN */
+ cmpl $SPL7,%edx /* spl7? */
+ je EXT(spl7) /* yes, handle specially */
movl EXT(pic_mask)(,%edx,4),%eax
/* get PIC mask */
cli /* disable interrupts */
diff --git a/i386/i386/thread.h b/i386/i386/thread.h
index eddd25c2..35a28025 100644
--- a/i386/i386/thread.h
+++ b/i386/i386/thread.h
@@ -36,6 +36,7 @@
#include <mach/boolean.h>
#include <mach/machine/vm_types.h>
#include <mach/machine/fp_reg.h>
+#include <mach/machine/thread_status.h>
#include <kern/lock.h>
@@ -168,6 +169,7 @@ struct i386_machine_state {
struct i386_fpsave_state *ifps;
struct v86_assist_state v86s;
struct real_descriptor user_gdt[USER_GDT_SLOTS];
+ struct i386_debug_state ids;
};
typedef struct pcb {
@@ -177,7 +179,7 @@ typedef struct pcb {
decl_simple_lock_data(, lock)
#ifdef LINUX_DEV
void *data;
-#endif
+#endif /* LINUX_DEV */
} *pcb_t;
/*
diff --git a/i386/i386/trap.c b/i386/i386/trap.c
index c6aab488..64705049 100644
--- a/i386/i386/trap.c
+++ b/i386/i386/trap.c
@@ -37,6 +37,7 @@
#include <i386/model_dep.h>
#include <intel/read_fault.h>
#include <machine/machspl.h> /* for spl_t */
+#include <machine/db_interface.h>
#include <mach/exception.h>
#include <mach/kern_return.h>
@@ -54,6 +55,7 @@
#include <kern/task.h>
#include <kern/sched.h>
#include <kern/sched_prim.h>
+#include <kern/exception.h>
#if MACH_KDB
#include <ddb/db_run.h>
@@ -62,21 +64,16 @@
#include "debug.h"
-extern void exception() __attribute__ ((noreturn));
-extern void thread_exception_return() __attribute__ ((noreturn));
-
-extern void i386_exception() __attribute__ ((noreturn));
-
#if MACH_KDB
boolean_t debug_all_traps_with_kdb = FALSE;
extern struct db_watchpoint *db_watchpoint_list;
extern boolean_t db_watchpoints_inserted;
void
-thread_kdb_return()
+thread_kdb_return(void)
{
- register thread_t thread = current_thread();
- register struct i386_saved_state *regs = USER_REGS(thread);
+ thread_t thread = current_thread();
+ struct i386_saved_state *regs = USER_REGS(thread);
if (kdb_trap(regs->trapno, regs->err, regs)) {
thread_exception_return();
@@ -91,11 +88,10 @@ boolean_t debug_all_traps_with_kttd = TRUE;
#endif /* MACH_TTD */
void
-user_page_fault_continue(kr)
- kern_return_t kr;
+user_page_fault_continue(kern_return_t kr)
{
- register thread_t thread = current_thread();
- register struct i386_saved_state *regs = USER_REGS(thread);
+ thread_t thread = current_thread();
+ struct i386_saved_state *regs = USER_REGS(thread);
if (kr == KERN_SUCCESS) {
#if MACH_KDB
@@ -150,23 +146,19 @@ char *trap_name(unsigned int trapnum)
return trapnum < TRAP_TYPES ? trap_type[trapnum] : "(unknown)";
}
-
-boolean_t brb = TRUE;
-
/*
* Trap from kernel mode. Only page-fault errors are recoverable,
* and then only in special circumstances. All other errors are
* fatal.
*/
-void kernel_trap(regs)
- register struct i386_saved_state *regs;
+void kernel_trap(struct i386_saved_state *regs)
{
- int code;
- int subcode;
- register int type;
+ int code;
+ int subcode;
+ int type;
vm_map_t map;
kern_return_t result;
- register thread_t thread;
+ thread_t thread;
extern char _start[], etext[];
type = regs->trapno;
@@ -225,9 +217,9 @@ dump_ss(regs);
goto badtrap;
}
} else {
- assert(thread);
- map = thread->task->map;
- if (map == kernel_map) {
+ if (thread)
+ map = thread->task->map;
+ if (!thread || map == kernel_map) {
printf("kernel page fault at %08x:\n", subcode);
dump_ss(regs);
panic("kernel thread accessed user space!\n");
@@ -275,7 +267,7 @@ dump_ss(regs);
* Certain faults require that we back up
* the EIP.
*/
- register struct recovery *rp;
+ struct recovery *rp;
/* Linear searching; but the list is small enough. */
for (rp = retry_table; rp < retry_table_end; rp++) {
@@ -292,7 +284,7 @@ dump_ss(regs);
* for this fault, go there.
*/
{
- register struct recovery *rp;
+ struct recovery *rp;
/* Linear searching; but the list is small enough. */
for (rp = recover_table;
@@ -351,14 +343,13 @@ dump_ss(regs);
* Trap from user mode.
* Return TRUE if from emulated system call.
*/
-int user_trap(regs)
- register struct i386_saved_state *regs;
+int user_trap(struct i386_saved_state *regs)
{
int exc = 0; /* Suppress gcc warning */
int code;
int subcode;
- register int type;
- register thread_t thread = current_thread();
+ int type;
+ thread_t thread = current_thread();
if ((vm_offset_t)thread < phys_last_addr) {
printf("user_trap: bad thread pointer 0x%p\n", thread);
@@ -403,7 +394,12 @@ printf("user trap %d error %d sub %08x\n", type, code, subcode);
if (kdb_trap(type, regs->err, regs))
return 0;
}
-#endif
+#endif /* MACH_KDB */
+ /* Make the content of the debug status register (DR6)
+ available to user space. */
+ if (thread->pcb)
+ thread->pcb->ims.ids.dr[6] = get_dr6() & 0x600F;
+ set_dr6(0);
exc = EXC_BREAKPOINT;
code = EXC_I386_SGL;
break;
@@ -425,7 +421,7 @@ printf("user trap %d error %d sub %08x\n", type, code, subcode);
return 0;
}
}
-#endif
+#endif /* MACH_KDB */
exc = EXC_BREAKPOINT;
code = EXC_I386_BPT;
break;
@@ -524,7 +520,7 @@ printf("user trap %d error %d sub %08x\n", type, code, subcode);
}
return 0;
}
-#endif
+#endif /* MACH_PV_PAGETABLES */
case T_FLOATING_POINT_ERROR:
fpexterrflt();
@@ -561,26 +557,15 @@ printf("user trap %d error %d sub %08x\n", type, code, subcode);
/*NOTREACHED*/
}
-/*
- * V86 mode assist for interrupt handling.
- */
-boolean_t v86_assist_on = TRUE;
-boolean_t v86_unsafe_ok = FALSE;
-boolean_t v86_do_sti_cli = TRUE;
-boolean_t v86_do_sti_immediate = FALSE;
-
#define V86_IRET_PENDING 0x4000
-int cli_count = 0;
-int sti_count = 0;
-
/*
* Handle AST traps for i386.
* Check for delayed floating-point exception from
* AT-bus machines.
*/
void
-i386_astintr()
+i386_astintr(void)
{
int mycpu = cpu_number();
@@ -589,7 +574,7 @@ i386_astintr()
if (need_ast[mycpu] & AST_I386_FP) {
/*
* AST was for delayed floating-point exception -
- * FP interrupt occured while in kernel.
+ * FP interrupt occurred while in kernel.
* Turn off this AST reason and handle the FPU error.
*/
ast_off(mycpu, AST_I386_FP);
@@ -619,10 +604,10 @@ i386_astintr()
* emulator.
*/
void
-i386_exception(exc, code, subcode)
- int exc;
- int code;
- int subcode;
+i386_exception(
+ int exc,
+ int code,
+ int subcode)
{
spl_t s;
@@ -643,11 +628,11 @@ i386_exception(exc, code, subcode)
*/
unsigned
interrupted_pc(t)
- thread_t t;
+ const thread_t t;
{
- register struct i386_saved_state *iss;
+ struct i386_saved_state *iss;
iss = USER_REGS(t);
return iss->eip;
}
-#endif /* MACH_PCSAMPLE > 0*/
+#endif /* MACH_PCSAMPLE > 0 */
diff --git a/i386/i386/trap.h b/i386/i386/trap.h
index b4e92246..46612db5 100644
--- a/i386/i386/trap.h
+++ b/i386/i386/trap.h
@@ -36,6 +36,15 @@ char *trap_name(unsigned int trapnum);
unsigned int interrupted_pc(thread_t);
+void
+i386_exception(
+ int exc,
+ int code,
+ int subcode) __attribute__ ((noreturn));
+
+extern void
+thread_kdb_return(void);
+
#endif /* !__ASSEMBLER__ */
#endif /* _I386_TRAP_H_ */
diff --git a/i386/i386/user_ldt.c b/i386/i386/user_ldt.c
index 74c10a4c..d8bdb90f 100644
--- a/i386/i386/user_ldt.c
+++ b/i386/i386/user_ldt.c
@@ -43,67 +43,17 @@
#include "ldt.h"
#include "vm_param.h"
-char acc_type[8][3] = {
- /* code stack data */
- { 0, 0, 1 }, /* data */
- { 0, 1, 1 }, /* data, writable */
- { 0, 0, 1 }, /* data, expand-down */
- { 0, 1, 1 }, /* data, writable, expand-down */
- { 1, 0, 0 }, /* code */
- { 1, 0, 1 }, /* code, readable */
- { 1, 0, 0 }, /* code, conforming */
- { 1, 0, 1 }, /* code, readable, conforming */
-};
-
-boolean_t selector_check(thread, sel, type)
- thread_t thread;
- int sel;
- int type; /* code, stack, data */
-{
- struct user_ldt *ldt;
- int access;
-
- ldt = thread->pcb->ims.ldt;
- if (ldt == 0) {
- switch (type) {
- case S_CODE:
- return sel == USER_CS;
- case S_STACK:
- return sel == USER_DS;
- case S_DATA:
- return sel == 0 ||
- sel == USER_CS ||
- sel == USER_DS;
- }
- }
-
- if (type != S_DATA && sel == 0)
- return FALSE;
- if ((sel & (SEL_LDT|SEL_PL)) != (SEL_LDT|SEL_PL_U)
- || sel > ldt->desc.limit_low)
- return FALSE;
-
- access = ldt->ldt[sel_idx(sel)].access;
-
- if ((access & (ACC_P|ACC_PL|ACC_TYPE_USER|SZ_64))
- != (ACC_P|ACC_PL_U|ACC_TYPE_USER))
- return FALSE;
- /* present, pl == pl.user, not system, not 64bits */
-
- return acc_type[(access & 0xe)>>1][type];
-}
-
/*
* Add the descriptors to the LDT, starting with
* the descriptor for 'first_selector'.
*/
kern_return_t
-i386_set_ldt(thread, first_selector, desc_list, count, desc_list_inline)
- thread_t thread;
- int first_selector;
- struct real_descriptor *desc_list;
- unsigned int count;
- boolean_t desc_list_inline;
+i386_set_ldt(
+ thread_t thread,
+ int first_selector,
+ struct real_descriptor *desc_list,
+ unsigned int count,
+ boolean_t desc_list_inline)
{
user_ldt_t new_ldt, old_ldt, temp;
struct real_descriptor *dp;
@@ -305,14 +255,14 @@ i386_set_ldt(thread, first_selector, desc_list, count, desc_list_inline)
kern_return_t
i386_get_ldt(thread, first_selector, selector_count, desc_list, count)
- thread_t thread;
+ const thread_t thread;
int first_selector;
int selector_count; /* number wanted */
struct real_descriptor **desc_list; /* in/out */
unsigned int *count; /* in/out */
{
struct user_ldt *user_ldt;
- pcb_t pcb = thread->pcb;
+ pcb_t pcb;
int first_desc = sel_idx(first_selector);
unsigned int ldt_count;
vm_size_t ldt_size;
@@ -326,6 +276,7 @@ i386_get_ldt(thread, first_selector, selector_count, desc_list, count)
if (first_desc + selector_count >= 8192)
return KERN_INVALID_ARGUMENT;
+ pcb = thread->pcb;
addr = 0;
size = 0;
@@ -416,8 +367,7 @@ i386_get_ldt(thread, first_selector, selector_count, desc_list, count)
}
void
-user_ldt_free(user_ldt)
- user_ldt_t user_ldt;
+user_ldt_free(user_ldt_t user_ldt)
{
#ifdef MACH_PV_DESCRIPTORS
int i;
@@ -481,7 +431,7 @@ i386_set_gdt (thread_t thread, int *selector, struct real_descriptor desc)
}
kern_return_t
-i386_get_gdt (thread_t thread, int selector, struct real_descriptor *desc)
+i386_get_gdt (const thread_t thread, int selector, struct real_descriptor *desc)
{
if (thread == THREAD_NULL)
return KERN_INVALID_ARGUMENT;
diff --git a/i386/i386/user_ldt.h b/i386/i386/user_ldt.h
index 6c6c858e..26caa274 100644
--- a/i386/i386/user_ldt.h
+++ b/i386/i386/user_ldt.h
@@ -44,15 +44,7 @@ struct user_ldt {
};
typedef struct user_ldt * user_ldt_t;
-/*
- * Check code/stack/data selector values against LDT if present.
- */
-#define S_CODE 0 /* code segment */
-#define S_STACK 1 /* stack segment */
-#define S_DATA 2 /* data segment */
-
-extern boolean_t selector_check(thread_t thread,
- int sel,
- int type);
+extern void
+user_ldt_free(user_ldt_t user_ldt);
#endif /* _I386_USER_LDT_H_ */
diff --git a/i386/i386/vm_tuning.h b/i386/i386/vm_tuning.h
deleted file mode 100644
index f54e110a..00000000
--- a/i386/i386/vm_tuning.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: i386/vm_tuning.h
- *
- * VM tuning parameters for the i386 (without reference bits).
- */
-
-#ifndef _I386_VM_TUNING_H_
-#define _I386_VM_TUNING_H_
-
-#endif /* _I386_VM_TUNING_H_ */
diff --git a/i386/i386/xen.h b/i386/i386/xen.h
index 5bdaf0b8..c6811873 100644
--- a/i386/i386/xen.h
+++ b/i386/i386/xen.h
@@ -21,6 +21,7 @@
#ifdef MACH_XEN
#ifndef __ASSEMBLER__
+#include <kern/macros.h>
#include <kern/printf.h>
#include <mach/machine/vm_types.h>
#include <mach/vm_param.h>
@@ -32,8 +33,7 @@
#include <xen/public/xen.h>
/* TODO: this should be moved in appropriate non-Xen place. */
-#define barrier() __asm__ __volatile__ ("": : :"memory")
-#define mb() __asm__ __volatile__("lock; addl $0,0(%esp)")
+#define mb() __asm__ __volatile__("lock; addl $0,0(%%esp)":::"memory")
#define rmb() mb()
#define wmb() mb()
MACH_INLINE unsigned long xchgl(volatile unsigned long *ptr, unsigned long x)
diff --git a/i386/i386at/acpi.c b/i386/i386at/acpi.c
new file mode 100644
index 00000000..ec8aeb1e
--- /dev/null
+++ b/i386/i386at/acpi.c
@@ -0,0 +1,82 @@
+/* acpi.c - get acpi tables. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/glue.h>
+#include <grub/acpi.h>
+#include <grub/misc.h>
+
+struct grub_acpi_rsdp_v10 *
+grub_machine_acpi_get_rsdpv1 (void)
+{
+ int ebda_len;
+ grub_uint8_t *ebda, *ptr;
+
+ grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
+ ebda = (grub_uint8_t *) phystokv ((* ((grub_uint16_t *) phystokv (0x40e))) << 4);
+ ebda_len = * (grub_uint16_t *) ebda;
+ if (! ebda_len)
+ return 0;
+ for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
+ if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
+ && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+ && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
+ return (struct grub_acpi_rsdp_v10 *) ptr;
+
+ grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
+ for (ptr = (grub_uint8_t *) phystokv (0xe0000); ptr < (grub_uint8_t *) phystokv (0x100000);
+ ptr += 16)
+ if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
+ && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+ && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
+ return (struct grub_acpi_rsdp_v10 *) ptr;
+ return 0;
+}
+
+struct grub_acpi_rsdp_v20 *
+grub_machine_acpi_get_rsdpv2 (void)
+{
+ int ebda_len;
+ grub_uint8_t *ebda, *ptr;
+
+ grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
+ ebda = (grub_uint8_t *) phystokv ((* ((grub_uint16_t *) phystokv (0x40e))) << 4);
+ ebda_len = * (grub_uint16_t *) ebda;
+ if (! ebda_len)
+ return 0;
+ for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
+ if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
+ && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+ && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
+ && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
+ && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
+ == 0)
+ return (struct grub_acpi_rsdp_v20 *) ptr;
+
+ grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
+ for (ptr = (grub_uint8_t *) phystokv (0xe0000); ptr < (grub_uint8_t *) phystokv (0x100000);
+ ptr += 16)
+ if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
+ && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+ && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
+ && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
+ && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
+ == 0)
+ return (struct grub_acpi_rsdp_v20 *) ptr;
+ return 0;
+}
diff --git a/i386/i386at/acpihalt.c b/i386/i386at/acpihalt.c
new file mode 100644
index 00000000..23df44ff
--- /dev/null
+++ b/i386/i386at/acpihalt.c
@@ -0,0 +1,409 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/glue.h>
+
+#ifdef GRUB_DSDT_TEST
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#define grub_dprintf(cond, args...) printf ( args )
+#define grub_printf printf
+typedef uint64_t grub_uint64_t;
+typedef uint32_t grub_uint32_t;
+typedef uint16_t grub_uint16_t;
+typedef uint8_t grub_uint8_t;
+
+#endif
+
+#include <grub/acpi.h>
+#ifndef GRUB_DSDT_TEST
+#include <grub/i18n.h>
+#else
+#define _(x) x
+#define N_(x) x
+#endif
+
+#ifndef GRUB_DSDT_TEST
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/time.h>
+#include <grub/cpu/io.h>
+#endif
+
+static inline grub_uint32_t
+decode_length (const grub_uint8_t *ptr, int *numlen)
+{
+ int num_bytes, i;
+ grub_uint32_t ret;
+ if (*ptr < 64)
+ {
+ if (numlen)
+ *numlen = 1;
+ return *ptr;
+ }
+ num_bytes = *ptr >> 6;
+ if (numlen)
+ *numlen = num_bytes + 1;
+ ret = *ptr & 0xf;
+ ptr++;
+ for (i = 0; i < num_bytes; i++)
+ {
+ ret |= *ptr << (8 * i + 4);
+ ptr++;
+ }
+ return ret;
+}
+
+static inline grub_uint32_t
+skip_name_string (const grub_uint8_t *ptr, const grub_uint8_t *end)
+{
+ const grub_uint8_t *ptr0 = ptr;
+
+ while (ptr < end && (*ptr == '^' || *ptr == '\\'))
+ ptr++;
+ switch (*ptr)
+ {
+ case '.':
+ ptr++;
+ ptr += 8;
+ break;
+ case '/':
+ ptr++;
+ ptr += 1 + (*ptr) * 4;
+ break;
+ case 0:
+ ptr++;
+ break;
+ default:
+ ptr += 4;
+ break;
+ }
+ return ptr - ptr0;
+}
+
+static inline grub_uint32_t
+skip_data_ref_object (const grub_uint8_t *ptr, const grub_uint8_t *end)
+{
+ grub_dprintf ("acpi", "data type = 0x%x\n", *ptr);
+ switch (*ptr)
+ {
+ case GRUB_ACPI_OPCODE_PACKAGE:
+ case GRUB_ACPI_OPCODE_BUFFER:
+ return 1 + decode_length (ptr + 1, 0);
+ case GRUB_ACPI_OPCODE_ZERO:
+ case GRUB_ACPI_OPCODE_ONES:
+ case GRUB_ACPI_OPCODE_ONE:
+ return 1;
+ case GRUB_ACPI_OPCODE_BYTE_CONST:
+ return 2;
+ case GRUB_ACPI_OPCODE_WORD_CONST:
+ return 3;
+ case GRUB_ACPI_OPCODE_DWORD_CONST:
+ return 5;
+ case GRUB_ACPI_OPCODE_STRING_CONST:
+ {
+ const grub_uint8_t *ptr0 = ptr;
+ for (ptr++; ptr < end && *ptr; ptr++);
+ if (ptr == end)
+ return 0;
+ return ptr - ptr0 + 1;
+ }
+ default:
+ if (*ptr == '^' || *ptr == '\\' || *ptr == '_'
+ || (*ptr >= 'A' && *ptr <= 'Z'))
+ return skip_name_string (ptr, end);
+ grub_printf ("Unknown opcode 0x%x\n", *ptr);
+ return 0;
+ }
+}
+
+static inline grub_uint32_t
+skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end)
+{
+ const grub_uint8_t *ptr0 = ptr;
+ int add;
+ grub_dprintf ("acpi", "Extended opcode: 0x%x\n", *ptr);
+ switch (*ptr)
+ {
+ case GRUB_ACPI_EXTOPCODE_MUTEX:
+ ptr++;
+ ptr += skip_name_string (ptr, end);
+ ptr++;
+ break;
+ case GRUB_ACPI_EXTOPCODE_EVENT_OP:
+ ptr++;
+ ptr += skip_name_string (ptr, end);
+ break;
+ case GRUB_ACPI_EXTOPCODE_OPERATION_REGION:
+ ptr++;
+ ptr += skip_name_string (ptr, end);
+ ptr++;
+ ptr += add = skip_data_ref_object (ptr, end);
+ if (!add)
+ return 0;
+ ptr += add = skip_data_ref_object (ptr, end);
+ if (!add)
+ return 0;
+ break;
+ case GRUB_ACPI_EXTOPCODE_FIELD_OP:
+ case GRUB_ACPI_EXTOPCODE_DEVICE_OP:
+ case GRUB_ACPI_EXTOPCODE_PROCESSOR_OP:
+ case GRUB_ACPI_EXTOPCODE_POWER_RES_OP:
+ case GRUB_ACPI_EXTOPCODE_THERMAL_ZONE_OP:
+ case GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP:
+ case GRUB_ACPI_EXTOPCODE_BANK_FIELD_OP:
+ ptr++;
+ ptr += decode_length (ptr, 0);
+ break;
+ default:
+ grub_printf ("Unexpected extended opcode: 0x%x\n", *ptr);
+ return 0;
+ }
+ return ptr - ptr0;
+}
+
+static int
+get_sleep_type (grub_uint8_t *table, grub_uint8_t *ptr, grub_uint8_t *end,
+ grub_uint8_t *scope, int scope_len)
+{
+ grub_uint8_t *prev = table;
+
+ if (!ptr)
+ ptr = table + sizeof (struct grub_acpi_table_header);
+ while (ptr < end && prev < ptr)
+ {
+ int add;
+ prev = ptr;
+ grub_dprintf ("acpi", "Opcode 0x%x\n", *ptr);
+ grub_dprintf ("acpi", "Tell %x\n", (unsigned) (ptr - table));
+ switch (*ptr)
+ {
+ case GRUB_ACPI_OPCODE_EXTOP:
+ ptr++;
+ ptr += add = skip_ext_op (ptr, end);
+ if (!add)
+ return -1;
+ break;
+ case GRUB_ACPI_OPCODE_CREATE_WORD_FIELD:
+ case GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD:
+ {
+ ptr += 5;
+ ptr += add = skip_data_ref_object (ptr, end);
+ if (!add)
+ return -1;
+ ptr += 4;
+ break;
+ }
+ case GRUB_ACPI_OPCODE_NAME:
+ ptr++;
+ if ((!scope || grub_memcmp (scope, "\\", scope_len) == 0) &&
+ (grub_memcmp (ptr, "_S5_", 4) == 0 || grub_memcmp (ptr, "\\_S5_", 4) == 0))
+ {
+ int ll;
+ grub_uint8_t *ptr2 = ptr;
+ grub_dprintf ("acpi", "S5 found\n");
+ ptr2 += skip_name_string (ptr, end);
+ if (*ptr2 != 0x12)
+ {
+ grub_printf ("Unknown opcode in _S5: 0x%x\n", *ptr2);
+ return -1;
+ }
+ ptr2++;
+ decode_length (ptr2, &ll);
+ ptr2 += ll;
+ ptr2++;
+ switch (*ptr2)
+ {
+ case GRUB_ACPI_OPCODE_ZERO:
+ return 0;
+ case GRUB_ACPI_OPCODE_ONE:
+ return 1;
+ case GRUB_ACPI_OPCODE_BYTE_CONST:
+ return ptr2[1];
+ default:
+ grub_printf ("Unknown data type in _S5: 0x%x\n", *ptr2);
+ return -1;
+ }
+ }
+ ptr += add = skip_name_string (ptr, end);
+ if (!add)
+ return -1;
+ ptr += add = skip_data_ref_object (ptr, end);
+ if (!add)
+ return -1;
+ break;
+ case GRUB_ACPI_OPCODE_SCOPE:
+ {
+ int scope_sleep_type;
+ int ll;
+ grub_uint8_t *name;
+ int name_len;
+
+ ptr++;
+ add = decode_length (ptr, &ll);
+ name = ptr + ll;
+ name_len = skip_name_string (name, ptr + add);
+ if (!name_len)
+ return -1;
+ scope_sleep_type = get_sleep_type (table, name + name_len,
+ ptr + add, name, name_len);
+ if (scope_sleep_type != -2)
+ return scope_sleep_type;
+ ptr += add;
+ break;
+ }
+ case GRUB_ACPI_OPCODE_IF:
+ case GRUB_ACPI_OPCODE_METHOD:
+ {
+ ptr++;
+ ptr += decode_length (ptr, 0);
+ break;
+ }
+ default:
+ grub_printf ("Unknown opcode 0x%x\n", *ptr);
+ return -1;
+ }
+ }
+
+ return -2;
+}
+
+#ifdef GRUB_DSDT_TEST
+int
+main (int argc, char **argv)
+{
+ FILE *f;
+ size_t len;
+ unsigned char *buf;
+ if (argc < 2)
+ printf ("Usage: %s FILE\n", argv[0]);
+ f = grub_util_fopen (argv[1], "rb");
+ if (!f)
+ {
+ printf ("Couldn't open file\n");
+ return 1;
+ }
+ fseek (f, 0, SEEK_END);
+ len = ftell (f);
+ fseek (f, 0, SEEK_SET);
+ buf = malloc (len);
+ if (!buf)
+ {
+ printf (_("error: %s.\n"), _("out of memory"));
+ fclose (f);
+ return 2;
+ }
+ if (fread (buf, 1, len, f) != len)
+ {
+ printf (_("cannot read `%s': %s"), argv[1], strerror (errno));
+ free (buf);
+ fclose (f);
+ return 2;
+ }
+
+ printf ("Sleep type = %d\n", get_sleep_type (buf, NULL, buf + len, NULL, 0));
+ free (buf);
+ fclose (f);
+ return 0;
+}
+
+#else
+
+void
+grub_acpi_halt (void)
+{
+ struct grub_acpi_rsdp_v20 *rsdp2;
+ struct grub_acpi_rsdp_v10 *rsdp1;
+ struct grub_acpi_table_header *rsdt;
+ grub_uint32_t *entry_ptr;
+ grub_uint32_t port = 0;
+ int sleep_type = -1;
+
+ rsdp2 = grub_acpi_get_rsdpv2 ();
+ if (rsdp2)
+ rsdp1 = &(rsdp2->rsdpv1);
+ else
+ rsdp1 = grub_acpi_get_rsdpv1 ();
+ grub_dprintf ("acpi", "rsdp1=%p\n", rsdp1);
+ if (!rsdp1)
+ return;
+
+ rsdt = (struct grub_acpi_table_header *)
+ io_map_cached (rsdp1->rsdt_addr, sizeof *rsdt);
+ rsdt = (struct grub_acpi_table_header *)
+ io_map_cached (rsdp1->rsdt_addr, rsdt->length);
+
+ for (entry_ptr = (grub_uint32_t *) (rsdt + 1);
+ entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt)
+ + rsdt->length);
+ entry_ptr++)
+ {
+ if (grub_memcmp ((void *) io_map_cached (*entry_ptr, 4),
+ "FACP", 4) == 0)
+ {
+ struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *)
+ io_map_cached (*entry_ptr, sizeof *fadt);
+
+ struct grub_acpi_table_header *dsdt =
+ (struct grub_acpi_table_header *)
+ io_map_cached (fadt->dsdt_addr, sizeof *dsdt);
+ grub_uint8_t *buf = (grub_uint8_t *)
+ io_map_cached (fadt->dsdt_addr, dsdt->length);
+
+ port = fadt->pm1a;
+
+ grub_dprintf ("acpi", "PM1a port=%x\n", port);
+
+ if (grub_memcmp (dsdt->signature, "DSDT",
+ sizeof (dsdt->signature)) == 0
+ && sleep_type < 0)
+ sleep_type = get_sleep_type (buf, NULL, buf + dsdt->length,
+ NULL, 0);
+ }
+ else
+ if (grub_memcmp ((void *) io_map_cached (*entry_ptr, 4), "SSDT", 4) == 0
+ && sleep_type < 0)
+ {
+ struct grub_acpi_table_header *ssdt
+ = (struct grub_acpi_table_header *) (grub_addr_t)
+ io_map_cached (*entry_ptr, sizeof *ssdt);
+ grub_uint8_t *buf = (grub_uint8_t *)
+ io_map_cached (*entry_ptr, ssdt->length);
+
+ grub_dprintf ("acpi", "SSDT = %p\n", ssdt);
+
+ sleep_type = get_sleep_type (buf, NULL, buf + ssdt->length, NULL, 0);
+ }
+ }
+
+ grub_dprintf ("acpi", "SLP_TYP = %d, port = 0x%x\n", sleep_type, port);
+ if (port && sleep_type >= 0 && sleep_type < 8)
+ grub_outw (GRUB_ACPI_SLP_EN | (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET),
+ port & 0xffff);
+
+ grub_millisleep (1500);
+
+ /* TRANSLATORS: It's computer shutdown using ACPI, not disabling ACPI. */
+ grub_puts_ (N_("ACPI shutdown failed"));
+}
+#endif
diff --git a/i386/i386at/acpihalt.h b/i386/i386at/acpihalt.h
new file mode 100644
index 00000000..a4fdb075
--- /dev/null
+++ b/i386/i386at/acpihalt.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2014 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ACPIHALT_H_
+#define _ACPIHALT_H_
+
+void grub_acpi_halt (void);
+
+#endif /* _ACPIHALT_H_ */
diff --git a/i386/i386at/autoconf.c b/i386/i386at/autoconf.c
index 93c71412..908c3ec0 100644
--- a/i386/i386at/autoconf.c
+++ b/i386/i386at/autoconf.c
@@ -38,12 +38,12 @@
#if NCOM > 0
extern struct bus_driver comdriver;
-extern void comintr();
+#include <i386at/com.h>
#endif /* NCOM */
#if NLPR > 0
extern struct bus_driver lprdriver;
-extern void lprintr();
+#include <i386at/lpr.h>
#endif /* NLPR */
struct bus_ctlr bus_master_init[] = {
@@ -92,9 +92,9 @@ struct bus_device bus_device_init[] = {
*/
void probeio(void)
{
- register struct bus_device *device;
- register struct bus_ctlr *master;
- int i = 0;
+ struct bus_device *device;
+ struct bus_ctlr *master;
+ int i = 0;
for (master = bus_master_init; master->driver; master++)
{
@@ -122,7 +122,7 @@ void probeio(void)
}
void take_dev_irq(
- struct bus_device *dev)
+ const struct bus_device *dev)
{
int pic = (int)dev->sysdep1;
@@ -144,7 +144,7 @@ void take_dev_irq(
}
void take_ctlr_irq(
- struct bus_ctlr *ctlr)
+ const struct bus_ctlr *ctlr)
{
int pic = ctlr->sysdep1;
if (intpri[pic] == 0) {
diff --git a/i386/i386at/com.c b/i386/i386at/com.c
index 93c3faaa..84891bd2 100644
--- a/i386/i386at/com.c
+++ b/i386/i386at/com.c
@@ -49,11 +49,7 @@
#include <device/cons.h>
-int comprobe(), commctl();
-void comstart(struct tty *);
-void comstop(), comattach(), comintr();
static void comparam();
-int comgetstat(), comsetstat();
static vm_offset_t com_std[NCOM] = { 0 };
struct bus_device *cominfo[NCOM];
@@ -149,7 +145,7 @@ comprobe_general(struct bus_device *dev, int noisy)
type = "82450 or 16450";
outb(FIFO_CTL(addr), iFIFOENA | iFIFO14CH); /* Enable fifo */
if ((inb(FIFO_CTL(addr)) & iFIFO14CH) != 0)
- { /* Was it successfull */
+ { /* Was it successful */
/* if both bits are not set then broken xx550 */
if ((inb(FIFO_CTL(addr)) & iFIFO14CH) == iFIFO14CH)
{
@@ -173,9 +169,9 @@ comprobe_general(struct bus_device *dev, int noisy)
* all of bus_device_init
*/
int
-comprobe(int port, struct bus_device *dev)
+comprobe(vm_offset_t port, struct bus_ctlr *dev)
{
- return comprobe_general(dev, /*noisy*/ 0);
+ return comprobe_general((struct bus_device *)dev, /*noisy*/ 0);
}
/*
@@ -265,7 +261,7 @@ comcninit(struct consdev *cp)
outb(LINE_CTL(addr), iDLAB);
outb(BAUD_LSB(addr), divisorreg[RCBAUD] & 0xff);
outb(BAUD_MSB(addr), divisorreg[RCBAUD] >>8);
- outb(LINE_CTL(addr), i8BITS);
+ outb(LINE_CTL(addr), i8BITS);
outb(INTR_ENAB(addr), 0);
outb(MODEM_CTL(addr), iDTR|iRTS|iOUT2);
@@ -323,7 +319,7 @@ boolean_t com_reprobe(
}
io_return_t comopen(
- int dev,
+ dev_t dev,
int flag,
io_req_t ior)
{
@@ -342,6 +338,8 @@ io_return_t comopen(
*/
if (!com_reprobe(unit))
return D_NO_SUCH_DEVICE;
+ if ((isai = cominfo[unit]) == 0 || isai->alive == 0)
+ return D_NO_SUCH_DEVICE;
}
tp = &com_tty[unit];
@@ -402,8 +400,8 @@ io_return_t comopen(
return result;
}
-io_return_t comclose(dev, flag)
-int dev;
+void comclose(dev, flag)
+dev_t dev;
int flag;
{
struct tty *tp = &com_tty[minor(dev)];
@@ -418,18 +416,18 @@ int flag;
if (comfifo[minor(dev)] != 0)
outb(INTR_ID(addr), 0x00); /* Disable fifos */
}
- return 0;
+ return;
}
io_return_t comread(dev, ior)
-int dev;
+dev_t dev;
io_req_t ior;
{
return char_read(&com_tty[minor(dev)], ior);
}
io_return_t comwrite(dev, ior)
-int dev;
+dev_t dev;
io_req_t ior;
{
return char_write(&com_tty[minor(dev)], ior);
@@ -466,11 +464,11 @@ natural_t *count; /* out */
}
io_return_t
-comsetstat(dev, flavor, data, count)
-dev_t dev;
-int flavor;
-int * data;
-natural_t count;
+comsetstat(
+ dev_t dev,
+ int flavor,
+ int * data,
+ natural_t count)
{
io_return_t result = D_SUCCESS;
int unit = minor(dev);
@@ -496,10 +494,9 @@ natural_t count;
}
void
-comintr(unit)
-int unit;
+comintr(int unit)
{
- register struct tty *tp = &com_tty[unit];
+ struct tty *tp = &com_tty[unit];
u_short addr = cominfo[unit]->address;
static char comoverrun = 0;
char c, line, intr_id;
@@ -521,10 +518,35 @@ int unit;
case RECi:
case CTIi: /* Character timeout indication */
if (tp->t_state&TS_ISOPEN) {
+ int escape = 0;
while ((line = inb(LINE_STAT(addr))) & iDR) {
c = inb(TXRX(addr));
- ttyinput(c, tp);
+
+ if (c == 0x1b) {
+ escape = 1;
+ continue;
+ }
+
+#if MACH_KDB
+ if (escape && c == 'D'-('A'-1))
+ /* ctrl-alt-d pressed,
+ invoke debugger */
+ kdb_kintr();
+ else
+#endif /* MACH_KDB */
+ if (escape) {
+ ttyinput(0x1b, tp);
+ ttyinput(c, tp);
+ }
+ else
+ ttyinput(c, tp);
+
+ escape = 0;
}
+
+ if (escape)
+ /* just escape */
+ ttyinput(0x1b, tp);
} else
tt_open_wakeup(tp);
break;
@@ -547,8 +569,7 @@ int unit;
}
static void
-comparam(unit)
-register int unit;
+comparam(int unit)
{
struct tty *tp = &com_tty[unit];
u_short addr = (int)tp->t_addr;
@@ -617,10 +638,9 @@ comparm(int unit, int baud, int intr, int mode, int modem)
int comst_1, comst_2, comst_3, comst_4, comst_5 = 14;
void
-comstart(tp)
-struct tty *tp;
+comstart(struct tty *tp)
{
- char nch;
+ int nch;
#if 0
int i;
#endif
@@ -656,6 +676,8 @@ comst_4++;
}
#else
nch = getc(&tp->t_outq);
+ if (nch == -1)
+ return;
if ((nch & 0200) && ((tp->t_flags & LITOUT) == 0)) {
timeout((timer_func_t *)ttrstrt, (char *)tp, (nch & 0x7f) + 6);
tp->t_state |= TS_TIMEOUT;
@@ -698,8 +720,9 @@ printf("Tty %p was stuck\n", tp);
* Set receive modem state from modem status register.
*/
void
-fix_modem_state(unit, modem_stat)
-int unit, modem_stat;
+fix_modem_state(
+ int unit,
+ int modem_stat)
{
int stat = 0;
@@ -751,14 +774,14 @@ commodem_intr(
*/
int
commctl(
- register struct tty *tp,
- int bits,
- int how)
+ struct tty *tp,
+ int bits,
+ int how)
{
spl_t s;
int unit;
vm_offset_t dev_addr;
- register int b = 0; /* Suppress gcc warning */
+ int b = 0; /* Suppress gcc warning */
unit = minor(tp->t_dev);
@@ -817,9 +840,9 @@ commctl(
}
void
-comstop(tp, flags)
-register struct tty *tp;
-int flags;
+comstop(
+ struct tty *tp,
+ int flags)
{
if ((tp->t_state & TS_BUSY) && (tp->t_state & TS_TTSTOP) == 0)
tp->t_state |= TS_FLUSH;
@@ -830,16 +853,16 @@ int flags;
* Code to be called from debugger.
*
*/
-void compr_addr(addr)
+void compr_addr(vm_offset_t addr)
{
/* The two line_stat prints may show different values, since
* touching some of the registers constitutes changing them.
*/
- printf("LINE_STAT(%x) %x\n",
+ printf("LINE_STAT(%lu) %x\n",
LINE_STAT(addr), inb(LINE_STAT(addr)));
- printf("TXRX(%x) %x, INTR_ENAB(%x) %x, INTR_ID(%x) %x, LINE_CTL(%x) %x,\n\
-MODEM_CTL(%x) %x, LINE_STAT(%x) %x, MODEM_STAT(%x) %x\n",
+ printf("TXRX(%lu) %x, INTR_ENAB(%lu) %x, INTR_ID(%lu) %x, LINE_CTL(%lu) %x,\n\
+MODEM_CTL(%lu) %x, LINE_STAT(%lu) %x, MODEM_STAT(%lu) %x\n",
TXRX(addr), inb(TXRX(addr)),
INTR_ENAB(addr), inb(INTR_ENAB(addr)),
INTR_ID(addr), inb(INTR_ID(addr)),
@@ -849,7 +872,7 @@ MODEM_CTL(%x) %x, LINE_STAT(%x) %x, MODEM_STAT(%x) %x\n",
MODEM_STAT(addr),inb(MODEM_STAT(addr)));
}
-int compr(unit)
+int compr(int unit)
{
compr_addr(cominfo[unit]->address);
return(0);
diff --git a/i386/i386at/com.h b/i386/i386at/com.h
index 49f23eec..779cdba8 100644
--- a/i386/i386at/com.h
+++ b/i386/i386at/com.h
@@ -28,6 +28,8 @@
#include <mach/std_types.h>
#include <device/cons.h>
+#include <device/tty.h>
+#include <chips/busses.h>
/*
* Set receive modem state from modem status register.
@@ -47,5 +49,36 @@ extern int comcnprobe(struct consdev *cp);
extern int comcninit(struct consdev *cp);
extern int comcngetc(dev_t dev, int wait);
extern int comcnputc(dev_t dev, int c);
+extern void comintr(int unit);
+
+int comprobe(vm_offset_t port, struct bus_ctlr *dev);
+int commctl(struct tty *tp, int bits, int how);
+void comstart(struct tty *tp);
+void comstop(struct tty *tp, int flags);
+void comattach(struct bus_device *dev);
+
+extern io_return_t
+comgetstat(
+ dev_t dev,
+ int flavor,
+ int *data,
+ natural_t *count);
+
+extern io_return_t
+comsetstat(
+ dev_t dev,
+ int flavor,
+ int *data,
+ natural_t count);
+
+#if MACH_KDB
+extern void kdb_kintr(void);
+#endif /* MACH_KDB */
+
+extern io_return_t comopen(dev_t dev, int flag, io_req_t ior);
+extern void comclose(dev_t dev, int flag);
+extern io_return_t comread(dev_t dev, io_req_t ior);
+extern io_return_t comwrite(dev_t dev, io_req_t ior);
+extern io_return_t comportdeath(dev_t dev, mach_port_t port);
#endif /* _COM_H_ */
diff --git a/i386/i386at/conf.c b/i386/i386at/conf.c
index 83c8dbfc..fe7c7c09 100644
--- a/i386/i386at/conf.c
+++ b/i386/i386at/conf.c
@@ -29,48 +29,42 @@
#include <mach/machine/vm_types.h>
#include <device/conf.h>
+#include <kern/mach_clock.h>
+#include <i386at/model_dep.h>
-extern int timeopen(), timeclose();
-extern vm_offset_t timemmap();
#define timename "time"
#ifndef MACH_HYP
-extern int kdopen(), kdclose(), kdread(), kdwrite();
-extern int kdgetstat(), kdsetstat(), kdportdeath();
-extern vm_offset_t kdmmap();
+#include <i386at/kd.h>
#define kdname "kd"
#if NCOM > 0
-extern int comopen(), comclose(), comread(), comwrite();
-extern int comgetstat(), comsetstat(), comportdeath();
+#include <i386at/com.h>
#define comname "com"
#endif /* NCOM > 0 */
#if NLPR > 0
-extern int lpropen(), lprclose(), lprread(), lprwrite();
-extern int lprgetstat(), lprsetstat(), lprportdeath();
+#include <i386at/lpr.h>
#define lprname "lpr"
#endif /* NLPR > 0 */
#endif /* MACH_HYP */
-extern int kbdopen(), kbdclose(), kbdread();
-extern int kbdgetstat(), kbdsetstat();
+#include <i386at/kd_event.h>
#define kbdname "kbd"
#ifndef MACH_HYP
-extern int mouseopen(), mouseclose(), mouseread(), mousegetstat();
+#include <i386at/kd_mouse.h>
#define mousename "mouse"
-extern vm_offset_t memmmap();
+#include <i386at/mem.h>
#define memname "mem"
#endif /* MACH_HYP */
-extern int kmsgopen(), kmsgclose(), kmsgread(), kmsggetstat();
+#include <device/kmsg.h>
#define kmsgname "kmsg"
#ifdef MACH_HYP
-extern int hypcnopen(), hypcnclose(), hypcnread(), hypcnwrite();
-extern int hypcngetstat(), hypcnsetstat(), hypcnportdeath();
+#include <xen/console.h>
#define hypcnname "hyp"
#endif /* MACH_HYP */
@@ -87,21 +81,27 @@ struct dev_ops dev_name_list[] =
/* We don't assign a console here, when we find one via
cninit() we stick something appropriate here through the
indirect list */
- { "cn", nulldev, nulldev, nulldev,
- nulldev, nulldev, nulldev, nomap,
- nodev, nulldev, nulldev, 0,
+ { "cn", nulldev_open, nulldev_close, nulldev_read,
+ nulldev_write, nulldev_getstat, nulldev_setstat, nomap,
+ nodev, nulldev, nulldev_portdeath, 0,
nodev },
#ifndef MACH_HYP
+#if ENABLE_IMMEDIATE_CONSOLE
+ { "immc", nulldev_open, nulldev_close, nulldev_read,
+ nulldev_write, nulldev_getstat, nulldev_setstat,
+ nomap, nodev, nulldev, nulldev_portdeath, 0,
+ nodev },
+#endif /* ENABLE_IMMEDIATE_CONSOLE */
{ kdname, kdopen, kdclose, kdread,
kdwrite, kdgetstat, kdsetstat, kdmmap,
nodev, nulldev, kdportdeath, 0,
nodev },
#endif /* MACH_HYP */
- { timename, timeopen, timeclose, nulldev,
- nulldev, nulldev, nulldev, timemmap,
- nodev, nulldev, nulldev, 0,
+ { timename, timeopen, timeclose, nulldev_read,
+ nulldev_write, nulldev_getstat, nulldev_setstat, timemmap,
+ nodev, nulldev, nulldev_portdeath, 0,
nodev },
#ifndef MACH_HYP
@@ -120,25 +120,25 @@ struct dev_ops dev_name_list[] =
#endif
{ mousename, mouseopen, mouseclose, mouseread,
- nodev, mousegetstat, nulldev, nomap,
- nodev, nulldev, nulldev, 0,
+ nulldev_write, mousegetstat, nulldev_setstat, nomap,
+ nodev, nulldev, nulldev_portdeath, 0,
nodev },
{ kbdname, kbdopen, kbdclose, kbdread,
- nodev, kbdgetstat, kbdsetstat, nomap,
- nodev, nulldev, nulldev, 0,
+ nulldev_write, kbdgetstat, kbdsetstat, nomap,
+ nodev, nulldev, nulldev_portdeath, 0,
nodev },
- { memname, nulldev, nulldev, nodev,
- nodev, nodev, nodev, memmmap,
- nodev, nulldev, nulldev, 0,
+ { memname, nulldev_open, nulldev_close, nulldev_read,
+ nulldev_write, nulldev_getstat, nulldev_setstat, memmmap,
+ nodev, nulldev, nulldev_portdeath, 0,
nodev },
#endif /* MACH_HYP */
#ifdef MACH_KMSG
{ kmsgname, kmsgopen, kmsgclose, kmsgread,
- nodev, kmsggetstat, nodev, nomap,
- nodev, nulldev, nulldev, 0,
+ nulldev_write, kmsggetstat, nulldev_setstat, nomap,
+ nodev, nulldev, nulldev_portdeath, 0,
nodev },
#endif
diff --git a/i386/i386at/cons_conf.c b/i386/i386at/cons_conf.c
index cf42bb63..1d7dd387 100644
--- a/i386/i386at/cons_conf.c
+++ b/i386/i386at/cons_conf.c
@@ -39,6 +39,10 @@
#endif
#endif /* MACH_HYP */
+#if ENABLE_IMMEDIATE_CONSOLE
+#include "immc.h"
+#endif /* ENABLE_IMMEDIATE_CONSOLE */
+
/*
* The rest of the consdev fields are filled in by the respective
* cnprobe routine.
@@ -47,6 +51,9 @@ struct consdev constab[] = {
#ifdef MACH_HYP
{"hyp", hypcnprobe, hypcninit, hypcngetc, hypcnputc},
#else /* MACH_HYP */
+#if ENABLE_IMMEDIATE_CONSOLE
+ {"immc", immc_cnprobe, immc_cninit, immc_cngetc, immc_cnputc},
+#endif /* ENABLE_IMMEDIATE_CONSOLE */
{"kd", kdcnprobe, kdcninit, kdcngetc, kdcnputc},
#if NCOM > 0
{"com", comcnprobe, comcninit, comcngetc, comcnputc},
diff --git a/i386/i386at/cram.h b/i386/i386at/cram.h
index 8373ce03..40f3f0a5 100644
--- a/i386/i386at/cram.h
+++ b/i386/i386at/cram.h
@@ -50,6 +50,9 @@ NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifndef _CRAM_H_
+#define _CRAM_H_
+
/*
* outb(CMOS_ADDR, addr);
* result = inb(CMOS_DATA);
@@ -73,3 +76,4 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define CM_CGA_80 0x20
#define CM_MONO_80 0x30
+#endif /* _CRAM_H_ */
diff --git a/i386/i386at/disk.h b/i386/i386at/disk.h
index e1fe6b98..63d033f0 100644
--- a/i386/i386at/disk.h
+++ b/i386/i386at/disk.h
@@ -49,6 +49,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* disk.h
*/
+#ifndef _DISK_H_
+#define _DISK_H_
+
/* Grab the public part. */
#include <mach/machine/disk.h>
@@ -184,3 +187,4 @@ struct mboot { /* master boot block */
u_short signature;
};
+#endif /* _DISK_H_ */
diff --git a/i386/i386at/grub_glue.c b/i386/i386at/grub_glue.c
new file mode 100644
index 00000000..68a4cb1f
--- /dev/null
+++ b/i386/i386at/grub_glue.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <kern/printf.h>
+#include <stdarg.h>
+#include <i386/vm_param.h>
+
+#include <grub/glue.h>
+#include <grub/acpi.h>
+
+#define GRUB_DEBUG 0
+
+void
+grub_real_dprintf (const char *file, const int line, const char *condition,
+ const char *fmt, ...)
+{
+#if GRUB_DEBUG
+ va_list listp;
+ va_start(listp, fmt);
+ vprintf (fmt, listp);
+ va_end(listp);
+#endif
+}
+
+void
+grub_millisleep (grub_uint32_t ms)
+{
+ /* Do nothing. */
+}
+
+struct grub_acpi_rsdp_v20 *
+grub_acpi_get_rsdpv2 (void)
+{
+ return grub_machine_acpi_get_rsdpv2 ();
+}
+
+struct grub_acpi_rsdp_v10 *
+grub_acpi_get_rsdpv1 (void)
+{
+ return grub_machine_acpi_get_rsdpv1 ();
+}
+
+/* Simple checksum by summing all bytes. Used by ACPI and SMBIOS. */
+grub_uint8_t
+grub_byte_checksum (void *base, grub_size_t size)
+{
+ grub_uint8_t *ptr;
+ grub_uint8_t ret = 0;
+ for (ptr = (grub_uint8_t *) base; ptr < ((grub_uint8_t *) base) + size;
+ ptr++)
+ ret += *ptr;
+ return ret;
+}
diff --git a/i386/i386at/i8250.h b/i386/i386at/i8250.h
index fa81173e..9b8a8019 100644
--- a/i386/i386at/i8250.h
+++ b/i386/i386at/i8250.h
@@ -49,6 +49,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* Header file for i8250 chip
*/
+#ifndef _I8250_H_
+#define _I8250_H_
+
/* port offsets from the base i/o address */
#define RDAT 0
@@ -127,3 +130,5 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define BCNT2400 0x30
#define BCNT4800 0x18
#define BCNT9600 0x0c
+
+#endif /* _I8250_H_ */
diff --git a/i386/i386at/idt.h b/i386/i386at/idt.h
index 1b3284fa..56e6296c 100644
--- a/i386/i386at/idt.h
+++ b/i386/i386at/idt.h
@@ -36,6 +36,6 @@
#ifndef __ASSEMBLER__
extern void idt_init (void);
-#endif
+#endif /* __ASSEMBLER__ */
#endif /* _I386AT_IDT_ */
diff --git a/i386/i386at/immc.c b/i386/i386at/immc.c
index db64620e..bd61522d 100644
--- a/i386/i386at/immc.c
+++ b/i386/i386at/immc.c
@@ -21,8 +21,11 @@
* Author: Bryan Ford, University of Utah CSL
*/
-#ifdef ENABLE_IMMEDIATE_CONSOLE
+#if ENABLE_IMMEDIATE_CONSOLE
+#include <device/cons.h>
+#include <mach/boolean.h>
+#include <i386/vm_param.h>
#include <string.h>
/* This is a special "feature" (read: kludge)
@@ -33,24 +36,67 @@
so it can be used to debug things that happen very early
before any devices are initialized. */
-int immediate_console_enable = 1;
+boolean_t immediate_console_enable = TRUE;
-void
-immc_cnputc(unsigned char c)
+/*
+ * XXX we assume that pcs *always* have a console
+ */
+int
+immc_cnprobe(struct consdev *cp)
+{
+ int maj, unit, pri;
+
+ maj = 0;
+ unit = 0;
+ pri = CN_INTERNAL;
+
+ cp->cn_dev = makedev(maj, unit);
+ cp->cn_pri = pri;
+ return 0;
+}
+
+int
+immc_cninit(struct consdev *cp)
+{
+ return 0;
+}
+
+int immc_cnmaygetc(void)
+{
+ return -1;
+}
+
+int
+immc_cngetc(dev_t dev, int wait)
+{
+ if (wait) {
+ int c;
+ while ((c = immc_cnmaygetc()) < 0)
+ continue;
+ return c;
+ }
+ else
+ return immc_cnmaygetc();
+}
+
+int
+immc_cnputc(dev_t dev, int c)
{
static int ofs = -1;
if (!immediate_console_enable)
- return;
- if (ofs < 0)
+ return -1;
+ if (ofs < 0 || ofs >= 80)
{
ofs = 0;
- immc_cnputc('\n');
+ immc_cnputc(dev, '\n');
}
- else if (c == '\n')
+
+ if (c == '\n')
{
- memmove(0xb8000, 0xb8000+80*2, 80*2*24);
- memset(0xb8000+80*2*24, 0, 80*2);
+ memmove((void *) phystokv(0xb8000),
+ (void *) phystokv(0xb8000+80*2), 80*2*24);
+ memset((void *) phystokv((0xb8000+80*2*24)), 0, 80*2);
ofs = 0;
}
else
@@ -59,20 +105,22 @@ immc_cnputc(unsigned char c)
if (ofs >= 80)
{
- immc_cnputc('\r');
- immc_cnputc('\n');
+ immc_cnputc(dev, '\r');
+ immc_cnputc(dev, '\n');
}
- p = (void*)0xb8000 + 80*2*24 + ofs*2;
+ p = (void *) phystokv(0xb8000 + 80*2*24 + ofs*2);
p[0] = c;
p[1] = 0x0f;
ofs++;
}
+ return 0;
}
-int immc_cnmaygetc(void)
+void
+immc_romputc(char c)
{
- return -1;
+ immc_cnputc (0, c);
}
#endif /* ENABLE_IMMEDIATE_CONSOLE */
diff --git a/i386/i386at/immc.h b/i386/i386at/immc.h
new file mode 100644
index 00000000..dc802c84
--- /dev/null
+++ b/i386/i386at/immc.h
@@ -0,0 +1,31 @@
+/* Declarations for the immediate console.
+
+ Copyright (C) 2015 Free Software Foundation, Inc.
+
+ This file is part of the GNU Mach.
+
+ The GNU Mach is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Mach is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the GNU Mach. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _IMMC_H_
+#define _IMMC_H_
+
+#include <sys/types.h>
+
+int immc_cnprobe(struct consdev *cp);
+int immc_cninit(struct consdev *cp);
+int immc_cngetc(dev_t dev, int wait);
+int immc_cnputc(dev_t dev, int c);
+void immc_romputc(char c);
+
+#endif /* _IMMC_H_ */
diff --git a/i386/i386at/int_init.c b/i386/i386at/int_init.c
index 0f00b868..43daad8b 100644
--- a/i386/i386at/int_init.c
+++ b/i386/i386at/int_init.c
@@ -27,7 +27,7 @@
/* defined in locore.S */
extern vm_offset_t int_entry_table[];
-void int_init()
+void int_init(void)
{
int i;
diff --git a/i386/i386at/int_init.h b/i386/i386at/int_init.h
index f4abef0b..f9b03b74 100644
--- a/i386/i386at/int_init.h
+++ b/i386/i386at/int_init.h
@@ -29,6 +29,6 @@
#ifndef __ASSEMBLER__
extern void int_init (void);
-#endif
+#endif /* __ASSEMBLER__ */
#endif /* _INT_INIT_H_ */
diff --git a/i386/i386at/kd.c b/i386/i386at/kd.c
index c9778629..5656e830 100644
--- a/i386/i386at/kd.c
+++ b/i386/i386at/kd.c
@@ -83,7 +83,7 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <device/conf.h>
#include <device/tty.h>
#include <device/io_req.h>
-#include <device/buf.h> /* for struct uio (!) */
+#include <device/buf.h>
#include <vm/vm_kern.h>
#include <i386/locore.h>
#include <i386/loose_ends.h>
@@ -100,20 +100,15 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define DEBUG 1 /* export feep() */
-void kd_enqsc(); /* enqueues a scancode */
-
#if 0
#define BROKEN_KEYBOARD_RESET
#endif
struct tty kd_tty;
-extern int rebootflag;
+extern boolean_t rebootflag;
static void charput(), charmvup(), charmvdown(), charclear(), charsetcursor();
-static void kd_noopreset();
-boolean_t kdcheckmagic();
-
-int do_modifier (int, Scancode, boolean_t);
+static void kd_noopreset(void);
/*
* These routines define the interface to the device-specific layer.
@@ -127,10 +122,6 @@ void (*kd_dsetcursor)() = charsetcursor;
/* set cursor position on displayed page */
void (*kd_dreset)() = kd_noopreset; /* prepare for reboot */
-/* forward declarations */
-unsigned char kd_getdata(), state2leds();
-
-
/*
* Globals used for both character-based controllers and bitmap-based
* controllers. Default is EGA.
@@ -213,7 +204,7 @@ u_char *esc_spt = (u_char *)0;
- Delete returns `ESC [ 9' instead of 0x7f.
- Alt + function keys return key sequences that are different
from the key sequences returned by the function keys alone.
- This is done with the idea of alowing a terminal server to
+ This is done with the idea of allowing a terminal server to
implement multiple virtual consoles mapped on Alt+F1, Alt+F2,
etc, as in Linux.
@@ -249,8 +240,7 @@ unsigned char key_map[NUMKEYS][WIDTH_KMAP] = {
{K_LBRKT,NC,NC, K_LBRACE,NC,NC, K_ESC,NC,NC, 0x1b,K_LBRKT,NC, 0x1b,0x4e,K_LBRACE},
{K_RBRKT,NC,NC, K_RBRACE,NC,NC, K_GS,NC,NC, 0x1b,K_RBRKT,NC, 0x1b,0x4e,K_RBRACE},
{K_CR,NC,NC, K_CR,NC,NC, K_CR,NC,NC, 0x1b,K_CR,NC, K_CR,NC,NC},
-{K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC,
- K_SCAN,K_CTLSC,NC},
+{K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC},
{K_a,NC,NC, K_A,NC,NC, K_SOH,NC,NC, 0x1b,K_a,NC, 0x1b,0x4e,K_A},
{K_s,NC,NC, K_S,NC,NC, K_DC3,NC,NC, 0x1b,K_s,NC, 0x1b,0x4e,K_S},
{K_d,NC,NC, K_D,NC,NC, K_EOT,NC,NC, 0x1b,K_d,NC, 0x1b,0x4e,K_D},
@@ -263,8 +253,7 @@ unsigned char key_map[NUMKEYS][WIDTH_KMAP] = {
{K_SEMI,NC,NC, K_COLON,NC,NC, K_SEMI,NC,NC, 0x1b,K_SEMI,NC, 0x1b,0x4e,K_COLON},
{K_SQUOTE,NC,NC,K_DQUOTE,NC,NC, K_SQUOTE,NC,NC,0x1b,K_SQUOTE,NC, 0x1b,0x4e,K_DQUOTE},
{K_GRAV,NC,NC, K_TILDE,NC,NC, K_RS,NC,NC, 0x1b,K_GRAV,NC, 0x1b,0x4e,K_TILDE},
-{K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC,
- K_SCAN,K_LSHSC,NC},
+{K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC},
{K_BSLSH,NC,NC, K_PIPE,NC,NC, K_FS,NC,NC, 0x1b,K_BSLSH,NC, 0x1b,0x4e,K_PIPE},
{K_z,NC,NC, K_Z,NC,NC, K_SUB,NC,NC, 0x1b,K_z,NC, 0x1b,0x4e,K_Z},
{K_x,NC,NC, K_X,NC,NC, K_CAN,NC,NC, 0x1b,K_x,NC, 0x1b,0x4e,K_X},
@@ -276,14 +265,11 @@ unsigned char key_map[NUMKEYS][WIDTH_KMAP] = {
{K_COMMA,NC,NC, K_LTHN,NC,NC, K_COMMA,NC,NC, 0x1b,K_COMMA,NC, 0x1b,0x4e,K_LTHN},
{K_PERIOD,NC,NC,K_GTHN,NC,NC, K_PERIOD,NC,NC,0x1b,K_PERIOD,NC, 0x1b,0x4e,K_GTHN},
{K_SLASH,NC,NC, K_QUES,NC,NC, K_SLASH,NC,NC, 0x1b,K_SLASH,NC, 0x1b,0x4e,K_QUES},
-{K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC,
- K_SCAN,K_RSHSC,NC},
+{K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC},
{K_ASTER,NC,NC, K_ASTER,NC,NC, K_ASTER,NC,NC, 0x1b,K_ASTER,NC, 0x1b,0x4e,K_ASTER},
-{K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC,
- K_SCAN,K_ALTSC,NC},
+{K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC},
{K_SPACE,NC,NC, K_SPACE,NC,NC, K_NUL,NC,NC, 0x1b,K_SPACE,NC, K_SPACE,NC,NC},
-{K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC,
- K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC},
+{K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC},
{K_F1, K_F1S, K_F1, K_F1A, K_F1S},
{K_F2, K_F2S, K_F2, K_F2A, K_F2S},
{K_F3, K_F3S, K_F3, K_F3A, K_F3S},
@@ -294,20 +280,16 @@ unsigned char key_map[NUMKEYS][WIDTH_KMAP] = {
{K_F8, K_F8S, K_F8, K_F8A, K_F8S},
{K_F9, K_F9S, K_F9, K_F9A, K_F9S},
{K_F10, K_F10S, K_F10, K_F10A, K_F10S},
-{K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC,
- K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC},
+{K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC},
{K_SCRL, K_NUL,NC,NC, K_SCRL, K_SCRL, K_NUL,NC,NC},
{K_HOME, K_SEVEN,NC,NC, K_HOME, K_HOME, 0x1b,0x4e,K_SEVEN},
{K_UA, K_EIGHT,NC,NC, K_UA, K_UA, 0x1b,0x4e,K_EIGHT},
{K_PUP, K_NINE,NC,NC, K_PUP, K_PUP, 0x1b,0x4e,K_NINE},
-{0x1b,0x5b,0x53, K_MINUS,NC,NC, 0x1b,0x5b,0x53, 0x1b,0x5b,0x53,
- 0x1b,0x4e,0x2d},
+{0x1b,0x5b,0x53, K_MINUS,NC,NC, 0x1b,0x5b,0x53, 0x1b,0x5b,0x53, 0x1b,0x4e,0x2d},
{K_LA, K_FOUR,NC,NC, K_LA, K_LA, 0x1b,0x4e,K_FOUR},
-{0x1b,0x5b,0x47, K_FIVE,NC,NC, 0x1b,0x5b,0x47, 0x1b,0x5b,0x47,
- 0x1b,0x4e,0x35},
+{0x1b,0x5b,0x47, K_FIVE,NC,NC, 0x1b,0x5b,0x47, 0x1b,0x5b,0x47, 0x1b,0x4e,0x35},
{K_RA, K_SIX,NC,NC, K_RA, K_RA, 0x1b,0x4e,K_SIX},
-{0x1b,0x5b,0x54, K_PLUS,NC,NC, 0x1b,0x5b,0x54, 0x1b,0x5b,0x54,
- 0x1b,0x4e,0x2b},
+{0x1b,0x5b,0x54, K_PLUS,NC,NC, 0x1b,0x5b,0x54, 0x1b,0x5b,0x54, 0x1b,0x4e,0x2b},
{K_END, K_ONE,NC,NC, K_END, K_END, 0x1b,0x4e,K_ONE},
{K_DA, K_TWO,NC,NC, K_DA, K_DA, 0x1b,0x4e,K_TWO},
{K_PDN, K_THREE,NC,NC, K_PDN, K_PDN, 0x1b,0x4e,K_THREE},
@@ -367,7 +349,7 @@ int kd_pollc = 0;
* Warning: uses outb(). You may prefer to use kd_debug_put.
*/
void
-feep()
+feep(void)
{
int i;
@@ -378,7 +360,7 @@ feep()
}
void
-pause()
+pause(void)
{
int i;
@@ -392,9 +374,9 @@ pause()
* one column to the left, etc.
*/
void
-kd_debug_put(loc, c)
-int loc;
-char c;
+kd_debug_put(
+ int loc,
+ char c)
{
csrpos_t pos = ONE_PAGE - (loc+1) * ONE_SPACE;
@@ -403,12 +385,11 @@ char c;
#endif /* DEBUG */
-extern int mouse_in_use;
-int old_kb_mode;
+extern boolean_t mouse_in_use;
+int old_kb_mode;
void
-cnpollc(on)
-boolean_t on;
+cnpollc(boolean_t on)
{
if (mouse_in_use) {
if (on) {
@@ -449,15 +430,13 @@ boolean_t on;
*
*/
int
-kdopen(dev, flag, ior)
- dev_t dev;
- int flag;
- io_req_t ior;
+kdopen(
+ dev_t dev,
+ int flag,
+ io_req_t ior)
{
struct tty *tp;
- void kdstart();
spl_t o_pri;
- void kdstop();
tp = &kd_tty;
o_pri = spltty();
@@ -498,7 +477,7 @@ kdopen(dev, flag, ior)
/*ARGSUSED*/
void
kdclose(dev, flag)
-int dev;
+dev_t dev;
int flag;
{
struct tty *tp;
@@ -530,8 +509,8 @@ int flag;
/*ARGSUSED*/
int
kdread(dev, uio)
-int dev;
-struct uio *uio;
+dev_t dev;
+io_req_t uio;
{
struct tty *tp;
@@ -555,8 +534,8 @@ struct uio *uio;
/*ARGSUSED*/
int
kdwrite(dev, uio)
-int dev;
-struct uio *uio;
+dev_t dev;
+io_req_t uio;
{
return((*linesw[kd_tty.t_line].l_write)(&kd_tty, uio));
}
@@ -569,10 +548,10 @@ struct uio *uio;
int
kdmmap(dev, off, prot)
dev_t dev;
- off_t off;
- int prot;
+ vm_offset_t off;
+ vm_prot_t prot;
{
- if ((u_int) off >= (128*1024))
+ if (off >= (128*1024))
return(-1);
/* Get page frame number for the page to be mapped. */
@@ -580,19 +559,19 @@ kdmmap(dev, off, prot)
}
int
-kdportdeath(dev, port)
- dev_t dev;
- mach_port_t port;
+kdportdeath(
+ dev_t dev,
+ mach_port_t port)
{
return (tty_portdeath(&kd_tty, (ipc_port_t)port));
}
/*ARGSUSED*/
-io_return_t kdgetstat(dev, flavor, data, count)
- dev_t dev;
- int flavor;
- int * data; /* pointer to OUT array */
- natural_t *count; /* OUT */
+io_return_t kdgetstat(
+ dev_t dev,
+ int flavor,
+ int * data, /* pointer to OUT array */
+ natural_t *count) /* OUT */
{
io_return_t result;
@@ -618,11 +597,11 @@ io_return_t kdgetstat(dev, flavor, data, count)
}
/*ARGSUSED*/
-io_return_t kdsetstat(dev, flavor, data, count)
- dev_t dev;
- int flavor;
- int * data;
- natural_t count;
+io_return_t kdsetstat(
+ dev_t dev,
+ int flavor,
+ int * data,
+ natural_t count)
{
io_return_t result;
@@ -655,13 +634,12 @@ io_return_t kdsetstat(dev, flavor, data, count)
* on/off value.
*/
int
-kdsetbell(val, flags)
-int val; /* on or off */
-int flags; /* flags set for console */
+kdsetbell(
+ int val, /* on or off */
+ int flags) /* flags set for console */
{
int err = 0;
-
if (val == KD_BELLON)
kd_bellon();
else if (val == KD_BELLOFF)
@@ -672,15 +650,13 @@ int flags; /* flags set for console */
return(err);
}
-
/*
* kdgetkbent:
*
* Get entry from key mapping table. Returns error code, if any.
*/
int
-kdgetkbent(kbent)
-struct kbentry * kbent;
+kdgetkbent(struct kbentry *kbent)
{
u_char *cp;
spl_t o_pri = SPLKD(); /* probably superfluous */
@@ -700,9 +676,9 @@ struct kbentry * kbent;
* Set entry in key mapping table. Return error code, if any.
*/
int
-kdsetkbent(kbent, flags)
-struct kbentry * kbent;
-int flags; /* flags set for console */
+kdsetkbent(
+ struct kbentry *kbent,
+ int flags) /* flags set for console */
{
u_char *cp;
spl_t o_pri;
@@ -732,15 +708,14 @@ int flags; /* flags set for console */
*/
/*ARGSUSED*/
void
-kdintr(vec)
-int vec;
+kdintr(int vec)
{
struct tty *tp;
unsigned char c;
unsigned char scancode;
- int char_idx;
+ unsigned int char_idx;
boolean_t up = FALSE; /* key-up event */
- extern int mouse_in_use;
+
if (kd_pollc)
return; /* kdb polling kbd */
@@ -749,7 +724,8 @@ int vec;
tp = &kd_tty;
#ifdef old
- while ((inb(K_STATUS) & K_OBUF_FUL) == 0); /* this should never loop */
+ while ((inb(K_STATUS) & K_OBUF_FUL) == 0)
+ ; /* this should never loop */
#else /* old */
{
/*
@@ -818,7 +794,7 @@ int vec;
set_kd_state(do_modifier(kd_state, c, up));
} else if (!up) {
/* regular key-down */
- int max; /* max index for char sequence */
+ unsigned int max; /* max index for char sequence */
max = char_idx + NUMOUTPUT;
char_idx++;
@@ -873,7 +849,7 @@ int vec;
* drop the ack on the floor.
*/
void
-kd_handle_ack()
+kd_handle_ack(void)
{
switch (kd_ack) {
case SET_LEDS:
@@ -898,7 +874,7 @@ kd_handle_ack()
* Resend a missed keyboard command or data byte.
*/
void
-kd_resend()
+kd_resend(void)
{
if (kd_ack == NOT_WAITING)
printf("unexpected RESEND from keyboard\n");
@@ -919,10 +895,10 @@ kd_resend()
* output: the new state
*/
int
-do_modifier(state, c, up)
-int state;
-Scancode c;
-boolean_t up;
+do_modifier(
+ int state,
+ Scancode c,
+ boolean_t up)
{
switch (c) {
case (K_ALTSC):
@@ -984,12 +960,10 @@ boolean_t up;
* are still held down.
*/
boolean_t
-kdcheckmagic(scancode)
-Scancode scancode;
+kdcheckmagic(Scancode scancode)
{
static int magic_state = KS_NORMAL; /* like kd_state */
boolean_t up = FALSE;
- extern int rebootflag;
if (scancode == 0x46) /* scroll lock */
/* if (scancode == 0x52) ** insert key */
@@ -1040,9 +1014,9 @@ Scancode scancode;
* Return the value for the 2nd index into key_map that
* corresponds to the given state.
*/
-int
+unsigned int
kdstate2idx(state, extended)
-int state; /* bit vector, not a state index */
+unsigned int state; /* bit vector, not a state index */
boolean_t extended;
{
int state_idx = NORM_STATE;
@@ -1081,8 +1055,7 @@ boolean_t extended;
* ASSUMES that it is never called from interrupt-driven code.
*/
void
-kdstart(tp)
-struct tty *tp;
+kdstart(struct tty *tp)
{
spl_t o_pri;
int ch;
@@ -1132,9 +1105,9 @@ struct tty *tp;
/*ARGSUSED*/
void
-kdstop(tp, flags)
- register struct tty *tp;
- int flags;
+kdstop(
+ struct tty *tp,
+ int flags)
{
/*
* do nothing - all characters are output by one call to
@@ -1159,9 +1132,8 @@ kdstop(tp, flags)
*
*/
void
-kdinit()
+kdinit(void)
{
- void kd_xga_init();
unsigned char k_comm; /* keyboard command byte */
if (kd_initialized)
@@ -1190,19 +1162,19 @@ kdinit()
kd_senddata(k_comm);
kd_initialized = TRUE;
-#ifdef ENABLE_IMMEDIATE_CONSOLE
+#if ENABLE_IMMEDIATE_CONSOLE
/* Now that we're set up, we no longer need or want the
immediate console. */
{
- extern int immediate_console_enable;
- immediate_console_enable = 0;
+ extern boolean_t immediate_console_enable;
+ immediate_console_enable = FALSE;
}
/* The immediate console printed stuff at the bottom of the
screen rather than at the cursor position, so that's where
we should start. */
kd_setpos(ONE_PAGE - ONE_LINE); printf("\n");
-#endif
+#endif /* ENABLE_IMMEDIATE_CONSOLE */
cnsetleds(kd_state = KS_NORMAL);
/* clear the LEDs AFTER we
@@ -1224,7 +1196,7 @@ kdinit()
* output : bell is turned off
*
*/
-static unsigned int kd_bellstate = 0;
+static boolean_t kd_bellstate = FALSE;
void
kd_belloff(void * param)
@@ -1233,7 +1205,7 @@ kd_belloff(void * param)
status = (inb(K_PORTB) & ~(K_SPKRDATA | K_ENABLETMR2));
outb(K_PORTB, status);
- kd_bellstate = 0;
+ kd_bellstate = FALSE;
return;
}
@@ -1248,7 +1220,7 @@ kd_belloff(void * param)
*
*/
void
-kd_bellon()
+kd_bellon(void)
{
unsigned char status;
@@ -1278,8 +1250,7 @@ kd_bellon()
int sit_for_0 = 1;
void
-kd_putc(ch)
-u_char ch;
+kd_putc(u_char ch)
{
if ((!ch) && sit_for_0)
return;
@@ -1306,7 +1277,7 @@ u_char ch;
{
kd_bellon();
timeout(kd_belloff, 0, hz/8 );
- kd_bellstate = 1;
+ kd_bellstate = TRUE;
}
break;
default:
@@ -1332,8 +1303,7 @@ u_char ch;
*
*/
void
-kd_setpos(newpos)
-csrpos_t newpos;
+kd_setpos(csrpos_t newpos)
{
if (newpos > ONE_PAGE) {
kd_scrollup();
@@ -1359,7 +1329,7 @@ csrpos_t newpos;
*
*/
void
-kd_scrollup()
+kd_scrollup(void)
{
csrpos_t to;
csrpos_t from;
@@ -1389,7 +1359,7 @@ kd_scrollup()
*
*/
void
-kd_scrolldn()
+kd_scrolldn(void)
{
csrpos_t to;
csrpos_t from;
@@ -1423,7 +1393,7 @@ kd_scrolldn()
*
*/
void
-kd_parseesc()
+kd_parseesc(void)
{
u_char *escp;
@@ -1495,8 +1465,7 @@ unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
*
*/
void
-kd_parserest(cp)
-u_char *cp;
+kd_parserest(u_char *cp)
{
int number[16], npar = 0, i;
csrpos_t newpos;
@@ -1760,7 +1729,7 @@ u_char *cp;
}
void
-kd_tab()
+kd_tab(void)
{
int i;
@@ -1781,7 +1750,7 @@ kd_tab()
*
*/
void
-kd_cls()
+kd_cls(void)
{
(*kd_dclear)(0, ONE_PAGE/ONE_SPACE, kd_attr);
return;
@@ -1799,7 +1768,7 @@ kd_cls()
*
*/
void
-kd_home()
+kd_home(void)
{
kd_setpos(0);
return;
@@ -1816,7 +1785,7 @@ kd_home()
*
*/
void
-kd_up()
+kd_up(void)
{
if (kd_curpos < ONE_LINE)
kd_scrolldn();
@@ -1836,7 +1805,7 @@ kd_up()
*
*/
void
-kd_down()
+kd_down(void)
{
if (kd_curpos >= (ONE_PAGE - ONE_LINE))
kd_scrollup();
@@ -1856,7 +1825,7 @@ kd_down()
*
*/
void
-kd_right()
+kd_right(void)
{
if (kd_curpos < (ONE_PAGE - ONE_SPACE))
kd_setpos(kd_curpos + ONE_SPACE);
@@ -1878,7 +1847,7 @@ kd_right()
*
*/
void
-kd_left()
+kd_left(void)
{
if (0 < kd_curpos)
kd_setpos(kd_curpos - ONE_SPACE);
@@ -1897,7 +1866,7 @@ kd_left()
*
*/
void
-kd_cr()
+kd_cr(void)
{
kd_setpos(BEG_OF_LINE(kd_curpos));
return;
@@ -1911,11 +1880,11 @@ kd_cr()
* of the screen.
*
* input : None
- * output : Screen is cleared from current cursor postion to bottom
+ * output : Screen is cleared from current cursor position to bottom
*
*/
void
-kd_cltobcur()
+kd_cltobcur(void)
{
csrpos_t start;
int count;
@@ -1934,11 +1903,11 @@ kd_cltobcur()
* of the screen.
*
* input : None
- * output : Screen is cleared from current cursor postion to top
+ * output : Screen is cleared from current cursor position to top
*
*/
void
-kd_cltopcur()
+kd_cltopcur(void)
{
int count;
@@ -1958,7 +1927,7 @@ kd_cltopcur()
*
*/
void
-kd_cltoecur()
+kd_cltoecur(void)
{
csrpos_t i;
csrpos_t hold;
@@ -1981,7 +1950,7 @@ kd_cltoecur()
*
*/
void
-kd_clfrbcur()
+kd_clfrbcur(void)
{
csrpos_t i;
@@ -2002,8 +1971,7 @@ kd_clfrbcur()
*
*/
void
-kd_delln(number)
-int number;
+kd_delln(int number)
{
csrpos_t to;
csrpos_t from;
@@ -2041,8 +2009,7 @@ int number;
*
*/
void
-kd_insln(number)
-int number;
+kd_insln(int number)
{
csrpos_t to;
csrpos_t from;
@@ -2081,12 +2048,11 @@ int number;
*
*/
void
-kd_delch(number)
-int number;
+kd_delch(int number)
{
- int count; /* num words moved/filled */
- int delbytes; /* bytes to delete */
- register csrpos_t to;
+ int count; /* num words moved/filled */
+ int delbytes; /* bytes to delete */
+ csrpos_t to;
csrpos_t from;
csrpos_t nextline; /* start of next line */
@@ -2123,8 +2089,7 @@ int number;
*
*/
void
-kd_erase(number)
-int number;
+kd_erase(int number)
{
csrpos_t i;
csrpos_t stop;
@@ -2149,7 +2114,7 @@ int number;
*
*/
void
-kd_eraseln()
+kd_eraseln(void)
{
csrpos_t i;
csrpos_t stop;
@@ -2173,8 +2138,7 @@ kd_eraseln()
*
*/
void
-kd_insch(number)
-int number;
+kd_insch(int number)
{
csrpos_t to;
csrpos_t from;
@@ -2215,8 +2179,7 @@ int number;
*
*/
boolean_t
-kd_isupper(c)
-u_char c;
+kd_isupper(u_char c)
{
if (('A' <= c) && (c <= 'Z'))
return(TRUE);
@@ -2224,8 +2187,7 @@ u_char c;
}
boolean_t
-kd_islower(c)
-u_char c;
+kd_islower(u_char c)
{
if (('a' <= c) && (c <= 'z'))
return(TRUE);
@@ -2242,10 +2204,10 @@ u_char c;
*
*/
void
-kd_senddata(ch)
-unsigned char ch;
+kd_senddata(unsigned char ch)
{
- while (inb(K_STATUS) & K_IBUF_FUL);
+ while (inb(K_STATUS) & K_IBUF_FUL)
+ ;
outb(K_RDWR, ch);
last_sent = ch;
return;
@@ -2260,10 +2222,10 @@ unsigned char ch;
*
*/
void
-kd_sendcmd(ch)
-unsigned char ch;
+kd_sendcmd(unsigned char ch)
{
- while (inb(K_STATUS) & K_IBUF_FUL);
+ while (inb(K_STATUS) & K_IBUF_FUL)
+ ;
outb(K_CMD, ch);
return;
}
@@ -2277,41 +2239,47 @@ unsigned char ch;
* read.
*/
unsigned char
-kd_getdata()
+kd_getdata(void)
{
- while ((inb(K_STATUS) & K_OBUF_FUL) == 0);
+ while ((inb(K_STATUS) & K_OBUF_FUL) == 0)
+ ;
return(inb(K_RDWR));
}
unsigned char
-kd_cmdreg_read()
+kd_cmdreg_read(void)
{
int ch=KC_CMD_READ;
- while (inb(K_STATUS) & K_IBUF_FUL);
+ while (inb(K_STATUS) & K_IBUF_FUL)
+ ;
outb(K_CMD, ch);
- while ((inb(K_STATUS) & K_OBUF_FUL) == 0);
+ while ((inb(K_STATUS) & K_OBUF_FUL) == 0)
+ ;
return(inb(K_RDWR));
}
void
-kd_cmdreg_write(val)
+kd_cmdreg_write(int val)
{
int ch=KC_CMD_WRITE;
- while (inb(K_STATUS) & K_IBUF_FUL);
+ while (inb(K_STATUS) & K_IBUF_FUL)
+ ;
outb(K_CMD, ch);
- while (inb(K_STATUS) & K_IBUF_FUL);
+ while (inb(K_STATUS) & K_IBUF_FUL)
+ ;
outb(K_RDWR, val);
}
void
-kd_mouse_drain()
+kd_mouse_drain(void)
{
int i;
- while(inb(K_STATUS) & K_IBUF_FUL);
+ while(inb(K_STATUS) & K_IBUF_FUL)
+ ;
while((i = inb(K_STATUS)) & K_OBUF_FUL)
printf("kbd: S = %x D = %x\n", i, inb(K_RDWR));
}
@@ -2322,8 +2290,7 @@ kd_mouse_drain()
* Set kd_state and update the keyboard status LEDs.
*/
void
-set_kd_state(newstate)
-int newstate;
+set_kd_state(int newstate)
{
kd_state = newstate;
kd_setleds1(state2leds(newstate));
@@ -2336,8 +2303,7 @@ int newstate;
* a state vector.
*/
u_char
-state2leds(state)
-int state;
+state2leds(int state)
{
u_char result = 0;
@@ -2354,8 +2320,7 @@ int state;
* Set the keyboard LEDs according to the given byte.
*/
void
-kd_setleds1(val)
-u_char val;
+kd_setleds1(u_char val)
{
if (kd_ack != NOT_WAITING) {
#ifdef MACH_KBD
@@ -2370,7 +2335,7 @@ u_char val;
}
void
-kd_setleds2()
+kd_setleds2(void)
{
kd_senddata(kd_nextled);
}
@@ -2384,8 +2349,7 @@ kd_setleds2()
* lock anyway.
*/
void
-cnsetleds(val)
-u_char val;
+cnsetleds(u_char val)
{
kd_senddata(K_CMD_LEDS);
(void)kd_getdata(); /* XXX - assume is ACK */
@@ -2394,7 +2358,7 @@ u_char val;
}
void
-kdreboot()
+kdreboot(void)
{
(*kd_dreset)();
@@ -2413,7 +2377,7 @@ static int which_button[] = {0, MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT};
static struct mouse_motion moved;
int
-kd_kbd_magic(scancode)
+kd_kbd_magic(int scancode)
{
int new_button = 0;
@@ -2507,14 +2471,18 @@ int new_button = 0;
* Initialization specific to character-based graphics adapters.
*/
void
-kd_xga_init()
+kd_xga_init(void)
{
csrpos_t xga_getpos();
unsigned char screen;
+ unsigned char start, stop;
outb(CMOS_ADDR, CMOS_EB);
screen = inb(CMOS_DATA) & CM_SCRMSK;
switch(screen) {
+ default:
+ printf("kd: unknown screen type, defaulting to EGA\n");
+ /* FALLTHROUGH */
case CM_EGA_VGA:
/*
* Here we'll want to query to bios on the card
@@ -2540,6 +2508,8 @@ kd_xga_init()
addr[i] = 0x00;
}
break;
+#if 0
+ /* XXX: some buggy BIOSes report these... */
case CM_CGA_40:
vid_start = (u_char *)phystokv(CGA_START);
kd_index_reg = CGA_IDX_REG;
@@ -2561,8 +2531,25 @@ kd_xga_init()
kd_lines = 25;
kd_cols = 80;
break;
- default:
- printf("kd: unknown screen type, defaulting to EGA\n");
+#endif
+ }
+
+ outb(kd_index_reg, C_START);
+ start = inb(kd_io_reg);
+ /* Make sure cursor is enabled */
+ start &= ~0x20;
+ outb(kd_io_reg, start);
+ outb(kd_index_reg, C_STOP);
+ stop = inb(kd_io_reg);
+
+ if (!start && !stop)
+ {
+ /* Some firmware seem not to be initializing the cursor size
+ * any more... Try using standard values. */
+ outb(kd_index_reg, C_START);
+ outb(kd_io_reg, 14);
+ outb(kd_index_reg, C_STOP);
+ outb(kd_io_reg, 15);
}
kd_setpos(xga_getpos());
@@ -2580,7 +2567,7 @@ kd_xga_init()
*
*/
csrpos_t
-xga_getpos()
+xga_getpos(void)
{
unsigned char low;
@@ -2683,38 +2670,24 @@ char chattr;
* No-op reset routine for kd_dreset.
*/
static void
-kd_noopreset()
+kd_noopreset(void)
{
}
-
-/*
- * Generic routines for bitmap devices (i.e., assume no hardware
- * assist). Assumes a simple byte ordering (i.e., a byte at a lower
- * address is to the left of the byte at the next higher address).
- * For the 82786, this works anyway if the characters are 2 bytes
- * wide. (more bubble gum and paper clips.)
- *
- * See the comments above about SLAMBPW.
- */
-
-void bmpch2bit(), bmppaintcsr();
-u_char *bit2fbptr();
-
-
/*
* bmpput: Copy a character from the font to the frame buffer.
*/
void
-bmpput(pos, ch, chattr)
-csrpos_t pos;
-char ch, chattr;
+bmpput(
+ csrpos_t pos,
+ char ch,
+ char chattr)
{
short xbit, ybit; /* u/l corner of char pos */
- register u_char *to, *from;
- register short i, j;
+ u_char *to, *from;
+ short i, j;
u_char mask = (chattr == KA_REVERSE ? 0xff : 0);
if ((u_char)ch >= chars_in_font)
@@ -2736,13 +2709,14 @@ char ch, chattr;
* another.
*/
void
-bmpcp1char(from, to)
-csrpos_t from, to;
+bmpcp1char(
+ csrpos_t from,
+ csrpos_t to)
{
short from_xbit, from_ybit;
short to_xbit, to_ybit;
- register u_char *tp, *fp;
- register short i, j;
+ u_char *tp, *fp;
+ short i, j;
bmpch2bit(from, &from_xbit, &from_ybit);
bmpch2bit(to, &to_xbit, &to_ybit);
@@ -2762,9 +2736,10 @@ csrpos_t from, to;
* bmpvmup: Copy a block of character positions upwards.
*/
void
-bmpmvup(from, to, count)
-csrpos_t from, to;
-int count;
+bmpmvup(
+ csrpos_t from,
+ csrpos_t to,
+ int count)
{
short from_xbit, from_ybit;
short to_xbit, to_ybit;
@@ -2797,9 +2772,10 @@ int count;
* bmpmvdown: copy a block of characters down.
*/
void
-bmpmvdown(from, to, count)
-csrpos_t from, to;
-int count;
+bmpmvdown(
+ csrpos_t from,
+ csrpos_t to,
+ int count)
{
short from_xbit, from_ybit;
short to_xbit, to_ybit;
@@ -2835,12 +2811,12 @@ int count;
* bmpclear: clear one or more character positions.
*/
void
-bmpclear(to, count, chattr)
-csrpos_t to; /* 1st char */
-int count; /* num chars */
-char chattr; /* reverse or normal */
+bmpclear(
+ csrpos_t to, /* 1st char */
+ int count, /* num chars */
+ char chattr) /* reverse or normal */
{
- register short i;
+ short i;
u_short clearval;
u_short clearbyte = (chattr == KA_REVERSE ? char_white : char_black);
@@ -2861,8 +2837,7 @@ char chattr; /* reverse or normal */
* bmpsetcursor: update the display and set the logical cursor.
*/
void
-bmpsetcursor(pos)
-csrpos_t pos;
+bmpsetcursor(csrpos_t pos)
{
/* erase old cursor & paint new one */
bmppaintcsr(kd_curpos, char_black);
@@ -2874,13 +2849,13 @@ csrpos_t pos;
* bmppaintcsr: paint cursor bits.
*/
void
-bmppaintcsr(pos, val)
-csrpos_t pos;
-u_char val;
+bmppaintcsr(
+ csrpos_t pos,
+ u_char val)
{
short xbit, ybit;
- register u_char *cp;
- register short line, byte;
+ u_char *cp;
+ short line, byte;
bmpch2bit(pos, &xbit, &ybit);
ybit += char_height; /* position at bottom of line */
@@ -2897,11 +2872,12 @@ u_char val;
* (0, 0) is the upper left corner.
*/
void
-bmpch2bit(pos, xb, yb)
-csrpos_t pos;
-short *xb, *yb; /* x, y bit positions, u/l corner */
+bmpch2bit(
+ csrpos_t pos,
+ short *xb,
+ short *yb) /* x, y bit positions, u/l corner */
{
- register short xch, ych;
+ short xch, ych;
xch = (pos / ONE_SPACE) % kd_cols;
ych = pos / (ONE_SPACE * kd_cols);
@@ -2916,8 +2892,9 @@ short *xb, *yb; /* x, y bit positions, u/l corner */
* byte.
*/
u_char *
-bit2fbptr(xb, yb)
-short xb, yb;
+bit2fbptr(
+ short xb,
+ short yb)
{
return(vid_start + yb * fb_byte_width + xb/8);
}
@@ -3052,6 +3029,39 @@ kdcnmaygetc(void)
#ifdef notdef
cnsetleds(state2leds(kd_state));
#endif
+ } else if (! up
+ && c == K_ESC
+ && key_map[scancode][char_idx+1] == 0x5b) {
+ /* As a convenience for the nice
+ people using our debugger, remap
+ some keys to the readline-like
+ shortcuts supported by dde.
+
+ XXX This is a workaround for the
+ limited kernel getchar interface.
+ It is only used by the debugger. */
+ c = key_map[scancode][char_idx+2];
+ switch (c) {
+#define _MAP(A,B,C) (C)
+#define MAP(T) _MAP(T)
+#define CTRL(c) ((c) & 0x1f)
+ case MAP(K_HOME): c = CTRL('a'); break;
+ case MAP(K_UA): c = CTRL('p'); break;
+ case MAP(K_LA): c = CTRL('b'); break;
+ case MAP(K_RA): c = CTRL('f'); break;
+ case MAP(K_DA): c = CTRL('n'); break;
+ case MAP(K_END): c = CTRL('e'); break;
+ /* delete */
+ case 0x39: c = CTRL('d'); break;
+#undef CTRL
+#undef MAP
+#undef _MAP
+ default:
+ /* Retain the old behavior. */
+ c = K_ESC;
+ }
+
+ return(c);
} else if (!up) {
/* regular key-down */
if (c == K_CR)
diff --git a/i386/i386at/kd.h b/i386/i386at/kd.h
index 1d53538b..0cfed695 100644
--- a/i386/i386at/kd.h
+++ b/i386/i386at/kd.h
@@ -76,7 +76,10 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <sys/types.h>
#include <sys/time.h>
#include <device/cons.h>
-
+#include <device/io_req.h>
+#include <device/buf.h>
+#include <device/tty.h>
+#include <i386at/kdsoft.h>
/*
* Where memory for various graphics adapters starts.
@@ -110,6 +113,8 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/*
* Commands sent to graphics adapter.
*/
+#define C_START 0x0a /* return cursor line start */
+#define C_STOP 0x0b /* return cursor line stop */
#define C_LOW 0x0f /* return low byte of cursor addr */
#define C_HIGH 0x0e /* high byte */
@@ -359,10 +364,10 @@ typedef u_char Scancode;
* Other mappable non-Ascii keys (e.g., "ctrl") are represented by a
* two-byte sequence: K_SCAN, followed by the key's scan code.
*/
-#define K_DONE 0xff /* must be same as NC */
-#define NC 0xff /* No character defined */
+#define K_DONE 0xffu /* must be same as NC */
+#define NC 0xffu /* No character defined */
-#define K_SCAN 0xfe /* followed by scan code */
+#define K_SCAN 0xfeu /* followed by scan code */
/* ascii char set */
#define K_NUL 0x00 /* Null character */
@@ -728,13 +733,14 @@ extern int kdsetbell (int, int);
extern void kd_resend (void);
extern void kd_handle_ack (void);
extern int kd_kbd_magic (int);
-extern int kdstate2idx (int, boolean_t);
+extern unsigned int kdstate2idx (unsigned int, boolean_t);
extern void kd_parserest (u_char *);
extern int kdcnprobe(struct consdev *cp);
extern int kdcninit(struct consdev *cp);
extern int kdcngetc(dev_t dev, int wait);
extern int kdcnmaygetc (void);
extern int kdcnputc(dev_t dev, int c);
+extern void kd_setpos(csrpos_t newpos);
extern void kd_slmwd (void *start, int count, int value);
extern void kd_slmscu (void *from, void *to, int count);
@@ -742,4 +748,53 @@ extern void kd_slmscd (void *from, void *to, int count);
extern void kdintr(int vec);
+#if MACH_KDB
+extern void kdb_kintr(void);
+#endif /* MACH_KDB */
+
+extern int kdopen(dev_t dev, int flag, io_req_t ior);
+extern void kdclose(dev_t dev, int flag);
+extern int kdread(dev_t dev, io_req_t uio);
+extern int kdwrite(dev_t dev, io_req_t uio);
+
+extern io_return_t kdgetstat(
+ dev_t dev,
+ int flavor,
+ int *data,
+ natural_t *count);
+
+extern io_return_t kdsetstat(
+ dev_t dev,
+ int flavor,
+ int * data,
+ natural_t count);
+
+extern int kdportdeath(dev_t dev, mach_port_t port);
+extern int kdmmap(dev_t dev, vm_offset_t off, vm_prot_t prot);
+
+boolean_t kdcheckmagic(Scancode scancode);
+
+int do_modifier(int state, Scancode c, boolean_t up);
+
+/*
+ * Generic routines for bitmap devices (i.e., assume no hardware
+ * assist). Assumes a simple byte ordering (i.e., a byte at a lower
+ * address is to the left of the byte at the next higher address).
+ * For the 82786, this works anyway if the characters are 2 bytes
+ * wide. (more bubble gum and paper clips.)
+ *
+ * See the comments above (in i386at/kd.c) about SLAMBPW.
+ */
+void bmpch2bit(csrpos_t pos, short *xb, short *yb);
+void bmppaintcsr(csrpos_t pos, u_char val);
+u_char *bit2fbptr(short xb, short yb);
+
+unsigned char kd_getdata(void);
+unsigned char state2leds(int state);
+
+void kdstart(struct tty *tp);
+void kdstop(struct tty *tp, int flags);
+
+void kd_xga_init(void);
+
#endif /* _KD_H_ */
diff --git a/i386/i386at/kd_event.c b/i386/i386at/kd_event.c
index 4d2ea008..694c165e 100644
--- a/i386/i386at/kd_event.c
+++ b/i386/i386at/kd_event.c
@@ -83,11 +83,6 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
kd_event_queue kbd_queue; /* queue of keyboard events */
queue_head_t kbd_read_queue = { &kbd_read_queue, &kbd_read_queue };
-
-void kbd_enqueue();
-io_return_t X_kdb_enter_init();
-io_return_t X_kdb_exit_init();
-
static boolean_t initialized = FALSE;
@@ -96,7 +91,7 @@ static boolean_t initialized = FALSE;
*/
void
-kbdinit()
+kbdinit(void)
{
spl_t s = SPLKD();
@@ -115,9 +110,10 @@ kbdinit()
/*ARGSUSED*/
int
-kbdopen(dev, flags)
+kbdopen(dev, flags, ior)
dev_t dev;
int flags;
+ io_req_t ior;
{
spl_t o_pri = spltty();
kdinit();
@@ -135,9 +131,9 @@ kbdopen(dev, flags)
/*ARGSUSED*/
void
-kbdclose(dev, flags)
- dev_t dev;
- int flags;
+kbdclose(
+ dev_t dev,
+ int flags)
{
spl_t s = SPLKD();
@@ -147,11 +143,11 @@ kbdclose(dev, flags)
}
-io_return_t kbdgetstat(dev, flavor, data, count)
- dev_t dev;
- int flavor;
- int * data; /* pointer to OUT array */
- unsigned int *count; /* OUT */
+io_return_t kbdgetstat(
+ dev_t dev,
+ int flavor,
+ int * data, /* pointer to OUT array */
+ unsigned int *count) /* OUT */
{
switch (flavor) {
case KDGKBDTYPE:
@@ -169,11 +165,11 @@ io_return_t kbdgetstat(dev, flavor, data, count)
return (D_SUCCESS);
}
-io_return_t kbdsetstat(dev, flavor, data, count)
- dev_t dev;
- int flavor;
- int * data;
- unsigned int count;
+io_return_t kbdsetstat(
+ dev_t dev,
+ int flavor,
+ int * data,
+ unsigned int count)
{
switch (flavor) {
case KDSKBDMODE:
@@ -187,9 +183,9 @@ io_return_t kbdsetstat(dev, flavor, data, count)
kd_setleds1 (*data);
break;
case K_X_KDB_ENTER:
- return X_kdb_enter_init(data, count);
+ return X_kdb_enter_init((unsigned int *)data, count);
case K_X_KDB_EXIT:
- return X_kdb_exit_init(data, count);
+ return X_kdb_exit_init((unsigned int *)data, count);
default:
return (D_INVALID_OPERATION);
}
@@ -201,16 +197,13 @@ io_return_t kbdsetstat(dev, flavor, data, count)
/*
* kbdread - dequeue and return any queued events.
*/
-
-boolean_t kbd_read_done(); /* forward */
-
int
-kbdread(dev, ior)
- dev_t dev;
- register io_req_t ior;
+kbdread(
+ dev_t dev,
+ io_req_t ior)
{
- register int err, count;
- register spl_t s;
+ int err, count;
+ spl_t s;
/* Check if IO_COUNT is a multiple of the record size. */
if (ior->io_count % sizeof(kd_event) != 0)
@@ -233,7 +226,7 @@ kbdread(dev, ior)
}
count = 0;
while (!kdq_empty(&kbd_queue) && count < ior->io_count) {
- register kd_event *ev;
+ kd_event *ev;
ev = kdq_get(&kbd_queue);
*(kd_event *)(&ior->io_data[count]) = *ev;
@@ -244,11 +237,10 @@ kbdread(dev, ior)
return (D_SUCCESS);
}
-boolean_t kbd_read_done(ior)
- register io_req_t ior;
+boolean_t kbd_read_done(io_req_t ior)
{
- register int count;
- register spl_t s;
+ int count;
+ spl_t s;
s = SPLKD();
if (kdq_empty(&kbd_queue)) {
@@ -260,7 +252,7 @@ boolean_t kbd_read_done(ior)
count = 0;
while (!kdq_empty(&kbd_queue) && count < ior->io_count) {
- register kd_event *ev;
+ kd_event *ev;
ev = kdq_get(&kbd_queue);
*(kd_event *)(&ior->io_data[count]) = *ev;
@@ -281,8 +273,7 @@ boolean_t kbd_read_done(ior)
*/
void
-kd_enqsc(sc)
- Scancode sc;
+kd_enqsc(Scancode sc)
{
kd_event ev;
@@ -299,16 +290,15 @@ kd_enqsc(sc)
*/
void
-kbd_enqueue(ev)
- kd_event *ev;
+kbd_enqueue(kd_event *ev)
{
if (kdq_full(&kbd_queue))
- printf("kbd: queue full\n");
+ printf_once("kbd: queue full\n");
else
kdq_put(&kbd_queue, ev);
{
- register io_req_t ior;
+ io_req_t ior;
while ((ior = (io_req_t)dequeue_head(&kbd_read_queue)) != 0)
iodone(ior);
}
@@ -319,9 +309,9 @@ int X_kdb_enter_len = 0, X_kdb_exit_len = 0;
void
kdb_in_out(p)
-u_int *p;
+const u_int *p;
{
-register int t = p[0];
+ int t = p[0];
switch (t & K_X_TYPE) {
case K_X_IN|K_X_BYTE:
@@ -351,9 +341,9 @@ register int t = p[0];
}
void
-X_kdb_enter()
+X_kdb_enter(void)
{
-register u_int *u_ip, *endp;
+ u_int *u_ip, *endp;
for (u_ip = X_kdb_enter_str, endp = &X_kdb_enter_str[X_kdb_enter_len];
u_ip < endp;
@@ -362,9 +352,9 @@ register u_int *u_ip, *endp;
}
void
-X_kdb_exit()
+X_kdb_exit(void)
{
-register u_int *u_ip, *endp;
+ u_int *u_ip, *endp;
for (u_ip = X_kdb_exit_str, endp = &X_kdb_exit_str[X_kdb_exit_len];
u_ip < endp;
@@ -373,9 +363,9 @@ register u_int *u_ip, *endp;
}
io_return_t
-X_kdb_enter_init(data, count)
- u_int *data;
- u_int count;
+X_kdb_enter_init(
+ u_int *data,
+ u_int count)
{
if (count * sizeof X_kdb_enter_str[0] > sizeof X_kdb_enter_str)
return D_INVALID_OPERATION;
@@ -386,9 +376,9 @@ X_kdb_enter_init(data, count)
}
io_return_t
-X_kdb_exit_init(data, count)
- u_int *data;
- u_int count;
+X_kdb_exit_init(
+ u_int *data,
+ u_int count)
{
if (count * sizeof X_kdb_exit_str[0] > sizeof X_kdb_exit_str)
return D_INVALID_OPERATION;
diff --git a/i386/i386at/kd_event.h b/i386/i386at/kd_event.h
index 677af99b..8b2d6642 100644
--- a/i386/i386at/kd_event.h
+++ b/i386/i386at/kd_event.h
@@ -26,8 +26,37 @@
#ifndef _KD_EVENT_H_
#define _KD_EVENT_H_
+#include <sys/types.h>
+#include <device/io_req.h>
+#include <i386at/kd.h>
+
extern void X_kdb_enter (void);
extern void X_kdb_exit (void);
+extern int kbdopen(dev_t dev, int flags, io_req_t ior);
+extern void kbdclose(dev_t dev, int flags);
+extern int kbdread(dev_t dev, io_req_t ior);
+
+extern io_return_t kbdgetstat(
+ dev_t dev,
+ int flavor,
+ int *data,
+ unsigned int *count);
+
+extern io_return_t kbdsetstat(
+ dev_t dev,
+ int flavor,
+ int *data,
+ unsigned int count);
+
+extern void kd_enqsc(Scancode sc);
+
+void kbd_enqueue(kd_event *ev);
+
+io_return_t X_kdb_enter_init(u_int *data, u_int count);
+io_return_t X_kdb_exit_init(u_int *data, u_int count);
+
+boolean_t kbd_read_done(io_req_t ior);
+
#endif /* _KD_EVENT_H_ */
diff --git a/i386/i386at/kd_mouse.c b/i386/i386at/kd_mouse.c
index 6e7b68a8..0f1881f4 100644
--- a/i386/i386at/kd_mouse.c
+++ b/i386/i386at/kd_mouse.c
@@ -101,8 +101,6 @@ u_char lastbuttons; /* previous state of mouse buttons */
#define MOUSE_DOWN 0
#define MOUSE_ALL_UP 0x7
-void mouseintr();
-void mouse_enqueue();
int mouse_baud = BCNT1200;
boolean_t mouse_char_cmd = FALSE; /* mouse response is to cmd */
@@ -114,7 +112,7 @@ int mouse_char_index; /* mouse response */
* init_mouse_hw - initialize the serial port.
*/
void
-init_mouse_hw(unit, mode)
+init_mouse_hw(dev_t unit, int mode)
{
unsigned short base_addr = cominfo[unit]->address;
@@ -149,9 +147,10 @@ int track_man[10];
/*ARGSUSED*/
int
-mouseopen(dev, flags)
+mouseopen(dev, flags, ior)
dev_t dev;
int flags;
+ io_req_t ior;
{
if (mouse_in_use)
return (D_ALREADY_OPEN);
@@ -164,6 +163,7 @@ mouseopen(dev, flags)
mousebufsize = 3;
serial_mouse_open(dev);
init_mouse_hw(dev&7, LC7);
+ break;
case MICROSOFT_MOUSE:
mousebufsize = 3;
serial_mouse_open(dev);
@@ -198,8 +198,7 @@ mouseopen(dev, flags)
}
void
-serial_mouse_open(dev)
- dev_t dev;
+serial_mouse_open(dev_t dev)
{
int unit = minor(dev) & 0x7;
int mouse_pic = cominfo[unit]->sysdep1;
@@ -219,12 +218,11 @@ serial_mouse_open(dev)
int mouse_packets = 0;
void
-kd_mouse_open(dev, mouse_pic)
- dev_t dev;
- int mouse_pic;
+kd_mouse_open(
+ dev_t dev,
+ int mouse_pic)
{
spl_t s = splhi(); /* disable interrupts */
- extern void kdintr();
oldvect = ivect[mouse_pic];
ivect[mouse_pic] = kdintr;
@@ -239,9 +237,9 @@ kd_mouse_open(dev, mouse_pic)
* and restore the serial port interrupt vector.
*/
void
-mouseclose(dev, flags)
- dev_t dev;
- int flags;
+mouseclose(
+ dev_t dev,
+ int flags)
{
switch (mouse_type) {
case MICROSOFT_MOUSE:
@@ -266,9 +264,9 @@ mouseclose(dev, flags)
/*ARGSUSED*/
void
-serial_mouse_close(dev, flags)
- dev_t dev;
- int flags;
+serial_mouse_close(
+ dev_t dev,
+ int flags)
{
spl_t o_pri = splhi(); /* mutex with open() */
int unit = minor(dev) & 0x7;
@@ -285,9 +283,9 @@ serial_mouse_close(dev, flags)
}
void
-kd_mouse_close(dev, mouse_pic)
- dev_t dev;
- int mouse_pic;
+kd_mouse_close(
+ dev_t dev,
+ int mouse_pic)
{
spl_t s = splhi();
@@ -297,11 +295,11 @@ kd_mouse_close(dev, mouse_pic)
splx(s);
}
-io_return_t mousegetstat(dev, flavor, data, count)
- dev_t dev;
- int flavor;
- int * data; /* pointer to OUT array */
- unsigned int *count; /* OUT */
+io_return_t mousegetstat(
+ dev_t dev,
+ int flavor,
+ int * data, /* pointer to OUT array */
+ unsigned int *count) /* OUT */
{
switch (flavor) {
case DEV_GET_SIZE:
@@ -319,15 +317,13 @@ io_return_t mousegetstat(dev, flavor, data, count)
/*
* mouseread - dequeue and return any queued events.
*/
-boolean_t mouse_read_done(); /* forward */
-
int
-mouseread(dev, ior)
- dev_t dev;
- register io_req_t ior;
+mouseread(
+ dev_t dev,
+ io_req_t ior)
{
- register int err, count;
- register spl_t s;
+ int err, count;
+ spl_t s;
/* Check if IO_COUNT is a multiple of the record size. */
if (ior->io_count % sizeof(kd_event) != 0)
@@ -350,7 +346,7 @@ mouseread(dev, ior)
}
count = 0;
while (!kdq_empty(&mouse_queue) && count < ior->io_count) {
- register kd_event *ev;
+ kd_event *ev;
ev = kdq_get(&mouse_queue);
*(kd_event *)(&ior->io_data[count]) = *ev;
@@ -361,11 +357,10 @@ mouseread(dev, ior)
return (D_SUCCESS);
}
-boolean_t mouse_read_done(ior)
- register io_req_t ior;
+boolean_t mouse_read_done(io_req_t ior)
{
- register int count;
- register spl_t s;
+ int count;
+ spl_t s;
s = SPLKD();
if (kdq_empty(&mouse_queue)) {
@@ -377,7 +372,7 @@ boolean_t mouse_read_done(ior)
count = 0;
while (!kdq_empty(&mouse_queue) && count < ior->io_count) {
- register kd_event *ev;
+ kd_event *ev;
ev = kdq_get(&mouse_queue);
*(kd_event *)(&ior->io_data[count]) = *ev;
@@ -397,7 +392,7 @@ boolean_t mouse_read_done(ior)
* mouseintr - Get a byte and pass it up for handling. Called at SPLKD.
*/
void
-mouseintr(unit)
+mouseintr(int unit)
{
unsigned short base_addr = cominfo[unit]->address;
unsigned char id, ls;
@@ -445,8 +440,7 @@ int middlegitech = 0; /* what should the middle button be */
static u_char mousebuf[MOUSEBUFSIZE]; /* 5-byte packet from mouse */
void
-mouse_handle_byte(ch)
- u_char ch;
+mouse_handle_byte(u_char ch)
{
if (show_mouse_byte) {
printf("%x(%c) ", ch, ch);
@@ -527,8 +521,7 @@ mouse_handle_byte(ch)
}
void
-mouse_packet_mouse_system_mouse(mousebuf)
-u_char mousebuf[MOUSEBUFSIZE];
+mouse_packet_mouse_system_mouse(u_char mousebuf[MOUSEBUFSIZE])
{
u_char buttons, buttonchanges;
struct mouse_motion moved;
@@ -563,8 +556,7 @@ u_char mousebuf[MOUSEBUFSIZE];
*
*/
void
-mouse_packet_microsoft_mouse(mousebuf)
-u_char mousebuf[MOUSEBUFSIZE];
+mouse_packet_microsoft_mouse(u_char mousebuf[MOUSEBUFSIZE])
{
u_char buttons, buttonchanges;
struct mouse_motion moved;
@@ -656,8 +648,7 @@ void kd_mouse_read_reset(void)
}
void
-ibm_ps2_mouse_open(dev)
- dev_t dev;
+ibm_ps2_mouse_open(dev_t dev)
{
spl_t s = spltty();
@@ -700,8 +691,7 @@ ibm_ps2_mouse_open(dev)
}
void
-ibm_ps2_mouse_close(dev)
- dev_t dev;
+ibm_ps2_mouse_close(dev_t dev)
{
spl_t s = spltty();
@@ -732,8 +722,7 @@ ibm_ps2_mouse_close(dev)
*
*/
void
-mouse_packet_ibm_ps2_mouse(mousebuf)
-u_char mousebuf[MOUSEBUFSIZE];
+mouse_packet_ibm_ps2_mouse(u_char mousebuf[MOUSEBUFSIZE])
{
u_char buttons, buttonchanges;
struct mouse_motion moved;
@@ -765,8 +754,7 @@ u_char mousebuf[MOUSEBUFSIZE];
* Enqueue a mouse-motion event. Called at SPLKD.
*/
void
-mouse_moved(where)
- struct mouse_motion where;
+mouse_moved(struct mouse_motion where)
{
kd_event ev;
@@ -776,14 +764,13 @@ mouse_moved(where)
mouse_enqueue(&ev);
}
-
/*
* Enqueue an event for mouse button press or release. Called at SPLKD.
*/
void
-mouse_button(which, direction)
- kev_type which;
- u_char direction;
+mouse_button(
+ kev_type which,
+ u_char direction)
{
kd_event ev;
@@ -793,23 +780,21 @@ mouse_button(which, direction)
mouse_enqueue(&ev);
}
-
/*
* mouse_enqueue - enqueue an event and wake up selecting processes, if
* any. Called at SPLKD.
*/
void
-mouse_enqueue(ev)
- kd_event *ev;
+mouse_enqueue(kd_event *ev)
{
if (kdq_full(&mouse_queue))
- printf("mouse: queue full\n");
+ printf_once("mouse: queue full\n");
else
kdq_put(&mouse_queue, ev);
{
- register io_req_t ior;
+ io_req_t ior;
while ((ior = (io_req_t)dequeue_head(&mouse_read_queue)) != 0)
iodone(ior);
}
diff --git a/i386/i386at/kd_mouse.h b/i386/i386at/kd_mouse.h
index baa51c8a..a8a72a3b 100644
--- a/i386/i386at/kd_mouse.h
+++ b/i386/i386at/kd_mouse.h
@@ -54,4 +54,17 @@ extern void mouse_packet_mouse_system_mouse (u_char *mousebuf);
extern void mouse_packet_ibm_ps2_mouse (u_char *mousebuf);
+extern int mouseopen(dev_t dev, int flags, io_req_t ior);
+extern void mouseclose(dev_t dev, int flags);
+extern int mouseread(dev_t dev, io_req_t ior);
+
+extern io_return_t mousegetstat(
+ dev_t dev,
+ int flavor,
+ int *data,
+ unsigned int *count);
+
+void mouseintr(int unit);
+boolean_t mouse_read_done(io_req_t ior);
+
#endif /* _KD_MOUSE_H_ */
diff --git a/i386/i386at/kd_queue.c b/i386/i386at/kd_queue.c
index 2b83044a..57d6fbf7 100644
--- a/i386/i386at/kd_queue.c
+++ b/i386/i386at/kd_queue.c
@@ -72,14 +72,14 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
boolean_t
kdq_empty(q)
- kd_event_queue *q;
+ const kd_event_queue *q;
{
return(q->firstfree == q->firstout);
}
boolean_t
kdq_full(q)
- kd_event_queue *q;
+ const kd_event_queue *q;
{
return(q_next(q->firstfree) == q->firstout);
}
@@ -98,8 +98,7 @@ kdq_put(q, ev)
}
kd_event *
-kdq_get(q)
- kd_event_queue *q;
+kdq_get(kd_event_queue *q)
{
kd_event *result = q->events + q->firstout;
@@ -108,8 +107,7 @@ kdq_get(q)
}
void
-kdq_reset(q)
- kd_event_queue *q;
+kdq_reset(kd_event_queue *q)
{
q->firstout = q->firstfree = 0;
}
diff --git a/i386/i386at/kd_queue.h b/i386/i386at/kd_queue.h
index c976acfa..702efe8a 100644
--- a/i386/i386at/kd_queue.h
+++ b/i386/i386at/kd_queue.h
@@ -64,6 +64,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* /dev/mouse.
*/
+#ifndef _KD_QUEUE_H_
+#define _KD_QUEUE_H_
+
#include <mach/std_types.h>
#include <i386at/kd.h>
@@ -76,6 +79,8 @@ typedef struct {
extern void kdq_put(kd_event_queue *, kd_event *);
extern void kdq_reset(kd_event_queue *);
-extern boolean_t kdq_empty(kd_event_queue *);
-extern boolean_t kdq_full(kd_event_queue *);
+extern boolean_t kdq_empty(const kd_event_queue *);
+extern boolean_t kdq_full(const kd_event_queue *);
extern kd_event *kdq_get(kd_event_queue *);
+
+#endif /* _KD_QUEUE_H_ */
diff --git a/i386/i386at/kdsoft.h b/i386/i386at/kdsoft.h
index 96e2df8c..1dfd2b2c 100644
--- a/i386/i386at/kdsoft.h
+++ b/i386/i386at/kdsoft.h
@@ -57,6 +57,9 @@ NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifndef _KDSOFT_H_
+#define _KDSOFT_H_
+
/*
* Globals used for both character-based controllers and bitmap-based
* controllers.
@@ -203,3 +206,5 @@ extern short xstart, ystart;
extern short char_byte_width; /* char_width/8 */
extern short fb_byte_width; /* fb_width/8 */
extern short font_byte_width; /* num bytes in 1 scan line of font */
+
+#endif /* _KDSOFT_H_ */
diff --git a/i386/i386at/lpr.c b/i386/i386at/lpr.c
index c92795ef..5c16b153 100644
--- a/i386/i386at/lpr.c
+++ b/i386/i386at/lpr.c
@@ -44,20 +44,12 @@
#include <i386/pio.h>
#include <chips/busses.h>
#include <i386at/autoconf.h>
-#include <i386at/lprreg.h>
+#include <i386at/lpr.h>
-
/*
* Driver information for auto-configuration stuff.
*/
-int lprprobe();
-void lprstop();
-void lprintr(), lprstart();
-void lprattach(struct bus_device *);
-int lprgetstat(), lprsetstat();
-void lprpr_addr();
-
struct bus_device *lprinfo[NLPR]; /* ??? */
static vm_offset_t lpr_std[NLPR] = { 0 };
@@ -71,7 +63,8 @@ int lpr_alive[NLPR];
int
lprprobe(port, dev)
-struct bus_device *dev;
+vm_offset_t port;
+struct bus_ctlr *dev;
{
u_short addr = (u_short) dev->address;
int unit = dev->unit;
@@ -113,7 +106,7 @@ void lprattach(struct bus_device *dev)
int
lpropen(dev, flag, ior)
-int dev;
+dev_t dev;
int flag;
io_req_t ior;
{
@@ -142,7 +135,7 @@ u_short addr;
void
lprclose(dev, flag)
-int dev;
+dev_t dev;
int flag;
{
int unit = minor(dev);
@@ -158,7 +151,7 @@ u_short addr = (u_short) lprinfo[unit]->address;
int
lprread(dev, ior)
-int dev;
+dev_t dev;
io_req_t ior;
{
return char_read(&lpr_tty[minor(dev)], ior);
@@ -166,7 +159,7 @@ io_req_t ior;
int
lprwrite(dev, ior)
-int dev;
+dev_t dev;
io_req_t ior;
{
return char_write(&lpr_tty[minor(dev)], ior);
@@ -199,11 +192,11 @@ natural_t *count; /* out */
}
io_return_t
-lprsetstat(dev, flavor, data, count)
-dev_t dev;
-int flavor;
-int * data;
-natural_t count;
+lprsetstat(
+ dev_t dev,
+ int flavor,
+ int * data,
+ natural_t count)
{
io_return_t result = D_SUCCESS;
int unit = minor(dev);
@@ -218,10 +211,9 @@ natural_t count;
return (D_SUCCESS);
}
-void lprintr(unit)
-int unit;
+void lprintr(int unit)
{
- register struct tty *tp = &lpr_tty[unit];
+ struct tty *tp = &lpr_tty[unit];
if ((tp->t_state & TS_ISOPEN) == 0)
return;
@@ -233,8 +225,7 @@ int unit;
lprstart(tp);
}
-void lprstart(tp)
-struct tty *tp;
+void lprstart(struct tty *tp)
{
spl_t s = spltty();
u_short addr = (natural_t) tp->t_addr;
@@ -274,22 +265,22 @@ struct tty *tp;
}
void
-lprstop(tp, flags)
-register struct tty *tp;
-int flags;
+lprstop(
+ struct tty *tp,
+ int flags)
{
if ((tp->t_state & TS_BUSY) && (tp->t_state & TS_TTSTOP) == 0)
tp->t_state |= TS_FLUSH;
}
int
-lprpr(unit)
+lprpr(int unit)
{
lprpr_addr(lprinfo[unit]->address);
return 0;
}
void
-lprpr_addr(addr)
+lprpr_addr(unsigned short addr)
{
printf("DATA(%x) %x, STATUS(%x) %x, INTR_ENAB(%x) %x\n",
DATA(addr), inb(DATA(addr)),
diff --git a/i386/i386at/lprreg.h b/i386/i386at/lpr.h
index c6fbed43..269fd643 100644
--- a/i386/i386at/lprreg.h
+++ b/i386/i386at/lpr.h
@@ -27,7 +27,40 @@
* Parallel port printer driver v1.0
* All rights reserved.
*/
+
+#ifndef _LPRREG_H_
+#define _LPRREG_H_
#define DATA(addr) (addr + 0)
#define STATUS(addr) (addr + 1)
#define INTR_ENAB(addr) (addr + 2)
+
+extern void lprintr(int unit);
+int lprprobe(vm_offset_t port, struct bus_ctlr *dev);
+void lprstop(struct tty *tp, int flags);
+void lprstart(struct tty *tp);
+void lprattach(struct bus_device *dev);
+
+extern io_return_t
+lprgetstat(
+ dev_t dev,
+ int flavor,
+ int *data,
+ natural_t *count);
+
+extern io_return_t
+lprsetstat(
+ dev_t dev,
+ int flavor,
+ int *data,
+ natural_t count);
+
+void lprpr_addr(unsigned short addr);
+
+extern int lpropen(dev_t dev, int flag, io_req_t ior);
+extern void lprclose(dev_t dev, int flag);
+extern int lprread(dev_t dev, io_req_t ior);
+extern int lprwrite(dev_t dev, io_req_t ior);
+extern int lprportdeath(dev_t dev, mach_port_t port);
+
+#endif /* _LPRREG_H_ */
diff --git a/i386/i386at/mem.c b/i386/i386at/mem.c
index 5e51676b..f239afac 100644
--- a/i386/i386at/mem.c
+++ b/i386/i386at/mem.c
@@ -32,7 +32,7 @@
/*ARGSUSED*/
int
memmmap(dev, off, prot)
-int dev;
+dev_t dev;
vm_offset_t off;
vm_prot_t prot;
{
diff --git a/i386/i386at/mem.h b/i386/i386at/mem.h
new file mode 100644
index 00000000..0bc85ea4
--- /dev/null
+++ b/i386/i386at/mem.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _MEM_H_
+#define _MEM_H_
+
+extern int memmmap(dev_t dev, vm_offset_t off, vm_prot_t prot);
+
+#endif /* _MEM_H_ */
diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c
index 3db03d76..fdf983b9 100644
--- a/i386/i386at/model_dep.c
+++ b/i386/i386at/model_dep.c
@@ -48,6 +48,7 @@
#include <kern/debug.h>
#include <kern/mach_clock.h>
#include <kern/printf.h>
+#include <kern/startup.h>
#include <sys/time.h>
#include <sys/types.h>
#include <vm/vm_page.h>
@@ -67,6 +68,8 @@
#include <i386at/int_init.h>
#include <i386at/kd.h>
#include <i386at/rtc.h>
+#include <i386at/model_dep.h>
+#include <i386at/acpihalt.h>
#ifdef MACH_XEN
#include <xen/console.h>
#include <xen/store.h>
@@ -74,14 +77,29 @@
#include <xen/xen.h>
#endif /* MACH_XEN */
+#if ENABLE_IMMEDIATE_CONSOLE
+#include "immc.h"
+#endif /* ENABLE_IMMEDIATE_CONSOLE */
+
/* Location of the kernel's symbol table.
Both of these are 0 if none is available. */
#if MACH_KDB
+#include <ddb/db_sym.h>
+#include <i386/db_interface.h>
+
+/* a.out symbol table */
static vm_offset_t kern_sym_start, kern_sym_end;
-#else
+
+/* ELF section header */
+static unsigned elf_shdr_num;
+static vm_size_t elf_shdr_size;
+static vm_offset_t elf_shdr_addr;
+static unsigned elf_shdr_shndx;
+
+#else /* MACH_KDB */
#define kern_sym_start 0
#define kern_sym_end 0
-#endif
+#endif /* MACH_KDB */
/* These indicate the total extent of physical memory addresses we're using.
They are page-aligned. */
@@ -123,14 +141,8 @@ static vm_size_t avail_remaining;
extern char version[];
-extern void setup_main();
-
-void halt_all_cpus (boolean_t reboot) __attribute__ ((noreturn));
-void halt_cpu (void) __attribute__ ((noreturn));
-
-void inittodr(); /* forward */
-
-int rebootflag = 0; /* exported to kdintr */
+/* If set, reboot the system on ctrl-alt-delete. */
+boolean_t rebootflag = FALSE; /* exported to kdintr */
/* XX interrupt stack pointer and highwater mark, for locore.S. */
vm_offset_t int_stack_top, int_stack_high;
@@ -139,8 +151,6 @@ vm_offset_t int_stack_top, int_stack_high;
extern void linux_init(void);
#endif
-boolean_t init_alloc_aligned(vm_size_t size, vm_offset_t *addrp);
-
/*
* Find devices. The system is alive.
*/
@@ -184,10 +194,14 @@ void machine_init(void)
*(unsigned short *)phystokv(0x472) = 0x1234;
#endif /* MACH_HYP */
+#if VM_MIN_KERNEL_ADDRESS == 0
/*
* Unmap page 0 to trap NULL references.
+ *
+ * Note that this breaks accessing some BIOS areas stored there.
*/
pmap_unmap_page_zero();
+#endif
}
/* Conserve power on processor CPU. */
@@ -201,7 +215,7 @@ void machine_idle (int cpu)
#endif /* MACH_HYP */
}
-void machine_relax ()
+void machine_relax (void)
{
asm volatile ("rep; nop" : : : "memory");
}
@@ -223,8 +237,7 @@ void halt_cpu(void)
/*
* Halt the system or reboot.
*/
-void halt_all_cpus(reboot)
- boolean_t reboot;
+void halt_all_cpus(boolean_t reboot)
{
if (reboot) {
#ifdef MACH_HYP
@@ -233,10 +246,11 @@ void halt_all_cpus(reboot)
kdreboot();
}
else {
- rebootflag = 1;
+ rebootflag = TRUE;
#ifdef MACH_HYP
hyp_halt();
#endif /* MACH_HYP */
+ grub_acpi_halt();
printf("In tight loop: hit ctl-alt-del to reboot\n");
(void) spl0();
}
@@ -249,6 +263,11 @@ void exit(int rc)
halt_all_cpus(0);
}
+void db_halt_cpu(void)
+{
+ halt_all_cpus(0);
+}
+
void db_reset_cpu(void)
{
halt_all_cpus(1);
@@ -274,14 +293,44 @@ mem_size_init(void)
} else
phys_last_addr = boot_info.nr_pages * 0x1000;
#else /* MACH_HYP */
- /* TODO: support mmap */
- vm_size_t phys_last_kb = 0x400 + boot_info.mem_upper;
- /* Avoid 4GiB overflow. */
- if (phys_last_kb < 0x400 || phys_last_kb >= 0x400000) {
- printf("Truncating memory size to 4GiB\n");
- phys_last_addr = 0xffffffffU;
- } else
- phys_last_addr = phys_last_kb * 0x400;
+ vm_size_t phys_last_kb;
+
+ if (boot_info.flags & MULTIBOOT_MEM_MAP) {
+ struct multiboot_mmap *map, *map_end;
+
+ map = (void*) phystokv(boot_info.mmap_addr);
+ map_end = (void*) map + boot_info.mmap_count;
+
+ while (map + 1 <= map_end) {
+ if (map->Type == MB_ARD_MEMORY) {
+ unsigned long long start = map->BaseAddr, end = map->BaseAddr + map->Length;;
+
+ if (start >= 0x100000000ULL) {
+ printf("Ignoring %luMiB RAM region above 4GiB\n", (unsigned long) (map->Length >> 20));
+ } else {
+ if (end >= 0x100000000ULL) {
+ printf("Truncating memory region to 4GiB\n");
+ end = 0x0ffffffffU;
+ }
+ if (end > phys_last_addr)
+ phys_last_addr = end;
+
+ printf("AT386 boot: physical memory map from 0x%lx to 0x%lx\n",
+ (unsigned long) start,
+ (unsigned long) end);
+ }
+ }
+ map = (void*) map + map->size + sizeof(map->size);
+ }
+ } else {
+ phys_last_kb = 0x400 + boot_info.mem_upper;
+ /* Avoid 4GiB overflow. */
+ if (phys_last_kb < 0x400 || phys_last_kb >= 0x400000) {
+ printf("Truncating memory size to 4GiB\n");
+ phys_last_addr = 0xffffffffU;
+ } else
+ phys_last_addr = phys_last_kb * 0x400;
+ }
#endif /* MACH_HYP */
printf("AT386 boot: physical memory from 0x%lx to 0x%lx\n",
@@ -292,7 +341,7 @@ mem_size_init(void)
max_phys_size = VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS - VM_KERNEL_MAP_SIZE;
if (phys_last_addr - phys_first_addr > max_phys_size) {
phys_last_addr = phys_first_addr + max_phys_size;
- printf("Truncating memory size to %luMiB\n", (phys_last_addr - phys_first_addr) / (1024 * 1024));
+ printf("Truncating memory to %luMiB\n", (phys_last_addr - phys_first_addr) / (1024 * 1024));
/* TODO Xen: be nice, free lost memory */
}
@@ -344,7 +393,7 @@ i386at_init(void)
int len = strlen ((char*)phystokv(boot_info.cmdline)) + 1;
assert(init_alloc_aligned(round_page(len), &addr));
kernel_cmdline = (char*) phystokv(addr);
- memcpy(kernel_cmdline, (char*)phystokv(boot_info.cmdline), len);
+ memcpy(kernel_cmdline, (void *)phystokv(boot_info.cmdline), len);
boot_info.cmdline = addr;
}
@@ -496,6 +545,10 @@ i386at_init(void)
*/
void c_boot_entry(vm_offset_t bi)
{
+#if ENABLE_IMMEDIATE_CONSOLE
+ romputc = immc_romputc;
+#endif /* ENABLE_IMMEDIATE_CONSOLE */
+
/* Stash the boot_image_info pointer. */
boot_info = *(typeof(boot_info)*)phystokv(bi);
int cpu_type;
@@ -535,6 +588,17 @@ void c_boot_entry(vm_offset_t bi)
kern_sym_start, kern_sym_end,
symtab_size, strtab_size);
}
+
+ if ((boot_info.flags & MULTIBOOT_ELF_SHDR)
+ && boot_info.syms.e.num)
+ {
+ elf_shdr_num = boot_info.syms.e.num;
+ elf_shdr_size = boot_info.syms.e.size;
+ elf_shdr_addr = (vm_offset_t)phystokv(boot_info.syms.e.addr);
+ elf_shdr_shndx = boot_info.syms.e.shndx;
+
+ printf("ELF section header table at %08lx\n", elf_shdr_addr);
+ }
#endif /* MACH_KDB */
#endif /* MACH_XEN */
@@ -551,7 +615,14 @@ void c_boot_entry(vm_offset_t bi)
*/
if (kern_sym_start)
{
- aout_db_sym_init(kern_sym_start, kern_sym_end, "mach", 0);
+ aout_db_sym_init((char *)kern_sym_start, (char *)kern_sym_end, "mach", (char *)0);
+ }
+
+ if (elf_shdr_num)
+ {
+ elf_db_sym_init(elf_shdr_num,elf_shdr_size,
+ elf_shdr_addr, elf_shdr_shndx,
+ "mach", NULL);
}
#endif /* MACH_KDB */
@@ -590,15 +661,13 @@ void c_boot_entry(vm_offset_t bi)
#include <mach/time_value.h>
int
-timemmap(dev,off,prot)
+timemmap(dev, off, prot)
+ dev_t dev;
+ vm_offset_t off;
vm_prot_t prot;
{
extern time_value_t *mtime;
-#ifdef lint
- dev++; off++;
-#endif /* lint */
-
if (prot & VM_PROT_WRITE) return (-1);
return (i386_btop(pmap_extract(pmap_kernel(), (vm_offset_t) mtime)));
@@ -710,7 +779,56 @@ init_alloc_aligned(vm_size_t size, vm_offset_t *addrp)
#ifndef MACH_HYP
/* Skip past the I/O and ROM area. */
- if ((avail_next > (boot_info.mem_lower * 0x400)) && (addr < 0x100000))
+ if (boot_info.flags & MULTIBOOT_MEM_MAP)
+ {
+ struct multiboot_mmap *map, *map_end, *current = NULL, *next = NULL;
+ unsigned long long minimum_next = ~0ULL;
+
+ map = (void*) phystokv(boot_info.mmap_addr);
+ map_end = (void*) map + boot_info.mmap_count;
+
+ /* Find both our current map, and the next one */
+ while (map + 1 <= map_end)
+ {
+ if (map->Type == MB_ARD_MEMORY)
+ {
+ unsigned long long start = map->BaseAddr;
+ unsigned long long end = start + map->Length;;
+
+ if (start <= addr && avail_next <= end)
+ {
+ /* Ok, fits in the current map */
+ current = map;
+ break;
+ }
+ else if (avail_next <= start && start < minimum_next)
+ {
+ /* This map is not far from avail_next */
+ next = map;
+ minimum_next = start;
+ }
+ }
+ map = (void*) map + map->size + sizeof(map->size);
+ }
+
+ if (!current) {
+ /* Area does not fit in the current map, switch to next
+ * map if any */
+ if (!next || next->BaseAddr >= phys_last_addr)
+ {
+ /* No further reachable map, we have reached
+ * the end of memory, but possibly wrap around
+ * 16MiB. */
+ avail_next = phys_last_addr;
+ goto retry;
+ }
+
+ /* Start from next map */
+ avail_next = next->BaseAddr;
+ goto retry;
+ }
+ }
+ else if ((avail_next > (boot_info.mem_lower * 0x400)) && (addr < 0x100000))
{
avail_next = 0x100000;
goto retry;
@@ -762,8 +880,7 @@ init_alloc_aligned(vm_size_t size, vm_offset_t *addrp)
return TRUE;
}
-boolean_t pmap_next_page(addrp)
- vm_offset_t *addrp;
+boolean_t pmap_next_page(vm_offset_t *addrp)
{
return init_alloc_aligned(PAGE_SIZE, addrp);
}
@@ -780,8 +897,7 @@ pmap_grab_page(void)
return addr;
}
-boolean_t pmap_valid_page(x)
- vm_offset_t x;
+boolean_t pmap_valid_page(vm_offset_t x)
{
/* XXX is this OK? What does it matter for? */
return (((phys_first_addr <= x) && (x < phys_last_addr))
diff --git a/i386/i386at/model_dep.h b/i386/i386at/model_dep.h
new file mode 100644
index 00000000..aa240320
--- /dev/null
+++ b/i386/i386at/model_dep.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _MODEL_DEP_H_
+#define _MODEL_DEP_H_
+
+#include <mach/vm_prot.h>
+
+extern int timemmap(dev_t dev, vm_offset_t off, vm_prot_t prot);
+
+void inittodr(void);
+
+boolean_t init_alloc_aligned(vm_size_t size, vm_offset_t *addrp);
+
+#endif /* _MODEL_DEP_H_ */
diff --git a/i386/i386at/pic_isa.c b/i386/i386at/pic_isa.c
index e48fb507..0b36534e 100644
--- a/i386/i386at/pic_isa.c
+++ b/i386/i386at/pic_isa.c
@@ -28,10 +28,10 @@
#include <i386/ipl.h>
#include <i386/pic.h>
#include <i386/fpu.h>
+#include <i386/hardclock.h>
#include <i386at/kd.h>
/* These interrupts are always present */
-extern void hardclock();
void (*ivect[NINTR])() = {
/* 00 */ hardclock, /* always */
diff --git a/i386/i386at/rtc.c b/i386/i386at/rtc.c
index 67768013..01e09772 100644
--- a/i386/i386at/rtc.c
+++ b/i386/i386at/rtc.c
@@ -53,10 +53,10 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <i386/pio.h>
#include <i386at/rtc.h>
-static int first_rtcopen_ever = 1;
+static boolean_t first_rtcopen_ever = TRUE;
void
-rtcinit()
+rtcinit(void)
{
outb(RTC_ADDR, RTC_A);
outb(RTC_DATA, RTC_DIV2 | RTC_RATE6);
@@ -66,12 +66,12 @@ rtcinit()
int
-rtcget(regs)
-unsigned char *regs;
+rtcget(struct rtc_st *st)
{
+ unsigned char *regs = (unsigned char *)st;
if (first_rtcopen_ever) {
rtcinit();
- first_rtcopen_ever = 0;
+ first_rtcopen_ever = FALSE;
}
outb(RTC_ADDR, RTC_D);
if ((inb(RTC_DATA) & RTC_VRT) == 0) return(-1);
@@ -83,14 +83,14 @@ unsigned char *regs;
}
void
-rtcput(regs)
-unsigned char *regs;
+rtcput(struct rtc_st *st)
{
- register unsigned char x;
+ unsigned char *regs = (unsigned char *)st;
+ unsigned char x;
if (first_rtcopen_ever) {
rtcinit();
- first_rtcopen_ever = 0;
+ first_rtcopen_ever = FALSE;
}
outb(RTC_ADDR, RTC_B);
x = inb(RTC_DATA);
@@ -103,34 +103,29 @@ unsigned char *regs;
extern struct timeval time;
-extern struct timezone tz;
static int month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int
-yeartoday(year)
-int year;
+yeartoday(int year)
{
return((year%4) ? 365 : 366);
}
int
-hexdectodec(n)
-char n;
+hexdectodec(char n)
{
return(((n>>4)&0x0F)*10 + (n&0x0F));
}
char
-dectohexdec(n)
-int n;
+dectohexdec(int n)
{
return((char)(((n/10)<<4)&0xF0) | ((n%10)&0x0F));
}
int
-readtodc(tp)
- u_int *tp;
+readtodc(u_int *tp)
{
struct rtc_st rtclk;
time_t n;
@@ -172,7 +167,7 @@ readtodc(tp)
}
int
-writetodc()
+writetodc(void)
{
struct rtc_st rtclk;
time_t n;
diff --git a/i386/i386at/rtc.h b/i386/i386at/rtc.h
index ced39b98..97eabe95 100644
--- a/i386/i386at/rtc.h
+++ b/i386/i386at/rtc.h
@@ -45,6 +45,9 @@ NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifndef _RTC_H_
+#define _RTC_H_
+
#define RTC_ADDR 0x70 /* I/O port address for register select */
#define RTC_DATA 0x71 /* I/O port address for data read/write */
@@ -114,7 +117,7 @@ struct rtc_st {
*/
#define load_rtc(regs) \
{\
- register int i; \
+ int i; \
\
for (i = 0; i < RTC_NREG; i++) { \
outb(RTC_ADDR, i); \
@@ -127,7 +130,7 @@ struct rtc_st {
*/
#define save_rtc(regs) \
{ \
- register int i; \
+ int i; \
for (i = 0; i < RTC_NREGP; i++) { \
outb(RTC_ADDR, i); \
outb(RTC_DATA, regs[i]);\
@@ -136,3 +139,5 @@ struct rtc_st {
extern int readtodc(u_int *tp);
extern int writetodc(void);
+
+#endif /* _RTC_H_ */
diff --git a/i386/include/mach/i386/asm.h b/i386/include/mach/i386/asm.h
index 3e3f48bf..4e3b589a 100644
--- a/i386/include/mach/i386/asm.h
+++ b/i386/include/mach/i386/asm.h
@@ -24,6 +24,8 @@
* the rights to redistribute these changes.
*/
+#ifndef _MACH_I386_ASM_H_
+#define _MACH_I386_ASM_H_
#define S_ARG0 4(%esp)
#define S_ARG1 8(%esp)
@@ -113,3 +115,5 @@
#define Entry(x) .globl EXT(x); .p2align TEXT_ALIGN; LEXT(x)
#define DATA(x) .globl EXT(x); .p2align DATA_ALIGN; LEXT(x)
+
+#endif /* _MACH_I386_ASM_H_ */
diff --git a/i386/include/mach/i386/cthreads.h b/i386/include/mach/i386/cthreads.h
index f9755b4a..d2aa16f5 100644
--- a/i386/include/mach/i386/cthreads.h
+++ b/i386/include/mach/i386/cthreads.h
@@ -53,4 +53,4 @@ typedef volatile int spin_lock_t;
#endif /* __GNUC__ */
-#endif _MACHINE_CTHREADS_H_
+#endif /* _MACHINE_CTHREADS_H_ */
diff --git a/i386/include/mach/i386/disk.h b/i386/include/mach/i386/disk.h
index 40ed4fa8..1bbbbdf3 100644
--- a/i386/include/mach/i386/disk.h
+++ b/i386/include/mach/i386/disk.h
@@ -49,6 +49,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* disk.h
*/
+#ifndef _MACH_I386_DISK_H_
+#define _MACH_I386_DISK_H_
+
#if defined(__linux__) || defined(__masix__)
#define PART_DISK 4 /* partition number for entire disk */
#else
@@ -118,3 +121,4 @@ struct absio {
char *abs_buf; /* Sector buffer */
};
+#endif /* _MACH_I386_DISK_H_ */
diff --git a/i386/include/mach/i386/mach_i386_types.h b/i386/include/mach/i386/mach_i386_types.h
index b03c0b06..b0552809 100644
--- a/i386/include/mach/i386/mach_i386_types.h
+++ b/i386/include/mach/i386/mach_i386_types.h
@@ -47,9 +47,9 @@ typedef struct descriptor *descriptor_list_t;
#ifdef MACH_KERNEL
#include <i386/io_perm.h>
-#else
+#else /* MACH_KERNEL */
typedef unsigned short io_port_t;
typedef mach_port_t io_perm_t;
-#endif
+#endif /* MACH_KERNEL */
#endif /* _MACH_MACH_I386_TYPES_H_ */
diff --git a/i386/include/mach/i386/multiboot.h b/i386/include/mach/i386/multiboot.h
index 7aa0b1c4..8f1c47b0 100644
--- a/i386/include/mach/i386/multiboot.h
+++ b/i386/include/mach/i386/multiboot.h
@@ -175,6 +175,16 @@ struct AddrRangeDesc
/* unspecified optional padding... */
};
+struct multiboot_mmap
+{
+ unsigned long size;
+ unsigned long long BaseAddr;
+ unsigned long long Length;
+ unsigned long Type;
+
+ /* unspecified optional padding... */
+};
+
/* usable memory "Type", all others are reserved. */
#define MB_ARD_MEMORY 1
diff --git a/i386/include/mach/i386/rpc.h b/i386/include/mach/i386/rpc.h
deleted file mode 100644
index 71d31fb9..00000000
--- a/i386/include/mach/i386/rpc.h
+++ /dev/null
@@ -1,9 +0,0 @@
-
-struct rpc_csig_action
-{
-};
-
-struct rpc_csig_entry
-{
-};
-
diff --git a/i386/include/mach/i386/thread_status.h b/i386/include/mach/i386/thread_status.h
index 5f20355e..ba1e3dea 100644
--- a/i386/include/mach/i386/thread_status.h
+++ b/i386/include/mach/i386/thread_status.h
@@ -56,6 +56,7 @@
#define i386_ISA_PORT_MAP_STATE 3
#define i386_V86_ASSIST_STATE 4
#define i386_REGS_SEGS_STATE 5
+#define i386_DEBUG_STATE 6
/*
* This structure is used for both
@@ -144,4 +145,10 @@ struct v86_interrupt_table {
#define i386_V86_ASSIST_STATE_COUNT \
(sizeof(struct i386_v86_assist_state)/sizeof(unsigned int))
+struct i386_debug_state {
+ unsigned int dr[8];
+};
+#define i386_DEBUG_STATE_COUNT \
+ (sizeof(struct i386_debug_state)/sizeof(unsigned int))
+
#endif /* _MACH_I386_THREAD_STATUS_H_ */
diff --git a/i386/include/mach/i386/vm_param.h b/i386/include/mach/i386/vm_param.h
index 8f708f0f..3a209b83 100644
--- a/i386/include/mach/i386/vm_param.h
+++ b/i386/include/mach/i386/vm_param.h
@@ -29,7 +29,7 @@
* Date: 1985
*
* I386 machine dependent virtual memory parameters.
- * Most of the declarations are preceeded by I386_ (or i386_)
+ * Most of the declarations are preceded by I386_ (or i386_)
* which is OK because only I386 specific code will be using
* them.
*/
diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c
index 490c1d95..dc9f3605 100644
--- a/i386/intel/pmap.c
+++ b/i386/intel/pmap.c
@@ -166,7 +166,7 @@ vm_offset_t kernel_virtual_end;
#define unlock_pvh_pai(pai) (bit_unlock(pai, pv_lock_table))
/*
- * Array of physical page attribites for managed pages.
+ * Array of physical page attributes for managed pages.
* One byte per physical page.
*/
char *pmap_phys_attributes;
@@ -402,7 +402,7 @@ pmap_t kernel_pmap;
struct kmem_cache pmap_cache; /* cache of pmap structures */
-int pmap_debug = 0; /* flag for debugging prints */
+boolean_t pmap_debug = FALSE; /* flag for debugging prints */
#if 0
int ptes_per_vm_page; /* number of hardware ptes needed
@@ -413,21 +413,20 @@ int ptes_per_vm_page; /* number of hardware ptes needed
unsigned int inuse_ptepages_count = 0; /* debugging */
-extern char end;
-
/*
* Pointer to the basic page directory for the kernel.
* Initialized by pmap_bootstrap().
*/
pt_entry_t *kernel_page_dir;
-void pmap_remove_range(); /* forward */
-#if NCPUS > 1
-void signal_cpus(); /* forward */
-#endif /* NCPUS > 1 */
+/*
+ * Two slots for temporary physical page mapping, to allow for
+ * physical-to-physical transfers.
+ */
+static pmap_mapwindow_t mapwindows[PMAP_NMAPWINDOWS];
static inline pt_entry_t *
-pmap_pde(pmap_t pmap, vm_offset_t addr)
+pmap_pde(const pmap_t pmap, vm_offset_t addr)
{
if (pmap == kernel_pmap)
addr = kvtolin(addr);
@@ -442,7 +441,7 @@ pmap_pde(pmap_t pmap, vm_offset_t addr)
* This is only used internally.
*/
pt_entry_t *
-pmap_pte(pmap_t pmap, vm_offset_t addr)
+pmap_pte(const pmap_t pmap, vm_offset_t addr)
{
pt_entry_t *ptp;
pt_entry_t pte;
@@ -459,10 +458,9 @@ pmap_pte(pmap_t pmap, vm_offset_t addr)
#define DEBUG_PTE_PAGE 0
#if DEBUG_PTE_PAGE
-void ptep_check(ptep)
- ptep_t ptep;
+void ptep_check(ptep_t ptep)
{
- register pt_entry_t *pte, *epte;
+ pt_entry_t *pte, *epte;
int ctu, ctw;
/* check the use and wired counts */
@@ -496,13 +494,13 @@ void ptep_check(ptep)
* For now, VM is already on, we only need to map the
* specified memory.
*/
-vm_offset_t pmap_map(virt, start, end, prot)
- register vm_offset_t virt;
- register vm_offset_t start;
- register vm_offset_t end;
- register int prot;
+vm_offset_t pmap_map(
+ vm_offset_t virt,
+ vm_offset_t start,
+ vm_offset_t end,
+ int prot)
{
- register int ps;
+ int ps;
ps = PAGE_SIZE;
while (start < end) {
@@ -519,15 +517,15 @@ vm_offset_t pmap_map(virt, start, end, prot)
* [phys_first_addr, phys_last_addr) (i.e., devices).
* Otherwise like pmap_map.
*/
-vm_offset_t pmap_map_bd(virt, start, end, prot)
- register vm_offset_t virt;
- register vm_offset_t start;
- register vm_offset_t end;
- vm_prot_t prot;
+vm_offset_t pmap_map_bd(
+ vm_offset_t virt,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_prot_t prot)
{
- register pt_entry_t template;
- register pt_entry_t *pte;
- int spl;
+ pt_entry_t template;
+ pt_entry_t *pte;
+ int spl;
#ifdef MACH_PV_PAGETABLES
int n, i = 0;
struct mmu_update update[HYP_BATCH_MMU_UPDATES];
@@ -580,7 +578,7 @@ vm_offset_t pmap_map_bd(virt, start, end, prot)
* and direct-map all physical memory.
* Called with mapping off.
*/
-void pmap_bootstrap()
+void pmap_bootstrap(void)
{
/*
* Mapping is turned off; we must reference only physical addresses.
@@ -781,6 +779,12 @@ void pmap_bootstrap()
}
for (; pte < ptable+NPTES; pte++)
{
+ if (va >= kernel_virtual_end - PMAP_NMAPWINDOWS * PAGE_SIZE && va < kernel_virtual_end)
+ {
+ pmap_mapwindow_t *win = &mapwindows[atop(va - (kernel_virtual_end - PMAP_NMAPWINDOWS * PAGE_SIZE))];
+ win->entry = pte;
+ win->vaddr = va;
+ }
WRITE_PTE(pte, 0);
va += INTEL_PGBYTES;
}
@@ -891,12 +895,41 @@ void pmap_clear_bootstrap_pagetable(pt_entry_t *base) {
}
#endif /* MACH_PV_PAGETABLES */
-void pmap_virtual_space(startp, endp)
- vm_offset_t *startp;
- vm_offset_t *endp;
+/*
+ * Create a temporary mapping for a given physical entry
+ *
+ * This can be used to access physical pages which are not mapped 1:1 by
+ * phystokv().
+ */
+pmap_mapwindow_t *pmap_get_mapwindow(pt_entry_t entry)
+{
+ pmap_mapwindow_t *map;
+
+ /* Find an empty one. */
+ for (map = &mapwindows[0]; map < &mapwindows[sizeof (mapwindows) / sizeof (*mapwindows)]; map++)
+ if (!(*map->entry))
+ break;
+ assert(map < &mapwindows[sizeof (mapwindows) / sizeof (*mapwindows)]);
+
+ WRITE_PTE(map->entry, entry);
+ return map;
+}
+
+/*
+ * Destroy a temporary mapping for a physical entry
+ */
+void pmap_put_mapwindow(pmap_mapwindow_t *map)
+{
+ WRITE_PTE(map->entry, 0);
+ PMAP_UPDATE_TLBS(kernel_pmap, map->vaddr, map->vaddr + PAGE_SIZE);
+}
+
+void pmap_virtual_space(
+ vm_offset_t *startp,
+ vm_offset_t *endp)
{
*startp = kernel_virtual_start;
- *endp = kernel_virtual_end;
+ *endp = kernel_virtual_end - PMAP_NMAPWINDOWS * PAGE_SIZE;
}
/*
@@ -904,11 +937,11 @@ void pmap_virtual_space(startp, endp)
* Called by vm_init, to initialize any structures that the pmap
* system needs to map virtual memory.
*/
-void pmap_init()
+void pmap_init(void)
{
- register long npages;
+ long npages;
vm_offset_t addr;
- register vm_size_t s;
+ vm_size_t s;
#if NCPUS > 1
int i;
#endif /* NCPUS > 1 */
@@ -926,7 +959,7 @@ void pmap_init()
s = round_page(s);
if (kmem_alloc_wired(kernel_map, &addr, s) != KERN_SUCCESS)
panic("pmap_init");
- memset((char *) addr, 0, s);
+ memset((void *) addr, 0, s);
/*
* Allocate the structures first to preserve word-alignment.
@@ -968,8 +1001,7 @@ void pmap_init()
#define valid_page(x) (pmap_initialized && pmap_valid_page(x))
-boolean_t pmap_verify_free(phys)
- vm_offset_t phys;
+boolean_t pmap_verify_free(vm_offset_t phys)
{
pv_entry_t pv_h;
int pai;
@@ -1003,10 +1035,10 @@ boolean_t pmap_verify_free(phys)
* since these must be unlocked to use vm_page_grab.
*/
vm_offset_t
-pmap_page_table_page_alloc()
+pmap_page_table_page_alloc(void)
{
- register vm_page_t m;
- register vm_offset_t pa;
+ vm_page_t m;
+ vm_offset_t pa;
check_simple_locks();
@@ -1092,8 +1124,7 @@ void pmap_map_mfn(void *_addr, unsigned long mfn) {
* and be removed from its page directory.
*/
void
-pmap_page_table_page_dealloc(pa)
- vm_offset_t pa;
+pmap_page_table_page_dealloc(vm_offset_t pa)
{
vm_page_t m;
@@ -1118,11 +1149,10 @@ pmap_page_table_page_dealloc(pa)
* the map will be used in software only, and
* is bounded by that size.
*/
-pmap_t pmap_create(size)
- vm_size_t size;
+pmap_t pmap_create(vm_size_t size)
{
- register pmap_t p;
- register pmap_statistics_t stats;
+ pmap_t p;
+ pmap_statistics_t stats;
/*
* A software use-only map doesn't even need a map.
@@ -1198,13 +1228,12 @@ pmap_t pmap_create(size)
* no valid mappings.
*/
-void pmap_destroy(p)
- register pmap_t p;
+void pmap_destroy(pmap_t p)
{
- register pt_entry_t *pdep;
- register vm_offset_t pa;
- register int c, s;
- register vm_page_t m;
+ pt_entry_t *pdep;
+ vm_offset_t pa;
+ int c, s;
+ vm_page_t m;
if (p == PMAP_NULL)
return;
@@ -1265,8 +1294,7 @@ void pmap_destroy(p)
* Add a reference to the specified pmap.
*/
-void pmap_reference(p)
- register pmap_t p;
+void pmap_reference(pmap_t p)
{
int s;
if (p != PMAP_NULL) {
@@ -1291,13 +1319,13 @@ void pmap_reference(p)
*/
/* static */
-void pmap_remove_range(pmap, va, spte, epte)
- pmap_t pmap;
- vm_offset_t va;
- pt_entry_t *spte;
- pt_entry_t *epte;
+void pmap_remove_range(
+ pmap_t pmap,
+ vm_offset_t va,
+ pt_entry_t *spte,
+ pt_entry_t *epte)
{
- register pt_entry_t *cpte;
+ pt_entry_t *cpte;
int num_removed, num_unwired;
int pai;
vm_offset_t pa;
@@ -1330,8 +1358,8 @@ void pmap_remove_range(pmap, va, spte, epte)
* Outside range of managed physical memory.
* Just remove the mappings.
*/
- register int i = ptes_per_vm_page;
- register pt_entry_t *lpte = cpte;
+ int i = ptes_per_vm_page;
+ pt_entry_t *lpte = cpte;
do {
#ifdef MACH_PV_PAGETABLES
update[ii].ptr = kv_to_ma(lpte);
@@ -1358,8 +1386,8 @@ void pmap_remove_range(pmap, va, spte, epte)
* Get the modify and reference bits.
*/
{
- register int i;
- register pt_entry_t *lpte;
+ int i;
+ pt_entry_t *lpte;
i = ptes_per_vm_page;
lpte = cpte;
@@ -1388,7 +1416,7 @@ void pmap_remove_range(pmap, va, spte, epte)
* this physical page.
*/
{
- register pv_entry_t pv_h, prev, cur;
+ pv_entry_t pv_h, prev, cur;
pv_h = pai_to_pvh(pai);
if (pv_h->pmap == PMAP_NULL) {
@@ -1447,13 +1475,14 @@ void pmap_remove_range(pmap, va, spte, epte)
* rounded to the hardware page size.
*/
-void pmap_remove(map, s, e)
- pmap_t map;
- vm_offset_t s, e;
+void pmap_remove(
+ pmap_t map,
+ vm_offset_t s,
+ vm_offset_t e)
{
int spl;
- register pt_entry_t *pde;
- register pt_entry_t *spte, *epte;
+ pt_entry_t *pde;
+ pt_entry_t *spte, *epte;
vm_offset_t l;
vm_offset_t _s = s;
@@ -1488,15 +1517,15 @@ void pmap_remove(map, s, e)
* Lower the permission for all mappings to a given
* page.
*/
-void pmap_page_protect(phys, prot)
- vm_offset_t phys;
- vm_prot_t prot;
+void pmap_page_protect(
+ vm_offset_t phys,
+ vm_prot_t prot)
{
pv_entry_t pv_h, prev;
- register pv_entry_t pv_e;
- register pt_entry_t *pte;
+ pv_entry_t pv_e;
+ pt_entry_t *pte;
int pai;
- register pmap_t pmap;
+ pmap_t pmap;
int spl;
boolean_t remove;
@@ -1542,7 +1571,7 @@ void pmap_page_protect(phys, prot)
prev = pv_e = pv_h;
do {
- register vm_offset_t va;
+ vm_offset_t va;
pmap = pv_e->pmap;
/*
@@ -1571,7 +1600,7 @@ void pmap_page_protect(phys, prot)
panic("pmap_remove_all removing a wired page");
{
- register int i = ptes_per_vm_page;
+ int i = ptes_per_vm_page;
do {
pmap_phys_attributes[pai] |=
@@ -1608,7 +1637,7 @@ void pmap_page_protect(phys, prot)
/*
* Write-protect.
*/
- register int i = ptes_per_vm_page;
+ int i = ptes_per_vm_page;
do {
#ifdef MACH_PV_PAGETABLES
@@ -1651,14 +1680,15 @@ void pmap_page_protect(phys, prot)
* specified range of this map as requested.
* Will not increase permissions.
*/
-void pmap_protect(map, s, e, prot)
- pmap_t map;
- vm_offset_t s, e;
- vm_prot_t prot;
+void pmap_protect(
+ pmap_t map,
+ vm_offset_t s,
+ vm_offset_t e,
+ vm_prot_t prot)
{
- register pt_entry_t *pde;
- register pt_entry_t *spte, *epte;
- vm_offset_t l;
+ pt_entry_t *pde;
+ pt_entry_t *spte, *epte;
+ vm_offset_t l;
int spl;
vm_offset_t _s = s;
@@ -1757,16 +1787,16 @@ void pmap_protect(map, s, e, prot)
* or lose information. That is, this routine must actually
* insert this page into the given map NOW.
*/
-void pmap_enter(pmap, v, pa, prot, wired)
- register pmap_t pmap;
- vm_offset_t v;
- register vm_offset_t pa;
- vm_prot_t prot;
- boolean_t wired;
+void pmap_enter(
+ pmap_t pmap,
+ vm_offset_t v,
+ vm_offset_t pa,
+ vm_prot_t prot,
+ boolean_t wired)
{
- register pt_entry_t *pte;
- register pv_entry_t pv_h;
- register int i, pai;
+ pt_entry_t *pte;
+ pv_entry_t pv_h;
+ int i, pai;
pv_entry_t pv_e;
pt_entry_t template;
int spl;
@@ -2059,14 +2089,14 @@ Retry:
* In/out conditions:
* The mapping must already exist in the pmap.
*/
-void pmap_change_wiring(map, v, wired)
- register pmap_t map;
- vm_offset_t v;
- boolean_t wired;
+void pmap_change_wiring(
+ pmap_t map,
+ vm_offset_t v,
+ boolean_t wired)
{
- register pt_entry_t *pte;
- register int i;
- int spl;
+ pt_entry_t *pte;
+ int i;
+ int spl;
/*
* We must grab the pmap system lock because we may
@@ -2114,13 +2144,13 @@ void pmap_change_wiring(map, v, wired)
* with the given map/virtual_address pair.
*/
-vm_offset_t pmap_extract(pmap, va)
- register pmap_t pmap;
- vm_offset_t va;
+vm_offset_t pmap_extract(
+ pmap_t pmap,
+ vm_offset_t va)
{
- register pt_entry_t *pte;
- register vm_offset_t pa;
- int spl;
+ pt_entry_t *pte;
+ vm_offset_t pa;
+ int spl;
SPLVM(spl);
simple_lock(&pmap->lock);
@@ -2150,9 +2180,6 @@ void pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
vm_size_t len;
vm_offset_t src_addr;
{
-#ifdef lint
- dst_pmap++; src_pmap++; dst_addr++; len++; src_addr++;
-#endif /* lint */
}
#endif /* 0 */
@@ -2167,10 +2194,9 @@ void pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
* Usage:
* Called by the pageout daemon when pages are scarce.
*/
-void pmap_collect(p)
- pmap_t p;
+void pmap_collect(pmap_t p)
{
- register pt_entry_t *pdp, *ptp;
+ pt_entry_t *pdp, *ptp;
pt_entry_t *eptp;
vm_offset_t pa;
int spl, wired;
@@ -2201,7 +2227,7 @@ void pmap_collect(p)
*/
wired = 0;
{
- register pt_entry_t *ptep;
+ pt_entry_t *ptep;
for (ptep = ptp; ptep < eptp; ptep++) {
if (*ptep & INTEL_PTE_WIRED) {
wired = 1;
@@ -2227,8 +2253,8 @@ void pmap_collect(p)
* Invalidate the page directory pointer.
*/
{
- register int i = ptes_per_vm_page;
- register pt_entry_t *pdep = pdp;
+ int i = ptes_per_vm_page;
+ pt_entry_t *pdep = pdp;
do {
#ifdef MACH_PV_PAGETABLES
unsigned long pte = *pdep;
@@ -2250,7 +2276,7 @@ void pmap_collect(p)
* And free the pte page itself.
*/
{
- register vm_page_t m;
+ vm_page_t m;
vm_object_lock(pmap_object);
m = vm_page_lookup(pmap_object, pa);
@@ -2303,9 +2329,6 @@ void pmap_deactivate(pmap, th, which_cpu)
thread_t th;
int which_cpu;
{
-#ifdef lint
- pmap++; th++; which_cpu++;
-#endif /* lint */
PMAP_DEACTIVATE(pmap, th, which_cpu);
}
#endif /* 0 */
@@ -2378,30 +2401,27 @@ pmap_copy_page(src, dst)
* down (or not) as appropriate.
*/
void
-pmap_pageable(pmap, start, end, pageable)
- pmap_t pmap;
- vm_offset_t start;
- vm_offset_t end;
- boolean_t pageable;
+pmap_pageable(
+ pmap_t pmap,
+ vm_offset_t start,
+ vm_offset_t end,
+ boolean_t pageable)
{
-#ifdef lint
- pmap++; start++; end++; pageable++;
-#endif /* lint */
}
/*
* Clear specified attribute bits.
*/
void
-phys_attribute_clear(phys, bits)
- vm_offset_t phys;
- int bits;
+phys_attribute_clear(
+ vm_offset_t phys,
+ int bits)
{
pv_entry_t pv_h;
- register pv_entry_t pv_e;
- register pt_entry_t *pte;
+ pv_entry_t pv_e;
+ pt_entry_t *pte;
int pai;
- register pmap_t pmap;
+ pmap_t pmap;
int spl;
assert(phys != vm_page_fictitious_addr);
@@ -2432,7 +2452,7 @@ phys_attribute_clear(phys, bits)
* There are some mappings.
*/
for (pv_e = pv_h; pv_e != PV_ENTRY_NULL; pv_e = pv_e->next) {
- register vm_offset_t va;
+ vm_offset_t va;
pmap = pv_e->pmap;
/*
@@ -2455,7 +2475,7 @@ phys_attribute_clear(phys, bits)
* Clear modify or reference bits.
*/
{
- register int i = ptes_per_vm_page;
+ int i = ptes_per_vm_page;
do {
#ifdef MACH_PV_PAGETABLES
if (!(hyp_mmu_update_pte(kv_to_ma(pte), *pte & ~bits)))
@@ -2479,15 +2499,15 @@ phys_attribute_clear(phys, bits)
* Check specified attribute bits.
*/
boolean_t
-phys_attribute_test(phys, bits)
- vm_offset_t phys;
- int bits;
+phys_attribute_test(
+ vm_offset_t phys,
+ int bits)
{
pv_entry_t pv_h;
- register pv_entry_t pv_e;
- register pt_entry_t *pte;
+ pv_entry_t pv_e;
+ pt_entry_t *pte;
int pai;
- register pmap_t pmap;
+ pmap_t pmap;
int spl;
assert(phys != vm_page_fictitious_addr);
@@ -2531,7 +2551,7 @@ phys_attribute_test(phys, bits)
simple_lock(&pmap->lock);
{
- register vm_offset_t va;
+ vm_offset_t va;
va = pv_e->va;
pte = pmap_pte(pmap, va);
@@ -2549,7 +2569,7 @@ phys_attribute_test(phys, bits)
* Check modify or reference bits.
*/
{
- register int i = ptes_per_vm_page;
+ int i = ptes_per_vm_page;
do {
if (*pte & bits) {
@@ -2570,8 +2590,7 @@ phys_attribute_test(phys, bits)
* Clear the modify bits on the specified physical page.
*/
-void pmap_clear_modify(phys)
- register vm_offset_t phys;
+void pmap_clear_modify(vm_offset_t phys)
{
phys_attribute_clear(phys, PHYS_MODIFIED);
}
@@ -2583,8 +2602,7 @@ void pmap_clear_modify(phys)
* by any physical maps.
*/
-boolean_t pmap_is_modified(phys)
- register vm_offset_t phys;
+boolean_t pmap_is_modified(vm_offset_t phys)
{
return (phys_attribute_test(phys, PHYS_MODIFIED));
}
@@ -2595,8 +2613,7 @@ boolean_t pmap_is_modified(phys)
* Clear the reference bit on the specified physical page.
*/
-void pmap_clear_reference(phys)
- vm_offset_t phys;
+void pmap_clear_reference(vm_offset_t phys)
{
phys_attribute_clear(phys, PHYS_REFERENCED);
}
@@ -2608,8 +2625,7 @@ void pmap_clear_reference(phys)
* by any physical maps.
*/
-boolean_t pmap_is_referenced(phys)
- vm_offset_t phys;
+boolean_t pmap_is_referenced(vm_offset_t phys)
{
return (phys_attribute_test(phys, PHYS_REFERENCED));
}
@@ -2678,13 +2694,14 @@ boolean_t pmap_is_referenced(phys)
/*
* Signal another CPU that it must flush its TLB
*/
-void signal_cpus(use_list, pmap, start, end)
- cpu_set use_list;
- pmap_t pmap;
- vm_offset_t start, end;
+void signal_cpus(
+ cpu_set use_list,
+ pmap_t pmap,
+ vm_offset_t start,
+ vm_offset_t end)
{
- register int which_cpu, j;
- register pmap_update_list_t update_list_p;
+ int which_cpu, j;
+ pmap_update_list_t update_list_p;
while ((which_cpu = ffs(use_list)) != 0) {
which_cpu -= 1; /* convert to 0 origin */
@@ -2717,13 +2734,12 @@ void signal_cpus(use_list, pmap, start, end)
}
}
-void process_pmap_updates(my_pmap)
- register pmap_t my_pmap;
+void process_pmap_updates(pmap_t my_pmap)
{
- register int my_cpu = cpu_number();
- register pmap_update_list_t update_list_p;
- register int j;
- register pmap_t pmap;
+ int my_cpu = cpu_number();
+ pmap_update_list_t update_list_p;
+ int j;
+ pmap_t pmap;
update_list_p = &cpu_update_list[my_cpu];
simple_lock(&update_list_p->lock);
@@ -2748,9 +2764,9 @@ void process_pmap_updates(my_pmap)
*/
void pmap_update_interrupt(void)
{
- register int my_cpu;
- register pmap_t my_pmap;
- int s;
+ int my_cpu;
+ pmap_t my_pmap;
+ int s;
my_cpu = cpu_number();
@@ -2806,7 +2822,7 @@ void pmap_update_interrupt(void)
/*
* Dummy routine to satisfy external reference.
*/
-void pmap_update_interrupt()
+void pmap_update_interrupt(void)
{
/* should never be called. */
}
@@ -2815,10 +2831,11 @@ void pmap_update_interrupt()
#if defined(__i386__)
/* Unmap page 0 to trap NULL references. */
void
-pmap_unmap_page_zero ()
+pmap_unmap_page_zero (void)
{
int *pte;
+ printf("Unmapping the zero page. Some BIOS functions may not be working any more.\n");
pte = (int *) pmap_pte (kernel_pmap, 0);
if (!pte)
return;
diff --git a/i386/intel/pmap.h b/i386/intel/pmap.h
index 93293e3d..382cd5f4 100644
--- a/i386/intel/pmap.h
+++ b/i386/intel/pmap.h
@@ -192,6 +192,16 @@ extern void pmap_clear_bootstrap_pagetable(pt_entry_t *addr);
#define set_pmap(pmap) set_cr3(kvtophys((vm_offset_t)(pmap)->dirbase))
#endif /* PAE */
+typedef struct {
+ pt_entry_t *entry;
+ vm_offset_t vaddr;
+} pmap_mapwindow_t;
+
+extern pmap_mapwindow_t *pmap_get_mapwindow(pt_entry_t entry);
+extern void pmap_put_mapwindow(pmap_mapwindow_t *map);
+
+#define PMAP_NMAPWINDOWS 2
+
#if NCPUS > 1
/*
* List of cpus that are actively using mapped memory. Any
@@ -227,7 +237,7 @@ extern pmap_t kernel_pmap;
* Machine dependent routines that are used only for i386/i486.
*/
-pt_entry_t *pmap_pte(pmap_t pmap, vm_offset_t addr);
+pt_entry_t *pmap_pte(const pmap_t pmap, vm_offset_t addr);
/*
* Macros for speed.
@@ -282,7 +292,7 @@ pt_entry_t *pmap_pte(pmap_t pmap, vm_offset_t addr);
}
#define PMAP_ACTIVATE_USER(pmap, th, my_cpu) { \
- register pmap_t tpmap = (pmap); \
+ pmap_t tpmap = (pmap); \
\
if (tpmap == kernel_pmap) { \
/* \
@@ -324,7 +334,7 @@ pt_entry_t *pmap_pte(pmap_t pmap, vm_offset_t addr);
}
#define PMAP_DEACTIVATE_USER(pmap, thread, my_cpu) { \
- register pmap_t tpmap = (pmap); \
+ pmap_t tpmap = (pmap); \
\
/* \
* Do nothing if this is the kernel pmap. \
@@ -395,7 +405,7 @@ pt_entry_t *pmap_pte(pmap_t pmap, vm_offset_t addr);
}
#define PMAP_ACTIVATE_USER(pmap, th, my_cpu) { \
- register pmap_t tpmap = (pmap); \
+ pmap_t tpmap = (pmap); \
(void) (th); \
(void) (my_cpu); \
\
@@ -451,6 +461,20 @@ extern void pmap_copy_page (vm_offset_t, vm_offset_t);
*/
extern vm_offset_t kvtophys (vm_offset_t);
+void pmap_remove_range(
+ pmap_t pmap,
+ vm_offset_t va,
+ pt_entry_t *spte,
+ pt_entry_t *epte);
+
+#if NCPUS > 1
+void signal_cpus(
+ cpu_set use_list,
+ pmap_t pmap,
+ vm_offset_t start,
+ vm_offset_t end);
+#endif /* NCPUS > 1 */
+
#endif /* __ASSEMBLER__ */
#endif /* _PMAP_MACHINE_ */
diff --git a/i386/intel/read_fault.c b/i386/intel/read_fault.c
index 762f60da..4b1edce3 100644
--- a/i386/intel/read_fault.c
+++ b/i386/intel/read_fault.c
@@ -31,7 +31,7 @@
#include <vm/vm_page.h>
#include <vm/pmap.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
/*
* Expansion of vm_fault for read fault in kernel mode.
@@ -39,9 +39,9 @@
* ignores write protection in kernel mode.
*/
kern_return_t
-intel_read_fault(map, vaddr)
- vm_map_t map;
- vm_offset_t vaddr;
+intel_read_fault(
+ vm_map_t map,
+ vm_offset_t vaddr)
{
vm_map_version_t version; /* Map version for
verification */
@@ -52,7 +52,7 @@ intel_read_fault(map, vaddr)
vm_page_t top_page; /* Placeholder page */
boolean_t wired; /* Is map region wired? */
kern_return_t result;
- register vm_page_t m;
+ vm_page_t m;
RetryFault:
diff --git a/include/cache.h b/include/cache.h
new file mode 100644
index 00000000..6260366a
--- /dev/null
+++ b/include/cache.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MACH_CACHE_H_
+#define _MACH_CACHE_H_
+
+/* This macro can be used to align statically allocated objects so
+ that they start at a cache line. */
+#define __cacheline_aligned __attribute__((aligned(1 << CPU_L1_SHIFT)))
+
+#endif /* _MACH_CACHE_H_ */
diff --git a/include/device/device.defs b/include/device/device.defs
index d9234e39..409146f5 100644
--- a/include/device/device.defs
+++ b/include/device/device.defs
@@ -45,14 +45,29 @@ subsystem
serverprefix ds_;
type reply_port_t = MACH_MSG_TYPE_MAKE_SEND_ONCE | polymorphic
- ctype: mach_port_t;
+ ctype: mach_port_t
+#ifndef KERNEL_SERVER
+#ifdef MACH_PAYLOAD_TO_PORT
+ intranpayload: mach_port_t MACH_PAYLOAD_TO_PORT
+#endif /* MACH_PAYLOAD_TO_PORT */
+#endif /* KERNEL_SERVER */
+;
routine device_open(
master_port : mach_port_t;
sreplyport reply_port : reply_port_t;
mode : dev_mode_t;
name : dev_name_t;
- out device : device_t
+ out device : device_t =
+ MACH_MSG_TYPE_PORT_SEND
+ ctype: mach_port_t
+#if KERNEL_SERVER
+ outtran: mach_port_t convert_device_to_port(device_t)
+#else
+#ifdef DEVICE_OUTTRAN
+ outtran: DEVICE_OUTTRAN
+#endif
+#endif /* KERNEL_SERVER */
);
routine device_close(
diff --git a/include/device/device_reply.defs b/include/device/device_reply.defs
index 34156776..5a325075 100644
--- a/include/device/device_reply.defs
+++ b/include/device/device_reply.defs
@@ -54,7 +54,13 @@ serverdemux seqnos_device_reply_server;
#endif /* SEQNOS */
type reply_port_t = polymorphic|MACH_MSG_TYPE_PORT_SEND_ONCE
- ctype: mach_port_t;
+ ctype: mach_port_t
+#ifndef KERNEL_SERVER
+#ifdef MACH_PAYLOAD_TO_PORT
+ intranpayload: mach_port_t MACH_PAYLOAD_TO_PORT
+#endif /* MACH_PAYLOAD_TO_PORT */
+#endif /* KERNEL_SERVER */
+;
simpleroutine device_open_reply(
reply_port : reply_port_t;
diff --git a/include/device/device_request.defs b/include/device/device_request.defs
index e8aab2a6..7ea8637c 100644
--- a/include/device/device_request.defs
+++ b/include/device/device_request.defs
@@ -37,7 +37,13 @@ subsystem device_request 2800; /* to match device.defs */
serverprefix ds_;
type reply_port_t = MACH_MSG_TYPE_MAKE_SEND_ONCE
- ctype: mach_port_t;
+ ctype: mach_port_t
+#ifndef KERNEL_SERVER
+#ifdef MACH_PAYLOAD_TO_PORT
+ intranpayload: mach_port_t MACH_PAYLOAD_TO_PORT
+#endif /* MACH_PAYLOAD_TO_PORT */
+#endif /* KERNEL_SERVER */
+;
simpleroutine device_open_request(
device_server_port : mach_port_t;
diff --git a/include/device/device_types.defs b/include/device/device_types.defs
index 79e4c5b0..49cc2717 100644
--- a/include/device/device_types.defs
+++ b/include/device/device_types.defs
@@ -39,6 +39,10 @@
#include <mach/std_types.defs>
+#ifdef DEVICE_IMPORTS
+DEVICE_IMPORTS
+#endif
+
type recnum_t = unsigned32;
type dev_mode_t = unsigned32;
type dev_flavor_t = unsigned32;
@@ -55,6 +59,19 @@ type device_t = mach_port_t
intran: device_t dev_port_lookup(mach_port_t)
outtran: mach_port_t convert_device_to_port(device_t)
destructor: device_deallocate(device_t)
+#else /* KERNEL_SERVER */
+#ifdef DEVICE_INTRAN
+ intran: DEVICE_INTRAN
+#endif
+#ifdef DEVICE_INTRAN_PAYLOAD
+ intranpayload: DEVICE_INTRAN_PAYLOAD
+#endif
+#ifdef DEVICE_OUTTRAN
+ outtran: DEVICE_OUTTRAN
+#endif
+#ifdef DEVICE_DESTRUCTOR
+ destructor: DEVICE_DESTRUCTOR
+#endif
#endif /* KERNEL_SERVER */
;
diff --git a/include/device/device_types.h b/include/device/device_types.h
index caf4fc04..a6db051e 100644
--- a/include/device/device_types.h
+++ b/include/device/device_types.h
@@ -135,4 +135,6 @@ typedef int io_return_t;
#define D_NO_MEMORY 2508 /* memory allocation failure */
#define D_READ_ONLY 2509 /* device cannot be written to */
+void device_deallocate(device_t);
+
#endif /* DEVICE_TYPES_H */
diff --git a/include/device/tape_status.h b/include/device/tape_status.h
index 97cb098a..603d76c5 100644
--- a/include/device/tape_status.h
+++ b/include/device/tape_status.h
@@ -137,4 +137,4 @@ struct mtget {
#define MTIOCEEOT _IO('m', 4) /* enable EOT error */
-#endif _TAPE_STATUS_H_
+#endif /* _TAPE_STATUS_H_ */
diff --git a/include/device/tty_status.h b/include/device/tty_status.h
index 15249a40..2eed5d03 100644
--- a/include/device/tty_status.h
+++ b/include/device/tty_status.h
@@ -30,6 +30,9 @@
* Status information for tty.
*/
+#ifndef _DEVICE_TTY_STATUS_H_
+#define _DEVICE_TTY_STATUS_H_
+
struct tty_status {
int tt_ispeed; /* input speed */
int tt_ospeed; /* output speed */
@@ -127,3 +130,5 @@ struct tty_status {
/* clear break condition */
#define TTY_SET_TRANSLATION (dev_flavor_t)(('t'<<16) + 8)
/* set translation table */
+
+#endif /* _DEVICE_TTY_STATUS_H_ */
diff --git a/include/mach/alert.h b/include/mach/alert.h
index 8232f9ef..e8eb3713 100644
--- a/include/mach/alert.h
+++ b/include/mach/alert.h
@@ -34,4 +34,4 @@
#define ALERT_USER 0xffff0000 /* User-defined alert bits */
-#endif _MACH_ALERT_H_
+#endif /* _MACH_ALERT_H_ */
diff --git a/include/mach/boot.h b/include/mach/boot.h
index d3e141fa..7f14cc4b 100644
--- a/include/mach/boot.h
+++ b/include/mach/boot.h
@@ -65,7 +65,7 @@ struct boot_rendezvous
int code;
};
-#endif !__ASSEMBLER__
+#endif /* !__ASSEMBLER__ */
/* This is the magic value that must appear in boot_module.magic. */
@@ -90,4 +90,4 @@ struct boot_rendezvous
#define BRZV_DATA 'D'
-#endif _MACH_BOOT_
+#endif /* _MACH_BOOT_ */
diff --git a/include/mach/default_pager_types.defs b/include/mach/default_pager_types.defs
index 3164f047..bee7c259 100644
--- a/include/mach/default_pager_types.defs
+++ b/include/mach/default_pager_types.defs
@@ -41,4 +41,4 @@ type default_pager_filename_t = (MACH_MSG_TYPE_STRING_C, 8*256);
import <mach/default_pager_types.h>;
-#endif _MACH_DEFAULT_PAGER_TYPES_DEFS_
+#endif /* _MACH_DEFAULT_PAGER_TYPES_DEFS_ */
diff --git a/include/mach/default_pager_types.h b/include/mach/default_pager_types.h
index 99e43ce3..f5ce5a4f 100644
--- a/include/mach/default_pager_types.h
+++ b/include/mach/default_pager_types.h
@@ -55,4 +55,4 @@ typedef default_pager_page_t *default_pager_page_array_t;
typedef char default_pager_filename_t[256];
-#endif _MACH_DEFAULT_PAGER_TYPES_H_
+#endif /* _MACH_DEFAULT_PAGER_TYPES_H_ */
diff --git a/include/mach/gnumach.defs b/include/mach/gnumach.defs
index 73313343..dd4da870 100644
--- a/include/mach/gnumach.defs
+++ b/include/mach/gnumach.defs
@@ -27,6 +27,11 @@ subsystem
#include <mach/std_types.defs>
#include <mach/mach_types.defs>
+#include <mach_debug/mach_debug_types.defs>
+
+#ifdef GNUMACH_IMPORTS
+GNUMACH_IMPORTS
+#endif
type vm_cache_statistics_data_t = struct[11] of integer_t;
@@ -37,3 +42,45 @@ type vm_cache_statistics_data_t = struct[11] of integer_t;
routine vm_cache_statistics(
target_task : vm_task_t;
out vm_cache_stats : vm_cache_statistics_data_t);
+
+/*
+ * Terminate a thread and release rights and memory.
+ *
+ * Intended to be used by threading libraries to provide a clean way for
+ * threads to terminate themselves. The resources a thread wouldn't be able
+ * to release without this call when terminating itself are its
+ * last reference to its kernel port, its reply port, and its stack.
+ *
+ * This call is semantically equivalent to :
+ * - mach_port_deallocate(task, thread_name);
+ * - if (reply_port != MACH_PORT_NULL)
+ * mach_port_destroy(task, reply_port);
+ * - if ((address != 0) || (size != 0))
+ * vm_deallocate(task, address, size)
+ * - thread_terminate(thread)
+ *
+ * Implemented as a simple routine so a reply port isn't required.
+ */
+simpleroutine thread_terminate_release(
+ thread : thread_t;
+ task : task_t;
+ thread_name : mach_port_name_t;
+ reply_port : mach_port_name_t;
+ address : vm_address_t;
+ size : vm_size_t);
+
+/*
+ * Set the name of task TASK to NAME. This is a debugging aid.
+ * NAME will be used in error messages printed by the kernel.
+ */
+simpleroutine task_set_name(
+ task : task_t;
+ name : kernel_debug_name_t);
+
+/*
+ * Register a port to which a notification about newly created tasks
+ * are sent.
+ */
+routine register_new_task_notification(
+ host_priv : host_priv_t;
+ notification : mach_port_send_t);
diff --git a/include/mach/mach.defs b/include/mach/mach.defs
index 58510805..3786f657 100644
--- a/include/mach/mach.defs
+++ b/include/mach/mach.defs
@@ -46,6 +46,10 @@ userprefix r_;
#include <mach/std_types.defs>
#include <mach/mach_types.defs>
+#ifdef MACH_IMPORTS
+MACH_IMPORTS
+#endif
+
skip; /* old port_allocate */
skip; /* old port_deallocate */
skip; /* old port_enable */
diff --git a/include/mach/mach_host.defs b/include/mach/mach_host.defs
index 2644146f..28439a01 100644
--- a/include/mach/mach_host.defs
+++ b/include/mach/mach_host.defs
@@ -47,6 +47,10 @@ subsystem
#include <mach/std_types.defs>
#include <mach/mach_types.defs>
+#ifdef MACH_HOST_IMPORTS
+MACH_HOST_IMPORTS
+#endif
+
/*
* Get list of processors on this host.
*/
@@ -292,7 +296,7 @@ routine host_reboot(
* [ To unwire the pages, specify VM_PROT_NONE. ]
*/
routine vm_wire(
- host_priv : host_priv_t;
+ host : mach_port_t;
task : vm_task_t;
address : vm_address_t;
size : vm_size_t;
diff --git a/include/mach/mach_port.defs b/include/mach/mach_port.defs
index e1f45e3c..c21c34bc 100644
--- a/include/mach/mach_port.defs
+++ b/include/mach/mach_port.defs
@@ -176,14 +176,7 @@ routine mach_port_mod_refs(
right : mach_port_right_t;
delta : mach_port_delta_t);
-/*
- * Temporary compatibility call.
- */
-
-routine old_mach_port_get_receive_status(
- task : ipc_space_t;
- name : mach_port_name_t;
- out status : old_mach_port_status_t);
+skip; /* old old_mach_port_get_receive_status */
/*
* Only valid for receive rights.
@@ -342,5 +335,28 @@ routine mach_port_create_act(
user_rbuf_size : vm_size_t;
out new_act : thread_t);
+#else /* MIGRATING_THREADS */
+
+skip; /* mach_port_set_rpcinfo */
+skip; /* mach_port_create_act */
+
#endif /* MIGRATING_THREADS */
+/*
+ * Only valid for receive rights.
+ * Set the protected payload for this right to the given value.
+ */
+
+routine mach_port_set_protected_payload(
+ task : ipc_space_t;
+ name : mach_port_name_t;
+ payload : natural_t);
+
+/*
+ * Only valid for receive rights.
+ * Clear the protected payload for this right.
+ */
+
+routine mach_port_clear_protected_payload(
+ task : ipc_space_t;
+ name : mach_port_name_t);
diff --git a/include/mach/mach_types.defs b/include/mach/mach_types.defs
index 607d5d92..8e68d385 100644
--- a/include/mach/mach_types.defs
+++ b/include/mach/mach_types.defs
@@ -60,8 +60,6 @@ serverprefix SERVERPREFIX;
type mach_port_status_t = struct[9] of integer_t;
-type old_mach_port_status_t = struct[8] of integer_t; /* compatibility */
-
type task_t = mach_port_t
ctype: mach_port_t
#if KERNEL_SERVER
@@ -135,6 +133,19 @@ type memory_object_t = mach_port_t
ctype: mach_port_t
#if KERNEL_SERVER
intran: ipc_port_t null_conversion(mach_port_t)
+#else /* KERNEL_SERVER */
+#ifdef MEMORY_OBJECT_INTRAN
+ intran: MEMORY_OBJECT_INTRAN
+#endif
+#ifdef MEMORY_OBJECT_INTRAN_PAYLOAD
+ intranpayload: MEMORY_OBJECT_INTRAN_PAYLOAD
+#endif
+#ifdef MEMORY_OBJECT_OUTTRAN
+ outtran: MEMORY_OBJECT_OUTTRAN
+#endif
+#ifdef MEMORY_OBJECT_DESTRUCTOR
+ destructor: MEMORY_OBJECT_DESTRUCTOR
+#endif
#endif /* KERNEL_SERVER */
;
diff --git a/include/mach/memory_object.defs b/include/mach/memory_object.defs
index ea7989aa..6372ded8 100644
--- a/include/mach/memory_object.defs
+++ b/include/mach/memory_object.defs
@@ -42,6 +42,10 @@ subsystem
#include <mach/std_types.defs>
#include <mach/mach_types.defs>
+#ifdef MEMORY_OBJECT_IMPORTS
+MEMORY_OBJECT_IMPORTS
+#endif
+
#if SEQNOS
serverprefix seqnos_;
serverdemux seqnos_memory_object_server;
@@ -85,7 +89,18 @@ simpleroutine memory_object_init(
simpleroutine memory_object_terminate(
memory_object : memory_object_t =
MACH_MSG_TYPE_MOVE_SEND
- ctype: mach_port_t;
+ ctype: mach_port_t
+#ifdef MEMORY_OBJECT_INTRAN
+ intran: MEMORY_OBJECT_INTRAN
+#endif
+#ifdef MEMORY_OBJECT_INTRAN_PAYLOAD
+ intranpayload:
+ MEMORY_OBJECT_INTRAN_PAYLOAD
+#endif
+#ifdef MEMORY_OBJECT_DESTRUCTOR
+ destructor: MEMORY_OBJECT_DESTRUCTOR
+#endif
+ ;
#if SEQNOS
msgseqno seqno : mach_port_seqno_t;
#endif /* SEQNOS */
@@ -221,7 +236,17 @@ simpleroutine memory_object_data_write(
simpleroutine memory_object_lock_completed(
memory_object : memory_object_t =
polymorphic|MACH_MSG_TYPE_PORT_SEND_ONCE
- ctype: mach_port_t;
+ ctype: mach_port_t
+#ifdef MEMORY_OBJECT_INTRAN
+ intran: MEMORY_OBJECT_INTRAN
+#endif
+#ifdef MEMORY_OBJECT_INTRAN_PAYLOAD
+ intranpayload: MEMORY_OBJECT_INTRAN_PAYLOAD
+#endif
+#ifdef MEMORY_OBJECT_DESTRUCTOR
+ destructor: MEMORY_OBJECT_DESTRUCTOR
+#endif
+ ;
#if SEQNOS
msgseqno seqno : mach_port_seqno_t;
#endif /* SEQNOS */
@@ -252,7 +277,17 @@ simpleroutine memory_object_lock_completed(
simpleroutine memory_object_supply_completed(
memory_object : memory_object_t =
polymorphic|MACH_MSG_TYPE_PORT_SEND_ONCE
- ctype: mach_port_t;
+ ctype: mach_port_t
+#ifdef MEMORY_OBJECT_INTRAN
+ intran: MEMORY_OBJECT_INTRAN
+#endif
+#ifdef MEMORY_OBJECT_INTRAN_PAYLOAD
+ intranpayload: MEMORY_OBJECT_INTRAN_PAYLOAD
+#endif
+#ifdef MEMORY_OBJECT_DESTRUCTOR
+ destructor: MEMORY_OBJECT_DESTRUCTOR
+#endif
+ ;
#if SEQNOS
msgseqno seqno : mach_port_seqno_t;
#endif /* SEQNOS */
@@ -298,7 +333,17 @@ simpleroutine memory_object_data_return(
simpleroutine memory_object_change_completed(
memory_object : memory_object_t =
polymorphic|MACH_MSG_TYPE_PORT_SEND_ONCE
- ctype: mach_port_t;
+ ctype: mach_port_t
+#ifdef MEMORY_OBJECT_INTRAN
+ intran: MEMORY_OBJECT_INTRAN
+#endif
+#ifdef MEMORY_OBJECT_INTRAN_PAYLOAD
+ intranpayload: MEMORY_OBJECT_INTRAN_PAYLOAD
+#endif
+#ifdef MEMORY_OBJECT_DESTRUCTOR
+ destructor: MEMORY_OBJECT_DESTRUCTOR
+#endif
+ ;
#if SEQNOS
msgseqno seqno : mach_port_seqno_t;
#endif /* SEQNOS */
diff --git a/include/mach/memory_object_default.defs b/include/mach/memory_object_default.defs
index 0eac2714..cfd54a48 100644
--- a/include/mach/memory_object_default.defs
+++ b/include/mach/memory_object_default.defs
@@ -40,6 +40,10 @@ subsystem
#include <mach/std_types.defs>
#include <mach/mach_types.defs>
+#ifdef MEMORY_OBJECT_IMPORTS
+MEMORY_OBJECT_IMPORTS
+#endif
+
#if SEQNOS
serverprefix seqnos_;
serverdemux seqnos_memory_object_default_server;
diff --git a/include/mach/message.h b/include/mach/message.h
index f78e9780..0a7297e1 100644
--- a/include/mach/message.h
+++ b/include/mach/message.h
@@ -136,7 +136,10 @@ typedef struct {
mach_msg_bits_t msgh_bits;
mach_msg_size_t msgh_size;
mach_port_t msgh_remote_port;
- mach_port_t msgh_local_port;
+ union {
+ mach_port_t msgh_local_port;
+ unsigned long msgh_protected_payload;
+ };
mach_port_seqno_t msgh_seqno;
mach_msg_id_t msgh_id;
} mach_msg_header_t;
@@ -253,7 +256,9 @@ typedef struct {
#define MACH_MSG_TYPE_PORT_SEND MACH_MSG_TYPE_MOVE_SEND
#define MACH_MSG_TYPE_PORT_SEND_ONCE MACH_MSG_TYPE_MOVE_SEND_ONCE
-#define MACH_MSG_TYPE_LAST 22 /* Last assigned */
+#define MACH_MSG_TYPE_PROTECTED_PAYLOAD 23
+
+#define MACH_MSG_TYPE_LAST 23 /* Last assigned */
/*
* A dummy value. Mostly used to indicate that the actual value
diff --git a/include/mach/multiboot.h b/include/mach/multiboot.h
index 3880fa80..b23df4a4 100644
--- a/include/mach/multiboot.h
+++ b/include/mach/multiboot.h
@@ -79,4 +79,4 @@ struct multiboot_info
natural_t pad[4];
};
-#endif _MACH_MULTIBOOT_H_
+#endif /* _MACH_MULTIBOOT_H_ */
diff --git a/include/mach/notify.defs b/include/mach/notify.defs
index e06f6b41..6ba4cde7 100644
--- a/include/mach/notify.defs
+++ b/include/mach/notify.defs
@@ -28,16 +28,33 @@ subsystem notify 64;
#include <mach/std_types.defs>
+#ifdef NOTIFY_IMPORTS
+NOTIFY_IMPORTS
+#endif
+
#if SEQNOS
serverprefix do_seqnos_;
serverdemux seqnos_notify_server;
-#else SEQNOS
+#else
serverprefix do_;
serverdemux notify_server;
-#endif SEQNOS
+#endif
type notify_port_t = MACH_MSG_TYPE_MOVE_SEND_ONCE
- ctype: mach_port_t;
+ ctype: mach_port_t
+#ifdef NOTIFY_INTRAN
+ intran: NOTIFY_INTRAN
+#endif
+#ifdef NOTIFY_INTRAN_PAYLOAD
+ intranpayload: NOTIFY_INTRAN_PAYLOAD
+#endif
+#ifdef NOTIFY_OUTTRAN
+ outtran: NOTIFY_OUTTRAN
+#endif
+#ifdef NOTIFY_DESTRUCTOR
+ destructor: NOTIFY_DESTRUCTOR
+#endif
+;
/* MACH_NOTIFY_FIRST: 0100 */
skip;
@@ -47,7 +64,7 @@ simpleroutine mach_notify_port_deleted(
notify : notify_port_t;
#if SEQNOS
msgseqno seqno : mach_port_seqno_t;
-#endif SEQNOS
+#endif
name : mach_port_name_t);
/* MACH_NOTIFY_MSG_ACCEPTED: 0102 */
@@ -55,7 +72,7 @@ simpleroutine mach_notify_msg_accepted(
notify : notify_port_t;
#if SEQNOS
msgseqno seqno : mach_port_seqno_t;
-#endif SEQNOS
+#endif
name : mach_port_name_t);
skip; /* was NOTIFY_OWNERSHIP_RIGHTS: 0103 */
@@ -67,7 +84,7 @@ simpleroutine mach_notify_port_destroyed(
notify : notify_port_t;
#if SEQNOS
msgseqno seqno : mach_port_seqno_t;
-#endif SEQNOS
+#endif
rights : mach_port_receive_t);
/* MACH_NOTIFY_NO_SENDERS: 0106 */
@@ -75,7 +92,7 @@ simpleroutine mach_notify_no_senders(
notify : notify_port_t;
#if SEQNOS
msgseqno seqno : mach_port_seqno_t;
-#endif SEQNOS
+#endif
mscount : mach_port_mscount_t);
/* MACH_NOTIFY_SEND_ONCE: 0107 */
@@ -83,7 +100,7 @@ simpleroutine mach_notify_send_once(
notify : notify_port_t
#if SEQNOS
; msgseqno seqno : mach_port_seqno_t
-#endif SEQNOS
+#endif
);
/* MACH_NOTIFY_DEAD_NAME: 0110 */
@@ -91,5 +108,5 @@ simpleroutine mach_notify_dead_name(
notify : notify_port_t;
#if SEQNOS
msgseqno seqno : mach_port_seqno_t;
-#endif SEQNOS
+#endif
name : mach_port_name_t);
diff --git a/include/mach/port.h b/include/mach/port.h
index 53f60716..3036a921 100644
--- a/include/mach/port.h
+++ b/include/mach/port.h
@@ -137,6 +137,8 @@ typedef struct mach_port_status {
/*
* Compatibility definitions, for code written
* before there was an mps_seqno field.
+ *
+ * XXX: Remove this before releasing Gnumach 1.6.
*/
typedef struct old_mach_port_status {
diff --git a/include/mach/profil.h b/include/mach/profil.h
index 0eb4ce47..866f267b 100644
--- a/include/mach/profil.h
+++ b/include/mach/profil.h
@@ -137,7 +137,7 @@ extern vm_map_t kernel_map;
/* MACRO set_pbuf_value
**
** enters the value 'val' in the buffer 'pbuf' and returns the following
-** indications: 0: means that a fatal error occured: the buffer was full
+** indications: 0: means that a fatal error occurred: the buffer was full
** (it hasn't been sent yet)
** 1: means that a value has been inserted successfully
** 2: means that we'v just entered the last value causing
diff --git a/include/mach/rpc.h b/include/mach/rpc.h
index d3098f80..36eb5921 100644
--- a/include/mach/rpc.h
+++ b/include/mach/rpc.h
@@ -21,7 +21,6 @@
#include <mach/kern_return.h>
#include <mach/message.h>
-#include <mach/machine/rpc.h>
/*
* Description of a port passed up by the leaky-register RPC path
diff --git a/include/mach/std_types.defs b/include/mach/std_types.defs
index 00d1a698..a1f156d9 100644
--- a/include/mach/std_types.defs
+++ b/include/mach/std_types.defs
@@ -49,7 +49,13 @@ type pointer_t = ^array[] of MACH_MSG_TYPE_BYTE
ctype: vm_offset_t;
-type mach_port_t = MACH_MSG_TYPE_COPY_SEND;
+type mach_port_t = MACH_MSG_TYPE_COPY_SEND
+#ifndef KERNEL_SERVER
+#ifdef MACH_PAYLOAD_TO_PORT
+ intranpayload: mach_port_t MACH_PAYLOAD_TO_PORT
+#endif /* MACH_PAYLOAD_TO_PORT */
+#endif /* KERNEL_SERVER */
+;
type mach_port_array_t = array[] of mach_port_t;
type mach_port_name_t = MACH_MSG_TYPE_PORT_NAME
diff --git a/include/mach/task_notify.defs b/include/mach/task_notify.defs
new file mode 100644
index 00000000..5485d4e3
--- /dev/null
+++ b/include/mach/task_notify.defs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+subsystem
+#if KERNEL_SERVER
+ KernelServer
+#endif /* KERNEL_SERVER */
+#if KERNEL_USER
+ KernelUser
+#endif /* KERNEL_USER */
+ task_notify 4400;
+
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+
+/* These notifications are sent to the port registered via
+ `register_new_task_notification' and provide a robust parental
+ relation between tasks. */
+simpleroutine mach_notify_new_task(
+ notify : mach_port_t;
+ task : task_t;
+ parent : task_t);
diff --git a/include/mach/version.h b/include/mach/version.h
index ec12ea74..3ef78592 100644
--- a/include/mach/version.h
+++ b/include/mach/version.h
@@ -43,6 +43,9 @@
* minor 0.
*/
+#ifndef _MACH_VERSION_H_
+#define _MACH_VERSION_H_
+
#define KERNEL_MAJOR_VERSION 4
#define KERNEL_MINOR_VERSION 0
@@ -66,3 +69,5 @@
* excised from the CSD environment.
*/
#define INCLUDE_VERSION 0
+
+#endif /* _MACH_VERSION_H_ */
diff --git a/include/mach/vm_param.h b/include/mach/vm_param.h
index 03609815..cdccce82 100644
--- a/include/mach/vm_param.h
+++ b/include/mach/vm_param.h
@@ -39,7 +39,7 @@
#include <mach/machine/vm_types.h>
/*
- * The machine independent pages are refered to as PAGES. A page
+ * The machine independent pages are referred to as PAGES. A page
* is some number of hardware pages, depending on the target machine.
*
* All references to the size of a page should be done
diff --git a/include/mach_debug/ipc_info.h b/include/mach_debug/ipc_info.h
index ef0b0c6a..a47ae7b4 100644
--- a/include/mach_debug/ipc_info.h
+++ b/include/mach_debug/ipc_info.h
@@ -43,40 +43,17 @@
* in mach_debug_types.defs when adding/removing fields.
*/
-
-typedef struct ipc_info_space {
- natural_t iis_genno_mask; /* generation number mask */
- natural_t iis_table_size; /* size of table */
- natural_t iis_table_next; /* next possible size of table */
- natural_t iis_tree_size; /* size of tree */
- natural_t iis_tree_small; /* # of small entries in tree */
- natural_t iis_tree_hash; /* # of hashed entries in tree */
-} ipc_info_space_t;
-
-
typedef struct ipc_info_name {
mach_port_t iin_name; /* port name, including gen number */
-/*boolean_t*/integer_t iin_collision; /* collision at this entry? */
-/*boolean_t*/integer_t iin_compat; /* is this a compat-mode entry? */
/*boolean_t*/integer_t iin_marequest; /* extant msg-accepted request? */
mach_port_type_t iin_type; /* straight port type */
mach_port_urefs_t iin_urefs; /* user-references */
vm_offset_t iin_object; /* object pointer */
natural_t iin_next; /* marequest/next in free list */
- natural_t iin_hash; /* hash index */
} ipc_info_name_t;
typedef ipc_info_name_t *ipc_info_name_array_t;
-
-typedef struct ipc_info_tree_name {
- ipc_info_name_t iitn_name;
- mach_port_t iitn_lchild; /* name of left child */
- mach_port_t iitn_rchild; /* name of right child */
-} ipc_info_tree_name_t;
-
-typedef ipc_info_tree_name_t *ipc_info_tree_name_array_t;
-
/*
* Type definitions for mach_port_kernel_object.
* By remarkable coincidence, these closely resemble
diff --git a/include/mach_debug/mach_debug.defs b/include/mach_debug/mach_debug.defs
index 053c3fe6..c8e8b1b4 100644
--- a/include/mach_debug/mach_debug.defs
+++ b/include/mach_debug/mach_debug.defs
@@ -57,14 +57,7 @@ routine mach_port_get_srights(
name : mach_port_name_t;
out srights : mach_port_rights_t);
-/*
- * Returns information about the global reverse hash table.
- */
-
-routine host_ipc_hash_info(
- host : host_t;
- out info : hash_info_bucket_array_t,
- CountInOut, Dealloc);
+skip; /* host_ipc_hash_info */
/*
* Returns information about the marequest hash table.
@@ -76,17 +69,7 @@ routine host_ipc_marequest_info(
out info : hash_info_bucket_array_t,
CountInOut, Dealloc);
-/*
- * Returns information about an IPC space.
- */
-
-routine mach_port_space_info(
- task : ipc_space_t;
- out info : ipc_info_space_t;
- out table_info : ipc_info_name_array_t,
- CountInOut, Dealloc;
- out tree_info : ipc_info_tree_name_array_t,
- CountInOut, Dealloc);
+skip; /* mach_port_space_info */
/*
* Returns information about the dead-name requests
@@ -218,6 +201,12 @@ routine mach_vm_object_pages(
out pages : vm_page_info_array_t,
CountInOut, Dealloc);
+#else /* !defined(MACH_VM_DEBUG) || MACH_VM_DEBUG */
+skip; /* mach_vm_region_info */
+skip; /* mach_vm_object_info */
+skip; /* mach_vm_object_pages */
+#endif /* !defined(MACH_VM_DEBUG) || MACH_VM_DEBUG */
+
/*
* Returns information about the memory allocation caches.
*/
@@ -225,9 +214,3 @@ routine host_slab_info(
host : host_t;
out info : cache_info_array_t,
CountInOut, Dealloc);
-
-#else /* !defined(MACH_VM_DEBUG) || MACH_VM_DEBUG */
-skip; /* mach_vm_region_info */
-skip; /* mach_vm_object_info */
-skip; /* mach_vm_object_pages */
-#endif /* !defined(MACH_VM_DEBUG) || MACH_VM_DEBUG */
diff --git a/include/mach_debug/mach_debug_types.defs b/include/mach_debug/mach_debug_types.defs
index f60125a0..8df2f344 100644
--- a/include/mach_debug/mach_debug_types.defs
+++ b/include/mach_debug/mach_debug_types.defs
@@ -38,14 +38,9 @@ type cache_info_array_t = array[] of cache_info_t;
type hash_info_bucket_t = struct[1] of natural_t;
type hash_info_bucket_array_t = array[] of hash_info_bucket_t;
-type ipc_info_space_t = struct[6] of natural_t;
-
-type ipc_info_name_t = struct[9] of natural_t;
+type ipc_info_name_t = struct[6] of natural_t;
type ipc_info_name_array_t = array[] of ipc_info_name_t;
-type ipc_info_tree_name_t = struct[11] of natural_t;
-type ipc_info_tree_name_array_t = array[] of ipc_info_tree_name_t;
-
type vm_region_info_t = struct[11] of natural_t;
type vm_region_info_array_t = array[] of vm_region_info_t;
@@ -57,6 +52,8 @@ type vm_page_info_array_t = array[] of vm_page_info_t;
type symtab_name_t = (MACH_MSG_TYPE_STRING_C, 8*32);
+type kernel_debug_name_t = c_string[*: 64];
+
import <mach_debug/mach_debug_types.h>;
#endif /* _MACH_DEBUG_MACH_DEBUG_TYPES_DEFS_ */
diff --git a/include/mach_debug/mach_debug_types.h b/include/mach_debug/mach_debug_types.h
index 5d4efcde..9c7d1fde 100644
--- a/include/mach_debug/mach_debug_types.h
+++ b/include/mach_debug/mach_debug_types.h
@@ -37,4 +37,15 @@
typedef char symtab_name_t[32];
+/*
+ * A fixed-length string data type intended for names given to
+ * kernel objects.
+ *
+ * Note that it is not guaranteed that the in-kernel data
+ * structure will hold KERNEL_DEBUG_NAME_MAX bytes. The given
+ * name will be truncated to fit into the target data structure.
+ */
+#define KERNEL_DEBUG_NAME_MAX (64)
+typedef char kernel_debug_name_t[KERNEL_DEBUG_NAME_MAX];
+
#endif /* _MACH_DEBUG_MACH_DEBUG_TYPES_H_ */
diff --git a/include/mach_debug/pc_info.h b/include/mach_debug/pc_info.h
index bc43fa8d..912da9fd 100644
--- a/include/mach_debug/pc_info.h
+++ b/include/mach_debug/pc_info.h
@@ -40,4 +40,4 @@ typedef struct sampled_pc {
typedef sampled_pc_t *sampled_pc_array_t;
typedef unsigned int sampled_pc_seqno_t;
-#endif _MACH_DEBUG_PC_INFO_H_
+#endif /* _MACH_DEBUG_PC_INFO_H_ */
diff --git a/include/string.h b/include/string.h
index c77d387b..c31b4292 100644
--- a/include/string.h
+++ b/include/string.h
@@ -32,7 +32,7 @@ extern void *memcpy (void *dest, const void *src, size_t n);
extern void *memmove (void *dest, const void *src, size_t n);
-extern int memcmp (const void *s1, const void *s2, size_t n);
+extern int memcmp (const void *s1, const void *s2, size_t n) __attribute__ ((pure));
extern void *memset (void *s, int c, size_t n);
@@ -46,11 +46,11 @@ extern char *strrchr (const char *s, int c);
extern char *strsep (char **strp, const char *delim);
-extern int strcmp (const char *s1, const char *s2);
+extern int strcmp (const char *s1, const char *s2) __attribute__ ((pure));
-extern int strncmp (const char *s1, const char *s2, size_t n);
+extern int strncmp (const char *s1, const char *s2, size_t n) __attribute__ ((pure));
-extern size_t strlen (const char *s);
+extern size_t strlen (const char *s) __attribute__ ((pure));
extern char *strstr(const char *haystack, const char *needle);
diff --git a/ipc/ipc_entry.c b/ipc/ipc_entry.c
index 3a062447..0414ba5f 100644
--- a/ipc/ipc_entry.c
+++ b/ipc/ipc_entry.c
@@ -46,158 +46,17 @@
#include <ipc/ipc_types.h>
#include <ipc/ipc_entry.h>
#include <ipc/ipc_space.h>
-#include <ipc/ipc_splay.h>
-#include <ipc/ipc_hash.h>
#include <ipc/ipc_table.h>
#include <ipc/ipc_object.h>
-struct kmem_cache ipc_tree_entry_cache;
-
-/*
- * Routine: ipc_entry_tree_collision
- * Purpose:
- * Checks if "name" collides with an allocated name
- * in the space's tree. That is, returns TRUE
- * if the splay tree contains a name with the same
- * index as "name".
- * Conditions:
- * The space is locked (read or write) and active.
- */
-
-boolean_t
-ipc_entry_tree_collision(
- ipc_space_t space,
- mach_port_t name)
-{
- mach_port_index_t index;
- mach_port_t lower, upper;
-
- assert(space->is_active);
-
- /*
- * Check if we collide with the next smaller name
- * or the next larger name.
- */
-
- ipc_splay_tree_bounds(&space->is_tree, name, &lower, &upper);
-
- index = MACH_PORT_INDEX(name);
- return (((lower != ~0) && (MACH_PORT_INDEX(lower) == index)) ||
- ((upper != 0) && (MACH_PORT_INDEX(upper) == index)));
-}
-
-/*
- * Routine: ipc_entry_lookup
- * Purpose:
- * Searches for an entry, given its name.
- * Conditions:
- * The space must be read or write locked throughout.
- * The space must be active.
- */
-
-ipc_entry_t
-ipc_entry_lookup(space, name)
- ipc_space_t space;
- mach_port_t name;
-{
- mach_port_index_t index;
- ipc_entry_t entry;
-
- assert(space->is_active);
-
- index = MACH_PORT_INDEX(name);
- if (index < space->is_table_size) {
- entry = &space->is_table[index];
- if (IE_BITS_GEN(entry->ie_bits) != MACH_PORT_GEN(name))
- if (entry->ie_bits & IE_BITS_COLLISION) {
- assert(space->is_tree_total > 0);
- goto tree_lookup;
- } else
- entry = IE_NULL;
- else if (IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE)
- entry = IE_NULL;
- } else if (space->is_tree_total == 0)
- entry = IE_NULL;
- else
- tree_lookup:
- entry = (ipc_entry_t)
- ipc_splay_tree_lookup(&space->is_tree, name);
-
- assert((entry == IE_NULL) || IE_BITS_TYPE(entry->ie_bits));
- return entry;
-}
-
-/*
- * Routine: ipc_entry_get
- * Purpose:
- * Tries to allocate an entry out of the space.
- * Conditions:
- * The space is write-locked and active throughout.
- * An object may be locked. Will not allocate memory.
- * Returns:
- * KERN_SUCCESS A free entry was found.
- * KERN_NO_SPACE No entry allocated.
- */
-
-kern_return_t
-ipc_entry_get(space, namep, entryp)
- ipc_space_t space;
- mach_port_t *namep;
- ipc_entry_t *entryp;
-{
- ipc_entry_t table;
- mach_port_index_t first_free;
- mach_port_t new_name;
- ipc_entry_t free_entry;
-
- assert(space->is_active);
-
- table = space->is_table;
- first_free = table->ie_next;
-
- if (first_free == 0)
- return KERN_NO_SPACE;
-
- free_entry = &table[first_free];
- table->ie_next = free_entry->ie_next;
-
- /*
- * Initialize the new entry. We need only
- * increment the generation number and clear ie_request.
- */
-
- {
- mach_port_gen_t gen;
-
- assert((free_entry->ie_bits &~ IE_BITS_GEN_MASK) == 0);
- gen = free_entry->ie_bits + IE_BITS_GEN_ONE;
- free_entry->ie_bits = gen;
- free_entry->ie_request = 0;
- new_name = MACH_PORT_MAKE(first_free, gen);
- }
-
- /*
- * The new name can't be MACH_PORT_NULL because index
- * is non-zero. It can't be MACH_PORT_DEAD because
- * the table isn't allowed to grow big enough.
- * (See comment in ipc/ipc_table.h.)
- */
-
- assert(MACH_PORT_VALID(new_name));
- assert(free_entry->ie_object == IO_NULL);
-
- *namep = new_name;
- *entryp = free_entry;
- return KERN_SUCCESS;
-}
+struct kmem_cache ipc_entry_cache;
/*
* Routine: ipc_entry_alloc
* Purpose:
* Allocate an entry out of the space.
* Conditions:
- * The space is not locked before, but it is write-locked after
- * if the call is successful. May allocate memory.
+ * The space must be write-locked. May allocate memory.
* Returns:
* KERN_SUCCESS An entry was allocated.
* KERN_INVALID_TASK The space is dead.
@@ -212,23 +71,37 @@ ipc_entry_alloc(
ipc_entry_t *entryp)
{
kern_return_t kr;
+ ipc_entry_t entry;
+ rdxtree_key_t key;
- is_write_lock(space);
+ if (!space->is_active) {
+ return KERN_INVALID_TASK;
+ }
- for (;;) {
- if (!space->is_active) {
- is_write_unlock(space);
- return KERN_INVALID_TASK;
- }
+ kr = ipc_entry_get(space, namep, entryp);
+ if (kr == KERN_SUCCESS)
+ return kr;
- kr = ipc_entry_get(space, namep, entryp);
- if (kr == KERN_SUCCESS)
- return kr;
+ entry = ie_alloc();
+ if (entry == IE_NULL) {
+ return KERN_RESOURCE_SHORTAGE;
+ }
- kr = ipc_entry_grow_table(space);
- if (kr != KERN_SUCCESS)
- return kr; /* space is unlocked */
+ kr = rdxtree_insert_alloc(&space->is_map, entry, &key);
+ if (kr) {
+ ie_free(entry);
+ return kr;
}
+ space->is_size += 1;
+
+ entry->ie_bits = 0;
+ entry->ie_object = IO_NULL;
+ entry->ie_request = 0;
+ entry->ie_name = (mach_port_t) key;
+
+ *entryp = entry;
+ *namep = (mach_port_t) key;
+ return KERN_SUCCESS;
}
/*
@@ -237,8 +110,7 @@ ipc_entry_alloc(
* Allocates/finds an entry with a specific name.
* If an existing entry is returned, its type will be nonzero.
* Conditions:
- * The space is not locked before, but it is write-locked after
- * if the call is successful. May allocate memory.
+ * The space must be write-locked. May allocate memory.
* Returns:
* KERN_SUCCESS Found existing entry with same name.
* KERN_SUCCESS Allocated a new entry.
@@ -252,601 +124,80 @@ ipc_entry_alloc_name(
mach_port_t name,
ipc_entry_t *entryp)
{
- mach_port_index_t index = MACH_PORT_INDEX(name);
- mach_port_gen_t gen = MACH_PORT_GEN(name);
- ipc_tree_entry_t tree_entry = ITE_NULL;
-
+ kern_return_t kr;
+ ipc_entry_t entry, e, *prevp;
+ void **slot;
assert(MACH_PORT_VALID(name));
+ if (!space->is_active) {
+ return KERN_INVALID_TASK;
+ }
- is_write_lock(space);
-
- for (;;) {
- ipc_entry_t entry;
- ipc_tree_entry_t tentry;
- ipc_table_size_t its;
-
- if (!space->is_active) {
- is_write_unlock(space);
- if (tree_entry) ite_free(tree_entry);
- return KERN_INVALID_TASK;
- }
-
- /*
- * If we are under the table cutoff,
- * there are three cases:
- * 1) The entry is inuse, for the same name
- * 2) The entry is inuse, for a different name
- * 3) The entry is free
- */
-
- if ((0 < index) && (index < space->is_table_size)) {
- ipc_entry_t table = space->is_table;
-
- entry = &table[index];
-
- if (IE_BITS_TYPE(entry->ie_bits)) {
- if (IE_BITS_GEN(entry->ie_bits) == gen) {
- *entryp = entry;
- if (tree_entry) ite_free(tree_entry);
- return KERN_SUCCESS;
- }
- } else {
- mach_port_index_t free_index, next_index;
-
- /*
- * Rip the entry out of the free list.
- */
-
- for (free_index = 0;
- (next_index = table[free_index].ie_next)
- != index;
- free_index = next_index)
- continue;
-
- table[free_index].ie_next =
- table[next_index].ie_next;
-
- entry->ie_bits = gen;
- assert(entry->ie_object == IO_NULL);
- entry->ie_request = 0;
-
- *entryp = entry;
- if (tree_entry) ite_free(tree_entry);
- return KERN_SUCCESS;
- }
- }
-
- /*
- * Before trying to allocate any memory,
- * check if the entry already exists in the tree.
- * This avoids spurious resource errors.
- * The splay tree makes a subsequent lookup/insert
- * of the same name cheap, so this costs little.
- */
-
- if ((space->is_tree_total > 0) &&
- ((tentry = ipc_splay_tree_lookup(&space->is_tree, name))
- != ITE_NULL)) {
- assert(tentry->ite_space == space);
- assert(IE_BITS_TYPE(tentry->ite_bits));
+ slot = rdxtree_lookup_slot(&space->is_map, (rdxtree_key_t) name);
+ if (slot != NULL)
+ entry = *(ipc_entry_t *) slot;
- *entryp = &tentry->ite_entry;
- if (tree_entry) ite_free(tree_entry);
- return KERN_SUCCESS;
+ if (slot == NULL || entry == IE_NULL) {
+ entry = ie_alloc();
+ if (entry == IE_NULL) {
+ return KERN_RESOURCE_SHORTAGE;
}
- its = space->is_table_next;
-
- /*
- * Check if the table should be grown.
- *
- * Note that if space->is_table_size == its->its_size,
- * then we won't ever try to grow the table.
- *
- * Note that we are optimistically assuming that name
- * doesn't collide with any existing names. (So if
- * it were entered into the tree, is_tree_small would
- * be incremented.) This is OK, because even in that
- * case, we don't lose memory by growing the table.
- */
+ entry->ie_bits = 0;
+ entry->ie_object = IO_NULL;
+ entry->ie_request = 0;
+ entry->ie_name = name;
- if ((space->is_table_size <= index) &&
- (index < its->its_size) &&
- (((its->its_size - space->is_table_size) *
- sizeof(struct ipc_entry)) <
- ((space->is_tree_small + 1) *
- sizeof(struct ipc_tree_entry)))) {
- kern_return_t kr;
-
- /*
- * Can save space by growing the table.
- * Because the space will be unlocked,
- * we must restart.
- */
-
- kr = ipc_entry_grow_table(space);
- assert(kr != KERN_NO_SPACE);
+ if (slot != NULL)
+ rdxtree_replace_slot(slot, entry);
+ else {
+ kr = rdxtree_insert(&space->is_map,
+ (rdxtree_key_t) name, entry);
if (kr != KERN_SUCCESS) {
- /* space is unlocked */
- if (tree_entry) ite_free(tree_entry);
+ ie_free(entry);
return kr;
}
-
- continue;
- }
-
- /*
- * If a splay-tree entry was allocated previously,
- * go ahead and insert it into the tree.
- */
-
- if (tree_entry != ITE_NULL) {
- space->is_tree_total++;
-
- if (index < space->is_table_size)
- space->is_table[index].ie_bits |=
- IE_BITS_COLLISION;
- else if ((index < its->its_size) &&
- !ipc_entry_tree_collision(space, name))
- space->is_tree_small++;
-
- ipc_splay_tree_insert(&space->is_tree,
- name, tree_entry);
-
- tree_entry->ite_bits = 0;
- tree_entry->ite_object = IO_NULL;
- tree_entry->ite_request = 0;
- tree_entry->ite_space = space;
- *entryp = &tree_entry->ite_entry;
- return KERN_SUCCESS;
}
+ space->is_size += 1;
- /*
- * Allocate a tree entry and try again.
- */
-
- is_write_unlock(space);
- tree_entry = ite_alloc();
- if (tree_entry == ITE_NULL)
- return KERN_RESOURCE_SHORTAGE;
- is_write_lock(space);
+ *entryp = entry;
+ return KERN_SUCCESS;
}
-}
-
-/*
- * Routine: ipc_entry_dealloc
- * Purpose:
- * Deallocates an entry from a space.
- * Conditions:
- * The space must be write-locked throughout.
- * The space must be active.
- */
-
-void
-ipc_entry_dealloc(
- ipc_space_t space,
- mach_port_t name,
- ipc_entry_t entry)
-{
- ipc_entry_t table;
- ipc_entry_num_t size;
- mach_port_index_t index;
- assert(space->is_active);
- assert(entry->ie_object == IO_NULL);
- assert(entry->ie_request == 0);
-
- index = MACH_PORT_INDEX(name);
- table = space->is_table;
- size = space->is_table_size;
-
- if ((index < size) && (entry == &table[index])) {
- assert(IE_BITS_GEN(entry->ie_bits) == MACH_PORT_GEN(name));
-
- if (entry->ie_bits & IE_BITS_COLLISION) {
- struct ipc_splay_tree small, collisions;
- ipc_tree_entry_t tentry;
- mach_port_t tname;
- boolean_t pick;
- ipc_entry_bits_t bits;
- ipc_object_t obj;
-
- /* must move an entry from tree to table */
-
- ipc_splay_tree_split(&space->is_tree,
- MACH_PORT_MAKE(index+1, 0),
- &collisions);
- ipc_splay_tree_split(&collisions,
- MACH_PORT_MAKE(index, 0),
- &small);
-
- pick = ipc_splay_tree_pick(&collisions,
- &tname, &tentry);
- assert(pick);
- assert(MACH_PORT_INDEX(tname) == index);
-
- bits = tentry->ite_bits;
- entry->ie_bits = bits | MACH_PORT_GEN(tname);
- entry->ie_object = obj = tentry->ite_object;
- entry->ie_request = tentry->ite_request;
- assert(tentry->ite_space == space);
-
- if (IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND) {
- ipc_hash_global_delete(space, obj,
- tname, tentry);
- ipc_hash_local_insert(space, obj,
- index, entry);
- }
-
- ipc_splay_tree_delete(&collisions, tname, tentry);
-
- assert(space->is_tree_total > 0);
- space->is_tree_total--;
-
- /* check if collision bit should still be on */
-
- pick = ipc_splay_tree_pick(&collisions,
- &tname, &tentry);
- if (pick) {
- entry->ie_bits |= IE_BITS_COLLISION;
- ipc_splay_tree_join(&space->is_tree,
- &collisions);
- }
-
- ipc_splay_tree_join(&space->is_tree, &small);
- } else {
- entry->ie_bits &= IE_BITS_GEN_MASK;
- entry->ie_next = table->ie_next;
- table->ie_next = index;
- }
- } else {
- ipc_tree_entry_t tentry = (ipc_tree_entry_t) entry;
-
- assert(tentry->ite_space == space);
-
- ipc_splay_tree_delete(&space->is_tree, name, tentry);
-
- assert(space->is_tree_total > 0);
- space->is_tree_total--;
-
- if (index < size) {
- ipc_entry_t ientry = &table[index];
-
- assert(ientry->ie_bits & IE_BITS_COLLISION);
-
- if (!ipc_entry_tree_collision(space, name))
- ientry->ie_bits &= ~IE_BITS_COLLISION;
- } else if ((index < space->is_table_next->its_size) &&
- !ipc_entry_tree_collision(space, name)) {
- assert(space->is_tree_small > 0);
- space->is_tree_small--;
- }
+ if (IE_BITS_TYPE(entry->ie_bits)) {
+ /* Used entry. */
+ *entryp = entry;
+ return KERN_SUCCESS;
}
-}
-/*
- * Routine: ipc_entry_grow_table
- * Purpose:
- * Grows the table in a space.
- * Conditions:
- * The space must be write-locked and active before.
- * If successful, it is also returned locked.
- * Allocates memory.
- * Returns:
- * KERN_SUCCESS Grew the table.
- * KERN_SUCCESS Somebody else grew the table.
- * KERN_SUCCESS The space died.
- * KERN_NO_SPACE Table has maximum size already.
- * KERN_RESOURCE_SHORTAGE Couldn't allocate a new table.
- */
-
-kern_return_t
-ipc_entry_grow_table(space)
- ipc_space_t space;
-{
- ipc_entry_num_t osize, size, nsize;
-
- do {
- ipc_entry_t otable, table;
- ipc_table_size_t oits, its, nits;
- mach_port_index_t i, free_index;
-
- assert(space->is_active);
-
- if (space->is_growing) {
- /*
- * Somebody else is growing the table.
- * We just wait for them to finish.
- */
-
- assert_wait((event_t) space, FALSE);
- is_write_unlock(space);
- thread_block((void (*)()) 0);
- is_write_lock(space);
- return KERN_SUCCESS;
- }
-
- otable = space->is_table;
- its = space->is_table_next;
- size = its->its_size;
- oits = its - 1;
- osize = oits->its_size;
- nits = its + 1;
- nsize = nits->its_size;
-
- if (osize == size) {
- is_write_unlock(space);
- printf_once("no more room for ipc_entry_grow_table in space %p\n", space);
- return KERN_NO_SPACE;
- }
-
- assert((osize < size) && (size <= nsize));
-
- /*
- * OK, we'll attempt to grow the table.
- * The realloc requires that the old table
- * remain in existence.
- */
+ /* Free entry. Rip the entry out of the free list. */
+ for (prevp = &space->is_free_list, e = space->is_free_list;
+ e != entry;
+ ({ prevp = &e->ie_next_free; e = e->ie_next_free; }))
+ continue;
- space->is_growing = TRUE;
- is_write_unlock(space);
- if (it_entries_reallocable(oits))
- table = it_entries_realloc(oits, otable, its);
- else
- table = it_entries_alloc(its);
- is_write_lock(space);
- space->is_growing = FALSE;
+ *prevp = entry->ie_next_free;
+ space->is_free_list_size -= 1;
- /*
- * We need to do a wakeup on the space,
- * to rouse waiting threads. We defer
- * this until the space is unlocked,
- * because we don't want them to spin.
- */
-
- if (table == IE_NULL) {
- is_write_unlock(space);
- thread_wakeup((event_t) space);
- return KERN_RESOURCE_SHORTAGE;
- }
-
- if (!space->is_active) {
- /*
- * The space died while it was unlocked.
- */
-
- is_write_unlock(space);
- thread_wakeup((event_t) space);
- it_entries_free(its, table);
- is_write_lock(space);
- return KERN_SUCCESS;
- }
-
- assert(space->is_table == otable);
- assert(space->is_table_next == its);
- assert(space->is_table_size == osize);
-
- space->is_table = table;
- space->is_table_size = size;
- space->is_table_next = nits;
-
- /*
- * If we did a realloc, it remapped the data.
- * Otherwise we copy by hand first. Then we have
- * to clear the index fields in the old part and
- * zero the new part.
- */
-
- if (!it_entries_reallocable(oits))
- memcpy(table, otable,
- osize * sizeof(struct ipc_entry));
-
- for (i = 0; i < osize; i++)
- table[i].ie_index = 0;
-
- (void) memset((void *) (table + osize), 0,
- (size - osize) * sizeof(struct ipc_entry));
-
- /*
- * Put old entries into the reverse hash table.
- */
-
- for (i = 0; i < osize; i++) {
- ipc_entry_t entry = &table[i];
-
- if (IE_BITS_TYPE(entry->ie_bits) ==
- MACH_PORT_TYPE_SEND)
- ipc_hash_local_insert(space, entry->ie_object,
- i, entry);
- }
-
- /*
- * If there are entries in the splay tree,
- * then we have work to do:
- * 1) transfer entries to the table
- * 2) update is_tree_small
- */
-
- if (space->is_tree_total > 0) {
- mach_port_index_t index;
- boolean_t delete;
- struct ipc_splay_tree ignore;
- struct ipc_splay_tree move;
- struct ipc_splay_tree small;
- ipc_entry_num_t nosmall;
- ipc_tree_entry_t tentry;
-
- /*
- * The splay tree divides into four regions,
- * based on the index of the entries:
- * 1) 0 <= index < osize
- * 2) osize <= index < size
- * 3) size <= index < nsize
- * 4) nsize <= index
- *
- * Entries in the first part are ignored.
- * Entries in the second part, that don't
- * collide, are moved into the table.
- * Entries in the third part, that don't
- * collide, are counted for is_tree_small.
- * Entries in the fourth part are ignored.
- */
-
- ipc_splay_tree_split(&space->is_tree,
- MACH_PORT_MAKE(nsize, 0),
- &small);
- ipc_splay_tree_split(&small,
- MACH_PORT_MAKE(size, 0),
- &move);
- ipc_splay_tree_split(&move,
- MACH_PORT_MAKE(osize, 0),
- &ignore);
-
- /* move entries into the table */
-
- for (tentry = ipc_splay_traverse_start(&move);
- tentry != ITE_NULL;
- tentry = ipc_splay_traverse_next(&move, delete)) {
- mach_port_t name;
- mach_port_gen_t gen;
- mach_port_type_t type;
- ipc_entry_bits_t bits;
- ipc_object_t obj;
- ipc_entry_t entry;
-
- name = tentry->ite_name;
- gen = MACH_PORT_GEN(name);
- index = MACH_PORT_INDEX(name);
-
- assert(tentry->ite_space == space);
- assert((osize <= index) && (index < size));
-
- entry = &table[index];
-
- /* collision with previously moved entry? */
-
- bits = entry->ie_bits;
- if (bits != 0) {
- assert(IE_BITS_TYPE(bits));
- assert(IE_BITS_GEN(bits) != gen);
-
- entry->ie_bits =
- bits | IE_BITS_COLLISION;
- delete = FALSE;
- continue;
- }
-
- bits = tentry->ite_bits;
- type = IE_BITS_TYPE(bits);
- assert(type != MACH_PORT_TYPE_NONE);
-
- entry->ie_bits = bits | gen;
- entry->ie_object = obj = tentry->ite_object;
- entry->ie_request = tentry->ite_request;
-
- if (type == MACH_PORT_TYPE_SEND) {
- ipc_hash_global_delete(space, obj,
- name, tentry);
- ipc_hash_local_insert(space, obj,
- index, entry);
- }
-
- space->is_tree_total--;
- delete = TRUE;
- }
- ipc_splay_traverse_finish(&move);
-
- /* count entries for is_tree_small */
-
- nosmall = 0; index = 0;
- for (tentry = ipc_splay_traverse_start(&small);
- tentry != ITE_NULL;
- tentry = ipc_splay_traverse_next(&small, FALSE)) {
- mach_port_index_t nindex;
-
- nindex = MACH_PORT_INDEX(tentry->ite_name);
-
- if (nindex != index) {
- nosmall++;
- index = nindex;
- }
- }
- ipc_splay_traverse_finish(&small);
-
- assert(nosmall <= (nsize - size));
- assert(nosmall <= space->is_tree_total);
- space->is_tree_small = nosmall;
-
- /* put the splay tree back together */
-
- ipc_splay_tree_join(&space->is_tree, &small);
- ipc_splay_tree_join(&space->is_tree, &move);
- ipc_splay_tree_join(&space->is_tree, &ignore);
- }
-
- /*
- * Add entries in the new part which still aren't used
- * to the free list. Add them in reverse order,
- * and set the generation number to -1, so that
- * early allocations produce "natural" names.
- */
-
- free_index = table[0].ie_next;
- for (i = size-1; i >= osize; --i) {
- ipc_entry_t entry = &table[i];
-
- if (entry->ie_bits == 0) {
- entry->ie_bits = IE_BITS_GEN_MASK;
- entry->ie_next = free_index;
- free_index = i;
- }
- }
- table[0].ie_next = free_index;
-
- /*
- * Now we need to free the old table.
- * If the space dies or grows while unlocked,
- * then we can quit here.
- */
-
- is_write_unlock(space);
- thread_wakeup((event_t) space);
- it_entries_free(oits, otable);
- is_write_lock(space);
- if (!space->is_active || (space->is_table_next != nits))
- return KERN_SUCCESS;
-
- /*
- * We might have moved enough entries from
- * the splay tree into the table that
- * the table can be profitably grown again.
- *
- * Note that if size == nsize, then
- * space->is_tree_small == 0.
- */
- } while ((space->is_tree_small > 0) &&
- (((nsize - size) * sizeof(struct ipc_entry)) <
- (space->is_tree_small * sizeof(struct ipc_tree_entry))));
+ entry->ie_bits = 0;
+ assert(entry->ie_object == IO_NULL);
+ assert(entry->ie_name == name);
+ entry->ie_request = 0;
+ space->is_size += 1;
+ *entryp = entry;
return KERN_SUCCESS;
}
-
#if MACH_KDB
#include <ddb/db_output.h>
#include <kern/task.h>
#define printf kdbprintf
-ipc_entry_t db_ipc_object_by_name(
- task_t task,
- mach_port_t name);
-
-
ipc_entry_t
db_ipc_object_by_name(
- task_t task,
+ const task_t task,
mach_port_t name)
{
ipc_space_t space = task->itk_space;
diff --git a/ipc/ipc_entry.h b/ipc/ipc_entry.h
index 6afa4f68..b429984b 100644
--- a/ipc/ipc_entry.h
+++ b/ipc/ipc_entry.h
@@ -48,47 +48,27 @@
/*
* Spaces hold capabilities for ipc_object_t's (ports and port sets).
- * Each ipc_entry_t records a capability. Most capabilities have
- * small names, and the entries are elements of a table.
- * Capabilities can have large names, and a splay tree holds
- * those entries. The cutoff point between the table and the tree
- * is adjusted dynamically to minimize memory consumption.
- *
- * The ie_index field of entries in the table implements
- * a ordered hash table with open addressing and linear probing.
- * This hash table converts (space, object) -> name.
- * It is used independently of the other fields.
- *
- * Free (unallocated) entries in the table have null ie_object
- * fields. The ie_bits field is zero except for IE_BITS_GEN.
- * The ie_next (ie_request) field links free entries into a free list.
- *
- * The first entry in the table (index 0) is always free.
- * It is used as the head of the free list.
+ * Each ipc_entry_t records a capability.
*/
typedef unsigned int ipc_entry_bits_t;
typedef ipc_table_elems_t ipc_entry_num_t; /* number of entries */
typedef struct ipc_entry {
+ mach_port_t ie_name;
ipc_entry_bits_t ie_bits;
struct ipc_object *ie_object;
union {
- mach_port_index_t next;
+ struct ipc_entry *next_free;
/*XXX ipc_port_request_index_t request;*/
unsigned int request;
} index;
- union {
- mach_port_index_t table;
- struct ipc_tree_entry *tree;
- } hash;
} *ipc_entry_t;
#define IE_NULL ((ipc_entry_t) 0)
#define ie_request index.request
-#define ie_next index.next
-#define ie_index hash.table
+#define ie_next_free index.next_free
#define IE_BITS_UREFS_MASK 0x0000ffff /* 16 bits of user-reference */
#define IE_BITS_UREFS(bits) ((bits) & IE_BITS_UREFS_MASK)
@@ -98,12 +78,10 @@ typedef struct ipc_entry {
#define IE_BITS_MAREQUEST 0x00200000 /* 1 bit for msg-accepted */
-#define IE_BITS_COMPAT 0x00400000 /* 1 bit for compatibility */
-
-#define IE_BITS_COLLISION 0x00800000 /* 1 bit for collisions */
-#define IE_BITS_RIGHT_MASK 0x007fffff /* relevant to the right */
+#define IE_BITS_RIGHT_MASK 0x003fffff /* relevant to the right */
#if PORT_GENERATIONS
+#error "not supported"
#define IE_BITS_GEN_MASK 0xff000000U /* 8 bits for generation */
#define IE_BITS_GEN(bits) ((bits) & IE_BITS_GEN_MASK)
#define IE_BITS_GEN_ONE 0x01000000 /* low bit of generation */
@@ -114,32 +92,9 @@ typedef struct ipc_entry {
#endif
-typedef struct ipc_tree_entry {
- struct ipc_entry ite_entry;
- mach_port_t ite_name;
- struct ipc_space *ite_space;
- struct ipc_tree_entry *ite_lchild;
- struct ipc_tree_entry *ite_rchild;
-} *ipc_tree_entry_t;
-
-#define ITE_NULL ((ipc_tree_entry_t) 0)
-
-#define ite_bits ite_entry.ie_bits
-#define ite_object ite_entry.ie_object
-#define ite_request ite_entry.ie_request
-#define ite_next ite_entry.hash.tree
-
-extern struct kmem_cache ipc_tree_entry_cache;
-
-#define ite_alloc() ((ipc_tree_entry_t) kmem_cache_alloc(&ipc_tree_entry_cache))
-#define ite_free(ite) kmem_cache_free(&ipc_tree_entry_cache, (vm_offset_t) (ite))
-
-
-extern ipc_entry_t
-ipc_entry_lookup(ipc_space_t space, mach_port_t name);
-
-extern kern_return_t
-ipc_entry_get(ipc_space_t space, mach_port_t *namep, ipc_entry_t *entryp);
+extern struct kmem_cache ipc_entry_cache;
+#define ie_alloc() ((ipc_entry_t) kmem_cache_alloc(&ipc_entry_cache))
+#define ie_free(e) kmem_cache_free(&ipc_entry_cache, (vm_offset_t) (e))
extern kern_return_t
ipc_entry_alloc(ipc_space_t space, mach_port_t *namep, ipc_entry_t *entryp);
@@ -147,10 +102,9 @@ ipc_entry_alloc(ipc_space_t space, mach_port_t *namep, ipc_entry_t *entryp);
extern kern_return_t
ipc_entry_alloc_name(ipc_space_t space, mach_port_t name, ipc_entry_t *entryp);
-extern void
-ipc_entry_dealloc(ipc_space_t space, mach_port_t name, ipc_entry_t entry);
-
-extern kern_return_t
-ipc_entry_grow_table(ipc_space_t space);
+ipc_entry_t
+db_ipc_object_by_name(
+ task_t task,
+ mach_port_t name);
#endif /* _IPC_IPC_ENTRY_H_ */
diff --git a/ipc/ipc_hash.c b/ipc/ipc_hash.c
deleted file mode 100644
index 5eec58cb..00000000
--- a/ipc/ipc_hash.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: ipc/ipc_hash.c
- * Author: Rich Draves
- * Date: 1989
- *
- * Entry hash table operations.
- */
-
-#include <kern/printf.h>
-#include <mach/boolean.h>
-#include <mach/port.h>
-#include <kern/lock.h>
-#include <kern/kalloc.h>
-#include <ipc/port.h>
-#include <ipc/ipc_space.h>
-#include <ipc/ipc_object.h>
-#include <ipc/ipc_entry.h>
-#include <ipc/ipc_hash.h>
-#include <ipc/ipc_init.h>
-#include <ipc/ipc_types.h>
-
-#if MACH_IPC_DEBUG
-#include <mach/kern_return.h>
-#include <mach_debug/hash_info.h>
-#include <vm/vm_map.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_user.h>
-#endif
-
-
-
-/*
- * Routine: ipc_hash_lookup
- * Purpose:
- * Converts (space, obj) -> (name, entry).
- * Returns TRUE if an entry was found.
- * Conditions:
- * The space must be locked (read or write) throughout.
- */
-
-boolean_t
-ipc_hash_lookup(space, obj, namep, entryp)
- ipc_space_t space;
- ipc_object_t obj;
- mach_port_t *namep;
- ipc_entry_t *entryp;
-{
- return (ipc_hash_local_lookup(space, obj, namep, entryp) ||
- ((space->is_tree_hash > 0) &&
- ipc_hash_global_lookup(space, obj, namep,
- (ipc_tree_entry_t *) entryp)));
-}
-
-/*
- * Routine: ipc_hash_insert
- * Purpose:
- * Inserts an entry into the appropriate reverse hash table,
- * so that ipc_hash_lookup will find it.
- * Conditions:
- * The space must be write-locked.
- */
-
-void
-ipc_hash_insert(
- ipc_space_t space,
- ipc_object_t obj,
- mach_port_t name,
- ipc_entry_t entry)
-{
- mach_port_index_t index;
-
- index = MACH_PORT_INDEX(name);
- if ((index < space->is_table_size) &&
- (entry == &space->is_table[index]))
- ipc_hash_local_insert(space, obj, index, entry);
- else
- ipc_hash_global_insert(space, obj, name,
- (ipc_tree_entry_t) entry);
-}
-
-/*
- * Routine: ipc_hash_delete
- * Purpose:
- * Deletes an entry from the appropriate reverse hash table.
- * Conditions:
- * The space must be write-locked.
- */
-
-void
-ipc_hash_delete(
- ipc_space_t space,
- ipc_object_t obj,
- mach_port_t name,
- ipc_entry_t entry)
-{
- mach_port_index_t index;
-
- index = MACH_PORT_INDEX(name);
- if ((index < space->is_table_size) &&
- (entry == &space->is_table[index]))
- ipc_hash_local_delete(space, obj, index, entry);
- else
- ipc_hash_global_delete(space, obj, name,
- (ipc_tree_entry_t) entry);
-}
-
-/*
- * The global reverse hash table holds splay tree entries.
- * It is a simple open-chaining hash table with singly-linked buckets.
- * Each bucket is locked separately, with an exclusive lock.
- * Within each bucket, move-to-front is used.
- */
-
-ipc_hash_index_t ipc_hash_global_size;
-ipc_hash_index_t ipc_hash_global_mask;
-
-#define IH_GLOBAL_HASH(space, obj) \
- (((((ipc_hash_index_t) ((vm_offset_t)space)) >> 4) + \
- (((ipc_hash_index_t) ((vm_offset_t)obj)) >> 6)) & \
- ipc_hash_global_mask)
-
-typedef struct ipc_hash_global_bucket {
- decl_simple_lock_data(, ihgb_lock_data)
- ipc_tree_entry_t ihgb_head;
-} *ipc_hash_global_bucket_t;
-
-#define IHGB_NULL ((ipc_hash_global_bucket_t) 0)
-
-#define ihgb_lock_init(ihgb) simple_lock_init(&(ihgb)->ihgb_lock_data)
-#define ihgb_lock(ihgb) simple_lock(&(ihgb)->ihgb_lock_data)
-#define ihgb_unlock(ihgb) simple_unlock(&(ihgb)->ihgb_lock_data)
-
-ipc_hash_global_bucket_t ipc_hash_global_table;
-
-/*
- * Routine: ipc_hash_global_lookup
- * Purpose:
- * Converts (space, obj) -> (name, entry).
- * Looks in the global table, for splay tree entries.
- * Returns TRUE if an entry was found.
- * Conditions:
- * The space must be locked (read or write) throughout.
- */
-
-boolean_t
-ipc_hash_global_lookup(
- ipc_space_t space,
- ipc_object_t obj,
- mach_port_t *namep,
- ipc_tree_entry_t *entryp)
-{
- ipc_hash_global_bucket_t bucket;
- ipc_tree_entry_t this, *last;
-
- assert(space != IS_NULL);
- assert(obj != IO_NULL);
-
- bucket = &ipc_hash_global_table[IH_GLOBAL_HASH(space, obj)];
- ihgb_lock(bucket);
-
- if ((this = bucket->ihgb_head) != ITE_NULL) {
- if ((this->ite_object == obj) &&
- (this->ite_space == space)) {
- /* found it at front; no need to move */
-
- *namep = this->ite_name;
- *entryp = this;
- } else for (last = &this->ite_next;
- (this = *last) != ITE_NULL;
- last = &this->ite_next) {
- if ((this->ite_object == obj) &&
- (this->ite_space == space)) {
- /* found it; move to front */
-
- *last = this->ite_next;
- this->ite_next = bucket->ihgb_head;
- bucket->ihgb_head = this;
-
- *namep = this->ite_name;
- *entryp = this;
- break;
- }
- }
- }
-
- ihgb_unlock(bucket);
- return this != ITE_NULL;
-}
-
-/*
- * Routine: ipc_hash_global_insert
- * Purpose:
- * Inserts an entry into the global reverse hash table.
- * Conditions:
- * The space must be write-locked.
- */
-
-void
-ipc_hash_global_insert(
- ipc_space_t space,
- ipc_object_t obj,
- mach_port_t name,
- ipc_tree_entry_t entry)
-{
- ipc_hash_global_bucket_t bucket;
-
-
- assert(entry->ite_name == name);
- assert(space != IS_NULL);
- assert(entry->ite_space == space);
- assert(obj != IO_NULL);
- assert(entry->ite_object == obj);
-
- space->is_tree_hash++;
- assert(space->is_tree_hash <= space->is_tree_total);
-
- bucket = &ipc_hash_global_table[IH_GLOBAL_HASH(space, obj)];
- ihgb_lock(bucket);
-
- /* insert at front of bucket */
-
- entry->ite_next = bucket->ihgb_head;
- bucket->ihgb_head = entry;
-
- ihgb_unlock(bucket);
-}
-
-/*
- * Routine: ipc_hash_global_delete
- * Purpose:
- * Deletes an entry from the global reverse hash table.
- * Conditions:
- * The space must be write-locked.
- */
-
-void
-ipc_hash_global_delete(
- ipc_space_t space,
- ipc_object_t obj,
- mach_port_t name,
- ipc_tree_entry_t entry)
-{
- ipc_hash_global_bucket_t bucket;
- ipc_tree_entry_t this, *last;
-
- assert(entry->ite_name == name);
- assert(space != IS_NULL);
- assert(entry->ite_space == space);
- assert(obj != IO_NULL);
- assert(entry->ite_object == obj);
-
- assert(space->is_tree_hash > 0);
- space->is_tree_hash--;
-
- bucket = &ipc_hash_global_table[IH_GLOBAL_HASH(space, obj)];
- ihgb_lock(bucket);
-
- for (last = &bucket->ihgb_head;
- (this = *last) != ITE_NULL;
- last = &this->ite_next) {
- if (this == entry) {
- /* found it; remove from bucket */
-
- *last = this->ite_next;
- break;
- }
- }
- assert(this != ITE_NULL);
-
- ihgb_unlock(bucket);
-}
-
-/*
- * Each space has a local reverse hash table, which holds
- * entries from the space's table. In fact, the hash table
- * just uses a field (ie_index) in the table itself.
- *
- * The local hash table is an open-addressing hash table,
- * which means that when a collision occurs, instead of
- * throwing the entry into a bucket, the entry is rehashed
- * to another position in the table. In this case the rehash
- * is very simple: linear probing (ie, just increment the position).
- * This simple rehash makes deletions tractable (they're still a pain),
- * but it means that collisions tend to build up into clumps.
- *
- * Because at least one entry in the table (index 0) is always unused,
- * there will always be room in the reverse hash table. If a table
- * with n slots gets completely full, the reverse hash table will
- * have one giant clump of n-1 slots and one free slot somewhere.
- * Because entries are only entered into the reverse table if they
- * are pure send rights (not receive, send-once, port-set,
- * or dead-name rights), and free entries of course aren't entered,
- * I expect the reverse hash table won't get unreasonably full.
- *
- * Ordered hash tables (Amble & Knuth, Computer Journal, v. 17, no. 2,
- * pp. 135-142.) may be desirable here. They can dramatically help
- * unsuccessful lookups. But unsuccessful lookups are almost always
- * followed by insertions, and those slow down somewhat. They
- * also can help deletions somewhat. Successful lookups aren't affected.
- * So possibly a small win; probably nothing significant.
- */
-
-#define IH_LOCAL_HASH(obj, size) \
- ((((mach_port_index_t) (vm_offset_t) (obj)) >> 6) % (size))
-
-/*
- * Routine: ipc_hash_local_lookup
- * Purpose:
- * Converts (space, obj) -> (name, entry).
- * Looks in the space's local table, for table entries.
- * Returns TRUE if an entry was found.
- * Conditions:
- * The space must be locked (read or write) throughout.
- */
-
-boolean_t
-ipc_hash_local_lookup(
- ipc_space_t space,
- ipc_object_t obj,
- mach_port_t *namep,
- ipc_entry_t *entryp)
-{
- ipc_entry_t table;
- ipc_entry_num_t size;
- mach_port_index_t hindex, index;
-
- assert(space != IS_NULL);
- assert(obj != IO_NULL);
-
- table = space->is_table;
- size = space->is_table_size;
- hindex = IH_LOCAL_HASH(obj, size);
-
- /*
- * Ideally, table[hindex].ie_index is the name we want.
- * However, must check ie_object to verify this,
- * because collisions can happen. In case of a collision,
- * search farther along in the clump.
- */
-
- while ((index = table[hindex].ie_index) != 0) {
- ipc_entry_t entry = &table[index];
-
- if (entry->ie_object == obj) {
- *namep = MACH_PORT_MAKEB(index, entry->ie_bits);
- *entryp = entry;
- return TRUE;
- }
-
- if (++hindex == size)
- hindex = 0;
- }
-
- return FALSE;
-}
-
-/*
- * Routine: ipc_hash_local_insert
- * Purpose:
- * Inserts an entry into the space's reverse hash table.
- * Conditions:
- * The space must be write-locked.
- */
-
-void
-ipc_hash_local_insert(
- ipc_space_t space,
- ipc_object_t obj,
- mach_port_index_t index,
- ipc_entry_t entry)
-{
- ipc_entry_t table;
- ipc_entry_num_t size;
- mach_port_index_t hindex;
-
- assert(index != 0);
- assert(space != IS_NULL);
- assert(obj != IO_NULL);
-
- table = space->is_table;
- size = space->is_table_size;
- hindex = IH_LOCAL_HASH(obj, size);
-
- assert(entry == &table[index]);
- assert(entry->ie_object == obj);
-
- /*
- * We want to insert at hindex, but there may be collisions.
- * If a collision occurs, search for the end of the clump
- * and insert there.
- */
-
- while (table[hindex].ie_index != 0) {
- if (++hindex == size)
- hindex = 0;
- }
-
- table[hindex].ie_index = index;
-}
-
-/*
- * Routine: ipc_hash_local_delete
- * Purpose:
- * Deletes an entry from the space's reverse hash table.
- * Conditions:
- * The space must be write-locked.
- */
-
-void
-ipc_hash_local_delete(
- ipc_space_t space,
- ipc_object_t obj,
- mach_port_index_t index,
- ipc_entry_t entry)
-{
- ipc_entry_t table;
- ipc_entry_num_t size;
- mach_port_index_t hindex, dindex;
-
- assert(index != MACH_PORT_NULL);
- assert(space != IS_NULL);
- assert(obj != IO_NULL);
-
- table = space->is_table;
- size = space->is_table_size;
- hindex = IH_LOCAL_HASH(obj, size);
-
- assert(entry == &table[index]);
- assert(entry->ie_object == obj);
-
- /*
- * First check we have the right hindex for this index.
- * In case of collision, we have to search farther
- * along in this clump.
- */
-
- while (table[hindex].ie_index != index) {
- if (table[hindex].ie_index == 0)
- {
- static int gak = 0;
- if (gak == 0)
- {
- printf("gak! entry wasn't in hash table!\n");
- gak = 1;
- }
- return;
- }
- if (++hindex == size)
- hindex = 0;
- }
-
- /*
- * Now we want to set table[hindex].ie_index = 0.
- * But if we aren't the last index in a clump,
- * this might cause problems for lookups of objects
- * farther along in the clump that are displaced
- * due to collisions. Searches for them would fail
- * at hindex instead of succeeding.
- *
- * So we must check the clump after hindex for objects
- * that are so displaced, and move one up to the new hole.
- *
- * hindex - index of new hole in the clump
- * dindex - index we are checking for a displaced object
- *
- * When we move a displaced object up into the hole,
- * it creates a new hole, and we have to repeat the process
- * until we get to the end of the clump.
- */
-
- for (dindex = hindex; index != 0; hindex = dindex) {
- for (;;) {
- mach_port_index_t tindex;
- ipc_object_t tobj;
-
- if (++dindex == size)
- dindex = 0;
- assert(dindex != hindex);
-
- /* are we at the end of the clump? */
-
- index = table[dindex].ie_index;
- if (index == 0)
- break;
-
- /* is this a displaced object? */
-
- tobj = table[index].ie_object;
- assert(tobj != IO_NULL);
- tindex = IH_LOCAL_HASH(tobj, size);
-
- if ((dindex < hindex) ?
- ((dindex < tindex) && (tindex <= hindex)) :
- ((dindex < tindex) || (tindex <= hindex)))
- break;
- }
-
- table[hindex].ie_index = index;
- }
-}
-
-/*
- * Routine: ipc_hash_init
- * Purpose:
- * Initialize the reverse hash table implementation.
- */
-
-void
-ipc_hash_init(void)
-{
- ipc_hash_index_t i;
-
- /* initialize ipc_hash_global_size */
-
- ipc_hash_global_size = IPC_HASH_GLOBAL_SIZE;
-
- /* make sure it is a power of two */
-
- ipc_hash_global_mask = ipc_hash_global_size - 1;
- if ((ipc_hash_global_size & ipc_hash_global_mask) != 0) {
- natural_t bit;
-
- /* round up to closest power of two */
-
- for (bit = 1;; bit <<= 1) {
- ipc_hash_global_mask |= bit;
- ipc_hash_global_size = ipc_hash_global_mask + 1;
-
- if ((ipc_hash_global_size & ipc_hash_global_mask) == 0)
- break;
- }
- }
-
- /* allocate ipc_hash_global_table */
-
- ipc_hash_global_table = (ipc_hash_global_bucket_t)
- kalloc((vm_size_t) (ipc_hash_global_size *
- sizeof(struct ipc_hash_global_bucket)));
- assert(ipc_hash_global_table != IHGB_NULL);
-
- /* and initialize it */
-
- for (i = 0; i < ipc_hash_global_size; i++) {
- ipc_hash_global_bucket_t bucket;
-
- bucket = &ipc_hash_global_table[i];
- ihgb_lock_init(bucket);
- bucket->ihgb_head = ITE_NULL;
- }
-}
-
-#if MACH_IPC_DEBUG
-
-/*
- * Routine: ipc_hash_info
- * Purpose:
- * Return information about the global reverse hash table.
- * Fills the buffer with as much information as possible
- * and returns the desired size of the buffer.
- * Conditions:
- * Nothing locked. The caller should provide
- * possibly-pageable memory.
- */
-
-
-ipc_hash_index_t
-ipc_hash_info(
- hash_info_bucket_t *info,
- mach_msg_type_number_t count)
-{
- ipc_hash_index_t i;
-
- if (ipc_hash_global_size < count)
- count = ipc_hash_global_size;
-
- for (i = 0; i < count; i++) {
- ipc_hash_global_bucket_t bucket = &ipc_hash_global_table[i];
- unsigned int bucket_count = 0;
- ipc_tree_entry_t entry;
-
- ihgb_lock(bucket);
- for (entry = bucket->ihgb_head;
- entry != ITE_NULL;
- entry = entry->ite_next)
- bucket_count++;
- ihgb_unlock(bucket);
-
- /* don't touch pageable memory while holding locks */
- info[i].hib_count = bucket_count;
- }
-
- return ipc_hash_global_size;
-}
-
-#endif /* MACH_IPC_DEBUG */
diff --git a/ipc/ipc_hash.h b/ipc/ipc_hash.h
deleted file mode 100644
index 929ba77d..00000000
--- a/ipc/ipc_hash.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: ipc/ipc_hash.h
- * Author: Rich Draves
- * Date: 1989
- *
- * Declarations of entry hash table operations.
- */
-
-#ifndef _IPC_IPC_HASH_H_
-#define _IPC_IPC_HASH_H_
-
-#include <mach/boolean.h>
-#include <mach/kern_return.h>
-
-typedef natural_t ipc_hash_index_t;
-
-extern void
-ipc_hash_init(void);
-
-#if MACH_IPC_DEBUG
-
-extern ipc_hash_index_t
-ipc_hash_info(hash_info_bucket_t *, mach_msg_type_number_t);
-
-#endif /* MACH_IPC_DEBUG */
-
-extern boolean_t
-ipc_hash_lookup(ipc_space_t space, ipc_object_t obj,
- mach_port_t *namep, ipc_entry_t *entryp);
-
-extern void
-ipc_hash_insert(ipc_space_t space, ipc_object_t obj,
- mach_port_t name, ipc_entry_t entry);
-
-extern void
-ipc_hash_delete(ipc_space_t space, ipc_object_t obj,
- mach_port_t name, ipc_entry_t entry);
-
-/*
- * For use by functions that know what they're doing:
- * the global primitives, for splay tree entries,
- * and the local primitives, for table entries.
- */
-
-#define IPC_HASH_GLOBAL_SIZE 256
-
-extern boolean_t
-ipc_hash_global_lookup(ipc_space_t space, ipc_object_t obj,
- mach_port_t *namep, ipc_tree_entry_t *entryp);
-
-extern void
-ipc_hash_global_insert(ipc_space_t space, ipc_object_t obj,
- mach_port_t name, ipc_tree_entry_t entry);
-
-extern void
-ipc_hash_global_delete(ipc_space_t space, ipc_object_t obj,
- mach_port_t name, ipc_tree_entry_t entry);
-
-extern boolean_t
-ipc_hash_local_lookup(ipc_space_t space, ipc_object_t obj,
- mach_port_t *namep, ipc_entry_t *entryp);
-
-extern void
-ipc_hash_local_insert(ipc_space_t space, ipc_object_t obj,
- mach_port_index_t index, ipc_entry_t entry);
-
-extern void
-ipc_hash_local_delete(ipc_space_t space, ipc_object_t obj,
- mach_port_index_t index, ipc_entry_t entry);
-
-#endif /* _IPC_IPC_HASH_H_ */
diff --git a/ipc/ipc_init.c b/ipc/ipc_init.c
index ca7e7912..2c58a6e4 100644
--- a/ipc/ipc_init.c
+++ b/ipc/ipc_init.c
@@ -47,14 +47,13 @@
#include <ipc/ipc_marequest.h>
#include <ipc/ipc_notify.h>
#include <ipc/ipc_kmsg.h>
-#include <ipc/ipc_hash.h>
#include <ipc/ipc_init.h>
static struct vm_map ipc_kernel_map_store;
vm_map_t ipc_kernel_map = &ipc_kernel_map_store;
-vm_size_t ipc_kernel_map_size = 8 * 1024 * 1024;
+const vm_size_t ipc_kernel_map_size = 8 * 1024 * 1024;
/*
* Routine: ipc_bootstrap
@@ -76,8 +75,8 @@ ipc_bootstrap(void)
kmem_cache_init(&ipc_space_cache, "ipc_space",
sizeof(struct ipc_space), 0, NULL, NULL, NULL, 0);
- kmem_cache_init(&ipc_tree_entry_cache, "ipc_tree_entry",
- sizeof(struct ipc_tree_entry), 0, NULL, NULL, NULL, 0);
+ kmem_cache_init(&ipc_entry_cache, "ipc_entry",
+ sizeof(struct ipc_entry), 0, NULL, NULL, NULL, 0);
kmem_cache_init(&ipc_object_caches[IOT_PORT], "ipc_port",
sizeof(struct ipc_port), 0, NULL, NULL, NULL, 0);
@@ -97,7 +96,6 @@ ipc_bootstrap(void)
ipc_table_init();
ipc_notify_init();
- ipc_hash_init();
ipc_marequest_init();
}
@@ -108,7 +106,7 @@ ipc_bootstrap(void)
*/
void
-ipc_init()
+ipc_init(void)
{
vm_offset_t min, max;
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
index c2689a48..5076809e 100644
--- a/ipc/ipc_kmsg.c
+++ b/ipc/ipc_kmsg.c
@@ -50,7 +50,6 @@
#include <vm/vm_user.h>
#include <ipc/port.h>
#include <ipc/ipc_entry.h>
-#include <ipc/ipc_hash.h>
#include <ipc/ipc_kmsg.h>
#include <ipc/ipc_thread.h>
#include <ipc/ipc_marequest.h>
@@ -66,12 +65,9 @@
#if MACH_KDB
#include <ddb/db_output.h>
+#include <ipc/ipc_print.h>
#endif
-extern int copyinmap();
-extern int copyoutmap();
-void ipc_msg_print(); /* forward */
-
#define is_misaligned(x) ( ((vm_offset_t)(x)) & (sizeof(vm_offset_t)-1) )
#define ptr_align(x) \
( ( ((vm_offset_t)(x)) + (sizeof(vm_offset_t)-1) ) & ~(sizeof(vm_offset_t)-1) )
@@ -142,9 +138,7 @@ ipc_kmsg_rmqueue(
next->ikm_prev = prev;
prev->ikm_next = next;
}
- /* XXX Temporary debug logic */
- kmsg->ikm_next = IKM_BOGUS;
- kmsg->ikm_prev = IKM_BOGUS;
+ ikm_mark_bogus (kmsg);
}
/*
@@ -221,9 +215,9 @@ ipc_kmsg_destroy(
*/
void
-ipc_kmsg_clean_body(saddr, eaddr)
- vm_offset_t saddr;
- vm_offset_t eaddr;
+ipc_kmsg_clean_body(
+ vm_offset_t saddr,
+ vm_offset_t eaddr)
{
while (saddr < eaddr) {
mach_msg_type_long_t *type;
@@ -320,8 +314,7 @@ ipc_kmsg_clean_body(saddr, eaddr)
*/
void
-ipc_kmsg_clean(kmsg)
- ipc_kmsg_t kmsg;
+ipc_kmsg_clean(ipc_kmsg_t kmsg)
{
ipc_marequest_t marequest;
ipc_object_t object;
@@ -364,11 +357,11 @@ ipc_kmsg_clean(kmsg)
*/
void
-ipc_kmsg_clean_partial(kmsg, eaddr, dolast, number)
- ipc_kmsg_t kmsg;
- vm_offset_t eaddr;
- boolean_t dolast;
- mach_msg_type_number_t number;
+ipc_kmsg_clean_partial(
+ ipc_kmsg_t kmsg,
+ vm_offset_t eaddr,
+ boolean_t dolast,
+ mach_msg_type_number_t number)
{
ipc_object_t object;
mach_msg_bits_t mbits = kmsg->ikm_header.msgh_bits;
@@ -469,8 +462,7 @@ xxx: type = (mach_msg_type_long_t *) eaddr;
*/
void
-ipc_kmsg_free(kmsg)
- ipc_kmsg_t kmsg;
+ipc_kmsg_free(ipc_kmsg_t kmsg)
{
vm_size_t size = kmsg->ikm_size;
@@ -503,10 +495,10 @@ ipc_kmsg_free(kmsg)
*/
mach_msg_return_t
-ipc_kmsg_get(msg, size, kmsgp)
- mach_msg_header_t *msg;
- mach_msg_size_t size;
- ipc_kmsg_t *kmsgp;
+ipc_kmsg_get(
+ mach_msg_header_t *msg,
+ mach_msg_size_t size,
+ ipc_kmsg_t *kmsgp)
{
ipc_kmsg_t kmsg;
@@ -555,10 +547,10 @@ ipc_kmsg_get(msg, size, kmsgp)
*/
extern mach_msg_return_t
-ipc_kmsg_get_from_kernel(msg, size, kmsgp)
- mach_msg_header_t *msg;
- mach_msg_size_t size;
- ipc_kmsg_t *kmsgp;
+ipc_kmsg_get_from_kernel(
+ mach_msg_header_t *msg,
+ mach_msg_size_t size,
+ ipc_kmsg_t *kmsgp)
{
ipc_kmsg_t kmsg;
@@ -592,10 +584,10 @@ ipc_kmsg_get_from_kernel(msg, size, kmsgp)
*/
mach_msg_return_t
-ipc_kmsg_put(msg, kmsg, size)
- mach_msg_header_t *msg;
- ipc_kmsg_t kmsg;
- mach_msg_size_t size;
+ipc_kmsg_put(
+ mach_msg_header_t *msg,
+ ipc_kmsg_t kmsg,
+ mach_msg_size_t size)
{
mach_msg_return_t mr;
@@ -677,10 +669,10 @@ ipc_kmsg_put_to_kernel(
*/
mach_msg_return_t
-ipc_kmsg_copyin_header(msg, space, notify)
- mach_msg_header_t *msg;
- ipc_space_t space;
- mach_port_t notify;
+ipc_kmsg_copyin_header(
+ mach_msg_header_t *msg,
+ ipc_space_t space,
+ mach_port_t notify)
{
mach_msg_bits_t mbits = msg->msgh_bits &~ MACH_MSGH_BITS_CIRCULAR;
mach_port_t dest_name = msg->msgh_remote_port;
@@ -705,24 +697,14 @@ ipc_kmsg_copyin_header(msg, space, notify)
if (!space->is_active)
goto abort_async;
- /* optimized ipc_entry_lookup */
-
- {
- mach_port_index_t index = MACH_PORT_INDEX(dest_name);
- mach_port_gen_t gen = MACH_PORT_GEN(dest_name);
-
- if (index >= space->is_table_size)
+ entry = ipc_entry_lookup (space, dest_name);
+ if (entry == IE_NULL)
goto abort_async;
-
- entry = &space->is_table[index];
bits = entry->ie_bits;
- /* check generation number and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|MACH_PORT_TYPE_SEND)) !=
- (gen | MACH_PORT_TYPE_SEND))
+ /* check type bits */
+ if (IE_BITS_TYPE (bits) != MACH_PORT_TYPE_SEND)
goto abort_async;
- }
/* optimized ipc_right_copyin */
@@ -757,8 +739,6 @@ ipc_kmsg_copyin_header(msg, space, notify)
case MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,
MACH_MSG_TYPE_MAKE_SEND_ONCE): {
- ipc_entry_num_t size;
- ipc_entry_t table;
ipc_entry_t entry;
ipc_entry_bits_t bits;
ipc_port_t dest_port, reply_port;
@@ -769,51 +749,28 @@ ipc_kmsg_copyin_header(msg, space, notify)
if (!space->is_active)
goto abort_request;
- size = space->is_table_size;
- table = space->is_table;
-
- /* optimized ipc_entry_lookup of dest_name */
-
- {
- mach_port_index_t index = MACH_PORT_INDEX(dest_name);
- mach_port_gen_t gen = MACH_PORT_GEN(dest_name);
-
- if (index >= size)
+ entry = ipc_entry_lookup (space, dest_name);
+ if (entry == IE_NULL)
goto abort_request;
-
- entry = &table[index];
bits = entry->ie_bits;
- /* check generation number and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|MACH_PORT_TYPE_SEND)) !=
- (gen | MACH_PORT_TYPE_SEND))
+ /* check type bits */
+ if (IE_BITS_TYPE (bits) != MACH_PORT_TYPE_SEND)
goto abort_request;
- }
assert(IE_BITS_UREFS(bits) > 0);
dest_port = (ipc_port_t) entry->ie_object;
assert(dest_port != IP_NULL);
- /* optimized ipc_entry_lookup of reply_name */
-
- {
- mach_port_index_t index = MACH_PORT_INDEX(reply_name);
- mach_port_gen_t gen = MACH_PORT_GEN(reply_name);
-
- if (index >= size)
+ entry = ipc_entry_lookup (space, reply_name);
+ if (entry == IE_NULL)
goto abort_request;
-
- entry = &table[index];
bits = entry->ie_bits;
- /* check generation number and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|MACH_PORT_TYPE_RECEIVE)) !=
- (gen | MACH_PORT_TYPE_RECEIVE))
+ /* check type bits */
+ if (IE_BITS_TYPE (bits) != MACH_PORT_TYPE_RECEIVE)
goto abort_request;
- }
reply_port = (ipc_port_t) entry->ie_object;
assert(reply_port != IP_NULL);
@@ -860,9 +817,6 @@ ipc_kmsg_copyin_header(msg, space, notify)
}
case MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0): {
- mach_port_index_t index;
- mach_port_gen_t gen;
- ipc_entry_t table;
ipc_entry_t entry;
ipc_entry_bits_t bits;
ipc_port_t dest_port;
@@ -876,24 +830,13 @@ ipc_kmsg_copyin_header(msg, space, notify)
if (!space->is_active)
goto abort_reply;
- /* optimized ipc_entry_lookup */
-
- table = space->is_table;
-
- index = MACH_PORT_INDEX(dest_name);
- gen = MACH_PORT_GEN(dest_name);
-
- if (index >= space->is_table_size)
+ entry = ipc_entry_lookup (space, dest_name);
+ if (entry == IE_NULL)
goto abort_reply;
-
- entry = &table[index];
bits = entry->ie_bits;
- /* check generation number, collision bit, and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|IE_BITS_COLLISION|
- MACH_PORT_TYPE_SEND_ONCE)) !=
- (gen | MACH_PORT_TYPE_SEND_ONCE))
+ /* check and type bits */
+ if (IE_BITS_TYPE (bits) != MACH_PORT_TYPE_SEND_ONCE)
goto abort_reply;
/* optimized ipc_right_copyin */
@@ -917,12 +860,8 @@ ipc_kmsg_copyin_header(msg, space, notify)
assert(dest_port->ip_sorights > 0);
ip_unlock(dest_port);
- /* optimized ipc_entry_dealloc */
-
- entry->ie_next = table->ie_next;
- table->ie_next = index;
- entry->ie_bits = gen;
entry->ie_object = IO_NULL;
+ ipc_entry_dealloc (space, dest_name, entry);
is_write_unlock(space);
msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
@@ -1342,10 +1281,10 @@ ipc_kmsg_copyin_header(msg, space, notify)
}
mach_msg_return_t
-ipc_kmsg_copyin_body(kmsg, space, map)
- ipc_kmsg_t kmsg;
- ipc_space_t space;
- vm_map_t map;
+ipc_kmsg_copyin_body(
+ ipc_kmsg_t kmsg,
+ ipc_space_t space,
+ vm_map_t map)
{
ipc_object_t dest;
vm_offset_t saddr, eaddr;
@@ -1562,11 +1501,11 @@ ipc_kmsg_copyin_body(kmsg, space, map)
*/
mach_msg_return_t
-ipc_kmsg_copyin(kmsg, space, map, notify)
- ipc_kmsg_t kmsg;
- ipc_space_t space;
- vm_map_t map;
- mach_port_t notify;
+ipc_kmsg_copyin(
+ ipc_kmsg_t kmsg,
+ ipc_space_t space,
+ vm_map_t map,
+ mach_port_t notify)
{
mach_msg_return_t mr;
@@ -1597,8 +1536,7 @@ ipc_kmsg_copyin(kmsg, space, map, notify)
*/
void
-ipc_kmsg_copyin_from_kernel(
- ipc_kmsg_t kmsg)
+ipc_kmsg_copyin_from_kernel(ipc_kmsg_t kmsg)
{
mach_msg_bits_t bits = kmsg->ikm_header.msgh_bits;
mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits);
@@ -1757,10 +1695,10 @@ ipc_kmsg_copyin_from_kernel(
*/
mach_msg_return_t
-ipc_kmsg_copyout_header(msg, space, notify)
- mach_msg_header_t *msg;
- ipc_space_t space;
- mach_port_t notify;
+ipc_kmsg_copyout_header(
+ mach_msg_header_t *msg,
+ ipc_space_t space,
+ mach_port_t notify)
{
mach_msg_bits_t mbits = msg->msgh_bits;
ipc_port_t dest = (ipc_port_t) msg->msgh_remote_port;
@@ -1774,6 +1712,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
case MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0): {
mach_port_t dest_name;
ipc_port_t nsrequest;
+ unsigned long payload;
/* receiving an asynchronous message */
@@ -1792,6 +1731,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
dest_name = dest->ip_receiver_name;
else
dest_name = MACH_PORT_NULL;
+ payload = dest->ip_protected_payload;
if ((--dest->ip_srights == 0) &&
((nsrequest = dest->ip_nsrequest) != IP_NULL)) {
@@ -1805,21 +1745,27 @@ ipc_kmsg_copyout_header(msg, space, notify)
} else
ip_unlock(dest);
- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
- MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND));
- msg->msgh_local_port = dest_name;
+ if (! ipc_port_flag_protected_payload(dest)) {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND));
+ msg->msgh_local_port = dest_name;
+ } else {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(
+ 0, MACH_MSG_TYPE_PROTECTED_PAYLOAD));
+ msg->msgh_protected_payload = payload;
+ }
msg->msgh_remote_port = MACH_PORT_NULL;
return MACH_MSG_SUCCESS;
}
case MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND,
MACH_MSG_TYPE_PORT_SEND_ONCE): {
- ipc_entry_t table;
- mach_port_index_t index;
ipc_entry_t entry;
ipc_port_t reply = (ipc_port_t) msg->msgh_local_port;
mach_port_t dest_name, reply_name;
ipc_port_t nsrequest;
+ unsigned long payload;
/* receiving a request message */
@@ -1827,8 +1773,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
break;
is_write_lock(space);
- if (!space->is_active ||
- ((index = (table = space->is_table)->ie_next) == 0)) {
+ if (!space->is_active || space->is_free_list == NULL) {
is_write_unlock(space);
break;
}
@@ -1858,11 +1803,14 @@ ipc_kmsg_copyout_header(msg, space, notify)
assert(reply->ip_sorights > 0);
ip_unlock(reply);
- /* optimized ipc_entry_get */
-
- entry = &table[index];
- table->ie_next = entry->ie_next;
- entry->ie_request = 0;
+ kern_return_t kr;
+ kr = ipc_entry_get (space, &reply_name, &entry);
+ if (kr) {
+ ip_unlock(reply);
+ ip_unlock(dest);
+ is_write_unlock(space);
+ break;
+ }
{
mach_port_gen_t gen;
@@ -1870,8 +1818,6 @@ ipc_kmsg_copyout_header(msg, space, notify)
assert((entry->ie_bits &~ IE_BITS_GEN_MASK) == 0);
gen = entry->ie_bits + IE_BITS_GEN_ONE;
- reply_name = MACH_PORT_MAKE(index, gen);
-
/* optimized ipc_right_copyout */
entry->ie_bits = gen | (MACH_PORT_TYPE_SEND_ONCE | 1);
@@ -1890,6 +1836,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
dest_name = dest->ip_receiver_name;
else
dest_name = MACH_PORT_NULL;
+ payload = dest->ip_protected_payload;
if ((--dest->ip_srights == 0) &&
((nsrequest = dest->ip_nsrequest) != IP_NULL)) {
@@ -1903,16 +1850,24 @@ ipc_kmsg_copyout_header(msg, space, notify)
} else
ip_unlock(dest);
- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
- MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
- MACH_MSG_TYPE_PORT_SEND));
- msg->msgh_local_port = dest_name;
+ if (! ipc_port_flag_protected_payload(dest)) {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
+ MACH_MSG_TYPE_PORT_SEND));
+ msg->msgh_local_port = dest_name;
+ } else {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD));
+ msg->msgh_protected_payload = payload;
+ }
msg->msgh_remote_port = reply_name;
return MACH_MSG_SUCCESS;
}
case MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0): {
mach_port_t dest_name;
+ unsigned long payload;
/* receiving a reply message */
@@ -1926,6 +1881,8 @@ ipc_kmsg_copyout_header(msg, space, notify)
assert(dest->ip_sorights > 0);
+ payload = dest->ip_protected_payload;
+
if (dest->ip_receiver == space) {
ip_release(dest);
dest->ip_sorights--;
@@ -1938,9 +1895,17 @@ ipc_kmsg_copyout_header(msg, space, notify)
dest_name = MACH_PORT_NULL;
}
- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
- MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND_ONCE));
- msg->msgh_local_port = dest_name;
+ if (! ipc_port_flag_protected_payload(dest)) {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(0,
+ MACH_MSG_TYPE_PORT_SEND_ONCE));
+ msg->msgh_local_port = dest_name;
+ } else {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(0,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD));
+ msg->msgh_protected_payload = payload;
+ }
msg->msgh_remote_port = MACH_PORT_NULL;
return MACH_MSG_SUCCESS;
}
@@ -1956,6 +1921,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
ipc_port_t reply = (ipc_port_t) msg->msgh_local_port;
mach_port_t dest_name, reply_name;
+ unsigned long payload;
if (IP_VALID(reply)) {
ipc_port_t notify_port;
@@ -2036,28 +2002,20 @@ ipc_kmsg_copyout_header(msg, space, notify)
goto copyout_dest;
}
- kr = ipc_entry_get(space, &reply_name, &entry);
+ kr = ipc_entry_alloc(space, &reply_name, &entry);
if (kr != KERN_SUCCESS) {
ip_unlock(reply);
if (notify_port != IP_NULL)
ipc_port_release_sonce(notify_port);
- /* space is locked */
- kr = ipc_entry_grow_table(space);
- if (kr != KERN_SUCCESS) {
- /* space is unlocked */
-
- if (kr == KERN_RESOURCE_SHORTAGE)
- return (MACH_RCV_HEADER_ERROR|
- MACH_MSG_IPC_KERNEL);
- else
- return (MACH_RCV_HEADER_ERROR|
- MACH_MSG_IPC_SPACE);
- }
- /* space is locked again; start over */
-
- continue;
+ is_write_unlock(space);
+ if (kr == KERN_RESOURCE_SHORTAGE)
+ return (MACH_RCV_HEADER_ERROR|
+ MACH_MSG_IPC_KERNEL);
+ else
+ return (MACH_RCV_HEADER_ERROR|
+ MACH_MSG_IPC_SPACE);
}
assert(IE_BITS_TYPE(entry->ie_bits)
@@ -2202,6 +2160,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
*/
copyout_dest:
+ payload = dest->ip_protected_payload;
if (ip_active(dest)) {
ipc_object_copyout_dest(space, (ipc_object_t) dest,
@@ -2230,9 +2189,17 @@ ipc_kmsg_copyout_header(msg, space, notify)
if (IP_VALID(reply))
ipc_port_release(reply);
- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
- MACH_MSGH_BITS(reply_type, dest_type));
- msg->msgh_local_port = dest_name;
+ if (! ipc_port_flag_protected_payload(dest)) {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(reply_type, dest_type));
+ msg->msgh_local_port = dest_name;
+ } else {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(reply_type,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD));
+ msg->msgh_protected_payload = payload;
+ }
+
msg->msgh_remote_port = reply_name;
}
@@ -2257,11 +2224,11 @@ ipc_kmsg_copyout_header(msg, space, notify)
*/
mach_msg_return_t
-ipc_kmsg_copyout_object(space, object, msgt_name, namep)
- ipc_space_t space;
- ipc_object_t object;
- mach_msg_type_name_t msgt_name;
- mach_port_t *namep;
+ipc_kmsg_copyout_object(
+ ipc_space_t space,
+ ipc_object_t object,
+ mach_msg_type_name_t msgt_name,
+ mach_port_t *namep)
{
if (!IO_VALID(object)) {
*namep = (mach_port_t) object;
@@ -2279,7 +2246,7 @@ ipc_kmsg_copyout_object(space, object, msgt_name, namep)
goto slow_copyout;
{
- register ipc_port_t port = (ipc_port_t) object;
+ ipc_port_t port = (ipc_port_t) object;
ipc_entry_t entry;
is_write_lock(space);
@@ -2290,12 +2257,13 @@ ipc_kmsg_copyout_object(space, object, msgt_name, namep)
ip_lock(port);
if (!ip_active(port) ||
- !ipc_hash_local_lookup(space, (ipc_object_t) port,
- namep, &entry)) {
+ (entry = ipc_reverse_lookup(space,
+ (ipc_object_t) port)) == NULL) {
ip_unlock(port);
is_write_unlock(space);
goto slow_copyout;
}
+ *namep = entry->ie_name;
/*
* Copyout the send right, incrementing urefs
@@ -2312,7 +2280,7 @@ ipc_kmsg_copyout_object(space, object, msgt_name, namep)
assert(IE_BITS_UREFS(entry->ie_bits) < MACH_PORT_UREFS_MAX);
{
- register ipc_entry_bits_t bits = entry->ie_bits + 1;
+ ipc_entry_bits_t bits = entry->ie_bits + 1;
if (IE_BITS_UREFS(bits) < MACH_PORT_UREFS_MAX)
entry->ie_bits = bits;
@@ -2367,10 +2335,11 @@ ipc_kmsg_copyout_object(space, object, msgt_name, namep)
*/
mach_msg_return_t
-ipc_kmsg_copyout_body(saddr, eaddr, space, map)
- vm_offset_t saddr, eaddr;
- ipc_space_t space;
- vm_map_t map;
+ipc_kmsg_copyout_body(
+ vm_offset_t saddr,
+ vm_offset_t eaddr,
+ ipc_space_t space,
+ vm_map_t map)
{
mach_msg_return_t mr = MACH_MSG_SUCCESS;
kern_return_t kr;
@@ -2519,11 +2488,11 @@ ipc_kmsg_copyout_body(saddr, eaddr, space, map)
*/
mach_msg_return_t
-ipc_kmsg_copyout(kmsg, space, map, notify)
- ipc_kmsg_t kmsg;
- ipc_space_t space;
- vm_map_t map;
- mach_port_t notify;
+ipc_kmsg_copyout(
+ ipc_kmsg_t kmsg,
+ ipc_space_t space,
+ vm_map_t map,
+ mach_port_t notify)
{
mach_msg_bits_t mbits = kmsg->ikm_header.msgh_bits;
mach_msg_return_t mr;
@@ -2613,9 +2582,9 @@ ipc_kmsg_copyout_pseudo(
*/
void
-ipc_kmsg_copyout_dest(kmsg, space)
- ipc_kmsg_t kmsg;
- ipc_space_t space;
+ipc_kmsg_copyout_dest(
+ ipc_kmsg_t kmsg,
+ ipc_space_t space)
{
mach_msg_bits_t mbits = kmsg->ikm_header.msgh_bits;
ipc_object_t dest = (ipc_object_t) kmsg->ikm_header.msgh_remote_port;
@@ -2661,9 +2630,9 @@ ipc_kmsg_copyout_dest(kmsg, space)
#if MACH_KDB
char *
-ipc_type_name(type_name, received)
- int type_name;
- boolean_t received;
+ipc_type_name(
+ int type_name,
+ boolean_t received)
{
switch (type_name) {
case MACH_MSG_TYPE_BOOLEAN:
@@ -2744,8 +2713,7 @@ ipc_print_type_name(
* ipc_kmsg_print [ debug ]
*/
void
-ipc_kmsg_print(kmsg)
- ipc_kmsg_t kmsg;
+ipc_kmsg_print(ipc_kmsg_t kmsg)
{
db_printf("kmsg=0x%x\n", kmsg);
db_printf("ikm_next=0x%x,prev=0x%x,size=%d,marequest=0x%x",
@@ -2761,8 +2729,7 @@ ipc_kmsg_print(kmsg)
* ipc_msg_print [ debug ]
*/
void
-ipc_msg_print(msgh)
- mach_msg_header_t *msgh;
+ipc_msg_print(mach_msg_header_t *msgh)
{
vm_offset_t saddr, eaddr;
diff --git a/ipc/ipc_kmsg.h b/ipc/ipc_kmsg.h
index 8867310d..393c0392 100644
--- a/ipc/ipc_kmsg.h
+++ b/ipc/ipc_kmsg.h
@@ -38,7 +38,7 @@
#include <mach/message.h>
#include <kern/assert.h>
#include <kern/cpu_number.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/kalloc.h>
#include <ipc/ipc_marequest.h>
#include <ipc/ipc_object.h>
@@ -72,11 +72,24 @@ typedef struct ipc_kmsg {
#define ikm_plus_overhead(size) ((vm_size_t)((size) + IKM_OVERHEAD))
#define ikm_less_overhead(size) ((mach_msg_size_t)((size) - IKM_OVERHEAD))
+#if MACH_IPC_TEST
/*
- * XXX For debugging.
+ * For debugging.
*/
#define IKM_BOGUS ((ipc_kmsg_t) 0xffffff10)
+#define ikm_mark_bogus(kmsg) \
+MACRO_BEGIN \
+ (kmsg)->ikm_next = IKM_BOGUS; \
+ (kmsg)->ikm_prev = IKM_BOGUS; \
+MACRO_END
+
+#else /* MACH_IPC_TEST */
+
+#define ikm_mark_bogus(kmsg) ;
+
+#endif /* MACH_IPC_TEST */
+
/*
* We keep a per-processor cache of kernel message buffers.
* The cache saves the overhead/locking of using kalloc/kfree.
@@ -92,9 +105,12 @@ extern ipc_kmsg_t ipc_kmsg_cache[NCPUS];
/*
* The size of the kernel message buffers that will be cached.
* IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't.
+ *
+ * We use the page size for IKM_SAVED_KMSG_SIZE to make sure the
+ * page is pinned to a single processor.
*/
-#define IKM_SAVED_KMSG_SIZE ((vm_size_t) 256)
+#define IKM_SAVED_KMSG_SIZE PAGE_SIZE
#define IKM_SAVED_MSG_SIZE ikm_less_overhead(IKM_SAVED_KMSG_SIZE)
#define ikm_alloc(size) \
@@ -140,8 +156,7 @@ MACRO_BEGIN \
MACRO_END
/*
- * struct ipc_kmsg_queue is defined in kern/thread.h instead of here,
- * so that kern/thread.h doesn't have to include ipc/ipc_kmsg.h.
+ * struct ipc_kmsg_queue is defined in ipc/ipc_kmsg_queue.h
*/
#include <ipc/ipc_kmsg_queue.h>
@@ -196,9 +211,7 @@ MACRO_BEGIN \
_next->ikm_prev = _prev; \
_prev->ikm_next = _next; \
} \
- /* XXX Debug paranoia */ \
- kmsg->ikm_next = IKM_BOGUS; \
- kmsg->ikm_prev = IKM_BOGUS; \
+ ikm_mark_bogus (kmsg); \
MACRO_END
#define ipc_kmsg_enqueue_macro(queue, kmsg) \
diff --git a/ipc/ipc_kmsg_queue.h b/ipc/ipc_kmsg_queue.h
index 51ccbe24..b4b3df1d 100644
--- a/ipc/ipc_kmsg_queue.h
+++ b/ipc/ipc_kmsg_queue.h
@@ -27,5 +27,5 @@
#define _IPC_KMSG_QUEUE_H_
struct ipc_kmsg_queue {
struct ipc_kmsg *ikmq_base; };
-#endif
+#endif /* _IPC_KMSG_QUEUE_H_ */
diff --git a/ipc/ipc_machdep.h b/ipc/ipc_machdep.h
index e864c4b0..c205ba45 100755
--- a/ipc/ipc_machdep.h
+++ b/ipc/ipc_machdep.h
@@ -24,6 +24,9 @@
* the rights to redistribute these changes.
*/
+#ifndef _IPC_IPC_MACHDEP_H_
+#define _IPC_IPC_MACHDEP_H_
+
/*
* At times, we need to know the size of a port in bits
*/
@@ -38,3 +41,4 @@
#define PORT_T_SIZE_IN_BITS 32
#endif
+#endif /* _IPC_IPC_MACHDEP_H_ */
diff --git a/ipc/ipc_marequest.c b/ipc/ipc_marequest.c
index 06c53eb4..ded1711d 100644
--- a/ipc/ipc_marequest.c
+++ b/ipc/ipc_marequest.c
@@ -160,11 +160,11 @@ ipc_marequest_init(void)
*/
mach_msg_return_t
-ipc_marequest_create(space, port, notify, marequestp)
- ipc_space_t space;
- ipc_port_t port;
- mach_port_t notify;
- ipc_marequest_t *marequestp;
+ipc_marequest_create(
+ ipc_space_t space,
+ ipc_port_t port,
+ mach_port_t notify,
+ ipc_marequest_t *marequestp)
{
mach_port_t name;
ipc_entry_t entry;
@@ -256,9 +256,9 @@ ipc_marequest_create(space, port, notify, marequestp)
*/
void
-ipc_marequest_cancel(space, name)
- ipc_space_t space;
- mach_port_t name;
+ipc_marequest_cancel(
+ ipc_space_t space,
+ mach_port_t name)
{
ipc_marequest_bucket_t bucket;
ipc_marequest_t marequest, *last;
@@ -292,9 +292,10 @@ ipc_marequest_cancel(space, name)
*/
void
-ipc_marequest_rename(space, old, new)
- ipc_space_t space;
- mach_port_t old, new;
+ipc_marequest_rename(
+ ipc_space_t space,
+ mach_port_t old,
+ mach_port_t new)
{
ipc_marequest_bucket_t bucket;
ipc_marequest_t marequest, *last;
@@ -336,8 +337,7 @@ ipc_marequest_rename(space, old, new)
*/
void
-ipc_marequest_destroy(marequest)
- ipc_marequest_t marequest;
+ipc_marequest_destroy(ipc_marequest_t marequest)
{
ipc_space_t space = marequest->imar_space;
mach_port_t name;
@@ -404,10 +404,10 @@ ipc_marequest_destroy(marequest)
*/
unsigned int
-ipc_marequest_info(maxp, info, count)
- unsigned int *maxp;
- hash_info_bucket_t *info;
- unsigned int count;
+ipc_marequest_info(
+ unsigned int *maxp,
+ hash_info_bucket_t *info,
+ unsigned int count)
{
ipc_marequest_index_t i;
diff --git a/ipc/ipc_mqueue.c b/ipc/ipc_mqueue.c
index 80a34d3a..9138aec4 100644
--- a/ipc/ipc_mqueue.c
+++ b/ipc/ipc_mqueue.c
@@ -79,9 +79,9 @@ ipc_mqueue_init(
void
ipc_mqueue_move(
- ipc_mqueue_t dest,
- ipc_mqueue_t source,
- ipc_port_t port)
+ ipc_mqueue_t dest,
+ ipc_mqueue_t source,
+ const ipc_port_t port)
{
ipc_kmsg_queue_t oldq, newq;
ipc_thread_queue_t blockedq;
@@ -171,10 +171,10 @@ ipc_mqueue_changed(
*/
mach_msg_return_t
-ipc_mqueue_send(kmsg, option, time_out)
- ipc_kmsg_t kmsg;
- mach_msg_option_t option;
- mach_msg_timeout_t time_out;
+ipc_mqueue_send(
+ ipc_kmsg_t kmsg,
+ mach_msg_option_t option,
+ mach_msg_timeout_t time_out)
{
ipc_port_t port;
diff --git a/ipc/ipc_mqueue.h b/ipc/ipc_mqueue.h
index ef0f9425..2af5e02e 100644
--- a/ipc/ipc_mqueue.h
+++ b/ipc/ipc_mqueue.h
@@ -37,7 +37,8 @@
#include <mach/message.h>
#include <kern/assert.h>
#include <kern/lock.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
+#include <ipc/ipc_kmsg_queue.h>
#include <ipc/ipc_kmsg.h>
#include <ipc/ipc_thread.h>
diff --git a/ipc/ipc_notify.c b/ipc/ipc_notify.c
index 25fa421b..df5f68bc 100644
--- a/ipc/ipc_notify.c
+++ b/ipc/ipc_notify.c
@@ -59,8 +59,7 @@ mach_dead_name_notification_t ipc_notify_dead_name_template;
*/
void
-ipc_notify_init_port_deleted(n)
- mach_port_deleted_notification_t *n;
+ipc_notify_init_port_deleted(mach_port_deleted_notification_t *n)
{
mach_msg_header_t *m = &n->not_header;
mach_msg_type_t *t = &n->not_type;
@@ -90,8 +89,7 @@ ipc_notify_init_port_deleted(n)
*/
void
-ipc_notify_init_msg_accepted(n)
- mach_msg_accepted_notification_t *n;
+ipc_notify_init_msg_accepted(mach_msg_accepted_notification_t *n)
{
mach_msg_header_t *m = &n->not_header;
mach_msg_type_t *t = &n->not_type;
@@ -121,8 +119,7 @@ ipc_notify_init_msg_accepted(n)
*/
void
-ipc_notify_init_port_destroyed(
- mach_port_destroyed_notification_t *n)
+ipc_notify_init_port_destroyed(mach_port_destroyed_notification_t *n)
{
mach_msg_header_t *m = &n->not_header;
mach_msg_type_t *t = &n->not_type;
@@ -255,9 +252,9 @@ ipc_notify_init(void)
*/
void
-ipc_notify_port_deleted(port, name)
- ipc_port_t port;
- mach_port_t name;
+ipc_notify_port_deleted(
+ ipc_port_t port,
+ mach_port_t name)
{
ipc_kmsg_t kmsg;
mach_port_deleted_notification_t *n;
@@ -289,9 +286,9 @@ ipc_notify_port_deleted(port, name)
*/
void
-ipc_notify_msg_accepted(port, name)
- ipc_port_t port;
- mach_port_t name;
+ipc_notify_msg_accepted(
+ ipc_port_t port,
+ mach_port_t name)
{
ipc_kmsg_t kmsg;
mach_msg_accepted_notification_t *n;
@@ -326,9 +323,9 @@ ipc_notify_msg_accepted(port, name)
*/
void
-ipc_notify_port_destroyed(port, right)
- ipc_port_t port;
- ipc_port_t right;
+ipc_notify_port_destroyed(
+ ipc_port_t port,
+ ipc_port_t right)
{
ipc_kmsg_t kmsg;
mach_port_destroyed_notification_t *n;
@@ -362,9 +359,9 @@ ipc_notify_port_destroyed(port, right)
*/
void
-ipc_notify_no_senders(port, mscount)
- ipc_port_t port;
- mach_port_mscount_t mscount;
+ipc_notify_no_senders(
+ ipc_port_t port,
+ mach_port_mscount_t mscount)
{
ipc_kmsg_t kmsg;
mach_no_senders_notification_t *n;
@@ -396,8 +393,7 @@ ipc_notify_no_senders(port, mscount)
*/
void
-ipc_notify_send_once(port)
- ipc_port_t port;
+ipc_notify_send_once(ipc_port_t port)
{
ipc_kmsg_t kmsg;
mach_send_once_notification_t *n;
@@ -428,9 +424,9 @@ ipc_notify_send_once(port)
*/
void
-ipc_notify_dead_name(port, name)
- ipc_port_t port;
- mach_port_t name;
+ipc_notify_dead_name(
+ ipc_port_t port,
+ mach_port_t name)
{
ipc_kmsg_t kmsg;
mach_dead_name_notification_t *n;
diff --git a/ipc/ipc_object.c b/ipc/ipc_object.c
index b8cae8f5..320fbcb2 100644
--- a/ipc/ipc_object.c
+++ b/ipc/ipc_object.c
@@ -41,7 +41,6 @@
#include <ipc/ipc_space.h>
#include <ipc/ipc_entry.h>
#include <ipc/ipc_object.h>
-#include <ipc/ipc_hash.h>
#include <ipc/ipc_right.h>
#include <ipc/ipc_notify.h>
#include <ipc/ipc_pset.h>
@@ -156,11 +155,12 @@ ipc_object_alloc_dead(
ipc_entry_t entry;
kern_return_t kr;
-
+ is_write_lock(space);
kr = ipc_entry_alloc(space, namep, &entry);
- if (kr != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
return kr;
- /* space is write-locked */
+ }
/* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */
@@ -192,11 +192,12 @@ ipc_object_alloc_dead_name(
ipc_entry_t entry;
kern_return_t kr;
-
+ is_write_lock(space);
kr = ipc_entry_alloc_name(space, name, &entry);
- if (kr != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
return kr;
- /* space is write-locked */
+ }
if (ipc_right_inuse(space, name, entry))
return KERN_NAME_EXISTS;
@@ -255,12 +256,13 @@ ipc_object_alloc(
memset(pset, 0, sizeof(*pset));
}
+ is_write_lock(space);
kr = ipc_entry_alloc(space, namep, &entry);
if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
io_free(otype, object);
return kr;
}
- /* space is write-locked */
entry->ie_bits |= type | urefs;
entry->ie_object = object;
@@ -322,12 +324,13 @@ ipc_object_alloc_name(
memset(pset, 0, sizeof(*pset));
}
+ is_write_lock(space);
kr = ipc_entry_alloc_name(space, name, &entry);
if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
io_free(otype, object);
return kr;
}
- /* space is write-locked */
if (ipc_right_inuse(space, name, entry)) {
io_free(otype, object);
@@ -481,6 +484,7 @@ ipc_object_copyin_from_kernel(
port->ip_receiver_name = MACH_PORT_NULL;
port->ip_destination = IP_NULL;
+ ipc_port_flag_protected_payload_clear(port);
ip_unlock(port);
break;
}
@@ -629,15 +633,10 @@ ipc_object_copyout(
break;
}
- kr = ipc_entry_get(space, &name, &entry);
+ kr = ipc_entry_alloc(space, &name, &entry);
if (kr != KERN_SUCCESS) {
- /* unlocks/locks space, so must start again */
-
- kr = ipc_entry_grow_table(space);
- if (kr != KERN_SUCCESS)
- return kr; /* space is unlocked */
-
- continue;
+ is_write_unlock(space);
+ return kr;
}
assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE);
@@ -690,15 +689,10 @@ ipc_object_copyout_multiname(space, object, namep)
return KERN_INVALID_TASK;
}
- kr = ipc_entry_get(space, &name, &entry);
+ kr = ipc_entry_alloc(space, &name, &entry);
if (kr != KERN_SUCCESS) {
- /* unlocks/locks space, so must start again */
-
- kr = ipc_entry_grow_table(space);
- if (kr != KERN_SUCCESS)
- return kr; /* space is unlocked */
-
- continue;
+ is_write_unlock(space);
+ return kr; /* space is unlocked */
}
assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE);
@@ -763,10 +757,12 @@ ipc_object_copyout_name(
assert(IO_VALID(object));
assert(io_otype(object) == IOT_PORT);
+ is_write_lock(space);
kr = ipc_entry_alloc_name(space, name, &entry);
- if (kr != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
return kr;
- /* space is write-locked and active */
+ }
if ((msgt_name != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
ipc_right_reverse(space, object, &oname, &oentry)) {
@@ -940,10 +936,12 @@ ipc_object_rename(
ipc_entry_t oentry, nentry;
kern_return_t kr;
+ is_write_lock(space);
kr = ipc_entry_alloc_name(space, nname, &nentry);
- if (kr != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
return kr;
- /* space is write-locked and active */
+ }
if (ipc_right_inuse(space, nname, nentry)) {
/* space is unlocked */
@@ -1007,7 +1005,7 @@ char *ikot_print_array[IKOT_MAX_TYPE] = {
void
ipc_object_print(
- ipc_object_t object)
+ const ipc_object_t object)
{
int kotype;
diff --git a/ipc/ipc_object.h b/ipc/ipc_object.h
index adf5bca4..be5bea71 100644
--- a/ipc/ipc_object.h
+++ b/ipc/ipc_object.h
@@ -38,7 +38,7 @@
#include <mach/message.h>
#include <ipc/ipc_types.h>
#include <kern/lock.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/slab.h>
typedef unsigned int ipc_object_refs_t;
@@ -57,7 +57,9 @@ typedef struct ipc_object {
#define IO_VALID(io) (((io) != IO_NULL) && ((io) != IO_DEAD))
#define IO_BITS_KOTYPE 0x0000ffff /* used by the object */
-#define IO_BITS_OTYPE 0x7fff0000 /* determines a cache */
+#define IO_BITS_OTYPE 0x3fff0000 /* determines a cache */
+/* The following masks are used to store attributes of ipc ports. */
+#define IO_BITS_PROTECTED_PAYLOAD 0x40000000 /* pp set? */
#define IO_BITS_ACTIVE 0x80000000U /* is object alive? */
#define io_active(io) ((int)(io)->io_bits < 0) /* hack */
diff --git a/ipc/ipc_port.c b/ipc/ipc_port.c
index 8e41c3ca..86a4ee2a 100644
--- a/ipc/ipc_port.c
+++ b/ipc/ipc_port.c
@@ -53,6 +53,7 @@
#if MACH_KDB
#include <ddb/db_output.h>
+#include <ipc/ipc_print.h>
#endif /* MACH_KDB */
@@ -93,11 +94,11 @@ ipc_port_timestamp(void)
*/
kern_return_t
-ipc_port_dnrequest(port, name, soright, indexp)
- ipc_port_t port;
- mach_port_t name;
- ipc_port_t soright;
- ipc_port_request_index_t *indexp;
+ipc_port_dnrequest(
+ ipc_port_t port,
+ mach_port_t name,
+ ipc_port_t soright,
+ ipc_port_request_index_t *indexp)
{
ipc_port_request_t ipr, table;
ipc_port_request_index_t index;
@@ -141,8 +142,7 @@ ipc_port_dnrequest(port, name, soright, indexp)
*/
kern_return_t
-ipc_port_dngrow(port)
- ipc_port_t port;
+ipc_port_dngrow(ipc_port_t port)
{
ipc_table_size_t its;
ipc_port_request_t otable, ntable;
@@ -274,9 +274,9 @@ ipc_port_dncancel(
void
ipc_port_pdrequest(
- ipc_port_t port,
- ipc_port_t notify,
- ipc_port_t *previousp)
+ ipc_port_t port,
+ const ipc_port_t notify,
+ ipc_port_t *previousp)
{
ipc_port_t previous;
@@ -381,8 +381,7 @@ ipc_port_set_qlimit(
*/
ipc_mqueue_t
-ipc_port_lock_mqueue(port)
- ipc_port_t port;
+ipc_port_lock_mqueue(ipc_port_t port)
{
if (port->ip_pset != IPS_NULL) {
ipc_pset_t pset = port->ip_pset;
@@ -412,9 +411,9 @@ ipc_port_lock_mqueue(port)
*/
void
-ipc_port_set_seqno(port, seqno)
- ipc_port_t port;
- mach_port_seqno_t seqno;
+ipc_port_set_seqno(
+ ipc_port_t port,
+ mach_port_seqno_t seqno)
{
ipc_mqueue_t mqueue;
@@ -424,6 +423,44 @@ ipc_port_set_seqno(port, seqno)
}
/*
+ * Routine: ipc_port_set_protected_payload
+ * Purpose:
+ * Changes a port's protected payload.
+ * Conditions:
+ * The port is locked and active.
+ */
+
+void
+ipc_port_set_protected_payload(ipc_port_t port, unsigned long payload)
+{
+ ipc_mqueue_t mqueue;
+
+ mqueue = ipc_port_lock_mqueue(port);
+ port->ip_protected_payload = payload;
+ ipc_port_flag_protected_payload_set(port);
+ imq_unlock(mqueue);
+}
+
+/*
+ * Routine: ipc_port_clear_protected_payload
+ * Purpose:
+ * Clear a port's protected payload.
+ * Conditions:
+ * The port is locked and active.
+ */
+
+void
+ipc_port_clear_protected_payload(ipc_port_t port)
+{
+ ipc_mqueue_t mqueue;
+
+ mqueue = ipc_port_lock_mqueue(port);
+ ipc_port_flag_protected_payload_clear(port);
+ imq_unlock(mqueue);
+}
+
+
+/*
* Routine: ipc_port_clear_receiver
* Purpose:
* Prepares a receive right for transmission/destruction.
@@ -492,6 +529,8 @@ ipc_port_init(
port->ip_seqno = 0;
port->ip_msgcount = 0;
port->ip_qlimit = MACH_PORT_QLIMIT_DEFAULT;
+ ipc_port_flag_protected_payload_clear(port);
+ port->ip_protected_payload = 0;
ipc_mqueue_init(&port->ip_messages);
ipc_thread_queue_init(&port->ip_blocked);
@@ -614,6 +653,7 @@ ipc_port_destroy(
/* make port be in limbo */
port->ip_receiver_name = MACH_PORT_NULL;
port->ip_destination = IP_NULL;
+ ipc_port_flag_protected_payload_clear(port);
ip_unlock(port);
if (!ipc_port_check_circularity(port, pdrequest)) {
@@ -1134,16 +1174,15 @@ ipc_port_release_receive(
*/
ipc_port_t
-ipc_port_alloc_special(space)
- ipc_space_t space;
+ipc_port_alloc_special(ipc_space_t space)
{
ipc_port_t port;
- port = (ipc_port_t) io_alloc(IOT_PORT);
+ port = ip_alloc();
if (port == IP_NULL)
return IP_NULL;
- io_lock_init(&port->ip_object);
+ ip_lock_init(port);
port->ip_references = 1;
port->ip_object.io_bits = io_makebits(TRUE, IOT_PORT, 0);
@@ -1211,12 +1250,17 @@ ipc_port_dealloc_special(
void
ipc_port_print(port)
- ipc_port_t port;
+ const ipc_port_t port;
{
printf("port 0x%x\n", port);
indent += 2;
+ iprintf("flags ");
+ printf("has_protected_payload=%d",
+ ipc_port_flag_protected_payload(port));
+ printf("\n");
+
ipc_object_print(&port->ip_object);
iprintf("receiver=0x%x", port->ip_receiver);
printf(", receiver_name=0x%x\n", port->ip_receiver_name);
@@ -1239,7 +1283,9 @@ ipc_port_print(port)
printf(", sndrs=0x%x", port->ip_blocked.ithq_base);
printf(", kobj=0x%x\n", port->ip_kobject);
- indent -=2;
+ iprintf("protected_payload=%p\n", (void *) port->ip_protected_payload);
+
+ indent -= 2;
}
#endif /* MACH_KDB */
diff --git a/ipc/ipc_port.h b/ipc/ipc_port.h
index 70ec4946..ade69679 100644
--- a/ipc/ipc_port.h
+++ b/ipc/ipc_port.h
@@ -43,11 +43,12 @@
#include <mach/kern_return.h>
#include <mach/port.h>
#include <kern/lock.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/ipc_kobject.h>
#include <ipc/ipc_mqueue.h>
#include <ipc/ipc_table.h>
#include <ipc/ipc_thread.h>
+#include <ipc/ipc_object.h>
#include "ipc_target.h"
#include <mach/rpc.h>
@@ -96,6 +97,7 @@ struct ipc_port {
mach_port_msgcount_t ip_msgcount;
mach_port_msgcount_t ip_qlimit;
struct ipc_thread_queue ip_blocked;
+ unsigned long ip_protected_payload;
};
#define ip_object ip_target.ipt_object
@@ -262,6 +264,12 @@ extern void
ipc_port_set_seqno(ipc_port_t, mach_port_seqno_t);
extern void
+ipc_port_set_protected_payload(ipc_port_t, unsigned long);
+
+extern void
+ipc_port_clear_protected_payload(ipc_port_t);
+
+extern void
ipc_port_clear_receiver(ipc_port_t);
extern void
@@ -325,7 +333,23 @@ ipc_port_dealloc_special(ipc_port_t, ipc_space_t);
#define ipc_port_release(port) \
ipc_object_release(&(port)->ip_object)
-extern void
-ipc_port_print(ipc_port_t);
+static inline boolean_t
+ipc_port_flag_protected_payload(const struct ipc_port *port)
+{
+ return !! (port->ip_target.ipt_object.io_bits
+ & IO_BITS_PROTECTED_PAYLOAD);
+}
+
+static inline void
+ipc_port_flag_protected_payload_set(struct ipc_port *port)
+{
+ port->ip_target.ipt_object.io_bits |= IO_BITS_PROTECTED_PAYLOAD;
+}
+
+static inline void
+ipc_port_flag_protected_payload_clear(struct ipc_port *port)
+{
+ port->ip_target.ipt_object.io_bits &= ~IO_BITS_PROTECTED_PAYLOAD;
+}
#endif /* _IPC_IPC_PORT_H_ */
diff --git a/ipc/ipc_print.h b/ipc/ipc_print.h
new file mode 100644
index 00000000..5e8e4f34
--- /dev/null
+++ b/ipc/ipc_print.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _IPC_PRINT_H_
+#define _IPC_PRINT_H_
+
+#if MACH_KDB
+
+#include <mach/mach_types.h>
+#include <mach/message.h>
+#include <ipc/ipc_types.h>
+#include <ipc/ipc_pset.h>
+
+extern void ipc_port_print(const ipc_port_t);
+
+extern void ipc_pset_print(const ipc_pset_t);
+
+extern void ipc_kmsg_print(const ipc_kmsg_t);
+
+extern void ipc_msg_print(mach_msg_header_t*);
+
+#endif /* MACH_KDB */
+
+#endif /* IPC_PRINT_H */
diff --git a/ipc/ipc_pset.c b/ipc/ipc_pset.c
index e2b3c862..884e8972 100644
--- a/ipc/ipc_pset.c
+++ b/ipc/ipc_pset.c
@@ -48,6 +48,7 @@
#if MACH_KDB
#include <ddb/db_output.h>
+#include <ipc/ipc_print.h>
#endif /* MACH_KDB */
@@ -333,7 +334,7 @@ ipc_pset_destroy(
void
ipc_pset_print(
- ipc_pset_t pset)
+ const ipc_pset_t pset)
{
printf("pset 0x%x\n", pset);
@@ -344,7 +345,7 @@ ipc_pset_print(
iprintf("kmsgs = 0x%x", pset->ips_messages.imq_messages.ikmq_base);
printf(",rcvrs = 0x%x\n", pset->ips_messages.imq_threads.ithq_base);
- indent -=2;
+ indent -= 2;
}
#endif /* MACH_KDB */
diff --git a/ipc/ipc_pset.h b/ipc/ipc_pset.h
index ac984f99..e9936fef 100644
--- a/ipc/ipc_pset.h
+++ b/ipc/ipc_pset.h
@@ -89,7 +89,4 @@ ipc_pset_destroy(ipc_pset_t);
#define ipc_pset_release(pset) \
ipc_object_release(&(pset)->ips_object)
-extern void
-ipc_pset_print(ipc_pset_t);
-
#endif /* _IPC_IPC_PSET_H_ */
diff --git a/ipc/ipc_right.c b/ipc/ipc_right.c
index 41fe3de1..773b3b10 100644
--- a/ipc/ipc_right.c
+++ b/ipc/ipc_right.c
@@ -43,7 +43,6 @@
#include <ipc/ipc_entry.h>
#include <ipc/ipc_space.h>
#include <ipc/ipc_object.h>
-#include <ipc/ipc_hash.h>
#include <ipc/ipc_port.h>
#include <ipc/ipc_pset.h>
#include <ipc/ipc_marequest.h>
@@ -142,7 +141,8 @@ ipc_right_reverse(
return TRUE;
}
- if (ipc_hash_lookup(space, (ipc_object_t) port, namep, entryp)) {
+ if ((*entryp = ipc_reverse_lookup(space, (ipc_object_t) port))) {
+ *namep = (*entryp)->ie_name;
assert((entry = *entryp) != IE_NULL);
assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_SEND);
assert(port == (ipc_port_t) entry->ie_object);
@@ -331,10 +331,10 @@ ipc_right_dncancel(
*/
boolean_t
-ipc_right_inuse(space, name, entry)
- ipc_space_t space;
- mach_port_t name;
- ipc_entry_t entry;
+ipc_right_inuse(
+ ipc_space_t space,
+ mach_port_t name,
+ ipc_entry_t entry)
{
ipc_entry_bits_t bits = entry->ie_bits;
@@ -359,11 +359,11 @@ ipc_right_inuse(space, name, entry)
*/
boolean_t
-ipc_right_check(space, port, name, entry)
- ipc_space_t space;
- ipc_port_t port;
- mach_port_t name;
- ipc_entry_t entry;
+ipc_right_check(
+ ipc_space_t space,
+ ipc_port_t port,
+ mach_port_t name,
+ ipc_entry_t entry)
{
ipc_entry_bits_t bits;
@@ -392,7 +392,7 @@ ipc_right_check(space, port, name, entry)
ipc_marequest_cancel(space, name);
}
- ipc_hash_delete(space, (ipc_object_t) port, name, entry);
+ ipc_reverse_remove(space, (ipc_object_t) port);
} else {
assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND_ONCE);
assert(IE_BITS_UREFS(bits) == 1);
@@ -423,7 +423,7 @@ ipc_right_check(space, port, name, entry)
* Purpose:
* Cleans up an entry in a dead space.
* The entry isn't deallocated or removed
- * from reverse hash tables.
+ * from the reverse mappings.
* Conditions:
* The space is dead and unlocked.
*/
@@ -609,8 +609,7 @@ ipc_right_destroy(
}
if (type == MACH_PORT_TYPE_SEND)
- ipc_hash_delete(space, (ipc_object_t) port,
- name, entry);
+ ipc_reverse_remove(space, (ipc_object_t) port);
ip_lock(port);
@@ -697,10 +696,10 @@ ipc_right_destroy(
*/
kern_return_t
-ipc_right_dealloc(space, name, entry)
- ipc_space_t space;
- mach_port_t name;
- ipc_entry_t entry;
+ipc_right_dealloc(
+ ipc_space_t space,
+ mach_port_t name,
+ ipc_entry_t entry)
{
ipc_entry_bits_t bits = entry->ie_bits;
mach_port_type_t type = IE_BITS_TYPE(bits);
@@ -789,8 +788,7 @@ ipc_right_dealloc(space, name, entry)
dnrequest = ipc_right_dncancel_macro(space, port,
name, entry);
- ipc_hash_delete(space, (ipc_object_t) port,
- name, entry);
+ ipc_reverse_remove(space, (ipc_object_t) port);
if (bits & IE_BITS_MAREQUEST)
ipc_marequest_cancel(space, name);
@@ -874,12 +872,12 @@ ipc_right_dealloc(space, name, entry)
*/
kern_return_t
-ipc_right_delta(space, name, entry, right, delta)
- ipc_space_t space;
- mach_port_t name;
- ipc_entry_t entry;
- mach_port_right_t right;
- mach_port_delta_t delta;
+ipc_right_delta(
+ ipc_space_t space,
+ mach_port_t name,
+ ipc_entry_t entry,
+ mach_port_right_t right,
+ mach_port_delta_t delta)
{
ipc_entry_bits_t bits = entry->ie_bits;
@@ -1134,8 +1132,7 @@ ipc_right_delta(space, name, entry, right, delta)
dnrequest = ipc_right_dncancel_macro(
space, port, name, entry);
- ipc_hash_delete(space, (ipc_object_t) port,
- name, entry);
+ ipc_reverse_remove(space, (ipc_object_t) port);
if (bits & IE_BITS_MAREQUEST)
ipc_marequest_cancel(space, name);
@@ -1410,8 +1407,8 @@ ipc_right_copyin(
assert(IE_BITS_UREFS(bits) > 0);
assert(port->ip_srights > 0);
- ipc_hash_insert(space, (ipc_object_t) port,
- name, entry);
+ entry->ie_name = name;
+ ipc_reverse_insert(space, (ipc_object_t) port, entry);
ip_reference(port);
} else {
@@ -1432,6 +1429,12 @@ ipc_right_copyin(
port->ip_receiver_name = MACH_PORT_NULL;
port->ip_destination = IP_NULL;
+
+ /*
+ * Clear the protected payload field to retain
+ * the behavior of mach_msg.
+ */
+ ipc_port_flag_protected_payload_clear(port);
ip_unlock(port);
*objectp = (ipc_object_t) port;
@@ -1528,8 +1531,7 @@ ipc_right_copyin(
dnrequest = ipc_right_dncancel_macro(
space, port, name, entry);
- ipc_hash_delete(space, (ipc_object_t) port,
- name, entry);
+ ipc_reverse_remove(space, (ipc_object_t) port);
if (bits & IE_BITS_MAREQUEST)
ipc_marequest_cancel(space, name);
@@ -1790,8 +1792,7 @@ ipc_right_copyin_two(
dnrequest = ipc_right_dncancel_macro(space, port,
name, entry);
- ipc_hash_delete(space, (ipc_object_t) port,
- name, entry);
+ ipc_reverse_remove(space, (ipc_object_t) port);
if (bits & IE_BITS_MAREQUEST)
ipc_marequest_cancel(space, name);
@@ -1915,8 +1916,8 @@ ipc_right_copyout(
/* entry is locked holding ref, so can use port */
- ipc_hash_insert(space, (ipc_object_t) port,
- name, entry);
+ entry->ie_name = name;
+ ipc_reverse_insert(space, (ipc_object_t) port, entry);
}
entry->ie_bits = (bits | MACH_PORT_TYPE_SEND) + 1;
@@ -1932,6 +1933,12 @@ ipc_right_copyout(
port->ip_receiver_name = name;
port->ip_receiver = space;
+ /*
+ * Clear the protected payload field to retain
+ * the behavior of mach_msg.
+ */
+ ipc_port_flag_protected_payload_clear(port);
+
assert((bits & MACH_PORT_TYPE_RECEIVE) == 0);
if (bits & MACH_PORT_TYPE_SEND) {
@@ -1944,8 +1951,7 @@ ipc_right_copyout(
/* entry is locked holding ref, so can use port */
- ipc_hash_delete(space, (ipc_object_t) port,
- name, entry);
+ ipc_reverse_remove(space, (ipc_object_t) port);
} else {
assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_NONE);
assert(IE_BITS_UREFS(bits) == 0);
@@ -2071,7 +2077,7 @@ ipc_right_rename(
ipc_marequest_rename(space, oname, nname);
}
- /* initialize nentry before letting ipc_hash_insert see it */
+ /* initialize nentry before letting ipc_reverse_insert see it */
assert((nentry->ie_bits & IE_BITS_RIGHT_MASK) == 0);
nentry->ie_bits |= bits & IE_BITS_RIGHT_MASK;
@@ -2085,8 +2091,9 @@ ipc_right_rename(
port = (ipc_port_t) object;
assert(port != IP_NULL);
- ipc_hash_delete(space, (ipc_object_t) port, oname, oentry);
- ipc_hash_insert(space, (ipc_object_t) port, nname, nentry);
+ ipc_reverse_remove(space, (ipc_object_t) port);
+ nentry->ie_name = nname;
+ ipc_reverse_insert(space, (ipc_object_t) port, nentry);
break;
}
diff --git a/ipc/ipc_space.c b/ipc/ipc_space.c
index ab55e838..894cf58e 100644
--- a/ipc/ipc_space.c
+++ b/ipc/ipc_space.c
@@ -46,8 +46,6 @@
#include <kern/slab.h>
#include <ipc/port.h>
#include <ipc/ipc_entry.h>
-#include <ipc/ipc_splay.h>
-#include <ipc/ipc_hash.h>
#include <ipc/ipc_table.h>
#include <ipc/ipc_port.h>
#include <ipc/ipc_space.h>
@@ -82,6 +80,9 @@ ipc_space_release(
ipc_space_release_macro(space);
}
+/* A place-holder object for the zeroth entry. */
+struct ipc_entry zero_entry;
+
/*
* Routine: ipc_space_create
* Purpose:
@@ -98,56 +99,27 @@ ipc_space_release(
kern_return_t
ipc_space_create(
- ipc_table_size_t initial,
ipc_space_t *spacep)
{
ipc_space_t space;
- ipc_entry_t table;
- ipc_entry_num_t new_size;
- mach_port_index_t index;
space = is_alloc();
if (space == IS_NULL)
return KERN_RESOURCE_SHORTAGE;
- table = it_entries_alloc(initial);
- if (table == IE_NULL) {
- is_free(space);
- return KERN_RESOURCE_SHORTAGE;
- }
-
- new_size = initial->its_size;
- memset((void *) table, 0, new_size * sizeof(struct ipc_entry));
-
- /*
- * Initialize the free list in the table.
- * Add the entries in reverse order, and
- * set the generation number to -1, so that
- * initial allocations produce "natural" names.
- */
-
- for (index = 0; index < new_size; index++) {
- ipc_entry_t entry = &table[index];
-
- entry->ie_bits = IE_BITS_GEN_MASK;
- entry->ie_next = index+1;
- }
- table[new_size-1].ie_next = 0;
-
is_ref_lock_init(space);
space->is_references = 2;
is_lock_init(space);
space->is_active = TRUE;
- space->is_growing = FALSE;
- space->is_table = table;
- space->is_table_size = new_size;
- space->is_table_next = initial+1;
- ipc_splay_tree_init(&space->is_tree);
- space->is_tree_total = 0;
- space->is_tree_small = 0;
- space->is_tree_hash = 0;
+ rdxtree_init(&space->is_map);
+ rdxtree_init(&space->is_reverse_map);
+ /* The zeroth entry is reserved. */
+ rdxtree_insert(&space->is_map, 0, &zero_entry);
+ space->is_size = 1;
+ space->is_free_list = NULL;
+ space->is_free_list_size = 0;
*spacep = space;
return KERN_SUCCESS;
@@ -201,10 +173,6 @@ void
ipc_space_destroy(
ipc_space_t space)
{
- ipc_tree_entry_t tentry;
- ipc_entry_t table;
- ipc_entry_num_t size;
- mach_port_index_t index;
boolean_t active;
assert(space != IS_NULL);
@@ -217,59 +185,25 @@ ipc_space_destroy(
if (!active)
return;
- /*
- * If somebody is trying to grow the table,
- * we must wait until they finish and figure
- * out the space died.
- */
+ ipc_entry_t entry;
+ struct rdxtree_iter iter;
+ rdxtree_for_each(&space->is_map, &iter, entry) {
+ if (entry->ie_name == MACH_PORT_NULL)
+ continue;
- is_read_lock(space);
- while (space->is_growing) {
- assert_wait((event_t) space, FALSE);
- is_read_unlock(space);
- thread_block((void (*)(void)) 0);
- is_read_lock(space);
- }
- is_read_unlock(space);
-
- /*
- * Now we can futz with it without having it locked.
- */
-
- table = space->is_table;
- size = space->is_table_size;
-
- for (index = 0; index < size; index++) {
- ipc_entry_t entry = &table[index];
mach_port_type_t type = IE_BITS_TYPE(entry->ie_bits);
if (type != MACH_PORT_TYPE_NONE) {
mach_port_t name =
- MACH_PORT_MAKEB(index, entry->ie_bits);
+ MACH_PORT_MAKEB(entry->ie_name, entry->ie_bits);
ipc_right_clean(space, name, entry);
}
- }
-
- it_entries_free(space->is_table_next-1, table);
-
- for (tentry = ipc_splay_traverse_start(&space->is_tree);
- tentry != ITE_NULL;
- tentry = ipc_splay_traverse_next(&space->is_tree, TRUE)) {
- mach_port_type_t type = IE_BITS_TYPE(tentry->ite_bits);
- mach_port_t name = tentry->ite_name;
-
- assert(type != MACH_PORT_TYPE_NONE);
-
- /* use object before ipc_right_clean releases ref */
-
- if (type == MACH_PORT_TYPE_SEND)
- ipc_hash_global_delete(space, tentry->ite_object,
- name, tentry);
- ipc_right_clean(space, name, &tentry->ite_entry);
+ ie_free(entry);
}
- ipc_splay_traverse_finish(&space->is_tree);
+ rdxtree_remove_all(&space->is_map);
+ rdxtree_remove_all(&space->is_reverse_map);
/*
* Because the space is now dead,
diff --git a/ipc/ipc_space.h b/ipc/ipc_space.h
index c4683d20..73c90ef8 100644
--- a/ipc/ipc_space.h
+++ b/ipc/ipc_space.h
@@ -42,25 +42,18 @@
#include <mach/boolean.h>
#include <mach/kern_return.h>
#include <mach/mach_types.h>
-#include <kern/macro_help.h>
+#include <machine/vm_param.h>
+#include <kern/macros.h>
#include <kern/lock.h>
+#include <kern/rdxtree.h>
#include <kern/slab.h>
-#include <ipc/ipc_splay.h>
+#include <ipc/ipc_entry.h>
#include <ipc/ipc_types.h>
/*
* Every task has a space of IPC capabilities.
* IPC operations like send and receive use this space.
* IPC kernel calls manipulate the space of the target task.
- *
- * Every space has a non-NULL is_table with is_table_size entries.
- * A space may have a NULL is_tree. is_tree_small records the
- * number of entries in the tree that, if the table were to grow
- * to the next larger size, would move from the tree to the table.
- *
- * is_growing marks when the table is in the process of growing.
- * When the table is growing, it can't be freed or grown by another
- * thread, because of krealloc/kmem_realloc's requirements.
*/
typedef unsigned int ipc_space_refs_t;
@@ -69,18 +62,18 @@ struct ipc_space {
decl_simple_lock_data(,is_ref_lock_data)
ipc_space_refs_t is_references;
- decl_simple_lock_data(,is_lock_data)
+ struct lock is_lock_data;
boolean_t is_active; /* is the space alive? */
- boolean_t is_growing; /* is the space growing? */
- ipc_entry_t is_table; /* an array of entries */
- ipc_entry_num_t is_table_size; /* current size of table */
- struct ipc_table_size *is_table_next; /* info for larger table */
- struct ipc_splay_tree is_tree; /* a splay tree of entries */
- ipc_entry_num_t is_tree_total; /* number of entries in the tree */
- ipc_entry_num_t is_tree_small; /* # of small entries in the tree */
- ipc_entry_num_t is_tree_hash; /* # of hashed entries in the tree */
+ struct rdxtree is_map; /* a map of entries */
+ size_t is_size; /* number of entries */
+ struct rdxtree is_reverse_map; /* maps objects to entries */
+ ipc_entry_t is_free_list; /* a linked list of free entries */
+ size_t is_free_list_size; /* number of free entries */
+#define IS_FREE_LIST_SIZE_LIMIT 64 /* maximum number of entries
+ in the free list */
};
+
#define IS_NULL ((ipc_space_t) 0)
extern struct kmem_cache ipc_space_cache;
@@ -114,16 +107,16 @@ MACRO_BEGIN \
is_free(is); \
MACRO_END
-#define is_lock_init(is) simple_lock_init(&(is)->is_lock_data)
+#define is_lock_init(is) lock_init(&(is)->is_lock_data, TRUE)
-#define is_read_lock(is) simple_lock(&(is)->is_lock_data)
-#define is_read_unlock(is) simple_unlock(&(is)->is_lock_data)
+#define is_read_lock(is) lock_read(&(is)->is_lock_data)
+#define is_read_unlock(is) lock_done(&(is)->is_lock_data)
-#define is_write_lock(is) simple_lock(&(is)->is_lock_data)
-#define is_write_lock_try(is) simple_lock_try(&(is)->is_lock_data)
-#define is_write_unlock(is) simple_unlock(&(is)->is_lock_data)
+#define is_write_lock(is) lock_write(&(is)->is_lock_data)
+#define is_write_lock_try(is) lock_try_write(&(is)->is_lock_data)
+#define is_write_unlock(is) lock_done(&(is)->is_lock_data)
-#define is_write_to_read_lock(is)
+#define is_write_to_read_lock(is) lock_write_to_read(&(is)->is_lock_data)
extern void ipc_space_reference(struct ipc_space *space);
extern void ipc_space_release(struct ipc_space *space);
@@ -131,8 +124,187 @@ extern void ipc_space_release(struct ipc_space *space);
#define is_reference(is) ipc_space_reference(is)
#define is_release(is) ipc_space_release(is)
-kern_return_t ipc_space_create(ipc_table_size_t, ipc_space_t *);
+kern_return_t ipc_space_create(ipc_space_t *);
kern_return_t ipc_space_create_special(struct ipc_space **);
void ipc_space_destroy(struct ipc_space *);
+/* IPC entry lookups. */
+
+/*
+ * Routine: ipc_entry_lookup
+ * Purpose:
+ * Searches for an entry, given its name.
+ * Conditions:
+ * The space must be read or write locked throughout.
+ * The space must be active.
+ */
+
+static inline ipc_entry_t
+ipc_entry_lookup(
+ ipc_space_t space,
+ mach_port_t name)
+{
+ ipc_entry_t entry;
+
+ assert(space->is_active);
+ entry = rdxtree_lookup(&space->is_map, (rdxtree_key_t) name);
+ if (entry != IE_NULL
+ && IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE)
+ entry = NULL;
+ assert((entry == IE_NULL) || IE_BITS_TYPE(entry->ie_bits));
+ return entry;
+}
+
+/*
+ * Routine: ipc_entry_get
+ * Purpose:
+ * Tries to allocate an entry out of the space.
+ * Conditions:
+ * The space is write-locked and active throughout.
+ * An object may be locked. Will not allocate memory.
+ * Returns:
+ * KERN_SUCCESS A free entry was found.
+ * KERN_NO_SPACE No entry allocated.
+ */
+
+static inline kern_return_t
+ipc_entry_get(
+ ipc_space_t space,
+ mach_port_t *namep,
+ ipc_entry_t *entryp)
+{
+ mach_port_t new_name;
+ ipc_entry_t free_entry;
+
+ assert(space->is_active);
+
+ /* Get entry from the free list. */
+ free_entry = space->is_free_list;
+ if (free_entry == IE_NULL)
+ return KERN_NO_SPACE;
+
+ space->is_free_list = free_entry->ie_next_free;
+ space->is_free_list_size -= 1;
+
+ /*
+ * Initialize the new entry. We need only
+ * increment the generation number and clear ie_request.
+ */
+
+ {
+ mach_port_gen_t gen;
+
+ assert((free_entry->ie_bits &~ IE_BITS_GEN_MASK) == 0);
+ gen = free_entry->ie_bits + IE_BITS_GEN_ONE;
+ free_entry->ie_bits = gen;
+ free_entry->ie_request = 0;
+ new_name = MACH_PORT_MAKE(free_entry->ie_name, gen);
+ }
+
+ /*
+ * The new name can't be MACH_PORT_NULL because index
+ * is non-zero. It can't be MACH_PORT_DEAD because
+ * the table isn't allowed to grow big enough.
+ * (See comment in ipc/ipc_table.h.)
+ */
+
+ assert(MACH_PORT_VALID(new_name));
+ assert(free_entry->ie_object == IO_NULL);
+
+ space->is_size += 1;
+ *namep = new_name;
+ *entryp = free_entry;
+ return KERN_SUCCESS;
+}
+
+/*
+ * Routine: ipc_entry_dealloc
+ * Purpose:
+ * Deallocates an entry from a space.
+ * Conditions:
+ * The space must be write-locked throughout.
+ * The space must be active.
+ */
+
+static inline void
+ipc_entry_dealloc(
+ ipc_space_t space,
+ mach_port_t name,
+ ipc_entry_t entry)
+{
+ assert(space->is_active);
+ assert(entry->ie_object == IO_NULL);
+ assert(entry->ie_request == 0);
+
+ if (space->is_free_list_size < IS_FREE_LIST_SIZE_LIMIT) {
+ space->is_free_list_size += 1;
+ entry->ie_bits &= IE_BITS_GEN_MASK;
+ entry->ie_next_free = space->is_free_list;
+ space->is_free_list = entry;
+ } else {
+ rdxtree_remove(&space->is_map, (rdxtree_key_t) name);
+ ie_free(entry);
+ }
+ space->is_size -= 1;
+}
+
+/* Reverse lookups. */
+
+/* Cast a pointer to a suitable key. */
+#define KEY(X) \
+ ({ \
+ assert((((unsigned long) (X)) & 0x07) == 0); \
+ ((unsigned long long) \
+ (((unsigned long) (X) - VM_MIN_KERNEL_ADDRESS) >> 3)); \
+ })
+
+/* Insert (OBJ, ENTRY) pair into the reverse mapping. SPACE must
+ be write-locked. */
+static inline kern_return_t
+ipc_reverse_insert(ipc_space_t space,
+ ipc_object_t obj,
+ ipc_entry_t entry)
+{
+ assert(space != IS_NULL);
+ assert(obj != IO_NULL);
+ return (kern_return_t) rdxtree_insert(&space->is_reverse_map,
+ KEY(obj), entry);
+}
+
+/* Remove OBJ from the reverse mapping. SPACE must be
+ write-locked. */
+static inline ipc_entry_t
+ipc_reverse_remove(ipc_space_t space,
+ ipc_object_t obj)
+{
+ assert(space != IS_NULL);
+ assert(obj != IO_NULL);
+ return rdxtree_remove(&space->is_reverse_map, KEY(obj));
+}
+
+/* Remove all entries from the reverse mapping. SPACE must be
+ write-locked. */
+static inline void
+ipc_reverse_remove_all(ipc_space_t space)
+{
+ assert(space != IS_NULL);
+ rdxtree_remove_all(&space->is_reverse_map);
+ assert(space->is_reverse_map.height == 0);
+ assert(space->is_reverse_map.root == NULL);
+}
+
+/* Return ENTRY related to OBJ, or NULL if no such entry is found in
+ the reverse mapping. SPACE must be read-locked or
+ write-locked. */
+static inline ipc_entry_t
+ipc_reverse_lookup(ipc_space_t space,
+ ipc_object_t obj)
+{
+ assert(space != IS_NULL);
+ assert(obj != IO_NULL);
+ return rdxtree_lookup(&space->is_reverse_map, KEY(obj));
+}
+
+#undef KEY
+
#endif /* _IPC_IPC_SPACE_H_ */
diff --git a/ipc/ipc_splay.c b/ipc/ipc_splay.c
deleted file mode 100644
index 6fb5bcbc..00000000
--- a/ipc/ipc_splay.c
+++ /dev/null
@@ -1,920 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- */
-/*
- * File: ipc/ipc_splay.c
- * Author: Rich Draves
- * Date: 1989
- *
- * Primitive splay tree operations.
- */
-
-#include <mach/port.h>
-#include <kern/assert.h>
-#include <kern/macro_help.h>
-#include <ipc/ipc_entry.h>
-#include <ipc/ipc_splay.h>
-
-/*
- * Splay trees are self-adjusting binary search trees.
- * They have the following attractive properties:
- * 1) Space efficient; only two pointers per entry.
- * 2) Robust performance; amortized O(log n) per operation.
- * 3) Recursion not needed.
- * This makes them a good fall-back data structure for those
- * entries that don't fit into the lookup table.
- *
- * The paper by Sleator and Tarjan, JACM v. 32, no. 3, pp. 652-686,
- * describes the splaying operation. ipc_splay_prim_lookup
- * and ipc_splay_prim_assemble implement the top-down splay
- * described on p. 669.
- *
- * The tree is stored in an unassembled form. If ist_root is null,
- * then the tree has no entries. Otherwise, ist_name records
- * the value used for the last lookup. ist_root points to the
- * middle tree obtained from the top-down splay. ist_ltree and
- * ist_rtree point to left and right subtrees, whose entries
- * are all smaller (larger) than those in the middle tree.
- * ist_ltreep and ist_rtreep are pointers to fields in the
- * left and right subtrees. ist_ltreep points to the rchild field
- * of the largest entry in ltree, and ist_rtreep points to the
- * lchild field of the smallest entry in rtree. The pointed-to
- * fields aren't initialized. If the left (right) subtree is null,
- * then ist_ltreep (ist_rtreep) points to the ist_ltree (ist_rtree)
- * field in the splay structure itself.
- *
- * The primary advantage of the unassembled form is that repeated
- * unsuccessful lookups are efficient. In particular, an unsuccessful
- * lookup followed by an insert only requires one splaying operation.
- *
- * The traversal algorithm works via pointer inversion.
- * When descending down the tree, child pointers are reversed
- * to point back to the parent entry. When ascending,
- * the pointers are restored to their original value.
- *
- * The biggest potential problem with the splay tree implementation
- * is that the operations, even lookup, require an exclusive lock.
- * If IPC spaces are protected with exclusive locks, then
- * the splay tree doesn't require its own lock, and ist_lock/ist_unlock
- * needn't do anything. If IPC spaces are protected with read/write
- * locks then ist_lock/ist_unlock should provide exclusive access.
- *
- * If it becomes important to let lookups run in parallel,
- * or if the restructuring makes lookups too expensive, then
- * there is hope. Use a read/write lock on the splay tree.
- * Keep track of the number of entries in the tree. When doing
- * a lookup, first try a non-restructuring lookup with a read lock held,
- * with a bound (based on log of size of the tree) on the number of
- * entries to traverse. If the lookup runs up against the bound,
- * then take a write lock and do a reorganizing lookup.
- * This way, if lookups only access roughly balanced parts
- * of the tree, then lookups run in parallel and do no restructuring.
- *
- * The traversal algorithm currently requires an exclusive lock.
- * If that is a problem, the tree could be changed from an lchild/rchild
- * representation to a leftmost child/right sibling representation.
- * In conjunction with non-restructing lookups, this would let
- * lookups and traversals all run in parallel. But this representation
- * is more complicated and would slow down the operations.
- */
-
-/*
- * Boundary values to hand to ipc_splay_prim_lookup:
- */
-
-#define MACH_PORT_SMALLEST ((mach_port_t) 0)
-#define MACH_PORT_LARGEST ((mach_port_t) ~0)
-
-/*
- * Routine: ipc_splay_prim_lookup
- * Purpose:
- * Searches for the node labeled name in the splay tree.
- * Returns three nodes (treep, ltreep, rtreep) and
- * two pointers to nodes (ltreepp, rtreepp).
- *
- * ipc_splay_prim_lookup splits the supplied tree into
- * three subtrees, left, middle, and right, returned
- * in ltreep, treep, and rtreep.
- *
- * If name is present in the tree, then it is at
- * the root of the middle tree. Otherwise, the root
- * of the middle tree is the last node traversed.
- *
- * ipc_splay_prim_lookup returns a pointer into
- * the left subtree, to the rchild field of its
- * largest node, in ltreepp. It returns a pointer
- * into the right subtree, to the lchild field of its
- * smallest node, in rtreepp.
- */
-
-static void
-ipc_splay_prim_lookup(
- mach_port_t name,
- ipc_tree_entry_t tree,
- ipc_tree_entry_t *treep,
- ipc_tree_entry_t *ltreep,
- ipc_tree_entry_t **ltreepp,
- ipc_tree_entry_t *rtreep,
- ipc_tree_entry_t **rtreepp)
-{
- mach_port_t tname; /* temp name */
- ipc_tree_entry_t lchild, rchild; /* temp child pointers */
-
- assert(tree != ITE_NULL);
-
-#define link_left \
-MACRO_BEGIN \
- *ltreep = tree; \
- ltreep = &tree->ite_rchild; \
- tree = *ltreep; \
-MACRO_END
-
-#define link_right \
-MACRO_BEGIN \
- *rtreep = tree; \
- rtreep = &tree->ite_lchild; \
- tree = *rtreep; \
-MACRO_END
-
-#define rotate_left \
-MACRO_BEGIN \
- ipc_tree_entry_t temp = tree; \
- \
- tree = temp->ite_rchild; \
- temp->ite_rchild = tree->ite_lchild; \
- tree->ite_lchild = temp; \
-MACRO_END
-
-#define rotate_right \
-MACRO_BEGIN \
- ipc_tree_entry_t temp = tree; \
- \
- tree = temp->ite_lchild; \
- temp->ite_lchild = tree->ite_rchild; \
- tree->ite_rchild = temp; \
-MACRO_END
-
- while (name != (tname = tree->ite_name)) {
- if (name < tname) {
- /* descend to left */
-
- lchild = tree->ite_lchild;
- if (lchild == ITE_NULL)
- break;
- tname = lchild->ite_name;
-
- if ((name < tname) &&
- (lchild->ite_lchild != ITE_NULL))
- rotate_right;
- link_right;
- if ((name > tname) &&
- (lchild->ite_rchild != ITE_NULL))
- link_left;
- } else {
- /* descend to right */
-
- rchild = tree->ite_rchild;
- if (rchild == ITE_NULL)
- break;
- tname = rchild->ite_name;
-
- if ((name > tname) &&
- (rchild->ite_rchild != ITE_NULL))
- rotate_left;
- link_left;
- if ((name < tname) &&
- (rchild->ite_lchild != ITE_NULL))
- link_right;
- }
-
- assert(tree != ITE_NULL);
- }
-
- *treep = tree;
- *ltreepp = ltreep;
- *rtreepp = rtreep;
-
-#undef link_left
-#undef link_right
-#undef rotate_left
-#undef rotate_right
-}
-
-/*
- * Routine: ipc_splay_prim_assemble
- * Purpose:
- * Assembles the results of ipc_splay_prim_lookup
- * into a splay tree with the found node at the root.
- *
- * ltree and rtree are by-reference so storing
- * through ltreep and rtreep can change them.
- */
-
-static void
-ipc_splay_prim_assemble(
- ipc_tree_entry_t tree,
- ipc_tree_entry_t *ltree,
- ipc_tree_entry_t *ltreep,
- ipc_tree_entry_t *rtree,
- ipc_tree_entry_t *rtreep)
-{
- assert(tree != ITE_NULL);
-
- *ltreep = tree->ite_lchild;
- *rtreep = tree->ite_rchild;
-
- tree->ite_lchild = *ltree;
- tree->ite_rchild = *rtree;
-}
-
-/*
- * Routine: ipc_splay_tree_init
- * Purpose:
- * Initialize a raw splay tree for use.
- */
-
-void
-ipc_splay_tree_init(
- ipc_splay_tree_t splay)
-{
- splay->ist_root = ITE_NULL;
-}
-
-/*
- * Routine: ipc_splay_tree_pick
- * Purpose:
- * Picks and returns a random entry in a splay tree.
- * Returns FALSE if the splay tree is empty.
- */
-
-boolean_t
-ipc_splay_tree_pick(
- ipc_splay_tree_t splay,
- mach_port_t *namep,
- ipc_tree_entry_t *entryp)
-{
- ipc_tree_entry_t root;
-
- ist_lock(splay);
-
- root = splay->ist_root;
- if (root != ITE_NULL) {
- *namep = root->ite_name;
- *entryp = root;
- }
-
- ist_unlock(splay);
-
- return root != ITE_NULL;
-}
-
-/*
- * Routine: ipc_splay_tree_lookup
- * Purpose:
- * Finds an entry in a splay tree.
- * Returns ITE_NULL if not found.
- */
-
-ipc_tree_entry_t
-ipc_splay_tree_lookup(
- ipc_splay_tree_t splay,
- mach_port_t name)
-{
- ipc_tree_entry_t root;
-
- ist_lock(splay);
-
- root = splay->ist_root;
- if (root != ITE_NULL) {
- if (splay->ist_name != name) {
- ipc_splay_prim_assemble(root,
- &splay->ist_ltree, splay->ist_ltreep,
- &splay->ist_rtree, splay->ist_rtreep);
- ipc_splay_prim_lookup(name, root, &root,
- &splay->ist_ltree, &splay->ist_ltreep,
- &splay->ist_rtree, &splay->ist_rtreep);
- splay->ist_name = name;
- splay->ist_root = root;
- }
-
- if (name != root->ite_name)
- root = ITE_NULL;
- }
-
- ist_unlock(splay);
-
- return root;
-}
-
-/*
- * Routine: ipc_splay_tree_insert
- * Purpose:
- * Inserts a new entry into a splay tree.
- * The caller supplies a new entry.
- * The name can't already be present in the tree.
- */
-
-void
-ipc_splay_tree_insert(
- ipc_splay_tree_t splay,
- mach_port_t name,
- ipc_tree_entry_t entry)
-{
- ipc_tree_entry_t root;
-
- assert(entry != ITE_NULL);
-
- ist_lock(splay);
-
- root = splay->ist_root;
- if (root == ITE_NULL) {
- entry->ite_lchild = ITE_NULL;
- entry->ite_rchild = ITE_NULL;
- } else {
- if (splay->ist_name != name) {
- ipc_splay_prim_assemble(root,
- &splay->ist_ltree, splay->ist_ltreep,
- &splay->ist_rtree, splay->ist_rtreep);
- ipc_splay_prim_lookup(name, root, &root,
- &splay->ist_ltree, &splay->ist_ltreep,
- &splay->ist_rtree, &splay->ist_rtreep);
- }
-
- assert(root->ite_name != name);
-
- if (name < root->ite_name) {
- assert(root->ite_lchild == ITE_NULL);
-
- *splay->ist_ltreep = ITE_NULL;
- *splay->ist_rtreep = root;
- } else {
- assert(root->ite_rchild == ITE_NULL);
-
- *splay->ist_ltreep = root;
- *splay->ist_rtreep = ITE_NULL;
- }
-
- entry->ite_lchild = splay->ist_ltree;
- entry->ite_rchild = splay->ist_rtree;
- }
-
- entry->ite_name = name;
- splay->ist_root = entry;
- splay->ist_name = name;
- splay->ist_ltreep = &splay->ist_ltree;
- splay->ist_rtreep = &splay->ist_rtree;
-
- ist_unlock(splay);
-}
-
-/*
- * Routine: ipc_splay_tree_delete
- * Purpose:
- * Deletes an entry from a splay tree.
- * The name must be present in the tree.
- * Frees the entry.
- *
- * The "entry" argument isn't currently used.
- * Other implementations might want it, though.
- */
-
-void
-ipc_splay_tree_delete(
- ipc_splay_tree_t splay,
- mach_port_t name,
- ipc_tree_entry_t entry)
-{
- ipc_tree_entry_t root, saved;
-
- ist_lock(splay);
-
- root = splay->ist_root;
- assert(root != ITE_NULL);
-
- if (splay->ist_name != name) {
- ipc_splay_prim_assemble(root,
- &splay->ist_ltree, splay->ist_ltreep,
- &splay->ist_rtree, splay->ist_rtreep);
- ipc_splay_prim_lookup(name, root, &root,
- &splay->ist_ltree, &splay->ist_ltreep,
- &splay->ist_rtree, &splay->ist_rtreep);
- }
-
- assert(root->ite_name == name);
- assert(root == entry);
-
- *splay->ist_ltreep = root->ite_lchild;
- *splay->ist_rtreep = root->ite_rchild;
- ite_free(root);
-
- root = splay->ist_ltree;
- saved = splay->ist_rtree;
-
- if (root == ITE_NULL)
- root = saved;
- else if (saved != ITE_NULL) {
- /*
- * Find the largest node in the left subtree, and splay it
- * to the root. Then add the saved right subtree.
- */
-
- ipc_splay_prim_lookup(MACH_PORT_LARGEST, root, &root,
- &splay->ist_ltree, &splay->ist_ltreep,
- &splay->ist_rtree, &splay->ist_rtreep);
- ipc_splay_prim_assemble(root,
- &splay->ist_ltree, splay->ist_ltreep,
- &splay->ist_rtree, splay->ist_rtreep);
-
- assert(root->ite_rchild == ITE_NULL);
- root->ite_rchild = saved;
- }
-
- splay->ist_root = root;
- if (root != ITE_NULL) {
- splay->ist_name = root->ite_name;
- splay->ist_ltreep = &splay->ist_ltree;
- splay->ist_rtreep = &splay->ist_rtree;
- }
-
- ist_unlock(splay);
-}
-
-/*
- * Routine: ipc_splay_tree_split
- * Purpose:
- * Split a splay tree. Puts all entries smaller than "name"
- * into a new tree, "small".
- *
- * Doesn't do locking on "small", because nobody else
- * should be fiddling with the uninitialized tree.
- */
-
-void
-ipc_splay_tree_split(
- ipc_splay_tree_t splay,
- mach_port_t name,
- ipc_splay_tree_t small)
-{
- ipc_tree_entry_t root;
-
- ipc_splay_tree_init(small);
-
- ist_lock(splay);
-
- root = splay->ist_root;
- if (root != ITE_NULL) {
- /* lookup name, to get it (or last traversed) to the top */
-
- if (splay->ist_name != name) {
- ipc_splay_prim_assemble(root,
- &splay->ist_ltree, splay->ist_ltreep,
- &splay->ist_rtree, splay->ist_rtreep);
- ipc_splay_prim_lookup(name, root, &root,
- &splay->ist_ltree, &splay->ist_ltreep,
- &splay->ist_rtree, &splay->ist_rtreep);
- }
-
- if (root->ite_name < name) {
- /* root goes into small */
-
- *splay->ist_ltreep = root->ite_lchild;
- *splay->ist_rtreep = ITE_NULL;
- root->ite_lchild = splay->ist_ltree;
- assert(root->ite_rchild == ITE_NULL);
-
- small->ist_root = root;
- small->ist_name = root->ite_name;
- small->ist_ltreep = &small->ist_ltree;
- small->ist_rtreep = &small->ist_rtree;
-
- /* rtree goes into splay */
-
- root = splay->ist_rtree;
- splay->ist_root = root;
- if (root != ITE_NULL) {
- splay->ist_name = root->ite_name;
- splay->ist_ltreep = &splay->ist_ltree;
- splay->ist_rtreep = &splay->ist_rtree;
- }
- } else {
- /* root stays in splay */
-
- *splay->ist_ltreep = root->ite_lchild;
- root->ite_lchild = ITE_NULL;
-
- splay->ist_root = root;
- splay->ist_name = name;
- splay->ist_ltreep = &splay->ist_ltree;
-
- /* ltree goes into small */
-
- root = splay->ist_ltree;
- small->ist_root = root;
- if (root != ITE_NULL) {
- small->ist_name = root->ite_name;
- small->ist_ltreep = &small->ist_ltree;
- small->ist_rtreep = &small->ist_rtree;
- }
- }
- }
-
- ist_unlock(splay);
-}
-
-/*
- * Routine: ipc_splay_tree_join
- * Purpose:
- * Joins two splay trees. Merges the entries in "small",
- * which must all be smaller than the entries in "splay",
- * into "splay".
- */
-
-void
-ipc_splay_tree_join(
- ipc_splay_tree_t splay,
- ipc_splay_tree_t small)
-{
- ipc_tree_entry_t sroot;
-
- /* pull entries out of small */
-
- ist_lock(small);
-
- sroot = small->ist_root;
- if (sroot != ITE_NULL) {
- ipc_splay_prim_assemble(sroot,
- &small->ist_ltree, small->ist_ltreep,
- &small->ist_rtree, small->ist_rtreep);
- small->ist_root = ITE_NULL;
- }
-
- ist_unlock(small);
-
- /* put entries, if any, into splay */
-
- if (sroot != ITE_NULL) {
- ipc_tree_entry_t root;
-
- ist_lock(splay);
-
- root = splay->ist_root;
- if (root == ITE_NULL) {
- root = sroot;
- } else {
- /* get smallest entry in splay tree to top */
-
- if (splay->ist_name != MACH_PORT_SMALLEST) {
- ipc_splay_prim_assemble(root,
- &splay->ist_ltree, splay->ist_ltreep,
- &splay->ist_rtree, splay->ist_rtreep);
- ipc_splay_prim_lookup(MACH_PORT_SMALLEST,
- root, &root,
- &splay->ist_ltree, &splay->ist_ltreep,
- &splay->ist_rtree, &splay->ist_rtreep);
- }
-
- ipc_splay_prim_assemble(root,
- &splay->ist_ltree, splay->ist_ltreep,
- &splay->ist_rtree, splay->ist_rtreep);
-
- assert(root->ite_lchild == ITE_NULL);
- assert(sroot->ite_name < root->ite_name);
- root->ite_lchild = sroot;
- }
-
- splay->ist_root = root;
- splay->ist_name = root->ite_name;
- splay->ist_ltreep = &splay->ist_ltree;
- splay->ist_rtreep = &splay->ist_rtree;
-
- ist_unlock(splay);
- }
-}
-
-/*
- * Routine: ipc_splay_tree_bounds
- * Purpose:
- * Given a name, returns the largest value present
- * in the tree that is smaller than or equal to the name,
- * or ~0 if no such value exists. Similarly, returns
- * the smallest value present that is greater than or
- * equal to the name, or 0 if no such value exists.
- *
- * Hence, if
- * lower = upper, then lower = name = upper
- * and name is present in the tree
- * lower = ~0 and upper = 0,
- * then the tree is empty
- * lower = ~0 and upper > 0, then name < upper
- * and upper is smallest value in tree
- * lower < ~0 and upper = 0, then lower < name
- * and lower is largest value in tree
- * lower < ~0 and upper > 0, then lower < name < upper
- * and they are tight bounds on name
- *
- * (Note MACH_PORT_SMALLEST = 0 and MACH_PORT_LARGEST = ~0.)
- */
-
-void
-ipc_splay_tree_bounds(
- ipc_splay_tree_t splay,
- mach_port_t name,
- mach_port_t *lowerp,
- mach_port_t *upperp)
-{
- ipc_tree_entry_t root;
-
- ist_lock(splay);
-
- root = splay->ist_root;
- if (root == ITE_NULL) {
- *lowerp = MACH_PORT_LARGEST;
- *upperp = MACH_PORT_SMALLEST;
- } else {
- mach_port_t rname;
-
- if (splay->ist_name != name) {
- ipc_splay_prim_assemble(root,
- &splay->ist_ltree, splay->ist_ltreep,
- &splay->ist_rtree, splay->ist_rtreep);
- ipc_splay_prim_lookup(name, root, &root,
- &splay->ist_ltree, &splay->ist_ltreep,
- &splay->ist_rtree, &splay->ist_rtreep);
- splay->ist_name = name;
- splay->ist_root = root;
- }
-
- rname = root->ite_name;
-
- /*
- * OK, it's a hack. We convert the ltreep and rtreep
- * pointers back into real entry pointers,
- * so we can pick the names out of the entries.
- */
-
- if (rname <= name)
- *lowerp = rname;
- else if (splay->ist_ltreep == &splay->ist_ltree)
- *lowerp = MACH_PORT_LARGEST;
- else {
- ipc_tree_entry_t entry;
-
- entry = (ipc_tree_entry_t)
- ((char *)splay->ist_ltreep -
- ((char *)&root->ite_rchild -
- (char *)root));
- *lowerp = entry->ite_name;
- }
-
- if (rname >= name)
- *upperp = rname;
- else if (splay->ist_rtreep == &splay->ist_rtree)
- *upperp = MACH_PORT_SMALLEST;
- else {
- ipc_tree_entry_t entry;
-
- entry = (ipc_tree_entry_t)
- ((char *)splay->ist_rtreep -
- ((char *)&root->ite_lchild -
- (char *)root));
- *upperp = entry->ite_name;
- }
- }
-
- ist_unlock(splay);
-}
-
-/*
- * Routine: ipc_splay_traverse_start
- * Routine: ipc_splay_traverse_next
- * Routine: ipc_splay_traverse_finish
- * Purpose:
- * Perform a symmetric order traversal of a splay tree.
- * Usage:
- * for (entry = ipc_splay_traverse_start(splay);
- * entry != ITE_NULL;
- * entry = ipc_splay_traverse_next(splay, delete)) {
- * do something with entry
- * }
- * ipc_splay_traverse_finish(splay);
- *
- * If "delete" is TRUE, then the current entry
- * is removed from the tree and deallocated.
- *
- * During the traversal, the splay tree is locked.
- */
-
-ipc_tree_entry_t
-ipc_splay_traverse_start(
- ipc_splay_tree_t splay)
-{
- ipc_tree_entry_t current, parent;
-
- ist_lock(splay);
-
- current = splay->ist_root;
- if (current != ITE_NULL) {
- ipc_splay_prim_assemble(current,
- &splay->ist_ltree, splay->ist_ltreep,
- &splay->ist_rtree, splay->ist_rtreep);
-
- parent = ITE_NULL;
-
- while (current->ite_lchild != ITE_NULL) {
- ipc_tree_entry_t next;
-
- next = current->ite_lchild;
- current->ite_lchild = parent;
- parent = current;
- current = next;
- }
-
- splay->ist_ltree = current;
- splay->ist_rtree = parent;
- }
-
- return current;
-}
-
-ipc_tree_entry_t
-ipc_splay_traverse_next(
- ipc_splay_tree_t splay,
- boolean_t delete)
-{
- ipc_tree_entry_t current, parent;
-
- /* pick up where traverse_entry left off */
-
- current = splay->ist_ltree;
- parent = splay->ist_rtree;
- assert(current != ITE_NULL);
-
- if (!delete)
- goto traverse_right;
-
- /* we must delete current and patch the tree */
-
- if (current->ite_lchild == ITE_NULL) {
- if (current->ite_rchild == ITE_NULL) {
- /* like traverse_back, but with deletion */
-
- if (parent == ITE_NULL) {
- ite_free(current);
-
- splay->ist_root = ITE_NULL;
- return ITE_NULL;
- }
-
- if (current->ite_name < parent->ite_name) {
- ite_free(current);
-
- current = parent;
- parent = current->ite_lchild;
- current->ite_lchild = ITE_NULL;
- goto traverse_entry;
- } else {
- ite_free(current);
-
- current = parent;
- parent = current->ite_rchild;
- current->ite_rchild = ITE_NULL;
- goto traverse_back;
- }
- } else {
- ipc_tree_entry_t prev;
-
- prev = current;
- current = current->ite_rchild;
- ite_free(prev);
- goto traverse_left;
- }
- } else {
- if (current->ite_rchild == ITE_NULL) {
- ipc_tree_entry_t prev;
-
- prev = current;
- current = current->ite_lchild;
- ite_free(prev);
- goto traverse_back;
- } else {
- ipc_tree_entry_t prev;
- ipc_tree_entry_t ltree, rtree;
- ipc_tree_entry_t *ltreep, *rtreep;
-
- /* replace current with largest of left children */
-
- prev = current;
- ipc_splay_prim_lookup(MACH_PORT_LARGEST,
- current->ite_lchild, &current,
- &ltree, &ltreep, &rtree, &rtreep);
- ipc_splay_prim_assemble(current,
- &ltree, ltreep, &rtree, rtreep);
-
- assert(current->ite_rchild == ITE_NULL);
- current->ite_rchild = prev->ite_rchild;
- ite_free(prev);
- goto traverse_right;
- }
- }
- /*NOTREACHED*/
-
- /*
- * A state machine: for each entry, we
- * 1) traverse left subtree
- * 2) traverse the entry
- * 3) traverse right subtree
- * 4) traverse back to parent
- */
-
- traverse_left:
- if (current->ite_lchild != ITE_NULL) {
- ipc_tree_entry_t next;
-
- next = current->ite_lchild;
- current->ite_lchild = parent;
- parent = current;
- current = next;
- goto traverse_left;
- }
-
- traverse_entry:
- splay->ist_ltree = current;
- splay->ist_rtree = parent;
- return current;
-
- traverse_right:
- if (current->ite_rchild != ITE_NULL) {
- ipc_tree_entry_t next;
-
- next = current->ite_rchild;
- current->ite_rchild = parent;
- parent = current;
- current = next;
- goto traverse_left;
- }
-
- traverse_back:
- if (parent == ITE_NULL) {
- splay->ist_root = current;
- return ITE_NULL;
- }
-
- if (current->ite_name < parent->ite_name) {
- ipc_tree_entry_t prev;
-
- prev = current;
- current = parent;
- parent = current->ite_lchild;
- current->ite_lchild = prev;
- goto traverse_entry;
- } else {
- ipc_tree_entry_t prev;
-
- prev = current;
- current = parent;
- parent = current->ite_rchild;
- current->ite_rchild = prev;
- goto traverse_back;
- }
-}
-
-void
-ipc_splay_traverse_finish(
- ipc_splay_tree_t splay)
-{
- ipc_tree_entry_t root;
-
- root = splay->ist_root;
- if (root != ITE_NULL) {
- splay->ist_name = root->ite_name;
- splay->ist_ltreep = &splay->ist_ltree;
- splay->ist_rtreep = &splay->ist_rtree;
- }
-
- ist_unlock(splay);
-}
-
diff --git a/ipc/ipc_splay.h b/ipc/ipc_splay.h
deleted file mode 100644
index d3316ef8..00000000
--- a/ipc/ipc_splay.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- */
-/*
- * File: ipc/ipc_splay.h
- * Author: Rich Draves
- * Date: 1989
- *
- * Declarations of primitive splay tree operations.
- */
-
-#ifndef _IPC_IPC_SPLAY_H_
-#define _IPC_IPC_SPLAY_H_
-
-#include <mach/port.h>
-#include <kern/assert.h>
-#include <kern/macro_help.h>
-#include <ipc/ipc_entry.h>
-
-typedef struct ipc_splay_tree {
- mach_port_t ist_name; /* name used in last lookup */
- ipc_tree_entry_t ist_root; /* root of middle tree */
- ipc_tree_entry_t ist_ltree; /* root of left tree */
- ipc_tree_entry_t *ist_ltreep; /* pointer into left tree */
- ipc_tree_entry_t ist_rtree; /* root of right tree */
- ipc_tree_entry_t *ist_rtreep; /* pointer into right tree */
-} *ipc_splay_tree_t;
-
-#define ist_lock(splay) /* no locking */
-#define ist_unlock(splay) /* no locking */
-
-/* Initialize a raw splay tree */
-extern void ipc_splay_tree_init(
- ipc_splay_tree_t splay);
-
-/* Pick a random entry in a splay tree */
-extern boolean_t ipc_splay_tree_pick(
- ipc_splay_tree_t splay,
- mach_port_t *namep,
- ipc_tree_entry_t *entryp);
-
-/* Find an entry in a splay tree */
-extern ipc_tree_entry_t ipc_splay_tree_lookup(
- ipc_splay_tree_t splay,
- mach_port_t name);
-
-/* Insert a new entry into a splay tree */
-extern void ipc_splay_tree_insert(
- ipc_splay_tree_t splay,
- mach_port_t name,
- ipc_tree_entry_t entry);
-
-/* Delete an entry from a splay tree */
-extern void ipc_splay_tree_delete(
- ipc_splay_tree_t splay,
- mach_port_t name,
- ipc_tree_entry_t entry);
-
-/* Split a splay tree */
-extern void ipc_splay_tree_split(
- ipc_splay_tree_t splay,
- mach_port_t name,
- ipc_splay_tree_t entry);
-
-/* Join two splay trees */
-extern void ipc_splay_tree_join(
- ipc_splay_tree_t splay,
- ipc_splay_tree_t small);
-
-/* Do a bounded splay tree lookup */
-extern void ipc_splay_tree_bounds(
- ipc_splay_tree_t splay,
- mach_port_t name,
- mach_port_t *lowerp,
- mach_port_t *upperp);
-
-/* Initialize a symmetric order traversal of a splay tree */
-extern ipc_tree_entry_t ipc_splay_traverse_start(
- ipc_splay_tree_t splay);
-
-/* Return the next entry in a symmetric order traversal of a splay tree */
-extern ipc_tree_entry_t ipc_splay_traverse_next(
- ipc_splay_tree_t splay,
- boolean_t delete);
-
-/* Terminate a symmetric order traversal of a splay tree */
-extern void ipc_splay_traverse_finish(
- ipc_splay_tree_t splay);
-
-#endif /* _IPC_IPC_SPLAY_H_ */
diff --git a/ipc/ipc_table.c b/ipc/ipc_table.c
index cbb6a894..0f8592a3 100644
--- a/ipc/ipc_table.c
+++ b/ipc/ipc_table.c
@@ -42,20 +42,8 @@
#include <kern/slab.h>
#include <vm/vm_kern.h>
-/*
- * Forward declarations
- */
-void ipc_table_fill(
- ipc_table_size_t its,
- unsigned int num,
- unsigned int min,
- vm_size_t elemsize);
-
-ipc_table_size_t ipc_table_entries;
-unsigned int ipc_table_entries_size = 512;
-
ipc_table_size_t ipc_table_dnrequests;
-unsigned int ipc_table_dnrequests_size = 64;
+const unsigned int ipc_table_dnrequests_size = 64;
void
ipc_table_fill(
@@ -101,20 +89,6 @@ ipc_table_fill(
void
ipc_table_init(void)
{
- ipc_table_entries = (ipc_table_size_t)
- kalloc(sizeof(struct ipc_table_size) *
- ipc_table_entries_size);
- assert(ipc_table_entries != ITS_NULL);
-
- ipc_table_fill(ipc_table_entries, ipc_table_entries_size - 1,
- 4, sizeof(struct ipc_entry));
-
- /* the last two elements should have the same size */
-
- ipc_table_entries[ipc_table_entries_size - 1].its_size =
- ipc_table_entries[ipc_table_entries_size - 2].its_size;
-
-
ipc_table_dnrequests = (ipc_table_size_t)
kalloc(sizeof(struct ipc_table_size) *
ipc_table_dnrequests_size);
@@ -140,42 +114,7 @@ vm_offset_t
ipc_table_alloc(
vm_size_t size)
{
- vm_offset_t table;
-
- if (size < PAGE_SIZE)
- table = kalloc(size);
- else
- if (kmem_alloc(kmem_map, &table, size) != KERN_SUCCESS)
- table = 0;
-
- return table;
-}
-
-/*
- * Routine: ipc_table_realloc
- * Purpose:
- * Reallocate a big table.
- *
- * The new table remaps the old table,
- * so copying is not necessary.
- * Conditions:
- * Only works for page-size or bigger tables.
- * May block.
- */
-
-vm_offset_t
-ipc_table_realloc(
- vm_size_t old_size,
- vm_offset_t old_table,
- vm_size_t new_size)
-{
- vm_offset_t new_table;
-
- if (kmem_realloc(kmem_map, old_table, old_size,
- &new_table, new_size) != KERN_SUCCESS)
- new_table = 0;
-
- return new_table;
+ return kalloc(size);
}
/*
@@ -192,8 +131,5 @@ ipc_table_free(
vm_size_t size,
vm_offset_t table)
{
- if (size < PAGE_SIZE)
- kfree(table, size);
- else
- kmem_free(kmem_map, table, size);
+ kfree(table, size);
}
diff --git a/ipc/ipc_table.h b/ipc/ipc_table.h
index 695adae4..7968e6bb 100644
--- a/ipc/ipc_table.h
+++ b/ipc/ipc_table.h
@@ -30,8 +30,8 @@
* Author: Rich Draves
* Date: 1989
*
- * Definitions for tables, used for IPC capabilities (ipc_entry_t)
- * and dead-name requests (ipc_port_request_t).
+ * Definitions for tables, used for dead-name requests
+ * (ipc_port_request_t).
*/
#ifndef _IPC_IPC_TABLE_H_
@@ -41,20 +41,7 @@
#include <mach/vm_param.h>
/*
- * The is_table_next field of an ipc_space_t points to
- * an ipc_table_size structure. These structures must
- * be elements of an array, ipc_table_entries.
- *
- * The array must end with two elements with the same its_size value.
- * Except for the terminating element, the its_size values must
- * be strictly increasing. The largest (last) its_size value
- * must be less than or equal to MACH_PORT_INDEX(MACH_PORT_DEAD).
- * This ensures that
- * 1) MACH_PORT_INDEX(MACH_PORT_DEAD) isn't a valid index
- * in the table, so ipc_entry_get won't allocate it.
- * 2) MACH_PORT_MAKE(index+1, 0) and MAKE_PORT_MAKE(size, 0)
- * won't ever overflow.
- *
+ * Every its_size value must must be a power of two.
*
* The ipr_size field of the first element in a table of
* dead-name requests (ipc_port_request_t) points to the
@@ -63,8 +50,6 @@
* with an element with zero its_size, and except for this last
* element, the its_size values must be strictly increasing.
*
- * The is_table_next field points to the ipc_table_size structure
- * for the next larger size of table, not the one currently in use.
* The ipr_size field points to the currently used ipc_table_size.
*/
@@ -77,53 +62,31 @@ typedef struct ipc_table_size {
#define ITS_NULL ((ipc_table_size_t) 0)
-extern ipc_table_size_t ipc_table_entries;
extern ipc_table_size_t ipc_table_dnrequests;
extern void
ipc_table_init(void);
/*
- * Note that ipc_table_alloc, ipc_table_realloc, and ipc_table_free
- * all potentially use the VM system. Hence simple locks can't
- * be held across them.
- *
- * We can't use a copying realloc, because the realloc happens
- * with the data unlocked. ipc_table_realloc remaps the data,
- * so it is OK.
+ * Note that ipc_table_alloc, and ipc_table_free all potentially
+ * use the VM system. Hence simple locks can't be held across
+ * them.
*/
/* Allocate a table */
extern vm_offset_t ipc_table_alloc(
vm_size_t size);
-/* Reallocate a big table */
-extern vm_offset_t ipc_table_realloc(
- vm_size_t old_size,
- vm_offset_t old_table,
- vm_size_t new_size);
-
/* Free a table */
extern void ipc_table_free(
vm_size_t size,
vm_offset_t table);
-#define it_entries_alloc(its) \
- ((ipc_entry_t) \
- ipc_table_alloc((its)->its_size * sizeof(struct ipc_entry)))
-
-#define it_entries_reallocable(its) \
- (((its)->its_size * sizeof(struct ipc_entry)) >= PAGE_SIZE)
-
-#define it_entries_realloc(its, table, nits) \
- ((ipc_entry_t) \
- ipc_table_realloc((its)->its_size * sizeof(struct ipc_entry), \
- (vm_offset_t)(table), \
- (nits)->its_size * sizeof(struct ipc_entry)))
-
-#define it_entries_free(its, table) \
- ipc_table_free((its)->its_size * sizeof(struct ipc_entry), \
- (vm_offset_t)(table))
+void ipc_table_fill(
+ ipc_table_size_t its,
+ unsigned int num,
+ unsigned int min,
+ vm_size_t elemsize);
#define it_dnrequests_alloc(its) \
((ipc_port_request_t) \
diff --git a/ipc/ipc_thread.h b/ipc/ipc_thread.h
index fbeea46a..008ab4a9 100644
--- a/ipc/ipc_thread.h
+++ b/ipc/ipc_thread.h
@@ -75,7 +75,7 @@ MACRO_END
#define ipc_thread_rmqueue_first_macro(queue, thread) \
MACRO_BEGIN \
- register ipc_thread_t _next; \
+ ipc_thread_t _next; \
\
assert((queue)->ithq_base == (thread)); \
\
@@ -84,7 +84,7 @@ MACRO_BEGIN \
assert((thread)->ith_prev == (thread)); \
(queue)->ithq_base = ITH_NULL; \
} else { \
- register ipc_thread_t _prev = (thread)->ith_prev; \
+ ipc_thread_t _prev = (thread)->ith_prev; \
\
(queue)->ithq_base = _next; \
_next->ith_prev = _prev; \
@@ -95,14 +95,14 @@ MACRO_END
#define ipc_thread_enqueue_macro(queue, thread) \
MACRO_BEGIN \
- register ipc_thread_t _first = (queue)->ithq_base; \
+ ipc_thread_t _first = (queue)->ithq_base; \
\
if (_first == ITH_NULL) { \
(queue)->ithq_base = (thread); \
assert((thread)->ith_next == (thread)); \
assert((thread)->ith_prev == (thread)); \
} else { \
- register ipc_thread_t _last = _first->ith_prev; \
+ ipc_thread_t _last = _first->ith_prev; \
\
(thread)->ith_next = _first; \
(thread)->ith_prev = _last; \
diff --git a/ipc/mach_debug.c b/ipc/mach_debug.c
index 28dd6935..efb07a4f 100644
--- a/ipc/mach_debug.c
+++ b/ipc/mach_debug.c
@@ -46,7 +46,6 @@
#include <vm/vm_kern.h>
#include <ipc/ipc_space.h>
#include <ipc/ipc_port.h>
-#include <ipc/ipc_hash.h>
#include <ipc/ipc_marequest.h>
#include <ipc/ipc_table.h>
#include <ipc/ipc_right.h>
@@ -94,85 +93,6 @@ mach_port_get_srights(
}
/*
- * Routine: host_ipc_hash_info
- * Purpose:
- * Return information about the global reverse hash table.
- * Conditions:
- * Nothing locked. Obeys CountInOut protocol.
- * Returns:
- * KERN_SUCCESS Returned information.
- * KERN_INVALID_HOST The host is null.
- * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
- */
-
-kern_return_t
-host_ipc_hash_info(
- host_t host,
- hash_info_bucket_array_t *infop,
- mach_msg_type_number_t *countp)
-{
- vm_offset_t addr;
- vm_size_t size = 0; /* Suppress gcc warning */
- hash_info_bucket_t *info;
- unsigned int potential, actual;
- kern_return_t kr;
-
- if (host == HOST_NULL)
- return KERN_INVALID_HOST;
-
- /* start with in-line data */
-
- info = *infop;
- potential = *countp;
-
- for (;;) {
- actual = ipc_hash_info(info, potential);
- if (actual <= potential)
- break;
-
- /* allocate more memory */
-
- if (info != *infop)
- kmem_free(ipc_kernel_map, addr, size);
-
- size = round_page(actual * sizeof *info);
- kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
- if (kr != KERN_SUCCESS)
- return KERN_RESOURCE_SHORTAGE;
-
- info = (hash_info_bucket_t *) addr;
- potential = size/sizeof *info;
- }
-
- if (info == *infop) {
- /* data fit in-line; nothing to deallocate */
-
- *countp = actual;
- } else if (actual == 0) {
- kmem_free(ipc_kernel_map, addr, size);
-
- *countp = 0;
- } else {
- vm_map_copy_t copy;
- vm_size_t used;
-
- used = round_page(actual * sizeof *info);
-
- if (used != size)
- kmem_free(ipc_kernel_map, addr + used, size - used);
-
- kr = vm_map_copyin(ipc_kernel_map, addr, used,
- TRUE, &copy);
- assert(kr == KERN_SUCCESS);
-
- *infop = (hash_info_bucket_t *) copy;
- *countp = actual;
- }
-
- return KERN_SUCCESS;
-}
-
-/*
* Routine: host_ipc_marequest_info
* Purpose:
* Return information about the marequest hash table.
@@ -185,11 +105,11 @@ host_ipc_hash_info(
*/
kern_return_t
-host_ipc_marequest_info(host, maxp, infop, countp)
- host_t host;
- unsigned int *maxp;
- hash_info_bucket_array_t *infop;
- unsigned int *countp;
+host_ipc_marequest_info(
+ host_t host,
+ unsigned int *maxp,
+ hash_info_bucket_array_t *infop,
+ unsigned int *countp)
{
vm_offset_t addr;
vm_size_t size = 0; /* '=0' to shut up lint */
@@ -253,251 +173,6 @@ host_ipc_marequest_info(host, maxp, infop, countp)
}
/*
- * Routine: mach_port_space_info
- * Purpose:
- * Returns information about an IPC space.
- * Conditions:
- * Nothing locked. Obeys CountInOut protocol.
- * Returns:
- * KERN_SUCCESS Returned information.
- * KERN_INVALID_TASK The space is null.
- * KERN_INVALID_TASK The space is dead.
- * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
- */
-
-kern_return_t
-mach_port_space_info(
- ipc_space_t space,
- ipc_info_space_t *infop,
- ipc_info_name_array_t *tablep,
- mach_msg_type_number_t *tableCntp,
- ipc_info_tree_name_array_t *treep,
- mach_msg_type_number_t *treeCntp)
-{
- ipc_info_name_t *table_info;
- unsigned int table_potential, table_actual;
- vm_offset_t table_addr;
- vm_size_t table_size = 0; /* Suppress gcc warning */
- ipc_info_tree_name_t *tree_info;
- unsigned int tree_potential, tree_actual;
- vm_offset_t tree_addr;
- vm_size_t tree_size = 0; /* Suppress gcc warning */
- ipc_tree_entry_t tentry;
- ipc_entry_t table;
- ipc_entry_num_t tsize;
- mach_port_index_t index;
- kern_return_t kr;
-
- if (space == IS_NULL)
- return KERN_INVALID_TASK;
-
- /* start with in-line memory */
-
- table_info = *tablep;
- table_potential = *tableCntp;
- tree_info = *treep;
- tree_potential = *treeCntp;
-
- for (;;) {
- is_read_lock(space);
- if (!space->is_active) {
- is_read_unlock(space);
- if (table_info != *tablep)
- kmem_free(ipc_kernel_map,
- table_addr, table_size);
- if (tree_info != *treep)
- kmem_free(ipc_kernel_map,
- tree_addr, tree_size);
- return KERN_INVALID_TASK;
- }
-
- table_actual = space->is_table_size;
- tree_actual = space->is_tree_total;
-
- if ((table_actual <= table_potential) &&
- (tree_actual <= tree_potential))
- break;
-
- is_read_unlock(space);
-
- if (table_actual > table_potential) {
- if (table_info != *tablep)
- kmem_free(ipc_kernel_map,
- table_addr, table_size);
-
- table_size = round_page(table_actual *
- sizeof *table_info);
- kr = kmem_alloc(ipc_kernel_map,
- &table_addr, table_size);
- if (kr != KERN_SUCCESS) {
- if (tree_info != *treep)
- kmem_free(ipc_kernel_map,
- tree_addr, tree_size);
-
- return KERN_RESOURCE_SHORTAGE;
- }
-
- table_info = (ipc_info_name_t *) table_addr;
- table_potential = table_size/sizeof *table_info;
- }
-
- if (tree_actual > tree_potential) {
- if (tree_info != *treep)
- kmem_free(ipc_kernel_map,
- tree_addr, tree_size);
-
- tree_size = round_page(tree_actual *
- sizeof *tree_info);
- kr = kmem_alloc(ipc_kernel_map,
- &tree_addr, tree_size);
- if (kr != KERN_SUCCESS) {
- if (table_info != *tablep)
- kmem_free(ipc_kernel_map,
- table_addr, table_size);
-
- return KERN_RESOURCE_SHORTAGE;
- }
-
- tree_info = (ipc_info_tree_name_t *) tree_addr;
- tree_potential = tree_size/sizeof *tree_info;
- }
- }
- /* space is read-locked and active; we have enough wired memory */
-
- infop->iis_genno_mask = MACH_PORT_NGEN(MACH_PORT_DEAD);
- infop->iis_table_size = space->is_table_size;
- infop->iis_table_next = space->is_table_next->its_size;
- infop->iis_tree_size = space->is_tree_total;
- infop->iis_tree_small = space->is_tree_small;
- infop->iis_tree_hash = space->is_tree_hash;
-
- table = space->is_table;
- tsize = space->is_table_size;
-
- for (index = 0; index < tsize; index++) {
- ipc_info_name_t *iin = &table_info[index];
- ipc_entry_t entry = &table[index];
- ipc_entry_bits_t bits = entry->ie_bits;
-
- iin->iin_name = MACH_PORT_MAKEB(index, bits);
- iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
- iin->iin_compat = FALSE;
- iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
- iin->iin_type = IE_BITS_TYPE(bits);
- iin->iin_urefs = IE_BITS_UREFS(bits);
- iin->iin_object = (vm_offset_t) entry->ie_object;
- iin->iin_next = entry->ie_next;
- iin->iin_hash = entry->ie_index;
- }
-
- for (tentry = ipc_splay_traverse_start(&space->is_tree), index = 0;
- tentry != ITE_NULL;
- tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
- ipc_info_tree_name_t *iitn = &tree_info[index++];
- ipc_info_name_t *iin = &iitn->iitn_name;
- ipc_entry_t entry = &tentry->ite_entry;
- ipc_entry_bits_t bits = entry->ie_bits;
-
- assert(IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE);
-
- iin->iin_name = tentry->ite_name;
- iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
- iin->iin_compat = FALSE;
- iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
- iin->iin_type = IE_BITS_TYPE(bits);
- iin->iin_urefs = IE_BITS_UREFS(bits);
- iin->iin_object = (vm_offset_t) entry->ie_object;
- iin->iin_next = entry->ie_next;
- iin->iin_hash = entry->ie_index;
-
- if (tentry->ite_lchild == ITE_NULL)
- iitn->iitn_lchild = MACH_PORT_NULL;
- else
- iitn->iitn_lchild = tentry->ite_lchild->ite_name;
-
- if (tentry->ite_rchild == ITE_NULL)
- iitn->iitn_rchild = MACH_PORT_NULL;
- else
- iitn->iitn_rchild = tentry->ite_rchild->ite_name;
-
- }
- ipc_splay_traverse_finish(&space->is_tree);
- is_read_unlock(space);
-
- if (table_info == *tablep) {
- /* data fit in-line; nothing to deallocate */
-
- *tableCntp = table_actual;
- } else if (table_actual == 0) {
- kmem_free(ipc_kernel_map, table_addr, table_size);
-
- *tableCntp = 0;
- } else {
- vm_size_t size_used, rsize_used;
- vm_map_copy_t copy;
-
- /* kmem_alloc doesn't zero memory */
-
- size_used = table_actual * sizeof *table_info;
- rsize_used = round_page(size_used);
-
- if (rsize_used != table_size)
- kmem_free(ipc_kernel_map,
- table_addr + rsize_used,
- table_size - rsize_used);
-
- if (size_used != rsize_used)
- memset((char *) (table_addr + size_used), 0,
- rsize_used - size_used);
-
- kr = vm_map_copyin(ipc_kernel_map, table_addr, rsize_used,
- TRUE, &copy);
-
- assert(kr == KERN_SUCCESS);
-
- *tablep = (ipc_info_name_t *) copy;
- *tableCntp = table_actual;
- }
-
- if (tree_info == *treep) {
- /* data fit in-line; nothing to deallocate */
-
- *treeCntp = tree_actual;
- } else if (tree_actual == 0) {
- kmem_free(ipc_kernel_map, tree_addr, tree_size);
-
- *treeCntp = 0;
- } else {
- vm_size_t size_used, rsize_used;
- vm_map_copy_t copy;
-
- /* kmem_alloc doesn't zero memory */
-
- size_used = tree_actual * sizeof *tree_info;
- rsize_used = round_page(size_used);
-
- if (rsize_used != tree_size)
- kmem_free(ipc_kernel_map,
- tree_addr + rsize_used,
- tree_size - rsize_used);
-
- if (size_used != rsize_used)
- memset((char *) (tree_addr + size_used), 0,
- rsize_used - size_used);
-
- kr = vm_map_copyin(ipc_kernel_map, tree_addr, rsize_used,
- TRUE, &copy);
-
- assert(kr == KERN_SUCCESS);
-
- *treep = (ipc_info_tree_name_t *) copy;
- *treeCntp = tree_actual;
- }
-
- return KERN_SUCCESS;
-}
-
-/*
* Routine: mach_port_dnrequest_info
* Purpose:
* Returns information about the dead-name requests
@@ -603,8 +278,8 @@ mach_port_kernel_object(
return KERN_INVALID_RIGHT;
}
- *typep = (unsigned int) ip_kotype(port);
- *addrp = (vm_offset_t) port->ip_kobject;
+ *typep = ip_kotype(port);
+ *addrp = port->ip_kobject;
ip_unlock(port);
return KERN_SUCCESS;
}
diff --git a/ipc/mach_msg.c b/ipc/mach_msg.c
index 00ab085b..fe0c43e3 100644
--- a/ipc/mach_msg.c
+++ b/ipc/mach_msg.c
@@ -46,6 +46,7 @@
#include <kern/printf.h>
#include <kern/sched_prim.h>
#include <kern/ipc_sched.h>
+#include <kern/exception.h>
#include <vm/vm_map.h>
#include <ipc/ipc_kmsg.h>
#include <ipc/ipc_marequest.h>
@@ -61,9 +62,6 @@
#include <machine/locore.h>
#include <machine/pcb.h>
-extern void exception_raise_continue();
-extern void exception_raise_continue_fast();
-
/*
* Routine: mach_msg_send
* Purpose:
@@ -90,12 +88,12 @@ extern void exception_raise_continue_fast();
*/
mach_msg_return_t
-mach_msg_send(msg, option, send_size, time_out, notify)
- mach_msg_header_t *msg;
- mach_msg_option_t option;
- mach_msg_size_t send_size;
- mach_msg_timeout_t time_out;
- mach_port_t notify;
+mach_msg_send(
+ mach_msg_header_t *msg,
+ mach_msg_option_t option,
+ mach_msg_size_t send_size,
+ mach_msg_timeout_t time_out,
+ mach_port_t notify)
{
ipc_space_t space = current_space();
vm_map_t map = current_map();
@@ -172,13 +170,13 @@ mach_msg_send(msg, option, send_size, time_out, notify)
*/
mach_msg_return_t
-mach_msg_receive(msg, option, rcv_size, rcv_name, time_out, notify)
- mach_msg_header_t *msg;
- mach_msg_option_t option;
- mach_msg_size_t rcv_size;
- mach_port_t rcv_name;
- mach_msg_timeout_t time_out;
- mach_port_t notify;
+mach_msg_receive(
+ mach_msg_header_t *msg,
+ mach_msg_option_t option,
+ mach_msg_size_t rcv_size,
+ mach_port_t rcv_name,
+ mach_msg_timeout_t time_out,
+ mach_port_t notify)
{
ipc_thread_t self = current_thread();
ipc_space_t space = current_space();
@@ -381,26 +379,26 @@ mach_msg_receive_continue(void)
*/
mach_msg_return_t
-mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
- mach_msg_header_t *msg;
- mach_msg_option_t option;
- mach_msg_size_t send_size;
- mach_msg_size_t rcv_size;
- mach_port_t rcv_name;
- mach_msg_timeout_t time_out;
- mach_port_t notify;
+mach_msg_trap(
+ mach_msg_header_t *msg,
+ mach_msg_option_t option,
+ mach_msg_size_t send_size,
+ mach_msg_size_t rcv_size,
+ mach_port_t rcv_name,
+ mach_msg_timeout_t time_out,
+ mach_port_t notify)
{
mach_msg_return_t mr;
/* first check for common cases */
if (option == (MACH_SEND_MSG|MACH_RCV_MSG)) {
- register ipc_thread_t self = current_thread();
+ ipc_thread_t self = current_thread();
ipc_space_t space = self->task->itk_space;
- register ipc_kmsg_t kmsg;
- register ipc_port_t dest_port;
+ ipc_kmsg_t kmsg;
+ ipc_port_t dest_port;
ipc_object_t rcv_object;
- register ipc_mqueue_t rcv_mqueue;
+ ipc_mqueue_t rcv_mqueue;
mach_msg_size_t reply_size;
/*
@@ -484,85 +482,38 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
switch (kmsg->ikm_header.msgh_bits) {
case MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,
MACH_MSG_TYPE_MAKE_SEND_ONCE): {
- register ipc_entry_t table;
- register ipc_entry_num_t size;
- register ipc_port_t reply_port;
-
- /* sending a request message */
-
+ ipc_port_t reply_port;
{
- register mach_port_index_t index;
- register mach_port_gen_t gen;
-
- {
- register mach_port_t reply_name =
+ mach_port_t reply_name =
kmsg->ikm_header.msgh_local_port;
if (reply_name != rcv_name)
goto slow_copyin;
- /* optimized ipc_entry_lookup of reply_name */
-
- index = MACH_PORT_INDEX(reply_name);
- gen = MACH_PORT_GEN(reply_name);
- }
-
is_read_lock(space);
assert(space->is_active);
- size = space->is_table_size;
- table = space->is_table;
-
- if (index >= size)
- goto abort_request_copyin;
-
- {
- register ipc_entry_t entry;
- register ipc_entry_bits_t bits;
-
- entry = &table[index];
- bits = entry->ie_bits;
-
- /* check generation number and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|
- MACH_PORT_TYPE_RECEIVE)) !=
- (gen | MACH_PORT_TYPE_RECEIVE))
+ ipc_entry_t entry;
+ entry = ipc_entry_lookup (space, reply_name);
+ if (entry == IE_NULL)
goto abort_request_copyin;
-
reply_port = (ipc_port_t) entry->ie_object;
assert(reply_port != IP_NULL);
}
- }
-
- /* optimized ipc_entry_lookup of dest_name */
-
- {
- register mach_port_index_t index;
- register mach_port_gen_t gen;
{
- register mach_port_t dest_name =
+ mach_port_t dest_name =
kmsg->ikm_header.msgh_remote_port;
- index = MACH_PORT_INDEX(dest_name);
- gen = MACH_PORT_GEN(dest_name);
- }
-
- if (index >= size)
+ ipc_entry_t entry;
+ ipc_entry_bits_t bits;
+ entry = ipc_entry_lookup (space, dest_name);
+ if (entry == IE_NULL)
goto abort_request_copyin;
-
- {
- register ipc_entry_t entry;
- register ipc_entry_bits_t bits;
-
- entry = &table[index];
bits = entry->ie_bits;
- /* check generation number and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|MACH_PORT_TYPE_SEND)) !=
- (gen | MACH_PORT_TYPE_SEND))
+ /* check type bits */
+ if (IE_BITS_TYPE (bits) != MACH_PORT_TYPE_SEND)
goto abort_request_copyin;
assert(IE_BITS_UREFS(bits) > 0);
@@ -570,7 +521,6 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
dest_port = (ipc_port_t) entry->ie_object;
assert(dest_port != IP_NULL);
}
- }
/*
* To do an atomic copyin, need simultaneous
@@ -651,13 +601,10 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
}
case MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0): {
- register ipc_entry_num_t size;
- register ipc_entry_t table;
-
/* sending a reply message */
{
- register mach_port_t reply_name =
+ mach_port_t reply_name =
kmsg->ikm_header.msgh_local_port;
if (reply_name != MACH_PORT_NULL)
@@ -667,35 +614,18 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
is_write_lock(space);
assert(space->is_active);
- /* optimized ipc_entry_lookup */
-
- size = space->is_table_size;
- table = space->is_table;
-
- {
- register ipc_entry_t entry;
- register mach_port_gen_t gen;
- register mach_port_index_t index;
-
{
- register mach_port_t dest_name =
+ ipc_entry_t entry;
+ mach_port_t dest_name =
kmsg->ikm_header.msgh_remote_port;
- index = MACH_PORT_INDEX(dest_name);
- gen = MACH_PORT_GEN(dest_name);
- }
-
- if (index >= size)
+ entry = ipc_entry_lookup (space, dest_name);
+ if (entry == IE_NULL)
goto abort_reply_dest_copyin;
- entry = &table[index];
-
- /* check generation, collision bit, and type bit */
-
- if ((entry->ie_bits & (IE_BITS_GEN_MASK|
- IE_BITS_COLLISION|
- MACH_PORT_TYPE_SEND_ONCE)) !=
- (gen | MACH_PORT_TYPE_SEND_ONCE))
+ /* check type bits */
+ if (IE_BITS_TYPE (entry->ie_bits) !=
+ MACH_PORT_TYPE_SEND_ONCE)
goto abort_reply_dest_copyin;
/* optimized ipc_right_copyin */
@@ -718,13 +648,8 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
}
assert(dest_port->ip_sorights > 0);
-
- /* optimized ipc_entry_dealloc */
-
- entry->ie_next = table->ie_next;
- table->ie_next = index;
- entry->ie_bits = gen;
entry->ie_object = IO_NULL;
+ ipc_entry_dealloc (space, dest_name, entry);
}
kmsg->ikm_header.msgh_bits =
@@ -737,35 +662,20 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
assert(dest_port->ip_receiver != ipc_space_kernel);
- /* optimized ipc_entry_lookup/ipc_mqueue_copyin */
-
- {
- register ipc_entry_t entry;
- register ipc_entry_bits_t bits;
+ /* optimized ipc_mqueue_copyin */
{
- register mach_port_index_t index;
- register mach_port_gen_t gen;
-
- index = MACH_PORT_INDEX(rcv_name);
- gen = MACH_PORT_GEN(rcv_name);
-
- if (index >= size)
+ ipc_entry_t entry;
+ ipc_entry_bits_t bits;
+ entry = ipc_entry_lookup (space, rcv_name);
+ if (entry == IE_NULL)
goto abort_reply_rcv_copyin;
-
- entry = &table[index];
bits = entry->ie_bits;
- /* check generation number */
-
- if ((bits & IE_BITS_GEN_MASK) != gen)
- goto abort_reply_rcv_copyin;
- }
-
/* check type bits; looking for receive or set */
if (bits & MACH_PORT_TYPE_PORT_SET) {
- register ipc_pset_t rcv_pset;
+ ipc_pset_t rcv_pset;
rcv_pset = (ipc_pset_t) entry->ie_object;
assert(rcv_pset != IPS_NULL);
@@ -776,7 +686,7 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
rcv_object = (ipc_object_t) rcv_pset;
rcv_mqueue = &rcv_pset->ips_messages;
} else if (bits & MACH_PORT_TYPE_RECEIVE) {
- register ipc_port_t rcv_port;
+ ipc_port_t rcv_port;
rcv_port = (ipc_port_t) entry->ie_object;
assert(rcv_port != IP_NULL);
@@ -841,11 +751,11 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
MACH_MSGH_BITS_CIRCULAR) == 0);
{
- register ipc_mqueue_t dest_mqueue;
- register ipc_thread_t receiver;
+ ipc_mqueue_t dest_mqueue;
+ ipc_thread_t receiver;
{
- register ipc_pset_t dest_pset;
+ ipc_pset_t dest_pset;
dest_pset = dest_port->ip_pset;
if (dest_pset == IPS_NULL)
@@ -1043,6 +953,7 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
ipc_port_t reply_port =
(ipc_port_t) kmsg->ikm_header.msgh_local_port;
mach_port_t dest_name, reply_name;
+ unsigned long payload;
/* receiving a request message */
@@ -1074,30 +985,19 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
ip_unlock(reply_port);
{
- register ipc_entry_t table;
- register ipc_entry_t entry;
- register mach_port_index_t index;
-
- /* optimized ipc_entry_get */
-
- table = space->is_table;
- index = table->ie_next;
-
- if (index == 0)
+ ipc_entry_t entry;
+ kern_return_t kr;
+ kr = ipc_entry_get (space, &reply_name, &entry);
+ if (kr)
goto abort_request_copyout;
-
- entry = &table[index];
- table->ie_next = entry->ie_next;
- entry->ie_request = 0;
+ assert (entry != NULL);
{
- register mach_port_gen_t gen;
+ mach_port_gen_t gen;
assert((entry->ie_bits &~ IE_BITS_GEN_MASK) == 0);
gen = entry->ie_bits + IE_BITS_GEN_ONE;
- reply_name = MACH_PORT_MAKE(index, gen);
-
/* optimized ipc_right_copyout */
entry->ie_bits = gen | (MACH_PORT_TYPE_SEND_ONCE | 1);
@@ -1117,6 +1017,7 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
dest_name = dest_port->ip_receiver_name;
else
dest_name = MACH_PORT_NULL;
+ payload = dest_port->ip_protected_payload;
if ((--dest_port->ip_srights == 0) &&
(dest_port->ip_nsrequest != IP_NULL)) {
@@ -1134,11 +1035,19 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
} else
ip_unlock(dest_port);
- kmsg->ikm_header.msgh_bits =
- MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
- MACH_MSG_TYPE_PORT_SEND);
+ if (! ipc_port_flag_protected_payload(dest_port)) {
+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
+ MACH_MSG_TYPE_PORT_SEND_ONCE,
+ MACH_MSG_TYPE_PORT_SEND);
+ kmsg->ikm_header.msgh_local_port = dest_name;
+ } else {
+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
+ MACH_MSG_TYPE_PORT_SEND_ONCE,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD);
+ kmsg->ikm_header.msgh_protected_payload =
+ payload;
+ }
kmsg->ikm_header.msgh_remote_port = reply_name;
- kmsg->ikm_header.msgh_local_port = dest_name;
goto fast_put;
abort_request_copyout:
@@ -1148,7 +1057,8 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
}
case MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0): {
- register mach_port_t dest_name;
+ mach_port_t dest_name;
+ unsigned long payload;
/* receiving a reply message */
@@ -1160,6 +1070,8 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
assert(dest_port->ip_sorights > 0);
+ payload = dest_port->ip_protected_payload;
+
if (dest_port->ip_receiver == space) {
ip_release(dest_port);
dest_port->ip_sorights--;
@@ -1172,17 +1084,26 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
dest_name = MACH_PORT_NULL;
}
- kmsg->ikm_header.msgh_bits =
- MACH_MSGH_BITS(0,
- MACH_MSG_TYPE_PORT_SEND_ONCE);
+ if (! ipc_port_flag_protected_payload(dest_port)) {
+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
+ 0,
+ MACH_MSG_TYPE_PORT_SEND_ONCE);
+ kmsg->ikm_header.msgh_local_port = dest_name;
+ } else {
+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
+ 0,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD);
+ kmsg->ikm_header.msgh_protected_payload =
+ payload;
+ }
kmsg->ikm_header.msgh_remote_port = MACH_PORT_NULL;
- kmsg->ikm_header.msgh_local_port = dest_name;
goto fast_put;
}
case MACH_MSGH_BITS_COMPLEX|
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0): {
- register mach_port_t dest_name;
+ mach_port_t dest_name;
+ unsigned long payload;
/* receiving a complex reply message */
@@ -1194,6 +1115,8 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
assert(dest_port->ip_sorights > 0);
+ payload = dest_port->ip_protected_payload;
+
if (dest_port->ip_receiver == space) {
ip_release(dest_port);
dest_port->ip_sorights--;
@@ -1206,12 +1129,23 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
dest_name = MACH_PORT_NULL;
}
- kmsg->ikm_header.msgh_bits =
- MACH_MSGH_BITS_COMPLEX |
- MACH_MSGH_BITS(0,
- MACH_MSG_TYPE_PORT_SEND_ONCE);
+ if (! ipc_port_flag_protected_payload(dest_port)) {
+ kmsg->ikm_header.msgh_bits =
+ MACH_MSGH_BITS_COMPLEX
+ | MACH_MSGH_BITS(
+ 0,
+ MACH_MSG_TYPE_PORT_SEND_ONCE);
+ kmsg->ikm_header.msgh_local_port = dest_name;
+ } else {
+ kmsg->ikm_header.msgh_bits =
+ MACH_MSGH_BITS_COMPLEX
+ | MACH_MSGH_BITS(
+ 0,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD);
+ kmsg->ikm_header.msgh_protected_payload =
+ payload;
+ }
kmsg->ikm_header.msgh_remote_port = MACH_PORT_NULL;
- kmsg->ikm_header.msgh_local_port = dest_name;
mr = ipc_kmsg_copyout_body(
(vm_offset_t) (&kmsg->ikm_header + 1),
@@ -1322,7 +1256,7 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
* It will work if this is a request message.
*/
- register ipc_port_t reply_port;
+ ipc_port_t reply_port;
reply_port = (ipc_port_t)
kmsg->ikm_header.msgh_local_port;
@@ -1357,7 +1291,7 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
*/
{
- register ipc_port_t reply_port;
+ ipc_port_t reply_port;
/*
* Perform the kernel function.
@@ -1735,8 +1669,7 @@ mach_msg_continue(void)
*/
boolean_t
-mach_msg_interrupt(thread)
- thread_t thread;
+mach_msg_interrupt(thread_t thread)
{
ipc_mqueue_t mqueue;
diff --git a/ipc/mach_port.c b/ipc/mach_port.c
index d0310b55..93a1248f 100644
--- a/ipc/mach_port.c
+++ b/ipc/mach_port.c
@@ -150,10 +150,6 @@ mach_port_names(
mach_port_type_t **typesp,
mach_msg_type_number_t *typesCnt)
{
- ipc_tree_entry_t tentry;
- ipc_entry_t table;
- ipc_entry_num_t tsize;
- mach_port_index_t index;
ipc_entry_num_t actual; /* this many names */
ipc_port_timestamp_t timestamp; /* logical time of this operation */
mach_port_t *names;
@@ -190,7 +186,7 @@ mach_port_names(
/* upper bound on number of names in the space */
- bound = space->is_table_size + space->is_tree_total;
+ bound = space->is_size;
size_needed = round_page(bound * sizeof(mach_port_t));
if (size_needed <= size)
@@ -235,33 +231,16 @@ mach_port_names(
timestamp = ipc_port_timestamp();
- table = space->is_table;
- tsize = space->is_table_size;
-
- for (index = 0; index < tsize; index++) {
- ipc_entry_t entry = &table[index];
+ ipc_entry_t entry;
+ struct rdxtree_iter iter;
+ rdxtree_for_each(&space->is_map, &iter, entry) {
ipc_entry_bits_t bits = entry->ie_bits;
if (IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE) {
- mach_port_t name = MACH_PORT_MAKEB(index, bits);
-
- mach_port_names_helper(timestamp, entry, name,
+ mach_port_names_helper(timestamp, entry, entry->ie_name,
names, types, &actual);
}
}
-
- for (tentry = ipc_splay_traverse_start(&space->is_tree);
- tentry != ITE_NULL;
- tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
- ipc_entry_t entry = &tentry->ite_entry;
- mach_port_t name = tentry->ite_name;
-
- assert(IE_BITS_TYPE(tentry->ite_bits) != MACH_PORT_TYPE_NONE);
-
- mach_port_names_helper(timestamp, entry, name,
- names, types, &actual);
- }
- ipc_splay_traverse_finish(&space->is_tree);
is_read_unlock(space);
if (actual == 0) {
@@ -434,10 +413,10 @@ mach_port_rename(
*/
kern_return_t
-mach_port_allocate_name(space, right, name)
- ipc_space_t space;
- mach_port_right_t right;
- mach_port_t name;
+mach_port_allocate_name(
+ ipc_space_t space,
+ mach_port_right_t right,
+ mach_port_t name)
{
kern_return_t kr;
@@ -497,10 +476,10 @@ mach_port_allocate_name(space, right, name)
*/
kern_return_t
-mach_port_allocate(space, right, namep)
- ipc_space_t space;
- mach_port_right_t right;
- mach_port_t *namep;
+mach_port_allocate(
+ ipc_space_t space,
+ mach_port_right_t right,
+ mach_port_t *namep)
{
kern_return_t kr;
@@ -555,7 +534,7 @@ mach_port_allocate(space, right, namep)
* KERN_INVALID_NAME The name doesn't denote a right.
*/
-static volatile int mach_port_deallocate_debug = 0;
+static volatile boolean_t mach_port_deallocate_debug = FALSE;
kern_return_t
mach_port_destroy(
@@ -570,8 +549,8 @@ mach_port_destroy(
kr = ipc_right_lookup_write(space, name, &entry);
if (kr != KERN_SUCCESS) {
- if (name != MACH_PORT_NULL && name != MACH_PORT_DEAD && space == current_space()) {
- printf("task %p destroying an invalid port %lu, most probably a bug.\n", current_task(), name);
+ if (MACH_PORT_VALID (name) && space == current_space()) {
+ printf("task %.*s destroying a bogus port %lu, most probably a bug.\n", sizeof current_task()->name, current_task()->name, name);
if (mach_port_deallocate_debug)
SoftDebugger("mach_port_deallocate");
}
@@ -614,8 +593,8 @@ mach_port_deallocate(
kr = ipc_right_lookup_write(space, name, &entry);
if (kr != KERN_SUCCESS) {
- if (name != MACH_PORT_NULL && name != MACH_PORT_DEAD && space == current_space()) {
- printf("task %p deallocating an invalid port %lu, most probably a bug.\n", current_task(), name);
+ if (MACH_PORT_VALID (name) && space == current_space()) {
+ printf("task %.*s deallocating a bogus port %lu, most probably a bug.\n", sizeof current_task()->name, current_task()->name, name);
if (mach_port_deallocate_debug)
SoftDebugger("mach_port_deallocate");
}
@@ -735,8 +714,19 @@ mach_port_mod_refs(
return KERN_INVALID_VALUE;
kr = ipc_right_lookup_write(space, name, &entry);
- if (kr != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS) {
+ if (MACH_PORT_VALID (name) && space == current_space()) {
+ printf("task %.*s %screasing a bogus port "
+ "%lu by %d, most probably a bug.\n",
+ sizeof current_task()->name,
+ current_task()->name,
+ delta < 0 ? "de" : "in", name,
+ delta < 0 ? -delta : delta);
+ if (mach_port_deallocate_debug)
+ SoftDebugger("mach_port_mod_refs");
+ }
return kr;
+ }
/* space is write-locked and active */
kr = ipc_right_delta(space, name, entry, right, delta); /* unlocks */
@@ -744,48 +734,6 @@ mach_port_mod_refs(
}
/*
- * Routine: old_mach_port_get_receive_status [kernel call]
- * Purpose:
- * Compatibility for code written before sequence numbers.
- * Retrieves mucho info about a receive right.
- * Conditions:
- * Nothing locked.
- * Returns:
- * KERN_SUCCESS Retrieved status.
- * KERN_INVALID_TASK The space is null.
- * KERN_INVALID_TASK The space is dead.
- * KERN_INVALID_NAME The name doesn't denote a right.
- * KERN_INVALID_RIGHT Name doesn't denote receive rights.
- */
-
-kern_return_t
-mach_port_get_receive_status(ipc_space_t, mach_port_t, mach_port_status_t *);
-kern_return_t
-old_mach_port_get_receive_status(space, name, statusp)
- ipc_space_t space;
- mach_port_t name;
- old_mach_port_status_t *statusp;
-{
- mach_port_status_t status;
- kern_return_t kr;
-
- kr = mach_port_get_receive_status(space, name, &status);
- if (kr != KERN_SUCCESS)
- return kr;
-
- statusp->mps_pset = status.mps_pset;
- statusp->mps_mscount = status.mps_mscount;
- statusp->mps_qlimit = status.mps_qlimit;
- statusp->mps_msgcount = status.mps_msgcount;
- statusp->mps_sorights = status.mps_sorights;
- statusp->mps_srights = status.mps_srights;
- statusp->mps_pdrequest = status.mps_pdrequest;
- statusp->mps_nsrequest = status.mps_nsrequest;
-
- return KERN_SUCCESS;
-}
-
-/*
* Routine: mach_port_set_qlimit [kernel call]
* Purpose:
* Changes a receive right's queue limit.
@@ -803,10 +751,10 @@ old_mach_port_get_receive_status(space, name, statusp)
*/
kern_return_t
-mach_port_set_qlimit(space, name, qlimit)
- ipc_space_t space;
- mach_port_t name;
- mach_port_msgcount_t qlimit;
+mach_port_set_qlimit(
+ ipc_space_t space,
+ mach_port_t name,
+ mach_port_msgcount_t qlimit)
{
ipc_port_t port;
kern_return_t kr;
@@ -977,10 +925,7 @@ mach_port_get_set_status(
size = PAGE_SIZE; /* initial guess */
for (;;) {
- ipc_tree_entry_t tentry;
- ipc_entry_t entry, table;
- ipc_entry_num_t tsize;
- mach_port_index_t index;
+ ipc_entry_t entry;
mach_port_t *names;
ipc_pset_t pset;
@@ -1017,11 +962,9 @@ mach_port_get_set_status(
maxnames = size / sizeof(mach_port_t);
actual = 0;
- table = space->is_table;
- tsize = space->is_table_size;
-
- for (index = 0; index < tsize; index++) {
- ipc_entry_t ientry = &table[index];
+ ipc_entry_t ientry;
+ struct rdxtree_iter iter;
+ rdxtree_for_each(&space->is_map, &iter, ientry) {
ipc_entry_bits_t bits = ientry->ie_bits;
if (bits & MACH_PORT_TYPE_RECEIVE) {
@@ -1033,22 +976,6 @@ mach_port_get_set_status(
}
}
- for (tentry = ipc_splay_traverse_start(&space->is_tree);
- tentry != ITE_NULL;
- tentry = ipc_splay_traverse_next(&space->is_tree,FALSE)) {
- ipc_entry_bits_t bits = tentry->ite_bits;
-
- assert(IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE);
-
- if (bits & MACH_PORT_TYPE_RECEIVE) {
- ipc_port_t port =
- (ipc_port_t) tentry->ite_object;
-
- mach_port_gst_helper(pset, port, maxnames,
- names, &actual);
- }
- }
- ipc_splay_traverse_finish(&space->is_tree);
is_read_unlock(space);
if (actual <= maxnames)
@@ -1367,10 +1294,10 @@ mach_port_extract_right(
*/
kern_return_t
-mach_port_get_receive_status(space, name, statusp)
- ipc_space_t space;
- mach_port_t name;
- mach_port_status_t *statusp;
+mach_port_get_receive_status(
+ ipc_space_t space,
+ mach_port_t name,
+ mach_port_status_t *statusp)
{
ipc_port_t port;
kern_return_t kr;
@@ -1421,11 +1348,11 @@ mach_port_get_receive_status(space, name, statusp)
#ifdef MIGRATING_THREADS
kern_return_t
-mach_port_set_rpcinfo(space, name, rpc_info, rpc_info_count)
- ipc_space_t space;
- mach_port_t name;
- void *rpc_info;
- unsigned int rpc_info_count;
+mach_port_set_rpcinfo(
+ ipc_space_t space,
+ mach_port_t name,
+ void *rpc_info,
+ unsigned int rpc_info_count)
{
ipc_target_t target;
ipc_object_t object;
@@ -1459,19 +1386,19 @@ mach_port_set_rpcinfo(space, name, rpc_info, rpc_info_count)
int sacts, maxsacts;
#endif
-sact_count()
+void sact_count(void)
{
printf("%d server activations in use, %d max\n", sacts, maxsacts);
}
kern_return_t
-mach_port_create_act(task, name, user_stack, user_rbuf, user_rbuf_size, out_act)
- task_t task;
- mach_port_t name;
- vm_offset_t user_stack;
- vm_offset_t user_rbuf;
- vm_size_t user_rbuf_size;
- Act **out_act;
+mach_port_create_act(
+ task_t task,
+ mach_port_t name,
+ vm_offset_t user_stack,
+ vm_offset_t user_rbuf,
+ vm_size_t user_rbuf_size,
+ Act **out_act)
{
ipc_target_t target;
ipc_space_t space;
@@ -1538,12 +1465,11 @@ mach_port_create_act(task, name, user_stack, user_rbuf, user_rbuf_size, out_act)
#ifdef RPCKERNELSIG
kern_return_t
-mach_port_set_syscall_right(task, name)
- task_t task;
- mach_port_t name;
+mach_port_set_syscall_right(
+ task_t task,
+ mach_port_t name)
{
ipc_entry_t entry;
- ipc_port_t port;
kern_return_t kr;
if (task == IS_NULL)
@@ -1567,3 +1493,76 @@ mach_port_set_syscall_right(task, name)
}
#endif
#endif /* MIGRATING_THREADS */
+
+/*
+ * Routine: mach_port_set_protected_payload [kernel call]
+ * Purpose:
+ * Changes a receive right's protected payload.
+ * Conditions:
+ * Nothing locked.
+ * Returns:
+ * KERN_SUCCESS Set protected payload.
+ * KERN_INVALID_TASK The space is null.
+ * KERN_INVALID_TASK The space is dead.
+ * KERN_INVALID_NAME The name doesn't denote a right.
+ * KERN_INVALID_RIGHT Name doesn't denote receive rights.
+ */
+
+kern_return_t
+mach_port_set_protected_payload(
+ ipc_space_t space,
+ mach_port_t name,
+ unsigned long payload)
+{
+ ipc_port_t port;
+ kern_return_t kr;
+
+ if (space == IS_NULL)
+ return KERN_INVALID_TASK;
+
+ kr = ipc_port_translate_receive(space, name, &port);
+ if (kr != KERN_SUCCESS)
+ return kr;
+ /* port is locked and active */
+
+ ipc_port_set_protected_payload(port, payload);
+
+ ip_unlock(port);
+ return KERN_SUCCESS;
+}
+
+/*
+ * Routine: mach_port_clear_protected_payload [kernel call]
+ * Purpose:
+ * Clears a receive right's protected payload.
+ * Conditions:
+ * Nothing locked.
+ * Returns:
+ * KERN_SUCCESS Clear protected payload.
+ * KERN_INVALID_TASK The space is null.
+ * KERN_INVALID_TASK The space is dead.
+ * KERN_INVALID_NAME The name doesn't denote a right.
+ * KERN_INVALID_RIGHT Name doesn't denote receive rights.
+ */
+
+kern_return_t
+mach_port_clear_protected_payload(
+ ipc_space_t space,
+ mach_port_t name)
+{
+ ipc_port_t port;
+ kern_return_t kr;
+
+ if (space == IS_NULL)
+ return KERN_INVALID_TASK;
+
+ kr = ipc_port_translate_receive(space, name, &port);
+ if (kr != KERN_SUCCESS)
+ return kr;
+ /* port is locked and active */
+
+ ipc_port_clear_protected_payload(port);
+
+ ip_unlock(port);
+ return KERN_SUCCESS;
+}
diff --git a/ipc/mach_port.h b/ipc/mach_port.h
index a82228fe..c4d9a1c3 100644
--- a/ipc/mach_port.h
+++ b/ipc/mach_port.h
@@ -43,6 +43,11 @@ mach_port_allocate (
mach_port_t *namep);
extern kern_return_t
+mach_port_destroy(
+ ipc_space_t space,
+ mach_port_t name);
+
+extern kern_return_t
mach_port_deallocate(
ipc_space_t space,
mach_port_t name);
@@ -54,4 +59,10 @@ mach_port_insert_right(
ipc_port_t poly,
mach_msg_type_name_t polyPoly);
+kern_return_t
+mach_port_get_receive_status(
+ ipc_space_t space,
+ mach_port_t name,
+ mach_port_status_t *statusp);
+
#endif /* _IPC_MACH_PORT_H_ */
diff --git a/ipc/mach_rpc.c b/ipc/mach_rpc.c
index 7f5b2eb2..6ca46cc9 100644
--- a/ipc/mach_rpc.c
+++ b/ipc/mach_rpc.c
@@ -58,9 +58,10 @@
* info to the other side.
*/
kern_return_t
-mach_port_rpc_copy(portp, sact, dact)
- struct rpc_port_desc *portp;
- struct Act *sact, *dact;
+mach_port_rpc_copy(
+ struct rpc_port_desc *portp,
+ struct Act *sact,
+ struct Act *dact)
{
ipc_space_t sspace, dspace;
mach_msg_type_name_t tname;
@@ -141,7 +142,7 @@ mach_port_rpc_copy(portp, sact, dact)
}
kern_return_t
-mach_port_rpc_sig(space, name, buffer, buflen)
+mach_port_rpc_sig(const ipc_space_t space, const char *name, const char *buffer, unsigned int buflen)
{
return KERN_FAILURE;
}
diff --git a/ipc/notify.defs b/ipc/notify.defs
new file mode 100644
index 00000000..db059b8d
--- /dev/null
+++ b/ipc/notify.defs
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* We use custom functions to send notifications. These functions can
+ be found in `ipc_notify.c'. We use this file merely to produce the
+ list of message ids. */
+
+#include <mach/notify.defs>
diff --git a/ipc/port.h b/ipc/port.h
index 6e9f77b4..49af6e2c 100644
--- a/ipc/port.h
+++ b/ipc/port.h
@@ -29,7 +29,7 @@
/*
*/
/*
- * File: ipc/ipc_port.h
+ * File: ipc/port.h
* Author: Rich Draves
* Date: 1989
*
@@ -45,10 +45,7 @@
* mach_port_t must be an unsigned type. Port values
* have two parts, a generation number and an index.
* These macros encapsulate all knowledge of how
- * a mach_port_t is layed out. However, ipc/ipc_entry.c
- * implicitly assumes when it uses the splay tree functions
- * that the generation number is in the low bits, so that
- * names are ordered first by index and then by generation.
+ * a mach_port_t is laid out.
*
* If the size of generation numbers changes,
* be sure to update IE_BITS_GEN_MASK and friends
diff --git a/kern/act.c b/kern/act.c
index 36fa79c1..3186f7e9 100644
--- a/kern/act.c
+++ b/kern/act.c
@@ -64,7 +64,7 @@ static Act free_acts[ACT_STATIC_KLUDGE];
Act null_act;
void
-global_act_init()
+global_act_init(void)
{
#ifndef ACT_STATIC_KLUDGE
kmem_cache_init(&act_cache, "Act", sizeof(struct Act), 0,
@@ -97,7 +97,6 @@ kern_return_t act_create(task_t task, vm_offset_t user_stack,
struct Act **new_act)
{
Act *act;
- int rc;
#ifndef ACT_STATIC_KLUDGE
act = (Act*)kmem_cache_alloc(&act_cache);
@@ -258,7 +257,7 @@ void act_detach(Act *cur_act)
so RPC entry paths need not check it.
Locking: Act */
-void act_execute_returnhandlers()
+void act_execute_returnhandlers(void)
{
Act *act = current_act();
@@ -1014,11 +1013,11 @@ act_set_special_port(Act *act, int which, ipc_port_t port)
* Return thread's machine-dependent state.
*/
kern_return_t
-act_get_state_immediate(act, flavor, old_state, old_state_count)
- register Act *act;
- int flavor;
- void *old_state; /* pointer to OUT array */
- unsigned int *old_state_count; /*IN/OUT*/
+act_get_state_immediate(
+ Act *act,
+ int flavor,
+ void *old_state, /* pointer to OUT array */
+ unsigned int *old_state_count) /*IN/OUT*/
{
kern_return_t ret;
@@ -1040,11 +1039,11 @@ act_get_state_immediate(act, flavor, old_state, old_state_count)
* Change thread's machine-dependent state.
*/
kern_return_t
-act_set_state_immediate(act, flavor, new_state, new_state_count)
- register Act *act;
- int flavor;
- void *new_state;
- unsigned int new_state_count;
+act_set_state_immediate(
+ Act *act,
+ int flavor,
+ void *new_state,
+ unsigned int new_state_count)
{
kern_return_t ret;
@@ -1062,7 +1061,7 @@ act_set_state_immediate(act, flavor, new_state, new_state_count)
return act_set_state(act, flavor, new_state, new_state_count);
}
-void act_count()
+void act_count(void)
{
int i;
Act *act;
@@ -1077,7 +1076,7 @@ void act_count()
ACT_STATIC_KLUDGE-i, ACT_STATIC_KLUDGE, ACT_STATIC_KLUDGE-amin);
}
-dump_act(act)
+void dump_act(act)
Act *act;
{
act_count();
@@ -1098,8 +1097,7 @@ dump_act(act)
#ifdef ACTWATCH
Act *
-get_next_act(sp)
- int sp;
+get_next_act(int sp)
{
static int i;
Act *act;
@@ -1115,6 +1113,6 @@ get_next_act(sp)
return act;
}
}
-#endif
+#endif /* ACTWATCH */
#endif /* MIGRATING_THREADS */
diff --git a/kern/act.h b/kern/act.h
index e0647244..f46f53a3 100644
--- a/kern/act.h
+++ b/kern/act.h
@@ -40,8 +40,6 @@
#include <kern/refcount.h>
#include <kern/queue.h>
-#include "act.h"/*XXX*/
-
struct task;
struct thread;
struct Act;
@@ -176,7 +174,6 @@ kern_return_t act_terminate_task_locked(struct Act *act);
/* Exported to thread.c */
extern Act null_act;
-kern_return_t act_create_kernel(Act **out_act);
/* Exported to machine-dependent activation code */
void act_execute_returnhandlers(void);
@@ -192,4 +189,4 @@ kern_return_t act_machine_get_state(Act *inc, int flavor, int *tstate, unsigned
#endif /* MIGRATING_THREADS */
-#endif _KERN_ACT_H_
+#endif /* _KERN_ACT_H_ */
diff --git a/kern/assert.h b/kern/assert.h
index 2829728b..7b66d1b1 100644
--- a/kern/assert.h
+++ b/kern/assert.h
@@ -29,26 +29,21 @@
/* assert.h 4.2 85/01/21 */
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#ifndef NDEBUG
#define MACH_ASSERT 1
#endif
#if MACH_ASSERT
-extern void Assert(char *exp, char *filename, int line) __attribute__ ((noreturn));
+extern void Assert(const char *exp, const char *filename, int line) __attribute__ ((noreturn));
#define assert(ex) \
-MACRO_BEGIN \
- if (!(ex)) \
- Assert(#ex, __FILE__, __LINE__); \
-MACRO_END
-
-#ifdef lint
-#define assert_static(x)
-#else /* lint */
+ ((ex) \
+ ? (void) (0) \
+ : Assert (#ex, __FILE__, __LINE__))
+
#define assert_static(x) assert(x)
-#endif /* lint */
#else /* MACH_ASSERT */
#define assert(ex)
diff --git a/kern/ast.c b/kern/ast.c
index 97da3abc..4b9d63d6 100644
--- a/kern/ast.c
+++ b/kern/ast.c
@@ -56,10 +56,10 @@
volatile ast_t need_ast[NCPUS];
void
-ast_init()
+ast_init(void)
{
#ifndef MACHINE_AST
- register int i;
+ int i;
for (i=0; i<NCPUS; i++)
need_ast[i] = 0;
@@ -69,8 +69,8 @@ ast_init()
void
ast_taken(void)
{
- register thread_t self = current_thread();
- register ast_t reasons;
+ thread_t self = current_thread();
+ ast_t reasons;
/*
* Interrupts are still disabled.
@@ -114,12 +114,12 @@ ast_taken(void)
}
void
-ast_check()
+ast_check(void)
{
- register int mycpu = cpu_number();
- register processor_t myprocessor;
- register thread_t thread = current_thread();
- register run_queue_t rq;
+ int mycpu = cpu_number();
+ processor_t myprocessor;
+ thread_t thread = current_thread();
+ run_queue_t rq;
spl_t s = splsched();
/*
@@ -190,7 +190,7 @@ ast_check()
#endif /* MACH_FIXPRI */
rq = &(myprocessor->processor_set->runq);
if (!(myprocessor->first_quantum) && (rq->count > 0)) {
- register queue_t q;
+ queue_t q;
/*
* This is not the first quantum, and there may
* be something in the processor_set runq.
@@ -198,7 +198,7 @@ ast_check()
*/
q = rq->runq + *(volatile int *)&rq->low;
if (queue_empty(q)) {
- register int i;
+ int i;
/*
* Need to recheck and possibly update hint.
diff --git a/kern/ast.h b/kern/ast.h
index 4c28b1e6..7d472be9 100644
--- a/kern/ast.h
+++ b/kern/ast.h
@@ -41,7 +41,7 @@
*/
#include "cpu_number.h"
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <machine/ast.h>
/*
diff --git a/kern/boot_script.c b/kern/boot_script.c
index b2e9393b..b245d1d8 100644
--- a/kern/boot_script.c
+++ b/kern/boot_script.c
@@ -76,14 +76,14 @@ create_task (struct cmd *cmd, long *val)
/* Resume a task. */
static int
-resume_task (struct cmd *cmd, long *val)
+resume_task (struct cmd *cmd, const long *val)
{
return boot_script_task_resume (cmd);
}
/* Resume a task when the user hits return. */
static int
-prompt_resume_task (struct cmd *cmd, long *val)
+prompt_resume_task (struct cmd *cmd, const long *val)
{
return boot_script_prompt_task_resume (cmd);
}
@@ -485,7 +485,7 @@ boot_script_parse_line (void *hook, char *cmdline)
/* Execute commands previously parsed. */
int
-boot_script_exec ()
+boot_script_exec (void)
{
int cmd_index;
diff --git a/kern/boot_script.h b/kern/boot_script.h
index c5ad6732..c007d777 100644
--- a/kern/boot_script.h
+++ b/kern/boot_script.h
@@ -69,10 +69,6 @@ int boot_script_exec_cmd (void *hook,
task_t task, char *path, int argc,
char **argv, char *strings, int stringlen);
-/* The user must define this function. Load the contents of FILE
- into a fresh anonymous memory object and return the memory object port. */
-mach_port_t boot_script_read_file (const char *file);
-
/* The user must define this functions to perform the corresponding
Mach task manipulations. */
int boot_script_task_create (struct cmd *); /* task_create + task_suspend */
diff --git a/kern/bootstrap.c b/kern/bootstrap.c
index 4a39f26a..0a8dcedb 100644
--- a/kern/bootstrap.c
+++ b/kern/bootstrap.c
@@ -37,6 +37,7 @@
#include <mach/message.h>
#include <machine/locore.h>
#include <machine/vm_param.h>
+#include <machine/pcb.h>
#include <ipc/ipc_port.h>
#include <ipc/mach_port.h>
#include <kern/debug.h>
@@ -86,8 +87,8 @@ static mach_port_t boot_host_port; /* local name */
extern char *kernel_cmdline;
-static void user_bootstrap(); /* forward */
-static void user_bootstrap_compat(); /* forward */
+static void user_bootstrap(void); /* forward */
+static void user_bootstrap_compat(void); /* forward */
static void bootstrap_exec_compat(void *exec_data); /* forward */
static void get_compat_strings(char *flags_str, char *root_str); /* forward */
@@ -111,7 +112,7 @@ task_insert_send_right(
return name;
}
-void bootstrap_create()
+void bootstrap_create(void)
{
int compat;
int n = 0;
@@ -165,18 +166,18 @@ void bootstrap_create()
}
else
{
- int i, losers, maxlen;
+ int i, losers;
/* Initialize boot script variables. We leak these send rights. */
losers = boot_script_set_variable
("host-port", VAL_PORT,
- (long)ipc_port_make_send(realhost.host_priv_self));
+ (long) realhost.host_priv_self);
if (losers)
panic ("cannot set boot-script variable host-port: %s",
boot_script_error_string (losers));
losers = boot_script_set_variable
("device-port", VAL_PORT,
- (long) ipc_port_make_send(master_device_port));
+ (long) master_device_port);
if (losers)
panic ("cannot set boot-script variable device-port: %s",
boot_script_error_string (losers));
@@ -256,15 +257,11 @@ void bootstrap_create()
}
#endif
- maxlen = 0;
for (i = 0; i < boot_info.mods_count; ++i)
{
int err;
char *line = (char*)phystokv(bmods[i].string);
- int len = strlen (line) + 1;
- if (len > maxlen)
- maxlen = len;
- printf ("\rmodule %d: %*s", i, -maxlen, line);
+ printf ("module %d: %s\n", i, line);
err = boot_script_parse_line (&bmods[i], line);
if (err)
{
@@ -272,7 +269,7 @@ void bootstrap_create()
++losers;
}
}
- printf ("\r%d multiboot modules %*s", i, -maxlen, "");
+ printf ("%d multiboot modules\n", i);
if (losers)
panic ("%d of %d boot script commands could not be parsed",
losers, boot_info.mods_count);
@@ -334,7 +331,7 @@ itoa(
vm_size_t num)
{
char buf[sizeof(vm_size_t)*2+3];
- register char *np;
+ char *np;
np = buf + sizeof(buf);
*--np = 0;
@@ -354,7 +351,7 @@ itoa(
*/
static void get_compat_strings(char *flags_str, char *root_str)
{
- register char *ip, *cp;
+ char *ip, *cp;
strcpy (root_str, "UNKNOWN");
@@ -535,16 +532,12 @@ static void copy_bootstrap(void *e, exec_info_t *boot_exec_info)
/*
* Allocate the stack, and build the argument list.
*/
-extern vm_offset_t user_stack_low();
-extern vm_offset_t set_user_regs();
-
static void
build_args_and_stack(struct exec_info *boot_exec_info,
char **argv, char **envp)
{
vm_offset_t stack_base;
vm_size_t stack_size;
- register
char * arg_ptr;
int arg_count, envc;
int arg_len;
@@ -606,7 +599,7 @@ build_args_and_stack(struct exec_info *boot_exec_info,
/*
* first the argument count
*/
- (void) copyout((char *)&arg_count,
+ (void) copyout(&arg_count,
arg_pos,
sizeof(integer_t));
arg_pos += sizeof(integer_t);
@@ -619,7 +612,7 @@ build_args_and_stack(struct exec_info *boot_exec_info,
arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */
/* set string pointer */
- (void) copyout((char *)&string_pos,
+ (void) copyout(&string_pos,
arg_pos,
sizeof (char *));
arg_pos += sizeof(char *);
@@ -632,7 +625,7 @@ build_args_and_stack(struct exec_info *boot_exec_info,
/*
* Null terminator for argv.
*/
- (void) copyout((char *)&zero, arg_pos, sizeof(char *));
+ (void) copyout(&zero, arg_pos, sizeof(char *));
arg_pos += sizeof(char *);
/*
@@ -643,7 +636,7 @@ build_args_and_stack(struct exec_info *boot_exec_info,
arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */
/* set string pointer */
- (void) copyout((char *)&string_pos,
+ (void) copyout(&string_pos,
arg_pos,
sizeof (char *));
arg_pos += sizeof(char *);
@@ -656,12 +649,12 @@ build_args_and_stack(struct exec_info *boot_exec_info,
/*
* Null terminator for envp.
*/
- (void) copyout((char *)&zero, arg_pos, sizeof(char *));
+ (void) copyout(&zero, arg_pos, sizeof(char *));
}
static void
-user_bootstrap_compat()
+user_bootstrap_compat(void)
{
exec_info_t boot_exec_info;
@@ -748,7 +741,8 @@ boot_script_exec_cmd (void *hook, task_t task, char *path, int argc,
assert(err == 0);
thread->saved.other = &info;
thread_start (thread, user_bootstrap);
- thread_resume (thread);
+ err = thread_resume (thread);
+ assert(err == 0);
/* We need to synchronize with the new thread and block this
main thread until it has finished referring to our local state. */
@@ -757,13 +751,14 @@ boot_script_exec_cmd (void *hook, task_t task, char *path, int argc,
thread_sleep ((event_t) &info, simple_lock_addr(info.lock), FALSE);
simple_lock (&info.lock);
}
+ simple_unlock (&info.lock);
printf ("\n");
}
return 0;
}
-static void user_bootstrap()
+static void user_bootstrap(void)
{
struct user_bootstrap_info *info = current_thread()->saved.other;
exec_info_t boot_exec_info;
@@ -791,6 +786,7 @@ static void user_bootstrap()
simple_lock (&info->lock);
assert (!info->done);
info->done = 1;
+ simple_unlock (&info->lock);
thread_wakeup ((event_t) info);
/*
@@ -823,6 +819,7 @@ boot_script_task_create (struct cmd *cmd)
printf("boot_script_task_create failed with %x\n", rc);
return BOOT_SCRIPT_MACH_ERROR;
}
+ task_set_name(cmd->task, cmd->path);
return 0;
}
@@ -860,7 +857,8 @@ boot_script_free_task (task_t task, int aborting)
int
boot_script_insert_right (struct cmd *cmd, mach_port_t port, mach_port_t *name)
{
- *name = task_insert_send_right (cmd->task, (ipc_port_t)port);
+ *name = task_insert_send_right (cmd->task,
+ ipc_port_make_send((ipc_port_t) port));
return 0;
}
diff --git a/kern/bootstrap.h b/kern/bootstrap.h
new file mode 100644
index 00000000..b8ed8d9f
--- /dev/null
+++ b/kern/bootstrap.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _KERN_BOOTSTRAP_H_
+#define _KERN_BOOTSTRAP_H_
+
+extern void bootstrap_create(void);
+
+#endif /* _KERN_BOOTSTRAP_H_ */
diff --git a/kern/counters.c b/kern/counters.c
index a9d450e1..0a0665bf 100644
--- a/kern/counters.c
+++ b/kern/counters.c
@@ -32,13 +32,12 @@
* This makes them easier to examine with ddb.
*/
+#if MACH_COUNTERS
mach_counter_t c_thread_invoke_hits = 0;
mach_counter_t c_thread_invoke_misses = 0;
mach_counter_t c_thread_invoke_csw = 0;
mach_counter_t c_thread_handoff_hits = 0;
mach_counter_t c_thread_handoff_misses = 0;
-
-#if MACH_COUNTERS
mach_counter_t c_threads_current = 0;
mach_counter_t c_threads_max = 0;
mach_counter_t c_threads_min = 0;
@@ -47,6 +46,9 @@ mach_counter_t c_stacks_current = 0;
mach_counter_t c_stacks_max = 0;
mach_counter_t c_stacks_min = 0;
mach_counter_t c_stacks_total = 0;
+mach_counter_t c_stack_alloc_hits = 0;
+mach_counter_t c_stack_alloc_misses = 0;
+mach_counter_t c_stack_alloc_max = 0;
mach_counter_t c_clock_ticks = 0;
mach_counter_t c_ipc_mqueue_send_block = 0;
mach_counter_t c_ipc_mqueue_receive_block_user = 0;
diff --git a/kern/counters.h b/kern/counters.h
index 474c6a29..aa1e739b 100644
--- a/kern/counters.h
+++ b/kern/counters.h
@@ -55,13 +55,12 @@
typedef unsigned int mach_counter_t;
+#if MACH_COUNTERS
extern mach_counter_t c_thread_invoke_hits;
extern mach_counter_t c_thread_invoke_misses;
extern mach_counter_t c_thread_invoke_csw;
extern mach_counter_t c_thread_handoff_hits;
extern mach_counter_t c_thread_handoff_misses;
-
-#if MACH_COUNTERS
extern mach_counter_t c_threads_current;
extern mach_counter_t c_threads_max;
extern mach_counter_t c_threads_min;
@@ -70,6 +69,9 @@ extern mach_counter_t c_stacks_current;
extern mach_counter_t c_stacks_max;
extern mach_counter_t c_stacks_min;
extern mach_counter_t c_stacks_total;
+extern mach_counter_t c_stack_alloc_hits;
+extern mach_counter_t c_stack_alloc_misses;
+extern mach_counter_t c_stack_alloc_max;
extern mach_counter_t c_clock_ticks;
extern mach_counter_t c_ipc_mqueue_send_block;
extern mach_counter_t c_ipc_mqueue_receive_block_user;
diff --git a/kern/debug.c b/kern/debug.c
index 8a04f1db..faa03565 100644
--- a/kern/debug.c
+++ b/kern/debug.c
@@ -38,11 +38,7 @@
#include <machine/loose_ends.h>
#include <machine/model_dep.h>
-extern void cnputc();
-
-#if MACH_KDB
-extern int db_breakpoints_inserted;
-#endif
+#include <device/cons.h>
#if NCPUS>1
simple_lock_data_t Assert_print_lock; /* uninited, we take our chances */
@@ -55,7 +51,7 @@ do_cnputc(char c, vm_offset_t offset)
}
void
-Assert(char *exp, char *file, int line)
+Assert(const char *exp, const char *file, int line)
{
#if NCPUS > 1
simple_lock(&Assert_print_lock);
@@ -67,14 +63,11 @@ Assert(char *exp, char *file, int line)
exp, file, line);
#endif
-#if MACH_KDB
- if (db_breakpoints_inserted)
-#endif
Debugger("assertion failure");
}
void SoftDebugger(message)
- char * message;
+ const char *message;
{
printf("Debugger invoked: %s\n", message);
@@ -96,7 +89,7 @@ void SoftDebugger(message)
asm("ta 0x81");
#endif /* sun4 */
-#if defined(mips ) || defined(luna88k) || defined(i860) || defined(alpha)
+#if defined(mips ) || defined(i860) || defined(alpha)
gimmeabreak();
#endif
@@ -106,7 +99,7 @@ void SoftDebugger(message)
}
void Debugger(message)
- char * message;
+ const char *message;
{
#if !MACH_KDB
panic("Debugger invoked, but there isn't one!");
@@ -201,14 +194,12 @@ log(int level, const char *fmt, ...)
{
va_list listp;
-#ifdef lint
- level++;
-#endif
va_start(listp, fmt);
_doprnt(fmt, listp, do_cnputc, 0, 0);
va_end(listp);
}
+/* GCC references this for stack protection. */
unsigned char __stack_chk_guard [ sizeof (vm_offset_t) ] =
{
[ sizeof (vm_offset_t) - 3 ] = '\r',
diff --git a/kern/debug.h b/kern/debug.h
index e429bdd1..6c8977b8 100644
--- a/kern/debug.h
+++ b/kern/debug.h
@@ -62,7 +62,7 @@ extern void log (int level, const char *fmt, ...);
extern void panic_init(void);
extern void panic (const char *s, ...) __attribute__ ((noreturn));
-extern void SoftDebugger (char *message);
-extern void Debugger (char *message) __attribute__ ((noreturn));
+extern void SoftDebugger (const char *message);
+extern void Debugger (const char *message) __attribute__ ((noreturn));
#endif /* _mach_debug__debug_ */
diff --git a/kern/elf-load.c b/kern/elf-load.c
index 1d103d3c..441276ef 100644
--- a/kern/elf-load.c
+++ b/kern/elf-load.c
@@ -80,6 +80,8 @@ int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec,
result = (*read_exec)(handle,
ph->p_offset, ph->p_filesz,
ph->p_vaddr, ph->p_memsz, type);
+ if (result)
+ return result;
}
}
diff --git a/kern/eventcount.c b/kern/eventcount.c
index 6fcebff5..a9d7bd41 100644
--- a/kern/eventcount.c
+++ b/kern/eventcount.c
@@ -53,13 +53,6 @@
#include <kern/eventcount.h>
-
-#if NCPUS <= 1
-void simpler_thread_setrun(
- thread_t th,
- boolean_t may_preempt); /* forward */
-#endif
-
#define MAX_EVCS 10 /* xxx for now */
evc_t all_eventcounters[MAX_EVCS];
@@ -105,7 +98,7 @@ evc_destroy(evc_t ev)
* Thread termination.
* HORRIBLE. This stuff needs to be fixed.
*/
-void evc_notify_abort(thread_t thread)
+void evc_notify_abort(const thread_t thread)
{
int i;
evc_t ev;
@@ -130,7 +123,7 @@ void evc_notify_abort(thread_t thread)
* Just so that we return success, and give
* up the stack while blocked
*/
-static void
+static void __attribute__((noreturn))
evc_continue(void)
{
thread_syscall_return(KERN_SUCCESS);
@@ -235,8 +228,8 @@ kern_return_t evc_wait_clear(natural_t ev_id)
void
evc_signal(evc_t ev)
{
- register volatile thread_t thread;
- register int state;
+ volatile thread_t thread;
+ int state;
spl_t s;
if (ev->sanity != ev)
return;
@@ -325,8 +318,8 @@ simpler_thread_setrun(
thread_t th,
boolean_t may_preempt)
{
- register struct run_queue *rq;
- register int whichq;
+ struct run_queue *rq;
+ int whichq;
/*
* XXX should replace queue with a boolean in this case.
@@ -347,7 +340,7 @@ simpler_thread_setrun(
whichq = (th)->sched_pri;
simple_lock(&(rq)->lock); /* lock the run queue */
- enqueue_head(&(rq)->runq[whichq], (queue_entry_t) (th));
+ enqueue_head(&(rq)->runq[whichq], &((th)->links));
if (whichq < (rq)->low || (rq)->count == 0)
(rq)->low = whichq; /* minimize */
diff --git a/kern/eventcount.h b/kern/eventcount.h
index 6872a347..7cc82207 100644
--- a/kern/eventcount.h
+++ b/kern/eventcount.h
@@ -53,7 +53,12 @@ extern void evc_init(evc_t ev),
/* kernel and user visible */
extern kern_return_t evc_wait(natural_t ev_id);
+extern kern_return_t evc_wait_clear(natural_t ev_id);
-extern void evc_notify_abort (thread_t thread);
+#if NCPUS <= 1
+void simpler_thread_setrun(
+ thread_t th,
+ boolean_t may_preempt);
+#endif
#endif /* _KERN_EVENTCOUNT_H_ */
diff --git a/kern/exception.c b/kern/exception.c
index 453a0758..6cb3bfbf 100644
--- a/kern/exception.c
+++ b/kern/exception.c
@@ -47,23 +47,13 @@
#include <kern/processor.h>
#include <kern/sched.h>
#include <kern/sched_prim.h>
+#include <kern/exception.h>
+#include <kern/macros.h>
#include <mach/machine/vm_types.h>
-
-
-extern void exception() __attribute__ ((noreturn));
-extern void exception_try_task() __attribute__ ((noreturn));
-extern void exception_no_server() __attribute__ ((noreturn));
-
-extern void exception_raise() __attribute__ ((noreturn));
-extern kern_return_t exception_parse_reply();
-extern void exception_raise_continue() __attribute__ ((noreturn));
-extern void exception_raise_continue_slow() __attribute__ ((noreturn));
-extern void exception_raise_continue_fast() __attribute__ ((noreturn));
-
#if MACH_KDB
-extern void thread_kdb_return();
-extern void db_printf();
+#include <machine/trap.h>
+#include <ddb/db_output.h>
boolean_t debug_user_with_kdb = FALSE;
#endif /* MACH_KDB */
@@ -93,11 +83,13 @@ boolean_t debug_user_with_kdb = FALSE;
*/
void
-exception(_exception, code, subcode)
- integer_t _exception, code, subcode;
+exception(
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode)
{
- register ipc_thread_t self = current_thread();
- register ipc_port_t exc_port;
+ ipc_thread_t self = current_thread();
+ ipc_port_t exc_port;
if (_exception == KERN_SUCCESS)
panic("exception");
@@ -163,12 +155,14 @@ exception(_exception, code, subcode)
*/
void
-exception_try_task(_exception, code, subcode)
- integer_t _exception, code, subcode;
+exception_try_task(
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode)
{
ipc_thread_t self = current_thread();
- register task_t task = self->task;
- register ipc_port_t exc_port;
+ task_t task = self->task;
+ ipc_port_t exc_port;
/*
* Optimized version of retrieve_task_exception.
@@ -228,9 +222,9 @@ exception_try_task(_exception, code, subcode)
*/
void
-exception_no_server()
+exception_no_server(void)
{
- register ipc_thread_t self = current_thread();
+ ipc_thread_t self = current_thread();
/*
* If this thread is being terminated, cooperate.
@@ -330,12 +324,13 @@ mach_msg_type_t exc_code_proto = {
int exception_raise_misses = 0;
void
-exception_raise(dest_port, thread_port, task_port,
- _exception, code, subcode)
- ipc_port_t dest_port;
- ipc_port_t thread_port;
- ipc_port_t task_port;
- integer_t _exception, code, subcode;
+exception_raise(
+ ipc_port_t dest_port,
+ ipc_port_t thread_port,
+ ipc_port_t task_port,
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode)
{
ipc_thread_t self = current_thread();
ipc_thread_t receiver;
@@ -428,7 +423,7 @@ exception_raise(dest_port, thread_port, task_port,
*/
{
- register ipc_pset_t dest_pset;
+ ipc_pset_t dest_pset;
dest_pset = dest_port->ip_pset;
if (dest_pset == IPS_NULL)
@@ -490,7 +485,7 @@ exception_raise(dest_port, thread_port, task_port,
* Release the receiver's reference for his object.
*/
{
- register ipc_object_t object = receiver->ith_object;
+ ipc_object_t object = receiver->ith_object;
io_lock(object);
io_release(object);
@@ -498,7 +493,7 @@ exception_raise(dest_port, thread_port, task_port,
}
{
- register struct mach_exception *exc =
+ struct mach_exception *exc =
(struct mach_exception *) &kmsg->ikm_header;
ipc_space_t space = receiver->task->itk_space;
@@ -609,30 +604,18 @@ exception_raise(dest_port, thread_port, task_port,
ip_unlock(reply_port);
{
- register ipc_entry_t table;
- register ipc_entry_t entry;
- register mach_port_index_t index;
-
- /* optimized ipc_entry_get */
-
- table = space->is_table;
- index = table->ie_next;
+ kern_return_t kr;
+ ipc_entry_t entry;
- if (index == 0)
+ kr = ipc_entry_get (space, &exc->Head.msgh_remote_port, &entry);
+ if (kr)
goto abort_copyout;
-
- entry = &table[index];
- table->ie_next = entry->ie_next;
- entry->ie_request = 0;
-
{
- register mach_port_gen_t gen;
+ mach_port_gen_t gen;
assert((entry->ie_bits &~ IE_BITS_GEN_MASK) == 0);
gen = entry->ie_bits + IE_BITS_GEN_ONE;
- exc->Head.msgh_remote_port = MACH_PORT_MAKE(index, gen);
-
/* optimized ipc_right_copyout */
entry->ie_bits = gen | (MACH_PORT_TYPE_SEND_ONCE | 1);
@@ -710,7 +693,7 @@ exception_raise(dest_port, thread_port, task_port,
#endif
slow_exception_raise: {
- register struct mach_exception *exc =
+ struct mach_exception *exc =
(struct mach_exception *) &kmsg->ikm_header;
ipc_kmsg_t reply_kmsg;
mach_port_seqno_t reply_seqno;
@@ -772,6 +755,12 @@ exception_raise(dest_port, thread_port, task_port,
}
}
+/* Macro used by MIG to cleanly check the type. */
+#define BAD_TYPECHECK(type, check) unlikely (({\
+ union { mach_msg_type_t t; unsigned32_t w; } _t, _c;\
+ _t.t = *(type); _c.t = *(check);_t.w != _c.w; }))
+
+/* Type descriptor for the return code. */
mach_msg_type_t exc_RetCode_proto = {
/* msgt_name = */ MACH_MSG_TYPE_INTEGER_32,
/* msgt_size = */ 32,
@@ -794,10 +783,9 @@ mach_msg_type_t exc_RetCode_proto = {
*/
kern_return_t
-exception_parse_reply(kmsg)
- ipc_kmsg_t kmsg;
+exception_parse_reply(ipc_kmsg_t kmsg)
{
- register mig_reply_header_t *msg =
+ mig_reply_header_t *msg =
(mig_reply_header_t *) &kmsg->ikm_header;
kern_return_t kr;
@@ -805,7 +793,7 @@ exception_parse_reply(kmsg)
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0)) ||
(msg->Head.msgh_size != sizeof *msg) ||
(msg->Head.msgh_id != MACH_EXCEPTION_REPLY_ID) ||
- (* (int *) &msg->RetCodeType != * (int *) &exc_RetCode_proto)) {
+ (BAD_TYPECHECK(&msg->RetCodeType, &exc_RetCode_proto))) {
/*
* Bozo user sent us a misformatted reply.
*/
@@ -839,7 +827,7 @@ exception_parse_reply(kmsg)
*/
void
-exception_raise_continue()
+exception_raise_continue(void)
{
ipc_thread_t self = current_thread();
ipc_port_t reply_port = self->ith_port;
@@ -871,10 +859,10 @@ exception_raise_continue()
*/
void
-exception_raise_continue_slow(mr, kmsg, seqno)
- mach_msg_return_t mr;
- ipc_kmsg_t kmsg;
- mach_port_seqno_t seqno;
+exception_raise_continue_slow(
+ mach_msg_return_t mr,
+ ipc_kmsg_t kmsg,
+ mach_port_seqno_t seqno)
{
ipc_thread_t self = current_thread();
ipc_port_t reply_port = self->ith_port;
@@ -954,9 +942,9 @@ exception_raise_continue_slow(mr, kmsg, seqno)
*/
void
-exception_raise_continue_fast(reply_port, kmsg)
- ipc_port_t reply_port;
- ipc_kmsg_t kmsg;
+exception_raise_continue_fast(
+ ipc_port_t reply_port,
+ ipc_kmsg_t kmsg)
{
ipc_thread_t self = current_thread();
kern_return_t kr;
diff --git a/kern/exception.h b/kern/exception.h
new file mode 100644
index 00000000..55902dd1
--- /dev/null
+++ b/kern/exception.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _KERN_EXCEPTION_H_
+#define _KERN_EXCEPTION_H_
+
+#include <ipc/ipc_types.h>
+#include <ipc/ipc_kmsg.h>
+
+extern void
+exception(
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode) __attribute__ ((noreturn));
+
+extern void
+exception_try_task(
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode) __attribute__ ((noreturn));
+
+extern void
+exception_no_server(void) __attribute__ ((noreturn));
+
+extern void
+exception_raise(
+ ipc_port_t dest_port,
+ ipc_port_t thread_port,
+ ipc_port_t task_port,
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode) __attribute__ ((noreturn));
+
+extern kern_return_t
+exception_parse_reply(ipc_kmsg_t kmsg);
+
+extern void
+exception_raise_continue(void) __attribute__ ((noreturn));
+
+extern void
+exception_raise_continue_slow(
+ mach_msg_return_t mr,
+ ipc_kmsg_t kmsg,
+ mach_port_seqno_t seqno) __attribute__ ((noreturn));
+
+extern void
+exception_raise_continue_fast(
+ ipc_port_t reply_port,
+ ipc_kmsg_t kmsg) __attribute__ ((noreturn));
+
+#endif /* _KERN_EXCEPTION_H_ */
diff --git a/kern/host.c b/kern/host.c
index 57a40b43..2855cd2d 100644
--- a/kern/host.c
+++ b/kern/host.c
@@ -47,12 +47,12 @@
host_data_t realhost;
kern_return_t host_processors(
- host_t host,
+ const host_t host,
processor_array_t *processor_list,
natural_t *countp)
{
- register int i;
- register processor_t *tp;
+ int i;
+ processor_t *tp;
vm_offset_t addr;
unsigned int count;
@@ -95,12 +95,12 @@ kern_return_t host_processors(
}
kern_return_t host_info(
- host_t host,
+ const host_t host,
int flavor,
host_info_t info,
natural_t *count)
{
- register integer_t i, *slot_ptr;
+ integer_t i, *slot_ptr;
if (host == HOST_NULL)
return KERN_INVALID_ARGUMENT;
@@ -109,7 +109,7 @@ kern_return_t host_info(
case HOST_BASIC_INFO:
{
- register host_basic_info_t basic_info;
+ host_basic_info_t basic_info;
/*
* Basic information about this host.
@@ -152,7 +152,7 @@ kern_return_t host_info(
case HOST_SCHED_INFO:
{
- register host_sched_info_t sched_info;
+ host_sched_info_t sched_info;
extern int min_quantum;
/* minimum quantum, in microseconds */
@@ -174,7 +174,7 @@ kern_return_t host_info(
case HOST_LOAD_INFO:
{
- register host_load_info_t load_info;
+ host_load_info_t load_info;
extern long avenrun[3], mach_factor[3];
if (*count < HOST_LOAD_INFO_COUNT)
@@ -204,7 +204,7 @@ kern_return_t host_info(
*/
kern_return_t host_kernel_version(
- host_t host,
+ const host_t host,
kernel_version_t out_version)
{
extern char version[];
@@ -225,7 +225,7 @@ kern_return_t host_kernel_version(
#if MACH_HOST
kern_return_t
host_processor_sets(
- host_t host,
+ const host_t host,
processor_set_name_array_t *pset_list,
natural_t *count)
{
@@ -302,7 +302,7 @@ host_processor_sets(
return KERN_RESOURCE_SHORTAGE;
}
- memcpy((char *) newaddr, (char *) addr, size_needed);
+ memcpy((void *) newaddr, (void *) addr, size_needed);
kfree(addr, size);
psets = (processor_set_t *) newaddr;
}
@@ -324,7 +324,7 @@ host_processor_sets(
*/
kern_return_t
host_processor_sets(
- host_t host,
+ const host_t host,
processor_set_name_array_t *pset_list,
natural_t *count)
{
@@ -362,7 +362,7 @@ host_processor_sets(
*/
kern_return_t
host_processor_set_priv(
- host_t host,
+ const host_t host,
processor_set_t pset_name,
processor_set_t *pset)
{
diff --git a/kern/ipc_host.c b/kern/ipc_host.c
index cd1c11ab..a02eb6f6 100644
--- a/kern/ipc_host.c
+++ b/kern/ipc_host.c
@@ -205,7 +205,7 @@ ipc_pset_terminate(
*/
kern_return_t
processor_set_default(
- host_t host,
+ const host_t host,
processor_set_t *pset)
{
if (host == HOST_NULL)
diff --git a/kern/ipc_kobject.c b/kern/ipc_kobject.c
index 37d4eb99..709ec9ec 100644
--- a/kern/ipc_kobject.c
+++ b/kern/ipc_kobject.c
@@ -49,8 +49,21 @@
#include <vm/memory_object_proxy.h>
#include <device/ds_routines.h>
+#include <kern/mach.server.h>
+#include <ipc/mach_port.server.h>
+#include <kern/mach_host.server.h>
+#include <device/device.server.h>
+#include <device/device_pager.server.h>
+#include <kern/mach4.server.h>
+#include <kern/gnumach.server.h>
+
+#if MACH_DEBUG
+#include <kern/mach_debug.server.h>
+#endif
+
#if MACH_MACHINE_ROUTINES
#include <machine/machine_routines.h>
+#include MACHINE_SERVER_HEADER
#endif
@@ -146,21 +159,6 @@ ipc_kobject_server(request)
* to perform the kernel function
*/
{
- extern mig_routine_t mach_server_routine(),
- mach_port_server_routine(),
- mach_host_server_routine(),
- device_server_routine(),
- device_pager_server_routine(),
- mach4_server_routine(),
- gnumach_server_routine();
-#if MACH_DEBUG
- extern mig_routine_t mach_debug_server_routine();
-#endif
-
-#if MACH_MACHINE_ROUTINES
- extern mig_routine_t MACHINE_SERVER_ROUTINE();
-#endif
-
check_simple_locks();
if ((routine = mach_server_routine(&request->ikm_header)) != 0
|| (routine = mach_port_server_routine(&request->ikm_header)) != 0
@@ -246,7 +244,7 @@ ipc_kobject_server(request)
} else {
/*
* The message contents of the request are intact.
- * Destroy everthing except the reply port right,
+ * Destroy everything except the reply port right,
* which is needed in the reply message.
*/
diff --git a/kern/ipc_kobject.h b/kern/ipc_kobject.h
index cb795741..606a66a9 100644
--- a/kern/ipc_kobject.h
+++ b/kern/ipc_kobject.h
@@ -36,13 +36,12 @@
* Declarations for letting a port represent a kernel object.
*/
-#include <ipc/ipc_kmsg.h>
-#include <ipc/ipc_types.h>
-
#ifndef _KERN_IPC_KOBJECT_H_
#define _KERN_IPC_KOBJECT_H_
#include <mach/machine/vm_types.h>
+#include <ipc/ipc_types.h>
+#include <ipc/ipc_kmsg.h>
typedef vm_offset_t ipc_kobject_t;
diff --git a/kern/ipc_mig.c b/kern/ipc_mig.c
index 3f55da7c..22dac420 100644
--- a/kern/ipc_mig.c
+++ b/kern/ipc_mig.c
@@ -37,6 +37,7 @@
#include <kern/task.h>
#include <kern/ipc_kobject.h>
#include <kern/ipc_tt.h>
+#include <kern/ipc_mig.h>
#include <vm/vm_map.h>
#include <vm/vm_user.h>
#include <ipc/port.h>
@@ -91,7 +92,7 @@ mach_msg_send_from_kernel(
mach_msg_return_t
mach_msg_rpc_from_kernel(msg, send_size, reply_size)
- mach_msg_header_t *msg;
+ const mach_msg_header_t *msg;
mach_msg_size_t send_size;
mach_msg_size_t reply_size;
{
@@ -109,8 +110,7 @@ mach_msg_rpc_from_kernel(msg, send_size, reply_size)
*/
void
-mach_msg_abort_rpc(thread)
- ipc_thread_t thread;
+mach_msg_abort_rpc(ipc_thread_t thread)
{
ipc_port_t reply = IP_NULL;
@@ -140,14 +140,14 @@ mach_msg_abort_rpc(thread)
*/
mach_msg_return_t
-mach_msg(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
- mach_msg_header_t *msg;
- mach_msg_option_t option;
- mach_msg_size_t send_size;
- mach_msg_size_t rcv_size;
- mach_port_t rcv_name;
- mach_msg_timeout_t time_out;
- mach_port_t notify;
+mach_msg(
+ mach_msg_header_t *msg,
+ mach_msg_option_t option,
+ mach_msg_size_t send_size,
+ mach_msg_size_t rcv_size,
+ mach_port_t rcv_name,
+ mach_msg_timeout_t time_out,
+ mach_port_t notify)
{
ipc_space_t space = current_space();
vm_map_t map = current_map();
@@ -271,10 +271,10 @@ mig_put_reply_port(
/*
* mig_strncpy.c - by Joshua Block
*
- * mig_strncp -- Bounded string copy. Does what the library routine strncpy
- * OUGHT to do: Copies the (null terminated) string in src into dest, a
- * buffer of length len. Assures that the copy is still null terminated
- * and doesn't overflow the buffer, truncating the copy if necessary.
+ * mig_strncpy -- Bounded string copy. Does what the library routine
+ * strncpy does: Copies the (null terminated) string in src into dest,
+ * a buffer of length len. Returns the length of the destination
+ * string excluding the terminating null.
*
* Parameters:
*
@@ -284,37 +284,44 @@ mig_put_reply_port(
*
* len - Length of destination buffer.
*/
-void mig_strncpy(dest, src, len)
-char *dest, *src;
-int len;
+vm_size_t
+mig_strncpy(dest, src, len)
+ char *dest;
+ const char *src;
+ int len;
{
- int i;
+ char *dest_ = dest;
+ int i;
- if (len <= 0)
- return;
+ if (len <= 0)
+ return 0;
- for (i=1; i<len; i++)
- if (! (*dest++ = *src++))
- return;
+ for (i = 0; i < len; i++) {
+ if (! (*dest = *src))
+ break;
+ dest++;
+ src++;
+ }
- *dest = '\0';
- return;
+ return dest - dest_;
}
#define fast_send_right_lookup(name, port, abort) \
MACRO_BEGIN \
- register ipc_space_t space = current_space(); \
- register ipc_entry_t entry; \
- register mach_port_index_t index = MACH_PORT_INDEX(name); \
+ ipc_space_t space = current_space(); \
+ ipc_entry_t entry; \
\
is_read_lock(space); \
assert(space->is_active); \
\
- if ((index >= space->is_table_size) || \
- (((entry = &space->is_table[index])->ie_bits & \
- (IE_BITS_GEN_MASK|MACH_PORT_TYPE_SEND)) != \
- (MACH_PORT_GEN(name) | MACH_PORT_TYPE_SEND))) { \
- is_read_unlock(space); \
+ entry = ipc_entry_lookup (space, name); \
+ if (entry == IE_NULL) { \
+ is_read_unlock (space); \
+ abort; \
+ } \
+ \
+ if (IE_BITS_TYPE (entry->ie_bits) != MACH_PORT_TYPE_SEND) { \
+ is_read_unlock (space); \
abort; \
} \
\
@@ -327,11 +334,10 @@ MACRO_BEGIN \
MACRO_END
device_t
-port_name_to_device(name)
- mach_port_t name;
+port_name_to_device(mach_port_t name)
{
- register ipc_port_t port;
- register device_t device;
+ ipc_port_t port;
+ device_t device;
fast_send_right_lookup(name, port, goto abort);
/* port is locked */
@@ -371,17 +377,16 @@ port_name_to_device(name)
}
thread_t
-port_name_to_thread(name)
- mach_port_t name;
+port_name_to_thread(mach_port_t name)
{
- register ipc_port_t port;
+ ipc_port_t port;
fast_send_right_lookup(name, port, goto abort);
/* port is locked */
if (ip_active(port) &&
(ip_kotype(port) == IKOT_THREAD)) {
- register thread_t thread;
+ thread_t thread;
thread = (thread_t) port->ip_kobject;
assert(thread != THREAD_NULL);
@@ -417,17 +422,16 @@ port_name_to_thread(name)
}
task_t
-port_name_to_task(name)
- mach_port_t name;
+port_name_to_task(mach_port_t name)
{
- register ipc_port_t port;
+ ipc_port_t port;
fast_send_right_lookup(name, port, goto abort);
/* port is locked */
if (ip_active(port) &&
(ip_kotype(port) == IKOT_TASK)) {
- register task_t task;
+ task_t task;
task = (task_t) port->ip_kobject;
assert(task != TASK_NULL);
@@ -468,14 +472,14 @@ vm_map_t
port_name_to_map(
mach_port_t name)
{
- register ipc_port_t port;
+ ipc_port_t port;
fast_send_right_lookup(name, port, goto abort);
/* port is locked */
if (ip_active(port) &&
(ip_kotype(port) == IKOT_TASK)) {
- register vm_map_t map;
+ vm_map_t map;
map = ((task_t) port->ip_kobject)->map;
assert(map != VM_MAP_NULL);
@@ -513,17 +517,16 @@ port_name_to_map(
}
ipc_space_t
-port_name_to_space(name)
- mach_port_t name;
+port_name_to_space(mach_port_t name)
{
- register ipc_port_t port;
+ ipc_port_t port;
fast_send_right_lookup(name, port, goto abort);
/* port is locked */
if (ip_active(port) &&
(ip_kotype(port) == IKOT_TASK)) {
- register ipc_space_t space;
+ ipc_space_t space;
space = ((task_t) port->ip_kobject)->itk_space;
assert(space != IS_NULL);
@@ -569,12 +572,11 @@ port_name_to_space(name)
* AARGH!
*/
-kern_return_t thread_get_state_KERNEL(thread_port, flavor,
- old_state, old_state_count)
- mach_port_t thread_port; /* port right for thread */
- int flavor;
- thread_state_t old_state; /* pointer to OUT array */
- natural_t *old_state_count; /* IN/OUT */
+kern_return_t thread_get_state_KERNEL(
+ mach_port_t thread_port, /* port right for thread */
+ int flavor,
+ thread_state_t old_state, /* pointer to OUT array */
+ natural_t *old_state_count) /* IN/OUT */
{
thread_t thread;
kern_return_t result;
@@ -586,12 +588,11 @@ kern_return_t thread_get_state_KERNEL(thread_port, flavor,
return result;
}
-kern_return_t thread_set_state_KERNEL(thread_port, flavor,
- new_state, new_state_count)
- mach_port_t thread_port; /* port right for thread */
- int flavor;
- thread_state_t new_state;
- natural_t new_state_count;
+kern_return_t thread_set_state_KERNEL(
+ mach_port_t thread_port, /* port right for thread */
+ int flavor,
+ thread_state_t new_state,
+ natural_t new_state_count)
{
thread_t thread;
kern_return_t result;
@@ -613,7 +614,7 @@ kern_return_t thread_set_state_KERNEL(thread_port, flavor,
* knows to fall back on an RPC. For other return values, it won't
* retry with an RPC. The retry might get a different (incorrect) rc.
* Return values are only set (and should only be set, with copyout)
- * on successfull calls.
+ * on successful calls.
*/
kern_return_t
@@ -650,12 +651,12 @@ syscall_vm_map(
} else
port = (ipc_port_t) memory_object;
- copyin((char *)address, (char *)&addr, sizeof(vm_offset_t));
+ copyin(address, &addr, sizeof(vm_offset_t));
result = vm_map(map, &addr, size, mask, anywhere,
port, offset, copy,
cur_protection, max_protection, inheritance);
if (result == KERN_SUCCESS)
- copyout((char *)&addr, (char *)address, sizeof(vm_offset_t));
+ copyout(&addr, address, sizeof(vm_offset_t));
if (IP_VALID(port))
ipc_port_release_send(port);
vm_map_deallocate(map);
@@ -663,11 +664,11 @@ syscall_vm_map(
return result;
}
-kern_return_t syscall_vm_allocate(target_map, address, size, anywhere)
- mach_port_t target_map;
- vm_offset_t *address;
- vm_size_t size;
- boolean_t anywhere;
+kern_return_t syscall_vm_allocate(
+ mach_port_t target_map,
+ vm_offset_t *address,
+ vm_size_t size,
+ boolean_t anywhere)
{
vm_map_t map;
vm_offset_t addr;
@@ -677,19 +678,19 @@ kern_return_t syscall_vm_allocate(target_map, address, size, anywhere)
if (map == VM_MAP_NULL)
return MACH_SEND_INTERRUPTED;
- copyin((char *)address, (char *)&addr, sizeof(vm_offset_t));
+ copyin(address, &addr, sizeof(vm_offset_t));
result = vm_allocate(map, &addr, size, anywhere);
if (result == KERN_SUCCESS)
- copyout((char *)&addr, (char *)address, sizeof(vm_offset_t));
+ copyout(&addr, address, sizeof(vm_offset_t));
vm_map_deallocate(map);
return result;
}
-kern_return_t syscall_vm_deallocate(target_map, start, size)
- mach_port_t target_map;
- vm_offset_t start;
- vm_size_t size;
+kern_return_t syscall_vm_deallocate(
+ mach_port_t target_map,
+ vm_offset_t start,
+ vm_size_t size)
{
vm_map_t map;
kern_return_t result;
@@ -704,10 +705,10 @@ kern_return_t syscall_vm_deallocate(target_map, start, size)
return result;
}
-kern_return_t syscall_task_create(parent_task, inherit_memory, child_task)
- mach_port_t parent_task;
- boolean_t inherit_memory;
- mach_port_t *child_task; /* OUT */
+kern_return_t syscall_task_create(
+ mach_port_t parent_task,
+ boolean_t inherit_memory,
+ mach_port_t *child_task) /* OUT */
{
task_t t, c;
ipc_port_t port;
@@ -725,7 +726,7 @@ kern_return_t syscall_task_create(parent_task, inherit_memory, child_task)
(void) ipc_kmsg_copyout_object(current_space(),
(ipc_object_t) port,
MACH_MSG_TYPE_PORT_SEND, &name);
- copyout((char *)&name, (char *)child_task,
+ copyout(&name, child_task,
sizeof(mach_port_t));
}
task_deallocate(t);
@@ -733,8 +734,7 @@ kern_return_t syscall_task_create(parent_task, inherit_memory, child_task)
return result;
}
-kern_return_t syscall_task_terminate(task)
- mach_port_t task;
+kern_return_t syscall_task_terminate(mach_port_t task)
{
task_t t;
kern_return_t result;
@@ -749,8 +749,7 @@ kern_return_t syscall_task_terminate(task)
return result;
}
-kern_return_t syscall_task_suspend(task)
- mach_port_t task;
+kern_return_t syscall_task_suspend(mach_port_t task)
{
task_t t;
kern_return_t result;
@@ -765,10 +764,10 @@ kern_return_t syscall_task_suspend(task)
return result;
}
-kern_return_t syscall_task_set_special_port(task, which_port, port_name)
- mach_port_t task;
- int which_port;
- mach_port_t port_name;
+kern_return_t syscall_task_set_special_port(
+ mach_port_t task,
+ int which_port,
+ mach_port_t port_name)
{
task_t t;
ipc_port_t port;
@@ -798,10 +797,10 @@ kern_return_t syscall_task_set_special_port(task, which_port, port_name)
}
kern_return_t
-syscall_mach_port_allocate(task, right, namep)
- mach_port_t task;
- mach_port_right_t right;
- mach_port_t *namep;
+syscall_mach_port_allocate(
+ mach_port_t task,
+ mach_port_right_t right,
+ mach_port_t *namep)
{
ipc_space_t space;
mach_port_t name;
@@ -813,17 +812,17 @@ syscall_mach_port_allocate(task, right, namep)
kr = mach_port_allocate(space, right, &name);
if (kr == KERN_SUCCESS)
- copyout((char *)&name, (char *)namep, sizeof(mach_port_t));
+ copyout(&name, namep, sizeof(mach_port_t));
is_release(space);
return kr;
}
kern_return_t
-syscall_mach_port_allocate_name(task, right, name)
- mach_port_t task;
- mach_port_right_t right;
- mach_port_t name;
+syscall_mach_port_allocate_name(
+ mach_port_t task,
+ mach_port_right_t right,
+ mach_port_t name)
{
ipc_space_t space;
kern_return_t kr;
@@ -839,9 +838,9 @@ syscall_mach_port_allocate_name(task, right, name)
}
kern_return_t
-syscall_mach_port_deallocate(task, name)
- mach_port_t task;
- mach_port_t name;
+syscall_mach_port_deallocate(
+ mach_port_t task,
+ mach_port_t name)
{
ipc_space_t space;
kern_return_t kr;
@@ -857,11 +856,11 @@ syscall_mach_port_deallocate(task, name)
}
kern_return_t
-syscall_mach_port_insert_right(task, name, right, rightType)
- mach_port_t task;
- mach_port_t name;
- mach_port_t right;
- mach_msg_type_name_t rightType;
+syscall_mach_port_insert_right(
+ mach_port_t task,
+ mach_port_t name,
+ mach_port_t right,
+ mach_msg_type_name_t rightType)
{
ipc_space_t space;
ipc_object_t object;
@@ -896,8 +895,7 @@ syscall_mach_port_insert_right(task, name, right, rightType)
return kr;
}
-kern_return_t syscall_thread_depress_abort(thread)
- mach_port_t thread;
+kern_return_t syscall_thread_depress_abort(mach_port_t thread)
{
thread_t t;
kern_return_t result;
@@ -915,10 +913,6 @@ kern_return_t syscall_thread_depress_abort(thread)
/*
* Device traps -- these are way experimental.
*/
-
-extern io_return_t ds_device_write_trap();
-extern io_return_t ds_device_writev_trap();
-
io_return_t
syscall_device_write_request(mach_port_t device_name,
mach_port_t reply_name,
@@ -928,7 +922,7 @@ syscall_device_write_request(mach_port_t device_name,
vm_size_t data_count)
{
device_t dev;
- ipc_port_t reply_port;
+ /*ipc_port_t reply_port;*/
io_return_t res;
/*
@@ -949,9 +943,10 @@ syscall_device_write_request(mach_port_t device_name,
/*
* Translate reply port.
*/
- if (reply_name == MACH_PORT_NULL)
+ /*if (reply_name == MACH_PORT_NULL)
reply_port = IP_NULL;
- else {
+ */
+ if (reply_name != MACH_PORT_NULL) {
/* Homey don't play that. */
device_deallocate(dev);
return KERN_INVALID_RIGHT;
@@ -978,7 +973,7 @@ syscall_device_writev_request(mach_port_t device_name,
vm_size_t iocount)
{
device_t dev;
- ipc_port_t reply_port;
+ /*ipc_port_t reply_port;*/
io_return_t res;
/*
@@ -999,9 +994,10 @@ syscall_device_writev_request(mach_port_t device_name,
/*
* Translate reply port.
*/
- if (reply_name == MACH_PORT_NULL)
+ /*if (reply_name == MACH_PORT_NULL)
reply_port = IP_NULL;
- else {
+ */
+ if (reply_name != MACH_PORT_NULL) {
/* Homey don't play that. */
device_deallocate(dev);
return KERN_INVALID_RIGHT;
diff --git a/kern/ipc_mig.h b/kern/ipc_mig.h
index f352bdc6..6f063eca 100644
--- a/kern/ipc_mig.h
+++ b/kern/ipc_mig.h
@@ -27,6 +27,7 @@
#define _IPC_MIG_H_
#include <mach/std_types.h>
+#include <device/device_types.h>
/*
* Routine: mach_msg_send_from_kernel
@@ -58,8 +59,84 @@ extern mach_msg_return_t mach_msg_send_from_kernel(
extern void mach_msg_abort_rpc (ipc_thread_t);
extern mach_msg_return_t mach_msg_rpc_from_kernel(
- mach_msg_header_t *msg,
+ const mach_msg_header_t *msg,
mach_msg_size_t send_size,
mach_msg_size_t reply_size);
+extern kern_return_t syscall_vm_map(
+ mach_port_t target_map,
+ vm_offset_t *address,
+ vm_size_t size,
+ vm_offset_t mask,
+ boolean_t anywhere,
+ mach_port_t memory_object,
+ vm_offset_t offset,
+ boolean_t copy,
+ vm_prot_t cur_protection,
+ vm_prot_t max_protection,
+ vm_inherit_t inheritance);
+
+extern kern_return_t syscall_vm_allocate(
+ mach_port_t target_map,
+ vm_offset_t *address,
+ vm_size_t size,
+ boolean_t anywhere);
+
+extern kern_return_t syscall_vm_deallocate(
+ mach_port_t target_map,
+ vm_offset_t start,
+ vm_size_t size);
+
+extern kern_return_t syscall_task_create(
+ mach_port_t parent_task,
+ boolean_t inherit_memory,
+ mach_port_t *child_task);
+
+extern kern_return_t syscall_task_terminate(mach_port_t task);
+
+extern kern_return_t syscall_task_suspend(mach_port_t task);
+
+extern kern_return_t syscall_task_set_special_port(
+ mach_port_t task,
+ int which_port,
+ mach_port_t port_name);
+
+extern kern_return_t syscall_mach_port_allocate(
+ mach_port_t task,
+ mach_port_right_t right,
+ mach_port_t *namep);
+
+extern kern_return_t syscall_mach_port_deallocate(
+ mach_port_t task,
+ mach_port_t name);
+
+extern kern_return_t syscall_mach_port_insert_right(
+ mach_port_t task,
+ mach_port_t name,
+ mach_port_t right,
+ mach_msg_type_name_t rightType);
+
+extern kern_return_t syscall_mach_port_allocate_name(
+ mach_port_t task,
+ mach_port_right_t right,
+ mach_port_t name);
+
+extern kern_return_t syscall_thread_depress_abort(mach_port_t thread);
+
+extern io_return_t syscall_device_write_request(
+ mach_port_t device_name,
+ mach_port_t reply_name,
+ dev_mode_t mode,
+ recnum_t recnum,
+ vm_offset_t data,
+ vm_size_t data_count);
+
+io_return_t syscall_device_writev_request(
+ mach_port_t device_name,
+ mach_port_t reply_name,
+ dev_mode_t mode,
+ recnum_t recnum,
+ io_buf_vec_t *iovec,
+ vm_size_t iocount);
+
#endif /* _IPC_MIG_H_ */
diff --git a/kern/ipc_sched.c b/kern/ipc_sched.c
index 615ad608..be82971b 100644
--- a/kern/ipc_sched.c
+++ b/kern/ipc_sched.c
@@ -182,9 +182,9 @@ thread_will_wait_with_timeout(
boolean_t
thread_handoff(
- register thread_t old,
- register continuation_t continuation,
- register thread_t new)
+ thread_t old,
+ continuation_t continuation,
+ thread_t new)
{
spl_t s;
@@ -214,7 +214,7 @@ thread_handoff(
thread_unlock(new);
(void) splx(s);
- counter_always(c_thread_handoff_misses++);
+ counter(c_thread_handoff_misses++);
return FALSE;
}
@@ -268,7 +268,7 @@ thread_handoff(
*/
old->wake_active = FALSE;
thread_unlock(old);
- thread_wakeup((event_t)&old->wake_active);
+ thread_wakeup(TH_EV_WAKE_ACTIVE(old));
goto after_old_thread;
}
} else
@@ -278,6 +278,6 @@ thread_handoff(
after_old_thread:
(void) splx(s);
- counter_always(c_thread_handoff_hits++);
+ counter(c_thread_handoff_hits++);
return TRUE;
}
diff --git a/kern/ipc_tt.c b/kern/ipc_tt.c
index 6d32e5b0..e4d657b7 100644
--- a/kern/ipc_tt.c
+++ b/kern/ipc_tt.c
@@ -72,7 +72,7 @@ ipc_task_init(
int i;
- kr = ipc_space_create(&ipc_table_entries[0], &space);
+ kr = ipc_space_create(&space);
if (kr != KERN_SUCCESS)
panic("ipc_task_init");
@@ -213,8 +213,7 @@ ipc_task_terminate(
*/
void
-ipc_thread_init(thread)
- thread_t thread;
+ipc_thread_init(thread_t thread)
{
ipc_port_t kport;
@@ -243,8 +242,7 @@ ipc_thread_init(thread)
*/
void
-ipc_thread_enable(thread)
- thread_t thread;
+ipc_thread_enable(thread_t thread)
{
ipc_port_t kport;
@@ -264,8 +262,7 @@ ipc_thread_enable(thread)
*/
void
-ipc_thread_disable(thread)
- thread_t thread;
+ipc_thread_disable(thread_t thread)
{
ipc_port_t kport;
@@ -286,8 +283,7 @@ ipc_thread_disable(thread)
*/
void
-ipc_thread_terminate(thread)
- thread_t thread;
+ipc_thread_terminate(thread_t thread)
{
ipc_port_t kport;
@@ -387,9 +383,9 @@ retrieve_thread_self(thread)
ipc_port_t
retrieve_task_self_fast(
- register task_t task)
+ task_t task)
{
- register ipc_port_t port;
+ ipc_port_t port;
assert(task == current_task());
@@ -424,10 +420,9 @@ retrieve_task_self_fast(
*/
ipc_port_t
-retrieve_thread_self_fast(thread)
- register thread_t thread;
+retrieve_thread_self_fast(thread_t thread)
{
- register ipc_port_t port;
+ ipc_port_t port;
assert(thread == current_thread());
@@ -648,9 +643,9 @@ task_get_special_port(
kern_return_t
task_set_special_port(
- task_t task,
- int which,
- ipc_port_t port)
+ task_t task,
+ int which,
+ const ipc_port_t port)
{
ipc_port_t *whichp;
ipc_port_t old;
@@ -705,10 +700,10 @@ task_set_special_port(
*/
kern_return_t
-thread_get_special_port(thread, which, portp)
- thread_t thread;
- int which;
- ipc_port_t *portp;
+thread_get_special_port(
+ thread_t thread,
+ int which,
+ ipc_port_t *portp)
{
ipc_port_t *whichp;
ipc_port_t port;
@@ -758,10 +753,10 @@ thread_get_special_port(thread, which, portp)
*/
kern_return_t
-thread_set_special_port(thread, which, port)
- thread_t thread;
- int which;
- ipc_port_t port;
+thread_set_special_port(
+ thread_t thread,
+ int which,
+ ipc_port_t port)
{
ipc_port_t *whichp;
ipc_port_t old;
@@ -890,10 +885,10 @@ mach_ports_register(
*/
kern_return_t
-mach_ports_lookup(task, portsp, portsCnt)
- task_t task;
- ipc_port_t **portsp;
- mach_msg_type_number_t *portsCnt;
+mach_ports_lookup(
+ task_t task,
+ ipc_port_t **portsp,
+ mach_msg_type_number_t *portsCnt)
{
vm_offset_t memory;
vm_size_t size;
@@ -1003,8 +998,7 @@ convert_port_to_space(
*/
vm_map_t
-convert_port_to_map(port)
- ipc_port_t port;
+convert_port_to_map(ipc_port_t port)
{
vm_map_t map = VM_MAP_NULL;
@@ -1032,8 +1026,7 @@ convert_port_to_map(port)
*/
thread_t
-convert_port_to_thread(port)
- ipc_port_t port;
+convert_port_to_thread(ipc_port_t port)
{
thread_t thread = THREAD_NULL;
@@ -1061,8 +1054,7 @@ convert_port_to_thread(port)
*/
ipc_port_t
-convert_task_to_port(task)
- task_t task;
+convert_task_to_port(task_t task)
{
ipc_port_t port;
@@ -1088,8 +1080,7 @@ convert_task_to_port(task)
*/
ipc_port_t
-convert_thread_to_port(thread)
- thread_t thread;
+convert_thread_to_port(thread_t thread)
{
ipc_port_t port;
@@ -1113,8 +1104,7 @@ convert_thread_to_port(thread)
*/
void
-space_deallocate(space)
- ipc_space_t space;
+space_deallocate(ipc_space_t space)
{
if (space != IS_NULL)
is_release(space);
diff --git a/kern/list.h b/kern/list.h
index 03414718..be927625 100644
--- a/kern/list.h
+++ b/kern/list.h
@@ -31,9 +31,7 @@
#include <stddef.h>
#include <sys/types.h>
-
-#define structof(ptr, type, member) \
- ((type *)((char *)ptr - offsetof(type, member)))
+#include <kern/macros.h>
/*
* Structure used as both head and node.
@@ -240,7 +238,7 @@ static inline void list_add(struct list *prev, struct list *next,
/*
* Insert a node at the head of a list.
*/
-static inline void list_insert(struct list *list, struct list *node)
+static inline void list_insert_head(struct list *list, struct list *node)
{
list_add(list, list->next, node);
}
diff --git a/kern/lock.c b/kern/lock.c
index 44d4448e..3c74fec8 100644
--- a/kern/lock.c
+++ b/kern/lock.c
@@ -133,7 +133,7 @@ unsigned int simple_locks_taken = 0;
struct simple_locks_info {
simple_lock_t l;
- unsigned int ra;
+ void *ra;
} simple_locks_info[NSLINFO];
void check_simple_locks(void)
@@ -161,10 +161,8 @@ void simple_lock(
info = &simple_locks_info[simple_locks_taken++];
info->l = l;
- /* XXX we want our return address, if possible */
-#if defined(__i386__)
- info->ra = *((unsigned long *)&l - 1);
-#endif /* i386 */
+ info->ra =
+ __builtin_extract_return_addr (__builtin_return_address (0));
}
boolean_t simple_lock_try(
@@ -179,10 +177,8 @@ boolean_t simple_lock_try(
info = &simple_locks_info[simple_locks_taken++];
info->l = l;
- /* XXX we want our return address, if possible */
-#if defined(__i386__)
- info->ra = *((unsigned long *)&l - 1);
-#endif /* i386 */
+ info->ra =
+ __builtin_extract_return_addr (__builtin_return_address (0));
return TRUE;
}
@@ -250,9 +246,9 @@ void lock_sleepable(
*/
void lock_write(
- register lock_t l)
+ lock_t l)
{
- register int i;
+ int i;
check_simple_locks();
simple_lock(&l->interlock);
@@ -308,7 +304,7 @@ void lock_write(
}
void lock_done(
- register lock_t l)
+ lock_t l)
{
simple_lock(&l->interlock);
@@ -340,9 +336,9 @@ void lock_done(
}
void lock_read(
- register lock_t l)
+ lock_t l)
{
- register int i;
+ int i;
check_simple_locks();
simple_lock(&l->interlock);
@@ -387,9 +383,9 @@ void lock_read(
* Returns TRUE if the upgrade *failed*.
*/
boolean_t lock_read_to_write(
- register lock_t l)
+ lock_t l)
{
- register int i;
+ int i;
check_simple_locks();
simple_lock(&l->interlock);
@@ -443,7 +439,7 @@ boolean_t lock_read_to_write(
}
void lock_write_to_read(
- register lock_t l)
+ lock_t l)
{
simple_lock(&l->interlock);
@@ -474,7 +470,7 @@ void lock_write_to_read(
*/
boolean_t lock_try_write(
- register lock_t l)
+ lock_t l)
{
simple_lock(&l->interlock);
@@ -513,7 +509,7 @@ boolean_t lock_try_write(
*/
boolean_t lock_try_read(
- register lock_t l)
+ lock_t l)
{
simple_lock(&l->interlock);
@@ -547,7 +543,7 @@ boolean_t lock_try_read(
* Returns FALSE if the upgrade *failed*.
*/
boolean_t lock_try_read_to_write(
- register lock_t l)
+ lock_t l)
{
check_simple_locks();
simple_lock(&l->interlock);
diff --git a/kern/lock.h b/kern/lock.h
index a8f2fd1c..a6d286a1 100644
--- a/kern/lock.h
+++ b/kern/lock.h
@@ -94,7 +94,9 @@ extern void check_simple_locks(void);
/*
* Do not allocate storage for locks if not needed.
*/
-#define decl_simple_lock_data(class,name)
+struct simple_lock_data_empty {};
+#define decl_simple_lock_data(class,name) \
+class struct simple_lock_data_empty name;
#define simple_lock_addr(lock) ((simple_lock_t)0)
/*
@@ -102,7 +104,7 @@ extern void check_simple_locks(void);
*/
#define simple_lock_init(l)
#define simple_lock(l)
-#define simple_unlock(l)
+#define simple_unlock(l) ((void)(l))
#define simple_lock_try(l) (TRUE) /* always succeeds */
#define simple_lock_taken(l) (1) /* always succeeds */
#define check_simple_locks()
@@ -171,4 +173,6 @@ extern boolean_t lock_try_read_to_write(lock_t);
extern void lock_set_recursive(lock_t);
extern void lock_clear_recursive(lock_t);
+void db_show_all_slocks(void);
+
#endif /* _KERN_LOCK_H_ */
diff --git a/kern/lock_mon.c b/kern/lock_mon.c
index 14504281..f6bbd5dd 100644
--- a/kern/lock_mon.c
+++ b/kern/lock_mon.c
@@ -64,7 +64,6 @@ typedef unsigned int time_stamp_t;
#define LOCK_INFO_HASH_COUNT 1024
#define LOCK_INFO_PER_BUCKET (LOCK_INFO_MAX/LOCK_INFO_HASH_COUNT)
-
#define HASH_LOCK(lock) ((long)lock>>5 & (LOCK_INFO_HASH_COUNT-1))
struct lock_info {
@@ -85,7 +84,7 @@ struct lock_info_bucket lock_info[LOCK_INFO_HASH_COUNT];
struct lock_info default_lock_info;
unsigned default_lock_stack = 0;
-extern int curr_ipl[];
+extern spl_t curr_ipl[];
@@ -94,8 +93,8 @@ locate_lock_info(lock)
decl_simple_lock_data(, **lock)
{
struct lock_info *li = &(lock_info[HASH_LOCK(*lock)].info[0]);
- register i;
- register my_cpu = cpu_number();
+ int i;
+ my_cpu = cpu_number();
for (i=0; i < LOCK_INFO_PER_BUCKET; i++, li++)
if (li->lock) {
@@ -112,11 +111,11 @@ decl_simple_lock_data(, **lock)
}
-simple_lock(lock)
+void simple_lock(lock)
decl_simple_lock_data(, *lock)
{
- register struct lock_info *li = locate_lock_info(&lock);
- register my_cpu = cpu_number();
+ struct lock_info *li = locate_lock_info(&lock);
+ my_cpu = cpu_number();
if (current_thread())
li->stack = current_thread()->lock_stack++;
@@ -131,11 +130,11 @@ decl_simple_lock_data(, *lock)
li->time = time_stamp - li->time;
}
-simple_lock_try(lock)
+int simple_lock_try(lock)
decl_simple_lock_data(, *lock)
{
- register struct lock_info *li = locate_lock_info(&lock);
- register my_cpu = cpu_number();
+ struct lock_info *li = locate_lock_info(&lock);
+ my_cpu = cpu_number();
if (curr_ipl[my_cpu])
li->masked++;
@@ -151,12 +150,12 @@ decl_simple_lock_data(, *lock)
}
}
-simple_unlock(lock)
+void simple_unlock(lock)
decl_simple_lock_data(, *lock)
{
- register time_stamp_t stamp = time_stamp;
- register time_stamp_t *time = &locate_lock_info(&lock)->time;
- register unsigned *lock_stack;
+ time_stamp_t stamp = time_stamp;
+ time_stamp_t *time = &locate_lock_info(&lock)->time;
+ unsigned *lock_stack;
*time = stamp - *time;
_simple_unlock(lock);
@@ -167,16 +166,13 @@ decl_simple_lock_data(, *lock)
}
}
-lip() {
+void lip(void) {
lis(4, 1, 0);
}
#define lock_info_sort lis
-unsigned scurval, ssum;
-struct lock_info *sli;
-
-lock_info_sort(arg, abs, count)
+void lock_info_sort(arg, abs, count)
{
struct lock_info *li, mean;
int bucket = 0;
@@ -215,9 +211,6 @@ lock_info_sort(arg, abs, count)
sum = li->success + li->fail;
if(!sum && !abs)
continue;
- scurval = curval;
- ssum = sum;
- sli = li;
if (!abs) switch(arg) {
case 0:
break;
@@ -257,7 +250,7 @@ lock_info_sort(arg, abs, count)
#define lock_info_clear lic
-lock_info_clear()
+void lock_info_clear(void)
{
struct lock_info *li;
int bucket = 0;
@@ -271,7 +264,7 @@ lock_info_clear()
memset(&default_lock_info, 0, sizeof(struct lock_info));
}
-print_lock_info(li)
+void print_lock_info(li)
struct lock_info *li;
{
int off;
@@ -299,11 +292,11 @@ struct lock_info *li;
* Measure lock/unlock operations
*/
-time_lock(loops)
+void time_lock(int loops)
{
decl_simple_lock_data(, lock)
- register time_stamp_t stamp;
- register int i;
+ time_stamp_t stamp;
+ int i;
if (!loops)
@@ -340,7 +333,7 @@ void
retry_simple_lock(lock)
decl_simple_lock_data(, *lock)
{
- register count = 0;
+ count = 0;
while(!simple_lock_try(lock))
if (count++ > 1000000 && lock != &kdb_lock) {
@@ -356,7 +349,7 @@ decl_simple_lock_data(, *lock)
void
retry_bit_lock(index, addr)
{
- register count = 0;
+ count = 0;
while(!bit_lock_try(index, addr))
if (count++ > 1000000) {
diff --git a/kern/mach_clock.c b/kern/mach_clock.c
index edf87f07..b627b89d 100644
--- a/kern/mach_clock.c
+++ b/kern/mach_clock.c
@@ -27,7 +27,7 @@
* the rights to redistribute these changes.
*/
/*
- * File: clock_prim.c
+ * File: mach_clock.c
* Author: Avadis Tevanian, Jr.
* Date: 1986
*
@@ -54,6 +54,7 @@
#include <kern/thread.h>
#include <kern/time_stamp.h>
#include <kern/timer.h>
+#include <kern/priority.h>
#include <vm/vm_kern.h>
#include <sys/time.h>
#include <machine/mach_param.h> /* HZ */
@@ -64,8 +65,6 @@
#include <kern/pc_sample.h>
#endif
-void softclock(); /* forward */
-
int hz = HZ; /* number of ticks per second */
int tick = (1000000 / HZ); /* number of usec per tick */
time_value_t time = { 0, 0 }; /* time since bootup (uncorrected) */
@@ -121,13 +120,13 @@ timer_elt_data_t timer_head; /* ordered list of timeouts */
* the accuracy of the hardware clock.
*
*/
-void clock_interrupt(usec, usermode, basepri)
- register int usec; /* microseconds per tick */
- boolean_t usermode; /* executing user code */
- boolean_t basepri; /* at base priority */
+void clock_interrupt(
+ int usec, /* microseconds per tick */
+ boolean_t usermode, /* executing user code */
+ boolean_t basepri) /* at base priority */
{
- register int my_cpu = cpu_number();
- register thread_t thread = current_thread();
+ int my_cpu = cpu_number();
+ thread_t thread = current_thread();
counter(c_clock_ticks++);
counter(c_threads_total += c_threads_current);
@@ -150,8 +149,7 @@ void clock_interrupt(usec, usermode, basepri)
* Increment the CPU time statistics.
*/
{
- extern void thread_quantum_update(); /* in priority.c */
- register int state;
+ int state;
if (usermode)
state = CPU_STATE_USER;
@@ -187,8 +185,8 @@ void clock_interrupt(usec, usermode, basepri)
*/
if (my_cpu == master_cpu) {
- register spl_t s;
- register timer_elt_t telt;
+ spl_t s;
+ timer_elt_t telt;
boolean_t needsoft = FALSE;
#if TS_FORMAT == 1
@@ -221,7 +219,7 @@ void clock_interrupt(usec, usermode, basepri)
time_value_add_usec(&time, usec);
}
else {
- register int delta;
+ int delta;
if (timedelta < 0) {
delta = usec - tickdelta;
@@ -236,7 +234,7 @@ void clock_interrupt(usec, usermode, basepri)
update_mapped_time(&time);
/*
- * Schedule soft-interupt for timeout if needed
+ * Schedule soft-interrupt for timeout if needed
*/
if (needsoft) {
if (basepri) {
@@ -272,15 +270,15 @@ void clock_interrupt(usec, usermode, basepri)
* and corrupts it.
*/
-void softclock()
+void softclock(void)
{
/*
* Handle timeouts.
*/
spl_t s;
- register timer_elt_t telt;
- register void (*fcn)( void * param );
- register void *param;
+ timer_elt_t telt;
+ void (*fcn)( void * param );
+ void *param;
while (TRUE) {
s = splsched();
@@ -311,12 +309,12 @@ void softclock()
* telt timer element. Function and param are already set.
* interval time-out interval, in hz.
*/
-void set_timeout(telt, interval)
- register timer_elt_t telt; /* already loaded */
- register unsigned int interval;
+void set_timeout(
+ timer_elt_t telt, /* already loaded */
+ unsigned int interval)
{
spl_t s;
- register timer_elt_t next;
+ timer_elt_t next;
s = splsched();
simple_lock(&timer_lock);
@@ -341,8 +339,7 @@ void set_timeout(telt, interval)
splx(s);
}
-boolean_t reset_timeout(telt)
- register timer_elt_t telt;
+boolean_t reset_timeout(timer_elt_t telt)
{
spl_t s;
@@ -362,7 +359,7 @@ boolean_t reset_timeout(telt)
}
}
-void init_timeout()
+void init_timeout(void)
{
simple_lock_init(&timer_lock);
queue_init(&timer_head.chain);
@@ -389,7 +386,7 @@ record_time_stamp (time_value_t *stamp)
*/
kern_return_t
host_get_time(host, current_time)
- host_t host;
+ const host_t host;
time_value_t *current_time; /* OUT */
{
if (host == HOST_NULL)
@@ -408,7 +405,7 @@ host_get_time(host, current_time)
*/
kern_return_t
host_set_time(host, new_time)
- host_t host;
+ const host_t host;
time_value_t new_time;
{
spl_t s;
@@ -446,7 +443,7 @@ host_set_time(host, new_time)
*/
kern_return_t
host_adjust_time(host, new_adjustment, old_adjustment)
- host_t host;
+ const host_t host;
time_value_t new_adjustment;
time_value_t *old_adjustment; /* OUT */
{
@@ -492,7 +489,7 @@ host_adjust_time(host, new_adjustment, old_adjustment)
return (KERN_SUCCESS);
}
-void mapable_time_init()
+void mapable_time_init(void)
{
if (kmem_alloc_wired(kernel_map, (vm_offset_t *) &mtime, PAGE_SIZE)
!= KERN_SUCCESS)
@@ -501,13 +498,13 @@ void mapable_time_init()
update_mapped_time(&time);
}
-int timeopen()
+int timeopen(dev_t dev, int flag, io_req_t ior)
{
return(0);
}
-int timeclose()
+void timeclose(dev_t dev, int flag)
{
- return(0);
+ return;
}
/*
@@ -528,13 +525,13 @@ timer_elt_data_t timeout_timers[NTIMERS];
* param: parameter to pass to function
* interval: timeout interval, in hz.
*/
-void timeout(fcn, param, interval)
- void (*fcn)( void * param );
- void * param;
- int interval;
+void timeout(
+ void (*fcn)(void *param),
+ void * param,
+ int interval)
{
spl_t s;
- register timer_elt_t elt;
+ timer_elt_t elt;
s = splsched();
simple_lock(&timer_lock);
@@ -557,11 +554,11 @@ void timeout(fcn, param, interval)
* and removed.
*/
boolean_t untimeout(fcn, param)
- register void (*fcn)( void * param );
- register void * param;
+ void (*fcn)( void * param );
+ const void * param;
{
spl_t s;
- register timer_elt_t elt;
+ timer_elt_t elt;
s = splsched();
simple_lock(&timer_lock);
diff --git a/kern/mach_clock.h b/kern/mach_clock.h
index 4e4e8ff1..89fd3352 100644
--- a/kern/mach_clock.h
+++ b/kern/mach_clock.h
@@ -29,6 +29,10 @@
#include <mach/time_value.h>
#include <kern/host.h>
#include <kern/queue.h>
+#include <sys/types.h>
+
+struct io_req;
+typedef struct io_req *io_req_t;
/* Timers in kernel. */
@@ -102,6 +106,9 @@ extern void mapable_time_init (void);
/* For public timer elements. */
extern void timeout(timer_func_t *fcn, void *param, int interval);
-extern boolean_t untimeout(timer_func_t *fcn, void *param);
+extern boolean_t untimeout(timer_func_t *fcn, const void *param);
+
+extern int timeopen(dev_t dev, int flag, io_req_t ior);
+extern void timeclose(dev_t dev, int flag);
#endif /* _KERN_MACH_CLOCK_H_ */
diff --git a/kern/mach_factor.c b/kern/mach_factor.c
index 558c4a06..debce0b0 100644
--- a/kern/mach_factor.c
+++ b/kern/mach_factor.c
@@ -55,13 +55,13 @@ static long fract[3] = {
void compute_mach_factor(void)
{
- register processor_set_t pset;
- register processor_t processor;
- register int ncpus;
- register int nthreads;
- register long factor_now;
- register long average_now;
- register long load_now;
+ processor_set_t pset;
+ processor_t processor;
+ int ncpus;
+ int nthreads;
+ long factor_now;
+ long average_now;
+ long load_now;
simple_lock(&all_psets_lock);
pset = (processor_set_t) queue_first(&all_psets);
@@ -123,7 +123,7 @@ void compute_mach_factor(void)
* And some ugly stuff to keep w happy.
*/
if (pset == &default_pset) {
- register int i;
+ int i;
for (i = 0; i < 3; i++) {
mach_factor[i] = ( (mach_factor[i]*fract[i])
diff --git a/kern/machine.c b/kern/machine.c
index c2a19b99..eced7688 100644
--- a/kern/machine.c
+++ b/kern/machine.c
@@ -72,12 +72,11 @@ decl_simple_lock_data(,action_lock);
* Flag specified cpu as up and running. Called when a processor comes
* online.
*/
-void cpu_up(cpu)
- int cpu;
+void cpu_up(int cpu)
{
- register struct machine_slot *ms;
- register processor_t processor;
- register spl_t s;
+ struct machine_slot *ms;
+ processor_t processor;
+ spl_t s;
processor = cpu_to_processor(cpu);
pset_lock(&default_pset);
@@ -102,12 +101,11 @@ void cpu_up(cpu)
* Flag specified cpu as down. Called when a processor is about to
* go offline.
*/
-void cpu_down(cpu)
- int cpu;
+void cpu_down(int cpu)
{
- register struct machine_slot *ms;
- register processor_t processor;
- register spl_t s;
+ struct machine_slot *ms;
+ processor_t processor;
+ spl_t s;
s = splsched();
processor = cpu_to_processor(cpu);
@@ -126,8 +124,8 @@ void cpu_down(cpu)
kern_return_t
host_reboot(host, options)
- host_t host;
- int options;
+ const host_t host;
+ int options;
{
if (host == HOST_NULL)
return (KERN_INVALID_HOST);
@@ -153,11 +151,11 @@ host_reboot(host, options)
* a reference.
*/
void
-processor_request_action(processor, new_pset)
-processor_t processor;
-processor_set_t new_pset;
+processor_request_action(
+ processor_t processor,
+ processor_set_t new_pset)
{
- register processor_set_t pset;
+ processor_set_t pset;
/*
* Processor must be in a processor set. Must lock its idle lock to
@@ -228,10 +226,10 @@ processor_set_t new_pset;
* Synchronizes with assignment completion if wait is TRUE.
*/
kern_return_t
-processor_assign(processor, new_pset, wait)
-processor_t processor;
-processor_set_t new_pset;
-boolean_t wait;
+processor_assign(
+ processor_t processor,
+ processor_set_t new_pset,
+ boolean_t wait)
{
spl_t s;
@@ -315,14 +313,11 @@ Retry:
#else /* MACH_HOST */
kern_return_t
-processor_assign(processor, new_pset, wait)
-processor_t processor;
-processor_set_t new_pset;
-boolean_t wait;
+processor_assign(
+ processor_t processor,
+ processor_set_t new_pset,
+ boolean_t wait)
{
-#ifdef lint
- processor++; new_pset++; wait++;
-#endif
return KERN_FAILURE;
}
@@ -334,8 +329,7 @@ boolean_t wait;
* with the shutdown (can be called from interrupt level).
*/
kern_return_t
-processor_shutdown(processor)
-processor_t processor;
+processor_shutdown(processor_t processor)
{
spl_t s;
@@ -364,12 +358,10 @@ processor_t processor;
/*
* action_thread() shuts down processors or changes their assignment.
*/
-void processor_doaction(); /* forward */
-
-void action_thread_continue()
+void action_thread_continue(void)
{
- register processor_t processor;
- register spl_t s;
+ processor_t processor;
+ spl_t s;
while (TRUE) {
s = splsched();
@@ -395,7 +387,7 @@ void action_thread_continue()
}
}
-void action_thread()
+void __attribute__((noreturn)) action_thread(void)
{
action_thread_continue();
/*NOTREACHED*/
@@ -406,21 +398,15 @@ void action_thread()
* is to schedule ourselves onto a cpu and then save our
* context back into the runqs before taking out the cpu.
*/
-#ifdef __GNUC__
-__volatile__
-#endif
-void processor_doshutdown(); /* forward */
-
-void processor_doaction(processor)
-register processor_t processor;
+void processor_doaction(processor_t processor)
{
thread_t this_thread;
spl_t s;
- register processor_set_t pset;
+ processor_set_t pset;
#if MACH_HOST
- register processor_set_t new_pset;
- register thread_t thread;
- register thread_t prev_thread = THREAD_NULL;
+ processor_set_t new_pset;
+ thread_t thread;
+ thread_t prev_thread = THREAD_NULL;
boolean_t have_pset_ref = FALSE;
#endif /* MACH_HOST */
@@ -633,13 +619,10 @@ Restart_pset:
* running on the processor's shutdown stack.
*/
-#ifdef __GNUC__
-__volatile__
-#endif
void processor_doshutdown(processor)
-register processor_t processor;
+processor_t processor;
{
- register int cpu = processor->slot_num;
+ int cpu = processor->slot_num;
timer_switch(&kernel_timer[cpu]);
@@ -663,23 +646,20 @@ register processor_t processor;
#else /* NCPUS > 1 */
kern_return_t
-processor_assign(processor, new_pset, wait)
-processor_t processor;
-processor_set_t new_pset;
-boolean_t wait;
+processor_assign(
+ processor_t processor,
+ processor_set_t new_pset,
+ boolean_t wait)
{
-#ifdef lint
- processor++; new_pset++; wait++;
-#endif /* lint */
return(KERN_FAILURE);
}
#endif /* NCPUS > 1 */
kern_return_t
-host_get_boot_info(priv_host, boot_info)
- host_t priv_host;
- kernel_boot_info_t boot_info;
+host_get_boot_info(
+ host_t priv_host,
+ kernel_boot_info_t boot_info)
{
char *src = "";
diff --git a/kern/machine.h b/kern/machine.h
index af2b7e91..c67213a2 100644
--- a/kern/machine.h
+++ b/kern/machine.h
@@ -53,6 +53,6 @@ extern kern_return_t processor_shutdown (processor_t);
/*
* action_thread() shuts down processors or changes their assignment.
*/
-extern void action_thread_continue (void);
+extern void action_thread_continue (void) __attribute__((noreturn));
#endif /* _MACHINE_H_ */
diff --git a/kern/macro_help.h b/kern/macro_help.h
deleted file mode 100644
index a3d156b7..00000000
--- a/kern/macro_help.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: kern/macro_help.h
- *
- * Provide help in making lint-free macro routines
- *
- */
-
-#ifndef _KERN_MACRO_HELP_H_
-#define _KERN_MACRO_HELP_H_
-
-#if !defined(MACRO_BEGIN)
-
-#include <mach/boolean.h>
-
-#ifdef lint
-boolean_t NEVER;
-boolean_t ALWAYS;
-#else /* lint */
-#define NEVER FALSE
-#define ALWAYS TRUE
-#endif /* lint */
-
-#define MACRO_BEGIN ({
-#define MACRO_END })
-
-#define MACRO_RETURN if (ALWAYS) return
-
-#endif /* !MACRO_BEGIN */
-
-#endif /* _KERN_MACRO_HELP_H_ */
diff --git a/kern/macros.h b/kern/macros.h
new file mode 100644
index 00000000..fb8dc5e1
--- /dev/null
+++ b/kern/macros.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2009, 2010, 2013 Richard Braun.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Helper macros.
+ */
+
+#ifndef _KERN_MACROS_H
+#define _KERN_MACROS_H
+
+#define MACRO_BEGIN ({
+#define MACRO_END })
+#define MACRO_RETURN if (1) return
+
+#define __QUOTE(x) #x
+#define QUOTE(x) __QUOTE(x)
+
+#ifdef __ASSEMBLER__
+#define DECL_CONST(x, s) x
+#else /* __ASSEMBLER__ */
+#define __DECL_CONST(x, s) x##s
+#define DECL_CONST(x, s) __DECL_CONST(x, s)
+#endif /* __ASSEMBLER__ */
+
+#define STRLEN(x) (sizeof(x) - 1)
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+#define DIV_CEIL(n, d) (((n) + (d) - 1) / (d))
+
+#define P2ALIGNED(x, a) (((x) & ((a) - 1)) == 0)
+#define ISP2(x) P2ALIGNED(x, x)
+#define P2ALIGN(x, a) ((x) & -(a))
+#define P2ROUND(x, a) (-(-(x) & -(a)))
+#define P2END(x, a) (-(~(x) & -(a)))
+
+#define structof(ptr, type, member) \
+ ((type *)((char *)(ptr) - offsetof(type, member)))
+
+#define alignof(x) __alignof__(x)
+
+#define likely(expr) __builtin_expect(!!(expr), 1)
+#define unlikely(expr) __builtin_expect(!!(expr), 0)
+
+#define barrier() asm volatile("" : : : "memory")
+
+#define __noreturn __attribute__((noreturn))
+#define __aligned(x) __attribute__((aligned(x)))
+#define __always_inline inline __attribute__((always_inline))
+#define __section(x) __attribute__((section(x)))
+#define __packed __attribute__((packed))
+#define __alias(x) __attribute__((alias(x)))
+
+#define __format_printf(fmt, args) \
+ __attribute__((format(printf, fmt, args)))
+
+#endif /* _KERN_MACROS_H */
diff --git a/kern/pc_sample.c b/kern/pc_sample.c
index 57002581..fcb9d71b 100644
--- a/kern/pc_sample.c
+++ b/kern/pc_sample.c
@@ -43,12 +43,9 @@
typedef sampled_pc_t sampled_pcs[MAX_PC_SAMPLES];
-int pc_sampling_enabled = 0;
-decl_simple_lock_data(, pc_sampling_lock) /* lock for enabling */
-
void take_pc_sample(
- register thread_t t,
- register sample_control_t *cp,
+ const thread_t t,
+ sample_control_t *cp,
sampled_pc_flavor_t flavor)
{
vm_offset_t pc;
@@ -192,6 +189,9 @@ get_sampled_pcs(
(sampled_pc_array_t)cp->buffer,
(seqidx2 + 1) * sizeof(sampled_pc_t));
}
+ } else if (nsamples < 0) {
+ /* Bogus SEQNO supplied. */
+ nsamples = 0;
} else {
/* could either be zero because of overflow, or because
* we are being lied to. In either case, return nothing.
@@ -244,8 +244,8 @@ task_get_sampled_pcs(
kern_return_t
thread_enable_pc_sampling(
- thread_t thread,
- int *tickp,
+ const thread_t thread,
+ const int *tickp,
sampled_pc_flavor_t flavors)
{
return KERN_FAILURE; /* not implemented */
@@ -253,8 +253,8 @@ thread_enable_pc_sampling(
kern_return_t
task_enable_pc_sampling(
- task_t task,
- int *tickp,
+ const task_t task,
+ const int *tickp,
sampled_pc_flavor_t flavors)
{
return KERN_FAILURE; /* not implemented */
@@ -262,36 +262,36 @@ task_enable_pc_sampling(
kern_return_t
thread_disable_pc_sampling(
- thread_t thread,
- int *samplecntp)
+ const thread_t thread,
+ const int *samplecntp)
{
return KERN_FAILURE; /* not implemented */
}
kern_return_t
task_disable_pc_sampling(
- task_t task,
- int *samplecntp)
+ const task_t task,
+ const int *samplecntp)
{
return KERN_FAILURE; /* not implemented */
}
kern_return_t
thread_get_sampled_pcs(
- thread_t thread,
- sampled_pc_seqno_t *seqnop,
- sampled_pc_array_t sampled_pcs_out,
- int *sampled_pcs_cntp)
+ const thread_t thread,
+ const sampled_pc_seqno_t *seqnop,
+ const sampled_pc_array_t sampled_pcs_out,
+ const int *sampled_pcs_cntp)
{
return KERN_FAILURE; /* not implemented */
}
kern_return_t
task_get_sampled_pcs(
- task_t task,
- sampled_pc_seqno_t *seqnop,
- sampled_pc_array_t sampled_pcs_out,
- int *sampled_pcs_cntp)
+ const task_t task,
+ const sampled_pc_seqno_t *seqnop,
+ const sampled_pc_array_t sampled_pcs_out,
+ const int *sampled_pcs_cntp)
{
return KERN_FAILURE; /* not implemented */
}
diff --git a/kern/pc_sample.h b/kern/pc_sample.h
index 3c64068d..4832cb9f 100644
--- a/kern/pc_sample.h
+++ b/kern/pc_sample.h
@@ -49,7 +49,7 @@
#include <mach/pc_sample.h>
#include <mach/machine/vm_types.h>
#include <kern/kern_types.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
/*
* Control structure for sampling, included in
diff --git a/kern/printf.c b/kern/printf.c
index a3a771d0..50f23623 100644
--- a/kern/printf.c
+++ b/kern/printf.c
@@ -126,17 +126,17 @@
#define isdigit(d) ((d) >= '0' && (d) <= '9')
#define Ctod(c) ((c) - '0')
-#define MAXBUF (sizeof(long int) * 8) /* enough for binary */
+#define MAXBUF (sizeof(long long int) * 8) /* enough for binary */
void printnum(
- register unsigned long u,
- register int base,
+ unsigned long long u,
+ int base,
void (*putc)( char, vm_offset_t ),
vm_offset_t putc_arg)
{
char buf[MAXBUF]; /* build number here */
- register char * p = &buf[MAXBUF-1];
+ char * p = &buf[MAXBUF-1];
static char digs[] = "0123456789abcdef";
do {
@@ -151,23 +151,8 @@ void printnum(
boolean_t _doprnt_truncates = FALSE;
-/* printf could be called at _any_ point during system initialization,
- including before printf_init() gets called from the "normal" place
- in kern/startup.c. */
-boolean_t _doprnt_lock_initialized = FALSE;
-decl_simple_lock_data(,_doprnt_lock)
-
-void printf_init(void)
-{
- if (!_doprnt_lock_initialized)
- {
- _doprnt_lock_initialized = TRUE;
- simple_lock_init(&_doprnt_lock);
- }
-}
-
void _doprnt(
- register const char *fmt,
+ const char *fmt,
va_list argp,
/* character output routine */
void (*putc)( char, vm_offset_t),
@@ -178,29 +163,14 @@ void _doprnt(
int prec;
boolean_t ladjust;
char padc;
- long n;
- unsigned long u;
+ long long n;
+ unsigned long long u;
+ int have_long_long;
int plus_sign;
int sign_char;
boolean_t altfmt, truncate;
int base;
- register char c;
-
- printf_init();
-
-#if 0
- /* Make sure that we get *some* printout, no matter what */
- simple_lock(&_doprnt_lock);
-#else
- {
- register int i = 0;
- while (i < 1*1024*1024) {
- if (simple_lock_try(&_doprnt_lock))
- break;
- i++;
- }
- }
-#endif
+ char c;
while ((c = *fmt) != '\0') {
if (c != '%') {
@@ -218,6 +188,7 @@ void _doprnt(
plus_sign = 0;
sign_char = 0;
altfmt = FALSE;
+ have_long_long = FALSE;
while (TRUE) {
c = *fmt;
@@ -276,6 +247,10 @@ void _doprnt(
if (c == 'l')
c = *++fmt; /* need it if sizeof(int) < sizeof(long) */
+ if (c == 'l') {
+ c = *++fmt; /* handle `long long' */
+ have_long_long = TRUE;
+ }
truncate = FALSE;
@@ -283,11 +258,14 @@ void _doprnt(
case 'b':
case 'B':
{
- register char *p;
- boolean_t any;
- register int i;
-
- u = va_arg(argp, unsigned long);
+ char *p;
+ boolean_t any;
+ int i;
+
+ if (! have_long_long)
+ u = va_arg(argp, unsigned long);
+ else
+ u = va_arg(argp, unsigned long long);
p = va_arg(argp, char *);
base = *p++;
printnum(u, base, putc, putc_arg);
@@ -302,7 +280,7 @@ void _doprnt(
/*
* Bit field
*/
- register int j;
+ int j;
if (any)
(*putc)(',', putc_arg);
else {
@@ -342,8 +320,8 @@ void _doprnt(
case 's':
{
- register char *p;
- register char *p2;
+ char *p;
+ char *p2;
if (prec == -1)
prec = 0x7fffffff; /* MAXINT */
@@ -431,7 +409,10 @@ void _doprnt(
goto print_unsigned;
print_signed:
- n = va_arg(argp, long);
+ if (! have_long_long)
+ n = va_arg(argp, long);
+ else
+ n = va_arg(argp, long long);
if (n >= 0) {
u = n;
sign_char = plus_sign;
@@ -443,13 +424,16 @@ void _doprnt(
goto print_num;
print_unsigned:
- u = va_arg(argp, unsigned long);
+ if (! have_long_long)
+ u = va_arg(argp, unsigned long);
+ else
+ u = va_arg(argp, unsigned long long);
goto print_num;
print_num:
{
char buf[MAXBUF]; /* build number here */
- register char * p = &buf[MAXBUF-1];
+ char * p = &buf[MAXBUF-1];
static char digits[] = "0123456789abcdef";
char *prefix = 0;
@@ -507,8 +491,6 @@ void _doprnt(
}
fmt++;
}
-
- simple_unlock(&_doprnt_lock);
}
/*
@@ -540,7 +522,7 @@ int indent = 0;
void iprintf(const char *fmt, ...)
{
va_list listp;
- register int i;
+ int i;
for (i = indent; i > 0; ){
if (i >= 8) {
@@ -567,8 +549,8 @@ sputc(
char c,
vm_offset_t arg)
{
- register char **bufp = (char **) arg;
- register char *p = *bufp;
+ char **bufp = (char **) arg;
+ char *p = *bufp;
*p++ = c;
*bufp = p;
}
@@ -615,13 +597,23 @@ vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
return cookie.index;
}
+int
+snprintf(char *buf, size_t size, const char *fmt, ...)
+{
+ int written;
+ va_list listp;
+ va_start(listp, fmt);
+ written = vsnprintf(buf, size, fmt, listp);
+ va_end(listp);
+ return written;
+}
-void safe_gets(str, maxlen)
- char *str;
- int maxlen;
+void safe_gets(
+ char *str,
+ int maxlen)
{
- register char *lp;
- register int c;
+ char *lp;
+ int c;
char *strmax = str + maxlen - 1; /* allow space for trailing 0 */
lp = str;
diff --git a/kern/printf.h b/kern/printf.h
index 8b4e7606..b72640aa 100644
--- a/kern/printf.h
+++ b/kern/printf.h
@@ -27,22 +27,26 @@
#include <sys/types.h>
#include <stdarg.h>
-extern void printf_init (void);
-
extern void _doprnt (const char *fmt,
va_list argp,
void (*putc)(char, vm_offset_t),
int radix,
vm_offset_t putc_arg);
-extern void printnum (unsigned long u, int base,
+extern void printnum (unsigned long long u, int base,
void (*putc)(char, vm_offset_t),
vm_offset_t putc_arg);
-extern int sprintf (char *buf, const char *fmt, ...);
-extern int vsnprintf (char *buf, size_t size, const char *fmt, va_list args);
+extern int sprintf (char *buf, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+extern int snprintf (char *buf, size_t size, const char *fmt, ...)
+ __attribute__ ((format (printf, 3, 4)));
+extern int vsnprintf (char *buf, size_t size, const char *fmt, va_list args)
+ __attribute__ ((format (printf, 3, 0)));
+
-extern int printf (const char *fmt, ...);
+extern int printf (const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
#define printf_once(fmt, ...) \
MACRO_BEGIN \
diff --git a/kern/priority.c b/kern/priority.c
index 17541b8b..587ea2f9 100644
--- a/kern/priority.c
+++ b/kern/priority.c
@@ -27,7 +27,7 @@
* the rights to redistribute these changes.
*/
/*
- * File: clock_prim.c
+ * File: priority.c
* Author: Avadis Tevanian, Jr.
* Date: 1986
*
@@ -74,16 +74,16 @@
* Called only from clock_interrupt().
*/
-void thread_quantum_update(mycpu, thread, nticks, state)
- register int mycpu;
- register thread_t thread;
- int nticks;
- int state;
+void thread_quantum_update(
+ int mycpu,
+ thread_t thread,
+ int nticks,
+ int state)
{
- register int quantum;
- register processor_t myprocessor;
+ int quantum;
+ processor_t myprocessor;
#if NCPUS > 1
- register processor_set_t pset;
+ processor_set_t pset;
#endif
spl_t s;
diff --git a/kern/priority.h b/kern/priority.h
new file mode 100644
index 00000000..2da93ebe
--- /dev/null
+++ b/kern/priority.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _KERN_PRIORITY_H_
+#define _KERN_PRIORITY_H_
+
+extern void thread_quantum_update(
+ int mycpu,
+ thread_t thread,
+ int nticks,
+ int state);
+
+#endif /* _KERN_PRIORITY_H_ */
diff --git a/kern/processor.c b/kern/processor.c
index 19868609..48e92731 100644
--- a/kern/processor.c
+++ b/kern/processor.c
@@ -66,18 +66,11 @@ processor_t master_processor;
processor_t processor_ptr[NCPUS];
/*
- * Forward declarations.
- */
-void quantum_set(processor_set_t);
-void pset_init(processor_set_t);
-void processor_init(processor_t, int);
-
-/*
* Bootstrap the processor/pset system so the scheduler can run.
*/
void pset_sys_bootstrap(void)
{
- register int i;
+ int i;
pset_init(&default_pset);
default_pset.empty = FALSE;
@@ -109,8 +102,8 @@ void pset_sys_bootstrap(void)
*/
void pset_sys_init(void)
{
- register int i;
- register processor_t processor;
+ int i;
+ processor_t processor;
/*
* Allocate the cache for processor sets.
@@ -138,7 +131,7 @@ void pset_sys_init(void)
*/
void pset_init(
- register processor_set_t pset)
+ processor_set_t pset)
{
int i;
@@ -189,7 +182,7 @@ void pset_init(
*/
void processor_init(
- register processor_t pr,
+ processor_t pr,
int slot_num)
{
int i;
@@ -414,14 +407,14 @@ void pset_reference(
kern_return_t
processor_info(
- register processor_t processor,
+ processor_t processor,
int flavor,
host_t *host,
processor_info_t info,
natural_t *count)
{
- register int slot_num, state;
- register processor_basic_info_t basic_info;
+ int slot_num, state;
+ processor_basic_info_t basic_info;
if (processor == PROCESSOR_NULL)
return KERN_INVALID_ARGUMENT;
@@ -503,7 +496,7 @@ void quantum_set(
processor_set_t pset)
{
#if NCPUS > 1
- register int i,ncpus;
+ int i, ncpus;
ncpus = pset->processor_count;
@@ -567,8 +560,8 @@ processor_set_create(
kern_return_t processor_set_destroy(
processor_set_t pset)
{
- register queue_entry_t elem;
- register queue_head_t *list;
+ queue_entry_t elem;
+ queue_head_t *list;
if (pset == PROCESSOR_SET_NULL || pset == &default_pset)
return KERN_INVALID_ARGUMENT;
@@ -647,18 +640,12 @@ processor_set_create(
processor_set_t *new_set,
processor_set_t *new_name)
{
-#ifdef lint
- host++; new_set++; new_name++;
-#endif /* lint */
return KERN_FAILURE;
}
kern_return_t processor_set_destroy(
processor_set_t pset)
{
-#ifdef lint
- pset++;
-#endif /* lint */
return KERN_FAILURE;
}
@@ -670,6 +657,8 @@ processor_get_assignment(
processor_set_t *pset)
{
int state;
+ if (processor == PROCESSOR_NULL)
+ return KERN_INVALID_ARGUMENT;
state = processor->state;
if (state == PROCESSOR_SHUTDOWN || state == PROCESSOR_OFF_LINE)
@@ -692,7 +681,7 @@ processor_set_info(
return KERN_INVALID_ARGUMENT;
if (flavor == PROCESSOR_SET_BASIC_INFO) {
- register processor_set_basic_info_t basic_info;
+ processor_set_basic_info_t basic_info;
if (*count < PROCESSOR_SET_BASIC_INFO_COUNT)
return KERN_FAILURE;
@@ -712,7 +701,7 @@ processor_set_info(
return KERN_SUCCESS;
}
else if (flavor == PROCESSOR_SET_SCHED_INFO) {
- register processor_set_sched_info_t sched_info;
+ processor_set_sched_info_t sched_info;
if (*count < PROCESSOR_SET_SCHED_INFO_COUNT)
return KERN_FAILURE;
@@ -757,8 +746,8 @@ processor_set_max_priority(
pset->max_priority = max_priority;
if (change_threads) {
- register queue_head_t *list;
- register thread_t thread;
+ queue_head_t *list;
+ thread_t thread;
list = &pset->threads;
queue_iterate(list, thread, thread_t, pset_threads) {
@@ -828,8 +817,8 @@ processor_set_policy_disable(
pset->policies &= ~policy;
if (change_threads) {
- register queue_head_t *list;
- register thread_t thread;
+ queue_head_t *list;
+ thread_t thread;
list = &pset->threads;
queue_iterate(list, thread, thread_t, pset_threads) {
diff --git a/kern/processor.h b/kern/processor.h
index 9a6c944b..b81526c0 100644
--- a/kern/processor.h
+++ b/kern/processor.h
@@ -320,4 +320,10 @@ extern kern_return_t processor_set_threads(
natural_t *count);
#endif
+void processor_doaction(processor_t processor);
+void processor_doshutdown(processor_t processor);
+void quantum_set(processor_set_t pset);
+void pset_init(processor_set_t pset);
+void processor_init(processor_t pr, int slot_num);
+
#endif /* _KERN_PROCESSOR_H_ */
diff --git a/kern/profile.c b/kern/profile.c
index e14d4116..55107218 100644
--- a/kern/profile.c
+++ b/kern/profile.c
@@ -194,7 +194,7 @@ thread_t th;
* Make a request to the profile_thread by inserting
* the buffer in the send queue, and wake it up.
* The last buffer must be inserted at the head of the
- * send queue, so the profile_thread handles it immediatly.
+ * send queue, so the profile_thread handles it immediately.
*/
if (kmem_alloc( kernel_map, &vm_buf_entry,
sizeof(struct buf_to_send)) != KERN_SUCCESS)
diff --git a/kern/queue.c b/kern/queue.c
index 98b74c20..d9396e54 100644
--- a/kern/queue.c
+++ b/kern/queue.c
@@ -35,8 +35,8 @@
* Insert element at head of queue.
*/
void enqueue_head(
- register queue_t que,
- register queue_entry_t elt)
+ queue_t que,
+ queue_entry_t elt)
{
elt->next = que->next;
elt->prev = que;
@@ -48,8 +48,8 @@ void enqueue_head(
* Insert element at tail of queue.
*/
void enqueue_tail(
- register queue_t que,
- register queue_entry_t elt)
+ queue_t que,
+ queue_entry_t elt)
{
elt->next = que;
elt->prev = que->prev;
@@ -61,9 +61,9 @@ void enqueue_tail(
* Remove and return element at head of queue.
*/
queue_entry_t dequeue_head(
- register queue_t que)
+ queue_t que)
{
- register queue_entry_t elt;
+ queue_entry_t elt;
if (que->next == que)
return((queue_entry_t)0);
@@ -78,9 +78,9 @@ queue_entry_t dequeue_head(
* Remove and return element at tail of queue.
*/
queue_entry_t dequeue_tail(
- register queue_t que)
+ queue_t que)
{
- register queue_entry_t elt;
+ queue_entry_t elt;
if (que->prev == que)
return((queue_entry_t)0);
@@ -100,7 +100,7 @@ queue_entry_t dequeue_tail(
/*ARGSUSED*/
void remqueue(
queue_t que,
- register queue_entry_t elt)
+ queue_entry_t elt)
{
elt->next->prev = elt->prev;
elt->prev->next = elt->next;
@@ -111,8 +111,8 @@ void remqueue(
* package.
*/
void insque(
- register struct queue_entry *entry,
- register struct queue_entry *pred)
+ struct queue_entry *entry,
+ struct queue_entry *pred)
{
entry->next = pred->next;
entry->prev = pred;
@@ -122,7 +122,7 @@ void insque(
struct queue_entry
*remque(
- register struct queue_entry *elt)
+ struct queue_entry *elt)
{
(elt->next)->prev = elt->prev;
(elt->prev)->next = elt->next;
diff --git a/kern/queue.h b/kern/queue.h
index 1846922a..f0b4002f 100644
--- a/kern/queue.h
+++ b/kern/queue.h
@@ -87,6 +87,14 @@ void remqueue(queue_t, queue_entry_t);
void insque(queue_entry_t, queue_entry_t);
/*
+ * Macro: queue_assert
+ * Function:
+ * Used by macros to assert that the given argument is a
+ * queue.
+ */
+#define queue_assert(q) (void) ((void) (q)->next, (q)->prev)
+
+/*
* Macro: queue_init
* Function:
* Initialize the given queue.
@@ -104,7 +112,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_first(q)
* queue_t q; *IN*
*/
-#define queue_first(q) ((q)->next)
+#define queue_first(q) (queue_assert(q), (q)->next)
/*
* Macro: queue_next
@@ -114,7 +122,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_next(qc)
* queue_t qc;
*/
-#define queue_next(qc) ((qc)->next)
+#define queue_next(qc) (queue_assert(qc), (qc)->next)
/*
* Macro: queue_last
@@ -124,7 +132,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_last(q)
* queue_t q; *IN*
*/
-#define queue_last(q) ((q)->prev)
+#define queue_last(q) (queue_assert(q), (q)->prev)
/*
* Macro: queue_prev
@@ -134,7 +142,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_prev(qc)
* queue_t qc;
*/
-#define queue_prev(qc) ((qc)->prev)
+#define queue_prev(qc) (queue_assert(qc), (qc)->prev)
/*
* Macro: queue_end
@@ -146,7 +154,8 @@ void insque(queue_entry_t, queue_entry_t);
* queue_t q;
* queue_entry_t qe;
*/
-#define queue_end(q, qe) ((q) == (qe))
+#define queue_end(q, qe) (queue_assert(q), queue_assert(qe), \
+ (q) == (qe))
/*
* Macro: queue_empty
@@ -179,7 +188,9 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_enter(head, elt, type, field) \
{ \
- register queue_entry_t prev; \
+ queue_assert(head); \
+ queue_assert(&(elt)->field); \
+ queue_entry_t prev; \
\
prev = (head)->prev; \
if ((head) == prev) { \
@@ -206,7 +217,9 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_enter_first(head, elt, type, field) \
{ \
- register queue_entry_t next; \
+ queue_assert(head); \
+ queue_assert(&(elt)->field); \
+ queue_entry_t next; \
\
next = (head)->next; \
if ((head) == next) { \
@@ -239,7 +252,9 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_remove(head, elt, type, field) \
{ \
- register queue_entry_t next, prev; \
+ queue_assert(head); \
+ queue_assert(&(elt)->field); \
+ queue_entry_t next, prev; \
\
next = (elt)->field.next; \
prev = (elt)->field.prev; \
@@ -266,7 +281,9 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_remove_first(head, entry, type, field) \
{ \
- register queue_entry_t next; \
+ queue_assert(head); \
+ queue_assert(&(entry)->field); \
+ queue_entry_t next; \
\
(entry) = (type) ((head)->next); \
next = (entry)->field.next; \
@@ -289,7 +306,9 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_remove_last(head, entry, type, field) \
{ \
- register queue_entry_t prev; \
+ queue_assert(head); \
+ queue_assert(&(entry)->field); \
+ queue_entry_t prev; \
\
(entry) = (type) ((head)->prev); \
prev = (entry)->field.prev; \
@@ -306,6 +325,8 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_assign(to, from, type, field) \
{ \
+ queue_assert(&(to)->field); \
+ queue_assert(&(from)->field); \
((type)((from)->prev))->field.next = (to); \
((type)((from)->next))->field.prev = (to); \
*to = *from; \
diff --git a/kern/rbtree.h b/kern/rbtree.h
index 5a65d1ef..16ef2736 100644
--- a/kern/rbtree.h
+++ b/kern/rbtree.h
@@ -31,13 +31,9 @@
#include <stddef.h>
#include <kern/assert.h>
-#include <kern/macro_help.h>
-#include <kern/rbtree.h>
+#include <kern/macros.h>
#include <sys/types.h>
-#define structof(ptr, type, member) \
- ((type *)((char *)ptr - offsetof(type, member)))
-
/*
* Indexes of the left and right nodes in the children array of a node.
*/
@@ -178,8 +174,8 @@ MACRO_END
* This macro performs a standard lookup to obtain the insertion point of
* the given node in the tree (it is assumed that the inserted node never
* compares equal to any other entry in the tree) and links the node. It
- * then It then checks red-black rules violations, and rebalances the tree
- * if necessary.
+ * then checks red-black rules violations, and rebalances the tree if
+ * necessary.
*
* Unlike rbtree_lookup(), the cmp_fn parameter must compare two complete
* entries, so it is suggested to use two different comparison inline
diff --git a/kern/rdxtree.c b/kern/rdxtree.c
new file mode 100644
index 00000000..78868b1f
--- /dev/null
+++ b/kern/rdxtree.c
@@ -0,0 +1,830 @@
+/*
+ * Copyright (c) 2011-2015 Richard Braun.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Upstream site with license notes :
+ * http://git.sceen.net/rbraun/librbraun.git/
+ */
+
+#include <kern/assert.h>
+#include <kern/slab.h>
+#include <mach/kern_return.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "macros.h"
+#include "rdxtree.h"
+#include "rdxtree_i.h"
+
+/* XXX */
+#define CHAR_BIT 8U
+#define ERR_SUCCESS KERN_SUCCESS
+#define ERR_BUSY KERN_INVALID_ARGUMENT
+#define ERR_NOMEM KERN_RESOURCE_SHORTAGE
+
+/*
+ * Mask applied on an entry to obtain its address.
+ */
+#define RDXTREE_ENTRY_ADDR_MASK (~0x3UL)
+
+/*
+ * Global properties used to shape radix trees.
+ */
+#define RDXTREE_RADIX 6
+#define RDXTREE_RADIX_SIZE (1UL << RDXTREE_RADIX)
+#define RDXTREE_RADIX_MASK (RDXTREE_RADIX_SIZE - 1)
+
+#if RDXTREE_RADIX < 6
+typedef unsigned long rdxtree_bm_t;
+#define rdxtree_ffs(x) __builtin_ffsl(x)
+#elif RDXTREE_RADIX == 6 /* RDXTREE_RADIX < 6 */
+typedef unsigned long long rdxtree_bm_t;
+#define rdxtree_ffs(x) __builtin_ffsll(x)
+#else /* RDXTREE_RADIX < 6 */
+#error "radix too high"
+#endif /* RDXTREE_RADIX < 6 */
+
+/*
+ * Allocation bitmap size in bits.
+ */
+#define RDXTREE_BM_SIZE (sizeof(rdxtree_bm_t) * CHAR_BIT)
+
+/*
+ * Empty/full allocation bitmap words.
+ */
+#define RDXTREE_BM_EMPTY ((rdxtree_bm_t)0)
+#define RDXTREE_BM_FULL \
+ ((~(rdxtree_bm_t)0) >> (RDXTREE_BM_SIZE - RDXTREE_RADIX_SIZE))
+
+/*
+ * These macros can be replaced by actual functions in an environment
+ * that provides lockless synchronization such as RCU.
+ */
+#define llsync_assign_ptr(ptr, value) ((ptr) = (value))
+#define llsync_read_ptr(ptr) (ptr)
+
+/*
+ * Radix tree node.
+ *
+ * The height of a tree is the number of nodes to traverse until stored
+ * pointers are reached. A height of 0 means the entries of a node (or the
+ * tree root) directly point to stored pointers.
+ *
+ * The index is valid if and only if the parent isn't NULL.
+ *
+ * Concerning the allocation bitmap, a bit is set when the node it denotes,
+ * or one of its children, can be used to allocate an entry. Conversely, a bit
+ * is clear when the matching node and all of its children have no free entry.
+ *
+ * In order to support safe lockless lookups, in particular during a resize,
+ * each node includes the height of its subtree, which is invariant during
+ * the entire node lifetime. Since the tree height does vary, it can't be
+ * used to determine whether the tree root is a node or a stored pointer.
+ * This implementation assumes that all nodes and stored pointers are at least
+ * 4-byte aligned, and uses the least significant bit of entries to indicate
+ * the pointer type. This bit is set for internal nodes, and clear for stored
+ * pointers so that they can be accessed from slots without conversion.
+ */
+struct rdxtree_node {
+ struct rdxtree_node *parent;
+ unsigned int index;
+ unsigned int height;
+ unsigned int nr_entries;
+ rdxtree_bm_t alloc_bm;
+ void *entries[RDXTREE_RADIX_SIZE];
+};
+
+/*
+ * We allocate nodes using the slab allocator.
+ */
+static struct kmem_cache rdxtree_node_cache;
+
+void
+rdxtree_cache_init(void)
+{
+ kmem_cache_init(&rdxtree_node_cache, "rdxtree_node",
+ sizeof(struct rdxtree_node), 0, NULL, NULL, NULL, 0);
+}
+
+#ifdef RDXTREE_ENABLE_NODE_CREATION_FAILURES
+unsigned int rdxtree_fail_node_creation_threshold;
+unsigned int rdxtree_nr_node_creations;
+#endif /* RDXTREE_ENABLE_NODE_CREATION_FAILURES */
+
+static inline int
+rdxtree_check_alignment(const void *ptr)
+{
+ return ((unsigned long)ptr & ~RDXTREE_ENTRY_ADDR_MASK) == 0;
+}
+
+static inline void *
+rdxtree_entry_addr(void *entry)
+{
+ return (void *)((unsigned long)entry & RDXTREE_ENTRY_ADDR_MASK);
+}
+
+static inline int
+rdxtree_entry_is_node(const void *entry)
+{
+ return ((unsigned long)entry & 1) != 0;
+}
+
+static inline void *
+rdxtree_node_to_entry(struct rdxtree_node *node)
+{
+ return (void *)((unsigned long)node | 1);
+}
+
+static int
+rdxtree_node_create(struct rdxtree_node **nodep, unsigned int height)
+{
+ struct rdxtree_node *node;
+
+#ifdef RDXTREE_ENABLE_NODE_CREATION_FAILURES
+ if (rdxtree_fail_node_creation_threshold != 0) {
+ rdxtree_nr_node_creations++;
+
+ if (rdxtree_nr_node_creations == rdxtree_fail_node_creation_threshold)
+ return ERR_NOMEM;
+ }
+#endif /* RDXTREE_ENABLE_NODE_CREATION_FAILURES */
+
+ node = (struct rdxtree_node *) kmem_cache_alloc(&rdxtree_node_cache);
+
+ if (node == NULL)
+ return ERR_NOMEM;
+
+ assert(rdxtree_check_alignment(node));
+ node->parent = NULL;
+ node->height = height;
+ node->nr_entries = 0;
+ node->alloc_bm = RDXTREE_BM_FULL;
+ memset(node->entries, 0, sizeof(node->entries));
+ *nodep = node;
+ return 0;
+}
+
+static void
+rdxtree_node_schedule_destruction(struct rdxtree_node *node)
+{
+ /*
+ * This function is intended to use the appropriate interface to defer
+ * destruction until all read-side references are dropped in an
+ * environment that provides lockless synchronization.
+ *
+ * Otherwise, it simply "schedules" destruction immediately.
+ */
+ kmem_cache_free(&rdxtree_node_cache, (vm_offset_t) node);
+}
+
+static inline void
+rdxtree_node_link(struct rdxtree_node *node, struct rdxtree_node *parent,
+ unsigned int index)
+{
+ node->parent = parent;
+ node->index = index;
+}
+
+static inline void
+rdxtree_node_unlink(struct rdxtree_node *node)
+{
+ assert(node->parent != NULL);
+ node->parent = NULL;
+}
+
+static inline int
+rdxtree_node_full(struct rdxtree_node *node)
+{
+ return (node->nr_entries == ARRAY_SIZE(node->entries));
+}
+
+static inline int
+rdxtree_node_empty(struct rdxtree_node *node)
+{
+ return (node->nr_entries == 0);
+}
+
+static inline void
+rdxtree_node_insert(struct rdxtree_node *node, unsigned int index,
+ void *entry)
+{
+ assert(index < ARRAY_SIZE(node->entries));
+ assert(node->entries[index] == NULL);
+
+ node->nr_entries++;
+ llsync_assign_ptr(node->entries[index], entry);
+}
+
+static inline void
+rdxtree_node_insert_node(struct rdxtree_node *node, unsigned int index,
+ struct rdxtree_node *child)
+{
+ rdxtree_node_insert(node, index, rdxtree_node_to_entry(child));
+}
+
+static inline void
+rdxtree_node_remove(struct rdxtree_node *node, unsigned int index)
+{
+ assert(index < ARRAY_SIZE(node->entries));
+ assert(node->entries[index] != NULL);
+
+ node->nr_entries--;
+ llsync_assign_ptr(node->entries[index], NULL);
+}
+
+static inline void *
+rdxtree_node_find(struct rdxtree_node *node, unsigned int *indexp)
+{
+ unsigned int index;
+ void *ptr;
+
+ index = *indexp;
+
+ while (index < ARRAY_SIZE(node->entries)) {
+ ptr = rdxtree_entry_addr(llsync_read_ptr(node->entries[index]));
+
+ if (ptr != NULL) {
+ *indexp = index;
+ return ptr;
+ }
+
+ index++;
+ }
+
+ return NULL;
+}
+
+static inline void
+rdxtree_node_bm_set(struct rdxtree_node *node, unsigned int index)
+{
+ node->alloc_bm |= (rdxtree_bm_t)1 << index;
+}
+
+static inline void
+rdxtree_node_bm_clear(struct rdxtree_node *node, unsigned int index)
+{
+ node->alloc_bm &= ~((rdxtree_bm_t)1 << index);
+}
+
+static inline int
+rdxtree_node_bm_is_set(struct rdxtree_node *node, unsigned int index)
+{
+ return (node->alloc_bm & ((rdxtree_bm_t)1 << index));
+}
+
+static inline int
+rdxtree_node_bm_empty(struct rdxtree_node *node)
+{
+ return (node->alloc_bm == RDXTREE_BM_EMPTY);
+}
+
+static inline unsigned int
+rdxtree_node_bm_first(struct rdxtree_node *node)
+{
+ return rdxtree_ffs(node->alloc_bm) - 1;
+}
+
+static inline rdxtree_key_t
+rdxtree_max_key(unsigned int height)
+{
+ size_t shift;
+
+ shift = RDXTREE_RADIX * height;
+
+ if (likely(shift < (sizeof(rdxtree_key_t) * CHAR_BIT)))
+ return ((rdxtree_key_t)1 << shift) - 1;
+ else
+ return ~((rdxtree_key_t)0);
+}
+
+static void
+rdxtree_shrink(struct rdxtree *tree)
+{
+ struct rdxtree_node *node;
+ void *entry;
+
+ while (tree->height > 0) {
+ node = rdxtree_entry_addr(tree->root);
+
+ if (node->nr_entries != 1)
+ break;
+
+ entry = node->entries[0];
+
+ if (entry == NULL)
+ break;
+
+ tree->height--;
+
+ if (tree->height > 0)
+ rdxtree_node_unlink(rdxtree_entry_addr(entry));
+
+ llsync_assign_ptr(tree->root, entry);
+ rdxtree_node_schedule_destruction(node);
+ }
+}
+
+static int
+rdxtree_grow(struct rdxtree *tree, rdxtree_key_t key)
+{
+ struct rdxtree_node *root, *node;
+ unsigned int new_height;
+ int error;
+
+ new_height = tree->height + 1;
+
+ while (key > rdxtree_max_key(new_height))
+ new_height++;
+
+ if (tree->root == NULL) {
+ tree->height = new_height;
+ return ERR_SUCCESS;
+ }
+
+ root = rdxtree_entry_addr(tree->root);
+
+ do {
+ error = rdxtree_node_create(&node, tree->height);
+
+ if (error) {
+ rdxtree_shrink(tree);
+ return error;
+ }
+
+ if (tree->height == 0)
+ rdxtree_node_bm_clear(node, 0);
+ else {
+ rdxtree_node_link(root, node, 0);
+
+ if (rdxtree_node_bm_empty(root))
+ rdxtree_node_bm_clear(node, 0);
+ }
+
+ rdxtree_node_insert(node, 0, tree->root);
+ tree->height++;
+ llsync_assign_ptr(tree->root, rdxtree_node_to_entry(node));
+ root = node;
+ } while (new_height > tree->height);
+
+ return ERR_SUCCESS;
+}
+
+static void
+rdxtree_cleanup(struct rdxtree *tree, struct rdxtree_node *node)
+{
+ struct rdxtree_node *prev;
+
+ for (;;) {
+ if (likely(!rdxtree_node_empty(node))) {
+ if (unlikely(node->parent == NULL))
+ rdxtree_shrink(tree);
+
+ break;
+ }
+
+ if (node->parent == NULL) {
+ tree->height = 0;
+ llsync_assign_ptr(tree->root, NULL);
+ rdxtree_node_schedule_destruction(node);
+ break;
+ }
+
+ prev = node;
+ node = node->parent;
+ rdxtree_node_unlink(prev);
+ rdxtree_node_remove(node, prev->index);
+ rdxtree_node_schedule_destruction(prev);
+ }
+}
+
+static void
+rdxtree_insert_bm_clear(struct rdxtree_node *node, unsigned int index)
+{
+ for (;;) {
+ rdxtree_node_bm_clear(node, index);
+
+ if (!rdxtree_node_full(node) || (node->parent == NULL))
+ break;
+
+ index = node->index;
+ node = node->parent;
+ }
+}
+
+int
+rdxtree_insert_common(struct rdxtree *tree, rdxtree_key_t key,
+ void *ptr, void ***slotp)
+{
+ struct rdxtree_node *node, *prev;
+ unsigned int height, shift, index = index;
+ int error;
+
+ assert(ptr != NULL);
+ assert(rdxtree_check_alignment(ptr));
+
+ if (unlikely(key > rdxtree_max_key(tree->height))) {
+ error = rdxtree_grow(tree, key);
+
+ if (error)
+ return error;
+ }
+
+ height = tree->height;
+
+ if (unlikely(height == 0)) {
+ if (tree->root != NULL)
+ return ERR_BUSY;
+
+ llsync_assign_ptr(tree->root, ptr);
+
+ if (slotp != NULL)
+ *slotp = &tree->root;
+
+ return ERR_SUCCESS;
+ }
+
+ node = rdxtree_entry_addr(tree->root);
+ shift = (height - 1) * RDXTREE_RADIX;
+ prev = NULL;
+
+ do {
+ if (node == NULL) {
+ error = rdxtree_node_create(&node, height - 1);
+
+ if (error) {
+ if (prev == NULL)
+ tree->height = 0;
+ else
+ rdxtree_cleanup(tree, prev);
+
+ return error;
+ }
+
+ if (prev == NULL)
+ llsync_assign_ptr(tree->root, rdxtree_node_to_entry(node));
+ else {
+ rdxtree_node_link(node, prev, index);
+ rdxtree_node_insert_node(prev, index, node);
+ }
+ }
+
+ prev = node;
+ index = (unsigned int)(key >> shift) & RDXTREE_RADIX_MASK;
+ node = rdxtree_entry_addr(prev->entries[index]);
+ shift -= RDXTREE_RADIX;
+ height--;
+ } while (height > 0);
+
+ if (unlikely(node != NULL))
+ return ERR_BUSY;
+
+ rdxtree_node_insert(prev, index, ptr);
+ rdxtree_insert_bm_clear(prev, index);
+
+ if (slotp != NULL)
+ *slotp = &prev->entries[index];
+
+ return ERR_SUCCESS;
+}
+
+int
+rdxtree_insert_alloc_common(struct rdxtree *tree, void *ptr,
+ rdxtree_key_t *keyp, void ***slotp)
+{
+ struct rdxtree_node *node, *prev;
+ unsigned int height, shift, index = index;
+ rdxtree_key_t key;
+ int error;
+
+ assert(ptr != NULL);
+ assert(rdxtree_check_alignment(ptr));
+
+ height = tree->height;
+
+ if (unlikely(height == 0)) {
+ if (tree->root == NULL) {
+ llsync_assign_ptr(tree->root, ptr);
+ *keyp = 0;
+
+ if (slotp != NULL)
+ *slotp = &tree->root;
+
+ return ERR_SUCCESS;
+ }
+
+ goto grow;
+ }
+
+ node = rdxtree_entry_addr(tree->root);
+ key = 0;
+ shift = (height - 1) * RDXTREE_RADIX;
+ prev = NULL;
+
+ do {
+ if (node == NULL) {
+ error = rdxtree_node_create(&node, height - 1);
+
+ if (error) {
+ rdxtree_cleanup(tree, prev);
+ return error;
+ }
+
+ rdxtree_node_link(node, prev, index);
+ rdxtree_node_insert_node(prev, index, node);
+ }
+
+ prev = node;
+ index = rdxtree_node_bm_first(node);
+
+ if (index == (unsigned int)-1)
+ goto grow;
+
+ key |= (rdxtree_key_t)index << shift;
+ node = rdxtree_entry_addr(node->entries[index]);
+ shift -= RDXTREE_RADIX;
+ height--;
+ } while (height > 0);
+
+ rdxtree_node_insert(prev, index, ptr);
+ rdxtree_insert_bm_clear(prev, index);
+
+ if (slotp != NULL)
+ *slotp = &prev->entries[index];
+
+ goto out;
+
+grow:
+ key = rdxtree_max_key(height) + 1;
+ error = rdxtree_insert_common(tree, key, ptr, slotp);
+
+ if (error)
+ return error;
+
+out:
+ *keyp = key;
+ return ERR_SUCCESS;
+}
+
+static void
+rdxtree_remove_bm_set(struct rdxtree_node *node, unsigned int index)
+{
+ do {
+ rdxtree_node_bm_set(node, index);
+
+ if (node->parent == NULL)
+ break;
+
+ index = node->index;
+ node = node->parent;
+ } while (!rdxtree_node_bm_is_set(node, index));
+}
+
+void *
+rdxtree_remove(struct rdxtree *tree, rdxtree_key_t key)
+{
+ struct rdxtree_node *node, *prev;
+ unsigned int height, shift, index;
+
+ height = tree->height;
+
+ if (unlikely(key > rdxtree_max_key(height)))
+ return NULL;
+
+ node = rdxtree_entry_addr(tree->root);
+
+ if (unlikely(height == 0)) {
+ llsync_assign_ptr(tree->root, NULL);
+ return node;
+ }
+
+ shift = (height - 1) * RDXTREE_RADIX;
+
+ do {
+ if (node == NULL)
+ return NULL;
+
+ prev = node;
+ index = (unsigned int)(key >> shift) & RDXTREE_RADIX_MASK;
+ node = rdxtree_entry_addr(node->entries[index]);
+ shift -= RDXTREE_RADIX;
+ height--;
+ } while (height > 0);
+
+ if (node == NULL)
+ return NULL;
+
+ rdxtree_node_remove(prev, index);
+ rdxtree_remove_bm_set(prev, index);
+ rdxtree_cleanup(tree, prev);
+ return node;
+}
+
+void *
+rdxtree_lookup_common(const struct rdxtree *tree, rdxtree_key_t key,
+ int get_slot)
+{
+ struct rdxtree_node *node, *prev;
+ unsigned int height, shift, index;
+ void *entry;
+
+ entry = llsync_read_ptr(tree->root);
+
+ if (entry == NULL) {
+ node = NULL;
+ height = 0;
+ } else {
+ node = rdxtree_entry_addr(entry);
+ height = rdxtree_entry_is_node(entry) ? node->height + 1 : 0;
+ }
+
+ if (key > rdxtree_max_key(height))
+ return NULL;
+
+ if (height == 0) {
+ if (node == NULL)
+ return NULL;
+
+ return get_slot ? (void *)&tree->root : node;
+ }
+
+ shift = (height - 1) * RDXTREE_RADIX;
+
+ do {
+ if (node == NULL)
+ return NULL;
+
+ prev = node;
+ index = (unsigned int)(key >> shift) & RDXTREE_RADIX_MASK;
+ entry = llsync_read_ptr(node->entries[index]);
+ node = rdxtree_entry_addr(entry);
+ shift -= RDXTREE_RADIX;
+ height--;
+ } while (height > 0);
+
+ if (node == NULL)
+ return NULL;
+
+ return get_slot ? (void *)&prev->entries[index] : node;
+}
+
+void *
+rdxtree_replace_slot(void **slot, void *ptr)
+{
+ void *old;
+
+ assert(ptr != NULL);
+ assert(rdxtree_check_alignment(ptr));
+
+ old = *slot;
+ assert(old != NULL);
+ assert(rdxtree_check_alignment(old));
+ llsync_assign_ptr(*slot, ptr);
+ return old;
+}
+
+static void *
+rdxtree_walk_next(struct rdxtree *tree, struct rdxtree_iter *iter)
+{
+ struct rdxtree_node *root, *node, *prev;
+ unsigned int height, shift, index, orig_index;
+ rdxtree_key_t key;
+ void *entry;
+
+ entry = llsync_read_ptr(tree->root);
+
+ if (entry == NULL)
+ return NULL;
+
+ if (!rdxtree_entry_is_node(entry)) {
+ if (iter->key != (rdxtree_key_t)-1)
+ return NULL;
+ else {
+ iter->key = 0;
+ return rdxtree_entry_addr(entry);
+ }
+ }
+
+ key = iter->key + 1;
+
+ if ((key == 0) && (iter->node != NULL))
+ return NULL;
+
+ root = rdxtree_entry_addr(entry);
+
+restart:
+ node = root;
+ height = root->height + 1;
+
+ if (key > rdxtree_max_key(height))
+ return NULL;
+
+ shift = (height - 1) * RDXTREE_RADIX;
+
+ do {
+ prev = node;
+ index = (key >> shift) & RDXTREE_RADIX_MASK;
+ orig_index = index;
+ node = rdxtree_node_find(node, &index);
+
+ if (node == NULL) {
+ shift += RDXTREE_RADIX;
+ key = ((key >> shift) + 1) << shift;
+
+ if (key == 0)
+ return NULL;
+
+ goto restart;
+ }
+
+ if (orig_index != index)
+ key = ((key >> shift) + (index - orig_index)) << shift;
+
+ shift -= RDXTREE_RADIX;
+ height--;
+ } while (height > 0);
+
+ iter->node = prev;
+ iter->key = key;
+ return node;
+}
+
+void *
+rdxtree_walk(struct rdxtree *tree, struct rdxtree_iter *iter)
+{
+ unsigned int index, orig_index;
+ void *ptr;
+
+ if (iter->node == NULL)
+ return rdxtree_walk_next(tree, iter);
+
+ index = (iter->key + 1) & RDXTREE_RADIX_MASK;
+
+ if (index != 0) {
+ orig_index = index;
+ ptr = rdxtree_node_find(iter->node, &index);
+
+ if (ptr != NULL) {
+ iter->key += (index - orig_index) + 1;
+ return ptr;
+ }
+ }
+
+ return rdxtree_walk_next(tree, iter);
+}
+
+void
+rdxtree_remove_all(struct rdxtree *tree)
+{
+ struct rdxtree_node *node, *parent;
+ struct rdxtree_iter iter;
+
+ if (tree->height == 0) {
+ if (tree->root != NULL)
+ llsync_assign_ptr(tree->root, NULL);
+
+ return;
+ }
+
+ for (;;) {
+ rdxtree_iter_init(&iter);
+ rdxtree_walk_next(tree, &iter);
+
+ if (iter.node == NULL)
+ break;
+
+ node = iter.node;
+ parent = node->parent;
+
+ if (parent == NULL)
+ rdxtree_init(tree);
+ else {
+ rdxtree_node_remove(parent, node->index);
+ rdxtree_remove_bm_set(parent, node->index);
+ rdxtree_cleanup(tree, parent);
+ node->parent = NULL;
+ }
+
+ rdxtree_node_schedule_destruction(node);
+ }
+}
diff --git a/kern/rdxtree.h b/kern/rdxtree.h
new file mode 100644
index 00000000..1f8456e0
--- /dev/null
+++ b/kern/rdxtree.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2011-2015 Richard Braun.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Radix tree.
+ *
+ * In addition to the standard insertion operation, this implementation
+ * can allocate keys for the caller at insertion time.
+ *
+ * Upstream site with license notes :
+ * http://git.sceen.net/rbraun/librbraun.git/
+ */
+
+#ifndef _RDXTREE_H
+#define _RDXTREE_H
+
+#include <stddef.h>
+#include <sys/types.h>
+
+/*
+ * Initialize the node cache.
+ */
+void rdxtree_cache_init(void);
+
+/*
+ * This macro selects between 32 or 64-bits (the default) keys.
+ */
+#if 0
+#define RDXTREE_KEY_32
+#endif
+
+#ifdef RDXTREE_KEY_32
+typedef uint32_t rdxtree_key_t;
+#else /* RDXTREE_KEY_32 */
+typedef uint64_t rdxtree_key_t;
+#endif /* RDXTREE_KEY_32 */
+
+/*
+ * Radix tree.
+ */
+struct rdxtree;
+
+/*
+ * Radix tree iterator.
+ */
+struct rdxtree_iter;
+
+/*
+ * Static tree initializer.
+ */
+#define RDXTREE_INITIALIZER { 0, NULL }
+
+#include "rdxtree_i.h"
+
+/*
+ * Initialize a tree.
+ */
+static inline void
+rdxtree_init(struct rdxtree *tree)
+{
+ tree->height = 0;
+ tree->root = NULL;
+}
+
+/*
+ * Insert a pointer in a tree.
+ *
+ * The ptr parameter must not be NULL.
+ */
+static inline int
+rdxtree_insert(struct rdxtree *tree, rdxtree_key_t key, void *ptr)
+{
+ return rdxtree_insert_common(tree, key, ptr, NULL);
+}
+
+/*
+ * Insert a pointer in a tree and obtain its slot.
+ *
+ * The ptr and slotp parameters must not be NULL. If successful, the slot of
+ * the newly inserted pointer is stored at the address pointed to by the slotp
+ * parameter.
+ */
+static inline int
+rdxtree_insert_slot(struct rdxtree *tree, rdxtree_key_t key,
+ void *ptr, void ***slotp)
+{
+ return rdxtree_insert_common(tree, key, ptr, slotp);
+}
+
+/*
+ * Insert a pointer in a tree, for which a new key is allocated.
+ *
+ * The ptr and keyp parameters must not be NULL. The newly allocated key is
+ * stored at the address pointed to by the keyp parameter.
+ */
+static inline int
+rdxtree_insert_alloc(struct rdxtree *tree, void *ptr, rdxtree_key_t *keyp)
+{
+ return rdxtree_insert_alloc_common(tree, ptr, keyp, NULL);
+}
+
+/*
+ * Insert a pointer in a tree, for which a new key is allocated, and obtain
+ * its slot.
+ *
+ * The ptr, keyp and slotp parameters must not be NULL. The newly allocated
+ * key is stored at the address pointed to by the keyp parameter while the
+ * slot of the inserted pointer is stored at the address pointed to by the
+ * slotp parameter.
+ */
+static inline int
+rdxtree_insert_alloc_slot(struct rdxtree *tree, void *ptr,
+ rdxtree_key_t *keyp, void ***slotp)
+{
+ return rdxtree_insert_alloc_common(tree, ptr, keyp, slotp);
+}
+
+/*
+ * Remove a pointer from a tree.
+ *
+ * The matching pointer is returned if successful, NULL otherwise.
+ */
+void * rdxtree_remove(struct rdxtree *tree, rdxtree_key_t key);
+
+/*
+ * Look up a pointer in a tree.
+ *
+ * The matching pointer is returned if successful, NULL otherwise.
+ */
+static inline void *
+rdxtree_lookup(const struct rdxtree *tree, rdxtree_key_t key)
+{
+ return rdxtree_lookup_common(tree, key, 0);
+}
+
+/*
+ * Look up a slot in a tree.
+ *
+ * A slot is a pointer to a stored pointer in a tree. It can be used as
+ * a placeholder for fast replacements to avoid multiple lookups on the same
+ * key.
+ *
+ * A slot for the matching pointer is returned if successful, NULL otherwise.
+ *
+ * See rdxtree_replace_slot().
+ */
+static inline void **
+rdxtree_lookup_slot(const struct rdxtree *tree, rdxtree_key_t key)
+{
+ return rdxtree_lookup_common(tree, key, 1);
+}
+
+/*
+ * Replace a pointer in a tree.
+ *
+ * The ptr parameter must not be NULL. The previous pointer is returned.
+ *
+ * See rdxtree_lookup_slot().
+ */
+void * rdxtree_replace_slot(void **slot, void *ptr);
+
+/*
+ * Forge a loop to process all pointers of a tree.
+ */
+#define rdxtree_for_each(tree, iter, ptr) \
+for (rdxtree_iter_init(iter), ptr = rdxtree_walk(tree, iter); \
+ ptr != NULL; \
+ ptr = rdxtree_walk(tree, iter))
+
+/*
+ * Return the key of the current pointer from an iterator.
+ */
+static inline rdxtree_key_t
+rdxtree_iter_key(const struct rdxtree_iter *iter)
+{
+ return iter->key;
+}
+
+/*
+ * Remove all pointers from a tree.
+ *
+ * The common way to destroy a tree and its pointers is to loop over all
+ * the pointers using rdxtree_for_each(), freeing them, then call this
+ * function.
+ */
+void rdxtree_remove_all(struct rdxtree *tree);
+
+#endif /* _RDXTREE_H */
diff --git a/kern/rdxtree_i.h b/kern/rdxtree_i.h
new file mode 100644
index 00000000..1bd1f64a
--- /dev/null
+++ b/kern/rdxtree_i.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2013-2015 Richard Braun.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Upstream site with license notes :
+ * http://git.sceen.net/rbraun/librbraun.git/
+ */
+
+#ifndef _RDXTREE_I_H
+#define _RDXTREE_I_H
+
+/*
+ * Radix tree.
+ */
+struct rdxtree {
+ unsigned int height;
+ void *root;
+};
+
+/*
+ * Radix tree iterator.
+ *
+ * The node member refers to the node containing the current pointer, if any.
+ * The key member refers to the current pointer, and is valid if and only if
+ * rdxtree_walk() has been called at least once on the iterator.
+ */
+struct rdxtree_iter {
+ void *node;
+ rdxtree_key_t key;
+};
+
+/*
+ * Initialize an iterator.
+ */
+static inline void
+rdxtree_iter_init(struct rdxtree_iter *iter)
+{
+ iter->node = NULL;
+ iter->key = (rdxtree_key_t)-1;
+}
+
+int rdxtree_insert_common(struct rdxtree *tree, rdxtree_key_t key,
+ void *ptr, void ***slotp);
+
+int rdxtree_insert_alloc_common(struct rdxtree *tree, void *ptr,
+ rdxtree_key_t *keyp, void ***slotp);
+
+void * rdxtree_lookup_common(const struct rdxtree *tree, rdxtree_key_t key,
+ int get_slot);
+
+void * rdxtree_walk(struct rdxtree *tree, struct rdxtree_iter *iter);
+
+#endif /* _RDXTREE_I_H */
diff --git a/kern/refcount.h b/kern/refcount.h
index 7fd6cdfb..f32feb87 100644
--- a/kern/refcount.h
+++ b/kern/refcount.h
@@ -27,9 +27,7 @@
#ifndef _KERN_REFCOUNT_H_
#define _KERN_REFCOUNT_H_
-#include <kern/macro_help.h>
-
-#include "refcount.h" /*XXX*/
+#include <kern/macros.h>
/* Unless the above include file specified otherwise,
use the system-independent (unoptimized) atomic reference counter. */
@@ -65,6 +63,6 @@ typedef struct RefCount RefCount;
if (new_value == 0) { func; } \
MACRO_END
-#endif
+#endif /* MACHINE_REFCOUNT */
-#endif _KERN_REFCOUNT_H_
+#endif /* _KERN_REFCOUNT_H_ */
diff --git a/kern/sched.h b/kern/sched.h
index 434e0228..f82f9f56 100644
--- a/kern/sched.h
+++ b/kern/sched.h
@@ -38,7 +38,7 @@
#include <kern/queue.h>
#include <kern/lock.h>
#include <kern/kern_types.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#if MACH_FIXPRI
#include <mach/policy.h>
@@ -60,7 +60,7 @@
#include <machine/sched_param.h>
#endif /* STAT_TIME */
-#define NRQS 32 /* 32 run queues per cpu */
+#define NRQS 50 /* 50 run queues per cpu */
struct run_queue {
queue_head_t runq[NRQS]; /* one for each priority */
@@ -118,7 +118,7 @@ extern int min_quantum; /* defines max context switch rate */
* Default base priorities for threads.
*/
#define BASEPRI_SYSTEM 6
-#define BASEPRI_USER 12
+#define BASEPRI_USER 25
/*
* Macro to check for invalid priorities.
@@ -153,7 +153,7 @@ extern unsigned sched_tick;
#define thread_timer_delta(thread) \
MACRO_BEGIN \
- register unsigned delta; \
+ unsigned delta; \
\
delta = 0; \
TIMER_DELTA((thread)->system_timer, \
diff --git a/kern/sched_prim.c b/kern/sched_prim.c
index ba2dc8ab..e8f260e3 100644
--- a/kern/sched_prim.c
+++ b/kern/sched_prim.c
@@ -44,7 +44,7 @@
#include <kern/lock.h>
#include <kern/mach_clock.h>
#include <kern/mach_factor.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/processor.h>
#include <kern/queue.h>
#include <kern/sched.h>
@@ -70,18 +70,8 @@ int sched_usec;
thread_t sched_thread_id;
-void set_pri(thread_t, int, boolean_t);
-void do_thread_scan(void);
-
-thread_t choose_pset_thread();
-
timer_elt_data_t recompute_priorities_timer;
-#if DEBUG
-void checkrq(run_queue_t, char *);
-void thread_check(thread_t, run_queue_t);
-#endif
-
/*
* State machine
*
@@ -150,7 +140,7 @@ decl_simple_lock_data(, wait_lock[NUMQUEUES])
void wait_queue_init(void)
{
- register int i;
+ int i;
for (i = 0; i < NUMQUEUES; i++) {
queue_init(&wait_queue[i]);
@@ -165,7 +155,7 @@ void sched_init(void)
min_quantum = hz / 10; /* context switch 10 times/second */
wait_queue_init();
- pset_sys_bootstrap(); /* initialize processer mgmt. */
+ pset_sys_bootstrap(); /* initialize processor mgmt. */
queue_init(&action_queue);
simple_lock_init(&action_lock);
sched_tick = 0;
@@ -199,8 +189,8 @@ void thread_timeout(
void thread_set_timeout(
int t) /* timeout interval in ticks */
{
- register thread_t thread = current_thread();
- register spl_t s;
+ thread_t thread = current_thread();
+ spl_t s;
s = splsched();
thread_lock(thread);
@@ -215,7 +205,7 @@ void thread_set_timeout(
* Set up thread timeout element when thread is created.
*/
void thread_timeout_setup(
- register thread_t thread)
+ thread_t thread)
{
thread->timer.fcn = thread_timeout;
thread->timer.param = thread;
@@ -233,12 +223,10 @@ void assert_wait(
event_t event,
boolean_t interruptible)
{
- register queue_t q;
- register int index;
- register thread_t thread;
-#if MACH_SLOCKS
- register simple_lock_t lock;
-#endif /* MACH_SLOCKS */
+ queue_t q;
+ int index;
+ thread_t thread;
+ decl_simple_lock_data( , *lock);
spl_t s;
thread = current_thread();
@@ -250,12 +238,10 @@ void assert_wait(
if (event != 0) {
index = wait_hash(event);
q = &wait_queue[index];
-#if MACH_SLOCKS
lock = &wait_lock[index];
-#endif /* MACH_SLOCKS */
simple_lock(lock);
thread_lock(thread);
- enqueue_tail(q, (queue_entry_t) thread);
+ enqueue_tail(q, &(thread->links));
thread->wait_event = event;
if (interruptible)
thread->state |= TH_WAIT;
@@ -288,16 +274,14 @@ void assert_wait(
* interruptible.
*/
void clear_wait(
- register thread_t thread,
+ thread_t thread,
int result,
boolean_t interrupt_only)
{
- register int index;
- register queue_t q;
-#if MACH_SLOCKS
- register simple_lock_t lock;
-#endif /* MACH_SLOCKS */
- register event_t event;
+ int index;
+ queue_t q;
+ decl_simple_lock_data( , *lock);
+ event_t event;
spl_t s;
s = splsched();
@@ -316,9 +300,7 @@ void clear_wait(
thread_unlock(thread);
index = wait_hash(event);
q = &wait_queue[index];
-#if MACH_SLOCKS
lock = &wait_lock[index];
-#endif /* MACH_SLOCKS */
simple_lock(lock);
/*
* If the thread is still waiting on that event,
@@ -335,7 +317,7 @@ void clear_wait(
simple_unlock(lock);
}
if (event == 0) {
- register int state = thread->state;
+ int state = thread->state;
reset_timeout_check(&thread->timer);
@@ -376,7 +358,7 @@ void clear_wait(
}
static inline void __attribute__((noreturn))
-state_panic(thread_t thread, const char *caller)
+state_panic(const thread_t thread, const char *caller)
{
panic ("%s: thread %x has unexpected state %x",
caller, thread, thread->state);
@@ -394,21 +376,17 @@ void thread_wakeup_prim(
boolean_t one_thread,
int result)
{
- register queue_t q;
- register int index;
- register thread_t thread, next_th;
-#if MACH_SLOCKS
- register simple_lock_t lock;
-#endif /* MACH_SLOCKS */
+ queue_t q;
+ int index;
+ thread_t thread, next_th;
+ decl_simple_lock_data( , *lock);
spl_t s;
- register int state;
+ int state;
index = wait_hash(event);
q = &wait_queue[index];
s = splsched();
-#if MACH_SLOCKS
lock = &wait_lock[index];
-#endif /* MACH_SLOCKS */
simple_lock(lock);
thread = (thread_t) queue_first(q);
while (!queue_end(q, (queue_entry_t)thread)) {
@@ -490,8 +468,8 @@ void thread_sleep(
* xxx - DO NOT export this to users.
*/
void thread_bind(
- register thread_t thread,
- processor_t processor)
+ thread_t thread,
+ processor_t processor)
{
spl_t s;
@@ -509,9 +487,9 @@ void thread_bind(
*/
thread_t thread_select(
- register processor_t myprocessor)
+ processor_t myprocessor)
{
- register thread_t thread;
+ thread_t thread;
myprocessor->first_quantum = TRUE;
/*
@@ -523,7 +501,7 @@ thread_t thread_select(
myprocessor->quantum = min_quantum;
}
else {
- register processor_set_t pset;
+ processor_set_t pset;
#if MACH_HOST
pset = myprocessor->processor_set;
@@ -559,7 +537,7 @@ thread_t thread_select(
}
}
else {
- register queue_t q;
+ queue_t q;
/*
* If there is a thread at hint, grab it,
@@ -622,9 +600,9 @@ thread_t thread_select(
*/
boolean_t thread_invoke(
- register thread_t old_thread,
- continuation_t continuation,
- register thread_t new_thread)
+ thread_t old_thread,
+ continuation_t continuation,
+ thread_t new_thread)
{
/*
* Check for invoking the same thread.
@@ -637,7 +615,7 @@ boolean_t thread_invoke(
thread_lock(new_thread);
new_thread->state &= ~TH_UNINT;
thread_unlock(new_thread);
- thread_wakeup(&new_thread->state);
+ thread_wakeup(TH_EV_STATE(new_thread));
if (continuation != (void (*)()) 0) {
(void) spl0();
@@ -659,7 +637,7 @@ boolean_t thread_invoke(
new_thread->state &= ~(TH_SWAPPED | TH_UNINT);
thread_unlock(new_thread);
- thread_wakeup(&new_thread->state);
+ thread_wakeup(TH_EV_STATE(new_thread));
#if NCPUS > 1
new_thread->last_processor = current_processor();
@@ -698,7 +676,7 @@ boolean_t thread_invoke(
if (old_thread->wake_active) {
old_thread->wake_active = FALSE;
thread_unlock(old_thread);
- thread_wakeup((event_t)&old_thread->wake_active);
+ thread_wakeup(TH_EV_WAKE_ACTIVE(old_thread));
goto after_old_thread;
}
@@ -748,7 +726,7 @@ boolean_t thread_invoke(
* running out of stack.
*/
- counter_always(c_thread_invoke_hits++);
+ counter(c_thread_invoke_hits++);
(void) spl0();
call_continuation(new_thread->swap_func);
/*NOTREACHED*/
@@ -760,7 +738,7 @@ boolean_t thread_invoke(
*/
thread_swapin(new_thread);
thread_unlock(new_thread);
- counter_always(c_thread_invoke_misses++);
+ counter(c_thread_invoke_misses++);
return FALSE;
case 0:
@@ -781,7 +759,7 @@ boolean_t thread_invoke(
{
thread_swapin(new_thread);
thread_unlock(new_thread);
- counter_always(c_thread_invoke_misses++);
+ counter(c_thread_invoke_misses++);
return FALSE;
}
}
@@ -789,7 +767,7 @@ boolean_t thread_invoke(
new_thread->state &= ~(TH_SWAPPED | TH_UNINT);
thread_unlock(new_thread);
- thread_wakeup(&new_thread->state);
+ thread_wakeup(TH_EV_STATE(new_thread));
/*
* Thread is now interruptible.
@@ -810,7 +788,7 @@ boolean_t thread_invoke(
* changing address spaces. It updates active_threads.
* It returns only if a continuation is not supplied.
*/
- counter_always(c_thread_invoke_csw++);
+ counter(c_thread_invoke_csw++);
old_thread = switch_context(old_thread, continuation, new_thread);
/*
@@ -829,9 +807,9 @@ boolean_t thread_invoke(
* Called at splsched.
*/
void thread_continue(
- register thread_t old_thread)
+ thread_t old_thread)
{
- register continuation_t continuation = current_thread()->swap_func;
+ continuation_t continuation = current_thread()->swap_func;
/*
* We must dispatch the old thread and then
@@ -865,9 +843,9 @@ void thread_continue(
void thread_block(
continuation_t continuation)
{
- register thread_t thread = current_thread();
- register processor_t myprocessor = cpu_to_processor(cpu_number());
- register thread_t new_thread;
+ thread_t thread = current_thread();
+ processor_t myprocessor = cpu_to_processor(cpu_number());
+ thread_t new_thread;
spl_t s;
check_simple_locks();
@@ -906,10 +884,10 @@ void thread_block(
*/
void thread_run(
continuation_t continuation,
- register thread_t new_thread)
+ thread_t new_thread)
{
- register thread_t thread = current_thread();
- register processor_t myprocessor = cpu_to_processor(cpu_number());
+ thread_t thread = current_thread();
+ processor_t myprocessor = cpu_to_processor(cpu_number());
spl_t s;
check_simple_locks();
@@ -928,7 +906,7 @@ void thread_run(
*/
void thread_dispatch(
- register thread_t thread)
+ thread_t thread)
{
/*
* If we are discarding the thread's stack, we must do it
@@ -954,7 +932,7 @@ void thread_dispatch(
if (thread->wake_active) {
thread->wake_active = FALSE;
thread_unlock(thread);
- thread_wakeup((event_t)&thread->wake_active);
+ thread_wakeup(TH_EV_WAKE_ACTIVE(thread));
return;
}
break;
@@ -1020,7 +998,7 @@ shift_data_t wait_shift[32] = {
(pri) = (th)->priority /* start with base priority */ \
+ ((th)->sched_usage >> (PRI_SHIFT + SCHED_SHIFT)) \
+ ((th)->sched_usage >> (PRI_SHIFT_2 + SCHED_SHIFT)); \
- if ((pri) > 31) (pri) = 31; \
+ if ((pri) > NRQS - 1) (pri) = NRQS - 1; \
MACRO_END
#else /* PRI_SHIFT_2 */
#define do_priority_computation(th, pri) \
@@ -1028,7 +1006,7 @@ shift_data_t wait_shift[32] = {
(pri) = (th)->priority /* start with base priority */ \
+ ((th)->sched_usage >> (PRI_SHIFT + SCHED_SHIFT)) \
- ((th)->sched_usage >> (SCHED_SHIFT - PRI_SHIFT_2)); \
- if ((pri) > 31) (pri) = 31; \
+ if ((pri) > NRQS - 1) (pri) = NRQS - 1; \
MACRO_END
#endif /* PRI_SHIFT_2 */
#else /* defined(PRI_SHIFT_2) */
@@ -1036,7 +1014,7 @@ shift_data_t wait_shift[32] = {
MACRO_BEGIN \
(pri) = (th)->priority /* start with base priority */ \
+ ((th)->sched_usage >> (PRI_SHIFT + SCHED_SHIFT)); \
- if ((pri) > 31) (pri) = 31; \
+ if ((pri) > NRQS - 1) (pri) = NRQS - 1; \
MACRO_END
#endif /* defined(PRI_SHIFT_2) */
@@ -1053,10 +1031,10 @@ shift_data_t wait_shift[32] = {
*/
void compute_priority(
- register thread_t thread,
+ thread_t thread,
boolean_t resched)
{
- register int pri;
+ int pri;
#if MACH_FIXPRI
if (thread->policy == POLICY_TIMESHARE) {
@@ -1085,9 +1063,9 @@ void compute_priority(
*/
void compute_my_priority(
- register thread_t thread)
+ thread_t thread)
{
- register int temp_pri;
+ int temp_pri;
do_priority_computation(thread,temp_pri);
thread->sched_pri = temp_pri;
@@ -1132,11 +1110,11 @@ void recompute_priorities(void *param)
* can only be called by the thread on itself.
*/
void update_priority(
- register thread_t thread)
+ thread_t thread)
{
- register unsigned int ticks;
- register shift_t shiftp;
- register int temp_pri;
+ unsigned int ticks;
+ shift_t shiftp;
+ int temp_pri;
ticks = sched_tick - thread->sched_stamp;
@@ -1196,7 +1174,7 @@ void update_priority(
#if DEBUG
#define run_queue_enqueue(rq, th) \
MACRO_BEGIN \
- register unsigned int whichq; \
+ unsigned int whichq; \
\
whichq = (th)->sched_pri; \
if (whichq >= NRQS) { \
@@ -1206,7 +1184,7 @@ void update_priority(
\
simple_lock(&(rq)->lock); /* lock the run queue */ \
checkrq((rq), "thread_setrun: before adding thread"); \
- enqueue_tail(&(rq)->runq[whichq], (queue_entry_t) (th)); \
+ enqueue_tail(&(rq)->runq[whichq], &((th)->links)); \
\
if (whichq < (rq)->low || (rq)->count == 0) \
(rq)->low = whichq; /* minimize */ \
@@ -1220,7 +1198,7 @@ void update_priority(
#else /* DEBUG */
#define run_queue_enqueue(rq, th) \
MACRO_BEGIN \
- register unsigned int whichq; \
+ unsigned int whichq; \
\
whichq = (th)->sched_pri; \
if (whichq >= NRQS) { \
@@ -1229,7 +1207,7 @@ void update_priority(
} \
\
simple_lock(&(rq)->lock); /* lock the run queue */ \
- enqueue_tail(&(rq)->runq[whichq], (queue_entry_t) (th)); \
+ enqueue_tail(&(rq)->runq[whichq], &((th)->links)); \
\
if (whichq < (rq)->low || (rq)->count == 0) \
(rq)->low = whichq; /* minimize */ \
@@ -1249,13 +1227,13 @@ void update_priority(
*/
void thread_setrun(
- register thread_t th,
+ thread_t th,
boolean_t may_preempt)
{
- register processor_t processor;
- register run_queue_t rq;
+ processor_t processor;
+ run_queue_t rq;
#if NCPUS > 1
- register processor_set_t pset;
+ processor_set_t pset;
#endif /* NCPUS > 1 */
/*
@@ -1423,7 +1401,7 @@ void set_pri(
int pri,
boolean_t resched)
{
- register struct run_queue *rq;
+ struct run_queue *rq;
rq = rem_runq(th);
th->sched_pri = pri;
@@ -1448,7 +1426,7 @@ void set_pri(
struct run_queue *rem_runq(
thread_t th)
{
- register struct run_queue *rq;
+ struct run_queue *rq;
rq = th->runq;
/*
@@ -1514,10 +1492,10 @@ thread_t choose_thread(
processor_t myprocessor)
{
thread_t th;
- register queue_t q;
- register run_queue_t runq;
- register int i;
- register processor_set_t pset;
+ queue_t q;
+ run_queue_t runq;
+ int i;
+ processor_set_t pset;
runq = &myprocessor->runq;
@@ -1558,13 +1536,13 @@ thread_t choose_thread(
*/
thread_t choose_pset_thread(
- register processor_t myprocessor,
+ processor_t myprocessor,
processor_set_t pset)
{
- register run_queue_t runq;
- register thread_t th;
- register queue_t q;
- register int i;
+ run_queue_t runq;
+ thread_t th;
+ queue_t q;
+ int i;
runq = &pset->runq;
@@ -1640,14 +1618,14 @@ int no_dispatch_count = 0;
* to execute.
*/
-void idle_thread_continue(void)
+void __attribute__((noreturn)) idle_thread_continue(void)
{
- register processor_t myprocessor;
- register volatile thread_t *threadp;
- register volatile int *gcount;
- register volatile int *lcount;
- register thread_t new_thread;
- register int state;
+ processor_t myprocessor;
+ volatile thread_t *threadp;
+ volatile int *gcount;
+ volatile int *lcount;
+ thread_t new_thread;
+ int state;
int mycpu;
spl_t s;
@@ -1746,7 +1724,7 @@ retry:
thread_run(idle_thread_continue, new_thread);
}
else if (state == PROCESSOR_IDLE) {
- register processor_set_t pset;
+ processor_set_t pset;
pset = myprocessor->processor_set;
simple_lock(&pset->idle_lock);
@@ -1797,14 +1775,14 @@ retry:
void idle_thread(void)
{
- register thread_t self = current_thread();
+ thread_t self = current_thread();
spl_t s;
stack_privilege(self);
s = splsched();
- self->priority = 31;
- self->sched_pri = 31;
+ self->priority = NRQS-1;
+ self->sched_pri = NRQS-1;
/*
* Set the idle flag to indicate that this is an idle thread,
@@ -1900,10 +1878,10 @@ boolean_t
do_runq_scan(
run_queue_t runq)
{
- register spl_t s;
- register queue_t q;
- register thread_t thread;
- register int count;
+ spl_t s;
+ queue_t q;
+ thread_t thread;
+ int count;
s = splsched();
simple_lock(&runq->lock);
@@ -1964,11 +1942,11 @@ if (do_thread_scan_debug)
void do_thread_scan(void)
{
- register spl_t s;
- register boolean_t restart_needed = 0;
- register thread_t thread;
+ spl_t s;
+ boolean_t restart_needed = 0;
+ thread_t thread;
#if MACH_HOST
- register processor_set_t pset;
+ processor_set_t pset;
#endif /* MACH_HOST */
do {
@@ -2012,12 +1990,12 @@ void do_thread_scan(void)
#if DEBUG
void checkrq(
run_queue_t rq,
- char *msg)
+ const char *msg)
{
- register queue_t q1;
- register int i, j;
- register queue_entry_t e;
- register int low;
+ queue_t q1;
+ int i, j;
+ queue_entry_t e;
+ int low;
low = -1;
j = 0;
@@ -2048,10 +2026,10 @@ void checkrq(
}
void thread_check(
- register thread_t th,
- register run_queue_t rq)
+ thread_t th,
+ run_queue_t rq)
{
- register unsigned int whichq;
+ unsigned int whichq;
whichq = th->sched_pri;
if (whichq >= NRQS) {
diff --git a/kern/sched_prim.h b/kern/sched_prim.h
index 5311d160..62698dc2 100644
--- a/kern/sched_prim.h
+++ b/kern/sched_prim.h
@@ -69,7 +69,7 @@ extern void thread_sleep(
event_t event,
simple_lock_t lock,
boolean_t interruptible);
-extern void thread_wakeup(); /* for function pointers */
+extern void thread_wakeup(void); /* for function pointers */
extern void thread_wakeup_prim(
event_t event,
boolean_t one_thread,
@@ -103,7 +103,7 @@ extern boolean_t thread_handoff(
thread_t old_thread,
continuation_t continuation,
thread_t new_thread);
-extern void recompute_priorities();
+extern void recompute_priorities(void *param);
extern void update_priority(
thread_t thread);
extern void compute_my_priority(
@@ -115,7 +115,7 @@ extern void compute_priority(
thread_t thread,
boolean_t resched);
extern void thread_timeout_setup(
- register thread_t thread);
+ thread_t thread);
/*
* Routines defined as macros
@@ -132,13 +132,10 @@ extern void thread_timeout_setup(
* Machine-dependent code must define these functions.
*/
-extern void thread_bootstrap_return(void);
-extern void thread_exception_return(void);
-#ifdef __GNUC__
+extern void thread_bootstrap_return(void) __attribute__((noreturn));
+extern void thread_exception_return(void) __attribute__((noreturn));
extern void __attribute__((__noreturn__)) thread_syscall_return(kern_return_t);
-#else
-extern void thread_syscall_return(kern_return_t);
-#endif
+
extern thread_t switch_context(
thread_t old_thread,
continuation_t continuation,
@@ -153,7 +150,7 @@ extern void stack_handoff(
* or are defined directly by machine-dependent code.
*/
-extern void stack_alloc(
+extern kern_return_t stack_alloc(
thread_t thread,
void (*resume)(thread_t));
extern boolean_t stack_alloc_try(
@@ -172,4 +169,16 @@ extern void stack_free(
#define convert_ipc_timeout_to_ticks(millis) \
(((millis) * hz + 999) / 1000)
+void set_pri(thread_t th, int pri, boolean_t resched);
+void do_thread_scan(void);
+thread_t choose_pset_thread(processor_t myprocessor, processor_set_t pset);
+
+#if DEBUG
+void checkrq(run_queue_t rq, char *msg);
+void thread_check(thread_t th, run_queue_t rq);
+#endif /* DEBUG */
+
+extern void idle_thread(void) __attribute__((noreturn));
+extern void sched_thread(void);
+
#endif /* _KERN_SCHED_PRIM_H_ */
diff --git a/kern/server_loop.ch b/kern/server_loop.ch
deleted file mode 100644
index 409e013d..00000000
--- a/kern/server_loop.ch
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: kern/server_loop.c
- *
- * A common server loop for builtin tasks.
- */
-
-/*
- * Must define symbols for:
- * SERVER_NAME String name of this module
- * SERVER_LOOP Routine name for the loop
- * SERVER_DISPATCH MiG function(s) to handle message
- *
- * Must redefine symbols for pager_server functions.
- */
-
-#include <kern/debug.h>
-#include <kern/kalloc.h>
-#include <mach/port.h>
-#include <mach/message.h>
-#include <vm/vm_kern.h> /* for kernel_map */
-
-void SERVER_LOOP(rcv_set, max_size)
-{
- register mach_msg_header_t *in_msg;
- register mach_msg_header_t *out_msg;
- register mach_msg_header_t *tmp_msg;
- vm_offset_t messages;
- mach_msg_return_t r;
-
- /*
- * Allocate our message buffers.
- */
-
- messages = kalloc(2 * max_size);
- if (messages == 0)
- panic(SERVER_NAME);
- in_msg = (mach_msg_header_t *) messages;
- out_msg = (mach_msg_header_t *) (messages + max_size);
-
- /*
- * Service loop... receive messages and process them.
- */
-
- for (;;) {
- /* receive first message */
-
- receive_msg:
- r = mach_msg(in_msg, MACH_RCV_MSG, 0, max_size, rcv_set,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if (r == MACH_MSG_SUCCESS)
- break;
-
- printf("%s: receive failed, 0x%x.\n", SERVER_NAME, r);
- }
-
- for (;;) {
- /* process request message */
-
- (void) SERVER_DISPATCH(in_msg, out_msg);
-
- /* send reply and receive next request */
-
- if (out_msg->msgh_remote_port == MACH_PORT_NULL)
- goto receive_msg;
-
- r = mach_msg(out_msg, MACH_SEND_MSG|MACH_RCV_MSG,
- out_msg->msgh_size, max_size, rcv_set,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if (r != MACH_MSG_SUCCESS) {
- printf("%s: send/receive failed, 0x%x.\n",
- SERVER_NAME, r);
- goto receive_msg;
- }
-
- /* swap message buffers */
-
- tmp_msg = in_msg; in_msg = out_msg; out_msg = tmp_msg;
- }
-}
diff --git a/kern/shuttle.h b/kern/shuttle.h
index e8e574b6..0b1c2c5e 100644
--- a/kern/shuttle.h
+++ b/kern/shuttle.h
@@ -68,4 +68,4 @@ typedef struct Shuttle Shuttle;
-#endif _KERN_SHUTTLE_H_
+#endif /* _KERN_SHUTTLE_H_ */
diff --git a/kern/slab.c b/kern/slab.c
index 99d5bca3..1114cfa3 100644
--- a/kern/slab.c
+++ b/kern/slab.c
@@ -79,6 +79,7 @@
#include <string.h>
#include <kern/assert.h>
#include <kern/mach_clock.h>
+#include <kern/macros.h>
#include <kern/printf.h>
#include <kern/slab.h>
#include <kern/kalloc.h>
@@ -96,7 +97,6 @@
/*
* Utility macros.
*/
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define P2ALIGNED(x, a) (((x) & ((a) - 1)) == 0)
#define ISP2(x) P2ALIGNED(x, x)
#define P2ALIGN(x, a) ((x) & -(a))
@@ -165,7 +165,7 @@
/*
* Size of the VM submap from which default backend functions allocate.
*/
-#define KMEM_MAP_SIZE (128 * 1024 * 1024)
+#define KMEM_MAP_SIZE (96 * 1024 * 1024)
/*
* Shift for the first kalloc cache size.
@@ -289,8 +289,8 @@ vm_map_t kmem_map = &kmem_map_store;
static unsigned long kmem_gc_last_tick;
#define kmem_error(format, ...) \
- printf("mem: error: %s(): " format "\n", __func__, \
- ## __VA_ARGS__)
+ panic("mem: error: %s(): " format "\n", __func__, \
+ ## __VA_ARGS__)
#define kmem_warn(format, ...) \
printf("mem: warning: %s(): " format "\n", __func__, \
@@ -615,18 +615,24 @@ static inline void kmem_cpu_pool_push(struct kmem_cpu_pool *cpu_pool, void *obj)
static int kmem_cpu_pool_fill(struct kmem_cpu_pool *cpu_pool,
struct kmem_cache *cache)
{
- void *obj;
+ kmem_cache_ctor_t ctor;
+ void *buf;
int i;
+ ctor = (cpu_pool->flags & KMEM_CF_VERIFY) ? NULL : cache->ctor;
+
simple_lock(&cache->lock);
for (i = 0; i < cpu_pool->transfer_size; i++) {
- obj = kmem_cache_alloc_from_slab(cache);
+ buf = kmem_cache_alloc_from_slab(cache);
- if (obj == NULL)
+ if (buf == NULL)
break;
- kmem_cpu_pool_push(cpu_pool, obj);
+ if (ctor != NULL)
+ ctor(buf);
+
+ kmem_cpu_pool_push(cpu_pool, buf);
}
simple_unlock(&cache->lock);
@@ -656,7 +662,7 @@ static void kmem_cache_error(struct kmem_cache *cache, void *buf, int error,
{
struct kmem_buftag *buftag;
- kmem_error("cache: %s, buffer: %p", cache->name, (void *)buf);
+ kmem_warn("cache: %s, buffer: %p", cache->name, (void *)buf);
switch(error) {
case KMEM_ERR_INVALID:
@@ -696,9 +702,9 @@ static void kmem_cache_error(struct kmem_cache *cache, void *buf, int error,
*/
static void kmem_cache_compute_sizes(struct kmem_cache *cache, int flags)
{
- size_t i, buffers, buf_size, slab_size, free_slab_size, optimal_size;
+ size_t i, buffers, buf_size, slab_size, free_slab_size, optimal_size = 0;
size_t waste, waste_min;
- int embed, optimal_embed = optimal_embed;
+ int embed, optimal_embed = 0;
buf_size = cache->buf_size;
@@ -739,6 +745,7 @@ static void kmem_cache_compute_sizes(struct kmem_cache *cache, int flags)
} while ((buffers < KMEM_MIN_BUFS_PER_SLAB)
&& (slab_size < KMEM_SLAB_SIZE_THRESHOLD));
+ assert(optimal_size > 0);
assert(!(flags & KMEM_CACHE_NOOFFSLAB) || optimal_embed);
cache->slab_size = optimal_size;
@@ -878,7 +885,7 @@ static int kmem_cache_grow(struct kmem_cache *cache)
simple_lock(&cache->lock);
if (slab != NULL) {
- list_insert_tail(&cache->free_slabs, &slab->list_node);
+ list_insert_head(&cache->free_slabs, &slab->list_node);
cache->nr_bufs += cache->bufs_per_slab;
cache->nr_slabs++;
cache->nr_free_slabs++;
@@ -899,31 +906,28 @@ static void kmem_cache_reap(struct kmem_cache *cache)
{
struct kmem_slab *slab;
struct list dead_slabs;
+ unsigned long nr_free_slabs;
if (cache->flags & KMEM_CF_NO_RECLAIM)
return;
- list_init(&dead_slabs);
-
simple_lock(&cache->lock);
-
- while (!list_empty(&cache->free_slabs)) {
- slab = list_first_entry(&cache->free_slabs, struct kmem_slab,
- list_node);
- list_remove(&slab->list_node);
- list_insert(&dead_slabs, &slab->list_node);
- cache->nr_bufs -= cache->bufs_per_slab;
- cache->nr_slabs--;
- cache->nr_free_slabs--;
- }
-
+ list_set_head(&dead_slabs, &cache->free_slabs);
+ list_init(&cache->free_slabs);
+ nr_free_slabs = cache->nr_free_slabs;
+ cache->nr_bufs -= cache->bufs_per_slab * nr_free_slabs;
+ cache->nr_slabs -= nr_free_slabs;
+ cache->nr_free_slabs = 0;
simple_unlock(&cache->lock);
while (!list_empty(&dead_slabs)) {
slab = list_first_entry(&dead_slabs, struct kmem_slab, list_node);
list_remove(&slab->list_node);
kmem_slab_destroy(slab, cache);
+ nr_free_slabs--;
}
+
+ assert(nr_free_slabs == 0);
}
/*
@@ -951,49 +955,20 @@ static void * kmem_cache_alloc_from_slab(struct kmem_cache *cache)
slab->nr_refs++;
cache->nr_objs++;
- /*
- * The slab has become complete.
- */
if (slab->nr_refs == cache->bufs_per_slab) {
+ /* The slab has become complete */
list_remove(&slab->list_node);
if (slab->nr_refs == 1)
cache->nr_free_slabs--;
} else if (slab->nr_refs == 1) {
/*
- * The slab has become partial.
+ * The slab has become partial. Insert the new slab at the end of
+ * the list to reduce fragmentation.
*/
list_remove(&slab->list_node);
list_insert_tail(&cache->partial_slabs, &slab->list_node);
cache->nr_free_slabs--;
- } else if (!list_singular(&cache->partial_slabs)) {
- struct list *node;
- struct kmem_slab *tmp;
-
- /*
- * The slab remains partial. If there are more than one partial slabs,
- * maintain the list sorted.
- */
-
- assert(slab->nr_refs > 1);
-
- for (node = list_prev(&slab->list_node);
- !list_end(&cache->partial_slabs, node);
- node = list_prev(node)) {
- tmp = list_entry(node, struct kmem_slab, list_node);
-
- if (tmp->nr_refs >= slab->nr_refs)
- break;
- }
-
- /*
- * If the direct neighbor was found, the list is already sorted.
- * If no slab was found, the slab is inserted at the head of the list.
- */
- if (node != list_prev(&slab->list_node)) {
- list_remove(&slab->list_node);
- list_insert_after(node, &slab->list_node);
- }
}
if ((slab->nr_refs == 1) && kmem_slab_use_tree(cache->flags))
@@ -1036,54 +1011,20 @@ static void kmem_cache_free_to_slab(struct kmem_cache *cache, void *buf)
slab->nr_refs--;
cache->nr_objs--;
- /*
- * The slab has become free.
- */
if (slab->nr_refs == 0) {
+ /* The slab has become free */
+
if (kmem_slab_use_tree(cache->flags))
rbtree_remove(&cache->active_slabs, &slab->tree_node);
- /*
- * The slab was partial.
- */
if (cache->bufs_per_slab > 1)
list_remove(&slab->list_node);
- list_insert_tail(&cache->free_slabs, &slab->list_node);
+ list_insert_head(&cache->free_slabs, &slab->list_node);
cache->nr_free_slabs++;
} else if (slab->nr_refs == (cache->bufs_per_slab - 1)) {
- /*
- * The slab has become partial.
- */
- list_insert(&cache->partial_slabs, &slab->list_node);
- } else if (!list_singular(&cache->partial_slabs)) {
- struct list *node;
- struct kmem_slab *tmp;
-
- /*
- * The slab remains partial. If there are more than one partial slabs,
- * maintain the list sorted.
- */
-
- assert(slab->nr_refs > 0);
-
- for (node = list_next(&slab->list_node);
- !list_end(&cache->partial_slabs, node);
- node = list_next(node)) {
- tmp = list_entry(node, struct kmem_slab, list_node);
-
- if (tmp->nr_refs <= slab->nr_refs)
- break;
- }
-
- /*
- * If the direct neighbor was found, the list is already sorted.
- * If no slab was found, the slab is inserted at the tail of the list.
- */
- if (node != list_next(&slab->list_node)) {
- list_remove(&slab->list_node);
- list_insert_before(node, &slab->list_node);
- }
+ /* The slab has become partial */
+ list_insert_head(&cache->partial_slabs, &slab->list_node);
}
}
@@ -1295,6 +1236,7 @@ fast_free:
simple_unlock(&cpu_pool->lock);
kmem_cache_free(cache->cpu_pool_type->array_cache,
(vm_offset_t)array);
+ simple_lock(&cpu_pool->lock);
goto fast_free;
}
@@ -1305,7 +1247,9 @@ fast_free:
slab_free:
#endif /* SLAB_USE_CPU_POOLS */
+ simple_lock(&cache->lock);
kmem_cache_free_to_slab(cache, (void *)obj);
+ simple_unlock(&cache->lock);
}
void slab_collect(void)
@@ -1386,7 +1330,6 @@ void kalloc_init(void)
{
char name[KMEM_CACHE_NAME_SIZE];
size_t i, size;
- vm_offset_t min, max;
size = 1 << KALLOC_FIRST_SHIFT;
@@ -1508,7 +1451,7 @@ void slab_info(void)
mem_usage = (cache->nr_slabs * cache->slab_size) >> 10;
mem_reclaimable = (cache->nr_free_slabs * cache->slab_size) >> 10;
- printf("%-19s %6lu %3luk %4lu %6lu %6lu %7luk %10luk\n",
+ printf("%-19s %6lu %3luk %4lu %6lu %6lu %7uk %10uk\n",
cache->name, cache->obj_size, cache->slab_size >> 10,
cache->bufs_per_slab, cache->nr_objs, cache->nr_bufs,
mem_usage, mem_reclaimable);
@@ -1526,7 +1469,7 @@ kern_return_t host_slab_info(host_t host, cache_info_array_t *infop,
struct kmem_cache *cache;
cache_info_t *info;
unsigned int i, nr_caches;
- vm_size_t info_size = info_size;
+ vm_size_t info_size = 0;
kern_return_t kr;
if (host == HOST_NULL)
@@ -1560,7 +1503,7 @@ kern_return_t host_slab_info(host_t host, cache_info_array_t *infop,
i = 0;
list_for_each_entry(&kmem_cache_list, cache, node) {
- simple_lock(&cache_lock);
+ simple_lock(&cache->lock);
info[i].flags = ((cache->flags & KMEM_CF_NO_CPU_POOL)
? CACHE_FLAGS_NO_CPU_POOL : 0)
| ((cache->flags & KMEM_CF_SLAB_EXTERNAL)
diff --git a/kern/slab.h b/kern/slab.h
index 47bef218..c7be1692 100644
--- a/kern/slab.h
+++ b/kern/slab.h
@@ -47,6 +47,7 @@
#ifndef _KERN_SLAB_H
#define _KERN_SLAB_H
+#include <cache.h>
#include <kern/lock.h>
#include <kern/list.h>
#include <kern/rbtree.h>
@@ -147,21 +148,20 @@ typedef vm_offset_t (*kmem_slab_alloc_fn_t)(vm_size_t);
typedef void (*kmem_slab_free_fn_t)(vm_offset_t, vm_size_t);
/*
- * Cache name buffer size.
+ * Cache name buffer size. The size is chosen so that struct
+ * kmem_cache fits into two cache lines. The size of a cache line on
+ * a typical CPU is 64 bytes.
*/
-#define KMEM_CACHE_NAME_SIZE 32
+#define KMEM_CACHE_NAME_SIZE 24
/*
* Cache of objects.
*
* Locking order : cpu_pool -> cache. CPU pools locking is ordered by CPU ID.
*
- * The partial slabs list is sorted by slab references. Slabs with a high
- * number of references are placed first on the list to reduce fragmentation.
- * Sorting occurs at insertion/removal of buffers in a slab. As the list
- * is maintained sorted, and the number of references only changes by one,
- * this is a very cheap operation in the average case and the worst (linear)
- * case is very unlikely.
+ * Currently, SLAB_USE_CPU_POOLS is not defined. KMEM_CACHE_NAME_SIZE
+ * is chosen so that the struct fits into two cache lines. The first
+ * cache line contains all hot fields.
*/
struct kmem_cache {
#if SLAB_USE_CPU_POOLS
@@ -177,25 +177,27 @@ struct kmem_cache {
struct list free_slabs;
struct rbtree active_slabs;
int flags;
+ size_t bufctl_dist; /* Distance from buffer to bufctl */
+ size_t slab_size;
+ unsigned long bufs_per_slab;
+ unsigned long nr_objs; /* Number of allocated objects */
+ unsigned long nr_free_slabs;
+ kmem_cache_ctor_t ctor;
+ /* All fields below are cold */
size_t obj_size; /* User-provided size */
+ /* Assuming ! SLAB_USE_CPU_POOLS, here is the cacheline boundary */
size_t align;
size_t buf_size; /* Aligned object size */
- size_t bufctl_dist; /* Distance from buffer to bufctl */
- size_t slab_size;
size_t color;
size_t color_max;
- unsigned long bufs_per_slab;
- unsigned long nr_objs; /* Number of allocated objects */
unsigned long nr_bufs; /* Total number of buffers */
unsigned long nr_slabs;
- unsigned long nr_free_slabs;
- kmem_cache_ctor_t ctor;
kmem_slab_alloc_fn_t slab_alloc_fn;
kmem_slab_free_fn_t slab_free_fn;
char name[KMEM_CACHE_NAME_SIZE];
size_t buftag_dist; /* Distance from buffer to buftag */
size_t redzone_pad; /* Bytes from end of object to redzone word */
-};
+} __cacheline_aligned;
/*
* Mach-style declarations for struct kmem_cache.
diff --git a/kern/startup.c b/kern/startup.c
index 0c04ccf8..de21ca4a 100644
--- a/kern/startup.c
+++ b/kern/startup.c
@@ -39,51 +39,41 @@
#include <kern/machine.h>
#include <kern/mach_factor.h>
#include <kern/mach_clock.h>
-#include <kern/printf.h>
#include <kern/processor.h>
+#include <kern/rdxtree.h>
#include <kern/sched_prim.h>
#include <kern/task.h>
#include <kern/thread.h>
#include <kern/thread_swap.h>
#include <kern/timer.h>
#include <kern/xpr.h>
+#include <kern/bootstrap.h>
#include <kern/time_stamp.h>
+#include <kern/startup.h>
#include <vm/vm_kern.h>
#include <vm/vm_map.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
+#include <vm/vm_init.h>
+#include <vm/vm_pageout.h>
#include <machine/machspl.h>
#include <machine/pcb.h>
#include <machine/pmap.h>
#include <machine/model_dep.h>
#include <mach/version.h>
+#include <device/device_init.h>
-
-
-extern void vm_mem_init();
-extern void vm_mem_bootstrap();
-extern void init_timeout();
-extern void machine_init();
-
-extern void idle_thread();
-extern void vm_pageout();
-extern void reaper_thread();
-extern void swapin_thread();
-extern void sched_thread();
-
-extern void bootstrap_create();
-extern void device_service_create();
-
-void cpu_launch_first_thread(); /* forward */
-void start_kernel_threads(); /* forward */
+#if MACH_KDB
+#include <device/cons.h>
+#endif /* MACH_KDB */
#if ! MACH_KBD
-boolean_t reboot_on_panic = 1;
+boolean_t reboot_on_panic = TRUE;
#endif
#if NCPUS > 1
-extern void start_other_cpus();
-extern void action_thread();
+#include <machine/mp_desc.h>
+#include <kern/machine.h>
#endif /* NCPUS > 1 */
/* XX */
@@ -96,7 +86,7 @@ extern char *kernel_cmdline;
*
* Assumes that master_cpu is set.
*/
-void setup_main()
+void setup_main(void)
{
thread_t startup_thread;
@@ -113,15 +103,15 @@ void setup_main()
}
#else /* MACH_KDB */
if (strstr (kernel_cmdline, "-H ")) {
- reboot_on_panic = 0;
+ reboot_on_panic = FALSE;
}
#endif /* MACH_KDB */
panic_init();
- printf_init();
sched_init();
vm_mem_bootstrap();
+ rdxtree_cache_init();
ipc_bootstrap();
vm_mem_init();
ipc_init();
@@ -169,7 +159,7 @@ void setup_main()
* Kick off the time-out driven routines by calling
* them the first time.
*/
- recompute_priorities();
+ recompute_priorities(NULL);
compute_mach_factor();
/*
@@ -212,9 +202,9 @@ void setup_main()
* Now running in a thread. Create the rest of the kernel threads
* and the bootstrap task.
*/
-void start_kernel_threads()
+void start_kernel_threads(void)
{
- register int i;
+ int i;
/*
* Create the idle threads and the other
@@ -280,7 +270,7 @@ void start_kernel_threads()
}
#if NCPUS > 1
-void slave_main()
+void slave_main(void)
{
cpu_launch_first_thread(THREAD_NULL);
}
@@ -290,10 +280,9 @@ void slave_main()
* Start up the first thread on a CPU.
* First thread is specified for the master CPU.
*/
-void cpu_launch_first_thread(th)
- register thread_t th;
+void cpu_launch_first_thread(thread_t th)
{
- register int mycpu;
+ int mycpu;
mycpu = cpu_number();
diff --git a/kern/startup.h b/kern/startup.h
new file mode 100644
index 00000000..d924d154
--- /dev/null
+++ b/kern/startup.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _KERN_STARTUP_H_
+#define _KERN_STARTUP_H_
+
+#include <kern/thread.h>
+
+extern void setup_main(void);
+void cpu_launch_first_thread(thread_t th);
+void start_kernel_threads(void);
+
+#endif /* _KERN_STARTUP_H_ */
diff --git a/kern/strings.c b/kern/strings.c
index 3676f98e..e299534a 100644
--- a/kern/strings.c
+++ b/kern/strings.c
@@ -50,15 +50,15 @@
* the contents are identical up to the length of s2.
* It returns < 0 if the first differing character is smaller
* in s1 than in s2 or if s1 is shorter than s2 and the
- * contents are identical upto the length of s1.
+ * contents are identical up to the length of s1.
*/
-int
+int __attribute__ ((pure))
strcmp(
- register const char *s1,
- register const char *s2)
+ const char *s1,
+ const char *s2)
{
- register unsigned int a, b;
+ unsigned int a, b;
do {
a = *s1++;
@@ -80,13 +80,13 @@ strcmp(
* comparison runs for at most "n" characters.
*/
-int
+int __attribute__ ((pure))
strncmp(
- register const char *s1,
- register const char *s2,
+ const char *s1,
+ const char *s2,
size_t n)
{
- register unsigned int a, b;
+ unsigned int a, b;
while (n != 0) {
a = *s1++;
@@ -113,10 +113,10 @@ strncmp(
char *
strcpy(
- register char *to,
- register const char *from)
+ char *to,
+ const char *from)
{
- register char *ret = to;
+ char *ret = to;
while ((*to++ = *from++) != '\0')
continue;
@@ -135,11 +135,11 @@ strcpy(
char *
strncpy(
- register char *to,
- register const char *from,
- register size_t count)
+ char *to,
+ const char *from,
+ size_t count)
{
- register char *ret = to;
+ char *ret = to;
while (count != 0) {
count--;
@@ -157,15 +157,15 @@ strncpy(
/*
* Abstract:
- * strlen returns the number of characters in "string" preceeding
+ * strlen returns the number of characters in "string" preceding
* the terminating null character.
*/
-size_t
+size_t __attribute__ ((pure))
strlen(
- register const char *string)
+ const char *string)
{
- register const char *ret = string;
+ const char *ret = string;
while (*string++ != '\0')
continue;
diff --git a/kern/syscall_emulation.c b/kern/syscall_emulation.c
index c1c3096c..95e91d55 100644
--- a/kern/syscall_emulation.c
+++ b/kern/syscall_emulation.c
@@ -57,7 +57,7 @@
/*
* eml_init: initialize user space emulation code
*/
-void eml_init()
+void eml_init(void)
{
}
@@ -68,10 +68,11 @@ void eml_init()
* vector.
*/
-void eml_task_reference(task, parent)
- task_t task, parent;
+void eml_task_reference(
+ task_t task,
+ task_t parent)
{
- register eml_dispatch_t eml;
+ eml_dispatch_t eml;
if (parent == TASK_NULL)
eml = EML_DISPATCH_NULL;
@@ -94,9 +95,9 @@ void eml_task_reference(task, parent)
*/
void eml_task_deallocate(task)
- task_t task;
+ const task_t task;
{
- register eml_dispatch_t eml;
+ eml_dispatch_t eml;
eml = task->eml_dispatch;
if (eml != EML_DISPATCH_NULL) {
@@ -116,12 +117,11 @@ void eml_task_deallocate(task)
* set a list of emulated system calls for this task.
*/
kern_return_t
-task_set_emulation_vector_internal(task, vector_start, emulation_vector,
- emulation_vector_count)
- task_t task;
- int vector_start;
- emulation_vector_t emulation_vector;
- unsigned int emulation_vector_count;
+task_set_emulation_vector_internal(
+ task_t task,
+ int vector_start,
+ emulation_vector_t emulation_vector,
+ unsigned int emulation_vector_count)
{
eml_dispatch_t cur_eml, new_eml, old_eml;
vm_size_t new_size;
@@ -295,12 +295,11 @@ task_set_emulation_vector_internal(task, vector_start, emulation_vector,
* The list is out-of-line.
*/
kern_return_t
-task_set_emulation_vector(task, vector_start, emulation_vector,
- emulation_vector_count)
- task_t task;
- int vector_start;
- emulation_vector_t emulation_vector;
- unsigned int emulation_vector_count;
+task_set_emulation_vector(
+ task_t task,
+ int vector_start,
+ emulation_vector_t emulation_vector,
+ unsigned int emulation_vector_count)
{
kern_return_t kr;
vm_offset_t emul_vector_addr;
@@ -342,12 +341,11 @@ task_set_emulation_vector(task, vector_start, emulation_vector,
* List is returned out-of-line.
*/
kern_return_t
-task_get_emulation_vector(task, vector_start, emulation_vector,
- emulation_vector_count)
- task_t task;
- int *vector_start; /* out */
- emulation_vector_t *emulation_vector; /* out */
- unsigned int *emulation_vector_count; /* out */
+task_get_emulation_vector(
+ task_t task,
+ int *vector_start, /* out */
+ emulation_vector_t *emulation_vector, /* out */
+ unsigned int *emulation_vector_count) /* out */
{
eml_dispatch_t eml;
vm_size_t vector_size, size;
@@ -445,10 +443,10 @@ task_get_emulation_vector(task, vector_start, emulation_vector,
* task_set_emulation: [Server Entry]
* set up for user space emulation of syscalls within this task.
*/
-kern_return_t task_set_emulation(task, routine_entry_pt, routine_number)
- task_t task;
- vm_offset_t routine_entry_pt;
- int routine_number;
+kern_return_t task_set_emulation(
+ task_t task,
+ vm_offset_t routine_entry_pt,
+ int routine_number)
{
return task_set_emulation_vector_internal(task, routine_number,
&routine_entry_pt, 1);
diff --git a/kern/syscall_emulation.h b/kern/syscall_emulation.h
index 501b0a83..bf20e441 100644
--- a/kern/syscall_emulation.h
+++ b/kern/syscall_emulation.h
@@ -33,6 +33,7 @@
#ifndef __ASSEMBLER__
#include <mach/machine/vm_types.h>
#include <kern/lock.h>
+#include <kern/task.h>
typedef vm_offset_t eml_routine_t;
@@ -56,6 +57,11 @@ typedef vm_offset_t *emulation_vector_t; /* Variable-length array */
#define EML_MOD (err_kern|err_sub(2))
#define EML_BAD_TASK (EML_MOD|0x0001)
#define EML_BAD_CNT (EML_MOD|0x0002)
+
+extern void eml_init(void);
+extern void eml_task_reference(task_t task, task_t parent);
+extern void eml_task_deallocate(task_t task);
+
#endif /* __ASSEMBLER__ */
#endif /* _KERN_SYSCALL_EMULATION_H_ */
diff --git a/kern/syscall_subr.c b/kern/syscall_subr.c
index ae2d7d73..6d23462c 100644
--- a/kern/syscall_subr.c
+++ b/kern/syscall_subr.c
@@ -48,8 +48,6 @@
#include <mach/policy.h>
#endif /* MACH_FIXPRI */
-
-
/*
* swtch and swtch_pri both attempt to context switch (logic in
* thread_block no-ops the context switch if nothing would happen).
@@ -63,12 +61,9 @@
* returned, the thread should make one more check on the
* lock and then be a good citizen and really suspend.
*/
-
-void thread_depress_priority(thread_t, mach_msg_timeout_t);
-
void swtch_continue(void)
{
- register processor_t myprocessor;
+ processor_t myprocessor;
myprocessor = current_processor();
thread_syscall_return(myprocessor->runq.count > 0 ||
@@ -78,7 +73,7 @@ void swtch_continue(void)
boolean_t swtch(void)
{
- register processor_t myprocessor;
+ processor_t myprocessor;
#if NCPUS > 1
myprocessor = current_processor();
@@ -96,8 +91,8 @@ boolean_t swtch(void)
void swtch_pri_continue(void)
{
- register thread_t thread = current_thread();
- register processor_t myprocessor;
+ thread_t thread = current_thread();
+ processor_t myprocessor;
if (thread->depress_priority >= 0)
(void) thread_depress_abort(thread);
@@ -107,15 +102,10 @@ void swtch_pri_continue(void)
/*NOTREACHED*/
}
-boolean_t swtch_pri(pri)
- int pri;
+boolean_t swtch_pri(int pri)
{
- register thread_t thread = current_thread();
- register processor_t myprocessor;
-
-#ifdef lint
- pri++;
-#endif /* lint */
+ thread_t thread = current_thread();
+ processor_t myprocessor;
#if NCPUS > 1
myprocessor = current_processor();
@@ -142,7 +132,7 @@ boolean_t swtch_pri(pri)
void thread_switch_continue(void)
{
- register thread_t cur_thread = current_thread();
+ thread_t cur_thread = current_thread();
/*
* Restore depressed priority
@@ -161,13 +151,13 @@ void thread_switch_continue(void)
* Fixed priority threads that call this get what they asked for
* even if that violates priority order.
*/
-kern_return_t thread_switch(thread_name, option, option_time)
-mach_port_t thread_name;
-int option;
-mach_msg_timeout_t option_time;
+kern_return_t thread_switch(
+ mach_port_t thread_name,
+ int option,
+ mach_msg_timeout_t option_time)
{
- register thread_t cur_thread = current_thread();
- register processor_t myprocessor;
+ thread_t cur_thread = current_thread();
+ processor_t myprocessor;
ipc_port_t port;
/*
@@ -208,8 +198,8 @@ mach_msg_timeout_t option_time;
* Get corresponding thread.
*/
if (ip_active(port) && (ip_kotype(port) == IKOT_THREAD)) {
- register thread_t thread;
- register spl_t s;
+ thread_t thread;
+ spl_t s;
thread = (thread_t) port->ip_kobject;
/*
@@ -289,9 +279,9 @@ mach_msg_timeout_t option_time;
* of zero will result in no timeout being scheduled.
*/
void
-thread_depress_priority(thread, depress_time)
-register thread_t thread;
-mach_msg_timeout_t depress_time;
+thread_depress_priority(
+ thread_t thread,
+ mach_msg_timeout_t depress_time)
{
unsigned int ticks;
spl_t s;
@@ -312,8 +302,8 @@ mach_msg_timeout_t depress_time;
* sched_pri to their lowest possible values.
*/
thread->depress_priority = thread->priority;
- thread->priority = 31;
- thread->sched_pri = 31;
+ thread->priority = NRQS-1;
+ thread->sched_pri = NRQS-1;
if (ticks != 0)
set_timeout(&thread->depress_timer, ticks);
@@ -327,8 +317,7 @@ mach_msg_timeout_t depress_time;
* Timeout routine for priority depression.
*/
void
-thread_depress_timeout(thread)
-register thread_t thread;
+thread_depress_timeout(thread_t thread)
{
spl_t s;
@@ -356,8 +345,7 @@ register thread_t thread;
* Prematurely abort priority depression if there is one.
*/
kern_return_t
-thread_depress_abort(thread)
-register thread_t thread;
+thread_depress_abort(thread_t thread)
{
spl_t s;
diff --git a/kern/syscall_subr.h b/kern/syscall_subr.h
index a2e39205..b6b61ab2 100644
--- a/kern/syscall_subr.h
+++ b/kern/syscall_subr.h
@@ -37,5 +37,6 @@ extern int thread_switch(mach_port_t, int, mach_msg_timeout_t);
extern void thread_depress_timeout(thread_t);
extern kern_return_t thread_depress_abort(thread_t);
extern void mach_print(const char *);
+extern void thread_depress_priority(thread_t thread, mach_msg_timeout_t depress_time);
#endif /* _KERN_SYSCALL_SUBR_H_ */
diff --git a/kern/syscall_sw.c b/kern/syscall_sw.c
index 607d843e..a383e467 100644
--- a/kern/syscall_sw.c
+++ b/kern/syscall_sw.c
@@ -36,6 +36,8 @@
#include <mach/mach_traps.h>
#include <mach/message.h>
#include <kern/syscall_subr.h>
+#include <kern/ipc_mig.h>
+#include <kern/eventcount.h>
#include <ipc/mach_port.h>
@@ -56,41 +58,20 @@
* the positive numbers) are reserved for Unix.
*/
-int kern_invalid_debug = 0;
+boolean_t kern_invalid_debug = FALSE;
-mach_port_t null_port()
+mach_port_t null_port(void)
{
if (kern_invalid_debug) SoftDebugger("null_port mach trap");
return(MACH_PORT_NULL);
}
-kern_return_t kern_invalid()
+kern_return_t kern_invalid(void)
{
if (kern_invalid_debug) SoftDebugger("kern_invalid mach trap");
return(KERN_INVALID_ARGUMENT);
}
-extern kern_return_t syscall_vm_map();
-extern kern_return_t syscall_vm_allocate();
-extern kern_return_t syscall_vm_deallocate();
-
-extern kern_return_t syscall_task_create();
-extern kern_return_t syscall_task_terminate();
-extern kern_return_t syscall_task_suspend();
-extern kern_return_t syscall_task_set_special_port();
-
-extern kern_return_t syscall_mach_port_allocate();
-extern kern_return_t syscall_mach_port_deallocate();
-extern kern_return_t syscall_mach_port_insert_right();
-extern kern_return_t syscall_mach_port_allocate_name();
-
-extern kern_return_t syscall_thread_depress_abort();
-extern kern_return_t evc_wait();
-extern kern_return_t evc_wait_clear();
-
-extern kern_return_t syscall_device_write_request();
-extern kern_return_t syscall_device_writev_request();
-
mach_trap_t mach_trap_table[] = {
MACH_TRAP(kern_invalid, 0), /* 0 */ /* Unix */
MACH_TRAP(kern_invalid, 0), /* 1 */ /* Unix */
diff --git a/kern/task.c b/kern/task.c
index 114dd319..b384347f 100644
--- a/kern/task.c
+++ b/kern/task.c
@@ -37,6 +37,7 @@
#include <mach/vm_param.h>
#include <mach/task_info.h>
#include <mach/task_special_ports.h>
+#include <mach_debug/mach_debug_types.h>
#include <ipc/ipc_space.h>
#include <ipc/ipc_types.h>
#include <kern/debug.h>
@@ -45,17 +46,19 @@
#include <kern/slab.h>
#include <kern/kalloc.h>
#include <kern/processor.h>
+#include <kern/printf.h>
#include <kern/sched_prim.h> /* for thread_wakeup */
#include <kern/ipc_tt.h>
+#include <kern/syscall_emulation.h>
+#include <kern/task_notify.user.h>
#include <vm/vm_kern.h> /* for kernel_map, ipc_kernel_map */
#include <machine/machspl.h> /* for splsched */
task_t kernel_task = TASK_NULL;
struct kmem_cache task_cache;
-extern void eml_init(void);
-extern void eml_task_reference(task_t, task_t);
-extern void eml_task_deallocate(task_t);
+/* Where to send notifications about newly created tasks. */
+ipc_port_t new_task_notification = NULL;
void task_init(void)
{
@@ -71,6 +74,7 @@ void task_init(void)
* for other initialization. (:-()
*/
(void) task_create(TASK_NULL, FALSE, &kernel_task);
+ (void) task_set_name(kernel_task, "gnumach");
}
kern_return_t task_create(
@@ -78,16 +82,15 @@ kern_return_t task_create(
boolean_t inherit_memory,
task_t *child_task) /* OUT */
{
- register task_t new_task;
- register processor_set_t pset;
+ task_t new_task;
+ processor_set_t pset;
#if FAST_TAS
int i;
#endif
new_task = (task_t) kmem_cache_alloc(&task_cache);
- if (new_task == TASK_NULL) {
- panic("task_create: no memory for task structure");
- }
+ if (new_task == TASK_NULL)
+ return KERN_RESOURCE_SHORTAGE;
/* one ref for just being alive; one for our caller */
new_task->ref_count = 2;
@@ -167,6 +170,21 @@ kern_return_t task_create(
}
#endif /* FAST_TAS */
+ if (parent_task == TASK_NULL)
+ snprintf (new_task->name, sizeof new_task->name, "%p",
+ new_task);
+ else
+ snprintf (new_task->name, sizeof new_task->name, "(%.*s)",
+ sizeof new_task->name - 3, parent_task->name);
+
+ if (new_task_notification != NULL) {
+ task_reference (new_task);
+ task_reference (parent_task);
+ mach_notify_new_task (new_task_notification,
+ convert_task_to_port (new_task),
+ convert_task_to_port (parent_task));
+ }
+
ipc_task_enable(new_task);
*child_task = new_task;
@@ -181,10 +199,10 @@ kern_return_t task_create(
* is never in this task.
*/
void task_deallocate(
- register task_t task)
+ task_t task)
{
- register int c;
- register processor_set_t pset;
+ int c;
+ processor_set_t pset;
if (task == TASK_NULL)
return;
@@ -210,7 +228,7 @@ void task_deallocate(
}
void task_reference(
- register task_t task)
+ task_t task)
{
if (task == TASK_NULL)
return;
@@ -227,11 +245,11 @@ void task_reference(
* (kern/thread.c) about problems with terminating the "current task."
*/
kern_return_t task_terminate(
- register task_t task)
+ task_t task)
{
- register thread_t thread, cur_thread;
- register queue_head_t *list;
- register task_t cur_task;
+ thread_t thread, cur_thread;
+ queue_head_t *list;
+ task_t cur_task;
spl_t s;
if (task == TASK_NULL)
@@ -270,6 +288,7 @@ kern_return_t task_terminate(
thread_terminate(cur_thread);
return KERN_FAILURE;
}
+ task_hold_locked(task);
task->active = FALSE;
queue_remove(list, cur_thread, thread_t, thread_list);
thread_unlock(cur_thread);
@@ -323,6 +342,7 @@ kern_return_t task_terminate(
task_unlock(task);
return KERN_FAILURE;
}
+ task_hold_locked(task);
task->active = FALSE;
task_unlock(task);
}
@@ -333,9 +353,8 @@ kern_return_t task_terminate(
* If this is the current task, the current thread will
* be left running.
*/
- ipc_task_disable(task);
- (void) task_hold(task);
(void) task_dowait(task,TRUE); /* may block */
+ ipc_task_disable(task);
/*
* Terminate each thread in the task.
@@ -400,20 +419,18 @@ kern_return_t task_terminate(
* Suspend execution of the specified task.
* This is a recursive-style suspension of the task, a count of
* suspends is maintained.
+ *
+ * CONDITIONS: the task is locked and active.
*/
-kern_return_t task_hold(
- register task_t task)
+void task_hold_locked(
+ task_t task)
{
- register queue_head_t *list;
- register thread_t thread, cur_thread;
+ queue_head_t *list;
+ thread_t thread, cur_thread;
- cur_thread = current_thread();
+ assert(task->active);
- task_lock(task);
- if (!task->active) {
- task_unlock(task);
- return KERN_FAILURE;
- }
+ cur_thread = current_thread();
task->suspend_count++;
@@ -427,6 +444,26 @@ kern_return_t task_hold(
if (thread != cur_thread)
thread_hold(thread);
}
+}
+
+/*
+ * task_hold:
+ *
+ * Suspend execution of the specified task.
+ * This is a recursive-style suspension of the task, a count of
+ * suspends is maintained.
+ */
+kern_return_t task_hold(
+ task_t task)
+{
+ task_lock(task);
+ if (!task->active) {
+ task_unlock(task);
+ return KERN_FAILURE;
+ }
+
+ task_hold_locked(task);
+
task_unlock(task);
return KERN_SUCCESS;
}
@@ -441,12 +478,12 @@ kern_return_t task_hold(
* must_wait is true.
*/
kern_return_t task_dowait(
- register task_t task,
+ task_t task,
boolean_t must_wait)
{
- register queue_head_t *list;
- register thread_t thread, cur_thread, prev_thread;
- register kern_return_t ret = KERN_SUCCESS;
+ queue_head_t *list;
+ thread_t thread, cur_thread, prev_thread;
+ kern_return_t ret = KERN_SUCCESS;
/*
* Iterate through all the threads.
@@ -493,10 +530,10 @@ kern_return_t task_dowait(
}
kern_return_t task_release(
- register task_t task)
+ task_t task)
{
- register queue_head_t *list;
- register thread_t thread, next;
+ queue_head_t *list;
+ thread_t thread, next;
task_lock(task);
if (!task->active) {
@@ -624,9 +661,9 @@ kern_return_t task_threads(
}
kern_return_t task_suspend(
- register task_t task)
+ task_t task)
{
- register boolean_t hold;
+ boolean_t hold;
if (task == TASK_NULL)
return KERN_INVALID_ARGUMENT;
@@ -675,9 +712,9 @@ kern_return_t task_suspend(
}
kern_return_t task_resume(
- register task_t task)
+ task_t task)
{
- register boolean_t release;
+ boolean_t release;
if (task == TASK_NULL)
return KERN_INVALID_ARGUMENT;
@@ -717,7 +754,7 @@ kern_return_t task_info(
switch (flavor) {
case TASK_BASIC_INFO:
{
- register task_basic_info_t basic_info;
+ task_basic_info_t basic_info;
/* Allow *task_info_count to be two words smaller than
the usual amount, because creation_time is a new member
@@ -756,7 +793,7 @@ kern_return_t task_info(
case TASK_EVENTS_INFO:
{
- register task_events_info_t event_info;
+ task_events_info_t event_info;
if (*task_info_count < TASK_EVENTS_INFO_COUNT) {
return KERN_INVALID_ARGUMENT;
@@ -764,7 +801,7 @@ kern_return_t task_info(
event_info = (task_events_info_t) task_info_out;
- task_lock(&task);
+ task_lock(task);
event_info->faults = task->faults;
event_info->zero_fills = task->zero_fills;
event_info->reactivations = task->reactivations;
@@ -772,7 +809,7 @@ kern_return_t task_info(
event_info->cow_faults = task->cow_faults;
event_info->messages_sent = task->messages_sent;
event_info->messages_received = task->messages_received;
- task_unlock(&task);
+ task_unlock(task);
*task_info_count = TASK_EVENTS_INFO_COUNT;
break;
@@ -780,8 +817,8 @@ kern_return_t task_info(
case TASK_THREAD_TIMES_INFO:
{
- register task_thread_times_info_t times_info;
- register thread_t thread;
+ task_thread_times_info_t times_info;
+ thread_t thread;
if (*task_info_count < TASK_THREAD_TIMES_INFO_COUNT) {
return KERN_INVALID_ARGUMENT;
@@ -837,9 +874,9 @@ task_assign(
boolean_t assign_threads)
{
kern_return_t ret = KERN_SUCCESS;
- register thread_t thread, prev_thread;
- register queue_head_t *list;
- register processor_set_t pset;
+ thread_t thread, prev_thread;
+ queue_head_t *list;
+ processor_set_t pset;
if (task == TASK_NULL || new_pset == PROCESSOR_SET_NULL) {
return KERN_INVALID_ARGUMENT;
@@ -1026,6 +1063,9 @@ kern_return_t task_get_assignment(
task_t task,
processor_set_t *pset)
{
+ if (task == TASK_NULL)
+ return KERN_INVALID_ARGUMENT;
+
if (!task->active)
return KERN_FAILURE;
@@ -1055,8 +1095,8 @@ task_priority(
task->priority = priority;
if (change_threads) {
- register thread_t thread;
- register queue_head_t *list;
+ thread_t thread;
+ queue_head_t *list;
list = &task->thread_list;
queue_iterate(list, thread, thread_t, thread_list) {
@@ -1071,6 +1111,22 @@ task_priority(
}
/*
+ * task_set_name
+ *
+ * Set the name of task TASK to NAME. This is a debugging aid.
+ * NAME will be used in error messages printed by the kernel.
+ */
+kern_return_t
+task_set_name(
+ task_t task,
+ kernel_debug_name_t name)
+{
+ strncpy(task->name, name, sizeof task->name - 1);
+ task->name[sizeof task->name - 1] = '\0';
+ return KERN_SUCCESS;
+}
+
+/*
* task_collect_scan:
*
* Attempt to free resources owned by tasks.
@@ -1078,7 +1134,7 @@ task_priority(
void task_collect_scan(void)
{
- register task_t task, prev_task;
+ task_t task, prev_task;
processor_set_t pset, prev_pset;
prev_task = TASK_NULL;
@@ -1209,6 +1265,27 @@ task_ras_control(
break;
}
task_unlock(task);
-#endif
+#endif /* FAST_TAS */
return ret;
}
+
+/*
+ * register_new_task_notification
+ *
+ * Register a port to which a notification about newly created
+ * tasks are sent.
+ */
+kern_return_t
+register_new_task_notification(
+ const host_t host,
+ ipc_port_t notification)
+{
+ if (host == HOST_NULL)
+ return KERN_INVALID_HOST;
+
+ if (new_task_notification != NULL)
+ return KERN_NO_ACCESS;
+
+ new_task_notification = notification;
+ return KERN_SUCCESS;
+}
diff --git a/kern/task.h b/kern/task.h
index 9bfea571..2a4c28fc 100644
--- a/kern/task.h
+++ b/kern/task.h
@@ -39,6 +39,7 @@
#include <mach/time_value.h>
#include <mach/mach_param.h>
#include <mach/task_info.h>
+#include <mach_debug/mach_debug_types.h>
#include <kern/kern_types.h>
#include <kern/lock.h>
#include <kern/queue.h>
@@ -48,11 +49,22 @@
#include <vm/vm_types.h>
#include <machine/task.h>
+/*
+ * Task name buffer size. The size is chosen so that struct task fits
+ * into three cache lines. The size of a cache line on a typical CPU
+ * is 64 bytes.
+ */
+#define TASK_NAME_SIZE 32
+
struct task {
/* Synchronization/destruction information */
decl_simple_lock_data(,lock) /* Task's lock */
int ref_count; /* Number of references to me */
- boolean_t active; /* Task has not been terminated */
+
+ /* Flags */
+ unsigned int active:1, /* Task has not been terminated */
+ /* boolean_t */ may_assign:1, /* can assigned pset be changed? */
+ assign_active:1; /* waiting for may_assign */
/* Miscellaneous */
vm_map_t map; /* Address space description */
@@ -63,8 +75,6 @@ struct task {
queue_head_t thread_list; /* list of threads */
int thread_count; /* number of threads */
processor_set_t processor_set; /* processor set for new threads */
- boolean_t may_assign; /* can assigned pset be changed? */
- boolean_t assign_active; /* waiting for may_assign */
/* User-visible scheduling information */
int user_stop_count; /* outstanding stops */
@@ -111,6 +121,8 @@ struct task {
natural_t cow_faults; /* copy-on-write faults counter */
natural_t messages_sent; /* messages sent counter */
natural_t messages_received; /* messages received counter */
+
+ char name[TASK_NAME_SIZE];
};
#define task_lock(task) simple_lock(&(task)->lock)
@@ -158,6 +170,9 @@ extern kern_return_t task_assign(
extern kern_return_t task_assign_default(
task_t task,
boolean_t assign_threads);
+extern kern_return_t task_set_name(
+ task_t task,
+ kernel_debug_name_t name);
extern void consider_task_collect(void);
/*
@@ -167,6 +182,7 @@ extern void consider_task_collect(void);
extern void task_init(void);
extern void task_reference(task_t);
extern void task_deallocate(task_t);
+extern void task_hold_locked(task_t);
extern kern_return_t task_hold(task_t);
extern kern_return_t task_dowait(task_t, boolean_t);
extern kern_return_t task_release(task_t);
diff --git a/kern/task_notify.cli b/kern/task_notify.cli
new file mode 100644
index 00000000..c6c85d99
--- /dev/null
+++ b/kern/task_notify.cli
@@ -0,0 +1,7 @@
+/* XXX */
+
+/* This is a client presentation file. */
+
+#define KERNEL_USER 1
+
+#include <mach/task_notify.defs>
diff --git a/kern/thread.c b/kern/thread.c
index 87be9231..1f47553f 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -57,9 +57,11 @@
#include <kern/slab.h>
#include <kern/mach_clock.h>
#include <vm/vm_kern.h>
+#include <vm/vm_user.h>
#include <ipc/ipc_kmsg.h>
#include <ipc/ipc_port.h>
#include <ipc/mach_msg.h>
+#include <ipc/mach_port.h>
#include <machine/machspl.h> /* for splsched */
#include <machine/pcb.h>
#include <machine/thread.h> /* for MACHINE_STACK */
@@ -72,15 +74,10 @@ struct kmem_cache thread_cache;
queue_head_t reaper_queue;
decl_simple_lock_data(, reaper_lock)
-extern void pcb_module_init(void);
-
/* private */
struct thread thread_template;
#if MACH_DEBUG
-void stack_init(vm_offset_t stack); /* forward */
-void stack_finalize(vm_offset_t stack); /* forward */
-
#define STACK_MARKER 0xdeadbeefU
boolean_t stack_check_usage = FALSE;
decl_simple_lock_data(, stack_usage_lock)
@@ -127,10 +124,6 @@ vm_offset_t stack_free_list; /* splsched only */
unsigned int stack_free_count = 0; /* splsched only */
unsigned int stack_free_limit = 1; /* patchable */
-unsigned int stack_alloc_hits = 0; /* debugging */
-unsigned int stack_alloc_misses = 0; /* debugging */
-unsigned int stack_alloc_max = 0; /* debugging */
-
/*
* The next field is at the base of the stack,
* so the low end is left unsullied.
@@ -149,7 +142,7 @@ boolean_t stack_alloc_try(
thread_t thread,
void (*resume)(thread_t))
{
- register vm_offset_t stack;
+ vm_offset_t stack;
stack_lock();
stack = stack_free_list;
@@ -163,10 +156,10 @@ boolean_t stack_alloc_try(
if (stack != 0) {
stack_attach(thread, stack, resume);
- stack_alloc_hits++;
+ counter(c_stack_alloc_hits++);
return TRUE;
} else {
- stack_alloc_misses++;
+ counter(c_stack_alloc_misses++);
return FALSE;
}
}
@@ -178,7 +171,7 @@ boolean_t stack_alloc_try(
* May block.
*/
-void stack_alloc(
+kern_return_t stack_alloc(
thread_t thread,
void (*resume)(thread_t))
{
@@ -202,15 +195,15 @@ void stack_alloc(
(void) splx(s);
if (stack == 0) {
+ kern_return_t kr;
/*
* Kernel stacks should be naturally aligned,
* so that it is easy to find the starting/ending
* addresses of a stack given an address in the middle.
*/
-
- if (kmem_alloc_aligned(kmem_map, &stack, KERNEL_STACK_SIZE)
- != KERN_SUCCESS)
- panic("stack_alloc");
+ kr = kmem_alloc_aligned(kmem_map, &stack, KERNEL_STACK_SIZE);
+ if (kr != KERN_SUCCESS)
+ return kr;
#if MACH_DEBUG
stack_init(stack);
@@ -218,6 +211,7 @@ void stack_alloc(
}
stack_attach(thread, stack, resume);
+ return KERN_SUCCESS;
}
/*
@@ -230,7 +224,7 @@ void stack_alloc(
void stack_free(
thread_t thread)
{
- register vm_offset_t stack;
+ vm_offset_t stack;
stack = stack_detach(thread);
@@ -238,8 +232,11 @@ void stack_free(
stack_lock();
stack_next(stack) = stack_free_list;
stack_free_list = stack;
- if (++stack_free_count > stack_alloc_max)
- stack_alloc_max = stack_free_count;
+ stack_free_count += 1;
+#if MACH_COUNTERS
+ if (stack_free_count > c_stack_alloc_max)
+ c_stack_alloc_max = stack_free_count;
+#endif /* MACH_COUNTERS */
stack_unlock();
}
}
@@ -253,7 +250,7 @@ void stack_free(
void stack_collect(void)
{
- register vm_offset_t stack;
+ vm_offset_t stack;
spl_t s;
s = splsched();
@@ -285,7 +282,7 @@ void stack_collect(void)
*/
void stack_privilege(
- register thread_t thread)
+ thread_t thread)
{
/*
* This implementation only works for the current thread.
@@ -398,11 +395,11 @@ void thread_init(void)
}
kern_return_t thread_create(
- register task_t parent_task,
+ task_t parent_task,
thread_t *child_thread) /* OUT */
{
- register thread_t new_thread;
- register processor_set_t pset;
+ thread_t new_thread;
+ processor_set_t pset;
if (parent_task == TASK_NULL)
return KERN_INVALID_ARGUMENT;
@@ -533,7 +530,6 @@ kern_return_t thread_create(
#endif /* HW_FOOTPRINT */
#if MACH_PCSAMPLE
- new_thread->pc_sample.buffer = 0;
new_thread->pc_sample.seqno = 0;
new_thread->pc_sample.sampletypes = 0;
#endif /* MACH_PCSAMPLE */
@@ -576,11 +572,11 @@ kern_return_t thread_create(
unsigned int thread_deallocate_stack = 0;
void thread_deallocate(
- register thread_t thread)
+ thread_t thread)
{
spl_t s;
- register task_t task;
- register processor_set_t pset;
+ task_t task;
+ processor_set_t pset;
time_value_t user_time, system_time;
@@ -711,7 +707,7 @@ void thread_deallocate(
}
void thread_reference(
- register thread_t thread)
+ thread_t thread)
{
spl_t s;
@@ -745,10 +741,10 @@ void thread_reference(
* since it needs a kernel stack to execute.)
*/
kern_return_t thread_terminate(
- register thread_t thread)
+ thread_t thread)
{
- register thread_t cur_thread = current_thread();
- register task_t cur_task;
+ thread_t cur_thread = current_thread();
+ task_t cur_task;
spl_t s;
if (thread == THREAD_NULL)
@@ -851,6 +847,28 @@ kern_return_t thread_terminate(
return KERN_SUCCESS;
}
+kern_return_t thread_terminate_release(
+ thread_t thread,
+ task_t task,
+ mach_port_t thread_name,
+ mach_port_t reply_port,
+ vm_offset_t address,
+ vm_size_t size)
+{
+ if (task == NULL)
+ return KERN_INVALID_ARGUMENT;
+
+ mach_port_deallocate(task->itk_space, thread_name);
+
+ if (reply_port != MACH_PORT_NULL)
+ mach_port_destroy(task->itk_space, reply_port);
+
+ if ((address != 0) || (size != 0))
+ vm_deallocate(task->map, address, size);
+
+ return thread_terminate(thread);
+}
+
/*
* thread_force_terminate:
*
@@ -860,9 +878,9 @@ kern_return_t thread_terminate(
*/
void
thread_force_terminate(
- register thread_t thread)
+ thread_t thread)
{
- boolean_t deallocate_here = FALSE;
+ boolean_t deallocate_here;
spl_t s;
ipc_thread_disable(thread);
@@ -902,11 +920,11 @@ thread_force_terminate(
*
*/
kern_return_t thread_halt(
- register thread_t thread,
+ thread_t thread,
boolean_t must_halt)
{
- register thread_t cur_thread = current_thread();
- register kern_return_t ret;
+ thread_t cur_thread = current_thread();
+ kern_return_t ret;
spl_t s;
if (thread == cur_thread)
@@ -950,7 +968,7 @@ kern_return_t thread_halt(
* operation can never cause a deadlock.)
*/
if (cur_thread->ast & AST_HALT) {
- thread_wakeup_with_result((event_t)&cur_thread->wake_active,
+ thread_wakeup_with_result(TH_EV_WAKE_ACTIVE(cur_thread),
THREAD_INTERRUPTED);
thread_unlock(thread);
thread_unlock(cur_thread);
@@ -988,7 +1006,7 @@ kern_return_t thread_halt(
*/
while ((thread->ast & AST_HALT) && (!(thread->state & TH_HALTED))) {
thread->wake_active = TRUE;
- thread_sleep((event_t) &thread->wake_active,
+ thread_sleep(TH_EV_WAKE_ACTIVE(thread),
simple_lock_addr(thread->lock), TRUE);
if (thread->state & TH_HALTED) {
@@ -1027,7 +1045,7 @@ kern_return_t thread_halt(
s = splsched();
thread_lock(thread);
thread_ast_clear(thread, AST_HALT);
- thread_wakeup_with_result((event_t)&thread->wake_active,
+ thread_wakeup_with_result(TH_EV_WAKE_ACTIVE(thread),
THREAD_INTERRUPTED);
thread_unlock(thread);
(void) splx(s);
@@ -1105,7 +1123,7 @@ kern_return_t thread_halt(
}
}
-void walking_zombie(void)
+void __attribute__((noreturn)) walking_zombie(void)
{
panic("the zombie walks!");
}
@@ -1116,7 +1134,7 @@ void walking_zombie(void)
*/
void thread_halt_self(void)
{
- register thread_t thread = current_thread();
+ thread_t thread = current_thread();
spl_t s;
if (thread->ast & AST_TERMINATE) {
@@ -1131,7 +1149,7 @@ void thread_halt_self(void)
s = splsched();
simple_lock(&reaper_lock);
- enqueue_tail(&reaper_queue, (queue_entry_t) thread);
+ enqueue_tail(&reaper_queue, &(thread->links));
simple_unlock(&reaper_lock);
thread_lock(thread);
@@ -1170,7 +1188,7 @@ void thread_halt_self(void)
* suspends is maintained.
*/
void thread_hold(
- register thread_t thread)
+ thread_t thread)
{
spl_t s;
@@ -1192,11 +1210,11 @@ void thread_hold(
*/
kern_return_t
thread_dowait(
- register thread_t thread,
+ thread_t thread,
boolean_t must_halt)
{
- register boolean_t need_wakeup;
- register kern_return_t ret = KERN_SUCCESS;
+ boolean_t need_wakeup;
+ kern_return_t ret = KERN_SUCCESS;
spl_t s;
if (thread == current_thread())
@@ -1266,7 +1284,7 @@ thread_dowait(
* Check for failure if interrupted.
*/
thread->wake_active = TRUE;
- thread_sleep((event_t) &thread->wake_active,
+ thread_sleep(TH_EV_WAKE_ACTIVE(thread),
simple_lock_addr(thread->lock), TRUE);
thread_lock(thread);
if ((current_thread()->wait_result != THREAD_AWAKENED) &&
@@ -1290,13 +1308,13 @@ thread_dowait(
(void) splx(s);
if (need_wakeup)
- thread_wakeup((event_t) &thread->wake_active);
+ thread_wakeup(TH_EV_WAKE_ACTIVE(thread));
return ret;
}
void thread_release(
- register thread_t thread)
+ thread_t thread)
{
spl_t s;
@@ -1315,9 +1333,9 @@ void thread_release(
}
kern_return_t thread_suspend(
- register thread_t thread)
+ thread_t thread)
{
- register boolean_t hold;
+ boolean_t hold;
spl_t spl;
if (thread == THREAD_NULL)
@@ -1328,7 +1346,7 @@ kern_return_t thread_suspend(
thread_lock(thread);
/* Wait for thread to get interruptible */
while (thread->state & TH_UNINT) {
- assert_wait(&thread->state, TRUE);
+ assert_wait(TH_EV_STATE(thread), TRUE);
thread_unlock(thread);
thread_block(NULL);
thread_lock(thread);
@@ -1361,9 +1379,9 @@ kern_return_t thread_suspend(
kern_return_t thread_resume(
- register thread_t thread)
+ thread_t thread)
{
- register kern_return_t ret;
+ kern_return_t ret;
spl_t s;
if (thread == THREAD_NULL)
@@ -1399,7 +1417,7 @@ kern_return_t thread_resume(
* Return thread's machine-dependent state.
*/
kern_return_t thread_get_state(
- register thread_t thread,
+ thread_t thread,
int flavor,
thread_state_t old_state, /* pointer to OUT array */
natural_t *old_state_count) /*IN/OUT*/
@@ -1423,7 +1441,7 @@ kern_return_t thread_get_state(
* Change thread's machine-dependent state.
*/
kern_return_t thread_set_state(
- register thread_t thread,
+ thread_t thread,
int flavor,
thread_state_t new_state,
natural_t new_state_count)
@@ -1444,7 +1462,7 @@ kern_return_t thread_set_state(
}
kern_return_t thread_info(
- register thread_t thread,
+ thread_t thread,
int flavor,
thread_info_t thread_info_out, /* pointer to OUT array */
natural_t *thread_info_count) /*IN/OUT*/
@@ -1456,7 +1474,7 @@ kern_return_t thread_info(
return KERN_INVALID_ARGUMENT;
if (flavor == THREAD_BASIC_INFO) {
- register thread_basic_info_t basic_info;
+ thread_basic_info_t basic_info;
/* Allow *thread_info_count to be one smaller than the
usual amount, because creation_time is a new member
@@ -1542,7 +1560,7 @@ kern_return_t thread_info(
return KERN_SUCCESS;
}
else if (flavor == THREAD_SCHED_INFO) {
- register thread_sched_info_t sched_info;
+ thread_sched_info_t sched_info;
if (*thread_info_count < THREAD_SCHED_INFO_COUNT) {
return KERN_INVALID_ARGUMENT;
@@ -1584,7 +1602,7 @@ kern_return_t thread_info(
}
kern_return_t thread_abort(
- register thread_t thread)
+ thread_t thread)
{
if (thread == THREAD_NULL || thread == current_thread()) {
return KERN_INVALID_ARGUMENT;
@@ -1649,9 +1667,13 @@ thread_t kernel_thread(
continuation_t start,
void * arg)
{
+ kern_return_t kr;
thread_t thread;
- (void) thread_create(task, &thread);
+ kr = thread_create(task, &thread);
+ if (kr != KERN_SUCCESS)
+ return THREAD_NULL;
+
/* release "extra" ref that thread_create gave us */
thread_deallocate(thread);
thread_start(thread, start);
@@ -1675,10 +1697,10 @@ thread_t kernel_thread(
* This kernel thread runs forever looking for threads to destroy
* (when they request that they be destroyed, of course).
*/
-void reaper_thread_continue(void)
+void __attribute__((noreturn)) reaper_thread_continue(void)
{
for (;;) {
- register thread_t thread;
+ thread_t thread;
spl_t s;
s = splsched();
@@ -1793,12 +1815,12 @@ thread_unfreeze(
void
thread_doassign(
- register thread_t thread,
- register processor_set_t new_pset,
+ thread_t thread,
+ processor_set_t new_pset,
boolean_t release_freeze)
{
- register processor_set_t pset;
- register boolean_t old_empty, new_empty;
+ processor_set_t pset;
+ boolean_t old_empty, new_empty;
boolean_t recompute_pri = FALSE;
spl_t s;
@@ -1956,6 +1978,9 @@ kern_return_t thread_get_assignment(
thread_t thread,
processor_set_t *pset)
{
+ if (thread == THREAD_NULL)
+ return KERN_INVALID_ARGUMENT;
+
*pset = thread->processor_set;
pset_reference(*pset);
return KERN_SUCCESS;
@@ -2101,8 +2126,8 @@ thread_policy(
int data)
{
#if MACH_FIXPRI
- register kern_return_t ret = KERN_SUCCESS;
- register int temp;
+ kern_return_t ret = KERN_SUCCESS;
+ int temp;
spl_t s;
#endif /* MACH_FIXPRI */
@@ -2218,7 +2243,6 @@ thread_wire(
void thread_collect_scan(void)
{
-#if 0
register thread_t thread, prev_thread;
processor_set_t pset, prev_pset;
@@ -2271,7 +2295,6 @@ void thread_collect_scan(void)
thread_deallocate(prev_thread);
if (prev_pset != PROCESSOR_SET_NULL)
pset_deallocate(prev_pset);
-#endif /* 0 */
}
boolean_t thread_collect_allowed = TRUE;
@@ -2305,7 +2328,7 @@ void consider_thread_collect(void)
#if MACH_DEBUG
vm_size_t stack_usage(
- register vm_offset_t stack)
+ vm_offset_t stack)
{
int i;
@@ -2322,7 +2345,7 @@ vm_size_t stack_usage(
*/
void stack_init(
- register vm_offset_t stack)
+ vm_offset_t stack)
{
if (stack_check_usage) {
int i;
@@ -2338,7 +2361,7 @@ void stack_init(
*/
void stack_finalize(
- register vm_offset_t stack)
+ vm_offset_t stack)
{
if (stack_check_usage) {
vm_size_t used = stack_usage(stack);
@@ -2431,8 +2454,8 @@ kern_return_t processor_set_stack_usage(
vm_size_t maxusage;
vm_offset_t maxstack;
- register thread_t *threads;
- register thread_t tmp_thread;
+ thread_t *threads;
+ thread_t tmp_thread;
unsigned int actual; /* this many things */
unsigned int i;
@@ -2550,7 +2573,7 @@ kern_return_t processor_set_stack_usage(
void
thread_stats(void)
{
- register thread_t thread;
+ thread_t thread;
int total = 0, rpcreply = 0;
queue_iterate(&default_pset.threads, thread, thread_t, pset_threads) {
diff --git a/kern/thread.h b/kern/thread.h
index 3959dfce..0e85d8c4 100644
--- a/kern/thread.h
+++ b/kern/thread.h
@@ -70,6 +70,22 @@ struct thread {
task_t task; /* Task to which I belong */
queue_chain_t thread_list; /* list of threads in task */
+ /* Flags */
+ /* The flags are grouped here, but documented at the original
+ position. */
+ union {
+ struct {
+ unsigned state:16;
+ unsigned wake_active:1;
+ unsigned vm_privilege:1;
+ unsigned active:1;
+ };
+ event_t event_key;
+/* These keys can be used with thread_wakeup and friends. */
+#define TH_EV_WAKE_ACTIVE(t) ((event_t) (&(t)->event_key + 0))
+#define TH_EV_STATE(t) ((event_t) (&(t)->event_key + 1))
+ };
+
/* Thread bookkeeping */
queue_chain_t pset_threads; /* list of all threads in proc set*/
@@ -92,9 +108,10 @@ struct thread {
kern_return_t wait_result; /* outcome of wait -
may be examined by this thread
WITHOUT locking */
- boolean_t wake_active; /* someone is waiting for this
+ /* Defined above */
+ /* boolean_t wake_active; someone is waiting for this
thread to become suspended */
- int state; /* Thread state: */
+ /* int state; Thread state: */
/*
* Thread states [bits or'ed]
*/
@@ -129,7 +146,8 @@ struct thread {
/* VM global variables */
vm_offset_t recover; /* page fault recovery (copyin/out) */
- boolean_t vm_privilege; /* Can use reserved memory? */
+ /* Defined above */
+ /* boolean_t vm_privilege; Can use reserved memory? */
/* User-visible scheduling state */
int user_stop_count; /* outstanding stops */
@@ -194,7 +212,8 @@ struct thread {
timer_elt_data_t depress_timer; /* timer for priority depression */
/* Ast/Halt data structures */
- boolean_t active; /* how alive is the thread */
+ /* Defined above */
+ /* boolean_t active; how alive is the thread */
int ast; /* ast's needed. See ast.h */
/* Processor data structures */
@@ -259,6 +278,13 @@ extern kern_return_t thread_create(
thread_t *child_thread);
extern kern_return_t thread_terminate(
thread_t thread);
+extern kern_return_t thread_terminate_release(
+ thread_t thread,
+ task_t task,
+ mach_port_t thread_name,
+ mach_port_t reply_port,
+ vm_offset_t address,
+ vm_size_t size);
extern kern_return_t thread_suspend(
thread_t thread);
extern kern_return_t thread_resume(
@@ -338,14 +364,12 @@ extern kern_return_t thread_halt(
boolean_t must_halt);
extern void thread_halt_self(void);
extern void thread_force_terminate(thread_t);
-extern void thread_set_own_priority(
- int priority);
extern thread_t kernel_thread(
task_t task,
void (*start)(void),
void * arg);
-extern void reaper_thread(void);
+extern void reaper_thread(void) __attribute__((noreturn));
#if MACH_HOST
extern void thread_freeze(
@@ -384,4 +408,9 @@ extern void thread_unfreeze(
#define current_space() (current_task()->itk_space)
#define current_map() (current_task()->map)
+#if MACH_DEBUG
+void stack_init(vm_offset_t stack);
+void stack_finalize(vm_offset_t stack);
+#endif /* MACH_DEBUG */
+
#endif /* _KERN_THREAD_H_ */
diff --git a/kern/thread_swap.c b/kern/thread_swap.c
index f29bd5b7..20ad0409 100644
--- a/kern/thread_swap.c
+++ b/kern/thread_swap.c
@@ -86,8 +86,7 @@ void swapper_init(void)
* our callers have already tried that route.
*/
-void thread_swapin(thread)
- thread_t thread;
+void thread_swapin(thread_t thread)
{
switch (thread->state & TH_SWAP_STATE) {
case TH_SWAPPED:
@@ -97,7 +96,7 @@ void thread_swapin(thread)
thread->state = (thread->state & ~TH_SWAP_STATE)
| TH_SW_COMING_IN;
swapper_lock();
- enqueue_tail(&swapin_queue, (queue_entry_t) thread);
+ enqueue_tail(&swapin_queue, &(thread->links));
swapper_unlock();
thread_wakeup((event_t) &swapin_queue);
break;
@@ -124,16 +123,18 @@ void thread_swapin(thread)
* it on a run queue. No locks should be held on entry, as it is
* likely that this routine will sleep (waiting for stack allocation).
*/
-void thread_doswapin(thread)
- register thread_t thread;
+kern_return_t thread_doswapin(thread_t thread)
{
+ kern_return_t kr;
spl_t s;
/*
* Allocate the kernel stack.
*/
- stack_alloc(thread, thread_continue);
+ kr = stack_alloc(thread, thread_continue);
+ if (kr != KERN_SUCCESS)
+ return kr;
/*
* Place on run queue.
@@ -146,6 +147,7 @@ void thread_doswapin(thread)
thread_setrun(thread, TRUE);
thread_unlock(thread);
(void) splx(s);
+ return KERN_SUCCESS;
}
/*
@@ -154,10 +156,10 @@ void thread_doswapin(thread)
* This procedure executes as a kernel thread. Threads that need to
* be swapped in are swapped in by this thread.
*/
-void swapin_thread_continue(void)
+void __attribute__((noreturn)) swapin_thread_continue(void)
{
for (;;) {
- register thread_t thread;
+ thread_t thread;
spl_t s;
s = splsched();
@@ -165,13 +167,20 @@ void swapin_thread_continue(void)
while ((thread = (thread_t) dequeue_head(&swapin_queue))
!= THREAD_NULL) {
+ kern_return_t kr;
swapper_unlock();
(void) splx(s);
- thread_doswapin(thread); /* may block */
+ kr = thread_doswapin(thread); /* may block */
s = splsched();
swapper_lock();
+
+ if (kr != KERN_SUCCESS) {
+ enqueue_head(&swapin_queue,
+ (queue_entry_t) thread);
+ break;
+ }
}
assert_wait((event_t) &swapin_queue, FALSE);
diff --git a/kern/thread_swap.h b/kern/thread_swap.h
index 31130301..d032accf 100644
--- a/kern/thread_swap.h
+++ b/kern/thread_swap.h
@@ -37,8 +37,7 @@
*/
extern void swapper_init(void);
extern void thread_swapin(thread_t thread);
-extern void thread_doswapin(thread_t thread);
-extern void swapin_thread(void);
-extern void thread_swapout(thread_t thread);
+extern kern_return_t thread_doswapin(thread_t thread);
+extern void swapin_thread(void) __attribute__((noreturn));
#endif /* _KERN_THREAD_SWAP_H_ */
diff --git a/kern/time_stamp.c b/kern/time_stamp.c
index 22885b18..ee141a0e 100644
--- a/kern/time_stamp.c
+++ b/kern/time_stamp.c
@@ -32,31 +32,18 @@
/*
* ts.c - kern_timestamp system call.
*/
-#ifdef multimax
-#include <mmax/timer.h>
-#endif /* multimax */
-
-
-
kern_return_t
-kern_timestamp(tsp)
-struct tsval *tsp;
+kern_timestamp(struct tsval *tsp)
{
-#ifdef multimax
- struct tsval temp;
- temp.low_val = FRcounter;
- temp.high_val = 0;
-#else /* multimax */
/*
temp.low_val = 0;
temp.high_val = ts_tick_count;
*/
time_value_t temp;
temp = time;
-#endif /* multimax */
- if (copyout((char *)&temp,
- (char *)tsp,
+ if (copyout(&temp,
+ tsp,
sizeof(struct tsval)) != KERN_SUCCESS)
return(KERN_INVALID_ADDRESS);
return(KERN_SUCCESS);
@@ -66,10 +53,7 @@ struct tsval *tsp;
* Initialization procedure.
*/
-void timestamp_init()
+void timestamp_init(void)
{
-#ifdef multimax
-#else /* multimax */
ts_tick_count = 0;
-#endif /* multimax */
}
diff --git a/kern/timer.c b/kern/timer.c
index ec0524a8..79ada27e 100644
--- a/kern/timer.c
+++ b/kern/timer.c
@@ -33,24 +33,22 @@
#include <kern/cpu_number.h>
#include <kern/assert.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
timer_t current_timer[NCPUS];
timer_data_t kernel_timer[NCPUS];
-void timer_init(); /* forward */
-
/*
* init_timers initializes all non-thread timers and puts the
* service routine on the callout queue. All timers must be
* serviced by the callout routine once an hour.
*/
-void init_timers()
+void init_timers(void)
{
- register int i;
- register timer_t this_timer;
+ int i;
+ timer_t this_timer;
/*
* Initialize all the kernel timers and start the one
@@ -68,9 +66,7 @@ void init_timers()
/*
* timer_init initializes a single timer.
*/
-void timer_init(this_timer)
-register
-timer_t this_timer;
+void timer_init(timer_t this_timer)
{
this_timer->low_bits = 0;
this_timer->high_bits = 0;
@@ -94,8 +90,7 @@ timer_t this_timer;
* exactly once for each cpu during the boot sequence.
*/
void
-start_timer(timer)
-timer_t timer;
+start_timer(timer_t timer)
{
timer->tstamp = get_timestamp();
current_timer[cpu_number()] = timer;
@@ -108,8 +103,7 @@ timer_t timer;
* from user mode.
*/
void
-time_trap_uentry(ts)
-unsigned ts;
+time_trap_uentry(unsigned ts)
{
int elapsed;
int mycpu;
@@ -150,7 +144,7 @@ unsigned ts;
* user mode.
*/
void
-time_trap_uexit(ts)
+time_trap_uexit(int ts)
{
int elapsed;
int mycpu;
@@ -194,9 +188,9 @@ time_trap_uexit(ts)
* saved for time_int_exit.
*/
timer_t
-time_int_entry(ts,new_timer)
-unsigned ts;
-timer_t new_timer;
+time_int_entry(
+ unsigned ts,
+ timer_t new_timer)
{
int elapsed;
int mycpu;
@@ -235,9 +229,9 @@ timer_t new_timer;
* it.
*/
void
-time_int_exit(ts, old_timer)
-unsigned ts;
-timer_t old_timer;
+time_int_exit(
+ unsigned ts,
+ timer_t old_timer)
{
int elapsed;
int mycpu;
@@ -282,8 +276,7 @@ timer_t old_timer;
* Caller must lock out interrupts.
*/
void
-timer_switch(new_timer)
-timer_t new_timer;
+timer_switch(timer_t new_timer)
{
int elapsed;
int mycpu;
@@ -328,9 +321,7 @@ timer_t new_timer;
* timer_normalize normalizes the value of a timer. It is
* called only rarely, to make sure low_bits never overflows.
*/
-void timer_normalize(timer)
-register
-timer_t timer;
+void timer_normalize(timer_t timer)
{
unsigned int high_increment;
@@ -356,9 +347,9 @@ timer_t timer;
* Keep coherent with db_time_grab below.
*/
-static void timer_grab(timer, save)
-timer_t timer;
-timer_save_t save;
+static void timer_grab(
+ timer_t timer,
+ timer_save_t save)
{
#if MACH_ASSERT
unsigned int passes=0;
@@ -390,9 +381,9 @@ timer_save_t save;
* above.
*
*/
-void db_timer_grab(timer, save)
-timer_t timer;
-timer_save_t save;
+void db_timer_grab(
+ timer_t timer,
+ timer_save_t save)
{
/* Don't worry about coherency */
@@ -409,10 +400,9 @@ timer_save_t save;
*/
void
-timer_read(timer, tv)
-timer_t timer;
-register
-time_value_t *tv;
+timer_read(
+ timer_t timer,
+ time_value_t *tv)
{
timer_save_data_t temp;
@@ -436,13 +426,13 @@ time_value_t *tv;
*
* Needs to be kept coherent with thread_read_times ahead.
*/
-void thread_read_times(thread, user_time_p, system_time_p)
- thread_t thread;
- time_value_t *user_time_p;
- time_value_t *system_time_p;
+void thread_read_times(
+ thread_t thread,
+ time_value_t *user_time_p,
+ time_value_t *system_time_p)
{
timer_save_data_t temp;
- register timer_t timer;
+ timer_t timer;
timer = &thread->user_timer;
timer_grab(timer, &temp);
@@ -470,13 +460,13 @@ void thread_read_times(thread, user_time_p, system_time_p)
* thread_read_times above.
*
*/
-void db_thread_read_times(thread, user_time_p, system_time_p)
- thread_t thread;
- time_value_t *user_time_p;
- time_value_t *system_time_p;
+void db_thread_read_times(
+ thread_t thread,
+ time_value_t *user_time_p,
+ time_value_t *system_time_p)
{
timer_save_data_t temp;
- register timer_t timer;
+ timer_t timer;
timer = &thread->user_timer;
db_timer_grab(timer, &temp);
@@ -505,13 +495,12 @@ void db_thread_read_times(thread, user_time_p, system_time_p)
*/
unsigned
-timer_delta(timer, save)
-register
-timer_t timer;
-timer_save_t save;
+timer_delta(
+ timer_t timer,
+ timer_save_t save)
{
timer_save_data_t new_save;
- register unsigned result;
+ unsigned result;
timer_grab(timer,&new_save);
result = (new_save.high - save->high) * TIMER_HIGH_UNIT +
diff --git a/kern/timer.h b/kern/timer.h
index 817fa356..2f473cf8 100644
--- a/kern/timer.h
+++ b/kern/timer.h
@@ -27,7 +27,7 @@
#ifndef _KERN_TIMER_H_
#define _KERN_TIMER_H_
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#if STAT_TIME
/*
@@ -168,7 +168,7 @@ extern void time_int_exit(unsigned, timer_t);
#define TIMER_DELTA(timer, save, result) \
MACRO_BEGIN \
- register unsigned temp; \
+ unsigned temp; \
\
temp = (timer).low_bits; \
if ((save).high != (timer).high_bits_check) { \
@@ -182,4 +182,6 @@ MACRO_END
extern void init_timers(void);
+void timer_init(timer_t this_timer);
+
#endif /* _KERN_TIMER_H_ */
diff --git a/kern/xpr.c b/kern/xpr.c
index 465ba7bb..46cb2273 100644
--- a/kern/xpr.c
+++ b/kern/xpr.c
@@ -56,12 +56,16 @@ struct xprbuf *xprptr; /* Currently allocated xprbuf */
struct xprbuf *xprlast; /* Pointer to end of circular buffer */
/*VARARGS1*/
-void xpr(msg, arg1, arg2, arg3, arg4, arg5)
-char *msg;
-int arg1, arg2, arg3, arg4, arg5;
+void xpr(
+ char *msg,
+ int arg1,
+ int arg2,
+ int arg3,
+ int arg4,
+ int arg5)
{
- register spl_t s;
- register struct xprbuf *x;
+ spl_t s;
+ struct xprbuf *x;
/* If we aren't initialized, ignore trace request */
if (!xprenable || (xprptr == 0))
@@ -115,7 +119,7 @@ void xprbootstrap(void)
* the previous buffer contents.
*/
- memset((char *) addr, 0, size);
+ memset((void *) addr, 0, size);
}
xprbase = (struct xprbuf *) addr;
@@ -132,9 +136,8 @@ void xprinit(void)
#if MACH_KDB
#include <machine/setjmp.h>
+#include <ddb/db_output.h>
-
-extern void db_printf();
extern jmp_buf_t *db_recover;
/*
@@ -145,16 +148,16 @@ extern jmp_buf_t *db_recover;
* Called with arguments, it can dump xpr buffers in user tasks,
* assuming they use the same format as the kernel.
*/
-void xpr_dump(base, nbufs)
- struct xprbuf *base;
- int nbufs;
+void xpr_dump(
+ struct xprbuf *base,
+ int nbufs)
{
jmp_buf_t db_jmpbuf;
jmp_buf_t *prev;
struct xprbuf *last, *ptr;
- register struct xprbuf *x;
+ struct xprbuf *x;
int i;
- spl_t s;
+ spl_t s = s;
if (base == 0) {
base = xprbase;
diff --git a/kern/xpr.h b/kern/xpr.h
index 4a06216a..72f68170 100644
--- a/kern/xpr.h
+++ b/kern/xpr.h
@@ -34,7 +34,7 @@
* which will expand into the following code:
* if (xprflags & XPR_SYSCALLS)
* xpr("syscall: %d, 0x%x\n", syscallno, arg1);
- * Xpr will log the pointer to the printf string and up to 6 arguements,
+ * Xpr will log the pointer to the printf string and up to 6 arguments,
* along with a timestamp and cpuinfo (for multi-processor systems), into
* a circular buffer. The actual printf processing is delayed until after
* the buffer has been collected. It is assumed that the text/data segments
diff --git a/linux/Makefrag.am b/linux/Makefrag.am
index 7c7b432d..1b690108 100644
--- a/linux/Makefrag.am
+++ b/linux/Makefrag.am
@@ -36,6 +36,11 @@ liblinux_a_CPPFLAGS = $(AM_CPPFLAGS) \
# Because of the use of `extern inline' in some Linux header files without
# corresponding text segment definitions, we must always optimize.
liblinux_a_CFLAGS = -O2 $(AM_CFLAGS)
+
+# See <http://lists.gnu.org/archive/html/bug-hurd/2006-01/msg00148.html>.
+liblinux_a_CFLAGS += \
+ -fno-strict-aliasing
+
# TODO. Do we really need `-traditional'?
liblinux_a_CCASFLAGS = $(AM_CCASFLAGS) \
-D__ASSEMBLY__ -traditional \
@@ -78,6 +83,8 @@ liblinux_a_SOURCES += \
linux/src/drivers/block/ide-cd.c \
linux/src/drivers/block/ide.c \
linux/src/drivers/block/ide.h \
+ linux/dev/drivers/block/ahci.c \
+ linux/dev/include/ahci.h \
linux/src/drivers/block/ide_modes.h \
linux/src/drivers/block/rz1000.c \
linux/src/drivers/block/triton.c
@@ -747,6 +754,12 @@ EXTRA_DIST += \
linux/dev/README \
linux/src/COPYING
+# Those get #included...
+EXTRA_DIST += \
+ linux/src/drivers/scsi/FlashPoint.c \
+ linux/src/drivers/scsi/eata_pio_proc.c \
+ linux/src/drivers/scsi/scsiiom.c
+
# Instead of listing each file individually...
EXTRA_DIST += \
linux/dev/include \
diff --git a/linux/dev/arch/i386/kernel/irq.c b/linux/dev/arch/i386/kernel/irq.c
index 68bf0c4b..7753814b 100644
--- a/linux/dev/arch/i386/kernel/irq.c
+++ b/linux/dev/arch/i386/kernel/irq.c
@@ -695,7 +695,7 @@ init_IRQ (void)
* Program counter 0 of 8253 to interrupt hz times per second.
*/
outb_p (PIT_C0 | PIT_SQUAREMODE | PIT_READMODE, PITCTL_PORT);
- outb_p (latch && 0xff, PITCTR0_PORT);
+ outb_p (latch & 0xff, PITCTR0_PORT);
outb (latch >> 8, PITCTR0_PORT);
/*
diff --git a/linux/dev/drivers/block/ahci.c b/linux/dev/drivers/block/ahci.c
new file mode 100644
index 00000000..9bb2e6b4
--- /dev/null
+++ b/linux/dev/drivers/block/ahci.c
@@ -0,0 +1,1009 @@
+/*
+ * Copyright (C) 2013 Free Software Foundation
+ *
+ * This program is free software ; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation ; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY ; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with the program ; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <ahci.h>
+#include <kern/assert.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include <linux/bios32.h>
+#include <linux/major.h>
+#include <linux/hdreg.h>
+#include <linux/genhd.h>
+#include <asm/io.h>
+
+#define MAJOR_NR SCSI_DISK_MAJOR
+#include <linux/blk.h>
+
+/* Standard AHCI BAR for mmio */
+#define AHCI_PCI_BAR 5
+
+/* minor: 2 bits for device number, 6 bits for partition number. */
+
+#define MAX_PORTS 8
+#define PARTN_BITS 5
+#define PARTN_MASK ((1<<PARTN_BITS)-1)
+
+/* We need to use one DMA scatter element per physical page.
+ * ll_rw_block creates at most 8 buffer heads */
+/* See MAX_BUF */
+#define PRDTL_SIZE 8
+
+#define WAIT_MAX (1*HZ) /* Wait at most 1s for requests completion */
+
+/* AHCI standard structures */
+
+struct ahci_prdt {
+ u32 dba; /* Data base address */
+ u32 dbau; /* upper 32bit */
+ u32 rsv0; /* Reserved */
+
+ u32 dbc; /* Byte count bits 0-21,
+ * bit31 interrupt on completion. */
+};
+
+struct ahci_cmd_tbl {
+ u8 cfis[64];
+ u8 acmd[16];
+ u8 rsv[48];
+
+ struct ahci_prdt prdtl[PRDTL_SIZE];
+};
+
+struct ahci_command {
+ u32 opts; /* Command options */
+
+ u32 prdbc; /* Physical Region Descriptor byte count */
+
+ u32 ctba; /* Command Table Descriptor Base Address */
+ u32 ctbau; /* upper 32bit */
+
+ u32 rsv1[4]; /* Reserved */
+};
+
+struct ahci_fis_dma {
+ u8 fis_type;
+ u8 flags;
+ u8 rsved[2];
+ u64 id;
+ u32 rsvd;
+ u32 offset;
+ u32 count;
+ u32 resvd;
+};
+
+struct ahci_fis_pio {
+ u8 fis_type;
+ u8 flags;
+ u8 status;
+ u8 error;
+
+ u8 lba0;
+ u8 lba1;
+ u8 lba2;
+ u8 device;
+
+ u8 lba3;
+ u8 lba4;
+ u8 lba5;
+ u8 rsv2;
+
+ u8 countl;
+ u8 counth;
+ u8 rsv3;
+ u8 e_status;
+
+ u16 tc; /* Transfer Count */
+ u8 rsv4[2];
+};
+
+struct ahci_fis_d2h {
+ u8 fis_type;
+ u8 flags;
+ u8 status;
+ u8 error;
+
+ u8 lba0;
+ u8 lba1;
+ u8 lba2;
+ u8 device;
+
+ u8 lba3;
+ u8 lba4;
+ u8 lba5;
+ u8 rsv2;
+
+ u8 countl;
+ u8 counth;
+ u8 rsv3[2];
+
+ u8 rsv4[4];
+};
+
+struct ahci_fis_dev {
+ u8 rsvd[8];
+};
+
+struct ahci_fis_h2d {
+ u8 fis_type;
+ u8 flags;
+ u8 command;
+ u8 featurel;
+
+ u8 lba0;
+ u8 lba1;
+ u8 lba2;
+ u8 device;
+
+ u8 lba3;
+ u8 lba4;
+ u8 lba5;
+ u8 featureh;
+
+ u8 countl;
+ u8 counth;
+ u8 icc;
+ u8 control;
+
+ u8 rsv1[4];
+};
+
+struct ahci_fis_data {
+ u8 fis_type;
+ u8 flags;
+ u8 rsv1[2];
+ u32 data1[];
+};
+
+struct ahci_fis {
+ struct ahci_fis_dma dma_fis;
+ u8 pad0[4];
+
+ struct ahci_fis_pio pio_fis;
+ u8 pad1[12];
+
+ struct ahci_fis_d2h d2h_fis;
+ u8 pad2[4];
+
+ struct ahci_fis_dev dev_fis;
+
+ u8 ufis[64];
+
+ u8 rsv[0x100 - 0xa0];
+};
+
+struct ahci_port {
+ u32 clb; /* Command List Base address */
+ u32 clbu; /* upper 32bit */
+ u32 fb; /* FIS Base */
+ u32 fbu; /* upper 32bit */
+ u32 is; /* Interrupt Status */
+ u32 ie; /* Interrupt Enable */
+ u32 cmd; /* Command and Status */
+ u32 rsv0; /* Reserved */
+ u32 tfd; /* Task File Data */
+ u32 sig; /* Signature */
+ u32 ssts; /* SATA Status */
+ u32 sctl; /* SATA Control */
+ u32 serr; /* SATA Error */
+ u32 sact; /* SATA Active */
+ u32 ci; /* Command Issue */
+ u32 sntf; /* SATA Notification */
+ u32 fbs; /* FIS-based switch control */
+ u8 rsv1[0x70 - 0x44]; /* Reserved */
+ u8 vendor[0x80 - 0x70]; /* Vendor-specific */
+};
+
+struct ahci_host {
+ u32 cap; /* Host capabilities */
+ u32 ghc; /* Global Host Control */
+ u32 is; /* Interrupt Status */
+ u32 pi; /* Port Implemented */
+ u32 v; /* Version */
+ u32 ccc_ctl; /* Command Completion Coalescing control */
+ u32 ccc_pts; /* Command Completion Coalescing ports */
+ u32 em_loc; /* Enclosure Management location */
+ u32 em_ctrl; /* Enclosure Management control */
+ u32 cap2; /* Host capabilities extended */
+ u32 bohc; /* BIOS/OS Handoff Control and status */
+ u8 rsv[0xa0 - 0x2c]; /* Reserved */
+ u8 vendor[0x100 - 0xa0]; /* Vendor-specific */
+ struct ahci_port ports[]; /* Up to 32 ports */
+};
+
+/* Our own data */
+
+static struct port {
+ /* memory-mapped regions */
+ const volatile struct ahci_host *ahci_host;
+ const volatile struct ahci_port *ahci_port;
+
+ /* host-memory buffers */
+ struct ahci_command *command;
+ struct ahci_fis *fis;
+ struct ahci_cmd_tbl *prdtl;
+
+ struct hd_driveid id;
+ unsigned is_cd;
+ unsigned long long capacity; /* Nr of sectors */
+ u32 status; /* interrupt status */
+ unsigned cls; /* Command list maximum size.
+ We currently only use 1. */
+ struct wait_queue *q; /* IRQ wait queue */
+ struct hd_struct *part; /* drive partition table */
+ unsigned lba48; /* Whether LBA48 is supported */
+ unsigned identify; /* Whether we are just identifying
+ at boot */
+ struct gendisk *gd;
+} ports[MAX_PORTS];
+
+
+/* do_request() gets called by the block layer to push a request to the disk.
+ We just push one, and when an interrupt tells it's over, we call do_request()
+ ourself again to push the next request, etc. */
+
+/* Request completed, either successfully or with an error */
+static void ahci_end_request(int uptodate)
+{
+ struct request *rq = CURRENT;
+ struct buffer_head *bh;
+
+ rq->errors = 0;
+ if (!uptodate) {
+ if (!rq->quiet)
+ printk("end_request: I/O error, dev %s, sector %lu\n",
+ kdevname(rq->rq_dev), rq->sector);
+ }
+
+ for (bh = rq->bh; bh; )
+ {
+ struct buffer_head *next = bh->b_reqnext;
+ bh->b_reqnext = NULL;
+ mark_buffer_uptodate (bh, uptodate);
+ unlock_buffer (bh);
+ bh = next;
+ }
+
+ CURRENT = rq->next;
+ if (rq->sem != NULL)
+ up(rq->sem);
+ rq->rq_status = RQ_INACTIVE;
+ wake_up(&wait_for_request);
+}
+
+/* Push the request to the controler port */
+static void ahci_do_port_request(struct port *port, unsigned long long sector, struct request *rq)
+{
+ struct ahci_command *command = port->command;
+ struct ahci_cmd_tbl *prdtl = port->prdtl;
+ struct ahci_fis_h2d *fis_h2d;
+ unsigned slot = 0;
+ struct buffer_head *bh;
+ unsigned i;
+
+ rq->rq_status = RQ_SCSI_BUSY;
+
+ /* Shouldn't ever happen: the block glue is limited at 8 blocks */
+ assert(rq->nr_sectors < 0x10000);
+
+ fis_h2d = (void*) &prdtl[slot].cfis;
+ fis_h2d->fis_type = FIS_TYPE_REG_H2D;
+ fis_h2d->flags = 128;
+ if (port->lba48)
+ if (rq->cmd == READ)
+ fis_h2d->command = WIN_READDMA_EXT;
+ else
+ fis_h2d->command = WIN_WRITEDMA_EXT;
+ else
+ if (rq->cmd == READ)
+ fis_h2d->command = WIN_READDMA;
+ else
+ fis_h2d->command = WIN_WRITEDMA;
+
+ fis_h2d->device = 1<<6; /* LBA */
+
+ fis_h2d->lba0 = sector;
+ fis_h2d->lba1 = sector >> 8;
+ fis_h2d->lba2 = sector >> 16;
+
+ fis_h2d->lba3 = sector >> 24;
+ fis_h2d->lba4 = sector >> 32;
+ fis_h2d->lba5 = sector >> 40;
+
+ fis_h2d->countl = rq->nr_sectors;
+ fis_h2d->counth = rq->nr_sectors >> 8;
+
+ command[slot].opts = sizeof(*fis_h2d) / sizeof(u32);
+
+ if (rq->cmd == WRITE)
+ command[slot].opts |= AHCI_CMD_WRITE;
+
+ for (i = 0, bh = rq->bh; bh; i++, bh = bh->b_reqnext)
+ {
+ assert(i < PRDTL_SIZE);
+ assert((((unsigned long) bh->b_data) & ~PAGE_MASK) ==
+ (((unsigned long) bh->b_data + bh->b_size - 1) & ~PAGE_MASK));
+ prdtl[slot].prdtl[i].dbau = 0;
+ prdtl[slot].prdtl[i].dba = vmtophys(bh->b_data);
+ prdtl[slot].prdtl[i].dbc = bh->b_size - 1;
+ }
+
+ command[slot].opts |= i << 16;
+
+ /* Make sure main memory buffers are up to date */
+ mb();
+
+ /* Issue command */
+ writel(1 << slot, &port->ahci_port->ci);
+
+ /* TODO: IRQ timeout handler */
+}
+
+/* Called by block core to push a request */
+/* TODO: ideally, would have one request queue per port */
+/* TODO: ideally, would use tags to process several requests at a time */
+static void ahci_do_request() /* invoked with cli() */
+{
+ struct request *rq;
+ unsigned minor, unit;
+ unsigned long long block, blockend;
+ struct port *port;
+
+ rq = CURRENT;
+ if (!rq)
+ return;
+
+ if (rq->rq_status != RQ_ACTIVE)
+ /* Current one is already ongoing, let the interrupt handler
+ * push the new one when the current one is finished. */
+ return;
+
+ if (MAJOR(rq->rq_dev) != MAJOR_NR) {
+ printk("bad ahci major %u\n", MAJOR(rq->rq_dev));
+ goto kill_rq;
+ }
+
+ minor = MINOR(rq->rq_dev);
+ unit = minor >> PARTN_BITS;
+ if (unit > MAX_PORTS) {
+ printk("bad ahci unit %u\n", unit);
+ goto kill_rq;
+ }
+
+ port = &ports[unit];
+
+ /* Compute start sector */
+ block = rq->sector;
+ block += port->part[minor & PARTN_MASK].start_sect;
+
+ /* And check end */
+ blockend = block + rq->nr_sectors;
+ if (blockend < block) {
+ if (!rq->quiet)
+ printk("bad blockend %lu vs %lu\n", (unsigned long) blockend, (unsigned long) block);
+ goto kill_rq;
+ }
+ if (blockend > port->capacity) {
+ if (!rq->quiet)
+ {
+ printk("offset for %u was %lu\n", minor, port->part[minor & PARTN_MASK].start_sect);
+ printk("bad access: block %lu, count= %lu\n", (unsigned long) blockend, (unsigned long) port->capacity);
+ }
+ goto kill_rq;
+ }
+
+ /* Push this to the port */
+ ahci_do_port_request(port, block, rq);
+ return;
+
+kill_rq:
+ ahci_end_request(0);
+}
+
+/* The given port got an interrupt, terminate the current request if any */
+static void ahci_port_interrupt(struct port *port, u32 status)
+{
+ unsigned slot = 0;
+
+ if (readl(&port->ahci_port->ci) & (1 << slot)) {
+ /* Command still pending */
+ return;
+ }
+
+ if (port->identify) {
+ port->status = status;
+ wake_up(&port->q);
+ return;
+ }
+
+ if (!CURRENT || CURRENT->rq_status != RQ_SCSI_BUSY) {
+ /* No request currently running */
+ return;
+ }
+
+ if (status & (PORT_IRQ_TF_ERR | PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR | PORT_IRQ_IF_ERR | PORT_IRQ_IF_NONFATAL)) {
+ printk("ahci error %x %x\n", status, readl(&port->ahci_port->tfd));
+ ahci_end_request(0);
+ return;
+ }
+
+ ahci_end_request(1);
+}
+
+/* Start of IRQ handler. Iterate over all ports for this host */
+static void ahci_interrupt (int irq, void *host, struct pt_regs *regs)
+{
+ struct port *port;
+ struct ahci_host *ahci_host = host;
+ u32 irq_mask;
+ u32 status;
+
+ irq_mask = readl(&ahci_host->is);
+
+ if (!irq_mask)
+ return;
+
+ for (port = &ports[0]; port < &ports[MAX_PORTS]; port++) {
+ if (port->ahci_host == ahci_host && (irq_mask & (1 << (port->ahci_port - ahci_host->ports)))) {
+ status = readl(&port->ahci_port->is);
+ /* Clear interrupt before possibly triggering others */
+ writel(status, &port->ahci_port->is);
+ ahci_port_interrupt (port, status);
+ }
+ }
+
+ if (CURRENT)
+ /* Still some requests, queue another one */
+ ahci_do_request();
+
+ /* Clear host after clearing ports */
+ writel(irq_mask, &ahci_host->is);
+
+ /* unlock */
+}
+
+static int ahci_ioctl (struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int major, unit;
+
+ if (!inode || !inode->i_rdev)
+ return -EINVAL;
+
+ major = MAJOR(inode->i_rdev);
+ if (major != MAJOR_NR)
+ return -ENOTTY;
+
+ unit = DEVICE_NR(inode->i_rdev);
+ if (unit >= MAX_PORTS)
+ return -EINVAL;
+
+ switch (cmd) {
+ case BLKRRPART:
+ if (!suser()) return -EACCES;
+ if (!ports[unit].gd)
+ return -EINVAL;
+ resetup_one_dev(ports[unit].gd, unit);
+ return 0;
+ default:
+ return -EPERM;
+ }
+}
+
+static int ahci_open (struct inode *inode, struct file *file)
+{
+ int target;
+
+ if (MAJOR(inode->i_rdev) != MAJOR_NR)
+ return -ENXIO;
+
+ target = MINOR(inode->i_rdev) >> PARTN_BITS;
+ if (target >= MAX_PORTS)
+ return -ENXIO;
+
+ if (!ports[target].ahci_port)
+ return -ENXIO;
+
+ return 0;
+}
+
+static void ahci_release (struct inode *inode, struct file *file)
+{
+}
+
+static int ahci_fsync (struct inode *inode, struct file *file)
+{
+ printk("fsync\n");
+ return -ENOSYS;
+}
+
+static struct file_operations ahci_fops = {
+ .lseek = NULL,
+ .read = block_read,
+ .write = block_write,
+ .readdir = NULL,
+ .select = NULL,
+ .ioctl = ahci_ioctl,
+ .mmap = NULL,
+ .open = ahci_open,
+ .release = ahci_release,
+ .fsync = ahci_fsync,
+ .fasync = NULL,
+ .check_media_change = NULL,
+ .revalidate = NULL,
+};
+
+/* Disk timed out while processing identify, interrupt ahci_probe_port */
+static void identify_timeout(unsigned long data)
+{
+ struct port *port = (void*) data;
+
+ wake_up(&port->q);
+}
+
+static struct timer_list identify_timer = { .function = identify_timeout };
+
+static int ahci_identify(const volatile struct ahci_host *ahci_host, const volatile struct ahci_port *ahci_port, struct port *port, unsigned cmd)
+{
+ struct hd_driveid id;
+ struct ahci_fis_h2d *fis_h2d;
+ struct ahci_command *command = port->command;
+ struct ahci_cmd_tbl *prdtl = port->prdtl;
+ unsigned long flags;
+ unsigned slot;
+ unsigned long first_part;
+ unsigned long long timeout;
+ int ret = 0;
+
+ /* Identify device */
+ /* TODO: make this a request */
+ slot = 0;
+
+ fis_h2d = (void*) &prdtl[slot].cfis;
+ fis_h2d->fis_type = FIS_TYPE_REG_H2D;
+ fis_h2d->flags = 128;
+ fis_h2d->command = cmd;
+ fis_h2d->device = 0;
+
+ /* Fetch the 512 identify data */
+ memset(&id, 0, sizeof(id));
+
+ command[slot].opts = sizeof(*fis_h2d) / sizeof(u32);
+
+ first_part = PAGE_ALIGN((unsigned long) &id) - (unsigned long) &id;
+
+ if (first_part && first_part < sizeof(id)) {
+ /* split over two pages */
+
+ command[slot].opts |= (2 << 16);
+
+ prdtl[slot].prdtl[0].dbau = 0;
+ prdtl[slot].prdtl[0].dba = vmtophys((void*) &id);
+ prdtl[slot].prdtl[0].dbc = first_part - 1;
+ prdtl[slot].prdtl[1].dbau = 0;
+ prdtl[slot].prdtl[1].dba = vmtophys((void*) &id + first_part);
+ prdtl[slot].prdtl[1].dbc = sizeof(id) - first_part - 1;
+ }
+ else
+ {
+ command[slot].opts |= (1 << 16);
+
+ prdtl[slot].prdtl[0].dbau = 0;
+ prdtl[slot].prdtl[0].dba = vmtophys((void*) &id);
+ prdtl[slot].prdtl[0].dbc = sizeof(id) - 1;
+ }
+
+ timeout = jiffies + WAIT_MAX;
+ while (readl(&ahci_port->tfd) & (BUSY_STAT | DRQ_STAT))
+ if (jiffies > timeout) {
+ printk("sd%u: timeout waiting for ready\n", port-ports);
+ port->ahci_host = NULL;
+ port->ahci_port = NULL;
+ return 3;
+ }
+
+ save_flags(flags);
+ cli();
+
+ port->identify = 1;
+ port->status = 0;
+
+ /* Issue command */
+ mb();
+ writel(1 << slot, &ahci_port->ci);
+
+ timeout = jiffies + WAIT_MAX;
+ identify_timer.expires = timeout;
+ identify_timer.data = (unsigned long) port;
+ add_timer(&identify_timer);
+ while (!port->status) {
+ if (jiffies >= timeout) {
+ printk("sd%u: timeout waiting for ready\n", port-ports);
+ port->ahci_host = NULL;
+ port->ahci_port = NULL;
+ del_timer(&identify_timer);
+ restore_flags(flags);
+ return 3;
+ }
+ sleep_on(&port->q);
+ }
+ del_timer(&identify_timer);
+ restore_flags(flags);
+
+ if ((port->status & PORT_IRQ_TF_ERR) || readl(&ahci_port->is) & PORT_IRQ_TF_ERR)
+ {
+ /* Identify error */
+ port->capacity = 0;
+ port->lba48 = 0;
+ ret = 2;
+ } else {
+ memcpy(&port->id, &id, sizeof(id));
+ port->is_cd = 0;
+
+ ide_fixstring(id.model, sizeof(id.model), 1);
+ ide_fixstring(id.fw_rev, sizeof(id.fw_rev), 1);
+ ide_fixstring(id.serial_no, sizeof(id.serial_no), 1);
+ if (cmd == WIN_PIDENTIFY)
+ {
+ unsigned char type = (id.config >> 8) & 0x1f;
+
+ printk("sd%u: %s, ATAPI ", port - ports, id.model);
+ if (type == 5)
+ {
+ printk("unsupported CDROM drive\n");
+ port->is_cd = 1;
+ port->lba48 = 0;
+ port->capacity = 0;
+ }
+ else
+ {
+ printk("unsupported type %d\n", type);
+ port->lba48 = 0;
+ port->capacity = 0;
+ return 2;
+ }
+ return 0;
+ }
+
+ if (id.command_set_2 & (1U<<10))
+ {
+ port->lba48 = 1;
+ port->capacity = id.lba_capacity_2;
+ if (port->capacity >= (1ULL << 32))
+ {
+ port->capacity = (1ULL << 32) - 1;
+ printk("Warning: truncating disk size to 2TiB\n");
+ }
+ }
+ else
+ {
+ port->lba48 = 0;
+ port->capacity = id.lba_capacity;
+ if (port->capacity > (1ULL << 24))
+ {
+ port->capacity = (1ULL << 24);
+ printk("Warning: truncating disk size to 128GiB\n");
+ }
+ }
+ if (port->capacity/2048 >= 10240)
+ printk("sd%u: %s, %uGB w/%dkB Cache\n", port - ports, id.model, (unsigned) (port->capacity/(2048*1024)), id.buf_size/2);
+ else
+ printk("sd%u: %s, %uMB w/%dkB Cache\n", port - ports, id.model, (unsigned) (port->capacity/2048), id.buf_size/2);
+ }
+ port->identify = 0;
+
+ return ret;
+}
+
+/* Probe one AHCI port */
+static void ahci_probe_port(const volatile struct ahci_host *ahci_host, const volatile struct ahci_port *ahci_port)
+{
+ struct port *port;
+ void *mem;
+ unsigned cls = ((readl(&ahci_host->cap) >> 8) & 0x1f) + 1;
+ struct ahci_command *command;
+ struct ahci_fis *fis;
+ struct ahci_cmd_tbl *prdtl;
+ vm_size_t size =
+ cls * sizeof(*command)
+ + sizeof(*fis)
+ + cls * sizeof(*prdtl);
+ unsigned i;
+ unsigned long long timeout;
+
+ for (i = 0; i < MAX_PORTS; i++) {
+ if (!ports[i].ahci_port)
+ break;
+ }
+ if (i == MAX_PORTS)
+ return;
+ port = &ports[i];
+
+ /* Has to be 1K-aligned */
+ mem = vmalloc (size);
+ if (!mem)
+ return;
+ assert (!(((unsigned long) mem) & (1024-1)));
+ memset (mem, 0, size);
+
+ port->ahci_host = ahci_host;
+ port->ahci_port = ahci_port;
+ port->cls = cls;
+
+ port->command = command = mem;
+ port->fis = fis = (void*) command + cls * sizeof(*command);
+ port->prdtl = prdtl = (void*) fis + sizeof(*fis);
+
+ /* Stop commands */
+ writel(readl(&ahci_port->cmd) & ~PORT_CMD_START, &ahci_port->cmd);
+ timeout = jiffies + WAIT_MAX;
+ while (readl(&ahci_port->cmd) & PORT_CMD_LIST_ON)
+ if (jiffies > timeout) {
+ printk("sd%u: timeout waiting for list completion\n", port-ports);
+ port->ahci_host = NULL;
+ port->ahci_port = NULL;
+ return;
+ }
+
+ writel(readl(&ahci_port->cmd) & ~PORT_CMD_FIS_RX, &ahci_port->cmd);
+ timeout = jiffies + WAIT_MAX;
+ while (readl(&ahci_port->cmd) & PORT_CMD_FIS_ON)
+ if (jiffies > timeout) {
+ printk("sd%u: timeout waiting for FIS completion\n", port-ports);
+ port->ahci_host = NULL;
+ port->ahci_port = NULL;
+ return;
+ }
+
+ /* We don't support 64bit */
+ /* Point controller to our buffers */
+ writel(0, &ahci_port->clbu);
+ writel(vmtophys((void*) command), &ahci_port->clb);
+ writel(0, &ahci_port->fbu);
+ writel(vmtophys((void*) fis), &ahci_port->fb);
+
+ /* Clear any previous interrupts */
+ writel(readl(&ahci_port->is), &ahci_port->is);
+ writel(1 << (ahci_port - ahci_host->ports), &ahci_host->is);
+
+ /* And activate them */
+ writel(DEF_PORT_IRQ, &ahci_port->ie);
+ writel(readl(&ahci_host->ghc) | HOST_IRQ_EN, &ahci_host->ghc);
+
+ for (i = 0; i < cls; i++)
+ {
+ command[i].ctbau = 0;
+ command[i].ctba = vmtophys((void*) &prdtl[i]);
+ }
+
+ /* Start commands */
+ timeout = jiffies + WAIT_MAX;
+ while (readl(&ahci_port->cmd) & PORT_CMD_LIST_ON)
+ if (jiffies > timeout) {
+ printk("sd%u: timeout waiting for list completion\n", port-ports);
+ port->ahci_host = NULL;
+ port->ahci_port = NULL;
+ return;
+ }
+
+ writel(readl(&ahci_port->cmd) | PORT_CMD_FIS_RX | PORT_CMD_START, &ahci_port->cmd);
+
+ if (ahci_identify(ahci_host, ahci_port, port, WIN_IDENTIFY) >= 2)
+ /* Try ATAPI */
+ ahci_identify(ahci_host, ahci_port, port, WIN_PIDENTIFY);
+}
+
+/* Probe one AHCI PCI device */
+static void ahci_probe_dev(unsigned char bus, unsigned char device)
+{
+ unsigned char hdrtype;
+ unsigned char dev, fun;
+ const volatile struct ahci_host *ahci_host;
+ const volatile struct ahci_port *ahci_port;
+ unsigned nports, n, i;
+ unsigned port_map;
+ unsigned bar;
+ unsigned char irq;
+
+ dev = PCI_SLOT(device);
+ fun = PCI_FUNC(device);
+
+ /* Get configuration */
+ if (pcibios_read_config_byte(bus, device, PCI_HEADER_TYPE, &hdrtype) != PCIBIOS_SUCCESSFUL) {
+ printk("ahci: %02u:%02u.%u: Can not read configuration", bus, dev, fun);
+ return;
+ }
+
+ if (hdrtype != 0) {
+ printk("ahci: %02u:%02u.%u: Unknown hdrtype %d\n", bus, dev, fun, hdrtype);
+ return;
+ }
+
+ if (pcibios_read_config_dword(bus, device, PCI_BASE_ADDRESS_5, &bar) != PCIBIOS_SUCCESSFUL) {
+ printk("ahci: %02u:%02u.%u: Can not read BAR 5", bus, dev, fun);
+ return;
+ }
+ if (bar & 0x01) {
+ printk("ahci: %02u:%02u.%u: BAR 5 is I/O?!", bus, dev, fun);
+ return;
+ }
+ bar &= ~0x0f;
+
+ if (pcibios_read_config_byte(bus, device, PCI_INTERRUPT_LINE, &irq) != PCIBIOS_SUCCESSFUL) {
+ printk("ahci: %02u:%02u.%u: Can not read IRQ", bus, dev, fun);
+ return;
+ }
+
+ printk("AHCI SATA %02u:%02u.%u BAR 0x%x IRQ %u\n", bus, dev, fun, bar, irq);
+
+ /* Map mmio */
+ ahci_host = vremap(bar, 0x2000);
+
+ /* Request IRQ */
+ if (request_irq(irq, &ahci_interrupt, SA_SHIRQ, "ahci", (void*) ahci_host)) {
+ printk("ahci: %02u:%02u.%u: Can not get irq %u\n", bus, dev, fun, irq);
+ return;
+ }
+
+ nports = (readl(&ahci_host->cap) & 0x1f) + 1;
+ port_map = readl(&ahci_host->pi);
+
+ for (n = 0, i = 0; i < AHCI_MAX_PORTS; i++)
+ if (port_map & (1U << i))
+ n++;
+
+ if (nports != n) {
+ printk("ahci: %02u:%02u.%u: Odd number of ports %u, assuming %u is correct\n", bus, dev, fun, n, nports);
+ port_map = 0;
+ }
+ if (!port_map) {
+ port_map = (1U << nports) - 1;
+ }
+
+ for (i = 0; i < AHCI_MAX_PORTS; i++) {
+ u32 ssts;
+ u8 spd, ipm;
+
+ if (!(port_map & (1U << i)))
+ continue;
+
+ ahci_port = &ahci_host->ports[i];
+
+ ssts = readl(&ahci_port->ssts);
+ spd = ssts & 0xf;
+ switch (spd)
+ {
+ case 0x0:
+ /* Device not present */
+ continue;
+ case 0x1:
+ printk("ahci: %02u:%02u.%u: Port %u communication not established. TODO: power on device\n", bus, dev, fun, i);
+ continue;
+ case 0x3:
+ /* Present and communication established */
+ break;
+ case 0x4:
+ printk("ahci: %02u:%02u.%u: Phy offline?!\n", bus, dev, fun, i);
+ continue;
+ default:
+ printk("ahci: %02u:%02u.%u: Unknown port %u SPD %x\n", bus, dev, fun, i, spd);
+ continue;
+ }
+
+ ipm = (ssts >> 8) & 0xf;
+ switch (ipm)
+ {
+ case 0x0:
+ /* Device not present */
+ continue;
+ case 0x1:
+ /* Active */
+ break;
+ case 0x2:
+ printk("ahci: %02u:%02u.%u: Port %u in Partial power management. TODO: power on device\n", bus, dev, fun, i);
+ continue;
+ case 0x6:
+ printk("ahci: %02u:%02u.%u: Port %u in Slumber power management. TODO: power on device\n", bus, dev, fun, i);
+ continue;
+ default:
+ printk("ahci: %02u:%02u.%u: Unknown port %u IPM %x\n", bus, dev, fun, i, ipm);
+ continue;
+ }
+
+ /* OK! Probe this port */
+ ahci_probe_port(ahci_host, ahci_port);
+ }
+}
+
+/* genhd callback to set size of disks */
+static void ahci_geninit(struct gendisk *gd)
+{
+ unsigned unit;
+ struct port *port;
+
+ for (unit = 0; unit < gd->nr_real; unit++) {
+ port = &ports[unit];
+ port->part[0].nr_sects = port->capacity;
+ if (!port->part[0].nr_sects)
+ port->part[0].nr_sects = -1;
+ }
+}
+
+/* Probe all AHCI PCI devices */
+void ahci_probe_pci(void)
+{
+ unsigned char bus, device;
+ unsigned short index;
+ int ret;
+ unsigned nports, unit, nminors;
+ struct port *port;
+ struct gendisk *gd, **gdp;
+ int *bs;
+
+ for (index = 0;
+ (ret = pcibios_find_class(PCI_CLASS_STORAGE_SATA_AHCI, index, &bus, &device)) == PCIBIOS_SUCCESSFUL;
+ index++)
+ {
+ /* Note: this prevents from also having a SCSI controler.
+ * It shouldn't harm too much until we have proper hardware
+ * enumeration.
+ */
+ if (register_blkdev(MAJOR_NR, "sd", &ahci_fops) < 0)
+ printk("could not register ahci\n");
+ ahci_probe_dev(bus, device);
+ }
+
+ for (nports = 0, port = &ports[0]; port < &ports[MAX_PORTS]; port++)
+ if (port->ahci_port)
+ nports++;
+
+ nminors = nports * (1<<PARTN_BITS);
+
+ gd = kmalloc(sizeof(*gd), GFP_KERNEL);
+ gd->sizes = kmalloc(nminors * sizeof(*gd->sizes), GFP_KERNEL);
+ gd->part = kmalloc(nminors * sizeof(*gd->part), GFP_KERNEL);
+ bs = kmalloc(nminors * sizeof(*bs), GFP_KERNEL);
+
+ blksize_size[MAJOR_NR] = bs;
+ for (unit = 0; unit < nminors; unit++)
+ /* We prefer to transfer whole pages */
+ *bs++ = PAGE_SIZE;
+
+ memset(gd->part, 0, nminors * sizeof(*gd->part));
+
+ for (unit = 0; unit < nports; unit++) {
+ ports[unit].gd = gd;
+ ports[unit].part = &gd->part[unit << PARTN_BITS];
+ }
+
+ gd->major = MAJOR_NR;
+ gd->major_name = "sd";
+ gd->minor_shift = PARTN_BITS;
+ gd->max_p = 1<<PARTN_BITS;
+ gd->max_nr = nports;
+ gd->nr_real = nports;
+ gd->init = ahci_geninit;
+ gd->next = NULL;
+
+ for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
+ ;
+ *gdp = gd;
+
+ blk_dev[MAJOR_NR].request_fn = ahci_do_request;
+}
diff --git a/linux/dev/drivers/block/floppy.c b/linux/dev/drivers/block/floppy.c
index 4c0977a3..83d66f05 100644
--- a/linux/dev/drivers/block/floppy.c
+++ b/linux/dev/drivers/block/floppy.c
@@ -3723,7 +3723,7 @@ static int floppy_revalidate(kdev_t dev)
return 1;
}
if (bh && !buffer_uptodate(bh))
- ll_rw_block(READ, 1, &bh);
+ ll_rw_block(READ, 1, &bh, 1);
process_fd_request();
wait_on_buffer(bh);
brelse(bh);
diff --git a/linux/dev/drivers/block/genhd.c b/linux/dev/drivers/block/genhd.c
index 95b499b1..3a861386 100644
--- a/linux/dev/drivers/block/genhd.c
+++ b/linux/dev/drivers/block/genhd.c
@@ -27,6 +27,8 @@
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#endif
+#include <linux/hdreg.h>
+#include <alloca.h>
#include <asm/system.h>
@@ -768,12 +770,36 @@ static void setup_dev(struct gendisk *dev)
void device_setup(void)
{
extern void console_map_init(void);
+ extern char *kernel_cmdline;
+ char *c, *param, *white;
struct gendisk *p;
int nr=0;
#ifdef MACH
linux_intr_pri = SPL6;
#endif
+ for (c = kernel_cmdline; c; )
+ {
+ param = strstr(c, " ide");
+ if (!param)
+ param = strstr(c, " hd");
+ if (!param)
+ break;
+ if (param) {
+ param++;
+ white = strchr(param, ' ');
+ if (!white) {
+ ide_setup(param);
+ c = NULL;
+ } else {
+ char *word = alloca(white - param + 1);
+ strncpy(word, param, white - param);
+ word[white-param] = '\0';
+ ide_setup(word);
+ c = white + 1;
+ }
+ }
+ }
#ifndef MACH
chr_dev_init();
#endif
diff --git a/linux/dev/glue/block.c b/linux/dev/glue/block.c
index 8c41f088..da4ef38e 100644
--- a/linux/dev/glue/block.c
+++ b/linux/dev/glue/block.c
@@ -384,7 +384,7 @@ bread (kdev_t dev, int block, int size)
bh = getblk (dev, block, size);
if (bh)
{
- ll_rw_block (READ, 1, &bh);
+ ll_rw_block (READ, 1, &bh, 0);
wait_on_buffer (bh);
if (! buffer_uptodate (bh))
{
@@ -444,7 +444,7 @@ enqueue_request (struct request *req)
/* Perform the I/O operation RW on the buffer list BH
containing NR buffers. */
void
-ll_rw_block (int rw, int nr, struct buffer_head **bh)
+ll_rw_block (int rw, int nr, struct buffer_head **bh, int quiet)
{
int i, bshift, bsize;
unsigned major;
@@ -476,6 +476,7 @@ ll_rw_block (int rw, int nr, struct buffer_head **bh)
r->rq_dev = bh[0]->b_dev;
r->cmd = rw;
r->errors = 0;
+ r->quiet = quiet;
r->sector = bh[0]->b_blocknr << (bshift - 9);
r->current_nr_sectors = bh[0]->b_size >> 9;
r->buffer = bh[0]->b_data;
@@ -528,7 +529,7 @@ rdwr_partial (int rw, kdev_t dev, loff_t *off,
bh->b_data = alloc_buffer (bh->b_size);
if (! bh->b_data)
return -ENOMEM;
- ll_rw_block (READ, 1, &bh);
+ ll_rw_block (READ, 1, &bh, 0);
wait_on_buffer (bh);
if (buffer_uptodate (bh))
{
@@ -542,7 +543,7 @@ rdwr_partial (int rw, kdev_t dev, loff_t *off,
{
memcpy (bh->b_data + o, *buf, c);
bh->b_state = (1 << BH_Dirty) | (1 << BH_Lock);
- ll_rw_block (WRITE, 1, &bh);
+ ll_rw_block (WRITE, 1, &bh, 0);
wait_on_buffer (bh);
if (! buffer_uptodate (bh))
{
@@ -589,8 +590,8 @@ rdwr_full (int rw, kdev_t dev, loff_t *off, char **buf, int *resid, int bshift)
set_bit (BH_Lock, &bh->b_state);
if (rw == WRITE)
set_bit (BH_Dirty, &bh->b_state);
- cc = PAGE_SIZE - (((int) *buf) & PAGE_MASK);
- if (cc >= BSIZE && ((int) *buf & 511) == 0)
+ cc = PAGE_SIZE - (((int) *buf + (nb << bshift)) & PAGE_MASK);
+ if (cc >= BSIZE && (((int) *buf + (nb << bshift)) & 511) == 0)
cc &= ~BMASK;
else
{
@@ -623,7 +624,8 @@ rdwr_full (int rw, kdev_t dev, loff_t *off, char **buf, int *resid, int bshift)
}
if (! err)
{
- ll_rw_block (rw, i, bhp);
+ assert (i > 0);
+ ll_rw_block (rw, i, bhp, 0);
wait_on_buffer (bhp[i - 1]);
}
for (bh = bhead, cc = 0, j = 0; j < i; cc += bh->b_size, bh++, j++)
@@ -1650,7 +1652,7 @@ device_get_status (void *d, dev_flavor_t flavor, dev_status_t status,
/* It would be nice to return the block size as reported by
the driver, but a lot of user level code assumes the sector
size to be 512. */
- status[DEV_GET_SIZE_RECORD_SIZE] = 512;
+ status[DEV_GET_RECORDS_RECORD_SIZE] = 512;
/* Always return DEV_GET_RECORDS_COUNT. This is what all native
Mach drivers do, and makes it possible to detect the absence
of the call by setting it to a different value on input. MiG
@@ -1703,7 +1705,7 @@ device_get_status (void *d, dev_flavor_t flavor, dev_status_t status,
static io_return_t
device_set_status (void *d, dev_flavor_t flavor, dev_status_t status,
- mach_msg_type_number_t *status_count)
+ mach_msg_type_number_t status_count)
{
struct block_data *bd = d;
diff --git a/linux/dev/glue/kmem.c b/linux/dev/glue/kmem.c
index 28321711..ff052ffc 100644
--- a/linux/dev/glue/kmem.c
+++ b/linux/dev/glue/kmem.c
@@ -560,6 +560,12 @@ vfree (void *addr)
vmalloc_list_remove (p);
}
+unsigned long
+vmtophys (void *addr)
+{
+ return kvtophys((vm_offset_t) addr);
+}
+
/* XXX: Quick hacking. */
/* Remap physical address into virtual address. */
void *
diff --git a/linux/dev/include/ahci.h b/linux/dev/include/ahci.h
new file mode 100644
index 00000000..31977b63
--- /dev/null
+++ b/linux/dev/include/ahci.h
@@ -0,0 +1,268 @@
+#ifndef _GNUMACH_AHCI_H
+#define _GNUMACH_AHCI_H
+extern void ahci_probe_pci(void);
+
+/* From linux 3.9's drivers/ata/ahci.h */
+
+/*
+ * ahci.h - Common AHCI SATA definitions and declarations
+ *
+ * Maintained by: Jeff Garzik <jgarzik@pobox.com>
+ * Please ALWAYS copy linux-ide@vger.kernel.org
+ * on emails.
+ *
+ * Copyright 2004-2005 Red Hat, Inc.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * libata documentation is available via 'make {ps|pdf}docs',
+ * as Documentation/DocBook/libata.*
+ *
+ * AHCI hardware documentation:
+ * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
+ * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf
+ *
+ */
+
+enum {
+ AHCI_MAX_PORTS = 32,
+ AHCI_MAX_SG = 168, /* hardware max is 64K */
+ AHCI_DMA_BOUNDARY = 0xffffffff,
+ AHCI_MAX_CMDS = 32,
+ AHCI_CMD_SZ = 32,
+ AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ,
+ AHCI_RX_FIS_SZ = 256,
+ AHCI_CMD_TBL_CDB = 0x40,
+ AHCI_CMD_TBL_HDR_SZ = 0x80,
+ AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 16),
+ AHCI_CMD_TBL_AR_SZ = AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS,
+ AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ +
+ AHCI_RX_FIS_SZ,
+ AHCI_PORT_PRIV_FBS_DMA_SZ = AHCI_CMD_SLOT_SZ +
+ AHCI_CMD_TBL_AR_SZ +
+ (AHCI_RX_FIS_SZ * 16),
+ AHCI_IRQ_ON_SG = (1 << 31),
+ AHCI_CMD_ATAPI = (1 << 5),
+ AHCI_CMD_WRITE = (1 << 6),
+ AHCI_CMD_PREFETCH = (1 << 7),
+ AHCI_CMD_RESET = (1 << 8),
+ AHCI_CMD_CLR_BUSY = (1 << 10),
+
+ RX_FIS_PIO_SETUP = 0x20, /* offset of PIO Setup FIS data */
+ RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */
+ RX_FIS_SDB = 0x58, /* offset of SDB FIS data */
+ RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */
+
+ /* global controller registers */
+ HOST_CAP = 0x00, /* host capabilities */
+ HOST_CTL = 0x04, /* global host control */
+ HOST_IRQ_STAT = 0x08, /* interrupt status */
+ HOST_PORTS_IMPL = 0x0c, /* bitmap of implemented ports */
+ HOST_VERSION = 0x10, /* AHCI spec. version compliancy */
+ HOST_EM_LOC = 0x1c, /* Enclosure Management location */
+ HOST_EM_CTL = 0x20, /* Enclosure Management Control */
+ HOST_CAP2 = 0x24, /* host capabilities, extended */
+
+ /* HOST_CTL bits */
+ HOST_RESET = (1 << 0), /* reset controller; self-clear */
+ HOST_IRQ_EN = (1 << 1), /* global IRQ enable */
+ HOST_AHCI_EN = (1 << 31), /* AHCI enabled */
+
+ /* HOST_CAP bits */
+ HOST_CAP_SXS = (1 << 5), /* Supports External SATA */
+ HOST_CAP_EMS = (1 << 6), /* Enclosure Management support */
+ HOST_CAP_CCC = (1 << 7), /* Command Completion Coalescing */
+ HOST_CAP_PART = (1 << 13), /* Partial state capable */
+ HOST_CAP_SSC = (1 << 14), /* Slumber state capable */
+ HOST_CAP_PIO_MULTI = (1 << 15), /* PIO multiple DRQ support */
+ HOST_CAP_FBS = (1 << 16), /* FIS-based switching support */
+ HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */
+ HOST_CAP_ONLY = (1 << 18), /* Supports AHCI mode only */
+ HOST_CAP_CLO = (1 << 24), /* Command List Override support */
+ HOST_CAP_LED = (1 << 25), /* Supports activity LED */
+ HOST_CAP_ALPM = (1 << 26), /* Aggressive Link PM support */
+ HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
+ HOST_CAP_MPS = (1 << 28), /* Mechanical presence switch */
+ HOST_CAP_SNTF = (1 << 29), /* SNotification register */
+ HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */
+ HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */
+
+ /* HOST_CAP2 bits */
+ HOST_CAP2_BOH = (1 << 0), /* BIOS/OS handoff supported */
+ HOST_CAP2_NVMHCI = (1 << 1), /* NVMHCI supported */
+ HOST_CAP2_APST = (1 << 2), /* Automatic partial to slumber */
+ HOST_CAP2_SDS = (1 << 3), /* Support device sleep */
+ HOST_CAP2_SADM = (1 << 4), /* Support aggressive DevSlp */
+ HOST_CAP2_DESO = (1 << 5), /* DevSlp from slumber only */
+
+ /* registers for each SATA port */
+ PORT_LST_ADDR = 0x00, /* command list DMA addr */
+ PORT_LST_ADDR_HI = 0x04, /* command list DMA addr hi */
+ PORT_FIS_ADDR = 0x08, /* FIS rx buf addr */
+ PORT_FIS_ADDR_HI = 0x0c, /* FIS rx buf addr hi */
+ PORT_IRQ_STAT = 0x10, /* interrupt status */
+ PORT_IRQ_MASK = 0x14, /* interrupt enable/disable mask */
+ PORT_CMD = 0x18, /* port command */
+ PORT_TFDATA = 0x20, /* taskfile data */
+ PORT_SIG = 0x24, /* device TF signature */
+ PORT_CMD_ISSUE = 0x38, /* command issue */
+ PORT_SCR_STAT = 0x28, /* SATA phy register: SStatus */
+ PORT_SCR_CTL = 0x2c, /* SATA phy register: SControl */
+ PORT_SCR_ERR = 0x30, /* SATA phy register: SError */
+ PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */
+ PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */
+ PORT_FBS = 0x40, /* FIS-based Switching */
+ PORT_DEVSLP = 0x44, /* device sleep */
+
+ /* PORT_IRQ_{STAT,MASK} bits */
+ PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */
+ PORT_IRQ_TF_ERR = (1 << 30), /* task file error */
+ PORT_IRQ_HBUS_ERR = (1 << 29), /* host bus fatal error */
+ PORT_IRQ_HBUS_DATA_ERR = (1 << 28), /* host bus data error */
+ PORT_IRQ_IF_ERR = (1 << 27), /* interface fatal error */
+ PORT_IRQ_IF_NONFATAL = (1 << 26), /* interface non-fatal error */
+ PORT_IRQ_OVERFLOW = (1 << 24), /* xfer exhausted available S/G */
+ PORT_IRQ_BAD_PMP = (1 << 23), /* incorrect port multiplier */
+
+ PORT_IRQ_PHYRDY = (1 << 22), /* PhyRdy changed */
+ PORT_IRQ_DEV_ILCK = (1 << 7), /* device interlock */
+ PORT_IRQ_CONNECT = (1 << 6), /* port connect change status */
+ PORT_IRQ_SG_DONE = (1 << 5), /* descriptor processed */
+ PORT_IRQ_UNK_FIS = (1 << 4), /* unknown FIS rx'd */
+ PORT_IRQ_SDB_FIS = (1 << 3), /* Set Device Bits FIS rx'd */
+ PORT_IRQ_DMAS_FIS = (1 << 2), /* DMA Setup FIS rx'd */
+ PORT_IRQ_PIOS_FIS = (1 << 1), /* PIO Setup FIS rx'd */
+ PORT_IRQ_D2H_REG_FIS = (1 << 0), /* D2H Register FIS rx'd */
+
+ PORT_IRQ_FREEZE = PORT_IRQ_HBUS_ERR |
+ PORT_IRQ_IF_ERR |
+ PORT_IRQ_CONNECT |
+ PORT_IRQ_PHYRDY |
+ PORT_IRQ_UNK_FIS |
+ PORT_IRQ_BAD_PMP,
+ PORT_IRQ_ERROR = PORT_IRQ_FREEZE |
+ PORT_IRQ_TF_ERR |
+ PORT_IRQ_HBUS_DATA_ERR,
+ DEF_PORT_IRQ = PORT_IRQ_ERROR | PORT_IRQ_SG_DONE |
+ PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS |
+ PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS,
+
+ /* PORT_CMD bits */
+ PORT_CMD_ASP = (1 << 27), /* Aggressive Slumber/Partial */
+ PORT_CMD_ALPE = (1 << 26), /* Aggressive Link PM enable */
+ PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */
+ PORT_CMD_FBSCP = (1 << 22), /* FBS Capable Port */
+ PORT_CMD_PMP = (1 << 17), /* PMP attached */
+ PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */
+ PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */
+ PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */
+ PORT_CMD_CLO = (1 << 3), /* Command list override */
+ PORT_CMD_POWER_ON = (1 << 2), /* Power up device */
+ PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */
+ PORT_CMD_START = (1 << 0), /* Enable port DMA engine */
+
+ PORT_CMD_ICC_MASK = (0xf << 28), /* i/f ICC state mask */
+ PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */
+ PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
+ PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */
+
+ /* PORT_FBS bits */
+ PORT_FBS_DWE_OFFSET = 16, /* FBS device with error offset */
+ PORT_FBS_ADO_OFFSET = 12, /* FBS active dev optimization offset */
+ PORT_FBS_DEV_OFFSET = 8, /* FBS device to issue offset */
+ PORT_FBS_DEV_MASK = (0xf << PORT_FBS_DEV_OFFSET), /* FBS.DEV */
+ PORT_FBS_SDE = (1 << 2), /* FBS single device error */
+ PORT_FBS_DEC = (1 << 1), /* FBS device error clear */
+ PORT_FBS_EN = (1 << 0), /* Enable FBS */
+
+ /* PORT_DEVSLP bits */
+ PORT_DEVSLP_DM_OFFSET = 25, /* DITO multiplier offset */
+ PORT_DEVSLP_DM_MASK = (0xf << 25), /* DITO multiplier mask */
+ PORT_DEVSLP_DITO_OFFSET = 15, /* DITO offset */
+ PORT_DEVSLP_MDAT_OFFSET = 10, /* Minimum assertion time */
+ PORT_DEVSLP_DETO_OFFSET = 2, /* DevSlp exit timeout */
+ PORT_DEVSLP_DSP = (1 << 1), /* DevSlp present */
+ PORT_DEVSLP_ADSE = (1 << 0), /* Aggressive DevSlp enable */
+
+ /* hpriv->flags bits */
+
+#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)
+
+ AHCI_HFLAG_NO_NCQ = (1 << 0),
+ AHCI_HFLAG_IGN_IRQ_IF_ERR = (1 << 1), /* ignore IRQ_IF_ERR */
+ AHCI_HFLAG_IGN_SERR_INTERNAL = (1 << 2), /* ignore SERR_INTERNAL */
+ AHCI_HFLAG_32BIT_ONLY = (1 << 3), /* force 32bit */
+ AHCI_HFLAG_MV_PATA = (1 << 4), /* PATA port */
+ AHCI_HFLAG_NO_MSI = (1 << 5), /* no PCI MSI */
+ AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */
+ AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */
+ AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */
+ AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */
+ AHCI_HFLAG_SRST_TOUT_IS_OFFLINE = (1 << 11), /* treat SRST timeout as
+ link offline */
+ AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */
+ AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */
+ AHCI_HFLAG_YES_FBS = (1 << 14), /* force FBS cap on */
+ AHCI_HFLAG_DELAY_ENGINE = (1 << 15), /* do not start engine on
+ port start (wait until
+ error-handling stage) */
+ AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */
+
+ /* ap->flags bits */
+
+ /*
+ AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA |
+ ATA_FLAG_ACPI_SATA | ATA_FLAG_AN,
+ */
+
+ ICH_MAP = 0x90, /* ICH MAP register */
+
+ /* em constants */
+ EM_MAX_SLOTS = 8,
+ EM_MAX_RETRY = 5,
+
+ /* em_ctl bits */
+ EM_CTL_RST = (1 << 9), /* Reset */
+ EM_CTL_TM = (1 << 8), /* Transmit Message */
+ EM_CTL_MR = (1 << 0), /* Message Received */
+ EM_CTL_ALHD = (1 << 26), /* Activity LED */
+ EM_CTL_XMT = (1 << 25), /* Transmit Only */
+ EM_CTL_SMB = (1 << 24), /* Single Message Buffer */
+ EM_CTL_SGPIO = (1 << 19), /* SGPIO messages supported */
+ EM_CTL_SES = (1 << 18), /* SES-2 messages supported */
+ EM_CTL_SAFTE = (1 << 17), /* SAF-TE messages supported */
+ EM_CTL_LED = (1 << 16), /* LED messages supported */
+
+ /* em message type */
+ EM_MSG_TYPE_LED = (1 << 0), /* LED */
+ EM_MSG_TYPE_SAFTE = (1 << 1), /* SAF-TE */
+ EM_MSG_TYPE_SES2 = (1 << 2), /* SES-2 */
+ EM_MSG_TYPE_SGPIO = (1 << 3), /* SGPIO */
+
+ FIS_TYPE_REG_H2D = 0x27,
+ FIS_TYPE_REG_D2H = 0x34,
+ FIS_TYPE_DMA_ACT = 0x39,
+ FIS_TYPE_DMA_SETUP = 0x41,
+ FIS_TYPE_DATA = 0x46,
+ FIS_TYPE_BIST = 0x58,
+ FIS_TYPE_PIO_SETUP = 0x5F,
+ FIS_TYPE_DEV_BITS = 0xA1,
+};
+
+/* End from linux 3.9 */
+
+#endif /* _GNUMACH_AHCI_H */
diff --git a/linux/dev/include/asm-i386/string.h b/linux/dev/include/asm-i386/string.h
index bdb75455..f41ca5c0 100644
--- a/linux/dev/include/asm-i386/string.h
+++ b/linux/dev/include/asm-i386/string.h
@@ -28,7 +28,7 @@
*/
#define __HAVE_ARCH_STRCPY
-extern inline char * strcpy(char * dest,const char *src)
+static inline char * strcpy(char * dest,const char *src)
{
int d0, d1, d2;
__asm__ __volatile__(
@@ -43,7 +43,7 @@ return dest;
}
#define __HAVE_ARCH_STRNCPY
-extern inline char * strncpy(char * dest,const char *src,size_t count)
+static inline char * strncpy(char * dest,const char *src,size_t count)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
@@ -63,7 +63,7 @@ return dest;
}
#define __HAVE_ARCH_STRCAT
-extern inline char * strcat(char * dest,const char * src)
+static inline char * strcat(char * dest,const char * src)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
@@ -81,7 +81,7 @@ return dest;
}
#define __HAVE_ARCH_STRNCAT
-extern inline char * strncat(char * dest,const char * src,size_t count)
+static inline char * strncat(char * dest,const char * src,size_t count)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
@@ -105,7 +105,7 @@ return dest;
}
#define __HAVE_ARCH_STRCMP
-extern inline int strcmp(const char * cs,const char * ct)
+static inline int strcmp(const char * cs,const char * ct)
{
int d0, d1;
register int __res;
@@ -127,7 +127,7 @@ return __res;
}
#define __HAVE_ARCH_STRNCMP
-extern inline int strncmp(const char * cs,const char * ct,size_t count)
+static inline int strncmp(const char * cs,const char * ct,size_t count)
{
register int __res;
int d0, d1, d2;
@@ -151,7 +151,7 @@ return __res;
}
#define __HAVE_ARCH_STRCHR
-extern inline char * strchr(const char * s, int c)
+static inline char * strchr(const char * s, int c)
{
int d0;
register char * __res;
@@ -171,7 +171,7 @@ return __res;
}
#define __HAVE_ARCH_STRRCHR
-extern inline char * strrchr(const char * s, int c)
+static inline char * strrchr(const char * s, int c)
{
int d0, d1;
register char * __res;
@@ -189,7 +189,7 @@ return __res;
}
#define __HAVE_ARCH_STRLEN
-extern inline size_t strlen(const char * s)
+static inline size_t strlen(const char * s)
{
int d0;
register int __res;
@@ -203,7 +203,7 @@ __asm__ __volatile__(
return __res;
}
-extern inline void * __memcpy(void * to, const void * from, size_t n)
+static inline void * __memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
__asm__ __volatile__(
@@ -226,7 +226,7 @@ return (to);
* This looks horribly ugly, but the compiler can optimize it totally,
* as the count is constant.
*/
-extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
+static inline void * __constant_memcpy(void * to, const void * from, size_t n)
{
switch (n) {
case 0:
@@ -299,7 +299,7 @@ __asm__ __volatile__( \
__memcpy((t),(f),(n)))
#define __HAVE_ARCH_MEMMOVE
-extern inline void * memmove(void * dest,const void * src, size_t n)
+static inline void * memmove(void * dest,const void * src, size_t n)
{
int d0, d1, d2;
if (dest<src)
@@ -327,7 +327,7 @@ return dest;
#define memcmp __builtin_memcmp
#define __HAVE_ARCH_MEMCHR
-extern inline void * memchr(const void * cs,int c,size_t count)
+static inline void * memchr(const void * cs,int c,size_t count)
{
int d0;
register void * __res;
@@ -344,7 +344,7 @@ __asm__ __volatile__(
return __res;
}
-extern inline void * __memset_generic(void * s, char c,size_t count)
+static inline void * __memset_generic(void * s, char c,size_t count)
{
int d0, d1;
__asm__ __volatile__(
@@ -365,7 +365,7 @@ return s;
* things 32 bits at a time even when we don't know the size of the
* area at compile-time..
*/
-extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
+static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
{
int d0, d1;
__asm__ __volatile__(
@@ -386,7 +386,7 @@ return (s);
/* Added by Gertjan van Wingerde to make minix and sysv module work */
#define __HAVE_ARCH_STRNLEN
-extern inline size_t strnlen(const char * s, size_t count)
+static inline size_t strnlen(const char * s, size_t count)
{
int d0;
register int __res;
@@ -410,7 +410,7 @@ return __res;
* This looks horribly ugly, but the compiler can optimize it totally,
* as we by now know that both pattern and count is constant..
*/
-extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
+static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
{
switch (count) {
case 0:
@@ -469,7 +469,7 @@ __asm__ __volatile__("cld\n\t" \
* find the first occurrence of byte 'c', or 1 past the area if none
*/
#define __HAVE_ARCH_MEMSCAN
-extern inline void * memscan(void * addr, int c, size_t size)
+static inline void * memscan(void * addr, int c, size_t size)
{
if (!size)
return addr;
diff --git a/linux/dev/include/linux/blk.h b/linux/dev/include/linux/blk.h
index 412b8641..156d91c4 100644
--- a/linux/dev/include/linux/blk.h
+++ b/linux/dev/include/linux/blk.h
@@ -391,8 +391,9 @@ static void end_request(int uptodate) {
req->errors = 0;
if (!uptodate) {
- printk("end_request: I/O error, dev %s, sector %lu\n",
- kdevname(req->rq_dev), req->sector);
+ if (!req->quiet)
+ printk("end_request: I/O error, dev %s, sector %lu\n",
+ kdevname(req->rq_dev), req->sector);
#ifdef MACH
for (bh = req->bh; bh; )
{
diff --git a/linux/dev/include/linux/blkdev.h b/linux/dev/include/linux/blkdev.h
index e9a40d7e..5bf0a288 100644
--- a/linux/dev/include/linux/blkdev.h
+++ b/linux/dev/include/linux/blkdev.h
@@ -23,6 +23,7 @@ struct request {
kdev_t rq_dev;
int cmd; /* READ or WRITE */
int errors;
+ int quiet;
unsigned long sector;
unsigned long nr_sectors;
unsigned long current_nr_sectors;
diff --git a/linux/dev/include/linux/fs.h b/linux/dev/include/linux/fs.h
index 740ebb54..a2f9383e 100644
--- a/linux/dev/include/linux/fs.h
+++ b/linux/dev/include/linux/fs.h
@@ -638,7 +638,7 @@ extern int nr_buffer_heads;
#define NR_LIST 4
#ifdef MACH
-extern inline void
+static inline void
mark_buffer_uptodate (struct buffer_head *bh, int on)
{
if (on)
@@ -733,7 +733,7 @@ extern struct file * get_empty_filp(void);
extern int close_fp(struct file *filp);
extern struct buffer_head * get_hash_table(kdev_t dev, int block, int size);
extern struct buffer_head * getblk(kdev_t dev, int block, int size);
-extern void ll_rw_block(int rw, int nr, struct buffer_head * bh[]);
+extern void ll_rw_block(int rw, int nr, struct buffer_head * bh[], int quiet);
extern void ll_rw_page(int rw, kdev_t dev, unsigned long nr, char * buffer);
extern void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buffer);
extern int is_read_only(kdev_t dev);
diff --git a/linux/dev/include/linux/mm.h b/linux/dev/include/linux/mm.h
index 0500e0cf..cd061378 100644
--- a/linux/dev/include/linux/mm.h
+++ b/linux/dev/include/linux/mm.h
@@ -281,6 +281,7 @@ extern void * vmalloc(unsigned long size);
extern void * vremap(unsigned long offset, unsigned long size);
extern void vfree(void * addr);
extern int vread(char *buf, char *addr, int count);
+extern unsigned long vmtophys (void *);
/* mmap.c */
extern unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
diff --git a/linux/dev/include/linux/types.h b/linux/dev/include/linux/types.h
index 57bb25f4..b697d9ec 100644
--- a/linux/dev/include/linux/types.h
+++ b/linux/dev/include/linux/types.h
@@ -109,6 +109,15 @@ struct ustat {
char f_fpack[6];
};
+/* stdint.h */
+typedef s8 int8_t;
+typedef u8 uint8_t;
+typedef s16 int16_t;
+typedef u16 uint16_t;
+typedef s32 int32_t;
+typedef u32 uint32_t;
+typedef s64 int64_t;
+typedef u64 uint64_t;
/* Yes, this is ugly. But that's why it is called glue code. */
diff --git a/linux/pcmcia-cs/clients/axnet_cs.c b/linux/pcmcia-cs/clients/axnet_cs.c
index bcd79b0e..2e7d9edc 100644
--- a/linux/pcmcia-cs/clients/axnet_cs.c
+++ b/linux/pcmcia-cs/clients/axnet_cs.c
@@ -1814,7 +1814,7 @@ static void set_multicast_list(struct net_device *dev)
static int axdev_init(struct net_device *dev)
{
if (ei_debug > 1)
- printk(version_8390);
+ printk("%s", version_8390);
if (dev->priv == NULL)
{
diff --git a/linux/src/drivers/block/ide-cd.c b/linux/src/drivers/block/ide-cd.c
index e4548f54..020a8313 100644
--- a/linux/src/drivers/block/ide-cd.c
+++ b/linux/src/drivers/block/ide-cd.c
@@ -649,7 +649,7 @@ static void cdrom_end_request (int uptodate, ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
- if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate) {
+ if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate && !rq->quiet) {
struct packet_command *pc = (struct packet_command *)
rq->buffer;
cdrom_analyze_sense_data (drive,
@@ -727,16 +727,18 @@ static int cdrom_decode_status (ide_drive_t *drive, int good_stat,
because workman constantly polls the drive
with this command, and we don't want
to uselessly fill up the syslog. */
- if (pc->c[0] != SCMD_READ_SUBCHANNEL)
+ if (pc->c[0] != SCMD_READ_SUBCHANNEL && !rq->quiet)
printk ("%s : tray open or drive not ready\n",
drive->name);
} else if (sense_key == UNIT_ATTENTION) {
/* Check for media change. */
cdrom_saw_media_change (drive);
- printk ("%s: media changed\n", drive->name);
+ if (!rq->quiet)
+ printk ("%s: media changed\n", drive->name);
} else {
/* Otherwise, print an error. */
- ide_dump_status (drive, "packet command error",
+ if (!rq->quiet)
+ ide_dump_status (drive, "packet command error",
stat);
}
@@ -768,7 +770,8 @@ static int cdrom_decode_status (ide_drive_t *drive, int good_stat,
cdrom_saw_media_change (drive);
/* Fail the request. */
- printk ("%s : tray open\n", drive->name);
+ if (!rq->quiet)
+ printk ("%s : tray open\n", drive->name);
cdrom_end_request (0, drive);
} else if (sense_key == UNIT_ATTENTION) {
/* Media change. */
@@ -783,7 +786,8 @@ static int cdrom_decode_status (ide_drive_t *drive, int good_stat,
sense_key == DATA_PROTECT) {
/* No point in retrying after an illegal
request or data protect error.*/
- ide_dump_status (drive, "command error", stat);
+ if (!rq->quiet)
+ ide_dump_status (drive, "command error", stat);
cdrom_end_request (0, drive);
} else if ((err & ~ABRT_ERR) != 0) {
/* Go to the default handler
@@ -1406,7 +1410,7 @@ void cdrom_sleep (int time)
#endif
static
-int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
+int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc, int quiet)
{
struct atapi_request_sense my_reqbuf;
int retries = 10;
@@ -1423,6 +1427,7 @@ int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
ide_init_drive_cmd (&req);
req.cmd = PACKET_COMMAND;
req.buffer = (char *)pc;
+ req.quiet = quiet;
(void) ide_do_drive_cmd (drive, &req, ide_wait);
if (pc->stat != 0) {
@@ -1563,7 +1568,7 @@ cdrom_check_status (ide_drive_t *drive,
pc.c[7] = CDROM_STATE_FLAGS (drive)->sanyo_slot % 3;
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 1);
}
@@ -1588,7 +1593,7 @@ cdrom_lockdoor (ide_drive_t *drive, int lockflag,
pc.c[0] = ALLOW_MEDIUM_REMOVAL;
pc.c[4] = (lockflag != 0);
- stat = cdrom_queue_packet_command (drive, &pc);
+ stat = cdrom_queue_packet_command (drive, &pc, 0);
}
if (stat == 0)
@@ -1622,7 +1627,7 @@ cdrom_eject (ide_drive_t *drive, int ejectflag,
pc.c[0] = START_STOP;
pc.c[4] = 2 + (ejectflag != 0);
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1637,7 +1642,7 @@ cdrom_pause (ide_drive_t *drive, int pauseflag,
pc.c[0] = SCMD_PAUSE_RESUME;
pc.c[8] = !pauseflag;
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1653,7 +1658,7 @@ cdrom_startstop (ide_drive_t *drive, int startflag,
pc.c[0] = START_STOP;
pc.c[1] = 1;
pc.c[4] = startflag;
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1676,7 +1681,7 @@ cdrom_read_capacity (ide_drive_t *drive, unsigned *capacity,
pc.buffer = (unsigned char *)&capbuf;
pc.buflen = sizeof (capbuf);
- stat = cdrom_queue_packet_command (drive, &pc);
+ stat = cdrom_queue_packet_command (drive, &pc, 1);
if (stat == 0)
*capacity = ntohl (capbuf.lba);
@@ -1702,7 +1707,7 @@ cdrom_read_tocentry (ide_drive_t *drive, int trackno, int msf_flag,
pc.c[8] = (buflen & 0xff);
pc.c[9] = (format << 6);
if (msf_flag) pc.c[1] = 2;
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 1);
}
@@ -1834,7 +1839,7 @@ cdrom_read_subchannel (ide_drive_t *drive, int format,
pc.c[3] = format,
pc.c[7] = (buflen >> 8);
pc.c[8] = (buflen & 0xff);
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1855,7 +1860,7 @@ cdrom_mode_sense (ide_drive_t *drive, int pageno, int modeflag,
pc.c[2] = pageno | (modeflag << 6);
pc.c[7] = (buflen >> 8);
pc.c[8] = (buflen & 0xff);
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1875,7 +1880,7 @@ cdrom_mode_select (ide_drive_t *drive, int pageno, char *buf, int buflen,
pc.c[2] = pageno;
pc.c[7] = (buflen >> 8);
pc.c[8] = (buflen & 0xff);
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1903,7 +1908,7 @@ cdrom_play_lba_range_1 (ide_drive_t *drive, int lba_start, int lba_end,
}
#endif /* not STANDARD_ATAPI */
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -2004,7 +2009,7 @@ cdrom_read_block (ide_drive_t *drive, int format, int lba, int nblocks,
else
pc.c[9] = 0x10;
- stat = cdrom_queue_packet_command (drive, &pc);
+ stat = cdrom_queue_packet_command (drive, &pc, 0);
#if ! STANDARD_ATAPI
/* If the drive doesn't recognize the READ CD opcode, retry the command
@@ -2059,7 +2064,7 @@ cdrom_load_unload (ide_drive_t *drive, int slot,
pc.c[0] = LOAD_UNLOAD;
pc.c[4] = 2 + (slot >= 0);
pc.c[8] = slot;
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
}
@@ -2575,7 +2580,7 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
pc.buffer = buf;
}
- stat = cdrom_queue_packet_command (drive, &pc);
+ stat = cdrom_queue_packet_command (drive, &pc, 0);
if (len > 0)
memcpy_tofs ((void *)arg, buf, len);
@@ -2638,6 +2643,10 @@ int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive)
if (stat == 0 || my_reqbuf.sense_key == UNIT_ATTENTION) {
(void) cdrom_lockdoor (drive, 1, &my_reqbuf);
(void) cdrom_read_toc (drive, &my_reqbuf);
+ } else {
+ /* Otherwise return as missing */
+ --drive->usage;
+ return -ENXIO;
}
}
diff --git a/linux/src/drivers/block/ide.c b/linux/src/drivers/block/ide.c
index 7ab790d4..41a26017 100644
--- a/linux/src/drivers/block/ide.c
+++ b/linux/src/drivers/block/ide.c
@@ -302,6 +302,8 @@
#include <linux/genhd.h>
#include <linux/malloc.h>
+#include <ahci.h>
+
#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/segment.h>
@@ -1925,6 +1927,7 @@ void ide_init_drive_cmd (struct request *rq)
rq->rq_status = RQ_ACTIVE;
rq->rq_dev = ????;
#endif
+ rq->quiet = 0;
}
/*
@@ -2523,7 +2526,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
drive->media = ide_tape;
drive->present = 1;
drive->removable = 1;
- if (drive->autotune != 2 && HWIF(drive)->dmaproc != NULL) {
+ if (drive->autotune != 2 && HWIF(drive)->dmaproc != NULL && !drive->nodma) {
if (!HWIF(drive)->dmaproc(ide_dma_check, drive))
printk(", DMA");
}
@@ -2650,7 +2653,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect))
drive->special.b.set_multmode = 1;
}
- if (drive->autotune != 2 && HWIF(drive)->dmaproc != NULL) {
+ if (drive->autotune != 2 && HWIF(drive)->dmaproc != NULL && !drive->nodma) {
if (!(HWIF(drive)->dmaproc(ide_dma_check, drive))) {
if ((id->field_valid & 4) && (id->dma_ultra & (id->dma_ultra >> 8) & 7))
printk(", UDMA");
@@ -3105,6 +3108,7 @@ static int match_parm (char *s, const char *keywords[], int vals[], int max_vals
* Not fully supported by all chipset types,
* and quite likely to cause trouble with
* older/odd IDE drives.
+ * "hdx=nodma" : disallow DMA for the drive
*
* "idebus=xx" : inform IDE driver of VESA/PCI bus speed in Mhz,
* where "xx" is between 20 and 66 inclusive,
@@ -3149,7 +3153,11 @@ void ide_setup (char *s)
ide_hwif_t *hwif;
ide_drive_t *drive;
unsigned int hw, unit;
+#ifdef MACH
+ const char max_drive = '0' + ((MAX_HWIFS * MAX_DRIVES) - 1);
+#else
const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
+#endif
const char max_hwif = '0' + (MAX_HWIFS - 1);
printk("ide_setup: %s", s);
@@ -3158,11 +3166,19 @@ void ide_setup (char *s)
/*
* Look for drive options: "hdx="
*/
+#ifdef MACH
+ if (s[0] == 'h' && s[1] == 'd' && s[2] >= '0' && s[2] <= max_drive) {
+#else
if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
+#endif
const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom",
"serialize", "autotune", "noautotune",
- "slow", "ide-scsi", NULL};
+ "slow", "ide-scsi", "nodma", NULL};
+#ifdef MACH
+ unit = s[2] - '0';
+#else
unit = s[2] - 'a';
+#endif
hw = unit / MAX_DRIVES;
unit = unit % MAX_DRIVES;
hwif = &ide_hwifs[hw];
@@ -3197,6 +3213,9 @@ void ide_setup (char *s)
case -9: /* "ide-scsi" */
drive->ide_scsi = 1;
goto done;
+ case -10: /* "nodma" */
+ drive->nodma = 1;
+ goto done;
case 3: /* cyl,head,sect */
drive->media = ide_disk;
drive->cyl = drive->bios_cyl = vals[0];
@@ -3682,6 +3701,7 @@ static void probe_for_hwifs (void)
#ifdef CONFIG_BLK_DEV_PROMISE
init_dc4030();
#endif
+ ahci_probe_pci();
}
static int hwif_init (int h)
diff --git a/linux/src/drivers/block/ide.h b/linux/src/drivers/block/ide.h
index edeedc97..28e371bf 100644
--- a/linux/src/drivers/block/ide.h
+++ b/linux/src/drivers/block/ide.h
@@ -344,6 +344,7 @@ typedef struct ide_drive_s {
unsigned nobios : 1; /* flag: do not probe bios for drive */
unsigned slow : 1; /* flag: slow data port */
unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */
+ unsigned nodma : 1; /* disk should not use dma for read/write */
#if FAKE_FDISK_FOR_EZDRIVE
unsigned remap_0_to_1 : 1; /* flag: partitioned with ezdrive */
#endif /* FAKE_FDISK_FOR_EZDRIVE */
diff --git a/linux/src/drivers/net/3c507.c b/linux/src/drivers/net/3c507.c
index 63f85a4c..58ba2d75 100644
--- a/linux/src/drivers/net/3c507.c
+++ b/linux/src/drivers/net/3c507.c
@@ -354,7 +354,7 @@ int el16_probe1(struct device *dev, int ioaddr)
dev = init_etherdev(0, sizeof(struct net_local));
if (net_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("%s: 3c507 at %#x,", dev->name, ioaddr);
@@ -410,7 +410,7 @@ int el16_probe1(struct device *dev, int ioaddr)
dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
if (net_debug)
- printk(version);
+ printk("%s", version);
/* Initialize the device structure. */
dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
diff --git a/linux/src/drivers/net/3c509.c b/linux/src/drivers/net/3c509.c
index f8842882..727595cd 100644
--- a/linux/src/drivers/net/3c509.c
+++ b/linux/src/drivers/net/3c509.c
@@ -314,7 +314,7 @@ int el3_probe(struct device *dev)
el3_root_dev = dev;
if (el3_debug > 0)
- printk(version);
+ printk("%s", version);
/* The EL3-specific entries in the device structure. */
dev->open = &el3_open;
diff --git a/linux/src/drivers/net/3c515.c b/linux/src/drivers/net/3c515.c
index fd6ec50c..52f47032 100644
--- a/linux/src/drivers/net/3c515.c
+++ b/linux/src/drivers/net/3c515.c
@@ -404,7 +404,7 @@ init_module(void)
if (debug >= 0)
vortex_debug = debug;
if (vortex_debug)
- printk(version);
+ printk("%s", version);
root_vortex_dev = NULL;
cards_found = vortex_scan(0);
@@ -419,7 +419,7 @@ int tc515_probe(struct device *dev)
cards_found = vortex_scan(dev);
if (vortex_debug > 0 && cards_found)
- printk(version);
+ printk("%s", version);
return cards_found ? 0 : -ENODEV;
}
diff --git a/linux/src/drivers/net/ac3200.c b/linux/src/drivers/net/ac3200.c
index 0337bab7..600949fa 100644
--- a/linux/src/drivers/net/ac3200.c
+++ b/linux/src/drivers/net/ac3200.c
@@ -208,7 +208,7 @@ static int ac_probe1(int ioaddr, struct device *dev)
dev->mem_start, dev->mem_end-1);
if (ei_debug > 0)
- printk(version);
+ printk("%s", version);
ei_status.reset_8390 = &ac_reset_8390;
ei_status.block_input = &ac_block_input;
diff --git a/linux/src/drivers/net/apricot.c b/linux/src/drivers/net/apricot.c
index d106e50d..57fccafb 100644
--- a/linux/src/drivers/net/apricot.c
+++ b/linux/src/drivers/net/apricot.c
@@ -720,7 +720,7 @@ int apricot_probe(struct device *dev)
dev->irq = 10;
printk(" IRQ %d.\n", dev->irq);
- if (i596_debug > 0) printk(version);
+ if (i596_debug > 0) printk("%s", version);
/* The APRICOT-specific entries in the device structure. */
dev->open = &i596_open;
diff --git a/linux/src/drivers/net/at1700.c b/linux/src/drivers/net/at1700.c
index 9e42ab48..f4025f46 100644
--- a/linux/src/drivers/net/at1700.c
+++ b/linux/src/drivers/net/at1700.c
@@ -258,7 +258,7 @@ int at1700_probe1(struct device *dev, int ioaddr)
outb(0x00, ioaddr + CONFIG_1);
if (net_debug)
- printk(version);
+ printk("%s", version);
/* Initialize the device structure. */
dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
diff --git a/linux/src/drivers/net/de4x5.c b/linux/src/drivers/net/de4x5.c
index a66f0564..c85bcdbf 100644
--- a/linux/src/drivers/net/de4x5.c
+++ b/linux/src/drivers/net/de4x5.c
@@ -1308,7 +1308,7 @@ de4x5_hw_init(struct device *dev, u_long iobase))
}
if (de4x5_debug & DEBUG_VERSION) {
- printk(version);
+ printk("%s", version);
}
/* The DE4X5-specific entries in the device structure. */
diff --git a/linux/src/drivers/net/de600.c b/linux/src/drivers/net/de600.c
index 2488cd76..ce969422 100644
--- a/linux/src/drivers/net/de600.c
+++ b/linux/src/drivers/net/de600.c
@@ -644,7 +644,7 @@ de600_probe(struct device *dev)
printk("%s: D-Link DE-600 pocket adapter", dev->name);
/* Alpha testers must have the version number to report bugs. */
if (de600_debug > 1)
- printk(version);
+ printk("%s", version);
/* probe for adapter */
rx_page = 0;
diff --git a/linux/src/drivers/net/de620.c b/linux/src/drivers/net/de620.c
index ec639101..0e0c5522 100644
--- a/linux/src/drivers/net/de620.c
+++ b/linux/src/drivers/net/de620.c
@@ -843,7 +843,7 @@ de620_probe(struct device *dev)
dev->irq = irq;
if (de620_debug)
- printk(version);
+ printk("%s", version);
printk("D-Link DE-620 pocket adapter");
diff --git a/linux/src/drivers/net/depca.c b/linux/src/drivers/net/depca.c
index e1b03429..2048812d 100644
--- a/linux/src/drivers/net/depca.c
+++ b/linux/src/drivers/net/depca.c
@@ -649,7 +649,7 @@ depca_hw_init(struct device *dev, u_long ioaddr)
}
if (!status) {
if (depca_debug > 1) {
- printk(version);
+ printk("%s", version);
}
/* The DEPCA-specific entries in the device structure. */
diff --git a/linux/src/drivers/net/e2100.c b/linux/src/drivers/net/e2100.c
index 7ba12d31..537295a2 100644
--- a/linux/src/drivers/net/e2100.c
+++ b/linux/src/drivers/net/e2100.c
@@ -162,7 +162,7 @@ int e21_probe1(struct device *dev, int ioaddr)
outb(0, ioaddr + E21_ASIC); /* and disable the secondary interface. */
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
/* We should have a "dev" from Space.c or the static module table. */
if (dev == NULL) {
diff --git a/linux/src/drivers/net/eepro.c b/linux/src/drivers/net/eepro.c
index 2c3a6b26..3d4fc578 100644
--- a/linux/src/drivers/net/eepro.c
+++ b/linux/src/drivers/net/eepro.c
@@ -498,7 +498,7 @@ eepro_probe1(struct device *dev, short ioaddr)
}
if (net_debug)
- printk(version);
+ printk("%s", version);
/* Grab the region so we can find another board if autoIRQ fails. */
request_region(ioaddr, EEPRO_IO_EXTENT, "eepro");
diff --git a/linux/src/drivers/net/eepro100.c b/linux/src/drivers/net/eepro100.c
index 6909cdc4..d03462cd 100644
--- a/linux/src/drivers/net/eepro100.c
+++ b/linux/src/drivers/net/eepro100.c
@@ -726,7 +726,7 @@ static void *speedo_found1(struct pci_dev *pdev, void *init_dev,
eeprom[8], eeprom[9]>>8, eeprom[9] & 0xff);
for (i = 0; i < 4; i++)
if (eeprom[5] & (1<<i))
- printk(connectors[i]);
+ printk("%s", connectors[i]);
printk("\n"KERN_INFO" Primary interface chip %s PHY #%d.\n",
phys[(eeprom[6]>>8)&15], eeprom[6] & 0x1f);
if (eeprom[7] & 0x0700)
diff --git a/linux/src/drivers/net/eexpress.c b/linux/src/drivers/net/eexpress.c
index d7065509..9c816ee9 100644
--- a/linux/src/drivers/net/eexpress.c
+++ b/linux/src/drivers/net/eexpress.c
@@ -794,7 +794,7 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
}
if (net_debug)
- printk(version);
+ printk("%s", version);
dev->open = eexp_open;
dev->stop = eexp_close;
dev->hard_start_xmit = eexp_xmit;
diff --git a/linux/src/drivers/net/ewrk3.c b/linux/src/drivers/net/ewrk3.c
index f91315ff..07b0f13f 100644
--- a/linux/src/drivers/net/ewrk3.c
+++ b/linux/src/drivers/net/ewrk3.c
@@ -589,7 +589,7 @@ ewrk3_hw_init(struct device *dev, u_long iobase)
if (!status) {
if (ewrk3_debug > 1) {
- printk(version);
+ printk("%s", version);
}
/* The EWRK3-specific entries in the device structure. */
diff --git a/linux/src/drivers/net/fmv18x.c b/linux/src/drivers/net/fmv18x.c
index 121dd0bb..b29ddf00 100644
--- a/linux/src/drivers/net/fmv18x.c
+++ b/linux/src/drivers/net/fmv18x.c
@@ -249,7 +249,7 @@ int fmv18x_probe1(struct device *dev, short ioaddr)
outb(dev->if_port, ioaddr + MODE13);
if (net_debug)
- printk(version);
+ printk("%s", version);
/* Initialize the device structure. */
dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
diff --git a/linux/src/drivers/net/hp-plus.c b/linux/src/drivers/net/hp-plus.c
index c8e36111..c2b71169 100644
--- a/linux/src/drivers/net/hp-plus.c
+++ b/linux/src/drivers/net/hp-plus.c
@@ -164,7 +164,7 @@ int hpp_probe1(struct device *dev, int ioaddr)
}
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("%s: %s at %#3x,", dev->name, name, ioaddr);
diff --git a/linux/src/drivers/net/hp.c b/linux/src/drivers/net/hp.c
index 741924f9..6ddbfd2e 100644
--- a/linux/src/drivers/net/hp.c
+++ b/linux/src/drivers/net/hp.c
@@ -136,7 +136,7 @@ int hp_probe1(struct device *dev, int ioaddr)
}
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);
diff --git a/linux/src/drivers/net/lance.c b/linux/src/drivers/net/lance.c
index f64f0fee..fe3cf687 100644
--- a/linux/src/drivers/net/lance.c
+++ b/linux/src/drivers/net/lance.c
@@ -674,7 +674,7 @@ int lance_probe1(struct device *dev, int ioaddr, int irq, int options)
}
if (lance_debug > 0 && did_version++ == 0)
- printk(version);
+ printk("%s", version);
/* The LANCE-specific entries in the device structure. */
dev->open = lance_open;
diff --git a/linux/src/drivers/net/ne.c b/linux/src/drivers/net/ne.c
index 825b768e..ea2f9290 100644
--- a/linux/src/drivers/net/ne.c
+++ b/linux/src/drivers/net/ne.c
@@ -291,7 +291,7 @@ static int ne_probe1(struct device *dev, int ioaddr)
}
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("NE*000 ethercard probe at %#3x:", ioaddr);
diff --git a/linux/src/drivers/net/pci-scan.c b/linux/src/drivers/net/pci-scan.c
index 60525b76..ffb7b128 100644
--- a/linux/src/drivers/net/pci-scan.c
+++ b/linux/src/drivers/net/pci-scan.c
@@ -31,7 +31,7 @@ static int min_pci_latency = 32;
#if ! defined(__KERNEL__)
#define __KERNEL__ 1
#endif
-#if !defined(__OPTIMIZE__)
+#if !defined(__OPTIMIZE__) && /* Mach glue, we think this is ok now: */ 0
#warning You must compile this file with the correct options!
#warning See the last lines of the source file.
#error You must compile this driver with the proper options, including "-O".
diff --git a/linux/src/drivers/net/pcnet32.c b/linux/src/drivers/net/pcnet32.c
index 02e70982..da0e8709 100644
--- a/linux/src/drivers/net/pcnet32.c
+++ b/linux/src/drivers/net/pcnet32.c
@@ -344,7 +344,7 @@ static int pcnet32_probe1(struct device *dev, unsigned int ioaddr, unsigned char
dev->irq = irq_line;
if (pcnet32_debug > 0)
- printk(version);
+ printk("%s", version);
/* The PCNET32-specific entries in the device structure. */
dev->open = &pcnet32_open;
diff --git a/linux/src/drivers/net/seeq8005.c b/linux/src/drivers/net/seeq8005.c
index c4d48521..4adebdea 100644
--- a/linux/src/drivers/net/seeq8005.c
+++ b/linux/src/drivers/net/seeq8005.c
@@ -274,7 +274,7 @@ static int seeq8005_probe1(struct device *dev, int ioaddr)
dev = init_etherdev(0, sizeof(struct net_local));
if (net_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr);
diff --git a/linux/src/drivers/net/smc-ultra.c b/linux/src/drivers/net/smc-ultra.c
index 074a235b..f593aeb6 100644
--- a/linux/src/drivers/net/smc-ultra.c
+++ b/linux/src/drivers/net/smc-ultra.c
@@ -156,7 +156,7 @@ int ultra_probe1(struct device *dev, int ioaddr)
dev = init_etherdev(0, 0);
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
model_name = (idreg & 0xF0) == 0x20 ? "SMC Ultra" : "SMC EtherEZ";
diff --git a/linux/src/drivers/net/smc-ultra32.c b/linux/src/drivers/net/smc-ultra32.c
index f616e259..6cde4c27 100644
--- a/linux/src/drivers/net/smc-ultra32.c
+++ b/linux/src/drivers/net/smc-ultra32.c
@@ -153,7 +153,7 @@ int ultra32_probe1(struct device *dev, int ioaddr)
}
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
model_name = "SMC Ultra32";
diff --git a/linux/src/drivers/net/sundance.c b/linux/src/drivers/net/sundance.c
index 47f32ebd..37231644 100644
--- a/linux/src/drivers/net/sundance.c
+++ b/linux/src/drivers/net/sundance.c
@@ -986,7 +986,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
if (np->msg_level & NETIF_MSG_TX_QUEUED) {
- printk(KERN_DEBUG "%s: Transmit frame #%d len %ld queued in slot %ld.\n",
+ printk(KERN_DEBUG "%s: Transmit frame #%d len %ld queued in slot %u.\n",
dev->name, np->cur_tx, skb->len, entry);
}
return 0;
diff --git a/linux/src/drivers/net/tlan.c b/linux/src/drivers/net/tlan.c
index 11e12bbc..fedc11f3 100644
--- a/linux/src/drivers/net/tlan.c
+++ b/linux/src/drivers/net/tlan.c
@@ -1132,7 +1132,7 @@ u32 TLan_HandleTxEOF( struct device *dev, u16 host_int )
if ( head_list->cStat & TLAN_CSTAT_EOC )
eoc = 1;
- if ( ! head_list->cStat & TLAN_CSTAT_FRM_CMP ) {
+ if (!(head_list->cStat & TLAN_CSTAT_FRM_CMP)) {
printk( "TLAN: Received interrupt for uncompleted TX frame.\n" );
}
@@ -1244,7 +1244,7 @@ u32 TLan_HandleRxEOF( struct device *dev, u16 host_int )
eoc = 1;
}
- if ( ! head_list->cStat & TLAN_CSTAT_FRM_CMP ) {
+ if (!(head_list->cStat & TLAN_CSTAT_FRM_CMP)) {
printk( "TLAN: Received interrupt for uncompleted RX frame.\n" );
} else if ( bbuf ) {
skb = dev_alloc_skb( head_list->frameSize + 7 );
diff --git a/linux/src/drivers/net/wd.c b/linux/src/drivers/net/wd.c
index a737a01d..dd879021 100644
--- a/linux/src/drivers/net/wd.c
+++ b/linux/src/drivers/net/wd.c
@@ -137,7 +137,7 @@ int wd_probe1(struct device *dev, int ioaddr)
}
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("%s: WD80x3 at %#3x, ", dev->name, ioaddr);
for (i = 0; i < 6; i++)
diff --git a/linux/src/drivers/scsi/AM53C974.c b/linux/src/drivers/scsi/AM53C974.c
index 5178ccf7..da139ced 100644
--- a/linux/src/drivers/scsi/AM53C974.c
+++ b/linux/src/drivers/scsi/AM53C974.c
@@ -1919,7 +1919,7 @@ if ((statreg & STATREG_PHASE) != PHASE_MSGIN) {
goto EXIT_ABORT; }
msg[0] = AM53C974_read_8(FFREG);
-if (!msg[0] & 0x80) {
+if (!(msg[0] & 0x80)) {
printk("scsi%d: error: expecting IDENTIFY message, got ", instance->host_no);
print_msg(msg);
hostdata->aborted = 1;
diff --git a/linux/src/drivers/scsi/FlashPoint.c b/linux/src/drivers/scsi/FlashPoint.c
index aae35c03..8d2f1020 100644
--- a/linux/src/drivers/scsi/FlashPoint.c
+++ b/linux/src/drivers/scsi/FlashPoint.c
@@ -3756,17 +3756,17 @@ STATIC int SetDevSyncRate(PSCCBcard pCurrCard, PUCB p_ucb)
}
if(currTar_Info->TarEEValue && EE_SYNC_MASK == syncVal)
return(0);
- currTar_Info->TarEEValue = (currTar_Info->TarEEValue & !EE_SYNC_MASK)
+ currTar_Info->TarEEValue = (!(EE_SYNC_MASK & currTar_Info->TarEEValue))
| syncVal;
syncOffset = (SYNC_RATE_TBL + scsiID) / 2;
temp2.tempw = utilEERead(ioPort, syncOffset);
if(scsiID & 0x01)
{
- temp2.tempb[0] = (temp2.tempb[0] & !EE_SYNC_MASK) | syncVal;
+ temp2.tempb[0] = (!(EE_SYNC_MASK & temp2.tempb[0])) | syncVal;
}
else
{
- temp2.tempb[1] = (temp2.tempb[1] & !EE_SYNC_MASK) | syncVal;
+ temp2.tempb[1] = (!(EE_SYNC_MASK & temp2.tempb[1])) | syncVal;
}
utilEEWriteOnOff(ioPort, 1);
utilEEWrite(ioPort, temp2.tempw, syncOffset);
@@ -3845,7 +3845,7 @@ int SetDevWideMode(PSCCBcard pCurrCard,PUCB p_ucb)
}
else
{
- if(!currTar_Info->TarEEValue & EE_WIDE_SCSI)
+ if(!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
{
return(0);
}
@@ -3854,18 +3854,18 @@ int SetDevWideMode(PSCCBcard pCurrCard,PUCB p_ucb)
scsiWideMode = 0;
}
}
- currTar_Info->TarEEValue = (currTar_Info->TarEEValue & !EE_WIDE_SCSI)
+ currTar_Info->TarEEValue = (!(EE_WIDE_SCSI & currTar_Info->TarEEValue))
| scsiWideMode;
syncOffset = (SYNC_RATE_TBL + scsiID) / 2;
temp2.tempw = utilEERead(ioPort, syncOffset);
if(scsiID & 0x01)
{
- temp2.tempb[0] = (temp2.tempb[0] & !EE_WIDE_SCSI) | scsiWideMode;
+ temp2.tempb[0] = (!(EE_WIDE_SCSI & temp2.tempb[0])) | scsiWideMode;
}
else
{
- temp2.tempb[1] = (temp2.tempb[1] & !EE_WIDE_SCSI) | scsiWideMode;
+ temp2.tempb[1] = (!(EE_WIDE_SCSI & temp2.tempb[1])) | scsiWideMode;
}
utilEEWriteOnOff(ioPort, 1);
utilEEWrite(ioPort, temp2.tempw, syncOffset);
diff --git a/linux/src/drivers/scsi/NCR5380.c b/linux/src/drivers/scsi/NCR5380.c
index 295f2ad2..4f085e9b 100644
--- a/linux/src/drivers/scsi/NCR5380.c
+++ b/linux/src/drivers/scsi/NCR5380.c
@@ -1949,7 +1949,7 @@ static int do_abort (struct Scsi_Host *host) {
* the target sees, so we just handshake.
*/
- while (!(tmp = NCR5380_read(STATUS_REG)) & SR_REQ);
+ while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ));
NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
@@ -2900,7 +2900,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance) {
NCR5380_transfer_pio(instance, &phase, &len, &data);
- if (!msg[0] & 0x80) {
+ if (!(msg[0] & 0x80)) {
printk("scsi%d : expecting IDENTIFY message, got ",
instance->host_no);
print_msg(msg);
diff --git a/linux/src/drivers/scsi/t128.c b/linux/src/drivers/scsi/t128.c
index d4c7452b..198e910b 100644
--- a/linux/src/drivers/scsi/t128.c
+++ b/linux/src/drivers/scsi/t128.c
@@ -327,7 +327,7 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
for (; i; --i) {
while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
#else
- while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
+ while (!((instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY)) barrier();
for (; i; --i) {
#endif
*d++ = *reg;
@@ -370,7 +370,7 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src
for (; i; --i) {
while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
#else
- while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
+ while (!((instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY)) barrier();
for (; i; --i) {
#endif
*reg = *s++;
diff --git a/linux/src/include/asm-i386/bitops.h b/linux/src/include/asm-i386/bitops.h
index fc4cf192..e2a4c14a 100644
--- a/linux/src/include/asm-i386/bitops.h
+++ b/linux/src/include/asm-i386/bitops.h
@@ -28,7 +28,7 @@ struct __dummy { unsigned long a[100]; };
#define ADDR (*(struct __dummy *) addr)
#define CONST_ADDR (*(const struct __dummy *) addr)
-extern __inline__ int set_bit(int nr, SMPVOL void * addr)
+static __inline__ int set_bit(int nr, SMPVOL void * addr)
{
int oldbit;
@@ -39,7 +39,7 @@ extern __inline__ int set_bit(int nr, SMPVOL void * addr)
return oldbit;
}
-extern __inline__ int clear_bit(int nr, SMPVOL void * addr)
+static __inline__ int clear_bit(int nr, SMPVOL void * addr)
{
int oldbit;
@@ -50,7 +50,7 @@ extern __inline__ int clear_bit(int nr, SMPVOL void * addr)
return oldbit;
}
-extern __inline__ int change_bit(int nr, SMPVOL void * addr)
+static __inline__ int change_bit(int nr, SMPVOL void * addr)
{
int oldbit;
@@ -61,7 +61,7 @@ extern __inline__ int change_bit(int nr, SMPVOL void * addr)
return oldbit;
}
-extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
{
int oldbit;
@@ -72,7 +72,7 @@ extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
return oldbit;
}
-extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
{
int oldbit;
@@ -83,7 +83,7 @@ extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
return oldbit;
}
-extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
{
int oldbit;
@@ -98,7 +98,7 @@ extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
/*
* This routine doesn't need to be atomic.
*/
-extern __inline__ int test_bit(int nr, const SMPVOL void * addr)
+static __inline__ int test_bit(int nr, const SMPVOL void * addr)
{
return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0;
}
@@ -106,8 +106,9 @@ extern __inline__ int test_bit(int nr, const SMPVOL void * addr)
/*
* Find-bit routines..
*/
-extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
+static __inline__ int find_first_zero_bit(void * addr, unsigned size)
{
+ int d0, d1, d2;
int res;
if (!size)
@@ -123,13 +124,12 @@ extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
"1:\tsubl %%ebx,%%edi\n\t"
"shll $3,%%edi\n\t"
"addl %%edi,%%edx"
- :"=d" (res)
- :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
- :"ax", "cx", "di");
+ :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
+ :"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
return res;
}
-extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
{
unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
int set = 0, bit = offset & 31, res;
@@ -160,7 +160,7 @@ extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
* ffz = Find First Zero in word. Undefined if no zero exists,
* so code should check against ~0UL first..
*/
-extern __inline__ unsigned long ffz(unsigned long word)
+static __inline__ unsigned long ffz(unsigned long word)
{
__asm__("bsfl %1,%0"
:"=r" (word)
@@ -176,7 +176,7 @@ extern __inline__ unsigned long ffz(unsigned long word)
* differs in spirit from the above ffz (man ffs).
*/
-extern __inline__ int ffs(int x)
+static __inline__ int ffs(int x)
{
int r;
diff --git a/linux/src/include/asm-i386/io.h b/linux/src/include/asm-i386/io.h
index f961f1d2..34cf105b 100644
--- a/linux/src/include/asm-i386/io.h
+++ b/linux/src/include/asm-i386/io.h
@@ -45,12 +45,12 @@
* make the kernel segment mapped at 0, we need to do translation
* on the i386 as well)
*/
-extern inline unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(volatile void * address)
{
return (unsigned long) _kvtophys(address);
}
-extern inline void * phys_to_virt(unsigned long address)
+static inline void * phys_to_virt(unsigned long address)
{
return (void *) phystokv(address);
}
@@ -90,7 +90,7 @@ extern inline void * phys_to_virt(unsigned long address)
*/
#define __OUT1(s,x) \
-extern inline void __out##s(unsigned x value, unsigned short port) {
+static inline void __out##s(unsigned x value, unsigned short port) {
#define __OUT2(s,s1,s2) \
__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
@@ -102,7 +102,7 @@ __OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \
__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; }
#define __IN1(s) \
-extern inline RETURN_TYPE __in##s(unsigned short port) { RETURN_TYPE _v;
+static inline RETURN_TYPE __in##s(unsigned short port) { RETURN_TYPE _v;
#define __IN2(s,s1,s2) \
__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
@@ -114,12 +114,12 @@ __IN1(s##_p) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; retu
__IN1(s##c_p) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; }
#define __INS(s) \
-extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
+static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
{ __asm__ __volatile__ ("cld ; rep ; ins" #s \
: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
#define __OUTS(s) \
-extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
+static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
diff --git a/linux/src/include/asm-i386/segment.h b/linux/src/include/asm-i386/segment.h
index 5f8af993..d23aa173 100644
--- a/linux/src/include/asm-i386/segment.h
+++ b/linux/src/include/asm-i386/segment.h
@@ -60,7 +60,11 @@ static inline void __attribute__((always_inline)) __put_user(unsigned long x, vo
:"ir" (x), "m" (*__sd(y)));
break;
default:
+#ifdef __OPTIMIZE__
bad_user_access_length();
+#else
+ asm volatile("ud2");
+#endif
}
}
@@ -85,7 +89,11 @@ static inline unsigned long __attribute__((always_inline)) __get_user(const void
:"m" (*__const_sd(y)));
return result;
default:
+#ifdef __OPTIMIZE__
return bad_user_access_length();
+#else
+ asm volatile("ud2");
+#endif
}
}
diff --git a/linux/src/include/asm-i386/semaphore.h b/linux/src/include/asm-i386/semaphore.h
index 1486d1c1..18e12c10 100644
--- a/linux/src/include/asm-i386/semaphore.h
+++ b/linux/src/include/asm-i386/semaphore.h
@@ -30,6 +30,10 @@ struct semaphore {
#define MUTEX ((struct semaphore) { 1, 0, 0, NULL })
#define MUTEX_LOCKED ((struct semaphore) { 0, 0, 0, NULL })
+/* Special register calling convention:
+ * eax contains return address
+ * ecx contains semaphore address
+ */
asmlinkage void down_failed(void /* special register calling convention */);
asmlinkage void up_wakeup(void /* special register calling convention */);
@@ -41,20 +45,21 @@ extern void __up(struct semaphore * sem);
* "down_failed" is a special asm handler that calls the C
* routine that actually waits. See arch/i386/lib/semaphore.S
*/
-extern inline void down(struct semaphore * sem)
+static inline void down(struct semaphore * sem)
{
+ int d0;
__asm__ __volatile__(
"# atomic down operation\n\t"
"movl $1f,%%eax\n\t"
#ifdef __SMP__
"lock ; "
#endif
- "decl 0(%0)\n\t"
+ "decl %1\n\t"
"js " SYMBOL_NAME_STR(down_failed) "\n"
"1:\n"
- :/* no outputs */
+ :"=&a" (d0), "=m" (sem->count)
:"c" (sem)
- :"ax","dx","memory");
+ :"memory");
}
/*
@@ -81,7 +86,7 @@ asmlinkage int down_failed_interruptible(void); /* params in registers */
* process can be killed. The down_failed_interruptible routine
* returns negative for signalled and zero for semaphore acquired.
*/
-extern inline int down_interruptible(struct semaphore * sem)
+static inline int down_interruptible(struct semaphore * sem)
{
int ret ;
@@ -91,13 +96,13 @@ extern inline int down_interruptible(struct semaphore * sem)
#ifdef __SMP__
"lock ; "
#endif
- "decl 0(%1)\n\t"
+ "decl %1\n\t"
"js " SYMBOL_NAME_STR(down_failed_interruptible) "\n\t"
"xorl %%eax,%%eax\n"
"2:\n"
- :"=a" (ret)
+ :"=&a" (ret), "=m" (sem->count)
:"c" (sem)
- :"ax","dx","memory");
+ :"memory");
return(ret) ;
}
@@ -108,20 +113,21 @@ extern inline int down_interruptible(struct semaphore * sem)
* The default case (no contention) will result in NO
* jumps for both down() and up().
*/
-extern inline void up(struct semaphore * sem)
+static inline void up(struct semaphore * sem)
{
+ int d0;
__asm__ __volatile__(
"# atomic up operation\n\t"
"movl $1f,%%eax\n\t"
#ifdef __SMP__
"lock ; "
#endif
- "incl 0(%0)\n\t"
+ "incl %1\n\t"
"jle " SYMBOL_NAME_STR(up_wakeup)
"\n1:"
- :/* no outputs */
+ :"=&a" (d0), "=m" (sem->count)
:"c" (sem)
- :"ax", "dx", "memory");
+ :"memory");
}
#endif
diff --git a/linux/src/include/linux/compiler-gcc5.h b/linux/src/include/linux/compiler-gcc5.h
new file mode 100644
index 00000000..efee4937
--- /dev/null
+++ b/linux/src/include/linux/compiler-gcc5.h
@@ -0,0 +1,67 @@
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead."
+#endif
+
+#define __used __attribute__((__used__))
+#define __must_check __attribute__((warn_unused_result))
+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
+
+/* Mark functions as cold. gcc will assume any path leading to a call
+ to them will be unlikely. This means a lot of manual unlikely()s
+ are unnecessary now for any paths leading to the usual suspects
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
+ older compilers]
+
+ Early snapshots of gcc 4.3 don't support this and we can't detect this
+ in the preprocessor, but we can live with this because they're unreleased.
+ Maketime probing would be overkill here.
+
+ gcc also has a __attribute__((__hot__)) to move hot functions into
+ a special section, but I don't see any sense in this right now in
+ the kernel context */
+#define __cold __attribute__((__cold__))
+
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
+
+#ifndef __CHECKER__
+# define __compiletime_warning(message) __attribute__((warning(message)))
+# define __compiletime_error(message) __attribute__((error(message)))
+#endif /* __CHECKER__ */
+
+/*
+ * Mark a position in code as unreachable. This can be used to
+ * suppress control flow warnings after asm blocks that transfer
+ * control elsewhere.
+ *
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
+ * this in the preprocessor, but we can live with this because they're
+ * unreleased. Really, we need to have autoconf for the kernel.
+ */
+#define unreachable() __builtin_unreachable()
+
+/* Mark a function definition as prohibited from being cloned. */
+#define __noclone __attribute__((__noclone__))
+
+/*
+ * Tell the optimizer that something else uses this function or variable.
+ */
+#define __visible __attribute__((externally_visible))
+
+/*
+ * GCC 'asm goto' miscompiles certain code sequences:
+ *
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
+ *
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
+ *
+ * (asm goto is automatically volatile - the naming reflects this.)
+ */
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
+
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
+#define __HAVE_BUILTIN_BSWAP32__
+#define __HAVE_BUILTIN_BSWAP64__
+#define __HAVE_BUILTIN_BSWAP16__
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
+
+#define KASAN_ABI_VERSION 4
diff --git a/linux/src/include/linux/hdreg.h b/linux/src/include/linux/hdreg.h
index e223480d..4a388c5d 100644
--- a/linux/src/include/linux/hdreg.h
+++ b/linux/src/include/linux/hdreg.h
@@ -62,6 +62,8 @@
#define WIN_SETFEATURES 0xEF /* set special drive features */
#define WIN_READDMA 0xc8 /* read sectors using DMA transfers */
#define WIN_WRITEDMA 0xca /* write sectors using DMA transfers */
+#define WIN_READDMA_EXT 0x25 /* read sectors using LBA48 DMA transfers */
+#define WIN_WRITEDMA_EXT 0x35 /* write sectors using LBA48 DMA transfers */
/* Additional drive command codes used by ATAPI devices. */
#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */
@@ -168,7 +170,7 @@ struct hd_driveid {
unsigned short word80;
unsigned short word81;
unsigned short command_sets; /* bits 0:Smart 1:Security 2:Removable 3:PM */
- unsigned short word83; /* bits 14:Smart Enabled 13:0 zero */
+ unsigned short command_set_2; /* bits 14:Smart Enabled 13:0 zero */
unsigned short word84;
unsigned short word85;
unsigned short word86;
@@ -185,10 +187,7 @@ struct hd_driveid {
unsigned short word97; /* reserved (word 97) */
unsigned short word98; /* reserved (word 98) */
unsigned short word99; /* reserved (word 99) */
- unsigned short word100; /* reserved (word 100) */
- unsigned short word101; /* reserved (word 101) */
- unsigned short word102; /* reserved (word 102) */
- unsigned short word103; /* reserved (word 103) */
+ unsigned long long lba_capacity_2; /* 48-bit total number of sectors */
unsigned short word104; /* reserved (word 104) */
unsigned short word105; /* reserved (word 105) */
unsigned short word106; /* reserved (word 106) */
diff --git a/linux/src/include/linux/pci.h b/linux/src/include/linux/pci.h
index 3508979f..8aad3d59 100644
--- a/linux/src/include/linux/pci.h
+++ b/linux/src/include/linux/pci.h
@@ -140,6 +140,8 @@
#define PCI_CLASS_STORAGE_FLOPPY 0x0102
#define PCI_CLASS_STORAGE_IPI 0x0103
#define PCI_CLASS_STORAGE_RAID 0x0104
+#define PCI_CLASS_STORAGE_SATA 0x0106
+#define PCI_CLASS_STORAGE_SATA_AHCI 0x010601
#define PCI_CLASS_STORAGE_OTHER 0x0180
#define PCI_BASE_CLASS_NETWORK 0x02
diff --git a/linux/src/include/linux/string.h b/linux/src/include/linux/string.h
index 214503c2..62ff8802 100644
--- a/linux/src/include/linux/string.h
+++ b/linux/src/include/linux/string.h
@@ -12,25 +12,33 @@ extern "C" {
#endif
extern char * ___strtok;
+#if 0
extern char * strcpy(char *,const char *);
extern char * strncpy(char *,const char *, __kernel_size_t);
extern char * strcat(char *, const char *);
extern char * strncat(char *, const char *, __kernel_size_t);
extern char * strchr(const char *,int);
extern char * strrchr(const char *,int);
+#endif
extern char * strpbrk(const char *,const char *);
extern char * strtok(char *,const char *);
extern char * strstr(const char *,const char *);
+#if 0
extern __kernel_size_t strlen(const char *);
extern __kernel_size_t strnlen(const char *,__kernel_size_t);
+#endif
extern __kernel_size_t strspn(const char *,const char *);
+#if 0
extern int strcmp(const char *,const char *);
extern int strncmp(const char *,const char *,__kernel_size_t);
+#endif
extern void * memset(void *,int,__kernel_size_t);
extern void * memcpy(void *,const void *,__kernel_size_t);
+#if 0
extern void * memmove(void *,const void *,__kernel_size_t);
extern void * memscan(void *,int,__kernel_size_t);
+#endif
extern int memcmp(const void *,const void *,__kernel_size_t);
/*
diff --git a/util/atoi.c b/util/atoi.c
index 64816b9d..e56f50d7 100644
--- a/util/atoi.c
+++ b/util/atoi.c
@@ -91,11 +91,11 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
int
mach_atoi(cp, nump)
-u_char *cp;
-int *nump;
+const u_char *cp;
+int *nump;
{
- int number;
- u_char *original;
+ int number;
+ const u_char *original;
original = cp;
for (number = 0; ('0' <= *cp) && (*cp <= '9'); cp++)
diff --git a/util/atoi.h b/util/atoi.h
index 921b1e81..47adb42e 100644
--- a/util/atoi.h
+++ b/util/atoi.h
@@ -62,6 +62,6 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <sys/types.h>
#define MACH_ATOI_DEFAULT -1
-extern int mach_atoi (u_char *, int *);
+extern int mach_atoi (const u_char *, int *);
#endif /* _UTIL_ATOI_H_ */
diff --git a/version.m4 b/version.m4
index 3bf4275f..9bebd3b8 100644
--- a/version.m4
+++ b/version.m4
@@ -1,4 +1,4 @@
m4_define([AC_PACKAGE_NAME],[GNU Mach])
-m4_define([AC_PACKAGE_VERSION],[1.3.99])
+m4_define([AC_PACKAGE_VERSION],[1.5])
m4_define([AC_PACKAGE_BUGREPORT],[bug-hurd@gnu.org])
m4_define([AC_PACKAGE_TARNAME],[gnumach])
diff --git a/vm/memory_object.c b/vm/memory_object.c
index e281c6a3..097ed23d 100644
--- a/vm/memory_object.c
+++ b/vm/memory_object.c
@@ -82,24 +82,19 @@ decl_simple_lock_data(,memory_manager_default_lock)
* argument conversion. Explicit deallocation is necessary.
*/
-kern_return_t memory_object_data_supply(object, offset, data_copy, data_cnt,
- lock_value, precious, reply_to, reply_to_type)
- register
- vm_object_t object;
- register
- vm_offset_t offset;
- vm_map_copy_t data_copy;
- unsigned int data_cnt;
- vm_prot_t lock_value;
- boolean_t precious;
- ipc_port_t reply_to;
- mach_msg_type_name_t reply_to_type;
+kern_return_t memory_object_data_supply(
+ vm_object_t object,
+ vm_offset_t offset,
+ vm_map_copy_t data_copy,
+ unsigned int data_cnt,
+ vm_prot_t lock_value,
+ boolean_t precious,
+ ipc_port_t reply_to,
+ mach_msg_type_name_t reply_to_type)
{
kern_return_t result = KERN_SUCCESS;
vm_offset_t error_offset = 0;
- register
vm_page_t m;
- register
vm_page_t data_m;
vm_size_t original_length;
vm_offset_t original_offset;
@@ -307,29 +302,26 @@ retry_lookup:
return(result);
}
-
/*
* If successful, destroys the map copy object.
*/
-kern_return_t memory_object_data_provided(object, offset, data, data_cnt,
- lock_value)
- vm_object_t object;
- vm_offset_t offset;
- pointer_t data;
- unsigned int data_cnt;
- vm_prot_t lock_value;
+kern_return_t memory_object_data_provided(
+ vm_object_t object,
+ vm_offset_t offset,
+ pointer_t data,
+ unsigned int data_cnt,
+ vm_prot_t lock_value)
{
return memory_object_data_supply(object, offset, (vm_map_copy_t) data,
data_cnt, lock_value, FALSE, IP_NULL,
0);
}
-
-kern_return_t memory_object_data_error(object, offset, size, error_value)
- vm_object_t object;
- vm_offset_t offset;
- vm_size_t size;
- kern_return_t error_value;
+kern_return_t memory_object_data_error(
+ vm_object_t object,
+ vm_offset_t offset,
+ vm_size_t size,
+ kern_return_t error_value)
{
if (object == VM_OBJECT_NULL)
return(KERN_INVALID_ARGUMENT);
@@ -337,16 +329,11 @@ kern_return_t memory_object_data_error(object, offset, size, error_value)
if (size != round_page(size))
return(KERN_INVALID_ARGUMENT);
-#ifdef lint
- /* Error value is ignored at this time */
- error_value++;
-#endif
-
vm_object_lock(object);
offset -= object->paging_offset;
while (size != 0) {
- register vm_page_t m;
+ vm_page_t m;
m = vm_page_lookup(object, offset);
if ((m != VM_PAGE_NULL) && m->busy && m->absent) {
@@ -370,10 +357,10 @@ kern_return_t memory_object_data_error(object, offset, size, error_value)
return(KERN_SUCCESS);
}
-kern_return_t memory_object_data_unavailable(object, offset, size)
- vm_object_t object;
- vm_offset_t offset;
- vm_size_t size;
+kern_return_t memory_object_data_unavailable(
+ vm_object_t object,
+ vm_offset_t offset,
+ vm_size_t size)
{
#if MACH_PAGEMAP
vm_external_t existence_info = VM_EXTERNAL_NULL;
@@ -406,7 +393,7 @@ kern_return_t memory_object_data_unavailable(object, offset, size)
offset -= object->paging_offset;
while (size != 0) {
- register vm_page_t m;
+ vm_page_t m;
/*
* We're looking for pages that are both busy and
@@ -453,12 +440,11 @@ kern_return_t memory_object_data_unavailable(object, offset, size)
#define MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN 2
#define MEMORY_OBJECT_LOCK_RESULT_MUST_RETURN 3
-memory_object_lock_result_t memory_object_lock_page(m, should_return,
- should_flush, prot)
- vm_page_t m;
- memory_object_return_t should_return;
- boolean_t should_flush;
- vm_prot_t prot;
+memory_object_lock_result_t memory_object_lock_page(
+ vm_page_t m,
+ memory_object_return_t should_return,
+ boolean_t should_flush,
+ vm_prot_t prot)
{
/*
* Don't worry about pages for which the kernel
@@ -656,19 +642,17 @@ memory_object_lock_result_t memory_object_lock_page(m, should_return,
*/
kern_return_t
-memory_object_lock_request(object, offset, size,
- should_return, should_flush, prot,
- reply_to, reply_to_type)
- register vm_object_t object;
- register vm_offset_t offset;
- register vm_size_t size;
- memory_object_return_t should_return;
- boolean_t should_flush;
- vm_prot_t prot;
- ipc_port_t reply_to;
- mach_msg_type_name_t reply_to_type;
+memory_object_lock_request(
+ vm_object_t object,
+ vm_offset_t offset,
+ vm_size_t size,
+ memory_object_return_t should_return,
+ boolean_t should_flush,
+ vm_prot_t prot,
+ ipc_port_t reply_to,
+ mach_msg_type_name_t reply_to_type)
{
- register vm_page_t m;
+ vm_page_t m;
vm_offset_t original_offset = offset;
vm_size_t original_size = size;
vm_offset_t paging_offset = 0;
@@ -720,8 +704,8 @@ memory_object_lock_request(object, offset, size,
#define PAGEOUT_PAGES \
MACRO_BEGIN \
vm_map_copy_t copy; \
- register int i; \
- register vm_page_t hp; \
+ int i; \
+ vm_page_t hp; \
\
vm_object_unlock(object); \
\
@@ -892,13 +876,12 @@ MACRO_END
}
kern_return_t
-memory_object_set_attributes_common(object, object_ready, may_cache,
- copy_strategy, use_old_pageout)
- vm_object_t object;
- boolean_t object_ready;
- boolean_t may_cache;
- memory_object_copy_strategy_t copy_strategy;
- boolean_t use_old_pageout;
+memory_object_set_attributes_common(
+ vm_object_t object,
+ boolean_t object_ready,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy,
+ boolean_t use_old_pageout)
{
if (object == VM_OBJECT_NULL)
return(KERN_INVALID_ARGUMENT);
@@ -959,13 +942,12 @@ memory_object_set_attributes_common(object, object_ready, may_cache,
* XXX stub that made change_attributes an RPC. Need investigation.
*/
-kern_return_t memory_object_change_attributes(object, may_cache,
- copy_strategy, reply_to, reply_to_type)
- vm_object_t object;
- boolean_t may_cache;
- memory_object_copy_strategy_t copy_strategy;
- ipc_port_t reply_to;
- mach_msg_type_name_t reply_to_type;
+kern_return_t memory_object_change_attributes(
+ vm_object_t object,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy,
+ ipc_port_t reply_to,
+ mach_msg_type_name_t reply_to_type)
{
kern_return_t result;
@@ -995,33 +977,32 @@ kern_return_t memory_object_change_attributes(object, may_cache,
}
kern_return_t
-memory_object_set_attributes(object, object_ready, may_cache, copy_strategy)
- vm_object_t object;
- boolean_t object_ready;
- boolean_t may_cache;
- memory_object_copy_strategy_t copy_strategy;
+memory_object_set_attributes(
+ vm_object_t object,
+ boolean_t object_ready,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy)
{
return memory_object_set_attributes_common(object, object_ready,
may_cache, copy_strategy,
TRUE);
}
-kern_return_t memory_object_ready(object, may_cache, copy_strategy)
- vm_object_t object;
- boolean_t may_cache;
- memory_object_copy_strategy_t copy_strategy;
+kern_return_t memory_object_ready(
+ vm_object_t object,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy)
{
return memory_object_set_attributes_common(object, TRUE,
may_cache, copy_strategy,
FALSE);
}
-kern_return_t memory_object_get_attributes(object, object_ready,
- may_cache, copy_strategy)
- vm_object_t object;
- boolean_t *object_ready;
- boolean_t *may_cache;
- memory_object_copy_strategy_t *copy_strategy;
+kern_return_t memory_object_get_attributes(
+ vm_object_t object,
+ boolean_t *object_ready,
+ boolean_t *may_cache,
+ memory_object_copy_strategy_t *copy_strategy)
{
if (object == VM_OBJECT_NULL)
return(KERN_INVALID_ARGUMENT);
@@ -1041,7 +1022,7 @@ kern_return_t memory_object_get_attributes(object, object_ready,
* If successful, consumes the supplied naked send right.
*/
kern_return_t vm_set_default_memory_manager(host, default_manager)
- host_t host;
+ const host_t host;
ipc_port_t *default_manager;
{
ipc_port_t current_manager;
@@ -1123,7 +1104,7 @@ ipc_port_t memory_manager_default_reference(void)
*/
boolean_t memory_manager_default_port(port)
- ipc_port_t port;
+ const ipc_port_t port;
{
ipc_port_t current;
boolean_t result;
diff --git a/vm/memory_object_proxy.c b/vm/memory_object_proxy.c
index 4fed312e..a64bfcce 100644
--- a/vm/memory_object_proxy.c
+++ b/vm/memory_object_proxy.c
@@ -115,11 +115,11 @@ memory_object_proxy_notify (mach_msg_header_t *msg)
given OBJECT at OFFSET in the new object with the maximum
protection MAX_PROTECTION and return it in *PORT. */
kern_return_t
-memory_object_create_proxy (ipc_space_t space, vm_prot_t max_protection,
+memory_object_create_proxy (const ipc_space_t space, vm_prot_t max_protection,
ipc_port_t *object, natural_t object_count,
- vm_offset_t *offset, natural_t offset_count,
- vm_offset_t *start, natural_t start_count,
- vm_offset_t *len, natural_t len_count,
+ const vm_offset_t *offset, natural_t offset_count,
+ const vm_offset_t *start, natural_t start_count,
+ const vm_offset_t *len, natural_t len_count,
ipc_port_t *port)
{
memory_object_proxy_t proxy;
diff --git a/vm/memory_object_proxy.h b/vm/memory_object_proxy.h
index f4be0d0d..dc0ea747 100644
--- a/vm/memory_object_proxy.h
+++ b/vm/memory_object_proxy.h
@@ -19,7 +19,7 @@
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#ifndef _VM_MEMORY_OBJECT_PROXY_H_
-#define _VM_MEMORY_OBJECT_PROXT_H_
+#define _VM_MEMORY_OBJECT_PROXY_H_
#include <ipc/ipc_types.h>
#include <mach/boolean.h>
@@ -30,19 +30,8 @@
extern void memory_object_proxy_init (void);
extern boolean_t memory_object_proxy_notify (mach_msg_header_t *msg);
-extern kern_return_t memory_object_create_proxy (ipc_space_t space,
- vm_prot_t max_protection,
- ipc_port_t *object,
- natural_t object_count,
- vm_offset_t *offset,
- natural_t offset_count,
- vm_offset_t *start,
- natural_t start_count,
- vm_offset_t *len,
- natural_t len_count,
- ipc_port_t *port);
extern kern_return_t memory_object_proxy_lookup (ipc_port_t port,
ipc_port_t *object,
vm_prot_t *max_protection);
-#endif /* _VM_MEMORY_OBJECT_PROXT_H_ */
+#endif /* _VM_MEMORY_OBJECT_PROXY_H_ */
diff --git a/vm/pmap.h b/vm/pmap.h
index 59fd03ab..134f9c64 100644
--- a/vm/pmap.h
+++ b/vm/pmap.h
@@ -163,38 +163,16 @@ void pmap_clear_modify(vm_offset_t pa);
/* Return modify bit */
boolean_t pmap_is_modified(vm_offset_t pa);
-
-/*
- * Statistics routines
- */
-
-#ifndef pmap_resident_count
-extern int pmap_resident_count();
-#endif /* pmap_resident_count */
-
/*
* Sundry required routines
*/
/* Return a virtual-to-physical mapping, if possible. */
extern vm_offset_t pmap_extract(pmap_t, vm_offset_t);
-/* Is virtual address valid? */
-extern boolean_t pmap_access();
/* Perform garbage collection, if any. */
extern void pmap_collect(pmap_t);
/* Specify pageability. */
extern void pmap_change_wiring(pmap_t, vm_offset_t, boolean_t);
-#ifndef pmap_phys_address
-/* Transform address returned by device driver mapping function to physical
- * address known to this module. */
-extern vm_offset_t pmap_phys_address();
-#endif /* pmap_phys_address */
-#ifndef pmap_phys_to_frame
-/* Inverse of pmap_phys_address, for use by device driver mapping function in
- * machine-independent pseudo-devices. */
-extern int pmap_phys_to_frame();
-#endif /* pmap_phys_to_frame */
-
/*
* Optional routines
*/
@@ -205,7 +183,7 @@ extern void pmap_copy(pmap_t, pmap_t, vm_offset_t, vm_size_t,
#endif /* pmap_copy */
#ifndef pmap_attribute
/* Get/Set special memory attributes. */
-extern kern_return_t pmap_attribute();
+extern kern_return_t pmap_attribute(void);
#endif /* pmap_attribute */
/*
diff --git a/vm/vm_debug.c b/vm/vm_debug.c
index 0af58b69..227090e6 100644
--- a/vm/vm_debug.c
+++ b/vm/vm_debug.c
@@ -65,8 +65,7 @@
*/
ipc_port_t
-vm_object_real_name(object)
- vm_object_t object;
+vm_object_real_name(vm_object_t object)
{
ipc_port_t port = IP_NULL;
@@ -94,11 +93,11 @@ vm_object_real_name(object)
*/
kern_return_t
-mach_vm_region_info(map, address, regionp, portp)
- vm_map_t map;
- vm_offset_t address;
- vm_region_info_t *regionp;
- ipc_port_t *portp;
+mach_vm_region_info(
+ vm_map_t map,
+ vm_offset_t address,
+ vm_region_info_t *regionp,
+ ipc_port_t *portp)
{
vm_map_t cmap; /* current map in traversal */
vm_map_t nmap; /* next map to look at */
@@ -184,11 +183,11 @@ mach_vm_region_info(map, address, regionp, portp)
*/
kern_return_t
-mach_vm_object_info(object, infop, shadowp, copyp)
- vm_object_t object;
- vm_object_info_t *infop;
- ipc_port_t *shadowp;
- ipc_port_t *copyp;
+mach_vm_object_info(
+ vm_object_t object,
+ vm_object_info_t *infop,
+ ipc_port_t *shadowp,
+ ipc_port_t *copyp)
{
vm_object_info_t info;
vm_object_info_state_t state;
@@ -278,10 +277,10 @@ mach_vm_object_info(object, infop, shadowp, copyp)
*/
kern_return_t
-mach_vm_object_pages(object, pagesp, countp)
- vm_object_t object;
- vm_page_info_array_t *pagesp;
- natural_t *countp;
+mach_vm_object_pages(
+ vm_object_t object,
+ vm_page_info_array_t *pagesp,
+ natural_t *countp)
{
vm_size_t size;
vm_offset_t addr;
@@ -404,7 +403,7 @@ mach_vm_object_pages(object, pagesp, countp)
addr + rsize_used, size - rsize_used);
if (size_used != rsize_used)
- memset((char *) (addr + size_used), 0,
+ memset((void *) (addr + size_used), 0,
rsize_used - size_used);
kr = vm_map_copyin(ipc_kernel_map, addr, rsize_used,
@@ -434,7 +433,7 @@ mach_vm_object_pages(object, pagesp, countp)
kern_return_t
host_virtual_physical_table_info(host, infop, countp)
- host_t host;
+ const host_t host;
hash_info_bucket_array_t *infop;
natural_t *countp;
{
diff --git a/vm/vm_external.c b/vm/vm_external.c
index e9643ffc..2e2593b1 100644
--- a/vm/vm_external.c
+++ b/vm/vm_external.c
@@ -56,8 +56,7 @@ struct kmem_cache vm_object_small_existence_map_cache;
struct kmem_cache vm_object_large_existence_map_cache;
-vm_external_t vm_external_create(size)
- vm_offset_t size;
+vm_external_t vm_external_create(vm_offset_t size)
{
vm_external_t result;
vm_size_t bytes;
@@ -78,8 +77,7 @@ vm_external_t vm_external_create(size)
return(result);
}
-void vm_external_destroy(e)
- vm_external_t e;
+void vm_external_destroy(vm_external_t e)
{
if (e == VM_EXTERNAL_NULL)
return;
@@ -97,8 +95,8 @@ void vm_external_destroy(e)
}
vm_external_state_t _vm_external_state_get(e, offset)
- vm_external_t e;
- vm_offset_t offset;
+ const vm_external_t e;
+ vm_offset_t offset;
{
unsigned
int bit, byte;
@@ -115,10 +113,10 @@ vm_external_state_t _vm_external_state_get(e, offset)
VM_EXTERNAL_STATE_EXISTS : VM_EXTERNAL_STATE_ABSENT );
}
-void vm_external_state_set(e, offset, state)
- vm_external_t e;
- vm_offset_t offset;
- vm_external_state_t state;
+void vm_external_state_set(
+ vm_external_t e,
+ vm_offset_t offset,
+ vm_external_state_t state)
{
unsigned
int bit, byte;
diff --git a/vm/vm_fault.c b/vm/vm_fault.c
index 7e849616..0fa4d6af 100644
--- a/vm/vm_fault.c
+++ b/vm/vm_fault.c
@@ -51,7 +51,7 @@
#include <mach/memory_object.h>
#include <vm/memory_object_user.user.h>
/* For memory_object_data_{request,unlock} */
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/slab.h>
#if MACH_PCSAMPLE
@@ -88,8 +88,6 @@ struct kmem_cache vm_fault_state_cache;
int vm_object_absent_max = 50;
-int vm_fault_debug = 0;
-
boolean_t vm_fault_dirty_handling = FALSE;
boolean_t vm_fault_interruptible = TRUE;
@@ -125,9 +123,9 @@ void vm_fault_init(void)
* "object" must be locked.
*/
void
-vm_fault_cleanup(object, top_page)
- register vm_object_t object;
- register vm_page_t top_page;
+vm_fault_cleanup(
+ vm_object_t object,
+ vm_page_t top_page)
{
vm_object_paging_end(object);
vm_object_unlock(object);
@@ -204,33 +202,26 @@ vm_fault_cleanup(object, top_page)
* The "result_page" is also left busy. It is not removed
* from the pageout queues.
*/
-vm_fault_return_t vm_fault_page(first_object, first_offset,
- fault_type, must_be_resident, interruptible,
- protection,
- result_page, top_page,
- resume, continuation)
+vm_fault_return_t vm_fault_page(
/* Arguments: */
- vm_object_t first_object; /* Object to begin search */
- vm_offset_t first_offset; /* Offset into object */
- vm_prot_t fault_type; /* What access is requested */
- boolean_t must_be_resident;/* Must page be resident? */
- boolean_t interruptible; /* May fault be interrupted? */
+ vm_object_t first_object, /* Object to begin search */
+ vm_offset_t first_offset, /* Offset into object */
+ vm_prot_t fault_type, /* What access is requested */
+ boolean_t must_be_resident,/* Must page be resident? */
+ boolean_t interruptible, /* May fault be interrupted? */
/* Modifies in place: */
- vm_prot_t *protection; /* Protection for mapping */
+ vm_prot_t *protection, /* Protection for mapping */
/* Returns: */
- vm_page_t *result_page; /* Page found, if successful */
- vm_page_t *top_page; /* Page in top object, if
+ vm_page_t *result_page, /* Page found, if successful */
+ vm_page_t *top_page, /* Page in top object, if
* not result_page.
*/
/* More arguments: */
- boolean_t resume; /* We are restarting. */
- void (*continuation)(); /* Continuation for blocking. */
+ boolean_t resume, /* We are restarting. */
+ void (*continuation)()) /* Continuation for blocking. */
{
- register
vm_page_t m;
- register
vm_object_t object;
- register
vm_offset_t offset;
vm_page_t first_m;
vm_object_t next_object;
@@ -239,7 +230,7 @@ vm_fault_return_t vm_fault_page(first_object, first_offset,
vm_prot_t access_required;
if (resume) {
- register vm_fault_state_t *state =
+ vm_fault_state_t *state =
(vm_fault_state_t *) current_thread()->ith_other;
if (state->vmfp_backoff)
@@ -357,7 +348,7 @@ vm_fault_return_t vm_fault_page(first_object, first_offset,
PAGE_ASSERT_WAIT(m, interruptible);
vm_object_unlock(object);
if (continuation != (void (*)()) 0) {
- register vm_fault_state_t *state =
+ vm_fault_state_t *state =
(vm_fault_state_t *) current_thread()->ith_other;
/*
@@ -1094,7 +1085,7 @@ vm_fault_return_t vm_fault_page(first_object, first_offset,
vm_fault_cleanup(object, first_m);
if (continuation != (void (*)()) 0) {
- register vm_fault_state_t *state =
+ vm_fault_state_t *state =
(vm_fault_state_t *) current_thread()->ith_other;
/*
@@ -1141,9 +1132,9 @@ vm_fault_return_t vm_fault_page(first_object, first_offset,
*/
void
-vm_fault_continue()
+vm_fault_continue(void)
{
- register vm_fault_state_t *state =
+ vm_fault_state_t *state =
(vm_fault_state_t *) current_thread()->ith_other;
(void) vm_fault(state->vmf_map,
@@ -1154,14 +1145,13 @@ vm_fault_continue()
/*NOTREACHED*/
}
-kern_return_t vm_fault(map, vaddr, fault_type, change_wiring,
- resume, continuation)
- vm_map_t map;
- vm_offset_t vaddr;
- vm_prot_t fault_type;
- boolean_t change_wiring;
- boolean_t resume;
- void (*continuation)();
+kern_return_t vm_fault(
+ vm_map_t map,
+ vm_offset_t vaddr,
+ vm_prot_t fault_type,
+ boolean_t change_wiring,
+ boolean_t resume,
+ void (*continuation)())
{
vm_map_version_t version; /* Map version for verificiation */
boolean_t wired; /* Should mapping be wired down? */
@@ -1173,11 +1163,10 @@ kern_return_t vm_fault(map, vaddr, fault_type, change_wiring,
vm_page_t top_page; /* Placeholder page */
kern_return_t kr;
- register
vm_page_t m; /* Fast access to result_page */
if (resume) {
- register vm_fault_state_t *state =
+ vm_fault_state_t *state =
(vm_fault_state_t *) current_thread()->ith_other;
/*
@@ -1253,7 +1242,7 @@ kern_return_t vm_fault(map, vaddr, fault_type, change_wiring,
vm_object_paging_begin(object);
if (continuation != (void (*)()) 0) {
- register vm_fault_state_t *state =
+ vm_fault_state_t *state =
(vm_fault_state_t *) current_thread()->ith_other;
/*
@@ -1307,7 +1296,7 @@ kern_return_t vm_fault(map, vaddr, fault_type, change_wiring,
goto done;
case VM_FAULT_MEMORY_SHORTAGE:
if (continuation != (void (*)()) 0) {
- register vm_fault_state_t *state =
+ vm_fault_state_t *state =
(vm_fault_state_t *) current_thread()->ith_other;
/*
@@ -1490,7 +1479,7 @@ kern_return_t vm_fault(map, vaddr, fault_type, change_wiring,
done:
if (continuation != (void (*)()) 0) {
- register vm_fault_state_t *state =
+ vm_fault_state_t *state =
(vm_fault_state_t *) current_thread()->ith_other;
kmem_cache_free(&vm_fault_state_cache, (vm_offset_t) state);
@@ -1501,21 +1490,19 @@ kern_return_t vm_fault(map, vaddr, fault_type, change_wiring,
return(kr);
}
-kern_return_t vm_fault_wire_fast();
-
/*
* vm_fault_wire:
*
* Wire down a range of virtual addresses in a map.
*/
-void vm_fault_wire(map, entry)
- vm_map_t map;
- vm_map_entry_t entry;
+void vm_fault_wire(
+ vm_map_t map,
+ vm_map_entry_t entry)
{
- register vm_offset_t va;
- register pmap_t pmap;
- register vm_offset_t end_addr = entry->vme_end;
+ vm_offset_t va;
+ pmap_t pmap;
+ vm_offset_t end_addr = entry->vme_end;
pmap = vm_map_pmap(map);
@@ -1544,14 +1531,14 @@ void vm_fault_wire(map, entry)
*
* Unwire a range of virtual addresses in a map.
*/
-void vm_fault_unwire(map, entry)
- vm_map_t map;
- vm_map_entry_t entry;
+void vm_fault_unwire(
+ vm_map_t map,
+ vm_map_entry_t entry)
{
- register vm_offset_t va;
- register pmap_t pmap;
- register vm_offset_t end_addr = entry->vme_end;
- vm_object_t object;
+ vm_offset_t va;
+ pmap_t pmap;
+ vm_offset_t end_addr = entry->vme_end;
+ vm_object_t object;
pmap = vm_map_pmap(map);
@@ -1633,14 +1620,14 @@ void vm_fault_unwire(map, entry)
* other than the common case will return KERN_FAILURE, and the caller
* is expected to call vm_fault().
*/
-kern_return_t vm_fault_wire_fast(map, va, entry)
- vm_map_t map;
- vm_offset_t va;
- vm_map_entry_t entry;
+kern_return_t vm_fault_wire_fast(
+ vm_map_t map,
+ vm_offset_t va,
+ vm_map_entry_t entry)
{
vm_object_t object;
vm_offset_t offset;
- register vm_page_t m;
+ vm_page_t m;
vm_prot_t prot;
vm_stat.faults++; /* needs lock XXX */
@@ -1782,9 +1769,9 @@ kern_return_t vm_fault_wire_fast(map, va, entry)
* Release a page used by vm_fault_copy.
*/
-void vm_fault_copy_cleanup(page, top_page)
- vm_page_t page;
- vm_page_t top_page;
+void vm_fault_copy_cleanup(
+ vm_page_t page,
+ vm_page_t top_page)
{
vm_object_t object = page->object;
@@ -1825,23 +1812,14 @@ void vm_fault_copy_cleanup(page, top_page)
* requested.
*/
kern_return_t vm_fault_copy(
- src_object,
- src_offset,
- src_size,
- dst_object,
- dst_offset,
- dst_map,
- dst_version,
- interruptible
- )
- vm_object_t src_object;
- vm_offset_t src_offset;
- vm_size_t *src_size; /* INOUT */
- vm_object_t dst_object;
- vm_offset_t dst_offset;
- vm_map_t dst_map;
- vm_map_version_t *dst_version;
- boolean_t interruptible;
+ vm_object_t src_object,
+ vm_offset_t src_offset,
+ vm_size_t *src_size, /* INOUT */
+ vm_object_t dst_object,
+ vm_offset_t dst_offset,
+ vm_map_t dst_map,
+ vm_map_version_t *dst_version,
+ boolean_t interruptible)
{
vm_page_t result_page;
vm_prot_t prot;
@@ -2022,13 +2000,11 @@ kern_return_t vm_fault_copy(
* XXX Untested. Also unused. Eventually, this technology
* could be used in vm_fault_copy() to advantage.
*/
-vm_fault_return_t vm_fault_page_overwrite(dst_object, dst_offset, result_page)
- register
- vm_object_t dst_object;
- vm_offset_t dst_offset;
- vm_page_t *result_page; /* OUT */
+vm_fault_return_t vm_fault_page_overwrite(
+ vm_object_t dst_object,
+ vm_offset_t dst_offset,
+ vm_page_t *result_page) /* OUT */
{
- register
vm_page_t dst_page;
#define interruptible FALSE /* XXX */
diff --git a/vm/vm_fault.h b/vm/vm_fault.h
index 0492ccf4..7fdbc417 100644
--- a/vm/vm_fault.h
+++ b/vm/vm_fault.h
@@ -69,4 +69,10 @@ extern void vm_fault_unwire(vm_map_t, vm_map_entry_t);
extern kern_return_t vm_fault_copy(vm_object_t, vm_offset_t, vm_size_t *,
vm_object_t, vm_offset_t, vm_map_t,
vm_map_version_t *, boolean_t);
+
+kern_return_t vm_fault_wire_fast(
+ vm_map_t map,
+ vm_offset_t va,
+ vm_map_entry_t entry);
+
#endif /* _VM_VM_FAULT_H_ */
diff --git a/vm/vm_init.c b/vm/vm_init.c
index 89eb0984..3d1081cc 100644
--- a/vm/vm_init.c
+++ b/vm/vm_init.c
@@ -51,7 +51,7 @@
* This is done only by the first cpu up.
*/
-void vm_mem_bootstrap()
+void vm_mem_bootstrap(void)
{
vm_offset_t start, end;
@@ -79,7 +79,7 @@ void vm_mem_bootstrap()
memory_manager_default_init();
}
-void vm_mem_init()
+void vm_mem_init(void)
{
vm_object_init();
memory_object_proxy_init();
diff --git a/vm/vm_init.h b/vm/vm_init.h
new file mode 100644
index 00000000..42ef48b2
--- /dev/null
+++ b/vm/vm_init.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _VM_VM_INIT_H_
+#define _VM_VM_INIT_H_
+
+extern void vm_mem_init(void);
+extern void vm_mem_bootstrap(void);
+
+#endif /* _VM_VM_INIT_H_ */
diff --git a/vm/vm_kern.c b/vm/vm_kern.c
index fd46e982..9c0a20b7 100644
--- a/vm/vm_kern.c
+++ b/vm/vm_kern.c
@@ -42,6 +42,7 @@
#include <kern/assert.h>
#include <kern/debug.h>
#include <kern/lock.h>
+#include <kern/slab.h>
#include <kern/thread.h>
#include <kern/printf.h>
#include <vm/pmap.h>
@@ -62,9 +63,6 @@ static struct vm_map kernel_map_store;
vm_map_t kernel_map = &kernel_map_store;
vm_map_t kernel_pageable_map;
-extern void kmem_alloc_pages();
-extern void kmem_remap_pages();
-
/*
* projected_buffer_allocate
*
@@ -82,15 +80,14 @@ extern void kmem_remap_pages();
*/
kern_return_t
-projected_buffer_allocate(map, size, persistence, kernel_p,
- user_p, protection, inheritance)
- vm_map_t map;
- vm_size_t size;
- int persistence;
- vm_offset_t *kernel_p;
- vm_offset_t *user_p;
- vm_prot_t protection;
- vm_inherit_t inheritance; /*Currently only VM_INHERIT_NONE supported*/
+projected_buffer_allocate(
+ vm_map_t map,
+ vm_size_t size,
+ int persistence,
+ vm_offset_t *kernel_p,
+ vm_offset_t *user_p,
+ vm_prot_t protection,
+ vm_inherit_t inheritance) /*Currently only VM_INHERIT_NONE supported*/
{
vm_object_t object;
vm_map_entry_t u_entry, k_entry;
@@ -180,13 +177,13 @@ projected_buffer_allocate(map, size, persistence, kernel_p,
*/
kern_return_t
-projected_buffer_map(map, kernel_addr, size, user_p, protection, inheritance)
- vm_map_t map;
- vm_offset_t kernel_addr;
- vm_size_t size;
- vm_offset_t *user_p;
- vm_prot_t protection;
- vm_inherit_t inheritance; /*Currently only VM_INHERIT_NONE supported*/
+projected_buffer_map(
+ vm_map_t map,
+ vm_offset_t kernel_addr,
+ vm_size_t size,
+ vm_offset_t *user_p,
+ vm_prot_t protection,
+ vm_inherit_t inheritance) /*Currently only VM_INHERIT_NONE supported*/
{
vm_map_entry_t u_entry, k_entry;
vm_offset_t physical_addr, user_addr;
@@ -253,15 +250,18 @@ projected_buffer_map(map, kernel_addr, size, user_p, protection, inheritance)
*/
kern_return_t
-projected_buffer_deallocate(map, start, end)
- vm_map_t map;
- vm_offset_t start, end;
+projected_buffer_deallocate(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_offset_t end)
{
vm_map_entry_t entry, k_entry;
+ if (map == VM_MAP_NULL || map == kernel_map)
+ return KERN_INVALID_ARGUMENT;
+
vm_map_lock(map);
- if (map == VM_MAP_NULL || map == kernel_map ||
- !vm_map_lookup_entry(map, start, &entry) ||
+ if (!vm_map_lookup_entry(map, start, &entry) ||
end > entry->vme_end ||
/*Check corresponding kernel entry*/
(k_entry = entry->projected_on) == 0) {
@@ -303,8 +303,7 @@ projected_buffer_deallocate(map, start, end)
*/
kern_return_t
-projected_buffer_collect(map)
- vm_map_t map;
+projected_buffer_collect(vm_map_t map)
{
vm_map_entry_t entry, next;
@@ -330,9 +329,10 @@ projected_buffer_collect(map)
*/
boolean_t
-projected_buffer_in_range(map, start, end)
- vm_map_t map;
- vm_offset_t start, end;
+projected_buffer_in_range(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_offset_t end)
{
vm_map_entry_t entry;
@@ -359,14 +359,15 @@ projected_buffer_in_range(map, start, end)
*/
kern_return_t
-kmem_alloc(map, addrp, size)
- vm_map_t map;
- vm_offset_t *addrp;
- vm_size_t size;
+kmem_alloc(
+ vm_map_t map,
+ vm_offset_t *addrp,
+ vm_size_t size)
{
vm_object_t object;
vm_map_entry_t entry;
vm_offset_t addr;
+ unsigned int attempts;
kern_return_t kr;
/*
@@ -385,12 +386,22 @@ kmem_alloc(map, addrp, size)
size = round_page(size);
object = vm_object_allocate(size);
+ attempts = 0;
+
+retry:
vm_map_lock(map);
kr = vm_map_find_entry(map, &addr, size, (vm_offset_t) 0,
VM_OBJECT_NULL, &entry);
if (kr != KERN_SUCCESS) {
- printf_once("no more room for kmem_alloc in %p\n", map);
vm_map_unlock(map);
+
+ if (attempts == 0) {
+ attempts++;
+ slab_collect();
+ goto retry;
+ }
+
+ printf_once("no more room for kmem_alloc in %p\n", map);
vm_object_deallocate(object);
return kr;
}
@@ -420,113 +431,25 @@ kmem_alloc(map, addrp, size)
}
/*
- * kmem_realloc:
- *
- * Reallocate wired-down memory in the kernel's address map
- * or a submap. Newly allocated pages are not zeroed.
- * This can only be used on regions allocated with kmem_alloc.
- *
- * If successful, the pages in the old region are mapped twice.
- * The old region is unchanged. Use kmem_free to get rid of it.
- */
-kern_return_t kmem_realloc(map, oldaddr, oldsize, newaddrp, newsize)
- vm_map_t map;
- vm_offset_t oldaddr;
- vm_size_t oldsize;
- vm_offset_t *newaddrp;
- vm_size_t newsize;
-{
- vm_offset_t oldmin, oldmax;
- vm_offset_t newaddr;
- vm_object_t object;
- vm_map_entry_t oldentry, newentry;
- kern_return_t kr;
-
- oldmin = trunc_page(oldaddr);
- oldmax = round_page(oldaddr + oldsize);
- oldsize = oldmax - oldmin;
- newsize = round_page(newsize);
-
- /*
- * Find space for the new region.
- */
-
- vm_map_lock(map);
- kr = vm_map_find_entry(map, &newaddr, newsize, (vm_offset_t) 0,
- VM_OBJECT_NULL, &newentry);
- if (kr != KERN_SUCCESS) {
- vm_map_unlock(map);
- printf_once("no more room for kmem_realloc in %p\n", map);
- return kr;
- }
-
- /*
- * Find the VM object backing the old region.
- */
-
- if (!vm_map_lookup_entry(map, oldmin, &oldentry))
- panic("kmem_realloc");
- object = oldentry->object.vm_object;
-
- /*
- * Increase the size of the object and
- * fill in the new region.
- */
-
- vm_object_reference(object);
- vm_object_lock(object);
- if (object->size != oldsize)
- panic("kmem_realloc");
- object->size = newsize;
- vm_object_unlock(object);
-
- newentry->object.vm_object = object;
- newentry->offset = 0;
-
- /*
- * Since we have not given out this address yet,
- * it is safe to unlock the map. We are trusting
- * that nobody will play with either region.
- */
-
- vm_map_unlock(map);
-
- /*
- * Remap the pages in the old region and
- * allocate more pages for the new region.
- */
-
- kmem_remap_pages(object, 0,
- newaddr, newaddr + oldsize,
- VM_PROT_DEFAULT);
- kmem_alloc_pages(object, oldsize,
- newaddr + oldsize, newaddr + newsize,
- VM_PROT_DEFAULT);
-
- *newaddrp = newaddr;
- return KERN_SUCCESS;
-}
-
-/*
* kmem_alloc_wired:
*
* Allocate wired-down memory in the kernel's address map
* or a submap. The memory is not zero-filled.
*
* The memory is allocated in the kernel_object.
- * It may not be copied with vm_map_copy, and
- * it may not be reallocated with kmem_realloc.
+ * It may not be copied with vm_map_copy.
*/
kern_return_t
-kmem_alloc_wired(map, addrp, size)
- vm_map_t map;
- vm_offset_t *addrp;
- vm_size_t size;
+kmem_alloc_wired(
+ vm_map_t map,
+ vm_offset_t *addrp,
+ vm_size_t size)
{
vm_map_entry_t entry;
vm_offset_t offset;
vm_offset_t addr;
+ unsigned int attempts;
kern_return_t kr;
/*
@@ -537,12 +460,22 @@ kmem_alloc_wired(map, addrp, size)
*/
size = round_page(size);
+ attempts = 0;
+
+retry:
vm_map_lock(map);
kr = vm_map_find_entry(map, &addr, size, (vm_offset_t) 0,
kernel_object, &entry);
if (kr != KERN_SUCCESS) {
- printf_once("no more room for kmem_alloc_wired in %p\n", map);
vm_map_unlock(map);
+
+ if (attempts == 0) {
+ attempts++;
+ slab_collect();
+ goto retry;
+ }
+
+ printf_once("no more room for kmem_alloc_wired in %p\n", map);
return kr;
}
@@ -591,14 +524,15 @@ kmem_alloc_wired(map, addrp, size)
*/
kern_return_t
-kmem_alloc_aligned(map, addrp, size)
- vm_map_t map;
- vm_offset_t *addrp;
- vm_size_t size;
+kmem_alloc_aligned(
+ vm_map_t map,
+ vm_offset_t *addrp,
+ vm_size_t size)
{
vm_map_entry_t entry;
vm_offset_t offset;
vm_offset_t addr;
+ unsigned int attempts;
kern_return_t kr;
if ((size & (size - 1)) != 0)
@@ -612,12 +546,22 @@ kmem_alloc_aligned(map, addrp, size)
*/
size = round_page(size);
+ attempts = 0;
+
+retry:
vm_map_lock(map);
kr = vm_map_find_entry(map, &addr, size, size - 1,
kernel_object, &entry);
if (kr != KERN_SUCCESS) {
- printf_once("no more rooom for kmem_alloc_aligned in %p\n", map);
vm_map_unlock(map);
+
+ if (attempts == 0) {
+ attempts++;
+ slab_collect();
+ goto retry;
+ }
+
+ printf_once("no more room for kmem_alloc_aligned in %p\n", map);
return kr;
}
@@ -665,10 +609,10 @@ kmem_alloc_aligned(map, addrp, size)
*/
kern_return_t
-kmem_alloc_pageable(map, addrp, size)
- vm_map_t map;
- vm_offset_t *addrp;
- vm_size_t size;
+kmem_alloc_pageable(
+ vm_map_t map,
+ vm_offset_t *addrp,
+ vm_size_t size)
{
vm_offset_t addr;
kern_return_t kr;
@@ -696,10 +640,10 @@ kmem_alloc_pageable(map, addrp, size)
*/
void
-kmem_free(map, addr, size)
- vm_map_t map;
- vm_offset_t addr;
- vm_size_t size;
+kmem_free(
+ vm_map_t map,
+ vm_offset_t addr,
+ vm_size_t size)
{
kern_return_t kr;
@@ -714,11 +658,12 @@ kmem_free(map, addr, size)
* a submap.
*/
void
-kmem_alloc_pages(object, offset, start, end, protection)
- register vm_object_t object;
- register vm_offset_t offset;
- register vm_offset_t start, end;
- vm_prot_t protection;
+kmem_alloc_pages(
+ vm_object_t object,
+ vm_offset_t offset,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_prot_t protection)
{
/*
* Mark the pmap region as not pageable.
@@ -726,7 +671,7 @@ kmem_alloc_pages(object, offset, start, end, protection)
pmap_pageable(kernel_pmap, start, end, FALSE);
while (start < end) {
- register vm_page_t mem;
+ vm_page_t mem;
vm_object_lock(object);
@@ -769,11 +714,12 @@ kmem_alloc_pages(object, offset, start, end, protection)
* a submap.
*/
void
-kmem_remap_pages(object, offset, start, end, protection)
- register vm_object_t object;
- register vm_offset_t offset;
- register vm_offset_t start, end;
- vm_prot_t protection;
+kmem_remap_pages(
+ vm_object_t object,
+ vm_offset_t offset,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_prot_t protection)
{
/*
* Mark the pmap region as not pageable.
@@ -781,7 +727,7 @@ kmem_remap_pages(object, offset, start, end, protection)
pmap_pageable(kernel_pmap, start, end, FALSE);
while (start < end) {
- register vm_page_t mem;
+ vm_page_t mem;
vm_object_lock(object);
@@ -827,11 +773,13 @@ kmem_remap_pages(object, offset, start, end, protection)
*/
void
-kmem_submap(map, parent, min, max, size, pageable)
- vm_map_t map, parent;
- vm_offset_t *min, *max;
- vm_size_t size;
- boolean_t pageable;
+kmem_submap(
+ vm_map_t map,
+ vm_map_t parent,
+ vm_offset_t *min,
+ vm_offset_t *max,
+ vm_size_t size,
+ boolean_t pageable)
{
vm_offset_t addr;
kern_return_t kr;
@@ -845,7 +793,7 @@ kmem_submap(map, parent, min, max, size, pageable)
*/
vm_object_reference(vm_submap_object);
- addr = (vm_offset_t) vm_map_min(parent);
+ addr = vm_map_min(parent);
kr = vm_map_enter(parent, &addr, size,
(vm_offset_t) 0, TRUE,
vm_submap_object, (vm_offset_t) 0, FALSE,
@@ -869,9 +817,9 @@ kmem_submap(map, parent, min, max, size, pageable)
* Initialize the kernel's virtual memory map, taking
* into account all memory allocated up to this time.
*/
-void kmem_init(start, end)
- vm_offset_t start;
- vm_offset_t end;
+void kmem_init(
+ vm_offset_t start,
+ vm_offset_t end)
{
vm_map_setup(kernel_map, pmap_kernel(), VM_MIN_KERNEL_ADDRESS, end,
FALSE);
@@ -879,7 +827,6 @@ void kmem_init(start, end)
/*
* Reserve virtual memory allocated up to this time.
*/
-
if (start != VM_MIN_KERNEL_ADDRESS) {
kern_return_t rc;
vm_offset_t addr = VM_MIN_KERNEL_ADDRESS;
@@ -890,7 +837,7 @@ void kmem_init(start, end)
VM_PROT_DEFAULT, VM_PROT_ALL,
VM_INHERIT_DEFAULT);
if (rc)
- panic("%s:%d: vm_map_enter failed (%d)\n", rc);
+ panic("vm_map_enter failed (%d)\n", rc);
}
}
@@ -907,21 +854,19 @@ void kmem_init(start, end)
*/
kern_return_t
-kmem_io_map_copyout(map, addr, alloc_addr, alloc_size, copy, min_size)
- vm_map_t map;
- vm_offset_t *addr; /* actual addr of data */
- vm_offset_t *alloc_addr; /* page aligned addr */
- vm_size_t *alloc_size; /* size allocated */
- vm_map_copy_t copy;
- vm_size_t min_size; /* Do at least this much */
+kmem_io_map_copyout(
+ vm_map_t map,
+ vm_offset_t *addr, /* actual addr of data */
+ vm_offset_t *alloc_addr, /* page aligned addr */
+ vm_size_t *alloc_size, /* size allocated */
+ vm_map_copy_t copy,
+ vm_size_t min_size) /* Do at least this much */
{
vm_offset_t myaddr, offset;
vm_size_t mysize, copy_size;
kern_return_t ret;
- register
vm_page_t *page_list;
vm_map_copy_t new_copy;
- register
int i;
assert(copy->type == VM_MAP_COPY_PAGE_LIST);
@@ -1013,10 +958,10 @@ kmem_io_map_copyout(map, addr, alloc_addr, alloc_size, copy, min_size)
*/
void
-kmem_io_map_deallocate(map, addr, size)
- vm_map_t map;
- vm_offset_t addr;
- vm_size_t size;
+kmem_io_map_deallocate(
+ vm_map_t map,
+ vm_offset_t addr,
+ vm_size_t size)
{
/*
* Remove the mappings. The pmap_remove is needed.
@@ -1035,10 +980,11 @@ kmem_io_map_deallocate(map, addr, size)
* and the kernel map/submaps.
*/
-int copyinmap(map, fromaddr, toaddr, length)
- vm_map_t map;
- char *fromaddr, *toaddr;
- int length;
+int copyinmap(
+ vm_map_t map,
+ char *fromaddr,
+ char *toaddr,
+ int length)
{
if (vm_map_pmap(map) == kernel_pmap) {
/* assume a correct copy */
@@ -1061,10 +1007,11 @@ int copyinmap(map, fromaddr, toaddr, length)
* and the kernel map/submaps.
*/
-int copyoutmap(map, fromaddr, toaddr, length)
- vm_map_t map;
- char *fromaddr, *toaddr;
- int length;
+int copyoutmap(
+ vm_map_t map,
+ char *fromaddr,
+ char *toaddr,
+ int length)
{
if (vm_map_pmap(map) == kernel_pmap) {
/* assume a correct copy */
diff --git a/vm/vm_kern.h b/vm/vm_kern.h
index 22b7c123..fb8ac7f8 100644
--- a/vm/vm_kern.h
+++ b/vm/vm_kern.h
@@ -54,8 +54,6 @@ extern kern_return_t kmem_alloc_pageable(vm_map_t, vm_offset_t *,
vm_size_t);
extern kern_return_t kmem_alloc_wired(vm_map_t, vm_offset_t *, vm_size_t);
extern kern_return_t kmem_alloc_aligned(vm_map_t, vm_offset_t *, vm_size_t);
-extern kern_return_t kmem_realloc(vm_map_t, vm_offset_t, vm_size_t,
- vm_offset_t *, vm_size_t);
extern void kmem_free(vm_map_t, vm_offset_t, vm_size_t);
extern void kmem_submap(vm_map_t, vm_map_t, vm_offset_t *,
@@ -82,4 +80,18 @@ extern boolean_t projected_buffer_in_range(
vm_offset_t start,
vm_offset_t end);
+extern void kmem_alloc_pages(
+ vm_object_t object,
+ vm_offset_t offset,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_prot_t protection);
+
+extern void kmem_remap_pages(
+ vm_object_t object,
+ vm_offset_t offset,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_prot_t protection);
+
#endif /* _VM_VM_KERN_H_ */
diff --git a/vm/vm_map.c b/vm/vm_map.c
index 47db118f..ae3ce21f 100644
--- a/vm/vm_map.c
+++ b/vm/vm_map.c
@@ -55,22 +55,9 @@
#if MACH_KDB
#include <ddb/db_output.h>
+#include <vm/vm_print.h>
#endif /* MACH_KDB */
-
-/* Forward declarations */
-kern_return_t vm_map_delete(
- vm_map_t map,
- vm_offset_t start,
- vm_offset_t end);
-
-kern_return_t vm_map_copyout_page_list(
- vm_map_t dst_map,
- vm_offset_t *dst_addr, /* OUT */
- vm_map_copy_t copy);
-
-void vm_map_copy_page_discard (vm_map_copy_t copy);
-
/*
* Macros to copy a vm_map_entry. We must be careful to correctly
* manage the wired page count. vm_map_entry_copy() creates a new
@@ -142,8 +129,6 @@ struct kmem_cache vm_map_entry_cache; /* cache for vm_map_entry structures */
struct kmem_cache vm_map_kentry_cache; /* cache for kernel entry structures */
struct kmem_cache vm_map_copy_cache; /* cache for vm_map_copy structures */
-boolean_t vm_map_lookup_entry(); /* forward declaration */
-
/*
* Placeholder object for submap operations. This object is dropped
* into the range by a call to vm_map_find, and removed when
@@ -209,11 +194,12 @@ void vm_map_init(void)
*/
}
-void vm_map_setup(map, pmap, min, max, pageable)
- vm_map_t map;
- pmap_t pmap;
- vm_offset_t min, max;
- boolean_t pageable;
+void vm_map_setup(
+ vm_map_t map,
+ pmap_t pmap,
+ vm_offset_t min,
+ vm_offset_t max,
+ boolean_t pageable)
{
vm_map_first_entry(map) = vm_map_to_entry(map);
vm_map_last_entry(map) = vm_map_to_entry(map);
@@ -222,6 +208,7 @@ void vm_map_setup(map, pmap, min, max, pageable)
rbtree_init(&map->hdr.tree);
map->size = 0;
+ map->user_wired = 0;
map->ref_count = 1;
map->pmap = pmap;
map->min_offset = min;
@@ -242,12 +229,13 @@ void vm_map_setup(map, pmap, min, max, pageable)
* the given physical map structure, and having
* the given lower and upper address bounds.
*/
-vm_map_t vm_map_create(pmap, min, max, pageable)
- pmap_t pmap;
- vm_offset_t min, max;
- boolean_t pageable;
+vm_map_t vm_map_create(
+ pmap_t pmap,
+ vm_offset_t min,
+ vm_offset_t max,
+ boolean_t pageable)
{
- register vm_map_t result;
+ vm_map_t result;
result = (vm_map_t) kmem_cache_alloc(&vm_map_cache);
if (result == VM_MAP_NULL)
@@ -271,10 +259,10 @@ vm_map_t vm_map_create(pmap, min, max, pageable)
_vm_map_entry_create(&(copy)->cpy_hdr)
vm_map_entry_t _vm_map_entry_create(map_header)
- register struct vm_map_header *map_header;
+ const struct vm_map_header *map_header;
{
- register kmem_cache_t cache;
- register vm_map_entry_t entry;
+ kmem_cache_t cache;
+ vm_map_entry_t entry;
if (map_header->entries_pageable)
cache = &vm_map_entry_cache;
@@ -300,10 +288,10 @@ vm_map_entry_t _vm_map_entry_create(map_header)
_vm_map_entry_dispose(&(copy)->cpy_hdr, (entry))
void _vm_map_entry_dispose(map_header, entry)
- register struct vm_map_header *map_header;
- register vm_map_entry_t entry;
+ const struct vm_map_header *map_header;
+ vm_map_entry_t entry;
{
- register kmem_cache_t cache;
+ kmem_cache_t cache;
if (map_header->entries_pageable)
cache = &vm_map_entry_cache;
@@ -385,8 +373,7 @@ static inline int vm_map_entry_cmp_insert(const struct rbtree_node *a,
* Creates another valid reference to the given map.
*
*/
-void vm_map_reference(map)
- register vm_map_t map;
+void vm_map_reference(vm_map_t map)
{
if (map == VM_MAP_NULL)
return;
@@ -403,10 +390,9 @@ void vm_map_reference(map)
* destroying it if no references remain.
* The map should not be locked.
*/
-void vm_map_deallocate(map)
- register vm_map_t map;
+void vm_map_deallocate(vm_map_t map)
{
- register int c;
+ int c;
if (map == VM_MAP_NULL)
return;
@@ -448,13 +434,13 @@ void vm_map_deallocate(map)
* result indicates whether the address is
* actually contained in the map.
*/
-boolean_t vm_map_lookup_entry(map, address, entry)
- register vm_map_t map;
- register vm_offset_t address;
- vm_map_entry_t *entry; /* OUT */
+boolean_t vm_map_lookup_entry(
+ vm_map_t map,
+ vm_offset_t address,
+ vm_map_entry_t *entry) /* OUT */
{
- register struct rbtree_node *node;
- register vm_map_entry_t hint;
+ struct rbtree_node *node;
+ vm_map_entry_t hint;
/*
* First, make a quick check to see if we are already
@@ -505,10 +491,11 @@ boolean_t vm_map_lookup_entry(map, address, entry)
*/
boolean_t
-invalid_user_access(map, start, end, prot)
- vm_map_t map;
- vm_offset_t start, end;
- vm_prot_t prot;
+invalid_user_access(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_prot_t prot)
{
vm_map_entry_t entry;
@@ -532,17 +519,17 @@ invalid_user_access(map, start, end, prot)
* are initialized to zero. If an object is supplied,
* then an existing entry may be extended.
*/
-kern_return_t vm_map_find_entry(map, address, size, mask, object, o_entry)
- register vm_map_t map;
- vm_offset_t *address; /* OUT */
- vm_size_t size;
- vm_offset_t mask;
- vm_object_t object;
- vm_map_entry_t *o_entry; /* OUT */
+kern_return_t vm_map_find_entry(
+ vm_map_t map,
+ vm_offset_t *address, /* OUT */
+ vm_size_t size,
+ vm_offset_t mask,
+ vm_object_t object,
+ vm_map_entry_t *o_entry) /* OUT */
{
- register vm_map_entry_t entry, new_entry;
- register vm_offset_t start;
- register vm_offset_t end;
+ vm_map_entry_t entry, new_entry;
+ vm_offset_t start;
+ vm_offset_t end;
/*
* Look for the first possible address;
@@ -561,7 +548,7 @@ kern_return_t vm_map_find_entry(map, address, size, mask, object, o_entry)
*/
while (TRUE) {
- register vm_map_entry_t next;
+ vm_map_entry_t next;
/*
* Find the end of the proposed new region.
@@ -686,8 +673,8 @@ kern_return_t vm_map_find_entry(map, address, size, mask, object, o_entry)
return(KERN_SUCCESS);
}
-int vm_map_pmap_enter_print = FALSE;
-int vm_map_pmap_enter_enable = FALSE;
+boolean_t vm_map_pmap_enter_print = FALSE;
+boolean_t vm_map_pmap_enter_enable = FALSE;
/*
* Routine: vm_map_pmap_enter
@@ -704,19 +691,16 @@ int vm_map_pmap_enter_enable = FALSE;
* The source map should not be locked on entry.
*/
void
-vm_map_pmap_enter(map, addr, end_addr, object, offset, protection)
- vm_map_t map;
- register
- vm_offset_t addr;
- register
- vm_offset_t end_addr;
- register
- vm_object_t object;
- vm_offset_t offset;
- vm_prot_t protection;
+vm_map_pmap_enter(
+ vm_map_t map,
+ vm_offset_t addr,
+ vm_offset_t end_addr,
+ vm_object_t object,
+ vm_offset_t offset,
+ vm_prot_t protection)
{
while (addr < end_addr) {
- register vm_page_t m;
+ vm_page_t m;
vm_object_lock(object);
vm_object_paging_begin(object);
@@ -765,27 +749,22 @@ vm_map_pmap_enter(map, addr, end_addr, object, offset, protection)
* Arguments are as defined in the vm_map call.
*/
kern_return_t vm_map_enter(
- map,
- address, size, mask, anywhere,
- object, offset, needs_copy,
- cur_protection, max_protection, inheritance)
- register
- vm_map_t map;
- vm_offset_t *address; /* IN/OUT */
- vm_size_t size;
- vm_offset_t mask;
- boolean_t anywhere;
- vm_object_t object;
- vm_offset_t offset;
- boolean_t needs_copy;
- vm_prot_t cur_protection;
- vm_prot_t max_protection;
- vm_inherit_t inheritance;
+ vm_map_t map,
+ vm_offset_t *address, /* IN/OUT */
+ vm_size_t size,
+ vm_offset_t mask,
+ boolean_t anywhere,
+ vm_object_t object,
+ vm_offset_t offset,
+ boolean_t needs_copy,
+ vm_prot_t cur_protection,
+ vm_prot_t max_protection,
+ vm_inherit_t inheritance)
{
- register vm_map_entry_t entry;
- register vm_offset_t start;
- register vm_offset_t end;
- kern_return_t result = KERN_SUCCESS;
+ vm_map_entry_t entry;
+ vm_offset_t start;
+ vm_offset_t end;
+ kern_return_t result = KERN_SUCCESS;
#define RETURN(value) { result = value; goto BailOut; }
@@ -831,7 +810,7 @@ kern_return_t vm_map_enter(
*/
while (TRUE) {
- register vm_map_entry_t next;
+ vm_map_entry_t next;
/*
* Find the end of the proposed new region.
@@ -979,7 +958,7 @@ kern_return_t vm_map_enter(
*/
/**/ {
- register vm_map_entry_t new_entry;
+ vm_map_entry_t new_entry;
new_entry = vm_map_entry_create(map);
@@ -1050,14 +1029,12 @@ kern_return_t vm_map_enter(
* the specified address; if necessary,
* it splits the entry into two.
*/
-void _vm_map_clip_start();
#define vm_map_clip_start(map, entry, startaddr) \
MACRO_BEGIN \
if ((startaddr) > (entry)->vme_start) \
_vm_map_clip_start(&(map)->hdr,(entry),(startaddr)); \
MACRO_END
-void _vm_map_copy_clip_start();
#define vm_map_copy_clip_start(copy, entry, startaddr) \
MACRO_BEGIN \
if ((startaddr) > (entry)->vme_start) \
@@ -1068,12 +1045,12 @@ void _vm_map_copy_clip_start();
* This routine is called only when it is known that
* the entry must be split.
*/
-void _vm_map_clip_start(map_header, entry, start)
- register struct vm_map_header *map_header;
- register vm_map_entry_t entry;
- register vm_offset_t start;
+void _vm_map_clip_start(
+ struct vm_map_header *map_header,
+ vm_map_entry_t entry,
+ vm_offset_t start)
{
- register vm_map_entry_t new_entry;
+ vm_map_entry_t new_entry;
/*
* Split off the front portion --
@@ -1105,14 +1082,12 @@ void _vm_map_clip_start(map_header, entry, start)
* the specified address; if necessary,
* it splits the entry into two.
*/
-void _vm_map_clip_end();
#define vm_map_clip_end(map, entry, endaddr) \
MACRO_BEGIN \
if ((endaddr) < (entry)->vme_end) \
_vm_map_clip_end(&(map)->hdr,(entry),(endaddr)); \
MACRO_END
-void _vm_map_copy_clip_end();
#define vm_map_copy_clip_end(copy, entry, endaddr) \
MACRO_BEGIN \
if ((endaddr) < (entry)->vme_end) \
@@ -1123,12 +1098,12 @@ void _vm_map_copy_clip_end();
* This routine is called only when it is known that
* the entry must be split.
*/
-void _vm_map_clip_end(map_header, entry, end)
- register struct vm_map_header *map_header;
- register vm_map_entry_t entry;
- register vm_offset_t end;
+void _vm_map_clip_end(
+ struct vm_map_header *map_header,
+ vm_map_entry_t entry,
+ vm_offset_t end)
{
- register vm_map_entry_t new_entry;
+ vm_map_entry_t new_entry;
/*
* Create a new entry and insert it
@@ -1183,15 +1158,15 @@ void _vm_map_clip_end(map_header, entry, end)
* range from the superior map, and then destroy the
* submap (if desired). [Better yet, don't try it.]
*/
-kern_return_t vm_map_submap(map, start, end, submap)
- register vm_map_t map;
- register vm_offset_t start;
- register vm_offset_t end;
- vm_map_t submap;
+kern_return_t vm_map_submap(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_map_t submap)
{
vm_map_entry_t entry;
- register kern_return_t result = KERN_INVALID_ARGUMENT;
- register vm_object_t object;
+ kern_return_t result = KERN_INVALID_ARGUMENT;
+ vm_object_t object;
vm_map_lock(map);
@@ -1231,15 +1206,15 @@ kern_return_t vm_map_submap(map, start, end, submap)
* specified, the maximum protection is to be set;
* otherwise, only the current protection is affected.
*/
-kern_return_t vm_map_protect(map, start, end, new_prot, set_max)
- register vm_map_t map;
- register vm_offset_t start;
- register vm_offset_t end;
- register vm_prot_t new_prot;
- register boolean_t set_max;
+kern_return_t vm_map_protect(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_prot_t new_prot,
+ boolean_t set_max)
{
- register vm_map_entry_t current;
- vm_map_entry_t entry;
+ vm_map_entry_t current;
+ vm_map_entry_t entry;
vm_map_lock(map);
@@ -1319,13 +1294,13 @@ kern_return_t vm_map_protect(map, start, end, new_prot, set_max)
* affects how the map will be shared with
* child maps at the time of vm_map_fork.
*/
-kern_return_t vm_map_inherit(map, start, end, new_inheritance)
- register vm_map_t map;
- register vm_offset_t start;
- register vm_offset_t end;
- register vm_inherit_t new_inheritance;
+kern_return_t vm_map_inherit(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_inherit_t new_inheritance)
{
- register vm_map_entry_t entry;
+ vm_map_entry_t entry;
vm_map_entry_t temp_entry;
vm_map_lock(map);
@@ -1368,14 +1343,14 @@ kern_return_t vm_map_inherit(map, start, end, new_inheritance)
* Callers should use macros in vm/vm_map.h (i.e. vm_map_pageable,
* or vm_map_pageable_user); don't call vm_map_pageable directly.
*/
-kern_return_t vm_map_pageable_common(map, start, end, access_type, user_wire)
- register vm_map_t map;
- register vm_offset_t start;
- register vm_offset_t end;
- register vm_prot_t access_type;
- boolean_t user_wire;
+kern_return_t vm_map_pageable_common(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_offset_t end,
+ vm_prot_t access_type,
+ boolean_t user_wire)
{
- register vm_map_entry_t entry;
+ vm_map_entry_t entry;
vm_map_entry_t start_entry;
vm_map_lock(map);
@@ -1435,7 +1410,10 @@ kern_return_t vm_map_pageable_common(map, start, end, access_type, user_wire)
if (user_wire) {
if (--(entry->user_wired_count) == 0)
+ {
+ map->user_wired -= entry->vme_end - entry->vme_start;
entry->wired_count--;
+ }
}
else {
entry->wired_count--;
@@ -1512,7 +1490,10 @@ kern_return_t vm_map_pageable_common(map, start, end, access_type, user_wire)
if (user_wire) {
if ((entry->user_wired_count)++ == 0)
+ {
+ map->user_wired += entry->vme_end - entry->vme_start;
entry->wired_count++;
+ }
}
else {
entry->wired_count++;
@@ -1538,6 +1519,7 @@ kern_return_t vm_map_pageable_common(map, start, end, access_type, user_wire)
(entry->vme_end > start)) {
if (user_wire) {
if (--(entry->user_wired_count) == 0)
+ map->user_wired -= entry->vme_end - entry->vme_start;
entry->wired_count--;
}
else {
@@ -1617,12 +1599,12 @@ kern_return_t vm_map_pageable_common(map, start, end, access_type, user_wire)
*
* Deallocate the given entry from the target map.
*/
-void vm_map_entry_delete(map, entry)
- register vm_map_t map;
- register vm_map_entry_t entry;
+void vm_map_entry_delete(
+ vm_map_t map,
+ vm_map_entry_t entry)
{
- register vm_offset_t s, e;
- register vm_object_t object;
+ vm_offset_t s, e;
+ vm_object_t object;
extern vm_object_t kernel_object;
s = entry->vme_start;
@@ -1653,6 +1635,8 @@ void vm_map_entry_delete(map, entry)
if (entry->wired_count != 0) {
vm_fault_unwire(map, entry);
entry->wired_count = 0;
+ if (entry->user_wired_count)
+ map->user_wired -= entry->vme_end - entry->vme_start;
entry->user_wired_count = 0;
}
@@ -1701,10 +1685,10 @@ void vm_map_entry_delete(map, entry)
* map.
*/
-kern_return_t vm_map_delete(map, start, end)
- register vm_map_t map;
- register vm_offset_t start;
- register vm_offset_t end;
+kern_return_t vm_map_delete(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_offset_t end)
{
vm_map_entry_t entry;
vm_map_entry_t first_entry;
@@ -1784,12 +1768,12 @@ kern_return_t vm_map_delete(map, start, end)
* Remove the given address range from the target map.
* This is the exported form of vm_map_delete.
*/
-kern_return_t vm_map_remove(map, start, end)
- register vm_map_t map;
- register vm_offset_t start;
- register vm_offset_t end;
+kern_return_t vm_map_remove(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_offset_t end)
{
- register kern_return_t result;
+ kern_return_t result;
vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end);
@@ -1807,12 +1791,11 @@ kern_return_t vm_map_remove(map, start, end)
* that have not already been stolen.
*/
void
-vm_map_copy_steal_pages(copy)
-vm_map_copy_t copy;
+vm_map_copy_steal_pages(vm_map_copy_t copy)
{
- register vm_page_t m, new_m;
- register int i;
- vm_object_t object;
+ vm_page_t m, new_m;
+ int i;
+ vm_object_t object;
for (i = 0; i < copy->cpy_npages; i++) {
@@ -1854,8 +1837,7 @@ vm_map_copy_t copy;
* stolen, they are freed. If the pages are not stolen, they
* are unbusied, and associated state is cleaned up.
*/
-void vm_map_copy_page_discard(copy)
-vm_map_copy_t copy;
+void vm_map_copy_page_discard(vm_map_copy_t copy)
{
while (copy->cpy_npages > 0) {
vm_page_t m;
@@ -1900,8 +1882,7 @@ vm_map_copy_t copy;
* vm_map_copyin).
*/
void
-vm_map_copy_discard(copy)
- vm_map_copy_t copy;
+vm_map_copy_discard(vm_map_copy_t copy)
{
free_next_copy:
if (copy == VM_MAP_COPY_NULL)
@@ -1942,7 +1923,7 @@ free_next_copy:
* here to avoid tail recursion.
*/
if (copy->cpy_cont == vm_map_copy_discard_cont) {
- register vm_map_copy_t new_copy;
+ vm_map_copy_t new_copy;
new_copy = (vm_map_copy_t) copy->cpy_cont_args;
kmem_cache_free(&vm_map_copy_cache, (vm_offset_t) copy);
@@ -1977,8 +1958,7 @@ free_next_copy:
* deallocation will not fail.
*/
vm_map_copy_t
-vm_map_copy_copy(copy)
- vm_map_copy_t copy;
+vm_map_copy_copy(vm_map_copy_t copy)
{
vm_map_copy_t new_copy;
@@ -2024,9 +2004,9 @@ vm_map_copy_copy(copy)
* A version of vm_map_copy_discard that can be called
* as a continuation from a vm_map_copy page list.
*/
-kern_return_t vm_map_copy_discard_cont(cont_args, copy_result)
-vm_map_copyin_args_t cont_args;
-vm_map_copy_t *copy_result; /* OUT */
+kern_return_t vm_map_copy_discard_cont(
+vm_map_copyin_args_t cont_args,
+vm_map_copy_t *copy_result) /* OUT */
{
vm_map_copy_discard((vm_map_copy_t) cont_args);
if (copy_result != (vm_map_copy_t *)0)
@@ -2081,11 +2061,11 @@ vm_map_copy_t *copy_result; /* OUT */
* atomically and interruptibly, an error indication is
* returned.
*/
-kern_return_t vm_map_copy_overwrite(dst_map, dst_addr, copy, interruptible)
- vm_map_t dst_map;
- vm_offset_t dst_addr;
- vm_map_copy_t copy;
- boolean_t interruptible;
+kern_return_t vm_map_copy_overwrite(
+ vm_map_t dst_map,
+ vm_offset_t dst_addr,
+ vm_map_copy_t copy,
+ boolean_t interruptible)
{
vm_size_t size;
vm_offset_t start;
@@ -2304,6 +2284,8 @@ start_pass_1:
entry->offset = copy_entry->offset;
entry->needs_copy = copy_entry->needs_copy;
entry->wired_count = 0;
+ if (entry->user_wired_count)
+ dst_map->user_wired -= entry->vme_end - entry->vme_start;
entry->user_wired_count = 0;
vm_map_copy_entry_unlink(copy, copy_entry);
@@ -2458,19 +2440,16 @@ start_pass_1:
* If successful, consumes the copy object.
* Otherwise, the caller is responsible for it.
*/
-kern_return_t vm_map_copyout(dst_map, dst_addr, copy)
- register
- vm_map_t dst_map;
- vm_offset_t *dst_addr; /* OUT */
- register
- vm_map_copy_t copy;
+kern_return_t vm_map_copyout(
+ vm_map_t dst_map,
+ vm_offset_t *dst_addr, /* OUT */
+ vm_map_copy_t copy)
{
vm_size_t size;
vm_size_t adjustment;
vm_offset_t start;
vm_offset_t vm_copy_start;
vm_map_entry_t last;
- register
vm_map_entry_t entry;
/*
@@ -2616,9 +2595,9 @@ kern_return_t vm_map_copyout(dst_map, dst_addr, copy)
* map the pages into the destination map.
*/
if (entry->wired_count != 0) {
- register vm_offset_t va;
- vm_offset_t offset;
- register vm_object_t object;
+ vm_offset_t va;
+ vm_offset_t offset;
+ vm_object_t object;
object = entry->object.vm_object;
offset = entry->offset;
@@ -2630,7 +2609,7 @@ kern_return_t vm_map_copyout(dst_map, dst_addr, copy)
TRUE);
while (va < entry->vme_end) {
- register vm_page_t m;
+ vm_page_t m;
/*
* Look up the page in the object.
@@ -2715,19 +2694,16 @@ kern_return_t vm_map_copyout(dst_map, dst_addr, copy)
* Version of vm_map_copyout() for page list vm map copies.
*
*/
-kern_return_t vm_map_copyout_page_list(dst_map, dst_addr, copy)
- register
- vm_map_t dst_map;
- vm_offset_t *dst_addr; /* OUT */
- register
- vm_map_copy_t copy;
+kern_return_t vm_map_copyout_page_list(
+ vm_map_t dst_map,
+ vm_offset_t *dst_addr, /* OUT */
+ vm_map_copy_t copy)
{
vm_size_t size;
vm_offset_t start;
vm_offset_t end;
vm_offset_t offset;
vm_map_entry_t last;
- register
vm_object_t object;
vm_page_t *page_list, m;
vm_map_entry_t entry;
@@ -2905,6 +2881,7 @@ create_object:
if (must_wire) {
entry->wired_count = 1;
+ dst_map->user_wired += entry->vme_end - entry->vme_start;
entry->user_wired_count = 1;
} else {
entry->wired_count = 0;
@@ -3105,12 +3082,12 @@ error:
* In/out conditions:
* The source map should not be locked on entry.
*/
-kern_return_t vm_map_copyin(src_map, src_addr, len, src_destroy, copy_result)
- vm_map_t src_map;
- vm_offset_t src_addr;
- vm_size_t len;
- boolean_t src_destroy;
- vm_map_copy_t *copy_result; /* OUT */
+kern_return_t vm_map_copyin(
+ vm_map_t src_map,
+ vm_offset_t src_addr,
+ vm_size_t len,
+ boolean_t src_destroy,
+ vm_map_copy_t *copy_result) /* OUT */
{
vm_map_entry_t tmp_entry; /* Result of last map lookup --
* in multi-level lookup, this
@@ -3124,7 +3101,6 @@ kern_return_t vm_map_copyin(src_map, src_addr, len, src_destroy, copy_result)
vm_offset_t src_end; /* End of entire region to be
* copied */
- register
vm_map_copy_t copy; /* Resulting copy */
/*
@@ -3191,14 +3167,12 @@ kern_return_t vm_map_copyin(src_map, src_addr, len, src_destroy, copy_result)
*/
while (TRUE) {
- register
vm_map_entry_t src_entry = tmp_entry; /* Top-level entry */
vm_size_t src_size; /* Size of source
* map entry (in both
* maps)
*/
- register
vm_object_t src_object; /* Object to copy */
vm_offset_t src_offset;
@@ -3207,7 +3181,6 @@ kern_return_t vm_map_copyin(src_map, src_addr, len, src_destroy, copy_result)
* for copy-on-write?
*/
- register
vm_map_entry_t new_entry; /* Map entry for copy */
boolean_t new_entry_needs_copy; /* Will new entry be COW? */
@@ -3471,11 +3444,11 @@ kern_return_t vm_map_copyin(src_map, src_addr, len, src_destroy, copy_result)
* Our caller donates an object reference.
*/
-kern_return_t vm_map_copyin_object(object, offset, size, copy_result)
- vm_object_t object;
- vm_offset_t offset; /* offset of region in object */
- vm_size_t size; /* size of region in object */
- vm_map_copy_t *copy_result; /* OUT */
+kern_return_t vm_map_copyin_object(
+ vm_object_t object,
+ vm_offset_t offset, /* offset of region in object */
+ vm_size_t size, /* size of region in object */
+ vm_map_copy_t *copy_result) /* OUT */
{
vm_map_copy_t copy; /* Resulting copy */
@@ -3516,12 +3489,12 @@ kern_return_t vm_map_copyin_object(object, offset, size, copy_result)
* the scheduler.
*/
-kern_return_t vm_map_copyin_page_list_cont(cont_args, copy_result)
-vm_map_copyin_args_t cont_args;
-vm_map_copy_t *copy_result; /* OUT */
+kern_return_t vm_map_copyin_page_list_cont(
+ vm_map_copyin_args_t cont_args,
+ vm_map_copy_t *copy_result) /* OUT */
{
kern_return_t result = 0; /* '=0' to quiet gcc warnings */
- register boolean_t do_abort, src_destroy, src_destroy_only;
+ boolean_t do_abort, src_destroy, src_destroy_only;
/*
* Check for cases that only require memory destruction.
@@ -3572,27 +3545,23 @@ vm_map_copy_t *copy_result; /* OUT */
* the recipient of this copy_result must be prepared to deal with it.
*/
-kern_return_t vm_map_copyin_page_list(src_map, src_addr, len, src_destroy,
- steal_pages, copy_result, is_cont)
- vm_map_t src_map;
- vm_offset_t src_addr;
- vm_size_t len;
- boolean_t src_destroy;
- boolean_t steal_pages;
- vm_map_copy_t *copy_result; /* OUT */
- boolean_t is_cont;
+kern_return_t vm_map_copyin_page_list(
+ vm_map_t src_map,
+ vm_offset_t src_addr,
+ vm_size_t len,
+ boolean_t src_destroy,
+ boolean_t steal_pages,
+ vm_map_copy_t *copy_result, /* OUT */
+ boolean_t is_cont)
{
vm_map_entry_t src_entry;
vm_page_t m;
vm_offset_t src_start;
vm_offset_t src_end;
vm_size_t src_size;
- register
vm_object_t src_object;
- register
vm_offset_t src_offset;
vm_offset_t src_last_offset;
- register
vm_map_copy_t copy; /* Resulting copy */
kern_return_t result = KERN_SUCCESS;
boolean_t need_map_lookup;
@@ -3926,7 +3895,7 @@ retry:
*/
src_start = trunc_page(src_addr);
if (steal_pages) {
- register int i;
+ int i;
vm_offset_t unwire_end;
unwire_end = src_start;
@@ -3998,6 +3967,8 @@ retry:
assert(src_entry->wired_count > 0);
src_entry->wired_count = 0;
+ if (src_entry->user_wired_count)
+ src_map->user_wired -= src_entry->vme_end - src_entry->vme_start;
src_entry->user_wired_count = 0;
unwire_end = src_entry->vme_end;
pmap_pageable(vm_map_pmap(src_map),
@@ -4103,18 +4074,14 @@ error:
*
* The source map must not be locked.
*/
-vm_map_t vm_map_fork(old_map)
- vm_map_t old_map;
+vm_map_t vm_map_fork(vm_map_t old_map)
{
vm_map_t new_map;
- register
vm_map_entry_t old_entry;
- register
vm_map_entry_t new_entry;
pmap_t new_pmap = pmap_create((vm_size_t) 0);
vm_size_t new_size = 0;
vm_size_t entry_size;
- register
vm_object_t object;
vm_map_lock(old_map);
@@ -4377,21 +4344,20 @@ vm_map_t vm_map_fork(old_map)
* copying operations, although the data referenced will
* remain the same.
*/
-kern_return_t vm_map_lookup(var_map, vaddr, fault_type, out_version,
- object, offset, out_prot, wired)
- vm_map_t *var_map; /* IN/OUT */
- register vm_offset_t vaddr;
- register vm_prot_t fault_type;
-
- vm_map_version_t *out_version; /* OUT */
- vm_object_t *object; /* OUT */
- vm_offset_t *offset; /* OUT */
- vm_prot_t *out_prot; /* OUT */
- boolean_t *wired; /* OUT */
+kern_return_t vm_map_lookup(
+ vm_map_t *var_map, /* IN/OUT */
+ vm_offset_t vaddr,
+ vm_prot_t fault_type,
+
+ vm_map_version_t *out_version, /* OUT */
+ vm_object_t *object, /* OUT */
+ vm_offset_t *offset, /* OUT */
+ vm_prot_t *out_prot, /* OUT */
+ boolean_t *wired) /* OUT */
{
- register vm_map_entry_t entry;
- register vm_map_t map = *var_map;
- register vm_prot_t prot;
+ vm_map_entry_t entry;
+ vm_map_t map = *var_map;
+ vm_prot_t prot;
RetryLookup: ;
@@ -4559,11 +4525,9 @@ kern_return_t vm_map_lookup(var_map, vaddr, fault_type, out_version,
* since the given version. If successful, the map
* will not change until vm_map_verify_done() is called.
*/
-boolean_t vm_map_verify(map, version)
- register
- vm_map_t map;
- register
- vm_map_version_t *version; /* REF */
+boolean_t vm_map_verify(
+ vm_map_t map,
+ vm_map_version_t *version) /* REF */
{
boolean_t result;
@@ -4592,24 +4556,19 @@ boolean_t vm_map_verify(map, version)
* a task's address map.
*/
-kern_return_t vm_region(map, address, size,
- protection, max_protection,
- inheritance, is_shared,
- object_name, offset_in_object)
- vm_map_t map;
- vm_offset_t *address; /* IN/OUT */
- vm_size_t *size; /* OUT */
- vm_prot_t *protection; /* OUT */
- vm_prot_t *max_protection; /* OUT */
- vm_inherit_t *inheritance; /* OUT */
- boolean_t *is_shared; /* OUT */
- ipc_port_t *object_name; /* OUT */
- vm_offset_t *offset_in_object; /* OUT */
+kern_return_t vm_region(
+ vm_map_t map,
+ vm_offset_t *address, /* IN/OUT */
+ vm_size_t *size, /* OUT */
+ vm_prot_t *protection, /* OUT */
+ vm_prot_t *max_protection, /* OUT */
+ vm_inherit_t *inheritance, /* OUT */
+ boolean_t *is_shared, /* OUT */
+ ipc_port_t *object_name, /* OUT */
+ vm_offset_t *offset_in_object) /* OUT */
{
vm_map_entry_t tmp_entry;
- register
vm_map_entry_t entry;
- register
vm_offset_t tmp_offset;
vm_offset_t start;
@@ -4666,9 +4625,9 @@ kern_return_t vm_region(map, address, size,
* at allocation time because the adjacent entry
* is often wired down.
*/
-void vm_map_simplify(map, start)
- vm_map_t map;
- vm_offset_t start;
+void vm_map_simplify(
+ vm_map_t map,
+ vm_offset_t start)
{
vm_map_entry_t this_entry;
vm_map_entry_t prev_entry;
@@ -4727,12 +4686,12 @@ void vm_map_simplify(map, start)
* it itself. [This assumes that attributes do not
* need to be inherited, which seems ok to me]
*/
-kern_return_t vm_map_machine_attribute(map, address, size, attribute, value)
- vm_map_t map;
- vm_offset_t address;
- vm_size_t size;
- vm_machine_attribute_t attribute;
- vm_machine_attribute_val_t* value; /* IN/OUT */
+kern_return_t vm_map_machine_attribute(
+ vm_map_t map,
+ vm_offset_t address,
+ vm_size_t size,
+ vm_machine_attribute_t attribute,
+ vm_machine_attribute_val_t* value) /* IN/OUT */
{
kern_return_t ret;
@@ -4757,10 +4716,9 @@ kern_return_t vm_map_machine_attribute(map, address, size, attribute, value)
/*
* vm_map_print: [ debug ]
*/
-void vm_map_print(map)
- register vm_map_t map;
+void vm_map_print(vm_map_t map)
{
- register vm_map_entry_t entry;
+ vm_map_entry_t entry;
iprintf("Task map 0x%X: pmap=0x%X,",
(vm_offset_t) map, (vm_offset_t) (map->pmap));
@@ -4826,7 +4784,7 @@ void vm_map_print(map)
*/
void vm_map_copy_print(copy)
- vm_map_copy_t copy;
+ const vm_map_copy_t copy;
{
int i, npages;
@@ -4886,6 +4844,6 @@ void vm_map_copy_print(copy)
break;
}
- indent -=2;
+ indent -= 2;
}
#endif /* MACH_KDB */
diff --git a/vm/vm_map.h b/vm/vm_map.h
index a15e681b..9b31f90a 100644
--- a/vm/vm_map.h
+++ b/vm/vm_map.h
@@ -52,10 +52,10 @@
#include <vm/vm_types.h>
#include <kern/lock.h>
#include <kern/rbtree.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
/* TODO: make it dynamic */
-#define KENTRY_DATA_SIZE (64*PAGE_SIZE)
+#define KENTRY_DATA_SIZE (256*PAGE_SIZE)
/*
* Types defined:
@@ -170,14 +170,18 @@ struct vm_map {
#define max_offset hdr.links.end /* end of range */
pmap_t pmap; /* Physical map */
vm_size_t size; /* virtual size */
+ vm_size_t user_wired; /* wired by user size */
int ref_count; /* Reference count */
decl_simple_lock_data(, ref_lock) /* Lock for ref_count field */
vm_map_entry_t hint; /* hint for quick lookups */
decl_simple_lock_data(, hint_lock) /* lock for hint storage */
vm_map_entry_t first_free; /* First free space hint */
- boolean_t wait_for_space; /* Should callers wait
+
+ /* Flags */
+ unsigned int wait_for_space:1, /* Should callers wait
for space? */
- boolean_t wiring_required;/* All memory wired? */
+ /* boolean_t */ wiring_required:1; /* All memory wired? */
+
unsigned int timestamp; /* Version number */
};
@@ -397,9 +401,6 @@ extern kern_return_t vm_map_protect(vm_map_t, vm_offset_t, vm_offset_t,
extern kern_return_t vm_map_inherit(vm_map_t, vm_offset_t, vm_offset_t,
vm_inherit_t);
-/* Debugging: print a map */
-extern void vm_map_print(vm_map_t);
-
/* Look up an address */
extern kern_return_t vm_map_lookup(vm_map_t *, vm_offset_t, vm_prot_t,
vm_map_version_t *, vm_object_t *,
@@ -440,6 +441,23 @@ extern kern_return_t vm_map_machine_attribute(vm_map_t, vm_offset_t,
/* Delete entry from map */
extern void vm_map_entry_delete(vm_map_t, vm_map_entry_t);
+kern_return_t vm_map_delete(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_offset_t end);
+
+kern_return_t vm_map_copyout_page_list(
+ vm_map_t dst_map,
+ vm_offset_t *dst_addr, /* OUT */
+ vm_map_copy_t copy);
+
+void vm_map_copy_page_discard (vm_map_copy_t copy);
+
+boolean_t vm_map_lookup_entry(
+ vm_map_t map,
+ vm_offset_t address,
+ vm_map_entry_t *entry); /* OUT */
+
/*
* Functions implemented as macros
*/
@@ -541,6 +559,9 @@ extern void _vm_map_clip_start(
* the specified address; if necessary,
* it splits the entry into two.
*/
-void _vm_map_clip_end();
+void _vm_map_clip_end(
+ struct vm_map_header *map_header,
+ vm_map_entry_t entry,
+ vm_offset_t end);
#endif /* _VM_VM_MAP_H_ */
diff --git a/vm/vm_object.c b/vm/vm_object.c
index d83c39fe..deac0c2a 100644
--- a/vm/vm_object.c
+++ b/vm/vm_object.c
@@ -59,14 +59,6 @@
#include <ddb/db_output.h>
#endif /* MACH_KDB */
-
-void memory_object_release(
- ipc_port_t pager,
- pager_request_t pager_request,
- ipc_port_t pager_name); /* forward */
-
-void vm_object_deactivate_pages(vm_object_t);
-
/*
* Virtual memory objects maintain the actual data
* associated with allocated virtual memory. A given
@@ -233,7 +225,7 @@ static void _vm_object_setup(
vm_object_t _vm_object_allocate(
vm_size_t size)
{
- register vm_object_t object;
+ vm_object_t object;
object = (vm_object_t) kmem_cache_alloc(&vm_object_cache);
@@ -245,8 +237,8 @@ vm_object_t _vm_object_allocate(
vm_object_t vm_object_allocate(
vm_size_t size)
{
- register vm_object_t object;
- register ipc_port_t port;
+ vm_object_t object;
+ ipc_port_t port;
object = _vm_object_allocate(size);
port = ipc_port_alloc_kernel();
@@ -353,7 +345,7 @@ void vm_object_init(void)
* Gets another reference to the given object.
*/
void vm_object_reference(
- register vm_object_t object)
+ vm_object_t object)
{
if (object == VM_OBJECT_NULL)
return;
@@ -376,7 +368,7 @@ void vm_object_reference(
* No object may be locked.
*/
void vm_object_deallocate(
- register vm_object_t object)
+ vm_object_t object)
{
vm_object_t temp;
@@ -530,8 +522,6 @@ void vm_object_deallocate(
}
}
-boolean_t vm_object_terminate_remove_all = FALSE;
-
/*
* Routine: vm_object_terminate
* Purpose:
@@ -546,10 +536,10 @@ boolean_t vm_object_terminate_remove_all = FALSE;
* object will cease to exist.
*/
void vm_object_terminate(
- register vm_object_t object)
+ vm_object_t object)
{
- register vm_page_t p;
- vm_object_t shadow_object;
+ vm_page_t p;
+ vm_object_t shadow_object;
/*
* Make sure the object isn't already being terminated
@@ -598,10 +588,6 @@ void vm_object_terminate(
VM_PAGE_CHECK(p);
- if (p->busy && !p->absent)
- panic("vm_object_terminate.2 0x%x 0x%x",
- object, p);
-
VM_PAGE_FREE(p);
}
} else while (!queue_empty(&object->memq)) {
@@ -609,9 +595,6 @@ void vm_object_terminate(
VM_PAGE_CHECK(p);
- if (p->busy && !p->absent)
- panic("vm_object_terminate.3 0x%x 0x%x", object, p);
-
vm_page_lock_queues();
VM_PAGE_QUEUES_REMOVE(p);
vm_page_unlock_queues();
@@ -629,9 +612,6 @@ void vm_object_terminate(
goto free_page;
}
- if (p->fictitious)
- panic("vm_object_terminate.4 0x%x 0x%x", object, p);
-
if (!p->dirty)
p->dirty = pmap_is_modified(p->phys_addr);
@@ -752,7 +732,6 @@ void memory_object_release(
void vm_object_abort_activity(
vm_object_t object)
{
- register
vm_page_t p;
vm_page_t next;
@@ -806,17 +785,12 @@ void vm_object_abort_activity(
* or from port destruction handling (via vm_object_destroy).
*/
kern_return_t memory_object_destroy(
- register
vm_object_t object,
kern_return_t reason)
{
ipc_port_t old_object, old_name;
pager_request_t old_control;
-#ifdef lint
- reason++;
-#endif /* lint */
-
if (object == VM_OBJECT_NULL)
return KERN_SUCCESS;
@@ -892,9 +866,9 @@ kern_return_t memory_object_destroy(
* The object must be locked.
*/
void vm_object_deactivate_pages(
- register vm_object_t object)
+ vm_object_t object)
{
- register vm_page_t p;
+ vm_page_t p;
queue_iterate(&object->memq, p, vm_page_t, listq) {
vm_page_lock_queues();
@@ -931,8 +905,8 @@ void vm_object_deactivate_pages(
boolean_t vm_object_pmap_protect_by_page = FALSE;
void vm_object_pmap_protect(
- register vm_object_t object,
- register vm_offset_t offset,
+ vm_object_t object,
+ vm_offset_t offset,
vm_size_t size,
pmap_t pmap,
vm_offset_t pmap_start,
@@ -954,8 +928,8 @@ void vm_object_pmap_protect(
}
{
- register vm_page_t p;
- register vm_offset_t end;
+ vm_page_t p;
+ vm_offset_t end;
end = offset + size;
@@ -986,7 +960,7 @@ void vm_object_pmap_protect(
* Must follow shadow chain to remove access
* to pages in shadowed objects.
*/
- register vm_object_t next_object;
+ vm_object_t next_object;
next_object = object->shadow;
if (next_object != VM_OBJECT_NULL) {
@@ -1023,11 +997,11 @@ void vm_object_pmap_protect(
* The object must *not* be locked.
*/
void vm_object_pmap_remove(
- register vm_object_t object,
- register vm_offset_t start,
- register vm_offset_t end)
+ vm_object_t object,
+ vm_offset_t start,
+ vm_offset_t end)
{
- register vm_page_t p;
+ vm_page_t p;
if (object == VM_OBJECT_NULL)
return;
@@ -1073,7 +1047,6 @@ void vm_object_pmap_remove(
* VM_OBJECT_NULL.
*/
kern_return_t vm_object_copy_slowly(
- register
vm_object_t src_object,
vm_offset_t src_offset,
vm_size_t size,
@@ -1127,7 +1100,6 @@ kern_return_t vm_object_copy_slowly(
vm_prot_t prot = VM_PROT_READ;
vm_page_t _result_page;
vm_page_t top_page;
- register
vm_page_t result_page;
vm_object_lock(src_object);
@@ -1247,8 +1219,6 @@ kern_return_t vm_object_copy_slowly(
* The object should be unlocked on entry and exit.
*/
-vm_object_t vm_object_copy_delayed(); /* forward declaration */
-
boolean_t vm_object_copy_temporary(
vm_object_t *_object, /* INOUT */
vm_offset_t *_offset, /* INOUT */
@@ -1257,10 +1227,6 @@ boolean_t vm_object_copy_temporary(
{
vm_object_t object = *_object;
-#ifdef lint
- ++*_offset;
-#endif /* lint */
-
if (object == VM_OBJECT_NULL) {
*_src_needs_copy = FALSE;
*_dst_needs_copy = FALSE;
@@ -1360,16 +1326,6 @@ kern_return_t vm_object_copy_call(
vm_page_t p;
/*
- * Set the backing object for the new
- * temporary object.
- */
-
- assert(src_object->ref_count > 0);
- src_object->ref_count++;
- vm_object_paging_begin(src_object);
- vm_object_unlock(src_object);
-
- /*
* Create a memory object port to be associated
* with this new vm_object.
*
@@ -1382,10 +1338,18 @@ kern_return_t vm_object_copy_call(
*/
new_memory_object = ipc_port_alloc_kernel();
- if (new_memory_object == IP_NULL) {
- panic("vm_object_copy_call: allocate memory object port");
- /* XXX Shouldn't panic here. */
- }
+ if (new_memory_object == IP_NULL)
+ return KERN_RESOURCE_SHORTAGE;
+
+ /*
+ * Set the backing object for the new
+ * temporary object.
+ */
+
+ assert(src_object->ref_count > 0);
+ src_object->ref_count++;
+ vm_object_paging_begin(src_object);
+ vm_object_unlock(src_object);
/* we hold a naked receive right for new_memory_object */
(void) ipc_port_make_send(new_memory_object);
@@ -1490,7 +1454,7 @@ vm_object_t vm_object_copy_delayed(
* synchronization required in the "push"
* operation described above.
*
- * The copy-on-write is said to be assymetric because
+ * The copy-on-write is said to be asymmetric because
* the original object is *not* marked copy-on-write.
* A copied page is pushed to the copy object, regardless
* which party attempted to modify the page.
@@ -1623,7 +1587,6 @@ vm_object_t vm_object_copy_delayed(
* and may be interrupted.
*/
kern_return_t vm_object_copy_strategically(
- register
vm_object_t src_object,
vm_offset_t src_offset,
vm_size_t size,
@@ -1736,8 +1699,8 @@ void vm_object_shadow(
vm_offset_t *offset, /* IN/OUT */
vm_size_t length)
{
- register vm_object_t source;
- register vm_object_t result;
+ vm_object_t source;
+ vm_object_t result;
source = *object;
@@ -2009,7 +1972,6 @@ vm_object_t vm_object_enter(
vm_size_t size,
boolean_t internal)
{
- register
vm_object_t object;
vm_object_t new_object;
boolean_t must_init;
@@ -2227,7 +2189,6 @@ restart:
* daemon will be using this routine.
*/
void vm_object_pager_create(
- register
vm_object_t object)
{
ipc_port_t pager;
@@ -2372,14 +2333,14 @@ boolean_t vm_object_collapse_bypass_allowed = TRUE;
* so the caller should hold a reference for the object.
*/
void vm_object_collapse(
- register vm_object_t object)
+ vm_object_t object)
{
- register vm_object_t backing_object;
- register vm_offset_t backing_offset;
- register vm_size_t size;
- register vm_offset_t new_offset;
- register vm_page_t p, pp;
- ipc_port_t old_name_port;
+ vm_object_t backing_object;
+ vm_offset_t backing_offset;
+ vm_size_t size;
+ vm_offset_t new_offset;
+ vm_page_t p, pp;
+ ipc_port_t old_name_port;
if (!vm_object_collapse_allowed)
return;
@@ -2749,11 +2710,11 @@ unsigned int vm_object_page_remove_lookup = 0;
unsigned int vm_object_page_remove_iterate = 0;
void vm_object_page_remove(
- register vm_object_t object,
- register vm_offset_t start,
- register vm_offset_t end)
+ vm_object_t object,
+ vm_offset_t start,
+ vm_offset_t end)
{
- register vm_page_t p, next;
+ vm_page_t p, next;
/*
* One and two page removals are most popular.
@@ -2814,7 +2775,7 @@ void vm_object_page_remove(
*/
boolean_t vm_object_coalesce(
- register vm_object_t prev_object,
+ vm_object_t prev_object,
vm_object_t next_object,
vm_offset_t prev_offset,
vm_offset_t next_offset,
@@ -2823,10 +2784,6 @@ boolean_t vm_object_coalesce(
{
vm_size_t newsize;
-#ifdef lint
- next_offset++;
-#endif /* lint */
-
if (next_object != VM_OBJECT_NULL) {
return FALSE;
}
@@ -2969,6 +2926,7 @@ vm_object_page_map(
#if MACH_KDB
+#include <vm/vm_print.h>
#define printf kdbprintf
boolean_t vm_object_print_pages = FALSE;
@@ -2979,9 +2937,9 @@ boolean_t vm_object_print_pages = FALSE;
void vm_object_print(
vm_object_t object)
{
- register vm_page_t p;
+ vm_page_t p;
- register int count;
+ int count;
if (object == VM_OBJECT_NULL)
return;
diff --git a/vm/vm_object.h b/vm/vm_object.h
index 4e4c9498..3bfc67ab 100644
--- a/vm/vm_object.h
+++ b/vm/vm_object.h
@@ -45,7 +45,7 @@
#include <kern/lock.h>
#include <kern/assert.h>
#include <kern/debug.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <vm/pmap.h>
#include <ipc/ipc_types.h>
@@ -233,8 +233,6 @@ extern void vm_object_page_map(
vm_offset_t (*)(void *, vm_offset_t),
void *);
-extern void vm_object_print(vm_object_t);
-
extern vm_object_t vm_object_request_object(struct ipc_port *);
extern boolean_t vm_object_coalesce(
@@ -247,6 +245,16 @@ extern boolean_t vm_object_coalesce(
extern void vm_object_pager_wakeup(ipc_port_t pager);
+void memory_object_release(
+ ipc_port_t pager,
+ pager_request_t pager_request,
+ ipc_port_t pager_name);
+
+void vm_object_deactivate_pages(vm_object_t);
+
+vm_object_t vm_object_copy_delayed(
+ vm_object_t src_object);
+
/*
* Event waiting handling
*/
diff --git a/vm/vm_page.h b/vm/vm_page.h
index 4536d1c5..e6a8c497 100644
--- a/vm/vm_page.h
+++ b/vm/vm_page.h
@@ -42,7 +42,7 @@
#include <kern/queue.h>
#include <kern/lock.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/sched_prim.h> /* definitions of wait/wakeup */
#if MACH_VM_DEBUG
@@ -84,7 +84,7 @@ struct vm_page {
vm_object_t object; /* which object am I in (O,P) */
vm_offset_t offset; /* offset into that object (O,P) */
- unsigned int wire_count:16, /* how many wired down maps use me?
+ unsigned int wire_count:15, /* how many wired down maps use me?
(O&P) */
/* boolean_t */ inactive:1, /* page is in inactive list (P) */
active:1, /* page is in active list (P) */
@@ -92,14 +92,8 @@ struct vm_page {
free:1, /* page is on free list (P) */
reference:1, /* page has been used (P) */
external:1, /* page considered external (P) */
- extcounted:1, /* page counted in ext counts (P) */
- :0; /* (force to 'long' boundary) */
-#ifdef ns32000
- int pad; /* extra space for ns32000 bit ops */
-#endif /* ns32000 */
-
- unsigned int
- /* boolean_t */ busy:1, /* page is in transit (O) */
+ extcounted:1, /* page counted in ext counts (P) */
+ busy:1, /* page is in transit (O) */
wanted:1, /* someone is waiting for page (O) */
tabled:1, /* page is in VP table (O) */
fictitious:1, /* Physical page doesn't exist (O) */
@@ -112,10 +106,9 @@ struct vm_page {
dirty:1, /* Page must be cleaned (O) */
precious:1, /* Page is precious; data must be
* returned even if clean (O) */
- overwriting:1, /* Request to unlock has been made
+ overwriting:1; /* Request to unlock has been made
* without having data. (O)
* [See vm_object_overwrite] */
- :0;
vm_offset_t phys_addr; /* Physical address of page, passed
* to pmap_enter (read-only) */
@@ -156,11 +149,6 @@ extern
queue_head_t vm_page_queue_inactive; /* inactive memory queue */
extern
-vm_offset_t first_phys_addr; /* physical address for first_page */
-extern
-vm_offset_t last_phys_addr; /* physical address for last_page */
-
-extern
int vm_page_free_count; /* How many pages are free? */
extern
int vm_page_fictitious_count;/* How many fictitious pages are free? */
@@ -247,8 +235,6 @@ extern void vm_page_copy(vm_page_t src_m, vm_page_t dest_m);
extern void vm_page_wire(vm_page_t);
extern void vm_page_unwire(vm_page_t);
-extern void vm_set_page_size(void);
-
#if MACH_VM_DEBUG
extern unsigned int vm_page_info(
hash_info_bucket_t *info,
diff --git a/vm/vm_pageout.c b/vm/vm_pageout.c
index 661675f0..51a6a0d4 100644
--- a/vm/vm_pageout.c
+++ b/vm/vm_pageout.c
@@ -52,7 +52,6 @@
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
#include <machine/locore.h>
-#include <machine/vm_tuning.h>
@@ -98,7 +97,7 @@
*/
#ifndef VM_PAGE_FREE_TARGET
-#define VM_PAGE_FREE_TARGET(free) (15 + (free) / 80)
+#define VM_PAGE_FREE_TARGET(free) (150 + (free) * 10 / 100)
#endif /* VM_PAGE_FREE_TARGET */
/*
@@ -107,7 +106,7 @@
*/
#ifndef VM_PAGE_FREE_MIN
-#define VM_PAGE_FREE_MIN(free) (10 + (free) / 100)
+#define VM_PAGE_FREE_MIN(free) (100 + (free) * 8 / 100)
#endif /* VM_PAGE_FREE_MIN */
/* When vm_page_external_count exceeds vm_page_external_limit,
@@ -133,7 +132,7 @@
* operation by dipping into the reserved pool of pages. */
#ifndef VM_PAGE_FREE_RESERVED
-#define VM_PAGE_FREE_RESERVED 50
+#define VM_PAGE_FREE_RESERVED 500
#endif /* VM_PAGE_FREE_RESERVED */
/*
@@ -145,7 +144,7 @@
*/
#ifndef VM_PAGEOUT_RESERVED_INTERNAL
-#define VM_PAGEOUT_RESERVED_INTERNAL(reserve) ((reserve) - 25)
+#define VM_PAGEOUT_RESERVED_INTERNAL(reserve) ((reserve) - 250)
#endif /* VM_PAGEOUT_RESERVED_INTERNAL */
/*
@@ -157,12 +156,9 @@
*/
#ifndef VM_PAGEOUT_RESERVED_REALLY
-#define VM_PAGEOUT_RESERVED_REALLY(reserve) ((reserve) - 40)
+#define VM_PAGEOUT_RESERVED_REALLY(reserve) ((reserve) - 400)
#endif /* VM_PAGEOUT_RESERVED_REALLY */
-extern void vm_pageout_continue();
-extern void vm_pageout_scan_continue();
-
unsigned int vm_pageout_reserved_internal = 0;
unsigned int vm_pageout_reserved_really = 0;
@@ -230,16 +226,16 @@ unsigned int vm_pageout_inactive_cleaned_external = 0;
* not busy on exit.
*/
vm_page_t
-vm_pageout_setup(m, paging_offset, new_object, new_offset, flush)
- register vm_page_t m;
- vm_offset_t paging_offset;
- register vm_object_t new_object;
- vm_offset_t new_offset;
- boolean_t flush;
+vm_pageout_setup(
+ vm_page_t m,
+ vm_offset_t paging_offset,
+ vm_object_t new_object,
+ vm_offset_t new_offset,
+ boolean_t flush)
{
- register vm_object_t old_object = m->object;
- register vm_page_t holding_page = 0; /*'=0'to quiet gcc warnings*/
- register vm_page_t new_m;
+ vm_object_t old_object = m->object;
+ vm_page_t holding_page = 0; /*'=0'to quiet gcc warnings*/
+ vm_page_t new_m;
assert(m->busy && !m->absent && !m->fictitious);
@@ -417,15 +413,15 @@ vm_pageout_setup(m, paging_offset, new_object, new_offset, flush)
* copy to a new page in a new object, if not.
*/
void
-vm_pageout_page(m, initial, flush)
- register vm_page_t m;
- boolean_t initial;
- boolean_t flush;
+vm_pageout_page(
+ vm_page_t m,
+ boolean_t initial,
+ boolean_t flush)
{
vm_map_copy_t copy;
- register vm_object_t old_object;
- register vm_object_t new_object;
- register vm_page_t holding_page;
+ vm_object_t old_object;
+ vm_object_t new_object;
+ vm_page_t holding_page;
vm_offset_t paging_offset;
kern_return_t rc;
boolean_t precious_clean;
@@ -511,7 +507,7 @@ vm_pageout_page(m, initial, flush)
* vm_page_free_wanted == 0.
*/
-void vm_pageout_scan()
+void vm_pageout_scan(void)
{
unsigned int burst_count;
unsigned int want_pages;
@@ -555,12 +551,14 @@ void vm_pageout_scan()
stack_collect();
net_kmsg_collect();
consider_task_collect();
+ if (0) /* XXX: pcb_collect doesn't do anything yet, so it is
+ pointless to call consider_thread_collect. */
consider_thread_collect();
slab_collect();
for (burst_count = 0;;) {
- register vm_page_t m;
- register vm_object_t object;
+ vm_page_t m;
+ vm_object_t object;
unsigned int free_count;
/*
@@ -578,7 +576,7 @@ void vm_pageout_scan()
while ((vm_page_inactive_count < vm_page_inactive_target) &&
!queue_empty(&vm_page_queue_active)) {
- register vm_object_t obj;
+ vm_object_t obj;
vm_pageout_active++;
m = (vm_page_t) queue_first(&vm_page_queue_active);
@@ -695,7 +693,7 @@ void vm_pageout_scan()
if (want_pages || m->external)
break;
- m = (vm_page_t) queue_next (m);
+ m = (vm_page_t) queue_next (&m->pageq);
if (!m)
goto pause;
}
@@ -857,7 +855,7 @@ void vm_pageout_scan()
}
}
-void vm_pageout_scan_continue()
+void vm_pageout_scan_continue(void)
{
/*
* We just paused to let the pagers catch up.
@@ -888,7 +886,7 @@ void vm_pageout_scan_continue()
* vm_pageout is the high level pageout daemon.
*/
-void vm_pageout_continue()
+void vm_pageout_continue(void)
{
/*
* The pageout daemon is never done, so loop forever.
@@ -910,12 +908,13 @@ void vm_pageout_continue()
}
}
-void vm_pageout()
+void vm_pageout(void)
{
int free_after_reserve;
current_thread()->vm_privilege = TRUE;
stack_privilege(current_thread());
+ thread_set_own_priority(0);
/*
* Initialize some paging parameters.
diff --git a/vm/vm_pageout.h b/vm/vm_pageout.h
index d41ee30a..ea6cfaf4 100644
--- a/vm/vm_pageout.h
+++ b/vm/vm_pageout.h
@@ -44,4 +44,10 @@ extern vm_page_t vm_pageout_setup(vm_page_t, vm_offset_t, vm_object_t,
vm_offset_t, boolean_t);
extern void vm_pageout_page(vm_page_t, boolean_t, boolean_t);
+extern void vm_pageout(void) __attribute__((noreturn));
+
+extern void vm_pageout_continue(void) __attribute__((noreturn));
+
+extern void vm_pageout_scan_continue(void) __attribute__((noreturn));
+
#endif /* _VM_VM_PAGEOUT_H_ */
diff --git a/vm/vm_print.h b/vm/vm_print.h
new file mode 100644
index 00000000..eab534eb
--- /dev/null
+++ b/vm/vm_print.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef VM_PRINT_H
+#define VM_PRINT_H
+
+#include <vm/vm_map.h>
+#include <machine/db_machdep.h>
+
+/* Debugging: print a map */
+extern void vm_map_print(vm_map_t);
+
+/* Pretty-print a copy object for ddb. */
+extern void vm_map_copy_print(const vm_map_copy_t);
+
+#include <vm/vm_object.h>
+
+extern void vm_object_print(vm_object_t);
+
+#include <vm/vm_page.h>
+
+extern void vm_page_print(const vm_page_t);
+
+#endif /* VM_PRINT_H */
+
diff --git a/vm/vm_resident.c b/vm/vm_resident.c
index 7cf4fb16..c70fa734 100644
--- a/vm/vm_resident.c
+++ b/vm/vm_resident.c
@@ -27,7 +27,7 @@
* the rights to redistribute these changes.
*/
/*
- * File: vm/vm_page.c
+ * File: vm/vm_resident.c
* Author: Avadis Tevanian, Jr., Michael Wayne Young
*
* Resident memory management module.
@@ -60,11 +60,12 @@
#if MACH_KDB
#include <ddb/db_output.h>
+#include <vm/vm_print.h>
#endif /* MACH_KDB */
/*
- * Associated with eacn page of user-allocatable memory is a
+ * Associated with each page of user-allocatable memory is a
* page structure.
*/
@@ -191,7 +192,7 @@ void vm_page_bootstrap(
vm_offset_t *startp,
vm_offset_t *endp)
{
- register vm_page_t m;
+ vm_page_t m;
int i;
/*
@@ -273,7 +274,7 @@ void vm_page_bootstrap(
sizeof(vm_page_bucket_t));
for (i = 0; i < vm_page_bucket_count; i++) {
- register vm_page_bucket_t *bucket = &vm_page_buckets[i];
+ vm_page_bucket_t *bucket = &vm_page_buckets[i];
bucket->pages = VM_PAGE_NULL;
simple_lock_init(&bucket->lock);
@@ -395,7 +396,7 @@ void pmap_startup(
while (pmap_next_page(&paddr))
i++;
if (i)
- printf("%d memory page(s) left away\n", i);
+ printf("%u memory page(s) left away\n", i);
/*
* Release pages in reverse order so that physical pages
@@ -482,11 +483,11 @@ void vm_page_create(
*/
void vm_page_insert(
- register vm_page_t mem,
- register vm_object_t object,
- register vm_offset_t offset)
+ vm_page_t mem,
+ vm_object_t object,
+ vm_offset_t offset)
{
- register vm_page_bucket_t *bucket;
+ vm_page_bucket_t *bucket;
VM_PAGE_CHECK(mem);
@@ -554,11 +555,11 @@ void vm_page_insert(
*/
void vm_page_replace(
- register vm_page_t mem,
- register vm_object_t object,
- register vm_offset_t offset)
+ vm_page_t mem,
+ vm_object_t object,
+ vm_offset_t offset)
{
- register vm_page_bucket_t *bucket;
+ vm_page_bucket_t *bucket;
VM_PAGE_CHECK(mem);
@@ -581,7 +582,7 @@ void vm_page_replace(
simple_lock(&bucket->lock);
if (bucket->pages) {
vm_page_t *mp = &bucket->pages;
- register vm_page_t m = *mp;
+ vm_page_t m = *mp;
do {
if (m->object == object && m->offset == offset) {
/*
@@ -645,10 +646,10 @@ void vm_page_replace(
*/
void vm_page_remove(
- register vm_page_t mem)
+ vm_page_t mem)
{
- register vm_page_bucket_t *bucket;
- register vm_page_t this;
+ vm_page_bucket_t *bucket;
+ vm_page_t this;
assert(mem->tabled);
VM_PAGE_CHECK(mem);
@@ -664,7 +665,7 @@ void vm_page_remove(
bucket->pages = mem->next;
} else {
- register vm_page_t *prev;
+ vm_page_t *prev;
for (prev = &this->next;
(this = *prev) != mem;
@@ -703,11 +704,11 @@ void vm_page_remove(
*/
vm_page_t vm_page_lookup(
- register vm_object_t object,
- register vm_offset_t offset)
+ vm_object_t object,
+ vm_offset_t offset)
{
- register vm_page_t mem;
- register vm_page_bucket_t *bucket;
+ vm_page_t mem;
+ vm_page_bucket_t *bucket;
/*
* Search the hash table for this object/offset pair
@@ -734,9 +735,9 @@ vm_page_t vm_page_lookup(
* The object must be locked.
*/
void vm_page_rename(
- register vm_page_t mem,
- register vm_object_t new_object,
- vm_offset_t new_offset)
+ vm_page_t mem,
+ vm_object_t new_object,
+ vm_offset_t new_offset)
{
/*
* Changes to mem->object require the page lock because
@@ -773,7 +774,7 @@ void vm_page_init(
vm_page_t vm_page_grab_fictitious(void)
{
- register vm_page_t m;
+ vm_page_t m;
simple_lock(&vm_page_queue_free_lock);
m = vm_page_queue_fictitious;
@@ -794,7 +795,7 @@ vm_page_t vm_page_grab_fictitious(void)
*/
void vm_page_release_fictitious(
- register vm_page_t m)
+ vm_page_t m)
{
simple_lock(&vm_page_queue_free_lock);
if (m->free)
@@ -817,7 +818,7 @@ int vm_page_fictitious_quantum = 5;
void vm_page_more_fictitious(void)
{
- register vm_page_t m;
+ vm_page_t m;
int i;
for (i = 0; i < vm_page_fictitious_quantum; i++) {
@@ -838,10 +839,10 @@ void vm_page_more_fictitious(void)
*/
boolean_t vm_page_convert(
- register vm_page_t m,
+ vm_page_t m,
boolean_t external)
{
- register vm_page_t real_m;
+ vm_page_t real_m;
real_m = vm_page_grab(external);
if (real_m == VM_PAGE_NULL)
@@ -867,7 +868,7 @@ boolean_t vm_page_convert(
vm_page_t vm_page_grab(
boolean_t external)
{
- register vm_page_t mem;
+ vm_page_t mem;
simple_lock(&vm_page_queue_free_lock);
@@ -917,7 +918,7 @@ vm_page_t vm_page_grab(
return mem;
}
-vm_offset_t vm_page_grab_phys_addr()
+vm_offset_t vm_page_grab_phys_addr(void)
{
vm_page_t p = vm_page_grab(FALSE);
if (p == VM_PAGE_NULL)
@@ -948,7 +949,7 @@ vm_page_grab_contiguous_pages(
natural_t *bits,
boolean_t external)
{
- register int first_set;
+ int first_set;
int size, alloc_size;
kern_return_t ret;
vm_page_t mem, *prevmemp;
@@ -1005,7 +1006,7 @@ vm_page_grab_contiguous_pages(
*/
mem = vm_page_queue_free;
while (mem) {
- register int word_index, bit_index;
+ int word_index, bit_index;
bit_index = (mem->phys_addr >> PAGE_SHIFT);
word_index = bit_index / NBPEL;
@@ -1022,14 +1023,14 @@ vm_page_grab_contiguous_pages(
* the free list.
*/
{
- register int bits_so_far = 0, i;
+ int bits_so_far = 0, i;
first_set = 0;
for (i = 0; i < size; i += sizeof(natural_t)) {
- register natural_t v = bits[i / sizeof(natural_t)];
- register int bitpos;
+ natural_t v = bits[i / sizeof(natural_t)];
+ int bitpos;
/*
* Bitscan this one word
@@ -1098,7 +1099,7 @@ found_em:
if (external)
vm_page_external_count += npages;
{
- register vm_offset_t first_phys, last_phys;
+ vm_offset_t first_phys, last_phys;
/* cache values for compare */
first_phys = first_set << PAGE_SHIFT;
@@ -1110,7 +1111,7 @@ found_em:
while (mem) {
- register vm_offset_t addr;
+ vm_offset_t addr;
addr = mem->phys_addr;
@@ -1164,8 +1165,8 @@ out:
*/
void vm_page_release(
- register vm_page_t mem,
- boolean_t external)
+ vm_page_t mem,
+ boolean_t external)
{
simple_lock(&vm_page_queue_free_lock);
if (mem->free)
@@ -1256,7 +1257,7 @@ vm_page_t vm_page_alloc(
vm_object_t object,
vm_offset_t offset)
{
- register vm_page_t mem;
+ vm_page_t mem;
mem = vm_page_grab(!object->internal);
if (mem == VM_PAGE_NULL)
@@ -1278,7 +1279,7 @@ vm_page_t vm_page_alloc(
* Object and page queues must be locked prior to entry.
*/
void vm_page_free(
- register vm_page_t mem)
+ vm_page_t mem)
{
if (mem->free)
panic("vm_page_free");
@@ -1329,7 +1330,7 @@ void vm_page_free(
* The page's object and the page queues must be locked.
*/
void vm_page_wire(
- register vm_page_t mem)
+ vm_page_t mem)
{
VM_PAGE_CHECK(mem);
@@ -1350,7 +1351,7 @@ void vm_page_wire(
* The page's object and the page queues must be locked.
*/
void vm_page_unwire(
- register vm_page_t mem)
+ vm_page_t mem)
{
VM_PAGE_CHECK(mem);
@@ -1373,7 +1374,7 @@ void vm_page_unwire(
* The page queues must be locked.
*/
void vm_page_deactivate(
- register vm_page_t m)
+ vm_page_t m)
{
VM_PAGE_CHECK(m);
@@ -1407,7 +1408,7 @@ void vm_page_deactivate(
*/
void vm_page_activate(
- register vm_page_t m)
+ vm_page_t m)
{
VM_PAGE_CHECK(m);
@@ -1504,10 +1505,10 @@ vm_page_info(
* Routine: vm_page_print [exported]
*/
void vm_page_print(p)
- vm_page_t p;
+ const vm_page_t p;
{
iprintf("Page 0x%X: object 0x%X,", (vm_offset_t) p, (vm_offset_t) p->object);
- printf(" offset 0x%X", (vm_offset_t) p->offset);
+ printf(" offset 0x%X", p->offset);
printf("wire_count %d,", p->wire_count);
printf(" %s",
(p->active ? "active" : (p->inactive ? "inactive" : "loose")));
@@ -1532,7 +1533,7 @@ void vm_page_print(p)
printf("%s,",
(p->tabled ? "" : "not_tabled"));
printf("phys_addr = 0x%X, lock = 0x%X, unlock_request = 0x%X\n",
- (vm_offset_t) p->phys_addr,
+ p->phys_addr,
(vm_offset_t) p->page_lock,
(vm_offset_t) p->unlock_request);
}
diff --git a/vm/vm_resident.h b/vm/vm_resident.h
index 67f1807f..e8bf6818 100644
--- a/vm/vm_resident.h
+++ b/vm/vm_resident.h
@@ -38,8 +38,8 @@
* The object and page must be locked.
*/
extern void vm_page_replace (
- register vm_page_t mem,
- register vm_object_t object,
- register vm_offset_t offset);
+ vm_page_t mem,
+ vm_object_t object,
+ vm_offset_t offset);
#endif /* _VM_RESIDENT_H_ */
diff --git a/vm/vm_user.c b/vm/vm_user.c
index 6fe398e0..8c7a5d8f 100644
--- a/vm/vm_user.c
+++ b/vm/vm_user.c
@@ -56,11 +56,11 @@ vm_statistics_data_t vm_stat;
* vm_allocate allocates "zero fill" memory in the specfied
* map.
*/
-kern_return_t vm_allocate(map, addr, size, anywhere)
- register vm_map_t map;
- register vm_offset_t *addr;
- register vm_size_t size;
- boolean_t anywhere;
+kern_return_t vm_allocate(
+ vm_map_t map,
+ vm_offset_t *addr,
+ vm_size_t size,
+ boolean_t anywhere)
{
kern_return_t result;
@@ -97,10 +97,10 @@ kern_return_t vm_allocate(map, addr, size, anywhere)
* vm_deallocate deallocates the specified range of addresses in the
* specified address map.
*/
-kern_return_t vm_deallocate(map, start, size)
- register vm_map_t map;
- vm_offset_t start;
- vm_size_t size;
+kern_return_t vm_deallocate(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_size_t size)
{
if (map == VM_MAP_NULL)
return(KERN_INVALID_ARGUMENT);
@@ -115,11 +115,11 @@ kern_return_t vm_deallocate(map, start, size)
* vm_inherit sets the inheritance of the specified range in the
* specified map.
*/
-kern_return_t vm_inherit(map, start, size, new_inheritance)
- register vm_map_t map;
- vm_offset_t start;
- vm_size_t size;
- vm_inherit_t new_inheritance;
+kern_return_t vm_inherit(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_size_t size,
+ vm_inherit_t new_inheritance)
{
if (map == VM_MAP_NULL)
return(KERN_INVALID_ARGUMENT);
@@ -149,12 +149,12 @@ kern_return_t vm_inherit(map, start, size, new_inheritance)
* specified map.
*/
-kern_return_t vm_protect(map, start, size, set_maximum, new_protection)
- register vm_map_t map;
- vm_offset_t start;
- vm_size_t size;
- boolean_t set_maximum;
- vm_prot_t new_protection;
+kern_return_t vm_protect(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_size_t size,
+ boolean_t set_maximum,
+ vm_prot_t new_protection)
{
if ((map == VM_MAP_NULL) ||
(new_protection & ~(VM_PROT_ALL|VM_PROT_NOTIFY)))
@@ -172,9 +172,9 @@ kern_return_t vm_protect(map, start, size, set_maximum, new_protection)
set_maximum));
}
-kern_return_t vm_statistics(map, stat)
- vm_map_t map;
- vm_statistics_data_t *stat;
+kern_return_t vm_statistics(
+ vm_map_t map,
+ vm_statistics_data_t *stat)
{
if (map == VM_MAP_NULL)
return(KERN_INVALID_ARGUMENT);
@@ -217,15 +217,13 @@ kern_return_t vm_cache_statistics(
* Handle machine-specific attributes for a mapping, such
* as cachability, migrability, etc.
*/
-kern_return_t vm_machine_attribute(map, address, size, attribute, value)
- vm_map_t map;
- vm_address_t address;
- vm_size_t size;
- vm_machine_attribute_t attribute;
- vm_machine_attribute_val_t* value; /* IN/OUT */
+kern_return_t vm_machine_attribute(
+ vm_map_t map,
+ vm_address_t address,
+ vm_size_t size,
+ vm_machine_attribute_t attribute,
+ vm_machine_attribute_val_t* value) /* IN/OUT */
{
- extern kern_return_t vm_map_machine_attribute();
-
if (map == VM_MAP_NULL)
return(KERN_INVALID_ARGUMENT);
@@ -237,12 +235,12 @@ kern_return_t vm_machine_attribute(map, address, size, attribute, value)
return vm_map_machine_attribute(map, address, size, attribute, value);
}
-kern_return_t vm_read(map, address, size, data, data_size)
- vm_map_t map;
- vm_address_t address;
- vm_size_t size;
- pointer_t *data;
- vm_size_t *data_size;
+kern_return_t vm_read(
+ vm_map_t map,
+ vm_address_t address,
+ vm_size_t size,
+ pointer_t *data,
+ vm_size_t *data_size)
{
kern_return_t error;
vm_map_copy_t ipc_address;
@@ -261,11 +259,11 @@ kern_return_t vm_read(map, address, size, data, data_size)
return(error);
}
-kern_return_t vm_write(map, address, data, size)
- vm_map_t map;
- vm_address_t address;
- pointer_t data;
- vm_size_t size;
+kern_return_t vm_write(
+ vm_map_t map,
+ vm_address_t address,
+ pointer_t data,
+ vm_size_t size)
{
if (map == VM_MAP_NULL)
return KERN_INVALID_ARGUMENT;
@@ -274,11 +272,11 @@ kern_return_t vm_write(map, address, data, size)
FALSE /* interruptible XXX */);
}
-kern_return_t vm_copy(map, source_address, size, dest_address)
- vm_map_t map;
- vm_address_t source_address;
- vm_size_t size;
- vm_address_t dest_address;
+kern_return_t vm_copy(
+ vm_map_t map,
+ vm_address_t source_address,
+ vm_size_t size,
+ vm_address_t dest_address)
{
vm_map_copy_t copy;
kern_return_t kr;
@@ -306,26 +304,19 @@ kern_return_t vm_copy(map, source_address, size, dest_address)
* Routine: vm_map
*/
kern_return_t vm_map(
- target_map,
- address, size, mask, anywhere,
- memory_object, offset,
- copy,
- cur_protection, max_protection, inheritance)
- vm_map_t target_map;
- vm_offset_t *address;
- vm_size_t size;
- vm_offset_t mask;
- boolean_t anywhere;
- ipc_port_t memory_object;
- vm_offset_t offset;
- boolean_t copy;
- vm_prot_t cur_protection;
- vm_prot_t max_protection;
- vm_inherit_t inheritance;
+ vm_map_t target_map,
+ vm_offset_t *address,
+ vm_size_t size,
+ vm_offset_t mask,
+ boolean_t anywhere,
+ ipc_port_t memory_object,
+ vm_offset_t offset,
+ boolean_t copy,
+ vm_prot_t cur_protection,
+ vm_prot_t max_protection,
+ vm_inherit_t inheritance)
{
- register
vm_object_t object;
- register
kern_return_t result;
if ((target_map == VM_MAP_NULL) ||
@@ -414,15 +405,32 @@ kern_return_t vm_map(
*
* [ To unwire the pages, specify VM_PROT_NONE. ]
*/
-kern_return_t vm_wire(host, map, start, size, access)
- host_t host;
- register vm_map_t map;
+kern_return_t vm_wire(port, map, start, size, access)
+ const ipc_port_t port;
+ vm_map_t map;
vm_offset_t start;
vm_size_t size;
vm_prot_t access;
{
- if (host == HOST_NULL)
+ host_t host;
+ boolean_t priv;
+
+ if (!IP_VALID(port))
+ return KERN_INVALID_HOST;
+
+ ip_lock(port);
+ if (!ip_active(port) ||
+ (ip_kotype(port) != IKOT_HOST_PRIV
+ && ip_kotype(port) != IKOT_HOST))
+ {
+ ip_unlock(port);
return KERN_INVALID_HOST;
+ }
+
+ priv = ip_kotype(port) == IKOT_HOST_PRIV;
+ ip_unlock(port);
+
+ host = (host_t) port->ip_kobject;
if (map == VM_MAP_NULL)
return KERN_INVALID_TASK;
@@ -435,6 +443,10 @@ kern_return_t vm_wire(host, map, start, size, access)
if (projected_buffer_in_range(map, start, start+size))
return(KERN_INVALID_ARGUMENT);
+ /* TODO: make it tunable */
+ if (!priv && access != VM_PROT_NONE && map->user_wired + size > 65536)
+ return KERN_NO_ACCESS;
+
return vm_map_pageable_user(map,
trunc_page(start),
round_page(start+size),
diff --git a/xen/block.c b/xen/block.c
index 4253ef04..d98b31e2 100644
--- a/xen/block.c
+++ b/xen/block.c
@@ -214,10 +214,10 @@ void hyp_block_init(void) {
continue;
}
if (partition)
- sprintf(device_name, "%s%us%u", prefix, disk, partition);
+ sprintf(device_name, "%s%ds%d", prefix, disk, partition);
else
- sprintf(device_name, "%s%u", prefix, disk);
- bd->name = (char*) kalloc(strlen(device_name));
+ sprintf(device_name, "%s%d", prefix, disk);
+ bd->name = (char*) kalloc(strlen(device_name) + 1);
strcpy(bd->name, device_name);
/* Get domain id of backend driver. */
@@ -238,7 +238,7 @@ void hyp_block_init(void) {
grant = hyp_grant_give(domid, atop(addr), 0);
/* and give it to backend. */
- i = sprintf(port_name, "%u", grant);
+ i = sprintf(port_name, "%d", grant);
c = hyp_store_write(t, port_name, 5, VBD_PATH, "/", vbds[n], "/", "ring-ref");
if (!c)
panic("%s: couldn't store ring reference (%s)", device_name, hyp_store_error);
@@ -382,8 +382,8 @@ device_open (ipc_port_t reply_port, mach_msg_type_name_t reply_port_type,
port = ipc_port_alloc_kernel();
if (port == IP_NULL) {
- err = KERN_RESOURCE_SHORTAGE;
- goto out;
+ device_close(bd);
+ return KERN_RESOURCE_SHORTAGE;
}
bd->port = port;
@@ -396,7 +396,6 @@ device_open (ipc_port_t reply_port, mach_msg_type_name_t reply_port_type,
ipc_port_nsrequest (bd->port, 1, notify, &notify);
assert (notify == IP_NULL);
-out:
if (IP_VALID (reply_port))
ds_device_open_reply (reply_port, reply_port_type, D_SUCCESS, port);
else
@@ -670,7 +669,7 @@ device_write(void *d, ipc_port_t reply_port,
hyp_grant_takeback(gref[j]);
if (err) {
- printf("error writing %d bytes at sector %d\n", count, bn);
+ printf("error writing %u bytes at sector %d\n", count, bn);
break;
}
}
diff --git a/xen/console.c b/xen/console.c
index 884376ff..313b9342 100644
--- a/xen/console.c
+++ b/xen/console.c
@@ -47,7 +47,7 @@ int hypputc(int c)
hyp_console_io(CONSOLEIO_write, 1, kvtolin(&d));
} else {
spl_t spl = splhigh();
- int complain;
+ static int complain;
simple_lock(&outlock);
while (hyp_ring_smash(console->out, console->out_prod, console->out_cons)) {
if (!complain) {
diff --git a/xen/console.h b/xen/console.h
index ad171a47..061ba281 100644
--- a/xen/console.h
+++ b/xen/console.h
@@ -21,7 +21,9 @@
#include <machine/xen.h>
#include <string.h>
+#include <mach/port.h>
#include <device/cons.h>
+#include <device/io_req.h>
#define hyp_console_write(str, len) hyp_console_io (CONSOLEIO_write, (len), kvtolin(str))
@@ -37,4 +39,12 @@ extern int hypcngetc(dev_t dev, int wait);
extern int hypcnprobe(struct consdev *cp);
extern int hypcninit(struct consdev *cp);
+extern int hypcnopen(dev_t dev, int flag, io_req_t ior);
+extern int hypcnread(int dev, io_req_t ior);
+extern int hypcnwrite(int dev, io_req_t ior);
+extern int hypcnclose(int dev, int flag);
+extern io_return_t hypcngetstat(dev_t dev, int flavor, int *data, unsigned int *count);
+extern io_return_t hypcnsetstat(dev_t dev, int flavor, int *data, unsigned int count);
+extern int hypcnportdeath(dev_t dev, mach_port_t port);
+
#endif /* XEN_CONSOLE_H */
diff --git a/xen/grant.c b/xen/grant.c
index 3d5c3fe7..ae3a7bfc 100644
--- a/xen/grant.c
+++ b/xen/grant.c
@@ -25,7 +25,7 @@
#include "grant.h"
#define NR_RESERVED_ENTRIES 8
-#define NR_GRANT_PAGES 4
+#define NR_GRANT_PAGES 8
decl_simple_lock_data(static,lock);
static struct grant_entry *grants;
diff --git a/xen/net.c b/xen/net.c
index 10e4bbef..55643651 100644
--- a/xen/net.c
+++ b/xen/net.c
@@ -366,7 +366,7 @@ void hyp_net_init(void) {
grant = hyp_grant_give(domid, atop(addr), 0);
/* and give it to backend. */
- i = sprintf(port_name, "%u", grant);
+ i = sprintf(port_name, "%d", grant);
c = hyp_store_write(t, port_name, 5, VIF_PATH, "/", vifs[n], "/", "tx-ring-ref");
if (!c)
panic("eth: couldn't store tx_ring reference for VIF %s (%s)", vifs[n], hyp_store_error);
@@ -381,7 +381,7 @@ void hyp_net_init(void) {
grant = hyp_grant_give(domid, atop(addr), 0);
/* and give it to backend. */
- i = sprintf(port_name, "%u", grant);
+ i = sprintf(port_name, "%d", grant);
c = hyp_store_write(t, port_name, 5, VIF_PATH, "/", vifs[n], "/", "rx-ring-ref");
if (!c)
panic("eth: couldn't store rx_ring reference for VIF %s (%s)", vifs[n], hyp_store_error);
@@ -568,8 +568,8 @@ device_open (ipc_port_t reply_port, mach_msg_type_name_t reply_port_type,
port = ipc_port_alloc_kernel();
if (port == IP_NULL) {
- err = KERN_RESOURCE_SHORTAGE;
- goto out;
+ device_close (nd);
+ return KERN_RESOURCE_SHORTAGE;
}
nd->port = port;
@@ -582,7 +582,6 @@ device_open (ipc_port_t reply_port, mach_msg_type_name_t reply_port_type,
ipc_port_nsrequest (nd->port, 1, notify, &notify);
assert (notify == IP_NULL);
-out:
if (IP_VALID (reply_port))
ds_device_open_reply (reply_port, reply_port_type, D_SUCCESS, dev_to_port(nd));
else
diff --git a/xen/time.c b/xen/time.c
index a11e7eb4..4ebe91fa 100644
--- a/xen/time.c
+++ b/xen/time.c
@@ -34,6 +34,7 @@ static unsigned64_t lastnsec;
static unsigned64_t hyp_get_stime(void) {
unsigned32_t version;
unsigned64_t cpu_clock, last_cpu_clock, delta, system_time;
+ unsigned64_t delta_high, delta_low;
unsigned32_t mul;
signed8_t shift;
volatile struct vcpu_time_info *time = &hyp_shared_info.vcpu_info[0].time;
@@ -54,7 +55,10 @@ static unsigned64_t hyp_get_stime(void) {
delta >>= -shift;
else
delta <<= shift;
- return system_time + ((delta * (unsigned64_t) mul) >> 32);
+ delta_high = delta >> 32;
+ delta_low = (unsigned32_t) delta;
+ return system_time + ((delta_low * (unsigned64_t) mul) >> 32)
+ + (delta_high * (unsigned64_t) mul);
}
unsigned64_t hyp_get_time(void) {
@@ -107,7 +111,6 @@ static void hypclock_intr(int unit, int old_ipl, void *ret_addr, struct i386_int
}
extern struct timeval time;
-extern struct timezone tz;
int
readtodc(tp)