2 * Copyright 2013 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
25 /******************************************************************************
27 *****************************************************************************/
30 process(PROC_KERN, 0, 0)
40 /******************************************************************************
42 *****************************************************************************/
50 // $r13 - data (return)
53 nv_iowr(NV_PPWR_MMIO_ADDR, $r14)
54 mov $r14 NV_PPWR_MMIO_CTRL_OP_RD
55 sethi $r14 NV_PPWR_MMIO_CTRL_TRIGGER
56 nv_iowr(NV_PPWR_MMIO_CTRL, $r14)
58 nv_iord($r14, NV_PPWR_MMIO_CTRL)
59 and $r14 NV_PPWR_MMIO_CTRL_STATUS
61 nv_iord($r13, NV_PPWR_MMIO_DATA)
71 nv_iowr(NV_PPWR_MMIO_ADDR, $r14)
72 nv_iowr(NV_PPWR_MMIO_DATA, $r13)
73 mov $r14 NV_PPWR_MMIO_CTRL_OP_WR
74 or $r14 NV_PPWR_MMIO_CTRL_MASK_B32_0
75 sethi $r14 NV_PPWR_MMIO_CTRL_TRIGGER
77 #ifdef NVKM_FALCON_MMIO_TRAP
78 mov $r8 NV_PPWR_INTR_TRIGGER_USER1
79 nv_iowr(NV_PPWR_INTR_TRIGGER, $r8)
81 nv_iord($r8, NV_PPWR_INTR)
82 and $r8 NV_PPWR_INTR_USER1
86 nv_iowr(NV_PPWR_MMIO_CTRL, $r14)
88 nv_iord($r14, NV_PPWR_MMIO_CTRL)
89 and $r14 NV_PPWR_MMIO_CTRL_STATUS
93 // busy-wait for a period of time
99 nv_iord($r8, NV_PPWR_TIMER_LOW)
101 nv_iord($r9, NV_PPWR_TIMER_LOW)
107 // busy-wait for a period of time
113 // $r11 - timeout (ns)
116 nv_iord($r8, NV_PPWR_TIMER_LOW)
122 nv_iord($r9, NV_PPWR_TIMER_LOW)
129 // $r15 - current (kern)
131 // $r8 - NV_PPWR_INTR
133 // read process' timer status, skip if not enabled
134 ld b32 $r9 D[$r14 + #proc_time]
136 bra z #intr_watchdog_next_proc
138 // subtract last timer's value from process' timer,
139 // if it's <= 0 then the timer has expired
140 ld b32 $r10 D[$r0 + #time_prev]
142 bra g #intr_watchdog_next_time
146 bra #intr_watchdog_next_proc
148 // otherwise, update the next timer's value if this
149 // process' timer is the soonest
150 intr_watchdog_next_time:
151 // ... or if there's no next timer yet
152 ld b32 $r10 D[$r0 + #time_next]
154 bra z #intr_watchdog_next_time_set
157 bra g #intr_watchdog_next_proc
158 intr_watchdog_next_time_set:
159 st b32 D[$r0 + #time_next] $r9
161 // update process' timer status, and advance
162 intr_watchdog_next_proc:
163 st b32 D[$r14 + #proc_time] $r9
164 add b32 $r14 #proc_size
165 cmp b32 $r14 #proc_list_tail
166 bra ne #intr_watchdog
184 nv_iord($r8, NV_PPWR_DSCRATCH(0))
186 nv_iowr(NV_PPWR_DSCRATCH(0), $r8)
188 nv_iord($r8, NV_PPWR_INTR)
189 and $r9 $r8 NV_PPWR_INTR_WATCHDOG
190 bra z #intr_skip_watchdog
191 st b32 D[$r0 + #time_next] $r0
192 mov $r14 #proc_list_head
194 ld b32 $r9 D[$r0 + #time_next]
196 bra z #intr_skip_watchdog
197 nv_iowr(NV_PPWR_WATCHDOG_TIME, $r9)
198 st b32 D[$r0 + #time_prev] $r9
201 and $r9 $r8 NV_PPWR_INTR_SUBINTR
202 bra z #intr_skip_subintr
203 nv_iord($r9, NV_PPWR_SUBINTR)
204 and $r10 $r9 NV_PPWR_SUBINTR_FIFO
205 bra z #intr_subintr_skip_fifo
206 nv_iord($r12, NV_PPWR_FIFO_INTR)
208 mov $r14 (PROC_HOST & 0x0000ffff)
209 sethi $r14 (PROC_HOST & 0xffff0000)
213 nv_iowr(NV_PPWR_FIFO_INTR, $r12)
214 intr_subintr_skip_fifo:
215 nv_iowr(NV_PPWR_SUBINTR, $r9)
218 and $r9 $r8 NV_PPWR_INTR_PAUSE
219 bra z #intr_skip_pause
223 and $r9 $r8 NV_PPWR_INTR_USER0
224 bra z #intr_skip_user0
228 nv_iowr(NV_PPWR_INTR_ACK, $r8)
243 // request the current process be sent a message after a timeout expires
249 // interrupts off to prevent racing with timer isr
252 // if current process already has a timer set, bail
253 ld b32 $r8 D[$r15 + #proc_time]
256 st b32 D[$r15 + #proc_time] $r14
258 // halt watchdog timer temporarily and check for a pending
259 // interrupt. if there's one already pending, we can just
260 // bail since the timer isr will queue the next soonest
261 // right after it's done
262 nv_iowr(NV_PPWR_WATCHDOG_ENABLE, $r8)
263 nv_iord($r8, NV_PPWR_INTR)
264 and $r8 NV_PPWR_INTR_WATCHDOG
267 // update the watchdog if this timer should expire first,
268 // or if there's no timeout already set
269 nv_iord($r8, NV_PPWR_WATCHDOG_TIME)
275 nv_iowr(NV_PPWR_WATCHDOG_TIME, $r14)
276 st b32 D[$r0 + #time_prev] $r14
278 // re-enable the watchdog timer
281 nv_iowr(NV_PPWR_WATCHDOG_ENABLE, $r8)
283 // interrupts back on
288 // send message to another process
293 // $r12 - message data 0
294 // $r11 - message data 1
299 // check for space in queue
300 ld b32 $r8 D[$r14 + #proc_qget]
301 ld b32 $r9 D[$r14 + #proc_qput]
307 and $r8 $r9 #proc_qmaskp
308 shl b32 $r8 $r8 #proc_qlen
309 add b32 $r8 #proc_queue
312 ld b32 $r10 D[$r15 + #proc_id]
313 st b32 D[$r8 + #msg_process] $r10
314 st b32 D[$r8 + #msg_message] $r13
315 st b32 D[$r8 + #msg_data0] $r12
316 st b32 D[$r8 + #msg_data1] $r11
321 st b32 D[$r14 + #proc_qput] $r9
328 // lookup process structure by its name
331 // $r14 - process name
338 mov $r8 #proc_list_head
341 ld b32 $r10 D[$r8 + #proc_id]
344 add b32 $r8 #proc_size
345 cmp b32 $r8 #proc_list_tail
353 // send message to another process
358 // $r12 - message data 0
359 // $r11 - message data 1
366 // process single message for a given process
372 ld b32 $r8 D[$r14 + #proc_qget]
373 ld b32 $r9 D[$r14 + #proc_qput]
378 and $r9 $r8 #proc_qmaskp
381 st b32 D[$r14 + #proc_qget] $r8
382 ld b32 $r10 D[$r14 + #proc_recv]
389 shl b32 $r9 $r9 #proc_qlen
391 add b32 $r14 #proc_queue
392 ld b32 $r11 D[$r14 + #msg_data1]
393 ld b32 $r12 D[$r14 + #msg_data0]
394 ld b32 $r13 D[$r14 + #msg_message]
395 ld b32 $r14 D[$r14 + #msg_process]
408 nv_iord($r1, NV_PPWR_CAPS)
413 #ifdef NVKM_FALCON_MMIO_UAS
414 // somehow allows the magic "access mmio via D[]" stuff that's
415 // used by the nv_rd32/nv_wr32 macros to work
417 sethi $r1 NV_PPWR_UAS_CONFIG_ENABLE
418 nv_iowrs(NV_PPWR_UAS_CONFIG, $r1)
421 // route all interrupts except user0/1 and pause to fuc
424 nv_iowr(NV_PPWR_INTR_ROUTE, $r1)
426 // enable watchdog and subintr intrs
427 mov $r1 NV_PPWR_INTR_EN_CLR_MASK
428 nv_iowr(NV_PPWR_INTR_EN_CLR, $r1)
429 mov $r1 NV_PPWR_INTR_EN_SET_WATCHDOG
430 or $r1 NV_PPWR_INTR_EN_SET_SUBINTR
431 nv_iowr(NV_PPWR_INTR_EN_SET, $r1)
433 // enable interrupts globally
439 // enable watchdog timer
441 nv_iowr(NV_PPWR_WATCHDOG_ENABLE, $r1)
443 // bootstrap processes, idle process will be last, and not return
444 mov $r15 #proc_list_head
446 ld b32 $r1 D[$r15 + #proc_init]
450 add b32 $r15 #proc_size