Rev 131 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 131 | Rev 133 | ||
---|---|---|---|
1 | <?xml version="1.0" encoding="UTF-8"?> |
1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | <chapter id="hardware"> |
2 | <chapter id="hardware"> |
3 | <?dbhtml filename="hardware.html"?> |
3 | <?dbhtml filename="hardware.html"?> |
4 | 4 | ||
5 | <title>Device Drivers</title> |
5 | <title>Device Drivers</title> |
6 | 6 | ||
7 | <para>Since HelenOS is a microkernel, a framework for supporting userspace |
7 | <para>Since HelenOS is a microkernel, a framework for supporting userspace |
8 | device drivers has been implemented. A typical userspace task acting as a |
8 | device drivers has been implemented. A typical userspace task acting as a |
9 | device driver might need to:</para> |
9 | device driver might need to:</para> |
10 | 10 | ||
11 | <itemizedlist> |
11 | <itemizedlist> |
12 | <listitem> |
12 | <listitem> |
13 | <para>receive notifications about interrupts sent by its device,</para> |
13 | <para>receive notifications about interrupts sent by its device,</para> |
14 | </listitem> |
14 | </listitem> |
15 | 15 | ||
16 | <listitem> |
16 | <listitem> |
17 | <para>access physical memory address space,</para> |
17 | <para>access physical memory address space,</para> |
18 | </listitem> |
18 | </listitem> |
19 | 19 | ||
20 | <listitem> |
20 | <listitem> |
21 | <para>access I/O space and</para> |
21 | <para>access I/O space and</para> |
22 | </listitem> |
22 | </listitem> |
23 | 23 | ||
24 | <listitem> |
24 | <listitem> |
25 | <para>control preemption.</para> |
25 | <para>control preemption.</para> |
26 | </listitem> |
26 | </listitem> |
27 | </itemizedlist> |
27 | </itemizedlist> |
28 | 28 | ||
29 | <section> |
29 | <section> |
30 | <title>Interrupt Notifications</title> |
30 | <title>Interrupt Notifications</title> |
31 | 31 | ||
32 | <para>Userspace tasks that are in hold of the |
32 | <para>Userspace tasks that are in hold of the |
33 | <constant>CAP_IRQ_REG</constant> capability can register themselves via |
33 | <constant>CAP_IRQ_REG</constant> capability can register themselves via |
34 | the <code>ipc_register_irq()</code> to be notified about occurrences of a |
34 | the <code>ipc_register_irq()</code> to be notified about occurrences of a |
35 | given interrupt. The registration call takes two arguments. The first |
35 | given interrupt. The registration call takes two arguments. The first |
36 | argument is the IRQ number and the second is the pointer to special |
36 | argument is the IRQ number and the second is the pointer to special |
37 | pseudocode that instructs the kernel interrupt handler how to process the |
37 | pseudocode that instructs the kernel interrupt handler how to process the |
38 | IRQ. Currently the pseudocode language supports reading and writing |
38 | IRQ. Currently the pseudocode language supports reading and writing |
39 | physical memory, reading from and writing to I/O space and actions related |
39 | physical memory, reading from and writing to I/O space and actions related |
40 | to running HelenOS in virtual environments.</para> |
40 | to running HelenOS in virtual environments.</para> |
41 | 41 | ||
42 | <para>When the interrupt comes after its handler has been registered by a |
42 | <para>When the interrupt comes after its handler has been registered by a |
43 | userspace task, the kernel interrupt handler interprets the pseudocode |
43 | userspace task, the kernel interrupt handler interprets the pseudocode |
44 | program and sends an IPC notification to the respective task. The |
44 | program and sends an IPC notification to the respective task. The |
45 | userspace task can get certain information about the interrupt (e.g. what |
45 | userspace task can get certain information about the interrupt (e.g. what |
46 | key was pressed) by issuing memory or I/O space reads in the pseudocode |
46 | key was pressed) by issuing memory or I/O space reads in the pseudocode |
47 | program. The read values are wrapped into the IPC notification sent to the |
47 | program. The read values are wrapped into the IPC notification sent to the |
48 | task. The write operations are also very essential because some interrupts |
48 | task. The write operations are also very essential because some interrupts |
49 | are level-sensitive and need to be processed in the kernel interrupt |
49 | are level-sensitive and need to be processed in the kernel interrupt |
50 | routine. In many situations, the interrupt is considered serviced only |
50 | routine. In many situations, the interrupt is considered serviced only |
51 | when the interrupt handler performs certain reads or writes of memory or |
51 | when the interrupt handler performs certain reads or writes of memory or |
52 | I/O space.</para> |
52 | I/O space.</para> |
53 | </section> |
53 | </section> |
54 | 54 | ||
55 | <section> |
55 | <section> |
56 | <title>Accessing Memory and I/O Space</title> |
56 | <title>Accessing Memory and I/O Space</title> |
57 | 57 | ||
58 | <para>When a task has the <constant>CAP_MEM_MANAGER</constant> capability, |
58 | <para>When a task has the <constant>CAP_MEM_MANAGER</constant> capability, |
59 | it can use the <constant>SYS_MAP_PHYSMEM</constant> to map regions of |
59 | it can use the <constant>SYS_MAP_PHYSMEM</constant> to map regions of |
60 | physical memory to its address space. When successful, the syscall creates |
60 | physical memory to its address space. When successful, the syscall creates |
61 | an address space area for the physical memory region. The address space |
61 | an address space area for the physical memory region. The address space |
62 | area can be further shared by other tasks. Similarily, when a task has the |
62 | area can be further shared by other tasks. Similarily, when a task has the |
63 | <constant>CAP_IOSPACE_MANAGER</constant> capability, it is entitled to |
63 | <constant>CAP_IOSPACE_MANAGER</constant> capability, it is entitled to |
64 | request access to the I/O space by using the |
64 | request access to the I/O space by using the |
65 | <constant>SYS_IOSPACE_ENABLE</constant>. However, this syscall is relevant |
65 | <constant>SYS_IOSPACE_ENABLE</constant>. However, this syscall is relevant |
66 | only on architectures that have separate I/O space (e.g. amd64 and |
66 | only on architectures that have separate I/O space (e.g. amd64 and |
67 | ia32).</para> |
67 | ia32).</para> |
68 | </section> |
68 | </section> |
69 | 69 | ||
70 | <section> |
70 | <section> |
71 | <title>Disabling Preemption</title> |
71 | <title>Disabling Preemption</title> |
72 | 72 | ||
73 | <para>It might be desirable for a device driver to temporarily disable |
73 | <para>It might be desirable for a device driver to temporarily disable |
74 | preemption. Tasks that can do this are required to have the |
74 | preemption. Tasks that can do this are required to have the |
75 | CAP_PREEMPT_CONTROL capability. Preemption could be theoretically disabled |
75 | <constant>CAP_PREEMPT_CONTROL</constant> capability. Preemption could be theoretically disabled |
76 | by disabling interrupts on the current processor, but disabling preemption |
76 | by disabling interrupts on the current processor, but disabling preemption |
77 | is more lightweight as interrupt processing remains enabled.</para> |
77 | is more lightweight as interrupt processing remains enabled.</para> |
78 | </section> |
78 | </section> |
79 | </chapter> |
79 | </chapter> |