Message ID | 1358252735-14227-2-git-send-email-colin.king@canonical.com |
---|---|
State | Accepted |
Headers | show |
On Tue, Jan 15, 2013 at 8:25 PM, Colin King <colin.king@canonical.com> wrote: > From: Colin Ian King <colin.king@canonical.com> > > When testing on a Xen Dom0 I discovered that restricted port I/O causes > a segfault. This patch adds a thin layer of abstraction onto the > port read/write operations to catch segfaults and to return FWTS_ERROR. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/lib/include/fwts.h | 1 + > src/lib/include/fwts_ioport.h | 32 ++++++++++ > src/lib/src/Makefile.am | 1 + > src/lib/src/fwts_ioport.c | 136 ++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 170 insertions(+) > create mode 100644 src/lib/include/fwts_ioport.h > create mode 100644 src/lib/src/fwts_ioport.c > > diff --git a/src/lib/include/fwts.h b/src/lib/include/fwts.h > index 414252d..cbf9dd9 100644 > --- a/src/lib/include/fwts.h > +++ b/src/lib/include/fwts.h > @@ -78,5 +78,6 @@ > #include "fwts_battery.h" > #include "fwts_button.h" > #include "fwts_json.h" > +#include "fwts_ioport.h" > > #endif > diff --git a/src/lib/include/fwts_ioport.h b/src/lib/include/fwts_ioport.h > new file mode 100644 > index 0000000..183fb4a > --- /dev/null > +++ b/src/lib/include/fwts_ioport.h > @@ -0,0 +1,32 @@ > +/* > + * Copyright (C) 2013 Canonical > + * > + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > +#ifndef __FWTS_IO_PORT_H__ > +#define __FWTS_IO_PORT_H__ > + > +#include <stdint.h> > + > +int fwts_inb(uint32_t port, uint8_t *value); > +int fwts_inw(uint32_t port, uint16_t *value); > +int fwts_inl(uint32_t port, uint32_t *value); > + > +int fwts_outb(uint32_t port, uint8_t value); > +int fwts_outw(uint32_t port, uint16_t value); > +int fwts_outl(uint32_t port, uint32_t value); > + > +#endif > diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am > index a91d9ab..6a44641 100644 > --- a/src/lib/src/Makefile.am > +++ b/src/lib/src/Makefile.am > @@ -44,6 +44,7 @@ libfwts_la_SOURCES = \ > fwts_hwinfo.c \ > fwts_iasl.c \ > fwts_interactive.c \ > + fwts_ioport.c \ > fwts_keymap.c \ > fwts_klog.c \ > fwts_list.c \ > diff --git a/src/lib/src/fwts_ioport.c b/src/lib/src/fwts_ioport.c > new file mode 100644 > index 0000000..bc6243e > --- /dev/null > +++ b/src/lib/src/fwts_ioport.c > @@ -0,0 +1,136 @@ > +/* > + * Copyright (C) 2013 Canonical > + * > + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > + > +#include <sys/io.h> > +#include <stdint.h> > +#include <signal.h> > +#include <setjmp.h> > + > +#include "fwts.h" > + > +static jmp_buf jmpbuf; > + > +/* > + * If we hit a SIGSEGV then the port read > + * failed and we longjmp back and return > + * FWTS_ERROR > + */ > +static void segv_handler(int dummy) > +{ > + FWTS_UNUSED(dummy); > + > + signal(SIGSEGV, SIG_DFL); > + longjmp(jmpbuf, 1); > +} > + > +/* > + * fwts_inb() > + * 8 bit port read, handle access errors > + */ > +int fwts_inb(uint32_t port, uint8_t *value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + *value = inb(port); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_inw() > + * 16 bit port read, handle access errors > + */ > +int fwts_inw(uint32_t port, uint16_t *value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + *value = inw(port); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_inl() > + * 32 bit port read, handle access errors > + */ > +int fwts_inl(uint32_t port, uint32_t *value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + *value = inl(port); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_outb() > + * 8 bit port write, handle access errors > + */ > +int fwts_outb(uint32_t port, uint8_t value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + outb(port, value); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_outw() > + * 16 bit port write, handle access errors > + */ > +int fwts_outw(uint32_t port, uint16_t value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + outw(port, value); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_outl() > + * 32 bit port write, handle access errors > + */ > +int fwts_outl(uint32_t port, uint32_t value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + outw(port, value); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > -- > 1.8.0 > Acked-by: Keng-Yu Lin <kengyu@canonical.com>
On 01/15/2013 08:25 PM, Colin King wrote: > From: Colin Ian King <colin.king@canonical.com> > > When testing on a Xen Dom0 I discovered that restricted port I/O causes > a segfault. This patch adds a thin layer of abstraction onto the > port read/write operations to catch segfaults and to return FWTS_ERROR. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/lib/include/fwts.h | 1 + > src/lib/include/fwts_ioport.h | 32 ++++++++++ > src/lib/src/Makefile.am | 1 + > src/lib/src/fwts_ioport.c | 136 ++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 170 insertions(+) > create mode 100644 src/lib/include/fwts_ioport.h > create mode 100644 src/lib/src/fwts_ioport.c > > diff --git a/src/lib/include/fwts.h b/src/lib/include/fwts.h > index 414252d..cbf9dd9 100644 > --- a/src/lib/include/fwts.h > +++ b/src/lib/include/fwts.h > @@ -78,5 +78,6 @@ > #include "fwts_battery.h" > #include "fwts_button.h" > #include "fwts_json.h" > +#include "fwts_ioport.h" > > #endif > diff --git a/src/lib/include/fwts_ioport.h b/src/lib/include/fwts_ioport.h > new file mode 100644 > index 0000000..183fb4a > --- /dev/null > +++ b/src/lib/include/fwts_ioport.h > @@ -0,0 +1,32 @@ > +/* > + * Copyright (C) 2013 Canonical > + * > + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > +#ifndef __FWTS_IO_PORT_H__ > +#define __FWTS_IO_PORT_H__ > + > +#include <stdint.h> > + > +int fwts_inb(uint32_t port, uint8_t *value); > +int fwts_inw(uint32_t port, uint16_t *value); > +int fwts_inl(uint32_t port, uint32_t *value); > + > +int fwts_outb(uint32_t port, uint8_t value); > +int fwts_outw(uint32_t port, uint16_t value); > +int fwts_outl(uint32_t port, uint32_t value); > + > +#endif > diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am > index a91d9ab..6a44641 100644 > --- a/src/lib/src/Makefile.am > +++ b/src/lib/src/Makefile.am > @@ -44,6 +44,7 @@ libfwts_la_SOURCES = \ > fwts_hwinfo.c \ > fwts_iasl.c \ > fwts_interactive.c \ > + fwts_ioport.c \ > fwts_keymap.c \ > fwts_klog.c \ > fwts_list.c \ > diff --git a/src/lib/src/fwts_ioport.c b/src/lib/src/fwts_ioport.c > new file mode 100644 > index 0000000..bc6243e > --- /dev/null > +++ b/src/lib/src/fwts_ioport.c > @@ -0,0 +1,136 @@ > +/* > + * Copyright (C) 2013 Canonical > + * > + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > + > +#include <sys/io.h> > +#include <stdint.h> > +#include <signal.h> > +#include <setjmp.h> > + > +#include "fwts.h" > + > +static jmp_buf jmpbuf; > + > +/* > + * If we hit a SIGSEGV then the port read > + * failed and we longjmp back and return > + * FWTS_ERROR > + */ > +static void segv_handler(int dummy) > +{ > + FWTS_UNUSED(dummy); > + > + signal(SIGSEGV, SIG_DFL); > + longjmp(jmpbuf, 1); > +} > + > +/* > + * fwts_inb() > + * 8 bit port read, handle access errors > + */ > +int fwts_inb(uint32_t port, uint8_t *value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + *value = inb(port); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_inw() > + * 16 bit port read, handle access errors > + */ > +int fwts_inw(uint32_t port, uint16_t *value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + *value = inw(port); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_inl() > + * 32 bit port read, handle access errors > + */ > +int fwts_inl(uint32_t port, uint32_t *value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + *value = inl(port); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_outb() > + * 8 bit port write, handle access errors > + */ > +int fwts_outb(uint32_t port, uint8_t value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + outb(port, value); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_outw() > + * 16 bit port write, handle access errors > + */ > +int fwts_outw(uint32_t port, uint16_t value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + outw(port, value); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_outl() > + * 32 bit port write, handle access errors > + */ > +int fwts_outl(uint32_t port, uint32_t value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + outw(port, value); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > Acked-by: Ivan Hu <ivan.hu@canonical.com>
On 01/15/2013 04:25 AM, Colin King wrote: > From: Colin Ian King <colin.king@canonical.com> > > When testing on a Xen Dom0 I discovered that restricted port I/O causes > a segfault. This patch adds a thin layer of abstraction onto the > port read/write operations to catch segfaults and to return FWTS_ERROR. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/lib/include/fwts.h | 1 + > src/lib/include/fwts_ioport.h | 32 ++++++++++ > src/lib/src/Makefile.am | 1 + > src/lib/src/fwts_ioport.c | 136 ++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 170 insertions(+) > create mode 100644 src/lib/include/fwts_ioport.h > create mode 100644 src/lib/src/fwts_ioport.c > > diff --git a/src/lib/include/fwts.h b/src/lib/include/fwts.h > index 414252d..cbf9dd9 100644 > --- a/src/lib/include/fwts.h > +++ b/src/lib/include/fwts.h > @@ -78,5 +78,6 @@ > #include "fwts_battery.h" > #include "fwts_button.h" > #include "fwts_json.h" > +#include "fwts_ioport.h" > > #endif > diff --git a/src/lib/include/fwts_ioport.h b/src/lib/include/fwts_ioport.h > new file mode 100644 > index 0000000..183fb4a > --- /dev/null > +++ b/src/lib/include/fwts_ioport.h > @@ -0,0 +1,32 @@ > +/* > + * Copyright (C) 2013 Canonical > + * > + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > +#ifndef __FWTS_IO_PORT_H__ > +#define __FWTS_IO_PORT_H__ > + > +#include <stdint.h> > + > +int fwts_inb(uint32_t port, uint8_t *value); > +int fwts_inw(uint32_t port, uint16_t *value); > +int fwts_inl(uint32_t port, uint32_t *value); > + > +int fwts_outb(uint32_t port, uint8_t value); > +int fwts_outw(uint32_t port, uint16_t value); > +int fwts_outl(uint32_t port, uint32_t value); > + > +#endif > diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am > index a91d9ab..6a44641 100644 > --- a/src/lib/src/Makefile.am > +++ b/src/lib/src/Makefile.am > @@ -44,6 +44,7 @@ libfwts_la_SOURCES = \ > fwts_hwinfo.c \ > fwts_iasl.c \ > fwts_interactive.c \ > + fwts_ioport.c \ > fwts_keymap.c \ > fwts_klog.c \ > fwts_list.c \ > diff --git a/src/lib/src/fwts_ioport.c b/src/lib/src/fwts_ioport.c > new file mode 100644 > index 0000000..bc6243e > --- /dev/null > +++ b/src/lib/src/fwts_ioport.c > @@ -0,0 +1,136 @@ > +/* > + * Copyright (C) 2013 Canonical > + * > + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > + > +#include <sys/io.h> > +#include <stdint.h> > +#include <signal.h> > +#include <setjmp.h> > + > +#include "fwts.h" > + > +static jmp_buf jmpbuf; > + > +/* > + * If we hit a SIGSEGV then the port read > + * failed and we longjmp back and return > + * FWTS_ERROR > + */ > +static void segv_handler(int dummy) > +{ > + FWTS_UNUSED(dummy); > + > + signal(SIGSEGV, SIG_DFL); > + longjmp(jmpbuf, 1); > +} > + > +/* > + * fwts_inb() > + * 8 bit port read, handle access errors > + */ > +int fwts_inb(uint32_t port, uint8_t *value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + *value = inb(port); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_inw() > + * 16 bit port read, handle access errors > + */ > +int fwts_inw(uint32_t port, uint16_t *value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + *value = inw(port); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_inl() > + * 32 bit port read, handle access errors > + */ > +int fwts_inl(uint32_t port, uint32_t *value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + *value = inl(port); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_outb() > + * 8 bit port write, handle access errors > + */ > +int fwts_outb(uint32_t port, uint8_t value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + outb(port, value); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_outw() > + * 16 bit port write, handle access errors > + */ > +int fwts_outw(uint32_t port, uint16_t value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + outw(port, value); > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > + > +/* > + * fwts_outl() > + * 32 bit port write, handle access errors > + */ > +int fwts_outl(uint32_t port, uint32_t value) > +{ > + if (setjmp(jmpbuf) != 0) > + return FWTS_ERROR; > + > + signal(SIGSEGV, segv_handler); > + outw(port, value); Does it mean *outl* here? > + signal(SIGSEGV, SIG_DFL); > + > + return FWTS_OK; > +} > Everything else look good to me.
diff --git a/src/lib/include/fwts.h b/src/lib/include/fwts.h index 414252d..cbf9dd9 100644 --- a/src/lib/include/fwts.h +++ b/src/lib/include/fwts.h @@ -78,5 +78,6 @@ #include "fwts_battery.h" #include "fwts_button.h" #include "fwts_json.h" +#include "fwts_ioport.h" #endif diff --git a/src/lib/include/fwts_ioport.h b/src/lib/include/fwts_ioport.h new file mode 100644 index 0000000..183fb4a --- /dev/null +++ b/src/lib/include/fwts_ioport.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2013 Canonical + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#ifndef __FWTS_IO_PORT_H__ +#define __FWTS_IO_PORT_H__ + +#include <stdint.h> + +int fwts_inb(uint32_t port, uint8_t *value); +int fwts_inw(uint32_t port, uint16_t *value); +int fwts_inl(uint32_t port, uint32_t *value); + +int fwts_outb(uint32_t port, uint8_t value); +int fwts_outw(uint32_t port, uint16_t value); +int fwts_outl(uint32_t port, uint32_t value); + +#endif diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am index a91d9ab..6a44641 100644 --- a/src/lib/src/Makefile.am +++ b/src/lib/src/Makefile.am @@ -44,6 +44,7 @@ libfwts_la_SOURCES = \ fwts_hwinfo.c \ fwts_iasl.c \ fwts_interactive.c \ + fwts_ioport.c \ fwts_keymap.c \ fwts_klog.c \ fwts_list.c \ diff --git a/src/lib/src/fwts_ioport.c b/src/lib/src/fwts_ioport.c new file mode 100644 index 0000000..bc6243e --- /dev/null +++ b/src/lib/src/fwts_ioport.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2013 Canonical + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include <sys/io.h> +#include <stdint.h> +#include <signal.h> +#include <setjmp.h> + +#include "fwts.h" + +static jmp_buf jmpbuf; + +/* + * If we hit a SIGSEGV then the port read + * failed and we longjmp back and return + * FWTS_ERROR + */ +static void segv_handler(int dummy) +{ + FWTS_UNUSED(dummy); + + signal(SIGSEGV, SIG_DFL); + longjmp(jmpbuf, 1); +} + +/* + * fwts_inb() + * 8 bit port read, handle access errors + */ +int fwts_inb(uint32_t port, uint8_t *value) +{ + if (setjmp(jmpbuf) != 0) + return FWTS_ERROR; + + signal(SIGSEGV, segv_handler); + *value = inb(port); + signal(SIGSEGV, SIG_DFL); + + return FWTS_OK; +} + +/* + * fwts_inw() + * 16 bit port read, handle access errors + */ +int fwts_inw(uint32_t port, uint16_t *value) +{ + if (setjmp(jmpbuf) != 0) + return FWTS_ERROR; + + signal(SIGSEGV, segv_handler); + *value = inw(port); + signal(SIGSEGV, SIG_DFL); + + return FWTS_OK; +} + +/* + * fwts_inl() + * 32 bit port read, handle access errors + */ +int fwts_inl(uint32_t port, uint32_t *value) +{ + if (setjmp(jmpbuf) != 0) + return FWTS_ERROR; + + signal(SIGSEGV, segv_handler); + *value = inl(port); + signal(SIGSEGV, SIG_DFL); + + return FWTS_OK; +} + +/* + * fwts_outb() + * 8 bit port write, handle access errors + */ +int fwts_outb(uint32_t port, uint8_t value) +{ + if (setjmp(jmpbuf) != 0) + return FWTS_ERROR; + + signal(SIGSEGV, segv_handler); + outb(port, value); + signal(SIGSEGV, SIG_DFL); + + return FWTS_OK; +} + +/* + * fwts_outw() + * 16 bit port write, handle access errors + */ +int fwts_outw(uint32_t port, uint16_t value) +{ + if (setjmp(jmpbuf) != 0) + return FWTS_ERROR; + + signal(SIGSEGV, segv_handler); + outw(port, value); + signal(SIGSEGV, SIG_DFL); + + return FWTS_OK; +} + +/* + * fwts_outl() + * 32 bit port write, handle access errors + */ +int fwts_outl(uint32_t port, uint32_t value) +{ + if (setjmp(jmpbuf) != 0) + return FWTS_ERROR; + + signal(SIGSEGV, segv_handler); + outw(port, value); + signal(SIGSEGV, SIG_DFL); + + return FWTS_OK; +}