Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/drivers/acpi/osl.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  acpi_osl.c - OS-dependent functions ($Revision: 83 $)
3
 *
4
 *  Copyright (C) 2000       Andrew Henroid
5
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
6
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
7
 *
8
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this program; If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24
 *
25
 */
26
#include <asm/io.h>
27
#include <xen/init.h>
28
#include <xen/pfn.h>
29
#include <xen/types.h>
30
#include <xen/errno.h>
31
#include <xen/acpi.h>
32
#include <xen/numa.h>
33
#include <acpi/acmacros.h>
34
#include <acpi/acpiosxf.h>
35
#include <acpi/platform/aclinux.h>
36
#include <xen/spinlock.h>
37
#include <xen/domain_page.h>
38
#include <xen/efi.h>
39
#include <xen/vmap.h>
40
41
#define _COMPONENT    ACPI_OS_SERVICES
42
ACPI_MODULE_NAME("osl")
43
44
#ifdef CONFIG_ACPI_CUSTOM_DSDT
45
#include CONFIG_ACPI_CUSTOM_DSDT_FILE
46
#endif
47
48
void __init acpi_os_printf(const char *fmt, ...)
49
36
{
50
36
  va_list args;
51
36
  va_start(args, fmt);
52
36
  acpi_os_vprintf(fmt, args);
53
36
  va_end(args);
54
36
}
55
56
void __init acpi_os_vprintf(const char *fmt, va_list args)
57
54
{
58
54
  static char buffer[512];
59
54
60
54
  vsnprintf(buffer, sizeof(buffer), fmt, args);
61
54
62
54
  printk("%s", buffer);
63
54
}
64
65
acpi_physical_address __init acpi_os_get_root_pointer(void)
66
3
{
67
3
  if (efi_enabled(EFI_BOOT)) {
68
0
    if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
69
0
      return efi.acpi20;
70
0
    else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
71
0
      return efi.acpi;
72
0
    else {
73
0
      printk(KERN_ERR PREFIX
74
0
             "System description tables not found\n");
75
0
      return 0;
76
0
    }
77
3
  } else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
78
3
    acpi_physical_address pa = 0;
79
3
80
3
    acpi_find_root_pointer(&pa);
81
3
    return pa;
82
3
  }
83
3
84
0
  return 0;
85
3
}
86
87
void __iomem *
88
acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
89
55
{
90
55
  if (system_state >= SYS_STATE_boot) {
91
30
    mfn_t mfn = _mfn(PFN_DOWN(phys));
92
30
    unsigned int offs = phys & (PAGE_SIZE - 1);
93
30
94
30
    /* The low first Mb is always mapped on x86. */
95
30
    if (IS_ENABLED(CONFIG_X86) && !((phys + size - 1) >> 20))
96
8
      return __va(phys);
97
22
    return __vmap(&mfn, PFN_UP(offs + size), 1, 1,
98
22
            ACPI_MAP_MEM_ATTR, VMAP_DEFAULT) + offs;
99
30
  }
100
25
  return __acpi_map_table(phys, size);
101
55
}
102
103
void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
104
34
{
105
34
  if (IS_ENABLED(CONFIG_X86) &&
106
34
      (unsigned long)virt >= DIRECTMAP_VIRT_START &&
107
12
      (unsigned long)virt < DIRECTMAP_VIRT_END) {
108
12
    ASSERT(!((__pa(virt) + size - 1) >> 20));
109
12
    return;
110
12
  }
111
34
112
22
  if (system_state >= SYS_STATE_boot)
113
1
    vunmap((void *)((unsigned long)virt & PAGE_MASK));
114
22
}
115
116
acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
117
0
{
118
0
  u32 dummy;
119
0
120
0
  if (!value)
121
0
    value = &dummy;
122
0
123
0
  *value = 0;
124
0
  if (width <= 8) {
125
0
    *(u8 *) value = inb(port);
126
0
  } else if (width <= 16) {
127
0
    *(u16 *) value = inw(port);
128
0
  } else if (width <= 32) {
129
0
    *(u32 *) value = inl(port);
130
0
  } else {
131
0
    BUG();
132
0
  }
133
0
134
0
  return AE_OK;
135
0
}
136
137
acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
138
0
{
139
0
  if (width <= 8) {
140
0
    outb(value, port);
141
0
  } else if (width <= 16) {
142
0
    outw(value, port);
143
0
  } else if (width <= 32) {
144
0
    outl(value, port);
145
0
  } else {
146
0
    BUG();
147
0
  }
148
0
149
0
  return AE_OK;
150
0
}
151
152
acpi_status
153
acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
154
0
{
155
0
  u32 dummy;
156
0
  void __iomem *virt_addr = acpi_os_map_memory(phys_addr, width >> 3);
157
0
158
0
  if (!virt_addr)
159
0
    return AE_ERROR;
160
0
161
0
  if (!value)
162
0
    value = &dummy;
163
0
164
0
  switch (width) {
165
0
  case 8:
166
0
    *(u8 *) value = readb(virt_addr);
167
0
    break;
168
0
  case 16:
169
0
    *(u16 *) value = readw(virt_addr);
170
0
    break;
171
0
  case 32:
172
0
    *(u32 *) value = readl(virt_addr);
173
0
    break;
174
0
  default:
175
0
    BUG();
176
0
  }
177
0
178
0
  acpi_os_unmap_memory(virt_addr, width >> 3);
179
0
180
0
  return AE_OK;
181
0
}
182
183
acpi_status
184
acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
185
0
{
186
0
  void __iomem *virt_addr = acpi_os_map_memory(phys_addr, width >> 3);
187
0
188
0
  if (!virt_addr)
189
0
    return AE_ERROR;
190
0
191
0
  switch (width) {
192
0
  case 8:
193
0
    writeb(value, virt_addr);
194
0
    break;
195
0
  case 16:
196
0
    writew(value, virt_addr);
197
0
    break;
198
0
  case 32:
199
0
    writel(value, virt_addr);
200
0
    break;
201
0
  default:
202
0
    BUG();
203
0
  }
204
0
205
0
  acpi_os_unmap_memory(virt_addr, width >> 3);
206
0
207
0
  return AE_OK;
208
0
}
209
210
0
#define is_xmalloc_memory(ptr) ((unsigned long)(ptr) & (PAGE_SIZE - 1))
211
212
void *__init acpi_os_alloc_memory(size_t sz)
213
1
{
214
1
  void *ptr;
215
1
216
1
  if (system_state == SYS_STATE_early_boot)
217
1
    return mfn_to_virt(mfn_x(alloc_boot_pages(PFN_UP(sz), 1)));
218
1
219
0
  ptr = xmalloc_bytes(sz);
220
0
  ASSERT(!ptr || is_xmalloc_memory(ptr));
221
0
  return ptr;
222
1
}
223
224
void *__init acpi_os_zalloc_memory(size_t sz)
225
1
{
226
1
  void *ptr;
227
1
228
1
  if (system_state != SYS_STATE_early_boot) {
229
0
    ptr = xzalloc_bytes(sz);
230
0
    ASSERT(!ptr || is_xmalloc_memory(ptr));
231
0
    return ptr;
232
0
  }
233
1
  ptr = acpi_os_alloc_memory(sz);
234
1
  return ptr ? memset(ptr, 0, sz) : NULL;
235
1
}
236
237
void __init acpi_os_free_memory(void *ptr)
238
0
{
239
0
  if (is_xmalloc_memory(ptr))
240
0
    xfree(ptr);
241
0
  else if (ptr && system_state == SYS_STATE_early_boot)
242
0
    init_boot_pages(__pa(ptr), __pa(ptr) + PAGE_SIZE);
243
0
}