diff --git a/.github/workflows/deploy-wasm.yml b/.github/workflows/deploy-wasm.yml
index c47e6143..cf9915e5 100644
--- a/.github/workflows/deploy-wasm.yml
+++ b/.github/workflows/deploy-wasm.yml
@@ -9,10 +9,14 @@ on:
workflow_dispatch:
branches:
- master
+ repository_dispatch: # listening to rv32emu-prebuilt events
+ types: [deploy_wasm]
jobs:
wasm-deploy:
- if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch'
+ if: github.event.pull_request.merged == true ||
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'repository_dispatch'
runs-on: ubuntu-latest
steps:
- name: Check out the repo
@@ -22,12 +26,20 @@ jobs:
uses: tj-actions/changed-files@v45
with:
files: |
- assets/html/index.html
- assets/js/pre.js
+ assets/wasm/html/index.html
+ assets/wasm/js/pre.js
build/*.elf
+ tools/gen-elf-list-js.py
+ # Files below may have a potential performance impact (reference from benchmark.yml)
+ src/riscv.c
+ src/decode.c
+ src/emulate.c
+ src/rv32_template.c
+ src/rv32_constopt.c
- name: install emcc
if: ${{ steps.changed-files.outputs.any_modified == 'true' ||
- github.event_name == 'workflow_dispatch'}}
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'repository_dispatch' }}
run: |
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
@@ -38,14 +50,25 @@ jobs:
source ./emsdk_env.sh
echo "$PATH" >> $GITHUB_PATH
shell: bash
+ - name: fetch artifact
+ run: |
+ make artifact
+ # Hack Cloudflare 403 Forbidden on GitHub Runner for Doom artifact download
+ wget --header="User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:122.0) Gecko/20100101 Firefox/122.0" \
+ --header="Referer: https://www.doomworld.com/" \
+ --header="Accept-Language: en-US,en;q=0.9" \
+ -O build/shareware_doom_iwad.zip \
+ "https://www.doomworld.com/3ddownloads/ports/shareware_doom_iwad.zip"
+ unzip -d build/ build/shareware_doom_iwad.zip
- name: build with emcc and move application files to /tmp
if: ${{ steps.changed-files.outputs.any_modified == 'true' ||
- github.event_name == 'workflow_dispatch'}}
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'repository_dispatch' }}
run: |
- make CC=emcc ENABLE_GDBSTUB=0 ENABLE_SDL=1
+ make CC=emcc ENABLE_SDL=1
mkdir /tmp/rv32emu-demo
- mv assets/html/index.html /tmp/rv32emu-demo
- mv assets/js/coi-serviceworker.min.js /tmp/rv32emu-demo
+ mv assets/wasm/html/index.html /tmp/rv32emu-demo
+ mv assets/wasm/js/coi-serviceworker.min.js /tmp/rv32emu-demo
mv build/elf_list.js /tmp/rv32emu-demo
mv build/rv32emu.js /tmp/rv32emu-demo
mv build/rv32emu.wasm /tmp/rv32emu-demo
@@ -53,14 +76,16 @@ jobs:
ls -al /tmp/rv32emu-demo
- name: Check out the rv32emu-demo repo
if: ${{ steps.changed-files.outputs.any_modified == 'true' ||
- github.event_name == 'workflow_dispatch'}}
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'repository_dispatch' }}
uses: actions/checkout@v4
with:
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
repository: sysprog21/rv32emu-demo
- name: Create local changes
if: ${{ steps.changed-files.outputs.any_modified == 'true' ||
- github.event_name == 'workflow_dispatch'}}
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'repository_dispatch' }}
run: |
mv /tmp/rv32emu-demo/index.html .
mv /tmp/rv32emu-demo/coi-serviceworker.min.js .
@@ -70,7 +95,8 @@ jobs:
mv /tmp/rv32emu-demo/rv32emu.worker.js .
- name: Commit files
if: ${{ steps.changed-files.outputs.any_modified == 'true' ||
- github.event_name == 'workflow_dispatch'}}
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'repository_dispatch' }}
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
@@ -78,7 +104,8 @@ jobs:
git commit -m "Add changes"
- name: Push changes
if: ${{ steps.changed-files.outputs.any_modified == 'true' ||
- github.event_name == 'workflow_dispatch'}}
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'repository_dispatch' }}
uses: ad-m/github-push-action@master
with:
repository: sysprog21/rv32emu-demo
diff --git a/assets/html/index.html b/assets/html/index.html
deleted file mode 100644
index 5beae7e6..00000000
--- a/assets/html/index.html
+++ /dev/null
@@ -1,243 +0,0 @@
-
-
-
-
-
- Emscripten-Generated Code
-
-
-
-
-
-
- Downloading...
-
-
- Resize canvas
- Lock/hide mouse pointer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/js/coi-serviceworker.min.js b/assets/js/coi-serviceworker.min.js
deleted file mode 100644
index 117f9f89..00000000
--- a/assets/js/coi-serviceworker.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! coi-serviceworker v0.1.7 - Guido Zuidhof and contributors, licensed under MIT */
-let coepCredentialless=!1;"undefined"==typeof window?(self.addEventListener("install",(()=>self.skipWaiting())),self.addEventListener("activate",(e=>e.waitUntil(self.clients.claim()))),self.addEventListener("message",(e=>{e.data&&("deregister"===e.data.type?self.registration.unregister().then((()=>self.clients.matchAll())).then((e=>{e.forEach((e=>e.navigate(e.url)))})):"coepCredentialless"===e.data.type&&(coepCredentialless=e.data.value))})),self.addEventListener("fetch",(function(e){const o=e.request;if("only-if-cached"===o.cache&&"same-origin"!==o.mode)return;const s=coepCredentialless&&"no-cors"===o.mode?new Request(o,{credentials:"omit"}):o;e.respondWith(fetch(s).then((e=>{if(0===e.status)return e;const o=new Headers(e.headers);return o.set("Cross-Origin-Embedder-Policy",coepCredentialless?"credentialless":"require-corp"),coepCredentialless||o.set("Cross-Origin-Resource-Policy","cross-origin"),o.set("Cross-Origin-Opener-Policy","same-origin"),new Response(e.body,{status:e.status,statusText:e.statusText,headers:o})})).catch((e=>console.error(e))))}))):(()=>{const e=window.sessionStorage.getItem("coiReloadedBySelf");window.sessionStorage.removeItem("coiReloadedBySelf");const o="coepdegrade"==e,s={shouldRegister:()=>!e,shouldDeregister:()=>!1,coepCredentialless:()=>!0,coepDegrade:()=>!0,doReload:()=>window.location.reload(),quiet:!1,...window.coi},r=navigator,t=r.serviceWorker&&r.serviceWorker.controller;t&&!window.crossOriginIsolated&&window.sessionStorage.setItem("coiCoepHasFailed","true");const i=window.sessionStorage.getItem("coiCoepHasFailed");if(t){const e=s.coepDegrade()&&!(o||window.crossOriginIsolated);r.serviceWorker.controller.postMessage({type:"coepCredentialless",value:!(e||i&&s.coepDegrade())&&s.coepCredentialless()}),e&&(!s.quiet&&console.log("Reloading page to degrade COEP."),window.sessionStorage.setItem("coiReloadedBySelf","coepdegrade"),s.doReload("coepdegrade")),s.shouldDeregister()&&r.serviceWorker.controller.postMessage({type:"deregister"})}!1===window.crossOriginIsolated&&s.shouldRegister()&&(window.isSecureContext?r.serviceWorker?r.serviceWorker.register(window.document.currentScript.src).then((e=>{!s.quiet&&console.log("COOP/COEP Service Worker registered",e.scope),e.addEventListener("updatefound",(()=>{!s.quiet&&console.log("Reloading page to make use of updated COOP/COEP Service Worker."),window.sessionStorage.setItem("coiReloadedBySelf","updatefound"),s.doReload()})),e.active&&!r.serviceWorker.controller&&(!s.quiet&&console.log("Reloading page to make use of COOP/COEP Service Worker."),window.sessionStorage.setItem("coiReloadedBySelf","notcontrolling"),s.doReload())}),(e=>{!s.quiet&&console.error("COOP/COEP Service Worker failed to register:",e)})):!s.quiet&&console.error("COOP/COEP Service Worker not registered, perhaps due to private mode."):!s.quiet&&console.log("COOP/COEP Service Worker not registered, a secure context is required."))})();
\ No newline at end of file
diff --git a/assets/js/pre.js b/assets/js/pre.js
deleted file mode 100644
index c541967e..00000000
--- a/assets/js/pre.js
+++ /dev/null
@@ -1,9 +0,0 @@
-Module['noInitialRun'] = true;
-Module['onRuntimeInitialized'] = function(target_elf) {
- if(target_elf === undefined){
- console.warn("target elf executable is undefined");
- return;
- }
-
- callMain([target_elf]);
-};
diff --git a/mk/wasm.mk b/mk/wasm.mk
index 4785f7c0..cf4d2c9e 100644
--- a/mk/wasm.mk
+++ b/mk/wasm.mk
@@ -6,8 +6,8 @@ WEB_JS_RESOURCES := $(ASSETS)/js
EXPORTED_FUNCS := _main,_indirect_rv_halt
DEMO_DIR := demo
WEB_FILES := $(BIN).js \
- $(BIN).wasm \
- $(BIN).worker.js \
+ $(BIN).wasm \
+ $(BIN).worker.js \
$(OUT)/elf_list.js
ifeq ("$(CC_IS_EMCC)", "1")
@@ -29,10 +29,19 @@ CFLAGS_emcc += -sINITIAL_MEMORY=2GB \
-s"EXPORTED_FUNCTIONS=$(EXPORTED_FUNCS)" \
-sSTACK_SIZE=4MB \
-sPTHREAD_POOL_SIZE=navigator.hardwareConcurrency \
- --embed-file build@/ \
+ --embed-file build/jit-bf.elf@/jit-bf.elf \
+ --embed-file build/coro.elf@/coro.elf \
+ --embed-file build/fibonacci.elf@/fibonacci.elf \
+ --embed-file build/hello.elf@/hello.elf \
+ --embed-file build/ieee754.elf@/ieee754.elf \
+ --embed-file build/perfcount.elf@/perfcount.elf \
+ --embed-file build/readelf.elf@/readelf.elf \
+ --embed-file build/smolnes.elf@/smolnes.elf \
--embed-file build/riscv32@/riscv32 \
+ --embed-file build/DOOM1.WAD@/DOOM1.WAD \
+ --embed-file build/id1/pak0.pak@/id1/pak0.pak \
--embed-file build/timidity@/etc/timidity \
- -DMEM_SIZE=0x40000000 \
+ -DMEM_SIZE=0x60000000 \
-DCYCLE_PER_STEP=2000000 \
--pre-js $(WEB_JS_RESOURCES)/pre.js \
-O3 \
diff --git a/src/emulate.c b/src/emulate.c
index 30474c35..31656966 100644
--- a/src/emulate.c
+++ b/src/emulate.c
@@ -1175,6 +1175,7 @@ void rv_step(void *arg)
if (rv_has_halted(rv)) {
emscripten_cancel_main_loop();
rv_delete(rv); /* clean up and reuse memory */
+ rv_log_info("RISC-V emulator is destroyed");
}
#endif
}
diff --git a/src/riscv.c b/src/riscv.c
index 61d95d2d..1ddaf235 100644
--- a/src/riscv.c
+++ b/src/riscv.c
@@ -615,7 +615,6 @@ void rv_run(riscv_t *rv)
attr->data.user.elf_program
#endif
);
- attr->cycle_per_step = 100000000;
if (!(attr->run_flag & (RV_RUN_TRACE | RV_RUN_GDBSTUB))) {
#ifdef __EMSCRIPTEN__
diff --git a/tools/gen-elf-list-js.py b/tools/gen-elf-list-js.py
index 05e082a1..213b2259 100755
--- a/tools/gen-elf-list-js.py
+++ b/tools/gen-elf-list-js.py
@@ -2,32 +2,55 @@
import os
-def list_files(d):
+
+def list_files(d, ignore_list=None):
+ if ignore_list is None:
+ ignore_list = []
try:
if d == "build":
- files = [f for f in os.listdir(d) if (os.path.isfile(os.path.join(d, f)) and f.endswith('.elf'))]
+ files = [
+ f
+ for f in os.listdir(d)
+ if os.path.isfile(os.path.join(d, f))
+ and f.endswith(".elf")
+ and not any(f.endswith(ign) or f.startswith(ign) for ign in ignore_list)
+ ]
else:
parent_dir = os.path.dirname(d)
files = [
os.path.relpath(os.path.join(d, f), start=parent_dir)
for f in os.listdir(d)
if os.path.isfile(os.path.join(d, f))
+ and not any(
+ f.endswith(ign) or os.path.join(d, f).endswith(ign)
+ for ign in ignore_list
+ )
]
return files
except FileNotFoundError:
- print(f"Directory {directory} not found.")
+ print(f"Directory {d} not found.")
return []
+
elf_exec_dirs = ["build", "build/riscv32"]
+msg_less_ignore_files = [
+ "cc.elf",
+ "chacha20.elf",
+ "riscv32/lena",
+ "riscv32/puzzle",
+ "riscv32/line",
+ "riscv32/captcha",
+] # List of files to ignore
elf_exec_list = []
for d in elf_exec_dirs:
- files = list_files(d)
+ files = list_files(d, ignore_list=msg_less_ignore_files)
elf_exec_list.extend(files)
-#print(elf_exec_list)
+
def gen_elf_list_js():
js_code = f"const elfFiles = {elf_exec_list};\n"
print(js_code)
+
gen_elf_list_js()