1 /* $NetBSD: acpi_machdep.c,v 1.10 2019/12/22 15:57:06 thorpej Exp $ */ 2 /* 3 * Copyright (c) 2009 KIYOHARA Takashi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 /* 28 * Machine-dependent routines for ACPICA. 29 */ 30 #include <sys/cdefs.h> 31 __KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.10 2019/12/22 15:57:06 thorpej Exp $"); 32 33 #include <sys/param.h> 34 35 #include <uvm/uvm_extern.h> 36 37 #include <machine/bus.h> 38 #include <machine/efi.h> 39 #include <machine/intrdefs.h> 40 41 #include <dev/acpi/acpica.h> 42 #include <dev/acpi/acpivar.h> 43 44 #include <machine/acpi_machdep.h> 45 46 47 static struct uuid acpi20_table = EFI_TABLE_ACPI20; 48 static u_long acpi_root_phys; 49 int has_i8259 = 0; 50 51 52 ACPI_STATUS 53 acpi_md_OsInitialize(void) 54 { 55 56 if (((ia64_get_cpuid(3) >> 24) & 0xff) == 0x07) 57 has_i8259 = 1; /* Firmware on old Itanium systems is broken */ 58 59 return AE_OK; 60 } 61 62 ACPI_PHYSICAL_ADDRESS 63 acpi_md_OsGetRootPointer(void) 64 { 65 void *acpi_root; 66 67 if (acpi_root_phys == 0) { 68 acpi_root = efi_get_table(&acpi20_table); 69 if (acpi_root == NULL) 70 return 0; 71 acpi_root_phys = IA64_RR_MASK((u_long)acpi_root); 72 } 73 74 return acpi_root_phys; 75 } 76 77 static int 78 acpi_isa_irq_to_vector(UINT32 irq) 79 { 80 static int isa_irq_to_vector_map[16] = { 81 /* i8259 IRQ translation, first 16 entries */ 82 0x2f, 0x20, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 83 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 84 }; 85 86 if (has_i8259 && irq < 16) 87 return isa_irq_to_vector_map[irq]; 88 89 return irq; 90 } 91 92 ACPI_STATUS 93 acpi_md_OsInstallInterruptHandler(UINT32 irq, 94 ACPI_OSD_HANDLER ServiceRoutine, 95 void *Context, void **cookiep, 96 const char *xname) 97 { 98 const int vec = acpi_isa_irq_to_vector(irq); 99 void *ih; 100 101 /* 102 * XXX probably, IPL_BIO is enough. 103 */ 104 ih = intr_establish(vec, IST_LEVEL, IPL_TTY, 105 (int (*)(void *)) ServiceRoutine, Context); 106 if (ih == NULL) 107 return AE_NO_MEMORY; 108 *cookiep = ih; 109 return AE_OK; 110 } 111 112 void 113 acpi_md_OsRemoveInterruptHandler(void *cookie) 114 { 115 116 intr_disestablish(cookie); 117 } 118 119 void * 120 acpi_md_intr_establish(uint32_t irq, int ipl, int type, int (*handler)(void *), 121 void *arg, bool mpsafe, const char *xname) 122 { 123 const int vec = acpi_isa_irq_to_vector(irq); 124 125 return intr_establish(vec, type, ipl, handler, arg); 126 } 127 128 void 129 acpi_md_intr_mask(void *ih) 130 { 131 /* XXX */ 132 panic("acpi_md_intr_mask(%p): not implemented", ih); 133 } 134 135 void 136 acpi_md_intr_unmask(void *ih) 137 { 138 /* XXX */ 139 panic("acpi_md_intr_unmask(%p): not implemented", ih); 140 } 141 142 void 143 acpi_md_intr_disestablish(void *ih) 144 { 145 intr_disestablish(ih); 146 } 147 148 ACPI_STATUS 149 acpi_md_OsMapMemory(ACPI_PHYSICAL_ADDRESS PhysicalAddress, UINT32 Length, 150 void **LogicalAddress) 151 { 152 153 if (bus_space_map(IA64_BUS_SPACE_MEM, PhysicalAddress, Length, 154 0, (bus_space_handle_t *) LogicalAddress) == 0) 155 return AE_OK; 156 157 return AE_NO_MEMORY; 158 } 159 160 void 161 acpi_md_OsUnmapMemory(void *LogicalAddress, UINT32 Length) 162 { 163 164 bus_space_unmap(IA64_BUS_SPACE_MEM, (bus_space_handle_t) LogicalAddress, 165 Length); 166 } 167 168 ACPI_STATUS 169 acpi_md_OsGetPhysicalAddress(void *LogicalAddress, 170 ACPI_PHYSICAL_ADDRESS *PhysicalAddress) 171 { 172 paddr_t pa; 173 174 printf("%s\n", __func__); 175 if (pmap_extract(pmap_kernel(), (vaddr_t) LogicalAddress, &pa)) { 176 *PhysicalAddress = pa; 177 return AE_OK; 178 } 179 180 return AE_ERROR; 181 } 182 183 BOOLEAN 184 acpi_md_OsReadable(void *Pointer, UINT32 Length) 185 { 186 BOOLEAN rv = TRUE; 187 printf("%s: not yet...\n", __func__); 188 189 return rv; 190 } 191 192 BOOLEAN 193 acpi_md_OsWritable(void *Pointer, UINT32 Length) 194 { 195 BOOLEAN rv = FALSE; 196 printf("%s: not yet...\n", __func__); 197 return rv; 198 } 199 200 void 201 acpi_md_OsEnableInterrupt(void) 202 { 203 204 enable_intr(); 205 } 206 207 void 208 acpi_md_OsDisableInterrupt(void) 209 { 210 211 disable_intr(); 212 } 213 214 uint32_t 215 acpi_md_pdc(void) 216 { 217 return 0; 218 } 219 220 uint32_t 221 acpi_md_ncpus(void) 222 { 223 return 0; /* XXX. */ 224 } 225 226 void 227 acpi_md_callback(struct acpi_softc *sc) 228 { 229 /* Nothing. */ 230 } 231 232 int 233 acpi_md_sleep(int state) 234 { 235 printf("%s: not yet...\n", __func__); 236 return 0; 237 } 238