Tag Sculpt 19.07
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCgAGBQJdJGPtAAoJEKckYDQX7Na3/3oP/3fgZKXRiFaSi0IWDX5leBLx bkKgqnnS9KRRLSIibOTZSOBE+HfIUb6gOr4Md1sdM9NILIF+R33cwPc8OUL4nsbc tefzgNCCtuDUmLTebDWrEE6Hz1ZJwUiXMOE3ACC/9zoMo9/lg1AQreK5QWt/+jDO JTH2SofQOeJjfme90qcJo0x/xg9/ARZzQLiPXigtlwWUEP6b0sA0q1wbcMZb4fyG 14oOJew/9/3ARawvzw18oSCW1hAQyrDnP0Lm9N/i1vi+mcJc7uBFojXeEKe8IudM rq+5NRwj7hV2GfiujVb2MbdM6JpFT5dhUP5pyFDjUd5CuDxpAslYqCBRz7OJQNjz a28inTbRucbUDeca7jIg6/IUjpqFyRjWDcmh2ChUbJHWddNeh+8N7bJQUguJmlEL XrHeiPEGEbkhofZ7cUHUKbxOtpr+YAonyxSwoKCPWa5Co20E2NOl3C8bAuPZzJxI ij+PiPwG79dfW+Q24gV6OImzCeUbTcVibo/GodtySapfdTamE8fdEfgfMEjyPzj4 2doK3Ufk2oN5XRIyThNErcgTj4Cm6zzhvocKt5Rk31d0FbKpDNM+aDwRMLMcCTTf lw8yYMjuFtEkGzQ1612VNB5occR4djx1TtG8EYF7aJ8hf+klpprM2/A4Uj4J6WIw M64j4W9LbVM5cj9ynL/m =ldp5 -----END PGP SIGNATURE----- Merge tag 'sculpt-19.07' into submodule
This commit is contained in:
commit
acbbb3ebe8
|
@ -16,70 +16,49 @@
|
|||
.global _start
|
||||
_start:
|
||||
|
||||
/****************
|
||||
** Enable FPU **
|
||||
****************/
|
||||
|
||||
mov x0, #0b11
|
||||
lsl x0, x0, #20
|
||||
msr cpacr_el1, x0
|
||||
|
||||
|
||||
/***********************
|
||||
** Detect CPU number **
|
||||
***********************/
|
||||
|
||||
mrs x0, mpidr_el1
|
||||
and x0, x0, #0b11111111
|
||||
cmp x0, #0
|
||||
bne __endless_sleep
|
||||
cbz x0, _crt0_fill_bss_zero
|
||||
wfe
|
||||
b _start
|
||||
|
||||
|
||||
/***************************
|
||||
** Zero-fill BSS segment **
|
||||
***************************/
|
||||
|
||||
ldr x0, =_bss_local_start
|
||||
ldr x1, =_bss_local_end
|
||||
_crt0_fill_bss_zero:
|
||||
ldr x0, =_bss_start
|
||||
ldr x1, =_bss_end
|
||||
1:
|
||||
cmp x1, x0
|
||||
ble 2f
|
||||
str xzr, [x0]
|
||||
add x0, x0, #8
|
||||
b 1b
|
||||
2:
|
||||
b.eq _crt0_enable_fpu
|
||||
str xzr, [x0], #8
|
||||
b 1b
|
||||
|
||||
|
||||
/************************************
|
||||
** Jump to high-level entry point **
|
||||
************************************/
|
||||
/****************
|
||||
** Enable FPU **
|
||||
****************/
|
||||
|
||||
ldr x0, =_start_stack /* load stack address into x0 */
|
||||
msr vbar_el1, x0
|
||||
_crt0_enable_fpu:
|
||||
mov x0, #0b11
|
||||
lsl x0, x0, #20
|
||||
msr cpacr_el1, x0
|
||||
|
||||
|
||||
/**********************
|
||||
** Initialize stack **
|
||||
**********************/
|
||||
|
||||
ldr x0, =_crt0_start_stack
|
||||
mov sp, x0
|
||||
bl init
|
||||
|
||||
__endless_sleep:
|
||||
wfe
|
||||
1: b 1b
|
||||
|
||||
_bss_local_start:
|
||||
.quad _bss_start
|
||||
|
||||
_bss_local_end:
|
||||
.quad _bss_end
|
||||
|
||||
.p2align 4
|
||||
.space 0x4000
|
||||
_start_stack:
|
||||
|
||||
.rept 512
|
||||
nop
|
||||
.endr
|
||||
mrs x24, far_el1
|
||||
mrs x25, ttbr0_el1
|
||||
mrs x26, ttbr1_el1
|
||||
mrs x27, elr_el1
|
||||
mrs x28, esr_el1
|
||||
1: b 1b
|
||||
|
||||
_crt0_start_stack:
|
||||
|
|
|
@ -133,6 +133,7 @@ unsigned Bootstrap::Platform::enable_mmu()
|
|||
|
||||
Cpu::Sctlr_el1::access_t sctlr = Cpu::Sctlr_el1::read();
|
||||
Cpu::Sctlr_el1::C::set(sctlr, 1);
|
||||
Cpu::Sctlr_el1::I::set(sctlr, 1);
|
||||
Cpu::Sctlr_el1::A::set(sctlr, 0);
|
||||
Cpu::Sctlr_el1::M::set(sctlr, 1);
|
||||
Cpu::Sctlr_el1::Sa0::set(sctlr, 1);
|
||||
|
|
|
@ -106,11 +106,12 @@ struct Hw::Arm_64_cpu
|
|||
);
|
||||
|
||||
SYSTEM_REGISTER(64, Sctlr_el1, sctlr_el1,
|
||||
struct M : Bitfield<0, 1> { };
|
||||
struct A : Bitfield<1, 1> { };
|
||||
struct C : Bitfield<2, 1> { };
|
||||
struct Sa : Bitfield<3, 1> { };
|
||||
struct Sa0 : Bitfield<4, 1> { };
|
||||
struct M : Bitfield<0, 1> { };
|
||||
struct A : Bitfield<1, 1> { };
|
||||
struct C : Bitfield<2, 1> { };
|
||||
struct Sa : Bitfield<3, 1> { };
|
||||
struct Sa0 : Bitfield<4, 1> { };
|
||||
struct I : Bitfield<12, 1> { };
|
||||
);
|
||||
|
||||
struct Spsr : Genode::Register<64>
|
||||
|
|
|
@ -66,30 +66,33 @@ void Genode::print_lines(char const *string, size_t len, FUNC const &func)
|
|||
if (Genode::strcmp(first_line, string, num_indent_chars) == 0)
|
||||
string += num_indent_chars;
|
||||
|
||||
size_t const line_len =
|
||||
({
|
||||
size_t i = 0;
|
||||
for (; i < len; i++) {
|
||||
if (string[i] == '\0' || string[i] == '\n') {
|
||||
size_t line_len = 0;
|
||||
size_t skip_char = 1;
|
||||
|
||||
/* the line length is the offset of the last real character + 1 */
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i;
|
||||
});
|
||||
for (; line_len < len; line_len++) {
|
||||
if (string[line_len] == '\0' || string[line_len] == '\n') {
|
||||
line_len++;
|
||||
break;
|
||||
}
|
||||
if (line_len == MAX_LINE_LEN) {
|
||||
skip_char = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!line_len)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Copy line from (untrusted) caller to local line buffer
|
||||
*/
|
||||
char line_buf[MAX_LINE_LEN];
|
||||
Genode::strncpy(line_buf, string, Genode::min(line_len, sizeof(line_buf)));
|
||||
/* buffer for sub-string of the input string plus null-termination */
|
||||
char line_buf[MAX_LINE_LEN + 1];
|
||||
|
||||
/* give strncpy one more as it will add the null termination */
|
||||
Genode::strncpy(line_buf, string, line_len - skip_char + 1);
|
||||
|
||||
/* process null-terminated string in buffer */
|
||||
func(line_buf);
|
||||
|
||||
/* move forward to the next sub-string to process */
|
||||
string += line_len;
|
||||
len -= line_len;
|
||||
}
|
||||
|
|
|
@ -391,7 +391,7 @@ struct Linker::Binary : private Root_object, public Elf_object
|
|||
{
|
||||
Init::list()->exec_static_constructors();
|
||||
|
||||
/* call static construtors and register destructors */
|
||||
/* call static constructors and register destructors */
|
||||
Func * const ctors_start = (Func *)lookup_symbol("_ctors_start");
|
||||
Func * const ctors_end = (Func *)lookup_symbol("_ctors_end");
|
||||
for (Func * ctor = ctors_end; ctor != ctors_start; (*--ctor)());
|
||||
|
@ -677,10 +677,6 @@ void Genode::init_ldso_phdr(Env &env)
|
|||
|
||||
void Genode::exec_static_constructors()
|
||||
{
|
||||
if (!binary_ptr->static_construction_pending())
|
||||
warning("Don't call Genode::Env::exec_static_constructors() "
|
||||
"in components without static globals");
|
||||
|
||||
binary_ptr->finish_static_construction();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,13 @@ linux-x.x.x/drivers/net/ethernet/freescale/fec.h
|
|||
linux-x.x.x/drivers/net/ethernet/freescale/fec_main.c
|
||||
linux-x.x.x/drivers/net/ethernet/freescale/fec_ptp.c
|
||||
linux-x.x.x/drivers/net/phy/mdio_bus.c
|
||||
linux-x.x.x/drivers/net/phy/mdio_device.c
|
||||
linux-x.x.x/drivers/net/phy/mdio-boardinfo.c
|
||||
linux-x.x.x/drivers/net/phy/mdio-boardinfo.h
|
||||
linux-x.x.x/drivers/net/phy/phy_device.c
|
||||
linux-x.x.x/drivers/net/phy/phy.c
|
||||
linux-x.x.x/drivers/net/phy/phy-c45.c
|
||||
linux-x.x.x/drivers/net/phy/phy-core.c
|
||||
linux-x.x.x/drivers/net/phy/at803x.c
|
||||
linux-x.x.x/net/core/skbuff.c
|
||||
linux-x.x.x/net/ethernet/eth.c
|
||||
|
@ -14,21 +19,26 @@ linux-x.x.x/include/asm-generic/bitops/__fls.h
|
|||
linux-x.x.x/include/asm-generic/bitops/ffs.h
|
||||
linux-x.x.x/include/asm-generic/bitops/fls.h
|
||||
linux-x.x.x/include/asm-generic/bitops/fls64.h
|
||||
linux-x.x.x/include/linux/cgroup-defs.h
|
||||
linux-x.x.x/include/linux/errqueue.h
|
||||
linux-x.x.x/include/linux/ethtool.h
|
||||
linux-x.x.x/include/linux/fec.h
|
||||
linux-x.x.x/include/linux/gpio/consumer.h
|
||||
linux-x.x.x/include/linux/if_ether.h
|
||||
linux-x.x.x/include/linux/list.h
|
||||
linux-x.x.x/include/linux/list_nulls.h
|
||||
linux-x.x.x/include/linux/log2.h
|
||||
linux-x.x.x/include/linux/mdio.h
|
||||
linux-x.x.x/include/linux/mii.h
|
||||
linux-x.x.x/include/linux/mod_devicetable.h
|
||||
linux-x.x.x/include/linux/net.h
|
||||
linux-x.x.x/include/linux/netdev_features.h
|
||||
linux-x.x.x/include/linux/phy.h
|
||||
linux-x.x.x/include/linux/ptp_clock_kernel.h
|
||||
linux-x.x.x/include/linux/rbtree.h
|
||||
linux-x.x.x/include/linux/rculist.h
|
||||
linux-x.x.x/include/linux/rculist_nulls.h
|
||||
linux-x.x.x/include/linux/refcount.h
|
||||
linux-x.x.x/include/linux/skbuff.h
|
||||
linux-x.x.x/include/linux/socket.h
|
||||
linux-x.x.x/include/linux/timecounter.h
|
||||
|
|
34
repos/dde_linux/patches/fec_ndev_owner.patch
Normal file
34
repos/dde_linux/patches/fec_ndev_owner.patch
Normal file
|
@ -0,0 +1,34 @@
|
|||
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
|
||||
index 74664a6..38cc18a 100644
|
||||
--- a/drivers/net/phy/phy_device.c
|
||||
+++ b/drivers/net/phy/phy_device.c
|
||||
@@ -944,7 +944,10 @@ EXPORT_SYMBOL(phy_attached_print);
|
||||
int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
|
||||
u32 flags, phy_interface_t interface)
|
||||
{
|
||||
+#if 0
|
||||
+ /* 'driver' has not been set yet on Genode */
|
||||
struct module *ndev_owner = dev->dev.parent->driver->owner;
|
||||
+#endif
|
||||
struct mii_bus *bus = phydev->mdio.bus;
|
||||
struct device *d = &phydev->mdio.dev;
|
||||
bool using_genphy = false;
|
||||
@@ -955,7 +958,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
|
||||
* our own module->refcnt here, otherwise we would not be able to
|
||||
* unload later on.
|
||||
*/
|
||||
- if (ndev_owner != bus->owner && !try_module_get(bus->owner)) {
|
||||
+ if (/*ndev_owner != bus->owner &&*/ !try_module_get(bus->owner)) {
|
||||
dev_err(&dev->dev, "failed to get the bus module\n");
|
||||
return -EIO;
|
||||
}
|
||||
@@ -1060,7 +1063,9 @@ error_module_put:
|
||||
module_put(d->driver->owner);
|
||||
error_put_device:
|
||||
put_device(d);
|
||||
+#if 0
|
||||
if (ndev_owner != bus->owner)
|
||||
+#endif
|
||||
module_put(bus->owner);
|
||||
return err;
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
diff --git a/include/net/sock.h b/include/net/sock.h
|
||||
index 14d3c07..818a1d1 100644
|
||||
--- a/include/net/sock.h
|
||||
+++ b/include/net/sock.h
|
||||
@@ -2148,8 +2148,8 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
|
||||
*/
|
||||
if (sock_flag(sk, SOCK_RCVTSTAMP) ||
|
||||
(sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) ||
|
||||
- (kt.tv64 && sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) ||
|
||||
- (hwtstamps->hwtstamp.tv64 &&
|
||||
+ (kt && sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) ||
|
||||
+ (hwtstamps->hwtstamp &&
|
||||
(sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)))
|
||||
__sock_recv_timestamp(msg, sk, skb);
|
||||
else
|
||||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
index b2df375..02c065f 100644
|
||||
--- a/net/core/skbuff.c
|
||||
+++ b/net/core/skbuff.c
|
||||
@@ -4212,7 +4212,7 @@ EXPORT_SYMBOL(skb_try_coalesce);
|
||||
*/
|
||||
void skb_scrub_packet(struct sk_buff *skb, bool xnet)
|
||||
{
|
||||
- skb->tstamp.tv64 = 0;
|
||||
+ skb->tstamp = 0;
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
skb->skb_iif = 0;
|
||||
skb->ignore_df = 0;
|
|
@ -1,11 +1,11 @@
|
|||
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
|
||||
index b2a3220..18629c6 100644
|
||||
index d4604bc..3f72629 100644
|
||||
--- a/drivers/net/ethernet/freescale/fec_main.c
|
||||
+++ b/drivers/net/ethernet/freescale/fec_main.c
|
||||
@@ -2825,7 +2825,7 @@ fec_enet_alloc_txq_buffers(struct net_device *ndev, unsigned int queue)
|
||||
@@ -2798,7 +2798,7 @@ fec_enet_alloc_txq_buffers(struct net_device *ndev, unsigned int queue)
|
||||
txq = fep->tx_queue[queue];
|
||||
bdp = txq->tx_bd_base;
|
||||
for (i = 0; i < txq->tx_ring_size; i++) {
|
||||
bdp = txq->bd.base;
|
||||
for (i = 0; i < txq->bd.ring_size; i++) {
|
||||
- txq->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
|
||||
+ txq->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL | GFP_LX_DMA);
|
||||
if (!txq->tx_bounce[i])
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
Device drivers needed for scenarios
|
||||
using one network interface
|
|
@ -0,0 +1,2 @@
|
|||
_/src/fec_nic_drv
|
||||
_/raw/drivers_nic-imx7d_sabre
|
1
repos/dde_linux/recipes/pkg/drivers_nic-imx7d_sabre/hash
Normal file
1
repos/dde_linux/recipes/pkg/drivers_nic-imx7d_sabre/hash
Normal file
|
@ -0,0 +1 @@
|
|||
2019-07-08 22eb1f5c9d136d343223df400af544eff2bad931
|
|
@ -0,0 +1,4 @@
|
|||
content: drivers.config
|
||||
|
||||
drivers.config:
|
||||
cp $(REP_DIR)/recipes/raw/drivers_nic-imx7d_sabre/$@ $@
|
|
@ -0,0 +1,31 @@
|
|||
<config>
|
||||
<parent-provides>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="ROM"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="Timer"/>
|
||||
<service name="Gpio"/>
|
||||
</parent-provides>
|
||||
|
||||
<default caps="100"/>
|
||||
|
||||
<service name="Nic">
|
||||
<default-policy> <child name="nic_drv"/> </default-policy> </service>
|
||||
|
||||
<start name="nic_drv" caps="130">
|
||||
<binary name="fec_nic_drv"/>
|
||||
<resource name="RAM" quantum="20M"/>
|
||||
<provides> <service name="Nic"/> </provides>
|
||||
<config>
|
||||
<!-- ENET1: IRQ 120 + 32 = 152 -->
|
||||
<card type="fsl,imx6sx-fec" mii="rgmii" irq="152" mmio="0x30be0000"/>
|
||||
<!-- ENET2: IRQ 102 + 32 = 134 -->
|
||||
<card type="fsl,imx6sx-fec" mii="rgmii" irq="134" mmio="0x30bf0000"/>
|
||||
</config>
|
||||
<route> <any-service> <parent/> </any-service> </route>
|
||||
</start>
|
||||
</config>
|
1
repos/dde_linux/recipes/raw/drivers_nic-imx7d_sabre/hash
Normal file
1
repos/dde_linux/recipes/raw/drivers_nic-imx7d_sabre/hash
Normal file
|
@ -0,0 +1 @@
|
|||
2019-06-27 583a26eccfd3241f727170f5d9451c9f2d55d3b4
|
|
@ -5,6 +5,16 @@
|
|||
#include <linux/timecounter.h>
|
||||
#include <net/tso.h>
|
||||
|
||||
void bus_unregister(struct bus_type *bus)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void class_unregister(struct class *cls)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
size_t copy_from_user(void *to, void const *from, size_t len)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
|
@ -45,6 +55,11 @@ void dma_free_coherent(struct device * d, size_t size, void *vaddr, dma_addr_t b
|
|||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void driver_unregister(struct device_driver *drv)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void dst_release(struct dst_entry *dst)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
|
@ -61,6 +76,17 @@ void eth_hw_addr_random(struct net_device *dev)
|
|||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst, u32 legacy_u32)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32,
|
||||
const unsigned long *src)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
u32 ethtool_op_get_link(struct net_device * d)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
|
@ -89,12 +115,22 @@ void free_netdev(struct net_device * d)
|
|||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void free_uid(struct user_struct *dummy)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
bool gfp_pfmemalloc_allowed(gfp_t g)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool gfpflags_allow_blocking(const gfp_t gfp_flags)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
int in_irq(void)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
|
@ -113,11 +149,31 @@ void *kmap_atomic(struct page *page)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const char *kobject_name(const struct kobject *kobj)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void kunmap_atomic(void *addr)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void might_sleep()
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void mm_unaccount_pinned_pages(struct mmpin *mmp)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void module_put(struct module *mod)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void netif_tx_disable(struct net_device *dev)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
|
@ -158,18 +214,53 @@ struct timespec64 ns_to_timespec64(const s64 nsec)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
int of_mdio_parse_addr(struct device *dev, const struct device_node *np)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
struct device_node *of_node_get(struct device_node *node)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void of_phy_deregister_fixed_link(struct device_node *np)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
int of_phy_register_fixed_link(struct device_node *np)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool of_property_read_bool(const struct device_node *np, const char *propname)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void phy_led_triggers_unregister(struct phy_device *phy)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void pm_runtime_disable(struct device *dev)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
int pm_runtime_put(struct device *dev)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
|
@ -187,12 +278,6 @@ int ptp_clock_unregister(struct ptp_clock *ptp)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int regulator_disable(struct regulator *r)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool page_is_pfmemalloc(struct page *page)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
|
@ -214,6 +299,52 @@ void read_unlock_bh(rwlock_t * l)
|
|||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
int regulator_disable(struct regulator *r)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int request_threaded_irq(unsigned int irq, irq_handler_t handler,
|
||||
irq_handler_t thread_fn,
|
||||
unsigned long flags, const char *name, void *dev)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void sk_free(struct sock *sk)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void sock_efree(struct sk_buff *skb)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *strncpy(char *dst, const char *src, size_t s)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
int sysfs_create_link_nowarn(struct kobject *kobj,
|
||||
struct kobject *target,
|
||||
const char *name)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void sysfs_remove_link(struct kobject *kobj, const char *name)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
unsigned int tcp_hdrlen(const struct sk_buff *skb)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
|
@ -252,42 +383,15 @@ void unregister_netdev(struct net_device * d)
|
|||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void usleep_range(unsigned long min, unsigned long max)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void __vlan_hwaccel_put_tag(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void module_put(struct module *mod)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void put_device(struct device *dev)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void class_unregister(struct class *cls)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void bus_unregister(struct bus_type *bus)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void driver_unregister(struct device_driver *drv)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
struct user_namespace init_user_ns;
|
||||
int sysctl_tstamp_allow_data;
|
||||
|
||||
|
|
|
@ -436,6 +436,7 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void * devm_ioremap_resource(struct device *dev, struct resource *res)
|
||||
{
|
||||
Fec * fec = (Fec*) dev->plat_dev->dev.of_node;
|
||||
|
@ -674,15 +675,15 @@ struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)
|
|||
}
|
||||
|
||||
|
||||
void *__alloc_page_frag(struct page_frag_cache *, unsigned int const fragsz,
|
||||
gfp_t const gfp_mask)
|
||||
void *page_frag_alloc(struct page_frag_cache *, unsigned int const fragsz,
|
||||
gfp_t const gfp_mask)
|
||||
{
|
||||
struct page *page = allocate_pages(gfp_mask, fragsz);
|
||||
return page ? page->addr : page;
|
||||
}
|
||||
|
||||
|
||||
void __free_page_frag(void *addr)
|
||||
void page_frag_free(void *addr)
|
||||
{
|
||||
struct page *page = Addr_to_page_mapping::remove((unsigned long)addr);
|
||||
|
||||
|
@ -693,6 +694,7 @@ void __free_page_frag(void *addr)
|
|||
kfree(page);
|
||||
}
|
||||
|
||||
|
||||
int driver_register(struct device_driver *drv)
|
||||
{
|
||||
new (Lx::Malloc::mem()) Driver(drv);
|
||||
|
@ -899,9 +901,10 @@ bool napi_schedule_prep(struct napi_struct *n)
|
|||
}
|
||||
|
||||
|
||||
void napi_complete(struct napi_struct *n)
|
||||
bool napi_complete_done(struct napi_struct *n, int work_done)
|
||||
{
|
||||
clear_bit(NAPI_STATE_SCHED, &n->state);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -982,7 +985,7 @@ static int of_mdiobus_register_phy(Fec::Mdio::Phy & ph, struct mii_bus *mdio)
|
|||
if (!phy || IS_ERR(phy)) return 1;
|
||||
|
||||
phy->irq = ph.gpio_irq;
|
||||
phy->dev.of_node = (device_node*) &ph;
|
||||
phy->mdio.dev.of_node = (device_node*) &ph;
|
||||
|
||||
/* All data is now stored in the phy struct;
|
||||
* register it */
|
||||
|
@ -1129,10 +1132,23 @@ u64 timecounter_read(struct timecounter *tc)
|
|||
return nsec;
|
||||
}
|
||||
|
||||
|
||||
/*********************
|
||||
** DUMMY FUNCTIONS **
|
||||
*********************/
|
||||
|
||||
int bus_register(struct bus_type *bus)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int class_register(struct class_ *cls)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clk_disable_unprepare(struct clk * c)
|
||||
{
|
||||
TRACE;
|
||||
|
@ -1144,6 +1160,12 @@ int clk_prepare_enable(struct clk * c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int device_bind_driver(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void device_initialize(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
|
@ -1155,107 +1177,46 @@ int device_init_wakeup(struct device *dev, bool val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int device_set_wakeup_enable(struct device *dev, bool enable)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct regulator *__must_check devm_regulator_get(struct device *dev, const char *id)
|
||||
{
|
||||
TRACE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct netdev_queue *netdev_get_tx_queue(const struct net_device *dev, unsigned int index)
|
||||
{
|
||||
TRACE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool of_phy_is_fixed_link(struct device_node *np)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pinctrl_pm_select_default_state(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pinctrl_pm_select_sleep_state(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct resource *platform_get_resource(struct platform_device * d, unsigned r1, unsigned r2)
|
||||
{
|
||||
TRACE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void pm_runtime_enable(struct device *dev)
|
||||
void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr, size_t size,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
void pm_runtime_get_noresume(struct device *dev)
|
||||
void dma_sync_single_for_device(struct device *dev, dma_addr_t addr,
|
||||
size_t size, enum dma_data_direction dir)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
int pm_runtime_set_active(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pm_runtime_set_autosuspend_delay(struct device *dev, int delay)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
void pm_runtime_use_autosuspend(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, struct device *parent)
|
||||
{
|
||||
TRACE;
|
||||
return (ptp_clock*)0xdeadbeef;
|
||||
}
|
||||
|
||||
int regulator_enable(struct regulator * d)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int class_register(struct class_ *cls)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int try_module_get(struct module *mod)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct device *get_device(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
return dev;
|
||||
}
|
||||
|
||||
int device_bind_driver(struct device *dev)
|
||||
struct netdev_queue *netdev_get_tx_queue(const struct net_device *dev, unsigned int index)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void netif_tx_start_all_queues(struct net_device *dev)
|
||||
bool netdev_uses_dsa(struct net_device *dev)
|
||||
{
|
||||
TRACE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void netif_tx_lock_bh(struct net_device *dev)
|
||||
|
@ -1263,18 +1224,7 @@ void netif_tx_lock_bh(struct net_device *dev)
|
|||
TRACE;
|
||||
}
|
||||
|
||||
int device_set_wakeup_enable(struct device *dev, bool enable)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void trace_consume_skb(struct sk_buff * sb)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
void trace_kfree_skb(struct sk_buff * sb, void * p)
|
||||
void netif_tx_start_all_queues(struct net_device *dev)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
@ -1289,22 +1239,17 @@ void netif_wake_queue(struct net_device * d)
|
|||
TRACE;
|
||||
}
|
||||
|
||||
bool netdev_uses_dsa(struct net_device *dev)
|
||||
const void *of_get_mac_address(struct device_node *np)
|
||||
{
|
||||
TRACE;
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void dma_sync_single_for_device(struct device *dev, dma_addr_t addr,
|
||||
size_t size, enum dma_data_direction dir)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
int of_machine_is_compatible(const char *compat)
|
||||
|
||||
void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr, size_t size,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void of_node_put(struct device_node *node)
|
||||
|
@ -1312,12 +1257,102 @@ void of_node_put(struct device_node *node)
|
|||
TRACE;
|
||||
}
|
||||
|
||||
const void *of_get_mac_address(struct device_node *np)
|
||||
bool of_phy_is_fixed_link(struct device_node *np)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void phy_led_trigger_change_speed(struct phy_device *phy)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
int phy_led_triggers_register(struct phy_device *phy)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pinctrl_pm_select_default_state(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pinctrl_pm_select_sleep_state(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int platform_get_irq_byname(struct platform_device *dev, const char *name)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct resource *platform_get_resource(struct platform_device * d, unsigned r1, unsigned r2)
|
||||
{
|
||||
TRACE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int platform_irq_count(struct platform_device *dev)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pm_runtime_enable(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
void pm_runtime_get_noresume(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
int pm_runtime_set_active(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pm_runtime_use_autosuspend(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
void pm_runtime_set_autosuspend_delay(struct device *dev, int delay)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, struct device *parent)
|
||||
{
|
||||
TRACE;
|
||||
return (ptp_clock*)0xdeadbeef;
|
||||
}
|
||||
|
||||
void put_device(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
int regulator_enable(struct regulator * d)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int request_module(const char *fmt, ...)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtnl_lock(void)
|
||||
{
|
||||
TRACE;
|
||||
|
@ -1328,16 +1363,36 @@ void rtnl_unlock(void)
|
|||
TRACE;
|
||||
}
|
||||
|
||||
int request_module(const char *fmt, ...)
|
||||
void secpath_reset(struct sk_buff *skb)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bus_register(struct bus_type *bus)
|
||||
int sysfs_create_link(struct kobject *kobj, struct kobject *target, const char *name)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void trace_consume_skb(struct sk_buff * sb)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
void trace_kfree_skb(struct sk_buff * sb, void * p)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
void trace_mdio_access(void *dummy, ...)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
int try_module_get(struct module *mod)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,10 +19,43 @@
|
|||
|
||||
#include <lx_emul/extern_c_begin.h>
|
||||
|
||||
#include <lx_emul/barrier.h>
|
||||
#include <lx_emul/compiler.h>
|
||||
#include <lx_emul/printf.h>
|
||||
#include <lx_emul/types.h>
|
||||
|
||||
static inline void __read_once_size(const volatile void *p, void *res, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
|
||||
case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
|
||||
case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
|
||||
case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
|
||||
default:
|
||||
barrier();
|
||||
__builtin_memcpy((void *)res, (const void *)p, size);
|
||||
barrier();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define READ_ONCE(x) \
|
||||
({ \
|
||||
barrier(); \
|
||||
x; \
|
||||
})
|
||||
#else
|
||||
#define READ_ONCE(x) \
|
||||
({ \
|
||||
union { typeof(x) __val; char __c[1]; } __u; \
|
||||
__read_once_size(&(x), __u.__c, sizeof(x)); \
|
||||
__u.__val; \
|
||||
})
|
||||
#endif
|
||||
|
||||
|
||||
#include <lx_emul/list.h>
|
||||
|
||||
void lx_backtrace(void);
|
||||
|
||||
#define DEBUG_LINUX_PRINTK 0
|
||||
|
@ -59,8 +92,6 @@ typedef int clockid_t;
|
|||
enum { PAGE_SHIFT = 12 };
|
||||
enum { HZ = 100UL, };
|
||||
|
||||
struct list_head;
|
||||
|
||||
typedef __u16 __le16;
|
||||
typedef __u32 __le32;
|
||||
typedef __u64 __le64;
|
||||
|
@ -129,7 +160,6 @@ enum {
|
|||
__GFP_REPEAT = 0x00000400u,
|
||||
};
|
||||
|
||||
#include <lx_emul/barrier.h>
|
||||
#include <uapi/linux/swab.h>
|
||||
#include <lx_emul/byteorder.h>
|
||||
#include <lx_emul/completion.h>
|
||||
|
@ -138,6 +168,7 @@ enum {
|
|||
#include <uapi/linux/ptp_clock.h>
|
||||
#include <lx_emul/pm.h>
|
||||
#include <lx_emul/scatterlist.h>
|
||||
#include <lx_emul/kobject.h>
|
||||
|
||||
enum {
|
||||
ETH_HLEN = 14,
|
||||
|
@ -206,11 +237,6 @@ static inline s64 timespec64_to_ns(const struct timespec64 *ts)
|
|||
|
||||
ktime_t ns_to_ktime(u64 ns);
|
||||
|
||||
struct device_node
|
||||
{
|
||||
const char * full_name;
|
||||
};
|
||||
|
||||
struct device;
|
||||
struct device_driver;
|
||||
|
||||
|
@ -220,6 +246,7 @@ struct bus_type
|
|||
const struct attribute_group **dev_groups;
|
||||
|
||||
int (*match)(struct device *dev, struct device_driver *drv);
|
||||
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
||||
int (*probe)(struct device *dev);
|
||||
|
||||
const struct dev_pm_ops *pm;
|
||||
|
@ -255,6 +282,7 @@ struct platform_device;
|
|||
struct device {
|
||||
char name[32];
|
||||
struct device * parent;
|
||||
struct kobject kobj;
|
||||
struct device_driver *driver;
|
||||
void * platform_data;
|
||||
void * driver_data;
|
||||
|
@ -263,7 +291,8 @@ struct device {
|
|||
struct bus_type *bus;
|
||||
struct class *class;
|
||||
struct device_node *of_node;
|
||||
struct platform_device * plat_dev;
|
||||
struct fwnode_handle *fwnode;
|
||||
struct platform_device *plat_dev;
|
||||
};
|
||||
|
||||
struct platform_device {
|
||||
|
@ -358,6 +387,7 @@ struct net_device
|
|||
netdev_features_t features;
|
||||
struct net_device_stats stats;
|
||||
netdev_features_t hw_features;
|
||||
int ifindex;
|
||||
const struct net_device_ops *netdev_ops;
|
||||
const struct ethtool_ops *ethtool_ops;
|
||||
const struct header_ops *header_ops;
|
||||
|
@ -365,7 +395,10 @@ struct net_device
|
|||
unsigned int priv_flags;
|
||||
unsigned short hard_header_len;
|
||||
unsigned long mtu;
|
||||
unsigned int min_mtu;
|
||||
unsigned long max_mtu;
|
||||
unsigned short type;
|
||||
unsigned char min_header_len;
|
||||
unsigned char addr_len;
|
||||
struct netdev_hw_addr_list mc;
|
||||
unsigned char *dev_addr;
|
||||
|
@ -373,7 +406,7 @@ struct net_device
|
|||
unsigned long tx_queue_len;
|
||||
int watchdog_timeo;
|
||||
struct timer_list watchdog_timer;
|
||||
struct device dev;
|
||||
struct device dev;
|
||||
u16 gso_max_segs;
|
||||
struct phy_device *phydev;
|
||||
};
|
||||
|
@ -427,8 +460,6 @@ static inline int rcu_read_lock_bh_held(void) { return 1; }
|
|||
|
||||
unsigned int jiffies_to_usecs(const unsigned long j);
|
||||
|
||||
struct rb_node {};
|
||||
|
||||
#define __aligned(x) __attribute__((aligned(x)))
|
||||
|
||||
#define kmemcheck_bitfield_begin(name)
|
||||
|
@ -602,7 +633,10 @@ bool netif_queue_stopped(const struct net_device *dev);
|
|||
|
||||
#define CONFIG_ARM 1
|
||||
#define CONFIG_ARCH_MXC 1
|
||||
#define CONFIG_DEBUG_LOCK_ALLOC 1
|
||||
#define CONFIG_MDIO_DEVICE 1
|
||||
#define CONFIG_OF_MDIO 1
|
||||
#define CONFIG_PHYLIB 1
|
||||
#define CONFIG_PTP_1588_CLOCK 1
|
||||
|
||||
void rtnl_lock(void);
|
||||
|
@ -617,26 +651,7 @@ void netif_tx_unlock_bh(struct net_device *dev);
|
|||
void napi_enable(struct napi_struct *n);
|
||||
void napi_disable(struct napi_struct *n);
|
||||
|
||||
static inline void __read_once_size(const volatile void *p, void *res, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
|
||||
case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
|
||||
case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
|
||||
case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
|
||||
default:
|
||||
barrier();
|
||||
__builtin_memcpy((void *)res, (const void *)p, size);
|
||||
barrier();
|
||||
}
|
||||
}
|
||||
|
||||
#define READ_ONCE(x) \
|
||||
({ \
|
||||
union { typeof(x) __val; char __c[1]; } __u; \
|
||||
__read_once_size(&(x), __u.__c, sizeof(x)); \
|
||||
__u.__val; \
|
||||
})
|
||||
#define __randomize_layout
|
||||
|
||||
extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
|
||||
size, unsigned long offset);
|
||||
|
@ -669,12 +684,6 @@ gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb);
|
|||
|
||||
void dma_sync_single_for_device(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir);
|
||||
|
||||
bool napi_schedule_prep(struct napi_struct *n);
|
||||
|
||||
void __napi_schedule(struct napi_struct *n);
|
||||
|
||||
void napi_complete(struct napi_struct *n);
|
||||
|
||||
void *dev_get_platdata(const struct device *dev);
|
||||
|
||||
int is_valid_ether_addr(const u8 *);
|
||||
|
@ -710,6 +719,473 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np);
|
|||
|
||||
struct resource *platform_get_resource(struct platform_device *, unsigned, unsigned);
|
||||
|
||||
/*******************************
|
||||
** asm-generic/atomic-long.h **
|
||||
*******************************/
|
||||
|
||||
static inline int atomic_long_cmpxchg(atomic_long_t *v, long old, long n) {
|
||||
return cmpxchg(&v->counter, old, n); }
|
||||
|
||||
/************************
|
||||
** linux/capability.h **
|
||||
************************/
|
||||
|
||||
bool capable(int);
|
||||
|
||||
/*************************
|
||||
** linux/cgroup-defs.h **
|
||||
*************************/
|
||||
|
||||
struct cgroup;
|
||||
|
||||
/******************
|
||||
** linux/cred.h **
|
||||
******************/
|
||||
|
||||
struct user_struct *current_user();
|
||||
|
||||
/*******************
|
||||
** linux/delay.h **
|
||||
*******************/
|
||||
|
||||
void usleep_range(unsigned long min, unsigned long max);
|
||||
|
||||
/*************************
|
||||
** linux/etherdevice.h **
|
||||
*************************/
|
||||
|
||||
static inline void ether_addr_copy(u8 *dst, const u8 *src)
|
||||
{
|
||||
*(u32 *)dst = *(const u32 *)src;
|
||||
*(u16 *)(dst+ 4) = *(const u16 *)(src + 4);
|
||||
}
|
||||
|
||||
/*********************
|
||||
** linux/ethtool.h **
|
||||
*********************/
|
||||
|
||||
struct ethtool_link_ksettings;
|
||||
|
||||
/****************
|
||||
** linux/fs.h **
|
||||
****************/
|
||||
|
||||
typedef struct {
|
||||
size_t written;
|
||||
size_t count;
|
||||
union {
|
||||
char __user *buf;
|
||||
void *data;
|
||||
} arg;
|
||||
int error;
|
||||
} read_descriptor_t;
|
||||
|
||||
/********************
|
||||
** linux/fwnode.h **
|
||||
********************/
|
||||
|
||||
struct fwnode_handle { int dummy; };
|
||||
|
||||
/**********************
|
||||
** linux/mm_types.h **
|
||||
**********************/
|
||||
|
||||
struct page_frag_cache
|
||||
{
|
||||
bool pfmemalloc;
|
||||
};
|
||||
|
||||
/*****************
|
||||
** linux/gfp.h **
|
||||
*****************/
|
||||
|
||||
void *page_frag_alloc(struct page_frag_cache *nc,
|
||||
unsigned int fragsz, gfp_t gfp_mask);
|
||||
|
||||
void page_frag_free(void *addr);
|
||||
|
||||
/*********************
|
||||
** linux/if_vlan.h **
|
||||
*********************/
|
||||
|
||||
static inline bool eth_type_vlan(__be16 ethertype) { return false; }
|
||||
|
||||
/***********************
|
||||
** linux/interrupt.h **
|
||||
***********************/
|
||||
|
||||
#define IRQF_SHARED 0x00000080
|
||||
#define IRQF_ONESHOT 0x00002000
|
||||
|
||||
int request_threaded_irq(unsigned int irq, irq_handler_t handler,
|
||||
irq_handler_t thread_fn,
|
||||
unsigned long flags, const char *name, void *dev);
|
||||
|
||||
/*********************
|
||||
** linux/lockdep.h **
|
||||
*********************/
|
||||
|
||||
struct lockdep_map { };
|
||||
|
||||
#define mutex_release(l, n, i)
|
||||
|
||||
/*****************************
|
||||
** linux/mod_devicetable.h **
|
||||
*****************************/
|
||||
|
||||
#define MDIO_NAME_SIZE 32
|
||||
|
||||
/************************
|
||||
** linux/memcontrol.h **
|
||||
************************/
|
||||
|
||||
struct mem_cgroup;
|
||||
|
||||
#define mem_cgroup_sockets_enabled 0
|
||||
|
||||
static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) {
|
||||
return false; }
|
||||
|
||||
/***********************
|
||||
** linux/netdevice.h **
|
||||
***********************/
|
||||
|
||||
void __napi_schedule(struct napi_struct *n);
|
||||
|
||||
typedef struct sk_buff **(*gro_receive_t)(struct sk_buff **, struct sk_buff *);
|
||||
|
||||
struct sk_buff **call_gro_receive(gro_receive_t cb, struct sk_buff **head, struct sk_buff *skb);
|
||||
|
||||
void dev_consume_skb_any(struct sk_buff *skb);
|
||||
|
||||
bool napi_complete_done(struct napi_struct *n, int work_done);
|
||||
|
||||
bool napi_schedule_prep(struct napi_struct *n);
|
||||
|
||||
void skb_gro_flush_final(struct sk_buff *skb, struct sk_buff **pp, int flush);
|
||||
|
||||
/****************
|
||||
** linux/of.h **
|
||||
****************/
|
||||
|
||||
struct device_node
|
||||
{
|
||||
const char * full_name;
|
||||
struct fwnode_handle fwnode;
|
||||
};
|
||||
|
||||
#define of_fwnode_handle(node) \
|
||||
({ \
|
||||
typeof(node) __of_fwnode_handle_node = (node); \
|
||||
\
|
||||
__of_fwnode_handle_node ? \
|
||||
&__of_fwnode_handle_node->fwnode : NULL; \
|
||||
})
|
||||
|
||||
int of_machine_is_compatible(const char *compat);
|
||||
|
||||
bool of_property_read_bool(const struct device_node *np, const char *propname);
|
||||
|
||||
/***********************
|
||||
** linux/of_device.h **
|
||||
***********************/
|
||||
|
||||
int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
|
||||
|
||||
/*********************
|
||||
** linux/of_mdio.h **
|
||||
*********************/
|
||||
|
||||
int of_mdio_parse_addr(struct device *dev, const struct device_node *np);
|
||||
|
||||
void of_phy_deregister_fixed_link(struct device_node *np);
|
||||
|
||||
/*****************
|
||||
** linux/pci.h **
|
||||
*****************/
|
||||
|
||||
int dev_is_pci(struct device *dev);
|
||||
|
||||
struct pci_dev;
|
||||
|
||||
struct device_node * pci_device_to_OF_node(const struct pci_dev *pdev);
|
||||
|
||||
#define to_pci_dev(n) NULL
|
||||
|
||||
/******************************
|
||||
** linux/phy_led_triggers.h **
|
||||
******************************/
|
||||
|
||||
void phy_led_trigger_change_speed(struct phy_device *phy);
|
||||
|
||||
int phy_led_triggers_register(struct phy_device *phy);
|
||||
|
||||
void phy_led_triggers_unregister(struct phy_device *phy);
|
||||
|
||||
/*****************************
|
||||
** linux/platform_device.h **
|
||||
*****************************/
|
||||
|
||||
int platform_get_irq_byname(struct platform_device *dev, const char *name);
|
||||
|
||||
int platform_irq_count(struct platform_device *);
|
||||
|
||||
/************************
|
||||
** linux/pm_runtime.h **
|
||||
************************/
|
||||
|
||||
void pm_runtime_disable(struct device *dev);
|
||||
|
||||
int pm_runtime_put(struct device *dev);
|
||||
|
||||
/*********************
|
||||
** linux/preempt.h **
|
||||
*********************/
|
||||
|
||||
#define in_task() (1)
|
||||
|
||||
/**********************
|
||||
** linux/rcupdate.h **
|
||||
**********************/
|
||||
|
||||
#define rcu_assign_pointer(p, v) (p = v);
|
||||
|
||||
#define rcu_dereference_protected(p, c) p
|
||||
|
||||
/*************************
|
||||
** linux/scatterlist.h **
|
||||
*************************/
|
||||
|
||||
#define sg_is_last(sg) ((sg)->page_link & 0x02)
|
||||
|
||||
/**************************
|
||||
** linux/sched/signal.h **
|
||||
**************************/
|
||||
|
||||
unsigned long rlimit(unsigned int limit);
|
||||
|
||||
/************************
|
||||
** linux/sched/user.h **
|
||||
************************/
|
||||
|
||||
struct user_struct
|
||||
{
|
||||
atomic_long_t locked_vm;
|
||||
};
|
||||
|
||||
void free_uid(struct user_struct *);
|
||||
|
||||
struct user_struct *get_uid(struct user_struct *u);
|
||||
|
||||
/******************
|
||||
** linux/sctp.h **
|
||||
******************/
|
||||
|
||||
struct sctphdr
|
||||
{
|
||||
unsigned unused;
|
||||
};
|
||||
|
||||
struct kmem_cache *kmem_cache_create_usercopy(const char *name, size_t size,
|
||||
size_t align, slab_flags_t flags,
|
||||
size_t useroffset, size_t usersize,
|
||||
void (*ctor)(void *));
|
||||
|
||||
/******************
|
||||
** linux/slab.h **
|
||||
******************/
|
||||
|
||||
void *kcalloc(size_t n, size_t size, gfp_t flags);
|
||||
|
||||
void kmem_cache_free_bulk(struct kmem_cache *, size_t, void **);
|
||||
|
||||
/**********************
|
||||
** linux/spinlock.h **
|
||||
**********************/
|
||||
|
||||
int spin_is_locked(spinlock_t *lock);
|
||||
|
||||
/********************
|
||||
** linux/stddef.h **
|
||||
********************/
|
||||
|
||||
#define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER))
|
||||
|
||||
/*******************
|
||||
** linux/sysfs.h **
|
||||
*******************/
|
||||
|
||||
int sysfs_create_link(struct kobject *kobj, struct kobject *target, const char *name);
|
||||
|
||||
int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target, const char *name);
|
||||
|
||||
void sysfs_remove_link(struct kobject *kobj, const char *name);
|
||||
|
||||
/*************************
|
||||
** linux/thread_info.h **
|
||||
*************************/
|
||||
|
||||
static inline void check_object_size(const void *ptr, unsigned long n,
|
||||
bool to_user) { }
|
||||
|
||||
void __bad_copy_from(void);
|
||||
void __bad_copy_to(void);
|
||||
|
||||
static inline void copy_overflow(int size, unsigned long count)
|
||||
{
|
||||
WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count);
|
||||
}
|
||||
|
||||
static __always_inline bool
|
||||
check_copy_size(const void *addr, size_t bytes, bool is_source)
|
||||
{
|
||||
int sz = __compiletime_object_size(addr);
|
||||
if (unlikely(sz >= 0 && sz < bytes)) {
|
||||
if (!__builtin_constant_p(bytes))
|
||||
copy_overflow(sz, bytes);
|
||||
else if (is_source)
|
||||
__bad_copy_from();
|
||||
else
|
||||
__bad_copy_to();
|
||||
return false;
|
||||
}
|
||||
check_object_size(addr, bytes, is_source);
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************
|
||||
** linux/user_namespace.h **
|
||||
****************************/
|
||||
|
||||
struct user_namespace { };
|
||||
|
||||
/********************
|
||||
** linux/uidgid.h **
|
||||
********************/
|
||||
|
||||
kuid_t make_kuid(struct user_namespace *from, uid_t uid);
|
||||
|
||||
/*****************
|
||||
** linux/uio.h **
|
||||
*****************/
|
||||
|
||||
struct kvec
|
||||
{
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
|
||||
bool _copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i);
|
||||
|
||||
static __always_inline __must_check
|
||||
bool copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i)
|
||||
{
|
||||
if (unlikely(!check_copy_size(addr, bytes, false)))
|
||||
return false;
|
||||
else
|
||||
return _copy_from_iter_full(addr, bytes, i);
|
||||
}
|
||||
|
||||
bool copy_from_iter_full_nocache(void *addr, size_t bytes, struct iov_iter *i);
|
||||
|
||||
bool csum_and_copy_from_iter_full(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);
|
||||
|
||||
/******************
|
||||
** linux/wait.h **
|
||||
******************/
|
||||
|
||||
bool wq_has_sleeper(struct wait_queue_head *wq_head);
|
||||
|
||||
/********************
|
||||
** net/checksum.h **
|
||||
********************/
|
||||
|
||||
static inline __wsum
|
||||
csum_block_sub(__wsum csum, __wsum csum2, int offset)
|
||||
{
|
||||
return csum_block_add(csum, ~csum2, offset);
|
||||
}
|
||||
|
||||
static inline __wsum csum_unfold(__sum16 n)
|
||||
{
|
||||
return (__force __wsum)n;
|
||||
}
|
||||
|
||||
/**************************
|
||||
** net/flow_dissector.h **
|
||||
**************************/
|
||||
|
||||
#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG BIT(0)
|
||||
|
||||
/*************************
|
||||
** net/net_namespace.h **
|
||||
*************************/
|
||||
|
||||
struct net;
|
||||
|
||||
/******************
|
||||
** net/l3mdev.h **
|
||||
******************/
|
||||
|
||||
int l3mdev_master_ifindex_by_index(struct net *net, int ifindex);
|
||||
|
||||
/*********************
|
||||
** net/pkt_sched.h **
|
||||
*********************/
|
||||
|
||||
#define DEFAULT_TX_QUEUE_LEN 1000
|
||||
|
||||
/***********************
|
||||
** soc/imx/cpuidle.h **
|
||||
***********************/
|
||||
|
||||
static inline void imx6q_cpuidle_fec_irqs_used(void) { }
|
||||
static inline void imx6q_cpuidle_fec_irqs_unused(void) { }
|
||||
|
||||
/*************************
|
||||
** trace/events/mdio.h **
|
||||
*************************/
|
||||
|
||||
void trace_mdio_access(void *dummy, ...);
|
||||
|
||||
/*********************************
|
||||
** uapi/asm-generic/resource.h **
|
||||
*********************************/
|
||||
|
||||
# define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
|
||||
|
||||
/*****************************
|
||||
** uapi/linux/capability.h **
|
||||
*****************************/
|
||||
|
||||
#define CAP_IPC_LOCK 14
|
||||
|
||||
/*************************
|
||||
** uapi/linux/kernel.h **
|
||||
*************************/
|
||||
|
||||
#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
|
||||
|
||||
/******************************
|
||||
** uapi/linux/libc-compat.h **
|
||||
******************************/
|
||||
|
||||
#define __UAPI_DEF_IF_IFMAP 1
|
||||
#define __UAPI_DEF_IF_IFNAMSIZ 1
|
||||
#define __UAPI_DEF_IF_IFREQ 1
|
||||
#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
|
||||
|
||||
/************************
|
||||
** uapi/linux/types.h **
|
||||
************************/
|
||||
|
||||
typedef unsigned __poll_t;
|
||||
|
||||
/************************/
|
||||
|
||||
#define DECLARE_BITMAP(name,bits) \
|
||||
unsigned long name[BITS_TO_LONGS(bits)]
|
||||
|
||||
#include <uapi/linux/if_ether.h>
|
||||
#include <uapi/linux/if_packet.h>
|
||||
#include <uapi/linux/ethtool.h>
|
||||
|
@ -727,30 +1203,6 @@ bool device_may_wakeup(struct device *dev);
|
|||
int enable_irq_wake(unsigned int irq);
|
||||
int disable_irq_wake(unsigned int irq);
|
||||
|
||||
struct ethtool_ops {
|
||||
int(*get_settings)(struct net_device *, struct ethtool_cmd *);
|
||||
int(*set_settings)(struct net_device *, struct ethtool_cmd *);
|
||||
void(*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *);
|
||||
int(*get_regs_len)(struct net_device *);
|
||||
void(*get_regs)(struct net_device *, struct ethtool_regs *, void *);
|
||||
void(*get_wol)(struct net_device *, struct ethtool_wolinfo *);
|
||||
int(*set_wol)(struct net_device *, struct ethtool_wolinfo *);
|
||||
int(*nway_reset)(struct net_device *);
|
||||
u32(*get_link)(struct net_device *);
|
||||
int(*get_coalesce)(struct net_device *, struct ethtool_coalesce *);
|
||||
int(*set_coalesce)(struct net_device *, struct ethtool_coalesce *);
|
||||
void(*get_pauseparam)(struct net_device *, struct ethtool_pauseparam*);
|
||||
int(*set_pauseparam)(struct net_device *, struct ethtool_pauseparam*);
|
||||
void(*get_strings)(struct net_device *, u32 stringset, u8 *);
|
||||
void(*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *);
|
||||
int(*get_sset_count)(struct net_device *, int);
|
||||
int(*get_ts_info)(struct net_device *, struct ethtool_ts_info *);
|
||||
int(*get_tunable)(struct net_device *,
|
||||
const struct ethtool_tunable *, void *);
|
||||
int(*set_tunable)(struct net_device *,
|
||||
const struct ethtool_tunable *, const void *);
|
||||
};
|
||||
|
||||
u32 ethtool_op_get_link(struct net_device *);
|
||||
|
||||
void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
|
||||
|
@ -764,10 +1216,6 @@ int pinctrl_pm_select_sleep_state(struct device *dev);
|
|||
|
||||
void netif_tx_disable(struct net_device *dev);
|
||||
|
||||
#include <lx_emul/list.h>
|
||||
|
||||
#define rcu_assign_pointer(p, v) (p = v);
|
||||
|
||||
#include <linux/rculist.h>
|
||||
|
||||
#define netdev_hw_addr_list_for_each(ha, l) \
|
||||
|
@ -899,8 +1347,6 @@ typedef int rwlock_t;
|
|||
|
||||
bool gfp_pfmemalloc_allowed(gfp_t);
|
||||
|
||||
struct user_namespace {};
|
||||
|
||||
struct cred {
|
||||
struct user_namespace * user_ns;
|
||||
};
|
||||
|
@ -909,7 +1355,10 @@ struct file {
|
|||
const struct cred * f_cred;
|
||||
};
|
||||
|
||||
struct net;
|
||||
struct net
|
||||
{
|
||||
struct user_namespace * user_ns;
|
||||
};
|
||||
|
||||
struct percpu_counter {
|
||||
s64 count;
|
||||
|
@ -975,9 +1424,6 @@ struct net *dev_net(const struct net_device *dev);
|
|||
|
||||
#define read_pnet(pnet) (&init_net)
|
||||
|
||||
#define DECLARE_BITMAP(name,bits) \
|
||||
unsigned long name[BITS_TO_LONGS(bits)]
|
||||
|
||||
void bitmap_fill(unsigned long *dst, int nbits);
|
||||
void bitmap_zero(unsigned long *dst, int nbits);
|
||||
|
||||
|
@ -1041,7 +1487,10 @@ void page_counter_uncharge(struct page_counter *counter, unsigned long nr_pages)
|
|||
|
||||
enum { UNDER_LIMIT, SOFT_LIMIT, OVER_LIMIT };
|
||||
|
||||
struct inode {};
|
||||
struct inode
|
||||
{
|
||||
kuid_t i_uid;
|
||||
};
|
||||
|
||||
struct vm_area_struct;
|
||||
|
||||
|
@ -1097,11 +1546,6 @@ struct page *virt_to_head_page(const void *x);
|
|||
typeof(type) name
|
||||
#define this_cpu_ptr(ptr) ptr
|
||||
|
||||
struct page_frag_cache
|
||||
{
|
||||
bool pfmemalloc;
|
||||
};
|
||||
|
||||
void *__alloc_page_frag(struct page_frag_cache *nc, unsigned int fragsz, gfp_t gfp_mask);
|
||||
|
||||
unsigned long local_irq_save(unsigned long flags);
|
||||
|
@ -1170,7 +1614,10 @@ void sg_mark_end(struct scatterlist *sg);
|
|||
void sg_set_buf(struct scatterlist *, const void *, unsigned int);
|
||||
void sg_set_page(struct scatterlist *, struct page *, unsigned int, unsigned int);
|
||||
|
||||
struct inet_skb_parm { };
|
||||
struct inet_skb_parm
|
||||
{
|
||||
int iif;
|
||||
};
|
||||
|
||||
enum {
|
||||
IPPROTO_IP = 0,
|
||||
|
@ -1374,10 +1821,6 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
|
|||
for (child = of_get_next_available_child(parent, NULL); child != NULL; \
|
||||
child = of_get_next_available_child(parent, child))
|
||||
|
||||
u32 mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap);
|
||||
u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv);
|
||||
u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv);
|
||||
|
||||
int driver_register(struct device_driver *drv);
|
||||
void driver_unregister(struct device_driver *drv);
|
||||
|
||||
|
@ -1401,9 +1844,10 @@ static inline bool is_multicast_ether_addr_64bits(const u8 addr[6+2])
|
|||
|
||||
static inline bool ether_addr_equal_64bits(const u8 addr1[6+2], const u8 addr2[6+2])
|
||||
{
|
||||
u64 fold = (*(const u64 *)addr1) ^ (*(const u64 *)addr2);
|
||||
const u16 *a = (const u16 *)addr1;
|
||||
const u16 *b = (const u16 *)addr2;
|
||||
|
||||
return (fold << 16) == 0;
|
||||
return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) == 0;
|
||||
}
|
||||
|
||||
static inline bool eth_proto_is_802_3(__be16 proto)
|
||||
|
@ -1483,6 +1927,7 @@ void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp);
|
|||
struct pm_qos_request {};
|
||||
|
||||
#define dma_wmb() __asm__ __volatile__ ("dmb oshst" : : : "memory")
|
||||
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
|
||||
#endif /* _SRC__DRIVERS__NIC__FEC__LX_EMUL_H_ */
|
||||
|
|
|
@ -29,16 +29,17 @@ CC_C_OPT += -std=gnu89
|
|||
#
|
||||
# Reduce build noise of compiling contrib code
|
||||
#
|
||||
CC_OPT_fec_ptp = -Wno-unused-but-set-variable -Wno-unused-variable \
|
||||
-Wno-maybe-uninitialized -Wno-uninitialized
|
||||
CC_OPT_fec_main = -Wno-unused-but-set-variable -Wno-unused-variable \
|
||||
-Wno-pointer-sign -Wno-int-conversion -Wno-unused-function \
|
||||
-Wno-uninitialized
|
||||
CC_OPT_skbuff = -Wno-pointer-sign -Wno-int-conversion -Wno-uninitialized
|
||||
CC_OPT_mdio_bus = -Wno-implicit-int -Wno-unused-function -Wno-pointer-sign
|
||||
CC_OPT_eth = -Wno-pointer-sign -Wno-unused-function
|
||||
CC_OPT_phy = -Wno-unused-function -Wno-unused-but-set-variable
|
||||
CC_OPT_at803x = -Wno-unused-variable
|
||||
CC_OPT_fec_ptp = -Wno-unused-but-set-variable -Wno-unused-variable \
|
||||
-Wno-maybe-uninitialized -Wno-uninitialized
|
||||
CC_OPT_fec_main = -Wno-unused-but-set-variable -Wno-unused-variable \
|
||||
-Wno-pointer-sign -Wno-int-conversion -Wno-unused-function \
|
||||
-Wno-uninitialized
|
||||
CC_OPT_skbuff = -Wno-pointer-sign -Wno-int-conversion -Wno-uninitialized
|
||||
CC_OPT_mdio_bus = -Wno-implicit-int -Wno-unused-function -Wno-pointer-sign
|
||||
CC_OPT_eth = -Wno-pointer-sign -Wno-unused-function
|
||||
CC_OPT_phy = -Wno-unused-function -Wno-unused-but-set-variable
|
||||
CC_OPT_phy_device = -Wno-unused-function
|
||||
CC_OPT_at803x = -Wno-unused-variable
|
||||
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/net/ethernet/freescale
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/net/phy
|
||||
|
|
|
@ -258,7 +258,7 @@ int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
|
|||
*********************/
|
||||
|
||||
int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) { TRACE; return 0; }
|
||||
char *kobject_name(const struct kobject *kobj) { TRACE; return 0; }
|
||||
const char *kobject_name(const struct kobject *kobj) { TRACE; return 0; }
|
||||
char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) { TRACE; return 0; }
|
||||
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@ int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
|
|||
*********************/
|
||||
|
||||
int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) { TRACE; return 0; }
|
||||
char *kobject_name(const struct kobject *kobj) { TRACE; return 0; }
|
||||
const char *kobject_name(const struct kobject *kobj) { TRACE; return 0; }
|
||||
char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) { TRACE; return 0; }
|
||||
|
||||
|
||||
|
|
|
@ -70,6 +70,10 @@
|
|||
#define smp_read_barrier_depends() do { } while (0)
|
||||
#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); barrier(); } while (0)
|
||||
|
||||
#ifndef __compiletime_object_size
|
||||
# define __compiletime_object_size(obj) -1
|
||||
#endif
|
||||
|
||||
/**************************
|
||||
** linux/compiler-gcc.h **
|
||||
**************************/
|
||||
|
@ -78,6 +82,8 @@
|
|||
#define __packed __attribute__((packed))
|
||||
#endif
|
||||
|
||||
#define __weak __attribute__((weak))
|
||||
|
||||
#define __aligned(x) __attribute__((aligned(x)))
|
||||
|
||||
#define uninitialized_var(x) x = x
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#define __is_defined(x) ___is_defined(x)
|
||||
#define IS_BUILTIN(option) __is_defined(option)
|
||||
#define IS_ENABLED(option) IS_BUILTIN(option)
|
||||
#define IS_REACHABLE(option) IS_BUILTIN(option)
|
||||
|
||||
/********************
|
||||
** linux/kernel.h **
|
||||
|
|
|
@ -52,6 +52,6 @@ struct kobj_uevent_env;
|
|||
|
||||
int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
|
||||
void kobject_put(struct kobject *);
|
||||
char *kobject_name(const struct kobject *kobj);
|
||||
const char *kobject_name(const struct kobject *kobj);
|
||||
char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask);
|
||||
struct kobject * kobject_create_and_add(const char *, struct kobject *);
|
||||
|
|
5
repos/gems/lib/mk/vfs_trace.mk
Normal file
5
repos/gems/lib/mk/vfs_trace.mk
Normal file
|
@ -0,0 +1,5 @@
|
|||
SRC_CC = vfs.cc
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/vfs/trace
|
||||
|
||||
SHARED_LIB = yes
|
|
@ -1,8 +1,15 @@
|
|||
<runtime ram="40M" caps="1000" binary="init" config="wm.config">
|
||||
|
||||
<requires> <nitpicker/> <timer/> </requires>
|
||||
<requires>
|
||||
<nitpicker label="focus"/>
|
||||
<nitpicker/>
|
||||
<report label="shape"/>
|
||||
<report label="clipboard"/>
|
||||
<rom label="clipboard"/>
|
||||
<timer/>
|
||||
</requires>
|
||||
|
||||
<provides> <nitpicker/> </provides>
|
||||
<provides> <nitpicker/> <report/> <rom/> </provides>
|
||||
|
||||
<content>
|
||||
<rom label="ld.lib.so"/>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
|
||||
=====================================
|
||||
Sculpt as a community experience (CE)
|
||||
=====================================
|
||||
=============================
|
||||
Sculpt Operating System 19.07
|
||||
=============================
|
||||
|
||||
|
||||
Norman Feske
|
||||
|
@ -58,13 +58,13 @@ Your feedback is appreciated!
|
|||
[https://www.genode-labs.com]
|
||||
|
||||
A printable PDF version of this document is available at
|
||||
[https://genode.org/documentation/sculpt-ce.pdf].
|
||||
[https://genode.org/documentation/sculpt-19-07.pdf].
|
||||
|
||||
|
||||
Hardware requirements and preparations
|
||||
######################################
|
||||
|
||||
Sculpt CE should be compatible with recent Intel-based PC hardware featuring
|
||||
Sculpt should be compatible with recent Intel-based PC hardware featuring
|
||||
Intel graphics, E1000 networking, Intel wireless, and AHCI/NVMe.
|
||||
|
||||
It is tested best on laptops of the Lenovo X and T series (X220, X250, X260,
|
||||
|
@ -185,16 +185,21 @@ information along with the option to remove it from the system.
|
|||
|
||||
As a next step, let us add a window system. In the '+' menu, you can find
|
||||
a readily packaged window system at _genodelabs_ -> _GUI_ -> _themed wm_.
|
||||
After installing the package, you are asked to take three decisions:
|
||||
After installing the package, you are asked to take five decisions:
|
||||
|
||||
The _GUI (focus)_ should be assigned to "keyboard focus" to put the
|
||||
window manager in charge of controlling the keyboard focus, which is part
|
||||
of its job after all.
|
||||
The _GUI_ should be assigned to "system GUI server" as the basic mechanism
|
||||
to be used for graphical output and user input for the windowed applications.
|
||||
Finally, by assigning _Report_ to _system reports_, we allow the window
|
||||
By assigning _Report (shape)_ to _pointer shape_, we allow the window
|
||||
manager to report information about mouse-pointer shapes.
|
||||
By adding the component, the "themed wm" will appear in the runtime view.
|
||||
By assigning _Report (clipboard)_ to _global clipboard_, we grant the
|
||||
window manager the right to change the content of the global clipboard.
|
||||
Vice versa, by assigning _ROM (clipboard)_, we permit the window manager
|
||||
to obtain clipboard content.
|
||||
|
||||
After adding the component, the "themed wm" will appear in the runtime view.
|
||||
To give the window system a quick try, add the small demo you can find at
|
||||
_genodelabs_ -> _Demos_ -> _nano3d_ and assign its _GUI_ to our "themed wm".
|
||||
|
||||
|
@ -238,6 +243,14 @@ dialog is a bit more elaborate this time.
|
|||
within the instance. Select "default vim configuration" to grant
|
||||
read-only access to this information.
|
||||
|
||||
:ROM (clipboard): defines the service to obtain clipboard content from.
|
||||
Select "themed wm" (not "global clipboard").
|
||||
|
||||
:Report (clipboard): defines the service for reporting new clipboard content.
|
||||
Select "themed wm". More information about the integration and use of the
|
||||
clipboard can be found in
|
||||
[https://genodians.org/nfeske/2019-07-03-copy-paste - a dedicated article].
|
||||
|
||||
With those decisions taken, a fresh noux runtime can be started, which appears
|
||||
in a window.
|
||||
|
||||
|
@ -261,6 +274,13 @@ Of course, there are many more components to explore and to combine.
|
|||
For inspiration, please follow the postings at
|
||||
[https://genodians.org], for example:
|
||||
|
||||
:Copy and paste mechanism:
|
||||
|
||||
Sculpt provides a built-in mechanism for exchanging data between
|
||||
virtual machines, terminals, and Qt applications:
|
||||
|
||||
[https://genodians.org/nfeske/2019-07-03-copy-paste]
|
||||
|
||||
:Use GNU/Linux inside a virtual machine on top of Sculpt:
|
||||
|
||||
There is a ready-to-use package for downloading Debian for the use inside
|
||||
|
@ -440,9 +460,9 @@ the running system using a command-line interface and the Vim text editor.
|
|||
Vim skills recommended
|
||||
----------------------
|
||||
|
||||
Sculpt CE leverages (a subset of) GNU coreutils, bash, and Vim as the user
|
||||
Sculpt leverages (a subset of) GNU coreutils, bash, and Vim as the user
|
||||
interface for sculpting the system. If you are not yet familiar with using
|
||||
Vim, you may take Sculpt CE as a welcome chance to get your toes wet. To
|
||||
Vim, you may take Sculpt as a welcome chance to get your toes wet. To
|
||||
enjoy the experience, you should be comfortable with the following
|
||||
operations:
|
||||
|
||||
|
@ -586,8 +606,14 @@ as options.
|
|||
| | platform information
|
||||
----------------------------------------------------------------------------
|
||||
| | system status
|
||||
----------------------------------------------------------------------------
|
||||
| | global clipboard
|
||||
----------------------------------------------------------------------------
|
||||
Report | 'Report' | system reports
|
||||
----------------------------------------------------------------------------
|
||||
| | pointer shape
|
||||
----------------------------------------------------------------------------
|
||||
| | global clipboard
|
||||
----------------------------------------------------------------------------
|
||||
File system | 'File_system' | writeable system configuration
|
||||
----------------------------------------------------------------------------
|
||||
|
@ -708,6 +734,11 @@ the following built-in ROM resources:
|
|||
optional ACPICA driver to respond to requests for a system reset or
|
||||
power-down.
|
||||
|
||||
:global clipboard: provides the current content of the global clipboard.
|
||||
The content can be accessed by a component only when the user interacts
|
||||
with the component. This prevents overly nosey components from snooping the
|
||||
clipboard content.
|
||||
|
||||
|
||||
Report
|
||||
~~~~~~
|
||||
|
@ -723,10 +754,16 @@ keep in mind that Sculpt's built-in report file system is limited in size.
|
|||
A misbehaving component may put the system in jeopardy by producing overly
|
||||
sized reports.
|
||||
|
||||
Reports labeled with 'shape' play a special role. They are routed to the mouse
|
||||
pointer and thereby enable graphical applications to suggest context-specific
|
||||
pointer shapes. The application-provided shape is shown whenever the
|
||||
corresponding application is hovered.
|
||||
:pointer shape: Reports labeled with 'shape' play a special role.
|
||||
They are routed to the mouse pointer and thereby enable graphical
|
||||
applications to suggest context-specific pointer shapes. The
|
||||
application-provided shape is shown whenever the corresponding application
|
||||
is hovered.
|
||||
|
||||
:global clipboard: enables components to write new content to the
|
||||
system-global clipboard. This operation, however, is restricted to the
|
||||
single component that the user currently interacts with. This prevents
|
||||
rogue components from spamming the global clipboard.
|
||||
|
||||
|
||||
File system
|
||||
|
@ -1123,26 +1160,26 @@ a free download at [https://genode.org].
|
|||
|
||||
# Download the support for the NOVA microkernel
|
||||
|
||||
! ./tool/depot/download genodelabs/bin/x86_64/base-nova/2019-03-17
|
||||
! ./tool/depot/download genodelabs/bin/x86_64/base-nova/2019-07-08
|
||||
|
||||
The content is downloaded to the _public/_ directory and extracted to
|
||||
the _depot/_ directory.
|
||||
|
||||
# Download all ingredients for the Sculpt boot image
|
||||
|
||||
! ./tool/depot/download genodelabs/pkg/x86_64/sculpt/2019-03-19
|
||||
! ./tool/depot/download genodelabs/pkg/x86_64/sculpt/2019-07-08
|
||||
|
||||
# Create a build directory
|
||||
|
||||
! ./tool/create_builddir x86_64
|
||||
|
||||
# Configure the build directory by editing _build/x86_64/etc/build.conf_.
|
||||
Most importantly, enable the 'gems' source-code repository where the
|
||||
Sculpt scenario resides. In addition, the 'ports', 'dde_linux' and 'dde_ipxe'
|
||||
repository are needed as well. Second, change the default configuration
|
||||
of the 'QEMU_RUN_OPT' variable to 'image/disk' instead of 'image/iso'.
|
||||
This way, the build process will produce a valid disk image with a GPT
|
||||
partition table instead of a legacy ISO image.
|
||||
Most importantly, enable the 'gems' source-code repository where the Sculpt
|
||||
scenario resides. In addition, the 'libports', 'ports', 'dde_linux' and
|
||||
'dde_ipxe' repository are needed as well. Second, change the default
|
||||
configuration of the 'QEMU_RUN_OPT' variable to 'image/disk' instead of
|
||||
'image/iso'. This way, the build process will produce a valid disk image
|
||||
with a GPT partition table instead of a legacy ISO image.
|
||||
|
||||
# Create the Sculpt boot image (defined by the run script at
|
||||
_repos/gems/run/sculpt.run_)
|
||||
|
@ -1170,12 +1207,13 @@ Before building the packages, various ports of 3rd-party software need to
|
|||
be prepared. The following command prepares all of them at once:
|
||||
|
||||
! <GENODE-DIR>/tool/ports/prepare_port \
|
||||
! bash coreutils curl dde_ipxe dde_linux \
|
||||
! dde_rump e2fsprogs gnupg grub2 jitterentropy \
|
||||
! libarchive libc libgcrypt libiconv libssh \
|
||||
! lwip_legacy ncurses nova openssl qemu-usb \
|
||||
! stdcxx vim virtualbox5 x86emu xz zlib libpng \
|
||||
! ttf-bitstream-vera stb
|
||||
! acpica bash coreutils curl dde_ipxe dde_linux \
|
||||
! dde_rump drm e2fsprogs expat freetype gnupg \
|
||||
! jitterentropy jpeg libarchive libc libgcrypt \
|
||||
! libiconv libpng libssh mesa ncurses nova openssl \
|
||||
! pcre qemu-usb qoost qt5 stb stdcxx \
|
||||
! ttf-bitstream-vera vim virtualbox5 x86emu xz \
|
||||
! zlib
|
||||
|
||||
The ingredients of the boot image are subsumed by the 'pkg/sculpt' package.
|
||||
The default set of software installed by the update runtime is defined by
|
||||
|
@ -1208,6 +1246,14 @@ to those that do not yet exist in binary form. If not specified, the
|
|||
command would recompile all packages each time. You may further add '-j<N>'
|
||||
to parallelize the build process where '<N>' is the level of parallelism.
|
||||
|
||||
Alternatively to managing the depot manually, you may choose to let the build
|
||||
system manage the versioning and updating of the depot content automatically
|
||||
by enabling the following line in your _build.conf_ file. This slows down
|
||||
the build time a bit but ensures that the depot content is consistent with
|
||||
your source tree at all times.
|
||||
|
||||
! RUN_OPT += --depot-auto-update
|
||||
|
||||
Building the 'sculpt-installation' package works analogously to the 'sculpt'
|
||||
package.
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ _/pkg/wifi
|
|||
_/pkg/depot_download
|
||||
_/pkg/terminal
|
||||
_/src/report_rom
|
||||
_/src/clipboard
|
||||
_/src/init
|
||||
_/src/ram_fs
|
||||
_/src/fs_rom
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
<requires>
|
||||
<nitpicker label="focus"/>
|
||||
<nitpicker/>
|
||||
<report/>
|
||||
<report label="shape"/>
|
||||
<report label="clipboard"/>
|
||||
<rom label="clipboard"/>
|
||||
<timer/>
|
||||
</requires>
|
||||
|
||||
<provides> <nitpicker/> <report/> </provides>
|
||||
<provides> <nitpicker/> <report/> <rom/> </provides>
|
||||
|
||||
<content>
|
||||
<rom label="ld.lib.so"/>
|
||||
|
|
1
repos/gems/recipes/pkg/trace_fs/README
Normal file
1
repos/gems/recipes/pkg/trace_fs/README
Normal file
|
@ -0,0 +1 @@
|
|||
File system for providing access to Genode tracing
|
3
repos/gems/recipes/pkg/trace_fs/archives
Normal file
3
repos/gems/recipes/pkg/trace_fs/archives
Normal file
|
@ -0,0 +1,3 @@
|
|||
_/src/trace_policy
|
||||
_/src/vfs
|
||||
_/src/vfs_trace
|
1
repos/gems/recipes/pkg/trace_fs/hash
Normal file
1
repos/gems/recipes/pkg/trace_fs/hash
Normal file
|
@ -0,0 +1 @@
|
|||
2019-07-08 e96823d8956e3a27b07dfe8936a58e7dfda0e228
|
19
repos/gems/recipes/pkg/trace_fs/runtime
Normal file
19
repos/gems/recipes/pkg/trace_fs/runtime
Normal file
|
@ -0,0 +1,19 @@
|
|||
<runtime ram="48M" caps="150" binary="vfs">
|
||||
|
||||
<provides> <file_system/> </provides>
|
||||
<requires> <trace/> </requires>
|
||||
|
||||
<content>
|
||||
<rom label="vfs"/>
|
||||
<rom label="ld.lib.so"/>
|
||||
<rom label="vfs_trace.lib.so"/>
|
||||
<rom label="vfs.lib.so"/>
|
||||
<rom label="null"/>
|
||||
</content>
|
||||
|
||||
<config>
|
||||
<vfs> <trace ram="32M"/> </vfs>
|
||||
<default-policy root="/" writeable="yes"/>
|
||||
</config>
|
||||
|
||||
</runtime>
|
|
@ -3,7 +3,9 @@
|
|||
<requires>
|
||||
<nitpicker label="focus"/>
|
||||
<nitpicker/>
|
||||
<report/>
|
||||
<report label="shape"/>
|
||||
<report label="clipboard"/>
|
||||
<rom label="clipboard"/>
|
||||
<timer/>
|
||||
</requires>
|
||||
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
<default-policy> <child name="wm"/> </default-policy>
|
||||
</service>
|
||||
|
||||
<service name="Report"> <!-- for reporting 'shape' reports through the wm -->
|
||||
<service name="Report"> <!-- for reporting 'shape' and 'clipboard' reports through the wm -->
|
||||
<default-policy> <child name="wm"/> </default-policy>
|
||||
</service>
|
||||
|
||||
<service name="ROM"> <!-- for accessing 'clipboard' ROMs through the wm -->
|
||||
<default-policy> <child name="wm"/> </default-policy>
|
||||
</service>
|
||||
|
||||
|
@ -45,7 +49,7 @@
|
|||
<start name="wm" caps="250">
|
||||
<resource name="RAM" quantum="6M"/>
|
||||
<provides>
|
||||
<service name="Nitpicker"/> <service name="Report"/>
|
||||
<service name="Nitpicker"/> <service name="Report"/> <service name="ROM"/>
|
||||
</provides>
|
||||
<config>
|
||||
<policy label_prefix="decorator" role="decorator"/>
|
||||
|
@ -56,6 +60,8 @@
|
|||
<service name="ROM" label="resize_request"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="focus"> <child name="report_rom"/> </service>
|
||||
<service name="Report" label_last="shape"> <parent/> </service>
|
||||
<service name="Report" label_last="clipboard"> <parent/> </service>
|
||||
<service name="ROM" label_last="clipboard"> <parent/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="Nitpicker" label=""> <parent label="focus"/> </service>
|
||||
<any-service>
|
||||
|
@ -75,9 +81,9 @@
|
|||
<service name="ROM" label="decorator_margins"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="rules"> <child name="report_rom"/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<any-service>
|
||||
<child name="wm"/> <parent/> <any-child/>
|
||||
</any-service>
|
||||
<service name="Nitpicker"> <child name="wm"/> </service>
|
||||
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
|
@ -92,10 +98,9 @@
|
|||
<service name="ROM" label="pointer"> <child name="report_rom"/> </service>
|
||||
<service name="Report" label="decorator_margins"> <child name="report_rom"/> </service>
|
||||
<service name="Report" label="hover"> <child name="report_rom"/> </service>
|
||||
<service name="Nitpicker"> <child name="wm"/> </service>
|
||||
|
||||
<any-service>
|
||||
<child name="wm"/> <parent/> <any-child/>
|
||||
</any-service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
</config>
|
||||
|
|
|
@ -20,36 +20,39 @@
|
|||
</service>
|
||||
|
||||
<service name="ROM">
|
||||
<policy label_suffix="layouter -> window_list">
|
||||
<policy label_suffix=" -> window_list">
|
||||
<child name="report_rom" label="layouter -> window_list"/> </policy>
|
||||
<policy label_suffix="layouter -> focus_request">
|
||||
<policy label_suffix=" -> focus_request">
|
||||
<child name="report_rom" label="layouter -> focus_request"/> </policy>
|
||||
<policy label_suffix="layouter -> hover">
|
||||
<policy label_suffix=" -> hover">
|
||||
<child name="report_rom" label="layouter -> hover"/> </policy>
|
||||
<policy label_suffix="layouter -> decorator_margins">
|
||||
<policy label_suffix=" -> decorator_margins">
|
||||
<child name="report_rom" label="layouter -> decorator_margins"/> </policy>
|
||||
<policy label_suffix="layouter -> rules">
|
||||
<policy label_suffix=" -> rules">
|
||||
<child name="report_rom" label="layouter -> rules"/> </policy>
|
||||
<policy label_suffix="decorator -> window_layout">
|
||||
<policy label_suffix=" -> window_layout">
|
||||
<child name="report_rom" label="decorator -> window_layout"/> </policy>
|
||||
<policy label_suffix="decorator -> pointer">
|
||||
<policy label_suffix=" -> pointer">
|
||||
<child name="report_rom" label="decorator -> pointer"/> </policy>
|
||||
<policy label_suffix=" -> clipboard">
|
||||
<child name="wm"/> </policy>
|
||||
</service>
|
||||
|
||||
<service name="Report">
|
||||
<policy label_suffix="layouter -> window_layout">
|
||||
<policy label_suffix=" -> window_layout">
|
||||
<child name="report_rom" label="layouter -> window_layout"/> </policy>
|
||||
<policy label_suffix="layouter -> resize_request">
|
||||
<policy label_suffix=" -> resize_request">
|
||||
<child name="report_rom" label="layouter -> resize_request"/> </policy>
|
||||
<policy label_suffix="layouter -> focus">
|
||||
<policy label_suffix=" -> focus">
|
||||
<child name="report_rom" label="layouter -> focus"/> </policy>
|
||||
<policy label_suffix="layouter -> rules">
|
||||
<policy label_suffix=" -> rules">
|
||||
<child name="report_rom" label="layouter -> rules"/> </policy>
|
||||
<policy label_suffix="decorator -> hover">
|
||||
<policy label_suffix=" -> hover">
|
||||
<child name="report_rom" label="decorator -> hover"/> </policy>
|
||||
<policy label_suffix="decorator -> decorator_margins">
|
||||
<policy label_suffix=" -> decorator_margins">
|
||||
<child name="report_rom" label="decorator -> decorator_margins"/> </policy>
|
||||
<policy label_suffix="-> shape"> <child name="wm"/> </policy>
|
||||
<policy label_suffix=" -> shape"> <child name="wm"/> </policy>
|
||||
<policy label_suffix=" -> clipboard"> <child name="wm"/> </policy>
|
||||
</service>
|
||||
|
||||
<start name="report_rom">
|
||||
|
@ -74,7 +77,7 @@
|
|||
<start name="wm" caps="250">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides>
|
||||
<service name="Nitpicker"/> <service name="Report"/>
|
||||
<service name="Nitpicker"/> <service name="Report"/> <service name="ROM"/>
|
||||
</provides>
|
||||
<config>
|
||||
<policy label_suffix="decorator -> " role="decorator"/>
|
||||
|
@ -84,8 +87,10 @@
|
|||
<route>
|
||||
<service name="ROM" label="resize_request"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="focus"> <child name="report_rom"/> </service>
|
||||
<service name="Report" label_last="shape"> <parent/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label_last="clipboard"> <parent/> </service>
|
||||
<service name="Report" label_last="clipboard"> <parent/> </service>
|
||||
<service name="Report" label_last="shape"> <parent/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="Nitpicker" label=""> <parent label="focus"/> </service>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>
|
||||
|
|
|
@ -153,6 +153,13 @@ install_config {
|
|||
<service name="Timer"> <parent/> </service>
|
||||
</common_routes>
|
||||
|
||||
<start name="recall_fs" pkg="} [depot_user]/pkg/[current_pkg chroot] {">
|
||||
<route>
|
||||
<service name="File_system"> <parent/> </service>
|
||||
</route>
|
||||
<config> <default-policy path_prefix="/recall" writeable="yes"/> </config>
|
||||
</start>
|
||||
|
||||
<start name="wm" pkg="} [depot_user]/pkg/[current_pkg wm] {">
|
||||
<route>
|
||||
<service name="Nitpicker"> <parent/> </service>
|
||||
|
@ -168,6 +175,7 @@ install_config {
|
|||
<service name="ROM" label="rules"> <child name="wm"/> </service>
|
||||
<service name="Report"> <child name="wm"/> </service>
|
||||
<service name="Nitpicker"> <child name="wm"/> </service>
|
||||
<service name="File_system" label="recall"> <child name="recall_fs"/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
|
@ -180,7 +188,6 @@ install_config {
|
|||
</route>
|
||||
</start>
|
||||
|
||||
|
||||
<start name="backdrop" pkg="} [depot_user]/pkg/[current_pkg sticks_blue_backdrop] {">
|
||||
<route>
|
||||
<service name="Nitpicker"> <parent label="backdrop"/> </service>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
create_boot_directory
|
||||
|
||||
if {[have_spec linux] || [have_spec imx7d_sabre] ||
|
||||
if {[have_spec linux] || [have_spec rpi3] ||
|
||||
[expr [have_spec imx53] && [have_spec trustzone]]} {
|
||||
puts "Run script does not support this platform."
|
||||
exit 0
|
||||
|
|
|
@ -143,7 +143,7 @@ install_config {
|
|||
<start name="wm" caps="200">
|
||||
<resource name="RAM" quantum="6M"/>
|
||||
<provides>
|
||||
<service name="Nitpicker"/> <service name="Report"/>
|
||||
<service name="Nitpicker"/> <service name="Report"/> <service name="ROM"/>
|
||||
</provides>
|
||||
<config>
|
||||
<policy label_prefix="decorator" role="decorator"/>
|
||||
|
|
|
@ -61,6 +61,7 @@ install_config {
|
|||
<policy label="pointer -> xray"
|
||||
report="global_keys_handler -> leitzentrale"/>
|
||||
<policy label="pointer -> shape" report="shape"/>
|
||||
<policy label="clipboard -> focus" report="nitpicker -> focus"/>
|
||||
<policy label="drivers -> capslock" report="global_keys_handler -> capslock"/>
|
||||
<policy label="runtime -> capslock" report="global_keys_handler -> capslock"/>
|
||||
<policy label="drivers -> numlock" report="global_keys_handler -> numlock"/>
|
||||
|
@ -112,6 +113,7 @@ install_config {
|
|||
<rom name="drivers" label="drivers.config"/>
|
||||
<rom name="deploy" label="manual_deploy.config"/>
|
||||
<rom name="usb" label="usb.config"/>
|
||||
<rom name="clipboard" label="clipboard.config"/>
|
||||
<rom name="en_us.chargen"/>
|
||||
<rom name="fr.chargen"/>
|
||||
<rom name="de.chargen"/>
|
||||
|
@ -369,6 +371,19 @@ install_config {
|
|||
</route>
|
||||
</start>
|
||||
|
||||
<start name="clipboard" priority="-2">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides>
|
||||
<service name="ROM"/> <service name="Report"/>
|
||||
</provides>
|
||||
<route>
|
||||
<service name="ROM" label="config">
|
||||
<child name="config_fs_rom" label="clipboard"/> </service>
|
||||
<service name="ROM" label="focus"> <child name="report_rom"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="leitzentrale" caps="4000" priority="-2">
|
||||
<binary name="init"/>
|
||||
<resource name="RAM" quantum="164M"/>
|
||||
|
@ -442,6 +457,12 @@ install_config {
|
|||
<service name="Nitpicker"> <child name="nitpicker"/> </service>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="Report" label_suffix="-> shape"> <child name="pointer"/> </service>
|
||||
<service name="Report" label="inspect terminal -> clipboard">
|
||||
<child name="clipboard" label="leitzentrale -> manager -> fader -> -> clipboard"/> </service>
|
||||
<service name="ROM" label="inspect terminal -> clipboard">
|
||||
<child name="clipboard" label="leitzentrale -> manager -> fader -> -> clipboard"/> </service>
|
||||
<service name="Report" label_suffix="-> clipboard"> <child name="clipboard"/> </service>
|
||||
<service name="ROM" label_suffix="-> clipboard"> <child name="clipboard"/> </service>
|
||||
<service name="Report" label="runtime_view -> hover">
|
||||
<child name="report_rom"/> </service>
|
||||
<service name="Report"> <child name="fs_report"/> </service>
|
||||
|
@ -498,7 +519,7 @@ exec gzip -dc [genode_dir]/repos/gems/run/sculpt/machine.vdi.gz > [run_dir]/geno
|
|||
# Note: the string must be exactly 5 bytes long.
|
||||
#
|
||||
proc sculpt_version { } {
|
||||
return "19.06" }
|
||||
return "19.07" }
|
||||
|
||||
# write file with newline (for producing nice output when using 'cat /VERSION')
|
||||
set fd [open [run_dir]/genode/VERSION w]
|
||||
|
|
6
repos/gems/run/sculpt/clipboard.config
Normal file
6
repos/gems/run/sculpt/clipboard.config
Normal file
|
@ -0,0 +1,6 @@
|
|||
<config verbose="no" match_labels="yes">
|
||||
<flow from="leitzentrale" to="desktop" />
|
||||
<flow from="desktop" to="leitzentrale" />
|
||||
<policy label_prefix="leitzentrale" domain="leitzentrale"/>
|
||||
<default-policy domain="desktop"/>
|
||||
</config>
|
|
@ -1,4 +1,4 @@
|
|||
<config>
|
||||
<config copy="yes" paste="yes">
|
||||
<vfs>
|
||||
<rom name="Vera.ttf"/>
|
||||
<rom name="VeraMono.ttf"/>
|
||||
|
|
|
@ -107,7 +107,9 @@
|
|||
|
||||
<start name="wm" caps="200">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides> <service name="Nitpicker"/> <service name="Report"/> </provides>
|
||||
<provides>
|
||||
<service name="Nitpicker"/> <service name="Report"/> <service name="ROM"/>
|
||||
</provides>
|
||||
<config>
|
||||
<policy label_prefix="decorator" role="decorator"/>
|
||||
<default-policy/>
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
<SharedFolders>
|
||||
<SharedFolder name="shared" hostPath="/shared" writable="true" autoMount="true"/>
|
||||
</SharedFolders>
|
||||
<Clipboard mode="Bidirectional"/>
|
||||
</Hardware>
|
||||
<StorageControllers>
|
||||
<StorageController name="SATA" type="AHCI" PortCount="4" useHostIOCache="true" Bootable="true" IDE0MasterEmulationPort="0" IDE0SlaveEmulationPort="1" IDE1MasterEmulationPort="2" IDE1SlaveEmulationPort="3">
|
||||
|
|
|
@ -74,7 +74,9 @@ install_config {
|
|||
<start name="wm" caps="1000">
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<binary name="init"/>
|
||||
<provides> <service name="Nitpicker"/> <service name="Report"/> </provides>
|
||||
<provides>
|
||||
<service name="Nitpicker"/> <service name="Report"/> <service name="ROM"/>
|
||||
</provides>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <parent label="wm.config"/> </service>
|
||||
<service name="Nitpicker"> <child name="nitpicker"/> </service>
|
||||
|
@ -151,8 +153,8 @@ close $fd
|
|||
|
||||
file copy -force [genode_dir]/repos/gems/recipes/raw/motif_wm/wm.config [run_dir]/genode/
|
||||
|
||||
build { app/decorator server/nitpicker server/wm test/nitpicker }
|
||||
build { app/window_layouter app/decorator server/nitpicker server/wm test/nitpicker }
|
||||
|
||||
build_boot_image { decorator nitpicker wm testnit }
|
||||
build_boot_image { window_layouter decorator nitpicker wm testnit }
|
||||
|
||||
run_genode_until forever
|
||||
|
|
|
@ -232,7 +232,7 @@ class Depot_deploy::Child : public List_model<Child>::Element
|
|||
: Xml_node("<empty/>");
|
||||
|
||||
if (_condition == UNSATISFIED && _start_xml.constructed())
|
||||
fn(_start_xml->xml(), launcher_xml);
|
||||
fn(_start_xml->xml(), launcher_xml, _name);
|
||||
}
|
||||
|
||||
void mark_as_incomplete(Xml_node missing)
|
||||
|
|
|
@ -18,11 +18,19 @@
|
|||
#include <os/reporter.h>
|
||||
#include <gems/vfs.h>
|
||||
#include <depot/archive.h>
|
||||
#include <gems/lru_cache.h>
|
||||
|
||||
namespace Depot_query {
|
||||
|
||||
using namespace Depot;
|
||||
|
||||
typedef String<64> Rom_label;
|
||||
|
||||
struct Recursion_limit;
|
||||
struct Dependencies;
|
||||
class Stat_cache;
|
||||
struct Rom_query;
|
||||
class Cached_rom_query;
|
||||
struct Main;
|
||||
}
|
||||
|
||||
|
@ -144,7 +152,172 @@ class Depot_query::Dependencies
|
|||
};
|
||||
|
||||
|
||||
struct Depot_query::Main
|
||||
class Depot_query::Stat_cache
|
||||
{
|
||||
private:
|
||||
|
||||
struct Key
|
||||
{
|
||||
struct Value
|
||||
{
|
||||
Archive::Path path;
|
||||
|
||||
bool operator > (Value const &other) const
|
||||
{
|
||||
return strcmp(path.string(), other.path.string()) > 0;
|
||||
}
|
||||
|
||||
bool operator == (Value const &other) const
|
||||
{
|
||||
return path == other.path;
|
||||
}
|
||||
|
||||
} value;
|
||||
};
|
||||
|
||||
struct Result { bool file_exists; };
|
||||
|
||||
typedef Lru_cache<Key, Result> Cache;
|
||||
|
||||
Cache::Size const _size;
|
||||
|
||||
Cache _cache;
|
||||
|
||||
Directory const &_dir;
|
||||
|
||||
public:
|
||||
|
||||
Stat_cache(Directory const &dir, Allocator &alloc, Xml_node const config)
|
||||
:
|
||||
_size({.value = config.attribute_value("stat_cache", Number_of_bytes(64*1024))
|
||||
/ Cache::element_size()}),
|
||||
_cache(alloc, _size),
|
||||
_dir(dir)
|
||||
{ }
|
||||
|
||||
bool file_exists(Archive::Path const path)
|
||||
{
|
||||
/* don't cache the state of the 'local' depot user */
|
||||
if (Archive::user(path) == "local")
|
||||
return _dir.file_exists(path);
|
||||
|
||||
bool result = false;
|
||||
|
||||
auto hit_fn = [&] (Result const &cached_result)
|
||||
{
|
||||
result = cached_result.file_exists;
|
||||
};
|
||||
|
||||
auto miss_fn = [&] (Cache::Missing_element &missing_element)
|
||||
{
|
||||
Result const stat_result { _dir.file_exists(path) };
|
||||
|
||||
/*
|
||||
* Don't cache negative results because files may appear
|
||||
* during installation. Later queries may find files absent
|
||||
* from earlier queries.
|
||||
*/
|
||||
if (stat_result.file_exists)
|
||||
missing_element.construct(stat_result);
|
||||
};
|
||||
|
||||
Key const key { .value = { .path = path } };
|
||||
(void)_cache.try_apply(key, hit_fn, miss_fn);
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Depot_query::Rom_query : Interface
|
||||
{
|
||||
/**
|
||||
* Look up ROM module 'rom_label' in the archives referenced by 'pkg_path'
|
||||
*
|
||||
* \throw Directory::Nonexistent_directory
|
||||
* \throw Directory::Nonexistent_file
|
||||
* \throw File::Truncated_during_read
|
||||
* \throw Recursion_limit::Reached
|
||||
*/
|
||||
virtual Archive::Path find_rom_in_pkg(Directory::Path const &pkg_path,
|
||||
Rom_label const &rom_label,
|
||||
Recursion_limit recursion_limit) = 0;
|
||||
};
|
||||
|
||||
|
||||
class Depot_query::Cached_rom_query : public Rom_query
|
||||
{
|
||||
private:
|
||||
|
||||
struct Key
|
||||
{
|
||||
struct Value
|
||||
{
|
||||
Archive::Path pkg;
|
||||
Rom_label rom;
|
||||
|
||||
bool operator > (Value const &other) const
|
||||
{
|
||||
return strcmp(pkg.string(), other.pkg.string()) > 0
|
||||
&& strcmp(rom.string(), other.rom.string()) > 0;
|
||||
}
|
||||
|
||||
bool operator == (Value const &other) const
|
||||
{
|
||||
return pkg == other.pkg && rom == other.rom;
|
||||
}
|
||||
|
||||
} value;
|
||||
};
|
||||
|
||||
typedef Lru_cache<Key, Archive::Path> Cache;
|
||||
|
||||
Cache::Size const _size;
|
||||
|
||||
Cache mutable _cache;
|
||||
|
||||
Rom_query &_rom_query;
|
||||
|
||||
public:
|
||||
|
||||
Cached_rom_query(Rom_query &rom_query, Allocator &alloc, Xml_node const config)
|
||||
:
|
||||
_size({.value = config.attribute_value("rom_query_cache", Number_of_bytes(64*1024))
|
||||
/ Cache::element_size() }),
|
||||
_cache(alloc, _size),
|
||||
_rom_query(rom_query)
|
||||
{ }
|
||||
|
||||
Archive::Path find_rom_in_pkg(Directory::Path const &pkg_path,
|
||||
Rom_label const &rom_label,
|
||||
Recursion_limit recursion_limit) override
|
||||
{
|
||||
/* don't cache the state of the 'local' depot user */
|
||||
if (Archive::user(pkg_path) == "local")
|
||||
return _rom_query.find_rom_in_pkg(pkg_path, rom_label, recursion_limit);
|
||||
|
||||
Archive::Path result { };
|
||||
|
||||
auto hit_fn = [&] (Archive::Path const &path) { result = path; };
|
||||
|
||||
auto miss_fn = [&] (Cache::Missing_element &missing_element)
|
||||
{
|
||||
Archive::Path const path =
|
||||
_rom_query.find_rom_in_pkg(pkg_path, rom_label, recursion_limit);
|
||||
|
||||
if (path.valid())
|
||||
missing_element.construct(path);
|
||||
};
|
||||
|
||||
Key const key { .value = { .pkg = pkg_path, .rom = rom_label } };
|
||||
(void)_cache.try_apply(key, hit_fn, miss_fn);
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Depot_query::Main : private Rom_query
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
|
@ -158,6 +331,8 @@ struct Depot_query::Main
|
|||
|
||||
Directory _depot_dir { _root, "depot" };
|
||||
|
||||
Stat_cache _depot_stat_cache { _depot_dir, _heap, _config.xml() };
|
||||
|
||||
Signal_handler<Main> _config_handler {
|
||||
_env.ep(), *this, &Main::_handle_config };
|
||||
|
||||
|
@ -182,7 +357,6 @@ struct Depot_query::Main
|
|||
obj.destruct();
|
||||
}
|
||||
|
||||
typedef String<64> Rom_label;
|
||||
typedef String<16> Architecture;
|
||||
typedef String<32> Version;
|
||||
|
||||
|
@ -210,17 +384,13 @@ struct Depot_query::Main
|
|||
});
|
||||
}
|
||||
|
||||
Cached_rom_query _cached_rom_query { *this, _heap, _config.xml() };
|
||||
|
||||
/**
|
||||
* Look up ROM module 'rom_label' in the archives referenced by 'pkg_path'
|
||||
*
|
||||
* \throw Directory::Nonexistent_directory
|
||||
* \throw Directory::Nonexistent_file
|
||||
* \throw File::Truncated_during_read
|
||||
* \throw Recursion_limit::Reached
|
||||
* Rom_query interface
|
||||
*/
|
||||
Archive::Path _find_rom_in_pkg(Directory::Path const &pkg_path,
|
||||
Rom_label const &rom_label,
|
||||
Recursion_limit recursion_limit);
|
||||
Archive::Path find_rom_in_pkg(Directory::Path const &, Rom_label const &,
|
||||
Recursion_limit) override;
|
||||
|
||||
void _query_blueprint(Directory::Path const &, Xml_generator &);
|
||||
void _collect_source_dependencies(Archive::Path const &, Dependencies &, Recursion_limit);
|
||||
|
@ -344,9 +514,9 @@ struct Depot_query::Main
|
|||
|
||||
|
||||
Depot_query::Archive::Path
|
||||
Depot_query::Main::_find_rom_in_pkg(Directory::Path const &pkg_path,
|
||||
Rom_label const &rom_label,
|
||||
Recursion_limit recursion_limit)
|
||||
Depot_query::Main::find_rom_in_pkg(Directory::Path const &pkg_path,
|
||||
Rom_label const &rom_label,
|
||||
Recursion_limit recursion_limit)
|
||||
{
|
||||
/*
|
||||
* \throw Directory::Nonexistent_directory
|
||||
|
@ -375,7 +545,7 @@ Depot_query::Main::_find_rom_in_pkg(Directory::Path const &pkg_path,
|
|||
Archive::name(archive_path), "/",
|
||||
Archive::version(archive_path), "/", rom_label);
|
||||
|
||||
if (_depot_dir.file_exists(rom_path))
|
||||
if (_depot_stat_cache.file_exists(rom_path))
|
||||
result = rom_path;
|
||||
}
|
||||
break;
|
||||
|
@ -387,16 +557,19 @@ Depot_query::Main::_find_rom_in_pkg(Directory::Path const &pkg_path,
|
|||
Archive::name(archive_path), "/",
|
||||
Archive::version(archive_path), "/", rom_label);
|
||||
|
||||
if (_depot_dir.file_exists(rom_path))
|
||||
if (_depot_stat_cache.file_exists(rom_path))
|
||||
result = rom_path;
|
||||
}
|
||||
break;
|
||||
|
||||
case Archive::PKG:
|
||||
|
||||
Archive::Path const result_from_pkg =
|
||||
_find_rom_in_pkg(archive_path, rom_label, recursion_limit);
|
||||
_cached_rom_query.find_rom_in_pkg(archive_path, rom_label, recursion_limit);
|
||||
|
||||
if (result_from_pkg.valid())
|
||||
result = result_from_pkg;
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
@ -448,7 +621,7 @@ void Depot_query::Main::_query_blueprint(Directory::Path const &pkg_path, Xml_ge
|
|||
}
|
||||
|
||||
Archive::Path const rom_path =
|
||||
_find_rom_in_pkg(pkg_path, label, Recursion_limit{8});
|
||||
_cached_rom_query.find_rom_in_pkg(pkg_path, label, Recursion_limit{8});
|
||||
|
||||
if (rom_path.valid()) {
|
||||
xml.node("rom", [&] () {
|
||||
|
|
|
@ -61,8 +61,6 @@ struct Gpt::Writer
|
|||
|
||||
Util::Number_of_bytes _entry_alignment { 4096u };
|
||||
|
||||
Genode::Xml_node *_config { nullptr };
|
||||
|
||||
void _handle_config(Genode::Xml_node config)
|
||||
{
|
||||
_verbose = config.attribute_value("verbose", false);
|
||||
|
@ -83,8 +81,6 @@ struct Gpt::Writer
|
|||
if (_wipe && (_initialize || commands)) {
|
||||
Genode::warning("will exit after wiping");
|
||||
}
|
||||
|
||||
_config = &config;
|
||||
}
|
||||
|
||||
/************
|
||||
|
@ -692,15 +688,13 @@ struct Gpt::Writer
|
|||
* \return true if actions were executed successfully, otherwise
|
||||
* false
|
||||
*/
|
||||
bool execute_actions()
|
||||
bool execute_actions(Genode::Xml_node actions)
|
||||
{
|
||||
if (_wipe) { return _wipe_tables(); }
|
||||
|
||||
if (_initialize) { _initialize_tables(); }
|
||||
|
||||
try {
|
||||
Genode::Xml_node actions = _config->sub_node("actions");
|
||||
|
||||
actions.for_each_sub_node([&] (Genode::Xml_node node) {
|
||||
bool result = false;
|
||||
|
||||
|
@ -750,14 +744,19 @@ struct Main
|
|||
|
||||
Util::init_random(_heap);
|
||||
|
||||
Genode::Xml_node const config = _config_rom.xml();
|
||||
|
||||
try {
|
||||
_writer.construct(_block, _config_rom.xml());
|
||||
_writer.construct(_block, config);
|
||||
} catch (...) {
|
||||
_env.parent().exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
bool const success = _writer->execute_actions();
|
||||
bool success = false;
|
||||
config.with_sub_node("actions", [&] (Genode::Xml_node actions) {
|
||||
success = _writer->execute_actions(actions); });
|
||||
|
||||
_env.parent().exit(success ? 0 : 1);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -92,8 +92,8 @@ namespace Util {
|
|||
/* handle suffixes */
|
||||
if (i > 0)
|
||||
switch (s[i]) {
|
||||
case 'G': res *= 1024;
|
||||
case 'M': res *= 1024;
|
||||
case 'G': res *= 1024; [[fallthrough]];
|
||||
case 'M': res *= 1024; [[fallthrough]];
|
||||
case 'K': res *= 1024; i++;
|
||||
default: break;
|
||||
}
|
||||
|
|
|
@ -42,10 +42,8 @@ void Sculpt::Deploy::gen_child_diagnostics(Xml_generator &xml) const
|
|||
typedef Registered_no_delete<Message> Registered_message;
|
||||
Registry<Registered_message> messages { };
|
||||
|
||||
auto gen_missing_dependencies = [&] (Xml_node start)
|
||||
auto gen_missing_dependencies = [&] (Xml_node start, Start_name const &name)
|
||||
{
|
||||
Start_name const name = start.attribute_value("name", Start_name());
|
||||
|
||||
_for_each_missing_server(start, [&] (Start_name const &server) {
|
||||
|
||||
Message const new_message(Pretty(name), " requires ", Pretty(server));
|
||||
|
@ -60,9 +58,10 @@ void Sculpt::Deploy::gen_child_diagnostics(Xml_generator &xml) const
|
|||
});
|
||||
};
|
||||
|
||||
_children.for_each_unsatisfied_child([&] (Xml_node start, Xml_node launcher) {
|
||||
gen_missing_dependencies(start);
|
||||
gen_missing_dependencies(launcher);
|
||||
_children.for_each_unsatisfied_child([&] (Xml_node start, Xml_node launcher,
|
||||
Start_name const &name) {
|
||||
gen_missing_dependencies(start, name);
|
||||
gen_missing_dependencies(launcher, name);
|
||||
});
|
||||
|
||||
/*
|
||||
|
|
|
@ -174,7 +174,7 @@ struct Sculpt::Deploy
|
|||
bool any_unsatisfied_child() const
|
||||
{
|
||||
bool all_satisfied = true;
|
||||
_children.for_each_unsatisfied_child([&] (Xml_node, Xml_node) {
|
||||
_children.for_each_unsatisfied_child([&] (Xml_node, Xml_node, Start_name const &) {
|
||||
all_satisfied = false; });
|
||||
return !all_satisfied;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <os/reporter.h>
|
||||
#include <nitpicker_session/connection.h>
|
||||
#include <vm_session/vm_session.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
/* included from depot_deploy tool */
|
||||
#include <children.h>
|
||||
|
@ -213,14 +214,15 @@ struct Sculpt::Main : Input_event_handler,
|
|||
return _query_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Depot_query interface
|
||||
*/
|
||||
void trigger_depot_query() override
|
||||
{
|
||||
_query_version.value++;
|
||||
Timer::Connection _timer { _env };
|
||||
|
||||
Timer::One_shot_timeout<Main> _deferred_depot_query_handler {
|
||||
_timer, *this, &Main::_handle_deferred_depot_query };
|
||||
|
||||
void _handle_deferred_depot_query(Duration)
|
||||
{
|
||||
if (_deploy._arch.valid()) {
|
||||
_query_version.value++;
|
||||
_depot_query_reporter.generate([&] (Xml_generator &xml) {
|
||||
xml.attribute("arch", _deploy._arch);
|
||||
xml.attribute("version", _query_version.value);
|
||||
|
@ -233,6 +235,21 @@ struct Sculpt::Main : Input_event_handler,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Depot_query interface
|
||||
*/
|
||||
void trigger_depot_query() override
|
||||
{
|
||||
/*
|
||||
* Defer the submission of the query for a few milliseconds because
|
||||
* 'trigger_depot_query' may be consecutively called several times
|
||||
* while evaluating different conditions. Without deferring, the depot
|
||||
* query component would produce intermediate results that take time
|
||||
* but are ultimately discarded.
|
||||
*/
|
||||
_deferred_depot_query_handler.schedule(Microseconds{5000});
|
||||
}
|
||||
|
||||
|
||||
/*********************
|
||||
** Blueprint query **
|
||||
|
@ -249,6 +266,16 @@ struct Sculpt::Main : Input_event_handler,
|
|||
|
||||
Xml_node const blueprint = _blueprint_rom.xml();
|
||||
|
||||
/*
|
||||
* Drop intermediate results that will be superseded by a newer query.
|
||||
* This is important because an outdated blueprint would be disregarded
|
||||
* by 'handle_deploy' anyway while at the same time a new query is
|
||||
* issued. This can result a feedback loop where blueprints are
|
||||
* requested but never applied.
|
||||
*/
|
||||
if (blueprint.attribute_value("version", 0U) != _query_version.value)
|
||||
return;
|
||||
|
||||
_runtime_state.apply_to_construction([&] (Component &component) {
|
||||
_popup_dialog.apply_blueprint(component, blueprint); });
|
||||
|
||||
|
@ -930,6 +957,8 @@ void Sculpt::Main::_handle_nitpicker_mode()
|
|||
_gui.font_size(text_size);
|
||||
|
||||
_fonts_config.generate([&] (Xml_generator &xml) {
|
||||
xml.attribute("copy", true);
|
||||
xml.attribute("paste", true);
|
||||
xml.node("vfs", [&] () {
|
||||
gen_named_node(xml, "rom", "Vera.ttf");
|
||||
gen_named_node(xml, "rom", "VeraMono.ttf");
|
||||
|
|
|
@ -122,8 +122,13 @@ struct Sculpt::Route : List_model<Route>::Element
|
|||
|
||||
gen_named_node(xml, "service", Service::name_attr(required), [&] () {
|
||||
|
||||
if (required_label.valid())
|
||||
xml.attribute("label", required_label);
|
||||
if (required_label.valid()) {
|
||||
|
||||
if (selected_service->match_label == Service::Match_label::LAST)
|
||||
xml.attribute("label_last", required_label);
|
||||
else
|
||||
xml.attribute("label", required_label);
|
||||
}
|
||||
|
||||
selected_service->gen_xml(xml);
|
||||
});
|
||||
|
|
|
@ -324,6 +324,9 @@ class Sculpt::Runtime_config
|
|||
_pf_info { _r, Type::ROM, "platform information", "platform_info" },
|
||||
_system { _r, Type::ROM, "system status", "config -> system" },
|
||||
_report { _r, Type::REPORT, "system reports" },
|
||||
_shape { _r, Type::REPORT, "pointer shape", "shape", Service::Match_label::LAST },
|
||||
_copy { _r, Type::REPORT, "global clipboard", "clipboard", Service::Match_label::LAST },
|
||||
_paste { _r, Type::ROM, "global clipboard", "clipboard", Service::Match_label::LAST },
|
||||
_rm { _r, Type::RM, "custom virtual memory objects" },
|
||||
_io_mem { _r, Type::IO_MEM, "raw hardware access" },
|
||||
_io_port { _r, Type::IO_PORT, "raw hardware access" },
|
||||
|
|
|
@ -29,10 +29,13 @@ struct Sculpt::Service
|
|||
RM, IO_MEM, IO_PORT, IRQ, REPORT, ROM, TERMINAL, TRACE,
|
||||
USB, RTC, PLATFORM, VM, UNDEFINED };
|
||||
|
||||
Start_name server { }; /* invalid for parent service */
|
||||
Type type;
|
||||
Label label;
|
||||
Info info;
|
||||
enum class Match_label { EXACT, LAST };
|
||||
|
||||
Start_name server { }; /* invalid for parent service */
|
||||
Type type;
|
||||
Label label;
|
||||
Info info;
|
||||
Match_label match_label { Match_label::EXACT };
|
||||
|
||||
/**
|
||||
* Return name attribute value of <service name="..."> node
|
||||
|
@ -72,8 +75,11 @@ struct Sculpt::Service
|
|||
/**
|
||||
* Constructor for parent service
|
||||
*/
|
||||
Service(Type type, Info const &info, Label const &label = Label())
|
||||
: type(type), label(label), info(info) { }
|
||||
Service(Type type, Info const &info, Label const &label = Label(),
|
||||
Match_label match_label = Match_label::EXACT)
|
||||
:
|
||||
type(type), label(label), info(info), match_label(match_label)
|
||||
{ }
|
||||
|
||||
void gen_xml(Xml_generator &xml) const
|
||||
{
|
||||
|
@ -84,7 +90,7 @@ struct Sculpt::Service
|
|||
if (!parent)
|
||||
xml.attribute("name", server);
|
||||
|
||||
if (label.valid())
|
||||
if (label.valid() && match_label == Match_label::EXACT)
|
||||
xml.attribute("label", label);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -91,6 +91,11 @@ void Sculpt::gen_terminal_start(Xml_generator &xml, Rom_name const &name,
|
|||
gen_parent_route<Pd_session> (xml);
|
||||
gen_parent_route<Log_session> (xml);
|
||||
gen_parent_route<Timer::Session> (xml);
|
||||
gen_parent_route<Report::Session>(xml);
|
||||
|
||||
gen_named_node(xml, "service", Rom_session::service_name(), [&] () {
|
||||
xml.attribute("label", "clipboard");
|
||||
xml.node("parent", [&] () { }); });
|
||||
|
||||
gen_named_node(xml, "service", Rom_session::service_name(), [&] () {
|
||||
xml.attribute("label", "config");
|
||||
|
|
|
@ -261,33 +261,18 @@ void Decorator::Main::_handle_nitpicker_sync()
|
|||
auto flush_window_stack_changes = [&] () {
|
||||
_window_stack.update_nitpicker_views(); };
|
||||
|
||||
if (_window_layout_update_needed && _window_layout.valid()) {
|
||||
if (_window_layout_update_needed) {
|
||||
|
||||
try {
|
||||
Xml_node xml(_window_layout.local_addr<char>(),
|
||||
_window_layout.size());
|
||||
_window_stack.update_model(_window_layout.xml(), flush_window_stack_changes);
|
||||
|
||||
_window_stack.update_model(xml, flush_window_stack_changes);
|
||||
model_updated = true;
|
||||
|
||||
model_updated = true;
|
||||
|
||||
/*
|
||||
* A decorator element might have appeared or disappeared under
|
||||
* the pointer.
|
||||
*/
|
||||
if (_pointer.constructed() && _pointer->valid())
|
||||
update_hover_report(Xml_node(_pointer->local_addr<char>()),
|
||||
_window_stack, _hover, _hover_reporter);
|
||||
|
||||
} catch (Xml_node::Invalid_syntax) {
|
||||
|
||||
/*
|
||||
* An error occured with processing the XML model. Flush the
|
||||
* internal representation.
|
||||
*/
|
||||
_window_stack.update_model(Xml_node("<window_layout/>"),
|
||||
flush_window_stack_changes);
|
||||
}
|
||||
/*
|
||||
* A decorator element might have appeared or disappeared under
|
||||
* the pointer.
|
||||
*/
|
||||
if (_pointer.constructed())
|
||||
update_hover_report(_pointer->xml(), _window_stack, _hover, _hover_reporter);
|
||||
|
||||
_window_layout_update_needed = false;
|
||||
}
|
||||
|
@ -317,9 +302,7 @@ void Decorator::Main::_handle_pointer_update()
|
|||
|
||||
_pointer->update();
|
||||
|
||||
if (_pointer->valid())
|
||||
update_hover_report(Xml_node(_pointer->local_addr<char>()),
|
||||
_window_stack, _hover, _hover_reporter);
|
||||
update_hover_report(_pointer->xml(), _window_stack, _hover, _hover_reporter);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@ Decorator::Window_base::Hover Decorator::Window::hover(Point abs_pos) const
|
|||
|
||||
hover.window_id = id();
|
||||
|
||||
/* omit the decoration checks below whenever the content is hovered */
|
||||
if (geometry().contains(abs_pos))
|
||||
return hover;
|
||||
|
||||
Rect const closer_geometry =
|
||||
_theme.absolute(_theme.element_geometry(Theme::ELEMENT_TYPE_CLOSER),
|
||||
outer_geometry());
|
||||
|
|
|
@ -115,6 +115,8 @@ class Window_layouter::Assign : public List_model<Assign>::Element
|
|||
return Rect(outer.p1() + target_geometry.p1(), outer.area());
|
||||
}
|
||||
|
||||
bool maximized() const { return _maximized; }
|
||||
|
||||
/**
|
||||
* Call 'fn' with 'Registry<Member>' if label matches assignment
|
||||
*
|
||||
|
|
|
@ -48,7 +48,9 @@ struct Window_layouter::Main : Operations,
|
|||
|
||||
Timer::Connection _drop_timer { _env };
|
||||
|
||||
bool _defer_layout_change = false;
|
||||
enum class Drag_state { IDLE, DRAGGING, SETTLING };
|
||||
|
||||
Drag_state _drag_state { Drag_state::IDLE };
|
||||
|
||||
Signal_handler<Main> _drop_timer_handler {
|
||||
_env.ep(), *this, &Main::_handle_drop_timer };
|
||||
|
@ -116,6 +118,7 @@ struct Window_layouter::Main : Operations,
|
|||
target.geometry(),
|
||||
_decorator_margins);
|
||||
member.window.outer_geometry(rect);
|
||||
member.window.maximized(assign.maximized());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -137,21 +140,9 @@ struct Window_layouter::Main : Operations,
|
|||
*/
|
||||
void layout_rules_changed() override
|
||||
{
|
||||
/*
|
||||
* When re-importing rules generated by the drop operation, issue an
|
||||
* updated resize request immediately instead of waiting for the
|
||||
* '_drop_timer_handler'. Clear '_defer_layout_change' before calling
|
||||
* '_update_window_layout' because '_gen_window_layout' evaluates
|
||||
* this flag.
|
||||
*/
|
||||
bool const issue_resize_request = _defer_layout_change;
|
||||
|
||||
_defer_layout_change = false;
|
||||
|
||||
_update_window_layout();
|
||||
|
||||
if (issue_resize_request)
|
||||
_gen_resize_request();
|
||||
_gen_resize_request();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,6 +210,11 @@ struct Window_layouter::Main : Operations,
|
|||
|
||||
void drag(Window_id id, Window::Element element, Point clicked, Point curr) override
|
||||
{
|
||||
if (_drag_state == Drag_state::SETTLING)
|
||||
return;
|
||||
|
||||
_drag_state = Drag_state::DRAGGING;
|
||||
|
||||
to_front(id);
|
||||
|
||||
bool window_layout_changed = false;
|
||||
|
@ -244,11 +240,15 @@ struct Window_layouter::Main : Operations,
|
|||
|
||||
void _handle_drop_timer()
|
||||
{
|
||||
/* discharge '_defer_layout_change' */
|
||||
layout_rules_changed();
|
||||
_drag_state = Drag_state::IDLE;
|
||||
|
||||
_gen_rules();
|
||||
|
||||
_window_list.for_each_window([&] (Window &window) {
|
||||
window.finalize_drag_operation(); });
|
||||
}
|
||||
|
||||
void finalize_drag(Window_id id, Window::Element, Point, Point) override
|
||||
void finalize_drag(Window_id, Window::Element, Point, Point) override
|
||||
{
|
||||
/*
|
||||
* Update window layout because highlighting may have changed after the
|
||||
|
@ -256,17 +256,9 @@ struct Window_layouter::Main : Operations,
|
|||
* dragging of a resize handle, the resize handle is no longer hovered.
|
||||
*/
|
||||
_gen_window_layout();
|
||||
_gen_rules();
|
||||
|
||||
_window_list.with_window(id, [&] (Window &window) {
|
||||
window.finalize_drag_operation(); });
|
||||
_drag_state = Drag_state::SETTLING;
|
||||
|
||||
/*
|
||||
* Mask the generation of resize requests until the updated rules are
|
||||
* imported the next time. Discharge the masking after a timeout for
|
||||
* the case where rules fixed and not fed back to the layouter.
|
||||
*/
|
||||
_defer_layout_change = true;
|
||||
_drop_timer.trigger_once(250*1000);
|
||||
}
|
||||
|
||||
|
@ -399,9 +391,6 @@ struct Window_layouter::Main : Operations,
|
|||
|
||||
void Window_layouter::Main::_gen_window_layout()
|
||||
{
|
||||
if (_defer_layout_change)
|
||||
return;
|
||||
|
||||
/* update hover and focus state of each window */
|
||||
_window_list.for_each_window([&] (Window &window) {
|
||||
|
||||
|
@ -419,9 +408,6 @@ void Window_layouter::Main::_gen_window_layout()
|
|||
|
||||
void Window_layouter::Main::_gen_resize_request()
|
||||
{
|
||||
if (_defer_layout_change)
|
||||
return;
|
||||
|
||||
bool resize_needed = false;
|
||||
_assign_list.for_each([&] (Assign const &assign) {
|
||||
assign.for_each_member([&] (Assign::Member const &member) {
|
||||
|
|
|
@ -187,21 +187,24 @@ class Window_layouter::Window : public List_model<Window>::Element
|
|||
{
|
||||
_dragged_element = element;
|
||||
|
||||
_drag_left_border = (element.type == Window::Element::LEFT)
|
||||
|| (element.type == Window::Element::TOP_LEFT)
|
||||
|| (element.type == Window::Element::BOTTOM_LEFT);
|
||||
if (_resizeable) {
|
||||
|
||||
_drag_right_border = (element.type == Window::Element::RIGHT)
|
||||
|| (element.type == Window::Element::TOP_RIGHT)
|
||||
|| (element.type == Window::Element::BOTTOM_RIGHT);
|
||||
_drag_left_border = (element.type == Window::Element::LEFT)
|
||||
|| (element.type == Window::Element::TOP_LEFT)
|
||||
|| (element.type == Window::Element::BOTTOM_LEFT);
|
||||
|
||||
_drag_top_border = (element.type == Window::Element::TOP)
|
||||
|| (element.type == Window::Element::TOP_LEFT)
|
||||
|| (element.type == Window::Element::TOP_RIGHT);
|
||||
_drag_right_border = (element.type == Window::Element::RIGHT)
|
||||
|| (element.type == Window::Element::TOP_RIGHT)
|
||||
|| (element.type == Window::Element::BOTTOM_RIGHT);
|
||||
|
||||
_drag_bottom_border = (element.type == Window::Element::BOTTOM)
|
||||
|| (element.type == Window::Element::BOTTOM_LEFT)
|
||||
|| (element.type == Window::Element::BOTTOM_RIGHT);
|
||||
_drag_top_border = (element.type == Window::Element::TOP)
|
||||
|| (element.type == Window::Element::TOP_LEFT)
|
||||
|| (element.type == Window::Element::TOP_RIGHT);
|
||||
|
||||
_drag_bottom_border = (element.type == Window::Element::BOTTOM)
|
||||
|| (element.type == Window::Element::BOTTOM_LEFT)
|
||||
|| (element.type == Window::Element::BOTTOM_RIGHT);
|
||||
}
|
||||
|
||||
_orig_geometry = _geometry;
|
||||
_drag_geometry = _geometry;
|
||||
|
@ -463,12 +466,13 @@ class Window_layouter::Window : public List_model<Window>::Element
|
|||
|
||||
void finalize_drag_operation()
|
||||
{
|
||||
_dragged = false;
|
||||
_drag_left_border = false;
|
||||
_drag_right_border = false;
|
||||
_drag_top_border = false;
|
||||
_drag_bottom_border = false;
|
||||
_dragged_size = effective_inner_geometry().area();
|
||||
_geometry = effective_inner_geometry();
|
||||
_dragged_size = _geometry.area();
|
||||
_dragged = false;
|
||||
}
|
||||
|
||||
void to_front_cnt(unsigned to_front_cnt) { _to_front_cnt = to_front_cnt; }
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
This is a graphical terminal implementation. It provides the Terminal
|
||||
service and uses a nitpicker session for screen representation.
|
||||
|
||||
Configuration
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Color configuration
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The default color palette can be configured via the <palette> XML
|
||||
configuration node like follows. There are 16 colors configurable -
|
||||
index 0-7 normal color and index 8-15 bright (bold) colors.
|
||||
|
||||
|
||||
! <config>
|
||||
! <palette>
|
||||
! <color index="0" value="#000000"/> <!-- black is real black -->
|
||||
|
@ -17,3 +17,17 @@ index 0-7 normal color and index 8-15 bright (bold) colors.
|
|||
! ...
|
||||
! </config>
|
||||
|
||||
|
||||
Clipboard support
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
With the '<config>' attribute 'copy="yes"' specified, the terminal allows
|
||||
the user to select text to be reported to a "clipboard" report. The selection
|
||||
mode is activated by holding the left shift key. While the selection mode
|
||||
is active, the text position under mouse pointer is highlighted and the
|
||||
user can select text via the left mouse button. Upon release of the mouse
|
||||
button, the selection is reported.
|
||||
|
||||
Vice versa, with the '<config>' attribute 'paste="yes"' specified, the
|
||||
terminal allows the user to paste the content of a "clipboard" ROM session
|
||||
to the terminal client by pressing the middle mouse button.
|
||||
|
|
|
@ -47,7 +47,7 @@ class Terminal::Color_palette
|
|||
" <color index=\"1\" value=\"#AC4142\"/>" /* red */
|
||||
" <color index=\"2\" value=\"#90A959\"/>" /* green */
|
||||
" <color index=\"3\" value=\"#F4BF75\"/>" /* yellow */
|
||||
" <color index=\"4\" value=\"#6A9FB5\"/>" /* blue */
|
||||
" <color index=\"4\" value=\"#7686BD\"/>" /* blue */
|
||||
" <color index=\"5\" value=\"#AA759F\"/>" /* magenta */
|
||||
" <color index=\"6\" value=\"#75B5AA\"/>" /* cyan */
|
||||
" <color index=\"7\" value=\"#D0D0D0\"/>" /* white */
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <input/event.h>
|
||||
#include <os/reporter.h>
|
||||
#include <gems/vfs.h>
|
||||
#include <gems/vfs_font.h>
|
||||
#include <gems/cached_font.h>
|
||||
|
@ -72,6 +73,9 @@ struct Terminal::Main : Character_consumer
|
|||
|
||||
Color_palette _color_palette { };
|
||||
|
||||
Constructible<Attached_rom_dataspace> _clipboard_rom { };
|
||||
Constructible<Expanding_reporter> _clipboard_reporter { };
|
||||
|
||||
void _handle_config();
|
||||
|
||||
Signal_handler<Main> _config_handler {
|
||||
|
@ -82,6 +86,14 @@ struct Terminal::Main : Character_consumer
|
|||
|
||||
Framebuffer _framebuffer { _env, _config_handler };
|
||||
|
||||
Point _pointer { }; /* pointer positon in pixels */
|
||||
|
||||
bool _shift_pressed = false;
|
||||
|
||||
bool _selecting = false;
|
||||
|
||||
struct Paste_buffer { char buffer[READ_BUFFER_SIZE]; } _paste_buffer { };
|
||||
|
||||
typedef Pixel_rgb565 PT;
|
||||
|
||||
Constructible<Text_screen_surface<PT>> _text_screen_surface { };
|
||||
|
@ -139,6 +151,9 @@ struct Terminal::Main : Character_consumer
|
|||
Signal_handler<Main> _input_handler {
|
||||
_env.ep(), *this, &Main::_handle_input };
|
||||
|
||||
void _report_clipboard_selection();
|
||||
void _paste_clipboard_content();
|
||||
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
_timer .sigh(_flush_handler);
|
||||
|
@ -170,6 +185,12 @@ void Terminal::Main::_handle_config()
|
|||
|
||||
_font.construct(_heap, _root_dir, cache_limit);
|
||||
|
||||
_clipboard_reporter.conditional(config.attribute_value("copy", false),
|
||||
_env, "clipboard", "clipboard");
|
||||
|
||||
_clipboard_rom.conditional(config.attribute_value("paste", false),
|
||||
_env, "clipboard");
|
||||
|
||||
/*
|
||||
* Adapt terminal to font or framebuffer mode changes
|
||||
*/
|
||||
|
@ -252,6 +273,56 @@ void Terminal::Main::_handle_input()
|
|||
{
|
||||
_input.for_each_event([&] (Input::Event const &event) {
|
||||
|
||||
event.handle_absolute_motion([&] (int x, int y) {
|
||||
|
||||
_pointer = Point(x, y);
|
||||
|
||||
if (_shift_pressed) {
|
||||
_text_screen_surface->pointer(_pointer);
|
||||
_schedule_flush();
|
||||
}
|
||||
|
||||
if (_selecting) {
|
||||
_text_screen_surface->define_selection(_pointer);
|
||||
_schedule_flush();
|
||||
}
|
||||
});
|
||||
|
||||
if (event.key_press(Input::KEY_LEFTSHIFT)) {
|
||||
if (_clipboard_reporter.constructed()) {
|
||||
_shift_pressed = true;
|
||||
_text_screen_surface->clear_selection();
|
||||
_text_screen_surface->pointer(_pointer);
|
||||
_schedule_flush();
|
||||
}
|
||||
}
|
||||
|
||||
if (event.key_release(Input::KEY_LEFTSHIFT)) {
|
||||
_shift_pressed = false;
|
||||
_text_screen_surface->pointer(Point(-1, -1));
|
||||
_schedule_flush();
|
||||
}
|
||||
|
||||
if (event.key_press(Input::BTN_LEFT)) {
|
||||
if (_shift_pressed) {
|
||||
_selecting = true;
|
||||
_text_screen_surface->start_selection(_pointer);
|
||||
} else {
|
||||
_text_screen_surface->clear_selection();
|
||||
}
|
||||
_schedule_flush();
|
||||
}
|
||||
|
||||
if (event.key_release(Input::BTN_LEFT)) {
|
||||
if (_selecting) {
|
||||
_selecting = false;
|
||||
_report_clipboard_selection();
|
||||
}
|
||||
}
|
||||
|
||||
if (event.key_press(Input::BTN_MIDDLE))
|
||||
_paste_clipboard_content();
|
||||
|
||||
event.handle_press([&] (Input::Keycode, Codepoint codepoint) {
|
||||
|
||||
/* function-key unicodes */
|
||||
|
@ -304,4 +375,56 @@ void Terminal::Main::_handle_input()
|
|||
}
|
||||
|
||||
|
||||
void Terminal::Main::_report_clipboard_selection()
|
||||
{
|
||||
if (!_clipboard_reporter.constructed())
|
||||
return;
|
||||
|
||||
_clipboard_reporter->generate([&] (Xml_generator &xml) {
|
||||
_text_screen_surface->for_each_selected_character([&] (Codepoint c) {
|
||||
String<10> const utf8(c);
|
||||
if (utf8.valid())
|
||||
xml.append_sanitized(utf8.string(), utf8.length() - 1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void Terminal::Main::_paste_clipboard_content()
|
||||
{
|
||||
if (!_clipboard_rom.constructed())
|
||||
return;
|
||||
|
||||
_clipboard_rom->update();
|
||||
|
||||
_paste_buffer = { };
|
||||
|
||||
/* leave last byte as zero-termination in tact */
|
||||
size_t const max_len = sizeof(_paste_buffer.buffer) - 1;
|
||||
size_t const len =
|
||||
_clipboard_rom->xml().decoded_content(_paste_buffer.buffer, max_len);
|
||||
|
||||
if (len == max_len) {
|
||||
warning("clipboard content exceeds paste buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
if (len >= (size_t)_read_buffer.avail_capacity()) {
|
||||
warning("clipboard content exceeds read-buffer capacity");
|
||||
return;
|
||||
}
|
||||
|
||||
for (Utf8_ptr utf8(_paste_buffer.buffer); utf8.complete(); utf8 = utf8.next()) {
|
||||
|
||||
Codepoint const c = utf8.codepoint();
|
||||
|
||||
/* filter out control characters */
|
||||
if (c.value < 32 && c.value != 10)
|
||||
continue;
|
||||
|
||||
_read_buffer.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env) { static Terminal::Main main(env); }
|
||||
|
|
|
@ -91,6 +91,17 @@ class Terminal::Text_screen_surface
|
|||
Point start() const { return Point(1, 1); }
|
||||
|
||||
bool valid() const { return columns*lines > 0; }
|
||||
|
||||
/**
|
||||
* Return character position at given pixel coordinates
|
||||
*/
|
||||
Position position(Point p) const
|
||||
{
|
||||
if (char_width.value == 0 || char_height == 0)
|
||||
return Position { };
|
||||
|
||||
return Position((p.x() << 8) / char_width.value, p.y() / char_height);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -133,6 +144,29 @@ class Terminal::Text_screen_surface
|
|||
|
||||
Decoder _decoder { _character_screen };
|
||||
|
||||
struct Selection
|
||||
{
|
||||
Position start { };
|
||||
Position end { };
|
||||
|
||||
bool defined = false;
|
||||
|
||||
bool selected(Position pos) const
|
||||
{
|
||||
return defined && pos.in_range(start, end);
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void for_each_line(FN const &fn) const
|
||||
{
|
||||
for (int i = min(start.y, end.y); i <= max(start.y, end.y); i++)
|
||||
fn(i);
|
||||
}
|
||||
|
||||
} _selection { };
|
||||
|
||||
Position _pointer { -1, -1 };
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
|
@ -199,7 +233,20 @@ class Terminal::Text_screen_surface
|
|||
|
||||
Char_cell const cell = _cell_array.get_cell(column, line);
|
||||
|
||||
_font.apply_glyph(cell.codepoint(), [&] (Glyph_painter::Glyph const &glyph) {
|
||||
Codepoint codepoint = cell.codepoint();
|
||||
|
||||
/* display absent codepoints as whitespace */
|
||||
bool const codepoint_valid = (codepoint.value != 0);
|
||||
|
||||
bool const selected = _selection.selected(Position(column, line))
|
||||
&& codepoint_valid;
|
||||
|
||||
bool const pointer = (_pointer == Position(column, line));
|
||||
|
||||
if (!codepoint_valid)
|
||||
codepoint = Codepoint{' '};
|
||||
|
||||
_font.apply_glyph(codepoint, [&] (Glyph_painter::Glyph const &glyph) {
|
||||
|
||||
Color_palette::Highlighted const highlighted { cell.highlight() };
|
||||
|
||||
|
@ -216,6 +263,16 @@ class Terminal::Text_screen_surface
|
|||
Color fg_color = _palette.foreground(fg_idx, highlighted);
|
||||
Color bg_color = _palette.background(bg_idx, highlighted);
|
||||
|
||||
if (selected) {
|
||||
bg_color = Color(180, 180, 180);
|
||||
fg_color = Color( 50, 50, 50);
|
||||
}
|
||||
|
||||
if (pointer) {
|
||||
bg_color = Color(220, 220, 220);
|
||||
fg_color = Color( 50, 50, 50);
|
||||
}
|
||||
|
||||
if (cell.has_cursor()) {
|
||||
fg_color = Color( 63, 63, 63);
|
||||
bg_color = Color(255, 255, 255);
|
||||
|
@ -271,6 +328,8 @@ class Terminal::Text_screen_surface
|
|||
|
||||
void apply_character(Character c)
|
||||
{
|
||||
clear_selection();
|
||||
|
||||
/* submit character to sequence decoder */
|
||||
_decoder.insert(c);
|
||||
}
|
||||
|
@ -284,6 +343,110 @@ class Terminal::Text_screen_surface
|
|||
* Return size in colums/rows
|
||||
*/
|
||||
Area size() const { return _geometry.size(); }
|
||||
|
||||
/**
|
||||
* Set pointer position in pixels (to show the cursor)
|
||||
*/
|
||||
void pointer(Point pointer)
|
||||
{
|
||||
auto position_valid = [&] (Position pos) {
|
||||
return pos.y >= 0 && pos.y < (int)_geometry.lines; };
|
||||
|
||||
/* update old position */
|
||||
if (position_valid(_pointer))
|
||||
_cell_array.mark_line_as_dirty(_pointer.y);
|
||||
|
||||
_pointer = _geometry.position(pointer);
|
||||
|
||||
/* update new position */
|
||||
if (position_valid(_pointer))
|
||||
_cell_array.mark_line_as_dirty(_pointer.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set anchor point of selection
|
||||
*
|
||||
* \param pointer pointer position in pixels
|
||||
*/
|
||||
void start_selection(Point pointer)
|
||||
{
|
||||
if (_selection.defined)
|
||||
clear_selection();
|
||||
|
||||
_selection.start = _geometry.position(pointer);
|
||||
|
||||
define_selection(pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set end position of current selection
|
||||
*
|
||||
* \param pointer pointer position in pixels
|
||||
*/
|
||||
void define_selection(Point pointer)
|
||||
{
|
||||
_selection.for_each_line([&] (int line) {
|
||||
_cell_array.mark_line_as_dirty(line); });
|
||||
|
||||
_selection.end = _geometry.position(pointer);
|
||||
_selection.defined = true;
|
||||
|
||||
_selection.for_each_line([&] (int line) {
|
||||
_cell_array.mark_line_as_dirty(line); });
|
||||
}
|
||||
|
||||
void clear_selection()
|
||||
{
|
||||
if (!_selection.defined)
|
||||
return;
|
||||
|
||||
_selection.for_each_line([&] (int line) {
|
||||
_cell_array.mark_line_as_dirty(line); });
|
||||
|
||||
_selection.defined = false;
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void for_each_selected_character(FN const &fn) const
|
||||
{
|
||||
for (unsigned row = 0; row < _geometry.lines; row++) {
|
||||
bool skip_remaining_chars_on_row = false;
|
||||
|
||||
for (unsigned column = 0; column < _geometry.columns; column++) {
|
||||
|
||||
if (skip_remaining_chars_on_row)
|
||||
continue;
|
||||
|
||||
if (!_selection.selected(Position(column, row)))
|
||||
continue;
|
||||
|
||||
Codepoint const c { _cell_array.get_cell(column, row).value };
|
||||
|
||||
if (c.value == 0) {
|
||||
|
||||
auto remaining_line_empty = [&] ()
|
||||
{
|
||||
for (unsigned i = column + 1; i < _geometry.columns; i++)
|
||||
if (_cell_array.get_cell(i, row).value)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/* generate one line break at the end of a selected line */
|
||||
if (remaining_line_empty()) {
|
||||
fn(Codepoint{'\n'});
|
||||
skip_remaining_chars_on_row = true;
|
||||
|
||||
} else {
|
||||
fn(Codepoint{' '});
|
||||
}
|
||||
} else {
|
||||
fn(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _TEXT_SCREEN_SURFACE_H_ */
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
/* local includes */
|
||||
#include <nitpicker.h>
|
||||
#include <report_forwarder.h>
|
||||
#include <rom_forwarder.h>
|
||||
|
||||
namespace Wm {
|
||||
|
||||
|
@ -110,6 +111,7 @@ struct Wm::Main
|
|||
{ env.ep(), *this, &Main::handle_resize_request_update };
|
||||
|
||||
Report_forwarder _report_forwarder { env, heap };
|
||||
Rom_forwarder _rom_forwarder { env, heap };
|
||||
|
||||
Main(Genode::Env &env) : env(env)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* \brief Report service for intercepting shape reports
|
||||
* \brief Report service for intercepting shape and clipboard reports
|
||||
* \author Norman Feske
|
||||
* \date 2019-02-18
|
||||
*
|
||||
|
@ -7,6 +7,9 @@
|
|||
* policy to an application's shape report as done for the application's
|
||||
* 'Nitpicker' session. This consistency is needed by the pointer to correlate
|
||||
* the currently hovered nitpicker session with the reported shapes.
|
||||
* Analogously, clipboard reports can be routed through the window
|
||||
* manager to support the clipboard component with associating its clients
|
||||
* with nitpicker's reported focus.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
96
repos/gems/src/server/wm/rom_forwarder.h
Normal file
96
repos/gems/src/server/wm/rom_forwarder.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* \brief ROM service for intercepting clipboard ROMs
|
||||
* \author Norman Feske
|
||||
* \date 2019-06-26
|
||||
*
|
||||
* This ROM service can be used as proxy for clipboard ROMs to ensure the
|
||||
* consistency of the client labels appearing at the clipboard component
|
||||
* with the label of the currently focused nitpicker client.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _ROM_FORWARDER_H_
|
||||
#define _ROM_FORWARDER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <root/component.h>
|
||||
#include <rom_session/connection.h>
|
||||
|
||||
namespace Wm { struct Rom_forwarder; }
|
||||
|
||||
|
||||
struct Wm::Rom_forwarder
|
||||
{
|
||||
struct Session : Genode::Rpc_object<Genode::Rom_session>
|
||||
{
|
||||
Genode::Env &_env;
|
||||
Genode::Rom_connection _connection;
|
||||
|
||||
Session(Genode::Env &env, Genode::Session_label const &label)
|
||||
: _env(env), _connection(env, label.string())
|
||||
{ _env.ep().manage(*this); }
|
||||
|
||||
~Session() { _env.ep().dissolve(*this); }
|
||||
|
||||
void upgrade(Genode::Session::Resources const &resources)
|
||||
{
|
||||
_connection.upgrade(resources);
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
** Rom_session interface **
|
||||
***************************/
|
||||
|
||||
Genode::Rom_dataspace_capability dataspace() override
|
||||
{
|
||||
return _connection.dataspace();
|
||||
}
|
||||
|
||||
bool update() override
|
||||
{
|
||||
return _connection.update();
|
||||
}
|
||||
|
||||
void sigh(Signal_context_capability sigh) override
|
||||
{
|
||||
_connection.sigh(sigh);
|
||||
}
|
||||
};
|
||||
|
||||
struct Root : Genode::Root_component<Session>
|
||||
{
|
||||
Genode::Env &_env;
|
||||
Genode::Allocator &_alloc;
|
||||
|
||||
Session *_create_session(char const *args) override
|
||||
{
|
||||
return new (md_alloc()) Session(_env, Genode::label_from_args(args));
|
||||
}
|
||||
|
||||
void _upgrade_session(Session *session, const char *args) override
|
||||
{
|
||||
session->upgrade(Genode::session_resources_from_args(args));
|
||||
}
|
||||
|
||||
Root(Genode::Env &env, Genode::Allocator &alloc)
|
||||
:
|
||||
Genode::Root_component<Session>(env.ep(), alloc),
|
||||
_env(env), _alloc(alloc)
|
||||
{
|
||||
_env.parent().announce(env.ep().manage(*this));
|
||||
}
|
||||
|
||||
} _root;
|
||||
|
||||
Rom_forwarder(Genode::Env &env, Genode::Allocator &alloc)
|
||||
: _root(env, alloc) { }
|
||||
};
|
||||
|
||||
#endif /* _ROM_FORWARDER_H_ */
|
|
@ -4,6 +4,8 @@
|
|||
<file_system/>
|
||||
<nitpicker/>
|
||||
<report label="shape"/>
|
||||
<report label="clipboard"/>
|
||||
<rom label="clipboard"/>
|
||||
<timer/>
|
||||
</requires>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<config>
|
||||
<config clipboard="yes">
|
||||
<vfs>
|
||||
<dir name="dev">
|
||||
<log/>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# \date 2016-06-05
|
||||
#
|
||||
|
||||
if {[have_spec linux] || [have_spec imx7d_sabre] ||
|
||||
if {[have_spec linux] || [have_spec rpi3] ||
|
||||
[expr [have_spec imx53] && [have_spec trustzone]]} {
|
||||
puts "Run script does not support this platform."
|
||||
exit 0
|
||||
|
|
|
@ -9,14 +9,14 @@ if {[have_spec odroid_xu] || [have_spec zynq]} {
|
|||
exit 0
|
||||
}
|
||||
|
||||
# use SD on ARM
|
||||
set use_sd_card_drv [expr [have_spec pbxa9]]
|
||||
# use SD on Qemu/pbxa9
|
||||
set use_sd_card_drv [expr [have_include "power_on/qemu"] && [have_spec pbxa9]]
|
||||
|
||||
# use AHCI on x86
|
||||
set use_ahci [expr [have_spec x86] && ![have_spec linux]]
|
||||
|
||||
# use ram_block on Linux
|
||||
set use_ram_block [have_spec linux]
|
||||
# use ram_block on Linux and Qemu/rpi3
|
||||
set use_ram_block [expr [have_spec linux] || [expr [have_include "power_on/qemu"] && [have_spec rpi3]]]
|
||||
|
||||
if {[catch { exec which $mkfs_cmd } ]} {
|
||||
puts stderr "Error: $mkfs_cmd not installed, aborting test"; exit }
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
if {[expr [have_spec linux]] ||
|
||||
[expr [have_spec imx53] && [have_spec trustzone]] ||
|
||||
[expr [have_spec imx7d_sabre]] ||
|
||||
[have_spec rpi3] ||
|
||||
[expr [have_spec riscv]]} {
|
||||
puts "\n Run script is not supported on this platform. \n"; exit 0 }
|
||||
|
||||
|
|
|
@ -70,7 +70,9 @@ set config {
|
|||
<start name="wm" caps="1000">
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<binary name="init"/>
|
||||
<provides> <service name="Nitpicker"/> </provides>
|
||||
<provides>
|
||||
<service name="Nitpicker"/> <service name="Report"/> <service name="ROM"/>
|
||||
</provides>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <parent label="wm.config"/> </service>
|
||||
<service name="Nitpicker"> <child name="nitpicker"/> </service>
|
||||
|
|
|
@ -3,6 +3,11 @@ if {![have_include power_on/qemu]} {
|
|||
exit 0
|
||||
}
|
||||
|
||||
if {[have_spec rpi3]} {
|
||||
puts "\n Run script is not supported on this platform. \n";
|
||||
exit 0
|
||||
}
|
||||
|
||||
create_boot_directory
|
||||
|
||||
import_from_depot [depot_user]/src/[base_src] \
|
||||
|
|
|
@ -187,7 +187,7 @@ proc qt5_start_nodes { feature_arg } {
|
|||
<start name="wm" caps="250">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides>
|
||||
<service name="Nitpicker"/> <service name="Report"/>
|
||||
<service name="Nitpicker"/> <service name="Report"/> <service name="ROM"/>
|
||||
</provides>
|
||||
<config>
|
||||
<policy label_prefix="decorator" role="decorator"/>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
if {![have_spec 64bit]} {
|
||||
puts "\nSolo5 requires a 64bit architecture\n"
|
||||
if {![have_spec x86_64]} {
|
||||
puts "\nTest requires x86_64\n"
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
if {![have_spec x86_64]} {
|
||||
puts "\nSolo5 requires a 64bit architecture\n"
|
||||
puts "\nTest requires x86_64\n"
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
if {![have_spec 64bit]} {
|
||||
puts "\nSolo5 requires a 64bit architecture\n"
|
||||
if {![have_spec x86_64]} {
|
||||
puts "\nTest requires x86_64\n"
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
|
|
@ -20,4 +20,5 @@
|
|||
-#define MB_CUR_MAX_L(x) ((size_t)___mb_cur_max_l(x))
|
||||
+/* ASCII only */
|
||||
+#define MB_CUR_MAX_L(x) 1
|
||||
|
||||
|
||||
|
||||
|
|
63
repos/libports/src/lib/libc/patches/cdefs_no_hidden.patch
Normal file
63
repos/libports/src/lib/libc/patches/cdefs_no_hidden.patch
Normal file
|
@ -0,0 +1,63 @@
|
|||
Prevent the use of the hidden attribute for symbols. In particular,
|
||||
the attribute must not be applied to '__libc'-prefixed symbols to allow
|
||||
overwriting the dummies defined in dummies.cc by other non-weak
|
||||
implementations such as those in 'libc_noux.lib.so'.
|
||||
|
||||
This attribute is applied inconsistently in
|
||||
libc/lib/libc/include/libc_private.h anyway.
|
||||
|
||||
Also, force i386 to call __libc_sigprocmask via PLT to prevent
|
||||
R_386_PC32 relocations, which had to change the text segment. Other
|
||||
architectures do this automatically.
|
||||
|
||||
--- src/lib/libc/sys/sys/cdefs.h
|
||||
+++ src/lib/libc/sys/sys/cdefs.h
|
||||
@@ -447,7 +447,7 @@
|
||||
#if __GNUC_PREREQ__(4, 0)
|
||||
#define __null_sentinel __attribute__((__sentinel__))
|
||||
#define __exported __attribute__((__visibility__("default")))
|
||||
-#define __hidden __attribute__((__visibility__("hidden")))
|
||||
+#define __hidden
|
||||
#else
|
||||
#define __null_sentinel
|
||||
#define __exported
|
||||
--- src/lib/libc/lib/libc/i386/gen/setjmp.S
|
||||
+++ src/lib/libc/lib/libc/i386/gen/setjmp.S
|
||||
@@ -54,7 +54,7 @@
|
||||
pushl %eax /* (sigset_t*)oset */
|
||||
pushl $0 /* (sigset_t*)set */
|
||||
pushl $1 /* SIG_BLOCK */
|
||||
- call __libc_sigprocmask
|
||||
+ call __i386_libc_sigprocmask
|
||||
addl $12,%esp
|
||||
movl 4(%esp),%ecx
|
||||
movl 0(%esp),%edx
|
||||
@@ -76,7 +76,7 @@
|
||||
leal 28(%edx), %eax
|
||||
pushl %eax /* (sigset_t*)set */
|
||||
pushl $3 /* SIG_SETMASK */
|
||||
- call __libc_sigprocmask
|
||||
+ call __i386_libc_sigprocmask
|
||||
addl $12,%esp
|
||||
movl 4(%esp),%edx
|
||||
movl 8(%esp),%eax
|
||||
--- src/lib/libc/lib/libc/i386/gen/sigsetjmp.S
|
||||
+++ src/lib/libc/lib/libc/i386/gen/sigsetjmp.S
|
||||
@@ -63,7 +63,7 @@
|
||||
pushl %eax /* (sigset_t*)oset */
|
||||
pushl $0 /* (sigset_t*)set */
|
||||
pushl $1 /* SIG_BLOCK */
|
||||
- call __libc_sigprocmask
|
||||
+ call __i386_libc_sigprocmask
|
||||
addl $12,%esp
|
||||
movl 4(%esp),%ecx
|
||||
2: movl 0(%esp),%edx
|
||||
@@ -87,7 +87,7 @@
|
||||
leal 28(%edx), %eax
|
||||
pushl %eax /* (sigset_t*)set */
|
||||
pushl $3 /* SIG_SETMASK */
|
||||
- call __libc_sigprocmask
|
||||
+ call __i386_libc_sigprocmask
|
||||
addl $12,%esp
|
||||
movl 4(%esp),%edx
|
||||
2: movl 8(%esp),%eax
|
|
@ -55,6 +55,14 @@ int __libc_sigprocmask(int how, const sigset_t *set, sigset_t *old) {
|
|||
return sigprocmask(how, set, old); }
|
||||
|
||||
|
||||
/* wrapper from text-relocated i386-assembler call to PLT call */
|
||||
extern "C" int __i386_libc_sigprocmask(int how, const sigset_t *set, sigset_t *old) __attribute__((visibility("hidden")));
|
||||
extern "C" int __i386_libc_sigprocmask(int how, const sigset_t *set, sigset_t *old)
|
||||
{
|
||||
return __libc_sigprocmask(how, set, old);
|
||||
}
|
||||
|
||||
|
||||
extern "C" __attribute__((weak))
|
||||
pid_t wait4(pid_t, int *, int, struct rusage *)
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
struct Char_cell
|
||||
{
|
||||
Genode::uint16_t value { ' ' };
|
||||
Genode::uint16_t value { 0 };
|
||||
|
||||
unsigned char attr;
|
||||
unsigned char color;
|
||||
|
|
|
@ -76,6 +76,23 @@ struct Terminal::Position
|
|||
bool operator != (Position const &pos) const {
|
||||
return (pos.x != x) || (pos.y != y); }
|
||||
|
||||
bool operator >= (Position const &other) const
|
||||
{
|
||||
if (y > other.y)
|
||||
return true;
|
||||
|
||||
if (y == other.y && x >= other.x)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool in_range(Position start, Position end) const
|
||||
{
|
||||
return (end >= start) ? *this >= start && end >= *this
|
||||
: *this >= end && start >= *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if position lies within the specified boundaries
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
if {[have_spec odroid_xu] ||
|
||||
[have_spec imx7d_sabre] ||
|
||||
[have_spec imx6q_sabrelite] ||
|
||||
[have_spec rpi3] ||
|
||||
[have_spec zynq] ||
|
||||
[have_spec imx53] && [have_spec foc]} {
|
||||
puts "\n Run script is not supported on this platform. \n";
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
if {[have_spec foc] || [have_spec odroid_xu] || [have_spec linux] || [have_spec imx7d_sabre] ||
|
||||
if {[have_spec foc] || [have_spec odroid_xu] || [have_spec linux] ||
|
||||
[have_spec rpi3] ||
|
||||
[expr [have_spec imx53] && [have_spec trustzone]]} {
|
||||
puts "Run script is not supported on this platform."
|
||||
exit 0
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
if {![have_include power_on/qemu] ||
|
||||
[have_spec foc] ||
|
||||
[have_spec rpi3] ||
|
||||
[expr [have_spec imx53] && [have_spec trustzone]]} {
|
||||
|
||||
puts "Run script is not supported on this platform."
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
if {[have_spec foc] || [have_spec linux] || [have_spec imx7d_sabre] ||
|
||||
if {[have_spec foc] || [have_spec linux] ||
|
||||
[have_spec rpi3] ||
|
||||
[expr [have_spec imx53] && [have_spec trustzone]]} {
|
||||
puts "Run script is not supported on this platform."
|
||||
exit 0
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
if {[have_spec foc] || [have_spec odroid_xu] || [have_spec linux] || [have_spec imx7d_sabre] ||
|
||||
if {[have_spec foc] || [have_spec odroid_xu] || [have_spec linux] ||
|
||||
[have_spec rpi3] ||
|
||||
[expr [have_spec imx53] && [have_spec trustzone]]} {
|
||||
puts "Run script is not supported on this platform."
|
||||
exit 0
|
||||
|
|
|
@ -223,7 +223,14 @@ foreach rom [content_rom_modules] {
|
|||
|
||||
# raw-archive content is installed directly into [run_dir]/genode
|
||||
if {![rom_module_from_raw_archive $rom]} {
|
||||
lappend boot_modules $rom }
|
||||
lappend boot_modules $rom
|
||||
}
|
||||
|
||||
# handle vfs plugin shared-object targets
|
||||
if {[regexp "^vfs_(.+).lib.so$" $rom dummy plugin]} {
|
||||
lappend build_targets lib/vfs/$plugin
|
||||
continue
|
||||
}
|
||||
|
||||
if {[info exists src_sub_dir($rom)]} {
|
||||
lappend build_targets $src_sub_dir($rom)
|
||||
|
|
|
@ -76,15 +76,11 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||
|
||||
Genode::Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
bool _verbose_config()
|
||||
{
|
||||
char const *attr = "verbose";
|
||||
return _config.xml().attribute_value(attr, false);
|
||||
}
|
||||
|
||||
bool verbose { _verbose_config() };
|
||||
bool _verbose = false;
|
||||
bool _match_labels = false;
|
||||
|
||||
typedef Genode::String<100> Domain;
|
||||
typedef Genode::String<100> Label;
|
||||
|
||||
Genode::Attached_rom_dataspace _focus_ds { _env, "focus" };
|
||||
|
||||
|
@ -94,6 +90,7 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||
{ _env.ep(), *this, &Main::_handle_focus };
|
||||
|
||||
Domain _focused_domain { };
|
||||
Label _focused_label { };
|
||||
|
||||
/**
|
||||
* Handle configuration changes
|
||||
|
@ -101,7 +98,8 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||
void _handle_config()
|
||||
{
|
||||
_config.update();
|
||||
verbose = _verbose_config();
|
||||
_verbose = _config.xml().attribute_value("verbose", false);
|
||||
_match_labels = _config.xml().attribute_value("match_labels", false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,14 +112,14 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||
_focus_ds.update();
|
||||
|
||||
_focused_domain = Domain();
|
||||
_focused_label = Label();
|
||||
|
||||
try {
|
||||
Genode::Xml_node focus(_focus_ds.local_addr<char>(), _focus_ds.size());
|
||||
Genode::Xml_node const focus = _focus_ds.xml();
|
||||
|
||||
if (focus.attribute_value("active", false))
|
||||
_focused_domain = focus.attribute_value("domain", Domain());
|
||||
|
||||
} catch (...) { }
|
||||
if (focus.attribute_value("active", false)) {
|
||||
_focused_domain = focus.attribute_value("domain", Domain());
|
||||
_focused_label = focus.attribute_value("label", Label());
|
||||
}
|
||||
}
|
||||
|
||||
Domain _domain(Genode::Session_label const &label) const
|
||||
|
@ -135,20 +133,30 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||
return Domain();
|
||||
}
|
||||
|
||||
Domain _domain(Rom::Reader const &reader) const
|
||||
Label _label(Rom::Reader const &reader) const
|
||||
{
|
||||
Rom::Session_component const &rom_session =
|
||||
static_cast<Rom::Session_component const &>(reader);
|
||||
|
||||
return _domain(rom_session.label());
|
||||
return rom_session.label();
|
||||
}
|
||||
|
||||
Domain _domain(Rom::Writer const &writer) const
|
||||
Domain _domain(Rom::Reader const &reader) const
|
||||
{
|
||||
return _domain(_label(reader));
|
||||
}
|
||||
|
||||
Label _label(Rom::Writer const &writer) const
|
||||
{
|
||||
Report::Session_component const &report_session =
|
||||
static_cast<Report::Session_component const &>(writer);
|
||||
|
||||
return _domain(report_session.label());
|
||||
return report_session.label();
|
||||
}
|
||||
|
||||
Domain _domain(Rom::Writer const &writer) const
|
||||
{
|
||||
return _domain(_label(writer));
|
||||
}
|
||||
|
||||
bool _flow_defined(Domain const &from, Domain const &to) const
|
||||
|
@ -175,6 +183,39 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||
return result;
|
||||
}
|
||||
|
||||
bool _client_label_matches_focus(Genode::Session_label const &label) const
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/*
|
||||
* The client label has the suffix " -> clipboard". Strip off this
|
||||
* part to make the label comparable with the label of the client's
|
||||
* nitpicker session (which has of course no such suffix).
|
||||
*/
|
||||
char const *suffix = " -> clipboard";
|
||||
size_t const suffix_len = strlen(suffix);
|
||||
|
||||
if (label.length() < suffix_len + 1)
|
||||
return false;
|
||||
|
||||
size_t const truncated_label_len = label.length() - suffix_len - 1;
|
||||
|
||||
Session_label const
|
||||
truncated_label(Cstring(label.string(), truncated_label_len));
|
||||
|
||||
/*
|
||||
* We accept any subsystem of the client to have the nitpicker focus.
|
||||
* E.g., a multi-window application may have multiple nitpicker
|
||||
* sessions, one for each window. The labels of all of those nitpicker
|
||||
* session share the first part with application's clipboard label.
|
||||
*/
|
||||
bool const focus_lies_in_client_subsystem =
|
||||
!strcmp(_focused_label.string(), truncated_label.string(),
|
||||
truncated_label_len);
|
||||
|
||||
return focus_lies_in_client_subsystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rom::Module::Read_policy interface
|
||||
*/
|
||||
|
@ -185,6 +226,9 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||
Domain const from_domain = _domain(writer);
|
||||
Domain const to_domain = _domain(reader);
|
||||
|
||||
if (_match_labels && !_client_label_matches_focus(_label(reader)))
|
||||
return false;
|
||||
|
||||
if (from_domain == to_domain)
|
||||
return true;
|
||||
|
||||
|
@ -194,14 +238,16 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rom::Module::Write_policy interface
|
||||
*/
|
||||
bool write_permitted(Rom::Module const &module,
|
||||
Rom::Writer const &writer) const override
|
||||
{
|
||||
if (_focused_domain.valid() && _domain(writer) == _focused_domain)
|
||||
bool const domain_matches =
|
||||
_focused_domain.valid() && _domain(writer) == _focused_domain;
|
||||
|
||||
if ((!_match_labels || _client_label_matches_focus(_label(writer))) && domain_matches)
|
||||
return true;
|
||||
|
||||
warning("unexpected attempt by '", writer.label(), "' "
|
||||
|
@ -212,11 +258,13 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||
|
||||
Rom::Registry _rom_registry { _env.ram(), _env.rm(), *this, *this };
|
||||
|
||||
Report::Root report_root = { _env, _sliced_heap, _rom_registry, verbose };
|
||||
Report::Root report_root = { _env, _sliced_heap, _rom_registry, _verbose };
|
||||
Rom ::Root rom_root = { _env, _sliced_heap, _rom_registry };
|
||||
|
||||
Main(Genode::Env &env) : _env(env)
|
||||
{
|
||||
_config.sigh(_config_handler);
|
||||
_handle_config();
|
||||
_focus_ds.sigh(_focus_handler);
|
||||
|
||||
_handle_focus();
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
The new _trace_fs_ server provides access to a trace session by providing a
|
||||
file-system session as front end. Combined with Noux, it allows for the
|
||||
interactive exploration and tracing of Genode's process tree using
|
||||
traditional Unix tools.
|
||||
|
||||
Each trace subject is represented by a directory ('thread_name.subject') that
|
||||
contains specific files, which are used to control the tracing process of the
|
||||
thread as well as storing the content of its trace buffer:
|
||||
|
||||
:'enable': The tracing of a thread is activated if there is a valid policy
|
||||
installed and the intend to trace the subject was made clear by writing '1'
|
||||
to the 'enable' file. The tracing of a thread may be deactivated by writing a
|
||||
'0' to this file.
|
||||
|
||||
:'policy': A policy may be changed by overwriting the currently used one in the
|
||||
'policy' file. In this case, the old policy is replaced by the new one and
|
||||
automatically used by the framework.
|
||||
|
||||
:'buffer_size': Writing a value to the 'buffer_size' file changes the size of
|
||||
the trace buffer. This value is evaluated only when reactivating the tracing
|
||||
of the thread.
|
||||
|
||||
:'events': The trace-buffer contents may be accessed by reading from the
|
||||
'events' file. New trace events are appended to this file.
|
||||
|
||||
:'active': Reading the file will return whether the tracing is active (1) or
|
||||
not (0).
|
||||
|
||||
:'cleanup': Nodes of untraced subjects are kept as long as they do not change
|
||||
their tracing state to dead. Dead untraced nodes are automatically removed
|
||||
from the file system. Subjects that were traced before and are now untraced
|
||||
can be removed by writing '1' to the 'cleanup' file.
|
||||
|
||||
To use the trace_fs, a configuration similar to the following may be used:
|
||||
|
||||
! <start name="trace_fs">
|
||||
! <resource name="RAM" quantum="128M"/>
|
||||
! <provides><service name="File_system"/></provides>
|
||||
! <config>
|
||||
! <policy label_prefix="noux -> trace"
|
||||
! interval="1000"
|
||||
! subject_limit="512"
|
||||
! trace_quota="64M" />
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
:'interval': sets the period the Trace_session is polled. The
|
||||
time is given in milliseconds.
|
||||
|
||||
:'subject_limit': specifies how many trace subjects should by acquired at
|
||||
max when the Trace_session is polled.
|
||||
|
||||
:'trace_quota': is the amount of quota the trace_fs should use for the
|
||||
Trace_session connection. The remaining amount of RAM quota will be used
|
||||
for the actual nodes of the file system and the 'policy' as well as the
|
||||
'events' files.
|
||||
|
||||
In addition, there are 'buffer_size' and 'buffer_size_limit' that define
|
||||
the initial and the upper limit of the size of a trace buffer.
|
||||
|
||||
A ready-to-use run script can by found in 'ports/run/noux_trace_fs.run'.
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
* \brief Buffer class
|
||||
* \author Josef Soentgen
|
||||
* \date 2014-01-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _BUFFER_H_
|
||||
#define _BUFFER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/string.h>
|
||||
|
||||
namespace Util {
|
||||
|
||||
typedef Genode::size_t size_t;
|
||||
|
||||
|
||||
/**
|
||||
* Buffer merely wrapps a simple char array
|
||||
*/
|
||||
template <size_t CAPACITY>
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
|
||||
class Out_of_range { };
|
||||
|
||||
private:
|
||||
|
||||
char _buf[CAPACITY];
|
||||
size_t _length;
|
||||
|
||||
public:
|
||||
|
||||
static size_t capacity() { return CAPACITY; }
|
||||
|
||||
Buffer() : _length(0) { }
|
||||
|
||||
Buffer(char const *s)
|
||||
:
|
||||
_length(Genode::min(Genode::strlen(s) + 1, CAPACITY))
|
||||
{
|
||||
Genode::strncpy(_buf, s, _length);
|
||||
}
|
||||
|
||||
char const *data() const { return (_buf[_length -1 ] == '\0') ? _buf : ""; }
|
||||
|
||||
char *data() { return _buf; }
|
||||
|
||||
size_t length() const { return _length; }
|
||||
|
||||
char & operator[](size_t i)
|
||||
{
|
||||
if (i >= CAPACITY)
|
||||
throw Out_of_range();
|
||||
|
||||
return _buf[i];
|
||||
}
|
||||
|
||||
void replace(char p, char c)
|
||||
{
|
||||
char *s = _buf;
|
||||
for (; *s; s++) {
|
||||
if (*s == p)
|
||||
*s = c;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This class walks along a label and returns the next element on request
|
||||
*/
|
||||
class Label_walker
|
||||
{
|
||||
private:
|
||||
|
||||
Buffer<64> _buffer;
|
||||
char const *_label;
|
||||
|
||||
char const *_next()
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
for (; *_label && (i < _buffer.capacity()); _label++, i++) {
|
||||
/* check seperator */
|
||||
if ((*_label == ' ') &&
|
||||
(*(_label + 1) == '-') &&
|
||||
(*(_label + 2) == '>') &&
|
||||
(*(_label + 3) == ' '))
|
||||
break;
|
||||
_buffer[i] = *_label;
|
||||
}
|
||||
|
||||
_buffer[i] = '\0';
|
||||
|
||||
/* sanatize the element */
|
||||
_buffer.replace('/', '_');
|
||||
|
||||
/* omit seperator */
|
||||
if (*_label)
|
||||
_label += 4;
|
||||
|
||||
return _label;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Label_walker(char const *label) : _label(label) { }
|
||||
|
||||
/**
|
||||
* Walk to the next element of the label
|
||||
*
|
||||
* \return pointer to the remaing part of the label
|
||||
*/
|
||||
char const *next() { return _next(); }
|
||||
|
||||
/**
|
||||
* Get current element of the label
|
||||
*
|
||||
* \return pointer to current element
|
||||
*/
|
||||
char const *element() { return _buffer.data(); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _BUFFER_H_ */
|
|
@ -1,441 +0,0 @@
|
|||
/*
|
||||
* \brief Data structure for storing sparse files in RAM
|
||||
* \author Norman Feske
|
||||
* \date 2012-04-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _CHUNK_H_
|
||||
#define _CHUNK_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/noncopyable.h>
|
||||
#include <base/allocator.h>
|
||||
#include <util/string.h>
|
||||
#include <file_system_session/file_system_session.h>
|
||||
|
||||
namespace File_system {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/**
|
||||
* Common base class of both 'Chunk' and 'Chunk_index'
|
||||
*/
|
||||
class Chunk_base : Noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
class Index_out_of_range { };
|
||||
|
||||
protected:
|
||||
|
||||
seek_off_t const _base_offset;
|
||||
size_t _num_entries; /* corresponds to last used entry */
|
||||
|
||||
/**
|
||||
* Test if specified range lies within the chunk
|
||||
*/
|
||||
void assert_valid_range(seek_off_t start, size_t len,
|
||||
file_size_t chunk_size) const
|
||||
{
|
||||
if (zero()) return;
|
||||
|
||||
if (start < _base_offset)
|
||||
throw Index_out_of_range();
|
||||
|
||||
if (start + len > _base_offset + chunk_size)
|
||||
throw Index_out_of_range();
|
||||
}
|
||||
|
||||
Chunk_base(seek_off_t base_offset)
|
||||
: _base_offset(base_offset), _num_entries(0) { }
|
||||
|
||||
/**
|
||||
* Construct zero chunk
|
||||
*
|
||||
* A zero chunk is a chunk that cannot be written to. When reading
|
||||
* from it, it returns zeros. Because there is a single zero chunk
|
||||
* for each chunk type, the base offset is meaningless. We use a
|
||||
* base offset of ~0 as marker to identify zero chunks.
|
||||
*/
|
||||
Chunk_base() : _base_offset(~0L), _num_entries(0) { }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Return absolute base offset of chunk in bytes
|
||||
*/
|
||||
seek_off_t base_offset() const { return _base_offset; }
|
||||
|
||||
/**
|
||||
* Return true if chunk is a read-only zero chunk
|
||||
*/
|
||||
bool zero() const { return _base_offset == (seek_off_t)(~0L); }
|
||||
|
||||
/**
|
||||
* Return true if chunk has no allocated sub chunks
|
||||
*/
|
||||
bool empty() const { return _num_entries == 0; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Chunk of bytes used as leaf in hierarchy of chunk indices
|
||||
*/
|
||||
template <unsigned CHUNK_SIZE>
|
||||
class Chunk : public Chunk_base
|
||||
{
|
||||
private:
|
||||
|
||||
char _data[CHUNK_SIZE];
|
||||
|
||||
public:
|
||||
|
||||
enum { SIZE = CHUNK_SIZE };
|
||||
|
||||
/**
|
||||
* Construct byte chunk
|
||||
*
|
||||
* \param base_offset absolute offset of chunk in bytes
|
||||
*
|
||||
* The first argument is unused. Its mere purpose is to make the
|
||||
* signature of the constructor compatible to the constructor
|
||||
* of 'Chunk_index'.
|
||||
*/
|
||||
Chunk(Allocator &, seek_off_t base_offset)
|
||||
:
|
||||
Chunk_base(base_offset)
|
||||
{
|
||||
memset(_data, 0, CHUNK_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct zero chunk
|
||||
*/
|
||||
Chunk() { }
|
||||
|
||||
/**
|
||||
* Return number of used entries
|
||||
*
|
||||
* The returned value corresponds to the index of the last used
|
||||
* entry + 1. It does not correlate to the number of actually
|
||||
* allocated entries (there may be ranges of zero blocks).
|
||||
*/
|
||||
file_size_t used_size() const { return _num_entries; }
|
||||
|
||||
void write(char const *src, size_t len, seek_off_t seek_offset)
|
||||
{
|
||||
assert_valid_range(seek_offset, len, SIZE);
|
||||
|
||||
/* offset relative to this chunk */
|
||||
seek_off_t const local_offset = seek_offset - base_offset();
|
||||
|
||||
memcpy(&_data[local_offset], src, len);
|
||||
|
||||
_num_entries = max(_num_entries, local_offset + len);
|
||||
}
|
||||
|
||||
void read(char *dst, size_t len, seek_off_t seek_offset) const
|
||||
{
|
||||
assert_valid_range(seek_offset, len, SIZE);
|
||||
|
||||
memcpy(dst, &_data[seek_offset - base_offset()], len);
|
||||
}
|
||||
|
||||
void truncate(file_size_t size)
|
||||
{
|
||||
assert_valid_range(size, 0, SIZE);
|
||||
|
||||
/*
|
||||
* Offset of the first free position (relative to the beginning
|
||||
* this chunk).
|
||||
*/
|
||||
seek_off_t const local_offset = size - base_offset();
|
||||
|
||||
if (local_offset >= _num_entries)
|
||||
return;
|
||||
|
||||
memset(&_data[local_offset], 0, _num_entries - local_offset);
|
||||
|
||||
_num_entries = local_offset;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <unsigned NUM_ENTRIES, typename ENTRY_TYPE>
|
||||
class Chunk_index : public Chunk_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ENTRY_TYPE Entry;
|
||||
|
||||
enum { ENTRY_SIZE = ENTRY_TYPE::SIZE,
|
||||
SIZE = ENTRY_SIZE*NUM_ENTRIES };
|
||||
|
||||
private:
|
||||
|
||||
Allocator &_alloc;
|
||||
|
||||
Entry * _entries[NUM_ENTRIES];
|
||||
|
||||
/**
|
||||
* Return instance of a zero sub chunk
|
||||
*/
|
||||
static Entry const &_zero_chunk()
|
||||
{
|
||||
static Entry zero_chunk;
|
||||
return zero_chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return sub chunk at given index
|
||||
*
|
||||
* If there is no sub chunk at the specified index, this function
|
||||
* transparently allocates one. Hence, the returned sub chunk
|
||||
* is ready to be written to.
|
||||
*/
|
||||
Entry &_entry_for_writing(unsigned index)
|
||||
{
|
||||
if (index >= NUM_ENTRIES)
|
||||
throw Index_out_of_range();
|
||||
|
||||
if (_entries[index])
|
||||
return *_entries[index];
|
||||
|
||||
seek_off_t entry_offset = base_offset() + index*ENTRY_SIZE;
|
||||
|
||||
_entries[index] = new (&_alloc) Entry(_alloc, entry_offset);
|
||||
|
||||
_num_entries = max(_num_entries, index + 1);
|
||||
|
||||
return *_entries[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return sub chunk at given index (for reading only)
|
||||
*
|
||||
* This function transparently provides a zero sub chunk for any
|
||||
* index that is not populated by a real chunk.
|
||||
*/
|
||||
Entry const &_entry_for_reading(unsigned index) const
|
||||
{
|
||||
if (index >= NUM_ENTRIES)
|
||||
throw Index_out_of_range();
|
||||
|
||||
if (_entries[index])
|
||||
return *_entries[index];
|
||||
|
||||
return _zero_chunk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return index of entry located at specified byte offset
|
||||
*
|
||||
* The caller of this function must make sure that the offset
|
||||
* parameter is within the bounds of the chunk.
|
||||
*/
|
||||
unsigned _index_by_offset(seek_off_t offset) const
|
||||
{
|
||||
return (offset - base_offset()) / ENTRY_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply operation 'func' to a range of entries
|
||||
*/
|
||||
template <typename THIS, typename DATA, typename FUNC>
|
||||
static void _range_op(THIS &obj, DATA *data, size_t len,
|
||||
seek_off_t seek_offset, FUNC const &func)
|
||||
{
|
||||
/*
|
||||
* Depending on whether this function is called for reading
|
||||
* (const function) or writing (non-const function), the
|
||||
* operand type is const or non-const Entry. The correct type
|
||||
* is embedded as a trait in the 'FUNC' functor type.
|
||||
*/
|
||||
typedef typename FUNC::Entry Const_qualified_entry;
|
||||
|
||||
obj.assert_valid_range(seek_offset, len, SIZE);
|
||||
|
||||
while (len > 0) {
|
||||
|
||||
unsigned const index = obj._index_by_offset(seek_offset);
|
||||
|
||||
Const_qualified_entry &entry = FUNC::lookup(obj, index);
|
||||
|
||||
/*
|
||||
* Calculate byte offset relative to the chunk
|
||||
*
|
||||
* We cannot use 'entry.base_offset()' for this calculation
|
||||
* because in the const case, the lookup might return a
|
||||
* zero chunk, which has no defined base offset. Therefore,
|
||||
* we calculate the base offset via index*ENTRY_SIZE.
|
||||
*/
|
||||
seek_off_t const local_seek_offset =
|
||||
seek_offset - obj.base_offset() - index*ENTRY_SIZE;
|
||||
|
||||
/* available capacity at 'entry' starting at seek offset */
|
||||
seek_off_t const capacity = ENTRY_SIZE - local_seek_offset;
|
||||
seek_off_t const curr_len = min(len, capacity);
|
||||
|
||||
/* apply functor (read or write) to entry */
|
||||
func(entry, data, curr_len, seek_offset);
|
||||
|
||||
/* advance to next entry */
|
||||
len -= curr_len;
|
||||
data += curr_len;
|
||||
seek_offset += curr_len;
|
||||
}
|
||||
}
|
||||
|
||||
struct Write_func
|
||||
{
|
||||
typedef ENTRY_TYPE Entry;
|
||||
|
||||
static Entry &lookup(Chunk_index &chunk, unsigned i) {
|
||||
return chunk._entry_for_writing(i); }
|
||||
|
||||
void operator () (Entry &entry, char const *src, size_t len,
|
||||
seek_off_t seek_offset) const
|
||||
{
|
||||
entry.write(src, len, seek_offset);
|
||||
}
|
||||
};
|
||||
|
||||
struct Read_func
|
||||
{
|
||||
typedef ENTRY_TYPE const Entry;
|
||||
|
||||
static Entry &lookup(Chunk_index const &chunk, unsigned i) {
|
||||
return chunk._entry_for_reading(i); }
|
||||
|
||||
void operator () (Entry &entry, char *dst, size_t len,
|
||||
seek_off_t seek_offset) const
|
||||
{
|
||||
if (entry.zero())
|
||||
memset(dst, 0, len);
|
||||
else
|
||||
entry.read(dst, len, seek_offset);
|
||||
}
|
||||
};
|
||||
|
||||
void _init_entries()
|
||||
{
|
||||
for (unsigned i = 0; i < NUM_ENTRIES; i++)
|
||||
_entries[i] = 0;
|
||||
}
|
||||
|
||||
void _destroy_entry(unsigned i)
|
||||
{
|
||||
if (_entries[i] && (i < _num_entries)) {
|
||||
destroy(&_alloc, _entries[i]);
|
||||
_entries[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param alloc allocator to use for allocating sub-chunk
|
||||
* indices and chunks
|
||||
* \param base_offset absolute offset of the chunk in bytes
|
||||
*/
|
||||
Chunk_index(Allocator &alloc, seek_off_t base_offset)
|
||||
: Chunk_base(base_offset), _alloc(alloc) { _init_entries(); }
|
||||
|
||||
/**
|
||||
* Construct zero chunk
|
||||
*/
|
||||
Chunk_index() : _alloc(*(Allocator *)0) { }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Chunk_index()
|
||||
{
|
||||
for (unsigned i = 0; i < NUM_ENTRIES; i++)
|
||||
_destroy_entry(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return size of chunk in bytes
|
||||
*
|
||||
* The returned value corresponds to the position after the highest
|
||||
* offset that was written to.
|
||||
*/
|
||||
file_size_t used_size() const
|
||||
{
|
||||
if (_num_entries == 0)
|
||||
return 0;
|
||||
|
||||
/* size of entries that lie completely within the used range */
|
||||
file_size_t const size_whole_entries = ENTRY_SIZE*(_num_entries - 1);
|
||||
|
||||
Entry *last_entry = _entries[_num_entries - 1];
|
||||
if (!last_entry)
|
||||
return size_whole_entries;
|
||||
|
||||
return size_whole_entries + last_entry->used_size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to chunk
|
||||
*/
|
||||
void write(char const *src, size_t len, seek_off_t seek_offset)
|
||||
{
|
||||
_range_op(*this, src, len, seek_offset, Write_func());
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from chunk
|
||||
*/
|
||||
void read(char *dst, size_t len, seek_off_t seek_offset) const
|
||||
{
|
||||
_range_op(*this, dst, len, seek_offset, Read_func());
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate chunk to specified size in bytes
|
||||
*
|
||||
* This function can be used to shrink a chunk only. Specifying a
|
||||
* 'size' larger than 'used_size' has no effect. The value returned
|
||||
* by 'used_size' refers always to the position of the last byte
|
||||
* written to the chunk.
|
||||
*/
|
||||
void truncate(file_size_t size)
|
||||
{
|
||||
unsigned const trunc_index = _index_by_offset(size);
|
||||
|
||||
if (trunc_index >= _num_entries)
|
||||
return;
|
||||
|
||||
for (unsigned i = trunc_index + 1; i < _num_entries; i++)
|
||||
_destroy_entry(i);
|
||||
|
||||
/* traverse into sub chunks */
|
||||
if (_entries[trunc_index])
|
||||
_entries[trunc_index]->truncate(size);
|
||||
|
||||
_num_entries = trunc_index + 1;
|
||||
|
||||
/*
|
||||
* If the truncated at a chunk boundary, we can release the
|
||||
* empty trailing chunk at 'trunc_index'.
|
||||
*/
|
||||
if (_entries[trunc_index] && _entries[trunc_index]->empty()) {
|
||||
_destroy_entry(trunc_index);
|
||||
_num_entries--;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* _CHUNK_H_ */
|
|
@ -1,222 +0,0 @@
|
|||
/*
|
||||
* \brief File-system directory node
|
||||
* \author Norman Feske
|
||||
* \date 2012-04-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _DIRECTORY_H_
|
||||
#define _DIRECTORY_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <file_system/util.h>
|
||||
|
||||
/* local includes */
|
||||
#include <node.h>
|
||||
#include <file.h>
|
||||
#include <symlink.h>
|
||||
|
||||
namespace Trace_fs {
|
||||
class Directory;
|
||||
}
|
||||
|
||||
class Trace_fs::Directory : public Node
|
||||
{
|
||||
private:
|
||||
|
||||
List<Node> _entries;
|
||||
size_t _num_entries;
|
||||
|
||||
public:
|
||||
|
||||
Directory(char const *name) : _num_entries(0) { Node::name(name); }
|
||||
|
||||
|
||||
/**
|
||||
* Check if the directory has the specified subnode
|
||||
*
|
||||
* \param name name of the searched subnode
|
||||
*
|
||||
* \return true if the subnode was found, either false
|
||||
*/
|
||||
bool has_sub_node_unsynchronized(char const *name) const
|
||||
{
|
||||
Node const *sub_node = _entries.first();
|
||||
for (; sub_node; sub_node = sub_node->next())
|
||||
if (strcmp(sub_node->name(), name) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add node to the list of subnodes
|
||||
*
|
||||
* \param pointer to node
|
||||
*/
|
||||
void adopt_unsynchronized(Node *node)
|
||||
{
|
||||
/*
|
||||
* XXX inc ref counter
|
||||
*/
|
||||
_entries.insert(node);
|
||||
_num_entries++;
|
||||
|
||||
mark_as_updated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the node from the list of subnodes
|
||||
*
|
||||
* \param node pointer to node
|
||||
*/
|
||||
void discard_unsynchronized(Node *node)
|
||||
{
|
||||
_entries.remove(node);
|
||||
_num_entries--;
|
||||
|
||||
mark_as_updated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup node which belongs to the specified path
|
||||
*
|
||||
* \param path path to lookup
|
||||
* \param return_parent if true return parent node, otherwise
|
||||
* actual path node
|
||||
*
|
||||
* \return node node founc
|
||||
* \throws Lookup_failed
|
||||
*/
|
||||
Node *lookup(char const *path, bool return_parent = false) override
|
||||
{
|
||||
if (strcmp(path, "") == 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (!path || path[0] == '/')
|
||||
throw Lookup_failed();
|
||||
|
||||
/* find first path delimiter */
|
||||
unsigned i = 0;
|
||||
for (; path[i] && path[i] != '/'; i++);
|
||||
|
||||
/*
|
||||
* If no path delimiter was found, we are the parent of the
|
||||
* specified path.
|
||||
*/
|
||||
if (path[i] == 0 && return_parent) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* The offset 'i' corresponds to the end of the first path
|
||||
* element, which can be either the end of the string or the
|
||||
* first '/' character.
|
||||
*/
|
||||
|
||||
/* try to find entry that matches the first path element */
|
||||
Node *sub_node = _entries.first();
|
||||
for (; sub_node; sub_node = sub_node->next())
|
||||
if ((strlen(sub_node->name()) == i) &&
|
||||
(strcmp(sub_node->name(), path, i) == 0))
|
||||
break;
|
||||
|
||||
if (!sub_node)
|
||||
throw Lookup_failed();
|
||||
|
||||
if (!contains_path_delimiter(path)) {
|
||||
|
||||
/*
|
||||
* Because 'path' is a basename that corresponds to an
|
||||
* existing sub_node, we have found what we were looking
|
||||
* for.
|
||||
*/
|
||||
return sub_node;
|
||||
}
|
||||
|
||||
/*
|
||||
* As 'path' contains one or more path delimiters, traverse
|
||||
* into the sub directory names after the first path element.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We cannot traverse into anything other than a directory.
|
||||
*
|
||||
* XXX we might follow symlinks here
|
||||
*/
|
||||
Directory *sub_dir = dynamic_cast<Directory *>(sub_node);
|
||||
if (!sub_dir)
|
||||
throw Lookup_failed();
|
||||
|
||||
return sub_dir->lookup(path + i + 1, return_parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return number of subnodes
|
||||
*/
|
||||
size_t num_entries() const { return _num_entries; }
|
||||
|
||||
|
||||
/********************
|
||||
** Node interface **
|
||||
********************/
|
||||
|
||||
size_t read(char *dst, size_t len, seek_off_t seek_offset)
|
||||
{
|
||||
if (len < sizeof(Directory_entry)) {
|
||||
Genode::error("read buffer too small for directory entry");
|
||||
return 0;
|
||||
}
|
||||
|
||||
seek_off_t index = seek_offset / sizeof(Directory_entry);
|
||||
|
||||
if (seek_offset % sizeof(Directory_entry)) {
|
||||
Genode::error("seek offset not alighed to sizeof(Directory_entry)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* find list element */
|
||||
Node *node = _entries.first();
|
||||
for (unsigned i = 0; i < index && node; node = node->next(), i++);
|
||||
|
||||
/* index out of range */
|
||||
if (!node)
|
||||
return 0;
|
||||
|
||||
Directory_entry *e = (Directory_entry *)(dst);
|
||||
|
||||
if (dynamic_cast<File *>(node)) e->type = Directory_entry::TYPE_FILE;
|
||||
if (dynamic_cast<Directory *>(node)) e->type = Directory_entry::TYPE_DIRECTORY;
|
||||
if (dynamic_cast<Symlink *>(node)) e->type = Directory_entry::TYPE_SYMLINK;
|
||||
|
||||
strncpy(e->name, node->name(), sizeof(e->name));
|
||||
|
||||
return sizeof(Directory_entry);
|
||||
}
|
||||
|
||||
size_t write(char const *src, size_t len, seek_off_t seek_offset)
|
||||
{
|
||||
/* writing to directory nodes is not supported */
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status status() const
|
||||
{
|
||||
Status s;
|
||||
s.inode = inode();
|
||||
s.size = _num_entries * sizeof (Directory_entry);
|
||||
s.mode = File_system::Status::MODE_DIRECTORY;
|
||||
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _DIRECTORY_H_ */
|
|
@ -1,220 +0,0 @@
|
|||
/*
|
||||
* \brief File node
|
||||
* \author Norman Feske
|
||||
* \author Josef Soentgen
|
||||
* \date 2012-04-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _FILE_H_
|
||||
#define _FILE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/allocator.h>
|
||||
#include <base/trace/types.h>
|
||||
|
||||
/* local includes */
|
||||
#include <node.h>
|
||||
#include <chunk.h>
|
||||
|
||||
namespace Trace_fs {
|
||||
class Changeable_content;
|
||||
class File;
|
||||
class Buffered_file;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
class Trace_fs::Changeable_content
|
||||
{
|
||||
protected:
|
||||
|
||||
/**
|
||||
* This member is used to communicate the state and
|
||||
* must be set true by classes using this class in case
|
||||
* the content has changed.
|
||||
*/
|
||||
bool _changed;
|
||||
|
||||
/**
|
||||
* This method is called when the content change is
|
||||
* acknowledged. It may be overriden by any class using
|
||||
* this particular class.
|
||||
*/
|
||||
virtual void _refresh_content() { }
|
||||
|
||||
public:
|
||||
|
||||
Changeable_content() : _changed(false) { }
|
||||
|
||||
/**
|
||||
* Check if the content was changed
|
||||
*
|
||||
* This evaluation has to be made by classes using this
|
||||
* particular class.
|
||||
*
|
||||
* \return true if changed, otherwise false
|
||||
*/
|
||||
bool changed() const { return _changed; }
|
||||
|
||||
|
||||
/**
|
||||
* Acknowledge the content has changed
|
||||
*/
|
||||
void acknowledge_change()
|
||||
{
|
||||
_changed = false;
|
||||
|
||||
_refresh_content();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* File interface
|
||||
*/
|
||||
|
||||
class Trace_fs::File : public Node
|
||||
{
|
||||
public:
|
||||
|
||||
File(char const *name)
|
||||
{
|
||||
Node::name(name);
|
||||
}
|
||||
|
||||
virtual ~File() { }
|
||||
|
||||
/********************
|
||||
** Node interface **
|
||||
********************/
|
||||
|
||||
virtual size_t read(char *dst, size_t len, seek_off_t seek_offset) = 0;
|
||||
|
||||
virtual size_t write(char const *src, size_t len, seek_off_t seek_offset) = 0;
|
||||
|
||||
virtual Status status() const = 0;
|
||||
|
||||
/********************
|
||||
** File interface **
|
||||
********************/
|
||||
|
||||
virtual file_size_t length() const = 0;
|
||||
|
||||
virtual void truncate(file_size_t size) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Memory buffered file
|
||||
*
|
||||
* This file merely exists in memory and grows automatically.
|
||||
*/
|
||||
|
||||
class Trace_fs::Buffered_file : public File
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Chunk<4096> Chunk_level_3;
|
||||
typedef Chunk_index<128, Chunk_level_3> Chunk_level_2;
|
||||
typedef Chunk_index<64, Chunk_level_2> Chunk_level_1;
|
||||
typedef Chunk_index<64, Chunk_level_1> Chunk_level_0;
|
||||
|
||||
Chunk_level_0 _chunk;
|
||||
|
||||
file_size_t _length;
|
||||
|
||||
public:
|
||||
|
||||
Buffered_file(Allocator &alloc, char const *name)
|
||||
: File(name), _chunk(alloc, 0), _length(0) { }
|
||||
|
||||
virtual size_t read(char *dst, size_t len, seek_off_t seek_offset)
|
||||
{
|
||||
file_size_t const chunk_used_size = _chunk.used_size();
|
||||
|
||||
if (seek_offset >= _length)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Constrain read transaction to available chunk data
|
||||
*
|
||||
* Note that 'chunk_used_size' may be lower than '_length'
|
||||
* because 'Chunk' may have truncated tailing zeros.
|
||||
*/
|
||||
if (seek_offset + len >= _length)
|
||||
len = _length - seek_offset;
|
||||
|
||||
file_size_t read_len = len;
|
||||
|
||||
if (seek_offset + read_len > chunk_used_size) {
|
||||
if (chunk_used_size >= seek_offset)
|
||||
read_len = chunk_used_size - seek_offset;
|
||||
else
|
||||
read_len = 0;
|
||||
}
|
||||
|
||||
_chunk.read(dst, read_len, seek_offset);
|
||||
|
||||
/* add zero padding if needed */
|
||||
if (read_len < len)
|
||||
memset(dst + read_len, 0, len - read_len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
virtual size_t write(char const *src, size_t len, seek_off_t seek_offset)
|
||||
{
|
||||
if (seek_offset == (seek_off_t)(~0))
|
||||
seek_offset = _chunk.used_size();
|
||||
|
||||
if (seek_offset + len >= Chunk_level_0::SIZE) {
|
||||
len = (Chunk_level_0::SIZE-1) - seek_offset;
|
||||
Genode::error(name(), ": size limit ", (long)Chunk_level_0::SIZE, " reached");
|
||||
}
|
||||
|
||||
_chunk.write(src, len, (size_t)seek_offset);
|
||||
|
||||
/*
|
||||
* Keep track of file length. We cannot use 'chunk.used_size()'
|
||||
* as file length because trailing zeros may by represented
|
||||
* by zero chunks, which do not contribute to 'used_size()'.
|
||||
*/
|
||||
_length = max(_length, seek_offset + len);
|
||||
|
||||
mark_as_updated();
|
||||
return len;
|
||||
}
|
||||
|
||||
virtual Status status() const
|
||||
{
|
||||
Status s;
|
||||
|
||||
s.inode = inode();
|
||||
s.size = _length;
|
||||
s.mode = File_system::Status::MODE_FILE;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
virtual file_size_t length() const { return _length; }
|
||||
|
||||
void truncate(file_size_t size) override
|
||||
{
|
||||
if (size < _chunk.used_size())
|
||||
_chunk.truncate(size);
|
||||
|
||||
_length = size;
|
||||
|
||||
mark_as_updated();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _FILE_H_ */
|
|
@ -1,283 +0,0 @@
|
|||
/*
|
||||
* \brief Facility for managing the trace subjects
|
||||
* \author Josef Soentgen
|
||||
* \date 2014-01-22
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _SUBJECT_REGISTRY_H_
|
||||
#define _SUBJECT_REGISTRY_H_
|
||||
|
||||
#include <base/allocator.h>
|
||||
#include <base/lock.h>
|
||||
#include <base/trace/types.h>
|
||||
|
||||
#include <directory.h>
|
||||
#include <trace_files.h>
|
||||
|
||||
namespace Trace_fs {
|
||||
typedef Genode::size_t size_t;
|
||||
class Followed_subject;
|
||||
class Followed_subject_registry;
|
||||
}
|
||||
|
||||
class Trace_fs::Followed_subject : public Directory
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* This class manages the access to the trace subject's trace buffer
|
||||
*/
|
||||
class Trace_buffer_manager
|
||||
{
|
||||
public:
|
||||
|
||||
class Already_managed { };
|
||||
class Not_managed { };
|
||||
|
||||
struct Process_entry
|
||||
{
|
||||
virtual size_t operator()(Genode::Trace::Buffer::Entry&) = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Genode::Trace::Buffer *buffer;
|
||||
Genode::Trace::Buffer::Entry current_entry;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Trace_buffer_manager(Genode::Region_map &rm,
|
||||
Genode::Dataspace_capability ds_cap)
|
||||
:
|
||||
buffer(rm.attach(ds_cap)),
|
||||
current_entry(buffer->first())
|
||||
{ }
|
||||
|
||||
size_t dump_entry(Process_entry &process)
|
||||
{
|
||||
size_t len = process(current_entry);
|
||||
|
||||
current_entry = buffer->next(current_entry);
|
||||
return len;
|
||||
}
|
||||
|
||||
bool last_entry() const
|
||||
{
|
||||
return current_entry.last();
|
||||
}
|
||||
|
||||
void rewind() { current_entry = buffer->first(); }
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Genode::Allocator &_md_alloc;
|
||||
|
||||
Genode::Region_map &_rm;
|
||||
|
||||
int _handle;
|
||||
|
||||
Genode::Trace::Subject_id _id;
|
||||
Genode::Trace::Policy_id _policy_id;
|
||||
|
||||
bool _was_traced;
|
||||
|
||||
Trace_buffer_manager *_buffer_manager;
|
||||
|
||||
public:
|
||||
|
||||
Active_file active_file;
|
||||
Buffer_size_file buffer_size_file;
|
||||
Cleanup_file cleanup_file;
|
||||
Enable_file enable_file;
|
||||
Events_file events_file;
|
||||
Policy_file policy_file;
|
||||
|
||||
Followed_subject(Genode::Allocator &md_alloc, char const *name,
|
||||
Genode::Region_map &rm,
|
||||
Genode::Trace::Subject_id &id, int handle)
|
||||
:
|
||||
Directory(name),
|
||||
_md_alloc(md_alloc),
|
||||
_rm(rm),
|
||||
_handle(handle),
|
||||
_id(id),
|
||||
_was_traced(false),
|
||||
_buffer_manager(0),
|
||||
active_file(_id),
|
||||
buffer_size_file(),
|
||||
cleanup_file(_id),
|
||||
enable_file(_id),
|
||||
events_file(_id, _md_alloc),
|
||||
policy_file(_id, _md_alloc)
|
||||
{
|
||||
adopt_unsynchronized(&active_file);
|
||||
adopt_unsynchronized(&cleanup_file);
|
||||
adopt_unsynchronized(&enable_file);
|
||||
adopt_unsynchronized(&events_file);
|
||||
adopt_unsynchronized(&buffer_size_file);
|
||||
adopt_unsynchronized(&policy_file);
|
||||
}
|
||||
|
||||
~Followed_subject()
|
||||
{
|
||||
discard_unsynchronized(&active_file);
|
||||
discard_unsynchronized(&cleanup_file);
|
||||
discard_unsynchronized(&enable_file);
|
||||
discard_unsynchronized(&events_file);
|
||||
discard_unsynchronized(&buffer_size_file);
|
||||
discard_unsynchronized(&policy_file);
|
||||
}
|
||||
|
||||
bool marked_for_cleanup() const { return cleanup_file.cleanup(); }
|
||||
bool was_traced() const { return _was_traced; }
|
||||
|
||||
Trace_buffer_manager* trace_buffer_manager() { return _buffer_manager; }
|
||||
|
||||
void manage_trace_buffer(Genode::Dataspace_capability ds_cap)
|
||||
{
|
||||
if (_buffer_manager != 0)
|
||||
throw Trace_buffer_manager::Already_managed();
|
||||
|
||||
_buffer_manager = new (&_md_alloc) Trace_buffer_manager(_rm, ds_cap);
|
||||
}
|
||||
|
||||
void unmanage_trace_buffer()
|
||||
{
|
||||
if (_buffer_manager == 0)
|
||||
throw Trace_buffer_manager::Not_managed();
|
||||
|
||||
destroy(&_md_alloc, _buffer_manager);
|
||||
_buffer_manager = 0;
|
||||
}
|
||||
|
||||
const Genode::Trace::Subject_id id() const { return _id; }
|
||||
|
||||
const Genode::Trace::Policy_id policy_id() const { return _policy_id; }
|
||||
void policy_id(Genode::Trace::Policy_id &id) { _policy_id.id = id.id; }
|
||||
bool policy_valid() const { return (_policy_id.id != 0); }
|
||||
void invalidate_policy() { _policy_id = Genode::Trace::Policy_id(); }
|
||||
|
||||
int handle() const { return _handle; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This registry contains all current followed trace subjects
|
||||
*/
|
||||
class Trace_fs::Followed_subject_registry
|
||||
{
|
||||
public:
|
||||
|
||||
class Invalid_subject { };
|
||||
class Out_of_subject_handles { };
|
||||
|
||||
private:
|
||||
|
||||
/* XXX abitrary limit - needs to be revisited when highly
|
||||
* dynamic scenarios are executed */
|
||||
enum { MAX_SUBJECTS = 1024U };
|
||||
|
||||
Followed_subject *_subjects[MAX_SUBJECTS];
|
||||
|
||||
Genode::Allocator &_md_alloc;
|
||||
|
||||
/**
|
||||
* Find free subject handle
|
||||
*
|
||||
* \throw Out_of_subject_handles
|
||||
*/
|
||||
int _find_free_handle()
|
||||
{
|
||||
for (unsigned i = 0; i < MAX_SUBJECTS; i++)
|
||||
if (!_subjects[i]) {
|
||||
return i;
|
||||
}
|
||||
|
||||
throw Out_of_subject_handles();
|
||||
}
|
||||
|
||||
bool _in_range(int handle) const
|
||||
{
|
||||
return ((handle >= 0) && (handle < MAX_SUBJECTS));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Followed_subject_registry(Genode::Allocator &md_alloc)
|
||||
:
|
||||
_md_alloc(md_alloc)
|
||||
{
|
||||
for (unsigned i = 0; i < MAX_SUBJECTS; i++)
|
||||
_subjects[i] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return maximal number of subject that can be stored in the registry
|
||||
*
|
||||
* \return maximal number of subjects
|
||||
*/
|
||||
unsigned max_subjects() const { return MAX_SUBJECTS; }
|
||||
|
||||
/**
|
||||
* Allocate new subject
|
||||
*
|
||||
* \param name name of subject
|
||||
* \param id subject id of tracre subject
|
||||
*/
|
||||
Followed_subject *alloc(char const *name, Genode::Trace::Subject_id &id,
|
||||
Genode::Region_map &rm)
|
||||
{
|
||||
int handle = _find_free_handle();
|
||||
|
||||
_subjects[handle] = new (&_md_alloc) Followed_subject(_md_alloc, name, rm, id, handle);
|
||||
|
||||
return _subjects[handle];
|
||||
}
|
||||
|
||||
/**
|
||||
* Free subject
|
||||
*
|
||||
* \param subject pointer to subject
|
||||
*/
|
||||
void free(Followed_subject *subject)
|
||||
{
|
||||
int handle = subject->handle();
|
||||
|
||||
if (!_in_range(handle))
|
||||
return;
|
||||
|
||||
if(!_subjects[handle])
|
||||
return;
|
||||
|
||||
_subjects[handle] = 0;
|
||||
destroy(&_md_alloc, subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup subject by using the id
|
||||
*
|
||||
* \throw Invalid_subject();
|
||||
*/
|
||||
Followed_subject *lookup(Genode::Trace::Subject_id const &sid)
|
||||
{
|
||||
for (unsigned i = 0; i < MAX_SUBJECTS; i++)
|
||||
if (_subjects[i]) {
|
||||
if (_subjects[i]->id().id == sid.id)
|
||||
return _subjects[i];
|
||||
}
|
||||
|
||||
throw Invalid_subject();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _SUBJECT_REGISTRY_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* \brief File-system node
|
||||
* \author Norman Feske
|
||||
* \date 2012-04-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _NODE_H_
|
||||
#define _NODE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <file_system/node.h>
|
||||
#include <util/list.h>
|
||||
#include <base/lock.h>
|
||||
#include <base/signal.h>
|
||||
|
||||
namespace Trace_fs {
|
||||
using namespace File_system;
|
||||
using namespace Genode;
|
||||
class Node;
|
||||
}
|
||||
|
||||
class Trace_fs::Node : public Node_base, public Weak_object<Node>,
|
||||
public List<Node>::Element
|
||||
{
|
||||
public:
|
||||
|
||||
typedef char Name[128];
|
||||
|
||||
private:
|
||||
|
||||
Name _name;
|
||||
unsigned long const _inode;
|
||||
|
||||
/**
|
||||
* Generate unique inode number
|
||||
*/
|
||||
static unsigned long _unique_inode()
|
||||
{
|
||||
static unsigned long inode_count;
|
||||
return ++inode_count;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Node()
|
||||
: _inode(_unique_inode())
|
||||
{ _name[0] = 0; }
|
||||
|
||||
virtual ~Node() { lock_for_destruction(); }
|
||||
|
||||
unsigned long inode() const { return _inode; }
|
||||
char const *name() const { return _name; }
|
||||
|
||||
/**
|
||||
* Assign name
|
||||
*/
|
||||
void name(char const *name) { strncpy(_name, name, sizeof(_name)); }
|
||||
|
||||
virtual Status status() const = 0;
|
||||
|
||||
virtual size_t read(char *dst, size_t len, seek_off_t) = 0;
|
||||
virtual size_t write(char const *src, size_t len, seek_off_t) = 0;
|
||||
|
||||
/*
|
||||
* Directory functionality
|
||||
*/
|
||||
virtual Node *lookup(char const *path, bool return_parent = false)
|
||||
{
|
||||
Genode::error(__PRETTY_FUNCTION__, " called on a non-directory node");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* File functionality
|
||||
*/
|
||||
virtual void truncate(file_size_t size)
|
||||
{
|
||||
Genode::error(__PRETTY_FUNCTION__, " called on a non-file node");
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _NODE_H_ */
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* \brief Symlink file-system node
|
||||
* \author Norman Feske
|
||||
* \date 2012-04-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _SYMLINK_H_
|
||||
#define _SYMLINK_H_
|
||||
|
||||
/* local includes */
|
||||
#include <file.h>
|
||||
|
||||
namespace Trace_fs {
|
||||
class Symlink;
|
||||
}
|
||||
|
||||
class Trace_fs::Symlink : public File
|
||||
{
|
||||
public:
|
||||
|
||||
Symlink(char const *name) : File(name) { }
|
||||
|
||||
size_t read(char *dst, size_t len, seek_off_t seek_offset) {
|
||||
return 0; }
|
||||
|
||||
size_t write(char const *src, size_t len, seek_off_t seek_offset) {
|
||||
return 0; }
|
||||
|
||||
file_size_t length() const { return 0; }
|
||||
|
||||
void truncate(file_size_t) { }
|
||||
};
|
||||
|
||||
#endif /* _SYMLINK_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user