VirtualBox

source: vbox/trunk/src/VBox/Additions/linux/drm/vbox_hgsmi.c@ 70801

Last change on this file since 70801 was 69325, checked in by vboxsync, 7 years ago

vbox_prime.c: Michael, what's this based on? Put in a placeholder so scm groks it.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.7 KB
Line 
1/** @file
2 * VirtualBox Additions Linux kernel video driver hgsmi interface code
3 */
4
5/*
6 * Contributed by Hans de Goede <[email protected]>
7 *
8 * Copyright (C) 2017 Oracle Corporation
9 *
10 * Permission is hereby granted, free of charge, to any person
11 * obtaining a copy of this software and associated documentation
12 * files (the "Software"), to deal in the Software without
13 * restriction, including without limitation the rights to use,
14 * copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following
17 * conditions:
18 *
19 * The above copyright notice and this permission notice shall be
20 * included in all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
24 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29 * OTHER DEALINGS IN THE SOFTWARE.
30 */
31
32#include <HGSMIBase.h>
33#include <VBoxVideoVBE.h>
34
35/* One-at-a-Time Hash from http://www.burtleburtle.net/bob/hash/doobs.html */
36static u32 hgsmi_hash_process(u32 hash, const u8 *data, int size)
37{
38 while (size--) {
39 hash += *data++;
40 hash += (hash << 10);
41 hash ^= (hash >> 6);
42 }
43
44 return hash;
45}
46
47static u32 hgsmi_hash_end(u32 hash)
48{
49 hash += (hash << 3);
50 hash ^= (hash >> 11);
51 hash += (hash << 15);
52
53 return hash;
54}
55
56/* Not really a checksum but that is the naming used in all vbox code */
57static u32 hgsmi_checksum(u32 offset,
58 const HGSMIBUFFERHEADER *header,
59 const HGSMIBUFFERTAIL *tail)
60{
61 u32 checksum;
62
63 checksum = hgsmi_hash_process(0, (u8 *)&offset, sizeof(offset));
64 checksum = hgsmi_hash_process(checksum, (u8 *)header, sizeof(*header));
65 /* 4 -> Do not checksum the checksum itself */
66 checksum = hgsmi_hash_process(checksum, (u8 *)tail, 4);
67
68 return hgsmi_hash_end(checksum);
69}
70
71#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
72void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma)
73{
74 unsigned long vaddr = gen_pool_alloc(pool, size);
75
76 if (vaddr)
77 *dma = gen_pool_virt_to_phys(pool, vaddr);
78 return (void *)vaddr;
79}
80#endif
81
82void *hgsmi_buffer_alloc(struct gen_pool *guest_pool, size_t size,
83 u8 channel, u16 channel_info)
84{
85 HGSMIBUFFERHEADER *h;
86 HGSMIBUFFERTAIL *t;
87 size_t total_size;
88 dma_addr_t offset;
89
90 total_size = size + sizeof(HGSMIBUFFERHEADER) + sizeof(HGSMIBUFFERTAIL);
91 h = gen_pool_dma_alloc(guest_pool, total_size, &offset);
92 if (!h)
93 return NULL;
94
95 t = (HGSMIBUFFERTAIL *)((u8 *)h + sizeof(HGSMIBUFFERHEADER) + size);
96
97 h->u8Flags = HGSMI_BUFFER_HEADER_F_SEQ_SINGLE;
98 h->u32DataSize = size;
99 h->u8Channel = channel;
100 h->u16ChannelInfo = channel_info;
101 memset(&h->u.au8Union, 0, sizeof(h->u.au8Union));
102
103 t->u32Reserved = 0;
104 t->u32Checksum = hgsmi_checksum(offset, h, t);
105
106 return (u8 *)h + sizeof(HGSMIBUFFERHEADER);
107}
108
109void hgsmi_buffer_free(struct gen_pool *guest_pool, void *buf)
110{
111 HGSMIBUFFERHEADER *h =
112 (HGSMIBUFFERHEADER *)((u8 *)buf - sizeof(HGSMIBUFFERHEADER));
113 size_t total_size = h->u32DataSize + sizeof(HGSMIBUFFERHEADER) +
114 sizeof(HGSMIBUFFERTAIL);
115
116 gen_pool_free(guest_pool, (unsigned long)h, total_size);
117}
118
119int hgsmi_buffer_submit(struct gen_pool *guest_pool, void *buf)
120{
121 phys_addr_t offset;
122
123 offset = gen_pool_virt_to_phys(guest_pool, (unsigned long)buf -
124 sizeof(HGSMIBUFFERHEADER));
125 outl(offset, VGA_PORT_HGSMI_GUEST);
126 /* Make the compiler aware that the host has changed memory. */
127 mb();
128
129 return VINF_SUCCESS;
130}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette