nanohub: new contexthub interface using chre messaging
range check messages
do not auto erase flash when writing an nanoapp that doesn't fit
enable crc calculation/checking for nanoapps
do not auto start chre 1.1+ nanoapps
Bug: 69980445
Test: check out new commands and make sure they work
Change-Id: I98af1f3d5c848be19a1d3687d1d51a58145ff956
Signed-off-by: Ben Fennema <[email protected]>
diff --git a/firmware/Android.mk b/firmware/Android.mk
index db2fb86..3f4b909 100644
--- a/firmware/Android.mk
+++ b/firmware/Android.mk
@@ -88,6 +88,7 @@
libnanohub_os \
LOCAL_STATIC_LIBRARIES := \
+ libnanohub_common_os \
libnanomath_os \
libnanolibc_os \
diff --git a/firmware/firmware.mk b/firmware/firmware.mk
index 9e02634..221ee0c 100644
--- a/firmware/firmware.mk
+++ b/firmware/firmware.mk
@@ -85,9 +85,7 @@
#some help for bootloader
SRCS_bl += os/core/printf.c
-ifndef PLATFORM_HAS_HARDWARE_CRC
SRCS_os += ../lib/nanohub/softcrc.c
-endif
#extra deps
DEPS += $(wildcard inc/*.h)
diff --git a/firmware/os/core/heap.c b/firmware/os/core/heap.c
index 2f38a0d..f6e5067 100644
--- a/firmware/os/core/heap.c
+++ b/firmware/os/core/heap.c
@@ -229,3 +229,50 @@
return count;
}
+
+int heapGetFreeSize(int *numChunks, int *largestChunk)
+{
+ struct HeapNode *node;
+ bool haveLock;
+ int bytes = 0;
+ *numChunks = *largestChunk = 0;
+
+ // this can only fail if called from interrupt
+ haveLock = trylockTryTake(&gHeapLock);
+ if (!haveLock)
+ return -1;
+
+ for (node = gHeapHead; node; node = heapPrvGetNext(node)) {
+ if (!node->used) {
+ if (node->size > *largestChunk)
+ *largestChunk = node->size;
+ bytes += node->size + sizeof(struct HeapNode);
+ (*numChunks)++;
+ }
+ }
+ trylockRelease(&gHeapLock);
+
+ return bytes;
+}
+
+int heapGetTaskSize(uint32_t tid)
+{
+ struct HeapNode *node;
+ bool haveLock;
+ int bytes = 0;
+
+ // this can only fail if called from interrupt
+ haveLock = trylockTryTake(&gHeapLock);
+ if (!haveLock)
+ return -1;
+
+ tid &= TIDX_MASK;
+ for (node = gHeapHead; node; node = heapPrvGetNext(node)) {
+ if (node->used && node->tidx == tid) {
+ bytes += node->size + sizeof(struct HeapNode);
+ }
+ }
+ trylockRelease(&gHeapLock);
+
+ return bytes;
+}
diff --git a/firmware/os/core/hostIntf.c b/firmware/os/core/hostIntf.c
index 325bf6f..ccd571d 100644
--- a/firmware/os/core/hostIntf.c
+++ b/firmware/os/core/hostIntf.c
@@ -35,6 +35,7 @@
#include <nanohubCommand.h>
#include <nanohubPacket.h>
#include <seos.h>
+#include <seos_priv.h>
#include <util.h>
#include <atomicBitset.h>
#include <atomic.h>
@@ -1097,18 +1098,36 @@
static void hostIntfNotifyReboot(uint32_t reason)
{
- struct NanohubHalRebootTx *resp = heapAlloc(sizeof(*resp));
__le32 raw_reason = htole32(reason);
+ struct NanohubHalSysMgmtTx *resp;
+ resp = heapAlloc(sizeof(*resp));
if (resp) {
- resp->hdr = (struct NanohubHalHdr){
+ resp->hdr = (struct NanohubHalHdr) {
.appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
- .len = sizeof(*resp) - sizeof(resp->hdr) + sizeof(resp->hdr.msg),
- .msg = NANOHUB_HAL_REBOOT,
+ .len = sizeof(*resp) - sizeof(resp->hdr),
};
- memcpy(&resp->reason, &raw_reason, sizeof(resp->reason));
- osEnqueueEvtOrFree(EVT_APP_TO_HOST, resp, heapFree);
+ resp->ret = (struct NanohubHalRet) {
+ .msg = NANOHUB_HAL_SYS_MGMT,
+ .status = raw_reason,
+ };
+ resp->cmd = NANOHUB_HAL_SYS_MGMT_REBOOT;
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
}
+
+#ifdef LEGACY_HAL_ENABLED
+ struct NanohubHalLegacyRebootTx *respLegacy;
+ respLegacy = heapAlloc(sizeof(*respLegacy));
+ if (respLegacy) {
+ respLegacy->hdr = (struct NanohubHalLegacyHdr) {
+ .appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
+ .len = sizeof(*respLegacy) - sizeof(respLegacy->hdr) + sizeof(respLegacy->hdr.msg),
+ .msg = NANOHUB_HAL_LEGACY_REBOOT,
+ };
+ memcpy(&respLegacy->reason, &raw_reason, sizeof(respLegacy->reason));
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST, respLegacy, heapFree);
+ }
+#endif
}
static void queueFlush(struct ActiveSensor *sensor)
@@ -1203,12 +1222,43 @@
}
}
+#ifdef LEGACY_HAL_ENABLED
+static void handleLegacyHalCmd(const uint8_t *halData, uint8_t size)
+{
+ const struct NanohubHalLegacyCommand *halCmd = nanohubHalLegacyFindCommand(halData[0]);
+ if (halCmd)
+ halCmd->handler((void *)&halData[1], size - 1);
+}
+
static void onEvtAppFromHost(const void *evtData)
{
const uint8_t *halMsg = evtData;
- const struct NanohubHalCommand *halCmd = nanohubHalFindCommand(halMsg[1]);
- if (halCmd)
- halCmd->handler((void *)&halMsg[2], halMsg[0] - 1);
+ handleLegacyHalCmd(&halMsg[1], halMsg[0]);
+}
+#endif
+
+static void onEvtAppFromHostChre(const void *evtData)
+{
+ const struct NanohubMsgChreHdr *halMsg = (const struct NanohubMsgChreHdr *)evtData;
+ const struct NanohubHalCommand *halCmd;
+ const uint8_t *halData = (const uint8_t *)(halMsg+1);
+ uint8_t len;
+ uint32_t transactionId;
+
+ memcpy(&transactionId, &halMsg->appEvent, sizeof(halMsg->appEvent));
+
+ if (halMsg->size >= 1) {
+ len = halMsg->size - 1;
+ halCmd = nanohubHalFindCommand(halData[0]);
+ if (halCmd) {
+ if (len >= halCmd->minDataLen && len <= halCmd->maxDataLen)
+ halCmd->handler((void *)&halData[1], len, transactionId);
+ return;
+ }
+ }
+#ifdef LEGACY_HAL_ENABLED
+ handleLegacyHalCmd(halData, halMsg->size);
+#endif
}
#ifdef DEBUG_LOG_EVT
@@ -1502,7 +1552,7 @@
static void hostIntfHandleEvent(uint32_t evtType, const void* evtData)
{
- switch (evtType) {
+ switch (EVENT_GET_EVENT(evtType)) {
case EVT_APP_START:
onEvtAppStart(evtData);
break;
@@ -1512,9 +1562,14 @@
case EVT_APP_TO_HOST_CHRE:
onEvtAppToHostChre(evtData);
break;
+#ifdef LEGACY_HAL_ENABLED
case EVT_APP_FROM_HOST:
onEvtAppFromHost(evtData);
break;
+#endif
+ case EVT_APP_FROM_HOST_CHRE:
+ onEvtAppFromHostChre(evtData);
+ break;
#ifdef DEBUG_LOG_EVT
case EVT_DEBUG_LOG:
onEvtDebugLog(evtData);
@@ -1530,7 +1585,7 @@
onEvtAppToSensorHalData(evtData);
break;
default:
- onEvtSensorData(evtType, evtData);
+ onEvtSensorData(EVENT_GET_EVENT(evtType), evtData);
break;
}
}
@@ -1633,4 +1688,4 @@
cpuIntsRestore(state);
}
-INTERNAL_APP_INIT(APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0), 0, hostIntfRequest, hostIntfRelease, hostIntfHandleEvent);
+INTERNAL_CHRE_APP_INIT(APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0), 0, hostIntfRequest, hostIntfRelease, hostIntfHandleEvent);
diff --git a/firmware/os/core/nanohubCommand.c b/firmware/os/core/nanohubCommand.c
index 1c31bb3..d679e73 100644
--- a/firmware/os/core/nanohubCommand.c
+++ b/firmware/os/core/nanohubCommand.c
@@ -39,6 +39,7 @@
#include <nanohubPacket.h>
#include <eeData.h>
#include <seos.h>
+#include <seos_priv.h>
#include <util.h>
#include <mpu.h>
#include <heap.h>
@@ -49,6 +50,7 @@
#include <cpu.h>
#include <cpu/cpuMath.h>
#include <algos/ap_hub_sync.h>
+#include <sensors_priv.h>
#include <chre.h>
@@ -56,9 +58,13 @@
{ .reason = _reason, .fastHandler = _fastHandler, .handler = _handler, \
.minDataLen = sizeof(_minReqType), .maxDataLen = sizeof(_maxReqType) }
-#define NANOHUB_HAL_COMMAND(_msg, _handler) \
+#define NANOHUB_HAL_LEGACY_COMMAND(_msg, _handler) \
{ .msg = _msg, .handler = _handler }
+#define NANOHUB_HAL_COMMAND(_msg, _handler, _minReqType, _maxReqType) \
+ { .msg = _msg, .handler = _handler, \
+ .minDataLen = sizeof(_minReqType), .maxDataLen = sizeof(_maxReqType) }
+
// maximum number of bytes to feed into appSecRxData at once
// The bigger the number, the more time we block other event processing
// appSecRxData only feeds 16 bytes at a time into writeCbk, so large
@@ -91,6 +97,7 @@
static struct DownloadState *mDownloadState;
static AppSecErr mAppSecStatus;
+static struct AppHdr *mApp;
static struct SlabAllocator *mEventSlab;
static struct HostIntfDataBuffer mTxCurr, mTxNext;
static uint8_t mTxCurrLength, mTxNextLength;
@@ -263,7 +270,7 @@
mDownloadState = NULL;
}
-static void resetDownloadState(bool initial)
+static bool resetDownloadState(bool initial, bool erase)
{
bool doCreate = true;
@@ -280,14 +287,19 @@
else
doCreate = false;
}
+ mDownloadState->dstOffset = 0;
if (doCreate)
mDownloadState->start = osAppSegmentCreate(mDownloadState->size);
- if (!mDownloadState->start)
- mDownloadState->erase = true;
- mDownloadState->dstOffset = 0;
+ if (!mDownloadState->start) {
+ if (erase)
+ mDownloadState->erase = true;
+ else
+ return false;
+ }
+ return true;
}
-static bool doStartFirmwareUpload(struct NanohubStartFirmwareUploadRequest *req)
+static bool doStartFirmwareUpload(struct NanohubStartFirmwareUploadRequest *req, bool erase)
{
if (!mDownloadState) {
mDownloadState = heapAlloc(sizeof(struct DownloadState));
@@ -301,9 +313,7 @@
mDownloadState->size = le32toh(req->size);
mDownloadState->crc = le32toh(req->crc);
mDownloadState->chunkReply = NANOHUB_FIRMWARE_CHUNK_REPLY_ACCEPTED;
- resetDownloadState(true);
-
- return true;
+ return resetDownloadState(true, erase);
}
static uint32_t startFirmwareUpload(void *rx, uint8_t rx_len, void *tx, uint64_t timestamp)
@@ -311,7 +321,7 @@
struct NanohubStartFirmwareUploadRequest *req = rx;
struct NanohubStartFirmwareUploadResponse *resp = tx;
- resp->accepted = doStartFirmwareUpload(req);
+ resp->accepted = doStartFirmwareUpload(req, true);
return sizeof(*resp);
}
@@ -444,15 +454,18 @@
if (!osAppSegmentClose(app, mDownloadState->dstOffset, segState)) {
osLog(LOG_INFO, "%s: Failed to close segment\n", __func__);
valid = false;
+ mApp = NULL;
} else {
segState = osAppSegmentGetState(app);
+ mApp = app;
valid = (segState == SEG_ST_VALID);
}
osLog(LOG_INFO, "Loaded %s image type %" PRIu8 ": %" PRIu32
- " bytes @ %p; state=%02" PRIX32 "\n",
+ " bytes @ %p; state=%02" PRIX32 "; crc=%08" PRIX32 "\n",
valid ? "valid" : "invalid",
app->hdr.payInfoType, mDownloadState->size,
- mDownloadState->start, segState);
+ mDownloadState->start, segState,
+ mApp ? osAppSegmentGetCrc(mApp) : 0xFFFFFFFF);
freeDownloadState(); // no more access to mDownloadState
@@ -502,11 +515,30 @@
mDownloadState->eraseScheduled = false;
}
+SET_PACKED_STRUCT_MODE_ON
+struct FirmwareWriteCookie
+{
+ uint32_t evtType;
+ union {
+#ifdef LEGACY_HAL_ENABLED
+ struct NanohubHalLegacyContUploadTx respLegacy;
+#endif
+ struct NanohubHalContUploadTx resp;
+ };
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+static void writeCookieFree(void *ptr)
+{
+ struct FirmwareWriteCookie *buf = container_of(ptr, struct FirmwareWriteCookie, resp);
+ heapFree(buf);
+}
+
static void firmwareWrite(void *cookie)
{
bool valid;
bool finished = false;
- struct NanohubHalContUploadTx *resp = cookie;
+ struct FirmwareWriteCookie *resp = cookie;
// only check crc when cookie is NULL (write came from kernel, not HAL)
bool checkCrc = !cookie;
@@ -545,8 +577,15 @@
valid = false;
}
if (resp) {
- resp->success = valid;
- osEnqueueEvtOrFree(EVT_APP_TO_HOST, resp, heapFree);
+ if (resp->evtType == EVT_APP_TO_HOST) {
+#ifdef LEGACY_HAL_ENABLED
+ resp->respLegacy.success = valid;
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST, &resp->respLegacy, writeCookieFree);
+#endif
+ } else {
+ resp->resp.ret.status = !valid;
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, &resp->resp, writeCookieFree);
+ }
}
}
@@ -575,10 +614,10 @@
firmwareFinish(false);
} else if (offset != mDownloadState->srcOffset) {
reply = NANOHUB_FIRMWARE_CHUNK_REPLY_RESTART;
- resetDownloadState(false);
+ resetDownloadState(false, true);
} else {
if (!cookie)
- mDownloadState->srcCrc = crc32(data, len, mDownloadState->srcCrc);
+ mDownloadState->srcCrc = soft_crc32(data, len, mDownloadState->srcCrc);
mDownloadState->srcOffset += len;
memcpy(mDownloadState->data, data, len);
mDownloadState->lenLeft = mDownloadState->len = len;
@@ -602,12 +641,24 @@
return sizeof(*resp);
}
-static uint32_t doFinishFirmwareUpload()
+static uint32_t doFinishFirmwareUpload(uint32_t *addr, uint32_t *crc)
{
uint32_t reply;
if (!mDownloadState) {
reply = appSecErrToNanohubReply(mAppSecStatus);
+ if (addr) {
+ if (mApp)
+ *addr = (uint32_t)mApp;
+ else
+ *addr = 0xFFFFFFFF;
+ }
+ if (crc) {
+ if (mApp)
+ *crc = osAppSegmentGetCrc(mApp);
+ else
+ *crc = 0xFFFFFFFF;
+ }
} else if (mDownloadState->srcOffset == mDownloadState->size) {
reply = NANOHUB_FIRMWARE_UPLOAD_PROCESSING;
} else {
@@ -620,7 +671,7 @@
static uint32_t finishFirmwareUpload(void *rx, uint8_t rx_len, void *tx, uint64_t timestamp)
{
struct NanohubFinishFirmwareUploadResponse *resp = tx;
- resp->uploadReply = doFinishFirmwareUpload();
+ resp->uploadReply = doFinishFirmwareUpload(NULL, NULL);
if (resp->uploadReply != NANOHUB_FIRMWARE_UPLOAD_PROCESSING)
osLog(LOG_INFO, "%s: reply=%" PRIu8 "\n", __func__, resp->uploadReply);
return sizeof(*resp);
@@ -666,26 +717,12 @@
return sizeof(*resp);
}
-static void nanohubDelayStartApps(void *cookie)
-{
- uint32_t status = 0;
- status = osExtAppStartAppsDelayed();
- osLog(LOG_DEBUG, "Started delayed apps; EXT status: %08" PRIX32 "\n", status);
-}
-
static void addDelta(struct ApHubSync *sync, uint64_t apTime, uint64_t hubTime)
{
- static bool delayStart = false;
-
#if DEBUG_APHUB_TIME_SYNC
syncDebugAdd(apTime, hubTime);
#endif
apHubSyncAddDelta(sync, apTime, hubTime);
-
- if (!delayStart) {
- delayStart = true;
- osDefer(nanohubDelayStartApps, NULL, false);
- }
}
static int64_t getAvgDelta(struct ApHubSync *sync)
@@ -1044,7 +1081,7 @@
NANOHUB_COMMAND(NANOHUB_REASON_GET_INTERRUPT,
getInterrupt,
getInterrupt,
- 0,
+ struct { },
struct NanohubGetInterruptRequest),
NANOHUB_COMMAND(NANOHUB_REASON_MASK_INTERRUPT,
maskInterrupt,
@@ -1080,13 +1117,15 @@
return NULL;
}
-static void halSendMgmtResponse(uint32_t cmd, uint32_t status)
+#ifdef LEGACY_HAL_ENABLED
+
+static void halSendLegacyMgmtResponse(uint32_t cmd, uint32_t status)
{
- struct NanohubHalMgmtTx *resp;
+ struct NanohubHalLegacyMgmtTx *resp;
resp = heapAlloc(sizeof(*resp));
if (resp) {
- resp->hdr = (struct NanohubHalHdr) {
+ resp->hdr = (struct NanohubHalLegacyHdr) {
.appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
.len = sizeof(*resp) - sizeof(resp->hdr) + sizeof(resp->hdr.msg),
.msg = cmd,
@@ -1096,36 +1135,36 @@
}
}
-static void halExtAppsOn(void *rx, uint8_t rx_len)
+static void halLegacyExtAppsOn(void *rx, uint8_t rx_len)
{
- struct NanohubHalMgmtRx *req = rx;
+ struct NanohubHalLegacyMgmtRx *req = rx;
- halSendMgmtResponse(NANOHUB_HAL_EXT_APPS_ON, osExtAppStartAppsByAppId(le64toh(unaligned_u64(&req->appId))));
+ halSendLegacyMgmtResponse(NANOHUB_HAL_LEGACY_EXT_APPS_ON, osExtAppStartAppsByAppId(le64toh(unaligned_u64(&req->appId))));
}
-static void halExtAppsOff(void *rx, uint8_t rx_len)
+static void halLegacyExtAppsOff(void *rx, uint8_t rx_len)
{
- struct NanohubHalMgmtRx *req = rx;
+ struct NanohubHalLegacyMgmtRx *req = rx;
- halSendMgmtResponse(NANOHUB_HAL_EXT_APPS_OFF, osExtAppStopAppsByAppId(le64toh(unaligned_u64(&req->appId))));
+ halSendLegacyMgmtResponse(NANOHUB_HAL_LEGACY_EXT_APPS_OFF, osExtAppStopAppsByAppId(le64toh(unaligned_u64(&req->appId))));
}
-static void halExtAppDelete(void *rx, uint8_t rx_len)
+static void halLegacyExtAppDelete(void *rx, uint8_t rx_len)
{
- struct NanohubHalMgmtRx *req = rx;
+ struct NanohubHalLegacyMgmtRx *req = rx;
- halSendMgmtResponse(NANOHUB_HAL_EXT_APP_DELETE, osExtAppEraseAppsByAppId(le64toh(unaligned_u64(&req->appId))));
+ halSendLegacyMgmtResponse(NANOHUB_HAL_LEGACY_EXT_APP_DELETE, osExtAppEraseAppsByAppId(le64toh(unaligned_u64(&req->appId))));
}
-static void halQueryMemInfo(void *rx, uint8_t rx_len)
+static void halLegacyQueryMemInfo(void *rx, uint8_t rx_len)
{
}
-static void halQueryApps(void *rx, uint8_t rx_len)
+static void halLegacyQueryApps(void *rx, uint8_t rx_len)
{
- struct NanohubHalQueryAppsRx *req = rx;
- struct NanohubHalQueryAppsTx *resp;
- struct NanohubHalHdr *hdr;
+ struct NanohubHalLegacyQueryAppsRx *req = rx;
+ struct NanohubHalLegacyQueryAppsTx *resp;
+ struct NanohubHalLegacyHdr *hdr;
uint64_t appId;
uint32_t appVer, appSize;
@@ -1133,8 +1172,8 @@
resp = heapAlloc(sizeof(*resp));
if (resp) {
resp->hdr.appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0);
- resp->hdr.len = sizeof(*resp) - sizeof(struct NanohubHalHdr) + 1;
- resp->hdr.msg = NANOHUB_HAL_QUERY_APPS;
+ resp->hdr.len = sizeof(*resp) - sizeof(struct NanohubHalLegacyHdr) + 1;
+ resp->hdr.msg = NANOHUB_HAL_LEGACY_QUERY_APPS;
resp->appId = appId;
resp->version = appVer;
resp->flashUse = appSize;
@@ -1146,16 +1185,16 @@
if (hdr) {
hdr->appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0);
hdr->len = 1;
- hdr->msg = NANOHUB_HAL_QUERY_APPS;
+ hdr->msg = NANOHUB_HAL_LEGACY_QUERY_APPS;
osEnqueueEvtOrFree(EVT_APP_TO_HOST, hdr, heapFree);
}
}
}
-static void halQueryRsaKeys(void *rx, uint8_t rx_len)
+static void halLegacyQueryRsaKeys(void *rx, uint8_t rx_len)
{
- struct NanohubHalQueryRsaKeysRx *req = rx;
- struct NanohubHalQueryRsaKeysTx *resp;
+ struct NanohubHalLegacyQueryRsaKeysRx *req = rx;
+ struct NanohubHalLegacyQueryRsaKeysTx *resp;
int len = 0;
const uint32_t *ptr;
uint32_t numKeys;
@@ -1172,75 +1211,77 @@
}
resp->hdr.appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0);
- resp->hdr.len = sizeof(*resp) - sizeof(struct NanohubHalHdr) + 1 + len;
- resp->hdr.msg = NANOHUB_HAL_QUERY_RSA_KEYS;
+ resp->hdr.len = sizeof(*resp) - sizeof(struct NanohubHalLegacyHdr) + 1 + len;
+ resp->hdr.msg = NANOHUB_HAL_LEGACY_QUERY_RSA_KEYS;
osEnqueueEvtOrFree(EVT_APP_TO_HOST, resp, heapFree);
}
-static void halStartUpload(void *rx, uint8_t rx_len)
+static void halLegacyStartUpload(void *rx, uint8_t rx_len)
{
- struct NanohubHalStartUploadRx *req = rx;
+ struct NanohubHalLegacyStartUploadRx *req = rx;
struct NanohubStartFirmwareUploadRequest hwReq = {
- .size= req->length
+ .size = req->length
};
- struct NanohubHalStartUploadTx *resp;
+ struct NanohubHalLegacyStartUploadTx *resp;
if (!(resp = heapAlloc(sizeof(*resp))))
return;
resp->hdr.appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0);
- resp->hdr.len = sizeof(*resp) - sizeof(struct NanohubHalHdr) + 1;
- resp->hdr.msg = NANOHUB_HAL_START_UPLOAD;
- resp->success = doStartFirmwareUpload(&hwReq);
+ resp->hdr.len = sizeof(*resp) - sizeof(struct NanohubHalLegacyHdr) + 1;
+ resp->hdr.msg = NANOHUB_HAL_LEGACY_START_UPLOAD;
+ resp->success = doStartFirmwareUpload(&hwReq, true);
osEnqueueEvtOrFree(EVT_APP_TO_HOST, resp, heapFree);
}
-static void halContUpload(void *rx, uint8_t rx_len)
+static void halLegacyContUpload(void *rx, uint8_t rx_len)
{
uint32_t offset;
uint32_t reply;
uint8_t len;
- struct NanohubHalContUploadRx *req = rx;
- struct NanohubHalContUploadTx *resp;
+ struct NanohubHalLegacyContUploadRx *req = rx;
+ struct FirmwareWriteCookie *cookie;
- if (!(resp = heapAlloc(sizeof(*resp))))
+ if (!(cookie = heapAlloc(sizeof(*cookie))))
return;
- resp->hdr.appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0);
- resp->hdr.len = sizeof(*resp) - sizeof(struct NanohubHalHdr) + 1;
- resp->hdr.msg = NANOHUB_HAL_CONT_UPLOAD;
+ cookie->evtType = EVT_APP_TO_HOST;
+ cookie->respLegacy.hdr = (struct NanohubHalLegacyHdr) {
+ .appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
+ .len = sizeof(cookie->respLegacy) - sizeof(struct NanohubHalLegacyHdr) + 1,
+ .msg = NANOHUB_HAL_LEGACY_CONT_UPLOAD,
+ };
+ cookie->respLegacy.success = false;
if (!mDownloadState) {
reply = NANOHUB_FIRMWARE_CHUNK_REPLY_CANCEL_NO_RETRY;
} else {
offset = le32toh(req->offset);
len = rx_len - sizeof(req->offset);
- reply = doFirmwareChunk(req->data, offset, len, resp);
+ reply = doFirmwareChunk(req->data, offset, len, cookie);
}
if (reply != NANOHUB_FIRMWARE_CHUNK_REPLY_ACCEPTED) {
osLog(LOG_ERROR, "%s: reply=%" PRIu32 "\n", __func__, reply);
- resp->success = false;
-
- osEnqueueEvtOrFree(EVT_APP_TO_HOST, resp, heapFree);
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST, &cookie->respLegacy, writeCookieFree);
}
}
-static void halFinishUpload(void *rx, uint8_t rx_len)
+static void halLegacyFinishUpload(void *rx, uint8_t rx_len)
{
- struct NanohubHalFinishUploadTx *resp;
+ struct NanohubHalLegacyFinishUploadTx *resp;
uint32_t reply;
if (!(resp = heapAlloc(sizeof(*resp))))
return;
resp->hdr.appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0);
- resp->hdr.len = sizeof(*resp) - sizeof(struct NanohubHalHdr) + 1;
- resp->hdr.msg = NANOHUB_HAL_FINISH_UPLOAD;
+ resp->hdr.len = sizeof(*resp) - sizeof(struct NanohubHalLegacyHdr) + 1;
+ resp->hdr.msg = NANOHUB_HAL_LEGACY_FINISH_UPLOAD;
- reply = doFinishFirmwareUpload();
+ reply = doFinishFirmwareUpload(NULL, NULL);
osLog(LOG_INFO, "%s: reply=%" PRIu32 "\n", __func__, reply);
@@ -1249,32 +1290,598 @@
osEnqueueEvtOrFree(EVT_APP_TO_HOST, resp, heapFree);
}
-static void halReboot(void *rx, uint8_t rx_len)
+static void halLegacyReboot(void *rx, uint8_t rx_len)
{
BL.blReboot();
}
+const static struct NanohubHalLegacyCommand mBuiltinHalLegacyCommands[] = {
+ NANOHUB_HAL_LEGACY_COMMAND(NANOHUB_HAL_LEGACY_EXT_APPS_ON,
+ halLegacyExtAppsOn),
+ NANOHUB_HAL_LEGACY_COMMAND(NANOHUB_HAL_LEGACY_EXT_APPS_OFF,
+ halLegacyExtAppsOff),
+ NANOHUB_HAL_LEGACY_COMMAND(NANOHUB_HAL_LEGACY_EXT_APP_DELETE,
+ halLegacyExtAppDelete),
+ NANOHUB_HAL_LEGACY_COMMAND(NANOHUB_HAL_LEGACY_QUERY_MEMINFO,
+ halLegacyQueryMemInfo),
+ NANOHUB_HAL_LEGACY_COMMAND(NANOHUB_HAL_LEGACY_QUERY_APPS,
+ halLegacyQueryApps),
+ NANOHUB_HAL_LEGACY_COMMAND(NANOHUB_HAL_LEGACY_QUERY_RSA_KEYS,
+ halLegacyQueryRsaKeys),
+ NANOHUB_HAL_LEGACY_COMMAND(NANOHUB_HAL_LEGACY_START_UPLOAD,
+ halLegacyStartUpload),
+ NANOHUB_HAL_LEGACY_COMMAND(NANOHUB_HAL_LEGACY_CONT_UPLOAD,
+ halLegacyContUpload),
+ NANOHUB_HAL_LEGACY_COMMAND(NANOHUB_HAL_LEGACY_FINISH_UPLOAD,
+ halLegacyFinishUpload),
+ NANOHUB_HAL_LEGACY_COMMAND(NANOHUB_HAL_LEGACY_REBOOT,
+ halLegacyReboot),
+};
+
+const struct NanohubHalLegacyCommand *nanohubHalLegacyFindCommand(uint8_t msg)
+{
+ uint32_t i;
+
+ for (i = 0; i < ARRAY_SIZE(mBuiltinHalLegacyCommands); i++) {
+ const struct NanohubHalLegacyCommand *cmd = &mBuiltinHalLegacyCommands[i];
+ if (cmd->msg == msg)
+ return cmd;
+ }
+ return NULL;
+}
+
+#endif /* LEGACY_HAL_ENABLED */
+
+static void halSendAppMgmtResponse(struct NanohubHalAppMgmtRx *req, uint32_t status, struct MgmtStatus stat, uint32_t transactionId)
+{
+ struct NanohubHalAppMgmtTx *resp;
+
+ resp = heapAlloc(sizeof(*resp));
+ if (resp) {
+ resp->hdr = (struct NanohubHalHdr) {
+ .appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
+ .len = sizeof(*resp) - sizeof(resp->hdr),
+ .transactionId = transactionId,
+ };
+ resp->ret = (struct NanohubHalRet) {
+ .msg = NANOHUB_HAL_APP_MGMT,
+ .status = htole32(status),
+ };
+ resp->cmd = req->cmd;
+ resp->stat = stat;
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+ }
+}
+
+static void halAppMgmt(void *rx, uint8_t rx_len, uint32_t transactionId)
+{
+ struct NanohubHalAppMgmtRx *req = rx;
+ struct MgmtStatus stat;
+ uint32_t ret;
+
+ switch (req->cmd) {
+ case NANOHUB_HAL_APP_MGMT_START:
+ stat.value= osExtAppStartAppsByAppId(le64toh(unaligned_u64(&req->appId)));
+ ret = stat.op > 0 ? 0 : -1;
+ break;
+ case NANOHUB_HAL_APP_MGMT_STOP:
+ stat.value = osExtAppStopAppsByAppId(le64toh(unaligned_u64(&req->appId)));
+ ret = stat.op > 0 ? 0 : -1;
+ break;
+ case NANOHUB_HAL_APP_MGMT_UNLOAD:
+ stat.value = osExtAppStopAppsByAppId(le64toh(unaligned_u64(&req->appId)));
+ ret = stat.op > 0 ? 0 : -1;
+ break;
+ case NANOHUB_HAL_APP_MGMT_DELETE:
+ stat.value = osExtAppEraseAppsByAppId(le64toh(unaligned_u64(&req->appId)));
+ ret = stat.erase > 0 ? 0 : -1;
+ break;
+ default:
+ return;
+ }
+
+ halSendAppMgmtResponse(req, ret, stat, transactionId);
+}
+
+static void deferHalSysMgmtErase(void *cookie)
+{
+ struct NanohubHalSysMgmtTx *resp = cookie;
+
+ bool success = osEraseShared();
+
+ if (success)
+ resp->ret.status = htole32(0);
+ else
+ resp->ret.status = htole32(-1);
+
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+}
+
+static void halSysMgmt(void *rx, uint8_t rx_len, uint32_t transactionId)
+{
+ struct NanohubHalSysMgmtRx *req = rx;
+ struct NanohubHalSysMgmtTx *resp;
+ uint32_t ret = 0;
+
+ if (!(resp = heapAlloc(sizeof(*resp))))
+ return;
+
+ resp->hdr = (struct NanohubHalHdr) {
+ .appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
+ .len = sizeof(*resp) - sizeof(resp->hdr),
+ .transactionId = transactionId,
+ };
+ resp->ret = (struct NanohubHalRet) {
+ .msg = NANOHUB_HAL_SYS_MGMT,
+ };
+ resp->cmd = req->cmd;
+
+ switch (req->cmd) {
+ case NANOHUB_HAL_SYS_MGMT_ERASE:
+ ret = osExtAppStopAppsByAppId(APP_ID_ANY);
+ osLog(LOG_INFO, "%s: unloaded apps, ret=%08lx\n", __func__, ret);
+ // delay to make sure all apps are unloaded before erasing
+ if (osDefer(deferHalSysMgmtErase, resp, false) == false) {
+ resp->ret.status = htole32(-1);
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+ }
+ break;
+ case NANOHUB_HAL_SYS_MGMT_REBOOT:
+ BL.blReboot();
+ break;
+ default:
+ resp->ret.status = htole32(-1);
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+ }
+}
+
+static bool copyTLV64(uint8_t *buf, size_t *offset, size_t max_len, uint8_t tag, uint64_t val)
+{
+ if (*offset + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint64_t) > max_len)
+ return false;
+ buf[(*offset)++] = tag;
+ buf[(*offset)++] = sizeof(uint64_t);
+ memcpy(&buf[*offset], &val, sizeof(uint64_t));
+ *offset += sizeof(uint64_t);
+ return true;
+}
+
+static bool copyTLV32(uint8_t *buf, size_t *offset, size_t max_len, uint8_t tag, uint32_t val)
+{
+ if (*offset + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t) > max_len)
+ return false;
+ buf[(*offset)++] = tag;
+ buf[(*offset)++] = sizeof(uint32_t);
+ memcpy(&buf[*offset], &val, sizeof(uint32_t));
+ *offset += sizeof(uint32_t);
+ return true;
+}
+
+static bool copyTLV8(uint8_t *buf, size_t *offset, size_t max_len, uint8_t tag, uint8_t val)
+{
+ if (*offset + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) > max_len)
+ return false;
+ buf[(*offset)++] = tag;
+ buf[(*offset)++] = sizeof(uint8_t);
+ memcpy(&buf[*offset], &val, sizeof(uint8_t));
+ *offset += sizeof(uint8_t);
+ return true;
+}
+
+static bool copyTLVEmpty(uint8_t *buf, size_t *offset, size_t max_len, uint8_t tag)
+{
+ if (*offset + sizeof(uint8_t) + sizeof(uint8_t) > max_len)
+ return false;
+ buf[(*offset)++] = tag;
+ buf[(*offset)++] = 0;
+ return true;
+}
+
+static int processAppTags(const struct AppHdr *app, uint32_t crc, uint32_t size, uint8_t *data, uint8_t *tags, int cnt, bool req_tid)
+{
+ int i;
+ size_t offset = 0;
+ const size_t max_len = HOST_HUB_CHRE_PACKET_MAX_LEN - sizeof(struct NanohubHalRet);
+ bool success = true;
+ uint32_t tid;
+ bool tid_valid = false;
+ struct Task *task;
+
+ if (app->hdr.magic != APP_HDR_MAGIC ||
+ app->hdr.fwVer != APP_HDR_VER_CUR ||
+ (app->hdr.fwFlags & FL_APP_HDR_APPLICATION) == 0 ||
+ app->hdr.payInfoType != LAYOUT_APP) {
+ return 0;
+ }
+
+ if (osTidById(&app->hdr.appId, &tid)) {
+ tid_valid = true;
+ task = osTaskFindByTid(tid);
+ if (task) {
+ if (task->app != app)
+ tid_valid = false;
+ } else
+ tid_valid = false;
+ }
+
+ if (!tid_valid && req_tid)
+ return 0;
+
+ for (i=0; i<cnt && success; i++) {
+ switch(tags[i]) {
+ case NANOHUB_HAL_APP_INFO_APPID:
+ success = copyTLV64(data, &offset, max_len, tags[i], app->hdr.appId);
+ break;
+ case NANOHUB_HAL_APP_INFO_CRC:
+ if (size)
+ success = copyTLV32(data, &offset, max_len, tags[i], crc);
+ else
+ success = copyTLVEmpty(data, &offset, max_len, tags[i]);
+ break;
+ case NANOHUB_HAL_APP_INFO_TID:
+ if (tid_valid)
+ success = copyTLV32(data, &offset, max_len, tags[i], tid);
+ else
+ success = copyTLVEmpty(data, &offset, max_len, tags[i]);
+ break;
+ case NANOHUB_HAL_APP_INFO_VERSION:
+ success = copyTLV32(data, &offset, max_len, tags[i], app->hdr.appVer);
+ break;
+ case NANOHUB_HAL_APP_INFO_ADDR:
+ success = copyTLV32(data, &offset, max_len, tags[i], (uint32_t)app);
+ break;
+ case NANOHUB_HAL_APP_INFO_SIZE:
+ if (size)
+ success = copyTLV32(data, &offset, max_len, tags[i], size);
+ else
+ success = copyTLVEmpty(data, &offset, max_len, tags[i]);
+ break;
+ case NANOHUB_HAL_APP_INFO_HEAP:
+ if (tid_valid)
+ success = copyTLV32(data, &offset, max_len, tags[i], heapGetTaskSize(tid));
+ else
+ success = copyTLVEmpty(data, &offset, max_len, tags[i]);
+ break;
+ case NANOHUB_HAL_APP_INFO_DATA:
+ success = copyTLV32(data, &offset, max_len, tags[i], app->sect.got_end - app->sect.data_start);
+ break;
+ case NANOHUB_HAL_APP_INFO_BSS:
+ success = copyTLV32(data, &offset, max_len, tags[i], app->sect.bss_end - app->sect.bss_start);
+ break;
+ case NANOHUB_HAL_APP_INFO_CHRE_MAJOR:
+ if (app->hdr.fwFlags & FL_APP_HDR_CHRE)
+ success = copyTLV8(data, &offset, max_len, tags[i],
+ (app->hdr.chreApiMajor == 0xFF && app->hdr.chreApiMinor == 0xFF) ? 0x01 :
+ app->hdr.chreApiMajor);
+ else
+ success = copyTLVEmpty(data, &offset, max_len, tags[i]);
+ break;
+ case NANOHUB_HAL_APP_INFO_CHRE_MINOR:
+ if (app->hdr.fwFlags & FL_APP_HDR_CHRE)
+ success = copyTLV8(data, &offset, max_len, tags[i],
+ (app->hdr.chreApiMajor == 0xFF && app->hdr.chreApiMinor == 0xFF) ? 0x00 :
+ app->hdr.chreApiMinor);
+ else
+ success = copyTLVEmpty(data, &offset, max_len, tags[i]);
+ break;
+ case NANOHUB_HAL_APP_INFO_END:
+ default:
+ success = false;
+ copyTLVEmpty(data, &offset, max_len, NANOHUB_HAL_APP_INFO_END);
+ break;
+ }
+ }
+
+ return offset;
+}
+
+static void halAppInfo(void *rx, uint8_t rx_len, uint32_t transactionId)
+{
+ struct NanohubHalAppInfoRx *req = rx;
+ struct NanohubHalAppInfoTx *resp;
+ struct SegmentIterator it;
+ uint32_t state;
+ int ret, i;
+ uint32_t sharedSize, numApps;
+ const struct AppHdr *internal;
+ const uint8_t *shared;
+
+ if (!(resp = heapAlloc(sizeof(*resp))))
+ return;
+
+ resp->hdr = (struct NanohubHalHdr) {
+ .appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
+ .len = sizeof(*resp) - sizeof(resp->hdr) - sizeof(resp->data),
+ .transactionId = transactionId,
+ };
+ resp->ret = (struct NanohubHalRet) {
+ .msg = NANOHUB_HAL_APP_INFO,
+ };
+
+ shared = platGetSharedAreaInfo(&sharedSize);
+ internal = platGetInternalAppList(&numApps);
+
+ if ((le32toh(req->addr) >= (uint32_t)shared && le32toh(req->addr) < (uint32_t)shared + sharedSize) ||
+ (le32toh(req->addr) < (uint32_t)shared &&
+ ((uint32_t)shared < (uint32_t)internal ||
+ (numApps > 0 && le32toh(req->addr) > (uint32_t)(internal+numApps-1))))) {
+ osSegmentIteratorInit(&it);
+ while (osSegmentIteratorNext(&it)) {
+ state = osSegmentGetState(it.seg);
+ switch (state) {
+ case SEG_ST_EMPTY:
+ case SEG_ST_RESERVED:
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+ return;
+ case SEG_ST_ERASED:
+ case SEG_ST_VALID:
+ if (le32toh(req->addr) <= (uint32_t)osSegmentGetData(it.seg)) {
+ ret = processAppTags(osSegmentGetData(it.seg), osSegmentGetCrc(it.seg), osSegmentGetSize(it.seg), resp->data, req->tags, rx_len - 4, state == SEG_ST_ERASED);
+ if (ret > 0) {
+ resp->hdr.len += ret;
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+ return;
+ }
+ }
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < numApps; i++, internal++) {
+ if (le32toh(req->addr) <= (uint32_t)internal) {
+ ret = processAppTags(internal, 0, 0, resp->data, req->tags, rx_len - 4, false);
+ if (ret > 0) {
+ resp->hdr.len += ret;
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+ return;
+ }
+ }
+ }
+ }
+
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+}
+
+static void halSysInfo(void *rx, uint8_t rx_len, uint32_t transactionId)
+{
+ extern uint8_t __code_start[];
+ extern uint8_t __code_end[];
+ extern uint8_t __text_end[];
+ extern uint8_t __ram_start[];
+ extern uint8_t __ram_end[];
+
+ struct NanohubHalSysInfoRx *req = rx;
+ struct NanohubHalSysInfoTx *resp;
+ int i;
+ size_t offset = 0;
+ const size_t max_len = HOST_HUB_CHRE_PACKET_MAX_LEN - sizeof(struct NanohubHalRet);
+ bool success = true;
+ int free, chunks, largest;
+ uint32_t shared_size;
+
+ free = heapGetFreeSize(&chunks, &largest);
+
+ if (!(resp = heapAlloc(sizeof(*resp))))
+ return;
+
+ resp->hdr = (struct NanohubHalHdr) {
+ .appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
+ .len = sizeof(*resp) - sizeof(resp->hdr) - sizeof(resp->data),
+ .transactionId = transactionId,
+ };
+ resp->ret = (struct NanohubHalRet) {
+ .msg = NANOHUB_HAL_SYS_INFO,
+ };
+
+ for (i=0; i<rx_len && success; i++) {
+ switch(req->tags[i]) {
+ case NANOHUB_HAL_SYS_INFO_HEAP_FREE:
+ if (free >= 0)
+ success = copyTLV32(resp->data, &offset, max_len, req->tags[i], free);
+ else
+ success = copyTLVEmpty(resp->data, &offset, max_len, req->tags[i]);
+ break;
+ case NANOHUB_HAL_SYS_INFO_RAM_SIZE:
+ success = copyTLV32(resp->data, &offset, max_len, req->tags[i], __ram_end - __ram_start);
+ break;
+ case NANOHUB_HAL_SYS_INFO_EEDATA_SIZE:
+ success = copyTLV32(resp->data, &offset, max_len, req->tags[i], eeDataGetSize());
+ break;
+ case NANOHUB_HAL_SYS_INFO_EEDATA_FREE:
+ success = copyTLV32(resp->data, &offset, max_len, req->tags[i], eeDataGetFree());
+ break;
+ case NANOHUB_HAL_SYS_INFO_CODE_SIZE:
+ success = copyTLV32(resp->data, &offset, max_len, req->tags[i], __code_end - __code_start);
+ break;
+ case NANOHUB_HAL_SYS_INFO_CODE_FREE:
+ success = copyTLV32(resp->data, &offset, max_len, req->tags[i], __code_end - __text_end);
+ break;
+ case NANOHUB_HAL_SYS_INFO_SHARED_SIZE:
+ platGetSharedAreaInfo(&shared_size);
+ success = copyTLV32(resp->data, &offset, max_len, req->tags[i], shared_size);
+ break;
+ case NANOHUB_HAL_SYS_INFO_SHARED_FREE:
+ success = copyTLV32(resp->data, &offset, max_len, req->tags[i], osSegmentGetFree());
+ break;
+ case NANOHUB_HAL_SYS_INFO_END:
+ default:
+ success = false;
+ copyTLVEmpty(resp->data, &offset, max_len, NANOHUB_HAL_APP_INFO_END);
+ break;
+ }
+ }
+
+ resp->hdr.len += offset;
+
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+}
+
+static void halKeyInfo(void *rx, uint8_t rx_len, uint32_t transactionId)
+{
+ struct NanohubHalKeyInfoRx *req = rx;
+ struct NanohubHalKeyInfoTx *resp;
+ const uint32_t *ptr;
+ uint32_t numKeys;
+ uint32_t dataLength;
+
+ if (!(resp = heapAlloc(sizeof(*resp))))
+ return;
+
+ ptr = BL.blGetPubKeysInfo(&numKeys);
+
+ resp->hdr = (struct NanohubHalHdr) {
+ .appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
+ .len = sizeof(*resp) - sizeof(resp->hdr) - sizeof(resp->data),
+ .transactionId = transactionId,
+ };
+ resp->ret = (struct NanohubHalRet) {
+ .msg = NANOHUB_HAL_KEY_INFO,
+ };
+
+ resp->keyLength = 0;
+
+ if (ptr && req->keyNum < numKeys) {
+ if (req->dataOffset < RSA_BYTES) {
+ resp->keyLength = RSA_BYTES;
+ if (RSA_BYTES - req->dataOffset > NANOHUB_RSA_KEY_CHUNK_LEN)
+ dataLength = NANOHUB_RSA_KEY_CHUNK_LEN;
+ else
+ dataLength = RSA_BYTES - req->dataOffset;
+ memcpy(resp->data, (const uint8_t *)ptr + (req->keyNum * RSA_BYTES) + req->dataOffset, dataLength);
+ resp->hdr.len += dataLength;
+ }
+ }
+
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+}
+
+static void halStartUpload(void *rx, uint8_t rx_len, uint32_t transactionId)
+{
+ struct NanohubHalStartUploadRx *req = rx;
+ struct NanohubStartFirmwareUploadRequest hwReq = {
+ .size = req->length
+ };
+ struct NanohubHalStartUploadTx *resp;
+
+ if (!(resp = heapAlloc(sizeof(*resp))))
+ return;
+
+ resp->hdr = (struct NanohubHalHdr) {
+ .appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
+ .len = sizeof(*resp) - sizeof(resp->hdr),
+ .transactionId = transactionId,
+ };
+
+ resp->ret.msg = NANOHUB_HAL_START_UPLOAD;
+ if (doStartFirmwareUpload(&hwReq, false))
+ resp->ret.status = NANOHUB_FIRMWARE_CHUNK_REPLY_ACCEPTED;
+ else
+ resp->ret.status = NANOHUB_FIRMWARE_CHUNK_REPLY_NO_SPACE;
+
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+}
+
+static void halContUpload(void *rx, uint8_t rx_len, uint32_t transactionId)
+{
+ uint32_t offset;
+ uint32_t reply;
+ uint8_t len;
+ struct NanohubHalContUploadRx *req = rx;
+ struct FirmwareWriteCookie *cookie;
+
+ if (!(cookie = heapAlloc(sizeof(*cookie))))
+ return;
+
+ cookie->evtType = EVT_APP_TO_HOST_CHRE;
+ cookie->resp.hdr = (struct NanohubHalHdr) {
+ .appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
+ .len = sizeof(cookie->resp) - sizeof(cookie->resp.hdr),
+ .transactionId = transactionId,
+ };
+ cookie->resp.ret = (struct NanohubHalRet) {
+ .msg = NANOHUB_HAL_CONT_UPLOAD,
+ };
+
+ if (!mDownloadState) {
+ reply = NANOHUB_FIRMWARE_CHUNK_REPLY_CANCEL_NO_RETRY;
+ } else {
+ offset = le32toh(req->offset);
+ len = rx_len - sizeof(req->offset);
+ reply = doFirmwareChunk(req->data, offset, len, cookie);
+ }
+ if (reply != NANOHUB_FIRMWARE_CHUNK_REPLY_ACCEPTED) {
+ osLog(LOG_ERROR, "%s: reply=%" PRIu32 "\n", __func__, reply);
+
+ cookie->resp.ret.status = reply;
+
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, &cookie->resp, writeCookieFree);
+ }
+}
+
+static void halFinishUpload(void *rx, uint8_t rx_len, uint32_t transactionId)
+{
+ struct NanohubHalFinishUploadTx *resp;
+ uint32_t reply;
+ uint32_t addr = 0xFFFFFFFF;
+ uint32_t crc = 0xFFFFFFFF;
+
+ if (!(resp = heapAlloc(sizeof(*resp))))
+ return;
+
+ resp->hdr = (struct NanohubHalHdr) {
+ .appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0),
+ .len = sizeof(*resp) - sizeof(resp->hdr),
+ .transactionId = transactionId,
+ };
+
+ reply = doFinishFirmwareUpload(&addr, &crc);
+
+ osLog(LOG_INFO, "%s: reply=%" PRIu32 "\n", __func__, reply);
+
+ resp->ret = (struct NanohubHalRet) {
+ .msg = NANOHUB_HAL_FINISH_UPLOAD,
+ .status = reply,
+ };
+
+ resp->addr = addr;
+ resp->crc = crc;
+
+ osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, resp, heapFree);
+}
+
const static struct NanohubHalCommand mBuiltinHalCommands[] = {
- NANOHUB_HAL_COMMAND(NANOHUB_HAL_EXT_APPS_ON,
- halExtAppsOn),
- NANOHUB_HAL_COMMAND(NANOHUB_HAL_EXT_APPS_OFF,
- halExtAppsOff),
- NANOHUB_HAL_COMMAND(NANOHUB_HAL_EXT_APP_DELETE,
- halExtAppDelete),
- NANOHUB_HAL_COMMAND(NANOHUB_HAL_QUERY_MEMINFO,
- halQueryMemInfo),
- NANOHUB_HAL_COMMAND(NANOHUB_HAL_QUERY_APPS,
- halQueryApps),
- NANOHUB_HAL_COMMAND(NANOHUB_HAL_QUERY_RSA_KEYS,
- halQueryRsaKeys),
+ NANOHUB_HAL_COMMAND(NANOHUB_HAL_APP_MGMT,
+ halAppMgmt,
+ struct NanohubHalAppMgmtRx,
+ struct NanohubHalAppMgmtRx),
+ NANOHUB_HAL_COMMAND(NANOHUB_HAL_SYS_MGMT,
+ halSysMgmt,
+ struct NanohubHalSysMgmtRx,
+ struct NanohubHalSysMgmtRx),
+ NANOHUB_HAL_COMMAND(NANOHUB_HAL_APP_INFO,
+ halAppInfo,
+ __le32,
+ struct NanohubHalAppInfoRx),
+ NANOHUB_HAL_COMMAND(NANOHUB_HAL_SYS_INFO,
+ halSysInfo,
+ struct { },
+ struct NanohubHalSysInfoRx),
+ NANOHUB_HAL_COMMAND(NANOHUB_HAL_KEY_INFO,
+ halKeyInfo,
+ struct NanohubHalKeyInfoRx,
+ struct NanohubHalKeyInfoRx),
NANOHUB_HAL_COMMAND(NANOHUB_HAL_START_UPLOAD,
- halStartUpload),
+ halStartUpload,
+ struct NanohubHalStartUploadRx,
+ struct NanohubHalStartUploadRx),
NANOHUB_HAL_COMMAND(NANOHUB_HAL_CONT_UPLOAD,
- halContUpload),
+ halContUpload,
+ __le32,
+ struct NanohubHalContUploadRx),
NANOHUB_HAL_COMMAND(NANOHUB_HAL_FINISH_UPLOAD,
- halFinishUpload),
- NANOHUB_HAL_COMMAND(NANOHUB_HAL_REBOOT,
- halReboot),
+ halFinishUpload,
+ struct { },
+ struct { }),
};
const struct NanohubHalCommand *nanohubHalFindCommand(uint8_t msg)
@@ -1289,6 +1896,7 @@
return NULL;
}
+
int64_t hostGetTimeDelta(void)
{
int64_t delta = getAvgDelta(&mTimeSync);
diff --git a/firmware/os/core/seos.c b/firmware/os/core/seos.c
index 418fe76..9756964 100644
--- a/firmware/os/core/seos.c
+++ b/firmware/os/core/seos.c
@@ -513,6 +513,24 @@
return (struct Segment *)(start + size);
}
+uint32_t osSegmentGetFree()
+{
+ struct SegmentIterator it;
+ const struct Segment *storageSeg = NULL;
+
+ osSegmentIteratorInit(&it);
+ while (osSegmentIteratorNext(&it)) {
+ if (osSegmentGetState(it.seg) == SEG_ST_EMPTY) {
+ storageSeg = it.seg;
+ break;
+ }
+ }
+ if (!storageSeg || storageSeg > it.sharedEnd)
+ return 0;
+
+ return (uint8_t *)it.sharedEnd - (uint8_t *)storageSeg;
+}
+
struct Segment *osGetSegment(const struct AppHdr *app)
{
uint32_t size;
@@ -614,13 +632,13 @@
footerLen = (-fullSize) & 3;
memset(footer, 0x00, footerLen);
-#ifdef SEGMENT_CRC_SUPPORT
- struct SegmentFooter segFooter {
- .crc = ~crc32(storageSeg, fullSize, ~0),
+ wdtDisableClk();
+ struct SegmentFooter segFooter = {
+ .crc = ~soft_crc32(storageSeg, fullSize, ~0),
};
+ wdtEnableClk();
memcpy(&footer[footerLen], &segFooter, sizeof(segFooter));
footerLen += sizeof(segFooter);
-#endif
if (ret && footerLen)
ret = osWriteShared((uint8_t*)storageSeg + fullSize, footer, footerLen);
@@ -673,10 +691,10 @@
static bool osExtAppIsValid(const struct AppHdr *app, uint32_t len)
{
- //TODO: when CRC support is ready, add CRC check here
return osAppIsValid(app) &&
len >= sizeof(*app) &&
osAppSegmentGetState(app) == SEG_ST_VALID &&
+ osAppSegmentCalcCrcResidue(app) == CRC_RESIDUE &&
!(app->hdr.fwFlags & FL_APP_HDR_INTERNAL);
}
@@ -781,20 +799,20 @@
osStopTask(task, true);
}
-static bool matchDelayStart(const void *cookie, const struct AppHdr *app)
+static bool matchAutoStart(const void *cookie, const struct AppHdr *app)
{
bool match = (bool)cookie;
if (app->hdr.fwFlags & FL_APP_HDR_CHRE) {
if (app->hdr.chreApiMajor == 0xFF && app->hdr.chreApiMinor == 0xFF)
- return !match;
+ return match;
else if ((app->hdr.chreApiMajor < 0x01) ||
(app->hdr.chreApiMajor == 0x01 && app->hdr.chreApiMinor < 0x01))
- return !match;
- else
return match;
+ else
+ return !match;
} else {
- return !match;
+ return match;
}
}
@@ -964,11 +982,6 @@
return osExtAppStartApps(matchAppId, &appId);
}
-uint32_t osExtAppStartAppsDelayed()
-{
- return osExtAppStartApps(matchDelayStart, (void *)true);
-}
-
static void osStartTasks(void)
{
const struct AppHdr *app;
@@ -1019,7 +1032,7 @@
}
osLog(LOG_DEBUG, "Starting external apps...\n");
- status = osExtAppStartApps(matchDelayStart, (void *)false);
+ status = osExtAppStartApps(matchAutoStart, (void *)true);
osLog(LOG_DEBUG, "Started %" PRIu32 " internal apps; EXT status: %08" PRIX32 "\n", taskCnt, status);
}
@@ -1395,7 +1408,7 @@
return osEnqueuePrivateEvtEx(evtType & EVT_MASK, evtData, taggedPtrMakeFromUint(osGetCurrentTid()), toTid);
}
-bool osTidById(uint64_t *appId, uint32_t *tid)
+bool osTidById(const uint64_t *appId, uint32_t *tid)
{
struct Task *task;
diff --git a/firmware/os/inc/eeData.h b/firmware/os/inc/eeData.h
index 9b313ee..0a6eca6 100644
--- a/firmware/os/inc/eeData.h
+++ b/firmware/os/inc/eeData.h
@@ -45,6 +45,9 @@
bool eeDataGet(uint32_t name, void *buf, uint32_t *szP);
bool eeDataSet(uint32_t name, const void *buf, uint32_t len);
+uint32_t eeDataGetSize();
+uint32_t eeDataGetFree();
+
//allow getting old "versions". Set state to NULL initially, call till you get NULL as return value
void *eeDataGetAllVersions(uint32_t name, void *buf, uint32_t *szP, void **stateP);
bool eeDataEraseOldVersion(uint32_t name, void *addr); // addr is non-NULL address returned by call to eeDataGetAllVersions
diff --git a/firmware/os/inc/heap.h b/firmware/os/inc/heap.h
index c5bea59..cb1ccb2 100644
--- a/firmware/os/inc/heap.h
+++ b/firmware/os/inc/heap.h
@@ -24,19 +24,16 @@
#include <stdint.h>
#include <stdbool.h>
-
-
-
bool heapInit(void);
void* heapAlloc(uint32_t sz);
void heapFree(void* ptr);
int heapFreeAll(uint32_t tid);
-
+int heapGetFreeSize(int *numChunks, int *largestChunk);
+int heapGetTaskSize(uint32_t tid);
#ifdef __cplusplus
}
#endif
-
#endif
diff --git a/firmware/os/inc/nanohubCommand.h b/firmware/os/inc/nanohubCommand.h
index 408cffd..e100980 100644
--- a/firmware/os/inc/nanohubCommand.h
+++ b/firmware/os/inc/nanohubCommand.h
@@ -34,11 +34,20 @@
void nanohubPrefetchTx(uint32_t interrupt, uint32_t wakeup, uint32_t nonwakeup);
const struct NanohubCommand *nanohubFindCommand(uint32_t packetReason);
-struct NanohubHalCommand {
+struct NanohubHalLegacyCommand {
uint8_t msg;
void (*handler)(void *, uint8_t);
};
+const struct NanohubHalLegacyCommand *nanohubHalLegacyFindCommand(uint8_t msg);
+
+struct NanohubHalCommand {
+ uint8_t msg;
+ void (*handler)(void *, uint8_t, uint32_t);
+ uint8_t minDataLen;
+ uint8_t maxDataLen;
+};
+
const struct NanohubHalCommand *nanohubHalFindCommand(uint8_t msg);
uint64_t hostGetTime(void);
int64_t hostGetTimeDelta(void);
diff --git a/firmware/os/inc/nanohubPacket.h b/firmware/os/inc/nanohubPacket.h
index ad962ea..df4af66 100644
--- a/firmware/os/inc/nanohubPacket.h
+++ b/firmware/os/inc/nanohubPacket.h
@@ -166,6 +166,7 @@
NANOHUB_FIRMWARE_CHUNK_REPLY_RESTART,
NANOHUB_FIRMWARE_CHUNK_REPLY_CANCEL,
NANOHUB_FIRMWARE_CHUNK_REPLY_CANCEL_NO_RETRY,
+ NANOHUB_FIRMWARE_CHUNK_REPLY_NO_SPACE,
};
SET_PACKED_STRUCT_MODE_ON
@@ -278,18 +279,6 @@
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
-SET_PACKED_STRUCT_MODE_ON
-struct NanohubHalHdr {
- uint64_t appId;
- uint8_t len;
- uint8_t msg;
-} ATTRIBUTE_PACKED;
-SET_PACKED_STRUCT_MODE_OFF
-
-#define NANOHUB_HAL_EXT_APPS_ON 0
-#define NANOHUB_HAL_EXT_APPS_OFF 1
-#define NANOHUB_HAL_EXT_APP_DELETE 2
-
// this behaves more stable w.r.t. endianness than bit field
// this is setting byte fields in MgmtStatus response
// the high-order bit, if set, is indication of counter overflow
@@ -310,32 +299,46 @@
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
+#ifdef LEGACY_HAL_ENABLED
+
SET_PACKED_STRUCT_MODE_ON
-struct NanohubHalMgmtRx {
+struct NanohubHalLegacyHdr {
+ uint64_t appId;
+ uint8_t len;
+ uint8_t msg;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_LEGACY_EXT_APPS_ON 0
+#define NANOHUB_HAL_LEGACY_EXT_APPS_OFF 1
+#define NANOHUB_HAL_LEGACY_EXT_APP_DELETE 2
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalLegacyMgmtRx {
__le64 appId;
struct MgmtStatus stat;
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
SET_PACKED_STRUCT_MODE_ON
-struct NanohubHalMgmtTx {
- struct NanohubHalHdr hdr;
+struct NanohubHalLegacyMgmtTx {
+ struct NanohubHalLegacyHdr hdr;
__le32 status;
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
-#define NANOHUB_HAL_QUERY_MEMINFO 3
-#define NANOHUB_HAL_QUERY_APPS 4
+#define NANOHUB_HAL_LEGACY_QUERY_MEMINFO 3
+#define NANOHUB_HAL_LEGACY_QUERY_APPS 4
SET_PACKED_STRUCT_MODE_ON
-struct NanohubHalQueryAppsRx {
+struct NanohubHalLegacyQueryAppsRx {
__le32 idx;
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
SET_PACKED_STRUCT_MODE_ON
-struct NanohubHalQueryAppsTx {
- struct NanohubHalHdr hdr;
+struct NanohubHalLegacyQueryAppsTx {
+ struct NanohubHalLegacyHdr hdr;
__le64 appId;
__le32 version;
__le32 flashUse;
@@ -343,22 +346,205 @@
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
-#define NANOHUB_HAL_QUERY_RSA_KEYS 5
+#define NANOHUB_HAL_LEGACY_QUERY_RSA_KEYS 5
SET_PACKED_STRUCT_MODE_ON
-struct NanohubHalQueryRsaKeysRx {
+struct NanohubHalLegacyQueryRsaKeysRx {
__le32 offset;
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
SET_PACKED_STRUCT_MODE_ON
-struct NanohubHalQueryRsaKeysTx {
- struct NanohubHalHdr hdr;
+struct NanohubHalLegacyQueryRsaKeysTx {
+ struct NanohubHalLegacyHdr hdr;
uint8_t data[];
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
-#define NANOHUB_HAL_START_UPLOAD 6
+#define NANOHUB_HAL_LEGACY_START_UPLOAD 6
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalLegacyStartUploadRx {
+ uint8_t isOs;
+ __le32 length;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalLegacyStartUploadTx {
+ struct NanohubHalLegacyHdr hdr;
+ uint8_t success;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_LEGACY_CONT_UPLOAD 7
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalLegacyContUploadRx {
+ __le32 offset;
+ uint8_t data[];
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalLegacyContUploadTx {
+ struct NanohubHalLegacyHdr hdr;
+ uint8_t success;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_LEGACY_FINISH_UPLOAD 8
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalLegacyFinishUploadTx {
+ struct NanohubHalLegacyHdr hdr;
+ uint8_t success;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_LEGACY_REBOOT 9
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalLegacyRebootTx {
+ struct NanohubHalLegacyHdr hdr;
+ __le32 reason;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#endif /* LEGACY_HAL_ENABLED */
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalHdr {
+ __le64 appId;
+ uint8_t len;
+ __le32 transactionId;
+ __le16 unused;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalRet {
+ uint8_t msg;
+ __le32 status;
+} ATTRIBUTE_PACKED;
+
+#define NANOHUB_HAL_APP_MGMT 0x10
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalAppMgmtRx {
+ __le64 appId;
+ uint8_t cmd;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_APP_MGMT_START 0
+#define NANOHUB_HAL_APP_MGMT_STOP 1
+#define NANOHUB_HAL_APP_MGMT_UNLOAD 2
+#define NANOHUB_HAL_APP_MGMT_DELETE 3
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalAppMgmtTx {
+ struct NanohubHalHdr hdr;
+ struct NanohubHalRet ret;
+ uint8_t cmd;
+ struct MgmtStatus stat;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_SYS_MGMT 0x11
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalSysMgmtRx {
+ uint8_t cmd;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_SYS_MGMT_ERASE 0
+#define NANOHUB_HAL_SYS_MGMT_REBOOT 1
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalSysMgmtTx {
+ struct NanohubHalHdr hdr;
+ struct NanohubHalRet ret;
+ uint8_t cmd;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_APP_INFO 0x12
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalAppInfoRx {
+ __le32 addr;
+ uint8_t tags[HOST_HUB_CHRE_PACKET_MAX_LEN - sizeof(__le32)];
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_APP_INFO_APPID 0x00
+#define NANOHUB_HAL_APP_INFO_CRC 0x01
+#define NANOHUB_HAL_APP_INFO_TID 0x02
+#define NANOHUB_HAL_APP_INFO_VERSION 0x03
+#define NANOHUB_HAL_APP_INFO_ADDR 0x04
+#define NANOHUB_HAL_APP_INFO_SIZE 0x05
+#define NANOHUB_HAL_APP_INFO_HEAP 0x06
+#define NANOHUB_HAL_APP_INFO_DATA 0x07
+#define NANOHUB_HAL_APP_INFO_BSS 0x08
+#define NANOHUB_HAL_APP_INFO_CHRE_MAJOR 0x09
+#define NANOHUB_HAL_APP_INFO_CHRE_MINOR 0x0A
+#define NANOHUB_HAL_APP_INFO_END 0xFF
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalAppInfoTx {
+ struct NanohubHalHdr hdr;
+ struct NanohubHalRet ret;
+ uint8_t data[HOST_HUB_CHRE_PACKET_MAX_LEN - sizeof(struct NanohubHalRet)];
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_SYS_INFO 0x13
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalSysInfoRx {
+ uint8_t tags[HOST_HUB_CHRE_PACKET_MAX_LEN];
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_SYS_INFO_HEAP_FREE 0x0F
+#define NANOHUB_HAL_SYS_INFO_RAM_SIZE 0x12
+#define NANOHUB_HAL_SYS_INFO_EEDATA_SIZE 0x13
+#define NANOHUB_HAL_SYS_INFO_EEDATA_FREE 0x14
+#define NANOHUB_HAL_SYS_INFO_CODE_SIZE 0x15
+#define NANOHUB_HAL_SYS_INFO_CODE_FREE 0x16
+#define NANOHUB_HAL_SYS_INFO_SHARED_SIZE 0x17
+#define NANOHUB_HAL_SYS_INFO_SHARED_FREE 0x18
+#define NANOHUB_HAL_SYS_INFO_END 0xFF
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalSysInfoTx {
+ struct NanohubHalHdr hdr;
+ struct NanohubHalRet ret;
+ uint8_t data[HOST_HUB_CHRE_PACKET_MAX_LEN - sizeof(struct NanohubHalRet)];
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_KEY_INFO 0x14
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalKeyInfoRx {
+ uint32_t keyNum;
+ uint32_t dataOffset;
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+SET_PACKED_STRUCT_MODE_ON
+struct NanohubHalKeyInfoTx {
+ struct NanohubHalHdr hdr;
+ struct NanohubHalRet ret;
+ uint32_t keyLength;
+ uint8_t data[NANOHUB_RSA_KEY_CHUNK_LEN];
+} ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+#define NANOHUB_HAL_START_UPLOAD 0x16
SET_PACKED_STRUCT_MODE_ON
struct NanohubHalStartUploadRx {
@@ -370,41 +556,34 @@
SET_PACKED_STRUCT_MODE_ON
struct NanohubHalStartUploadTx {
struct NanohubHalHdr hdr;
- uint8_t success;
+ struct NanohubHalRet ret;
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
-#define NANOHUB_HAL_CONT_UPLOAD 7
+#define NANOHUB_HAL_CONT_UPLOAD 0x17
SET_PACKED_STRUCT_MODE_ON
struct NanohubHalContUploadRx {
__le32 offset;
- uint8_t data[];
+ uint8_t data[HOST_HUB_CHRE_PACKET_MAX_LEN-sizeof(__le32)];
} ATTRIBUTE_PACKED;
-SET_PACKED_STRUCT_MODE_OFF
+SET_PACKED_STRUCT_MODE_ON
SET_PACKED_STRUCT_MODE_ON
struct NanohubHalContUploadTx {
struct NanohubHalHdr hdr;
- uint8_t success;
+ struct NanohubHalRet ret;
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
-#define NANOHUB_HAL_FINISH_UPLOAD 8
+#define NANOHUB_HAL_FINISH_UPLOAD 0x18
SET_PACKED_STRUCT_MODE_ON
struct NanohubHalFinishUploadTx {
struct NanohubHalHdr hdr;
- uint8_t success;
-} ATTRIBUTE_PACKED;
-SET_PACKED_STRUCT_MODE_OFF
-
-#define NANOHUB_HAL_REBOOT 9
-
-SET_PACKED_STRUCT_MODE_ON
-struct NanohubHalRebootTx {
- struct NanohubHalHdr hdr;
- __le32 reason;
+ struct NanohubHalRet ret;
+ __le32 addr;
+ __le32 crc;
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
diff --git a/firmware/os/inc/seos.h b/firmware/os/inc/seos.h
index c66d897..c8a3d48 100644
--- a/firmware/os/inc/seos.h
+++ b/firmware/os/inc/seos.h
@@ -22,6 +22,7 @@
#endif
#include <plat/taggedPtr.h>
+#include <plat/wdt.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdarg.h>
@@ -30,12 +31,11 @@
#include <plat/app.h>
#include <eventnums.h>
#include <variant/variant.h>
+#include <crc.h>
#include "toolchain.h"
#include <nanohub/nanohub.h>
-//#define SEGMENT_CRC_SUPPORT
-
#ifndef MAX_TASKS
/* Default to 16 tasks, override may come from variant.h */
#define MAX_TASKS 16
@@ -177,7 +177,7 @@
bool osDefer(OsDeferCbkF callback, void *cookie, bool urgent);
-bool osTidById(uint64_t *appId, uint32_t *tid);
+bool osTidById(const uint64_t *appId, uint32_t *tid);
bool osAppInfoById(uint64_t appId, uint32_t *appIdx, uint32_t *appVer, uint32_t *appSize);
bool osAppInfoByIndex(uint32_t appIdx, uint64_t *appId, uint32_t *appVer, uint32_t *appSize);
bool osExtAppInfoByIndex(uint32_t appIdx, uint64_t *appId, uint32_t *appVer, uint32_t *appSize);
@@ -189,8 +189,9 @@
bool osAppSegmentSetState(const struct AppHdr *app, uint32_t segState);
bool osSegmentSetSize(struct Segment *seg, uint32_t size);
bool osAppWipeData(struct AppHdr *app);
-struct Segment *osGetSegment(const struct AppHdr *app);
struct Segment *osSegmentGetEnd();
+uint32_t osSegmentGetFree();
+struct Segment *osGetSegment(const struct AppHdr *app);
static inline int32_t osSegmentGetSize(const struct Segment *seg)
{
@@ -207,17 +208,19 @@
return (struct AppHdr*)(&seg[1]);
}
-#ifdef SEGMENT_CRC_SUPPORT
-
struct SegmentFooter
{
uint32_t crc;
};
#define FOOTER_SIZE sizeof(struct SegmentFooter)
-#else
-#define FOOTER_SIZE 0
-#endif
+
+static inline uint32_t osSegmentGetCrc(const struct Segment *seg)
+{
+ struct SegmentFooter *footer = (struct SegmentFooter *)(((uint8_t*)seg) +
+ ((osSegmentGetSize(seg) + 3) & ~3) + sizeof(*seg));
+ return footer ? footer->crc : 0xFFFFFFFF;
+}
static inline uint32_t osSegmentSizeAlignedWithFooter(uint32_t size)
{
@@ -243,6 +246,24 @@
return osSegmentGetState(osGetSegment(app));
}
+static inline uint32_t osAppSegmentGetCrc(const struct AppHdr *app)
+{
+ return osSegmentGetCrc(osGetSegment(app));
+}
+
+static inline uint32_t osAppSegmentCalcCrcResidue(const struct AppHdr *app)
+{
+ struct Segment *seg = osGetSegment(app);
+ uint32_t size = osSegmentSizeAlignedWithFooter(osSegmentGetSize(seg));
+ uint32_t crc;
+
+ wdtDisableClk();
+ crc = soft_crc32((uint8_t*)seg, size + sizeof(*seg), ~0);
+ wdtEnableClk();
+
+ return crc;
+}
+
struct SegmentIterator {
const struct Segment *shared;
const struct Segment *sharedEnd;
@@ -272,7 +293,6 @@
uint32_t osExtAppStopAppsByAppId(uint64_t appId);
uint32_t osExtAppEraseAppsByAppId(uint64_t appId);
uint32_t osExtAppStartAppsByAppId(uint64_t appId);
-uint32_t osExtAppStartAppsDelayed();
bool osAppIsChre(uint16_t tid);
uint32_t osAppChreVersion(uint16_t tid);
@@ -293,15 +313,33 @@
#define INTERNAL_APP_INIT(_id, _ver, _init, _end, _event) \
SET_INTERNAL_LOCATION(location, ".internal_app_init")static const struct AppHdr \
SET_INTERNAL_LOCATION_ATTRIBUTES(used, section (".internal_app_init")) mAppHdr = { \
- .hdr.magic = APP_HDR_MAGIC, \
- .hdr.fwVer = APP_HDR_VER_CUR, \
- .hdr.fwFlags = FL_APP_HDR_INTERNAL | FL_APP_HDR_APPLICATION, \
- .hdr.appId = (_id), \
- .hdr.appVer = (_ver), \
+ .hdr.magic = APP_HDR_MAGIC, \
+ .hdr.fwVer = APP_HDR_VER_CUR, \
+ .hdr.fwFlags = FL_APP_HDR_INTERNAL | FL_APP_HDR_APPLICATION, \
+ .hdr.appId = (_id), \
+ .hdr.appVer = (_ver), \
.hdr.payInfoType = LAYOUT_APP, \
- .vec.init = (uint32_t)(_init), \
- .vec.end = (uint32_t)(_end), \
- .vec.handle = (uint32_t)(_event) \
+ .vec.init = (uint32_t)(_init), \
+ .vec.end = (uint32_t)(_end), \
+ .vec.handle = (uint32_t)(_event) \
+}
+#endif
+
+#ifndef INTERNAL_CHRE_APP_INIT
+#define INTERNAL_CHRE_APP_INIT(_id, _ver, _init, _end, _event) \
+SET_INTERNAL_LOCATION(location, ".internal_app_init")static const struct AppHdr \
+SET_INTERNAL_LOCATION_ATTRIBUTES(used, section (".internal_app_init")) mAppHdr = { \
+ .hdr.magic = APP_HDR_MAGIC, \
+ .hdr.fwVer = APP_HDR_VER_CUR, \
+ .hdr.fwFlags = FL_APP_HDR_INTERNAL | FL_APP_HDR_APPLICATION | FL_APP_HDR_CHRE, \
+ .hdr.chreApiMajor = 0x01, \
+ .hdr.chreApiMinor = 0x02, \
+ .hdr.appId = (_id), \
+ .hdr.appVer = (_ver), \
+ .hdr.payInfoType = LAYOUT_APP, \
+ .vec.init = (uint32_t)(_init), \
+ .vec.end = (uint32_t)(_end), \
+ .vec.handle = (uint32_t)(_event) \
}
#endif
diff --git a/firmware/os/platform/stm32/eeData.c b/firmware/os/platform/stm32/eeData.c
index 20e859e..2710ba0 100644
--- a/firmware/os/platform/stm32/eeData.c
+++ b/firmware/os/platform/stm32/eeData.c
@@ -90,6 +90,34 @@
return (uint32_t*)data - 1;
}
+uint32_t eeDataGetSize()
+{
+ return __eedata_end - __eedata_start;
+}
+
+uint32_t eeDataGetFree()
+{
+ uint32_t *p = __eedata_start;
+
+ //find the last incarnation of "name" in flash area
+ while (p < __eedata_end) {
+ uint32_t info = *p;
+ uint32_t name = info & EE_DATA_NAME_MAX;
+ uint32_t sz = info / (EE_DATA_NAME_MAX + 1);
+
+ //check for ending condition (name == max)
+ if (name == EE_DATA_NAME_MAX)
+ break;
+
+ p++;
+
+ //skip over to next data chunk header
+ p += (sz + 3) / 4;
+ }
+
+ return __eedata_end - p;
+}
+
bool eeDataGet(uint32_t name, void *buf, uint32_t *szP)
{
uint32_t offset = 0;
diff --git a/lib/Android.mk b/lib/Android.mk
index 0caa123..88707e1 100644
--- a/lib/Android.mk
+++ b/lib/Android.mk
@@ -20,7 +20,6 @@
nanohub/aes.c \
nanohub/rsa.c \
nanohub/sha2.c \
- nanohub/softcrc.c \
src_includes := \
$(LOCAL_PATH)/include \
@@ -36,12 +35,24 @@
include $(BUILD_NANOHUB_BL_STATIC_LIBRARY)
+include $(CLEAR_NANO_VARS)
+
+LOCAL_MODULE := libnanohub_common_os
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := nanohub/softcrc.c
+LOCAL_C_INCLUDES := $(src_includes)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(src_includes)
+
+include $(BUILD_NANOHUB_OS_STATIC_LIBRARY)
+
include $(CLEAR_VARS)
LOCAL_MODULE := libnanohub_common
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
$(src_files) \
+ nanohub/softcrc.c \
nanohub/nanoapp.c \
LOCAL_CFLAGS := \