From patchwork Tue Jan 15 12:25:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colin Ian King X-Patchwork-Id: 212144 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id E20732C00A0 for ; Tue, 15 Jan 2013 23:25:40 +1100 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1Tv5aF-0006Ag-MG; Tue, 15 Jan 2013 12:25:39 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1Tv5aC-0006A8-Jp for fwts-devel@lists.ubuntu.com; Tue, 15 Jan 2013 12:25:36 +0000 Received: from cpc3-craw6-2-0-cust180.croy.cable.virginmedia.com ([77.100.248.181] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1Tv5aC-0003nD-FO for fwts-devel@lists.ubuntu.com; Tue, 15 Jan 2013 12:25:36 +0000 From: Colin King To: fwts-devel@lists.ubuntu.com Subject: [PATCH 1/3] lib: fwts_ioport: add helper functions to do port I/O Date: Tue, 15 Jan 2013 12:25:33 +0000 Message-Id: <1358252735-14227-2-git-send-email-colin.king@canonical.com> X-Mailer: git-send-email 1.8.0 In-Reply-To: <1358252735-14227-1-git-send-email-colin.king@canonical.com> References: <1358252735-14227-1-git-send-email-colin.king@canonical.com> X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: fwts-devel-bounces@lists.ubuntu.com Errors-To: fwts-devel-bounces@lists.ubuntu.com From: Colin Ian King 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 Acked-by: Keng-Yu Lin Acked-by: Ivan Hu --- 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 + +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 +#include +#include +#include + +#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; +}