summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--resources/bios_extract/patches/0001-dell_inspiron_1100_unpacker-Fix-minor-style-issues.patch132
-rw-r--r--resources/bios_extract/patches/0002-dell_inspiron_1100_unpacker-Convert-from-python-2-to.patch105
-rw-r--r--resources/bios_extract/patches/0003-dell_inspiron_1100_unpacker-Add-module-type-0x52.patch50
-rw-r--r--resources/git/revisions2
-rw-r--r--util/e6400-flash-unlock/e6400_flash_unlock.c9
-rw-r--r--util/nvmutil/nvmutil.c304
-rw-r--r--util/nvmutil/nvmutil.h96
-rw-r--r--util/spkmodem_recv/spkmodem-recv.c138
8 files changed, 242 insertions, 594 deletions
diff --git a/resources/bios_extract/patches/0001-dell_inspiron_1100_unpacker-Fix-minor-style-issues.patch b/resources/bios_extract/patches/0001-dell_inspiron_1100_unpacker-Fix-minor-style-issues.patch
deleted file mode 100644
index e00379bf..00000000
--- a/resources/bios_extract/patches/0001-dell_inspiron_1100_unpacker-Fix-minor-style-issues.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From d187ceefacc4909c4a3fdb8098878cb9bcd2c198 Mon Sep 17 00:00:00 2001
-From: Nicholas Chin <nic.c3.14@gmail.com>
-Date: Fri, 5 May 2023 19:34:29 -0600
-Subject: [PATCH 1/3] dell_inspiron_1100_unpacker: Fix minor style issues
-
-- Make indent width consistent
-- Use spaces around -= operator
-- Rename variable type to type_id to avoid shadowing the type method,
- though that method isn't ever used in this program
-
-Signed-off-by: Nicholas Chin <nic.c3.14@gmail.com>
-Change-Id: I2d47501845591e228b6c5d61c36ca2edce91d36a
----
- dell_inspiron_1100_unpacker.py | 84 +++++++++++++++++-----------------
- 1 file changed, 42 insertions(+), 42 deletions(-)
-
-diff --git a/dell_inspiron_1100_unpacker.py b/dell_inspiron_1100_unpacker.py
-index 3d5adf5..b12059b 100755
---- a/dell_inspiron_1100_unpacker.py
-+++ b/dell_inspiron_1100_unpacker.py
-@@ -19,7 +19,7 @@ def memcpy(arr1, off1, arr2, off2, count):
- raise Exception("Trying to write out of bounds")
- off1 += 1
- off2 += 1
-- count -=1
-+ count -= 1
-
- # looks like some lzss variation
- def dell_unpack(indata):
-@@ -64,58 +64,58 @@ def dell_unpack(indata):
- return dst.tostring()
-
- mod_types = {
-- 0x01: "Main ROM",
-- 0x0C: "Microcode update",
-+ 0x01: "Main ROM",
-+ 0x0C: "Microcode update",
- }
-
- print "Dell/Phoenix ROM BIOS PLUS unpacker"
- if len(sys.argv) < 2:
-- print "Usage: dell_unpack.py bios.bin [offset]"
-- sys.exit(1)
-+ print "Usage: dell_unpack.py bios.bin [offset]"
-+ sys.exit(1)
- fname = sys.argv[1]
- offs = 0
- f = open(fname, "rb").read()
- if len(sys.argv) > 2:
-- offs = int(sys.argv[2], 16)
-+ offs = int(sys.argv[2], 16)
- else:
-- offs = f.find("\xF0\x00Copyright 1985-\x02\x04\xF0\x0F8 Phoenix Technologies Ltd.")
-- if offs == -1:
-- print "Does not look like a Dell/Phoenix ROM BIOS PLUS"
-- sys.exit(2)
-- if f[offs-5] == '\x01':
-- hlen = 5 # 32-bit length
-- offs -= 5
-- fmt = "<BI"
-- elif f[offs-3] == '\x01':
-- hlen = 3 # 16-bit length
-- offs -= 3
-- fmt = "<BH"
-- else:
-- print "Unhandled format!"
-- sys.exit(1)
-- print "Found compressed module at %08X" % offs
-+ offs = f.find("\xF0\x00Copyright 1985-\x02\x04\xF0\x0F8 Phoenix Technologies Ltd.")
-+ if offs == -1:
-+ print "Does not look like a Dell/Phoenix ROM BIOS PLUS"
-+ sys.exit(2)
-+ if f[offs-5] == '\x01':
-+ hlen = 5 # 32-bit length
-+ offs -= 5
-+ fmt = "<BI"
-+ elif f[offs-3] == '\x01':
-+ hlen = 3 # 16-bit length
-+ offs -= 3
-+ fmt = "<BH"
-+ else:
-+ print "Unhandled format!"
-+ sys.exit(1)
-+ print "Found compressed module at %08X" % offs
- if offs > 0:
- fn = "EC.bin"
- print "%08X EC code, %08X %s" % (0, offs, fn)
- open(fn, "wb").write(f[:offs])
- while True:
-- type, leng = struct.unpack(fmt, f[offs:offs+hlen])
-- print "%08X type %02X" % (offs, type),
-- offs += hlen
-- if type == 0xFF:
-- print "<end of chain>"
-- break
-- data = f[offs:offs+leng]
-- offs += leng
-- if type != 0xC:
-- odata = dell_unpack(data)
-- else:
-- odata = data
-- print " %08X -> %08X" % (leng, len(odata)),
-- fn = "mod_%02X.bin" % type
-- print " %s" % fn,
-- if type in mod_types:
-- print "(%s)" % mod_types[type]
-- else:
-- print ""
-- open(fn, "wb").write(odata)
-+ type_id, leng = struct.unpack(fmt, f[offs:offs+hlen])
-+ print "%08X type %02X" % (offs, type_id),
-+ offs += hlen
-+ if type_id == 0xFF:
-+ print "<end of chain>"
-+ break
-+ data = f[offs:offs+leng]
-+ offs += leng
-+ if type_id != 0xC:
-+ odata = dell_unpack(data)
-+ else:
-+ odata = data
-+ print " %08X -> %08X" % (leng, len(odata)),
-+ fn = "mod_%02X.bin" % type_id
-+ print " %s" % fn,
-+ if type_id in mod_types:
-+ print "(%s)" % mod_types[type_id]
-+ else:
-+ print ""
-+ open(fn, "wb").write(odata)
---
-2.40.1
-
diff --git a/resources/bios_extract/patches/0002-dell_inspiron_1100_unpacker-Convert-from-python-2-to.patch b/resources/bios_extract/patches/0002-dell_inspiron_1100_unpacker-Convert-from-python-2-to.patch
deleted file mode 100644
index f49c8dbd..00000000
--- a/resources/bios_extract/patches/0002-dell_inspiron_1100_unpacker-Convert-from-python-2-to.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 34ecbda8cc75eecb747004520c9e0bd6de3c7723 Mon Sep 17 00:00:00 2001
-From: Nicholas Chin <nic.c3.14@gmail.com>
-Date: Fri, 5 May 2023 19:35:45 -0600
-Subject: [PATCH 2/3] dell_inspiron_1100_unpacker: Convert from python 2 to 3
-
-TEST: The output of the script is the same as the python 2 version when
-run against the Inspiron 1100 BIOS
-
-Signed-off-by: Nicholas Chin <nic.c3.14@gmail.com>
-Change-Id: I2ab9a72bc65121b1106e9867b7d58d1eefb0eb3d
----
- dell_inspiron_1100_unpacker.py | 34 +++++++++++++++++-----------------
- 1 file changed, 17 insertions(+), 17 deletions(-)
-
-diff --git a/dell_inspiron_1100_unpacker.py b/dell_inspiron_1100_unpacker.py
-index b12059b..5e43813 100755
---- a/dell_inspiron_1100_unpacker.py
-+++ b/dell_inspiron_1100_unpacker.py
-@@ -1,4 +1,4 @@
--#!/usr/bin/env python2
-+#!/usr/bin/env python3
- # Dell/Phoenix ROM BIOS PLUS unpacker
- # 2012-09-12 version 0.1
- # 2012-10-10 version 0.2 added support for older BIOSes with 16-bit length (Dell Inspiron 1100)
-@@ -61,16 +61,16 @@ def dell_unpack(indata):
- dstoff += count
- srcoff += count
-
-- return dst.tostring()
-+ return dst
-
- mod_types = {
- 0x01: "Main ROM",
- 0x0C: "Microcode update",
- }
-
--print "Dell/Phoenix ROM BIOS PLUS unpacker"
-+print("Dell/Phoenix ROM BIOS PLUS unpacker")
- if len(sys.argv) < 2:
-- print "Usage: dell_unpack.py bios.bin [offset]"
-+ print("Usage: dell_unpack.py bios.bin [offset]")
- sys.exit(1)
- fname = sys.argv[1]
- offs = 0
-@@ -78,32 +78,32 @@ f = open(fname, "rb").read()
- if len(sys.argv) > 2:
- offs = int(sys.argv[2], 16)
- else:
-- offs = f.find("\xF0\x00Copyright 1985-\x02\x04\xF0\x0F8 Phoenix Technologies Ltd.")
-+ offs = f.find(b"\xF0\x00Copyright 1985-\x02\x04\xF0\x0F8 Phoenix Technologies Ltd.")
- if offs == -1:
-- print "Does not look like a Dell/Phoenix ROM BIOS PLUS"
-+ print("Does not look like a Dell/Phoenix ROM BIOS PLUS")
- sys.exit(2)
-- if f[offs-5] == '\x01':
-+ if f[offs-5] == 0x01:
- hlen = 5 # 32-bit length
- offs -= 5
- fmt = "<BI"
-- elif f[offs-3] == '\x01':
-+ elif f[offs-3] == 0x01:
- hlen = 3 # 16-bit length
- offs -= 3
- fmt = "<BH"
- else:
-- print "Unhandled format!"
-+ print("Unhandled format!")
- sys.exit(1)
-- print "Found compressed module at %08X" % offs
-+ print("Found compressed module at %08X" % offs)
- if offs > 0:
- fn = "EC.bin"
-- print "%08X EC code, %08X %s" % (0, offs, fn)
-+ print("%08X EC code, %08X %s" % (0, offs, fn))
- open(fn, "wb").write(f[:offs])
- while True:
- type_id, leng = struct.unpack(fmt, f[offs:offs+hlen])
-- print "%08X type %02X" % (offs, type_id),
-+ print("%08X type %02X" % (offs, type_id), end=" ")
- offs += hlen
- if type_id == 0xFF:
-- print "<end of chain>"
-+ print("<end of chain>")
- break
- data = f[offs:offs+leng]
- offs += leng
-@@ -111,11 +111,11 @@ while True:
- odata = dell_unpack(data)
- else:
- odata = data
-- print " %08X -> %08X" % (leng, len(odata)),
-+ print(" %08X -> %08X" % (leng, len(odata)), end=" ")
- fn = "mod_%02X.bin" % type_id
-- print " %s" % fn,
-+ print(" %s" % fn, end=" ")
- if type_id in mod_types:
-- print "(%s)" % mod_types[type_id]
-+ print("(%s)" % mod_types[type_id])
- else:
-- print ""
-+ print("")
- open(fn, "wb").write(odata)
---
-2.40.1
-
diff --git a/resources/bios_extract/patches/0003-dell_inspiron_1100_unpacker-Add-module-type-0x52.patch b/resources/bios_extract/patches/0003-dell_inspiron_1100_unpacker-Add-module-type-0x52.patch
deleted file mode 100644
index 6de392be..00000000
--- a/resources/bios_extract/patches/0003-dell_inspiron_1100_unpacker-Add-module-type-0x52.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From b3868ed71a390f925eb22b926b9c735f7b84b383 Mon Sep 17 00:00:00 2001
-From: Nicholas Chin <nic.c3.14@gmail.com>
-Date: Sat, 6 May 2023 11:14:45 -0600
-Subject: [PATCH 3/3] dell_inspiron_1100_unpacker: Add module type 0x52
-
-The module with type 0x52 in the Latitude E6400 BIOS is the EC firmware,
-and is not compressed. The current behavior tries to decompress this
-module leading to an index out of bounds error at runtime, so add a new
-condition to avoid decompressing it. This assumes type 0x52 is always
-used for EC firmware.
-
-The current behavior also assumes all the data before the first module
-is EC firmware, which was probably true for the Inspiron 1100, but for
-the E6400 the EC firmware is in module 0x52. However, for simplicity an
-exception is not made for this behavior, so the extracted EC.bin should
-just be treated as spurious data for the E6400.
-
-TEST: Inspiron 1100 BIOS is still unpacked correctly, Latitude E6400
-BIOS unpacks without runtime errors.
-
-Signed-off-by: Nicholas Chin <nic.c3.14@gmail.com>
-Change-Id: I3152150b7dea4d79840c61683692c65b1311cce2
----
- dell_inspiron_1100_unpacker.py | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/dell_inspiron_1100_unpacker.py b/dell_inspiron_1100_unpacker.py
-index 5e43813..3589550 100755
---- a/dell_inspiron_1100_unpacker.py
-+++ b/dell_inspiron_1100_unpacker.py
-@@ -66,6 +66,7 @@ def dell_unpack(indata):
- mod_types = {
- 0x01: "Main ROM",
- 0x0C: "Microcode update",
-+ 0x52: "EC firmware"
- }
-
- print("Dell/Phoenix ROM BIOS PLUS unpacker")
-@@ -107,7 +108,7 @@ while True:
- break
- data = f[offs:offs+leng]
- offs += leng
-- if type_id != 0xC:
-+ if type_id != 0xC and type_id != 0x52:
- odata = dell_unpack(data)
- else:
- odata = data
---
-2.40.1
-
diff --git a/resources/git/revisions b/resources/git/revisions
index 09857823..3ad9759c 100644
--- a/resources/git/revisions
+++ b/resources/git/revisions
@@ -52,7 +52,7 @@
}
{bios_extract}{
- rev: effb120babde7e351c253f7c485848c8ce455dc0
+ rev: 0a7bc1d71735ef97b00dfec0fd54a02fcc5d1bb0
loc: bios_extract
url: https://review.coreboot.org/bios_extract
}
diff --git a/util/e6400-flash-unlock/e6400_flash_unlock.c b/util/e6400-flash-unlock/e6400_flash_unlock.c
index 9302d099..9488a67e 100644
--- a/util/e6400-flash-unlock/e6400_flash_unlock.c
+++ b/util/e6400-flash-unlock/e6400_flash_unlock.c
@@ -44,7 +44,6 @@ void send_ec_cmd(uint8_t cmd);
void wait_ec(void);
int get_gbl_smi_en(void);
int set_gbl_smi_en(int enable);
-/* uint8_t read_ec_reg(uint8_t index); */
#define EC_INDEX 0x910
#define EC_DATA 0x911
@@ -157,11 +156,3 @@ set_gbl_smi_en(int enable)
return (get_gbl_smi_en() == enable);
}
-/*
-uint8_t
-read_ec_reg(uint8_t index)
-{
- outb(index, EC_INDEX);
- return inb(EC_DATA);
-}
-*/
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c
index a489dd8d..2af10373 100644
--- a/util/nvmutil/nvmutil.c
+++ b/util/nvmutil/nvmutil.c
@@ -1,180 +1,76 @@
-/*
- * Copyright (C) 2022, 2023 Leah Rowe <info@minifree.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
+/* Copyright (c) 2022, 2023 Leah Rowe <info@minifree.org> */
+/* SPDX-License-Identifier: MIT */
-/*
- * This file is part of Libreboot. See:
- * https://libreboot.org/docs/install/nvmutil.html
- */
-
-#include <sys/stat.h>
-
-#include <dirent.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-void readGbeFile(int *fd, const char *path, int flags,
- size_t nr);
-void cmd_setmac(const char *strMac);
-int invalidMacAddress(const char *strMac, uint16_t *mac);
-uint8_t hextonum(char chs);
-uint8_t rhex(void);
-void cmd_dump(void);
-void showmac(int partnum);
-void hexdump(int partnum);
-void cmd_setchecksum(void);
-void cmd_brick(void);
-void cmd_swap(void);
-void cmd_copy(void);
-int validChecksum(int partnum);
-uint16_t word(int pos16, int partnum);
-void setWord(int pos16, int partnum, uint16_t val16);
-void byteswap(int n, int partnum);
-void writeGbeFile(int *fd, const char *filename, size_t nw);
-
-#define FILENAME argv[1]
-#define COMMAND argv[2]
-#define MAC_ADDRESS argv[3]
-#define PARTNUM argv[3]
-#define SIZE_4KB 0x1000
-#define SIZE_8KB 0x2000
-
-uint16_t buf16[SIZE_4KB];
-uint8_t *buf;
-size_t gbe[2];
-uint8_t skipread[2] = {0, 0};
-
-int part, gbeFileModified = 0;
-uint8_t nvmPartModified[2] = {0, 0};
-
-uint16_t test;
-uint8_t big_endian;
+#include "nvmutil.h"
int
main(int argc, char *argv[])
{
- size_t nr = 128;
- int fd, flags = O_RDWR;
- void (*cmd)(void) = NULL;
- const char *strMac = NULL, *strRMac = "??:??:??:??:??:??";
-
-#ifdef HAVE_PLEDGE /* openbsd */
- if (pledge("stdio wpath", NULL) == -1)
- err(errno, "pledge");
-#endif
-
- buf = (uint8_t *) &buf16;
- gbe[1] = (gbe[0] = (size_t) buf) + SIZE_4KB;
-
- test = 1;
- big_endian = ((uint8_t *) &test)[0] ^ 1;
-
- if (argc == 3) {
- if (strcmp(COMMAND, "dump") == 0) {
-#ifdef HAVE_PLEDGE /* openbsd */
- if (pledge("stdio rpath", NULL) == -1)
- err(errno, "pledge");
-#endif
- flags = O_RDONLY;
- cmd = &cmd_dump;
- } else if (strcmp(COMMAND, "setmac") == 0) {
- strMac = (char *) strRMac; /* random mac address */
- } else if (strcmp(COMMAND, "swap") == 0) {
- cmd = &cmd_swap;
- nr = SIZE_4KB;
- }
- } else if (argc == 4) {
- if (strcmp(COMMAND, "setmac") == 0) {
- strMac = MAC_ADDRESS; /* user-supplied mac address */
- } else if ((!((part = PARTNUM[0] - '0') == 0 || part == 1))
- || PARTNUM[1]) { /* only allow '1' or '0' */
- errno = EINVAL;
- } else if (strcmp(COMMAND, "setchecksum") == 0) {
- cmd = &cmd_setchecksum;
- } else if (strcmp(COMMAND, "brick") == 0) {
- cmd = &cmd_brick;
- } else if (strcmp(COMMAND, "copy") == 0) {
- cmd = &cmd_copy;
- nr = SIZE_4KB;
- }
+ xpledge("stdio rpath wpath unveil", NULL);
+ xunveil("/dev/urandom", "r");
+ err_if((errno = argc < 3 ? EINVAL : errno));
+ if ((flags = (strcmp(COMMAND, "dump") == 0) ? O_RDONLY : flags)
+ == O_RDONLY) {
+ xunveil(FILENAME, "r");
+ xpledge("stdio rpath", NULL);
+ } else {
+ xunveil(FILENAME, "rw");
+ xpledge("stdio rpath wpath", NULL);
}
-
- if ((strMac == NULL) && (cmd == NULL))
- errno = EINVAL;
-
- if (errno == 0) {
- skipread[part ^ 1] = (cmd == &cmd_copy) |
- (cmd == &cmd_setchecksum) | (cmd == &cmd_brick);
- readGbeFile(&fd, FILENAME, flags, nr);
- if (strMac != NULL)
- cmd_setmac(strMac); /* nvm gbe.bin setmac */
- else if (cmd != NULL)
- (*cmd)(); /* all other commands except setmac */
- writeGbeFile(&fd, FILENAME, nr);
- }
-
- if ((errno != 0) && (cmd != &cmd_dump))
- err(errno, NULL);
+ openFiles(FILENAME);
+ xpledge("stdio", NULL);
+
+ for (int i = 0; i < 6; i++)
+ if (strcmp(COMMAND, op[i].str) == 0)
+ if ((cmd = argc >= op[i].args ? op[i].cmd : NULL))
+ break;
+ if (cmd == cmd_setmac)
+ strMac = (argc > 3) ? MAC_ADDRESS : strRMac;
+ else if ((cmd != NULL) && (argc > 3))
+ err_if((errno = (!((part = PARTNUM[0] - '0') == 0 || part == 1))
+ || PARTNUM[1] ? EINVAL : errno));
+ err_if((errno = (cmd == NULL) ? EINVAL : errno));
+
+ readGbeFile(FILENAME);
+ (*cmd)();
+
+ if ((gbeFileModified) && (flags != O_RDONLY))
+ writeGbeFile(FILENAME);
+ err_if((errno != 0) && (cmd != &cmd_dump));
return errno;
}
void
-readGbeFile(int *fd, const char *path, int flags, size_t nr)
+openFiles(const char *path)
{
struct stat st;
- if (opendir(path) != NULL)
- err(errno = EISDIR, "%s", path);
- else if (((*fd) = open(path, flags)) == -1)
- err(errno, "%s", path);
- else if (fstat((*fd), &st) == -1)
- err(errno, "%s", path);
- else if ((st.st_size != SIZE_8KB))
+ xopen(fd, path, flags);
+ if ((st.st_size != SIZE_8KB))
err(errno = ECANCELED, "File `%s` not 8KiB", path);
- else if (errno == ENOTDIR)
- errno = 0;
+ xopen(rfd, "/dev/urandom", O_RDONLY);
+ errno = errno != ENOTDIR ? errno : 0;
+}
+void
+readGbeFile(const char *path)
+{
+ nf = ((cmd == cmd_swap) || (cmd == cmd_copy)) ? SIZE_4KB : nf;
+ skipread[part ^ 1] = (cmd == &cmd_copy) | (cmd == &cmd_setchecksum)
+ | (cmd == &cmd_brick);
+ gbe[1] = (gbe[0] = (size_t) buf) + SIZE_4KB;
for (int p = 0; p < 2; p++) {
if (skipread[p])
continue;
- if (pread((*fd), (uint8_t *) gbe[p], nr, p << 12) == -1)
- err(errno, "%s", path);
- if (big_endian)
- byteswap(nr, p);
+ xpread(fd, (uint8_t *) gbe[p], nf, p << 12, path);
+ handle_endianness(p);
}
}
void
-cmd_setmac(const char *strMac)
+cmd_setmac(void)
{
- uint16_t mac[3] = {0, 0, 0};
if (invalidMacAddress(strMac, mac))
err(errno = ECANCELED, "Bad MAC address");
-
for (int partnum = 0; partnum < 2; partnum++) {
if (validChecksum(part = partnum)) {
for (int w = 0; w < 3; w++)
@@ -187,10 +83,9 @@ cmd_setmac(const char *strMac)
int
invalidMacAddress(const char *strMac, uint16_t *mac)
{
- uint8_t h;
uint64_t total = 0;
if (strnlen(strMac, 20) == 17) {
- for (int i = 0; i < 16; i += 3) {
+ for (uint8_t h, i = 0; i < 16; i += 3) {
if (i != 15)
if (strMac[i + 2] != ':')
return 1;
@@ -202,7 +97,7 @@ invalidMacAddress(const char *strMac, uint16_t *mac)
if (strMac[i + nib] == '?')
h = (h & 0xE) | 2; /* local, unicast */
mac[byte >> 1] |= ((uint16_t ) h)
- << ((8 * (byte % 2)) + (4 * (nib ^ 1)));
+ << ((8 * (byte % 2)) + (4 * (nib ^ 1)));
}
}}
return ((total == 0) | (mac[0] & 1)); /* multicast/all-zero banned */
@@ -217,50 +112,35 @@ hextonum(char ch)
return ch - 'A' + 10;
else if ((ch >= 'a') && (ch <= 'f'))
return ch - 'a' + 10;
- else if (ch == '?')
- return rhex(); /* random number */
- else
- return 16;
+ return (ch == '?') ? rhex() : 16;
}
uint8_t
rhex(void)
{
- static int rfd = -1;
- static uint64_t rnum = 0;
- if (rnum == 0) {
- if (rfd == -1)
- if ((rfd = open("/dev/urandom", O_RDONLY)) == -1)
- err(errno, "/dev/urandom");
- if (read(rfd, (uint8_t *) &rnum, 8) == -1)
- err(errno, "/dev/urandom");
- }
- uint8_t rval = (uint8_t) (rnum & 0xf);
- rnum >>= 4;
- return rval;
+ static uint8_t n = 0, rnum[16];
+ if (!n)
+ xpread(rfd, (uint8_t *) &rnum, (n = 15) + 1, 0, "/dev/urandom");
+ return rnum[n--] & 0xf;
}
void
cmd_dump(void)
{
- int partnum, numInvalid = 0;
- for (partnum = 0; partnum < 2; partnum++) {
+ for (int partnum = 0, numInvalid = 0; partnum < 2; partnum++) {
if (!validChecksum(partnum))
++numInvalid;
printf("MAC (part %d): ", partnum);
- showmac(partnum);
- hexdump(partnum);
+ showmac(partnum), hexdump(partnum);
+ errno = ((numInvalid < 2) && (partnum)) ? 0 : errno;
}
- if (numInvalid < 2)
- errno = 0;
}
void
showmac(int partnum)
{
- uint16_t val16;
for (int c = 0; c < 3; c++) {
- val16 = word(c, partnum);
+ uint16_t val16 = word(c, partnum);
printf("%02x:%02x", val16 & 0xff, val16 >> 8);
printf(c == 2 ? "\n" : ":");
}
@@ -274,8 +154,7 @@ hexdump(int partnum)
for (int c = 0; c < 8; c++) {
uint16_t val16 = word((row << 3) + c, partnum);
printf(" %02x%02x", val16 >> 8, val16 & 0xff);
- }
- printf("\n");
+ } printf("\n");
}
}
@@ -298,18 +177,16 @@ cmd_brick(void)
void
cmd_swap(void)
{
- gbe[0] ^= gbe[1]; /* speedhack: swap ptr, not words */
- gbe[1] ^= gbe[0];
- gbe[0] ^= gbe[1];
- gbeFileModified = nvmPartModified[0] = nvmPartModified[1]
- = validChecksum(1) | validChecksum(0);
+ if ((gbeFileModified = nvmPartModified[0] = nvmPartModified[1]
+ = validChecksum(1) | validChecksum(0)))
+ xorswap(gbe[0], gbe[1]); /* speedhack: swap ptr, not words */
}
void
cmd_copy(void)
{
- gbe[part ^ 1] = gbe[part]; /* speedhack: copy ptr, not words */
- gbeFileModified = nvmPartModified[part ^ 1] = validChecksum(part);
+ if ((gbeFileModified = nvmPartModified[part ^ 1] = validChecksum(part)))
+ gbe[part ^ 1] = gbe[part]; /* speedhack: copy ptr, not words */
}
int
@@ -324,53 +201,30 @@ validChecksum(int partnum)
return (errno = ECANCELED) & 0;
}
-uint16_t
-word(int pos16, int partnum)
-{
- return buf16[pos16 + (partnum << 11)];
-}
-
void
setWord(int pos16, int partnum, uint16_t val16)
{
- gbeFileModified = 1;
- if (word(pos16, partnum) == val16)
- return;
- buf16[pos16 + (partnum << 11)] = val16;
- nvmPartModified[partnum] = 1;
+ if ((gbeFileModified = 1) && word(pos16, partnum) != val16)
+ nvmPartModified[partnum] = 1 | (word(pos16, partnum) = val16);
}
void
-byteswap(int n, int partnum)
+xorswap_buf(int partnum)
{
- int b1, b2, wcount = n >> 1;
uint8_t *nbuf = (uint8_t *) gbe[partnum];
- for (int w = 0; w < wcount; w++) {
- b1 = b2 = w << 1;
- nbuf[b1] ^= nbuf[++b2]; /* xor swap */
- nbuf[b2] ^= nbuf[b1];
- nbuf[b1] ^= nbuf[b2];
- }
+ for (size_t w = 0; w < (nf >> 1); w++)
+ xorswap(nbuf[w << 1], nbuf[(w << 1) + 1]);
}
void
-writeGbeFile(int *fd, const char *filename, size_t nw)
+writeGbeFile(const char *filename)
{
- if (gbeFileModified)
- errno = 0;
- for (int p = 0; p < 2; p++) {
- if (gbe[0] > gbe[1])
- p ^= 1; /* speedhack: write sequentially on-disk */
- if (!nvmPartModified[p])
- goto next_part;
- if (big_endian)
- byteswap(nw, p);
- if (pwrite((*fd), (uint8_t *) gbe[p], nw, p << 12) == -1)
- err(errno, "%s", filename);
-next_part:
- if (gbe[0] > gbe[1])
- p ^= 1; /* speedhack: write sequentially on-disk */
+ errno = 0;
+ for (int x = gbe[0] > gbe[1] ? 1 : 0, p = 0; p < 2; p++, x ^= 1) {
+ if (!nvmPartModified[x])
+ continue;
+ handle_endianness(x);
+ xpwrite(fd, (uint8_t *) gbe[x], nf, x << 12, filename);
}
- if (close((*fd)))
- err(errno, "%s", filename);
+ xclose(fd, filename);
}
diff --git a/util/nvmutil/nvmutil.h b/util/nvmutil/nvmutil.h
new file mode 100644
index 00000000..3f084da4
--- /dev/null
+++ b/util/nvmutil/nvmutil.h
@@ -0,0 +1,96 @@
+/* Copyright (c) 2022, 2023 Leah Rowe <info@minifree.org> */
+/* SPDX-License-Identifier: MIT */
+
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+void openFiles(const char *path);
+void readGbeFile(const char *path);
+void cmd_setmac(void);
+int invalidMacAddress(const char *strMac, uint16_t *mac);
+uint8_t hextonum(char chs);
+uint8_t rhex(void);
+void cmd_dump(void);
+void showmac(int partnum);
+void hexdump(int partnum);
+void cmd_setchecksum(void);
+void cmd_brick(void);
+void cmd_swap(void);
+void cmd_copy(void);
+int validChecksum(int partnum);
+void setWord(int pos16, int partnum, uint16_t val16);
+void xorswap_buf(int partnum);
+void writeGbeFile(const char *filename);
+
+#define FILENAME argv[1]
+#define COMMAND argv[2]
+#define MAC_ADDRESS argv[3]
+#define PARTNUM argv[3]
+#define SIZE_4KB 0x1000
+#define SIZE_8KB 0x2000
+
+uint16_t buf16[SIZE_4KB], mac[3] = {0, 0, 0};
+uint8_t *buf = (uint8_t *) &buf16;
+size_t nf = 128, gbe[2];
+uint8_t nvmPartModified[2] = {0, 0}, skipread[2] = {0, 0};
+int endian = 1, flags = O_RDWR, rfd, fd, part, gbeFileModified = 0;
+
+const char *strMac = NULL, *strRMac = "??:??:??:??:??:??";
+
+typedef struct op {
+ char *str;
+ void (*cmd)(void);
+ int args;
+} op_t;
+op_t op[] = {
+{ .str = "dump", .cmd = cmd_dump, .args = 3},
+{ .str = "setmac", .cmd = cmd_setmac, .args = 3},
+{ .str = "swap", .cmd = cmd_swap, .args = 3},
+{ .str = "copy", .cmd = cmd_copy, .args = 4},
+{ .str = "brick", .cmd = cmd_brick, .args = 4},
+{ .str = "setchecksum", .cmd = cmd_setchecksum, .args = 4},
+};
+void (*cmd)(void) = NULL;
+
+#define ERR() errno = errno ? errno : ECANCELED
+#define err_if(x) if (x) err(ERR(), NULL)
+
+#define xopen(f,l,p) if (opendir(l) != NULL) err(errno = EISDIR, "%s", l); \
+ if ((f = open(l, p)) == -1) err(ERR(), "%s", l); \
+ if (fstat(f, &st) == -1) err(ERR(), "%s", l)
+#define xpread(f, b, n, o, l) if (pread(f, b, n, o) == -1) err(ERR(), "%s", l)
+#define handle_endianness(r) if (((uint8_t *) &endian)[0] ^ 1) xorswap_buf(r)
+#define xpwrite(f, b, n, o, l) if (pwrite(f, b, n, o) == -1) err(ERR(), "%s", l)
+#define xclose(f, l) if (close(f) == -1) err(ERR(), "%s", l)
+
+#define xorswap(x, y) x ^= y, y ^= x, x ^= y
+#define word(pos16, partnum) buf16[pos16 + (partnum << 11)]
+
+void
+xpledge(const char *promises, const char *execpromises)
+{
+ (void)promises; (void)execpromises;
+#ifdef __OpenBSD__
+ if (pledge(promises, execpromises) == -1)
+ err(ERR(), "pledge");
+#endif
+}
+
+void
+xunveil(const char *path, const char *permissions)
+{
+ (void)path; (void)permissions;
+#ifdef __OpenBSD__
+ if (unveil(path, permissions) == -1)
+ err(ERR(), "unveil");
+#endif
+}
diff --git a/util/spkmodem_recv/spkmodem-recv.c b/util/spkmodem_recv/spkmodem-recv.c
index 30e13d8a..7de911ec 100644
--- a/util/spkmodem_recv/spkmodem-recv.c
+++ b/util/spkmodem_recv/spkmodem-recv.c
@@ -19,117 +19,111 @@
#define FREQ_DATA_MAX 60
#define THRESHOLD 500
-#define DEBUG 0
-#define FLUSH_TIMEOUT 1
+#define ERR() (errno = errno ? errno : ECANCELED)
+#define reset_char() ascii = 0, ascii_bit = 7
-signed short frame[2 * SAMPLES_PER_FRAME];
-signed short pulse[2 * SAMPLES_PER_FRAME];
-int f1, f2, lp, ascii_bit = 7;
+signed short frame[2 * SAMPLES_PER_FRAME], pulse[2 * SAMPLES_PER_FRAME];
+int ringpos, debug, freq_data, freq_separator, sample_count, ascii_bit = 7;
char ascii = 0;
void handle_audio(void);
-void print_char(void);
void fetch_sample(void);
+void read_frame(void);
+int set_ascii_bit(void);
+void print_char(void);
+void print_stats(void);
int
main(int argc, char *argv[])
{
int c;
-
-#ifdef HAVE_PLEDGE
+#ifdef __OpenBSD__
if (pledge("stdio", NULL) == -1)
- err(errno, "pledge");
+ err(ERR(), "pledge");
#endif
-
- while ((c = getopt(argc, argv, "u")) != -1) {
- switch (c) {
- case 'u':
- setvbuf(stdout, NULL, _IONBF, 0);
- break;
- default:
+ while ((c = getopt(argc, argv, "d")) != -1) {
+ if (c != 'd')
err(errno = EINVAL, NULL);
- }
+ debug = 1;
}
-
+ setvbuf(stdout, NULL, _IONBF, 0);
while (!feof(stdin))
handle_audio();
-
+ if (errno && debug)
+ err(errno, "Unhandled error, errno %d", errno);
return errno;
}
void
handle_audio(void)
{
- static int llp = 0;
-
- if (lp > (3 * SAMPLES_PER_FRAME)) {
- ascii_bit = 7;
- ascii = 0;
- lp = 0;
- llp++;
- }
- if (llp == FLUSH_TIMEOUT)
- if (fflush(stdout) == EOF)
- err(errno, NULL);
-
- if ((f2 <= FREQ_SEP_MIN) || (f2 >= FREQ_SEP_MAX)
- || (f1 <= FREQ_DATA_MIN) || (f1 >= FREQ_DATA_MAX)) {
+ if (sample_count > (3 * SAMPLES_PER_FRAME))
+ sample_count = reset_char();
+ if ((freq_separator <= FREQ_SEP_MIN) || (freq_separator >= FREQ_SEP_MAX)
+ || (freq_data <= FREQ_DATA_MIN) || (freq_data >= FREQ_DATA_MAX)) {
fetch_sample();
return;
}
- print_char();
-
- lp = 0;
- llp = 0;
- for (int i = 0; i < SAMPLES_PER_FRAME; i++)
+ if (set_ascii_bit() < 0)
+ print_char();
+ sample_count = 0;
+ for (int sample = 0; sample < SAMPLES_PER_FRAME; sample++)
fetch_sample();
}
void
fetch_sample(void)
{
- static int ringpos = 0;
-
- f1 -= pulse[ringpos];
- f1 += pulse[(ringpos + SAMPLES_PER_FRAME) % (2 * SAMPLES_PER_FRAME)];
- f2 -= pulse[(ringpos + SAMPLES_PER_FRAME) % (2 * SAMPLES_PER_FRAME)];
- if (fread(frame + ringpos, 1, sizeof(frame[0]), stdin)
- != sizeof(frame[0]))
- err(errno = ECANCELED, "Could not read frame.");
+ freq_data -= pulse[ringpos];
+ freq_data += pulse[(ringpos + SAMPLES_PER_FRAME)
+ % (2 * SAMPLES_PER_FRAME)];
+ freq_separator -= pulse[(ringpos + SAMPLES_PER_FRAME)
+ % (2 * SAMPLES_PER_FRAME)];
+
+ read_frame();
+ if ((pulse[ringpos] = (abs(frame[ringpos]) > THRESHOLD) ? 1 : 0))
+ ++freq_separator;
+ ++ringpos;
+ ringpos %= 2 * SAMPLES_PER_FRAME;
+ ++sample_count;
+}
- if (abs(frame[ringpos]) > THRESHOLD) { /* rising/falling edge(pulse) */
- pulse[ringpos] = 1;
- f2++;
- } else {
- pulse[ringpos] = 0;
- }
+void
+read_frame(void)
+{
+ if ((fread(frame + ringpos, 1, sizeof(frame[0]), stdin)
+ != sizeof(frame[0])) || (ferror(stdin) != 0))
+ err(ERR(), "Could not read from frame.");
+}
- ringpos++;
- ringpos %= 2 * SAMPLES_PER_FRAME;
- lp++;
+int
+set_ascii_bit(void)
+{
+ if (debug)
+ print_stats();
+ if (freq_data < FREQ_DATA_THRESHOLD)
+ ascii |= (1 << ascii_bit);
+ --ascii_bit;
+ return ascii_bit;
}
void
print_char(void)
{
-#if DEBUG
- long stdin_pos = 0;
- if ((stdin_pos = ftell(stdin)) == -1)
- err(errno, NULL);
- printf ("%d %d %d @%ld\n", f1, f2, FREQ_DATA_THRESHOLD,
- stdin_pos - sizeof(frame));
-#endif
- if (f1 < FREQ_DATA_THRESHOLD)
- ascii |= (1 << ascii_bit);
- ascii_bit--;
- if (ascii_bit < 0) {
-#if DEBUG
+ if (debug)
printf("<%c, %x>", ascii, ascii);
-#else
+ else
printf("%c", ascii);
-#endif
- ascii_bit = 7;
- ascii = 0;
- }
+ reset_char();
+}
+
+void
+print_stats(void)
+{
+ long stdin_pos = 0;
+ if ((stdin_pos = ftell(stdin)) == -1)
+ err(ERR(), NULL);
+ printf ("%d %d %d @%ld\n", freq_data, freq_separator,
+ FREQ_DATA_THRESHOLD, stdin_pos - sizeof(frame));
}