From 5fc4129fcb9609790e2d1d3a93c7d9de8dd94ccb Mon Sep 17 00:00:00 2001 From: San Mehat Date: Tue, 16 Jun 2009 10:50:06 -0700 Subject: [PATCH 01/11] nexus: Add TiwlanEventListener for reading driver events directly Signed-off-by: San Mehat --- nexus/TiwlanEventListener.cpp | 61 ++++++++++++++++++++++++++++++++++ nexus/TiwlanEventListener.h | 55 ++++++++++++++++++++++++++++++ nexus/TiwlanWifiController.cpp | 56 +++++++++++++++++++++++++++++-- nexus/TiwlanWifiController.h | 7 ++++ 4 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 nexus/TiwlanEventListener.cpp create mode 100644 nexus/TiwlanEventListener.h diff --git a/nexus/TiwlanEventListener.cpp b/nexus/TiwlanEventListener.cpp new file mode 100644 index 000000000..76e6ec110 --- /dev/null +++ b/nexus/TiwlanEventListener.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#define LOG_TAG "TiwlanEventListener" +#include + +#include "TiwlanEventListener.h" + +TiwlanEventListener::TiwlanEventListener(int socket) : + SocketListener(socket, false) { +} + +bool TiwlanEventListener::onDataAvailable(SocketClient *cli) { + struct ipc_ev_data *data; + + if (!(data = (struct ipc_ev_data *) malloc(sizeof(struct ipc_ev_data)))) { + LOGE("Failed to allocate packet (out of memory)"); + return true; + } + + if (recv(cli->getSocket(), data, sizeof(struct ipc_ev_data), 0) < 0) { + LOGE("recv failed (%s)", strerror(errno)); + goto out; + } + + if (data->event_type == IPC_EVENT_LINK_SPEED) { + uint32_t *spd = (uint32_t *) data->buffer; + *spd /= 2; + LOGD("Link speed = %u MB/s", *spd); + } else if (data->event_type == IPC_EVENT_LOW_SNR) { + LOGD("Low signal/noise ratio"); + } else if (data->event_type == IPC_EVENT_LOW_RSSI) { + LOGD("Low RSSI"); + } else { + LOGD("Dropping unhandled driver event %d", data->event_type); + } + + // TODO: Tell WifiController about the event +out: + free(data); + return true; +} diff --git a/nexus/TiwlanEventListener.h b/nexus/TiwlanEventListener.h new file mode 100644 index 000000000..052d6b1c7 --- /dev/null +++ b/nexus/TiwlanEventListener.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _TIWLAN_EVENT_LISTENER_H__ +#define _TIWLAN_EVENT_LISTENER_H__ + +#include + +struct wpa_ctrl; +class SocketClient; +class ITiwlanEventHandler; +class TiwlanEventFactory; + +class TiwlanEventListener: public SocketListener { + +public: + TiwlanEventListener(int sock); + virtual ~TiwlanEventListener() {} + +protected: + virtual bool onDataAvailable(SocketClient *c); +}; + +// TODO: Move all this crap into a factory +#define TI_DRIVER_MSG_PORT 9001 + +#define IPC_EVENT_LINK_SPEED 2 +#define IPC_EVENT_LOW_SNR 13 +#define IPC_EVENT_LOW_RSSI 14 + +struct ipc_ev_data { + uint32_t event_type; + void *event_id; + uint32_t process_id; + uint32_t delivery_type; + uint32_t user_param; + void *event_callback; + uint32_t bufferSize; + uint8_t buffer[2048]; +}; + +#endif diff --git a/nexus/TiwlanWifiController.cpp b/nexus/TiwlanWifiController.cpp index 6945e3ea2..61535c356 100644 --- a/nexus/TiwlanWifiController.cpp +++ b/nexus/TiwlanWifiController.cpp @@ -18,6 +18,9 @@ #include #include #include +#include +#include +#include #include #define LOG_TAG "TiwlanWifiController" @@ -25,6 +28,7 @@ #include "PropertyManager.h" #include "TiwlanWifiController.h" +#include "TiwlanEventListener.h" #define DRIVER_PROP_NAME "wlan.driver.status" @@ -36,6 +40,8 @@ TiwlanWifiController::TiwlanWifiController(PropertyManager *propmngr, char *modargs) : WifiController(propmngr, handlers, modpath, modname, modargs) { + mEventListener = NULL; + mListenerSock = -1; } int TiwlanWifiController::powerUp() { @@ -43,6 +49,13 @@ int TiwlanWifiController::powerUp() { } int TiwlanWifiController::powerDown() { + if (mEventListener) { + delete mEventListener; + close(mListenerSock); + mListenerSock = -1; + mEventListener = NULL; + } + return 0; // Powerdown is currently done when the driver is unloaded } @@ -60,17 +73,56 @@ int TiwlanWifiController::loadFirmware() { // Wait for driver to be ready while (count-- > 0) { if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) { - if (strcmp(driver_status, "ok") == 0) + if (!strcmp(driver_status, "ok")) { + LOGD("Firmware loaded OK"); + + if (startDriverEventListener()) { + LOGW("Failed to start driver event listener"); + } + return 0; - else if (strcmp(DRIVER_PROP_NAME, "failed") == 0) + } else if (!strcmp(DRIVER_PROP_NAME, "failed")) { + LOGE("Firmware load failed"); return -1; + } } usleep(200000); } property_set(DRIVER_PROP_NAME, "timeout"); + LOGE("Firmware load timed out"); return -1; } +int TiwlanWifiController::startDriverEventListener() { + struct sockaddr_in addr; + int s; + + if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + return -1; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(TI_DRIVER_MSG_PORT); + + if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + close(s); + return -1; + } + + mEventListener = new TiwlanEventListener(s); + + if (mEventListener->startListener()) { + LOGE("Error starting driver listener (%s)", strerror(errno)); + delete mEventListener; + mEventListener = NULL; + close(s); + return -1; + } + mListenerSock = s; + return 0; +} + bool TiwlanWifiController::isFirmwareLoaded() { // Always load the firmware return false; diff --git a/nexus/TiwlanWifiController.h b/nexus/TiwlanWifiController.h index 852a288b2..583be7170 100644 --- a/nexus/TiwlanWifiController.h +++ b/nexus/TiwlanWifiController.h @@ -21,8 +21,12 @@ #include "WifiController.h" class IControllerHandler; +class TiwlanEventListener; class TiwlanWifiController : public WifiController { + int mListenerSock; + TiwlanEventListener *mEventListener; + public: TiwlanWifiController(PropertyManager *propmngr, IControllerHandler *handlers, char *modpath, char *modname, char *modargs); virtual ~TiwlanWifiController() {} @@ -32,5 +36,8 @@ public: virtual bool isPoweredUp(); virtual int loadFirmware(); virtual bool isFirmwareLoaded(); + +private: + int startDriverEventListener(); }; #endif From 0f48658d2052560141448dc8f90adbbb0879bc0d Mon Sep 17 00:00:00 2001 From: San Mehat Date: Tue, 16 Jun 2009 10:50:47 -0700 Subject: [PATCH 02/11] nexus: Add some logging output to WifiController Signed-off-by: San Mehat --- nexus/WifiController.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nexus/WifiController.cpp b/nexus/WifiController.cpp index 5c5db1a1d..b7bd6edad 100644 --- a/nexus/WifiController.cpp +++ b/nexus/WifiController.cpp @@ -69,7 +69,9 @@ int WifiController::stop() { } int WifiController::enable() { + if (!isPoweredUp()) { + LOGI("Powering up"); sendStatusBroadcast("Powering up WiFi hardware"); if (powerUp()) { LOGE("Powerup failed (%s)", strerror(errno)); @@ -78,6 +80,7 @@ int WifiController::enable() { } if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) { + LOGI("Loading driver"); sendStatusBroadcast("Loading WiFi driver"); if (loadKernelModule(mModulePath, mModuleArgs)) { LOGE("Kernel module load failed (%s)", strerror(errno)); @@ -86,6 +89,7 @@ int WifiController::enable() { } if (!isFirmwareLoaded()) { + LOGI("Loading firmware"); sendStatusBroadcast("Loading WiFI firmware"); if (loadFirmware()) { LOGE("Firmware load failed (%s)", strerror(errno)); @@ -94,6 +98,7 @@ int WifiController::enable() { } if (!mSupplicant->isStarted()) { + LOGI("Starting WPA Supplicant"); sendStatusBroadcast("Starting WPA Supplicant"); if (mSupplicant->start()) { LOGE("Supplicant start failed (%s)", strerror(errno)); @@ -113,6 +118,7 @@ int WifiController::enable() { mPropMngr->registerProperty("wifi.scanmode", this); mPropMngr->registerProperty("wifi.interface", this); + LOGI("Enabled successfully"); return 0; out_unloadmodule: From bbe92c370a614316d6320e8030b266f20b4fee0e Mon Sep 17 00:00:00 2001 From: San Mehat Date: Tue, 16 Jun 2009 10:51:14 -0700 Subject: [PATCH 03/11] nexus: Initialize frequency in SupplicantAssociatingEvent constructor Signed-off-by: San Mehat --- nexus/SupplicantAssociatingEvent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/nexus/SupplicantAssociatingEvent.cpp b/nexus/SupplicantAssociatingEvent.cpp index 00a85b654..c6e9fe338 100644 --- a/nexus/SupplicantAssociatingEvent.cpp +++ b/nexus/SupplicantAssociatingEvent.cpp @@ -29,6 +29,7 @@ SupplicantAssociatingEvent::SupplicantAssociatingEvent(int level, char *event, mBssid = NULL; mSsid = NULL; + mFreq = -1; // SSID 'default' // OR From 891cb2c13505985532acb81d759841d86df15004 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Tue, 16 Jun 2009 10:51:39 -0700 Subject: [PATCH 04/11] nexus: Add TiwlanEventListener to makefile Signed-off-by: San Mehat --- nexus/Android.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nexus/Android.mk b/nexus/Android.mk index 6172e62f7..865f58a87 100644 --- a/nexus/Android.mk +++ b/nexus/Android.mk @@ -33,7 +33,8 @@ LOCAL_SRC_FILES:= \ SupplicantScanResultsEvent.cpp \ SupplicantConnectionTimeoutEvent.cpp \ SupplicantDisconnectedEvent.cpp \ - SupplicantStatus.cpp + SupplicantStatus.cpp \ + TiwlanEventListener.cpp LOCAL_MODULE:= nexus From 052403ebbe0c5ee37bd31c882325238f92110baa Mon Sep 17 00:00:00 2001 From: San Mehat Date: Tue, 16 Jun 2009 12:01:24 -0700 Subject: [PATCH 05/11] nexus: Less verbosity in TiwlanEventListener for now Signed-off-by: San Mehat --- nexus/TiwlanEventListener.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nexus/TiwlanEventListener.cpp b/nexus/TiwlanEventListener.cpp index 76e6ec110..15e693017 100644 --- a/nexus/TiwlanEventListener.cpp +++ b/nexus/TiwlanEventListener.cpp @@ -45,13 +45,13 @@ bool TiwlanEventListener::onDataAvailable(SocketClient *cli) { if (data->event_type == IPC_EVENT_LINK_SPEED) { uint32_t *spd = (uint32_t *) data->buffer; *spd /= 2; - LOGD("Link speed = %u MB/s", *spd); +// LOGD("Link speed = %u MB/s", *spd); } else if (data->event_type == IPC_EVENT_LOW_SNR) { - LOGD("Low signal/noise ratio"); + LOGW("Low signal/noise ratio"); } else if (data->event_type == IPC_EVENT_LOW_RSSI) { - LOGD("Low RSSI"); + LOGW("Low RSSI"); } else { - LOGD("Dropping unhandled driver event %d", data->event_type); +// LOGD("Dropping unhandled driver event %d", data->event_type); } // TODO: Tell WifiController about the event From d0290eadc563f5a34fc1969f91621860d8756eff Mon Sep 17 00:00:00 2001 From: San Mehat Date: Tue, 16 Jun 2009 12:01:50 -0700 Subject: [PATCH 06/11] nexus: Fix SupplicantStatus decoding Signed-off-by: San Mehat --- nexus/SupplicantStatus.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/nexus/SupplicantStatus.cpp b/nexus/SupplicantStatus.cpp index 87f6c98dc..b3c560a81 100644 --- a/nexus/SupplicantStatus.cpp +++ b/nexus/SupplicantStatus.cpp @@ -17,7 +17,7 @@ #include #include -#define LOG_TAG "SupplicantState" +#define LOG_TAG "SupplicantStatus" #include #include "SupplicantStatus.h" @@ -52,18 +52,37 @@ SupplicantStatus *SupplicantStatus::createStatus(char *data, int len) { char *next = data; char *line; while((line = strsep(&next, "\n"))) { - char *token = strsep(&next, "="); - char *value = strsep(&next, "="); - + char *line_next = line; + char *token = strsep(&line_next, "="); + char *value = strsep(&line_next, "="); if (!strcmp(token, "bssid")) bssid = strdup(value); else if (!strcmp(token, "ssid")) ssid = strdup(value); else if (!strcmp(token, "id")) id = atoi(value); - else if (!strcmp(token, "wpa_state")) - state = atoi(value); - else + else if (!strcmp(token, "wpa_state")) { + if (!strcmp(value, "DISCONNECTED")) + state = SupplicantState::DISCONNECTED; + else if (!strcmp(value, "INACTIVE")) + state = SupplicantState::INACTIVE; + else if (!strcmp(value, "SCANNING")) + state = SupplicantState::SCANNING; + else if (!strcmp(value, "ASSOCIATING")) + state = SupplicantState::ASSOCIATING; + else if (!strcmp(value, "ASSOCIATED")) + state = SupplicantState::ASSOCIATED; + else if (!strcmp(value, "FOURWAY_HANDSHAKE")) + state = SupplicantState::FOURWAY_HANDSHAKE; + else if (!strcmp(value, "GROUP_HANDSHAKE")) + state = SupplicantState::GROUP_HANDSHAKE; + else if (!strcmp(value, "COMPLETED")) + state = SupplicantState::COMPLETED; + else if (!strcmp(value, "IDLE")) + state = SupplicantState::IDLE; + else + LOGE("Unknown supplicant state '%s'", value); + } else LOGD("Ignoring unsupported status token '%s'", token); } From 287c71ca84533da008e9cc240224910a9d05139e Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Tue, 16 Jun 2009 17:36:04 -0700 Subject: [PATCH 07/11] fix decompression bug in fastboot fastboot passes the *uncompressed* length of the file as the length of the input to the inflate() call, which happens to work unless the compressed data is actually larger than the uncompressed data (which it can be for very small files). Fix this to pass the correct compressed length down to the inflate call. --- libzipfile/centraldir.c | 15 ++++++--------- libzipfile/zipfile.c | 8 ++++---- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/libzipfile/centraldir.c b/libzipfile/centraldir.c index 4387cebaa..0391c0995 100644 --- a/libzipfile/centraldir.c +++ b/libzipfile/centraldir.c @@ -13,7 +13,7 @@ enum { // central directory entries ENTRY_SIGNATURE = 0x02014b50, ENTRY_LEN = 46, // CentralDirEnt len, excl. var fields - + // local file header LFH_SIZE = 30, }; @@ -73,8 +73,6 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry, unsigned short lastModFileTime; unsigned short lastModFileDate; unsigned long crc32; - unsigned long compressedSize; - unsigned long uncompressedSize; unsigned short extraFieldLength; unsigned short fileCommentLength; unsigned short diskNumberStart; @@ -85,7 +83,7 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry, const unsigned char* fileComment; unsigned int dataOffset; unsigned short lfhExtraFieldSize; - + p = *buf; @@ -106,7 +104,7 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry, lastModFileTime = read_le_short(&p[0x0c]); lastModFileDate = read_le_short(&p[0x0e]); crc32 = read_le_int(&p[0x10]); - compressedSize = read_le_int(&p[0x14]); + entry->compressedSize = read_le_int(&p[0x14]); entry->uncompressedSize = read_le_int(&p[0x18]); entry->fileNameLength = read_le_short(&p[0x1c]); extraFieldLength = read_le_short(&p[0x1e]); @@ -141,14 +139,14 @@ read_central_directory_entry(Zipfile* file, Zipentry* entry, fileComment = NULL; } p += fileCommentLength; - + *buf = p; // the size of the extraField in the central dir is how much data there is, // but the one in the local file header also contains some padding. p = file->buf + localHeaderRelOffset; extraFieldLength = read_le_short(&p[0x1c]); - + dataOffset = localHeaderRelOffset + LFH_SIZE + entry->fileNameLength + extraFieldLength; entry->data = file->buf + dataOffset; @@ -243,7 +241,7 @@ read_central_dir(Zipfile *file) free(entry); goto bail; } - + // add it to our list entry->next = file->entries; file->entries = entry; @@ -253,4 +251,3 @@ read_central_dir(Zipfile *file) bail: return -1; } - diff --git a/libzipfile/zipfile.c b/libzipfile/zipfile.c index b52d02df7..a401a9b16 100644 --- a/libzipfile/zipfile.c +++ b/libzipfile/zipfile.c @@ -82,13 +82,13 @@ uninflate(unsigned char* out, int unlen, const unsigned char* in, int clen) unsigned long crc; int err = 0; int zerr; - + memset(&zstream, 0, sizeof(zstream)); zstream.zalloc = Z_NULL; zstream.zfree = Z_NULL; zstream.opaque = Z_NULL; zstream.next_in = (void*)in; - zstream.avail_in = unlen; + zstream.avail_in = clen; zstream.next_out = (Bytef*) out; zstream.avail_out = unlen; zstream.data_type = Z_UNKNOWN; @@ -99,7 +99,7 @@ uninflate(unsigned char* out, int unlen, const unsigned char* in, int clen) if (zerr != Z_OK) { return -1; } - + // uncompress the data zerr = inflate(&zstream, Z_FINISH); if (zerr != Z_STREAM_END) { @@ -107,7 +107,7 @@ uninflate(unsigned char* out, int unlen, const unsigned char* in, int clen) zstream.total_out); err = -1; } - + inflateEnd(&zstream); return err; } From bfa2f8e9b506a4b710ebcefa7c1e324609b8ca34 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Tue, 16 Jun 2009 17:23:22 -0700 Subject: [PATCH 08/11] init: Bump up the max cpu bandwidth shares ratio for background. New ratio is 1024/16 (1.5625% for background when cpu is under load) Signed-off-by: San Mehat --- rootdir/init.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootdir/init.rc b/rootdir/init.rc index 2e00c7110..3fe4c258b 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -50,7 +50,7 @@ loglevel 3 mkdir /dev/cpuctl/bg_non_interactive chown system system /dev/cpuctl/bg_non_interactive/tasks chmod 0777 /dev/cpuctl/bg_non_interactive/tasks - write /dev/cpuctl/bg_non_interactive/cpu.shares 1 + write /dev/cpuctl/bg_non_interactive/cpu.shares 16 # mount mtd partitions # Mount /system rw first to give the filesystem a chance to save a checkpoint From 422972cb127c229a38e79bb5d2d8df44aebeeeea Mon Sep 17 00:00:00 2001 From: -b master Date: Wed, 17 Jun 2009 19:13:52 -0700 Subject: [PATCH 09/11] Align ARM stack pointer to an 8-byte boundary when calling functions. This is required by the ARM EABI standard. --- libacc/acc.cpp | 77 ++++++++++++++++++++++++++++++++++--------- libacc/tests/main.cpp | 9 +++++ 2 files changed, 70 insertions(+), 16 deletions(-) diff --git a/libacc/acc.cpp b/libacc/acc.cpp index 7d14e3fdf..fdddf2205 100644 --- a/libacc/acc.cpp +++ b/libacc/acc.cpp @@ -46,8 +46,11 @@ #define LOG_API(...) do {} while(0) // #define LOG_API(...) fprintf (stderr, __VA_ARGS__) -// #define ENABLE_ARM_DISASSEMBLY +#define LOG_STACK(...) do {} while(0) +// #define LOG_STACK(...) fprintf (stderr, __VA_ARGS__) + +// #define ENABLE_ARM_DISASSEMBLY // #define PROVIDE_TRACE_CODEGEN namespace acc { @@ -399,27 +402,38 @@ class Compiler : public ErrorSink { class ARMCodeGenerator : public CodeGenerator { public: ARMCodeGenerator() {} + virtual ~ARMCodeGenerator() {} /* returns address to patch with local variable size */ virtual int functionEntry(int argCount) { LOG_API("functionEntry(%d);\n", argCount); + mStackUse = 0; // sp -> arg4 arg5 ... // Push our register-based arguments back on the stack if (argCount > 0) { int regArgCount = argCount <= 4 ? argCount : 4; o4(0xE92D0000 | ((1 << argCount) - 1)); // stmfd sp!, {} + mStackUse += regArgCount * 4; } // sp -> arg0 arg1 ... o4(0xE92D4800); // stmfd sp!, {fp, lr} + mStackUse += 2 * 4; // sp, fp -> oldfp, retadr, arg0 arg1 .... o4(0xE1A0B00D); // mov fp, sp + LOG_STACK("functionEntry: %d\n", mStackUse); return o4(0xE24DD000); // sub sp, sp, # + // We don't know how many local variables we are going to use, + // but we will round the allocation up to a multiple of + // STACK_ALIGNMENT, so it won't affect the stack alignment. } virtual void functionExit(int argCount, int localVariableAddress, int localVariableSize) { LOG_API("functionExit(%d, %d, %d);\n", argCount, localVariableAddress, localVariableSize); + // Round local variable size up to a multiple of stack alignment + localVariableSize = ((localVariableSize + STACK_ALIGNMENT - 1) / + STACK_ALIGNMENT) * STACK_ALIGNMENT; // Patch local variable allocation code: if (localVariableSize < 0 || localVariableSize > 255) { error("localVariables out of range: %d", localVariableSize); @@ -547,11 +561,6 @@ class Compiler : public ErrorSink { error("Unimplemented op %d\n", op); break; } -#if 0 - o(decodeOp(op)); - if (op == OP_MOD) - o(0x92); /* xchg %edx, %eax */ -#endif } virtual void clearR1() { @@ -562,11 +571,15 @@ class Compiler : public ErrorSink { virtual void pushR0() { LOG_API("pushR0();\n"); o4(0xE92D0001); // stmfd sp!,{r0} + mStackUse += 4; + LOG_STACK("pushR0: %d\n", mStackUse); } virtual void popR1() { LOG_API("popR1();\n"); o4(0xE8BD0002); // ldmfd sp!,{r1} + mStackUse -= 4; + LOG_STACK("popR1: %d\n", mStackUse); } virtual void storeR0ToR1(bool isInt) { @@ -690,15 +703,31 @@ class Compiler : public ErrorSink { virtual void endFunctionCallArguments(int a, int l) { LOG_API("endFunctionCallArguments(0x%08x, %d);\n", a, l); + int argCount = l >> 2; + int argumentStackUse = l; + if (argCount > 0) { + int regArgCount = argCount > 4 ? 4 : argCount; + argumentStackUse -= regArgCount * 4; + o4(0xE8BD0000 | ((1 << regArgCount) - 1)); // ldmfd sp!,{} + } + mStackUse += argumentStackUse; + + // Align stack. + int missalignment = mStackUse - ((mStackUse / STACK_ALIGNMENT) + * STACK_ALIGNMENT); + mStackAlignmentAdjustment = 0; + if (missalignment > 0) { + mStackAlignmentAdjustment = STACK_ALIGNMENT - missalignment; + } + l += mStackAlignmentAdjustment; + if (l < 0 || l > 0x3FC) { error("L out of range for stack adjustment: 0x%08x", l); } * (int*) a = 0xE24DDF00 | (l >> 2); // sub sp, sp, #0 << 2 - int argCount = l >> 2; - if (argCount > 0) { - int regArgCount = argCount > 4 ? 4 : argCount; - o4(0xE8BD0000 | ((1 << regArgCount) - 1)); // ldmfd sp!,{} - } + mStackUse += mStackAlignmentAdjustment; + LOG_STACK("endFunctionCallArguments mStackUse: %d, mStackAlignmentAdjustment %d\n", + mStackUse, mStackAlignmentAdjustment); } virtual int callForward(int symbol) { @@ -727,7 +756,7 @@ class Compiler : public ErrorSink { LOG_API("callIndirect(%d);\n", l); int argCount = l >> 2; int poppedArgs = argCount > 4 ? 4 : argCount; - int adjustedL = l - (poppedArgs << 2); + int adjustedL = l - (poppedArgs << 2) + mStackAlignmentAdjustment; if (adjustedL < 0 || adjustedL > 4096-4) { error("l out of range for stack offset: 0x%08x", l); } @@ -739,12 +768,15 @@ class Compiler : public ErrorSink { LOG_API("adjustStackAfterCall(%d, %d);\n", l, isIndirect); int argCount = l >> 2; int stackArgs = argCount > 4 ? argCount - 4 : 0; - int stackUse = stackArgs + (isIndirect ? 1 : 0); + int stackUse = stackArgs + (isIndirect ? 1 : 0) + + (mStackAlignmentAdjustment >> 2); if (stackUse) { if (stackUse < 0 || stackUse > 255) { error("L out of range for stack adjustment: 0x%08x", l); } o4(0xE28DDF00 | stackUse); // add sp, sp, #stackUse << 2 + mStackUse -= stackUse * 4; + LOG_STACK("adjustStackAfterCall: %d\n", mStackUse); } } @@ -858,6 +890,13 @@ class Compiler : public ErrorSink { static int runtime_MOD(int a, int b) { return b % a; } + + static const int STACK_ALIGNMENT = 8; + int mStackUse; + // This variable holds the amount we adjusted the stack in the most + // recent endFunctionCallArguments call. It's examined by the + // following adjustStackAfterCall call. + int mStackAlignmentAdjustment; }; #endif // PROVIDE_ARM_CODEGEN @@ -981,7 +1020,9 @@ class Compiler : public ErrorSink { if (isIndirect) { l += 4; } - oad(0xc481, l); /* add $xxx, %esp */ + if (l > 0) { + oad(0xc481, l); /* add $xxx, %esp */ + } } virtual int jumpOffset() { @@ -2315,8 +2356,7 @@ class Compiler : public ErrorSink { } else { pGen->callRelative(n - codeBuf.getPC() - pGen->jumpOffset()); } - if (l | (n == 1)) - pGen->adjustStackAfterCall(l, n == 1); + pGen->adjustStackAfterCall(l, n == 1); } } @@ -3025,6 +3065,11 @@ void accGetPragmas(ACCscript* script, ACCsizei* actualStringCount, script->compiler.getPragmas(actualStringCount, maxStringCount, strings); } +extern "C" +void accDisassemble(ACCscript* script) { + script->compiler.disassemble(stderr); +} + } // namespace acc diff --git a/libacc/tests/main.cpp b/libacc/tests/main.cpp index 4f8a65de8..13a30d42f 100644 --- a/libacc/tests/main.cpp +++ b/libacc/tests/main.cpp @@ -29,6 +29,11 @@ int run(MainPtr mainFunc, int argc, char** argv) { return mainFunc(argc, argv); } +// Private API for development: + +extern "C" +void accDisassemble(ACCscript* script); + int main(int argc, char** argv) { const char* inFile = NULL; bool printListing; @@ -109,6 +114,10 @@ int main(int argc, char** argv) { } } + if (printListing) { + accDisassemble(script); + } + if (runResults) { accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer); From 9d0d888179e9d896e5b9ef0378b89143964025d7 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 17 Jun 2009 14:38:28 -0700 Subject: [PATCH 10/11] add kernel event logging tags for more gtalk/mcs logging (heartbeat resets and connection closed events) --- logcat/event-log-tags | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/logcat/event-log-tags b/logcat/event-log-tags index 13f74882a..8b49fa83d 100644 --- a/logcat/event-log-tags +++ b/logcat/event-log-tags @@ -94,7 +94,7 @@ 2800 gtalkservice (eventType|1) # This event is logged for GTalk connection state changes. The status field is an int, but # it really contains 4 separate values, each taking up a byte -# (eventType, connection state, connection error, network state) +# (eventType << 24) + (connection state << 16) + (connection error << 8) + network state 2801 gtalk_connection (status|1) 2802 watchdog (Service|3) @@ -135,6 +135,26 @@ 3100 boot_progress_pms_ready (time|2|3) # + check activity_launch_time for Home app +# This event is logged when GTalk connection is closed. +# The status field is an int, but contains 2 different values, it's represented as +# +# (networkType << 8) + connection error +# +# the possible error values are +# +# no_error=0, no_network=1, connection_failed=2, unknown_host=3, auth_failed=4, +# auth_expired=5, heart_beat_timeout=6, server_error=7, server_reject_rate_limiting=8, unknown=10 +# +# duration is the connection duration. +4000 gtalk_conn_close (status|1),(duration|1) + +# This event is logged for GTalk heartbeat resets +# interval_and_nt contains both the heartbeat interval and the network type, It's represented as +# (networkType << 16) + interval +# interval is in seconds; network type can be 0 (mobile) or 1 (wifi); ip is the host ip addr. +4001 gtalk_heartbeat_reset (interval_and_nt|1),(ip|3) + + # Do not change these names without updating the checkin_events setting in # google3/googledata/wireless/android/provisioning/gservices.config !! # From 1ccef18e69acdc4276a6c4a0c449ced6be395fc3 Mon Sep 17 00:00:00 2001 From: Masaki Sato Date: Fri, 29 May 2009 17:18:01 -0500 Subject: [PATCH 11/11] Change permissions on sound devices. --- init/devices.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/init/devices.c b/init/devices.c index 04ada6358..880536c4a 100644 --- a/init/devices.c +++ b/init/devices.c @@ -126,6 +126,9 @@ static struct perms_ devperms[] = { { "/dev/msm_mp3", 0660, AID_SYSTEM, AID_AUDIO, 1 }, { "/dev/msm_audpre", 0660, AID_SYSTEM, AID_AUDIO, 0 }, { "/dev/htc-acoustic", 0660, AID_SYSTEM, AID_AUDIO, 0 }, + { "/dev/snd/dsp", 0660, AID_SYSTEM, AID_AUDIO, 0 }, + { "/dev/snd/dsp1", 0660, AID_SYSTEM, AID_AUDIO, 0 }, + { "/dev/snd/mixer", 0660, AID_SYSTEM, AID_AUDIO, 0 }, { "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qemu_trace", 0666, AID_SYSTEM, AID_SYSTEM, 0 }, { "/dev/qmi", 0640, AID_RADIO, AID_RADIO, 0 },