Compare commits

...

99 Commits
master ... 3.5

Author SHA1 Message Date
Sebastien Bourdeauducq 59fdb32b7b conda: bump misoc 2018-03-10 22:59:09 +08:00
Sebastien Bourdeauducq 7337842ff9 runtime: add a missing overflow flag reset 2018-03-04 01:05:18 +08:00
Sebastien Bourdeauducq 87b51cbcc2 doc: DMA can also raise RTIOUnderflow 2018-03-04 01:04:11 +08:00
whitequark 232940e17f conda: don't use globs in file list. 2018-02-27 17:40:41 +00:00
Robert Jördens 806d583153 kc705_sma_spi: fix cri_con 2018-02-27 10:48:10 +00:00
whitequark 015189b2ae conda: modernize build.sh. 2018-02-26 16:25:49 +00:00
whitequark d0d150d974 conda: add back py_ prefix in dependencies. 2018-02-26 15:48:31 +00:00
whitequark 81f0efea9b conda: use a single artiq-board package. 2018-02-26 15:09:28 +00:00
Sebastien Bourdeauducq cb605cf014 use new misoc identifier 2018-02-22 11:17:57 +08:00
Sebastien Bourdeauducq 1568e55388 conda: bump misoc (#902) 2018-02-22 11:15:14 +08:00
whitequark fbb58b5c8a compiler: reject calls with unexpected keyword arguments.
Fixes #924.
2018-02-21 19:39:50 +08:00
whitequark 92c94c1f62 firmware: make network tracing runtime switchable. 2018-02-14 23:18:58 +00:00
Robert Jördens 9db30ce8dc conda: pin openocd build 2018-01-30 11:12:33 +01:00
Robert Jördens 49a265453d conda: sync artiq and artiq-dev
c.f. 4c22d64e
2018-01-30 11:03:55 +01:00
Sebastien Bourdeauducq e1aafcbb4f artiq_flash: add --preinit-command for buildbot compatibility 2018-01-30 17:35:48 +08:00
Sebastien Bourdeauducq 2548e9d833 RELEASE_NOTES: add 3.4 entry 2018-01-30 17:35:14 +08:00
whitequark b92b00a1c8 Update smoltcp.
Fixes #902.
2018-01-30 03:30:53 +00:00
Sebastien Bourdeauducq bfb03fdbba RELEASE_NOTES: 3.3 2018-01-28 00:18:24 +08:00
Sebastien Bourdeauducq 59fe69a4b3 conda: use new migen 2018-01-27 23:13:58 +08:00
Sebastien Bourdeauducq 8276c6588b conda: use misoc release 2018-01-27 22:22:55 +08:00
whitequark aa64b8ad7a runtime: build with -Cpanic=unwind.
This is required for backtraces to function. I'm not sure how it
turned out that master had -Cpanic=abort.
2018-01-26 23:01:54 +00:00
whitequark 6f7771cb01 Fix 3313e997. 2018-01-27 00:31:59 +08:00
whitequark d2e9ea8de6 test: fix test_worker to work when deprecation warnings are emitted. 2018-01-27 00:31:58 +08:00
Robert Jördens a85fd13c21 conda: bump misoc, close #905
* cherry-pick c9b36e35
* also pin migen as we don't do .dev tags anymore
2018-01-25 19:34:47 +01:00
Sebastien Bourdeauducq 5f2256cb25 conda: build artiq- as noarch: python, like artiq itself (#894) 2018-01-17 10:12:06 +08:00
Sebastien Bourdeauducq 917477f937 examples: update KC705 DNS (used for CI) 2018-01-17 09:41:47 +08:00
whitequark 4f3e7af8d5 doc: Rust uses recursive submodules (brrr).
[ci skip]
2018-01-10 01:28:40 +00:00
whitequark 3b82c585d1 doc: update Rust version.
[ci skip]
2018-01-10 01:28:39 +00:00
Sebastien Bourdeauducq a433794483 Work around another conda bug. 2018-01-09 17:04:33 +08:00
Sebastien Bourdeauducq 6641f4c1ac conda: use tagged migen/misoc 2018-01-09 15:39:27 +08:00
whitequark 24562d232e compiler: don't die if addr2line cannot extract line from backtrace.
Fixes #885.
2018-01-08 22:02:38 +00:00
whitequark 40b9a84a2b firmware: update smoltcp. 2018-01-08 22:02:27 +00:00
whitequark 46218c1fff conda: update rustc to 1.23.0. 2018-01-08 21:55:26 +00:00
whitequark 3ba82cf19c firmware: clean up makefiles. 2018-01-03 08:20:45 +00:00
Sebastien Bourdeauducq e14626e432 conda: bump migen 2017-12-29 11:11:18 +08:00
Sebastien Bourdeauducq 4ae93d4fd8 conda: bump misoc 2017-12-29 01:41:40 +08:00
Robert Jördens 66d1647efd spi: register clk 2017-12-29 01:40:45 +08:00
whitequark e6306b712d firmware: fix a typo replacing spiflash::SECTOR_SIZE with PAGE_SIZE. 2017-12-29 01:37:34 +08:00
Sebastien Bourdeauducq 14a90e5386 firmware: enlarge bootloader partition to 4 sectors. 2017-12-29 01:37:11 +08:00
Sebastien Bourdeauducq 00c9b20d1e firmware: remove bitflags references from Cargo.lock
Only master needs bitflags.
2017-12-28 12:28:37 +08:00
Sebastien Bourdeauducq 8c19d90179 firmware: prepare config block for access from BIOS/bootloader.
This is in 3.2 so that users lose storage only once.
2017-12-28 12:23:18 +08:00
whitequark 135c138ec3 runtime: remove borrow_mut!() in favor of backtraces. 2017-12-28 12:06:29 +08:00
whitequark d419ccdeca compiler: do not permit str(...). (#878) 2017-12-27 11:48:21 +08:00
Sebastien Bourdeauducq 246a2bb3e1 RELEASE_NOTES: add 3.2 entry 2017-12-27 10:52:12 +08:00
whitequark 26dbf0841c conda: ship runtime.elf in board-specific packages.
This is so that backtraces may be symbolized.
2017-12-27 10:48:35 +08:00
whitequark 7af02787e0 conda: bump rustc version requirement. 2017-12-27 10:45:52 +08:00
whitequark 4bda29f863 compiler: fix typo in a0a2650f. 2017-12-27 10:44:26 +08:00
whitequark c44d08a826 conda: update llvmlite-artiq dependency. 2017-12-27 10:44:11 +08:00
whitequark fbf7e70ef8 compiler: do not ever emit !tbaa on invoke instructions. 2017-12-27 10:44:03 +08:00
whitequark ca48c29a8b compiler: update for llvmlite 0.20.0. 2017-12-27 10:43:55 +08:00
whitequark c9be535ba5 compiler: do not use invoke for calls to nounwind ffi functions.
Otherwise, declarations such as:

  @syscall(flags={"nounwind", "nowrite"})
  def foo(...):

trip an LLVM assert because the invoke instruction and the !tbaa
metadata are no longer compatible since LLVM 4.0.
2017-12-27 10:43:48 +08:00
whitequark 3f8dc0233a runtime: update smoltcp. 2017-12-27 10:43:32 +08:00
whitequark 30b7bcf362 Update to LLVM 4.0. 2017-12-27 10:43:04 +08:00
whitequark 99bc18dcd7 runtime: fix some final flash storage issues. 2017-12-27 10:42:57 +08:00
whitequark 65204a091f runtime: we're growing, put storage at 1M instead of 512K. 2017-12-27 10:42:21 +08:00
whitequark 2fd3b3324a runtime: ensure flash storage never overlaps with runtime sections. 2017-12-27 10:41:13 +08:00
whitequark 7f04e75042 runtime: simplify. NFC. 2017-12-27 10:38:05 +08:00
whitequark e364213b62 runtime: remove accidentally committed parts of a Makefile. 2017-12-27 10:37:56 +08:00
whitequark 99bb1b0b70 runtime: print (address-only) backtraces on core device panics. 2017-12-27 10:37:44 +08:00
whitequark b72178756e firmware: fix compatibility with newer rustc. NFC. 2017-12-27 10:35:52 +08:00
whitequark 6cbf8786d8 runtime: get rid of config_dummy.rs. NFC.
Use the same strategy as elsewhere.
2017-12-27 10:35:36 +08:00
whitequark 0ede5d8638 doc: developing: show how to make clang source builds faster. 2017-12-27 10:33:43 +08:00
whitequark 231bf77b43 runtime: update smoltcp. 2017-12-19 23:52:50 +08:00
Sebastien Bourdeauducq df2f0ead4a runtime: no startup_clock config is not an error 2017-12-14 18:50:08 +08:00
whitequark 16d49f38c1 artiq_pcap: still grab the file if the command fails. 2017-12-11 07:31:58 +08:00
whitequark 3f0277197f runtime: update smoltcp. 2017-12-11 07:31:30 +08:00
Robert Jördens e02dc834e6 doc: clean up artiq-dev installation instructions
Add a heading to the openocd setup instruction so that it is
clearly distinguishable from the openocd installation. Otherwise people
"re-install" openocd the wrong way.
2017-12-11 07:31:02 +08:00
Robert Jördens 6cb7f2e8e2 conda/artiq-dev: fix channel list
Now, with conda 4.1 packages are sorted by channel, version, build
number in decreasing priority. The highest matching package is
taken. https://conda.io/docs/user-guide/tasks/manage-channels.html

For the artiq-dev environment, the m-labs/label/dev channel should be
first, then the main channel, then defaults, and then conda-forge
(community supported packages).

closes #864
2017-12-11 07:30:36 +08:00
Sebastien Bourdeauducq 4c2f25e85e RELEASE_NOTES: 3.1 2017-12-07 13:12:02 +08:00
Robert Jördens 2c85597daa test_performance: relax network speed to 2 MB/s
At QUARTIQ I am getting 2.4/2.3 MB/s and with single switch at M-Labs we
apparently regularly met 2.2/2.2 MB/s. But with the current multiple
switches and one of them being a problematic switch that triggered #837
it looks like it is a tad slower.

http://buildbot.m-labs.hk/builders/artiq/builds/1818/steps/python_coverage_1/logs/stdio
2017-12-07 12:24:14 +08:00
Sebastien Bourdeauducq 76a908c8a9 backport Ethernet bugfixes from master 2017-12-07 12:21:21 +08:00
whitequark 0e5a5441aa runtime: remove UDP-related code. 2017-12-07 12:16:33 +08:00
Sebastien Bourdeauducq 45f510bcdc phaser: remove ad9154 from mem_map 2017-11-29 18:23:50 +08:00
Sebastien Bourdeauducq 7e5a301a27 manual: fix formatting problem 2017-11-25 14:41:36 +08:00
Sebastien Bourdeauducq 14714d3f9d Hack-patch Sphinx so that ARTIQ-Python types are correctly printed.
Modification proposed to Sphinx but my issue is getting ignored.

Closes #741
2017-11-25 14:37:21 +08:00
Sebastien Bourdeauducq 25d3fc1e55 sawg: fix typo 2017-11-22 20:06:16 +08:00
Sebastien Bourdeauducq f83cf8d1bb artiq_influxdb: use aiohttp.ClientSession. Closes #829 2017-11-22 17:32:10 +08:00
Sebastien Bourdeauducq 8ebca38323 runtime: fix rtio::log 2017-11-03 09:25:56 +08:00
Sebastien Bourdeauducq 0c47f83634 clean up rtio_log 2017-11-03 01:13:07 +08:00
whitequark f0937bde16 runtime: update smoltcp. 2017-10-30 16:39:25 +08:00
whitequark 3ec1850949 runtime: update smoltcp. 2017-10-30 15:43:28 +08:00
whitequark 0d79b7d292 test: verify no network performance regression from current 2.2 MB/s. 2017-10-30 15:43:28 +08:00
whitequark 3e96e0b10d runtime: parse the "ip" configuration as IP, not CIDR.
Or it defaults to the default IP on settings that were previously
perfectly valid.
2017-10-30 15:43:28 +08:00
Sebastien Bourdeauducq 6902868d58 gui: remove '.0' in background logo 2017-10-26 12:53:35 +08:00
whitequark 89b7c9e091 Update smoltcp.
Fixes #840.
2017-10-25 10:57:42 +08:00
Sebastien Bourdeauducq 52e331204e examples: fix first_dds_bus_channel in device database 2017-10-23 15:05:20 +08:00
Robert Jördens 8edb6a135a conda: openocd=0.10.0 (single-tap proxy bitstreams) 2017-10-20 19:47:54 +02:00
Robert Jördens cd0d73a1a2 scanwidget: protect against resize from zero
fix #839
2017-10-11 22:27:09 +02:00
Sebastien Bourdeauducq a6cd42c4aa RELEASE_NOTES: 2.5 2017-10-02 12:16:46 +08:00
whitequark 45c6ca96f8 firmware: unbreak heap view.
This was missing since 7799413a for no good reason.
2017-10-02 11:03:52 +08:00
whitequark db8300c990 compiler: disallow op= on mutable values (fix #835).
In general, we can't reallocate a value in earlier stack frames,
or fixup references to it. This mainly impacts lists.
2017-10-02 11:03:03 +08:00
whitequark ce7e30edfe compiler: implement ~ operator (fix #836). 2017-10-02 11:03:02 +08:00
whitequark a06f04dfbe compiler: minor intrinsic refactoring. 2017-10-02 11:03:02 +08:00
whitequark 1521231b1b compiler: correct semantics of floating point % operator (fix #830). 2017-10-02 11:03:02 +08:00
whitequark 67997d8955 compiler: correct semantics of integer % operator (#830). 2017-10-02 11:03:02 +08:00
Sebastien Bourdeauducq a49bb2bc50 conda: fix llvmlite-artiq dependency 2017-09-30 01:31:50 +08:00
Sebastien Bourdeauducq d500e61d89 RELEASE_NOTES: formatting 2017-09-30 01:10:23 +08:00
Sebastien Bourdeauducq 04a9a0ce95 doc: no more win32 packages 2017-09-29 23:14:21 +08:00
Sebastien Bourdeauducq ac28b377c7 targets: phaser → kc705_phaser 2017-09-29 22:54:18 +08:00
65 changed files with 1184 additions and 880 deletions

View File

@ -3,13 +3,39 @@
Release notes
=============
3.4
---
No further notes.
3.3
---
No further notes.
3.2
---
* To accommodate larger runtimes, the flash layout as changed. As a result, the
contents of the flash storage will be lost when upgrading. Set the values back
(IP, MAC address, startup kernel, etc.) after the upgrade.
3.1
---
No further notes.
3.0
---
* The --embed option of applets is replaced with the environment variable
* The ``--embed`` option of applets is replaced with the environment variable
``ARTIQ_APPLET_EMBED``. The GUI sets this enviroment variable itself and the
user simply needs to remove the ``--embed`` argument.
* EnvExperiment's prepare calls prepare for all its children.
* ``EnvExperiment``'s ``prepare`` calls ``prepare`` for all its children.
* Dynamic ``__getattr__``'s returning RPC target methods are not supported anymore.
Controller driver classes must define all their methods intended for RPC as
members.
@ -22,7 +48,7 @@ Release notes
* The DDS class names and setup options have changed, this requires an update of
the device database.
* ``int(a, width=b)`` has been removed. Use ``int32(a)`` and ``int64(a)``.
* The kc705 gateware target has been renamed kc705_dds.
* The KC705 gateware target has been renamed ``kc705_dds``.
* ``artiq.coredevice.comm_tcp`` has been renamed ``artiq.coredevice.comm_kernel``,
and ``Comm`` has been renamed ``CommKernel``.
* The "collision" and "busy" RTIO errors are reported through the log instead of
@ -38,8 +64,8 @@ Release notes
identifiers (``true``, ``null``, ...) with their Python equivalents
(``True``, ``None`` ...).
* Controllers are now named ``aqctl_XXX`` instead of ``XXX_controller``.
* In the device database, the "comm" device has been folded into the "core" device.
Move the "host" argument into the "core" device, and remove the "comm" device.
* In the device database, the ``comm`` device has been folded into the ``core`` device.
Move the "host" argument into the ``core`` device, and remove the ``comm`` device.
* The core device log now contains important information about events such as
RTIO collisions. A new controller ``aqctl_corelog`` must be running to forward
those logs to the master. See the example device databases to see how to
@ -52,8 +78,15 @@ Release notes
at https://github.com/m-labs/pdq. All SPI/USB driver layers, Mediator,
CompoundPDQ and examples/documentation has been moved.
* The master now rotates log files at midnight, rather than based on log size.
* The results keys start_time and run_time are now stored as doubles of UNIX time,
* The results keys ``start_time`` and ``run_time`` are now stored as doubles of UNIX time,
rather than ints. The file names are still based on local time.
* Packages are no longer available for 32-bit Windows.
2.5
---
No further notes.
2.4
@ -62,7 +95,6 @@ Release notes
No further notes.
2.3
---

View File

@ -216,8 +216,12 @@ class Target:
filename, line = location.rsplit(":", 1)
if filename == "??" or filename == "<synthesized>":
continue
if line == "?":
line = -1
else:
line = int(line)
# can't get column out of addr2line D:
backtrace.append((filename, int(line), -1, function, address))
backtrace.append((filename, line, -1, function, address))
return backtrace
def demangle(self, names):

View File

@ -1289,6 +1289,10 @@ class ARTIQIRGenerator(algorithm.Visitor):
return self.append(ir.Select(cond,
ir.Constant(False, builtins.TBool()),
ir.Constant(True, builtins.TBool())))
elif isinstance(node.op, ast.Invert):
operand = self.visit(node.operand)
return self.append(ir.Arith(ast.BitXor(loc=None),
ir.Constant(-1, operand.type), operand))
elif isinstance(node.op, ast.USub):
operand = self.visit(node.operand)
return self.append(ir.Arith(ast.Sub(loc=None),
@ -1319,7 +1323,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
lambda: self.alloc_exn(builtins.TException("ValueError"),
ir.Constant("shift amount must be nonnegative", builtins.TStr())),
loc=node.right.loc)
elif isinstance(node.op, (ast.Div, ast.FloorDiv)):
elif isinstance(node.op, (ast.Div, ast.FloorDiv, ast.Mod)):
self._make_check(
self.append(ir.Compare(ast.NotEq(loc=None), rhs, ir.Constant(0, rhs.type))),
lambda: self.alloc_exn(builtins.TException("ZeroDivisionError"),
@ -1721,7 +1725,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
self.polymorphic_print([self.visit(prefix)],
separator=" ", suffix="\x1E", as_rtio=True)
self.polymorphic_print([self.visit(arg) for arg in args],
separator=" ", suffix="\n\x1D", as_rtio=True)
separator=" ", suffix="\x1D", as_rtio=True)
return ir.Constant(None, builtins.TNone())
elif types.is_builtin(typ, "delay"):
if len(node.args) == 1 and len(node.keywords) == 0:
@ -1808,7 +1812,8 @@ class ARTIQIRGenerator(algorithm.Visitor):
assert None not in args
if self.unwind_target is None:
if self.unwind_target is None or \
types.is_c_function(callee.type) and "nounwind" in callee.type.flags:
insn = self.append(ir.Call(func, args, arg_exprs))
else:
after_invoke = self.add_block("invoke")

View File

@ -682,6 +682,11 @@ class Inferencer(algorithm.Visitor):
pass
else:
diagnose(valid_forms())
elif types.is_builtin(typ, "str"):
diag = diagnostic.Diagnostic("error",
"strings currently cannot be constructed", {},
node.loc)
self.engine.process(diag)
elif types.is_builtin(typ, "list") or types.is_builtin(typ, "array"):
if types.is_builtin(typ, "list"):
valid_forms = lambda: [
@ -999,6 +1004,17 @@ class Inferencer(algorithm.Visitor):
elif keyword.arg in typ_optargs:
self._unify(keyword.value.type, typ_optargs[keyword.arg],
keyword.value.loc, None)
else:
note = diagnostic.Diagnostic("note",
"extraneous argument", {},
keyword.loc)
diag = diagnostic.Diagnostic("error",
"this function of type {type} does not accept argument '{name}'",
{"type": types.TypePrinter().name(node.func.type),
"name": keyword.arg},
node.func.loc, [], [note])
self.engine.process(diag)
return
passed_args[keyword.arg] = keyword.arg_loc
for formalname in typ_args:

View File

@ -22,7 +22,7 @@ llptr = ll.IntType(8).as_pointer()
llptrptr = ll.IntType(8).as_pointer().as_pointer()
llslice = ll.LiteralStructType([llptr, lli32])
llsliceptr = ll.LiteralStructType([llptr, lli32]).as_pointer()
llmetadata = ll.MetaData()
llmetadata = ll.MetaDataType()
def memoize(generator):
@ -270,7 +270,7 @@ class LLVMIRGenerator:
sanitized_str = re.sub(rb"[^a-zA-Z0-9_.]", b"", as_bytes[:20]).decode('ascii')
name = self.llmodule.get_unique_name("S.{}".format(sanitized_str))
llstr = self.llmodule.get_global(name)
llstr = self.llmodule.globals.get(name)
if llstr is None:
llstrty = ll.ArrayType(lli8, len(as_bytes))
llstr = ll.GlobalVariable(self.llmodule, llstrty, name)
@ -306,7 +306,7 @@ class LLVMIRGenerator:
assert False
def llbuiltin(self, name):
llglobal = self.llmodule.get_global(name)
llglobal = self.llmodule.globals.get(name)
if llglobal is not None:
return llglobal
@ -326,6 +326,12 @@ class LLVMIRGenerator:
llty = ll.FunctionType(llptr, [])
elif name == "llvm.stackrestore":
llty = ll.FunctionType(llvoid, [llptr])
elif name == "__py_modsi3":
llty = ll.FunctionType(lli32, [lli32, lli32])
elif name == "__py_moddi3":
llty = ll.FunctionType(lli64, [lli64, lli64])
elif name == "__py_moddf3":
llty = ll.FunctionType(lldouble, [lldouble, lldouble])
elif name == self.target.print_function:
llty = ll.FunctionType(llvoid, [llptr], var_arg=True)
elif name == "rtio_log":
@ -363,13 +369,96 @@ class LLVMIRGenerator:
"watchdog_set", "watchdog_clear",
self.target.print_function):
llglobal.attributes.add("nounwind")
if name.find("__py_") == 0:
llglobal.linkage = 'linkonce_odr'
self.emit_intrinsic(name, llglobal)
else:
llglobal = ll.GlobalVariable(self.llmodule, llty, name)
return llglobal
def emit_intrinsic(self, name, llfun):
llbuilder = ll.IRBuilder()
llbuilder.position_at_end(llfun.append_basic_block("entry"))
if name == "__py_modsi3" or name == "__py_moddi3":
if name == "__py_modsi3":
llty = lli32
elif name == "__py_moddi3":
llty = lli64
else:
assert False
"""
Reference Objects/intobject.c
xdivy = x / y;
xmody = (long)(x - (unsigned long)xdivy * y);
/* If the signs of x and y differ, and the remainder is non-0,
* C89 doesn't define whether xdivy is now the floor or the
* ceiling of the infinitely precise quotient. We want the floor,
* and we have it iff the remainder's sign matches y's.
*/
if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) {
xmody += y;
// ...
}
"""
llx, lly = llfun.args
llxdivy = llbuilder.sdiv(llx, lly)
llxremy = llbuilder.srem(llx, lly)
llxmodynonzero = llbuilder.icmp_signed('!=', llxremy, ll.Constant(llty, 0))
lldiffsign = llbuilder.icmp_signed('<', llbuilder.xor(llx, lly), ll.Constant(llty, 0))
llcond = llbuilder.and_(llxmodynonzero, lldiffsign)
with llbuilder.if_then(llcond):
llbuilder.ret(llbuilder.add(llxremy, lly))
llbuilder.ret(llxremy)
elif name == "__py_moddf3":
"""
Reference Objects/floatobject.c
mod = fmod(vx, wx);
/* fmod is typically exact, so vx-mod is *mathematically* an
exact multiple of wx. But this is fp arithmetic, and fp
vx - mod is an approximation; the result is that div may
not be an exact integral value after the division, although
it will always be very close to one.
*/
// ...
if (mod) {
/* ensure the remainder has the same sign as the denominator */
if ((wx < 0) != (mod < 0)) {
mod += wx;
// ...
}
}
else {
/* the remainder is zero, and in the presence of signed zeroes
fmod returns different results across platforms; ensure
it has the same sign as the denominator; we'd like to do
"mod = wx * 0.0", but that may get optimized away */
mod *= mod; /* hide "mod = +0" from optimizer */
if (wx < 0.0)
mod = -mod;
}
"""
llv, llw = llfun.args
llrem = llbuilder.frem(llv, llw)
llremnonzero = llbuilder.fcmp_unordered('!=', llrem, ll.Constant(lldouble, 0.0))
llwltzero = llbuilder.fcmp_ordered('<', llw, ll.Constant(lldouble, 0.0))
llremltzero = llbuilder.fcmp_ordered('<', llrem, ll.Constant(lldouble, 0.0))
lldiffsign = llbuilder.icmp_unsigned('!=', llwltzero, llremltzero)
llcond = llbuilder.and_(llremnonzero, lldiffsign)
with llbuilder.if_then(llcond):
llbuilder.ret(llbuilder.fadd(llrem, llw))
llbuilder.ret(llrem)
else:
assert False
def get_function(self, typ, name):
llfun = self.llmodule.get_global(name)
llfun = self.llmodule.globals.get(name)
if llfun is None:
llfunty = self.llty_of_type(typ, bare=True)
llfun = ll.Function(self.llmodule, llfunty, name)
@ -410,7 +499,7 @@ class LLVMIRGenerator:
llobjects = defaultdict(lambda: [])
for obj_id, obj_ref, obj_typ in self.embedding_map.iter_objects():
llobject = self.llmodule.get_global("O.{}".format(obj_id))
llobject = self.llmodule.globals.get("O.{}".format(obj_id))
if llobject is not None:
llobjects[obj_typ].append(llobject.bitcast(llptr))
@ -905,22 +994,15 @@ class LLVMIRGenerator:
return self.llbuilder.sdiv(self.map(insn.lhs()), self.map(insn.rhs()),
name=insn.name)
elif isinstance(insn.op, ast.Mod):
# Python only has the modulo operator, LLVM only has the remainder
lllhs, llrhs = map(self.map, (insn.lhs(), insn.rhs()))
if builtins.is_float(insn.type):
llvalue = self.llbuilder.frem(self.map(insn.lhs()), self.map(insn.rhs()))
self.add_fast_math_flags(llvalue)
return self.llbuilder.call(self.llbuiltin("llvm.copysign.f64"),
[llvalue, self.map(insn.rhs())],
name=insn.name)
else:
lllhs, llrhs = map(self.map, (insn.lhs(), insn.rhs()))
llxorsign = self.llbuilder.and_(self.llbuilder.xor(lllhs, llrhs),
ll.Constant(lllhs.type, 1 << lllhs.type.width - 1))
llnegate = self.llbuilder.icmp_unsigned('!=',
llxorsign, ll.Constant(llxorsign.type, 0))
llvalue = self.llbuilder.srem(lllhs, llrhs)
llnegvalue = self.llbuilder.sub(ll.Constant(llvalue.type, 0), llvalue)
return self.llbuilder.select(llnegate, llnegvalue, llvalue)
intrinsic = "__py_moddf3"
elif builtins.is_int32(insn.type):
intrinsic = "__py_modsi3"
elif builtins.is_int64(insn.type):
intrinsic = "__py_moddi3"
return self.llbuilder.call(self.llbuiltin(intrinsic), [lllhs, llrhs],
name=insn.name)
elif isinstance(insn.op, ast.Pow):
if builtins.is_float(insn.type):
return self.llbuilder.call(self.llbuiltin("llvm.pow.f64"),
@ -1127,7 +1209,7 @@ class LLVMIRGenerator:
llargs.append(llarg)
llfunname = insn.target_function().type.name
llfun = self.llmodule.get_global(llfunname)
llfun = self.llmodule.globals.get(llfunname)
if llfun is None:
llretty = self.llty_of_type(insn.type, for_return=True)
if self.needs_sret(llretty):
@ -1366,9 +1448,8 @@ class LLVMIRGenerator:
llcall = self.llbuilder.invoke(llfun, llargs, llnormalblock, llunwindblock,
name=insn.name)
# See the comment in process_Call.
if types.is_c_function(functiontyp) and 'nowrite' in functiontyp.flags:
llcall.set_metadata('tbaa', self.tbaa_nowrite_call)
# The !tbaa metadata is not legal to use with the invoke instruction,
# so unlike process_Call, we do not set it here.
return llcall
@ -1561,7 +1642,7 @@ class LLVMIRGenerator:
llclauseexnname = self.llconst_of_const(
ir.Constant(exnname, builtins.TStr()))
llclauseexnnameptr = self.llmodule.get_global("exn.{}".format(exnname))
llclauseexnnameptr = self.llmodule.globals.get("exn.{}".format(exnname))
if llclauseexnnameptr is None:
llclauseexnnameptr = ll.GlobalVariable(self.llmodule, llclauseexnname.type,
name="exn.{}".format(exnname))

View File

@ -298,8 +298,8 @@ class EscapeValidator(algorithm.Visitor):
# and exceptions can only refer to strings, so we don't actually check
# this property. But we will need to, if string operations are ever added.
def visit_assignment(self, target, value, is_aug_assign=False):
value_region = self._region_of(value) if not is_aug_assign else self.youngest_region
def visit_assignment(self, target, value):
value_region = self._region_of(value)
# If this is a variable, we might need to contract the live range.
if isinstance(value_region, Region):
@ -316,19 +316,11 @@ class EscapeValidator(algorithm.Visitor):
target_regions = [self._region_of(name) for name in target_names]
for target_region in target_regions:
if not Region.outlives(value_region, target_region):
if is_aug_assign:
target_desc = "the assignment target, allocated here,"
else:
target_desc = "the assignment target"
note = diagnostic.Diagnostic("note",
"this expression has type {type}",
{"type": types.TypePrinter().name(value.type)},
value.loc)
diag = diagnostic.Diagnostic("error",
"the assigned value does not outlive the assignment target", {},
value.loc, [target.loc],
notes=self._diagnostics_for(target_region, target.loc,
target_desc) +
"the assignment target") +
self._diagnostics_for(value_region, value.loc,
"the assigned value"))
self.engine.process(diag)
@ -339,9 +331,19 @@ class EscapeValidator(algorithm.Visitor):
def visit_AugAssign(self, node):
if builtins.is_allocated(node.target.type):
# If the target is mutable, op-assignment will allocate
# in the youngest region.
self.visit_assignment(node.target, node.value, is_aug_assign=True)
note = diagnostic.Diagnostic("note",
"try using `{lhs} = {lhs} {op} {rhs}` instead",
{"lhs": node.target.loc.source(),
"rhs": node.value.loc.source(),
"op": node.op.loc.source()[:-1]},
node.loc)
diag = diagnostic.Diagnostic("error",
"values cannot be mutated in-place", {},
node.op.loc, [node.target.loc],
notes=[note])
self.engine.process(diag)
self.visit_assignment(node.target, node.value)
def visit_Return(self, node):
region = self._region_of(node.value)

View File

@ -71,8 +71,8 @@ class CacheError(Exception):
class RTIOUnderflow(Exception):
"""Raised when the CPU fails to submit a RTIO event early enough
(with respect to the event's timestamp).
"""Raised when the CPU or DMA core fails to submit a RTIO event early
enough (with respect to the event's timestamp).
The offending event is discarded and the RTIO core keeps operating.
"""

View File

@ -32,7 +32,7 @@ class Config:
Exposes the configurable quantities of a single SAWG channel.
Access to the configuration registers for a SAWG channel can not
be concurrent. There must be at least :attr:_rtio_interval` machine
be concurrent. There must be at least :attr:`_rtio_interval` machine
units of delay between accesses. Replacement is not supported and will be
lead to an ``RTIOCollision`` as this is likely a programming error.
All methods therefore advance the timeline by the duration of one

View File

@ -2,7 +2,7 @@
# The RTIO channel numbers here are for NIST CLOCK on KC705.
# The list of devices here is not exhaustive.
core_addr = "kc705.lab.m-labs.hk"
core_addr = "kc705-1.lab.m-labs.hk"
device_db = {
"core": {
@ -33,7 +33,7 @@ device_db = {
"class": "DDSGroupAD9914",
"arguments": {
"sysclk": 3e9,
"first_dds_bus_channel": 26,
"first_dds_bus_channel": 27,
"dds_bus_count": 2,
"dds_channel_count": 3
}

View File

@ -1,7 +1,3 @@
[root]
name = "std_artiq"
version = "0.0.0"
[[package]]
name = "alloc_list"
version = "0.0.0"
@ -17,23 +13,28 @@ dependencies = [
"board 0.0.0",
]
[[package]]
name = "backtrace_artiq"
version = "0.0.0"
[[package]]
name = "board"
version = "0.0.0"
dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "build_artiq"
version = "0.0.0"
dependencies = [
"walkdir 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byteorder"
version = "1.0.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -41,7 +42,7 @@ name = "compiler_builtins"
version = "0.1.0"
source = "git+https://github.com/rust-lang-nursery/compiler-builtins?rev=631b568#631b5687b24af413fdbffa4c2644484e60660b00"
dependencies = [
"gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-cfg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -55,8 +56,8 @@ name = "drtioaux"
version = "0.0.0"
dependencies = [
"board 0.0.0",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"std_artiq 0.0.0",
]
@ -69,12 +70,12 @@ name = "fringe"
version = "1.1.0"
source = "git+https://github.com/m-labs/libfringe?rev=bd23494#bd2349467157969324ca7da5d2ae033c7ffac0c0"
dependencies = [
"libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gcc"
version = "0.3.42"
version = "0.3.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -94,7 +95,7 @@ dependencies = [
"amp 0.0.0",
"board 0.0.0",
"build_artiq 0.0.0",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dyld 0.0.0",
"proto 0.0.0",
@ -103,12 +104,12 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.18"
version = "0.2.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "log"
version = "0.3.6"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -121,23 +122,23 @@ name = "logger_artiq"
version = "0.0.0"
dependencies = [
"board 0.0.0",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"log_buffer 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "managed"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proto"
version = "0.0.0"
dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dyld 0.0.0",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"std_artiq 0.0.0",
]
@ -147,17 +148,18 @@ version = "0.0.0"
dependencies = [
"alloc_list 0.0.0",
"amp 0.0.0",
"backtrace_artiq 0.0.0",
"board 0.0.0",
"build_artiq 0.0.0",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins?rev=631b568)",
"cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"drtioaux 0.0.0",
"fringe 1.1.0 (git+https://github.com/m-labs/libfringe?rev=bd23494)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"logger_artiq 0.0.0",
"proto 0.0.0",
"smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=6f5ae33)",
"smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=181083f)",
"std_artiq 0.0.0",
]
@ -166,6 +168,15 @@ name = "rustc-cfg"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "same-file"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "satman"
version = "0.0.0"
@ -175,7 +186,7 @@ dependencies = [
"build_artiq 0.0.0",
"compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins?rev=631b568)",
"drtioaux 0.0.0",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"logger_artiq 0.0.0",
"std_artiq 0.0.0",
]
@ -183,19 +194,24 @@ dependencies = [
[[package]]
name = "smoltcp"
version = "0.4.0"
source = "git+https://github.com/m-labs/smoltcp?rev=6f5ae33#6f5ae33501827d57926469c6f1a860205a24f7ae"
source = "git+https://github.com/m-labs/smoltcp?rev=181083f#181083f18c977b8a0463a67e360e4db20594fa21"
dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"managed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"managed 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "std_artiq"
version = "0.0.0"
[[package]]
name = "walkdir"
version = "1.0.3"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -210,18 +226,19 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
"checksum compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins?rev=631b568)" = "<none>"
"checksum cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0f8cb7306107e4b10e64994de6d3274bd08996a7c1322a27b86482392f96be0a"
"checksum fringe 1.1.0 (git+https://github.com/m-labs/libfringe?rev=bd23494)" = "<none>"
"checksum gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "291055c78f59ca3d84c99026c9501c469413d386bb46be1e1cf1d285cd1db3b0"
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70"
"checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054"
"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
"checksum log_buffer 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec57723b84bbe7bdf76aa93169c9b59e67473317c6de3a83cb2a0f8ccb2aa493"
"checksum managed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d48e8c30a4363e2981fe4db20527f6ab0f32a243bbc75379dea5a64f60dae4"
"checksum managed 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "786bd3519bdfb0e1a57146a74b7584555dd6c4f1b6e1137c70e177d60dde8186"
"checksum rustc-cfg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56a596b5718bf5e059d59a30af12f7f462a152de147aa462b70892849ee18704"
"checksum smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=6f5ae33)" = "<none>"
"checksum walkdir 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd7c16466ecc507c7cb5988db03e6eab4aaeab89a5c37a29251fcfd3ac9b7afe"
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
"checksum smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=181083f)" = "<none>"
"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"

View File

@ -1,2 +1,5 @@
[workspace]
members = ["runtime", "ksupport", "satman"]
[profile.dev]
debug = 1 # either 0 or 2 cause an LLVM ICE

View File

@ -0,0 +1,24 @@
[package]
authors = ["M-Labs"]
name = "bootloader"
version = "0.0.0"
build = "build.rs"
[lib]
name = "bootloader"
crate-type = ["staticlib"]
path = "main.rs"
[build-dependencies]
build_misoc = { path = "../libbuild_misoc" }
[dependencies]
byteorder = { version = "1.0", default-features = false }
crc = { version = "1.7", default-features = false }
board = { path = "../libboard", features = ["uart_console", "smoltcp"] }
[dependencies.smoltcp]
git = "https://github.com/m-labs/smoltcp"
rev = "181083f"
default-features = false
features = ["proto-ipv4", "socket-tcp"]

View File

@ -5,7 +5,6 @@ CFLAGS += \
-I$(LIBUNWIND_DIRECTORY) \
-I$(LIBUNWIND_DIRECTORY)/../unwinder/include \
-I$(MISOC_DIRECTORY)/software/include/dyld
CFLAGS += -DNDEBUG
LDFLAGS += --eh-frame-hdr \
-L../libcompiler-rt \
@ -15,22 +14,15 @@ LDFLAGS += --eh-frame-hdr \
RUSTFLAGS += -Cpanic=unwind
all: ksupport.elf
all:: ksupport.elf
.PHONY: $(RUSTOUT)/libksupport.a
$(RUSTOUT)/libksupport.a:
$(cargo) --manifest-path $(KSUPPORT_DIRECTORY)/Cargo.toml
ksupport.elf: $(RUSTOUT)/libksupport.a glue.o
$(LD) $(LDFLAGS) -T $(KSUPPORT_DIRECTORY)/ksupport.ld -o $@ $^ \
-lunwind -lcompiler-rt -lbase -lm
@chmod -x $@
$(link) -T $(KSUPPORT_DIRECTORY)/ksupport.ld \
-lunwind-elf -lcompiler-rt -lbase -lm
%.o: $(KSUPPORT_DIRECTORY)/%.c
$(compile)
clean:
$(RM) *.o ksupport.elf
$(RM) -rf cargo
.PHONY: all clean

View File

@ -167,7 +167,7 @@ extern fn rpc_recv(slot: *mut ()) -> usize {
})
}
fn terminate(exception: &eh::Exception, mut backtrace: &mut [usize]) -> ! {
fn terminate(exception: &eh::Exception, backtrace: &mut [usize]) -> ! {
let mut cursor = 0;
for index in 0..backtrace.len() {
if backtrace[index] > kernel_proto::KERNELCPU_PAYLOAD_ADDRESS {
@ -333,8 +333,8 @@ extern fn dma_record_output_wide(timestamp: i64, channel: i32, address: i32, wor
if DMA_RECORDER.buffer.len() - DMA_RECORDER.data_len < length {
dma_record_flush()
}
let mut dst = &mut DMA_RECORDER.buffer[DMA_RECORDER.data_len..
DMA_RECORDER.data_len + length];
let dst = &mut DMA_RECORDER.buffer[DMA_RECORDER.data_len..
DMA_RECORDER.data_len + length];
dst[..header_length].copy_from_slice(&header[..]);
dst[header_length..].copy_from_slice(&data[..]);
DMA_RECORDER.data_len += length;

View File

@ -96,6 +96,7 @@ pub extern fn input_timestamp(timeout: i64, channel: i32) -> u64 {
}
if status & RTIO_I_STATUS_OVERFLOW != 0 {
csr::rtio::i_overflow_reset_write(1);
raise!("RTIOOverflow",
"RTIO input overflow on channel {0}",
channel as i64, 0, 0);
@ -140,16 +141,17 @@ pub fn log(timestamp: i64, data: &[u8]) {
for i in 0..data.len() {
word <<= 8;
word |= data[i] as u32;
if i % 4 == 0 {
if i % 4 == 3 {
rtio_o_data_write(0, word);
csr::rtio::o_we_write(1);
word = 0;
}
}
word <<= 8;
rtio_o_data_write(0, word);
csr::rtio::o_we_write(1);
if word != 0 {
rtio_o_data_write(0, word);
csr::rtio::o_we_write(1);
}
}
}

View File

@ -104,19 +104,17 @@ unsafe impl<'a> Alloc for &'a ListAlloc {
}
fn oom(&mut self, err: AllocErr) -> ! {
panic!("cannot allocate: {:?}", err)
panic!("heap view: {}\ncannot allocate: {:?}", self, err)
}
}
impl ListAlloc {
pub fn debug_dump(&self, f: &mut fmt::Write) -> fmt::Result {
impl fmt::Display for ListAlloc {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
unsafe {
let mut total_busy = 0;
let mut total_idle = 0;
let mut total_meta = 0;
write!(f, "Heap view:\n")?;
let mut curr = self.root;
while !curr.is_null() {
total_meta += mem::size_of::<Header>();

View File

@ -0,0 +1,8 @@
[package]
authors = ["M-Labs"]
name = "backtrace_artiq"
version = "0.0.0"
[lib]
name = "backtrace_artiq"
path = "lib.rs"

View File

@ -0,0 +1,30 @@
#![feature(libc, panic_unwind)]
#![no_std]
extern crate unwind;
extern crate libc;
use unwind as uw;
use libc::c_void;
pub fn backtrace<F>(mut f: F) -> Result<(), uw::_Unwind_Reason_Code>
where F: FnMut(usize) -> ()
{
extern fn trace<F>(context: *mut uw::_Unwind_Context, arg: *mut c_void)
-> uw::_Unwind_Reason_Code
where F: FnMut(usize) -> ()
{
unsafe {
let step_fn = &mut *(arg as *mut F);
step_fn(uw::_Unwind_GetIP(context));
uw::_URC_NO_REASON
}
}
unsafe {
match uw::_Unwind_Backtrace(trace::<F>, &mut f as *mut _ as *mut c_void) {
uw::_URC_NO_REASON => Ok(()),
err => Err(err)
}
}
}

View File

@ -9,6 +9,7 @@ name = "board"
path = "lib.rs"
[dependencies]
byteorder = { version = "1.0", default-features = false }
log = { version = "0.3", default-features = false }
[features]

View File

@ -0,0 +1,232 @@
#[cfg(has_spiflash)]
mod imp {
use core::str;
use byteorder::{ByteOrder, BigEndian};
use cache;
use spiflash;
// One flash sector immediately before the firmware.
const ADDR: usize = ::mem::FLASH_BOOT_ADDRESS - spiflash::SECTOR_SIZE;
const SIZE: usize = spiflash::SECTOR_SIZE;
mod lock {
use core::slice;
use core::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
static LOCKED: AtomicUsize = ATOMIC_USIZE_INIT;
pub struct Lock;
impl Lock {
pub fn take() -> Result<Lock, ()> {
if LOCKED.swap(1, Ordering::SeqCst) != 0 {
Err(()) // already locked
} else {
Ok(Lock) // locked now
}
}
pub fn data(&self) -> &'static [u8] {
unsafe { slice::from_raw_parts(super::ADDR as *const u8, super::SIZE) }
}
}
impl Drop for Lock {
fn drop(&mut self) {
LOCKED.store(0, Ordering::SeqCst)
}
}
}
use self::lock::Lock;
#[derive(Clone)]
struct Iter<'a> {
data: &'a [u8],
offset: usize
}
impl<'a> Iter<'a> {
fn new(data: &'a [u8]) -> Iter<'a> {
Iter { data: data, offset: 0 }
}
}
impl<'a> Iterator for Iter<'a> {
type Item = Result<(&'a [u8], &'a [u8]), ()>;
fn next(&mut self) -> Option<Self::Item> {
let data = &self.data[self.offset..];
if data.len() < 4 {
error!("offset {}: truncated record", self.offset);
return Some(Err(()))
}
let record_size = BigEndian::read_u32(data) as usize;
if record_size == !0 /* all ones; erased flash */ {
return None
} else if record_size < 4 || record_size > data.len() {
error!("offset {}: invalid record size {}", self.offset, record_size);
return Some(Err(()))
}
let record_body = &data[4..record_size];
match record_body.iter().position(|&x| x == 0) {
None => {
error!("offset {}: missing separator", self.offset);
Some(Err(()))
}
Some(pos) => {
self.offset += record_size;
let (key, zero_and_value) = record_body.split_at(pos);
Some(Ok((key, &zero_and_value[1..])))
}
}
}
}
pub fn read<F: FnOnce(Result<&[u8], ()>) -> R, R>(key: &str, f: F) -> R {
f(Lock::take().and_then(|lock| {
let mut iter = Iter::new(lock.data());
let mut value = &[][..];
while let Some(result) = iter.next() {
let (record_key, record_value) = result?;
if key.as_bytes() == record_key {
// last write wins
value = record_value
}
}
Ok(value)
}))
}
pub fn read_str<F: FnOnce(Result<&str, ()>) -> R, R>(key: &str, f: F) -> R {
read(key, |result| {
f(result.and_then(|value| str::from_utf8(value).map_err(|_| ())))
})
}
unsafe fn append_at<'a>(mut data: &'a [u8], key: &[u8], value: &[u8]) -> Result<&'a [u8], ()> {
let record_size = 4 + key.len() + 1 + value.len();
if data.len() < record_size {
return Err(())
}
let mut record_size_bytes = [0u8; 4];
BigEndian::write_u32(&mut record_size_bytes[..], record_size as u32);
spiflash::write(data.as_ptr() as usize, &record_size_bytes[..]);
data = &data[record_size_bytes.len()..];
spiflash::write(data.as_ptr() as usize, key);
data = &data[key.len()..];
spiflash::write(data.as_ptr() as usize, &[0]);
data = &data[1..];
spiflash::write(data.as_ptr() as usize, value);
data = &data[value.len()..];
cache::flush_l2_cache();
Ok(data)
}
fn compact() -> Result<(), ()> {
let lock = Lock::take()?;
static mut OLD_DATA: [u8; SIZE] = [0; SIZE];
let old_data = unsafe {
OLD_DATA.copy_from_slice(lock.data());
&OLD_DATA[..]
};
let mut data = lock.data();
unsafe { spiflash::erase_sector(data.as_ptr() as usize) };
// This is worst-case quadratic, but we're limited by a small SPI flash sector size,
// so it does not really matter.
let mut iter = Iter::new(old_data);
while let Some(result) = iter.next() {
let (key, mut value) = result?;
let mut next_iter = iter.clone();
while let Some(next_result) = next_iter.next() {
let (next_key, next_value) = next_result?;
if key == next_key {
value = next_value
}
}
data = unsafe { append_at(data, key, value)? };
}
Ok(())
}
fn append(key: &str, value: &[u8]) -> Result<(), ()> {
let lock = Lock::take()?;
let free = {
let mut iter = Iter::new(lock.data());
while let Some(result) = iter.next() {
let _ = result?;
}
&iter.data[iter.offset..]
};
unsafe { append_at(free, key.as_bytes(), value)? };
Ok(())
}
pub fn write(key: &str, value: &[u8]) -> Result<(), ()> {
match append(key, value) {
Ok(()) => (),
Err(()) => {
compact()?;
append(key, value)?;
}
}
Ok(())
}
pub fn remove(key: &str) -> Result<(), ()> {
write(key, &[])
}
pub fn erase() -> Result<(), ()> {
let lock = Lock::take()?;
unsafe { spiflash::erase_sector(lock.data().as_ptr() as usize) };
cache::flush_l2_cache();
Ok(())
}
}
#[cfg(not(has_spiflash))]
mod imp {
pub fn read<F: FnOnce(Result<&[u8], ()>) -> R, R>(_key: &str, f: F) -> R {
f(Err(()))
}
pub fn read_str<F: FnOnce(Result<&str, ()>) -> R, R>(_key: &str, f: F) -> R {
f(Err(()))
}
pub fn write(_key: &str, _value: &[u8]) -> Result<(), ()> {
Err(())
}
pub fn remove(_key: &str) -> Result<(), ()> {
Err(())
}
pub fn erase() -> Result<(), ()> {
Err(())
}
}
pub use self::imp::*;

View File

@ -1,10 +1,11 @@
#![feature(asm, lang_items)]
#![no_std]
extern crate byteorder;
#[macro_use]
extern crate log;
use core::{cmp, ptr, str};
use core::{cmp, str};
include!(concat!(env!("BUILDINC_DIRECTORY"), "/generated/mem.rs"));
include!(concat!(env!("BUILDINC_DIRECTORY"), "/generated/csr.rs"));
@ -18,6 +19,7 @@ pub mod uart_console;
#[cfg(has_spiflash)]
pub mod spiflash;
pub mod config;
pub mod i2c;
pub mod spi;
@ -43,11 +45,13 @@ pub use uart_console::Console;
pub fn ident(buf: &mut [u8]) -> &str {
unsafe {
let len = ptr::read_volatile(csr::IDENTIFIER_MEM_BASE);
let len = cmp::min(len as usize, buf.len());
csr::identifier::address_write(0);
let len = csr::identifier::data_read();
let len = cmp::min(len, buf.len() as u8);
for i in 0..len {
buf[i] = ptr::read_volatile(csr::IDENTIFIER_MEM_BASE.offset(1 + i as isize)) as u8
csr::identifier::address_write(1 + i);
buf[i as usize] = csr::identifier::data_read();
}
str::from_utf8_unchecked(&buf[..len])
str::from_utf8_unchecked(&buf[..len as usize])
}
}

View File

@ -3,6 +3,11 @@
use core::cmp;
use csr;
pub const SECTOR_SIZE: usize = csr::CONFIG_SPIFLASH_SECTOR_SIZE as usize;
pub const PAGE_SIZE: usize = csr::CONFIG_SPIFLASH_PAGE_SIZE as usize;
const PAGE_MASK: usize = PAGE_SIZE - 1;
const CMD_PP: u8 = 0x02;
const CMD_WRDI: u8 = 0x04;
const CMD_RDSR: u8 = 0x05;
@ -15,28 +20,24 @@ const PIN_DQ_I: u8 = 1 << 3;
const SR_WIP: u8 = 1;
fn write_byte(mut byte: u8) {
unsafe {
csr::spiflash::bitbang_write(0);
for _ in 0..8 {
csr::spiflash::bitbang_write((byte & 0x80) >> 7);
csr::spiflash::bitbang_write((byte & 0x80) >> 7 | PIN_CLK);
byte <<= 1;
}
csr::spiflash::bitbang_write(0);
unsafe fn write_byte(mut byte: u8) {
csr::spiflash::bitbang_write(0);
for _ in 0..8 {
csr::spiflash::bitbang_write((byte & 0x80) >> 7);
csr::spiflash::bitbang_write((byte & 0x80) >> 7 | PIN_CLK);
byte <<= 1;
}
csr::spiflash::bitbang_write(0);
}
fn write_addr(mut addr: usize) {
unsafe {
csr::spiflash::bitbang_write(0);
for _ in 0..24 {
csr::spiflash::bitbang_write(((addr & 0x800000) >> 23) as u8);
csr::spiflash::bitbang_write(((addr & 0x800000) >> 23) as u8 | PIN_CLK);
addr <<= 1;
}
csr::spiflash::bitbang_write(0);
unsafe fn write_addr(mut addr: usize) {
csr::spiflash::bitbang_write(0);
for _ in 0..24 {
csr::spiflash::bitbang_write(((addr & 0x800000) >> 23) as u8);
csr::spiflash::bitbang_write(((addr & 0x800000) >> 23) as u8 | PIN_CLK);
addr <<= 1;
}
csr::spiflash::bitbang_write(0);
}
fn wait_until_ready() {
@ -59,54 +60,47 @@ fn wait_until_ready() {
}
}
pub fn erase_sector(addr: usize) {
unsafe {
let sector_addr = addr & !(csr::CONFIG_SPIFLASH_SECTOR_SIZE as usize - 1);
pub unsafe fn erase_sector(addr: usize) {
let sector_addr = addr & !(csr::CONFIG_SPIFLASH_SECTOR_SIZE as usize - 1);
csr::spiflash::bitbang_en_write(1);
csr::spiflash::bitbang_en_write(1);
wait_until_ready();
wait_until_ready();
write_byte(CMD_WREN);
csr::spiflash::bitbang_write(PIN_CS_N);
write_byte(CMD_WREN);
csr::spiflash::bitbang_write(PIN_CS_N);
write_byte(CMD_SE);
write_addr(sector_addr);
csr::spiflash::bitbang_write(PIN_CS_N);
write_byte(CMD_SE);
write_addr(sector_addr);
csr::spiflash::bitbang_write(PIN_CS_N);
wait_until_ready();
wait_until_ready();
csr::spiflash::bitbang_en_write(0);
}
csr::spiflash::bitbang_en_write(0);
}
fn write_page(addr: usize, data: &[u8]) {
unsafe {
csr::spiflash::bitbang_en_write(1);
unsafe fn write_page(addr: usize, data: &[u8]) {
csr::spiflash::bitbang_en_write(1);
wait_until_ready();
wait_until_ready();
write_byte(CMD_WREN);
csr::spiflash::bitbang_write(PIN_CS_N);
write_byte(CMD_PP);
write_addr(addr);
for &byte in data {
write_byte(byte)
}
csr::spiflash::bitbang_write(PIN_CS_N);
csr::spiflash::bitbang_write(0);
wait_until_ready();
csr::spiflash::bitbang_en_write(0);
write_byte(CMD_WREN);
csr::spiflash::bitbang_write(PIN_CS_N);
write_byte(CMD_PP);
write_addr(addr);
for &byte in data {
write_byte(byte)
}
csr::spiflash::bitbang_write(PIN_CS_N);
csr::spiflash::bitbang_write(0);
wait_until_ready();
csr::spiflash::bitbang_en_write(0);
}
const PAGE_SIZE: usize = csr::CONFIG_SPIFLASH_PAGE_SIZE as usize;
const PAGE_MASK: usize = PAGE_SIZE - 1;
pub fn write(mut addr: usize, mut data: &[u8]) {
pub unsafe fn write(mut addr: usize, mut data: &[u8]) {
if addr & PAGE_MASK != 0 {
let size = cmp::min((PAGE_SIZE - (addr & PAGE_MASK)) as usize, data.len());
write_page(addr, &data[..size]);

View File

@ -19,6 +19,7 @@ log = { version = "0.3", default-features = false }
alloc_list = { path = "../liballoc_list" }
std_artiq = { path = "../libstd_artiq", features = ["alloc", "io_error_alloc"] }
logger_artiq = { path = "../liblogger_artiq" }
backtrace_artiq = { path = "../libbacktrace_artiq" }
board = { path = "../libboard", features = ["uart_console"] }
proto = { path = "../libproto", features = ["log"] }
amp = { path = "../libamp" }
@ -37,6 +38,6 @@ features = ["alloc"]
[dependencies.smoltcp]
git = "https://github.com/m-labs/smoltcp"
rev = "6f5ae33"
rev = "181083f"
default-features = false
features = ["alloc", "log"]
features = ["alloc", "log", "proto-ipv4", "socket-tcp"]

View File

@ -1,32 +1,30 @@
include ../include/generated/variables.mak
include $(MISOC_DIRECTORY)/software/common.mak
LDFLAGS += -L../libbase
CFLAGS += \
-I$(LIBUNWIND_DIRECTORY) \
-I$(LIBUNWIND_DIRECTORY)/../unwinder/include
RUSTFLAGS += -Cpanic=abort
LDFLAGS += -L../libbase \
-L../libunwind
all: runtime.bin runtime.fbi
RUSTFLAGS += -Cpanic=unwind
all:: runtime.bin runtime.fbi
.PHONY: $(RUSTOUT)/libruntime.a
$(RUSTOUT)/libruntime.a:
$(cargo) --manifest-path $(RUNTIME_DIRECTORY)/Cargo.toml
runtime.elf: $(RUSTOUT)/libruntime.a ksupport_data.o
$(LD) $(LDFLAGS) -T $(RUNTIME_DIRECTORY)/runtime.ld -o $@ $^
@chmod -x $@
$(link) -T $(RUNTIME_DIRECTORY)/runtime.ld \
-lunwind-bare
ksupport_data.o: ../ksupport/ksupport.elf
$(LD) -r -b binary -o $@ $<
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
@chmod -x $@
$(objcopy) -O binary
%.fbi: %.bin
@echo " MSCIMG " $@ && $(PYTHON) -m misoc.tools.mkmscimg -f -o $@ $<
clean:
$(RM) *.o runtime.elf runtime.bin runtime.fbi
$(RM) -rf cargo
.PHONY: all clean
$(mscimg) -f

View File

@ -1,192 +0,0 @@
use core::str;
use std::btree_map::BTreeMap;
use byteorder::{ByteOrder, BigEndian};
use board::{mem, csr, cache, spiflash};
const ADDR: usize = mem::FLASH_BOOT_ADDRESS + 0x80000 /* max runtime size */;
const SIZE: usize = csr::CONFIG_SPIFLASH_SECTOR_SIZE as usize;
mod lock {
use core::slice;
use core::sync::atomic::{AtomicUsize, Ordering};
static LOCKED: AtomicUsize = AtomicUsize::new(0);
pub struct Lock;
impl Lock {
pub fn take() -> Result<Lock, ()> {
if LOCKED.swap(1, Ordering::SeqCst) != 0 {
Err(()) // already locked
} else {
Ok(Lock) // locked now
}
}
pub fn data(&self) -> &'static [u8] {
unsafe { slice::from_raw_parts(super::ADDR as *const u8, super::SIZE) }
}
}
impl Drop for Lock {
fn drop(&mut self) {
LOCKED.store(0, Ordering::SeqCst)
}
}
}
pub use self::lock::Lock;
struct Iter<'a> {
data: &'a [u8],
offset: usize
}
impl<'a> Iter<'a> {
fn new(data: &'a [u8]) -> Iter<'a> {
Iter { data: data, offset: 0 }
}
}
impl<'a> Iterator for Iter<'a> {
type Item = Result<(&'a [u8], &'a [u8]), ()>;
fn next(&mut self) -> Option<Self::Item> {
let data = &self.data[self.offset..];
if data.len() < 4 {
error!("offset {}: truncated record", self.offset);
return Some(Err(()))
}
let record_size = BigEndian::read_u32(data) as usize;
if record_size < 4 {
error!("offset {}: invalid record size", self.offset);
return Some(Err(()))
}
if record_size == !0 /* all ones; erased flash */ {
return None
}
let record_body = &data[4..record_size];
match record_body.iter().position(|&x| x == 0) {
None => {
error!("offset {}: missing separator", self.offset);
Some(Err(()))
}
Some(pos) => {
self.offset += record_size;
let (key, zero_and_value) = record_body.split_at(pos);
Some(Ok((key, &zero_and_value[1..])))
}
}
}
}
pub fn read<F: FnOnce(Result<&[u8], ()>) -> R, R>(key: &str, f: F) -> R {
f(Lock::take().and_then(|lock| {
let mut iter = Iter::new(lock.data());
let mut value = &[][..];
while let Some(result) = iter.next() {
let (record_key, record_value) = result?;
if key.as_bytes() == record_key {
// last write wins
value = record_value
}
}
Ok(value)
}))
}
pub fn read_str<F: FnOnce(Result<&str, ()>) -> R, R>(key: &str, f: F) -> R {
read(key, |result| {
f(result.and_then(|value| str::from_utf8(value).map_err(|_| ())))
})
}
fn append_at(mut offset: usize, key: &[u8], value: &[u8]) -> Result<usize, ()> {
let record_size = 4 + key.len() + 1 + value.len();
if offset + record_size > SIZE {
return Err(())
}
let mut record_size_bytes = [0u8; 4];
BigEndian::write_u32(&mut record_size_bytes[..], record_size as u32);
spiflash::write(ADDR + offset, &record_size_bytes[..]);
offset += record_size_bytes.len();
spiflash::write(ADDR + offset, key);
offset += key.len();
spiflash::write(ADDR + offset, &[0]);
offset += 1;
spiflash::write(ADDR + offset, value);
offset += value.len();
cache::flush_l2_cache();
Ok(offset)
}
fn compact() -> Result<(), ()> {
let lock = Lock::take()?;
let mut items = BTreeMap::new();
{
let mut iter = Iter::new(lock.data());
while let Some(result) = iter.next() {
let (key, value) = result?;
items.insert(key, value);
}
}
spiflash::erase_sector(ADDR);
cache::flush_l2_cache();
let mut offset = 0;
for (key, value) in items {
offset = append_at(offset, key, value)?;
}
Ok(())
}
fn append(key: &str, value: &[u8]) -> Result<(), ()> {
let lock = Lock::take()?;
let free_offset = {
let mut iter = Iter::new(lock.data());
while let Some(result) = iter.next() {
let _ = result?;
}
iter.offset
};
append_at(free_offset, key.as_bytes(), value)?;
Ok(())
}
pub fn write(key: &str, value: &[u8]) -> Result<(), ()> {
match append(key, value) {
Ok(()) => (),
Err(()) => {
compact()?;
append(key, value)?;
}
}
Ok(())
}
pub fn remove(key: &str) -> Result<(), ()> {
write(key, &[])
}
pub fn erase() -> Result<(), ()> {
let _lock = Lock::take()?;
spiflash::erase_sector(ADDR);
cache::flush_l2_cache();
Ok(())
}

View File

@ -1,19 +0,0 @@
pub fn read<F: FnOnce(Result<&[u8], ()>) -> R, R>(_key: &str, f: F) -> R {
f(Err(()))
}
pub fn read_str<F: FnOnce(Result<&str, ()>) -> R, R>(_key: &str, f: F) -> R {
f(Err(()))
}
pub fn write(_key: &str, _value: &[u8]) -> Result<(), ()> {
Err(())
}
pub fn remove(_key: &str) -> Result<(), ()> {
Err(())
}
pub fn erase() -> Result<(), ()> {
Err(())
}

View File

@ -1,88 +1,158 @@
use core::slice;
use core::{slice, fmt};
use smoltcp::Result;
use smoltcp::phy::{self, DeviceCapabilities, Device};
use board::{csr, mem};
use smoltcp::Error;
use smoltcp::phy::{DeviceLimits, Device};
const RX0_BASE: usize = mem::ETHMAC_BASE + 0x0000;
const RX1_BASE: usize = mem::ETHMAC_BASE + 0x0800;
const RX2_BASE: usize = mem::ETHMAC_BASE + 0x1000;
const RX3_BASE: usize = mem::ETHMAC_BASE + 0x1800;
const TX0_BASE: usize = mem::ETHMAC_BASE + 0x2000;
const TX1_BASE: usize = mem::ETHMAC_BASE + 0x2800;
const TX2_BASE: usize = mem::ETHMAC_BASE + 0x3000;
const TX3_BASE: usize = mem::ETHMAC_BASE + 0x3800;
const RX_SLOTS: usize = csr::ETHMAC_RX_SLOTS as usize;
const TX_SLOTS: usize = csr::ETHMAC_TX_SLOTS as usize;
const SLOT_SIZE: usize = csr::ETHMAC_SLOT_SIZE as usize;
const RX_BUFFERS: [*mut u8; 4] = [RX0_BASE as *mut u8, RX1_BASE as *mut u8,
RX2_BASE as *mut u8, RX3_BASE as *mut u8];
const TX_BUFFERS: [*mut u8; 4] = [TX0_BASE as *mut u8, TX1_BASE as *mut u8,
TX2_BASE as *mut u8, TX3_BASE as *mut u8];
pub struct EthernetDevice;
impl Device for EthernetDevice {
type RxBuffer = RxBuffer;
type TxBuffer = TxBuffer;
fn limits(&self) -> DeviceLimits {
let mut limits = DeviceLimits::default();
limits.max_transmission_unit = 1514;
limits.max_burst_size = Some(RX_BUFFERS.len());
limits
}
fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer, Error> {
unsafe {
if csr::ethmac::sram_writer_ev_pending_read() != 0 {
let slot = csr::ethmac::sram_writer_slot_read();
let length = csr::ethmac::sram_writer_length_read();
Ok(RxBuffer(slice::from_raw_parts(RX_BUFFERS[slot as usize],
length as usize)))
} else {
Err(Error::Exhausted)
}
}
}
fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error> {
unsafe {
if csr::ethmac::sram_reader_ready_read() != 0 {
let slot = csr::ethmac::sram_reader_slot_read();
let slot = (slot + 1) % (TX_BUFFERS.len() as u8);
csr::ethmac::sram_reader_slot_write(slot);
csr::ethmac::sram_reader_length_write(length as u16);
Ok(TxBuffer(slice::from_raw_parts_mut(TX_BUFFERS[slot as usize],
length as usize)))
} else {
Err(Error::Exhausted)
}
fn next_rx_slot() -> Option<usize> {
unsafe {
if csr::ethmac::sram_writer_ev_pending_read() == 0 {
None
} else {
Some(csr::ethmac::sram_writer_slot_read() as usize)
}
}
}
pub struct RxBuffer(&'static [u8]);
impl AsRef<[u8]> for RxBuffer {
fn as_ref(&self) -> &[u8] { self.0 }
}
impl Drop for RxBuffer {
fn drop(&mut self) {
unsafe { csr::ethmac::sram_writer_ev_pending_write(1) }
fn next_tx_slot() -> Option<usize> {
unsafe {
if csr::ethmac::sram_reader_ready_read() == 0 {
None
} else {
Some((csr::ethmac::sram_reader_slot_read() as usize + 1) % TX_SLOTS)
}
}
}
pub struct TxBuffer(&'static mut [u8]);
impl AsRef<[u8]> for TxBuffer {
fn as_ref(&self) -> &[u8] { self.0 }
fn rx_buffer(slot: usize) -> *const u8 {
debug_assert!(slot < RX_SLOTS);
(mem::ETHMAC_BASE + SLOT_SIZE * slot) as _
}
impl AsMut<[u8]> for TxBuffer {
fn as_mut(&mut self) -> &mut [u8] { self.0 }
fn tx_buffer(slot: usize) -> *mut u8 {
debug_assert!(slot < TX_SLOTS);
(mem::ETHMAC_BASE + SLOT_SIZE * (RX_SLOTS + slot)) as _
}
impl Drop for TxBuffer {
fn drop(&mut self) {
unsafe { csr::ethmac::sram_reader_start_write(1) }
pub struct EthernetDevice(());
impl EthernetDevice {
pub unsafe fn new() -> EthernetDevice {
EthernetDevice(())
}
}
impl<'a> Device<'a> for EthernetDevice {
type RxToken = EthernetRxSlot;
type TxToken = EthernetTxSlot;
fn capabilities(&self) -> DeviceCapabilities {
let mut caps = DeviceCapabilities::default();
caps.max_transmission_unit = 1514;
caps.max_burst_size = Some(RX_SLOTS);
caps
}
fn receive(&mut self) -> Option<(Self::RxToken, Self::TxToken)> {
if let (Some(rx_slot), Some(tx_slot)) = (next_rx_slot(), next_tx_slot()) {
Some((EthernetRxSlot(rx_slot), EthernetTxSlot(tx_slot)))
} else {
None
}
}
fn transmit(&mut self) -> Option<Self::TxToken> {
if let Some(tx_slot) = next_tx_slot() {
Some(EthernetTxSlot(tx_slot))
} else {
None
}
}
}
pub struct EthernetRxSlot(usize);
impl phy::RxToken for EthernetRxSlot {
fn consume<R, F>(self, _timestamp: u64, f: F) -> Result<R>
where F: FnOnce(&[u8]) -> Result<R>
{
unsafe {
let length = csr::ethmac::sram_writer_length_read() as usize;
let result = f(slice::from_raw_parts(rx_buffer(self.0), length));
csr::ethmac::sram_writer_ev_pending_write(1);
result
}
}
}
pub struct EthernetTxSlot(usize);
impl phy::TxToken for EthernetTxSlot {
fn consume<R, F>(self, _timestamp: u64, length: usize, f: F) -> Result<R>
where F: FnOnce(&mut [u8]) -> Result<R>
{
debug_assert!(length < SLOT_SIZE);
unsafe {
let result = f(slice::from_raw_parts_mut(tx_buffer(self.0), length))?;
csr::ethmac::sram_reader_slot_write(self.0 as u8);
csr::ethmac::sram_reader_length_write(length as u16);
csr::ethmac::sram_reader_start_write(1);
Ok(result)
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct EthernetStatistics {
rx_preamble_errors: u32,
rx_crc_errors: u32,
rx_dropped: u32,
}
impl EthernetStatistics {
pub fn new() -> Self {
unsafe {
EthernetStatistics {
rx_preamble_errors: csr::ethmac::preamble_errors_read(),
rx_crc_errors: csr::ethmac::crc_errors_read(),
rx_dropped: csr::ethmac::sram_writer_errors_read(),
}
}
}
pub fn update(&mut self) -> Option<Self> {
let old = self.clone();
*self = Self::new();
let diff = EthernetStatistics {
rx_preamble_errors: self.rx_preamble_errors.wrapping_sub(old.rx_preamble_errors),
rx_crc_errors: self.rx_crc_errors.wrapping_sub(old.rx_crc_errors),
rx_dropped: self.rx_dropped.wrapping_sub(old.rx_dropped),
};
if diff == EthernetStatistics::default() {
None
} else {
Some(diff)
}
}
}
impl fmt::Display for EthernetStatistics {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.rx_preamble_errors > 0 {
write!(f, " rx preamble errors: {}", self.rx_preamble_errors)?
}
if self.rx_crc_errors > 0 {
write!(f, " rx crc errors: {}", self.rx_crc_errors)?
}
if self.rx_dropped > 0 {
write!(f, " rx dropped: {}", self.rx_dropped)?
}
Ok(())
}
}

View File

@ -14,6 +14,7 @@ extern crate alloc_list;
#[macro_use]
extern crate std_artiq as std;
extern crate logger_artiq;
extern crate backtrace_artiq;
#[macro_use]
extern crate board;
extern crate proto;
@ -21,24 +22,12 @@ extern crate amp;
#[cfg(has_drtio)]
extern crate drtioaux;
use std::boxed::Box;
use smoltcp::wire::{EthernetAddress, IpAddress};
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
use board::config;
use proto::{mgmt_proto, analyzer_proto, moninj_proto, rpc_proto, session_proto, kernel_proto};
use amp::{mailbox, rpc_queue};
macro_rules! borrow_mut {
($x:expr) => ({
match $x.try_borrow_mut() {
Ok(x) => x,
Err(_) => panic!("cannot borrow mutably at {}:{}", file!(), line!())
}
})
}
#[cfg(has_spiflash)]
mod config;
#[cfg(not(has_spiflash))]
#[path="config_dummy.rs"] mod config;
mod ethmac;
mod rtio_mgt;
@ -95,7 +84,7 @@ fn startup() {
let protocol_addr;
match config::read_str("ip", |r| r?.parse()) {
Err(()) | Ok(IpAddress::Unspecified) => {
Err(()) => {
protocol_addr = IpAddress::v4(192, 168, 1, 50);
info!("using default IP address {}", protocol_addr);
}
@ -105,19 +94,37 @@ fn startup() {
}
}
// fn _net_trace_writer<U>(timestamp: u64, printer: smoltcp::wire::PrettyPrinter<U>)
// where U: smoltcp::wire::pretty_print::PrettyPrint {
// let seconds = timestamp / 1000;
// let micros = timestamp % 1000 * 1000;
// print!("\x1b[37m[{:6}.{:06}s]\n{}\x1b[0m", seconds, micros, printer)
// }
let net_device = unsafe { ethmac::EthernetDevice::new() };
let net_device = ethmac::EthernetDevice;
// let net_device = smoltcp::phy::EthernetTracer::new(net_device, _net_trace_writer);
let arp_cache = smoltcp::iface::SliceArpCache::new([Default::default(); 8]);
let mut interface = smoltcp::iface::EthernetInterface::new(
Box::new(net_device), Box::new(arp_cache) as Box<smoltcp::iface::ArpCache>,
hardware_addr, [protocol_addr]);
let net_device = {
use smoltcp::wire::PrettyPrinter;
use smoltcp::wire::EthernetFrame;
fn net_trace_writer(timestamp: u64, printer: PrettyPrinter<EthernetFrame<&[u8]>>) {
let seconds = timestamp / 1000;
let micros = timestamp % 1000 * 1000;
print!("\x1b[37m[{:6}.{:06}s]\n{}\x1b[0m\n", seconds, micros, printer)
}
fn net_trace_silent(_timestamp: u64, _printer: PrettyPrinter<EthernetFrame<&[u8]>>) {}
let net_trace_fn: fn(u64, PrettyPrinter<EthernetFrame<&[u8]>>);
match config::read_str("net_trace", |r| r.map(|s| s == "1")) {
Ok(true) => net_trace_fn = net_trace_writer,
_ => net_trace_fn = net_trace_silent
}
smoltcp::phy::EthernetTracer::new(net_device, net_trace_fn)
};
let mut neighbor_cache_storage = [None; 8];
let neighbor_cache =
smoltcp::iface::NeighborCache::new(&mut neighbor_cache_storage[..]);
let mut interface =
smoltcp::iface::EthernetInterfaceBuilder::new(net_device)
.neighbor_cache(neighbor_cache)
.ethernet_addr(hardware_addr)
.ip_addrs([IpCidr::new(protocol_addr, 0)])
.finalize();
let mut scheduler = sched::Scheduler::new();
let io = scheduler.io();
@ -154,11 +161,16 @@ fn startup() {
loop {
scheduler.run();
match interface.poll(&mut *borrow_mut!(scheduler.sockets()),
board::clock::get_ms()) {
Ok(_poll_at) => (),
Err(smoltcp::Error::Unrecognized) => (),
Err(err) => warn!("network error: {}", err)
{
let sockets = &mut *scheduler.sockets().borrow_mut();
loop {
match interface.poll(sockets, board::clock::get_ms()) {
Ok(true) => (),
Ok(false) => break,
Err(smoltcp::Error::Unrecognized) => (),
Err(err) => warn!("network error: {}", err)
}
}
}
}
}
@ -189,7 +201,9 @@ pub extern fn exception_handler(vect: u32, _regs: *const u32, pc: u32, ea: u32)
#[no_mangle]
pub extern fn abort() {
panic!("aborted")
println!("aborted");
loop {}
}
#[no_mangle]
@ -197,6 +211,12 @@ pub extern fn abort() {
pub extern fn panic_fmt(args: core::fmt::Arguments, file: &'static str, line: u32) -> ! {
println!("panic at {}:{}: {}", file, line, args);
println!("backtrace for software version {}:",
include_str!(concat!(env!("OUT_DIR"), "/git-describe")));
let _ = backtrace_artiq::backtrace(|ip| {
println!("{:#08x}", ip);
});
if config::read_str("panic_reboot", |r| r == Ok("1")) {
println!("rebooting...");
unsafe { board::boot::reboot() }
@ -206,11 +226,3 @@ pub extern fn panic_fmt(args: core::fmt::Arguments, file: &'static str, line: u3
loop {}
}
}
// Allow linking with crates that are built as -Cpanic=unwind even if we use -Cpanic=abort.
// This is never called.
#[allow(non_snake_case)]
#[no_mangle]
pub extern fn _Unwind_Resume() -> ! {
loop {}
}

View File

@ -1,5 +1,4 @@
use config;
use board::csr;
use board::{csr, config};
use sched::Io;
#[cfg(has_rtio_crg)]
@ -219,16 +218,25 @@ pub fn startup(io: &Io) {
let clk = config::read("startup_clock", |result| {
match result {
Ok(b"i") => RtioClock::Internal,
Ok(b"e") => RtioClock::External,
_ => {
error!("unrecognized startup_clock configuration entry");
Ok(b"i") => {
info!("using internal startup RTIO clock");
RtioClock::Internal
},
Ok(b"e") => {
info!("using external startup RTIO clock");
RtioClock::External
},
Err(()) => {
info!("using internal startup RTIO clock (by default)");
RtioClock::Internal
},
Ok(_) => {
error!("unrecognized startup_clock configuration entry, using internal RTIO clock");
RtioClock::Internal
}
}
});
info!("startup RTIO clock: {:?}", clk);
if !crg::switch_clock(clk as u8) {
error!("startup RTIO clock failed");
warn!("this may cause the system initialization to fail");

View File

@ -20,6 +20,21 @@ SECTIONS
_etext = .;
} > runtime
.eh_frame :
{
__eh_frame_start = .;
KEEP(*(.eh_frame))
__eh_frame_end = .;
} > runtime
.eh_frame_hdr :
{
KEEP(*(.eh_frame_hdr))
} > runtime
__eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0;
__eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0;
/* https://sourceware.org/bugzilla/show_bug.cgi?id=20475 */
.got :
{
@ -79,10 +94,4 @@ SECTIONS
. = ORIGIN(runtime) + LENGTH(runtime);
_eheap = .;
} > runtime
/DISCARD/ :
{
*(.eh_frame)
*(.gcc_except_table)
}
}

View File

@ -1,19 +1,20 @@
#![allow(dead_code)]
use std::mem;
use std::cell::{Cell, RefCell, RefMut};
use std::cell::{Cell, RefCell};
use std::vec::Vec;
use std::io::{Read, Write, Result, Error, ErrorKind};
use fringe::OwnedStack;
use fringe::generator::{Generator, Yielder, State as GeneratorState};
use smoltcp::wire::IpEndpoint;
use smoltcp::socket::{AsSocket, SocketHandle};
type SocketSet = ::smoltcp::socket::SocketSet<'static, 'static, 'static>;
use smoltcp::socket::{SocketHandle, SocketRef};
use board;
use urc::Urc;
type SocketSet = ::smoltcp::socket::SocketSet<'static, 'static, 'static>;
#[derive(Debug)]
struct WaitRequest {
event: Option<*const (Fn() -> bool + 'static)>,
@ -123,7 +124,7 @@ impl Scheduler {
pub fn run(&mut self) {
self.sockets.borrow_mut().prune();
self.threads.append(&mut *borrow_mut!(self.spawned));
self.threads.append(&mut *self.spawned.borrow_mut());
if self.threads.len() == 0 { return }
let now = board::clock::get_ms();
@ -132,7 +133,7 @@ impl Scheduler {
self.run_idx = (self.run_idx + 1) % self.threads.len();
let result = {
let mut thread = borrow_mut!(self.threads[self.run_idx].0);
let mut thread = self.threads[self.run_idx].0.borrow_mut();
match thread.waiting_for {
_ if thread.interrupted => {
thread.interrupted = false;
@ -163,7 +164,7 @@ impl Scheduler {
},
Some(wait_request) => {
// The thread has suspended itself.
let mut thread = borrow_mut!(self.threads[self.run_idx].0);
let mut thread = self.threads[self.run_idx].0.borrow_mut();
thread.waiting_for = wait_request
}
}
@ -188,7 +189,7 @@ impl<'a> Io<'a> {
pub fn spawn<F>(&self, stack_size: usize, f: F) -> ThreadHandle
where F: 'static + FnOnce(Io) + Send {
let handle = unsafe { Thread::new(self, stack_size, f) };
borrow_mut!(self.spawned).push(handle.clone());
self.spawned.borrow_mut().push(handle.clone());
handle
}
@ -240,87 +241,18 @@ macro_rules! until {
($socket:expr, $ty:ty, |$var:ident| $cond:expr) => ({
let (sockets, handle) = ($socket.io.sockets.clone(), $socket.handle);
$socket.io.until(move || {
let mut sockets = borrow_mut!(sockets);
let $var: &mut $ty = sockets.get_mut(handle).as_socket();
let mut sockets = sockets.borrow_mut();
let $var = sockets.get::<$ty>(handle);
$cond
})
})
}
use ::smoltcp::Error as ErrorLower;
// https://github.com/rust-lang/rust/issues/44057
// type ErrorLower = ::smoltcp::Error;
type UdpPacketBuffer = ::smoltcp::socket::UdpPacketBuffer<'static>;
type UdpSocketBuffer = ::smoltcp::socket::UdpSocketBuffer<'static, 'static>;
type UdpSocketLower = ::smoltcp::socket::UdpSocket<'static, 'static>;
pub struct UdpSocket<'a> {
io: &'a Io<'a>,
handle: SocketHandle
}
impl<'a> UdpSocket<'a> {
pub fn new(io: &'a Io<'a>, buffer_depth: usize, buffer_width: usize) -> UdpSocket<'a> {
let mut rx_buffer = vec![];
let mut tx_buffer = vec![];
for _ in 0..buffer_depth {
rx_buffer.push(UdpPacketBuffer::new(vec![0; buffer_width]));
tx_buffer.push(UdpPacketBuffer::new(vec![0; buffer_width]));
}
let handle = borrow_mut!(io.sockets)
.add(UdpSocketLower::new(
UdpSocketBuffer::new(rx_buffer),
UdpSocketBuffer::new(tx_buffer)));
UdpSocket {
io: io,
handle: handle
}
}
fn as_lower<'b>(&'b self) -> RefMut<'b, UdpSocketLower> {
RefMut::map(borrow_mut!(self.io.sockets),
|sockets| sockets.get_mut(self.handle).as_socket())
}
pub fn bind<T: Into<IpEndpoint>>(&self, endpoint: T) -> Result<()> {
match self.as_lower().bind(endpoint) {
Ok(()) => Ok(()),
Err(ErrorLower::Illegal) =>
Err(Error::new(ErrorKind::Other, "already listening")),
Err(ErrorLower::Unaddressable) =>
Err(Error::new(ErrorKind::AddrNotAvailable, "port cannot be zero")),
_ => unreachable!()
}
}
pub fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, IpEndpoint)> {
until!(self, UdpSocketLower, |s| s.can_recv())?;
match self.as_lower().recv_slice(buf) {
Ok(result) => Ok(result),
Err(_) => unreachable!()
}
}
pub fn send_to(&self, buf: &[u8], addr: IpEndpoint) -> Result<()> {
until!(self, UdpSocketLower, |s| s.can_send())?;
match self.as_lower().send_slice(buf, addr) {
Ok(()) => Ok(()),
Err(ErrorLower::Unaddressable) =>
Err(Error::new(ErrorKind::AddrNotAvailable, "unaddressable destination")),
Err(ErrorLower::Truncated) =>
Err(Error::new(ErrorKind::Other, "packet does not fit in buffer")),
Err(_) => unreachable!()
}
}
}
impl<'a> Drop for UdpSocket<'a> {
fn drop(&mut self) {
borrow_mut!(self.io.sockets).release(self.handle)
}
}
type TcpSocketBuffer = ::smoltcp::socket::TcpSocketBuffer<'static>;
type TcpSocketLower = ::smoltcp::socket::TcpSocket<'static>;
@ -337,7 +269,8 @@ impl<'a> TcpListener<'a> {
fn new_lower(io: &'a Io<'a>, buffer_size: usize) -> SocketHandle {
let rx_buffer = vec![0; buffer_size];
let tx_buffer = vec![0; buffer_size];
borrow_mut!(io.sockets)
io.sockets
.borrow_mut()
.add(TcpSocketLower::new(
TcpSocketBuffer::new(rx_buffer),
TcpSocketBuffer::new(tx_buffer)))
@ -352,35 +285,41 @@ impl<'a> TcpListener<'a> {
}
}
fn as_lower<'b>(&'b self) -> RefMut<'b, TcpSocketLower> {
RefMut::map(borrow_mut!(self.io.sockets),
|sockets| sockets.get_mut(self.handle.get()).as_socket())
fn with_lower<F, R>(&self, f: F) -> R
where F: FnOnce(SocketRef<TcpSocketLower>) -> R {
let mut sockets = self.io.sockets.borrow_mut();
let result = f(sockets.get(self.handle.get()));
result
}
pub fn is_open(&self) -> bool {
self.as_lower().is_open()
self.with_lower(|s| s.is_open())
}
pub fn can_accept(&self) -> bool {
self.as_lower().is_active()
self.with_lower(|s| s.is_active())
}
pub fn local_endpoint(&self) -> IpEndpoint {
self.as_lower().local_endpoint()
self.with_lower(|s| s.local_endpoint())
}
pub fn listen<T: Into<IpEndpoint>>(&self, endpoint: T) -> Result<()> {
let endpoint = endpoint.into();
match self.as_lower().listen(endpoint) {
Ok(()) => Ok(()),
Err(ErrorLower::Illegal) =>
Err(Error::new(ErrorKind::Other, "already listening")),
Err(ErrorLower::Unaddressable) =>
Err(Error::new(ErrorKind::InvalidInput, "port cannot be zero")),
_ => unreachable!()
}?;
self.endpoint.set(endpoint);
Ok(())
self.with_lower(|mut s| s.listen(endpoint))
.map(|()| {
self.endpoint.set(endpoint);
()
})
.map_err(|err| {
match err {
ErrorLower::Illegal =>
Error::new(ErrorKind::Other, "already listening"),
ErrorLower::Unaddressable =>
Error::new(ErrorKind::InvalidInput, "port cannot be zero"),
_ => unreachable!()
}
})
}
pub fn accept(&self) -> Result<TcpStream<'a>> {
@ -389,8 +328,8 @@ impl<'a> TcpListener<'a> {
// that still counts as accepting even though nothing may be sent.
let (sockets, handle) = (self.io.sockets.clone(), self.handle.get());
self.io.until(move || {
let mut sockets = borrow_mut!(sockets);
let socket: &mut TcpSocketLower = sockets.get_mut(handle).as_socket();
let mut sockets = sockets.borrow_mut();
let socket = sockets.get::<TcpSocketLower>(handle);
socket.may_send() || socket.may_recv()
})?;
@ -407,14 +346,14 @@ impl<'a> TcpListener<'a> {
}
pub fn close(&self) {
self.as_lower().close()
self.with_lower(|mut s| s.close())
}
}
impl<'a> Drop for TcpListener<'a> {
fn drop(&mut self) {
self.as_lower().close();
borrow_mut!(self.io.sockets).release(self.handle.get())
self.with_lower(|mut s| s.close());
self.io.sockets.borrow_mut().release(self.handle.get())
}
}
@ -437,57 +376,59 @@ impl<'a> TcpStream<'a> {
}
}
fn as_lower<'b>(&'b self) -> RefMut<'b, TcpSocketLower> {
RefMut::map(borrow_mut!(self.io.sockets),
|sockets| sockets.get_mut(self.handle).as_socket())
fn with_lower<F, R>(&self, f: F) -> R
where F: FnOnce(SocketRef<TcpSocketLower>) -> R {
let mut sockets = self.io.sockets.borrow_mut();
let result = f(sockets.get(self.handle));
result
}
pub fn is_open(&self) -> bool {
self.as_lower().is_open()
self.with_lower(|s| s.is_open())
}
pub fn may_send(&self) -> bool {
self.as_lower().may_send()
self.with_lower(|s| s.may_send())
}
pub fn may_recv(&self) -> bool {
self.as_lower().may_recv()
self.with_lower(|s| s.may_recv())
}
pub fn can_send(&self) -> bool {
self.as_lower().can_send()
self.with_lower(|s| s.can_send())
}
pub fn can_recv(&self) -> bool {
self.as_lower().can_recv()
self.with_lower(|s| s.can_recv())
}
pub fn local_endpoint(&self) -> IpEndpoint {
self.as_lower().local_endpoint()
self.with_lower(|s| s.local_endpoint())
}
pub fn remote_endpoint(&self) -> IpEndpoint {
self.as_lower().remote_endpoint()
self.with_lower(|s| s.remote_endpoint())
}
pub fn timeout(&self) -> Option<u64> {
self.as_lower().timeout()
self.with_lower(|s| s.timeout())
}
pub fn set_timeout(&self, value: Option<u64>) {
self.as_lower().set_timeout(value)
self.with_lower(|mut s| s.set_timeout(value))
}
pub fn keep_alive(&self) -> Option<u64> {
self.as_lower().keep_alive()
self.with_lower(|s| s.keep_alive())
}
pub fn set_keep_alive(&self, value: Option<u64>) {
self.as_lower().set_keep_alive(value)
self.with_lower(|mut s| s.set_keep_alive(value))
}
pub fn close(&self) -> Result<()> {
self.as_lower().close();
self.with_lower(|mut s| s.close());
until!(self, TcpSocketLower, |s| !s.is_open())?;
// right now the socket may be in TIME-WAIT state. if we don't give it a chance to send
// a packet, and the user code executes a loop { s.listen(); s.read(); s.close(); }
@ -499,12 +440,12 @@ impl<'a> TcpStream<'a> {
impl<'a> Read for TcpStream<'a> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
// Only borrow the underlying socket for the span of the next statement.
let result = self.as_lower().recv_slice(buf);
let result = self.with_lower(|mut s| s.recv_slice(buf));
match result {
// Slow path: we need to block until buffer is non-empty.
Ok(0) => {
until!(self, TcpSocketLower, |s| s.can_recv() || !s.may_recv())?;
match self.as_lower().recv_slice(buf) {
match self.with_lower(|mut s| s.recv_slice(buf)) {
Ok(length) => Ok(length),
Err(ErrorLower::Illegal) => Ok(0),
_ => unreachable!()
@ -523,12 +464,12 @@ impl<'a> Read for TcpStream<'a> {
impl<'a> Write for TcpStream<'a> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
// Only borrow the underlying socket for the span of the next statement.
let result = self.as_lower().send_slice(buf);
let result = self.with_lower(|mut s| s.send_slice(buf));
match result {
// Slow path: we need to block until buffer is non-full.
Ok(0) => {
until!(self, TcpSocketLower, |s| s.can_send() || !s.may_send())?;
match self.as_lower().send_slice(buf) {
match self.with_lower(|mut s| s.send_slice(buf)) {
Ok(length) => Ok(length),
Err(ErrorLower::Illegal) => Ok(0),
_ => unreachable!()
@ -545,7 +486,7 @@ impl<'a> Write for TcpStream<'a> {
fn flush(&mut self) -> Result<()> {
until!(self, TcpSocketLower, |s| s.send_queue() == 0 || !s.may_send())?;
if self.as_lower().send_queue() == 0 {
if self.with_lower(|s| s.send_queue()) == 0 {
Ok(())
} else {
Err(Error::new(ErrorKind::ConnectionAborted, "connection aborted"))
@ -555,7 +496,7 @@ impl<'a> Write for TcpStream<'a> {
impl<'a> Drop for TcpStream<'a> {
fn drop(&mut self) {
self.as_lower().close();
borrow_mut!(self.io.sockets).release(self.handle)
self.with_lower(|mut s| s.close());
self.io.sockets.borrow_mut().release(self.handle)
}
}

View File

@ -3,14 +3,14 @@ use std::{mem, str};
use std::cell::{Cell, RefCell};
use std::io::{self, Read, Write};
use std::error::Error;
use {config, rtio_mgt, mailbox, rpc_queue, kernel};
use {rtio_mgt, mailbox, rpc_queue, kernel};
use cache::Cache;
use rtio_dma::Manager as DmaManager;
use urc::Urc;
use sched::{ThreadHandle, Io};
use sched::{TcpListener, TcpStream};
use byteorder::{ByteOrder, NetworkEndian};
use board;
use board::{self, config};
use rpc_proto as rpc;
use session_proto as host;
@ -615,7 +615,7 @@ pub fn thread(io: Io) {
{
let congress = congress.clone();
respawn(&io, &mut kernel_thread, move |io| {
let mut congress = borrow_mut!(congress);
let mut congress = congress.borrow_mut();
info!("running startup kernel");
match flash_kernel_worker(&io, &mut congress, "startup_kernel") {
Ok(()) => info!("startup kernel finished"),
@ -650,7 +650,7 @@ pub fn thread(io: Io) {
let congress = congress.clone();
let stream = stream.into_handle();
respawn(&io, &mut kernel_thread, move |io| {
let mut congress = borrow_mut!(congress);
let mut congress = congress.borrow_mut();
let mut stream = TcpStream::from_handle(&io, stream);
match host_kernel_worker(&io, &mut stream, &mut *congress) {
Ok(()) => (),
@ -673,7 +673,7 @@ pub fn thread(io: Io) {
let congress = congress.clone();
respawn(&io, &mut kernel_thread, move |io| {
let mut congress = borrow_mut!(congress);
let mut congress = congress.borrow_mut();
match flash_kernel_worker(&io, &mut *congress, "idle_kernel") {
Ok(()) =>
info!("idle kernel finished, standing by"),

View File

@ -5,25 +5,17 @@ LDFLAGS += -L../libbase
RUSTFLAGS += -Cpanic=abort
all: satman.bin satman.fbi
all:: satman.bin satman.fbi
.PHONY: $(RUSTOUT)/libsatman.a
$(RUSTOUT)/libsatman.a:
$(cargo) --manifest-path $(SATMAN_DIRECTORY)/Cargo.toml
satman.elf: $(RUSTOUT)/libsatman.a
$(LD) $(LDFLAGS) -T $(SATMAN_DIRECTORY)/satman.ld -o $@ $^
@chmod -x $@
$(link) -T $(SATMAN_DIRECTORY)/satman.ld
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
@chmod -x $@
$(objcopy) -O binary
%.fbi: %.bin
@echo " MSCIMG " $@ && $(PYTHON) -m misoc.tools.mkmscimg -f -o $@ $<
clean:
$(RM) satman.elf satman.bin satman.fbi
$(RM) -rf cargo
.PHONY: all clean
$(mscimg) -f

View File

@ -51,6 +51,10 @@ Prerequisites:
help="target adapter, default: %(default)s")
parser.add_argument("--target-file", default=None,
help="use alternative OpenOCD target file")
parser.add_argument("-I", "--preinit-command", default=[], action="append",
help="add a pre-initialization OpenOCD command. "
"Useful for selecting a development board "
"when several are connected.")
parser.add_argument("-f", "--storage", help="write file to storage area")
parser.add_argument("-d", "--dir", help="look for files in this directory")
parser.add_argument("action", metavar="ACTION", nargs="*",
@ -69,8 +73,8 @@ def main():
"start": "xc7_program xc7.tap",
"gateware": 0x000000,
"bios": 0xaf0000,
"runtime": 0xb00000,
"storage": 0xb80000,
"storage": 0xb30000,
"runtime": 0xb40000,
},
}[opts.target]
@ -84,6 +88,7 @@ def main():
conv = False
prog = []
prog.extend(opts.preinit_command)
prog.append("init")
for action in opts.action:
if action == "proxy":

View File

@ -94,26 +94,26 @@ class DBWriter(TaskObject):
"too many pending updates", k)
async def _do(self):
while True:
k, v, t = await self._queue.get()
url = self.base_url + "/write"
params = {"u": self.user, "p": self.password, "db": self.database,
"precision": "ms"}
data = "{},dataset={} {} {}".format(
self.table, k, format_influxdb(v), round(t*1e3))
try:
response = await aiohttp.request(
"POST", url, params=params, data=data)
except:
logger.warning("got exception trying to update '%s'",
k, exc_info=True)
else:
if response.status not in (200, 204):
content = (await response.content.read()).decode().strip()
logger.warning("got HTTP status %d "
"trying to update '%s': %s",
response.status, k, content)
response.close()
async with aiohttp.ClientSession() as session:
while True:
k, v, t = await self._queue.get()
url = self.base_url + "/write"
params = {"u": self.user, "p": self.password, "db": self.database,
"precision": "ms"}
data = "{},dataset={} {} {}".format(
self.table, k, format_influxdb(v), round(t*1e3))
try:
response = await session.post(url, params=params, data=data)
except:
logger.warning("got exception trying to update '%s'",
k, exc_info=True)
else:
if response.status not in (200, 204):
content = (await response.content.read()).decode().strip()
logger.warning("got HTTP status %d "
"trying to update '%s': %s",
response.status, k, content)
response.close()
class _Mock:

View File

@ -4,8 +4,8 @@
# * tcpdump has CAP_NET_RAW capabilities set
# use # setcap cap_net_raw+eip /usr/sbin/tcpdump
import argparse
import os
import argparse
import subprocess
from artiq.tools import verbosity_args, init_logger, logger, SSHClient
@ -49,7 +49,6 @@ def main():
subprocess.check_call(args.command)
except subprocess.CalledProcessError:
logger.error("Command failed")
sys.exit(1)
tcpdump.close()
sftp.get("{tmp}/trace.pcap".format(tmp=client.tmp),

View File

@ -208,9 +208,11 @@ class SPIMaster(Module):
clk_t = TSTriple()
self.specials += clk_t.get_tristate(pads.clk)
self.comb += [
clk_t.oe.eq(~config.offline),
clk_t.o.eq((spi.cg.clk & spi.cs) ^ config.clk_polarity),
self.comb += clk_t.oe.eq(~config.offline),
self.sync += [
If(spi.cg.ce & spi.cg.edge,
clk_t.o.eq((~spi.cg.clk & spi.cs_next) ^ config.clk_polarity)
)
]
mosi_t = TSTriple()

View File

@ -157,7 +157,6 @@ class Phaser(MiniSoC, AMPSoC):
"rtio": 0x20000000,
"rtio_dma": 0x30000000,
"mailbox": 0x70000000,
"ad9154": 0x50000000,
}
mem_map.update(MiniSoC.mem_map)

View File

@ -127,6 +127,7 @@ class SMA_SPI(_NIST_Ions):
self.submodules.cri_con = rtio.CRIInterconnectShared(
[self.rtio.cri, self.rtio_dma.cri],
[self.rtio_core.cri])
self.register_kernel_cpu_csrdevice("cri_con")
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
self.csr_devices.append("rtio_moninj")

View File

@ -12,17 +12,17 @@
version="1.1"
x="0px"
y="0px"
width="360.147"
width="323.49704"
height="432.04401"
viewBox="0 0 360.147 432.04401"
viewBox="0 0 323.49704 432.04401"
enable-background="new 0 0 800 800"
xml:space="preserve"
id="svg2"
inkscape:version="0.91 r13725"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="logo_ver.svg"><metadata
id="metadata548"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs546" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
@ -33,7 +33,7 @@
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1156"
inkscape:window-height="1124"
id="namedview544"
showgrid="false"
fit-margin-top="0"
@ -41,12 +41,12 @@
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="0.834386"
inkscape:cx="-244.98179"
inkscape:cy="163.75581"
inkscape:cx="-466.10247"
inkscape:cy="163.7558"
inkscape:window-x="0"
inkscape:window-y="44"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" /><path
inkscape:current-layer="text3371" /><path
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path381"
@ -54,7 +54,7 @@
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path383"
d="m 53.761,135.723 10.609,9.812 c 0.215,-0.162 0.461,-0.348 0.689,-0.549 20.543,-18.001 43.98,-33.619 69.662,-46.423 32.912,-16.404 60.969,-25.002 88.295,-27.058 2.504,-0.188 4.811,-0.279 7.051,-0.279 9.105,0 16.873,1.591 23.744,4.864 7.635,3.636 11.473,9.741 11.404,18.146 -0.053,6.609 -1.955,13.229 -5.812,20.239 -2.68,4.868 -5.713,9.68 -8.646,14.332 -1.248,1.979 -2.502,3.969 -3.744,5.982 l 10.135,9.65 c 8.092,-10.235 16.82,-22.731 20.846,-38.001 0.467,-1.765 0.861,-3.586 1.244,-5.348 0.174,-0.804 0.348,-1.606 0.529,-2.408 l 0,-8.887 c -0.049,-0.148 -0.102,-0.297 -0.154,-0.444 -0.141,-0.387 -0.285,-0.787 -0.357,-1.216 -2.037,-12.213 -8.967,-20.778 -21.184,-26.186 -7.824,-3.462 -16.289,-4.355 -23.535,-4.772 -2.264,-0.13 -4.576,-0.196 -6.877,-0.196 -11.945,0 -24.328,1.727 -37.859,5.278 -46.736,12.272 -90.896,35.554 -131.252,69.197 -1.098,0.917 -2.182,1.903 -3.332,2.947 -0.465,0.425 -0.948,0.863 -1.456,1.32 z" /><path
d="m 53.761,135.723 10.609,9.812 c 0.215,-0.162 0.461,-0.348 0.689,-0.549 20.543,-18.001 43.98,-33.619 69.662,-46.423 32.912,-16.404 60.969,-25.002 88.295,-27.058 2.504,-0.188 4.811,-0.279 7.051,-0.279 9.105,0 16.873,1.591 23.744,4.864 7.635,3.636 11.473,9.741 11.404,18.146 -0.053,6.609 -1.955,13.229 -5.812,20.239 -2.68,4.868 -5.713,9.68 -8.646,14.332 -1.248,1.979 -2.502,3.969 -3.744,5.982 l 10.135,9.65 c 8.092,-10.235 16.82,-22.731 20.846,-38.001 0.467,-1.765 0.861,-3.586 1.244,-5.348 0.174,-0.804 0.348,-1.606 0.529,-2.408 v -8.887 c -0.049,-0.148 -0.102,-0.297 -0.154,-0.444 -0.141,-0.387 -0.285,-0.787 -0.357,-1.216 -2.037,-12.213 -8.967,-20.778 -21.184,-26.186 -7.824,-3.462 -16.289,-4.355 -23.535,-4.772 -2.264,-0.13 -4.576,-0.196 -6.877,-0.196 -11.945,0 -24.328,1.727 -37.859,5.278 -46.736,12.272 -90.896,35.554 -131.252,69.197 -1.098,0.917 -2.182,1.903 -3.332,2.947 -0.465,0.425 -0.948,0.863 -1.456,1.32 z" /><path
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path385"
@ -82,11 +82,11 @@
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path397"
d="m 180.738,111.632 c -0.625,-4.189 -1.227,-8.218 -1.867,-12.238 -0.326,-2.036 -5.861,-6.224 -8.229,-6.224 -0.156,0 -0.291,0.02 -0.402,0.058 -4.172,1.46 -8.242,3.096 -12.551,4.827 -1.42,0.57 -2.855,1.146 -4.316,1.727 l 28,16.088 -0.635,-4.238 z" /><path
d="m 180.738,111.632 c -0.625,-4.189 -1.227,-8.218 -1.867,-12.238 -0.326,-2.036 -5.861,-6.224 -8.229,-6.224 -0.156,0 -0.291,0.02 -0.402,0.058 -4.172,1.46 -8.242,3.096 -12.551,4.827 -1.42,0.57 -2.855,1.146 -4.316,1.727 l 28,16.088 z" /><path
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path399"
d="m 90.154,136.545 c -0.338,0.264 -0.668,0.525 -1,0.788 -0.463,0.366 -0.936,0.736 -1.393,1.099 -2.838,2.248 -5.516,4.371 -8.346,6.353 -2.75,1.927 -3.779,4.095 -3.336,7.03 0.102,0.675 0.096,1.436 0.09,2.17 -0.01,1.219 -0.02,2.479 0.488,2.946 3.336,3.059 6.891,5.851 10.654,8.807 0.605,0.477 1.227,0.968 1.842,1.452 0.334,0.264 0.664,0.523 1,0.789 0.188,0.148 0.369,0.29 0.557,0.439 l 0,-32.312 c -0.189,0.148 -0.369,0.291 -0.556,0.439 z" /><path
d="m 90.154,136.545 c -0.338,0.264 -0.668,0.525 -1,0.788 -0.463,0.366 -0.936,0.736 -1.393,1.099 -2.838,2.248 -5.516,4.371 -8.346,6.353 -2.75,1.927 -3.779,4.095 -3.336,7.03 0.102,0.675 0.096,1.436 0.09,2.17 -0.01,1.219 -0.02,2.479 0.488,2.946 3.336,3.059 6.891,5.851 10.654,8.807 0.605,0.477 1.227,0.968 1.842,1.452 0.334,0.264 0.664,0.523 1,0.789 0.188,0.148 0.369,0.29 0.557,0.439 v -32.312 c -0.189,0.148 -0.369,0.291 -0.556,0.439 z" /><path
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path401"
@ -98,7 +98,7 @@
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path405"
d="M 231.324,171.353 221.01,161.63 c -0.9,2.513 -2.059,14.3 -1.457,19.737 l 11.771,-10.014 z" /><path
d="M 231.324,171.353 221.01,161.63 c -0.9,2.513 -2.059,14.3 -1.457,19.737 z" /><path
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path407"
@ -117,25 +117,25 @@
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path415"
d="m 366.13,593.558 c 7.498,-5.083 10.756,-15.119 7.922,-24.407 -2.773,-9.089 -10.521,-14.536 -20.727,-14.573 l -26.715,0 0,61.202 14.156,0 0,-18.602 9.979,0 10.836,18.602 16.479,0 0,-1.06 -12.725,-20.623 0.795,-0.539 z m -12.801,-8.731 -12.562,0 0,-17.809 1.004,0 c 1.254,0 2.529,-0.01 3.811,-0.02 2.6,-0.021 5.225,-0.041 7.771,0.02 5.328,0.052 7.74,4.621 7.719,8.845 -0.022,4.454 -2.688,8.964 -7.743,8.964 z" /><polygon
d="m 366.13,593.558 c 7.498,-5.083 10.756,-15.119 7.922,-24.407 -2.773,-9.089 -10.521,-14.536 -20.727,-14.573 H 326.61 v 61.202 h 14.156 v -18.602 h 9.979 l 10.836,18.602 h 16.479 v -1.06 l -12.725,-20.623 z m -12.801,-8.731 h -12.562 v -17.809 h 1.004 c 1.254,0 2.529,-0.01 3.811,-0.02 2.6,-0.021 5.225,-0.041 7.771,0.02 5.328,0.052 7.74,4.621 7.719,8.845 -0.022,4.454 -2.688,8.964 -7.743,8.964 z" /><polygon
style="fill:#ffffff"
id="polygon417"
points="432.151,554.577 387.202,554.577 387.202,567.019 402.733,567.019 402.733,615.779 416.71,615.779 416.71,567.019 432.151,567.019 " /><polygon
points="387.202,567.019 402.733,567.019 402.733,615.779 416.71,615.779 416.71,567.019 432.151,567.019 432.151,554.577 387.202,554.577 " /><polygon
style="fill:#ffffff"
id="polygon419"
points="464.571,566.657 471.976,566.657 471.976,554.577 443.19,554.577 443.19,566.657 450.595,566.657 450.595,603.608 442.558,603.608 442.558,615.779 472.606,615.779 472.606,603.608 464.571,603.608 " /><path
points="471.976,554.577 443.19,554.577 443.19,566.657 450.595,566.657 450.595,603.608 442.558,603.608 442.558,615.779 472.606,615.779 472.606,603.608 464.571,603.608 464.571,566.657 471.976,566.657 " /><path
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path421"
d="m 542.927,603.421 c 3.252,-5.109 4.9,-11.218 4.9,-18.153 0,-21.831 -16.283,-31.774 -31.414,-31.774 -15.129,0 -31.414,9.943 -31.414,31.774 0,21.683 16.174,31.56 31.199,31.56 5.541,0 10.949,-1.321 15.637,-3.82 l 0.885,-0.472 1.725,3.244 14.828,0 0,-0.794 -6.68,-11.039 0.334,-0.526 z m -26.514,0.053 c -8.094,0 -16.805,-5.697 -16.805,-18.206 0,-12.415 8.711,-18.069 16.805,-18.069 8.094,0 16.807,5.654 16.807,18.069 0,12.508 -8.713,18.206 -16.807,18.206 z" /></g><path
d="m 542.927,603.421 c 3.252,-5.109 4.9,-11.218 4.9,-18.153 0,-21.831 -16.283,-31.774 -31.414,-31.774 -15.129,0 -31.414,9.943 -31.414,31.774 0,21.683 16.174,31.56 31.199,31.56 5.541,0 10.949,-1.321 15.637,-3.82 l 0.885,-0.472 1.725,3.244 h 14.828 v -0.794 l -6.68,-11.039 z m -26.514,0.053 c -8.094,0 -16.805,-5.697 -16.805,-18.206 0,-12.415 8.711,-18.069 16.805,-18.069 8.094,0 16.807,5.654 16.807,18.069 0,12.508 -8.713,18.206 -16.807,18.206 z" /></g><path
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path431"
d="m 165.162,221.756 0.006,-0.025 C 140.75,212.522 116.912,200.02 94.189,184.475 69.636,167.678 51.56,151.283 37.304,132.879 28.589,121.632 23.536,112.162 20.923,102.174 c -3.068,-11.729 0.105,-20.54 9.178,-25.482 2.277,-1.241 4.834,-2.269 7.596,-3.054 7.576,-2.153 15.721,-2.812 25.201,-2.015 1.244,0.104 2.52,0.217 3.805,0.332 1.402,0.123 2.803,0.242 4.209,0.368 l 3.176,0.281 3.846,-13.919 c -0.947,-0.121 -1.893,-0.245 -2.83,-0.37 -2.537,-0.337 -4.934,-0.656 -7.25,-0.857 -4.689,-0.406 -8.803,-0.604 -12.578,-0.604 -8.74,0 -16.342,1.076 -23.24,3.29 -14.58,4.68 -23.049,13.281 -25.893,26.297 -1.943,8.9 -0.568,18.38 4.328,29.833 6.098,14.267 15.623,27.692 29.977,42.251 31.707,32.162 69.879,56.911 116.699,75.662 3.182,1.274 6.383,2.416 9.771,3.624 1.434,0.511 2.889,1.029 4.369,1.568 l 2.396,-8.365 -8.521,-9.258 z" /><path
d="m 165.162,221.756 0.006,-0.025 C 140.75,212.522 116.912,200.02 94.189,184.475 69.636,167.678 51.56,151.283 37.304,132.879 28.589,121.632 23.536,112.162 20.923,102.174 c -3.068,-11.729 0.105,-20.54 9.178,-25.482 2.277,-1.241 4.834,-2.269 7.596,-3.054 7.576,-2.153 15.721,-2.812 25.201,-2.015 1.244,0.104 2.52,0.217 3.805,0.332 1.402,0.123 2.803,0.242 4.209,0.368 l 3.176,0.281 3.846,-13.919 c -0.947,-0.121 -1.893,-0.245 -2.83,-0.37 -2.537,-0.337 -4.934,-0.656 -7.25,-0.857 -4.689,-0.406 -8.803,-0.604 -12.578,-0.604 -8.74,0 -16.342,1.076 -23.24,3.29 -14.58,4.68 -23.049,13.281 -25.893,26.297 -1.943,8.9 -0.568,18.38 4.328,29.833 6.098,14.267 15.623,27.692 29.977,42.251 31.707,32.162 69.879,56.911 116.699,75.662 3.182,1.274 6.383,2.416 9.771,3.624 1.434,0.511 2.889,1.029 4.369,1.568 l 2.396,-8.365 z" /><path
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path433"
d="m 279.656,208.102 c -0.146,-0.262 -0.314,-0.56 -0.359,-0.905 -0.99,-8.005 -3.834,-16.142 -8.688,-24.875 -7.945,-14.297 -18.83,-27.683 -34.252,-42.126 -3.812,-3.572 -7.723,-6.949 -11.863,-10.523 -1.678,-1.448 -3.377,-2.915 -5.096,-4.419 -0.006,0.032 -0.012,0.062 -0.018,0.092 -0.062,0.355 -0.096,0.551 -0.09,0.713 l 0.148,3.794 c 0.176,4.559 0.359,9.272 0.67,13.896 0.047,0.706 0.615,1.672 1.52,2.583 2.135,2.144 4.346,4.286 6.484,6.358 3.807,3.687 7.742,7.5 11.389,11.467 11.611,12.634 19.076,24.245 23.488,36.543 2.049,5.705 2.707,10.802 2.012,15.581 -1.146,7.896 -6.145,13.235 -15.281,16.322 -2.455,0.829 -5.002,1.474 -7.656,1.956 l 9.738,12.6 c 1.551,-0.468 3.08,-0.975 4.574,-1.562 12.387,-4.858 19.754,-12.956 22.521,-24.758 l 0.869,-3.686 0,-8.847 c -0.034,-0.068 -0.071,-0.136 -0.11,-0.204 z" /><g
d="m 279.656,208.102 c -0.146,-0.262 -0.314,-0.56 -0.359,-0.905 -0.99,-8.005 -3.834,-16.142 -8.688,-24.875 -7.945,-14.297 -18.83,-27.683 -34.252,-42.126 -3.812,-3.572 -7.723,-6.949 -11.863,-10.523 -1.678,-1.448 -3.377,-2.915 -5.096,-4.419 -0.006,0.032 -0.012,0.062 -0.018,0.092 -0.062,0.355 -0.096,0.551 -0.09,0.713 l 0.148,3.794 c 0.176,4.559 0.359,9.272 0.67,13.896 0.047,0.706 0.615,1.672 1.52,2.583 2.135,2.144 4.346,4.286 6.484,6.358 3.807,3.687 7.742,7.5 11.389,11.467 11.611,12.634 19.076,24.245 23.488,36.543 2.049,5.705 2.707,10.802 2.012,15.581 -1.146,7.896 -6.145,13.235 -15.281,16.322 -2.455,0.829 -5.002,1.474 -7.656,1.956 l 9.738,12.6 c 1.551,-0.468 3.08,-0.975 4.574,-1.562 12.387,-4.858 19.754,-12.956 22.521,-24.758 l 0.869,-3.686 v -8.847 c -0.034,-0.068 -0.071,-0.136 -0.11,-0.204 z" /><g
style="fill:#ffffff"
id="g435"
transform="translate(-250.847,-184.784)"><path
@ -146,19 +146,14 @@
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path439"
d="m 433.437,425.474 c -2.322,7.348 -4.98,14.184 -8.043,20.678 -3.967,8.416 -9.191,17.993 -17.877,25.219 -9.297,7.733 -19.082,7.701 -28.365,-0.092 -5.934,-4.982 -10.92,-11.633 -15.691,-20.929 -6.629,-12.926 -11.459,-27.311 -15.66,-46.642 l -0.072,-0.342 c -0.174,-0.828 -0.412,-1.962 -0.893,-2.284 -4.152,-2.786 -8.357,-5.448 -12.807,-8.267 -1.068,-0.677 -2.146,-1.359 -3.238,-2.054 0.164,0.969 0.32,1.911 0.475,2.834 0.434,2.596 0.842,5.047 1.303,7.478 4.703,24.702 10.705,42.76 19.463,58.551 7.541,13.604 17.859,28.05 37.209,32.08 l 8.318,0 c 17.949,-3.632 27.887,-16.568 35.24,-28.748 1.953,-3.234 3.717,-6.507 5.244,-9.726 2.389,-5.035 4.557,-10.249 6.533,-15.655 l -11.139,-12.101 z" /></g><path
d="m 433.437,425.474 c -2.322,7.348 -4.98,14.184 -8.043,20.678 -3.967,8.416 -9.191,17.993 -17.877,25.219 -9.297,7.733 -19.082,7.701 -28.365,-0.092 -5.934,-4.982 -10.92,-11.633 -15.691,-20.929 -6.629,-12.926 -11.459,-27.311 -15.66,-46.642 l -0.072,-0.342 c -0.174,-0.828 -0.412,-1.962 -0.893,-2.284 -4.152,-2.786 -8.357,-5.448 -12.807,-8.267 -1.068,-0.677 -2.146,-1.359 -3.238,-2.054 0.164,0.969 0.32,1.911 0.475,2.834 0.434,2.596 0.842,5.047 1.303,7.478 4.703,24.702 10.705,42.76 19.463,58.551 7.541,13.604 17.859,28.05 37.209,32.08 h 8.318 c 17.949,-3.632 27.887,-16.568 35.24,-28.748 1.953,-3.234 3.717,-6.507 5.244,-9.726 2.389,-5.035 4.557,-10.249 6.533,-15.655 z" /></g><path
inkscape:connector-curvature="0"
style="fill:#ffffff"
id="path493"
d="M 28.084,368.98 0,429.872 l 0,1.124 14.16,0 4.202,-8.945 25.208,0 4.195,8.945 14.16,0 0,-1.124 -28.172,-60.892 -5.669,0 z m -5.438,41.259 8.215,-19.134 8.424,19.134 -16.639,0 z" /><g
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:expanded;font-size:45px;line-height:125%;font-family:'Novecento sans wide';-inkscape-font-specification:'Novecento sans wide, Semi-Bold Expanded';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 28.084,368.98 0,429.872 v 1.124 h 14.16 l 4.202,-8.945 H 43.57 l 4.195,8.945 h 14.16 v -1.124 L 33.753,368.98 Z m -5.438,41.259 8.215,-19.134 8.424,19.134 z" /><g
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:expanded;font-size:45px;line-height:125%;font-family:'Novecento sans wide';-inkscape-font-specification:'Novecento sans wide, Semi-Bold Expanded';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="text3371"><path
d="m 318.27705,360.24104 c 2.295,-0.315 4.95,-2.115 4.95,-5.895 0,-3.96 -2.88,-6.57 -8.775,-6.57 -4.635,0 -8.685,1.62 -9.675,6.57 l 4.275,1.17 c 0.27,-1.98 1.395,-3.87 4.95,-3.87 2.925,0 4.635,1.305 4.635,3.51 0,2.295 -1.755,3.555 -4.77,3.555 l -2.475,0 0,3.42 2.655,0 c 2.925,0 4.86,1.215 4.86,3.69 0,2.295 -1.62,4.095 -4.86,4.095 -3.06,0 -5.04,-1.53 -5.625,-4.275 l -4.14,1.17 c 0.9,4.59 4.68,7.155 9.9,7.155 5.715,0 9.315,-3.015 9.315,-7.515 0,-3.69 -2.385,-5.76 -5.22,-6.03 l 0,-0.18 z"
d="m 318.27705,360.24104 c 2.295,-0.315 4.95,-2.115 4.95,-5.895 0,-3.96 -2.88,-6.57 -8.775,-6.57 -4.635,0 -8.685,1.62 -9.675,6.57 l 4.275,1.17 c 0.27,-1.98 1.395,-3.87 4.95,-3.87 2.925,0 4.635,1.305 4.635,3.51 0,2.295 -1.755,3.555 -4.77,3.555 h -2.475 v 3.42 h 2.655 c 2.925,0 4.86,1.215 4.86,3.69 0,2.295 -1.62,4.095 -4.86,4.095 -3.06,0 -5.04,-1.53 -5.625,-4.275 l -4.14,1.17 c 0.9,4.59 4.68,7.155 9.9,7.155 5.715,0 9.315,-3.015 9.315,-7.515 0,-3.69 -2.385,-5.76 -5.22,-6.03 z"
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:expanded;font-size:45px;line-height:125%;font-family:'Novecento sans wide';-inkscape-font-specification:'Novecento sans wide, Semi-Bold Expanded';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff"
id="path3376" /><path
d="m 330.56416,373.87604 c 1.89,0 2.88,-1.17 2.88,-2.7 0,-1.485 -0.99,-2.655 -2.88,-2.655 -1.89,0 -2.925,1.17 -2.925,2.655 0,1.485 0.99,2.7 2.925,2.7 z"
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:expanded;font-size:45px;line-height:125%;font-family:'Novecento sans wide';-inkscape-font-specification:'Novecento sans wide, Semi-Bold Expanded';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff"
id="path3378" /><path
d="m 346.79791,347.77604 c -6.39,0 -10.26,4.455 -10.26,13.095 0,8.64 3.87,13.095 10.26,13.095 6.345,0 10.215,-4.455 10.215,-13.095 0,-8.64 -3.87,-13.095 -10.215,-13.095 z m 0,4.32 c 3.78,0 5.49,2.79 5.49,8.775 0,5.94 -1.71,8.775 -5.49,8.775 -3.825,0 -5.535,-2.835 -5.535,-8.775 0,-5.985 1.71,-8.775 5.535,-8.775 z"
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:expanded;font-size:45px;line-height:125%;font-family:'Novecento sans wide';-inkscape-font-specification:'Novecento sans wide, Semi-Bold Expanded';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff"
id="path3380" /></g></svg>
id="path3376"
inkscape:connector-curvature="0" /></g></svg>

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -223,7 +223,7 @@ class ScanWidget(QtWidgets.QWidget):
self._zoom(self.zoomFactor**y, ev.x())
def resizeEvent(self, ev):
if not ev.oldSize().isValid():
if not ev.oldSize().isValid() or not ev.oldSize().width():
self.viewRange()
return
self.ticker.min_ticks = max(

View File

@ -74,4 +74,4 @@ class AnalyzerTest(ExperimentCase):
log = "".join([_extract_log_chars(msg.data)
for msg in dump.messages
if isinstance(msg, OutputMessage) and msg.channel == dump.log_channel])
self.assertEqual(log, "foo\x1E32\n\x1D")
self.assertEqual(log, "foo\x1E32\x1D")

View File

@ -0,0 +1,54 @@
import os
import unittest
from artiq.experiment import *
from artiq.test.hardware_testbench import ExperimentCase
artiq_low_latency = os.getenv("ARTIQ_LOW_LATENCY")
class _Transfer(EnvExperiment):
def build(self):
self.setattr_device("core")
self.data = b"\x00"*(10**6)
@rpc
def source(self) -> TBytes:
return self.data
@rpc(flags={"async"})
def sink(self, data):
assert data == self.data
@kernel
def host_to_device(self):
t0 = self.core.get_rtio_counter_mu()
data = self.source()
t1 = self.core.get_rtio_counter_mu()
return len(data)/self.core.mu_to_seconds(t1-t0)
@kernel
def device_to_host(self):
t0 = self.core.get_rtio_counter_mu()
self.sink(self.data)
t1 = self.core.get_rtio_counter_mu()
return len(self.data)/self.core.mu_to_seconds(t1-t0)
class TransferTest(ExperimentCase):
@unittest.skipUnless(artiq_low_latency,
"timings are dependent on CPU load and network conditions")
def test_host_to_device(self):
exp = self.create(_Transfer)
host_to_device_rate = exp.host_to_device()
print(host_to_device_rate, "B/s")
self.assertGreater(host_to_device_rate, 2e6)
@unittest.skipUnless(artiq_low_latency,
"timings are dependent on CPU load and network conditions")
def test_device_to_host(self):
exp = self.create(_Transfer)
device_to_host_rate = exp.device_to_host()
print(device_to_host_rate, "B/s")
self.assertGreater(device_to_host_rate, 2e6)

View File

@ -0,0 +1,12 @@
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
# RUN: OutputCheck %s --file-to-check=%t
from artiq.experiment import *
@kernel
def entrypoint():
a = [1,2]
# CHECK-L: ${LINE:+2}: error: values cannot be mutated in-place
# CHECK-L: ${LINE:+1}: note: try using `a = a + [3,4]`
a += [3,4]

View File

@ -9,3 +9,6 @@ list(1)
# CHECK-L: ${LINE:+1}: error: the arguments of min() must be of a numeric type
min([1], [1])
# CHECK-L: ${LINE:+1}: error: strings currently cannot be constructed
str(1)

View File

@ -18,3 +18,6 @@ f(1, x=1)
# CHECK-L: ${LINE:+1}: error: mandatory argument 'x' is not passed
f()
# CHECK: ${LINE:+1}: error: this function of type .* does not accept argument 'q'
f(1, q=1)

View File

@ -1,5 +1,5 @@
# RUN: %python -m artiq.compiler.testbench.jit %s
# RUN: %python %s
# RUN: %python -m artiq.compiler.testbench.jit %s
# REQUIRES: exceptions
assert -(-1) == 1
@ -20,6 +20,12 @@ assert 3 % 2 == 1
assert -3 % 2 == 1
assert 3 % -2 == -1
assert -3 % -2 == -1
assert -1 % 8 == 7
#ARTIQ#assert int64(3) % 2 == 1
#ARTIQ#assert int64(-3) % 2 == 1
#ARTIQ#assert int64(3) % -2 == -1
#ARTIQ#assert int64(-3) % -2 == -1
assert -1 % 8 == 7
assert 3.0 % 2.0 == 1.0
assert -3.0 % 2.0 == 1.0
assert 3.0 % -2.0 == -1.0
@ -35,6 +41,24 @@ assert -1 >> 32 == -1
assert 0x18 & 0x0f == 0x08
assert 0x18 | 0x0f == 0x1f
assert 0x18 ^ 0x0f == 0x17
#ARTIQ#assert ~0x18 == -25
#ARTIQ#assert ~int64(0x18) == -25
assert [1] + [2] == [1, 2]
assert [1] * 3 == [1, 1, 1]
try:
1 / 0
except ZeroDivisionError:
pass
else:
assert False
try:
1 // 0
except ZeroDivisionError:
pass
else:
assert False
try:
1 % 0
except ZeroDivisionError:
pass
else:
assert False

View File

@ -3,3 +3,6 @@
ary = array([1, 2, 3])
assert [x*x for x in ary] == [1, 4, 9]
assert [1] + [2] == [1, 2]
assert [1] * 3 == [1, 1, 1]

View File

@ -90,9 +90,9 @@ class WorkerCase(unittest.TestCase):
with self.assertLogs() as logs:
with self.assertRaises(WorkerInternalException):
_run_experiment("ExceptionTermination")
self.assertEqual(len(logs.records), 1)
self.assertGreater(len(logs.records), 0)
self.assertIn("Terminating with exception (TypeError)",
logs.output[0])
logs.output[-1])
def test_watchdog_no_timeout(self):
_run_experiment("WatchdogNoTimeout")

View File

@ -0,0 +1,11 @@
#!/bin/bash
SOC_PREFIX=$SP_DIR/artiq/binaries/${ARTIQ_TARGET}-${ARTIQ_VARIANT}
mkdir -p ${SOC_PREFIX}
V=1 $PYTHON -m artiq.gateware.targets.kc705_dds -H ${ARTIQ_VARIANT} --toolchain vivado $MISOC_EXTRA_VIVADO_CMDLINE
cp -v misoc_${ARTIQ_VARIANT}_kc705/gateware/top.bit $SOC_PREFIX
cp -v misoc_${ARTIQ_VARIANT}_kc705/software/bios/bios.bin $SOC_PREFIX
cp -v misoc_${ARTIQ_VARIANT}_kc705/software/runtime/runtime.{elf,fbi} $SOC_PREFIX
wget -P $SOC_PREFIX https://raw.githubusercontent.com/jordens/bscan_spi_bitstreams/single-tap/bscan_spi_xc7k325t.bit

View File

@ -0,0 +1,31 @@
package:
name: artiq-board
version: {{ environ["GIT_DESCRIBE_TAG"] }}
source:
git_url: ../..
build:
noarch: python
number: {{ environ["GIT_DESCRIBE_NUMBER"] }}
string: py_{{ environ["GIT_DESCRIBE_NUMBER"] }}+git{{ environ["GIT_FULL_HASH"][:8] }}
script_env:
- ARTIQ_TARGET
- ARTIQ_VARIANT
ignore_prefix_files: True
outputs:
- name: artiq-{{ environ["ARTIQ_TARGET"] }}-{{ environ["ARTIQ_VARIANT"] }}
files:
- lib
requirements:
build:
- artiq-dev {{ "{tag} py_{number}+git{hash}".format(tag=environ["GIT_DESCRIBE_TAG"], number=environ["GIT_DESCRIBE_NUMBER"], hash=environ["GIT_FULL_HASH"][:8]) }}
run:
- artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ["GIT_DESCRIBE_TAG"], number=environ["GIT_DESCRIBE_NUMBER"], hash=environ["GIT_FULL_HASH"][:8]) }}
about:
home: https://m-labs.hk/artiq
license: LGPL
summary: 'Bitstream, BIOS and firmware for the {{ environ.get("ARTIQ_TARGET") }}-{{ environ.get("ARTIQ_VARIANT") }} board variant'

View File

@ -2,9 +2,9 @@
# $ conda env create -f conda/artiq-dev.yaml
name: artiq-dev
channels:
- defaults
- conda-forge/label/main
- m-labs/label/dev
- m-labs/label/main
- defaults
- conda-forge/label/main
dependencies:
- artiq-dev

View File

@ -14,15 +14,14 @@ requirements:
run:
- python >=3.5.3,<3.6
- setuptools 33.1.1
- migen 0.5
- misoc 0.6
- migen 0.7 py35_0+gite554f07
- misoc 0.10 py35_0+gitd167deff
- jesd204b 0.3
- binutils-or1k-linux >=2.27
- llvm-or1k
- llvmlite-artiq 0.12.0
- rust-core-or1k 1.20.0 16
- cargo 0.11.0
- openocd >=0.10
- llvm-or1k 4.0.1
- llvmlite-artiq 0.20.0
- rust-core-or1k 1.23.0 19
- openocd 0.10.0 1
- lit
- outputcheck
- coverage
@ -38,7 +37,7 @@ requirements:
- python-dateutil
- pyqt >=5.5
- quamash
- pyqtgraph
- pyqtgraph 0.10.0
- pygit2
- aiohttp
- pythonparser >=1.1

View File

@ -2,10 +2,10 @@
# $ conda env create -f conda/artiq-doc.yaml
name: artiq-doc
channels:
- defaults
- conda-forge/label/main
- m-labs/label/dev
- m-labs/label/main
- defaults
- conda-forge/label/main
dependencies:
- python>=3.5.3,<3.6
- sphinx=1.4.8

View File

@ -1,14 +0,0 @@
#!/bin/bash
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705-nist_clock
mkdir -p $SOC_PREFIX
V=1 $PYTHON -m artiq.gateware.targets.kc705_dds -H nist_clock --toolchain vivado $MISOC_EXTRA_VIVADO_CMDLINE
cp misoc_nist_clock_kc705/gateware/top.bit $SOC_PREFIX
cp misoc_nist_clock_kc705/software/bios/bios.bin $SOC_PREFIX
cp misoc_nist_clock_kc705/software/runtime/runtime.fbi $SOC_PREFIX
wget -P $SOC_PREFIX https://raw.githubusercontent.com/jordens/bscan_spi_bitstreams/single-tap/bscan_spi_xc7k325t.bit

View File

@ -1,23 +0,0 @@
package:
name: artiq-kc705-nist_clock
version: {{ environ.get("GIT_DESCRIBE_TAG", "") }}
source:
git_url: ../..
build:
noarch: generic
ignore_prefix_files: True
number: {{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}
string: py_{{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}+git{{ environ.get("GIT_FULL_HASH", "")[:8] }}
requirements:
build:
- artiq-dev {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_FULL_HASH", "")[:8]) if "GIT_DESCRIBE_TAG" in environ else "" }}
run:
- artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_FULL_HASH", "")[:8]) if "GIT_DESCRIBE_TAG" in environ else "" }}
about:
home: https://m-labs.hk/artiq
license: LGPL
summary: 'Bitstream, BIOS and runtime for NIST_CLOCK on the KC705 board'

View File

@ -1,14 +0,0 @@
#!/bin/bash
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705-nist_qc2
mkdir -p $SOC_PREFIX
V=1 $PYTHON -m artiq.gateware.targets.kc705_dds -H nist_qc2 --toolchain vivado $MISOC_EXTRA_VIVADO_CMDLINE
cp misoc_nist_qc2_kc705/gateware/top.bit $SOC_PREFIX
cp misoc_nist_qc2_kc705/software/bios/bios.bin $SOC_PREFIX
cp misoc_nist_qc2_kc705/software/runtime/runtime.fbi $SOC_PREFIX
wget -P $SOC_PREFIX https://raw.githubusercontent.com/jordens/bscan_spi_bitstreams/single-tap/bscan_spi_xc7k325t.bit

View File

@ -1,23 +0,0 @@
package:
name: artiq-kc705-nist_qc2
version: {{ environ.get("GIT_DESCRIBE_TAG", "") }}
source:
git_url: ../..
build:
noarch: generic
ignore_prefix_files: True
number: {{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}
string: py_{{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}+git{{ environ.get("GIT_FULL_HASH", "")[:8] }}
requirements:
build:
- artiq-dev {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_FULL_HASH", "")[:8]) if "GIT_DESCRIBE_TAG" in environ else "" }}
run:
- artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_FULL_HASH", "")[:8]) if "GIT_DESCRIBE_TAG" in environ else "" }}
about:
home: https://m-labs.hk/artiq
license: LGPL
summary: 'Bitstream, BIOS and runtime for NIST_QC2 on the KC705 board'

View File

@ -1,14 +0,0 @@
#!/bin/bash
BUILD_SETTINGS_FILE=$HOME/.m-labs/build_settings.sh
[ -f $BUILD_SETTINGS_FILE ] && . $BUILD_SETTINGS_FILE
SOC_PREFIX=$PREFIX/lib/python3.5/site-packages/artiq/binaries/kc705-phaser
mkdir -p $SOC_PREFIX
V=1 $PYTHON -m artiq.gateware.targets.phaser --toolchain vivado $MISOC_EXTRA_VIVADO_CMDLINE
cp misoc_phaser_kc705/gateware/top.bit $SOC_PREFIX
cp misoc_phaser_kc705/software/bios/bios.bin $SOC_PREFIX
cp misoc_phaser_kc705/software/runtime/runtime.fbi $SOC_PREFIX
wget -P $SOC_PREFIX https://raw.githubusercontent.com/jordens/bscan_spi_bitstreams/single-tap/bscan_spi_xc7k325t.bit

View File

@ -1,23 +0,0 @@
package:
name: artiq-kc705-phaser
version: {{ environ.get("GIT_DESCRIBE_TAG", "") }}
source:
git_url: ../..
build:
noarch: generic
ignore_prefix_files: True
number: {{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}
string: py_{{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}+git{{ environ.get("GIT_FULL_HASH", "")[:8] }}
requirements:
build:
- artiq-dev {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_FULL_HASH", "")[:8]) if "GIT_DESCRIBE_TAG" in environ else "" }}
run:
- artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_FULL_HASH", "")[:8]) if "GIT_DESCRIBE_TAG" in environ else "" }}
about:
home: https://m-labs.hk/artiq
license: LGPL
summary: 'Bitstream, BIOS and runtime for Phaser on the KC705 board'

View File

@ -26,10 +26,10 @@ requirements:
- setuptools 33.1.1
run:
- python >=3.5.3,<3.6
- llvmlite-artiq 0.12.0.dev py35_30
- binutils-or1k-linux
- llvmlite-artiq 0.20.0
- binutils-or1k-linux >=2.27
- pythonparser >=1.1
- openocd >=0.10
- openocd 0.10.0 1
- lit
- outputcheck
- scipy

View File

@ -20,6 +20,12 @@ import sphinx_rtd_theme
from unittest.mock import MagicMock
# Hack-patch Sphinx so that ARTIQ-Python types are correctly printed
# See: https://github.com/m-labs/artiq/issues/741
from sphinx.ext import autodoc
autodoc.repr = str
class Mock(MagicMock):
@classmethod
def __getattr__(cls, name):

View File

@ -162,11 +162,10 @@ Installation
............
These installation instructions are a short form of those in the ARTIQ manual.
* See the chapter on setting up a :ref:`development environment <develop-from-conda>`.
* When compiling the binaries, use the ``phaser`` target:::
$ python -m artiq.gateware.targets.phaser
* From time to time and on request there may be pre-built binaries in the
``artiq-kc705-phaser`` package on the M-Labs conda package label.
* When compiling the binaries, use the ``phaser`` target: ``python -m artiq.gateware.targets.kc705_phaser``
* From time to time and on request there may be pre-built binaries in the ``artiq-kc705-phaser`` package on the M-Labs conda package label.
Setup
.....

View File

@ -27,7 +27,7 @@ ARTIQ Anaconda development environment
$ git clone --recursive https://github.com/m-labs/artiq ~/artiq-dev/artiq
$ cd ~/artiq-dev/artiq
Add ``-b release-X`` to the ``git clone`` command if you are building a stable branch of ARTIQ (the default will fetch the development ``master`` branch).
Add ``-b release-X`` to the ``git clone`` command if you are building a stable branch of ARTIQ. Replace ``X`` with the major release. The default will fetch the development ``master`` branch.
3. :ref:`Install Anaconda or Miniconda <install-anaconda>`
4. Create and activate a conda environment named ``artiq-dev`` and install the ``artiq-dev`` package which pulls in all the packages required to develop ARTIQ::
@ -37,10 +37,9 @@ ARTIQ Anaconda development environment
$ pip install -e .
6. :ref:`Install Vivado <install-xilinx>`
7. :ref:`Obtain and install the JTAG SPI flash proxy bitstream <install-bscan-spi>`
8. :ref:`Configure OpenOCD <setup-openocd>`
9. :ref:`Build target binaries <build-target-binaries>`
10. :ref:`Flash target binaries <flash-target-binaries>`
7. :ref:`Configure OpenOCD <setup-openocd>`
8. :ref:`Build target binaries <build-target-binaries>`
9. :ref:`Flash target binaries <flash-target-binaries>`
.. _install-from-source:
@ -90,22 +89,22 @@ and the ARTIQ kernels.
* Install LLVM and Clang: ::
$ cd ~/artiq-dev
$ git clone -b artiq-3.9 https://github.com/m-labs/llvm-or1k
$ git clone -b artiq-4.0 https://github.com/m-labs/llvm-or1k
$ cd llvm-or1k
$ git clone -b artiq-3.9 https://github.com/m-labs/clang-or1k tools/clang
$ git clone -b artiq-4.0 https://github.com/m-labs/clang-or1k tools/clang
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/llvm-or1k -DLLVM_TARGETS_TO_BUILD="OR1K;X86" -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_INSTALL_UTILS=ON
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/llvm-or1k -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=OR1K -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_INSTALL_UTILS=ON -DCLANG_ENABLE_ARCMT=OFF -DCLANG_ENABLE_STATIC_ANALYZER=OFF
$ make -j4
$ sudo make install
* Install Rust: ::
$ cd ~/artiq-dev
$ git clone -b artiq-1.20.0 https://github.com/m-labs/rust
$ git clone -b artiq-1.23.0 https://github.com/m-labs/rust
$ cd rust
$ git submodule update --init
$ git submodule update --init --recursive
$ mkdir build
$ cd build
$ ../configure --prefix=/usr/local/rust-or1k --llvm-root=/usr/local/llvm-or1k --disable-manage-submodules --disable-docs
@ -113,14 +112,16 @@ and the ARTIQ kernels.
$ sudo chown $USER.$USER /usr/local/rust-or1k
$ make install
$ libs="libcore libstd_unicode liballoc liblibc_mini libunwind"
$ rustc="/usr/local/rust-or1k/bin/rustc --target or1k-unknown-none -g -C target-feature=+mul,+div,+ffl1,+cmov,+addc -C opt-level=s -L ."
$ libs="core std_unicode alloc"
$ rustc="/usr/local/rust-or1k/bin/rustc --target or1k-unknown-none -C target-feature=+mul,+div,+ffl1,+cmov,+addc -C opt-level=s -g --crate-type rlib -L ."
$ destdir="/usr/local/rust-or1k/lib/rustlib/or1k-unknown-none/lib/"
$ mkdir ../build-or1k
$ cd ../build-or1k
$ for lib in ${libs}; do ${rustc} ../src/${lib}/lib.rs; done
$ ${rustc} -Cpanic=abort ../src/libpanic_abort/lib.rs
$ ${rustc} -Cpanic=unwind ../src/libpanic_unwind/lib.rs --cfg llvm_libunwind
$ for lib in ${libs}; do ${rustc} --crate-name ${lib} ../src/lib${lib}/lib.rs; done
$ ${rustc} --crate-name libc ../src/liblibc_mini/lib.rs
$ ${rustc} --crate-name unwind ../src/libunwind/lib.rs
$ ${rustc} -Cpanic=abort --crate-name panic_abort ../src/libpanic_abort/lib.rs
$ ${rustc} -Cpanic=unwind --crate-name panic_unwind ../src/libpanic_unwind/lib.rs --cfg llvm_libunwind
$ mkdir -p ${destdir}
$ cp *.rlib ${destdir}

View File

@ -13,8 +13,8 @@ The conda package contains pre-built binaries that you can directly flash to you
.. warning::
Conda packages are supported for Linux (64-bit) and Windows (32- and 64-bit).
Users of other operating systems (32-bit Linux, BSD, OSX ...) should and can :ref:`install from source <install-from-source>`.
Conda packages are supported for Linux (64-bit) and Windows (64-bit).
Users of other operating systems (32-bit Linux or Windows, BSD, OSX ...) should and can :ref:`install from source <install-from-source>`.
.. _install-anaconda:
@ -37,18 +37,18 @@ Installing the ARTIQ packages
First add the conda-forge repository containing ARTIQ dependencies to your conda configuration::
$ conda config --add channels http://conda.anaconda.org/conda-forge/label/main
$ conda config --prepend channels http://conda.anaconda.org/conda-forge/label/main
Then add the M-Labs ``main`` Anaconda package repository containing stable releases and release candidates::
$ conda config --add channels http://conda.anaconda.org/m-labs/label/main
$ conda config --prepend channels http://conda.anaconda.org/m-labs/label/main
.. note::
To use the development versions of ARTIQ, also add the ``dev`` label (http://conda.anaconda.org/m-labs/label/dev).
Development versions are built for every change and contain more features, but are not as well-tested and are more likely to contain more bugs or inconsistencies than the releases in the ``main`` label.
Then prepare to create a new conda environment with the ARTIQ package and the matching binaries for your hardware:
choose a suitable name for the environment, for example ``artiq-main`` if you intend to track the main label or ``artiq-2016-04-01`` if you consider the environment a snapshot of ARTIQ on 2016-04-01.
choose a suitable name for the environment, for example ``artiq-main`` if you intend to track the main label, ``artiq-3`` for the 3.x release series, or ``artiq-2016-04-01`` if you consider the environment a snapshot of ARTIQ on 2016-04-01.
Choose the package containing the binaries for your hardware:
* ``artiq-kc705-nist_clock`` for the KC705 board with the NIST "clock" FMC backplane and AD9914 DDS chips.
@ -112,6 +112,9 @@ The ``artiq`` or ``artiq-dev`` conda packages install ``openocd`` automatically
.. _setup-openocd:
Configuring OpenOCD
^^^^^^^^^^^^^^^^^^^
Some additional steps are necessary to ensure that OpenOCD can communicate with the FPGA board.
On Linux, first ensure that the current user belongs to the ``plugdev`` group. If it does not, run ``sudo adduser $USER plugdev`` and relogin. Afterwards::