wifi_drv: transition to the new base API

Issue #1987.
This commit is contained in:
Josef Söntgen 2016-06-23 13:34:47 +02:00 committed by Christian Helmuth
parent c8fe0df0ed
commit edf90aec42
10 changed files with 194 additions and 161 deletions

View File

@ -20,7 +20,7 @@ SRC_CC += dummies.cc init.cc lxcc_emul.cc nic.cc socket_call.cc
# lx_kit # lx_kit
CC_OPT += -DUSE_INTERNAL_SETJMP CC_OPT += -DUSE_INTERNAL_SETJMP
SRC_CC += mapped_io_mem_range.cc irq.cc pci.cc malloc.cc scheduler.cc \ SRC_CC += mapped_io_mem_range.cc irq.cc pci.cc malloc.cc scheduler.cc \
work.cc timer.cc printf.cc work.cc timer.cc printf.cc env.cc
SRC_S += setjmp.S SRC_S += setjmp.S
SRC_C += lxc_emul.c SRC_C += lxc_emul.c

View File

@ -5,18 +5,18 @@
*/ */
/* /*
* Copyright (C) 2014 Genode Labs GmbH * Copyright (C) 2014-2016 Genode Labs GmbH
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
*/ */
/* Genode includes */ /* Genode includes */
#include <base/env.h> #include <base/component.h>
#include <base/heap.h>
#include <base/log.h>
#include <base/sleep.h> #include <base/sleep.h>
#include <os/attached_rom_dataspace.h> #include <os/attached_rom_dataspace.h>
#include <os/config.h>
#include <os/server.h>
#include <util/xml_node.h> #include <util/xml_node.h>
#include <util/string.h> #include <util/string.h>
@ -25,12 +25,10 @@
typedef long long ssize_t; typedef long long ssize_t;
extern void wifi_init(Server::Entrypoint &, Genode::Lock &); extern void wifi_init(Genode::Env&, Genode::Lock&);
extern "C" void wpa_conf_reload(void); extern "C" void wpa_conf_reload(void);
extern "C" ssize_t wpa_write_conf(char const *, Genode::size_t); extern "C" ssize_t wpa_write_conf(char const *, Genode::size_t);
bool config_verbose = false;
static Genode::Lock &wpa_startup_lock() static Genode::Lock &wpa_startup_lock()
{ {
static Genode::Lock _l(Genode::Lock::LOCKED); static Genode::Lock _l(Genode::Lock::LOCKED);
@ -70,7 +68,7 @@ namespace {
/** /**
* Generate wpa_supplicant.conf file * Generate wpa_supplicant.conf file
*/ */
static int generate_wpa_supplicant_conf(char const **p, Genode::size_t *len, char const *ssid, static int generatewpa_supplicant_conf(char const **p, Genode::size_t *len, char const *ssid,
char const *bssid, bool protection = false, char const *psk = 0) char const *bssid, bool protection = false, char const *psk = 0)
{ {
static char const *start_fmt = "network={\n\tscan_ssid=1\n"; static char const *start_fmt = "network={\n\tscan_ssid=1\n";
@ -107,9 +105,9 @@ static int generate_wpa_supplicant_conf(char const **p, Genode::size_t *len, cha
struct Wlan_configration struct Wlan_configration
{ {
Genode::Attached_rom_dataspace config_rom { "wlan_configuration" }; Genode::Attached_rom_dataspace config_rom { "wlan_configuration" };
Genode::Signal_rpc_member<Wlan_configration> dispatcher; Genode::Signal_handler<Wlan_configration> dispatcher;
Genode::Lock update_lock; Genode::Lock update_lock;
char const *buffer; char const *buffer;
Genode::size_t size; Genode::size_t size;
@ -120,7 +118,7 @@ struct Wlan_configration
void _activate_configuration() void _activate_configuration()
{ {
if (wpa_write_conf(buffer, size) == 0) { if (wpa_write_conf(buffer, size) == 0) {
PINF("reload wpa_supplicant configuration"); Genode::log("Reload wpa_supplicant configuration");
wpa_conf_reload(); wpa_conf_reload();
} }
} }
@ -131,7 +129,7 @@ struct Wlan_configration
*/ */
void _active_dummy_configuration() void _active_dummy_configuration()
{ {
generate_wpa_supplicant_conf(&buffer, &size, "dummyssid", "00:00:00:00:00:00"); generatewpa_supplicant_conf(&buffer, &size, "dummyssid", "00:00:00:00:00:00");
_activate_configuration(); _activate_configuration();
} }
@ -197,20 +195,20 @@ struct Wlan_configration
/* psk must be between 8 and 63 characters long */ /* psk must be between 8 and 63 characters long */
if (use_protection && (psk.length() < MIN_PSK_LENGTH)) { if (use_protection && (psk.length() < MIN_PSK_LENGTH)) {
PERR("error: given psk is too short"); Genode::error("given pre-shared key is too short");
_active_dummy_configuration(); _active_dummy_configuration();
return; return;
} }
if (generate_wpa_supplicant_conf(&buffer, &size, ssid.string(), if (generatewpa_supplicant_conf(&buffer, &size, ssid.string(),
use_bssid ? bssid.string() : 0, use_bssid ? bssid.string() : 0,
use_protection, psk.string()) == 0) use_protection, psk.string()) == 0)
_activate_configuration(); _activate_configuration();
} }
void _handle_update(unsigned) { _update_configuration(); } void _handle_update() { _update_configuration(); }
Wlan_configration(Server::Entrypoint &ep) Wlan_configration(Genode::Entrypoint &ep)
: :
dispatcher(ep, *this, &Wlan_configration::_handle_update) dispatcher(ep, *this, &Wlan_configration::_handle_update)
{ {
@ -222,33 +220,34 @@ struct Wlan_configration
struct Main struct Main
{ {
Server::Entrypoint &_ep; Genode::Env &env;
Wpa_thread *_wpa; Genode::Heap heap { env.ram(), env.rm() };
Wlan_configration *_wc; Genode::Attached_rom_dataspace config_rom { env, "config" };
Main(Server::Entrypoint &ep) Wpa_thread *wpa;
: Wlan_configration *wlan_config;
_ep(ep)
Main(Genode::Env &env) : env(env)
{ {
Genode::Xml_node config = Genode::config()->xml_node(); bool const verbose = config_rom.xml().attribute_value("verbose", false);
config_verbose = config.attribute_value("verbose", config_verbose);
_wpa = new (Genode::env()->heap()) Wpa_thread(wpa_startup_lock(), config_verbose); wpa = new (&heap) Wpa_thread(env, wpa_startup_lock(), verbose);
_wpa->start(); wpa->start();
try { try {
_wc = new (Genode::env()->heap()) Wlan_configration(_ep); wlan_config = new (&heap) Wlan_configration(env.ep());
} catch (...) { PWRN("could not create wlan_configration handler"); } } catch (...) {
Genode::warning("could not create Wlan_configration handler");
}
wifi_init(ep, wpa_startup_lock()); wifi_init(env, wpa_startup_lock());
} }
}; };
namespace Server { namespace Component {
char const *name() { return "wifi_drv_ep"; } Genode::size_t stack_size() { return 32 * 1024 * sizeof(long); }
size_t stack_size() { return 32 * 1024 * sizeof(long); } void construct(Genode::Env &env) { static Main server(env); }
void construct(Entrypoint &ep) { static Main server(ep); }
} }

View File

@ -2,7 +2,7 @@ REQUIRES = x86
TARGET = wifi_drv TARGET = wifi_drv
SRC_CC = main.cc SRC_CC = main.cc
LIBS = wifi iwl_firmware wpa_supplicant server LIBS = wifi iwl_firmware wpa_supplicant
# needed for firmware.h # needed for firmware.h
INC_DIR += $(REP_DIR)/src/lib/wifi/include INC_DIR += $(REP_DIR)/src/lib/wifi/include

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (C) 2014 Genode Labs GmbH * Copyright (C) 2014-2016 Genode Labs GmbH
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
@ -21,7 +21,7 @@
extern "C" int wpa_main(int); extern "C" int wpa_main(int);
extern "C" void wpa_conf_reload(void); extern "C" void wpa_conf_reload(void);
class Wpa_thread : public Genode::Thread_deprecated<8 * 1024 * sizeof(long)> class Wpa_thread : public Genode::Thread
{ {
private: private:
@ -31,9 +31,9 @@ class Wpa_thread : public Genode::Thread_deprecated<8 * 1024 * sizeof(long)>
public: public:
Wpa_thread(Genode::Lock &lock, bool debug_msg) Wpa_thread(Genode::Env &env, Genode::Lock &lock, bool debug_msg)
: :
Thread_deprecated("wpa_supplicant"), Thread(env, "wpa_supplicant", 8*1024*sizeof(long)),
_lock(lock), _exit(-1), _debug_msg(debug_msg) { } _lock(lock), _exit(-1), _debug_msg(debug_msg) { }
void entry() void entry()

View File

@ -11,6 +11,8 @@
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
*/ */
/* Genode includes */
#include <base/log.h>
#include <base/printf.h> #include <base/printf.h>
#include <base/sleep.h> #include <base/sleep.h>
@ -18,7 +20,7 @@ extern "C" {
typedef long DUMMY; typedef long DUMMY;
enum { enum {
SHOW_DUMMY = 1, SHOW_DUMMY = 0,
SHOW_SKIP = 0, SHOW_SKIP = 0,
SHOW_RET = 0, SHOW_RET = 0,
}; };
@ -33,14 +35,14 @@ enum {
#define DUMMY_SKIP(retval, name) \ #define DUMMY_SKIP(retval, name) \
DUMMY name(void) { \ DUMMY name(void) { \
if (SHOW_SKIP) \ if (SHOW_SKIP) \
PLOG( #name " called (from %p) skipped", __builtin_return_address(0)); \ Genode::log( #name " called (from ", __builtin_return_address(0), ") skipped"); \
return retval; \ return retval; \
} }
#define DUMMY_STOP(retval, name) \ #define DUMMY_STOP(retval, name) \
DUMMY name(void) { \ DUMMY name(void) { \
do { \ do { \
PWRN( #name " called (from %p) stopped", __builtin_return_address(0)); \ Genode::warning( #name " called (from ", __builtin_return_address(0), ") stopped"); \
Genode::sleep_forever(); \ Genode::sleep_forever(); \
} while (0); \ } while (0); \
return retval; \ return retval; \
@ -49,7 +51,8 @@ enum {
#define DUMMY_RET(retval, name) \ #define DUMMY_RET(retval, name) \
DUMMY name(void) { \ DUMMY name(void) { \
if (SHOW_RET) \ if (SHOW_RET) \
PWRN( #name " called (from %p) return %d", __builtin_return_address(0), retval); \ Genode::warning( #name " called (from ", __builtin_return_address(0), ") return ", \
retval); \
return retval; \ return retval; \
} }

View File

@ -12,8 +12,8 @@
*/ */
/* Genode includes */ /* Genode includes */
#include <os/config.h> #include <base/env.h>
#include <os/server.h> #include <base/lock.h>
/* local includes */ /* local includes */
#include <firmware_list.h> #include <firmware_list.h>
@ -21,6 +21,7 @@
#include <lx_emul.h> #include <lx_emul.h>
#include <lx_kit/env.h>
#include <lx_kit/irq.h> #include <lx_kit/irq.h>
#include <lx_kit/work.h> #include <lx_kit/work.h>
#include <lx_kit/timer.h> #include <lx_kit/timer.h>
@ -45,8 +46,6 @@ extern "C" void module_krng_mod_init(void);
struct workqueue_struct *system_power_efficient_wq; struct workqueue_struct *system_power_efficient_wq;
struct workqueue_struct *system_wq; struct workqueue_struct *system_wq;
static bool mac80211_only = false;
struct pernet_operations loopback_net_ops; struct pernet_operations loopback_net_ops;
struct net init_net; struct net init_net;
@ -100,8 +99,8 @@ static Genode::Lock *_wpa_lock;
static void run_linux(void *) static void run_linux(void *)
{ {
system_power_efficient_wq = alloc_workqueue("system_power_efficient_wq", 0, 0); system_power_efficient_wq = alloc_workqueue("system_power_efficient_wq", 0, 0);
system_wq = alloc_workqueue("system_wq", 0, 0); system_wq = alloc_workqueue("system_wq", 0, 0);
core_sock_init(); core_sock_init();
core_netlink_proto_init(); core_netlink_proto_init();
@ -117,11 +116,8 @@ static void run_linux(void *)
module_aes_init(); module_aes_init();
module_arc4_init(); module_arc4_init();
module_chainiv_module_init(); module_chainiv_module_init();
// module_krng_mod_init();
if (!mac80211_only) { module_iwl_drv_init();
module_iwl_drv_init();
}
_wpa_lock->unlock(); _wpa_lock->unlock();
@ -133,15 +129,9 @@ static void run_linux(void *)
unsigned long jiffies; unsigned long jiffies;
void wifi_init(Server::Entrypoint &ep, Genode::Lock &lock) void wifi_init(Genode::Env &env, Genode::Lock &lock)
{ {
/** Lx_kit::construct_env(env);
* For testing testing only the wireless stack with wpa_supplicant,
* amongst other on linux, we do not want to load the iwlwifi drivers.
*/
mac80211_only = Genode::config()->xml_node().attribute_value("mac80211_only", mac80211_only);
if (mac80211_only)
PINF("Initalizing only mac80211 stack without any driver!");
_wpa_lock = &lock; _wpa_lock = &lock;
@ -151,13 +141,13 @@ void wifi_init(Server::Entrypoint &ep, Genode::Lock &lock)
Lx::scheduler(); Lx::scheduler();
Lx::timer(&ep, &jiffies); Lx::timer(&env.ep(), &jiffies);
Lx::Irq::irq(&ep, Genode::env()->heap()); Lx::Irq::irq(&env.ep(), &Lx_kit::env().heap());
Lx::Work::work_queue(Genode::env()->heap()); Lx::Work::work_queue(&Lx_kit::env().heap());
Lx::socket_init(ep); Lx::socket_init(env.ep(), Lx_kit::env().heap());
Lx::nic_init(ep); Lx::nic_init(env, Lx_kit::env().heap());
/* Linux task (handles the initialization only currently) */ /* Linux task (handles the initialization only currently) */
static Lx::Task linux(run_linux, nullptr, "linux", static Lx::Task linux(run_linux, nullptr, "linux",

View File

@ -28,9 +28,11 @@
namespace Lx namespace Lx
{ {
void socket_init(Server::Entrypoint &); void emul_init(Genode::Env&, Genode::Allocator&);
void nic_init(Server::Entrypoint &); void socket_init(Genode::Entrypoint&, Genode::Allocator&);
void nic_init(Genode::Env&, Genode::Allocator&);
Genode::Ram_dataspace_capability backend_alloc(Genode::addr_t, Genode::Cache_attribute); Genode::Ram_dataspace_capability backend_alloc(Genode::addr_t, Genode::Cache_attribute);
void backend_free(Genode::Ram_dataspace_capability); void backend_free(Genode::Ram_dataspace_capability);

View File

@ -12,9 +12,9 @@
*/ */
/* Genode includes */ /* Genode includes */
#include <base/env.h>
#include <base/allocator_avl.h> #include <base/allocator_avl.h>
#include <base/printf.h> #include <base/env.h>
#include <base/log.h>
#include <base/snprintf.h> #include <base/snprintf.h>
#include <base/sleep.h> #include <base/sleep.h>
#include <dataspace/client.h> #include <dataspace/client.h>
@ -28,17 +28,16 @@
#include <lx.h> #include <lx.h>
#include <lx_emul.h> #include <lx_emul.h>
#include <lx_kit/env.h>
#include <lx_kit/malloc.h> #include <lx_kit/malloc.h>
#include <lx_kit/scheduler.h> #include <lx_kit/scheduler.h>
static bool const verbose = false;
#define PWRNV(...) do { if (verbose) PWRN(__VA_ARGS__); } while (0)
typedef Genode::size_t size_t; typedef Genode::size_t size_t;
typedef Genode::addr_t addr_t; typedef Genode::addr_t addr_t;
/******************** /********************
** linux/string.h ** ** linux/string.h **
********************/ ********************/
@ -404,8 +403,10 @@ void *vmalloc(unsigned long size)
{ {
size_t real_size = size + sizeof(size_t); size_t real_size = size + sizeof(size_t);
size_t *addr; size_t *addr;
try { addr = (size_t *)Genode::env()->heap()->alloc(real_size); }
catch (...) { return 0; } if (!Lx_kit::env().heap().alloc(real_size, (void**)&addr)) {
return nullptr;
}
*addr = real_size; *addr = real_size;
return addr + 1; return addr + 1;
@ -417,7 +418,7 @@ void vfree(const void *addr)
if (!addr) return; if (!addr) return;
size_t size = *(((size_t *)addr) - 1); size_t size = *(((size_t *)addr) - 1);
Genode::env()->heap()->free(const_cast<void *>(addr), size); Lx_kit::env().heap().free(const_cast<void *>(addr), size);
} }
@ -494,7 +495,7 @@ class Driver : public Genode::List<Driver>::Element
int driver_register(struct device_driver *drv) int driver_register(struct device_driver *drv)
{ {
new (Genode::env()->heap()) Driver(drv); new (&Lx_kit::env().heap()) Driver(drv);
return 0; return 0;
} }
@ -577,12 +578,16 @@ int strict_strtoul(const char *s, unsigned int base, unsigned long *res)
** linux/delay.h ** ** linux/delay.h **
*******************/ *******************/
static Timer::Connection _timer; static Timer::Connection &timer_for_msleep()
{
static Timer::Connection inst(Lx_kit::env().env());
return inst;
}
void udelay(unsigned long usecs) void udelay(unsigned long usecs)
{ {
_timer.usleep(usecs); timer_for_msleep().usleep(usecs);
Lx::scheduler().current()->schedule(); Lx::scheduler().current()->schedule();
} }
@ -590,7 +595,7 @@ void udelay(unsigned long usecs)
void usleep_range(unsigned long min, unsigned long max) void usleep_range(unsigned long min, unsigned long max)
{ {
_timer.usleep(min); timer_for_msleep().usleep(min);
Lx::scheduler().current()->schedule(); Lx::scheduler().current()->schedule();
} }
@ -598,7 +603,7 @@ void usleep_range(unsigned long min, unsigned long max)
void msleep(unsigned int msecs) void msleep(unsigned int msecs)
{ {
_timer.msleep(msecs); timer_for_msleep().msleep(msecs);
Lx::scheduler().current()->schedule(); Lx::scheduler().current()->schedule();
} }
@ -718,7 +723,7 @@ int request_firmware_nowait(struct module *module, bool uevent,
} }
if (!fwl) { if (!fwl) {
PERR("Firmware '%s' is not in the firmware white list.", name); Genode::error("firmware '", name, "' is not in the firmware white list");
return -1; return -1;
} }
@ -728,27 +733,26 @@ int request_firmware_nowait(struct module *module, bool uevent,
Genode::Dataspace_capability ds_cap = rom.dataspace(); Genode::Dataspace_capability ds_cap = rom.dataspace();
if (!ds_cap.valid()) { if (!ds_cap.valid()) {
PERR("Could not get firmware ROM dataspace"); Genode::error("could not get firmware ROM dataspace");
return -1; return -1;
} }
firmware *fw = (firmware *)kzalloc(sizeof (firmware), 0); struct firmware *fw = (struct firmware *)kzalloc(sizeof(struct firmware), 0);
if (!fw) { if (!fw) {
PERR("Could not allocate memory for firmware metadata"); Genode::error("could not allocate memory for firmware metadata");
return -1; return -1;
} }
/* use Genode env because our slab only goes up to 64KiB */ /* use allocator because fw is too big for slab */
fw->data = (u8*)Genode::env()->heap()->alloc(fwl->size); if (!Lx_kit::env().heap().alloc(fwl->size, (void**)&fw->data)) {
if (!fw->data) { Genode::error("Could not allocate memory for firmware image");
PERR("Could not allocate memory for firmware image");
kfree(fw); kfree(fw);
return -1; return -1;
} }
void const *image = Genode::env()->rm_session()->attach(ds_cap); void const *image = Lx_kit::env().env().rm().attach(ds_cap);
Genode::memcpy((void*)fw->data, image, fwl->size); Genode::memcpy((void*)fw->data, image, fwl->size);
Genode::env()->rm_session()->detach(image); Lx_kit::env().env().rm().detach(image);
fw->size = fwl->size; fw->size = fwl->size;
@ -759,7 +763,7 @@ int request_firmware_nowait(struct module *module, bool uevent,
void release_firmware(const struct firmware *fw) void release_firmware(const struct firmware *fw)
{ {
Genode::env()->heap()->free(const_cast<u8 *>(fw->data), fw->size); Lx_kit::env().heap().free(const_cast<u8 *>(fw->data), fw->size);
kfree(fw); kfree(fw);
} }
@ -775,7 +779,6 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
void *addr = Lx::Malloc::dma().alloc(size, 12, &dma_addr); void *addr = Lx::Malloc::dma().alloc(size, 12, &dma_addr);
if (!addr) { if (!addr) {
// PERR("dma alloc: %zu failed", size);
return 0; return 0;
} }
@ -800,10 +803,11 @@ void *dma_zalloc_coherent(struct device *dev, size_t size,
void dma_free_coherent(struct device *dev, size_t size, void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle) void *vaddr, dma_addr_t dma_handle)
{ {
if (Lx::Malloc::dma().inside((Genode::addr_t)vaddr)) if (Lx::Malloc::dma().inside((Genode::addr_t)vaddr)) {
Lx::Malloc::dma().free(vaddr); Lx::Malloc::dma().free(vaddr);
else } else {
PERR("vaddr: %p is not DMA memory", vaddr); Genode::error("vaddr: ", vaddr, " is not DMA memory");
}
} }
@ -811,14 +815,16 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
size_t offset, size_t size, size_t offset, size_t size,
enum dma_data_direction direction) enum dma_data_direction direction)
{ {
if (!Lx::Malloc::dma().inside((Genode::addr_t)page->addr)) if (!Lx::Malloc::dma().inside((Genode::addr_t)page->addr)) {
PERR("page->page: %p not DMA address", page->addr); Genode::error(__func__, ": virtual address ", (void*)page->addr, " not an DMA address");
}
dma_addr_t dma_addr = (dma_addr_t) Lx::Malloc::dma().phys_addr(page->addr); dma_addr_t dma_addr = (dma_addr_t) Lx::Malloc::dma().phys_addr(page->addr);
if (dma_addr == ~0UL) if (dma_addr == ~0UL) {
PERR("%s: virtual address %p not registered for DMA, called from: %p", Genode::error(__func__, ": virtual address ", (void*)page->addr,
__func__, page->addr, __builtin_return_address(0)); " not registered for DMA");
}
return dma_addr; return dma_addr;
} }
@ -828,9 +834,10 @@ dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size,
{ {
dma_addr_t dma_addr = (dma_addr_t) Lx::Malloc::dma().phys_addr(cpu_addr); dma_addr_t dma_addr = (dma_addr_t) Lx::Malloc::dma().phys_addr(cpu_addr);
if (dma_addr == ~0UL) if (dma_addr == ~0UL) {
PERR("%s: virtual address %p not registered for DMA, called from: %p", Genode::error(__func__, ": virtual address ", cpu_addr,
__func__, cpu_addr, __builtin_return_address(0)); " not registered for DMA");
}
return dma_addr; return dma_addr;
} }
@ -948,7 +955,7 @@ struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)
page->addr = Lx::Malloc::dma().alloc(size, 12); page->addr = Lx::Malloc::dma().alloc(size, 12);
if (!page->addr) { if (!page->addr) {
PERR("alloc_pages: %zu failed", size); Genode::error("alloc_pages: ", size, " failed");
kfree(page); kfree(page);
return 0; return 0;
} }
@ -981,8 +988,8 @@ void __free_page_frag(void *addr)
void __free_pages(struct page *page, unsigned int order) void __free_pages(struct page *page, unsigned int order)
{ {
if (!atomic_dec_and_test(&page->_count)) { if (!atomic_dec_and_test(&page->_count)) {
PWRNV("attempting to free page %p with _count: %d, called from: %p", Genode::warning("attempting to free page ", page, " with _count: ",
page, atomic_read(&page->_count), __builtin_return_address(0)); atomic_read(&page->_count));
return; return;
} }
@ -1016,9 +1023,8 @@ struct page *virt_to_head_page(const void *addr)
unsigned long aligned_addr = (unsigned long)addr & ~0xfff; unsigned long aligned_addr = (unsigned long)addr & ~0xfff;
page = Addr_to_page_mapping::find_page(aligned_addr); page = Addr_to_page_mapping::find_page(aligned_addr);
if (!page) { if (!page) {
PERR("BUG: addr: %p and aligned addr: %p have no page mapping, " Genode::error("BUG: addr: ", addr, " and aligned addr: ",
" called from: %p", addr, (void*)aligned_addr, (void*)aligned_addr, " have no page mapping, ");
__builtin_return_address(0));
Genode::sleep_forever(); Genode::sleep_forever();
} }
} }
@ -1036,7 +1042,7 @@ void get_page(struct page *page)
void put_page(struct page *page) void put_page(struct page *page)
{ {
if (!page) { if (!page) {
PWRN("put_page: page is zero called from: %p", __builtin_return_address(0)); Genode::warning(__func__, ": page is zero");
return; return;
} }
@ -1223,15 +1229,30 @@ int request_module(char const* format, ...)
** kernel/locking/mutex.c ** ** kernel/locking/mutex.c **
****************************/ ****************************/
/*
* XXX We have to create the waiters list lazy because the way
* DEFINE_MUTEX is currently implemented does not work w/o
* a global Env that was constructed before the static ctors
* are called.
*/
static inline void __check_or_initialize_mutex(struct mutex *m)
{
if (!m->waiters) {
m->waiters = new (&Lx_kit::env().heap()) Lx::Task::List;
}
}
enum { MUTEX_UNLOCKED = 1, MUTEX_LOCKED = 0, MUTEX_WAITERS = -1 }; enum { MUTEX_UNLOCKED = 1, MUTEX_LOCKED = 0, MUTEX_WAITERS = -1 };
void mutex_init(struct mutex *m) void mutex_init(struct mutex *m)
{ {
static unsigned id = 0; static unsigned id = 0;
m->state = MUTEX_UNLOCKED; m->state = MUTEX_UNLOCKED;
m->holder = nullptr; m->holder = nullptr;
m->waiters = new (Genode::env()->heap()) Lx::Task::List; m->waiters = nullptr;
m->id = ++id; m->id = ++id;
} }
@ -1240,7 +1261,8 @@ void mutex_destroy(struct mutex *m)
{ {
/* FIXME potentially blocked tasks are not unblocked */ /* FIXME potentially blocked tasks are not unblocked */
Genode::destroy(Genode::env()->heap(), static_cast<Lx::Task::List *>(m->waiters)); Genode::destroy(&Lx_kit::env().heap(),
static_cast<Lx::Task::List *>(m->waiters));
m->holder = nullptr; m->holder = nullptr;
m->waiters = nullptr; m->waiters = nullptr;
@ -1250,6 +1272,8 @@ void mutex_destroy(struct mutex *m)
void mutex_lock(struct mutex *m) void mutex_lock(struct mutex *m)
{ {
__check_or_initialize_mutex(m);
while (1) { while (1) {
if (m->state == MUTEX_UNLOCKED) { if (m->state == MUTEX_UNLOCKED) {
m->state = MUTEX_LOCKED; m->state = MUTEX_LOCKED;
@ -1261,7 +1285,7 @@ void mutex_lock(struct mutex *m)
Lx::Task *t = reinterpret_cast<Lx::Task *>(m->holder); Lx::Task *t = reinterpret_cast<Lx::Task *>(m->holder);
if (t == Lx::scheduler().current()) { if (t == Lx::scheduler().current()) {
PERR("Bug: mutex does not support recursive locking"); Genode::error("BUG: mutex does not support recursive locking");
Genode::sleep_forever(); Genode::sleep_forever();
} }
@ -1277,12 +1301,14 @@ void mutex_lock(struct mutex *m)
void mutex_unlock(struct mutex *m) void mutex_unlock(struct mutex *m)
{ {
__check_or_initialize_mutex(m);
if (m->state == MUTEX_UNLOCKED) { if (m->state == MUTEX_UNLOCKED) {
PERR("Bug: multiple mutex unlock detected"); Genode::error("BUG: multiple mutex unlock detected");
Genode::sleep_forever(); Genode::sleep_forever();
} }
if (m->holder != Lx::scheduler().current()) { if (m->holder != Lx::scheduler().current()) {
PERR("Bug: mutex unlock by task not holding the mutex"); Genode::error("BUG: mutex unlock by task not holding the mutex");
Genode::sleep_forever(); Genode::sleep_forever();
} }

View File

@ -13,11 +13,11 @@
*/ */
/* Genode includes */ /* Genode includes */
#include <base/log.h>
#include <base/rpc_server.h> #include <base/rpc_server.h>
#include <base/snprintf.h> #include <base/snprintf.h>
#include <cap_session/connection.h> #include <cap_session/connection.h>
#include <nic/xml_node.h> #include <nic/xml_node.h>
#include <os/config.h>
#include <nic/component.h> #include <nic/component.h>
#include <root/component.h> #include <root/component.h>
#include <util/xml_node.h> #include <util/xml_node.h>
@ -32,7 +32,6 @@
# include <lxc.h> # include <lxc.h>
#include <lx_emul/extern_c_end.h> #include <lx_emul/extern_c_end.h>
extern bool config_verbose;
enum { enum {
HEAD_ROOM = 128, /* XXX guessed value but works */ HEAD_ROOM = 128, /* XXX guessed value but works */
@ -63,7 +62,7 @@ class Wifi_session_component : public Nic::Session_component
Packet_descriptor packet = _tx.sink()->get_packet(); Packet_descriptor packet = _tx.sink()->get_packet();
if (!packet.size()) { if (!packet.size()) {
PWRN("Invalid tx packet"); Genode::warning("invalid tx packet");
return true; return true;
} }
@ -122,7 +121,7 @@ class Wifi_session_component : public Nic::Session_component
_handle_packet_stream(); _handle_packet_stream();
if (!_rx.source()->ready_to_submit()) { if (!_rx.source()->ready_to_submit()) {
PWRN("Not ready to receive packet"); Genode::warning("not ready to receive packet");
return; return;
} }
@ -138,7 +137,7 @@ class Wifi_session_component : public Nic::Session_component
_rx.source()->submit_packet(p); _rx.source()->submit_packet(p);
} catch (...) { } catch (...) {
PWRN("failed to process received packet"); Genode::warning("failed to process received packet");
} }
} }
@ -166,7 +165,7 @@ class Root : public Genode::Root_component<Wifi_session_component,
{ {
private: private:
Server::Entrypoint &_ep; Genode::Env &_env;
protected: protected:
@ -189,16 +188,16 @@ class Root : public Genode::Root_component<Wifi_session_component,
*/ */
if (tx_buf_size + rx_buf_size < tx_buf_size || if (tx_buf_size + rx_buf_size < tx_buf_size ||
tx_buf_size + rx_buf_size > ram_quota - session_size) { tx_buf_size + rx_buf_size > ram_quota - session_size) {
PERR("insufficient 'ram_quota', got %zd, need %zd", Genode::error("insufficient 'ram_quota', got ", ram_quota, " need ",
ram_quota, tx_buf_size + rx_buf_size + session_size); tx_buf_size + rx_buf_size + session_size);
throw Genode::Root::Quota_exceeded(); throw Genode::Root::Quota_exceeded();
} }
session = new (md_alloc()) session = new (md_alloc())
Wifi_session_component(tx_buf_size, rx_buf_size, Wifi_session_component(tx_buf_size, rx_buf_size,
*env()->heap(), *md_alloc(),
*env()->ram_session(), _env.ram(),
_ep, device); _env.ep(), device);
return session; return session;
} }
@ -208,22 +207,29 @@ class Root : public Genode::Root_component<Wifi_session_component,
Wifi_session_component *session = nullptr; Wifi_session_component *session = nullptr;
static Root *instance; static Root *instance;
Root(Server::Entrypoint &ep, Genode::Allocator &md_alloc) Root(Genode::Env &env, Genode::Allocator &md_alloc)
: Genode::Root_component<Wifi_session_component, Genode::Single_client>(&ep.rpc_ep(), &md_alloc), : Genode::Root_component<Wifi_session_component, Genode::Single_client>(&env.ep().rpc_ep(), &md_alloc),
_ep(ep) _env(env)
{ } { }
void announce() { Genode::env()->parent()->announce(_ep.rpc_ep().manage(this)); } void announce() { _env.parent().announce(_env.ep().manage(*this)); }
}; };
Root *Root::instance; Root *Root::instance;
void Lx::nic_init(Server::Entrypoint &ep) static Genode::Env *_env;
static Genode::Allocator *_alloc;
void Lx::nic_init(Genode::Env &env, Genode::Allocator &alloc)
{ {
static Root root(ep, *Genode::env()->heap()); static Root root(env, alloc);
Root::instance = &root; Root::instance = &root;
_env = &env;
_alloc = &alloc;
} }
@ -253,7 +259,7 @@ class Lx::Notifier
public: public:
Notifier() : _block_alloc(Genode::env()->heap()) { } Notifier() : _block_alloc(_alloc) { }
void register_block(struct notifier_block *nb) void register_block(struct notifier_block *nb)
{ {
@ -395,7 +401,7 @@ class Proto_hook_list
static Proto_hook_list& proto_hook_list() static Proto_hook_list& proto_hook_list()
{ {
static Proto_hook_list inst(*Genode::env()->heap()); static Proto_hook_list inst(*_alloc);
return inst; return inst;
} }
@ -415,7 +421,7 @@ extern "C" void __dev_remove_pack(struct packet_type *pt)
extern "C" struct net_device *__dev_get_by_index(struct net *net, int ifindex) extern "C" struct net_device *__dev_get_by_index(struct net *net, int ifindex)
{ {
if (!Root::instance->device) { if (!Root::instance->device) {
PERR("no net device registered!"); Genode::error("no net device registered!");
return 0; return 0;
} }
@ -463,8 +469,9 @@ extern "C" int dev_queue_xmit(struct sk_buff *skb)
struct net_device_ops const *ops = dev->netdev_ops; struct net_device_ops const *ops = dev->netdev_ops;
int rv = NETDEV_TX_OK; int rv = NETDEV_TX_OK;
if (skb->next) if (skb->next) {
PWRN("more skb's queued"); Genode::warning("more skb's queued");
}
rv = ops->ndo_start_xmit(skb, dev); rv = ops->ndo_start_xmit(skb, dev);
@ -484,7 +491,7 @@ extern "C" int register_netdevice(struct net_device *ndev)
static bool already_registered = false; static bool already_registered = false;
if (already_registered) { if (already_registered) {
PERR("We don't support multiple network devices in one driver instance"); Genode::error("We don't support multiple network devices in one driver instance");
return -ENODEV; return -ENODEV;
} }
@ -503,14 +510,20 @@ extern "C" int register_netdevice(struct net_device *ndev)
/* set mac adress */ /* set mac adress */
Genode::memcpy(ndev->perm_addr, ndev->ieee80211_ptr->wiphy->perm_addr, ETH_ALEN); Genode::memcpy(ndev->perm_addr, ndev->ieee80211_ptr->wiphy->perm_addr, ETH_ALEN);
if (config_verbose) {
PINF("mac_address: %02x:%02x:%02x:%02x:%02x:%02x", using namespace Genode;
ndev->perm_addr[0], ndev->perm_addr[1], ndev->perm_addr[2], log("mac_address: ",
ndev->perm_addr[3], ndev->perm_addr[4], ndev->perm_addr[5]); Hex(ndev->perm_addr[0], Hex::OMIT_PREFIX, Hex::PAD), ":",
Hex(ndev->perm_addr[1], Hex::OMIT_PREFIX, Hex::PAD), ":",
Hex(ndev->perm_addr[2], Hex::OMIT_PREFIX, Hex::PAD), ":",
Hex(ndev->perm_addr[3], Hex::OMIT_PREFIX, Hex::PAD), ":",
Hex(ndev->perm_addr[4], Hex::OMIT_PREFIX, Hex::PAD), ":",
Hex(ndev->perm_addr[5], Hex::OMIT_PREFIX, Hex::PAD));
}
int err = ndev->netdev_ops->ndo_open(ndev); int err = ndev->netdev_ops->ndo_open(ndev);
if (err) { if (err) {
PERR("ndev->netdev_ops->ndo_open(ndev): %d", err); Genode::error("ndo_open() failed: ", err);
return err; return err;
} }
@ -553,9 +566,6 @@ extern "C" void netif_carrier_on(struct net_device *dev)
extern "C" void netif_carrier_off(struct net_device *dev) extern "C" void netif_carrier_off(struct net_device *dev)
{ {
if (!dev)
PERR("!dev %p", __builtin_return_address(0));
dev->state |= 1UL << __LINK_STATE_NOCARRIER; dev->state |= 1UL << __LINK_STATE_NOCARRIER;
Wifi_session_component *session = (Wifi_session_component *)dev->lx_nic_device; Wifi_session_component *session = (Wifi_session_component *)dev->lx_nic_device;
@ -616,8 +626,8 @@ extern "C" void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
extern "C" u16 netdev_cap_txqueue(struct net_device *dev, u16 queue_index) extern "C" u16 netdev_cap_txqueue(struct net_device *dev, u16 queue_index)
{ {
if (queue_index > dev-> real_num_tx_queues) { if (queue_index > dev-> real_num_tx_queues) {
PERR("error: queue_index %d out of range (%d max) called from: %p", Genode::error("queue_index ", queue_index, " out of range (",
queue_index, dev->real_num_tx_queues, __builtin_return_address(0)); dev->real_num_tx_queues, " max)");
return 0; return 0;
} }
@ -673,7 +683,7 @@ extern "C" struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name
kcalloc(txqs, sizeof(struct netdev_queue), kcalloc(txqs, sizeof(struct netdev_queue),
GFP_KERNEL | GFP_LX_DMA); GFP_KERNEL | GFP_LX_DMA);
if (!tx) { if (!tx) {
PERR("could not allocate ndev_queues"); Genode::error("could not allocate ndev_queues");
} }
dev->_tx = tx; dev->_tx = tx;

View File

@ -13,7 +13,7 @@
/* Genode includes */ /* Genode includes */
#include <base/env.h> #include <base/env.h>
#include <base/printf.h> #include <base/log.h>
/* local includes */ /* local includes */
#include <lx.h> #include <lx.h>
@ -135,7 +135,7 @@ class Lx::Socket
{ {
struct socket *sock = static_cast<struct socket*>(_call.handle->socket); struct socket *sock = static_cast<struct socket*>(_call.handle->socket);
if (!sock) if (!sock)
PERR("BUG: sock is zero"); Genode::error("BUG: sock is zero");
return sock; return sock;
} }
@ -151,7 +151,7 @@ class Lx::Socket
return; return;
} }
PERR("sock_create_kern failed, res: %d", res); Genode::error("sock_create_kern failed, res: ", res);
_call.socket.result = nullptr; _call.socket.result = nullptr;
_call.err = res; _call.err = res;
} }
@ -334,7 +334,7 @@ class Lx::Socket
public: public:
Socket(Server::Entrypoint &ep) Socket(Genode::Entrypoint &ep)
: :
_dispatcher(ep, *this, &Lx::Socket::_handle), _dispatcher(ep, *this, &Lx::Socket::_handle),
_task(run_socketcall, nullptr, "socketcall", _task(run_socketcall, nullptr, "socketcall",
@ -359,7 +359,7 @@ class Lx::Socket
default: default:
_call.err = -EINVAL; _call.err = -EINVAL;
PWRN("unknown opcode: %u", _call.opcode); Genode::warning("unknown opcode: ", (int)_call.opcode);
break; break;
} }
@ -376,12 +376,14 @@ class Lx::Socket
static Lx::Socket *_socket; static Lx::Socket *_socket;
static Genode::Allocator *_alloc;
void Lx::socket_init(Server::Entrypoint &ep) void Lx::socket_init(Genode::Entrypoint &ep, Genode::Allocator &alloc)
{ {
static Lx::Socket socket_ctx(ep); static Lx::Socket socket_ctx(ep);
_socket = &socket_ctx; _socket = &socket_ctx;
_alloc = &alloc;
} }
@ -422,7 +424,7 @@ Wifi::Socket *Socket_call::socket(int domain, int type, int protocol)
if (_call.socket.result == 0) if (_call.socket.result == 0)
return 0; return 0;
Wifi::Socket *s = new (Genode::env()->heap()) Wifi::Socket(_call.socket.result); Wifi::Socket *s = new (_alloc) Wifi::Socket(_call.socket.result);
return s; return s;
} }
@ -435,10 +437,11 @@ int Socket_call::close(Socket *s)
_socket->submit_and_block(); _socket->submit_and_block();
if (_call.err) if (_call.err) {
PWRN("error %d on close()", _call.err); Genode::error("closing socket failed: ", _call.err);
}
destroy(Genode::env()->heap(), s); destroy(_alloc, s);
return 0; return 0;
} }