Compare commits
38
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41a6307146 | ||
|
|
33f6568fa0 | ||
|
|
f28e09d297 | ||
|
|
0a72224228 | ||
|
|
bd071d588b | ||
|
|
9ec66b0eba | ||
|
|
95bcf78537 | ||
|
|
6f3cae4e0c | ||
|
|
b59e371c0e | ||
|
|
939505198f | ||
|
|
75cb80fd33 | ||
|
|
6ba901606d | ||
|
|
b1d329da2a | ||
|
|
df9946fe80 | ||
|
|
e3d744f1b5 | ||
|
|
8ca3758efb | ||
|
|
02916ed0ee | ||
|
|
873d4de379 | ||
|
|
b2f9cc9809 | ||
|
|
298155191d | ||
|
|
49b8cdcd54 | ||
|
|
c121db7a88 | ||
|
|
9527a0f3d1 | ||
|
|
1e05d19c4c | ||
|
|
ecdebae231 | ||
|
|
0150178c90 | ||
|
|
3caf2a7a72 | ||
|
|
019f2629dc | ||
|
|
63ee53f4a3 | ||
|
|
7c8eba2ed4 | ||
|
|
15396a0304 | ||
|
|
0969869ba8 | ||
|
|
dd3af88a30 | ||
|
|
85ae0c8703 | ||
|
|
2ad11d3acc | ||
|
|
450054a86c | ||
|
|
b0055ba472 | ||
|
|
f711f9286b |
No files matched your search
@@ -54,3 +54,27 @@
|
||||
src: "{{ stable_artifact_path }}/"
|
||||
dest: "{{ storage_path }}/../"
|
||||
mode: preserve
|
||||
|
||||
# older builds shrink to compressed images and lose their unpacked tree; the newest few keep both
|
||||
- name: Looking for zstd on the storage server
|
||||
ansible.builtin.shell: command -v zstd
|
||||
register: zstd_present
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Requiring zstd for compaction
|
||||
ansible.builtin.assert:
|
||||
that: zstd_present.rc == 0
|
||||
fail_msg: >-
|
||||
zstd is not installed on the storage server, so older builds cannot
|
||||
be compacted. Install it and re-run this build.
|
||||
|
||||
- name: Compacting older builds
|
||||
ansible.builtin.script:
|
||||
cmd: >-
|
||||
../../utils/compact-builds.sh
|
||||
{{ storage_path | quote }}
|
||||
{{ compact_keep | default(5) | int }}
|
||||
{{ compact_max | default(10) | int }}
|
||||
register: compaction
|
||||
changed_when: "'compacted 0 of' not in compaction.stdout"
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# SPDX-FileCopyrightText: 2026 KolibriOS team
|
||||
|
||||
# Shrink older builds on the storage server: compress their images and drop
|
||||
# their unpacked tree, which is rebuildable from the commit. sha256sums.txt
|
||||
# keeps naming the bare images, so a compacted build has to be decompressed
|
||||
# before it can be verified.
|
||||
#
|
||||
# Layout: <root>/<version>/<lang>/kolibrios-<descr>-<lang>.{img,iso,raw} -> .zst
|
||||
# <root>/<version>/<lang>/data/ -> removed
|
||||
#
|
||||
# Usage: compact-builds.sh <storage-root> [keep] [max-per-run]
|
||||
# DRY_RUN=1 walks the same selection and changes nothing
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
root=${1:?storage root required}
|
||||
# the build just published is always among these, so an upload in flight is safe
|
||||
keep=${2:-5}
|
||||
# a build is hundreds of MiB to re-compress: cap the first pass over the backlog
|
||||
max=${3:-10}
|
||||
dry=${DRY_RUN:-0}
|
||||
verb=compacted
|
||||
[ "$dry" = 1 ] && verb="would compact"
|
||||
|
||||
# --rm drops the source only once the archive is written; the box serves the
|
||||
# site over NFS, so compaction yields to it
|
||||
compress_image() {
|
||||
nice -n 10 ionice -c3 zstd -12 -T1 -q --rm "$1"
|
||||
}
|
||||
export -f compress_image
|
||||
|
||||
leftovers() {
|
||||
local build=$1
|
||||
find "$build" -mindepth 2 -maxdepth 2 \
|
||||
\( -type d -name data \
|
||||
-o -type f \( -name '*.img' -o -name '*.iso' -o -name '*.raw' \) \) \
|
||||
-print -quit
|
||||
}
|
||||
|
||||
compacted=0
|
||||
pending=0
|
||||
|
||||
while IFS= read -r version; do
|
||||
dir="$root/$version"
|
||||
[ -n "$(leftovers "$dir")" ] || continue
|
||||
|
||||
pending=$((pending + 1))
|
||||
[ "$compacted" -lt "$max" ] || continue
|
||||
|
||||
if [ "$dry" = 1 ]; then
|
||||
compacted=$((compacted + 1))
|
||||
echo "$verb $version"
|
||||
continue
|
||||
fi
|
||||
|
||||
# a build holds nine images: one per core, each zstd kept to one thread so
|
||||
# the two levels of parallelism do not fight. Archive before dropping the
|
||||
# tree, so a failure here leaves the build merely uncompacted and the next
|
||||
# run picks it up again
|
||||
find "$dir" -mindepth 2 -maxdepth 2 -type f \
|
||||
\( -name '*.img' -o -name '*.iso' -o -name '*.raw' \) -print0 \
|
||||
| xargs -0 -r -P "$(nproc)" -I{} bash -c 'compress_image "$@"' _ {}
|
||||
|
||||
find "$dir" -mindepth 2 -maxdepth 2 -type d -name data -exec rm -rf {} +
|
||||
|
||||
compacted=$((compacted + 1))
|
||||
echo "$verb $version"
|
||||
# <tag>-<commit count>-g<sha>: order by the count, never by mtime
|
||||
done < <(find "$root" -mindepth 1 -maxdepth 1 -type d -name '*-*-g*' -printf '%f\n' \
|
||||
| sort -t- -k2,2n | head -n "-$keep")
|
||||
|
||||
echo "$verb $compacted of $pending older build(s), $((pending - compacted)) left for the next run"
|
||||
@@ -128,7 +128,8 @@ jobs:
|
||||
fi
|
||||
|
||||
# cache restore resets ctimes; realign tup DB to skip a full rebuild,
|
||||
# but keep files changed since the cache's commit dirty so tup rebuilds them
|
||||
# but keep files changed since the cache's commit dirty so tup rebuilds them.
|
||||
# A submodule bump diffs as a bare gitlink, so expand it to its whole subtree
|
||||
- name: Sync tup DB with filesystem ctime
|
||||
if: steps.check-tup-cache.outputs.cache_restored == 'true'
|
||||
run: |
|
||||
@@ -136,6 +137,10 @@ jobs:
|
||||
BASE=$(cat .tup/build-commit 2>/dev/null || true)
|
||||
if [ -n "$BASE" ] && git cat-file -e "${BASE}^{commit}" 2>/dev/null; then
|
||||
git -c core.quotePath=false diff --name-only "$BASE" HEAD > "$DIRTY"
|
||||
git diff --raw "$BASE" HEAD | awk '$2 == "160000" { print $NF }' |
|
||||
while read -r sub; do
|
||||
git -C "$sub" -c core.quotePath=false ls-files | sed "s|^|$sub/|"
|
||||
done >> "$DIRTY"
|
||||
echo "Cache built at $BASE; $(wc -l < "$DIRTY") changed files kept dirty"
|
||||
python3 .gitea/utils/sync-tup-ctime.py .tup/db "$DIRTY"
|
||||
else
|
||||
|
||||
@@ -34,10 +34,11 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
|
||||
- name: Bump ${{ matrix.name }} and open PR
|
||||
env:
|
||||
TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
API: ${{ github.api_url }}
|
||||
REPO: ${{ github.repository }}
|
||||
NAME: ${{ matrix.name }}
|
||||
|
||||
+21
-18
@@ -41,10 +41,6 @@ img_files = {
|
||||
{"LIB/KMENU.OBJ", "common/lib/kmenu.obj"},
|
||||
{"LIB/PIXLIB.OBJ", "common/lib/pixlib.obj"},
|
||||
{"MEDIA/AC97SND", "common/media/ac97snd"},
|
||||
{"MEDIA/IMGF/IMGF", "common/media/ImgF/ImgF"},
|
||||
{"MEDIA/IMGF/CEDG.OBJ", "common/media/ImgF/cEdg.obj"},
|
||||
{"MEDIA/IMGF/DITHER.OBJ", "common/media/ImgF/dither.obj"},
|
||||
{"MEDIA/IMGF/INVSOL.OBJ", "common/media/ImgF/invSol.obj"},
|
||||
{"NETWORK/FTPC.INI", SRC_PROGS .. "/network/ftpc/ftpc.ini"},
|
||||
{"NETWORK/FTPD.INI", "common/network/ftpd.ini"},
|
||||
{"NETWORK/KNMAP", "common/network/knmap"},
|
||||
@@ -58,8 +54,7 @@ img_files = {
|
||||
{"SETTINGS/FB2READ.INI", "common/settings/fb2read.ini"},
|
||||
{"SETTINGS/HA.CFG", SRC_PROGS .. "/other/ha/SETTINGS/HA.CFG"},
|
||||
{"SETTINGS/ICON.INI", build_type .. "/settings/icon.ini"},
|
||||
{"SETTINGS/KEYMAP.KEY", SRC_PROGS .. "/system/taskbar/KEYMAP.KEY"},
|
||||
{"SETTINGS/KOLIBRI.LBL", build_type .. "/settings/kolibri.lbl"},
|
||||
{"SETTINGS/KEYMAP.KEY", VAR_PROGS .. "/system/taskbar/keymap.key.kpack"},
|
||||
{"SETTINGS/LANG.INI", build_type .. "/settings/lang.ini"},
|
||||
{"SETTINGS/MENU.DAT", build_type .. "/settings/menu.dat"},
|
||||
{"SETTINGS/NETWORK.INI", "common/settings/network.ini"},
|
||||
@@ -273,6 +268,10 @@ extra_files = {
|
||||
{"kolibrios/lib/i915_dri.drv", "common/lib/i915_dri.drv"},
|
||||
{"kolibrios/media/fplay", "common/media/fplay"},
|
||||
{"kolibrios/media/fplay_run", "common/media/fplay_run"},
|
||||
{"kolibrios/media/ImgF/ImgF", "common/media/ImgF/ImgF"},
|
||||
{"kolibrios/media/ImgF/cEdg.obj", "common/media/ImgF/cEdg.obj"},
|
||||
{"kolibrios/media/ImgF/dither.obj", "common/media/ImgF/dither.obj"},
|
||||
{"kolibrios/media/ImgF/invSol.obj", "common/media/ImgF/invSol.obj"},
|
||||
{"kolibrios/media/minimp3", "common/media/minimp3"},
|
||||
{"kolibrios/media/updf", SRC .. "/contrib/media/updf/build/uPDF"},
|
||||
{"kolibrios/media/vttf", "common/media/vttf"},
|
||||
@@ -487,11 +486,6 @@ tup.append_table(img_files, {
|
||||
{"DEVELOP/MTDBG", VAR_PROGS .. "/develop/mtdbg/mtdbg"},
|
||||
{"DEVELOP/MSTATE", VAR_PROGS .. "/develop/mstate/mstate"},
|
||||
{"DEVELOP/SCANCODE", VAR_PROGS .. "/develop/scancode/scancode"},
|
||||
{"DEVELOP/EXAMPLES/CIRCLE", VAR_PROGS .. "/develop/examples/circle/circle"},
|
||||
{"DEVELOP/EXAMPLES/COLORREF", VAR_PROGS .. "/demos/colorref/colorref"},
|
||||
{"DEVELOP/EXAMPLES/CONGET", VAR_PROGS .. "/develop/libraries/console_coff/examples/test_gets"},
|
||||
{"DEVELOP/EXAMPLES/CSLIDE", VAR_PROGS .. "/demos/cslide/cslide"},
|
||||
{"DEVELOP/EXAMPLES/THREAD", VAR_PROGS .. "/develop/examples/thread/thread"},
|
||||
{"File Managers/KFAR", VAR_PROGS .. "/fs/kfar/kfar"},
|
||||
{"File Managers/OPENDIAL", VAR_PROGS .. "/fs/opendial/opendial"},
|
||||
{"LOD", VAR_PROGS .. "/fs/lod/lod"},
|
||||
@@ -598,6 +592,7 @@ tup.append_table(img_files, {
|
||||
{"DRIVERS/VT823X.SYS", VAR_DRVS .. "/audio/vt823x.sys"},
|
||||
{"DRIVERS/SIS.SYS", VAR_DRVS .. "/audio/sis.sys"},
|
||||
{"DRIVERS/SDHCI.SYS", "../drivers/sdhci/sdhci.sys"},
|
||||
{"DRIVERS/I2CHID.SYS", VAR_DRVS .. "/i2chid/i2chid.sys"},
|
||||
})
|
||||
tup.append_table(extra_files, {
|
||||
{"HD_Load/9x2klbr/", VAR_PROGS .. "/hd_load/9x2klbr/9x2klbr.exe"},
|
||||
@@ -651,20 +646,28 @@ tup.append_table(extra_files, {
|
||||
{"kolibrios/3D/blocks/block.bin", VAR_PROGS .. "/bcc32/games/blocks/block.bin"},
|
||||
{"kolibrios/develop/tcc/lib/crt0.o", VAR_PROGS .. "/develop/ktcc/bin/lib/crt0.o", group = "../programs/develop/ktcc/<crt0.o>"},
|
||||
{"kolibrios/develop/tcc/lib/tiny.o", VAR_PROGS .. "/develop/ktcc/bin/lib/tiny.o", group = "../programs/develop/ktcc/<tiny.o>"},
|
||||
{"kolibrios/develop/tcc/lib/libsound.a", VAR_PROGS .. "/develop/ktcc/bin/lib/libsound.a", group = "../programs/develop/ktcc/<libsound.a>"}
|
||||
{"kolibrios/develop/tcc/lib/libsound.a", VAR_PROGS .. "/develop/ktcc/bin/lib/libsound.a", group = "../programs/develop/ktcc/<libsound.a>"},
|
||||
{"kolibrios/develop/examples/circle", VAR_PROGS .. "/develop/examples/circle/circle"},
|
||||
{"kolibrios/develop/examples/colorref", VAR_PROGS .. "/demos/colorref/colorref"},
|
||||
{"kolibrios/develop/examples/conget", VAR_PROGS .. "/develop/libraries/console_coff/examples/test_gets"},
|
||||
{"kolibrios/develop/examples/cslide", VAR_PROGS .. "/demos/cslide/cslide"},
|
||||
{"kolibrios/develop/examples/thread", VAR_PROGS .. "/develop/examples/thread/thread"}
|
||||
})
|
||||
-- For russian build, add russian-only programs.
|
||||
if build_type == "ru_RU" then tup.append_table(img_files, {
|
||||
{"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
|
||||
}) else tup.append_table(img_files, {
|
||||
{"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
|
||||
}) end
|
||||
-- -- For russian build, add russian-only programs.
|
||||
-- if build_type == "ru_RU" then tup.append_table(img_files, {
|
||||
-- {"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
|
||||
-- }) else tup.append_table(img_files, {
|
||||
-- {"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
|
||||
-- }) end
|
||||
|
||||
if build_type == "ru_RU" then tup.append_table(extra_files, {
|
||||
{"kolibrios/develop/examples/testcon2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
|
||||
{"kolibrios/utils/period", VAR_PROGS .. "/other/period/period"},
|
||||
{"kolibrios/games/Dungeons/Dungeons", VAR_PROGS .. "/games/Dungeons/Dungeons"},
|
||||
{"kolibrios/games/klavisha/klavisha", VAR_PROGS .. "/games/klavisha/klavisha"},
|
||||
{"kolibrios/games/klavisha/basekurs.kla", "ru_RU/games/basekurs.kla"},
|
||||
}) else tup.append_table(extra_files, {
|
||||
{"kolibrios/develop/examples/testcon2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
|
||||
}) end
|
||||
|
||||
end -- tup.getconfig('NO_FASM') ~= 'full'
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
#/SYS/CROPFLAT "XS800 YS480" 1 # set limits of screen
|
||||
#/SYS/LOADDRV COMMOUSE 1 # serial mouse driver
|
||||
#/SYS/DEVELOP/BOARD "" 0 # Load DEBUG board
|
||||
#/SYS/LOADDRV RDC 0 # videodriver for RDC M2010/M2012
|
||||
/SYS/SETUP BOOT 0 # Load device settings
|
||||
/SYS/LOADDRV RDC 0 # videodriver for RDC M2010/M2012
|
||||
/SYS/LOADDRV I2CHID 0 # Start I2C touchpad driver
|
||||
/SYS/@TASKBAR "" 0 # Start taskbar
|
||||
/SYS/ESKIN "" 0 # Set style
|
||||
/SYS/@ICON "" 0 # Multithread desktop icons
|
||||
|
||||
@@ -5,6 +5,22 @@ font smoothing=sbp
|
||||
font height=9
|
||||
speaker mute=off
|
||||
|
||||
[touchpad]
|
||||
speed=100
|
||||
; how far a finger must move before the pointer follows, in pad units;
|
||||
; larger is steadier under a pressing finger, 0 turns the filter off
|
||||
jitter=1
|
||||
; the same, for a finger that landed on the button strip: it is pressing
|
||||
; rather than steering there, so it needs a stricter margin
|
||||
jitter_buttons=45
|
||||
scroll_step=64
|
||||
scroll_invert=0
|
||||
tap_enable=1
|
||||
tap_drag=1
|
||||
right_click=1
|
||||
button_zone=15
|
||||
right_split=50
|
||||
|
||||
[mouse]
|
||||
speed=4
|
||||
acceleration=3
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
06 zSea Image Viewer * |/kolibrios/media/zsea/zsea
|
||||
38 Animage |media/animage
|
||||
38 IconEdit |media/iconedit
|
||||
40 Image Filtering |media/imgf/imgf
|
||||
40 Image Filtering * |/kolibrios/media/ImgF/ImgF
|
||||
52 Palitra |media/palitra
|
||||
39 Pipet |develop/pipet
|
||||
#4 **** MULTIMEDIA
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
16 Image viewer KIV |media/kiv
|
||||
16 Image viewer zSea * |/kolibrios/media/zsea/zsea
|
||||
16 Animage |media/animage
|
||||
16 Efectos de imаgenes |media/imgf/imgf
|
||||
16 Efectos de imаgenes * |/kolibrios/media/ImgF/ImgF
|
||||
16 Palitra |media/palitra
|
||||
#4 **** MULTIMEDIA
|
||||
16 Pixie Audioplayer |media/pixie
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
06 Image viewer zSea * |/kolibrios/media/zsea/zsea
|
||||
38 Animage |media/animage
|
||||
38 IconEdit |media/iconedit
|
||||
16 Image Filtering |media/imgf/imgf
|
||||
16 Image Filtering * |/kolibrios/media/ImgF/ImgF
|
||||
52 Palitra |media/palitra
|
||||
39 Pipet |develop/pipet
|
||||
#4 **** MULTIMEDIA ****
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
06 Image viewer zSea * |/kolibrios/media/zsea/zsea
|
||||
38 Animage |media/animage
|
||||
38 IconEdit |media/iconedit
|
||||
40 Image Filtering |media/imgf/imgf
|
||||
40 Image Filtering * |/kolibrios/media/ImgF/ImgF
|
||||
52 Palitra |media/palitra
|
||||
39 Pipet |develop/pipet
|
||||
#4 **** MULTIMEDIA
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
06 Просмотр фото zSea |/kolibrios/media/zsea/zsea
|
||||
38 Редактор Animage |media/animage
|
||||
38 Редактор иконок |media/iconedit
|
||||
40 Наложение фильтров |media/imgf/imgf
|
||||
40 Наложение фильтров * |/kolibrios/media/ImgF/ImgF
|
||||
52 Палитра |media/palitra
|
||||
39 Пипетка |develop/pipet
|
||||
#4 **** Звук и видео
|
||||
|
||||
@@ -273,8 +273,8 @@ RIRB_INT_RESPONSE equ 0x01
|
||||
RIRB_INT_OVERRUN equ 0x04
|
||||
RIRB_INT_MASK equ 0x05
|
||||
|
||||
; STATESTS int mask: SD2,SD1,SD0
|
||||
STATESTS_INT_MASK equ 0x07
|
||||
; STATESTS int mask: SDIWAKE[14:0], a 16-bit register
|
||||
STATESTS_INT_MASK equ 0x7FFF
|
||||
AZX_MAX_CODECS equ 4
|
||||
|
||||
; SD_CTL bits
|
||||
@@ -402,6 +402,7 @@ struc AC_CNTRL ;AC controller base class
|
||||
.response_reset dd 0
|
||||
.polling_mode db 0
|
||||
.poll_count db 0
|
||||
.no_irq db 0 ; no interrupt line: a thread runs hda_irq
|
||||
.posbuf dd ?
|
||||
.start_wallclk dd ? ; start + minimum wallclk
|
||||
.period_wallclk dd ? ; wallclk for period
|
||||
@@ -505,8 +506,6 @@ macro spin_unlock
|
||||
pop ebx eax
|
||||
}
|
||||
|
||||
data fixups
|
||||
end data
|
||||
|
||||
include '../../struct.inc'
|
||||
include '../../macros.inc'
|
||||
@@ -607,9 +606,6 @@ if IRQ_REMAP
|
||||
invoke SysMsgBoardStr
|
||||
end if
|
||||
|
||||
mov ebx, [ctrl.int_line]
|
||||
invoke AttachIntHandler, ebx, hda_irq, dword 0
|
||||
|
||||
;Asper This part is from "azx_probe" proc. [
|
||||
call azx_codec_create
|
||||
cmp eax, 0
|
||||
@@ -858,13 +854,13 @@ end if
|
||||
|
||||
mov edx, ICH6_REG_SD_STS + SDO_OFS
|
||||
call azx_readb
|
||||
mov bl, al
|
||||
mov cl, al
|
||||
|
||||
mov al, SD_INT_MASK
|
||||
mov edx, ICH6_REG_SD_STS + SDO_OFS
|
||||
call azx_writeb
|
||||
|
||||
test bl, SD_INT_COMPLETE
|
||||
test cl, SD_INT_COMPLETE
|
||||
jz @f
|
||||
|
||||
mov eax, [ctrl.civ_val]
|
||||
@@ -901,13 +897,13 @@ end if
|
||||
;if 0
|
||||
; clear state status int
|
||||
mov edx, ICH6_REG_STATESTS
|
||||
call azx_readb
|
||||
test al, 0x04
|
||||
call azx_readw
|
||||
and eax, STATESTS_INT_MASK
|
||||
jz @f
|
||||
|
||||
mov al, 0x04
|
||||
; ack all state-change bits, else the level IRQ line stays asserted
|
||||
mov edx, ICH6_REG_STATESTS
|
||||
call azx_writeb
|
||||
call azx_writew
|
||||
@@:
|
||||
;end if
|
||||
or eax, 1
|
||||
@@ -915,6 +911,24 @@ end if
|
||||
ret
|
||||
endp
|
||||
|
||||
; Stand-in for the interrupt when no interrupt line is available. A thread,
|
||||
; not a TimerHS callback: the kernel calls timer callbacks with the global
|
||||
; timer list lock held, and hda_irq may stall and refill the audio buffer.
|
||||
; hda_irq runs with interrupts off, as it would in IRQ context: it holds
|
||||
; aspinlock, which azx_rirb_get_response waits for with interrupts off, so
|
||||
; a holder that could be preempted would hang the machine.
|
||||
proc hda_poll_thread
|
||||
.loop:
|
||||
pushfd
|
||||
cli
|
||||
call hda_irq
|
||||
popfd
|
||||
mov eax, 5 ; delay, sleeping instead of spinning
|
||||
mov ebx, 1 ; 10 ms; a 16 KB period is ~85 ms at 48 kHz
|
||||
int 0x40
|
||||
jmp .loop
|
||||
endp
|
||||
|
||||
|
||||
align 4
|
||||
proc create_primary_buff
|
||||
@@ -1203,6 +1217,26 @@ end if
|
||||
; allocate CORB/RIRB
|
||||
call azx_alloc_cmd_io
|
||||
|
||||
; attach the IRQ handler BEFORE the controller may raise interrupts:
|
||||
; azx_init_chip enables GIE/CIE and a codec state-change can fire
|
||||
; right away; an unclaimed level IRQ makes the
|
||||
; kernel poll foreign handlers and relink their IRQH nodes onto our
|
||||
; line (see irq_serv .try_other_irqs), corrupting the dispatch list
|
||||
; a warm reboot can leave GIE and a stale completion bit behind, and
|
||||
; civ_val is never resynced, so silence the controller before attaching
|
||||
call azx_int_disable
|
||||
mov ebx, [ctrl.int_line]
|
||||
invoke AttachIntHandler, ebx, hda_irq, dword 0
|
||||
test eax, eax
|
||||
jnz @f
|
||||
; No usable interrupt line (INTLINE=0xFF on boards that route INTx only
|
||||
; through ACPI _PRT or MSI, which the kernel does not parse). The
|
||||
; controller still latches INTSTS/SD_STS, we only lose the wakeup - so
|
||||
; poll the RIRB for codec replies and run the interrupt handler from a
|
||||
; thread. A flag of its own: polling_mode is the timeout recovery state.
|
||||
mov [ctrl.no_irq], 1
|
||||
@@:
|
||||
|
||||
; initialize chip
|
||||
call azx_init_pci
|
||||
|
||||
@@ -1210,6 +1244,32 @@ end if
|
||||
call azx_init_chip
|
||||
;] Asper
|
||||
|
||||
; no IRQ line: let a polling thread stand in for the interrupt.
|
||||
; Started only now - earlier, hda_irq could ack STATESTS in the window
|
||||
; before reset_controller reads it into codec_mask
|
||||
cmp [ctrl.no_irq], 0
|
||||
je @f
|
||||
push esi edi ; CreateThread clobbers them, START needs esi
|
||||
mov ebx, 1
|
||||
mov ecx, hda_poll_thread
|
||||
xor edx, edx
|
||||
invoke CreateThread
|
||||
pop edi esi
|
||||
test eax, eax
|
||||
jns .thread_ok
|
||||
; nothing would ever complete a period and playback would stall,
|
||||
; so fail the init rather than register a service that hangs
|
||||
mov esi, msgNoIrqThread
|
||||
invoke SysMsgBoardStr
|
||||
xor eax, eax
|
||||
ret
|
||||
.thread_ok:
|
||||
if DEBUG
|
||||
mov esi, msgNoIrqPoll
|
||||
invoke SysMsgBoardStr
|
||||
end if
|
||||
@@:
|
||||
|
||||
xor eax, eax
|
||||
inc eax
|
||||
ret
|
||||
@@ -1243,7 +1303,7 @@ endl
|
||||
; clear STATESTS
|
||||
mov eax, STATESTS_INT_MASK
|
||||
mov edx, ICH6_REG_STATESTS
|
||||
call azx_writeb
|
||||
call azx_writew
|
||||
|
||||
; reset controller
|
||||
mov edx, ICH6_REG_GCTL
|
||||
@@ -1454,6 +1514,12 @@ endp
|
||||
|
||||
proc azx_alloc_cmd_io
|
||||
push eax ecx edx
|
||||
; the unsolicited-event ring lives in reserved storage, so its
|
||||
; pointers hold garbage until we clear them here - do it before
|
||||
; reset_controller enables unsolicited responses in GCTL
|
||||
mov [unsol_events.rp], 0
|
||||
mov [unsol_events.wp], 0
|
||||
|
||||
; single page (at least 4096 bytes) must suffice for both ringbuffers
|
||||
invoke KernelAlloc, 4096
|
||||
mov [ctrl.rb], eax
|
||||
@@ -1654,14 +1720,24 @@ endl
|
||||
mov ecx, 1000;+1000
|
||||
.next_try:
|
||||
mov al, [ctrl.polling_mode]
|
||||
test al, al
|
||||
or al, [ctrl.no_irq]
|
||||
jnz .poll
|
||||
mov ah, [do_poll]
|
||||
test ah, ah
|
||||
jz @f
|
||||
.poll:
|
||||
spin_lock_irq
|
||||
; take the lock hda_irq holds so two RIRB readers never overlap
|
||||
push eax ebx
|
||||
mov eax, aspinlock
|
||||
.poll_lock:
|
||||
mov ebx, SPINLOCK_BUSY
|
||||
lock xchg [eax], ebx
|
||||
cmp ebx, SPINLOCK_FREE
|
||||
jnz .poll_lock
|
||||
pop ebx eax
|
||||
call azx_update_rirb
|
||||
mov [aspinlock], SPINLOCK_FREE
|
||||
spin_unlock_irq
|
||||
@@:
|
||||
mov eax, [ctrl.rirb_cmd]
|
||||
@@ -1942,6 +2018,7 @@ proc azx_int_disable
|
||||
mov ebx, ICH6_INT_CTRL_EN or ICH6_INT_GLOBAL_EN
|
||||
xor ebx, -1
|
||||
and eax, ebx
|
||||
mov edx, ICH6_REG_INTCTL ; azx_readl turned edx into the absolute address
|
||||
call azx_writel
|
||||
pop edx ebx eax
|
||||
ret
|
||||
@@ -1957,9 +2034,9 @@ proc azx_int_clear
|
||||
call azx_writeb
|
||||
|
||||
; clear STATESTS
|
||||
mov al, STATESTS_INT_MASK
|
||||
mov ax, STATESTS_INT_MASK
|
||||
mov edx, ICH6_REG_STATESTS
|
||||
call azx_writeb
|
||||
call azx_writew
|
||||
|
||||
; clear rirb status
|
||||
mov al, RIRB_INT_MASK
|
||||
@@ -2696,6 +2773,7 @@ proc snd_hda_queue_unsol_event stdcall, res:dword, res_ex:dword
|
||||
; only carries EBX across iterations and reloads the rest, and TimerHS
|
||||
; preserves EBX too - so by using scratch regs only we need no saves.
|
||||
mov eax, [unsol_events.wp]
|
||||
and eax, HDA_UNSOL_QUEUE_SIZE - 1 ; never index the ring wild
|
||||
lea edx, [eax+1]
|
||||
and edx, HDA_UNSOL_QUEUE_SIZE - 1 ; next write pos (size must be 2^n)
|
||||
cmp edx, [unsol_events.rp]
|
||||
@@ -2998,6 +3076,7 @@ sz_sound_srv db 'SOUND',0
|
||||
|
||||
msgInit db 'detect hardware...',13,10,0
|
||||
msgFail db 'device not found',13,10,0
|
||||
msgNoIrqThread db 'no IRQ line: cannot create polling thread',13,10,0
|
||||
msgAttchIRQ db 'IRQ line not supported', 13,10,0
|
||||
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10,0
|
||||
msgPlay db 'start play', 13,10,0
|
||||
@@ -3067,6 +3146,7 @@ if DEBUG
|
||||
msgTCSEL db 'PCI TCSEL ',0
|
||||
msgTV db 'HDA test version ',TEST_VERSION_NUMBER,13,10,0
|
||||
msgGCap db 'GCAP = ',0
|
||||
msgNoIrqPoll db 'no IRQ line: polling thread',13,10,0
|
||||
end if
|
||||
|
||||
if USE_SINGLE_MODE
|
||||
@@ -3101,6 +3181,11 @@ end if
|
||||
|
||||
;] Asper
|
||||
|
||||
; relocation table lives after all code and initialized data: placed before the
|
||||
; code its size feeds back into every relocation site and fasm may never converge
|
||||
data fixups
|
||||
end data
|
||||
|
||||
aspinlock dd SPINLOCK_FREE
|
||||
|
||||
codec CODEC
|
||||
|
||||
+100
-14
@@ -130,6 +130,8 @@ RU_STATUS_IDLE = 0000b shl 2
|
||||
RU_STATUS_SUSPENDED = 0001b shl 2
|
||||
RU_STATUS_NO_RESOURCES = 0010b shl 2
|
||||
RU_STATUS_READY = 0100b shl 2
|
||||
SCB_STATUS_CUS = 11000000b ; CU Status
|
||||
CU_STATUS_ACTIVE = 10b shl 6
|
||||
SCB_STATUS_FCP = 1 shl 8 ; Flow Control Pause
|
||||
SCB_STATUS_SWI = 1 shl 10 ; Software Interrupt
|
||||
SCB_STATUS_MDI = 1 shl 11 ; MDI read/write complete
|
||||
@@ -183,6 +185,8 @@ struct txfd
|
||||
|
||||
ends
|
||||
|
||||
TXFD_STATUS_C = 1 shl 15
|
||||
|
||||
TXFD_CMD_IA = 1 shl 0
|
||||
TXFD_CMD_CFG = 1 shl 1
|
||||
TXFD_CMD_TX = 1 shl 2
|
||||
@@ -628,6 +632,9 @@ reset:
|
||||
mov ax, CU_START or INT_MASK
|
||||
out dx, ax
|
||||
call cmd_wait
|
||||
; cmd_wait only means the SCB accepted the command. The Configure below
|
||||
; reuses confcmd, so a slow chip would read it instead of our MAC.
|
||||
call confcmd_wait
|
||||
|
||||
;-------------
|
||||
; Configure CU
|
||||
@@ -652,6 +659,7 @@ reset:
|
||||
mov ax, CU_START ; expect Interrupts from now on
|
||||
out dx, ax
|
||||
call cmd_wait
|
||||
call confcmd_wait
|
||||
|
||||
; Start media check timer
|
||||
mov [ebx + device.state], ETH_LINK_DOWN
|
||||
@@ -678,6 +686,11 @@ init_rx_ring:
|
||||
;---------------------
|
||||
; build rxfd structure
|
||||
|
||||
cmp [ebx + device.rx_desc], 0 ; the RFD of an earlier reset
|
||||
je @f
|
||||
invoke NetFree, [ebx + device.rx_desc]
|
||||
mov [ebx + device.rx_desc], 0
|
||||
@@:
|
||||
invoke NetAlloc, 2000
|
||||
test eax, eax
|
||||
jz .out_of_mem
|
||||
@@ -689,6 +702,7 @@ init_rx_ring:
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.link], eax
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.rx_buf_addr], 0xffffffff ; simplified mode, no RBD
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
|
||||
|
||||
ret
|
||||
@@ -709,6 +723,15 @@ init_tx_ring:
|
||||
invoke GetPhysAddr
|
||||
mov ecx, TX_RING_SIZE
|
||||
.next_desc:
|
||||
; after a reset with frames still unreclaimed: free them, or transmit sees the
|
||||
; descriptor busy (virt_addr) and reports TX overrun forever
|
||||
cmp [esi + txfd.virt_addr], 0
|
||||
je @f
|
||||
push eax ecx
|
||||
invoke NetFree, [esi + txfd.virt_addr]
|
||||
pop ecx eax
|
||||
mov [esi + txfd.virt_addr], 0
|
||||
@@:
|
||||
mov [esi + txfd.status], 0
|
||||
mov [esi + txfd.command], 0
|
||||
lea edx, [eax + txfd.buf_addr]
|
||||
@@ -763,7 +786,7 @@ proc transmit stdcall bufferptr
|
||||
lea edi, [ebx + device.tx_ring + eax]
|
||||
|
||||
; Check if current descriptor is free or still in use
|
||||
cmp [edi + txfd.status], 0
|
||||
cmp [edi + txfd.virt_addr], 0 ; buffer not reclaimed yet
|
||||
jne .overrun
|
||||
|
||||
; Fill in status and command values
|
||||
@@ -786,6 +809,22 @@ proc transmit stdcall bufferptr
|
||||
mov eax, edi
|
||||
invoke GetPhysAddr
|
||||
set_io [ebx + device.io_addr], 0
|
||||
|
||||
; CU_START is only valid while the CU is idle or suspended:
|
||||
; wait for the previous frame to leave (1.2 ms at 10 Mbit)
|
||||
push eax ecx
|
||||
set_io [ebx + device.io_addr], REG_SCB_STATUS
|
||||
mov ecx, 100000
|
||||
.cu_busy:
|
||||
in al, dx
|
||||
and al, SCB_STATUS_CUS
|
||||
cmp al, CU_STATUS_ACTIVE
|
||||
jne .cu_free
|
||||
dec ecx
|
||||
jnz .cu_busy
|
||||
DEBUGF 2, "CU still active, starting anyway\n"
|
||||
.cu_free:
|
||||
pop ecx eax
|
||||
set_io [ebx + device.io_addr], REG_SCB_PTR
|
||||
out dx, eax
|
||||
|
||||
@@ -854,7 +893,7 @@ int_handler:
|
||||
|
||||
DEBUGF 1,"Status: %x\n", ax
|
||||
|
||||
test ax, SCB_STATUS_FR ; did we receive a frame?
|
||||
test ax, SCB_STATUS_FR or SCB_STATUS_RNR ; frame received or receiver stopped?
|
||||
jz .no_rx
|
||||
|
||||
push ax
|
||||
@@ -901,6 +940,7 @@ int_handler:
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.link], eax
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.rx_buf_addr], 0xffffffff ; simplified mode, no RBD
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
|
||||
|
||||
; restart RX
|
||||
@@ -916,11 +956,22 @@ int_handler:
|
||||
mov ax, RX_START
|
||||
out dx, ax
|
||||
call cmd_wait
|
||||
.out_of_mem:
|
||||
|
||||
; Hand the frame over to the kernel
|
||||
jmp [EthInput]
|
||||
|
||||
.out_of_mem:
|
||||
; The buffer is still our only RFD: drop the frame and reuse it
|
||||
mov esi, [esp] ; the buffer
|
||||
mov ecx, [esi + NET_BUFF.length]
|
||||
dec [ebx + device.packets_rx] ; counted above, before the allocation
|
||||
sub dword [ebx + device.bytes_rx], ecx
|
||||
sbb dword [ebx + device.bytes_rx + 4], 0
|
||||
inc [ebx + device.packets_rx_drop]
|
||||
add esp, 12 ; buffer, .rx_loop, ebx
|
||||
mov esi, [ebx + device.rx_desc]
|
||||
jmp .not_ok
|
||||
|
||||
.not_ok:
|
||||
; Reset the FD
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.status], 0
|
||||
@@ -945,6 +996,27 @@ int_handler:
|
||||
|
||||
.no_rx_:
|
||||
DEBUGF 1, "no more data\n"
|
||||
|
||||
; With a single RFD the receiver sits in No Resources/Suspended whenever a
|
||||
; frame arrived before we re-armed it. Nothing restarts it but us.
|
||||
set_io [ebx + device.io_addr], 0
|
||||
set_io [ebx + device.io_addr], REG_SCB_STATUS
|
||||
in al, dx
|
||||
and al, SCB_STATUS_RUS
|
||||
cmp al, RU_STATUS_READY
|
||||
je .ru_ready
|
||||
test byte[esp], 1 ; bit 0 of the saved status is reserved,
|
||||
jnz .ru_ready ; we mark it: one restart per IRQ
|
||||
or byte[esp], 1
|
||||
movzx eax, al
|
||||
DEBUGF 1, "Restarting receiver, RU status %x\n", eax:2
|
||||
mov esi, [ebx + device.rx_desc]
|
||||
push ebx
|
||||
test [esi + sizeof.NET_BUFF + rxfd.status], RXFD_STATUS_C
|
||||
jnz .rx_loop ; a frame completed meanwhile
|
||||
add esp, 4
|
||||
jmp .not_ok ; re-arm the empty RFD
|
||||
.ru_ready:
|
||||
pop ax
|
||||
|
||||
.no_rx:
|
||||
@@ -955,13 +1027,13 @@ int_handler:
|
||||
|
||||
push eax
|
||||
.loop_tx:
|
||||
mov edi, [ebx + device.last_tx]
|
||||
mov eax, sizeof.txfd
|
||||
mul eax
|
||||
mov eax, [ebx + device.last_tx]
|
||||
mov edx, sizeof.txfd
|
||||
mul edx
|
||||
lea edi, [ebx + device.tx_ring + eax]
|
||||
|
||||
cmp [edi + txfd.status], 0
|
||||
je .tx_done
|
||||
test [edi + txfd.status], TXFD_STATUS_C ; sent by the device?
|
||||
jz .tx_done
|
||||
|
||||
cmp [edi + txfd.virt_addr], 0
|
||||
je .tx_done
|
||||
@@ -970,6 +1042,7 @@ int_handler:
|
||||
|
||||
push [edi + txfd.virt_addr]
|
||||
mov [edi + txfd.virt_addr], 0
|
||||
mov [edi + txfd.status], 0 ; free for transmit again
|
||||
invoke NetFree
|
||||
|
||||
inc [ebx + device.last_tx]
|
||||
@@ -980,12 +1053,6 @@ int_handler:
|
||||
pop eax
|
||||
.no_tx:
|
||||
|
||||
test ax, RU_STATUS_NO_RESOURCES
|
||||
jz .not_out_of_resources
|
||||
|
||||
DEBUGF 2, "Out of resources!\n"
|
||||
|
||||
.not_out_of_resources:
|
||||
pop edi esi ebx
|
||||
xor eax, eax
|
||||
inc eax
|
||||
@@ -1079,6 +1146,25 @@ proc check_media_mii stdcall dev:dword
|
||||
endp
|
||||
|
||||
|
||||
; Wait (up to 1 s) until the device has executed the command in confcmd.
|
||||
align 4
|
||||
confcmd_wait:
|
||||
mov ecx, 1000 ; udelay = Sleep(1), 1 ms
|
||||
.loop:
|
||||
test [ebx + device.confcmd.status], TXFD_STATUS_C
|
||||
jnz .done
|
||||
call udelay
|
||||
dec ecx
|
||||
jnz .loop
|
||||
movzx eax, [ebx + device.confcmd.command]
|
||||
DEBUGF 2, "Command 0x%x not completed\n", eax:4
|
||||
ret
|
||||
.done:
|
||||
movzx eax, [ebx + device.confcmd.command]
|
||||
movzx ecx, [ebx + device.confcmd.status]
|
||||
DEBUGF 1, "Command 0x%x done, status 0x%x\n", eax:4, ecx:4
|
||||
ret
|
||||
|
||||
align 4
|
||||
cmd_wait:
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
if tup.getconfig("NO_FASM") ~= "" then return end
|
||||
ROOT = "../.."
|
||||
tup.rule("i2chid.asm", "fasm %f %o " .. tup.getconfig("PESTRIP_CMD") .. tup.getconfig("KPACK_CMD"), "%B.sys")
|
||||
@@ -0,0 +1,438 @@
|
||||
; Synopsys DesignWare I2C master, polled (PIO) mode only.
|
||||
; This is the controller inside Intel LPSS blocks (Skylake and newer, plus
|
||||
; Atom-derived SoCs); the same IP is used by many other vendors.
|
||||
;
|
||||
; The register file is always accessed as dwords. The controller must be
|
||||
; disabled to change IC_TAR, so every transfer disables it, programs the
|
||||
; target address, enables it back and feeds the TX FIFO by hand.
|
||||
|
||||
; ------------------------------ Registers ------------------------------------
|
||||
DwIcCon = 0x00
|
||||
DwIcTar = 0x04
|
||||
DwIcDataCmd = 0x10
|
||||
DwIcSsSclHcnt = 0x14
|
||||
DwIcSsSclLcnt = 0x18
|
||||
DwIcFsSclHcnt = 0x1C
|
||||
DwIcFsSclLcnt = 0x20
|
||||
DwIcIntrStat = 0x2C
|
||||
DwIcIntrMask = 0x30
|
||||
DwIcRawIntrStat = 0x34
|
||||
DwIcRxTl = 0x38
|
||||
DwIcTxTl = 0x3C
|
||||
DwIcClrIntr = 0x40
|
||||
DwIcClrTxAbrt = 0x54
|
||||
DwIcEnable = 0x6C
|
||||
DwIcStatus = 0x70
|
||||
DwIcTxflr = 0x74
|
||||
DwIcRxflr = 0x78
|
||||
DwIcSdaHold = 0x7C
|
||||
DwIcTxAbrtSource = 0x80
|
||||
DwIcEnableStatus = 0x9C
|
||||
DwIcCompParam1 = 0xF4
|
||||
DwIcCompVersion = 0xF8
|
||||
DwIcCompType = 0xFC
|
||||
|
||||
; "DW_apb_i2c" component signature ('DW' + 0x0140).
|
||||
DW_COMP_TYPE_VALUE = 0x44570140
|
||||
|
||||
; IC_CON: master, standard speed (100 kHz), restarts allowed, slave disabled.
|
||||
DW_CON_MASTER = 1 shl 0
|
||||
DW_CON_SPEED_STD = 1 shl 1
|
||||
DW_CON_SPEED_FAST = 2 shl 1
|
||||
DW_CON_RESTART_EN = 1 shl 5
|
||||
DW_CON_SLAVE_DIS = 1 shl 6
|
||||
|
||||
; IC_DATA_CMD bits above the data byte.
|
||||
DW_CMD_READ = 1 shl 8
|
||||
DW_CMD_STOP = 1 shl 9
|
||||
DW_CMD_RESTART = 1 shl 10
|
||||
|
||||
; IC_STATUS bits
|
||||
DW_STAT_TFNF = 1 shl 1 ; TX FIFO not full
|
||||
DW_STAT_TFE = 1 shl 2 ; TX FIFO empty
|
||||
DW_STAT_RFNE = 1 shl 3 ; RX FIFO not empty
|
||||
DW_STAT_MST_ACT = 1 shl 5 ; master FSM busy
|
||||
|
||||
; IC_RAW_INTR_STAT bits
|
||||
DW_INT_TX_ABRT = 1 shl 6
|
||||
|
||||
; SCL timing for standard mode. The LPSS input clock is 100 MHz on the PCH
|
||||
; parts and 133 MHz on the Atom-derived SoCs (Apollo Lake, Gemini Lake), and
|
||||
; nothing in PCI config space says which one this is, so the counts are
|
||||
; picked to satisfy the fast-mode minimums at the fastest of them: at
|
||||
; 133 MHz that is tHIGH = 0.98 us and tLOW = 1.5 us, 400 kHz. On a 100 MHz
|
||||
; part the same counts run the bus at 300 kHz, which is just as legal.
|
||||
; Fast mode rather than standard: HID over I2C requires every device to
|
||||
; support it, that is what Windows drives them at, and a polled host pays
|
||||
; for every byte with busy-waiting - at 100 kHz a 64-byte input read costs
|
||||
; 6 ms, more than a fast pad takes to produce the next report, and the
|
||||
; backlog that builds up plays back as the cursor coasting after the finger
|
||||
; has stopped. SDA hold stays well below tLOW.
|
||||
DW_FS_HCNT = 130
|
||||
DW_FS_LCNT = 200
|
||||
DW_SDA_HOLD = 28
|
||||
; The AMD FCH feeds its DesignWare masters from a 150 MHz reference, so
|
||||
; the same minimums need more counts there: 145/225 give tHIGH = 0.97 us,
|
||||
; tLOW = 1.5 us, again 400 kHz; SDA hold 45 = 300 ns.
|
||||
DW_AMD_FS_HCNT = 145
|
||||
DW_AMD_FS_LCNT = 225
|
||||
DW_AMD_SDA_HOLD = 45
|
||||
|
||||
; A transfer gives up after [XferTimeout] hundredths of a second. The init
|
||||
; value must cover a full report descriptor read: descriptors run up to 2 KB
|
||||
; and the bus may be as slow as 77 kHz, so at 9 SCL cycles per byte a single
|
||||
; transfer takes ~240 ms of wall-clock time. Polling is generous too now that it runs in its own thread
|
||||
; rather than in a timer callback - a wedged bus costs this thread its slice
|
||||
; and nothing else.
|
||||
DW_TIMEOUT_INIT = 60
|
||||
DW_TIMEOUT_POLL = 20
|
||||
|
||||
; Disables the controller and waits until it reports itself disabled.
|
||||
; in: ebx = MMIO base. Clobbers eax, ecx.
|
||||
proc dw_ctrl_disable
|
||||
mov dword [ebx+DwIcEnable], 0
|
||||
mov ecx, 100000
|
||||
@@:
|
||||
test dword [ebx+DwIcEnableStatus], 1
|
||||
jz .done
|
||||
pause
|
||||
loop @b
|
||||
.done:
|
||||
ret
|
||||
endp
|
||||
|
||||
; Aborts a stuck transfer cleanly: the ABORT bit makes the master issue STOP,
|
||||
; flush the TX FIFO and raise TX_ABRT, which releases a slave that is holding
|
||||
; the bus (a clock-stretching touchpad, for instance). Simply disabling the
|
||||
; controller in the middle of a byte would leave SDA held low and every
|
||||
; following transfer would time out too. Older cores without the ABORT bit
|
||||
; just ignore the write and fall through after the wait.
|
||||
; in: ebx = MMIO base. Clobbers eax, ecx.
|
||||
proc dw_ctrl_abort
|
||||
mov dword [ebx+DwIcEnable], 3
|
||||
mov ecx, 100000
|
||||
@@:
|
||||
test dword [ebx+DwIcRawIntrStat], DW_INT_TX_ABRT
|
||||
jnz @f
|
||||
pause
|
||||
loop @b
|
||||
@@:
|
||||
mov eax, [ebx+DwIcClrTxAbrt]
|
||||
call dw_ctrl_disable
|
||||
ret
|
||||
endp
|
||||
|
||||
; One idle step of a transfer wait loop.
|
||||
; A healthy transfer is over within a few milliseconds, well inside the
|
||||
; first two timer ticks, and spins through them: a transfer that yields
|
||||
; its slice is at the scheduler's mercy for the rest of it. Past that the
|
||||
; bus is stuck or crawling, and the wait gives up the CPU a tick at a time
|
||||
; instead of burning a core until XferTimeout.
|
||||
; in: eax = ticks elapsed since the transfer began. Preserves all but eax.
|
||||
DW_SPIN_TICKS = 2
|
||||
|
||||
proc dw_wait_step
|
||||
cmp eax, DW_SPIN_TICKS
|
||||
jae .yield
|
||||
pause
|
||||
ret
|
||||
.yield:
|
||||
push ebx
|
||||
movi ebx, 1
|
||||
invoke Delay ; preserves every register
|
||||
pop ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
; One-time controller setup after mapping.
|
||||
; in: ebx = MMIO base.
|
||||
proc dw_ctrl_init
|
||||
push eax ecx
|
||||
call dw_ctrl_disable
|
||||
mov dword [ebx+DwIcCon], DW_CON_MASTER + DW_CON_SPEED_FAST + \
|
||||
DW_CON_RESTART_EN + DW_CON_SLAVE_DIS
|
||||
; The counts come from variables: they depend on the reference clock, which
|
||||
; is decided by whoever found the controller (PCI LPSS or AMD FCH). The
|
||||
; standard-mode registers get the same values scaled up so that they are
|
||||
; sane should anything ever switch the speed bits back.
|
||||
mov eax, [DwHcnt]
|
||||
mov [ebx+DwIcFsSclHcnt], eax
|
||||
lea eax, [eax*4]
|
||||
mov [ebx+DwIcSsSclHcnt], eax
|
||||
mov eax, [DwLcnt]
|
||||
mov [ebx+DwIcFsSclLcnt], eax
|
||||
lea eax, [eax*4]
|
||||
mov [ebx+DwIcSsSclLcnt], eax
|
||||
mov eax, [DwSdaHold]
|
||||
mov [ebx+DwIcSdaHold], eax
|
||||
mov dword [ebx+DwIcIntrMask], 0
|
||||
mov dword [ebx+DwIcRxTl], 0
|
||||
mov dword [ebx+DwIcTxTl], 0
|
||||
mov eax, [ebx+DwIcClrIntr]
|
||||
pop ecx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; One combined I2C transaction: optional write phase, then optional read phase
|
||||
; with a repeated START between them. Fully polled.
|
||||
; out: eax = 0 on success, IC_TX_ABRT_SOURCE value on NAK/abort, -1 on timeout.
|
||||
proc dw_xfer stdcall uses ebx esi edi, addr:dword, wbuf:dword, wlen:dword, \
|
||||
rbuf:dword, rlen:dword
|
||||
locals
|
||||
wsent dd ?
|
||||
rqueued dd ?
|
||||
rgot dd ?
|
||||
t0 dd ?
|
||||
endl
|
||||
mov ebx, [I2cMmio]
|
||||
call dw_ctrl_disable
|
||||
mov eax, [addr]
|
||||
mov [ebx+DwIcTar], eax
|
||||
mov eax, [ebx+DwIcClrIntr]
|
||||
mov dword [ebx+DwIcEnable], 1
|
||||
xor eax, eax
|
||||
mov [wsent], eax
|
||||
mov [rqueued], eax
|
||||
mov [rgot], eax
|
||||
invoke GetTimerTicks
|
||||
mov [t0], eax
|
||||
.loop:
|
||||
; Abort (NAK and friends) ends the transfer immediately.
|
||||
test dword [ebx+DwIcRawIntrStat], DW_INT_TX_ABRT
|
||||
jnz .abort
|
||||
; Drain the RX FIFO first so it can never overflow.
|
||||
test dword [ebx+DwIcStatus], DW_STAT_RFNE
|
||||
jz .no_rx
|
||||
mov edx, [rgot]
|
||||
cmp edx, [rlen]
|
||||
jae .no_rx
|
||||
mov eax, [ebx+DwIcDataCmd]
|
||||
mov edi, [rbuf]
|
||||
mov [edi+edx], al
|
||||
inc edx
|
||||
mov [rgot], edx
|
||||
jmp .loop
|
||||
.no_rx:
|
||||
; Feed the write phase.
|
||||
mov eax, [wsent]
|
||||
cmp eax, [wlen]
|
||||
jae .push_reads
|
||||
test dword [ebx+DwIcStatus], DW_STAT_TFNF
|
||||
jz .check_done
|
||||
mov esi, [wbuf]
|
||||
movzx edx, byte [esi+eax]
|
||||
inc eax
|
||||
cmp eax, [wlen]
|
||||
jne @f
|
||||
cmp [rlen], 0
|
||||
jne @f
|
||||
or edx, DW_CMD_STOP ; last byte of a write-only transfer
|
||||
@@:
|
||||
mov [ebx+DwIcDataCmd], edx
|
||||
mov [wsent], eax
|
||||
jmp .loop
|
||||
.push_reads:
|
||||
; Feed read commands, at most 8 outstanding so the RX FIFO keeps up.
|
||||
mov eax, [rqueued]
|
||||
cmp eax, [rlen]
|
||||
jae .check_done
|
||||
mov edx, eax
|
||||
sub edx, [rgot]
|
||||
cmp edx, 8
|
||||
jae .check_done
|
||||
test dword [ebx+DwIcStatus], DW_STAT_TFNF
|
||||
jz .check_done
|
||||
mov edx, DW_CMD_READ
|
||||
test eax, eax
|
||||
jnz @f
|
||||
cmp [wlen], 0
|
||||
je @f
|
||||
or edx, DW_CMD_RESTART ; repeated START after the write phase
|
||||
@@:
|
||||
mov ecx, [rlen]
|
||||
dec ecx
|
||||
cmp eax, ecx
|
||||
jne @f
|
||||
or edx, DW_CMD_STOP
|
||||
@@:
|
||||
mov [ebx+DwIcDataCmd], edx
|
||||
inc eax
|
||||
mov [rqueued], eax
|
||||
jmp .loop
|
||||
.check_done:
|
||||
mov eax, [rgot]
|
||||
cmp eax, [rlen]
|
||||
jne .not_done
|
||||
mov eax, [wsent]
|
||||
cmp eax, [wlen]
|
||||
jne .not_done
|
||||
mov eax, [ebx+DwIcStatus]
|
||||
test eax, DW_STAT_TFE
|
||||
jz .not_done
|
||||
test eax, DW_STAT_MST_ACT
|
||||
jnz .not_done
|
||||
call dw_ctrl_disable
|
||||
xor eax, eax
|
||||
ret
|
||||
.not_done:
|
||||
invoke GetTimerTicks
|
||||
sub eax, [t0]
|
||||
cmp eax, [XferTimeout]
|
||||
jae .timeout
|
||||
call dw_wait_step
|
||||
jmp .loop
|
||||
.abort:
|
||||
mov esi, [ebx+DwIcTxAbrtSource]
|
||||
mov eax, [ebx+DwIcClrTxAbrt]
|
||||
call dw_ctrl_disable
|
||||
mov eax, esi
|
||||
test eax, eax
|
||||
jnz @f
|
||||
or eax, 0x80000000
|
||||
@@:
|
||||
ret
|
||||
.timeout:
|
||||
call dw_ctrl_abort
|
||||
or eax, -1
|
||||
ret
|
||||
endp
|
||||
|
||||
; Reads one HID input report as a single continuous bus transaction, the way
|
||||
; interrupt-driven hosts (Windows, Linux) do it: the optional register-address
|
||||
; write and every read command are queued into the TX FIFO before the bytes
|
||||
; start flowing, so nothing on the wire depends on how fast the host loop
|
||||
; runs. The previous adaptive read (fetch 2 length bytes, decide, fetch the
|
||||
; rest, stop short) was cut down on the wire to 3 bytes for an empty poll -
|
||||
; and the SIPODEV/Hantick touchpad firmwares are exactly the kind of thing
|
||||
; that wedges when an input read is shorter than the frame they prepared.
|
||||
; rlen should not exceed the TX FIFO depth (IC_COMP_PARAM_1 bits 23:16, plus
|
||||
; one) or the queue loop degrades to feeding the FIFO on the fly, which
|
||||
; reintroduces pauses.
|
||||
; in: addr = slave, wlen bytes at wbuf written first (0 = plain read),
|
||||
; rlen bytes read into buf.
|
||||
; out: eax = 0 ok, IC_TX_ABRT_SOURCE on NAK/abort, -1 on timeout.
|
||||
; Timeout check for the dw_read_block wait spots; expands inside the proc so
|
||||
; [t0] and [XferTimeout] resolve in the caller's own frame.
|
||||
macro BLOCK_TICK fail_label {
|
||||
invoke GetTimerTicks
|
||||
sub eax, [t0]
|
||||
cmp eax, [XferTimeout]
|
||||
jae fail_label
|
||||
call dw_wait_step
|
||||
}
|
||||
|
||||
proc dw_read_block stdcall uses ebx esi edi, addr:dword, wbuf:dword, wlen:dword, buf:dword, rlen:dword
|
||||
locals
|
||||
rgot dd ?
|
||||
t0 dd ?
|
||||
endl
|
||||
mov ebx, [I2cMmio]
|
||||
call dw_ctrl_disable
|
||||
mov eax, [addr]
|
||||
mov [ebx+DwIcTar], eax
|
||||
mov eax, [ebx+DwIcClrIntr]
|
||||
mov dword [ebx+DwIcEnable], 1
|
||||
invoke GetTimerTicks
|
||||
mov [t0], eax
|
||||
mov [rgot], 0
|
||||
; Write phase: the register address bytes, no STOP - the read continues the
|
||||
; same transaction after a repeated START.
|
||||
xor ecx, ecx
|
||||
.wr:
|
||||
cmp ecx, [wlen]
|
||||
jae .queue_reads
|
||||
test dword [ebx+DwIcRawIntrStat], DW_INT_TX_ABRT
|
||||
jnz .abort
|
||||
test dword [ebx+DwIcStatus], DW_STAT_TFNF
|
||||
jz .wr_wait
|
||||
mov esi, [wbuf]
|
||||
movzx edx, byte [esi+ecx]
|
||||
mov [ebx+DwIcDataCmd], edx
|
||||
inc ecx
|
||||
jmp .wr
|
||||
.wr_wait:
|
||||
BLOCK_TICK .timeout
|
||||
jmp .wr
|
||||
.queue_reads:
|
||||
xor ecx, ecx
|
||||
.rq:
|
||||
cmp ecx, [rlen]
|
||||
jae .drain
|
||||
test dword [ebx+DwIcRawIntrStat], DW_INT_TX_ABRT
|
||||
jnz .abort
|
||||
test dword [ebx+DwIcStatus], DW_STAT_TFNF
|
||||
jz .rq_wait
|
||||
mov edx, DW_CMD_READ
|
||||
test ecx, ecx
|
||||
jnz .not_first
|
||||
cmp [wlen], 0
|
||||
je .not_first
|
||||
or edx, DW_CMD_RESTART
|
||||
.not_first:
|
||||
mov eax, [rlen]
|
||||
dec eax
|
||||
cmp ecx, eax
|
||||
jne @f
|
||||
or edx, DW_CMD_STOP
|
||||
@@:
|
||||
mov [ebx+DwIcDataCmd], edx
|
||||
inc ecx
|
||||
; Drain opportunistically so a FIFO shallower than rlen cannot deadlock the
|
||||
; queue loop (the RX side fills while the TX side is full).
|
||||
test dword [ebx+DwIcStatus], DW_STAT_RFNE
|
||||
jz .rq
|
||||
call .take_byte
|
||||
jmp .rq
|
||||
.rq_wait:
|
||||
BLOCK_TICK .timeout
|
||||
jmp .rq
|
||||
.drain:
|
||||
test dword [ebx+DwIcRawIntrStat], DW_INT_TX_ABRT
|
||||
jnz .abort
|
||||
test dword [ebx+DwIcStatus], DW_STAT_RFNE
|
||||
jz .chk
|
||||
call .take_byte
|
||||
jmp .drain
|
||||
; Moves one byte from the RX FIFO into the caller's buffer. Exactly rlen
|
||||
; reads are queued into freshly flushed FIFOs, so a byte beyond rlen should
|
||||
; never arrive; if one does anyway it is still taken off the FIFO, so the
|
||||
; drain loop cannot stall on it, but it is dropped rather than written
|
||||
; past the end of the buffer.
|
||||
.take_byte:
|
||||
mov edx, [rgot]
|
||||
mov eax, [ebx+DwIcDataCmd]
|
||||
cmp edx, [rlen]
|
||||
jae @f
|
||||
mov edi, [buf]
|
||||
mov [edi+edx], al
|
||||
inc edx
|
||||
mov [rgot], edx
|
||||
@@:
|
||||
retn
|
||||
.chk:
|
||||
mov eax, [rgot]
|
||||
cmp eax, [rlen]
|
||||
jne .wait
|
||||
test dword [ebx+DwIcStatus], DW_STAT_MST_ACT
|
||||
jnz .wait
|
||||
call dw_ctrl_disable
|
||||
xor eax, eax
|
||||
ret
|
||||
.wait:
|
||||
BLOCK_TICK .timeout
|
||||
jmp .drain
|
||||
.abort:
|
||||
mov esi, [ebx+DwIcTxAbrtSource]
|
||||
mov eax, [ebx+DwIcClrTxAbrt]
|
||||
call dw_ctrl_disable
|
||||
mov eax, esi
|
||||
test eax, eax
|
||||
jnz @f
|
||||
or eax, 0x80000000
|
||||
@@:
|
||||
ret
|
||||
.timeout:
|
||||
call dw_ctrl_abort
|
||||
or eax, -1
|
||||
ret
|
||||
endp
|
||||
@@ -0,0 +1,646 @@
|
||||
; Minimal HID report descriptor parser.
|
||||
;
|
||||
; The goal is not a full HID implementation: the parser walks the descriptor
|
||||
; once and remembers the bit layout of the first input report that contains
|
||||
; relative X and relative Y (Generic Desktop / X, Y) - i.e. the mouse
|
||||
; compatibility collection that every I2C mouse and every Windows Precision
|
||||
; Touchpad exposes. Buttons (Usage Page 9) and a relative wheel found in the
|
||||
; same report are picked up too. Absolute (digitizer) reports are advanced
|
||||
; over but otherwise ignored.
|
||||
;
|
||||
; Report IDs are honoured: bit positions are counted separately per report ID
|
||||
; and the chosen ID is checked in every incoming packet.
|
||||
;
|
||||
; Alongside the mouse report, the parser also maps the touchpad (Windows
|
||||
; Precision Touchpad) report: the report that carries Tip Switch usages.
|
||||
; Each Tip Switch opens a new finger block; the absolute X and Y that follow
|
||||
; it belong to that finger; Contact Count and the Button-page fields of the
|
||||
; same report are recorded too. Once the pad is switched into touchpad mode
|
||||
; those offsets are what the frame decoder reads - every vendor lays the
|
||||
; frame out differently, and only the descriptor knows how.
|
||||
HID_MAX_FINGERS = 5
|
||||
|
||||
HID_MAX_USAGES = 16
|
||||
HID_MAX_REPIDS = 16
|
||||
|
||||
; Returns the pointer to the input bit counter of the current report ID,
|
||||
; allocating a new slot on first use.
|
||||
; out: ebx -> dword bit counter. Clobbers eax, ecx.
|
||||
proc hid_get_bits_slot
|
||||
mov eax, [p_report_id]
|
||||
xor ecx, ecx
|
||||
.scan:
|
||||
cmp ecx, [p_idcnt]
|
||||
jae .add
|
||||
cmp eax, [p_ids+ecx*4]
|
||||
jz .found
|
||||
inc ecx
|
||||
jmp .scan
|
||||
.add:
|
||||
cmp ecx, HID_MAX_REPIDS
|
||||
jb @f
|
||||
dec ecx ; table full: reuse the last slot
|
||||
jmp .found
|
||||
@@:
|
||||
mov [p_ids+ecx*4], eax
|
||||
mov dword [p_bits+ecx*4], 0
|
||||
mov dword [p_fbits+ecx*4], 0
|
||||
inc [p_idcnt]
|
||||
.found:
|
||||
lea ebx, [p_bits+ecx*4]
|
||||
ret
|
||||
endp
|
||||
|
||||
; Handles one Input main item. v_flags = item data (bit 2 = relative).
|
||||
proc hid_process_input
|
||||
push eax ebx ecx edx
|
||||
call hid_get_bits_slot
|
||||
mov eax, [ebx]
|
||||
mov [v_base], eax
|
||||
; Advance the counter over this field right away.
|
||||
mov eax, [p_report_size]
|
||||
imul eax, [p_report_count]
|
||||
add [ebx], eax
|
||||
; Remember the largest logical maximum ever attached to Generic Desktop X
|
||||
; and Y. The mouse collection declares a tiny relative range there while
|
||||
; the touchpad collection declares the real surface extents, so the
|
||||
; maximum over the whole descriptor is the size of the pad - which is what
|
||||
; the button zones are measured against, and it differs per model.
|
||||
cmp [p_usage_cnt], 0
|
||||
je .no_extent
|
||||
xor ecx, ecx
|
||||
.ext_loop:
|
||||
cmp ecx, [p_usage_cnt]
|
||||
jae .no_extent
|
||||
mov eax, [p_usages+ecx*4]
|
||||
cmp eax, 0x00010030
|
||||
jne .ext_y
|
||||
mov eax, [p_log_max]
|
||||
cmp eax, [t_padmaxx]
|
||||
jbe .ext_next
|
||||
mov [t_padmaxx], eax
|
||||
jmp .ext_next
|
||||
.ext_y:
|
||||
cmp eax, 0x00010031
|
||||
jne .ext_next
|
||||
mov eax, [p_log_max]
|
||||
cmp eax, [t_padmaxy]
|
||||
jbe .ext_next
|
||||
mov [t_padmaxy], eax
|
||||
.ext_next:
|
||||
inc ecx
|
||||
jmp .ext_loop
|
||||
.no_extent:
|
||||
; Button-style field: Usage Minimum/Maximum on the Button page.
|
||||
cmp [p_usage_min], -1
|
||||
je .not_buttons
|
||||
cmp [p_usage_max], -1
|
||||
je .not_buttons
|
||||
cmp [p_usage_page], 9
|
||||
jne .not_buttons
|
||||
cmp [p_report_size], 1 ; buttons are always 1-bit fields
|
||||
jne .done
|
||||
mov eax, [v_base]
|
||||
mov ecx, [p_report_count]
|
||||
call hid_note_buttons
|
||||
jmp .done
|
||||
.not_buttons:
|
||||
cmp [p_usage_cnt], 0
|
||||
je .done
|
||||
call hid_note_touchpad
|
||||
; Usage-list field: look for GD/X, GD/Y, GD/Wheel among the usages.
|
||||
test [v_flags], 4 ; only relative fields are interesting
|
||||
jz .done
|
||||
xor ecx, ecx
|
||||
.usage_loop:
|
||||
cmp ecx, [p_report_count]
|
||||
jae .done
|
||||
; usage index = min(field index, usage count - 1): a short usage list
|
||||
; applies its last usage to the remaining fields.
|
||||
mov edx, [p_usage_cnt]
|
||||
dec edx
|
||||
mov eax, ecx
|
||||
cmp eax, edx
|
||||
jbe @f
|
||||
mov eax, edx
|
||||
@@:
|
||||
mov eax, [p_usages+eax*4]
|
||||
cmp eax, 0x00010030
|
||||
je .is_x
|
||||
cmp eax, 0x00010031
|
||||
je .is_y
|
||||
cmp eax, 0x00010038
|
||||
je .is_wheel
|
||||
.next_usage:
|
||||
inc ecx
|
||||
jmp .usage_loop
|
||||
.is_x:
|
||||
test [t_have], 1
|
||||
jnz .next_usage
|
||||
call hid_claim_report_id
|
||||
jc .next_usage
|
||||
call hid_field_offset
|
||||
mov [t_xoff], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_xsize], eax
|
||||
or [t_have], 1
|
||||
jmp .next_usage
|
||||
.is_y:
|
||||
test [t_have], 2
|
||||
jnz .next_usage
|
||||
call hid_claim_report_id
|
||||
jc .next_usage
|
||||
call hid_field_offset
|
||||
mov [t_yoff], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_ysize], eax
|
||||
or [t_have], 2
|
||||
jmp .next_usage
|
||||
.is_wheel:
|
||||
test [t_have], 8
|
||||
jnz .next_usage
|
||||
mov eax, [t_id]
|
||||
cmp eax, -1 ; wheel never claims a report on its own
|
||||
je .next_usage
|
||||
cmp eax, [p_report_id]
|
||||
jne .next_usage
|
||||
call hid_field_offset
|
||||
mov [t_woff], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_wsize], eax
|
||||
or [t_have], 8
|
||||
jmp .next_usage
|
||||
.done:
|
||||
pop edx ecx ebx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Records a run of 1-bit Button-page fields starting at bit eax, ecx of them.
|
||||
; The mouse decoder wants the buttons of ITS report: an item from some other
|
||||
; report is kept only until a better one turns up, and .eof drops it if it
|
||||
; still does not match. The touchpad report keeps its own copy.
|
||||
proc hid_note_buttons
|
||||
push eax ecx edx
|
||||
cmp ecx, 8
|
||||
jbe @f
|
||||
mov ecx, 8
|
||||
@@:
|
||||
mov edx, [p_report_id]
|
||||
cmp edx, [t_ptp_id]
|
||||
jne .mouse
|
||||
cmp [t_pbtn_cnt], 0
|
||||
jne .mouse
|
||||
mov [t_pbtn_off], eax
|
||||
mov [t_pbtn_cnt], ecx
|
||||
.mouse:
|
||||
cmp [t_btncnt], 0
|
||||
je .take
|
||||
mov edx, [t_btnid]
|
||||
cmp edx, [t_id] ; already the chosen report's: keep
|
||||
je .done
|
||||
mov edx, [p_report_id]
|
||||
cmp edx, [t_btnid] ; a second run in the same report: keep the first
|
||||
je .done
|
||||
.take:
|
||||
mov [t_btnoff], eax
|
||||
mov [t_btncnt], ecx
|
||||
mov eax, [p_report_id]
|
||||
mov [t_btnid], eax
|
||||
.done:
|
||||
pop edx ecx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Walks the usages of the current input item looking for the touchpad
|
||||
; fields. Field k takes usage min(k, count-1), as in the mouse search.
|
||||
proc hid_note_touchpad
|
||||
push eax ebx ecx edx
|
||||
xor ecx, ecx
|
||||
.field:
|
||||
cmp ecx, [p_report_count]
|
||||
jae .done
|
||||
mov edx, [p_usage_cnt]
|
||||
dec edx
|
||||
mov eax, ecx
|
||||
cmp eax, edx
|
||||
jbe @f
|
||||
mov eax, edx
|
||||
@@:
|
||||
mov ebx, [p_usages+eax*4] ; ebx = usage of field ecx
|
||||
call hid_field_offset ; eax = its bit offset
|
||||
cmp ebx, 0x000D0042 ; Tip Switch: a new finger
|
||||
je .tip
|
||||
cmp ebx, 0x000D0054 ; Contact Count
|
||||
je .count
|
||||
cmp ebx, 0x000D0051 ; Contact Identifier
|
||||
je .cid
|
||||
cmp ebx, 0x00010030
|
||||
je .x
|
||||
cmp ebx, 0x00010031
|
||||
je .y
|
||||
shr ebx, 16
|
||||
cmp ebx, 9 ; buttons written as a usage list
|
||||
jne .next
|
||||
push ecx
|
||||
neg ecx
|
||||
add ecx, [p_report_count] ; the fields from here to the end
|
||||
call hid_note_buttons
|
||||
pop ecx
|
||||
jmp .done ; one run per item is enough
|
||||
.tip:
|
||||
cmp [t_ptp_id], -1
|
||||
jne @f
|
||||
mov edx, [p_report_id]
|
||||
mov [t_ptp_id], edx ; the first report with fingers is the one
|
||||
@@:
|
||||
call hid_in_ptp
|
||||
jne .next
|
||||
mov edx, [t_fcount]
|
||||
cmp edx, HID_MAX_FINGERS
|
||||
jae .next
|
||||
mov [t_ftip+edx*4], eax
|
||||
mov dword [t_fxs+edx*4], 0
|
||||
mov dword [t_fys+edx*4], 0
|
||||
mov dword [t_fcids+edx*4], 0
|
||||
inc [t_fcount]
|
||||
jmp .next
|
||||
.cid:
|
||||
call hid_in_ptp
|
||||
jne .next
|
||||
mov edx, [t_fcount]
|
||||
test edx, edx
|
||||
jz .next
|
||||
dec edx
|
||||
cmp dword [t_fcids+edx*4], 0
|
||||
jne .next
|
||||
mov [t_fcid+edx*4], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_fcids+edx*4], eax
|
||||
jmp .next
|
||||
.count:
|
||||
call hid_in_ptp
|
||||
jne .next
|
||||
mov [t_ccnt_off], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_ccnt_size], eax
|
||||
jmp .next
|
||||
.x:
|
||||
test [v_flags], 4 ; absolute only; relative is the mouse
|
||||
jnz .next
|
||||
call hid_in_ptp
|
||||
jne .next
|
||||
mov edx, [t_fcount]
|
||||
test edx, edx
|
||||
jz .next
|
||||
dec edx
|
||||
cmp dword [t_fxs+edx*4], 0
|
||||
jne .next
|
||||
mov [t_fx+edx*4], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_fxs+edx*4], eax
|
||||
jmp .next
|
||||
.y:
|
||||
test [v_flags], 4
|
||||
jnz .next
|
||||
call hid_in_ptp
|
||||
jne .next
|
||||
mov edx, [t_fcount]
|
||||
test edx, edx
|
||||
jz .next
|
||||
dec edx
|
||||
cmp dword [t_fys+edx*4], 0
|
||||
jne .next
|
||||
mov [t_fy+edx*4], eax
|
||||
mov eax, [p_report_size]
|
||||
mov [t_fys+edx*4], eax
|
||||
.next:
|
||||
inc ecx
|
||||
jmp .field
|
||||
.done:
|
||||
pop edx ecx ebx eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; ZF set when the current item belongs to the touchpad report.
|
||||
proc hid_in_ptp
|
||||
push eax
|
||||
mov eax, [p_report_id]
|
||||
cmp eax, [t_ptp_id]
|
||||
pop eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Size in bytes of the feature report with id eax; 0 when the descriptor
|
||||
; never mentioned one.
|
||||
proc hid_feature_bytes
|
||||
push ecx
|
||||
xor ecx, ecx
|
||||
@@:
|
||||
cmp ecx, [p_idcnt]
|
||||
jae .none
|
||||
cmp eax, [p_ids+ecx*4]
|
||||
je .found
|
||||
inc ecx
|
||||
jmp @b
|
||||
.found:
|
||||
mov eax, [p_fbits+ecx*4]
|
||||
add eax, 7
|
||||
shr eax, 3
|
||||
pop ecx
|
||||
ret
|
||||
.none:
|
||||
xor eax, eax
|
||||
pop ecx
|
||||
ret
|
||||
endp
|
||||
|
||||
; Locks the candidate report ID to the current one, or fails (CF=1) when a
|
||||
; different report already holds X/Y.
|
||||
proc hid_claim_report_id
|
||||
mov eax, [t_id]
|
||||
cmp eax, -1
|
||||
jne @f
|
||||
mov eax, [p_report_id]
|
||||
mov [t_id], eax
|
||||
clc
|
||||
ret
|
||||
@@:
|
||||
cmp eax, [p_report_id]
|
||||
jne .taken
|
||||
clc
|
||||
ret
|
||||
.taken:
|
||||
stc
|
||||
ret
|
||||
endp
|
||||
|
||||
; Bit offset of field #ecx of the current item.
|
||||
; in: ecx = field index. out: eax = v_base + ecx * report_size.
|
||||
proc hid_field_offset
|
||||
mov eax, [p_report_size]
|
||||
imul eax, ecx
|
||||
add eax, [v_base]
|
||||
ret
|
||||
endp
|
||||
|
||||
; Parses the report descriptor.
|
||||
; in: esi -> descriptor, ecx = length.
|
||||
; out: eax = 1 and f_* variables filled if a usable report was found.
|
||||
proc hid_parse_report_desc uses ebx esi edi
|
||||
lea edi, [esi+ecx]
|
||||
xor eax, eax
|
||||
mov [p_usage_page], eax
|
||||
mov [p_report_size], eax
|
||||
mov [p_report_count], eax
|
||||
mov [p_report_id], eax
|
||||
mov [p_uses_repid], eax
|
||||
mov [p_usage_cnt], eax
|
||||
mov [p_idcnt], eax
|
||||
mov [p_log_max], eax
|
||||
mov [t_padmaxx], eax
|
||||
mov [t_padmaxy], eax
|
||||
mov [t_have], eax
|
||||
mov [t_btncnt], eax
|
||||
mov [t_wsize], eax
|
||||
mov [p_usage_min], -1
|
||||
mov [p_usage_max], -1
|
||||
mov [t_id], -1
|
||||
mov [t_btnid], -2
|
||||
mov [t_ptp_id], -1
|
||||
mov [t_fcount], eax
|
||||
mov [t_ccnt_size], eax
|
||||
mov [t_pbtn_cnt], eax
|
||||
mov [t_ptp_bytes], eax
|
||||
.loop:
|
||||
cmp esi, edi
|
||||
jae .eof
|
||||
movzx eax, byte [esi]
|
||||
inc esi
|
||||
cmp al, 0xFE
|
||||
je .long_item
|
||||
mov ecx, eax
|
||||
and ecx, 3
|
||||
cmp ecx, 3
|
||||
jne @f
|
||||
inc ecx ; size code 3 means 4 bytes
|
||||
@@:
|
||||
lea ebx, [esi+ecx]
|
||||
cmp ebx, edi
|
||||
ja .eof
|
||||
xor edx, edx
|
||||
jecxz .no_data
|
||||
cmp ecx, 1
|
||||
jne @f
|
||||
movzx edx, byte [esi]
|
||||
jmp .have_data
|
||||
@@:
|
||||
cmp ecx, 2
|
||||
jne @f
|
||||
movzx edx, word [esi]
|
||||
jmp .have_data
|
||||
@@:
|
||||
mov edx, [esi]
|
||||
.have_data:
|
||||
add esi, ecx
|
||||
.no_data:
|
||||
and eax, 0xFC
|
||||
; Global items
|
||||
cmp al, 0x04
|
||||
je .g_usage_page
|
||||
cmp al, 0x84
|
||||
je .g_report_id
|
||||
cmp al, 0x74
|
||||
je .g_report_size
|
||||
cmp al, 0x94
|
||||
je .g_report_count
|
||||
cmp al, 0x24
|
||||
je .g_log_max
|
||||
; Local items
|
||||
cmp al, 0x08
|
||||
je .l_usage
|
||||
cmp al, 0x18
|
||||
je .l_usage_min
|
||||
cmp al, 0x28
|
||||
je .l_usage_max
|
||||
; Main items
|
||||
cmp al, 0x80
|
||||
je .m_input
|
||||
cmp al, 0x90
|
||||
je .m_clear_locals
|
||||
cmp al, 0xB0
|
||||
je .m_feature
|
||||
cmp al, 0xA0
|
||||
je .m_clear_locals
|
||||
cmp al, 0xC0
|
||||
je .m_clear_locals
|
||||
jmp .loop
|
||||
.g_usage_page:
|
||||
and edx, 0xFFFF
|
||||
mov [p_usage_page], edx
|
||||
jmp .loop
|
||||
.g_report_id:
|
||||
mov [p_report_id], edx
|
||||
mov [p_uses_repid], 1
|
||||
jmp .loop
|
||||
.g_report_size:
|
||||
mov [p_report_size], edx
|
||||
jmp .loop
|
||||
.g_report_count:
|
||||
mov [p_report_count], edx
|
||||
jmp .loop
|
||||
.g_log_max:
|
||||
mov [p_log_max], edx
|
||||
jmp .loop
|
||||
.l_usage:
|
||||
mov ebx, [p_usage_cnt]
|
||||
cmp ebx, HID_MAX_USAGES
|
||||
jae .loop
|
||||
cmp ecx, 4 ; 4-byte usage carries its own page
|
||||
je @f
|
||||
mov eax, [p_usage_page]
|
||||
shl eax, 16
|
||||
or edx, eax
|
||||
@@:
|
||||
mov [p_usages+ebx*4], edx
|
||||
inc [p_usage_cnt]
|
||||
jmp .loop
|
||||
.l_usage_min:
|
||||
mov [p_usage_min], edx
|
||||
jmp .loop
|
||||
.l_usage_max:
|
||||
mov [p_usage_max], edx
|
||||
jmp .loop
|
||||
.m_input:
|
||||
mov [v_flags], edx
|
||||
call hid_process_input
|
||||
jmp .m_clear_locals ; input bits are not feature bits
|
||||
.m_feature:
|
||||
; Feature reports are only ever written, never decoded, but writing one
|
||||
; needs its exact size: a SET_REPORT shorter than the report is ignored by
|
||||
; some firmwares (the Elan Input Mode report has two bytes, mode and the
|
||||
; selective-reporting switches - one byte does nothing there).
|
||||
call hid_get_bits_slot
|
||||
mov eax, [p_report_size]
|
||||
imul eax, [p_report_count]
|
||||
add [p_fbits+ecx*4], eax
|
||||
.m_clear_locals:
|
||||
xor eax, eax
|
||||
mov [p_usage_cnt], eax
|
||||
mov [p_usage_min], -1
|
||||
mov [p_usage_max], -1
|
||||
jmp .loop
|
||||
.long_item:
|
||||
cmp esi, edi
|
||||
jae .eof
|
||||
movzx ecx, byte [esi]
|
||||
lea esi, [esi+ecx+2]
|
||||
jmp .loop
|
||||
.eof:
|
||||
; Size of the touchpad report, when there is one.
|
||||
mov eax, [t_ptp_id]
|
||||
cmp eax, -1
|
||||
je .no_ptp
|
||||
xor ecx, ecx
|
||||
@@:
|
||||
cmp ecx, [p_idcnt]
|
||||
jae .no_ptp
|
||||
cmp eax, [p_ids+ecx*4]
|
||||
je @f
|
||||
inc ecx
|
||||
jmp @b
|
||||
@@:
|
||||
mov eax, [p_bits+ecx*4]
|
||||
add eax, 7
|
||||
shr eax, 3
|
||||
mov [t_ptp_bytes], eax
|
||||
.no_ptp:
|
||||
; Success needs relative X and Y in the same report - or, failing that, a
|
||||
; touchpad report with at least one complete finger, which is then the only
|
||||
; thing the device will be driven through.
|
||||
mov eax, [t_have]
|
||||
and eax, 3
|
||||
cmp eax, 3
|
||||
je .have_mouse
|
||||
cmp [t_fcount], 0
|
||||
je .fail
|
||||
cmp dword [t_fxs], 0
|
||||
je .fail
|
||||
cmp dword [t_fys], 0
|
||||
je .fail
|
||||
mov [f_repid], -1 ; no mouse report to match
|
||||
mov [f_bytes], 0
|
||||
mov [t_btncnt], 0
|
||||
movi eax, 1
|
||||
ret
|
||||
.have_mouse:
|
||||
; Keep buttons/wheel only when they live in the chosen report.
|
||||
mov eax, [t_btnid]
|
||||
cmp eax, [t_id]
|
||||
je @f
|
||||
mov [t_btncnt], 0
|
||||
@@:
|
||||
; Final layout.
|
||||
mov eax, [t_id]
|
||||
mov [f_repid], eax
|
||||
xor ecx, ecx
|
||||
@@:
|
||||
cmp ecx, [p_idcnt]
|
||||
jae .no_bits
|
||||
cmp eax, [p_ids+ecx*4]
|
||||
je .got_bits
|
||||
inc ecx
|
||||
jmp @b
|
||||
.got_bits:
|
||||
mov eax, [p_bits+ecx*4]
|
||||
add eax, 7
|
||||
shr eax, 3
|
||||
mov [f_bytes], eax
|
||||
movi eax, 1
|
||||
ret
|
||||
.no_bits:
|
||||
.fail:
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; Extracts an unsigned field from an input report.
|
||||
; in: esi -> report data, eax = bit offset, ecx = bit count (1..24).
|
||||
; out: eax = value.
|
||||
proc hid_extract_u
|
||||
push ebx ecx edx
|
||||
mov edx, eax
|
||||
shr edx, 3
|
||||
mov ebx, [esi+edx] ; buffer has spare bytes at the end
|
||||
and eax, 7
|
||||
push ecx
|
||||
mov ecx, eax
|
||||
shr ebx, cl
|
||||
pop ecx
|
||||
neg ecx
|
||||
add ecx, 32
|
||||
shl ebx, cl
|
||||
shr ebx, cl
|
||||
mov eax, ebx
|
||||
pop edx ecx ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
; Same, sign-extended.
|
||||
proc hid_extract_s
|
||||
push ebx ecx edx
|
||||
mov edx, eax
|
||||
shr edx, 3
|
||||
mov ebx, [esi+edx]
|
||||
and eax, 7
|
||||
push ecx
|
||||
mov ecx, eax
|
||||
shr ebx, cl
|
||||
pop ecx
|
||||
neg ecx
|
||||
add ecx, 32
|
||||
shl ebx, cl
|
||||
sar ebx, cl
|
||||
mov eax, ebx
|
||||
pop edx ecx ebx
|
||||
ret
|
||||
endp
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,26 @@
|
||||
[touchpad]
|
||||
; pointer speed in percent of the driver's default (on top of the [mouse]
|
||||
; speed above; pads differ in resolution)
|
||||
speed=100
|
||||
; how far a finger must move before the pointer follows, in pad units;
|
||||
; larger is steadier under a pressing finger, 0 turns the filter off
|
||||
jitter=1
|
||||
; the same, for a finger that landed on the button strip: it is pressing
|
||||
; rather than steering there, so it needs a stricter margin
|
||||
jitter_buttons=45
|
||||
; pad units of two-finger travel per wheel step, and the direction
|
||||
scroll_step=64
|
||||
scroll_invert=0
|
||||
; turn a short, still touch into a click: one finger left, two right,
|
||||
; three middle
|
||||
tap_enable=1
|
||||
; tap, then touch again at once and move: the button stays down for that
|
||||
; second touch - this is how text is selected and how one draws
|
||||
tap_drag=1
|
||||
; right click: 0 never, 1 bottom-right corner, 2 by finger count (two
|
||||
; fingers right, three middle), 3 either
|
||||
right_click=1
|
||||
; button strip along the bottom edge, in percent of the surface: its
|
||||
; height, and where its left half ends
|
||||
button_zone=15
|
||||
right_split=50
|
||||
@@ -0,0 +1,72 @@
|
||||
; Asks the I2C touchpad driver to read its settings again.
|
||||
;
|
||||
; The driver takes everything it can be tuned with from the [touchpad] section
|
||||
; of /sys/settings/system.ini, and it reads that file once while loading. This
|
||||
; tells it to read the file again, so editing a setting takes effect straight
|
||||
; away instead of at the next boot.
|
||||
;
|
||||
; There is no window: the outcome goes to the debug board, the way the driver
|
||||
; reports everything else.
|
||||
|
||||
format binary as ""
|
||||
use32
|
||||
db 'MENUET01'
|
||||
dd 1, start, i_end, mem, mem, 0, 0
|
||||
|
||||
include '../../programs/macros.inc'
|
||||
|
||||
SRV_RELOAD_CONF = 1
|
||||
|
||||
start:
|
||||
; 1. Find the driver's service by name.
|
||||
mcall 68, 16, srv_name
|
||||
test eax, eax
|
||||
jz .no_driver
|
||||
mov [ioctl.handle], eax
|
||||
; 2. Ask it to reload. No data travels either way: the driver reads the file
|
||||
; itself, so the settings file stays the only place they are written down.
|
||||
mcall 68, 17, ioctl
|
||||
test eax, eax
|
||||
jnz .refused
|
||||
mov esi, msg_ok
|
||||
jmp .say
|
||||
.no_driver:
|
||||
mov esi, msg_no_driver
|
||||
jmp .say
|
||||
.refused:
|
||||
mov esi, msg_refused
|
||||
.say:
|
||||
call board_str
|
||||
or eax, -1
|
||||
mcall
|
||||
|
||||
; Writes a zero-terminated string to the debug board.
|
||||
; in: esi -> string
|
||||
board_str:
|
||||
lodsb
|
||||
test al, al
|
||||
jz .done
|
||||
mov cl, al
|
||||
mcall 63, 1
|
||||
jmp board_str
|
||||
.done:
|
||||
ret
|
||||
|
||||
srv_name db 'I2CHID', 0
|
||||
|
||||
align 4
|
||||
ioctl:
|
||||
.handle dd 0
|
||||
.io_code dd SRV_RELOAD_CONF
|
||||
.input dd 0
|
||||
.inp_size dd 0
|
||||
.output dd 0
|
||||
.out_size dd 0
|
||||
|
||||
msg_ok db 'tpreload: touchpad settings reloaded', 13, 10, 0
|
||||
msg_no_driver db 'tpreload: the I2C touchpad driver is not loaded', 13, 10, 0
|
||||
msg_refused db 'tpreload: the driver refused the request', 13, 10, 0
|
||||
|
||||
i_end:
|
||||
rb 1024
|
||||
mem:
|
||||
@@ -1,68 +0,0 @@
|
||||
#ifndef _ACPI_ACPI_H
|
||||
#define _ACPI_ACPI_H
|
||||
/*
|
||||
* Minimal ACPI-CA type surface for KolibriOS.
|
||||
*
|
||||
* CONFIG_ACPI is never defined here, so <linux/acpi.h> compiles only its
|
||||
* "no ACPI" branch - but that branch still mentions a handful of ACPI-CA
|
||||
* types in the signatures of its inline stubs. Those types are what this
|
||||
* header provides; there is no ACPI interpreter behind them.
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
|
||||
typedef u32 acpi_status;
|
||||
typedef u32 acpi_object_type;
|
||||
typedef u64 acpi_size;
|
||||
typedef u64 acpi_io_address;
|
||||
typedef u64 acpi_physical_address;
|
||||
typedef void *acpi_handle;
|
||||
typedef char *acpi_string;
|
||||
|
||||
#define AE_OK ((acpi_status) 0x0000)
|
||||
#define AE_ERROR ((acpi_status) 0x0001)
|
||||
#define AE_NOT_FOUND ((acpi_status) 0x0005)
|
||||
#define AE_SUPPORT ((acpi_status) 0x001D)
|
||||
|
||||
#define ACPI_SUCCESS(a) ((a) == AE_OK)
|
||||
#define ACPI_FAILURE(a) ((a) != AE_OK)
|
||||
|
||||
#define ACPI_TYPE_INTEGER 0x01
|
||||
#define ACPI_TYPE_STRING 0x02
|
||||
#define ACPI_TYPE_BUFFER 0x03
|
||||
#define ACPI_TYPE_PACKAGE 0x04
|
||||
#define ACPI_TYPE_ANY 0x00
|
||||
|
||||
union acpi_object {
|
||||
acpi_object_type type;
|
||||
struct {
|
||||
acpi_object_type type;
|
||||
u64 value;
|
||||
} integer;
|
||||
struct {
|
||||
acpi_object_type type;
|
||||
u32 length;
|
||||
char *pointer;
|
||||
} string;
|
||||
struct {
|
||||
acpi_object_type type;
|
||||
u32 length;
|
||||
u8 *pointer;
|
||||
} buffer;
|
||||
struct {
|
||||
acpi_object_type type;
|
||||
u32 count;
|
||||
union acpi_object *elements;
|
||||
} package;
|
||||
};
|
||||
|
||||
struct acpi_buffer {
|
||||
acpi_size length;
|
||||
void *pointer;
|
||||
};
|
||||
|
||||
struct acpi_object_list {
|
||||
u32 count;
|
||||
union acpi_object *pointer;
|
||||
};
|
||||
|
||||
#endif /* _ACPI_ACPI_H */
|
||||
@@ -1,13 +0,0 @@
|
||||
#ifndef ACPI_BUTTON_H
|
||||
#define ACPI_BUTTON_H
|
||||
#include <linux/errno.h>
|
||||
#include <linux/notifier.h>
|
||||
/*
|
||||
* nouveau_connector.c asks the ACPI lid device whether the panel is open
|
||||
* before trusting an LVDS hotplug. No ACPI here, so report "open" - the same
|
||||
* answer the upstream !CONFIG_ACPI_BUTTON stub gives.
|
||||
*/
|
||||
static inline int acpi_lid_open(void) { return 1; }
|
||||
static inline int acpi_lid_notifier_register(struct notifier_block *nb) { return -ENODEV; }
|
||||
static inline int acpi_lid_notifier_unregister(struct notifier_block *nb) { return -ENODEV; }
|
||||
#endif
|
||||
@@ -1,40 +0,0 @@
|
||||
#ifndef _ACPI_PDC_INTEL_H
|
||||
#define _ACPI_PDC_INTEL_H
|
||||
/*
|
||||
* Intel _PDC / _OSC capability bits, included unconditionally by <asm/acpi.h>.
|
||||
*
|
||||
* Nothing here evaluates these - KolibriOS drivers never negotiate processor
|
||||
* capabilities with the firmware - but the definitions have to exist for
|
||||
* <linux/acpi.h> to be includable at all. Values match the kernel's
|
||||
* include/acpi/pdc_intel.h.
|
||||
*/
|
||||
|
||||
#define ACPI_PDC_P_FFH (0x0001)
|
||||
#define ACPI_PDC_C_C1_HALT (0x0002)
|
||||
#define ACPI_PDC_T_FFH (0x0004)
|
||||
#define ACPI_PDC_SMP_C1PT (0x0008)
|
||||
#define ACPI_PDC_SMP_C2C3 (0x0010)
|
||||
#define ACPI_PDC_SMP_P_SWCOORD (0x0020)
|
||||
#define ACPI_PDC_SMP_C_SWCOORD (0x0040)
|
||||
#define ACPI_PDC_SMP_T_SWCOORD (0x0080)
|
||||
#define ACPI_PDC_C_C1_FFH (0x0100)
|
||||
#define ACPI_PDC_C_C2C3_FFH (0x0200)
|
||||
#define ACPI_PDC_SMP_P_HWCOORD (0x0800)
|
||||
|
||||
#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \
|
||||
ACPI_PDC_C_C1_HALT | \
|
||||
ACPI_PDC_P_FFH)
|
||||
|
||||
#define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \
|
||||
ACPI_PDC_C_C1_HALT | \
|
||||
ACPI_PDC_SMP_P_SWCOORD | \
|
||||
ACPI_PDC_SMP_P_HWCOORD | \
|
||||
ACPI_PDC_P_FFH)
|
||||
|
||||
#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \
|
||||
ACPI_PDC_SMP_C1PT | \
|
||||
ACPI_PDC_C_C1_HALT | \
|
||||
ACPI_PDC_C_C1_FFH | \
|
||||
ACPI_PDC_C_C2C3_FFH)
|
||||
|
||||
#endif /* _ACPI_PDC_INTEL_H */
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef __ACPI_VIDEO_H
|
||||
#define __ACPI_VIDEO_H
|
||||
/* No ACPI video extensions; nouveau_display.c only calls the register hook. */
|
||||
#include <linux/errno.h>
|
||||
|
||||
enum acpi_backlight_type {
|
||||
acpi_backlight_undef = -1,
|
||||
acpi_backlight_none = 0,
|
||||
acpi_backlight_video,
|
||||
acpi_backlight_vendor,
|
||||
acpi_backlight_native,
|
||||
};
|
||||
|
||||
static inline int acpi_video_register(void) { return -ENODEV; }
|
||||
static inline void acpi_video_unregister(void) { }
|
||||
static inline enum acpi_backlight_type acpi_video_get_backlight_type(void)
|
||||
{ return acpi_backlight_vendor; }
|
||||
#endif
|
||||
@@ -85,9 +85,6 @@ dma_supported(struct device *dev, u64 mask);
|
||||
extern int
|
||||
dma_set_mask(struct device *dev, u64 mask);
|
||||
|
||||
extern int
|
||||
dma_set_coherent_mask(struct device *dev, u64 mask);
|
||||
|
||||
extern int
|
||||
dma_get_cache_alignment(void);
|
||||
|
||||
|
||||
@@ -315,18 +315,6 @@ extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffff
|
||||
|
||||
/*
|
||||
* Write-combining range management. Upstream declares these under
|
||||
* CONFIG_MTRR and provides !MTRR fallbacks from <linux/io.h>, which this tree
|
||||
* does not carry - so they are declared unconditionally here and implemented
|
||||
* as no-ops by each driver's kos_io.c. arch_io_*_memtype_wc() is the 4.9
|
||||
* spelling that came in with the PAT rework.
|
||||
*/
|
||||
extern int __must_check arch_phys_wc_add(unsigned long base, unsigned long size);
|
||||
extern void arch_phys_wc_del(int handle);
|
||||
extern int arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size);
|
||||
extern void arch_io_free_memtype_wc(resource_size_t start, resource_size_t size);
|
||||
|
||||
#ifdef CONFIG_MTRR
|
||||
extern int __must_check arch_phys_wc_index(int handle);
|
||||
#define arch_phys_wc_index arch_phys_wc_index
|
||||
|
||||
@@ -359,13 +359,6 @@ struct drm_file {
|
||||
int event_space;
|
||||
|
||||
struct mutex event_read_lock;
|
||||
|
||||
/*
|
||||
* Upstream stores the opening process here. Nothing opens a DRM node
|
||||
* on this port, so it stays NULL; nouveau_drm.c only feeds it to
|
||||
* pid_nr() when it names a client.
|
||||
*/
|
||||
struct pid *pid;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -685,14 +678,6 @@ struct drm_device {
|
||||
/*@} */
|
||||
|
||||
struct list_head filelist;
|
||||
/*
|
||||
* Backported from Linux 4.9, which moved filelist from under
|
||||
* struct_mutex to its own lock. Nothing in the 4.6 core takes it, so
|
||||
* it only ever serialises the driver against itself.
|
||||
*/
|
||||
struct mutex filelist_mutex;
|
||||
/* Backported from Linux 4.9; unused without a real inode layer. */
|
||||
struct inode *anon_inode;
|
||||
|
||||
/** \name Memory management */
|
||||
/*@{ */
|
||||
@@ -763,12 +748,6 @@ struct drm_device {
|
||||
// struct drm_agp_head *agp; /**< AGP data */
|
||||
|
||||
struct pci_dev *pdev; /**< PCI device structure */
|
||||
/*
|
||||
* Always NULL here - no platform bus. nouveau_drm.c branches on
|
||||
* pdev vs platformdev when it builds the device name, and the
|
||||
* Tegra half of that branch is never taken.
|
||||
*/
|
||||
struct platform_device *platformdev;
|
||||
#ifdef __alpha__
|
||||
struct pci_controller *hose;
|
||||
#endif
|
||||
@@ -1002,15 +981,6 @@ static __inline__ int drm_pci_device_is_agp(struct drm_device *dev)
|
||||
}
|
||||
void drm_pci_agp_destroy(struct drm_device *dev);
|
||||
|
||||
/*
|
||||
* Implemented in drm_pci.c and the entry point every port's probe calls, but
|
||||
* its upstream declaration is in the "#if 0" block below - so each main.c used
|
||||
* to declare it by hand. Declared here instead.
|
||||
*/
|
||||
extern int drm_get_pci_dev(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent,
|
||||
struct drm_driver *driver);
|
||||
|
||||
#if 0
|
||||
extern int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver);
|
||||
extern void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver);
|
||||
|
||||
@@ -152,13 +152,6 @@ struct drm_display_info {
|
||||
u8 edid_hdmi_dc_modes;
|
||||
|
||||
u8 cea_rev;
|
||||
|
||||
/*
|
||||
* Backported from Linux 4.9: maximum TMDS clock in kHz advertised by an
|
||||
* HDMI sink. drm_edid.c in this tree does not fill it in yet, so it
|
||||
* stays 0 and drivers fall back to their built-in limit.
|
||||
*/
|
||||
int max_tmds_clock;
|
||||
};
|
||||
|
||||
/* data corresponds to displayid vend/prod/serial */
|
||||
@@ -708,17 +701,6 @@ struct drm_crtc_funcs {
|
||||
const struct drm_crtc_state *state,
|
||||
struct drm_property *property,
|
||||
uint64_t *val);
|
||||
|
||||
/*
|
||||
* Backported from Linux 4.9 for the amdgpu port. The 4.6 DRM core in
|
||||
* this tree never calls these; they exist so that drivers written
|
||||
* against the newer struct layout still compile and keep their hooks.
|
||||
*/
|
||||
void (*early_unregister)(struct drm_crtc *crtc);
|
||||
int (*page_flip_target)(struct drm_crtc *crtc,
|
||||
struct drm_framebuffer *fb,
|
||||
struct drm_pending_vblank_event *event,
|
||||
uint32_t flags, uint32_t target);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1062,9 +1044,6 @@ struct drm_connector_funcs {
|
||||
const struct drm_connector_state *state,
|
||||
struct drm_property *property,
|
||||
uint64_t *val);
|
||||
|
||||
/* Backported from Linux 4.9 - see drm_crtc_funcs::early_unregister. */
|
||||
void (*early_unregister)(struct drm_connector *connector);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1090,9 +1069,6 @@ struct drm_encoder_funcs {
|
||||
* hotplugged in DRM.
|
||||
*/
|
||||
void (*destroy)(struct drm_encoder *encoder);
|
||||
|
||||
/* Backported from Linux 4.9 - see drm_crtc_funcs::early_unregister. */
|
||||
void (*early_unregister)(struct drm_encoder *encoder);
|
||||
};
|
||||
|
||||
#define DRM_CONNECTOR_MAX_ENCODER 3
|
||||
@@ -1514,9 +1490,6 @@ struct drm_plane_funcs {
|
||||
const struct drm_plane_state *state,
|
||||
struct drm_property *property,
|
||||
uint64_t *val);
|
||||
|
||||
/* Backported from Linux 4.9 - see drm_crtc_funcs::early_unregister. */
|
||||
void (*early_unregister)(struct drm_plane *plane);
|
||||
};
|
||||
|
||||
enum drm_plane_type {
|
||||
|
||||
@@ -43,15 +43,6 @@
|
||||
#include <drm/drm_modeset_helper_vtables.h>
|
||||
|
||||
extern void drm_helper_disable_unused_functions(struct drm_device *dev);
|
||||
|
||||
/*
|
||||
* Added after 4.6 and implemented by each port's kos_stubs.c:
|
||||
* drm_crtc_force_disable_all() is 4.9's unload-time "turn everything off",
|
||||
* and drm_kms_helper_is_poll_worker() is how 4.9 avoids deadlocking against
|
||||
* its own hotplug worker - there is no such worker here.
|
||||
*/
|
||||
extern void drm_crtc_force_disable_all(struct drm_device *dev);
|
||||
extern bool drm_kms_helper_is_poll_worker(void);
|
||||
extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
|
||||
extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Francisco Jerez.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DRM_ENCODER_SLAVE_H__
|
||||
#define __DRM_ENCODER_SLAVE_H__
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
|
||||
/**
|
||||
* struct drm_encoder_slave_funcs - Entry points exposed by a slave encoder driver
|
||||
* @set_config: Initialize any encoder-specific modesetting parameters.
|
||||
* The meaning of the @params parameter is implementation
|
||||
* dependent. It will usually be a structure with DVO port
|
||||
* data format settings or timings. It's not required for
|
||||
* the new parameters to take effect until the next mode
|
||||
* is set.
|
||||
*
|
||||
* Most of its members are analogous to the function pointers in
|
||||
* &drm_encoder_helper_funcs and they can optionally be used to
|
||||
* initialize the latter. Connector-like methods (e.g. @get_modes and
|
||||
* @set_property) will typically be wrapped around and only be called
|
||||
* if the encoder is the currently selected one for the connector.
|
||||
*/
|
||||
struct drm_encoder_slave_funcs {
|
||||
void (*set_config)(struct drm_encoder *encoder,
|
||||
void *params);
|
||||
|
||||
void (*destroy)(struct drm_encoder *encoder);
|
||||
void (*dpms)(struct drm_encoder *encoder, int mode);
|
||||
void (*save)(struct drm_encoder *encoder);
|
||||
void (*restore)(struct drm_encoder *encoder);
|
||||
bool (*mode_fixup)(struct drm_encoder *encoder,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
int (*mode_valid)(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode);
|
||||
void (*mode_set)(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
|
||||
enum drm_connector_status (*detect)(struct drm_encoder *encoder,
|
||||
struct drm_connector *connector);
|
||||
int (*get_modes)(struct drm_encoder *encoder,
|
||||
struct drm_connector *connector);
|
||||
int (*create_resources)(struct drm_encoder *encoder,
|
||||
struct drm_connector *connector);
|
||||
int (*set_property)(struct drm_encoder *encoder,
|
||||
struct drm_connector *connector,
|
||||
struct drm_property *property,
|
||||
uint64_t val);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_encoder_slave - Slave encoder struct
|
||||
* @base: DRM encoder object.
|
||||
* @slave_funcs: Slave encoder callbacks.
|
||||
* @slave_priv: Slave encoder private data.
|
||||
* @bus_priv: Bus specific data.
|
||||
*
|
||||
* A &drm_encoder_slave has two sets of callbacks, @slave_funcs and the
|
||||
* ones in @base. The former are never actually called by the common
|
||||
* CRTC code, it's just a convenience for splitting the encoder
|
||||
* functions in an upper, GPU-specific layer and a (hopefully)
|
||||
* GPU-agnostic lower layer: It's the GPU driver responsibility to
|
||||
* call the slave methods when appropriate.
|
||||
*
|
||||
* drm_i2c_encoder_init() provides a way to get an implementation of
|
||||
* this.
|
||||
*/
|
||||
struct drm_encoder_slave {
|
||||
struct drm_encoder base;
|
||||
|
||||
const struct drm_encoder_slave_funcs *slave_funcs;
|
||||
void *slave_priv;
|
||||
void *bus_priv;
|
||||
};
|
||||
#define to_encoder_slave(x) container_of((x), struct drm_encoder_slave, base)
|
||||
|
||||
int drm_i2c_encoder_init(struct drm_device *dev,
|
||||
struct drm_encoder_slave *encoder,
|
||||
struct i2c_adapter *adap,
|
||||
const struct i2c_board_info *info);
|
||||
|
||||
|
||||
/**
|
||||
* struct drm_i2c_encoder_driver
|
||||
*
|
||||
* Describes a device driver for an encoder connected to the GPU
|
||||
* through an I2C bus. In addition to the entry points in @i2c_driver
|
||||
* an @encoder_init function should be provided. It will be called to
|
||||
* give the driver an opportunity to allocate any per-encoder data
|
||||
* structures and to initialize the @slave_funcs and (optionally)
|
||||
* @slave_priv members of @encoder.
|
||||
*/
|
||||
struct drm_i2c_encoder_driver {
|
||||
struct i2c_driver i2c_driver;
|
||||
|
||||
int (*encoder_init)(struct i2c_client *client,
|
||||
struct drm_device *dev,
|
||||
struct drm_encoder_slave *encoder);
|
||||
|
||||
};
|
||||
#define to_drm_i2c_encoder_driver(x) container_of((x), \
|
||||
struct drm_i2c_encoder_driver, \
|
||||
i2c_driver)
|
||||
|
||||
/**
|
||||
* drm_i2c_encoder_get_client - Get the I2C client corresponding to an encoder
|
||||
*/
|
||||
static inline struct i2c_client *drm_i2c_encoder_get_client(struct drm_encoder *encoder)
|
||||
{
|
||||
return (struct i2c_client *)to_encoder_slave(encoder)->bus_priv;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_i2c_encoder_register - Register an I2C encoder driver
|
||||
* @owner: Module containing the driver.
|
||||
* @driver: Driver to be registered.
|
||||
*/
|
||||
static inline int drm_i2c_encoder_register(struct module *owner,
|
||||
struct drm_i2c_encoder_driver *driver)
|
||||
{
|
||||
return i2c_register_driver(owner, &driver->i2c_driver);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_i2c_encoder_unregister - Unregister an I2C encoder driver
|
||||
* @driver: Driver to be unregistered.
|
||||
*/
|
||||
static inline void drm_i2c_encoder_unregister(struct drm_i2c_encoder_driver *driver)
|
||||
{
|
||||
i2c_del_driver(&driver->i2c_driver);
|
||||
}
|
||||
|
||||
void drm_i2c_encoder_destroy(struct drm_encoder *encoder);
|
||||
|
||||
|
||||
/*
|
||||
* Wrapper fxns which can be plugged in to drm_encoder_helper_funcs:
|
||||
*/
|
||||
|
||||
void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode);
|
||||
bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
void drm_i2c_encoder_prepare(struct drm_encoder *encoder);
|
||||
void drm_i2c_encoder_commit(struct drm_encoder *encoder);
|
||||
void drm_i2c_encoder_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder,
|
||||
struct drm_connector *connector);
|
||||
void drm_i2c_encoder_save(struct drm_encoder *encoder);
|
||||
void drm_i2c_encoder_restore(struct drm_encoder *encoder);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -226,14 +226,6 @@ int drm_fb_helper_init(struct drm_device *dev,
|
||||
struct drm_fb_helper *helper, int crtc_count,
|
||||
int max_conn);
|
||||
void drm_fb_helper_fini(struct drm_fb_helper *helper);
|
||||
|
||||
/*
|
||||
* 4.9's fbdev handover. There is no other framebuffer driver to evict on
|
||||
* KolibriOS; implemented in each port's kos_stubs.c.
|
||||
*/
|
||||
struct apertures_struct;
|
||||
int drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a,
|
||||
const char *name, bool primary);
|
||||
int drm_fb_helper_blank(int blank, struct fb_info *info);
|
||||
int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
|
||||
struct fb_info *info);
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifndef _DRM_FOURCC_SHIM_H
|
||||
#define _DRM_FOURCC_SHIM_H
|
||||
/*
|
||||
* The tree keeps the format list in uapi/ and the in-kernel helpers in
|
||||
* drm_crtc.h. Upstream drivers include <drm/drm_fourcc.h>; give them that
|
||||
* spelling instead of patching every call site. The guard is deliberately
|
||||
* distinct from the uapi header's own.
|
||||
*/
|
||||
#include <uapi/drm/drm_fourcc.h>
|
||||
#endif
|
||||
@@ -1,9 +0,0 @@
|
||||
#ifndef _DRM_MODE_SHIM_H
|
||||
#define _DRM_MODE_SHIM_H
|
||||
/*
|
||||
* Same reason as drm_fourcc.h: upstream drivers spell this <drm/drm_mode.h>
|
||||
* while the tree keeps it under uapi/. The guard deliberately does not match
|
||||
* the uapi header's own _DRM_MODE_H, or including this first would suppress it.
|
||||
*/
|
||||
#include <uapi/drm/drm_mode.h>
|
||||
#endif
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Francisco Jerez.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DRM_I2C_CH7006_H__
|
||||
#define __DRM_I2C_CH7006_H__
|
||||
|
||||
/**
|
||||
* struct ch7006_encoder_params
|
||||
*
|
||||
* Describes how the ch7006 is wired up with the GPU. It should be
|
||||
* used as the @params parameter of its @set_config method.
|
||||
*
|
||||
* See "http://www.chrontel.com/pdf/7006.pdf" for their precise
|
||||
* meaning.
|
||||
*/
|
||||
struct ch7006_encoder_params {
|
||||
enum {
|
||||
CH7006_FORMAT_RGB16 = 0,
|
||||
CH7006_FORMAT_YCrCb24m16,
|
||||
CH7006_FORMAT_RGB24m16,
|
||||
CH7006_FORMAT_RGB15,
|
||||
CH7006_FORMAT_RGB24m12C,
|
||||
CH7006_FORMAT_RGB24m12I,
|
||||
CH7006_FORMAT_RGB24m8,
|
||||
CH7006_FORMAT_RGB16m8,
|
||||
CH7006_FORMAT_RGB15m8,
|
||||
CH7006_FORMAT_YCrCb24m8,
|
||||
} input_format;
|
||||
|
||||
enum {
|
||||
CH7006_CLOCK_SLAVE = 0,
|
||||
CH7006_CLOCK_MASTER,
|
||||
} clock_mode;
|
||||
|
||||
enum {
|
||||
CH7006_CLOCK_EDGE_NEG = 0,
|
||||
CH7006_CLOCK_EDGE_POS,
|
||||
} clock_edge;
|
||||
|
||||
int xcm, pcm;
|
||||
|
||||
enum {
|
||||
CH7006_SYNC_SLAVE = 0,
|
||||
CH7006_SYNC_MASTER,
|
||||
} sync_direction;
|
||||
|
||||
enum {
|
||||
CH7006_SYNC_SEPARATED = 0,
|
||||
CH7006_SYNC_EMBEDDED,
|
||||
} sync_encoding;
|
||||
|
||||
enum {
|
||||
CH7006_POUT_1_8V = 0,
|
||||
CH7006_POUT_3_3V,
|
||||
} pout_level;
|
||||
|
||||
enum {
|
||||
CH7006_ACTIVE_HSYNC = 0,
|
||||
CH7006_ACTIVE_DSTART,
|
||||
} active_detect;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Francisco Jerez.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DRM_I2C_SIL164_H__
|
||||
#define __DRM_I2C_SIL164_H__
|
||||
|
||||
/**
|
||||
* struct sil164_encoder_params
|
||||
*
|
||||
* Describes how the sil164 is connected to the GPU. It should be used
|
||||
* as the @params parameter of its @set_config method.
|
||||
*
|
||||
* See "http://www.siliconimage.com/docs/SiI-DS-0021-E-164.pdf".
|
||||
*/
|
||||
struct sil164_encoder_params {
|
||||
enum {
|
||||
SIL164_INPUT_EDGE_FALLING = 0,
|
||||
SIL164_INPUT_EDGE_RISING
|
||||
} input_edge;
|
||||
|
||||
enum {
|
||||
SIL164_INPUT_WIDTH_12BIT = 0,
|
||||
SIL164_INPUT_WIDTH_24BIT
|
||||
} input_width;
|
||||
|
||||
enum {
|
||||
SIL164_INPUT_SINGLE_EDGE = 0,
|
||||
SIL164_INPUT_DUAL_EDGE
|
||||
} input_dual;
|
||||
|
||||
enum {
|
||||
SIL164_PLL_FILTER_ON = 0,
|
||||
SIL164_PLL_FILTER_OFF,
|
||||
} pll_filter;
|
||||
|
||||
int input_skew; /** < Allowed range [-4, 3], use 0 for no de-skew. */
|
||||
int duallink_skew; /** < Allowed range [-4, 3]. */
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -257,15 +257,6 @@ struct ttm_buffer_object {
|
||||
struct reservation_object *resv;
|
||||
struct reservation_object ttm_resv;
|
||||
struct mutex wu_mutex;
|
||||
|
||||
/*
|
||||
* Backported from Linux 4.9: fence of the last accelerated move, kept
|
||||
* outside the reservation object so a pipelined eviction can be waited
|
||||
* on without blocking other users. The 4.6 TTM in this tree still
|
||||
* waits synchronously, so the core leaves this NULL; amdgpu sets and
|
||||
* checks it on its own paths.
|
||||
*/
|
||||
struct fence *moving;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -434,20 +434,8 @@ struct ttm_bo_driver {
|
||||
*/
|
||||
int (*io_mem_reserve)(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem);
|
||||
void (*io_mem_free)(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem);
|
||||
|
||||
/*
|
||||
* Backported from Linux 4.9 for the amdgpu port. The 4.6 TTM in this
|
||||
* tree does not consult these hooks - it always uses the default LRU
|
||||
* placement - but drivers written against 4.9 still populate them.
|
||||
*/
|
||||
void (*lru_removal)(struct ttm_buffer_object *bo);
|
||||
struct list_head *(*lru_tail)(struct ttm_buffer_object *bo);
|
||||
struct list_head *(*swap_lru_tail)(struct ttm_buffer_object *bo);
|
||||
};
|
||||
|
||||
struct list_head *ttm_bo_default_lru_tail(struct ttm_buffer_object *bo);
|
||||
struct list_head *ttm_bo_default_swap_lru_tail(struct ttm_buffer_object *bo);
|
||||
|
||||
/**
|
||||
* struct ttm_bo_global_ref - Argument to initialize a struct ttm_bo_global.
|
||||
*/
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#ifndef _LINUX_CLK_H
|
||||
#define _LINUX_CLK_H
|
||||
/*
|
||||
* Tegra-only. nvif/os.h pulls this in unconditionally, but the only nouveau
|
||||
* code that calls a clk_* helper is nvkm/engine/device/tegra.c, which this
|
||||
* port does not build.
|
||||
*/
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
struct clk;
|
||||
struct device;
|
||||
|
||||
static inline struct clk *clk_get(struct device *dev, const char *id)
|
||||
{ return ERR_PTR(-ENOENT); }
|
||||
static inline void clk_put(struct clk *clk) { }
|
||||
static inline int clk_prepare_enable(struct clk *clk) { return -ENOSYS; }
|
||||
static inline void clk_disable_unprepare(struct clk *clk) { }
|
||||
static inline unsigned long clk_get_rate(struct clk *clk) { return 0; }
|
||||
static inline int clk_set_rate(struct clk *clk, unsigned long rate) { return -ENOSYS; }
|
||||
#endif
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef _LINUX_CONSOLE_H
|
||||
#define _LINUX_CONSOLE_H
|
||||
/* KolibriOS has no VT console layer; the fbdev handover hooks are no-ops. */
|
||||
#define CON_PRINTBUFFER (1)
|
||||
#define CON_CONSDEV (2)
|
||||
#define CON_ENABLED (4)
|
||||
#define CON_BOOT (8)
|
||||
#define CON_ANYTIME (16)
|
||||
#define CON_BRL (32)
|
||||
|
||||
static inline void console_lock(void) { }
|
||||
static inline void console_unlock(void) { }
|
||||
static inline int console_trylock(void) { return 1; }
|
||||
#endif
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef _LINUX_DEBUGFS_H
|
||||
#define _LINUX_DEBUGFS_H
|
||||
/* No debugfs in KolibriOS - CONFIG_DEBUG_FS is never defined. */
|
||||
#include <linux/types.h>
|
||||
struct dentry;
|
||||
struct file_operations;
|
||||
#endif
|
||||
@@ -31,12 +31,6 @@ enum probe_type {
|
||||
|
||||
struct device_driver {
|
||||
const char *name;
|
||||
/*
|
||||
* Restored for drm_encoder_slave.c, which pins the slave encoder's
|
||||
* module around a bind. Nothing is ever bound on this port, so it
|
||||
* stays NULL and try_module_get()/module_put() are no-ops.
|
||||
*/
|
||||
struct module *owner;
|
||||
const char *mod_name; /* used for built-in modules */
|
||||
|
||||
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
|
||||
@@ -132,28 +126,5 @@ static inline __printf(2, 3)
|
||||
void dev_notice(const struct device *dev, const char *fmt, ...)
|
||||
{}
|
||||
|
||||
/*
|
||||
* sysfs attribute types. KolibriOS has no sysfs, so nothing ever walks these
|
||||
* tables - but drivers still declare them at file scope, so the layout has to
|
||||
* exist. Matches the upstream definitions field for field.
|
||||
*/
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
struct device_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
|
||||
char *buf);
|
||||
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
};
|
||||
|
||||
#define __ATTR(_name, _mode, _show, _store) { \
|
||||
.attr = { .name = __stringify(_name), .mode = (_mode) }, \
|
||||
.show = _show, \
|
||||
.store = _store, \
|
||||
}
|
||||
|
||||
#define DEVICE_ATTR(_name, _mode, _show, _store) \
|
||||
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
|
||||
|
||||
#endif /* _DEVICE_H_ */
|
||||
@@ -131,12 +131,6 @@ struct dma_buf {
|
||||
const char *exp_name;
|
||||
struct list_head list_node;
|
||||
void *priv;
|
||||
/*
|
||||
* Upstream keeps the exporter's reservation object here. No dma-buf
|
||||
* is ever created on this port, so nouveau_prime.c's import path is
|
||||
* dead code - but it dereferences the field, so it has to exist.
|
||||
*/
|
||||
struct reservation_object *resv;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef _LINUX_EFI_H
|
||||
#define _LINUX_EFI_H
|
||||
/* KolibriOS boots via BIOS only; amdgpu only tests efi_enabled(). */
|
||||
#define EFI_BOOT 0
|
||||
#define EFI_RUNTIME_SERVICES 1
|
||||
static inline bool efi_enabled(int feature) { return false; }
|
||||
#endif
|
||||
@@ -470,12 +470,7 @@ struct fb_info {
|
||||
struct fb_fix_screeninfo fix; /* Current fix */
|
||||
struct fb_monspecs monspecs; /* Current Monitor specs */
|
||||
// struct work_struct queue; /* Framebuffer event queue */
|
||||
/*
|
||||
* Restored for nouveau, which sets pixmap.buf_align after
|
||||
* drm_fb_helper_initial_config(). Nothing on this port consumes the
|
||||
* field - there is no fbcon - but the assignment has to compile.
|
||||
*/
|
||||
struct fb_pixmap pixmap; /* Image hardware mapper */
|
||||
// struct fb_pixmap pixmap; /* Image hardware mapper */
|
||||
// struct fb_pixmap sprite; /* Cursor hardware mapper */
|
||||
// struct fb_cmap cmap; /* Current cmap */
|
||||
struct list_head modelist; /* mode list */
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* fence-array: aggregates fence to be waited together
|
||||
*
|
||||
* Copyright (C) 2016 Collabora Ltd
|
||||
* Copyright (C) 2016 Advanced Micro Devices, Inc.
|
||||
* Authors:
|
||||
* Gustavo Padovan <gustavo@padovan.org>
|
||||
* Christian König <christian.koenig@amd.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_FENCE_ARRAY_H
|
||||
#define __LINUX_FENCE_ARRAY_H
|
||||
|
||||
#include <linux/fence.h>
|
||||
|
||||
/**
|
||||
* struct fence_array_cb - callback helper for fence array
|
||||
* @cb: fence callback structure for signaling
|
||||
* @array: reference to the parent fence array object
|
||||
*/
|
||||
struct fence_array_cb {
|
||||
struct fence_cb cb;
|
||||
struct fence_array *array;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct fence_array - fence to represent an array of fences
|
||||
* @base: fence base class
|
||||
* @lock: spinlock for fence handling
|
||||
* @num_fences: number of fences in the array
|
||||
* @num_pending: fences in the array still pending
|
||||
* @fences: array of the fences
|
||||
*/
|
||||
struct fence_array {
|
||||
struct fence base;
|
||||
|
||||
spinlock_t lock;
|
||||
unsigned num_fences;
|
||||
atomic_t num_pending;
|
||||
struct fence **fences;
|
||||
};
|
||||
|
||||
extern const struct fence_ops fence_array_ops;
|
||||
|
||||
/**
|
||||
* fence_is_array - check if a fence is from the array subsclass
|
||||
*
|
||||
* Return true if it is a fence_array and false otherwise.
|
||||
*/
|
||||
static inline bool fence_is_array(struct fence *fence)
|
||||
{
|
||||
return fence->ops == &fence_array_ops;
|
||||
}
|
||||
|
||||
/**
|
||||
* to_fence_array - cast a fence to a fence_array
|
||||
* @fence: fence to cast to a fence_array
|
||||
*
|
||||
* Returns NULL if the fence is not a fence_array,
|
||||
* or the fence_array otherwise.
|
||||
*/
|
||||
static inline struct fence_array *to_fence_array(struct fence *fence)
|
||||
{
|
||||
if (fence->ops != &fence_array_ops)
|
||||
return NULL;
|
||||
|
||||
return container_of(fence, struct fence_array, base);
|
||||
}
|
||||
|
||||
struct fence_array *fence_array_create(int num_fences, struct fence **fences,
|
||||
u64 context, unsigned seqno,
|
||||
bool signal_on_any);
|
||||
|
||||
#endif /* __LINUX_FENCE_ARRAY_H */
|
||||
@@ -1,35 +0,0 @@
|
||||
#ifndef _LINUX_HRTIMER_H
|
||||
#define _LINUX_HRTIMER_H
|
||||
/*
|
||||
* amdgpu_mode.h only embeds a struct hrtimer in the virtual-DCE crtc and never
|
||||
* arms it on this port, so a structural stub is enough.
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <linux/ktime.h>
|
||||
|
||||
enum hrtimer_restart { HRTIMER_NORESTART, HRTIMER_RESTART };
|
||||
enum hrtimer_mode {
|
||||
HRTIMER_MODE_ABS = 0x0,
|
||||
HRTIMER_MODE_REL = 0x1,
|
||||
HRTIMER_MODE_PINNED = 0x2,
|
||||
};
|
||||
enum hrtimer_base_type { HRTIMER_BASE_MONOTONIC, HRTIMER_MAX_CLOCK_BASES };
|
||||
|
||||
struct hrtimer {
|
||||
ktime_t _softexpires;
|
||||
enum hrtimer_restart (*function)(struct hrtimer *);
|
||||
int state;
|
||||
};
|
||||
|
||||
static inline void hrtimer_init(struct hrtimer *timer, int which, enum hrtimer_mode mode)
|
||||
{ timer->function = NULL; timer->state = 0; }
|
||||
static inline int hrtimer_start(struct hrtimer *t, ktime_t tim, enum hrtimer_mode m) { return 0; }
|
||||
static inline int hrtimer_cancel(struct hrtimer *t) { return 0; }
|
||||
static inline int hrtimer_try_to_cancel(struct hrtimer *t) { return 0; }
|
||||
static inline bool hrtimer_active(const struct hrtimer *t) { return false; }
|
||||
static inline void hrtimer_start_range_ns(struct hrtimer *t, ktime_t tim,
|
||||
u64 range_ns, enum hrtimer_mode m) { }
|
||||
|
||||
/* Sleeps through the DDK's delay(); see the driver's kos_* glue. */
|
||||
extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef _LINUX_HWMON_SYSFS_H
|
||||
#define _LINUX_HWMON_SYSFS_H
|
||||
/* sysfs is absent; amdgpu_pm.c's hwmon attributes are compiled out to stubs. */
|
||||
#include <linux/device.h>
|
||||
|
||||
struct sensor_device_attribute {
|
||||
struct device_attribute dev_attr;
|
||||
int index;
|
||||
};
|
||||
#define to_sensor_dev_attr(_dev_attr) \
|
||||
container_of(_dev_attr, struct sensor_device_attribute, dev_attr)
|
||||
|
||||
#define SENSOR_ATTR(_name, _mode, _show, _store, _index) \
|
||||
{ .dev_attr = __ATTR(_name, _mode, _show, _store), .index = _index }
|
||||
|
||||
#define SENSOR_DEVICE_ATTR(_name, _mode, _show, _store, _index) \
|
||||
struct sensor_device_attribute sensor_dev_attr_##_name = \
|
||||
SENSOR_ATTR(_name, _mode, _show, _store, _index)
|
||||
|
||||
struct sensor_device_attribute_2 {
|
||||
struct device_attribute dev_attr;
|
||||
u8 index;
|
||||
u8 nr;
|
||||
};
|
||||
#define to_sensor_dev_attr_2(_dev_attr) \
|
||||
container_of(_dev_attr, struct sensor_device_attribute_2, dev_attr)
|
||||
#endif
|
||||
@@ -52,19 +52,6 @@ struct i2c_board_info;
|
||||
extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
int num);
|
||||
|
||||
/*
|
||||
* Declared here rather than left implicit: i2c-core.c defines them, and
|
||||
* nouveau reaches all three - i2c_new_device()/i2c_unregister_device() from
|
||||
* nvkm/subdev/therm/ic.c, i2c_register_driver() through the i2c_add_driver()
|
||||
* inline below.
|
||||
*/
|
||||
struct module;
|
||||
extern int i2c_register_driver(struct module *owner, struct i2c_driver *driver);
|
||||
extern void i2c_del_driver(struct i2c_driver *driver);
|
||||
extern struct i2c_client *i2c_new_device(struct i2c_adapter *adap,
|
||||
struct i2c_board_info const *info);
|
||||
extern void i2c_unregister_device(struct i2c_client *client);
|
||||
|
||||
/**
|
||||
* struct i2c_driver - represent an I2C device driver
|
||||
* @class: What kind of i2c device we instantiate (for detect)
|
||||
@@ -127,18 +114,11 @@ struct i2c_driver {
|
||||
*/
|
||||
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
|
||||
|
||||
/*
|
||||
* Restored for nouveau: nvkm/subdev/therm/ic.c reaches the bound
|
||||
* driver through to_i2c_driver(client->dev.driver)->detect(). There
|
||||
* is no driver-model binding on this port, so dev.driver is always
|
||||
* NULL and the probe short-circuits - but the fields have to exist
|
||||
* for to_i2c_driver() to compile.
|
||||
*/
|
||||
struct device_driver driver;
|
||||
// struct device_driver driver;
|
||||
const struct i2c_device_id *id_table;
|
||||
|
||||
/* Device detection callback for automatic device creation */
|
||||
int (*detect)(struct i2c_client *, struct i2c_board_info *);
|
||||
// int (*detect)(struct i2c_client *, struct i2c_board_info *);
|
||||
const unsigned short *address_list;
|
||||
struct list_head clients;
|
||||
};
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/irqreturn.h>
|
||||
|
||||
/*
|
||||
* Taking an interrupt outside drm_irq_install(). nouveau's nvkm_pci_init()
|
||||
* does exactly that, so the driver supplies request_irq()/free_irq() over
|
||||
* AttachIntHandler(); the signatures are upstream's.
|
||||
*/
|
||||
typedef irqreturn_t (*irq_handler_t)(int irq, void *dev_id);
|
||||
|
||||
extern int request_irq(unsigned int irq, irq_handler_t handler,
|
||||
unsigned long flags, const char *name, void *dev_id);
|
||||
extern void free_irq(unsigned int irq, void *dev_id);
|
||||
|
||||
#include <linux/kref.h>
|
||||
#include <linux/atomic.h>
|
||||
/*
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#ifndef _LINUX_IOMMU_H
|
||||
#define _LINUX_IOMMU_H
|
||||
/*
|
||||
* No IOMMU on this port. nvif/os.h includes it unconditionally; the only user
|
||||
* is the Tegra SMMU path in nvkm/engine/device/tegra.c, which is not built.
|
||||
*/
|
||||
#include <linux/errno.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define IOMMU_READ (1 << 0)
|
||||
#define IOMMU_WRITE (1 << 1)
|
||||
#define IOMMU_CACHE (1 << 2)
|
||||
|
||||
struct device;
|
||||
struct iommu_domain;
|
||||
struct iommu_group;
|
||||
|
||||
struct iommu_domain_geometry {
|
||||
dma_addr_t aperture_start;
|
||||
dma_addr_t aperture_end;
|
||||
bool force_aperture;
|
||||
};
|
||||
|
||||
static inline struct iommu_domain *iommu_domain_alloc(void *bus) { return NULL; }
|
||||
static inline void iommu_domain_free(struct iommu_domain *d) { }
|
||||
static inline int iommu_attach_device(struct iommu_domain *d, struct device *dev)
|
||||
{ return -ENODEV; }
|
||||
static inline void iommu_detach_device(struct iommu_domain *d, struct device *dev) { }
|
||||
static inline struct iommu_group *iommu_group_get(struct device *dev) { return NULL; }
|
||||
static inline int iommu_map(struct iommu_domain *domain, unsigned long iova,
|
||||
phys_addr_t paddr, size_t size, int prot)
|
||||
{ return -ENODEV; }
|
||||
static inline size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
|
||||
size_t size)
|
||||
{ return 0; }
|
||||
static inline void iommu_group_put(struct iommu_group *g) { }
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef _LINUX_IRQ_H
|
||||
#define _LINUX_IRQ_H
|
||||
/*
|
||||
* KolibriOS has no irq_domain layer. amdgpu_irq.c is patched to dispatch IH
|
||||
* ring entries straight to the registered amdgpu_irq_src, so only the types it
|
||||
* still mentions need to exist.
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
|
||||
struct irq_data {
|
||||
unsigned int irq;
|
||||
unsigned long hwirq;
|
||||
void *chip_data;
|
||||
};
|
||||
|
||||
struct irq_chip {
|
||||
const char *name;
|
||||
void (*irq_mask)(struct irq_data *data);
|
||||
void (*irq_unmask)(struct irq_data *data);
|
||||
};
|
||||
|
||||
static inline void *irq_data_get_irq_chip_data(struct irq_data *d)
|
||||
{
|
||||
return d ? d->chip_data : NULL;
|
||||
}
|
||||
static inline void handle_simple_irq(void) { }
|
||||
#endif
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef _LINUX_IRQDOMAIN_H
|
||||
#define _LINUX_IRQDOMAIN_H
|
||||
/*
|
||||
* KolibriOS has no irq domain layer.
|
||||
*
|
||||
* amdgpu builds a linear domain purely so that a *different* driver (the ACP
|
||||
* audio co-processor) can receive GPU interrupts by Linux irq number. ACP is
|
||||
* not part of this port, so no mapping is ever created: adev->irq.virq[] stays
|
||||
* zero and amdgpu_irq_dispatch() always takes its direct-call branch.
|
||||
*
|
||||
* These declarations therefore exist to keep the domain setup compiling and
|
||||
* succeeding; the implementations in the driver's kos_stubs.c do nothing.
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
typedef unsigned long irq_hw_number_t;
|
||||
|
||||
struct irq_domain;
|
||||
struct device_node;
|
||||
|
||||
struct irq_domain_ops {
|
||||
int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
|
||||
void (*unmap)(struct irq_domain *d, unsigned int virq);
|
||||
int (*xlate)(struct irq_domain *d, struct device_node *node,
|
||||
const u32 *intspec, unsigned int intsize,
|
||||
unsigned long *out_hwirq, unsigned int *out_type);
|
||||
};
|
||||
|
||||
struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
|
||||
unsigned int size,
|
||||
const struct irq_domain_ops *ops,
|
||||
void *host_data);
|
||||
void irq_domain_remove(struct irq_domain *domain);
|
||||
unsigned int irq_create_mapping(struct irq_domain *domain, irq_hw_number_t hwirq);
|
||||
unsigned int irq_find_mapping(struct irq_domain *domain, irq_hw_number_t hwirq);
|
||||
int generic_handle_irq(unsigned int irq);
|
||||
void irq_set_chip_and_handler(unsigned int irq, struct irq_chip *chip,
|
||||
void (*handle)(void));
|
||||
|
||||
#endif /* _LINUX_IRQDOMAIN_H */
|
||||
@@ -684,20 +684,7 @@ typedef union
|
||||
u64 raw;
|
||||
}evhandle_t;
|
||||
|
||||
/*
|
||||
* KolibriOS has no user address space that drivers can map into, so these are
|
||||
* placeholders. The fields exist because the mmap/userptr entry points of the
|
||||
* ported DRM drivers reference them; those paths are never reached, since no
|
||||
* ioctl surface is exposed to user code.
|
||||
*/
|
||||
struct vm_area_struct {
|
||||
unsigned long vm_start;
|
||||
unsigned long vm_end;
|
||||
unsigned long vm_pgoff;
|
||||
unsigned long vm_flags;
|
||||
struct file *vm_file;
|
||||
void *vm_private_data;
|
||||
};
|
||||
struct vm_area_struct {};
|
||||
struct address_space {};
|
||||
|
||||
#define in_dbg_master() (0)
|
||||
@@ -744,13 +731,6 @@ int del_timer(struct timer_list *timer);
|
||||
|
||||
#define mmiowb() barrier()
|
||||
|
||||
/* String-to-integer conversions; each driver's kos_kernel.c implements them. */
|
||||
extern int kstrtol(const char *s, unsigned int base, long *res);
|
||||
extern int kstrtoul(const char *s, unsigned int base, unsigned long *res);
|
||||
extern int kstrtoint(const char *s, unsigned int base, int *res);
|
||||
extern int kstrtou32(const char *s, unsigned int base, u32 *res);
|
||||
|
||||
|
||||
#define dev_err(dev, format, arg...) \
|
||||
printk("Error %s " format, __func__ , ## arg)
|
||||
|
||||
@@ -760,18 +740,6 @@ extern int kstrtou32(const char *s, unsigned int base, u32 *res);
|
||||
#define dev_info(dev, format, arg...) \
|
||||
printk("Info %s " format , __func__, ## arg)
|
||||
|
||||
/*
|
||||
* nouveau routes all of its logging through dev_*() (NV_PRINTK in
|
||||
* nouveau_drv.h picks the level by name), so the two levels the other drivers
|
||||
* never needed have to exist as well. dev_dbg() keeps its arguments checked
|
||||
* but emits nothing, matching the !CONFIG_DYNAMIC_DEBUG behaviour upstream.
|
||||
*/
|
||||
#define dev_crit(dev, format, arg...) \
|
||||
printk("Critical %s " format, __func__ , ## arg)
|
||||
|
||||
#define dev_dbg(dev, format, arg...) \
|
||||
do { if (0) printk(format, ## arg); } while (0)
|
||||
|
||||
struct page
|
||||
{
|
||||
unsigned int addr;
|
||||
|
||||
@@ -1,833 +0,0 @@
|
||||
/*
|
||||
* A generic kernel FIFO implementation
|
||||
*
|
||||
* Copyright (C) 2013 Stefani Seibold <stefani@seibold.net>
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_KFIFO_H
|
||||
#define _LINUX_KFIFO_H
|
||||
|
||||
/*
|
||||
* How to porting drivers to the new generic FIFO API:
|
||||
*
|
||||
* - Modify the declaration of the "struct kfifo *" object into a
|
||||
* in-place "struct kfifo" object
|
||||
* - Init the in-place object with kfifo_alloc() or kfifo_init()
|
||||
* Note: The address of the in-place "struct kfifo" object must be
|
||||
* passed as the first argument to this functions
|
||||
* - Replace the use of __kfifo_put into kfifo_in and __kfifo_get
|
||||
* into kfifo_out
|
||||
* - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get
|
||||
* into kfifo_out_spinlocked
|
||||
* Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc
|
||||
* must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked
|
||||
* as the last parameter
|
||||
* - The formerly __kfifo_* functions are renamed into kfifo_*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note about locking : There is no locking required until only * one reader
|
||||
* and one writer is using the fifo and no kfifo_reset() will be * called
|
||||
* kfifo_reset_out() can be safely used, until it will be only called
|
||||
* in the reader thread.
|
||||
* For multiple writer and one reader there is only a need to lock the writer.
|
||||
* And vice versa for only one writer and multiple reader there is only a need
|
||||
* to lock the reader.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
struct __kfifo {
|
||||
unsigned int in;
|
||||
unsigned int out;
|
||||
unsigned int mask;
|
||||
unsigned int esize;
|
||||
void *data;
|
||||
};
|
||||
|
||||
#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \
|
||||
union { \
|
||||
struct __kfifo kfifo; \
|
||||
datatype *type; \
|
||||
const datatype *const_type; \
|
||||
char (*rectype)[recsize]; \
|
||||
ptrtype *ptr; \
|
||||
ptrtype const *ptr_const; \
|
||||
}
|
||||
|
||||
#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \
|
||||
{ \
|
||||
__STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \
|
||||
type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \
|
||||
}
|
||||
|
||||
#define STRUCT_KFIFO(type, size) \
|
||||
struct __STRUCT_KFIFO(type, size, 0, type)
|
||||
|
||||
#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \
|
||||
{ \
|
||||
__STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \
|
||||
type buf[0]; \
|
||||
}
|
||||
|
||||
#define STRUCT_KFIFO_PTR(type) \
|
||||
struct __STRUCT_KFIFO_PTR(type, 0, type)
|
||||
|
||||
/*
|
||||
* define compatibility "struct kfifo" for dynamic allocated fifos
|
||||
*/
|
||||
struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void);
|
||||
|
||||
#define STRUCT_KFIFO_REC_1(size) \
|
||||
struct __STRUCT_KFIFO(unsigned char, size, 1, void)
|
||||
|
||||
#define STRUCT_KFIFO_REC_2(size) \
|
||||
struct __STRUCT_KFIFO(unsigned char, size, 2, void)
|
||||
|
||||
/*
|
||||
* define kfifo_rec types
|
||||
*/
|
||||
struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void);
|
||||
struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void);
|
||||
|
||||
/*
|
||||
* helper macro to distinguish between real in place fifo where the fifo
|
||||
* array is a part of the structure and the fifo type where the array is
|
||||
* outside of the fifo structure.
|
||||
*/
|
||||
#define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo))
|
||||
|
||||
/**
|
||||
* DECLARE_KFIFO_PTR - macro to declare a fifo pointer object
|
||||
* @fifo: name of the declared fifo
|
||||
* @type: type of the fifo elements
|
||||
*/
|
||||
#define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo
|
||||
|
||||
/**
|
||||
* DECLARE_KFIFO - macro to declare a fifo object
|
||||
* @fifo: name of the declared fifo
|
||||
* @type: type of the fifo elements
|
||||
* @size: the number of elements in the fifo, this must be a power of 2
|
||||
*/
|
||||
#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo
|
||||
|
||||
/**
|
||||
* INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO
|
||||
* @fifo: name of the declared fifo datatype
|
||||
*/
|
||||
#define INIT_KFIFO(fifo) \
|
||||
(void)({ \
|
||||
typeof(&(fifo)) __tmp = &(fifo); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
__kfifo->in = 0; \
|
||||
__kfifo->out = 0; \
|
||||
__kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\
|
||||
__kfifo->esize = sizeof(*__tmp->buf); \
|
||||
__kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \
|
||||
})
|
||||
|
||||
/**
|
||||
* DEFINE_KFIFO - macro to define and initialize a fifo
|
||||
* @fifo: name of the declared fifo datatype
|
||||
* @type: type of the fifo elements
|
||||
* @size: the number of elements in the fifo, this must be a power of 2
|
||||
*
|
||||
* Note: the macro can be used for global and local fifo data type variables.
|
||||
*/
|
||||
#define DEFINE_KFIFO(fifo, type, size) \
|
||||
DECLARE_KFIFO(fifo, type, size) = \
|
||||
(typeof(fifo)) { \
|
||||
{ \
|
||||
{ \
|
||||
.in = 0, \
|
||||
.out = 0, \
|
||||
.mask = __is_kfifo_ptr(&(fifo)) ? \
|
||||
0 : \
|
||||
ARRAY_SIZE((fifo).buf) - 1, \
|
||||
.esize = sizeof(*(fifo).buf), \
|
||||
.data = __is_kfifo_ptr(&(fifo)) ? \
|
||||
NULL : \
|
||||
(fifo).buf, \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned int __must_check
|
||||
__kfifo_uint_must_check_helper(unsigned int val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline int __must_check
|
||||
__kfifo_int_must_check_helper(int val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* kfifo_initialized - Check if the fifo is initialized
|
||||
* @fifo: address of the fifo to check
|
||||
*
|
||||
* Return %true if fifo is initialized, otherwise %false.
|
||||
* Assumes the fifo was 0 before.
|
||||
*/
|
||||
#define kfifo_initialized(fifo) ((fifo)->kfifo.mask)
|
||||
|
||||
/**
|
||||
* kfifo_esize - returns the size of the element managed by the fifo
|
||||
* @fifo: address of the fifo to be used
|
||||
*/
|
||||
#define kfifo_esize(fifo) ((fifo)->kfifo.esize)
|
||||
|
||||
/**
|
||||
* kfifo_recsize - returns the size of the record length field
|
||||
* @fifo: address of the fifo to be used
|
||||
*/
|
||||
#define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype))
|
||||
|
||||
/**
|
||||
* kfifo_size - returns the size of the fifo in elements
|
||||
* @fifo: address of the fifo to be used
|
||||
*/
|
||||
#define kfifo_size(fifo) ((fifo)->kfifo.mask + 1)
|
||||
|
||||
/**
|
||||
* kfifo_reset - removes the entire fifo content
|
||||
* @fifo: address of the fifo to be used
|
||||
*
|
||||
* Note: usage of kfifo_reset() is dangerous. It should be only called when the
|
||||
* fifo is exclusived locked or when it is secured that no other thread is
|
||||
* accessing the fifo.
|
||||
*/
|
||||
#define kfifo_reset(fifo) \
|
||||
(void)({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
__tmp->kfifo.in = __tmp->kfifo.out = 0; \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_reset_out - skip fifo content
|
||||
* @fifo: address of the fifo to be used
|
||||
*
|
||||
* Note: The usage of kfifo_reset_out() is safe until it will be only called
|
||||
* from the reader thread and there is only one concurrent reader. Otherwise
|
||||
* it is dangerous and must be handled in the same way as kfifo_reset().
|
||||
*/
|
||||
#define kfifo_reset_out(fifo) \
|
||||
(void)({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
__tmp->kfifo.out = __tmp->kfifo.in; \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_len - returns the number of used elements in the fifo
|
||||
* @fifo: address of the fifo to be used
|
||||
*/
|
||||
#define kfifo_len(fifo) \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmpl = (fifo); \
|
||||
__tmpl->kfifo.in - __tmpl->kfifo.out; \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_is_empty - returns true if the fifo is empty
|
||||
* @fifo: address of the fifo to be used
|
||||
*/
|
||||
#define kfifo_is_empty(fifo) \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmpq = (fifo); \
|
||||
__tmpq->kfifo.in == __tmpq->kfifo.out; \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_is_full - returns true if the fifo is full
|
||||
* @fifo: address of the fifo to be used
|
||||
*/
|
||||
#define kfifo_is_full(fifo) \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmpq = (fifo); \
|
||||
kfifo_len(__tmpq) > __tmpq->kfifo.mask; \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_avail - returns the number of unused elements in the fifo
|
||||
* @fifo: address of the fifo to be used
|
||||
*/
|
||||
#define kfifo_avail(fifo) \
|
||||
__kfifo_uint_must_check_helper( \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmpq = (fifo); \
|
||||
const size_t __recsize = sizeof(*__tmpq->rectype); \
|
||||
unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \
|
||||
(__recsize) ? ((__avail <= __recsize) ? 0 : \
|
||||
__kfifo_max_r(__avail - __recsize, __recsize)) : \
|
||||
__avail; \
|
||||
}) \
|
||||
)
|
||||
|
||||
/**
|
||||
* kfifo_skip - skip output data
|
||||
* @fifo: address of the fifo to be used
|
||||
*/
|
||||
#define kfifo_skip(fifo) \
|
||||
(void)({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
if (__recsize) \
|
||||
__kfifo_skip_r(__kfifo, __recsize); \
|
||||
else \
|
||||
__kfifo->out++; \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_peek_len - gets the size of the next fifo record
|
||||
* @fifo: address of the fifo to be used
|
||||
*
|
||||
* This function returns the size of the next fifo record in number of bytes.
|
||||
*/
|
||||
#define kfifo_peek_len(fifo) \
|
||||
__kfifo_uint_must_check_helper( \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
(!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \
|
||||
__kfifo_len_r(__kfifo, __recsize); \
|
||||
}) \
|
||||
)
|
||||
|
||||
/**
|
||||
* kfifo_alloc - dynamically allocates a new fifo buffer
|
||||
* @fifo: pointer to the fifo
|
||||
* @size: the number of elements in the fifo, this must be a power of 2
|
||||
* @gfp_mask: get_free_pages mask, passed to kmalloc()
|
||||
*
|
||||
* This macro dynamically allocates a new fifo buffer.
|
||||
*
|
||||
* The numer of elements will be rounded-up to a power of 2.
|
||||
* The fifo will be release with kfifo_free().
|
||||
* Return 0 if no error, otherwise an error code.
|
||||
*/
|
||||
#define kfifo_alloc(fifo, size, gfp_mask) \
|
||||
__kfifo_int_must_check_helper( \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
__is_kfifo_ptr(__tmp) ? \
|
||||
__kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \
|
||||
-EINVAL; \
|
||||
}) \
|
||||
)
|
||||
|
||||
/**
|
||||
* kfifo_free - frees the fifo
|
||||
* @fifo: the fifo to be freed
|
||||
*/
|
||||
#define kfifo_free(fifo) \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
if (__is_kfifo_ptr(__tmp)) \
|
||||
__kfifo_free(__kfifo); \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_init - initialize a fifo using a preallocated buffer
|
||||
* @fifo: the fifo to assign the buffer
|
||||
* @buffer: the preallocated buffer to be used
|
||||
* @size: the size of the internal buffer, this have to be a power of 2
|
||||
*
|
||||
* This macro initialize a fifo using a preallocated buffer.
|
||||
*
|
||||
* The numer of elements will be rounded-up to a power of 2.
|
||||
* Return 0 if no error, otherwise an error code.
|
||||
*/
|
||||
#define kfifo_init(fifo, buffer, size) \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
__is_kfifo_ptr(__tmp) ? \
|
||||
__kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \
|
||||
-EINVAL; \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_put - put data into the fifo
|
||||
* @fifo: address of the fifo to be used
|
||||
* @val: the data to be added
|
||||
*
|
||||
* This macro copies the given value into the fifo.
|
||||
* It returns 0 if the fifo was full. Otherwise it returns the number
|
||||
* processed elements.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macro.
|
||||
*/
|
||||
#define kfifo_put(fifo, val) \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
typeof(*__tmp->const_type) __val = (val); \
|
||||
unsigned int __ret; \
|
||||
size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
if (__recsize) \
|
||||
__ret = __kfifo_in_r(__kfifo, &__val, sizeof(__val), \
|
||||
__recsize); \
|
||||
else { \
|
||||
__ret = !kfifo_is_full(__tmp); \
|
||||
if (__ret) { \
|
||||
(__is_kfifo_ptr(__tmp) ? \
|
||||
((typeof(__tmp->type))__kfifo->data) : \
|
||||
(__tmp->buf) \
|
||||
)[__kfifo->in & __tmp->kfifo.mask] = \
|
||||
*(typeof(__tmp->type))&__val; \
|
||||
smp_wmb(); \
|
||||
__kfifo->in++; \
|
||||
} \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_get - get data from the fifo
|
||||
* @fifo: address of the fifo to be used
|
||||
* @val: address where to store the data
|
||||
*
|
||||
* This macro reads the data from the fifo.
|
||||
* It returns 0 if the fifo was empty. Otherwise it returns the number
|
||||
* processed elements.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macro.
|
||||
*/
|
||||
#define kfifo_get(fifo, val) \
|
||||
__kfifo_uint_must_check_helper( \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
typeof(__tmp->ptr) __val = (val); \
|
||||
unsigned int __ret; \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
if (__recsize) \
|
||||
__ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \
|
||||
__recsize); \
|
||||
else { \
|
||||
__ret = !kfifo_is_empty(__tmp); \
|
||||
if (__ret) { \
|
||||
*(typeof(__tmp->type))__val = \
|
||||
(__is_kfifo_ptr(__tmp) ? \
|
||||
((typeof(__tmp->type))__kfifo->data) : \
|
||||
(__tmp->buf) \
|
||||
)[__kfifo->out & __tmp->kfifo.mask]; \
|
||||
smp_wmb(); \
|
||||
__kfifo->out++; \
|
||||
} \
|
||||
} \
|
||||
__ret; \
|
||||
}) \
|
||||
)
|
||||
|
||||
/**
|
||||
* kfifo_peek - get data from the fifo without removing
|
||||
* @fifo: address of the fifo to be used
|
||||
* @val: address where to store the data
|
||||
*
|
||||
* This reads the data from the fifo without removing it from the fifo.
|
||||
* It returns 0 if the fifo was empty. Otherwise it returns the number
|
||||
* processed elements.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macro.
|
||||
*/
|
||||
#define kfifo_peek(fifo, val) \
|
||||
__kfifo_uint_must_check_helper( \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
typeof(__tmp->ptr) __val = (val); \
|
||||
unsigned int __ret; \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
if (__recsize) \
|
||||
__ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \
|
||||
__recsize); \
|
||||
else { \
|
||||
__ret = !kfifo_is_empty(__tmp); \
|
||||
if (__ret) { \
|
||||
*(typeof(__tmp->type))__val = \
|
||||
(__is_kfifo_ptr(__tmp) ? \
|
||||
((typeof(__tmp->type))__kfifo->data) : \
|
||||
(__tmp->buf) \
|
||||
)[__kfifo->out & __tmp->kfifo.mask]; \
|
||||
smp_wmb(); \
|
||||
} \
|
||||
} \
|
||||
__ret; \
|
||||
}) \
|
||||
)
|
||||
|
||||
/**
|
||||
* kfifo_in - put data into the fifo
|
||||
* @fifo: address of the fifo to be used
|
||||
* @buf: the data to be added
|
||||
* @n: number of elements to be added
|
||||
*
|
||||
* This macro copies the given buffer into the fifo and returns the
|
||||
* number of copied elements.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macro.
|
||||
*/
|
||||
#define kfifo_in(fifo, buf, n) \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
typeof(__tmp->ptr_const) __buf = (buf); \
|
||||
unsigned long __n = (n); \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
(__recsize) ?\
|
||||
__kfifo_in_r(__kfifo, __buf, __n, __recsize) : \
|
||||
__kfifo_in(__kfifo, __buf, __n); \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_in_spinlocked - put data into the fifo using a spinlock for locking
|
||||
* @fifo: address of the fifo to be used
|
||||
* @buf: the data to be added
|
||||
* @n: number of elements to be added
|
||||
* @lock: pointer to the spinlock to use for locking
|
||||
*
|
||||
* This macro copies the given values buffer into the fifo and returns the
|
||||
* number of copied elements.
|
||||
*/
|
||||
#define kfifo_in_spinlocked(fifo, buf, n, lock) \
|
||||
({ \
|
||||
unsigned long __flags; \
|
||||
unsigned int __ret; \
|
||||
spin_lock_irqsave(lock, __flags); \
|
||||
__ret = kfifo_in(fifo, buf, n); \
|
||||
spin_unlock_irqrestore(lock, __flags); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
/* alias for kfifo_in_spinlocked, will be removed in a future release */
|
||||
#define kfifo_in_locked(fifo, buf, n, lock) \
|
||||
kfifo_in_spinlocked(fifo, buf, n, lock)
|
||||
|
||||
/**
|
||||
* kfifo_out - get data from the fifo
|
||||
* @fifo: address of the fifo to be used
|
||||
* @buf: pointer to the storage buffer
|
||||
* @n: max. number of elements to get
|
||||
*
|
||||
* This macro get some data from the fifo and return the numbers of elements
|
||||
* copied.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macro.
|
||||
*/
|
||||
#define kfifo_out(fifo, buf, n) \
|
||||
__kfifo_uint_must_check_helper( \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
typeof(__tmp->ptr) __buf = (buf); \
|
||||
unsigned long __n = (n); \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
(__recsize) ?\
|
||||
__kfifo_out_r(__kfifo, __buf, __n, __recsize) : \
|
||||
__kfifo_out(__kfifo, __buf, __n); \
|
||||
}) \
|
||||
)
|
||||
|
||||
/**
|
||||
* kfifo_out_spinlocked - get data from the fifo using a spinlock for locking
|
||||
* @fifo: address of the fifo to be used
|
||||
* @buf: pointer to the storage buffer
|
||||
* @n: max. number of elements to get
|
||||
* @lock: pointer to the spinlock to use for locking
|
||||
*
|
||||
* This macro get the data from the fifo and return the numbers of elements
|
||||
* copied.
|
||||
*/
|
||||
#define kfifo_out_spinlocked(fifo, buf, n, lock) \
|
||||
__kfifo_uint_must_check_helper( \
|
||||
({ \
|
||||
unsigned long __flags; \
|
||||
unsigned int __ret; \
|
||||
spin_lock_irqsave(lock, __flags); \
|
||||
__ret = kfifo_out(fifo, buf, n); \
|
||||
spin_unlock_irqrestore(lock, __flags); \
|
||||
__ret; \
|
||||
}) \
|
||||
)
|
||||
|
||||
/* alias for kfifo_out_spinlocked, will be removed in a future release */
|
||||
#define kfifo_out_locked(fifo, buf, n, lock) \
|
||||
kfifo_out_spinlocked(fifo, buf, n, lock)
|
||||
|
||||
/**
|
||||
* kfifo_from_user - puts some data from user space into the fifo
|
||||
* @fifo: address of the fifo to be used
|
||||
* @from: pointer to the data to be added
|
||||
* @len: the length of the data to be added
|
||||
* @copied: pointer to output variable to store the number of copied bytes
|
||||
*
|
||||
* This macro copies at most @len bytes from the @from into the
|
||||
* fifo, depending of the available space and returns -EFAULT/0.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macro.
|
||||
*/
|
||||
#define kfifo_from_user(fifo, from, len, copied) \
|
||||
__kfifo_uint_must_check_helper( \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
const void __user *__from = (from); \
|
||||
unsigned int __len = (len); \
|
||||
unsigned int *__copied = (copied); \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
(__recsize) ? \
|
||||
__kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \
|
||||
__kfifo_from_user(__kfifo, __from, __len, __copied); \
|
||||
}) \
|
||||
)
|
||||
|
||||
/**
|
||||
* kfifo_to_user - copies data from the fifo into user space
|
||||
* @fifo: address of the fifo to be used
|
||||
* @to: where the data must be copied
|
||||
* @len: the size of the destination buffer
|
||||
* @copied: pointer to output variable to store the number of copied bytes
|
||||
*
|
||||
* This macro copies at most @len bytes from the fifo into the
|
||||
* @to buffer and returns -EFAULT/0.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macro.
|
||||
*/
|
||||
#define kfifo_to_user(fifo, to, len, copied) \
|
||||
__kfifo_uint_must_check_helper( \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
void __user *__to = (to); \
|
||||
unsigned int __len = (len); \
|
||||
unsigned int *__copied = (copied); \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
(__recsize) ? \
|
||||
__kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \
|
||||
__kfifo_to_user(__kfifo, __to, __len, __copied); \
|
||||
}) \
|
||||
)
|
||||
|
||||
/**
|
||||
* kfifo_dma_in_prepare - setup a scatterlist for DMA input
|
||||
* @fifo: address of the fifo to be used
|
||||
* @sgl: pointer to the scatterlist array
|
||||
* @nents: number of entries in the scatterlist array
|
||||
* @len: number of elements to transfer
|
||||
*
|
||||
* This macro fills a scatterlist for DMA input.
|
||||
* It returns the number entries in the scatterlist array.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macros.
|
||||
*/
|
||||
#define kfifo_dma_in_prepare(fifo, sgl, nents, len) \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
struct scatterlist *__sgl = (sgl); \
|
||||
int __nents = (nents); \
|
||||
unsigned int __len = (len); \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
(__recsize) ? \
|
||||
__kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \
|
||||
__kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_dma_in_finish - finish a DMA IN operation
|
||||
* @fifo: address of the fifo to be used
|
||||
* @len: number of bytes to received
|
||||
*
|
||||
* This macro finish a DMA IN operation. The in counter will be updated by
|
||||
* the len parameter. No error checking will be done.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macros.
|
||||
*/
|
||||
#define kfifo_dma_in_finish(fifo, len) \
|
||||
(void)({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
unsigned int __len = (len); \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
if (__recsize) \
|
||||
__kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \
|
||||
else \
|
||||
__kfifo->in += __len / sizeof(*__tmp->type); \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_dma_out_prepare - setup a scatterlist for DMA output
|
||||
* @fifo: address of the fifo to be used
|
||||
* @sgl: pointer to the scatterlist array
|
||||
* @nents: number of entries in the scatterlist array
|
||||
* @len: number of elements to transfer
|
||||
*
|
||||
* This macro fills a scatterlist for DMA output which at most @len bytes
|
||||
* to transfer.
|
||||
* It returns the number entries in the scatterlist array.
|
||||
* A zero means there is no space available and the scatterlist is not filled.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macros.
|
||||
*/
|
||||
#define kfifo_dma_out_prepare(fifo, sgl, nents, len) \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
struct scatterlist *__sgl = (sgl); \
|
||||
int __nents = (nents); \
|
||||
unsigned int __len = (len); \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
(__recsize) ? \
|
||||
__kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \
|
||||
__kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_dma_out_finish - finish a DMA OUT operation
|
||||
* @fifo: address of the fifo to be used
|
||||
* @len: number of bytes transferred
|
||||
*
|
||||
* This macro finish a DMA OUT operation. The out counter will be updated by
|
||||
* the len parameter. No error checking will be done.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macros.
|
||||
*/
|
||||
#define kfifo_dma_out_finish(fifo, len) \
|
||||
(void)({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
unsigned int __len = (len); \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
if (__recsize) \
|
||||
__kfifo_dma_out_finish_r(__kfifo, __recsize); \
|
||||
else \
|
||||
__kfifo->out += __len / sizeof(*__tmp->type); \
|
||||
})
|
||||
|
||||
/**
|
||||
* kfifo_out_peek - gets some data from the fifo
|
||||
* @fifo: address of the fifo to be used
|
||||
* @buf: pointer to the storage buffer
|
||||
* @n: max. number of elements to get
|
||||
*
|
||||
* This macro get the data from the fifo and return the numbers of elements
|
||||
* copied. The data is not removed from the fifo.
|
||||
*
|
||||
* Note that with only one concurrent reader and one concurrent
|
||||
* writer, you don't need extra locking to use these macro.
|
||||
*/
|
||||
#define kfifo_out_peek(fifo, buf, n) \
|
||||
__kfifo_uint_must_check_helper( \
|
||||
({ \
|
||||
typeof((fifo) + 1) __tmp = (fifo); \
|
||||
typeof(__tmp->ptr) __buf = (buf); \
|
||||
unsigned long __n = (n); \
|
||||
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||
(__recsize) ? \
|
||||
__kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \
|
||||
__kfifo_out_peek(__kfifo, __buf, __n); \
|
||||
}) \
|
||||
)
|
||||
|
||||
extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
|
||||
size_t esize, gfp_t gfp_mask);
|
||||
|
||||
extern void __kfifo_free(struct __kfifo *fifo);
|
||||
|
||||
extern int __kfifo_init(struct __kfifo *fifo, void *buffer,
|
||||
unsigned int size, size_t esize);
|
||||
|
||||
extern unsigned int __kfifo_in(struct __kfifo *fifo,
|
||||
const void *buf, unsigned int len);
|
||||
|
||||
extern unsigned int __kfifo_out(struct __kfifo *fifo,
|
||||
void *buf, unsigned int len);
|
||||
|
||||
extern int __kfifo_from_user(struct __kfifo *fifo,
|
||||
const void __user *from, unsigned long len, unsigned int *copied);
|
||||
|
||||
extern int __kfifo_to_user(struct __kfifo *fifo,
|
||||
void __user *to, unsigned long len, unsigned int *copied);
|
||||
|
||||
extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo,
|
||||
struct scatterlist *sgl, int nents, unsigned int len);
|
||||
|
||||
extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo,
|
||||
struct scatterlist *sgl, int nents, unsigned int len);
|
||||
|
||||
extern unsigned int __kfifo_out_peek(struct __kfifo *fifo,
|
||||
void *buf, unsigned int len);
|
||||
|
||||
extern unsigned int __kfifo_in_r(struct __kfifo *fifo,
|
||||
const void *buf, unsigned int len, size_t recsize);
|
||||
|
||||
extern unsigned int __kfifo_out_r(struct __kfifo *fifo,
|
||||
void *buf, unsigned int len, size_t recsize);
|
||||
|
||||
extern int __kfifo_from_user_r(struct __kfifo *fifo,
|
||||
const void __user *from, unsigned long len, unsigned int *copied,
|
||||
size_t recsize);
|
||||
|
||||
extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to,
|
||||
unsigned long len, unsigned int *copied, size_t recsize);
|
||||
|
||||
extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo,
|
||||
struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
|
||||
|
||||
extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo,
|
||||
unsigned int len, size_t recsize);
|
||||
|
||||
extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo,
|
||||
struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
|
||||
|
||||
extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize);
|
||||
|
||||
extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize);
|
||||
|
||||
extern void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize);
|
||||
|
||||
extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo,
|
||||
void *buf, unsigned int len, size_t recsize);
|
||||
|
||||
extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize);
|
||||
|
||||
#endif
|
||||
@@ -1,57 +0,0 @@
|
||||
#ifndef _LINUX_KTHREAD_H
|
||||
#define _LINUX_KTHREAD_H
|
||||
/*
|
||||
* Minimal kthread emulation for KolibriOS.
|
||||
*
|
||||
* The GPU scheduler (drivers/video/drm/amdgpu/scheduler) is the only user in
|
||||
* the DRM tree. KolibriOS kernel threads are created with CreateKernelThread(),
|
||||
* which takes no argument, so kthread_run() stashes the payload in a small
|
||||
* pid-indexed table and the trampoline picks it up. Park/stop are cooperative
|
||||
* flags polled by the thread body, matching how the scheduler uses them.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/rwsem.h>
|
||||
|
||||
/*
|
||||
* Placeholder address space. Drivers reach it as current->mm on their userptr
|
||||
* paths only, which KolibriOS never enters (no ioctl surface for user code).
|
||||
*/
|
||||
struct mm_struct {
|
||||
struct rw_semaphore mmap_sem;
|
||||
};
|
||||
|
||||
struct task_struct {
|
||||
int (*threadfn)(void *data);
|
||||
void *data;
|
||||
int pid;
|
||||
volatile int should_stop;
|
||||
volatile int should_park;
|
||||
volatile int parked;
|
||||
char comm[16];
|
||||
struct mm_struct *mm;
|
||||
};
|
||||
|
||||
struct task_struct *kthread_create_kos(int (*threadfn)(void *data),
|
||||
void *data, const char *name);
|
||||
int kthread_stop(struct task_struct *k);
|
||||
bool kthread_should_stop(void);
|
||||
bool kthread_should_park(void);
|
||||
void kthread_parkme(void);
|
||||
int kthread_park(struct task_struct *k);
|
||||
void kthread_unpark(struct task_struct *k);
|
||||
struct task_struct *kthread_current(void);
|
||||
|
||||
#define kthread_run(threadfn, data, namefmt, ...) \
|
||||
kthread_create_kos((threadfn), (data), (namefmt))
|
||||
|
||||
#define kthread_create(threadfn, data, namefmt, ...) \
|
||||
kthread_create_kos((threadfn), (data), (namefmt))
|
||||
|
||||
static inline void wake_up_process(struct task_struct *k) { }
|
||||
static inline void get_task_struct(struct task_struct *k) { }
|
||||
static inline void put_task_struct(struct task_struct *k) { }
|
||||
|
||||
#endif /* _LINUX_KTHREAD_H */
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef _LINUX_MFD_CORE_H
|
||||
#define _LINUX_MFD_CORE_H
|
||||
/*
|
||||
* No multi-function-device bus on KolibriOS. amdgpu_acp.h embeds an
|
||||
* mfd_cell pointer in struct amdgpu_acp; the ACP block itself is not built.
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
struct device;
|
||||
struct resource;
|
||||
|
||||
struct mfd_cell {
|
||||
const char *name;
|
||||
int id;
|
||||
void *platform_data;
|
||||
size_t pdata_size;
|
||||
int num_resources;
|
||||
const struct resource *resources;
|
||||
};
|
||||
|
||||
static inline int mfd_add_hotplug_devices(struct device *parent,
|
||||
const struct mfd_cell *cells, int n)
|
||||
{ return -ENODEV; }
|
||||
static inline void mfd_remove_devices(struct device *parent) { }
|
||||
#endif
|
||||
@@ -8,12 +8,6 @@
|
||||
#define nth_page(page,n) ((void*)(((page_to_phys(page)>>12)+(n))<<12))
|
||||
|
||||
#define __page_to_pfn(page) (page_to_phys(page)>>12)
|
||||
/*
|
||||
* A struct page * here is just the physical address (see page_to_phys() in
|
||||
* <linux/kernel.h>), so the reverse direction is the same shift back.
|
||||
*/
|
||||
#define __pfn_to_page(pfn) ((struct page *)((dma_addr_t)(pfn) << 12))
|
||||
#define pfn_to_page(pfn) __pfn_to_page(pfn)
|
||||
|
||||
/* to align the pointer to the (next) page boundary */
|
||||
#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE)
|
||||
|
||||
@@ -26,14 +26,4 @@
|
||||
|
||||
struct module {};
|
||||
|
||||
/*
|
||||
* Nothing is a module here - everything is linked into the one image - so the
|
||||
* reference count can never drop and a request for another module can never be
|
||||
* satisfied. Implemented in the driver's kos_* glue.
|
||||
*/
|
||||
extern int request_module(const char *name, ...);
|
||||
extern int try_module_get(struct module *module);
|
||||
extern void module_put(struct module *module);
|
||||
|
||||
|
||||
#endif /* _LINUX_MODULE_H */
|
||||
@@ -77,15 +77,6 @@ void __attribute__ ((fastcall)) __attribute__ ((dllimport))
|
||||
void __attribute__ ((fastcall)) __attribute__ ((dllimport))
|
||||
mutex_unlock(struct mutex*)__asm__("MutexUnlock");
|
||||
|
||||
/*
|
||||
* mutex_init() is the DDK's MutexInit(); these two are the spellings upstream
|
||||
* code reaches for when it wants a lockdep class, which this port does not
|
||||
* have. Both end up in the same place.
|
||||
*/
|
||||
extern void __mutex_init(struct mutex *lock, const char *name,
|
||||
struct lock_class_key *key);
|
||||
extern void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
|
||||
|
||||
static inline int mutex_lock_interruptible(struct mutex *lock)
|
||||
{
|
||||
mutex_lock(lock);
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifndef _LINUX_OF_DEVICE_H
|
||||
#define _LINUX_OF_DEVICE_H
|
||||
/* No device tree on x86; pulled in unconditionally by nvif/os.h. */
|
||||
struct device;
|
||||
struct of_device_id;
|
||||
|
||||
static inline const struct of_device_id *
|
||||
of_match_device(const struct of_device_id *m, const struct device *dev)
|
||||
{ return NULL; }
|
||||
#endif
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef _LINUX_PAGEMAP_H
|
||||
#define _LINUX_PAGEMAP_H
|
||||
/* Only the shift/size helpers are used by the TTM/GEM paths on this port. */
|
||||
#include <linux/mm.h>
|
||||
#define PAGE_CACHE_SHIFT PAGE_SHIFT
|
||||
#define PAGE_CACHE_SIZE PAGE_SIZE
|
||||
#define PAGE_CACHE_MASK PAGE_MASK
|
||||
#endif
|
||||
@@ -275,13 +275,6 @@ struct pci_dev {
|
||||
struct pci_bus *bus; /* bus this device is on */
|
||||
struct pci_bus *subordinate; /* bus this device bridges to */
|
||||
|
||||
/*
|
||||
* Always NULL on this port: there is no driver model to bind through.
|
||||
* nouveau_drm.c reads it to decide whether the HDMI audio function is
|
||||
* claimed before powering the GPU down, and takes the safe branch.
|
||||
*/
|
||||
struct pci_driver *driver;
|
||||
|
||||
void *sysdata; /* hook for sys-specific extension */
|
||||
// struct proc_dir_entry *procent; /* device entry in /proc/bus/pci */
|
||||
struct pci_slot *slot; /* Physical slot this device is in */
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef _LINUX_PLATFORM_DEVICE_H
|
||||
#define _LINUX_PLATFORM_DEVICE_H
|
||||
/* No platform bus; amdgpu_drv.h only needs the type to exist. */
|
||||
#include <linux/device.h>
|
||||
struct platform_device { struct device dev; const char *name; int id; };
|
||||
struct platform_driver;
|
||||
#endif
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef _LINUX_POWER_SUPPLY_H
|
||||
#define _LINUX_POWER_SUPPLY_H
|
||||
/*
|
||||
* No battery subsystem on KolibriOS. power_supply_is_system_supplied() is
|
||||
* already provided by <syscall.h>; only the enum labels are missing.
|
||||
*/
|
||||
enum {
|
||||
POWER_SUPPLY_TYPE_UNKNOWN = 0,
|
||||
POWER_SUPPLY_TYPE_BATTERY,
|
||||
POWER_SUPPLY_TYPE_MAINS,
|
||||
};
|
||||
#endif
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef _LINUX_REBOOT_H
|
||||
#define _LINUX_REBOOT_H
|
||||
/*
|
||||
* No reboot notifier chain on this port. nvif/os.h includes this header for
|
||||
* every nvkm translation unit; nothing in the built set registers a notifier.
|
||||
*/
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#define SYS_RESTART 0x0001
|
||||
#define SYS_HALT 0x0002
|
||||
#define SYS_POWER_OFF 0x0003
|
||||
|
||||
static inline int register_reboot_notifier(struct notifier_block *nb) { return 0; }
|
||||
static inline int unregister_reboot_notifier(struct notifier_block *nb) { return 0; }
|
||||
|
||||
/*
|
||||
* nvkm/subdev/therm/temp.c asks for this when the GPU passes its shutdown
|
||||
* threshold. There is no orderly shutdown to request on KolibriOS; the
|
||||
* driver's implementation logs and returns.
|
||||
*/
|
||||
extern int orderly_poweroff(bool force);
|
||||
#endif
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef _LINUX_REGULATOR_CONSUMER_H
|
||||
#define _LINUX_REGULATOR_CONSUMER_H
|
||||
/* Tegra-only; see linux/clk.h for why this exists at all. */
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
struct regulator;
|
||||
struct device;
|
||||
|
||||
static inline struct regulator *regulator_get(struct device *dev, const char *id)
|
||||
{ return ERR_PTR(-ENOENT); }
|
||||
static inline void regulator_put(struct regulator *r) { }
|
||||
static inline int regulator_enable(struct regulator *r) { return -ENOSYS; }
|
||||
static inline int regulator_disable(struct regulator *r) { return -ENOSYS; }
|
||||
static inline int regulator_get_voltage(struct regulator *r) { return -ENODEV; }
|
||||
static inline int regulator_set_voltage(struct regulator *r, int min_uV, int max_uV)
|
||||
{ return -ENODEV; }
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef _LINUX_RESET_H
|
||||
#define _LINUX_RESET_H
|
||||
/* Tegra-only; see linux/clk.h for why this exists at all. */
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
struct reset_control;
|
||||
struct device;
|
||||
|
||||
static inline struct reset_control *reset_control_get(struct device *dev, const char *id)
|
||||
{ return ERR_PTR(-ENOENT); }
|
||||
static inline void reset_control_put(struct reset_control *rstc) { }
|
||||
static inline int reset_control_assert(struct reset_control *rstc) { return -ENOSYS; }
|
||||
static inline int reset_control_deassert(struct reset_control *rstc) { return -ENOSYS; }
|
||||
#endif
|
||||
@@ -49,14 +49,4 @@
|
||||
#define schedule_timeout(x) delay(x)
|
||||
#define MAX_SCHEDULE_TIMEOUT LONG_MAX
|
||||
|
||||
/*
|
||||
* No processes and no signals behind a driver thread: signal_pending() is
|
||||
* always false, so interruptible waits only ever end on their timeout, and
|
||||
* every task carries the singleton name set in kos_stubs.c.
|
||||
*/
|
||||
struct task_struct;
|
||||
extern int signal_pending(struct task_struct *p);
|
||||
extern void __set_current_state(int state);
|
||||
extern char *get_task_comm(char *buf, struct task_struct *tsk);
|
||||
|
||||
#endif
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef _LINUX_SCREEN_INFO_H
|
||||
#define _LINUX_SCREEN_INFO_H
|
||||
/*
|
||||
* nouveau_fbcon.c only uses this to decide whether it owns the boot console.
|
||||
* KolibriOS has no boot console to hand over, so the record stays empty.
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
|
||||
struct screen_info {
|
||||
__u8 orig_video_isVGA;
|
||||
__u16 lfb_width;
|
||||
__u16 lfb_height;
|
||||
__u16 lfb_depth;
|
||||
__u32 lfb_base;
|
||||
__u32 lfb_size;
|
||||
};
|
||||
|
||||
extern struct screen_info screen_info;
|
||||
#endif
|
||||
@@ -1,5 +0,0 @@
|
||||
#ifndef _LINUX_SWIOTLB_H
|
||||
#define _LINUX_SWIOTLB_H
|
||||
/* No bounce buffers on this port; amdgpu_ttm.c only queries swiotlb_nr_tbl(). */
|
||||
static inline unsigned long swiotlb_nr_tbl(void) { return 0; }
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
#ifndef _LINUX_TRACEPOINT_H
|
||||
#define _LINUX_TRACEPOINT_H
|
||||
/* Tracepoints compile away: amdgpu_trace.h expands to empty trace_*() calls. */
|
||||
/*
|
||||
* Each event still has to yield a callable trace_<name>(), because the driver
|
||||
* code calls it unconditionally - upstream generates one per event. Here they
|
||||
* expand to empty inlines, so the calls disappear at -O2 but the argument
|
||||
* expressions are still type-checked.
|
||||
*/
|
||||
#define TP_PROTO(args...) args
|
||||
#define TP_ARGS(args...) args
|
||||
#define TP_STRUCT__entry(args...)
|
||||
#define TP_fast_assign(args...)
|
||||
#define TP_printk(fmt, args...)
|
||||
#define TP_CONDITION(args...)
|
||||
|
||||
#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
|
||||
|
||||
#define DEFINE_EVENT(tmpl, name, proto, args) \
|
||||
static inline void trace_##name(proto) { } \
|
||||
static inline bool trace_##name##_enabled(void) { return false; }
|
||||
|
||||
#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
|
||||
static inline void trace_##name(proto) { } \
|
||||
static inline bool trace_##name##_enabled(void) { return false; }
|
||||
|
||||
#define TRACE_EVENT_CONDITION(name, proto, args, cond, tstruct, assign, print) \
|
||||
static inline void trace_##name(proto) { } \
|
||||
static inline bool trace_##name##_enabled(void) { return false; }
|
||||
|
||||
#define DECLARE_TRACE(name, proto, args) \
|
||||
static inline void trace_##name(proto) { }
|
||||
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
|
||||
#define EXPORT_TRACEPOINT_SYMBOL(name)
|
||||
#endif
|
||||
@@ -1,5 +0,0 @@
|
||||
#ifndef _LINUX_TTY_H
|
||||
#define _LINUX_TTY_H
|
||||
/* No tty layer; nouveau_fbcon.c includes it for console_lock() neighbours. */
|
||||
#include <linux/console.h>
|
||||
#endif
|
||||
@@ -188,7 +188,6 @@ static inline enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(v
|
||||
static inline int vga_switcheroo_lock_ddc(struct pci_dev *pdev) { return -ENODEV; }
|
||||
static inline int vga_switcheroo_unlock_ddc(struct pci_dev *pdev) { return -ENODEV; }
|
||||
static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
|
||||
static inline bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev) { return false; }
|
||||
static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; }
|
||||
|
||||
static inline void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic) {}
|
||||
|
||||
@@ -30,12 +30,6 @@ extern void *vmalloc(unsigned long size);
|
||||
extern void *vzalloc(unsigned long size);
|
||||
extern void vfree(const void *addr);
|
||||
|
||||
/*
|
||||
* kmalloc() and vmalloc() come from the same allocator on this port, so one
|
||||
* free serves both - which is what kvfree() means upstream too.
|
||||
*/
|
||||
extern void kvfree(const void *addr);
|
||||
|
||||
extern void *vmap(struct page **pages, unsigned int count,
|
||||
unsigned long flags, pgprot_t prot);
|
||||
extern void vunmap(const void *addr);
|
||||
|
||||
@@ -326,30 +326,6 @@ int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *
|
||||
|
||||
#define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function)
|
||||
|
||||
/*
|
||||
* The "_locked" variants are entered with wq.lock already held and must give
|
||||
* it up while waiting. That rules out the event-based path above, which takes
|
||||
* the lock itself, so these poll instead - the same trade the rest of this
|
||||
* header already makes.
|
||||
*
|
||||
* Because nothing ever blocks on an event here, wake_up_all_locked() has
|
||||
* nothing to signal: the waiter re-tests the condition on its next tick.
|
||||
*/
|
||||
#define wait_event_interruptible_locked(wq, condition) \
|
||||
({ \
|
||||
while (!(condition)) { \
|
||||
spin_unlock(&(wq).lock); \
|
||||
delay(1); \
|
||||
spin_lock(&(wq).lock); \
|
||||
} \
|
||||
0; \
|
||||
})
|
||||
|
||||
#define wait_event_locked(wq, condition) \
|
||||
wait_event_interruptible_locked(wq, condition)
|
||||
|
||||
#define wake_up_locked(q) do { } while (0)
|
||||
#define wake_up_all_locked(q) do { } while (0)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -268,9 +268,6 @@ static inline bool mod_delayed_work(struct workqueue_struct *wq,
|
||||
(_work)->work.func = _func; \
|
||||
} while (0)
|
||||
|
||||
/* Defined in each driver's kos_kernel.c. */
|
||||
extern bool flush_work(struct work_struct *work);
|
||||
|
||||
static inline bool schedule_work(struct work_struct *work)
|
||||
{
|
||||
return queue_work(system_wq, work);
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#ifndef __SOC_TEGRA_FUSE_H
|
||||
#define __SOC_TEGRA_FUSE_H
|
||||
/* Tegra-only; nvif/os.h includes it unconditionally. */
|
||||
static inline int tegra_sku_info_dummy(void) { return 0; }
|
||||
#endif
|
||||
@@ -1,5 +0,0 @@
|
||||
#ifndef __SOC_TEGRA_PMC_H
|
||||
#define __SOC_TEGRA_PMC_H
|
||||
/* Tegra-only; nvif/os.h includes it unconditionally. */
|
||||
static inline int tegra_pmc_dummy(void) { return 0; }
|
||||
#endif
|
||||
@@ -1,5 +0,0 @@
|
||||
#ifndef _TRACE_DEFINE_TRACE_H
|
||||
#define _TRACE_DEFINE_TRACE_H
|
||||
/* Tracepoints are compiled out - see linux/tracepoint.h. */
|
||||
#undef TRACE_HEADER_MULTI_READ
|
||||
#endif
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef _TRACE_EVENTS_FENCE_H
|
||||
#define _TRACE_EVENTS_FENCE_H
|
||||
/* Tracepoints are compiled out; nouveau_fence.c is the only includer. */
|
||||
struct fence;
|
||||
static inline void trace_fence_emit(struct fence *fence) { }
|
||||
#endif
|
||||
@@ -68,14 +68,7 @@
|
||||
((nr) << _IOC_NRSHIFT) | \
|
||||
((size) << _IOC_SIZESHIFT))
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* provoke compile error for invalid uses of size argument */
|
||||
extern unsigned int __invalid_size_argument_for_IOC;
|
||||
#define _IOC_TYPECHECK(t) \
|
||||
((sizeof(t) == sizeof(t[1]) && \
|
||||
sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
|
||||
sizeof(t) : __invalid_size_argument_for_IOC)
|
||||
#else
|
||||
#ifndef __KERNEL__
|
||||
#define _IOC_TYPECHECK(t) (sizeof(t))
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,662 +0,0 @@
|
||||
/* amdgpu_drm.h -- Public header for the amdgpu driver -*- linux-c -*-
|
||||
*
|
||||
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
|
||||
* Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* Copyright 2014 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef __AMDGPU_DRM_H__
|
||||
#define __AMDGPU_DRM_H__
|
||||
|
||||
#include "drm.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DRM_AMDGPU_GEM_CREATE 0x00
|
||||
#define DRM_AMDGPU_GEM_MMAP 0x01
|
||||
#define DRM_AMDGPU_CTX 0x02
|
||||
#define DRM_AMDGPU_BO_LIST 0x03
|
||||
#define DRM_AMDGPU_CS 0x04
|
||||
#define DRM_AMDGPU_INFO 0x05
|
||||
#define DRM_AMDGPU_GEM_METADATA 0x06
|
||||
#define DRM_AMDGPU_GEM_WAIT_IDLE 0x07
|
||||
#define DRM_AMDGPU_GEM_VA 0x08
|
||||
#define DRM_AMDGPU_WAIT_CS 0x09
|
||||
#define DRM_AMDGPU_GEM_OP 0x10
|
||||
#define DRM_AMDGPU_GEM_USERPTR 0x11
|
||||
|
||||
#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
|
||||
#define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
|
||||
#define DRM_IOCTL_AMDGPU_CTX DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CTX, union drm_amdgpu_ctx)
|
||||
#define DRM_IOCTL_AMDGPU_BO_LIST DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_BO_LIST, union drm_amdgpu_bo_list)
|
||||
#define DRM_IOCTL_AMDGPU_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CS, union drm_amdgpu_cs)
|
||||
#define DRM_IOCTL_AMDGPU_INFO DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_INFO, struct drm_amdgpu_info)
|
||||
#define DRM_IOCTL_AMDGPU_GEM_METADATA DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_METADATA, struct drm_amdgpu_gem_metadata)
|
||||
#define DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_WAIT_IDLE, union drm_amdgpu_gem_wait_idle)
|
||||
#define DRM_IOCTL_AMDGPU_GEM_VA DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_VA, struct drm_amdgpu_gem_va)
|
||||
#define DRM_IOCTL_AMDGPU_WAIT_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union drm_amdgpu_wait_cs)
|
||||
#define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op)
|
||||
#define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr)
|
||||
|
||||
#define AMDGPU_GEM_DOMAIN_CPU 0x1
|
||||
#define AMDGPU_GEM_DOMAIN_GTT 0x2
|
||||
#define AMDGPU_GEM_DOMAIN_VRAM 0x4
|
||||
#define AMDGPU_GEM_DOMAIN_GDS 0x8
|
||||
#define AMDGPU_GEM_DOMAIN_GWS 0x10
|
||||
#define AMDGPU_GEM_DOMAIN_OA 0x20
|
||||
|
||||
/* Flag that CPU access will be required for the case of VRAM domain */
|
||||
#define AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED (1 << 0)
|
||||
/* Flag that CPU access will not work, this VRAM domain is invisible */
|
||||
#define AMDGPU_GEM_CREATE_NO_CPU_ACCESS (1 << 1)
|
||||
/* Flag that USWC attributes should be used for GTT */
|
||||
#define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2)
|
||||
/* Flag that the memory should be in VRAM and cleared */
|
||||
#define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3)
|
||||
/* Flag that create shadow bo(GTT) while allocating vram bo */
|
||||
#define AMDGPU_GEM_CREATE_SHADOW (1 << 4)
|
||||
|
||||
struct drm_amdgpu_gem_create_in {
|
||||
/** the requested memory size */
|
||||
__u64 bo_size;
|
||||
/** physical start_addr alignment in bytes for some HW requirements */
|
||||
__u64 alignment;
|
||||
/** the requested memory domains */
|
||||
__u64 domains;
|
||||
/** allocation flags */
|
||||
__u64 domain_flags;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_gem_create_out {
|
||||
/** returned GEM object handle */
|
||||
__u32 handle;
|
||||
__u32 _pad;
|
||||
};
|
||||
|
||||
union drm_amdgpu_gem_create {
|
||||
struct drm_amdgpu_gem_create_in in;
|
||||
struct drm_amdgpu_gem_create_out out;
|
||||
};
|
||||
|
||||
/** Opcode to create new residency list. */
|
||||
#define AMDGPU_BO_LIST_OP_CREATE 0
|
||||
/** Opcode to destroy previously created residency list */
|
||||
#define AMDGPU_BO_LIST_OP_DESTROY 1
|
||||
/** Opcode to update resource information in the list */
|
||||
#define AMDGPU_BO_LIST_OP_UPDATE 2
|
||||
|
||||
struct drm_amdgpu_bo_list_in {
|
||||
/** Type of operation */
|
||||
__u32 operation;
|
||||
/** Handle of list or 0 if we want to create one */
|
||||
__u32 list_handle;
|
||||
/** Number of BOs in list */
|
||||
__u32 bo_number;
|
||||
/** Size of each element describing BO */
|
||||
__u32 bo_info_size;
|
||||
/** Pointer to array describing BOs */
|
||||
__u64 bo_info_ptr;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_bo_list_entry {
|
||||
/** Handle of BO */
|
||||
__u32 bo_handle;
|
||||
/** New (if specified) BO priority to be used during migration */
|
||||
__u32 bo_priority;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_bo_list_out {
|
||||
/** Handle of resource list */
|
||||
__u32 list_handle;
|
||||
__u32 _pad;
|
||||
};
|
||||
|
||||
union drm_amdgpu_bo_list {
|
||||
struct drm_amdgpu_bo_list_in in;
|
||||
struct drm_amdgpu_bo_list_out out;
|
||||
};
|
||||
|
||||
/* context related */
|
||||
#define AMDGPU_CTX_OP_ALLOC_CTX 1
|
||||
#define AMDGPU_CTX_OP_FREE_CTX 2
|
||||
#define AMDGPU_CTX_OP_QUERY_STATE 3
|
||||
|
||||
/* GPU reset status */
|
||||
#define AMDGPU_CTX_NO_RESET 0
|
||||
/* this the context caused it */
|
||||
#define AMDGPU_CTX_GUILTY_RESET 1
|
||||
/* some other context caused it */
|
||||
#define AMDGPU_CTX_INNOCENT_RESET 2
|
||||
/* unknown cause */
|
||||
#define AMDGPU_CTX_UNKNOWN_RESET 3
|
||||
|
||||
struct drm_amdgpu_ctx_in {
|
||||
/** AMDGPU_CTX_OP_* */
|
||||
__u32 op;
|
||||
/** For future use, no flags defined so far */
|
||||
__u32 flags;
|
||||
__u32 ctx_id;
|
||||
__u32 _pad;
|
||||
};
|
||||
|
||||
union drm_amdgpu_ctx_out {
|
||||
struct {
|
||||
__u32 ctx_id;
|
||||
__u32 _pad;
|
||||
} alloc;
|
||||
|
||||
struct {
|
||||
/** For future use, no flags defined so far */
|
||||
__u64 flags;
|
||||
/** Number of resets caused by this context so far. */
|
||||
__u32 hangs;
|
||||
/** Reset status since the last call of the ioctl. */
|
||||
__u32 reset_status;
|
||||
} state;
|
||||
};
|
||||
|
||||
union drm_amdgpu_ctx {
|
||||
struct drm_amdgpu_ctx_in in;
|
||||
union drm_amdgpu_ctx_out out;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is not a reliable API and you should expect it to fail for any
|
||||
* number of reasons and have fallback path that do not use userptr to
|
||||
* perform any operation.
|
||||
*/
|
||||
#define AMDGPU_GEM_USERPTR_READONLY (1 << 0)
|
||||
#define AMDGPU_GEM_USERPTR_ANONONLY (1 << 1)
|
||||
#define AMDGPU_GEM_USERPTR_VALIDATE (1 << 2)
|
||||
#define AMDGPU_GEM_USERPTR_REGISTER (1 << 3)
|
||||
|
||||
struct drm_amdgpu_gem_userptr {
|
||||
__u64 addr;
|
||||
__u64 size;
|
||||
/* AMDGPU_GEM_USERPTR_* */
|
||||
__u32 flags;
|
||||
/* Resulting GEM handle */
|
||||
__u32 handle;
|
||||
};
|
||||
|
||||
/* same meaning as the GB_TILE_MODE and GL_MACRO_TILE_MODE fields */
|
||||
#define AMDGPU_TILING_ARRAY_MODE_SHIFT 0
|
||||
#define AMDGPU_TILING_ARRAY_MODE_MASK 0xf
|
||||
#define AMDGPU_TILING_PIPE_CONFIG_SHIFT 4
|
||||
#define AMDGPU_TILING_PIPE_CONFIG_MASK 0x1f
|
||||
#define AMDGPU_TILING_TILE_SPLIT_SHIFT 9
|
||||
#define AMDGPU_TILING_TILE_SPLIT_MASK 0x7
|
||||
#define AMDGPU_TILING_MICRO_TILE_MODE_SHIFT 12
|
||||
#define AMDGPU_TILING_MICRO_TILE_MODE_MASK 0x7
|
||||
#define AMDGPU_TILING_BANK_WIDTH_SHIFT 15
|
||||
#define AMDGPU_TILING_BANK_WIDTH_MASK 0x3
|
||||
#define AMDGPU_TILING_BANK_HEIGHT_SHIFT 17
|
||||
#define AMDGPU_TILING_BANK_HEIGHT_MASK 0x3
|
||||
#define AMDGPU_TILING_MACRO_TILE_ASPECT_SHIFT 19
|
||||
#define AMDGPU_TILING_MACRO_TILE_ASPECT_MASK 0x3
|
||||
#define AMDGPU_TILING_NUM_BANKS_SHIFT 21
|
||||
#define AMDGPU_TILING_NUM_BANKS_MASK 0x3
|
||||
|
||||
#define AMDGPU_TILING_SET(field, value) \
|
||||
(((value) & AMDGPU_TILING_##field##_MASK) << AMDGPU_TILING_##field##_SHIFT)
|
||||
#define AMDGPU_TILING_GET(value, field) \
|
||||
(((value) >> AMDGPU_TILING_##field##_SHIFT) & AMDGPU_TILING_##field##_MASK)
|
||||
|
||||
#define AMDGPU_GEM_METADATA_OP_SET_METADATA 1
|
||||
#define AMDGPU_GEM_METADATA_OP_GET_METADATA 2
|
||||
|
||||
/** The same structure is shared for input/output */
|
||||
struct drm_amdgpu_gem_metadata {
|
||||
/** GEM Object handle */
|
||||
__u32 handle;
|
||||
/** Do we want get or set metadata */
|
||||
__u32 op;
|
||||
struct {
|
||||
/** For future use, no flags defined so far */
|
||||
__u64 flags;
|
||||
/** family specific tiling info */
|
||||
__u64 tiling_info;
|
||||
__u32 data_size_bytes;
|
||||
__u32 data[64];
|
||||
} data;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_gem_mmap_in {
|
||||
/** the GEM object handle */
|
||||
__u32 handle;
|
||||
__u32 _pad;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_gem_mmap_out {
|
||||
/** mmap offset from the vma offset manager */
|
||||
__u64 addr_ptr;
|
||||
};
|
||||
|
||||
union drm_amdgpu_gem_mmap {
|
||||
struct drm_amdgpu_gem_mmap_in in;
|
||||
struct drm_amdgpu_gem_mmap_out out;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_gem_wait_idle_in {
|
||||
/** GEM object handle */
|
||||
__u32 handle;
|
||||
/** For future use, no flags defined so far */
|
||||
__u32 flags;
|
||||
/** Absolute timeout to wait */
|
||||
__u64 timeout;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_gem_wait_idle_out {
|
||||
/** BO status: 0 - BO is idle, 1 - BO is busy */
|
||||
__u32 status;
|
||||
/** Returned current memory domain */
|
||||
__u32 domain;
|
||||
};
|
||||
|
||||
union drm_amdgpu_gem_wait_idle {
|
||||
struct drm_amdgpu_gem_wait_idle_in in;
|
||||
struct drm_amdgpu_gem_wait_idle_out out;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_wait_cs_in {
|
||||
/** Command submission handle */
|
||||
__u64 handle;
|
||||
/** Absolute timeout to wait */
|
||||
__u64 timeout;
|
||||
__u32 ip_type;
|
||||
__u32 ip_instance;
|
||||
__u32 ring;
|
||||
__u32 ctx_id;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_wait_cs_out {
|
||||
/** CS status: 0 - CS completed, 1 - CS still busy */
|
||||
__u64 status;
|
||||
};
|
||||
|
||||
union drm_amdgpu_wait_cs {
|
||||
struct drm_amdgpu_wait_cs_in in;
|
||||
struct drm_amdgpu_wait_cs_out out;
|
||||
};
|
||||
|
||||
#define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0
|
||||
#define AMDGPU_GEM_OP_SET_PLACEMENT 1
|
||||
|
||||
/* Sets or returns a value associated with a buffer. */
|
||||
struct drm_amdgpu_gem_op {
|
||||
/** GEM object handle */
|
||||
__u32 handle;
|
||||
/** AMDGPU_GEM_OP_* */
|
||||
__u32 op;
|
||||
/** Input or return value */
|
||||
__u64 value;
|
||||
};
|
||||
|
||||
#define AMDGPU_VA_OP_MAP 1
|
||||
#define AMDGPU_VA_OP_UNMAP 2
|
||||
|
||||
/* Delay the page table update till the next CS */
|
||||
#define AMDGPU_VM_DELAY_UPDATE (1 << 0)
|
||||
|
||||
/* Mapping flags */
|
||||
/* readable mapping */
|
||||
#define AMDGPU_VM_PAGE_READABLE (1 << 1)
|
||||
/* writable mapping */
|
||||
#define AMDGPU_VM_PAGE_WRITEABLE (1 << 2)
|
||||
/* executable mapping, new for VI */
|
||||
#define AMDGPU_VM_PAGE_EXECUTABLE (1 << 3)
|
||||
|
||||
struct drm_amdgpu_gem_va {
|
||||
/** GEM object handle */
|
||||
__u32 handle;
|
||||
__u32 _pad;
|
||||
/** AMDGPU_VA_OP_* */
|
||||
__u32 operation;
|
||||
/** AMDGPU_VM_PAGE_* */
|
||||
__u32 flags;
|
||||
/** va address to assign . Must be correctly aligned.*/
|
||||
__u64 va_address;
|
||||
/** Specify offset inside of BO to assign. Must be correctly aligned.*/
|
||||
__u64 offset_in_bo;
|
||||
/** Specify mapping size. Must be correctly aligned. */
|
||||
__u64 map_size;
|
||||
};
|
||||
|
||||
#define AMDGPU_HW_IP_GFX 0
|
||||
#define AMDGPU_HW_IP_COMPUTE 1
|
||||
#define AMDGPU_HW_IP_DMA 2
|
||||
#define AMDGPU_HW_IP_UVD 3
|
||||
#define AMDGPU_HW_IP_VCE 4
|
||||
#define AMDGPU_HW_IP_NUM 5
|
||||
|
||||
#define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1
|
||||
|
||||
#define AMDGPU_CHUNK_ID_IB 0x01
|
||||
#define AMDGPU_CHUNK_ID_FENCE 0x02
|
||||
#define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03
|
||||
|
||||
struct drm_amdgpu_cs_chunk {
|
||||
__u32 chunk_id;
|
||||
__u32 length_dw;
|
||||
__u64 chunk_data;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_cs_in {
|
||||
/** Rendering context id */
|
||||
__u32 ctx_id;
|
||||
/** Handle of resource list associated with CS */
|
||||
__u32 bo_list_handle;
|
||||
__u32 num_chunks;
|
||||
__u32 _pad;
|
||||
/** this points to __u64 * which point to cs chunks */
|
||||
__u64 chunks;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_cs_out {
|
||||
__u64 handle;
|
||||
};
|
||||
|
||||
union drm_amdgpu_cs {
|
||||
struct drm_amdgpu_cs_in in;
|
||||
struct drm_amdgpu_cs_out out;
|
||||
};
|
||||
|
||||
/* Specify flags to be used for IB */
|
||||
|
||||
/* This IB should be submitted to CE */
|
||||
#define AMDGPU_IB_FLAG_CE (1<<0)
|
||||
|
||||
/* CE Preamble */
|
||||
#define AMDGPU_IB_FLAG_PREAMBLE (1<<1)
|
||||
|
||||
struct drm_amdgpu_cs_chunk_ib {
|
||||
__u32 _pad;
|
||||
/** AMDGPU_IB_FLAG_* */
|
||||
__u32 flags;
|
||||
/** Virtual address to begin IB execution */
|
||||
__u64 va_start;
|
||||
/** Size of submission */
|
||||
__u32 ib_bytes;
|
||||
/** HW IP to submit to */
|
||||
__u32 ip_type;
|
||||
/** HW IP index of the same type to submit to */
|
||||
__u32 ip_instance;
|
||||
/** Ring index to submit to */
|
||||
__u32 ring;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_cs_chunk_dep {
|
||||
__u32 ip_type;
|
||||
__u32 ip_instance;
|
||||
__u32 ring;
|
||||
__u32 ctx_id;
|
||||
__u64 handle;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_cs_chunk_fence {
|
||||
__u32 handle;
|
||||
__u32 offset;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_cs_chunk_data {
|
||||
union {
|
||||
struct drm_amdgpu_cs_chunk_ib ib_data;
|
||||
struct drm_amdgpu_cs_chunk_fence fence_data;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Query h/w info: Flag that this is integrated (a.h.a. fusion) GPU
|
||||
*
|
||||
*/
|
||||
#define AMDGPU_IDS_FLAGS_FUSION 0x1
|
||||
|
||||
/* indicate if acceleration can be working */
|
||||
#define AMDGPU_INFO_ACCEL_WORKING 0x00
|
||||
/* get the crtc_id from the mode object id? */
|
||||
#define AMDGPU_INFO_CRTC_FROM_ID 0x01
|
||||
/* query hw IP info */
|
||||
#define AMDGPU_INFO_HW_IP_INFO 0x02
|
||||
/* query hw IP instance count for the specified type */
|
||||
#define AMDGPU_INFO_HW_IP_COUNT 0x03
|
||||
/* timestamp for GL_ARB_timer_query */
|
||||
#define AMDGPU_INFO_TIMESTAMP 0x05
|
||||
/* Query the firmware version */
|
||||
#define AMDGPU_INFO_FW_VERSION 0x0e
|
||||
/* Subquery id: Query VCE firmware version */
|
||||
#define AMDGPU_INFO_FW_VCE 0x1
|
||||
/* Subquery id: Query UVD firmware version */
|
||||
#define AMDGPU_INFO_FW_UVD 0x2
|
||||
/* Subquery id: Query GMC firmware version */
|
||||
#define AMDGPU_INFO_FW_GMC 0x03
|
||||
/* Subquery id: Query GFX ME firmware version */
|
||||
#define AMDGPU_INFO_FW_GFX_ME 0x04
|
||||
/* Subquery id: Query GFX PFP firmware version */
|
||||
#define AMDGPU_INFO_FW_GFX_PFP 0x05
|
||||
/* Subquery id: Query GFX CE firmware version */
|
||||
#define AMDGPU_INFO_FW_GFX_CE 0x06
|
||||
/* Subquery id: Query GFX RLC firmware version */
|
||||
#define AMDGPU_INFO_FW_GFX_RLC 0x07
|
||||
/* Subquery id: Query GFX MEC firmware version */
|
||||
#define AMDGPU_INFO_FW_GFX_MEC 0x08
|
||||
/* Subquery id: Query SMC firmware version */
|
||||
#define AMDGPU_INFO_FW_SMC 0x0a
|
||||
/* Subquery id: Query SDMA firmware version */
|
||||
#define AMDGPU_INFO_FW_SDMA 0x0b
|
||||
/* number of bytes moved for TTM migration */
|
||||
#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
|
||||
/* the used VRAM size */
|
||||
#define AMDGPU_INFO_VRAM_USAGE 0x10
|
||||
/* the used GTT size */
|
||||
#define AMDGPU_INFO_GTT_USAGE 0x11
|
||||
/* Information about GDS, etc. resource configuration */
|
||||
#define AMDGPU_INFO_GDS_CONFIG 0x13
|
||||
/* Query information about VRAM and GTT domains */
|
||||
#define AMDGPU_INFO_VRAM_GTT 0x14
|
||||
/* Query information about register in MMR address space*/
|
||||
#define AMDGPU_INFO_READ_MMR_REG 0x15
|
||||
/* Query information about device: rev id, family, etc. */
|
||||
#define AMDGPU_INFO_DEV_INFO 0x16
|
||||
/* visible vram usage */
|
||||
#define AMDGPU_INFO_VIS_VRAM_USAGE 0x17
|
||||
/* number of TTM buffer evictions */
|
||||
#define AMDGPU_INFO_NUM_EVICTIONS 0x18
|
||||
|
||||
#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
|
||||
#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
|
||||
#define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8
|
||||
#define AMDGPU_INFO_MMR_SH_INDEX_MASK 0xff
|
||||
|
||||
struct drm_amdgpu_query_fw {
|
||||
/** AMDGPU_INFO_FW_* */
|
||||
__u32 fw_type;
|
||||
/**
|
||||
* Index of the IP if there are more IPs of
|
||||
* the same type.
|
||||
*/
|
||||
__u32 ip_instance;
|
||||
/**
|
||||
* Index of the engine. Whether this is used depends
|
||||
* on the firmware type. (e.g. MEC, SDMA)
|
||||
*/
|
||||
__u32 index;
|
||||
__u32 _pad;
|
||||
};
|
||||
|
||||
/* Input structure for the INFO ioctl */
|
||||
struct drm_amdgpu_info {
|
||||
/* Where the return value will be stored */
|
||||
__u64 return_pointer;
|
||||
/* The size of the return value. Just like "size" in "snprintf",
|
||||
* it limits how many bytes the kernel can write. */
|
||||
__u32 return_size;
|
||||
/* The query request id. */
|
||||
__u32 query;
|
||||
|
||||
union {
|
||||
struct {
|
||||
__u32 id;
|
||||
__u32 _pad;
|
||||
} mode_crtc;
|
||||
|
||||
struct {
|
||||
/** AMDGPU_HW_IP_* */
|
||||
__u32 type;
|
||||
/**
|
||||
* Index of the IP if there are more IPs of the same
|
||||
* type. Ignored by AMDGPU_INFO_HW_IP_COUNT.
|
||||
*/
|
||||
__u32 ip_instance;
|
||||
} query_hw_ip;
|
||||
|
||||
struct {
|
||||
__u32 dword_offset;
|
||||
/** number of registers to read */
|
||||
__u32 count;
|
||||
__u32 instance;
|
||||
/** For future use, no flags defined so far */
|
||||
__u32 flags;
|
||||
} read_mmr_reg;
|
||||
|
||||
struct drm_amdgpu_query_fw query_fw;
|
||||
};
|
||||
};
|
||||
|
||||
struct drm_amdgpu_info_gds {
|
||||
/** GDS GFX partition size */
|
||||
__u32 gds_gfx_partition_size;
|
||||
/** GDS compute partition size */
|
||||
__u32 compute_partition_size;
|
||||
/** total GDS memory size */
|
||||
__u32 gds_total_size;
|
||||
/** GWS size per GFX partition */
|
||||
__u32 gws_per_gfx_partition;
|
||||
/** GSW size per compute partition */
|
||||
__u32 gws_per_compute_partition;
|
||||
/** OA size per GFX partition */
|
||||
__u32 oa_per_gfx_partition;
|
||||
/** OA size per compute partition */
|
||||
__u32 oa_per_compute_partition;
|
||||
__u32 _pad;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_info_vram_gtt {
|
||||
__u64 vram_size;
|
||||
__u64 vram_cpu_accessible_size;
|
||||
__u64 gtt_size;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_info_firmware {
|
||||
__u32 ver;
|
||||
__u32 feature;
|
||||
};
|
||||
|
||||
#define AMDGPU_VRAM_TYPE_UNKNOWN 0
|
||||
#define AMDGPU_VRAM_TYPE_GDDR1 1
|
||||
#define AMDGPU_VRAM_TYPE_DDR2 2
|
||||
#define AMDGPU_VRAM_TYPE_GDDR3 3
|
||||
#define AMDGPU_VRAM_TYPE_GDDR4 4
|
||||
#define AMDGPU_VRAM_TYPE_GDDR5 5
|
||||
#define AMDGPU_VRAM_TYPE_HBM 6
|
||||
#define AMDGPU_VRAM_TYPE_DDR3 7
|
||||
|
||||
struct drm_amdgpu_info_device {
|
||||
/** PCI Device ID */
|
||||
__u32 device_id;
|
||||
/** Internal chip revision: A0, A1, etc.) */
|
||||
__u32 chip_rev;
|
||||
__u32 external_rev;
|
||||
/** Revision id in PCI Config space */
|
||||
__u32 pci_rev;
|
||||
__u32 family;
|
||||
__u32 num_shader_engines;
|
||||
__u32 num_shader_arrays_per_engine;
|
||||
/* in KHz */
|
||||
__u32 gpu_counter_freq;
|
||||
__u64 max_engine_clock;
|
||||
__u64 max_memory_clock;
|
||||
/* cu information */
|
||||
__u32 cu_active_number;
|
||||
__u32 cu_ao_mask;
|
||||
__u32 cu_bitmap[4][4];
|
||||
/** Render backend pipe mask. One render backend is CB+DB. */
|
||||
__u32 enabled_rb_pipes_mask;
|
||||
__u32 num_rb_pipes;
|
||||
__u32 num_hw_gfx_contexts;
|
||||
__u32 _pad;
|
||||
__u64 ids_flags;
|
||||
/** Starting virtual address for UMDs. */
|
||||
__u64 virtual_address_offset;
|
||||
/** The maximum virtual address */
|
||||
__u64 virtual_address_max;
|
||||
/** Required alignment of virtual addresses. */
|
||||
__u32 virtual_address_alignment;
|
||||
/** Page table entry - fragment size */
|
||||
__u32 pte_fragment_size;
|
||||
__u32 gart_page_size;
|
||||
/** constant engine ram size*/
|
||||
__u32 ce_ram_size;
|
||||
/** video memory type info*/
|
||||
__u32 vram_type;
|
||||
/** video memory bit width*/
|
||||
__u32 vram_bit_width;
|
||||
/* vce harvesting instance */
|
||||
__u32 vce_harvest_config;
|
||||
};
|
||||
|
||||
struct drm_amdgpu_info_hw_ip {
|
||||
/** Version of h/w IP */
|
||||
__u32 hw_ip_version_major;
|
||||
__u32 hw_ip_version_minor;
|
||||
/** Capabilities */
|
||||
__u64 capabilities_flags;
|
||||
/** command buffer address start alignment*/
|
||||
__u32 ib_start_alignment;
|
||||
/** command buffer size alignment*/
|
||||
__u32 ib_size_alignment;
|
||||
/** Bitmask of available rings. Bit 0 means ring 0, etc. */
|
||||
__u32 available_rings;
|
||||
__u32 _pad;
|
||||
};
|
||||
|
||||
/*
|
||||
* Supported GPU families
|
||||
*/
|
||||
#define AMDGPU_FAMILY_UNKNOWN 0
|
||||
#define AMDGPU_FAMILY_SI 110 /* Hainan, Oland, Verde, Pitcairn, Tahiti */
|
||||
#define AMDGPU_FAMILY_CI 120 /* Bonaire, Hawaii */
|
||||
#define AMDGPU_FAMILY_KV 125 /* Kaveri, Kabini, Mullins */
|
||||
#define AMDGPU_FAMILY_VI 130 /* Iceland, Tonga */
|
||||
#define AMDGPU_FAMILY_CZ 135 /* Carrizo, Stoney */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005 Stephane Marchesin.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __NOUVEAU_DRM_H__
|
||||
#define __NOUVEAU_DRM_H__
|
||||
|
||||
#define DRM_NOUVEAU_EVENT_NVIF 0x80000000
|
||||
|
||||
#include "drm.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NOUVEAU_GEM_DOMAIN_CPU (1 << 0)
|
||||
#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
|
||||
#define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
|
||||
#define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3)
|
||||
#define NOUVEAU_GEM_DOMAIN_COHERENT (1 << 4)
|
||||
|
||||
#define NOUVEAU_GEM_TILE_COMP 0x00030000 /* nv50-only */
|
||||
#define NOUVEAU_GEM_TILE_LAYOUT_MASK 0x0000ff00
|
||||
#define NOUVEAU_GEM_TILE_16BPP 0x00000001
|
||||
#define NOUVEAU_GEM_TILE_32BPP 0x00000002
|
||||
#define NOUVEAU_GEM_TILE_ZETA 0x00000004
|
||||
#define NOUVEAU_GEM_TILE_NONCONTIG 0x00000008
|
||||
|
||||
struct drm_nouveau_gem_info {
|
||||
__u32 handle;
|
||||
__u32 domain;
|
||||
__u64 size;
|
||||
__u64 offset;
|
||||
__u64 map_handle;
|
||||
__u32 tile_mode;
|
||||
__u32 tile_flags;
|
||||
};
|
||||
|
||||
struct drm_nouveau_gem_new {
|
||||
struct drm_nouveau_gem_info info;
|
||||
__u32 channel_hint;
|
||||
__u32 align;
|
||||
};
|
||||
|
||||
#define NOUVEAU_GEM_MAX_BUFFERS 1024
|
||||
struct drm_nouveau_gem_pushbuf_bo_presumed {
|
||||
__u32 valid;
|
||||
__u32 domain;
|
||||
__u64 offset;
|
||||
};
|
||||
|
||||
struct drm_nouveau_gem_pushbuf_bo {
|
||||
__u64 user_priv;
|
||||
__u32 handle;
|
||||
__u32 read_domains;
|
||||
__u32 write_domains;
|
||||
__u32 valid_domains;
|
||||
struct drm_nouveau_gem_pushbuf_bo_presumed presumed;
|
||||
};
|
||||
|
||||
#define NOUVEAU_GEM_RELOC_LOW (1 << 0)
|
||||
#define NOUVEAU_GEM_RELOC_HIGH (1 << 1)
|
||||
#define NOUVEAU_GEM_RELOC_OR (1 << 2)
|
||||
#define NOUVEAU_GEM_MAX_RELOCS 1024
|
||||
struct drm_nouveau_gem_pushbuf_reloc {
|
||||
__u32 reloc_bo_index;
|
||||
__u32 reloc_bo_offset;
|
||||
__u32 bo_index;
|
||||
__u32 flags;
|
||||
__u32 data;
|
||||
__u32 vor;
|
||||
__u32 tor;
|
||||
};
|
||||
|
||||
#define NOUVEAU_GEM_MAX_PUSH 512
|
||||
struct drm_nouveau_gem_pushbuf_push {
|
||||
__u32 bo_index;
|
||||
__u32 pad;
|
||||
__u64 offset;
|
||||
__u64 length;
|
||||
};
|
||||
|
||||
struct drm_nouveau_gem_pushbuf {
|
||||
__u32 channel;
|
||||
__u32 nr_buffers;
|
||||
__u64 buffers;
|
||||
__u32 nr_relocs;
|
||||
__u32 nr_push;
|
||||
__u64 relocs;
|
||||
__u64 push;
|
||||
__u32 suffix0;
|
||||
__u32 suffix1;
|
||||
__u64 vram_available;
|
||||
__u64 gart_available;
|
||||
};
|
||||
|
||||
#define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001
|
||||
#define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004
|
||||
struct drm_nouveau_gem_cpu_prep {
|
||||
__u32 handle;
|
||||
__u32 flags;
|
||||
};
|
||||
|
||||
struct drm_nouveau_gem_cpu_fini {
|
||||
__u32 handle;
|
||||
};
|
||||
|
||||
#define DRM_NOUVEAU_GETPARAM 0x00 /* deprecated */
|
||||
#define DRM_NOUVEAU_SETPARAM 0x01 /* deprecated */
|
||||
#define DRM_NOUVEAU_CHANNEL_ALLOC 0x02 /* deprecated */
|
||||
#define DRM_NOUVEAU_CHANNEL_FREE 0x03 /* deprecated */
|
||||
#define DRM_NOUVEAU_GROBJ_ALLOC 0x04 /* deprecated */
|
||||
#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x05 /* deprecated */
|
||||
#define DRM_NOUVEAU_GPUOBJ_FREE 0x06 /* deprecated */
|
||||
#define DRM_NOUVEAU_NVIF 0x07
|
||||
#define DRM_NOUVEAU_GEM_NEW 0x40
|
||||
#define DRM_NOUVEAU_GEM_PUSHBUF 0x41
|
||||
#define DRM_NOUVEAU_GEM_CPU_PREP 0x42
|
||||
#define DRM_NOUVEAU_GEM_CPU_FINI 0x43
|
||||
#define DRM_NOUVEAU_GEM_INFO 0x44
|
||||
|
||||
#define DRM_IOCTL_NOUVEAU_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new)
|
||||
#define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf)
|
||||
#define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep)
|
||||
#define DRM_IOCTL_NOUVEAU_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_FINI, struct drm_nouveau_gem_cpu_fini)
|
||||
#define DRM_IOCTL_NOUVEAU_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_INFO, struct drm_nouveau_gem_info)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NOUVEAU_DRM_H__ */
|
||||
@@ -139,6 +139,7 @@ import core,\
|
||||
RegKeyboard,\
|
||||
DelKeyboard,\
|
||||
Sleep,\
|
||||
Delay,\
|
||||
GetTimerTicks,\
|
||||
\
|
||||
strncat,\
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Francisco Jerez.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <drm/drm_encoder_slave.h>
|
||||
|
||||
/**
|
||||
* drm_i2c_encoder_init - Initialize an I2C slave encoder
|
||||
* @dev: DRM device.
|
||||
* @encoder: Encoder to be attached to the I2C device. You aren't
|
||||
* required to have called drm_encoder_init() before.
|
||||
* @adap: I2C adapter that will be used to communicate with
|
||||
* the device.
|
||||
* @info: Information that will be used to create the I2C device.
|
||||
* Required fields are @addr and @type.
|
||||
*
|
||||
* Create an I2C device on the specified bus (the module containing its
|
||||
* driver is transparently loaded) and attach it to the specified
|
||||
* &drm_encoder_slave. The @slave_funcs field will be initialized with
|
||||
* the hooks provided by the slave driver.
|
||||
*
|
||||
* If @info->platform_data is non-NULL it will be used as the initial
|
||||
* slave config.
|
||||
*
|
||||
* Returns 0 on success or a negative errno on failure, in particular,
|
||||
* -ENODEV is returned when no matching driver is found.
|
||||
*/
|
||||
int drm_i2c_encoder_init(struct drm_device *dev,
|
||||
struct drm_encoder_slave *encoder,
|
||||
struct i2c_adapter *adap,
|
||||
const struct i2c_board_info *info)
|
||||
{
|
||||
struct module *module = NULL;
|
||||
struct i2c_client *client;
|
||||
struct drm_i2c_encoder_driver *encoder_drv;
|
||||
int err = 0;
|
||||
|
||||
request_module("%s%s", I2C_MODULE_PREFIX, info->type);
|
||||
|
||||
client = i2c_new_device(adap, info);
|
||||
if (!client) {
|
||||
err = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!client->dev.driver) {
|
||||
err = -ENODEV;
|
||||
goto fail_unregister;
|
||||
}
|
||||
|
||||
module = client->dev.driver->owner;
|
||||
if (!try_module_get(module)) {
|
||||
err = -ENODEV;
|
||||
goto fail_unregister;
|
||||
}
|
||||
|
||||
encoder->bus_priv = client;
|
||||
|
||||
encoder_drv = to_drm_i2c_encoder_driver(to_i2c_driver(client->dev.driver));
|
||||
|
||||
err = encoder_drv->encoder_init(client, dev, encoder);
|
||||
if (err)
|
||||
goto fail_module_put;
|
||||
|
||||
if (info->platform_data)
|
||||
encoder->slave_funcs->set_config(&encoder->base,
|
||||
info->platform_data);
|
||||
|
||||
return 0;
|
||||
|
||||
fail_module_put:
|
||||
module_put(module);
|
||||
fail_unregister:
|
||||
i2c_unregister_device(client);
|
||||
fail:
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_i2c_encoder_init);
|
||||
|
||||
/**
|
||||
* drm_i2c_encoder_destroy - Unregister the I2C device backing an encoder
|
||||
* @drm_encoder: Encoder to be unregistered.
|
||||
*
|
||||
* This should be called from the @destroy method of an I2C slave
|
||||
* encoder driver once I2C access is no longer needed.
|
||||
*/
|
||||
void drm_i2c_encoder_destroy(struct drm_encoder *drm_encoder)
|
||||
{
|
||||
struct drm_encoder_slave *encoder = to_encoder_slave(drm_encoder);
|
||||
struct i2c_client *client = drm_i2c_encoder_get_client(drm_encoder);
|
||||
struct module *module = client->dev.driver->owner;
|
||||
|
||||
i2c_unregister_device(client);
|
||||
encoder->bus_priv = NULL;
|
||||
|
||||
module_put(module);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_i2c_encoder_destroy);
|
||||
|
||||
/*
|
||||
* Wrapper fxns which can be plugged in to drm_encoder_helper_funcs:
|
||||
*/
|
||||
|
||||
static inline const struct drm_encoder_slave_funcs *
|
||||
get_slave_funcs(struct drm_encoder *enc)
|
||||
{
|
||||
return to_encoder_slave(enc)->slave_funcs;
|
||||
}
|
||||
|
||||
void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
get_slave_funcs(encoder)->dpms(encoder, mode);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_i2c_encoder_dpms);
|
||||
|
||||
bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
if (!get_slave_funcs(encoder)->mode_fixup)
|
||||
return true;
|
||||
|
||||
return get_slave_funcs(encoder)->mode_fixup(encoder, mode, adjusted_mode);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_i2c_encoder_mode_fixup);
|
||||
|
||||
void drm_i2c_encoder_prepare(struct drm_encoder *encoder)
|
||||
{
|
||||
drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_i2c_encoder_prepare);
|
||||
|
||||
void drm_i2c_encoder_commit(struct drm_encoder *encoder)
|
||||
{
|
||||
drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_i2c_encoder_commit);
|
||||
|
||||
void drm_i2c_encoder_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
get_slave_funcs(encoder)->mode_set(encoder, mode, adjusted_mode);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_i2c_encoder_mode_set);
|
||||
|
||||
enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
return get_slave_funcs(encoder)->detect(encoder, connector);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_i2c_encoder_detect);
|
||||
|
||||
void drm_i2c_encoder_save(struct drm_encoder *encoder)
|
||||
{
|
||||
get_slave_funcs(encoder)->save(encoder);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_i2c_encoder_save);
|
||||
|
||||
void drm_i2c_encoder_restore(struct drm_encoder *encoder)
|
||||
{
|
||||
get_slave_funcs(encoder)->restore(encoder);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_i2c_encoder_restore);
|
||||
+970
-105
File diff suppressed because it is too large.
Load diff
@@ -842,8 +842,7 @@ disk_scan_partitions:
|
||||
cmp ebx, mbr_buffer
|
||||
jz .release_partition_buffer
|
||||
; 15b. If we have allocated it, free it.
|
||||
xchg eax, ebx
|
||||
call free
|
||||
stdcall kernel_free, ebx
|
||||
jmp .nothing
|
||||
; 15c. Otherwise, release reference.
|
||||
.release_partition_buffer:
|
||||
|
||||
@@ -183,6 +183,8 @@ EFLAGS_ID = 0x200000 ; id flag
|
||||
IRQ_PIC = 0
|
||||
IRQ_APIC = 1
|
||||
|
||||
IO_MAP_SIZE = 65536/8 ; 8192 or 2 PAGE_SIZE
|
||||
|
||||
struct TSS
|
||||
_back rw 2
|
||||
_esp0 rd 1
|
||||
@@ -290,6 +292,9 @@ sys_proc = OS_BASE + 0x008E000
|
||||
|
||||
SLOT_BASE = OS_BASE + 0x0090000
|
||||
|
||||
APPDATA_IDLE_THREAD = SLOT_BASE + sizeof.APPDATA*1 ; poiner to IDLE thread
|
||||
APPDATA_OS_THREAD = SLOT_BASE + sizeof.APPDATA*2 ; poiner to OS thread
|
||||
|
||||
VGABasePtr = OS_BASE + 0x00A0000
|
||||
|
||||
virtual at OS_BASE + 0x05FFF80
|
||||
@@ -570,7 +575,7 @@ struct APPDATA
|
||||
ipc_start dd ? ;+160
|
||||
ipc_size dd ? ;+164
|
||||
occurred_events dd ? ;+168 ; mask which accumulates occurred events
|
||||
debugger_slot dd ? ;+172 ; index in SLOT_BASE array
|
||||
debugger_thread dd ? ;+172 ; pointer to APPDATA or 0
|
||||
terminate_protection dd ? ;+176
|
||||
keyboard_mode db ? ;+180
|
||||
rb 3
|
||||
|
||||
+41
-77
@@ -8,8 +8,8 @@
|
||||
|
||||
; diamond, 2006
|
||||
sys_debug_services:
|
||||
cmp ebx, 9
|
||||
ja @f
|
||||
cmp ebx, sys_debug_services_table.count
|
||||
jae @f
|
||||
jmp dword [sys_debug_services_table + ebx*4]
|
||||
@@:
|
||||
ret
|
||||
@@ -26,7 +26,9 @@ sys_debug_services_table:
|
||||
dd debug_write_process_memory
|
||||
dd debug_terminate
|
||||
dd debug_set_drx
|
||||
.count = ($ - sys_debug_services_table)/4
|
||||
endg
|
||||
|
||||
debug_set_event_data:
|
||||
; in: ecx = pointer
|
||||
; destroys eax
|
||||
@@ -34,22 +36,20 @@ debug_set_event_data:
|
||||
mov [eax + APPDATA.dbg_event_mem], ecx
|
||||
ret
|
||||
|
||||
get_debuggee_slot:
|
||||
get_debuggee_thread:
|
||||
; in: ecx=PID
|
||||
; out: CF=1 if error
|
||||
; CF=0 and eax=slot*0x20 if ok
|
||||
; CF=0 and eax = pointer to APPDATA if ok
|
||||
; out: interrupts disabled
|
||||
cli
|
||||
mov eax, ecx
|
||||
call pid_to_slot
|
||||
;call pid_to_appdata
|
||||
call pid_to_thread
|
||||
test eax, eax
|
||||
jz .ret_bad
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
|
||||
push ebx
|
||||
mov ebx, [current_slot_idx]
|
||||
cmp [SLOT_BASE + eax + APPDATA.debugger_slot], ebx
|
||||
;cmp [eax + APPDATA.debugger_slot], ebx
|
||||
mov ebx, [current_slot]
|
||||
cmp [eax + APPDATA.debugger_thread], ebx
|
||||
pop ebx
|
||||
jnz .ret_bad
|
||||
; clc ; automatically
|
||||
@@ -61,10 +61,9 @@ get_debuggee_slot:
|
||||
debug_detach:
|
||||
; in: ecx=pid
|
||||
; destroys eax,ebx
|
||||
call get_debuggee_slot
|
||||
call get_debuggee_thread
|
||||
jc .ret
|
||||
and dword [eax + SLOT_BASE + APPDATA.debugger_slot], 0
|
||||
;and dword [eax + APPDATA.debugger_slot], 0
|
||||
and dword [eax + APPDATA.debugger_thread], 0
|
||||
call do_resume
|
||||
.ret:
|
||||
sti
|
||||
@@ -72,40 +71,27 @@ debug_detach:
|
||||
|
||||
debug_terminate:
|
||||
; in: ecx=pid
|
||||
call get_debuggee_slot
|
||||
call get_debuggee_thread
|
||||
jc debug_detach.ret
|
||||
mov ecx, eax
|
||||
|
||||
shr ecx, BSF sizeof.APPDATA
|
||||
;movzx ecx, ch ; del when sysfn_term... will using APPDATA
|
||||
|
||||
; push 2
|
||||
; pop ebx
|
||||
mov edx, esi ; what?
|
||||
movzx ecx, ch ; del when sysfn_term... will using APPDATA
|
||||
jmp sysfn_terminate
|
||||
|
||||
debug_suspend:
|
||||
; in: ecx=pid
|
||||
; destroys eax,ecx
|
||||
; { Patch by Coldy (rev. 7125), reason: http://board.kolibrios.org/viewtopic.php?f=1&t=1712&p=75957#p75957
|
||||
; cli
|
||||
; mov eax, ecx
|
||||
; call pid_to_slot
|
||||
; shl eax, 5
|
||||
; jz .ret
|
||||
call get_debuggee_slot
|
||||
call get_debuggee_thread
|
||||
jc .ret
|
||||
; } End patch
|
||||
mov cl, [SLOT_BASE + eax + APPDATA.state] ; process state
|
||||
;mov cl, [eax + APPDATA.state] ; process state
|
||||
|
||||
mov cl, [eax + APPDATA.state] ; process state
|
||||
test cl, cl
|
||||
jz .1
|
||||
cmp cl, TSTATE_WAITING
|
||||
jnz .ret
|
||||
mov cl, TSTATE_WAIT_SUSPENDED
|
||||
.2:
|
||||
mov [SLOT_BASE + eax + APPDATA.state], cl
|
||||
;mov [eax + APPDATA.state], cl
|
||||
mov [eax + APPDATA.state], cl
|
||||
.ret:
|
||||
sti
|
||||
ret
|
||||
@@ -114,16 +100,14 @@ debug_suspend:
|
||||
jmp .2
|
||||
|
||||
do_resume:
|
||||
mov cl, [SLOT_BASE + eax + APPDATA.state]
|
||||
;mov cl, [eax + APPDATA.state]
|
||||
mov cl, [eax + APPDATA.state]
|
||||
cmp cl, TSTATE_RUN_SUSPENDED
|
||||
jz .1
|
||||
cmp cl, TSTATE_WAIT_SUSPENDED
|
||||
jnz .ret
|
||||
mov cl, TSTATE_WAITING
|
||||
.2:
|
||||
mov [SLOT_BASE + eax + APPDATA.state], cl
|
||||
;mov [eax + APPDATA.state], cl
|
||||
mov [eax + APPDATA.state], cl
|
||||
.ret:
|
||||
ret
|
||||
.1:
|
||||
@@ -133,11 +117,9 @@ do_resume:
|
||||
debug_resume:
|
||||
; in: ecx=pid
|
||||
; destroys eax,ebx
|
||||
cli
|
||||
mov eax, ecx
|
||||
call pid_to_slot
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
jz .ret
|
||||
call get_debuggee_thread
|
||||
jc .ret
|
||||
|
||||
call do_resume
|
||||
.ret:
|
||||
sti
|
||||
@@ -160,21 +142,15 @@ debug_getcontext:
|
||||
inc ebx ; 1 - get sse context
|
||||
; TODO legacy 32-bit FPU/MMX context
|
||||
.std_ctx:
|
||||
call get_debuggee_slot
|
||||
call get_debuggee_thread
|
||||
jc .ret
|
||||
|
||||
shr eax, BSF sizeof.APPDATA
|
||||
;movzx ebp, ah
|
||||
|
||||
cmp eax, [fpu_owner]
|
||||
;cmp ebp, [fpu_owner]
|
||||
jne @f
|
||||
inc bh ; set swap context flag
|
||||
@@:
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov edi, esi
|
||||
mov eax, [SLOT_BASE + eax + APPDATA.pl0_stack]
|
||||
;mov eax, [eax + APPDATA.pl0_stack]
|
||||
mov eax, [eax + APPDATA.pl0_stack]
|
||||
lea esi, [eax + RING0_STACK_SIZE]
|
||||
|
||||
.ring0:
|
||||
@@ -240,11 +216,10 @@ debug_setcontext:
|
||||
cmp edx, 28h
|
||||
jnz .ret
|
||||
|
||||
call get_debuggee_slot
|
||||
call get_debuggee_thread
|
||||
jc .stiret
|
||||
; mov esi, edx
|
||||
mov eax, [eax + SLOT_BASE+APPDATA.pl0_stack]
|
||||
;mov eax, [eax + APPDATA.pl0_stack]
|
||||
|
||||
mov eax, [eax + APPDATA.pl0_stack]
|
||||
lea edi, [eax + RING0_STACK_SIZE]
|
||||
|
||||
.ring0:
|
||||
@@ -277,15 +252,16 @@ debug_setcontext:
|
||||
ret
|
||||
|
||||
debug_set_drx:
|
||||
call get_debuggee_slot
|
||||
call get_debuggee_thread
|
||||
jc .errret
|
||||
|
||||
mov ebp, eax
|
||||
lea eax, [eax + SLOT_BASE + APPDATA.dbg_regs]
|
||||
;lea eax, [eax + APPDATA.dbg_regs]
|
||||
lea eax, [eax + APPDATA.dbg_regs]
|
||||
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
|
||||
; [eax+10]=dr7
|
||||
cmp esi, OS_BASE
|
||||
jae .errret
|
||||
|
||||
cmp dl, 3
|
||||
ja .errret
|
||||
mov ecx, dr7
|
||||
@@ -306,10 +282,7 @@ debug_set_drx:
|
||||
btr dword [eax + 10h], edx ; clear L<i> bit
|
||||
test byte [eax + 10h], 55h
|
||||
jnz .okret
|
||||
; imul eax, ebp, tss_step/32
|
||||
; and byte [eax + tss_data + TSS._trap], not 1
|
||||
and [SLOT_BASE + ebp + APPDATA.dbg_state], not 1
|
||||
;and [ebp + APPDATA.dbg_state], not 1
|
||||
and [ebp + APPDATA.dbg_state], not 1
|
||||
.okret:
|
||||
and dword [esp + SYSCALL_STACK.eax], 0
|
||||
sti
|
||||
@@ -354,10 +327,7 @@ debug_set_drx:
|
||||
not ebx
|
||||
and [eax + 10h+2], bx
|
||||
or [eax + 10h+2], dx ; set R/W and LEN fields
|
||||
; imul eax, ebp, tss_step/32
|
||||
; or byte [eax + tss_data + TSS._trap], 1
|
||||
or [SLOT_BASE + ebp + APPDATA.dbg_state], 1
|
||||
;or [ebp + APPDATA.dbg_state], 1
|
||||
or [ebp + APPDATA.dbg_state], 1
|
||||
jmp .okret
|
||||
|
||||
debug_read_process_memory:
|
||||
@@ -368,10 +338,9 @@ debug_read_process_memory:
|
||||
; esi=address in debuggee
|
||||
; out: [esp+36]=sizeof(read)
|
||||
; destroys all
|
||||
call get_debuggee_slot
|
||||
call get_debuggee_thread
|
||||
jc .err
|
||||
shr eax, BSF sizeof.APPDATA
|
||||
;movzx eax,ah
|
||||
|
||||
mov ecx, edi
|
||||
call read_process_memory
|
||||
sti
|
||||
@@ -389,10 +358,9 @@ debug_write_process_memory:
|
||||
; esi=address in debuggee
|
||||
; out: [esp+36]=sizeof(write)
|
||||
; destroys all
|
||||
call get_debuggee_slot
|
||||
call get_debuggee_thread
|
||||
jc debug_read_process_memory.err
|
||||
shr eax, BSF sizeof.APPDATA
|
||||
;movzx eax,ah
|
||||
|
||||
mov ecx, edi
|
||||
call write_process_memory
|
||||
sti
|
||||
@@ -400,7 +368,7 @@ debug_write_process_memory:
|
||||
ret
|
||||
|
||||
debugger_notify:
|
||||
; in: eax=debugger slot
|
||||
; in: eax=debugger thread
|
||||
; ecx=size of debug message
|
||||
; [esp+4]..[esp+4+ecx]=message
|
||||
; interrupts must be disabled!
|
||||
@@ -410,9 +378,7 @@ debugger_notify:
|
||||
mov edi, [timer_ticks]
|
||||
add edi, 500 ; 5 sec timeout
|
||||
.1:
|
||||
mov eax, ebp
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov esi, [SLOT_BASE + eax + APPDATA.dbg_event_mem]
|
||||
mov esi, [ebp + APPDATA.dbg_event_mem]
|
||||
test esi, esi
|
||||
jz .ret
|
||||
; read buffer header
|
||||
@@ -466,8 +432,6 @@ debugger_notify:
|
||||
pop edx
|
||||
call write_process_memory
|
||||
; new debug event
|
||||
mov eax, ebp
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
or [SLOT_BASE + eax + APPDATA.occurred_events], EVENT_DEBUG
|
||||
or [ebp + APPDATA.occurred_events], EVENT_DEBUG
|
||||
.ret:
|
||||
ret
|
||||
+49
-37
@@ -150,10 +150,10 @@ init_avx512:
|
||||
|
||||
ret
|
||||
|
||||
; param
|
||||
; eax= 512 bytes memory area aligned on a 16-byte boundary
|
||||
|
||||
align 4
|
||||
; @brief Export function - Save FPU context in buffer
|
||||
; @param eax - 512 bytes memory area aligned on a 16-byte boundary
|
||||
; @return not return
|
||||
fpu_save:
|
||||
push ecx
|
||||
push esi
|
||||
@@ -166,7 +166,7 @@ fpu_save:
|
||||
mov edi, eax
|
||||
|
||||
mov ecx, [fpu_owner]
|
||||
mov esi, [current_slot_idx]
|
||||
mov esi, [current_slot]
|
||||
cmp ecx, esi
|
||||
jne .save
|
||||
|
||||
@@ -175,14 +175,11 @@ fpu_save:
|
||||
.save:
|
||||
mov [fpu_owner], esi
|
||||
|
||||
shl ecx, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + ecx + APPDATA.fpu_state]
|
||||
|
||||
mov eax, [ecx + APPDATA.fpu_state]
|
||||
call save_context
|
||||
|
||||
; first 512 bytes of XSAVE area have the same format as FXSAVE
|
||||
shl esi, BSF sizeof.APPDATA
|
||||
mov esi, [SLOT_BASE + esi + APPDATA.fpu_state]
|
||||
mov esi, [esi + APPDATA.fpu_state]
|
||||
mov ecx, 512/4
|
||||
cld
|
||||
rep movsd
|
||||
@@ -194,14 +191,16 @@ fpu_save:
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
; @brief Export function - Get size from AVX context
|
||||
; @return size of buffer
|
||||
avx_save_size:
|
||||
mov eax, [xsave_area_size]
|
||||
ret
|
||||
|
||||
; param
|
||||
; eax= avx_save_size() bytes memory area aligned on a 64-byte boundary
|
||||
|
||||
align 4
|
||||
; @brief Export function - Save AVX context in buffer
|
||||
; @param eax - avx_save_size() bytes memory area aligned on a 64-byte boundary
|
||||
; @return not return
|
||||
avx_save:
|
||||
push ecx
|
||||
push esi
|
||||
@@ -214,7 +213,7 @@ avx_save:
|
||||
mov edi, eax
|
||||
|
||||
mov ecx, [fpu_owner]
|
||||
mov esi, [current_slot_idx]
|
||||
mov esi, [current_slot]
|
||||
cmp ecx, esi
|
||||
jne .save
|
||||
|
||||
@@ -223,13 +222,10 @@ avx_save:
|
||||
.save:
|
||||
mov [fpu_owner], esi
|
||||
|
||||
shl ecx, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + ecx + APPDATA.fpu_state]
|
||||
|
||||
mov eax, [ecx + APPDATA.fpu_state]
|
||||
call save_context
|
||||
|
||||
shl esi, BSF sizeof.APPDATA
|
||||
mov esi, [SLOT_BASE + esi + APPDATA.fpu_state]
|
||||
mov esi, [esi + APPDATA.fpu_state]
|
||||
mov ecx, [xsave_area_size]
|
||||
add ecx, 3
|
||||
shr ecx, 2
|
||||
@@ -264,9 +260,13 @@ save_fpu_context:
|
||||
|
||||
|
||||
align 4
|
||||
; @brief Export function - Restore FPU context
|
||||
; @param eax - 512 bytes memory area aligned on a 16-byte boundary
|
||||
; @return not return
|
||||
fpu_restore:
|
||||
push ecx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, eax
|
||||
|
||||
@@ -274,7 +274,7 @@ fpu_restore:
|
||||
cli
|
||||
|
||||
mov ecx, [fpu_owner]
|
||||
mov eax, [current_slot_idx]
|
||||
mov eax, [current_slot]
|
||||
cmp ecx, eax
|
||||
jne .copy
|
||||
|
||||
@@ -284,6 +284,8 @@ fpu_restore:
|
||||
|
||||
fxrstor [esi]
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
@@ -291,24 +293,31 @@ fpu_restore:
|
||||
fnclex ;fix possible problems
|
||||
frstor [esi]
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
.copy:
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov edi, [SLOT_BASE + eax + APPDATA.fpu_state]
|
||||
mov edi, [eax + APPDATA.fpu_state]
|
||||
mov ecx, 512/4
|
||||
cld
|
||||
rep movsd
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
align 4
|
||||
; @brief Export function - Restore AVX context
|
||||
; @param eax - avx_save_size() bytes memory area aligned on a 64-byte boundary
|
||||
; @return not return
|
||||
avx_restore:
|
||||
push ecx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, eax
|
||||
|
||||
@@ -316,7 +325,7 @@ avx_restore:
|
||||
cli
|
||||
|
||||
mov ecx, [fpu_owner]
|
||||
mov eax, [current_slot_idx]
|
||||
mov eax, [current_slot]
|
||||
cmp ecx, eax
|
||||
jne .copy
|
||||
|
||||
@@ -329,6 +338,8 @@ avx_restore:
|
||||
xrstor [esi]
|
||||
pop edx
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
@@ -338,6 +349,8 @@ avx_restore:
|
||||
|
||||
fxrstor [esi]
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
@@ -345,18 +358,21 @@ avx_restore:
|
||||
fnclex ;fix possible problems
|
||||
frstor [esi]
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
.copy:
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov edi, [SLOT_BASE + eax + APPDATA.fpu_state]
|
||||
mov edi, [eax + APPDATA.fpu_state]
|
||||
mov ecx, [xsave_area_size]
|
||||
add ecx, 3
|
||||
shr ecx, 2
|
||||
cld
|
||||
rep movsd
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
@@ -370,21 +386,19 @@ except_7: ;#NM exception handler
|
||||
mov es, ax
|
||||
|
||||
mov ebx, [fpu_owner]
|
||||
cmp ebx, [current_slot_idx]
|
||||
cmp ebx, [current_slot]
|
||||
je .exit
|
||||
|
||||
shl ebx, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + ebx + APPDATA.fpu_state]
|
||||
mov eax, [ebx + APPDATA.fpu_state]
|
||||
bt [cpu_caps + (CAPS_OSXSAVE/32)*4], CAPS_OSXSAVE mod 32
|
||||
jnc .no_xsave
|
||||
mov ecx, eax
|
||||
mov eax, [xsave_eax]
|
||||
mov edx, [xsave_edx]
|
||||
xsave [ecx]
|
||||
mov ebx, [current_slot_idx]
|
||||
mov ebx, [current_slot]
|
||||
mov [fpu_owner], ebx
|
||||
shl ebx, BSF sizeof.APPDATA
|
||||
mov ecx, [SLOT_BASE + ebx + APPDATA.fpu_state]
|
||||
mov ecx, [ebx + APPDATA.fpu_state]
|
||||
xrstor [ecx]
|
||||
.exit:
|
||||
restore_ring3_context
|
||||
@@ -394,24 +408,22 @@ except_7: ;#NM exception handler
|
||||
jnc .no_SSE
|
||||
|
||||
fxsave [eax]
|
||||
mov ebx, [current_slot_idx]
|
||||
mov ebx, [current_slot]
|
||||
mov [fpu_owner], ebx
|
||||
shl ebx, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + ebx + APPDATA.fpu_state]
|
||||
mov eax, [ebx + APPDATA.fpu_state]
|
||||
fxrstor [eax]
|
||||
restore_ring3_context
|
||||
iret
|
||||
|
||||
.no_SSE:
|
||||
fnsave [eax]
|
||||
mov ebx, [current_slot_idx]
|
||||
mov ebx, [current_slot]
|
||||
mov [fpu_owner], ebx
|
||||
shl ebx, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + ebx + APPDATA.fpu_state]
|
||||
mov eax, [ebx + APPDATA.fpu_state]
|
||||
frstor [eax]
|
||||
restore_ring3_context
|
||||
iret
|
||||
|
||||
iglobal
|
||||
fpu_owner dd 2
|
||||
fpu_owner dd APPDATA_OS_THREAD
|
||||
endg
|
||||
@@ -605,7 +605,7 @@ proc page_fault_handler
|
||||
|
||||
mov edi, [.err_addr]
|
||||
and edi, -PAGE_SIZE
|
||||
mov ecx, 1024
|
||||
mov ecx, PAGE_SIZE/4
|
||||
xor eax, eax
|
||||
;cld ;caller is duty for this
|
||||
rep stosd
|
||||
@@ -664,7 +664,7 @@ proc page_fault_handler
|
||||
cmp ebx, tss._io_map_0
|
||||
jb .fail
|
||||
|
||||
cmp ebx, tss._io_map_0+8192
|
||||
cmp ebx, tss._io_map_0 + IO_MAP_SIZE
|
||||
jae .fail
|
||||
|
||||
; io permission map
|
||||
@@ -695,7 +695,7 @@ proc page_fault_handler
|
||||
endp
|
||||
|
||||
; returns number of mapped bytes
|
||||
proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
|
||||
proc map_mem_ipc stdcall, lin_addr:dword,thread:dword,\
|
||||
ofs:dword,buf_size:dword,req_access:dword
|
||||
locals
|
||||
count dd ?
|
||||
@@ -706,9 +706,8 @@ proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
|
||||
cmp [buf_size], 0
|
||||
jz .exit
|
||||
|
||||
mov eax, [slot]
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + eax + APPDATA.process]
|
||||
mov eax, [thread]
|
||||
mov eax, [eax + APPDATA.process]
|
||||
test eax, eax
|
||||
jz .exit
|
||||
|
||||
@@ -732,7 +731,7 @@ proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
|
||||
shr edx, 12
|
||||
and edx, 0x3FF
|
||||
.map:
|
||||
stdcall safe_map_page, [slot], [req_access], [ofs]
|
||||
stdcall safe_map_page, [process], [req_access], [ofs]
|
||||
jnc .exit
|
||||
add [count], PAGE_SIZE
|
||||
add [ofs], PAGE_SIZE
|
||||
@@ -758,7 +757,7 @@ proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
|
||||
ret
|
||||
endp
|
||||
|
||||
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
|
||||
proc map_memEx stdcall, lin_addr:dword,thread:dword,\
|
||||
ofs:dword,buf_size:dword,req_access:dword
|
||||
locals
|
||||
count dd ?
|
||||
@@ -769,9 +768,8 @@ proc map_memEx stdcall, lin_addr:dword,slot:dword,\
|
||||
cmp [buf_size], 0
|
||||
jz .exit
|
||||
|
||||
mov eax, [slot]
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + eax + APPDATA.process]
|
||||
mov eax, [thread]
|
||||
mov eax, [eax + APPDATA.process]
|
||||
test eax, eax
|
||||
jz .exit
|
||||
|
||||
@@ -795,7 +793,7 @@ proc map_memEx stdcall, lin_addr:dword,slot:dword,\
|
||||
shr edx, 12
|
||||
and edx, 0x3FF
|
||||
.map:
|
||||
stdcall safe_map_page, [slot], [req_access], [ofs]
|
||||
stdcall safe_map_page, [process], [req_access], [ofs]
|
||||
jnc .exit
|
||||
add [count], PAGE_SIZE
|
||||
add [ofs], PAGE_SIZE
|
||||
@@ -826,7 +824,7 @@ endp
|
||||
; in: edi = linear address to map
|
||||
; out: CF cleared <=> failed
|
||||
; destroys: only eax
|
||||
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
|
||||
proc safe_map_page stdcall, process:dword, req_access:dword, ofs:dword
|
||||
mov eax, [esi + edx*4]
|
||||
test al, PG_READ
|
||||
jz .not_present
|
||||
@@ -861,9 +859,7 @@ proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
|
||||
cli
|
||||
cld
|
||||
push ebx ecx
|
||||
mov eax, [slot]
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + eax + APPDATA.process]
|
||||
mov eax, [process]
|
||||
mov eax, [eax + PROC.dlls_list_ptr]
|
||||
test eax, eax
|
||||
jz .no_hdll
|
||||
@@ -953,7 +949,7 @@ sys_IPC:
|
||||
|
||||
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
||||
locals
|
||||
dst_slot dd ?
|
||||
dst_thread dd ?
|
||||
dst_offset dd ?
|
||||
buf_size dd ?
|
||||
used_buf dd ?
|
||||
@@ -963,13 +959,12 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
||||
cli
|
||||
|
||||
mov eax, [PID]
|
||||
call pid_to_slot
|
||||
call pid_to_thread
|
||||
test eax, eax
|
||||
jz .no_pid
|
||||
|
||||
mov [dst_slot], eax
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
mov edi, [SLOT_BASE + eax + APPDATA.ipc_start] ;is ipc area defined?
|
||||
mov [dst_thread], eax
|
||||
mov edi, [eax + APPDATA.ipc_start] ;is ipc area defined?
|
||||
test edi, edi
|
||||
jz .no_ipc_area
|
||||
|
||||
@@ -977,7 +972,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
||||
and ebx, 0xFFF
|
||||
mov [dst_offset], ebx
|
||||
|
||||
mov esi, [SLOT_BASE + eax + APPDATA.ipc_size]
|
||||
mov esi, [eax + APPDATA.ipc_size]
|
||||
mov [buf_size], esi
|
||||
|
||||
mov ecx, [ipc_tmp]
|
||||
@@ -990,7 +985,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
||||
pop edi esi
|
||||
@@:
|
||||
mov [used_buf], ecx
|
||||
stdcall map_mem_ipc, ecx, [dst_slot], \
|
||||
stdcall map_mem_ipc, ecx, [dst_thread], \
|
||||
edi, esi, PG_SWR
|
||||
|
||||
mov edi, [dst_offset]
|
||||
@@ -1039,9 +1034,8 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
||||
mov [page_tabs + ebx*4], eax
|
||||
invlpg [edx]
|
||||
|
||||
mov eax, [dst_slot]
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
or [SLOT_BASE + eax + APPDATA.occurred_events], EVENT_IPC
|
||||
mov eax, [dst_thread]
|
||||
or [eax + APPDATA.occurred_events], EVENT_IPC
|
||||
push 0
|
||||
jmp .ret
|
||||
.no_pid:
|
||||
|
||||
@@ -139,14 +139,13 @@ do_change_task:
|
||||
mov eax, [xsave_eax]
|
||||
mov edx, [xsave_edx]
|
||||
xsave [ecx]
|
||||
mov ecx, [current_slot_idx]
|
||||
mov [fpu_owner], ecx
|
||||
mov ecx, [current_slot]
|
||||
mov [fpu_owner], ecx
|
||||
mov ecx, [ecx + APPDATA.fpu_state]
|
||||
xrstor [ecx]
|
||||
.no_xsave:
|
||||
; set CR0.TS
|
||||
cmp bh, byte[fpu_owner] ;bh == incoming task (new)
|
||||
cmp ebx, [fpu_owner] ;ebx == incoming task (new)
|
||||
clts ;clear a task switch flag
|
||||
je @f
|
||||
mov eax, cr0 ;and set it again if the owner
|
||||
|
||||
+19
-16
@@ -165,7 +165,7 @@ exc_c: ; exceptions (all but 7th - #NM)
|
||||
jnz IRetToUserHook
|
||||
@@:
|
||||
cli
|
||||
mov eax, [esi + APPDATA.debugger_slot]
|
||||
mov eax, [esi + APPDATA.debugger_thread]
|
||||
test eax, eax
|
||||
jnz .debug
|
||||
; not debuggee => say error and terminate
|
||||
@@ -514,28 +514,30 @@ destroy_thread:
|
||||
@@:
|
||||
mov eax, [esi + APPOBJ.fd]
|
||||
test eax, eax
|
||||
jz @F
|
||||
jz @f
|
||||
|
||||
cmp eax, esi
|
||||
je @F
|
||||
je @f
|
||||
|
||||
push esi
|
||||
call [eax + APPOBJ.destroy]
|
||||
DEBUGF 1,"%s",msg_obj_destroy
|
||||
pop esi
|
||||
jmp @B
|
||||
jmp @b
|
||||
@@:
|
||||
mov esi, [.slot]
|
||||
shl esi, BSF sizeof.APPDATA
|
||||
add esi, SLOT_BASE
|
||||
cmp [fpu_owner], esi ; if user fpu last -> fpu user = 2
|
||||
jne @F
|
||||
jne @f
|
||||
|
||||
mov [fpu_owner], 2
|
||||
mov eax, [SLOT_BASE + sizeof.APPDATA*2 + APPDATA.fpu_state]
|
||||
mov [fpu_owner], APPDATA_OS_THREAD
|
||||
mov eax, [APPDATA_OS_THREAD + APPDATA.fpu_state]
|
||||
clts
|
||||
bt [cpu_caps], CAPS_SSE
|
||||
jnc .no_SSE
|
||||
fxrstor [eax]
|
||||
jmp @F
|
||||
jmp @f
|
||||
.no_SSE:
|
||||
fnclex
|
||||
frstor [eax]
|
||||
@@ -544,8 +546,8 @@ destroy_thread:
|
||||
mov [KEY_COUNT], byte 0 ; empty keyboard buffer
|
||||
mov [BTN_COUNT], byte 0 ; empty button buffer
|
||||
|
||||
|
||||
; remove defined hotkeys
|
||||
mov esi, [.slot]
|
||||
mov eax, hotkey_list
|
||||
.loop:
|
||||
cmp [eax+8], esi
|
||||
@@ -638,7 +640,7 @@ destroy_thread:
|
||||
pushad
|
||||
mov edi, esi
|
||||
shl edi, BSF sizeof.APPDATA
|
||||
mov eax, [SLOT_BASE + edi + APPDATA.debugger_slot]
|
||||
mov eax, [SLOT_BASE + edi + APPDATA.debugger_thread]
|
||||
test eax, eax
|
||||
jz .nodebug
|
||||
movi ecx, 8
|
||||
@@ -666,12 +668,12 @@ destroy_thread:
|
||||
add edi, SLOT_BASE
|
||||
|
||||
mov eax, [edi + APPDATA.io_map]
|
||||
cmp eax, [SLOT_BASE + sizeof.APPDATA+APPDATA.io_map]
|
||||
cmp eax, [APPDATA_IDLE_THREAD + APPDATA.io_map]
|
||||
je @F
|
||||
call free_page
|
||||
@@:
|
||||
mov eax, [edi+APPDATA.io_map+4]
|
||||
cmp eax, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map+4]
|
||||
cmp eax, [APPDATA_IDLE_THREAD + APPDATA.io_map+4]
|
||||
je @F
|
||||
call free_page
|
||||
@@:
|
||||
@@ -712,12 +714,12 @@ destroy_thread:
|
||||
call free_cd_channel
|
||||
and [cd_status], 0
|
||||
@@:
|
||||
pop esi
|
||||
cmp [bgrlockpid], esi
|
||||
jnz @f
|
||||
and [bgrlockpid], 0
|
||||
and [bgrlock], 0
|
||||
@@:
|
||||
pop esi
|
||||
|
||||
pusha ; remove all port reservations
|
||||
mov edx, esi
|
||||
@@ -778,14 +780,15 @@ destroy_thread:
|
||||
|
||||
mov edi, esi ; do not run this process slot
|
||||
shl edi, BSF sizeof.APPDATA
|
||||
mov [SLOT_BASE + edi + APPDATA.state], TSTATE_FREE
|
||||
add edi, SLOT_BASE
|
||||
mov [edi + APPDATA.state], TSTATE_FREE
|
||||
; debugger test - terminate all debuggees
|
||||
mov eax, 2
|
||||
mov ecx, SLOT_BASE + 2*sizeof.APPDATA + APPDATA.debugger_slot
|
||||
mov ecx, APPDATA_OS_THREAD + APPDATA.debugger_thread
|
||||
.xd0:
|
||||
cmp eax, [thread_count]
|
||||
ja .xd1
|
||||
cmp dword [ecx], esi
|
||||
cmp dword [ecx], edi
|
||||
jnz @f
|
||||
and dword [ecx], 0
|
||||
pushad
|
||||
|
||||
@@ -537,21 +537,21 @@ pid_to_slot:
|
||||
align 4
|
||||
proc read_process_memory
|
||||
;Input:
|
||||
; eax - process slot
|
||||
; eax - process thread
|
||||
; ecx - buffer address
|
||||
; edx - buffer size
|
||||
; esi - start address in other process
|
||||
;Output:
|
||||
; eax - number of bytes read.
|
||||
locals
|
||||
slot dd ?
|
||||
thread dd ?
|
||||
buff dd ?
|
||||
r_count dd ?
|
||||
offset dd ?
|
||||
tmp_r_cnt dd ?
|
||||
endl
|
||||
|
||||
mov [slot], eax
|
||||
mov [thread], eax
|
||||
mov [buff], ecx
|
||||
and [r_count], 0
|
||||
mov [tmp_r_cnt], edx
|
||||
@@ -577,7 +577,7 @@ proc read_process_memory
|
||||
|
||||
push ecx
|
||||
stdcall map_memEx, [proc_mem_map], \
|
||||
[slot], ebx, ecx, PG_READ
|
||||
[thread], ebx, ecx, PG_READ
|
||||
pop ecx
|
||||
|
||||
mov esi, [offset]
|
||||
@@ -607,7 +607,7 @@ endp
|
||||
align 4
|
||||
proc write_process_memory
|
||||
;Input:
|
||||
; eax - process slot
|
||||
; eax - process thread
|
||||
; ecx - buffer address
|
||||
; edx - buffer size
|
||||
; esi - start address in other process
|
||||
@@ -615,14 +615,14 @@ proc write_process_memory
|
||||
; eax - number of bytes written
|
||||
|
||||
locals
|
||||
slot dd ?
|
||||
thread dd ?
|
||||
buff dd ?
|
||||
w_count dd ?
|
||||
offset dd ?
|
||||
tmp_w_cnt dd ?
|
||||
endl
|
||||
|
||||
mov [slot], eax
|
||||
mov [thread], eax
|
||||
mov [buff], ecx
|
||||
and [w_count], 0
|
||||
mov [tmp_w_cnt], edx
|
||||
@@ -647,7 +647,7 @@ proc write_process_memory
|
||||
mov ebx, [offset]
|
||||
push ecx
|
||||
stdcall map_memEx, [proc_mem_map], \
|
||||
[slot], ebx, ecx, PG_SWR
|
||||
[thread], ebx, ecx, PG_SWR
|
||||
pop ecx
|
||||
|
||||
mov edi, [offset]
|
||||
@@ -906,7 +906,7 @@ common_app_entry:
|
||||
stdcall free_kernel_space, [ebp+APP_HDR.img_base]
|
||||
stdcall kernel_free, ebp
|
||||
mov ebx, [current_slot]
|
||||
cmp [ebx + APPDATA.debugger_slot], 0
|
||||
cmp [ebx + APPDATA.debugger_thread], 0
|
||||
je .exit
|
||||
mov [ebx + APPDATA.state], TSTATE_RUN_SUSPENDED
|
||||
mov [ebx + APPDATA.state], TSTATE_RUN_SUSPENDED
|
||||
@@ -1054,8 +1054,8 @@ proc set_app_params stdcall,slot:dword, params:dword, flags:dword
|
||||
; set if debuggee
|
||||
test byte [flags], 1
|
||||
jz .no_debug
|
||||
mov eax, [current_slot_idx]
|
||||
mov [SLOT_BASE + ebx + APPDATA.debugger_slot], eax
|
||||
mov eax, [current_slot]
|
||||
mov [SLOT_BASE + ebx + APPDATA.debugger_thread], eax
|
||||
.no_debug:
|
||||
mov [SLOT_BASE + ebx + APPDATA.state], dl
|
||||
lea edx, [SLOT_BASE + ebx]
|
||||
@@ -1074,27 +1074,24 @@ get_curr_slot:
|
||||
mov eax, [current_slot]
|
||||
ret
|
||||
|
||||
pid_to_appdata:
|
||||
;Input:
|
||||
; eax - pid of process
|
||||
;Output:
|
||||
; eax - 0 - not found or pointer on APPDATA
|
||||
; @brief Get pointer to APPDATA by PID
|
||||
; @param eax - TID of thread
|
||||
; @return eax - 0 - not found or pointer on APPDATA
|
||||
pid_to_thread:
|
||||
push ebx
|
||||
push ecx
|
||||
mov ebx, [thread_count]
|
||||
shl ebx, BSF sizeof.APPDATA ; multiply by size
|
||||
; skip first process in the task table
|
||||
mov ecx, SLOT_BASE
|
||||
add ebx, ecx
|
||||
mov ecx, APPDATA_IDLE_THREAD
|
||||
.loop:
|
||||
add ecx, sizeof.APPDATA
|
||||
cmp [ecx + APPDATA.state], TSTATE_FREE
|
||||
jz @f ;skip empty slots
|
||||
cmp [ecx + APPDATA.tid], eax
|
||||
jz .pid_found
|
||||
@@:
|
||||
cmp ecx, ebx
|
||||
jb .loop
|
||||
add ecx, sizeof.APPDATA
|
||||
dec ebx
|
||||
jnz .loop
|
||||
|
||||
pop ecx
|
||||
pop ebx
|
||||
|
||||
@@ -48,7 +48,7 @@ endg
|
||||
|
||||
; This internal function acquires the lock for the global list.
|
||||
lock_timer_list:
|
||||
mov edx, [current_slot_idx]
|
||||
mov edx, [current_slot]
|
||||
@@:
|
||||
xor eax, eax
|
||||
lock cmpxchg [timer_list_owner], edx
|
||||
|
||||
@@ -4148,6 +4148,7 @@ Structure of block of data for folder entry (BDFE):
|
||||
and after archiving this bit is cleared - it can be useful
|
||||
for automatically creating of backup-archives as at writing
|
||||
this bit is usually set
|
||||
* bit 6 (mask 0x40): this is a symbolic link (currently only set by the ext driver).
|
||||
* +4: dword: encoding, equals to field +8 in the information structure
|
||||
* +8: 4*byte: time of file creation
|
||||
* +12 = +0xC: 4*byte: date of file creation
|
||||
|
||||
@@ -212,6 +212,7 @@ DIR_DIRECTORY = 2
|
||||
DIR_SYMLINK = 7
|
||||
KOS_HIDDEN = 2
|
||||
KOS_DIRECTORY = 10h
|
||||
KOS_SYMLINK = 40h
|
||||
READ_ONLY = 1
|
||||
SYMLINK_MAX_DEPTH = 40
|
||||
FAST_SYMLINK_MAX_SIZE = 60
|
||||
@@ -3392,6 +3393,11 @@ ext_ReadFolder:
|
||||
stosd
|
||||
mov eax, [esi+INODE.fileSizeHigh]
|
||||
stosd
|
||||
movzx eax, [esi+INODE.accessMode]
|
||||
and eax, TYPE_MASK
|
||||
cmp eax, FLAG_SYMLINK
|
||||
jne @f
|
||||
or dword [edx], KOS_SYMLINK
|
||||
@@:
|
||||
mov esi, [esp+12]
|
||||
movzx ecx, [esi+DIRENTRY.nameLength]
|
||||
|
||||
@@ -193,7 +193,8 @@ align 4
|
||||
;--------------------------------------
|
||||
align 4
|
||||
@@:
|
||||
mov eax, [current_slot_idx]
|
||||
mov eax, [current_slot]
|
||||
mov eax, [eax + APPDATA.tid]
|
||||
mov [bgrlockpid], eax
|
||||
cmp [img_background], static_background_data
|
||||
jz .nomem
|
||||
@@ -241,7 +242,8 @@ nosb6:
|
||||
jnz nosb7
|
||||
cmp [bgrlock], 0
|
||||
jz .err
|
||||
mov eax, [current_slot_idx]
|
||||
mov eax, [current_slot]
|
||||
mov eax, [eax + APPDATA.tid]
|
||||
cmp [bgrlockpid], eax
|
||||
jnz .err
|
||||
mov eax, ecx
|
||||
|
||||
@@ -1997,6 +1997,8 @@ align 4
|
||||
; esi - slot
|
||||
push eax ecx edx esi
|
||||
xchg eax, esi
|
||||
shl eax, BSF sizeof.APPDATA
|
||||
add eax, SLOT_BASE
|
||||
lea ecx, [esp + 12]
|
||||
mov edx, 1
|
||||
call read_process_memory
|
||||
|
||||
+17
-18
@@ -55,7 +55,6 @@ launcher_start db 1
|
||||
endg
|
||||
|
||||
max_processes = 255
|
||||
tss_step = 128 + 8192 ; tss & i/o - 65535 ports, * 256=557056*4
|
||||
|
||||
os_stack = os_data_l - gdts ; GDTs
|
||||
os_code = os_code_l - gdts
|
||||
@@ -389,7 +388,7 @@ high_code:
|
||||
mov edi, tss._io_map_0
|
||||
xor eax, eax
|
||||
not eax
|
||||
mov ecx, 8192/4
|
||||
mov ecx, IO_MAP_SIZE/4
|
||||
rep stosd ; access to 4096*8=65536 ports
|
||||
|
||||
mov ax, tss0
|
||||
@@ -410,7 +409,7 @@ high_code:
|
||||
stdcall alloc_kernel_space, 0x50000 ; FIXME check size
|
||||
mov [default_io_map], eax
|
||||
|
||||
add eax, 0x2000
|
||||
add eax, IO_MAP_SIZE
|
||||
mov [ipc_tmp], eax
|
||||
mov ebx, 0x1000
|
||||
|
||||
@@ -535,7 +534,7 @@ high_code:
|
||||
dec ecx
|
||||
jns @b
|
||||
|
||||
mov edx, SLOT_BASE + sizeof.APPDATA*1
|
||||
mov edx, APPDATA_IDLE_THREAD
|
||||
mov ebx, [os_stack_seg]
|
||||
add ebx, RING0_STACK_SIZE
|
||||
add ebx, [xsave_area_size]
|
||||
@@ -547,7 +546,7 @@ high_code:
|
||||
mov ecx, IDLE_PRIORITY
|
||||
call scheduler_add_thread
|
||||
|
||||
mov edx, SLOT_BASE + sizeof.APPDATA*2
|
||||
mov edx, APPDATA_OS_THREAD
|
||||
mov ebx, [os_stack_seg]
|
||||
call setup_os_slot
|
||||
mov dword [edx], 'OS'
|
||||
@@ -556,7 +555,7 @@ high_code:
|
||||
|
||||
mov [current_slot_idx], 2
|
||||
mov [thread_count], 2
|
||||
mov [current_slot], SLOT_BASE + sizeof.APPDATA*2
|
||||
mov [current_slot], APPDATA_OS_THREAD
|
||||
|
||||
; Move other CPUs to deep sleep, if it is useful
|
||||
uglobal
|
||||
@@ -848,15 +847,15 @@ include "detect/vortex86.inc" ; Vortex86 SoC detection code
|
||||
call reserve_irqs_ports
|
||||
|
||||
mov [SLOT_BASE + APPDATA.window], window_data
|
||||
mov [SLOT_BASE + sizeof.APPDATA + APPDATA.window], window_data + sizeof.WDATA
|
||||
mov [SLOT_BASE + sizeof.APPDATA*2 + APPDATA.window], window_data + sizeof.WDATA*2
|
||||
mov [APPDATA_IDLE_THREAD + APPDATA.window], background_window
|
||||
mov [APPDATA_OS_THREAD + APPDATA.window], window_data + sizeof.WDATA*2
|
||||
mov [window_data + WDATA.thread], SLOT_BASE
|
||||
mov [window_data + sizeof.WDATA + WDATA.thread], SLOT_BASE + sizeof.APPDATA
|
||||
mov [window_data + sizeof.WDATA*2 + WDATA.thread], SLOT_BASE + sizeof.APPDATA*2
|
||||
mov [background_window + WDATA.thread], APPDATA_IDLE_THREAD
|
||||
mov [window_data + sizeof.WDATA*2 + WDATA.thread], APPDATA_OS_THREAD
|
||||
|
||||
call init_display
|
||||
mov eax, [def_cursor]
|
||||
mov [window_data + sizeof.WDATA + WDATA.cursor], eax
|
||||
mov [background_window + WDATA.cursor], eax
|
||||
mov [window_data + sizeof.WDATA*2 + WDATA.cursor], eax
|
||||
|
||||
; PRINT CPU FREQUENCY
|
||||
@@ -953,14 +952,14 @@ include "detect/vortex86.inc" ; Vortex86 SoC detection code
|
||||
; Protect I/O permission map
|
||||
|
||||
mov esi, [default_io_map]
|
||||
stdcall map_page, esi, [SLOT_BASE + sizeof.APPDATA + APPDATA.io_map], PG_READ
|
||||
stdcall map_page, esi, [APPDATA_IDLE_THREAD + APPDATA.io_map], PG_READ
|
||||
add esi, 0x1000
|
||||
stdcall map_page, esi, [SLOT_BASE + sizeof.APPDATA + APPDATA.io_map + 4], PG_READ
|
||||
stdcall map_page, esi, [APPDATA_IDLE_THREAD + APPDATA.io_map + 4], PG_READ
|
||||
|
||||
stdcall map_page, tss._io_map_0, \
|
||||
[SLOT_BASE + sizeof.APPDATA + APPDATA.io_map], PG_READ
|
||||
[APPDATA_IDLE_THREAD + APPDATA.io_map], PG_READ
|
||||
stdcall map_page, tss._io_map_1, \
|
||||
[SLOT_BASE + sizeof.APPDATA + APPDATA.io_map + 4], PG_READ
|
||||
[APPDATA_IDLE_THREAD + APPDATA.io_map + 4], PG_READ
|
||||
|
||||
; SET KEYBOARD PARAMETERS
|
||||
mov al, 0xf6 ; reset keyboard, scan enabled
|
||||
@@ -1865,7 +1864,7 @@ sysfn_shutdown: ; 18.9 = system shutdown
|
||||
; out: Z/z -- is/not kernel thread
|
||||
is_kernel_thread:
|
||||
mov eax, [eax + APPDATA.process]
|
||||
cmp eax, [SLOT_BASE + 2*sizeof.APPDATA + APPDATA.process] ; OS
|
||||
cmp eax, [APPDATA_OS_THREAD + APPDATA.process] ; OS
|
||||
ret
|
||||
;------------------------------------------------------------------------------
|
||||
sysfn_terminate: ; 18.2 = TERMINATE
|
||||
@@ -2065,7 +2064,7 @@ sysfn_zmodif:
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
sysfn_getidletime: ; 18.4 = GET IDLETIME
|
||||
mov eax, [SLOT_BASE + sizeof.APPDATA + APPDATA.cpu_usage]
|
||||
mov eax, [APPDATA_IDLE_THREAD + APPDATA.cpu_usage]
|
||||
mov [esp + SYSCALL_STACK.eax], eax
|
||||
ret
|
||||
;------------------------------------------------------------------------------
|
||||
@@ -2825,7 +2824,7 @@ no_mark_system_shutdown:
|
||||
align 4
|
||||
noshutdown:
|
||||
mov eax, [thread_count] ; termination
|
||||
mov ebx, SLOT_BASE + sizeof.APPDATA + APPDATA.state
|
||||
mov ebx, APPDATA_IDLE_THREAD + APPDATA.state
|
||||
mov esi, 1
|
||||
;--------------------------------------
|
||||
align 4
|
||||
|
||||
Loaded 100 of 172 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user