summaryrefslogtreecommitdiff
path: root/usr.sbin/acpiscan/oslib.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/acpiscan/oslib.c')
-rw-r--r--usr.sbin/acpiscan/oslib.c441
1 files changed, 441 insertions, 0 deletions
diff --git a/usr.sbin/acpiscan/oslib.c b/usr.sbin/acpiscan/oslib.c
new file mode 100644
index 00000000000..2a624272575
--- /dev/null
+++ b/usr.sbin/acpiscan/oslib.c
@@ -0,0 +1,441 @@
+/* $OpenBSD: oslib.c,v 1.1 2006/11/03 19:33:56 marco Exp $ */
+/*
+ * Copyright (c) 2006 Jordan Hargrave <jordan@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <oslib.h>
+
+#define need_pciio 1
+#define need_physmem 1
+#define need_portio 1
+//#define need_pthread 1
+
+/*=====================================================================
+ *
+ * OpenBSD User Mode
+ *
+ *=====================================================================*/
+#ifdef __OpenBSD__
+void set_iopl(int x)
+{
+ i386_iopl(x);
+}
+#endif
+
+/*=====================================================================
+ *
+ * Solaris User Mode
+ *
+ *=====================================================================*/
+#if defined(__sun__)
+void set_iopl(int x)
+{
+ sysi86(SI86V86,V86SC_IOPL,0x3000);
+}
+#endif
+
+/*=====================================================================
+ *
+ * UnixWare User Mode
+ *
+ *=====================================================================*/
+#if defined(SCO)
+void set_iopl(int x)
+{
+ sysi86(SI86IOPL, x);
+}
+#endif
+
+/*=====================================================================
+ *
+ * Linux Kernel Mode
+ *
+ *=====================================================================*/
+#if defined(linux) && defined(__KERNEL__)
+
+#if (LINUX_KERNEL_VERSION >= 0x020400)
+MODULE_LICENSE("GPL");
+#endif
+
+char kernel_version[] = UTS_RELEASE;
+
+#define printf printk
+
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
+
+void ZeroMem(void *a, int c)
+{
+ uint8_t *b = (uint8_t *)a;
+ while(c--) {
+ *(b++) = 0;
+ }
+}
+
+void CopyMem(void *d, const void *s, int c)
+{
+ uint8_t *a = (uint8_t *)d;
+ uint8_t *b = (uint8_t *)s;
+
+ while(c--) {
+ *(a++) = *(b++);
+ }
+}
+
+#undef need_pthread
+#undef need_physmem
+int physmemcpy(void *dest, uint32_t src, size_t len)
+{
+ memcpy(dest, phys_to_virt(src), len);
+ return 0;
+}
+
+int physmemcmp(const void *dest, uint32_t src, size_t len)
+{
+ uint8_t buf[len];
+
+ physmemcpy(buf, src, len);
+ return memcmp(dest, buf, len);
+}
+#endif
+
+/*=====================================================================
+ *
+ * Linux User Mode
+ *
+ *=====================================================================*/
+#if defined(linux) && !defined(__KERNEL__)
+void set_iopl(int x)
+{
+ iopl(x);
+}
+
+#define need_mmap 1
+
+#undef need_pciio
+int pci_read_n(int b, int d, int f, int reg, int len, void *buf)
+{
+ char dev[32];
+ int fd;
+
+ memset(buf, 0, len);
+ sprintf(dev,"/proc/bus/pci/%.02x/%.02x.%x", b,d,f);
+ if ((fd = open(dev,O_RDWR)) >= 0) {
+ pread(fd,buf,len,reg);
+ close(fd);
+ return 0;
+ }
+ return -1;
+}
+#endif
+
+/*=====================================================================
+ *
+ * DOS 16-bit Mode
+ *
+ *=====================================================================*/
+#ifdef MSDOS
+
+/* Converts linear address to 16:16 pointer */
+void FAR *lintoseg(uint32_t v);
+#pragma aux lintoseg = "shl dx, 12" parm caller [dx ax] value [dx ax];
+
+void set_iopl(int x)
+{
+}
+
+#undef need_portio
+uint8_t os_inb(uint16_t port)
+{
+ return inb(port);
+}
+uint16_t os_inw(uint16_t port)
+{
+ return inw(port);
+}
+uint32_t os_inl(uint16_t port)
+{
+ return inl(port);
+}
+void os_outb(uint16_t port, uint8_t val)
+{
+ outb(port, val);
+}
+void os_outw(uint16_t port, uint16_t val)
+{
+ outw(port, val);
+}
+void os_outl(uint16_t port, uint32_t val)
+{
+ outl(port, val);
+}
+
+#ifdef WATCOM
+#pragma aux os_inb = "in al, dx" value [al] parms [dx];
+#pragma aux os_inw = "in ax, dx" value [ax] parms [dx];
+#pragma aux os_inl = \
+ "in eax, dx" \
+"mov dx, ax" \
+"shr eax, 16", \
+"xchg dx, ax" value [dx ax] parms [dx];
+
+#pragma aux os_outb = "out dx, al" parms [dx] [al];
+#pragma aux os_outw = "out dx, ax" parms [dx] [ax];
+#pragma aux os_outl = \
+ "mov ax, cx" \
+"shl eax, 16" \
+"mov ax, bx" \
+"out dx, eax" parm [dx] [cx bx] modifies [ax];
+#endif
+
+#undef need_physmem
+int physmemcpy(void FAR *dest, uint32_t src, int len)
+{
+ _fmemcpy(dest, lintoseg(src), len);
+ return 0;
+}
+
+int physmemcmp(const void FAR *dest, uint32_t src, int len)
+{
+ return _fmemcmp(dest, lintoseg(src), len);
+}
+#endif /* end dos */
+
+/*=====================================================================
+ *
+ * Common Physmem code
+ *
+ *=====================================================================*/
+#ifdef need_physmem
+
+#define PAGE_OFFSET(x) (uint64_t)((x) & ~PAGE_MASK)
+
+static const char *memfile = "/dev/mem";
+static uint64_t memoff;
+
+int physmemcpy(void FAR *dest, uint32_t src, size_t len)
+{
+ int fd,rc;
+ uint64_t memlimit;
+
+ memset(dest, 0, len);
+ if ((fd = open(memfile, O_RDONLY)) < 0) {
+ printf("Can't open: %s\n", memfile);
+ exit(0);
+ }
+#if 0
+ memlimit = lseek(fd, 0, SEEK_END);
+ if (src < (unsigned)memoff || src+len > memlimit + memoff) {
+ close(fd);
+ return -1;
+ }
+#endif
+ src -= memoff;
+#ifdef need_mmap
+ {
+ uint64_t offset;
+ void *ptr;
+
+ offset = PAGE_OFFSET(src);
+ ptr = mmap(NULL, offset+len, PROT_READ, MAP_PRIVATE, fd, src-offset);
+ if (ptr == (void *)-1L) {
+ printf("Can't mmap @ 0x%.08lx! %d\n", src, errno);
+ }
+ else {
+ memcpy(dest, ptr+offset, len);
+ munmap(ptr, offset+len);
+ }
+ }
+#else
+ rc=pread(fd, dest, len, (off_t)(src - memoff));
+ if (rc < 0) {
+ printf("Can't pread64 @ 0x%.08x %d\n", src, errno);
+ }
+#endif
+ close(fd);
+ return 0;
+}
+
+int physmemcmp(const void FAR *dest, uint32_t src, size_t len)
+{
+ unsigned char bufr[len];
+
+ physmemcpy(bufr, src, len);
+ return memcmp(bufr, dest, len);
+}
+#endif
+
+/*=====================================================================
+ *
+ * Common PCI Access code
+ *
+ *=====================================================================*/
+#ifdef need_pciio
+#define PCI_ADDR(b,d,f,r) (0x80000000+((b)<<16)+((d)<<10)+((f)<<8)+(r))
+int pci_read_n(int b, int d, int f, int reg, int len, void *buf)
+{
+ uint8_t *ptr = (uint8_t *)buf;
+ while(len--) {
+ os_outl(0xCF8, PCI_ADDR(b,d,f,reg++));
+ *(ptr++) = os_inb(0xCF8);
+ }
+}
+#endif
+
+/*=====================================================================
+ *
+ * Common Port code
+ *
+ *=====================================================================*/
+#ifdef need_portio
+uint8_t os_inb(uint16_t port)
+{
+ uint8_t v;
+
+ __asm__ __volatile__ ("inb %w1,%b0" : "=a" (v) : "Nd" (port));
+ return v;
+}
+uint16_t os_inw(uint16_t port)
+{
+ uint16_t v;
+
+ __asm__ __volatile__ ("inw %w1,%w0" : "=a" (v) : "Nd" (port));
+ return v;
+}
+uint32_t os_inl(uint16_t port)
+{
+ uint32_t v;
+
+ __asm__ __volatile__ ("inl %w1,%0" : "=a" (v) : "Nd" (port));
+ return v;
+}
+void os_outb(uint16_t port, uint8_t v)
+{
+ __asm__ __volatile__ ("outb %b0,%w1" : "=a" (v) : "Nd" (port));
+}
+void os_outw(uint16_t port, uint16_t v)
+{
+ __asm__ __volatile__ ("outw %w0,%w1" : "=a" (v) : "Nd" (port));
+}
+void os_outl(uint16_t port, uint32_t v)
+{
+ __asm__ __volatile__ ("outl %0,%w1" : "=a" (v) : "Nd" (port));
+}
+#endif
+
+
+/*==================================================================
+ * common pthread routines
+ *==================================================================*/
+#ifdef need_pthread
+#include <pthread.h>
+
+typedef int (*threadproc_t)(void *);
+
+typedef struct
+{
+ pthread_t tid;
+ threadproc_t proc;
+ void *arg;
+} osthread_t;
+
+static void *os_threadhelper(void *arg)
+{
+ osthread_t *thrd = (osthread_t *)arg;
+
+ thrd->proc(thrd->arg);
+ return NULL;
+}
+
+osthread_t *os_create_thread(threadproc_t threadproc, void *arg)
+{
+ osthread_t *thrd;
+
+ if ((thrd = (osthread_t *)malloc(sizeof(osthread_t))) == NULL) {
+ return NULL;
+ }
+ thrd->proc = threadproc;
+ thrd->arg = arg;
+ pthread_create(&thrd->tid, NULL, os_threadhelper, thrd);
+ return thrd;
+}
+
+int os_destroy_thread(osthread_t *thrd)
+{
+ void *rcval;
+
+ pthread_join(thrd->tid, &rcval);
+ free(thrd);
+}
+#endif
+
+/*====================================================================*
+ * Common code
+ *====================================================================*/
+uint32_t scanmem(uint32_t src, uint32_t end, int step, int sz,
+ const void FAR *mem)
+{
+ while(src < end) {
+ if (physmemcmp(mem, src, sz) == 0) {
+ return src;
+ }
+ src += step;
+ }
+ return 0;
+}
+
+void set_physmemfile(const char *name, uint64_t offset)
+{
+#ifdef need_physmem
+ memfile = name;
+ memoff = offset;
+#endif
+}
+
+char dxc(char v, int t)
+{
+ if (v < ' ' || v > 'z' || t) {
+ return '.';
+ }
+ return v;
+}
+uint8_t dxb(uint8_t v, int t)
+{
+ return (t) ? 0xFF : v;
+}
+
+void dump(void FAR *dest, int len)
+{
+ uint8_t FAR *b = (uint8_t FAR *)dest;
+ int i,j;
+
+ for(i=0;i<len;i+=16) {
+ printf("%.06x: ", i);
+ for(j=0;j<16;j++) {
+ if (i+j >= len) {
+ printf("-- ");
+ }
+ else {
+ printf("%.02x ", dxb(b[i+j],i+j>=len));
+ }
+ }
+ printf(" ");
+ for(j=0;j<16;j++) {
+ printf("%c", dxc(b[i+j],i+j>=len));
+ }
+ printf("\n");
+ }
+}