Parcourir la source

Merge remote-tracking branch 'origin/main'

H. Peter Anvin il y a 1 an
Parent
commit
1d8d0ec880

+ 7 - 4
common/sysvars.c

@@ -213,7 +213,7 @@ static const char *sysvar_mac_tostr(sysvar_t from, char *buf)
     if (!m)
 	return NULL;
 
-    snprintf(buf, MAC_BUFLEN, "%x:%x:%x:%x:%x:%x",
+    snprintf(buf, MAC_BUFLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
 	     m[0], m[1], m[2], m[3], m[4], m[5]);
     return buf;
 }
@@ -362,13 +362,16 @@ bool setvar_fromstr(size_t var, const char *str)
     if (!type->fromstr(to, str))
 	return false;
 
-    if (var < (size_t)sysvar_changed)
-	sysvar_changed = (enum sysvar_enum)var;
-
     if (free_ptr)
 	free(free_ptr);
 
+    if (var < (size_t)sysvar_changed)
+	sysvar_changed = (enum sysvar_enum)var;
+
     sysvar_isset[var] = true;
+    if (type->update)
+	type->update(*to, true);
+
     return true;
 }
 

+ 8 - 0
common/sysvars.vars

@@ -41,6 +41,8 @@ wifi.ssid		str
 hostname		str
 max80.fpga		bool
 max80.fw.date		str
+max80.fw.esp32.arduino	str
+max80.fw.esp32.idf	str
 max80.hw.serial		str
 max80.hw.ver		str
 net.ap.clients		uint
@@ -62,3 +64,9 @@ net.sta.ip4.gw		ip
 net.sta.ip4.mask	ip
 net.sta.mac		mac
 net.sta.ssid		str
+heap.sram.free		uint
+heap.sram.max		uint
+heap.sram.size		uint
+heap.spiram.free	uint
+heap.spiram.max		uint
+heap.spiram.size	uint

+ 1 - 1
esp32/Makefile

@@ -23,7 +23,7 @@ ARDUINO_OPTS  = -b $(BOARD) \
 		--build-property 'build.defines=$(build_defines)' \
 		--build-property 'build.cdc_on_boot=1' \
 		--build-property 'build.msc_on_boot=0' \
-		--build-property 'build.dfu_on_boot=1' \
+		--build-property 'build.dfu_on_boot=0' \
 		--build-property 'build.partitions=min_spiffs'
 
 all: $(TARGET)

+ 10 - 0
esp32/max80/common.h

@@ -48,6 +48,15 @@ typedef void *token_t;
 typedef int (*read_func_t)(token_t token, void *buf, size_t len);
 typedef int (*write_func_t)(token_t token, const void *buf, size_t len);
 
+/*
+ * Bad SPIRAM memory?
+ */
+extern_c bool _spiram_broken;
+static inline bool spiram_broken(void)
+{
+    return _spiram_broken;
+}
+
 /*
  * Sleep thread...
  */
@@ -106,3 +115,4 @@ extern_c void print_time(const char *msg, const struct timeval *tv);
 extern_c volatile bool do_log_config_status;
 extern_c void __fmt_printf(2,3)
   logmsg(const char *module, const char *fmt, ...);
+extern_c void heap_info(void);

+ 17 - 25
esp32/max80/fwupdate.c

@@ -27,49 +27,41 @@
 #define FWUPDATE_STACK		8192
 #define FWUPDATE_PRIORITY	3
 
-static void heap_info(void)
+static inline void spz_heap_info(bool always)
 {
-#if DEBUG > 1
-    MSG("Heap: sram ");
-    MSG("%u/", heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL));
-    MSG("%u, spiram ", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
-    MSG("%u/", heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM));
-    MSG("%u\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
-#endif
+    if (DEBUG || always)
+	heap_info();
 }
 
-static void *spz_calloc(void *opaque, unsigned int items, unsigned int size)
-{
-    spz_stream *spz = opaque;
-    heap_info();
-    MSG("spz_calloc(%u,%u) = %u = ", items, size, items*size);
-    void *p = calloc(items, size);
-    CMSG("%p\n", p);
-    heap_info();
-    if (!p)
-	spz->err = Z_MEM_ERROR;
-    return p;
-}
 static void *spz_malloc(void *opaque, unsigned int size)
 {
     spz_stream *spz = opaque;
-    heap_info();
     MSG("spz_malloc(%u) = ", size);
     void *p = malloc(size);
     CMSG("%p\n", p);
-    heap_info();
-    if (!p)
+    spz_heap_info(!p);
+    if (!p) {
 	spz->err = Z_MEM_ERROR;
+	printf("[FWUP] Out of memory error!\n");
+    }
+    return p;
+}
+static void *spz_calloc(void *opaque, unsigned int items, unsigned int size)
+{
+    size_t bytes = items*size;
+    void *p = spz_malloc(opaque, bytes);
+    if (likely(p))
+	memset(p, 0, bytes);
+
     return p;
 }
 
 static void spz_free(void *opaque, void *ptr)
 {
-    heap_info();
     MSG("spz_free(%p)\n", ptr);
     (void)opaque;
     free(ptr);
-    heap_info();
+    spz_heap_info(false);
 }
 
 int spz_read_data(spz_stream *spz, void *buf, size_t len)

+ 2 - 0
esp32/max80/httpd.c

@@ -536,6 +536,8 @@ static void httpd_get_status_extra(FILE *f, httpd_req_t *req)
     }
     fprintf(f, "http.status.refresh=%lu\n", statref);
 
+    fprintf(f, "TZ=%s\n", notempty(getenv("TZ")));
+
     gettimeofday(&tv,NULL);
     const struct tm *tm = localtime(&tv.tv_sec);
     len = strftime(timebuf, sizeof timebuf, "localtime=%Y-%m-%d %H:%M:%S.", tm);

+ 47 - 11
esp32/max80/max80.ino

@@ -18,6 +18,7 @@
 
 #include <USB.h>
 #include <HardwareSerial.h>
+#include <core_version.h>
 
 #define PIN_USB_PWR_EN		7
 #define PIN_USB_PWR_SINK	8
@@ -43,14 +44,32 @@ void setup_usb_ids()
     USB.serialNumber(serial_number);
 }
 
-static void heap_info()
+bool _spiram_broken;
+
+void heap_info()
 {
     size_t il = heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL);
     size_t ia = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
+    size_t it = heap_caps_get_total_size(MALLOC_CAP_INTERNAL);
     size_t sl = heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM);
     size_t sa = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
-
-    printf("Heap: sram %zu/%zu, spiram %zu/%zu\n", il, ia, sl, sa);
+    size_t st = heap_caps_get_total_size(MALLOC_CAP_SPIRAM);
+
+    char msg_buffer[128];
+    snprintf(msg_buffer, sizeof msg_buffer,
+	     "Heap: sram %zu/%zu/%zu, spiram %zu/%zu/%zu\r\n",
+	     il, ia, it, sl, sa, st);
+
+    fputs(msg_buffer, stdout);
+    Serial.print(msg_buffer);
+
+    setvar_uint(status_heap_sram_max, il);
+    setvar_uint(status_heap_sram_free, ia);
+    setvar_uint(status_heap_sram_size, it);
+    setvar_uint(status_heap_spiram_max, sl);
+    setvar_uint(status_heap_spiram_free, sa);
+    setvar_uint(status_heap_spiram_size, st);
+    _spiram_broken = st == 0;
 }
 
 #if 0
@@ -95,18 +114,29 @@ static void init_hw()
     led_set(LED_BLUE, LED_FLASH);	// ESP32 software initializing
 }
 
+#define _tostring(x) #x
+#define tostring(x) _tostring(x)
+
+static const char fwdate[] = __DATE__ " " __TIME__;
+static const char arduino_esp32_ver[] = tostring(ARDUINO_ESP32_GIT_DESC);
+
+static void set_build_status_info()
+{
+    setvar_str(status_max80_fw_date, fwdate);
+    setvar_str(status_max80_fw_esp32_arduino, arduino_esp32_ver);
+    setvar_str(status_max80_fw_esp32_idf, IDF_VER);
+}
+
 void setup() {
-    const char *fwdate = __DATE__ " " __TIME__;
     init_hw();
 
     // Enable external PSRAM for heap
     heap_caps_malloc_extmem_enable(3000); // >= 3K allocations in PSRAM
-    heap_info();
 
     TTY::init();
-    heap_info();
-
+    Serial.print("\r\n*** Hello, World! ***\r\n");
     sysvar_init();
+    heap_info();
 
     printf("[FW]   MAX80 firmware compiled on %s\n", fwdate);
     printf("[PCB]  MAX80 board version: %s\n", board_info.version_str);
@@ -116,16 +146,21 @@ void setup() {
     Serial.println("MAX80 start");
 
     init_config();
-    setvar_str(status_max80_fw_date, fwdate);
+    set_build_status_info();
     fpga_service_init();
     fpga_service_enable(true);
-    SetupWiFi();
+    if (spiram_broken()) {
+	const char spiram_broken_msg[] =
+	    "WARNING: SPIRAM broken, not starting network\r\n";
+	fputs(spiram_broken_msg, stdout);
+	Serial.print(spiram_broken_msg);
+    } else {
+	SetupWiFi();
+    }
     Serial.println("[RDY]");
     sysvar_print_updates = true;
     do_log_config_status = true; // Print configuration from main loop
     led_set(LED_BLUE, LED_ON);	// Software ready
-
-    heap_info();
 }
 
 static inline char task_state(eTaskState state)
@@ -174,6 +209,7 @@ void loop() {
 
     if (do_log_config_status) {
 	do_log_config_status = false;
+	heap_info();
 	log_config_status();
     }
 

+ 7 - 5
esp32/max80/spiflash.c

@@ -354,12 +354,14 @@ int spiflash_write_spz(spz_stream *spz,
     pinMode(PIN_FPGA_READY,    INPUT);
     pinMode(PIN_FPGA_BOARD_ID, INPUT);
 
-    MSG("waiting for FPGA bypass to be ready..");
-    while (digitalRead(PIN_FPGA_READY) != LOW) {
-	CMSG(".");
-	yield();
+    if (digitalRead(PIN_FPGA_READY) == LOW) {
+	MSG("waiting for FPGA bypass to be ready..");
+	while (digitalRead(PIN_FPGA_READY) != LOW) {
+	    CMSG(".");
+	    yield();
+	}
+	CMSG("\n");
     }
-    CMSG("\n");
     MSG("FPGA bypass ready, board version v%c.\n",
 	digitalRead(PIN_FPGA_BOARD_ID) ? '1' : '2');
 

+ 7 - 4
esp32/max80/src/common/sysvars.c

@@ -213,7 +213,7 @@ static const char *sysvar_mac_tostr(sysvar_t from, char *buf)
     if (!m)
 	return NULL;
 
-    snprintf(buf, MAC_BUFLEN, "%x:%x:%x:%x:%x:%x",
+    snprintf(buf, MAC_BUFLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
 	     m[0], m[1], m[2], m[3], m[4], m[5]);
     return buf;
 }
@@ -362,13 +362,16 @@ bool setvar_fromstr(size_t var, const char *str)
     if (!type->fromstr(to, str))
 	return false;
 
-    if (var < (size_t)sysvar_changed)
-	sysvar_changed = (enum sysvar_enum)var;
-
     if (free_ptr)
 	free(free_ptr);
 
+    if (var < (size_t)sysvar_changed)
+	sysvar_changed = (enum sysvar_enum)var;
+
     sysvar_isset[var] = true;
+    if (type->update)
+	type->update(*to, true);
+
     return true;
 }
 

+ 9 - 0
esp32/max80/wifi.cpp

@@ -451,6 +451,15 @@ static void wifi_config_ap(void)
     uint8_t mac[6];
     static char ap_ssid[64];
 
+    // The default SoftAP MAC is totally useless, so try to
+    // set it to something more sensible...
+    WiFi.macAddress(mac);
+    uint8_t add = !!(mac[0] & 2);
+    mac[0] |= 2;		// Set local bit
+    mac[5] += add;		// Increment last byte if already local
+    esp_wifi_set_mac(WIFI_IF_AP, mac);
+
+    // Read it back to check what we got...
     WiFi.softAPmacAddress(mac);
     setvar_mac(status_net_ap_mac, mac);
 

BIN
esp32/output/max80.ino.bin


+ 75 - 12
esp32/www/tzlist

@@ -3,6 +3,7 @@ Africa/Accra=GMT0
 Africa/Addis_Ababa=EAT-3
 Africa/Algiers=CET-1
 Africa/Asmara=EAT-3
+Africa/Asmera=EAT-3
 Africa/Bamako=GMT0
 Africa/Bangui=WAT-1
 Africa/Banjul=GMT0
@@ -10,7 +11,7 @@ Africa/Bissau=GMT0
 Africa/Blantyre=CAT-2
 Africa/Brazzaville=WAT-1
 Africa/Bujumbura=CAT-2
-Africa/Cairo=EET-2
+Africa/Cairo=EET-2EEST,M4.5.5/0,M10.5.4/24
 Africa/Ceuta=CET-1CEST,M3.5.0,M10.5.0/3
 Africa/Conakry=GMT0
 Africa/Dakar=GMT0
@@ -45,6 +46,7 @@ Africa/Nouakchott=GMT0
 Africa/Ouagadougou=GMT0
 Africa/Porto-Novo=WAT-1
 Africa/Sao_Tome=GMT0
+Africa/Timbuktu=GMT0
 Africa/Tripoli=EET-2
 Africa/Tunis=CET-1
 Africa/Windhoek=CAT-2
@@ -54,7 +56,8 @@ America/Anguilla=AST4
 America/Antigua=AST4
 America/Aruba=AST4
 America/Atikokan=EST5
-America/Bahia_Banderas=CST6CDT,M4.1.0,M10.5.0
+America/Atka=HST10HDT,M3.2.0,M11.1.0
+America/Bahia_Banderas=CST6
 America/Barbados=AST4
 America/Belize=CST6
 America/Blanc-Sablon=AST4
@@ -63,7 +66,9 @@ America/Cambridge_Bay=MST7MDT,M3.2.0,M11.1.0
 America/Cancun=EST5
 America/Cayman=EST5
 America/Chicago=CST6CDT,M3.2.0,M11.1.0
-America/Chihuahua=MST7MDT,M4.1.0,M10.5.0
+America/Chihuahua=CST6
+America/Ciudad_Juarez=MST7MDT,M3.2.0,M11.1.0
+America/Coral_Harbour=EST5
 America/Costa_Rica=CST6
 America/Creston=MST7
 America/Curacao=AST4
@@ -75,7 +80,9 @@ America/Detroit=EST5EDT,M3.2.0,M11.1.0
 America/Dominica=AST4
 America/Edmonton=MST7MDT,M3.2.0,M11.1.0
 America/El_Salvador=CST6
+America/Ensenada=PST8PDT,M3.2.0,M11.1.0
 America/Fort_Nelson=MST7
+America/Fort_Wayne=EST5EDT,M3.2.0,M11.1.0
 America/Glace_Bay=AST4ADT,M3.2.0,M11.1.0
 America/Goose_Bay=AST4ADT,M3.2.0,M11.1.0
 America/Grand_Turk=EST5EDT,M3.2.0,M11.1.0
@@ -93,26 +100,30 @@ America/Indiana/Tell_City=CST6CDT,M3.2.0,M11.1.0
 America/Indiana/Vevay=EST5EDT,M3.2.0,M11.1.0
 America/Indiana/Vincennes=EST5EDT,M3.2.0,M11.1.0
 America/Indiana/Winamac=EST5EDT,M3.2.0,M11.1.0
+America/Indianapolis=EST5EDT,M3.2.0,M11.1.0
 America/Inuvik=MST7MDT,M3.2.0,M11.1.0
 America/Iqaluit=EST5EDT,M3.2.0,M11.1.0
 America/Jamaica=EST5
 America/Juneau=AKST9AKDT,M3.2.0,M11.1.0
 America/Kentucky/Louisville=EST5EDT,M3.2.0,M11.1.0
 America/Kentucky/Monticello=EST5EDT,M3.2.0,M11.1.0
+America/Knox_IN=CST6CDT,M3.2.0,M11.1.0
 America/Kralendijk=AST4
 America/Los_Angeles=PST8PDT,M3.2.0,M11.1.0
+America/Louisville=EST5EDT,M3.2.0,M11.1.0
 America/Lower_Princes=AST4
 America/Managua=CST6
 America/Marigot=AST4
 America/Martinique=AST4
 America/Matamoros=CST6CDT,M3.2.0,M11.1.0
-America/Mazatlan=MST7MDT,M4.1.0,M10.5.0
+America/Mazatlan=MST7
 America/Menominee=CST6CDT,M3.2.0,M11.1.0
-America/Merida=CST6CDT,M4.1.0,M10.5.0
+America/Merida=CST6
 America/Metlakatla=AKST9AKDT,M3.2.0,M11.1.0
-America/Mexico_City=CST6CDT,M4.1.0,M10.5.0
+America/Mexico_City=CST6
 America/Moncton=AST4ADT,M3.2.0,M11.1.0
-America/Monterrey=CST6CDT,M4.1.0,M10.5.0
+America/Monterrey=CST6
+America/Montreal=EST5EDT,M3.2.0,M11.1.0
 America/Montserrat=AST4
 America/Nassau=EST5EDT,M3.2.0,M11.1.0
 America/New_York=EST5EDT,M3.2.0,M11.1.0
@@ -121,7 +132,7 @@ America/Nome=AKST9AKDT,M3.2.0,M11.1.0
 America/North_Dakota/Beulah=CST6CDT,M3.2.0,M11.1.0
 America/North_Dakota/Center=CST6CDT,M3.2.0,M11.1.0
 America/North_Dakota/New_Salem=CST6CDT,M3.2.0,M11.1.0
-America/Ojinaga=MST7MDT,M3.2.0,M11.1.0
+America/Ojinaga=CST6CDT,M3.2.0,M11.1.0
 America/Panama=EST5
 America/Pangnirtung=EST5EDT,M3.2.0,M11.1.0
 America/Phoenix=MST7
@@ -132,7 +143,9 @@ America/Rainy_River=CST6CDT,M3.2.0,M11.1.0
 America/Rankin_Inlet=CST6CDT,M3.2.0,M11.1.0
 America/Regina=CST6
 America/Resolute=CST6CDT,M3.2.0,M11.1.0
+America/Santa_Isabel=PST8PDT,M3.2.0,M11.1.0
 America/Santo_Domingo=AST4
+America/Shiprock=MST7MDT,M3.2.0,M11.1.0
 America/Sitka=AKST9AKDT,M3.2.0,M11.1.0
 America/St_Barthelemy=AST4
 America/St_Johns=NST3:30NDT,M3.2.0,M11.1.0
@@ -148,25 +161,30 @@ America/Tijuana=PST8PDT,M3.2.0,M11.1.0
 America/Toronto=EST5EDT,M3.2.0,M11.1.0
 America/Tortola=AST4
 America/Vancouver=PST8PDT,M3.2.0,M11.1.0
+America/Virgin=AST4
 America/Whitehorse=MST7
 America/Winnipeg=CST6CDT,M3.2.0,M11.1.0
 America/Yakutat=AKST9AKDT,M3.2.0,M11.1.0
 America/Yellowknife=MST7MDT,M3.2.0,M11.1.0
 Antarctica/Macquarie=AEST-10AEDT,M10.1.0,M4.1.0/3
 Antarctica/McMurdo=NZST-12NZDT,M9.5.0,M4.1.0/3
+Antarctica/South_Pole=NZST-12NZDT,M9.5.0,M4.1.0/3
 Arctic/Longyearbyen=CET-1CEST,M3.5.0,M10.5.0/3
-Asia/Amman=EET-2EEST,M2.5.4/24,M10.5.5/1
 Asia/Beirut=EET-2EEST,M3.5.0/0,M10.5.0/0
-Asia/Damascus=EET-2EEST,M3.5.5/0,M10.5.5/0
+Asia/Calcutta=IST-5:30
+Asia/Chongqing=CST-8
+Asia/Chungking=CST-8
 Asia/Famagusta=EET-2EEST,M3.5.0/3,M10.5.0/4
-Asia/Gaza=EET-2EEST,M3.4.4/72,M10.4.4/25
-Asia/Hebron=EET-2EEST,M3.4.4/72,M10.4.4/25
+Asia/Gaza=EET-2EEST,M3.4.4/50,M10.4.4/50
+Asia/Harbin=CST-8
+Asia/Hebron=EET-2EEST,M3.4.4/50,M10.4.4/50
 Asia/Hong_Kong=HKT-8
 Asia/Jakarta=WIB-7
 Asia/Jayapura=WIT-9
 Asia/Jerusalem=IST-2IDT,M3.4.4/26,M10.5.0
 Asia/Karachi=PKT-5
 Asia/Kolkata=IST-5:30
+Asia/Macao=CST-8
 Asia/Macau=CST-8
 Asia/Makassar=WITA-8
 Asia/Manila=PST-8
@@ -176,25 +194,49 @@ Asia/Pyongyang=KST-9
 Asia/Seoul=KST-9
 Asia/Shanghai=CST-8
 Asia/Taipei=CST-8
+Asia/Tel_Aviv=IST-2IDT,M3.4.4/26,M10.5.0
 Asia/Tokyo=JST-9
+Asia/Ujung_Pandang=WITA-8
 Atlantic/Bermuda=AST4ADT,M3.2.0,M11.1.0
 Atlantic/Canary=WET0WEST,M3.5.0/1,M10.5.0
+Atlantic/Faeroe=WET0WEST,M3.5.0/1,M10.5.0
 Atlantic/Faroe=WET0WEST,M3.5.0/1,M10.5.0
+Atlantic/Jan_Mayen=CET-1CEST,M3.5.0,M10.5.0/3
 Atlantic/Madeira=WET0WEST,M3.5.0/1,M10.5.0
 Atlantic/Reykjavik=GMT0
 Atlantic/St_Helena=GMT0
+Australia/ACT=AEST-10AEDT,M10.1.0,M4.1.0/3
 Australia/Adelaide=ACST-9:30ACDT,M10.1.0,M4.1.0/3
 Australia/Brisbane=AEST-10
 Australia/Broken_Hill=ACST-9:30ACDT,M10.1.0,M4.1.0/3
+Australia/Canberra=AEST-10AEDT,M10.1.0,M4.1.0/3
+Australia/Currie=AEST-10AEDT,M10.1.0,M4.1.0/3
 Australia/Darwin=ACST-9:30
 Australia/Hobart=AEST-10AEDT,M10.1.0,M4.1.0/3
 Australia/Lindeman=AEST-10
 Australia/Melbourne=AEST-10AEDT,M10.1.0,M4.1.0/3
+Australia/NSW=AEST-10AEDT,M10.1.0,M4.1.0/3
+Australia/North=ACST-9:30
 Australia/Perth=AWST-8
+Australia/Queensland=AEST-10
+Australia/South=ACST-9:30ACDT,M10.1.0,M4.1.0/3
 Australia/Sydney=AEST-10AEDT,M10.1.0,M4.1.0/3
+Australia/Tasmania=AEST-10AEDT,M10.1.0,M4.1.0/3
+Australia/Victoria=AEST-10AEDT,M10.1.0,M4.1.0/3
+Australia/West=AWST-8
+Australia/Yancowinna=ACST-9:30ACDT,M10.1.0,M4.1.0/3
+Canada/Atlantic=AST4ADT,M3.2.0,M11.1.0
+Canada/Central=CST6CDT,M3.2.0,M11.1.0
+Canada/Eastern=EST5EDT,M3.2.0,M11.1.0
+Canada/Mountain=MST7MDT,M3.2.0,M11.1.0
+Canada/Newfoundland=NST3:30NDT,M3.2.0,M11.1.0
+Canada/Pacific=PST8PDT,M3.2.0,M11.1.0
+Canada/Saskatchewan=CST6
+Canada/Yukon=MST7
 Europe/Amsterdam=CET-1CEST,M3.5.0,M10.5.0/3
 Europe/Andorra=CET-1CEST,M3.5.0,M10.5.0/3
 Europe/Athens=EET-2EEST,M3.5.0/3,M10.5.0/4
+Europe/Belfast=GMT0BST,M3.5.0/1,M10.5.0
 Europe/Belgrade=CET-1CEST,M3.5.0,M10.5.0/3
 Europe/Berlin=CET-1CEST,M3.5.0,M10.5.0/3
 Europe/Bratislava=CET-1CEST,M3.5.0,M10.5.0/3
@@ -211,6 +253,8 @@ Europe/Helsinki=EET-2EEST,M3.5.0/3,M10.5.0/4
 Europe/Isle_of_Man=GMT0BST,M3.5.0/1,M10.5.0
 Europe/Jersey=GMT0BST,M3.5.0/1,M10.5.0
 Europe/Kaliningrad=EET-2
+Europe/Kiev=EET-2EEST,M3.5.0/3,M10.5.0/4
+Europe/Kirov=MSK-3
 Europe/Kyiv=EET-2EEST,M3.5.0/3,M10.5.0/4
 Europe/Lisbon=WET0WEST,M3.5.0/1,M10.5.0
 Europe/Ljubljana=CET-1CEST,M3.5.0,M10.5.0/3
@@ -236,11 +280,13 @@ Europe/Sofia=EET-2EEST,M3.5.0/3,M10.5.0/4
 Europe/Stockholm=CET-1CEST,M3.5.0,M10.5.0/3
 Europe/Tallinn=EET-2EEST,M3.5.0/3,M10.5.0/4
 Europe/Tirane=CET-1CEST,M3.5.0,M10.5.0/3
+Europe/Tiraspol=EET-2EEST,M3.5.0,M10.5.0/3
 Europe/Uzhgorod=EET-2EEST,M3.5.0/3,M10.5.0/4
 Europe/Vaduz=CET-1CEST,M3.5.0,M10.5.0/3
 Europe/Vatican=CET-1CEST,M3.5.0,M10.5.0/3
 Europe/Vienna=CET-1CEST,M3.5.0,M10.5.0/3
 Europe/Vilnius=EET-2EEST,M3.5.0/3,M10.5.0/4
+Europe/Volgograd=MSK-3
 Europe/Warsaw=CET-1CEST,M3.5.0,M10.5.0/3
 Europe/Zagreb=CET-1CEST,M3.5.0,M10.5.0/3
 Europe/Zaporozhye=EET-2EEST,M3.5.0/3,M10.5.0/4
@@ -248,9 +294,26 @@ Europe/Zurich=CET-1CEST,M3.5.0,M10.5.0/3
 Indian/Antananarivo=EAT-3
 Indian/Comoro=EAT-3
 Indian/Mayotte=EAT-3
+Mexico/BajaNorte=PST8PDT,M3.2.0,M11.1.0
+Mexico/BajaSur=MST7
+Mexico/General=CST6
 Pacific/Auckland=NZST-12NZDT,M9.5.0,M4.1.0/3
 Pacific/Guam=ChST-10
 Pacific/Honolulu=HST10
+Pacific/Johnston=HST10
 Pacific/Midway=SST11
 Pacific/Pago_Pago=SST11
 Pacific/Saipan=ChST-10
+Pacific/Samoa=SST11
+US/Alaska=AKST9AKDT,M3.2.0,M11.1.0
+US/Aleutian=HST10HDT,M3.2.0,M11.1.0
+US/Arizona=MST7
+US/Central=CST6CDT,M3.2.0,M11.1.0
+US/East-Indiana=EST5EDT,M3.2.0,M11.1.0
+US/Eastern=EST5EDT,M3.2.0,M11.1.0
+US/Hawaii=HST10
+US/Indiana-Starke=CST6CDT,M3.2.0,M11.1.0
+US/Michigan=EST5EDT,M3.2.0,M11.1.0
+US/Mountain=MST7MDT,M3.2.0,M11.1.0
+US/Pacific=PST8PDT,M3.2.0,M11.1.0
+US/Samoa=SST11

+ 4 - 3
fpga/max80.qpf

@@ -19,14 +19,15 @@
 #
 # Quartus Prime
 # Version 22.1std.2 Build 922 07/20/2023 SC Lite Edition
-# Date created = 13:01:07  September 19, 2023
+# Date created = 19:20:13  October 01, 2023
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "22.1"
-DATE = "13:01:07  September 19, 2023"
+DATE = "19:20:13  October 01, 2023"
 
 # Revisions
 
-PROJECT_REVISION = "v2"
 PROJECT_REVISION = "v1"
+PROJECT_REVISION = "v2"
+PROJECT_REVISION = "bypass"

BIN
fpga/output/bypass.jic


BIN
fpga/output/bypass.sof


BIN
fpga/output/max80.fw


BIN
fpga/output/v1.fw


BIN
fpga/output/v1.jic


BIN
fpga/output/v1.sof


BIN
fpga/output/v2.fw


BIN
fpga/output/v2.jic


BIN
fpga/output/v2.sof


+ 2 - 2
rv32/Makefile

@@ -38,7 +38,7 @@ VPATH    := .:../common
 genhdrs = iodevs.h irqtable.h
 gensrcs =
 
-all: sram.bin jtagupd.bin dram.bin dram.hex checksum.h
+all: sram.bin dram.bin dram.hex checksum.h
 
 LIBS    = max80.a fatfs.a zlib.a
 
@@ -102,7 +102,7 @@ checksum.h: dram.bin sram.bin checksum.pl
 	$(PERL) checksum.pl -o $@ -p sram.bin \
 		-l $$(($$($(NM) -n max80.elf --radix=decimal | \
 			grep ' [A-Z] __dram_init_end$$' | \
-	                awk '{ print $$1; }') - (1 << 30))) \
+			awk '{ print $$1; }') - (1 << 30))) \
 		dram.bin
 
 testimg.bin: testimg.elf

+ 25 - 0
rv32/abcdisk.c

@@ -652,6 +652,7 @@ static void do_next_command(struct ctl_state *state)
 }
 
 static FATFS sd_fs;
+static bool sd_mounted;
 
 static int mount_disk(void)
 {
@@ -668,6 +669,7 @@ static int mount_disk(void)
 	set_led(LED_DISKIO, false);
 	return -1;
     }
+    sd_mounted = true;
 
     label[0] = '\0';
     volid = 0;
@@ -827,3 +829,26 @@ void abcdisk_config(void)
 	abc_register(&state->iodev, devsel);
     }
 }
+
+/*
+ * Shut down the disk subsystem for reboot
+ */
+void abcdisk_shutdown(void)
+{
+    if (!sd_mounted)
+	return;			/* Nothing to do */
+
+    for (int i = 0; i < CONTROLLER_TYPES; i++) {
+	struct ctl_state * const state = &controllers[i];
+	if (state->initialized)
+	    unmount_drives(state);
+    }
+
+    /* Unmount the SD card filesystem */
+    f_unmount("");
+
+    /* Check one last time to see if anything needs to be written out */
+    disk_ioctl(0, CTRL_SYNC, NULL);
+
+    sd_mounted = false;
+}

+ 1 - 0
rv32/abcio.h

@@ -108,6 +108,7 @@ void abc_init(void);
 void abcdisk_init(void);
 void abcdisk_config(void);
 void abcdisk_io_poll(void);
+void abcdisk_shutdown(void);
 
 void rtc_abc_init(void);
 void rtc_abc_config(void);

+ 1 - 1
rv32/checksum.h

@@ -1,4 +1,4 @@
 #ifndef CHECKSUM_H
 #define CHECKSUM_H
-#define SDRAM_SUM 0x17cbe205
+#define SDRAM_SUM 0x6b74a2de
 #endif

+ 57 - 30
rv32/romcopy.c

@@ -325,7 +325,7 @@ void rom_flash_from_memory(void *buf, size_t buflen)
     con_puts("update: flash complete, restarting in 500 ms...\n");
     udelay(500000);
 
-    reset(SYS_RESET_RECONFIG);
+    shutdown(SYS_RESET_RECONFIG);
 }
 
 static int rom_sdcard_read_data(void *cookie, void *buf, unsigned int bufsize)
@@ -339,57 +339,55 @@ static int rom_sdcard_read_data(void *cookie, void *buf, unsigned int bufsize)
 /*
  * Flash an image from an SD card, and reload the FPGA if successful
  */
-void rom_flash_from_sdcard(void)
+static int rom_flash_from_sdcard_file(const char *filename)
 {
     struct spiflash max80_flash;
-    char fw_orig_file_name[32];
-    char fw_file_name[32];
-    int l;
-    FRESULT fr;
+    char *fw_file_name = NULL;
+    FRESULT fr = FR_NO_FILE;
     FILINFO fno;
     FIL f;
 
-    rom_spiflash_init(&max80_flash);
-    max80_flash.read_data = rom_sdcard_read_data;
-    max80_flash.cookie    = &f;
-
-    l = snprintf(fw_orig_file_name, sizeof fw_orig_file_name,
-		 "/max80/v%u.fw", SYS_BOARDFPGA);
-
-    fr = f_stat(fw_orig_file_name, &fno);
+    fr = f_stat(filename, &fno);
     if (fr != FR_OK || (fno.fattrib & AM_DIR))
-	return;			/* No firmware file found */
+	return 0;		/* No such firmware file found but no error */
 
-    con_printf("update: firmware update file %s found\n", fw_orig_file_name);
+    con_printf("update: firmware update file %s found\n", filename);
 
     /* Rename the firmware file to avoid repeated updates */
-    memcpy(fw_file_name, fw_orig_file_name, l);
+    size_t l = strlen(filename);
+    fw_file_name = malloc(l+5);
+    if (!fw_file_name)
+	goto err;
+    memcpy(fw_file_name, filename, l);
 
-    for (unsigned int i = 1; i < 100000; i++) {
-	snprintf(fw_file_name+l, sizeof fw_file_name-l, ".%03u", i);
+    for (unsigned int i = 1; i < 1000; i++) {
+	snprintf(fw_file_name+l, 5, ".%03u", i);
 
-	fr = f_rename(fw_orig_file_name, fw_file_name);
+	fr = f_rename(filename, fw_file_name);
 	if (fr != FR_EXIST)
 	    break;
     }
 
     if (fr != FR_OK) {
 	con_puts("update: unable to rename update file, skipping\n");
-	return;
+	goto err;
     }
 
-    con_printf("update: renamed %s -> %s\n", fw_orig_file_name, fw_file_name);
+    con_printf("update: renamed %s -> %s\n", filename, fw_file_name);
+
+    rom_spiflash_init(&max80_flash);
+    max80_flash.read_data = rom_sdcard_read_data;
+    max80_flash.cookie    = &f;
 
     fr = f_open(&f, fw_file_name, FA_READ);
     if (fr != FR_OK) {
 	con_puts("update: cannot open file, terminating\n");
-	return;
+	goto err;
     }
 
     if (spiflash_flash_file(&max80_flash, NULL, 0)) {
 	con_puts("update: flash update data invalid\n");
-	f_close(&f);
-	return;
+	goto err;
     }
 
     /* Now do it for real */
@@ -398,18 +396,37 @@ void rom_flash_from_sdcard(void)
 
     if (spiflash_flash_file(&max80_flash, NULL, 0)) {
 	con_puts("update: flash update failed\n");
-	f_close(&f);
-	return;
+	goto err;
     }
 
-    /* Close file and then umount the filesystem to force sync */
     f_close(&f);
-    f_unmount("");
 
     con_puts("update: flash complete, restarting in 500 ms...\n");
     udelay(500000);
 
-    reset(SYS_RESET_RECONFIG);
+    shutdown(SYS_RESET_RECONFIG);
+
+err:
+    if (fr == FR_OK)
+	f_close(&f);
+    if (fw_file_name)
+	free(fw_file_name);
+    return -1;
+}
+
+/*
+ * Check for a firmware upgrade file on the sd card
+ */
+void rom_flash_from_sdcard(void)
+{
+    static char versioned_filename[] = "/max80/v?.fw";
+
+    /* Look for version-specific firmware file */
+    versioned_filename[8] = SYS_BOARDFPGA + '0';
+    rom_flash_from_sdcard_file(versioned_filename);
+
+    /* Look for universal firmware file */
+    rom_flash_from_sdcard_file("/max80/max80.fw");
 }
 
 static bool boardinfo_valid(const struct board_info *bi)
@@ -441,6 +458,16 @@ static void boardinfo_init(void)
     if (rlen < len)
 	memset((char *)&board_info + rlen, 0, sizeof board_info - rlen);
 
+    /*
+     * If no board version is specified, use the FPGA version as a
+     * resonable guess.  This might be useful if the FPGA firmware has
+     * been uploaded via JTAG.
+     */
+    if (!board_info.version_str[0]) {
+	snprintf(board_info.version_str, sizeof board_info.version_str,
+		 "MAX80 v%u", SYS_BOARDFPGA);
+    }
+
     /* Convert serial number and export to USB */
     rom_mangle_serial();
 }

+ 6 - 1
rv32/rtc.c

@@ -98,15 +98,20 @@ void read_rtc(void)
     int i;
     struct tms tms;
 
+    con_puts("RTC read: ");
+
     if (i2c_start_rtc())
 	return;
 
     i2c_send(0, I2C_SR);	/* Starting register */
     i2c_send(RTC_RCMD, 0);
 
-    for (i = 0; i < RTC_TIME_REGS-1; i++)
+    for (i = 0; i < RTC_TIME_REGS-1; i++) {
 	rtc_regs[i] = i2c_recv(0);
+	con_printf("%02x ", rtc_regs[i]);
+    }
     rtc_regs[i] = i2c_recv(I2C_NAK | I2C_P);
+    con_printf("%02x\n", rtc_regs[i]);
 
     /* Convert to struct tms and set systime */
     memset(&tms, 0, sizeof tms);

+ 4 - 3
rv32/shutdown.c

@@ -1,6 +1,7 @@
 #include "common.h"
 #include "io.h"
-#include "sdcard.h"
+#include "abcio.h"
+#include "ff.h"
 #include "console.h"
 
 /*
@@ -8,8 +9,8 @@
  */
 no_return shutdown(unsigned int type)
 {
-    /* Flush disk cache */
-    disk_ioctl(0, CTRL_SYNC, NULL);
+    /* Finish any SD card I/O and unmount the SD card */
+    abcdisk_shutdown();
 
     con_puts("Rebooting...\n");
     reset(type);

+ 0 - 419
sysvars.c

@@ -1,419 +0,0 @@
-#include "common.h"
-#include "sysvars.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <time.h>
-
-#define DEBUG 1
-
-#ifndef DEBUG
-# define DEBUG 0
-#endif
-
-static const char *sysvar_bool_tostr(sysvar_t from, char *buf)
-{
-    buf[0] = '0' + from.v_bool;
-    buf[1] = '\0';
-    return buf;
-}
-
-static bool sysvar_bool_fromstr(sysvar_t *to, const char *from)
-{
-    char c = from[0] | 0x20;
-    switch (c) {
-    case '1':
-    case 't':
-    case 'y':
-    case 'j':
-    case 's':
-	to->v_bool = true;
-	return true;
-    case ' ':			/* Blank or null */
-    case '0':
-    case 'f':
-    case 'n':
-	to->v_bool = false;
-	return true;
-    default:
-	return false;
-    }
-}
-
-const struct sysvar_ops sysvar_bool_ops = {
-    .tostr = sysvar_bool_tostr,
-    .fromstr = sysvar_bool_fromstr,
-    .buflen = BOOL_BUFLEN
-};
-
-static const char *sysvar_int_tostr(sysvar_t from, char *buf)
-{
-    snprintf(buf, INT_BUFLEN, "%ld", from.v_int);
-    return buf;
-}
-
-static bool sysvar_int_fromstr(sysvar_t *to, const char *from)
-{
-    char *ep;
-    long v = strtol(from, &ep, 0);
-    if (ep == from || *ep)
-	return false;
-    to->v_int = v;
-    return true;
-}
-
-const struct sysvar_ops sysvar_int_ops = {
-    .tostr = sysvar_int_tostr,
-    .fromstr = sysvar_int_fromstr,
-    .buflen = INT_BUFLEN
-};
-
-static const char *sysvar_uint_tostr(sysvar_t from, char *buf)
-{
-    snprintf(buf, UINT_BUFLEN, "%lu", from.v_uint);
-    return buf;
-}
-
-static bool sysvar_uint_fromstr(sysvar_t *to, const char *from)
-{
-    char *ep;
-    unsigned long v = strtoul(from, &ep, 0);
-    if (ep == from || *ep)
-	return false;
-    to->v_uint = v;
-    return true;
-}
-
-const struct sysvar_ops sysvar_uint_ops = {
-    .tostr = sysvar_uint_tostr,
-    .fromstr = sysvar_uint_fromstr,
-    .buflen = UINT_BUFLEN
-};
-
-static const char *sysvar_str_tostr(sysvar_t from, char *buf)
-{
-    (void)buf;
-    return from.v_str;
-}
-
-static bool sysvar_str_fromstr(sysvar_t *to, const char *from)
-{
-    char *ns;
-
-    if (!from) {
-	ns = NULL;
-    } else {
-	ns = strdup(from);
-	if (!ns)
-	    return false;
-    }
-    to->v_str = ns;
-    return true;
-}
-
-static bool sysvar_str_set(sysvar_t *to, sysvar_t from)
-{
-    return sysvar_str_fromstr(to, from.v_str);
-}
-
-static size_t sysvar_str_datasize(sysvar_t val)
-{
-    return (val.v_str ? strlen(val.v_str) : 0) + 1;
-}
-
-const struct sysvar_ops sysvar_str_ops = {
-    .set = sysvar_str_set,
-    .tostr = sysvar_str_tostr,
-    .fromstr = sysvar_str_fromstr,
-    .datasize = sysvar_str_datasize
-};
-
-static void sysvar_tz_update(sysvar_t val, bool isset)
-{
-    if (isset)
-	setenv("TZ", val.v_tz, 1);
-    else
-	unsetenv("TZ");
-    tzset();
-}
-
-const struct sysvar_ops sysvar_tz_ops = {
-    .set = sysvar_str_set,
-    .tostr = sysvar_str_tostr,
-    .fromstr = sysvar_str_fromstr,
-    .update = sysvar_tz_update,
-    .datasize = sysvar_str_datasize
-};
-
-static const char *sysvar_ip_tostr(sysvar_t from, char *buf)
-{
-    union ip_bytes {
-	uint8_t b[4];
-	uint32_t l;
-    } ip;
-
-    ip.l = from.v_ip;
-    snprintf(buf, IP_BUFLEN,
-	     "%u.%u.%u.%u", ip.b[0], ip.b[1], ip.b[2], ip.b[3]);
-    return buf;
-}
-
-static bool sysvar_ip_fromstr(sysvar_t *to, const char *str)
-{
-    union ip_bytes {
-	uint8_t b[4];
-	uint32_t l;
-    } ip;
-
-    ip.l = 0;
-    for (int i = 0; i < 4; i++) {
-	char *ep;
-	unsigned long v = strtoul(str, &ep, 10);
-	if (ep == str || *ep != (i == 3) ? '\0' : '.' || v > 255)
-	    return false;
-	str = ep + 1;
-	ip.b[i] = v;
-    }
-
-    to->v_ip = ip.l;
-    return true;
-}
-
-const struct sysvar_ops sysvar_ip_ops = {
-    .tostr = sysvar_ip_tostr,
-    .fromstr = sysvar_ip_fromstr,
-    .buflen = IP_BUFLEN
-};
-
-static bool sysvar_mac_set(sysvar_t *to, sysvar_t from)
-{
-    uint8_t *buf;
-
-    if (!from.v_mac) {
-	buf = NULL;
-    } else {
-	buf = malloc(6);
-	if (!buf)
-	    return false;
-
-	memcpy(buf, from.v_mac, 6);
-    }
-    to->v_mac = buf;
-    return true;
-}
-
-static const char *sysvar_mac_tostr(sysvar_t from, char *buf)
-{
-    const uint8_t *m = from.v_mac;
-    if (!m)
-	return NULL;
-
-    snprintf(buf, MAC_BUFLEN, "%x:%x:%x:%x:%x:%x",
-	     m[0], m[1], m[2], m[3], m[4], m[5]);
-    return buf;
-}
-
-static bool sysvar_mac_fromstr(sysvar_t *to, const char *str)
-{
-    sysvar_t from;
-    uint8_t m[6];
-
-    if (!str) {
-	from.v_mac = NULL;
-    } else {
-	for (int i = 0; i < 6; i++) {
-	    char *ep;
-	    unsigned long v = strtoul(str, &ep, 16);
-	    if (ep == str || *ep != (i == 5) ? '\0' : ':' || v > 255)
-		return false;
-	    str = ep + 1;
-	    m[i] = v;
-	}
-
-	from.v_mac = m;
-    }
-
-    return sysvar_mac_set(to, from);
-}
-
-static size_t sysvar_mac_datasize(sysvar_t val)
-{
-    (void)val;
-    return 6;
-}
-
-const struct sysvar_ops sysvar_mac_ops = {
-    .set = sysvar_mac_set,
-    .tostr = sysvar_mac_tostr,
-    .fromstr = sysvar_mac_fromstr,
-    .buflen = MAC_BUFLEN,
-    .datasize = sysvar_mac_datasize
-};
-
-/* --- Generic getters/setters --- */
-
-/* Contains the lowest numbered sysvar changed; or sysvar_count if nothing */
-enum sysvar_enum sysvar_changed;
-
-sysvar_t getvar(size_t var)
-{
-    if (var >= (size_t)sysvar_count)
-	return sysvar_defval[sysvar_null];
-
-    return sysvar_val[var];
-}
-
-static bool do_setvar(size_t var, sysvar_t val, bool is_set)
-{
-    const struct sysvar_ops *type = sysvar_types[var];
-    sysvar_t *to = &sysvar_val[var];
-    void *free_ptr = NULL;
-
-    if (type->datasize)
-	free_ptr = to->v_ptr;
-
-    if (DEBUG) {
-	char tostr_buf[SYSVAR_BUFLEN];
-	printf("%ssetvar %zu %s <- %s\n", is_set ? "" : "un",
-	       var, sysvar_name[var],
-	       notempty(type->tostr(val, tostr_buf)));
-    }
-
-    if (!type->set || (type->datasize && !val.v_ptr)) {
-	sysvar_val[var] = val;
-    } else {
-	if (!type->set(to, val))
-	    return false;
-    }
-
-    if (free_ptr)
-	free(free_ptr);
-
-    if (var < (size_t)sysvar_changed)
-	sysvar_changed = (enum sysvar_enum)var;
-
-    sysvar_isset[var] = is_set;
-    if (type->update)
-	type->update(*to, is_set);
-
-    return true;
-}
-
-bool setvar(size_t var, sysvar_t val)
-{
-    if (var >= (size_t)sysvar_count)
-	return false;
-
-    return do_setvar(var, val, true);
-}
-
-bool unsetvar(size_t var)
-{
-    if (var >= (size_t)sysvar_count)
-	return false;
-
-    return do_setvar(var, sysvar_defval[var], false);
-}
-
-/* --- Getters/setters converting to/from strings --- */
-
-const char *getvar_tostr(size_t var)
-{
-    static char buf[SYSVAR_BUFLEN];
-    return getvar_tostr_r(var, buf);
-}
-
-const char *getvar_tostr_r(size_t var, char *buf)
-{
-    if (var >= (size_t)sysvar_count)
-	return NULL;
-
-    const struct sysvar_ops *type = sysvar_types[var];
-
-    /* A tostr method is required */
-    return type->tostr(sysvar_val[var], buf);
-}
-
-bool setvar_fromstr(size_t var, const char *str)
-{
-    if (var >= (size_t)sysvar_count)
-	return NULL;
-
-    if (!str)
-	return unsetvar(var);
-
-    const struct sysvar_ops *type = sysvar_types[var];
-    sysvar_t *to = &sysvar_val[var];
-    void *free_ptr = NULL;
-
-    if (type->datasize)
-	free_ptr = to->v_ptr;
-
-    if (DEBUG) {
-	printf("setvar_fromstr %zu %s <- %s\n", var, sysvar_name[var], str);
-    }
-
-    /* A fromstr method is required */
-    if (!type->fromstr(to, str))
-	return false;
-
-    if (var < (size_t)sysvar_changed)
-	sysvar_changed = (enum sysvar_enum)var;
-
-    if (free_ptr)
-	free(free_ptr);
-
-    sysvar_isset[var] = true;
-    return true;
-}
-
-/* --- Find the index of a specific variable --- */
-
-static int string_ptr_compare(const void *a, const void *b)
-{
-    const char * const *aa = a;
-    const char * const *bb = b;
-    return strcmp(*aa, *bb);
-}
-
-size_t sysvar_find(size_t ns, const char *name)
-{
-    if (ns >= (size_t)sysvar_nscount)
-	return 0;
-
-    const sysvar_ns_t *nsi = &sysvar_ns[ns];
-    const char * const *varname;
-    const size_t count = nsi[1].first - nsi->first;
-
-    varname = bsearch(&name, sysvar_name + nsi->first,
-		      count, sizeof *sysvar_name,
-		      string_ptr_compare);
-    if (!varname)
-	return 0;
-
-    return varname - sysvar_name;
-}
-
-/* --- Initialization/reset to defaults --- */
-
-void sysvar_reset(size_t ns)
-{
-    if (ns >= (size_t)sysvar_nscount)
-	return;
-
-    enum sysvar_enum i;
-    for (i = sysvar_ns[ns].first; i < sysvar_ns[ns+1].first; i++)
-	unsetvar(i);
-
-    if (sysvar_changed < i)
-	sysvar_changed = i;
-}
-
-void sysvar_init(void)
-{
-    for (enum sysvar_enum i = sysvar_null+1; i < sysvar_count; i++)
-	unsetvar(i);
-
-    sysvar_changed = sysvar_count;
-}

+ 0 - 120
sysvars.h

@@ -1,120 +0,0 @@
-#ifndef SYSVARS_H
-#define SYSVARS_H
-
-#include <stddef.h>
-#include <stdbool.h>
-#include <inttypes.h>
-
-#ifndef extern_c
-# ifdef __cplusplus
-#  define extern_c extern "C"
-# else
-#  define extern_c extern
-# endif
-#endif
-
-typedef union sysvar_value {
-    bool v_bool;
-    long int v_int;
-    unsigned long int v_uint;
-    const char *v_str;
-    const char *v_tz;		/* Timezone */
-    uint32_t v_ip;		/* IPv4 address */
-    const uint8_t *v_mac;	/* MAC address */
-    void *v_ptr;
-} sysvar_t;
-
-struct sysvar_ops {
-    bool (*set)(sysvar_t *, sysvar_t);
-    /* bool (*unset)(sysvar_t *); - not used */
-    const char * (*tostr)(sysvar_t, char *);
-    bool (*fromstr)(sysvar_t *, const char *);
-    void (*update)(sysvar_t, bool); /* Called after set or fromstr; bool = isset */
-    size_t (*datasize)(sysvar_t);   /* If pointer, return size of data */
-    size_t buflen;		/* Minimal buffer size for string if needed */
-};
-
-typedef const struct sysvar_ops *sysvar_type_t;
-
-extern_c const struct sysvar_ops sysvar_bool_ops;
-extern_c const struct sysvar_ops sysvar_int_ops;
-extern_c const struct sysvar_ops sysvar_uint_ops;
-extern_c const struct sysvar_ops sysvar_str_ops;
-extern_c const struct sysvar_ops sysvar_tz_ops;
-extern_c const struct sysvar_ops sysvar_ip_ops;
-extern_c const struct sysvar_ops sysvar_mac_ops;
-
-#define SYSVAR_NULLTYPE NULL
-#define SYSVAR_TYPE(x) (&sysvar ## x ## _ops)
-
-#include "sysvars_gen.h"
-
-typedef struct sysvar_namespace {
-    const char *name;
-    enum sysvar_enum first;
-} sysvar_ns_t;
-
-extern_c const sysvar_ns_t sysvar_ns[(size_t)sysvar_nscount+1];
-extern_c enum sysvar_enum sysvar_changed;
-
-/* Buffer size needed to represent some data types */
-#define BOOL_BUFLEN 2
-#define INT_BUFLEN  (3*sizeof(unsigned int)+2)
-#define UINT_BUFLEN INT_BUFLEN
-#define IP_BUFLEN   (4*4)
-#define MAC_BUFLEN  (3*6)
-
-#define SYSVAR_BUFLEN	32	/* Conservative minimum */
-
-extern_c sysvar_t getvar(size_t var);
-extern_c bool setvar(size_t var, sysvar_t val);
-extern_c bool unsetvar(size_t var);
-extern_c const char *getvar_tostr(size_t var);
-extern_c const char *getvar_tostr_r(size_t var, char *buf);
-extern_c bool setvar_fromstr(size_t var, const char *str);
-extern_c void sysvar_init(void);
-extern_c void sysvar_reset(size_t ns);
-extern_c size_t sysvar_find(size_t ns, const char *name);
-extern_c size_t sysvar_marshall(enum sysvar_enum first, size_t count,
-				void *buf, size_t *buflen, uintptr_t extaddr);
-
-/* Type-specific definitions/getters/setters */
-/* Note that t contains a leading underscore to avoid bool/_Bool issues */
-
-#define const_assert(cond, str)					     \
-    do {							     \
-	extern void fail(void) __attribute__((error(str)));	     \
-	if (__builtin_constant_p(cond) && !(cond))		     \
-	    fail();						     \
-    } while (0)
-
-#define TRY_ASSERT_TYPE(var,t)						\
-    const_assert(sysvar_type(var) == SYSVAR_TYPE(t),			\
-	"invalid type for sysvar " #var)
-
-#define SYSVAR_MKTYPE(t,c_type)						\
-    static inline c_type getvar ## t (size_t var)			\
-    {									\
-	TRY_ASSERT_TYPE(var,t);						\
-	/* If var is constant and >= sysvar_count, TRY_ASSERT_TYPE() fails */ \
-	if (__builtin_constant_p(var < (size_t)sysvar_count))		\
-	    return sysvar_val[var].v ## t;				\
-	return getvar(var).v ## t ;					\
-    }									\
-    static inline bool setvar ## t (size_t var, c_type v)		\
-    {									\
-	sysvar_t vv;							\
-	TRY_ASSERT_TYPE(var,t);						\
-	vv.v ## t = v;							\
-	return setvar(var, vv);						\
-    }
-
-SYSVAR_MKTYPE(_bool, bool);
-SYSVAR_MKTYPE(_int, long int);
-SYSVAR_MKTYPE(_uint, unsigned long int);
-SYSVAR_MKTYPE(_str, const char *);
-SYSVAR_MKTYPE(_tz, const char *);
-SYSVAR_MKTYPE(_ip, uint32_t);
-SYSVAR_MKTYPE(_mac, const uint8_t *);
-
-#endif /* SYSVARS_H */