Add experimental (read: probably broken) VIA padlock support.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
diff --git a/Makefile.am b/Makefile.am
index 2c149d0..b3ad6d6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,7 +13,8 @@ bin_PROGRAMS = minerd
EXTRA_DIST = sha256_generic.c
-minerd_SOURCES = cpu-miner.c sha256_4way.c util.c miner.h compat.h
+minerd_SOURCES = cpu-miner.c sha256_4way.c sha256_via.c \
+ util.c miner.h compat.h
minerd_LDFLAGS = $(PTHREAD_FLAGS)
minerd_LDADD = @LIBCURL@ @JANSSON_LIBS@ @PTHREAD_LIBS@
diff --git a/cpu-miner.c b/cpu-miner.c
index f7dc37b..237f980 100644
--- a/cpu-miner.c
+++ b/cpu-miner.c
@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
+#include <stdint.h>
#include <unistd.h>
#include <sys/time.h>
#ifndef WIN32
@@ -29,8 +30,6 @@
#define DEF_RPC_URL "http://127.0.0.1:8332/"
#define DEF_RPC_USERPASS "rpcuser:rpcpass"
-#include "sha256_generic.c"
-
enum {
STAT_SLEEP_INTERVAL = 100,
STAT_CTR_INTERVAL = 10000000,
@@ -39,9 +38,10 @@ enum {
enum sha256_algos {
ALGO_C, /* plain C */
ALGO_4WAY, /* parallel SSE2 */
+ ALGO_VIA, /* VIA padlock */
};
-static bool opt_debug;
+bool opt_debug = false;
bool opt_protocol = false;
static bool program_running = true;
static const bool opt_time = true;
@@ -66,6 +66,9 @@ static struct option_help options_help[] = {
#ifdef WANT_SSE2_4WAY
"\n\t4way\t\ttcatm's 4-way SSE2 implementation (EXPERIMENTAL)"
#endif
+#ifdef WANT_VIA_PADLOCK
+ "\n\tvia\t\tVIA padlock implementation (EXPERIMENTAL)"
+#endif
},
{ "debug",
@@ -106,6 +109,8 @@ struct work {
unsigned char hash[32];
};
+#include "sha256_generic.c"
+
static bool jobj_binary(const json_t *obj, const char *key,
void *buf, size_t buflen)
{
@@ -222,7 +227,7 @@ static void runhash(void *state, void *input, const void *init)
sha256_transform(state, input);
}
-static const uint32_t init_state[8] = {
+const uint32_t sha256_init_state[8] = {
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
};
@@ -242,7 +247,7 @@ static bool scanhash(unsigned char *midstate, unsigned char *data,
*nonce = n;
runhash(hash1, data, midstate);
- runhash(hash, hash1, init_state);
+ runhash(hash, hash1, sha256_init_state);
stat_ctr++;
@@ -317,6 +322,14 @@ static void *miner_thread(void *thr_id_int)
}
break;
#endif
+
+#ifdef WANT_VIA_PADLOCK
+ case ALGO_VIA:
+ rc = scanhash_via(work.midstate, work.data + 64,
+ work.hash1, work.hash,
+ &hashes_done);
+ break;
+#endif
}
hashmeter(thr_id, &tv_start, hashes_done);
@@ -356,6 +369,10 @@ static void parse_arg (int key, char *arg)
else if (!strcmp(arg, "4way"))
opt_algo = ALGO_4WAY;
#endif
+#ifdef WANT_VIA_PADLOCK
+ else if (!strcmp(arg, "via"))
+ opt_algo = ALGO_VIA;
+#endif
else
show_usage();
break;
diff --git a/miner.h b/miner.h
index ff5bddc..bf86f56 100644
--- a/miner.h
+++ b/miner.h
@@ -2,17 +2,24 @@
#define __MINER_H__
#include <stdbool.h>
+#include <stdint.h>
#include <jansson.h>
#ifdef __SSE2__
#define WANT_SSE2_4WAY 1
#endif
+#if defined(__i386__) || defined(__x86_64__)
+#define WANT_VIA_PADLOCK 1
+#endif
+
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
+extern bool opt_debug;
extern bool opt_protocol;
+extern const uint32_t sha256_init_state[];
extern json_t *json_rpc_call(const char *url, const char *userpass,
const char *rpc_req);
extern char *bin2hex(unsigned char *p, size_t len);
@@ -22,6 +29,9 @@ extern unsigned int ScanHash_4WaySSE2(unsigned char *pmidstate,
unsigned char *pdata, unsigned char *phash1, unsigned char *phash,
unsigned long *nHashesDone);
+extern bool scanhash_via(unsigned char *midstate, const unsigned char *data_in,
+ unsigned char *hash1, unsigned char *hash,
+ unsigned long *hashes_done);
extern int
timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y);
diff --git a/sha256_via.c b/sha256_via.c
new file mode 100644
index 0000000..c03495b
--- /dev/null
+++ b/sha256_via.c
@@ -0,0 +1,92 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include "miner.h"
+
+#ifdef WANT_VIA_PADLOCK
+
+#define ___constant_swab32(x) ((uint32_t)( \
+ (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
+ (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
+ (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
+ (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
+
+static inline uint32_t swab32(uint32_t v)
+{
+ return ___constant_swab32(v);
+}
+
+static void via_sha256(void *hash, void *buf, unsigned len)
+{
+ unsigned stat = 0;
+ asm volatile(".byte 0xf3, 0x0f, 0xa6, 0xd0"
+ :"+S"(buf), "+a"(stat)
+ :"c"(len), "D" (hash)
+ :"memory");
+}
+
+bool scanhash_via(unsigned char *midstate, const unsigned char *data_in,
+ unsigned char *hash1, unsigned char *hash,
+ unsigned long *hashes_done)
+{
+ unsigned char data[128] __attribute__((aligned(128)));
+ unsigned char tmp_hash1[32] __attribute__((aligned(32)));
+ uint32_t *hash32 = (uint32_t *) hash;
+ uint32_t *nonce = (uint32_t *)(data + 12);
+ uint32_t n = 0;
+ unsigned long stat_ctr = 0;
+ int i;
+
+ /* bitcoin gives us big endian input, but via wants LE,
+ * so we reverse the swapping bitcoin has already done (extra work)
+ */
+ for (i = 0; i < 128/4; i++) {
+ uint32_t *data32 = (uint32_t *) data;
+ data32[i] = swab32(((uint32_t *)data_in)[i]);
+ }
+
+ while (1) {
+ n++;
+ *nonce = n;
+
+ /* first SHA256 transform */
+ memcpy(tmp_hash1, sha256_init_state, 32);
+ via_sha256(tmp_hash1, data, 80); /* or maybe 128? */
+
+ for (i = 0; i < 32/4; i++)
+ ((uint32_t *)tmp_hash1)[i] =
+ swab32(((uint32_t *)tmp_hash1)[i]);
+
+ /* second SHA256 transform */
+ memcpy(hash, sha256_init_state, 32);
+ via_sha256(hash, tmp_hash1, 32);
+
+ stat_ctr++;
+
+ if (hash32[7] == 0) {
+ char *hexstr;
+
+ hexstr = bin2hex(hash, 32);
+ fprintf(stderr,
+ "DBG: found zeroes in hash:\n%s\n",
+ hexstr);
+ free(hexstr);
+
+ *hashes_done = stat_ctr;
+ return true;
+ }
+
+ if ((n & 0xffffff) == 0) {
+ if (opt_debug)
+ fprintf(stderr, "DBG: end of nonce range\n");
+ *hashes_done = stat_ctr;
+ return false;
+ }
+ }
+}
+
+#endif /* WANT_VIA_PADLOCK */
+